All modules, excluding 3204 are debugged and seems to work
This commit is contained in:
parent
710a0327a7
commit
d55027d422
BIN
datasheets/MAX6070-MAX6071.pdf
Normal file
BIN
datasheets/MAX6070-MAX6071.pdf
Normal file
Binary file not shown.
7
src/DEADJOE
Normal file
7
src/DEADJOE
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
*** These modified files were found in JOE when it aborted on Tue Aug 9 19:43:11 2022
|
||||
*** JOE was aborted because the terminal closed
|
||||
|
||||
*** File '(Unnamed)'
|
||||
_registerAcc
|
||||
spi_write
|
||||
117
src/MAX11270.py
117
src/MAX11270.py
@ -83,6 +83,10 @@ MAX11270_SPS_4000 = 0b1101
|
||||
MAX11270_SPS_6400 = 0b1110
|
||||
MAX11270_SPS_12800 = 0b1111
|
||||
|
||||
def reverseBits(n,width):
|
||||
b = '{:0{width}b}'.format(n, width=width)
|
||||
return int(b[::-1], 2)
|
||||
|
||||
class MAX11270:
|
||||
'''
|
||||
Constructor of the class, setup the GPIO pin for SPI-communication
|
||||
@ -96,7 +100,7 @@ class MAX11270:
|
||||
self.rstbPin = RSTB_Pin
|
||||
|
||||
self.softSPI = True
|
||||
|
||||
'''
|
||||
if self.clkPin == 11 and self.mosiPin == 10 and self.misoPin == 9:
|
||||
self.spidev = 0
|
||||
if self.csPin == 8:
|
||||
@ -117,12 +121,14 @@ class MAX11270:
|
||||
elif self.csPin == 16:
|
||||
self.spichan == 2
|
||||
self.softSPI = False
|
||||
|
||||
'''
|
||||
if vref is None:
|
||||
self.vref = 3
|
||||
else:
|
||||
self.vref = vref
|
||||
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
|
||||
GPIO.setup(self.clkPin, GPIO.OUT)
|
||||
GPIO.setup(self.mosiPin, GPIO.OUT)
|
||||
GPIO.setup(self.csPin, GPIO.OUT)
|
||||
@ -132,10 +138,14 @@ class MAX11270:
|
||||
GPIO.setup(self.misoPin, GPIO.IN)
|
||||
|
||||
GPIO.output(self.syncPin, GPIO.LOW)
|
||||
#Reset the ADC at creation time
|
||||
GPIO.output(self.rstbPin, GPIO.HIGH)
|
||||
GPIO.output(self.rstbPin, GPIO.LOW)
|
||||
GPIO.output(self.rstbPin, GPIO.HIGH)
|
||||
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
GPIO.output(self.clkPin, GPIO.LOW)
|
||||
GPIO.output(self.mosiPin, GPIO.LOW)
|
||||
|
||||
self.ready = 0
|
||||
self.mstat = 0
|
||||
@ -176,11 +186,13 @@ class MAX11270:
|
||||
adc_command <<= 1
|
||||
|
||||
self._toggleClock()
|
||||
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
|
||||
'''
|
||||
Operates the ADC in register access mode, used for configuration and readout
|
||||
'''
|
||||
def _registerAccessMode(self,register=0x0,rw)
|
||||
def _registerAccessMode(self,rw,register=0x0):
|
||||
adc_command = 0b11000000 | register<<1 | rw
|
||||
# Start com
|
||||
GPIO.output(self.csPin, GPIO.LOW)
|
||||
@ -196,30 +208,31 @@ class MAX11270:
|
||||
|
||||
self._toggleClock()
|
||||
|
||||
#GPIO.output(self.csPin, GPIO.HIGH)
|
||||
|
||||
|
||||
def _spi_read(self, numbytes):
|
||||
retVal = 0
|
||||
|
||||
# Start readout
|
||||
# Start readout, in most cases cs is already low, because of register access
|
||||
GPIO.output(self.csPin, GPIO.LOW)
|
||||
#time.sleep(0.0001)
|
||||
#Commucation consists of 32 transfered bits
|
||||
for bit in range(numbytes*8):
|
||||
|
||||
numBits = numbytes*8
|
||||
for bit in range(numBits):
|
||||
# Read 1 data bit
|
||||
if GPIO.input(self.misoPin):
|
||||
retVal |= 0x1
|
||||
|
||||
# Advance input to next bit
|
||||
retVal <<= 1
|
||||
retVal |= (1<<(numBits-1-bit))
|
||||
|
||||
self._toggleClock()
|
||||
|
||||
# Set chip select high to end the read process
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
#print(bin(retVal))
|
||||
|
||||
print(bin(retVal))
|
||||
return retVal
|
||||
|
||||
def _spi_write(self,adc_command)
|
||||
|
||||
def _spi_write(self,adc_command):
|
||||
# Start com
|
||||
GPIO.output(self.csPin, GPIO.LOW)
|
||||
for bit in range(8):
|
||||
@ -233,24 +246,46 @@ class MAX11270:
|
||||
adc_command <<= 1
|
||||
|
||||
self._toggleClock()
|
||||
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
|
||||
def _readAndChangeRegisterValue(self,register,value,firstBit,bits=1):
|
||||
def _readAndChangeRegisterValue(self,register,newBits,firstBit,bits=1):
|
||||
print('--------------')
|
||||
#First readout register in order to change only one value
|
||||
#Select register
|
||||
self._registerAccessMode(register,1)
|
||||
self._registerAccessMode(1,register)
|
||||
#Read stored values
|
||||
value = self._spi_read(1)
|
||||
self._registerAccessMode(register,0)
|
||||
for bit in range(0,bits):
|
||||
if value >> bit & 1 == 0:
|
||||
value = value & ~(1<<firstBit+bit)
|
||||
else:
|
||||
value = value | (1<<firstBit+bit)
|
||||
self._spi_write(value)
|
||||
|
||||
def readStatusRegister(self):
|
||||
self._registerAccessMode(MAX11270_REG_STAT,1)
|
||||
value = self._spi_read(2)
|
||||
print('Inital register value')
|
||||
print(bin(value))
|
||||
|
||||
#Change value in register
|
||||
for bit in range(0,bits):
|
||||
#Compare register value with new value at position bit, if unequal set new value
|
||||
if value >> (firstBit + bit) & 1 != (newBits >> bit) & 1:
|
||||
if value >> bit & 1 == 1:
|
||||
value = value & ~(1<<firstBit+bit)
|
||||
else:
|
||||
value = value | (1<<firstBit+bit)
|
||||
print('Changed register value')
|
||||
print(bin(value))
|
||||
#Write back register
|
||||
self._registerAccessMode(0,register)
|
||||
self._spi_write(value)
|
||||
|
||||
#Readout register again to check if values changed
|
||||
#Select register
|
||||
self._registerAccessMode(1,register)
|
||||
#Read stored values
|
||||
value = self._spi_read(1)
|
||||
print('Final register value')
|
||||
print(bin(value))
|
||||
print('--------------')
|
||||
|
||||
def readStatusRegister(self,disp=0):
|
||||
self._registerAccessMode(1,MAX11270_REG_STAT)
|
||||
value = self._spi_read(2)
|
||||
|
||||
self.ready = value >> 0 & 1
|
||||
self.mstat = value >> 1 & 1
|
||||
self.dataOverrange = value >> 2 & 1
|
||||
@ -261,6 +296,24 @@ class MAX11270:
|
||||
self.powerState = value >> 10 & 0b11
|
||||
self.error = value >> 14 & 1
|
||||
self.inReset = value >> 15 & 1
|
||||
|
||||
if disp:
|
||||
if self.ready:
|
||||
print('Conversion result available')
|
||||
if self.mstat:
|
||||
print('Conversion, self-calibration or system-calibration in progress')
|
||||
if self.dataOverrange:
|
||||
print('Conversion result exceeded the max or min value')
|
||||
if self.systemGainOverrange:
|
||||
print(' system gain calibration was overranged')
|
||||
if self.analogOverrange:
|
||||
print(' the modulator detects that the analog input voltage exceeds 1.3 x full-scale range')
|
||||
if self.dataReadError:
|
||||
print(' result is being written to the DATA register while user is reading from the DATA register.')
|
||||
if self.error:
|
||||
print('CAL[1:0] bits are set to invalid setting of 11.')
|
||||
if self.inReset:
|
||||
print('software reset mode')
|
||||
|
||||
return value
|
||||
|
||||
@ -312,7 +365,7 @@ class MAX11270:
|
||||
else:
|
||||
raise Exception("No known power state selected")
|
||||
|
||||
def setSyncMode(self,mode):
|
||||
def setSyncMode(self,mode):
|
||||
if mode == 'continuousSync':
|
||||
self._readAndChangeRegisterValue(MAX11270_REG_CTRL1,1,6)
|
||||
elif mode == 'pulseSync':
|
||||
@ -393,17 +446,18 @@ class MAX11270:
|
||||
|
||||
#%% Data register functions
|
||||
def readDataRegister(self):
|
||||
self._registerAccessMode(MAX11270_REG_DATA,1)
|
||||
self._registerAccessMode(1,MAX11270_REG_DATA)
|
||||
return self._spi_read(self.dataBytes)
|
||||
|
||||
#This function is not complete, as I do not understand the data sheet...
|
||||
def value_to_voltage(self, adcValue):
|
||||
|
||||
if adcValue == 0:
|
||||
voltage = -self.vref
|
||||
elif adcValue == 1:
|
||||
voltage = 0
|
||||
else:
|
||||
voltage = self.vref / 2**(self.dataBytes*8) *adcValue
|
||||
voltage = self.vref / 2**(self.dataBytes*8-1) *adcValue
|
||||
|
||||
return voltage
|
||||
|
||||
@ -412,10 +466,9 @@ class MAX11270:
|
||||
'''
|
||||
def read_differential(self):
|
||||
#Triggers conversion
|
||||
self._conversionMode(self)
|
||||
self._conversionMode()
|
||||
time.sleep(0.001)
|
||||
adc_code = self.readDataRegister(self)
|
||||
|
||||
adc_code = self.readDataRegister()
|
||||
return self.value_to_voltage(adc_code)
|
||||
|
||||
|
||||
|
||||
@ -1,24 +1,77 @@
|
||||
class MCP3204(object):
|
||||
import spidev as SPI
|
||||
import pin as GPIO
|
||||
GPIO.config('./config.json')
|
||||
|
||||
class MCP3204():
|
||||
def __init__(self,spiDev,cs):
|
||||
self.spi = SPI.SpiDev(spiDev, cs, max_speed_hz=1000000)
|
||||
self.spi.set_mode(0)
|
||||
self.spi.set_bit_order(SPI.MSBFIRST)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
|
||||
#self.spi = SPI.SpiDev()
|
||||
#self.spi.open(spiDev, 0)
|
||||
#self.max_speed_hz = 1000000
|
||||
#self.spi.mode = 0
|
||||
#self.spi.set_bit_order(SPI.MSBFIRST)
|
||||
self.csPin = cs
|
||||
GPIO.setup(self.csPin, GPIO.OUT)
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
|
||||
self.clkPin = 21
|
||||
GPIO.setup(self.clkPin, GPIO.OUT)
|
||||
GPIO.output(self.clkPin, GPIO.LOW)
|
||||
|
||||
self.mosiPin = 20
|
||||
GPIO.setup(self.mosiPin, GPIO.OUT)
|
||||
GPIO.output(self.mosiPin, GPIO.LOW)
|
||||
|
||||
self.misoPin = 19
|
||||
GPIO.setup(self.misoPin, GPIO.IN)
|
||||
|
||||
def __del__(self):
|
||||
self.spi.close()
|
||||
#self.spi.close()
|
||||
pass
|
||||
|
||||
def _toggleClock(self):
|
||||
GPIO.output(self.clkPin, GPIO.HIGH)
|
||||
GPIO.output(self.clkPin, GPIO.LOW)
|
||||
|
||||
def read(self, ch):
|
||||
if 4 <= ch <= 0:
|
||||
raise Exception('MCP3204 channel must be 0-4: ' + str(ch))
|
||||
|
||||
GPIO.output(self.csPin, GPIO.LOW)
|
||||
|
||||
ret = []
|
||||
cmd = 128 # 1000 0000
|
||||
cmd += 64 # 1100 0000
|
||||
cmd += ((ch & 0x07) << 3)
|
||||
ret = self.spi.transfer([cmd, 0x0, 0x0])
|
||||
#ret = self.spi.xfer2([cmd, 0, 0, 0])
|
||||
#print(ret)
|
||||
for byte in range(3):
|
||||
retVal = 0
|
||||
for bit in range(8):
|
||||
if cmd & 0b10000000:
|
||||
GPIO.output(self.mosiPin, GPIO.HIGH)
|
||||
else:
|
||||
GPIO.output(self.mosiPin, GPIO.LOW)
|
||||
|
||||
# get the 12b out of the return
|
||||
#Shift command by 1 bit for next tick
|
||||
cmd <<= 1
|
||||
|
||||
# Read 1 data bit
|
||||
if GPIO.input(self.misoPin):
|
||||
retVal |= 0x1
|
||||
|
||||
# Advance input to next bit
|
||||
retVal <<= 1
|
||||
|
||||
self._toggleClock()
|
||||
ret.append(retVal)
|
||||
# get the 24b out of the return
|
||||
print(ret)
|
||||
val = (ret[0] & 0x01) << 11 # only B11 is here
|
||||
val |= ret[1] << 3 # B10:B3
|
||||
val |= ret[2] >> 5 # MSB has B2:B0 ... need to move down to LSB
|
||||
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
return (val & 0x0FFF) # ensure we are only sending 12b
|
||||
#return(0)
|
||||
@ -20,11 +20,14 @@ class MCP4822:
|
||||
'''
|
||||
Constructor of the class, setup the GPIO pin for SPI-communication
|
||||
'''
|
||||
def __init__(self, CLK_Pin, MOSI_Pin, CS_Pin, vref=None):
|
||||
def __init__(self, CLK_Pin, MOSI_Pin, CS_Pin, LDAC_Pin, vref=None):
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
|
||||
self.clkPin = CLK_Pin
|
||||
self.mosiPin = MOSI_Pin
|
||||
self.csPin = CS_Pin
|
||||
|
||||
self.ldacPin = LDAC_Pin
|
||||
|
||||
if vref is None:
|
||||
self.vref = 2.048
|
||||
else:
|
||||
@ -33,10 +36,14 @@ class MCP4822:
|
||||
GPIO.setup(self.clkPin, GPIO.OUT)
|
||||
GPIO.setup(self.mosiPin, GPIO.OUT)
|
||||
GPIO.setup(self.csPin, GPIO.OUT)
|
||||
GPIO.setup(self.ldacPin, GPIO.OUT)
|
||||
|
||||
GPIO.output(self.csPin, GPIO.HIGH)
|
||||
GPIO.output(self.clkPin, GPIO.LOW)
|
||||
GPIO.output(self.mosiPin, GPIO.LOW)
|
||||
GPIO.output(self.ldacPin, GPIO.LOW)
|
||||
|
||||
self.write(1.29,1)
|
||||
|
||||
def U2dac(self,U,DAC):
|
||||
#U: voltage (V) [0V-4.096V]
|
||||
|
||||
3
src/config.json
Normal file
3
src/config.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"test":false
|
||||
}
|
||||
129
src/pin.py
Normal file
129
src/pin.py
Normal file
@ -0,0 +1,129 @@
|
||||
from random import random
|
||||
import json
|
||||
|
||||
class InputOutputError(Exception):
|
||||
pass
|
||||
|
||||
conf={}
|
||||
TEST='test'
|
||||
conf[TEST]=False
|
||||
IN=1
|
||||
OUT=0
|
||||
HIGH=1
|
||||
LOW=0
|
||||
BCM=0
|
||||
BOARD=1
|
||||
pins={}
|
||||
out={}
|
||||
values={}
|
||||
|
||||
def config(path):
|
||||
global conf
|
||||
with open(path) as c:
|
||||
conf = json.load(c)
|
||||
if not conf[TEST]:
|
||||
global RPi
|
||||
global GPIO
|
||||
import RPi.GPIO as GPIO
|
||||
|
||||
#TODO check if initial is discarded for input or error is raised
|
||||
def setup(channel,in_out,initial=HIGH):
|
||||
global conf
|
||||
if type(channel) is list:
|
||||
for el in channel:
|
||||
_setup_one(el,in_out,initial)
|
||||
else:
|
||||
_setup_one(channel,in_out,initial)
|
||||
|
||||
def _setup_one(channel,in_out,initial):
|
||||
if conf[TEST]:
|
||||
pins[channel]=in_out
|
||||
else:
|
||||
if initial == HIGH:
|
||||
initial = GPIO.HIGH
|
||||
else:
|
||||
initial = GPIO.LOW
|
||||
if in_out == IN:
|
||||
GPIO.setup(channel,GPIO.IN) # initial not a valid parameter for input, GPIO error
|
||||
else:
|
||||
GPIO.setup(channel,GPIO.OUT,initial=initial)
|
||||
|
||||
def check_in_out(channel,in_out):
|
||||
try:
|
||||
if not pins[channel]==in_out:
|
||||
raise InputOutputError("Wrong confuration for channel {}! You're treating an input channel as output or vice versa.")
|
||||
except KeyError:
|
||||
raise InputOutputError("Wrong confuration for channel {}! setup() not called for this channel before calling input() or output().")
|
||||
|
||||
def setmode(mode):
|
||||
if conf[TEST]:
|
||||
pass
|
||||
else:
|
||||
if mode == BCM:
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
else:
|
||||
GPIO.setmode(GPIO.BOARD)
|
||||
|
||||
def input(channel):
|
||||
if conf[TEST]:
|
||||
check_in_out(channel,IN)
|
||||
try:
|
||||
values[channel]
|
||||
except KeyError:
|
||||
return random()
|
||||
return values[channel]
|
||||
else:
|
||||
return GPIO.input(channel)
|
||||
|
||||
def output(channel,value):
|
||||
if type(channel) is list:
|
||||
for el in channel:
|
||||
_output_one(el,value)
|
||||
else:
|
||||
_output_one(channel,value)
|
||||
|
||||
def _output_one(channel,value):
|
||||
if conf[TEST]:
|
||||
check_in_out(channel,OUT)
|
||||
out[channel]=value
|
||||
else:
|
||||
GPIO.output(channel,value)
|
||||
|
||||
def set_value(channel,value):
|
||||
values[channel]=value
|
||||
|
||||
def get_output(channel):
|
||||
return out[channel]
|
||||
|
||||
def cleanup(channel=None):
|
||||
global pins,out,values
|
||||
if channel==None:
|
||||
if conf[TEST]:
|
||||
pins,out,values={},{},{}
|
||||
else:
|
||||
GPIO.cleanup()
|
||||
else:
|
||||
if type(channel) is list or type(channel) is tuple:
|
||||
for el in channel:
|
||||
_cleanup_one(el)
|
||||
else:
|
||||
_cleanup_one(channel)
|
||||
|
||||
def _cleanup_one(channel):
|
||||
global pins,out,values
|
||||
if conf[TEST]:
|
||||
if channel in values.keys() and pins[channel]==IN:
|
||||
del values[channel]
|
||||
elif channel in out.keys():
|
||||
del out[channel]
|
||||
if channel in pins.keys():
|
||||
del pins[channel]
|
||||
else:
|
||||
GPIO.cleanup(channel)
|
||||
|
||||
def setwarnings(val):
|
||||
if conf[TEST]:
|
||||
pass
|
||||
else:
|
||||
GPIO.setwarnings(val)
|
||||
|
||||
61
src/test_MAX11270.py
Normal file
61
src/test_MAX11270.py
Normal file
@ -0,0 +1,61 @@
|
||||
|
||||
import MAX11270
|
||||
import math
|
||||
import MCP4822
|
||||
import time
|
||||
|
||||
def adc2T(dU):
|
||||
#constants
|
||||
#VREF = (REF+) – (REF–)
|
||||
#Vref = 2.5
|
||||
#wheatstonebridge
|
||||
# U0_____
|
||||
# |
|
||||
# R0
|
||||
# Uw_____|__
|
||||
# | |
|
||||
# R2 R4
|
||||
# |__dU__|
|
||||
# | |
|
||||
# R1 R3
|
||||
# |______|
|
||||
# Gnd_____|_
|
||||
#
|
||||
# R1 = resistance of thermistor
|
||||
R0 = 0
|
||||
R2 = 5100 #(Ohm)
|
||||
R3 = 97600 #(Ohm)
|
||||
R4 = 5100 #(Ohm)
|
||||
U0 = 3 #(V)
|
||||
#steinhart-Hart Coefficients 10uA
|
||||
# NTC_A = 9.7142e-4;
|
||||
# NTC_B = 2.3268e-4;
|
||||
# NTC_C = 8.0591e-8;
|
||||
#steinhart-Hart Coefficients 100uA
|
||||
NTC_A = 9.6542e-4
|
||||
NTC_B = 2.3356e-4
|
||||
NTC_C = 7.7781e-8
|
||||
|
||||
R1 = -(R0*R2*dU - R2*R3*U0 + R0*R3*dU + R0*R4*dU + R2*R3*dU + R2*R4*dU)/(R4*U0 + R0*dU + R3*dU + R4*dU)
|
||||
#calculate temperature
|
||||
try:
|
||||
T = 1/(NTC_A + NTC_B*math.log(float(R1)) + NTC_C*math.pow(math.log(float(R1)),3)) - 273.15
|
||||
except ValueError:
|
||||
T = 6666
|
||||
return T
|
||||
|
||||
myADC = MAX11270.MAX11270(21,20,19,17,27,22)
|
||||
myDAC = MCP4822.MCP4822(11, 10, 8, 5)
|
||||
|
||||
#myDAC.write(0,1)
|
||||
#myDAC.write(0,0)
|
||||
|
||||
print('-Status-')
|
||||
print(myADC.readStatusRegister(1))
|
||||
#myADC.performCalibration('offsetCalibration')
|
||||
#print(myADC.readStatusRegister(1))
|
||||
|
||||
print('--------Readout ADC value ---------')
|
||||
for i in range(0,100):
|
||||
print(adc2T(myADC.read_differential()))
|
||||
time.sleep(10)
|
||||
10
src/test_MCP3204.py
Normal file
10
src/test_MCP3204.py
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
import MCP3204
|
||||
|
||||
myADC = MCP3204.MCP3204(1,7)
|
||||
|
||||
print(myADC.read(0))
|
||||
print(myADC.read(1))
|
||||
print(myADC.read(2))
|
||||
print(myADC.read(3))
|
||||
|
||||
8
src/test_MCP4822.py
Normal file
8
src/test_MCP4822.py
Normal file
@ -0,0 +1,8 @@
|
||||
import MCP4822
|
||||
import time
|
||||
|
||||
myDAC = MCP4822.MCP4822(11, 10, 8, 5)
|
||||
myDAC.write(1,0)
|
||||
myDAC.write(0,1)
|
||||
|
||||
#time.sleep(10)
|
||||
Loading…
x
Reference in New Issue
Block a user