All modules, excluding 3204 are debugged and seems to work

This commit is contained in:
Elena Arenskötter 2023-11-04 13:51:50 +01:00
parent 710a0327a7
commit d55027d422
10 changed files with 372 additions and 41 deletions

Binary file not shown.

7
src/DEADJOE Normal file
View 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

View File

@ -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)

View File

@ -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)

View File

@ -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
View File

@ -0,0 +1,3 @@
{
"test":false
}

129
src/pin.py Normal file
View 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
View 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
View 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
View 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)