123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- #!/usr/bin/env python
- from smbus import SMBus
- import time
- from struct import*
- import array
- import numpy as np
- # instead of having some varisable associated to the class that we should
- # update continuously with the the chip, we only access to the variables
- # to the chip via set_/get_ functions
- class ADUCv2p1:
- # Initialize the connection to the board
- # addr: i2c addres, can be obtained by running "i2detect -y 1" from terminal
- # if with_about = True, will print information from the board
- def __init__(self,addr,with_about=False):
- self.bus_pi = SMBus(1)
- self._addr = addr;
- self.get_wf_len();
- if with_about==True:
- print( self.get_text())
- print( "-----------------\n")
- # Read last valid waveform from the microcontroller, up to 256 points
- def read_data(self):
- dat = []
- if self._wf_len>=256:
- N=16
- self._wf_len = 256
- else:
- N = int(self._wf_len/16+1)
- ## add an error message in case wf_len/16 is not an integer?
- self.set_transf(1)# to remove
- for i in range(0,N):
- block = self.bus_pi.read_i2c_block_data(self._addr,i,32)
- buff = pack("32B",*block)
- dat = np.append(dat,unpack("<16H",buff))
- self.set_transf(0) #to remove
-
- dat=np.uint16(dat)
- return dat[0:self._wf_len]
- #
- def get_text(self):
- dat = []
- for i in range(0,16):
- block = self.bus_pi.read_i2c_block_data(self._addr,i+50,32)
- buff = pack("32B",*block)
- dat = np.append(dat,unpack("32c",buff))
- return ''.join(dat.astype(str))#''.join(str((dat[0:3]).tostring()))
- # sets DACX where X is the channel ch to the voltage V (in the range 0 to 4095)
- # Make sure you are in a mode where the voltage is not being inmediately overwritten
- def set_Vout(self,ch,V):
- self.bus_pi.write_word_data(self._addr,100+ch,V)
- #execute the setting commande on the chip
- self.bus_pi.read_i2c_block_data(self._addr,105,1)
- return
- def get_Vout(self,ch):
- #execute the reading commande on the chip
- self.bus_pi.read_i2c_block_data(self._addr,104,1)
- block = self.bus_pi.read_i2c_block_data(self._addr,100+ch,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set the input offset (in the range 0 to 4095)
- def set_offset(self, V):
- set_Vout(0, V)
- def get_offset(self):
- return get_Vout(0)
- # sets the value of the coarse output voltage when the box is in learn mode
- def set_Vlearn(self,V):
- self.bus_pi.write_word_data(self._addr,110,V)
- return
- def get_Vlearn(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,110,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # reads the height of the last measured signal
- def get_Vin(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,111,8)
- buff = pack("8B",*block)
- dat = unpack("<d",buff)
- dat=np.float64(dat)
- return dat[0]
- # reads the height of the last measured ground
- def get_Vin_gnd(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,112,8)
- buff = pack("8B",*block)
- dat = unpack("<d",buff)
- dat=np.float64(dat)
- return dat[0]
- #
- def get_ID(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,120,1)
- self._addr = block[0]
- return block[0]>>1
- def set_ID(self,ID):
- self._addr = ID
- return self.bus_pi.write_byte_data(self._addr,120,ID<<1)
- #
- def get_channel(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,121,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- def set_channel(self,channel):
- return self.bus_pi.write_word_data(self._addr,121,channel)
- #
- def set_transf(self,status):
- return self.bus_pi.write_byte_data(self._addr,122,status)
- # Sets the remote_trigg flag. Set to 0 so that the microcontroller uses the trigger
- # input, set it to 1 so that it continuously triggers
- def set_remote_trigg(self,status):
- return self.bus_pi.write_byte_data(self._addr,115,status)
- def get_remote_trigg(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,115,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Sets the number of recorded points, up to a maximum of 256. Sampling frequency is approx. 1MHz.
- def set_wf_len(self,wf_len):
- self._wf_len = wf_len
- if wf_len>256:
- print( "sorry, it is not possible to have more than 256 point per waveform.\n")
- self._wf_len = 256
- return self.bus_pi.write_word_data(self._addr,123,self._wf_len)
- def get_wf_len(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,123,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- self._wf_len = dat[0]
- return dat[0]
- #
- def get_trigg_cnt(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,124,4)
- buff = pack("4B",*block)
- dat = unpack("<I",buff)
- dat=np.uint32(dat)
- return dat[0]
- #
- def get_wf_cnt(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,113,8)
- buff = pack("8B",*block)
- dat = unpack("<I",buff)
- dat=np.uint32(dat)
- return dat[0]
- #
- def get_v_cnt(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,114,8)
- buff = pack("8B",*block)
- dat = unpack("<I",buff)
- dat=np.uint32(dat)
- return dat[0]
- #
- def set_test(self,tmp):
- self.bus_pi.write_word_data(self._addr,141,tmp)
- self.bus_pi.read_i2c_block_data(self._addr,105,1)
- return
- def get_test(self):
- self.bus_pi.read_i2c_block_data(self._addr,104,1)
- block = self.bus_pi.read_i2c_block_data(self._addr,141,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- #
- def set_erase(self):
- #self.bus_pi.read_i2c_block_data(self._addr,106,1)
- self.bus_pi.write_byte_data(self._addr,106,0)
- time.sleep(0.04)
- return
-
- #
- def get_probe(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,142,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- #
- def set_probe(self,tmp):
- self.bus_pi.write_word_data(self._addr,142,tmp)
- return
-
- # Set the value we are aiming to achieve in the signal when in lock mode
- def set_Vset(self,Vset):
- return self.bus_pi.write_word_data(self._addr,125,Vset)
- def get_Vset(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,125,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set the number of waveforms to average before stabilizing
- def set_N(self,N):
- return self.bus_pi.write_word_data(self._addr,126,N)
- def get_N(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,126,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- #
- def get_FEE_addr(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,140,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- def set_FEE_addr(self,FEE_addr):
- return self.bus_pi.write_word_data(self._addr,140,FEE_addr)
- # Set the point at which we start measuring the signal
- def set_start(self,start):
- return self.bus_pi.write_word_data(self._addr,127,start)
- def get_start(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,127,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set the point at which we stop measuring the signal
- def get_stop(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,128,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- def set_stop(self,stop):
- return self.bus_pi.write_word_data(self._addr,128,stop)
- # Set the point at which we start measuring the background
- def set_start_gnd(self,start_gnd):
- return self.bus_pi.write_word_data(self._addr,131,start_gnd)
-
- def get_start_gnd(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,131,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set the point at which we stop measuring the background
- def set_stop_gnd(self,stop_gnd):
- return self.bus_pi.write_word_data(self._addr,132,stop_gnd)
- def get_stop_gnd(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,132,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set whether the microcontroller should automatically select the best offset
- # and gain when in learn mode. auto_set_pga=0 to turn off the functionality and
- # to do it manually using set_pga and set_Vout(0, x)
- def set_auto_set_pga(self,auto_set_pga):
- return self.bus_pi.write_word_data(self._addr,129,auto_set_pga)
- def get_auto_set_pga(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,129,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set the ratio of sensitivities of the fine to coarse voltage outputs of the board
- # This is 20 as per circuit design, but can be tuned more precisely
- def set_coarse_fine_ratio(self,coarse_fine_ratio):
- return self.bus_pi.write_word_data(self._addr,130,coarse_fine_ratio)
- def get_coarse_fine_ratio(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,130,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set whether the microcontroller should subtract the background when measuring.
- # status=0 to disable this. status=1 to enable it.
- def set_enab_gnd(self,status):
- return self.bus_pi.write_byte_data(self._addr,133,status)
- def get_enab_gnd(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,133,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
-
- # Set the pga_state, this is defined via state = g*16+8 where g is such that the gain G
- # in the input measurements is G=2^g and G is one of {1, 2, 4, 8, 16, 32, 64, 128}
- # i.e. 0<g<7
- def set_pga_state(self,state):
- self.bus_pi.write_byte_data(self._addr,136,state)
- #execute set on the chip
- self.bus_pi.read_i2c_block_data(self._addr,137,1)
- return
- def get_pga_state(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,136,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
-
- def read_pga_state(self):
- #execute set on the chip
- self.bus_pi.read_i2c_block_data(self._addr,138,1)
- return
- def set_input_gain(self, gain):
- state = int(math.log2(gain))*16 + 8
- self.set_pga_state(state)
- def get_input_gain(self):
- state = self.get_pga_state()
- return (state-8)//16
- # Set the feedback gain
- def set_Gain(self,Gain):
- tmp = (Gain)
- buff = pack("<f",Gain)
- #print buff
- dat = unpack("4B",buff)
- #print dat
- return self.bus_pi.write_i2c_block_data(self._addr,134,[dat[0],dat[1],dat[2],dat[3]])
- def get_Gain(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,134,4)
- #print block
- buff = pack("4B",*block)
- dat = unpack("<f",buff)
- dat=np.float32(dat)
- return dat[0]
- # Set the maximum step step_max, allowed in one iteration of the loop
- def set_step_max(self,step_max):
- return self.bus_pi.write_word_data(self._addr,135,step_max)
- def get_step_max(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,135,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Read whether we are in learn (0) or lock mode (1)
- def get_mode(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,139,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Set the relative sensitivities of the coarse and fine output
- def set_coarse_fine_ratio(self,status):
- return self.bus_pi.write_byte_data(self._addr,140,status)
- def get_coarse_fine_ratio(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,140,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Read whether we are out of lock
- def get_out_of_lock(self):
- block = self.bus_pi.read_i2c_block_data(self._addr,141,2)
- buff = pack("2B",*block)
- dat = unpack("<H",buff)
- dat=np.uint16(dat)
- return dat[0]
- # Debugging
- def read_all_param(self):
- print( "start = %d" %self.get_start())
- print( "stop = %d" %self.get_stop())
- print( "Vset = %d" %self.get_Vset())
- print( "wf_len = %d" %self.get_wf_len())
- print ("step = %d" %self.get_step())
- print( "N = %d" %self.get_N())
- print( "Channel = %d" %self.get_channel())
- print( "ID = %d" %self.get_ID())
-
- '''def set_test_all_param(self):
- self.set_start(0)
- self.set_stop(10)
- self.set_Vset(20)
- self.set_wf_len(30)
- self.set_step(40)
- self.set_N(60)'''
|