1
0

ADUCv2p1.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. #!/usr/bin/env python
  2. from smbus import SMBus
  3. import time
  4. from struct import*
  5. import array
  6. import numpy as np
  7. # instead of having some varisable associated to the class that we should
  8. # update continuously with the the chip, we only access to the variables
  9. # to the chip via set_/get_ functions
  10. class ADUCv2p1:
  11. # Initialize the connection to the board
  12. # addr: i2c addres, can be obtained by running "i2detect -y 1" from terminal
  13. # if with_about = True, will print information from the board
  14. def __init__(self,addr,with_about=False):
  15. self.bus_pi = SMBus(1)
  16. self._addr = addr;
  17. self.get_wf_len();
  18. if with_about==True:
  19. print( self.get_text())
  20. print( "-----------------\n")
  21. # Read last valid waveform from the microcontroller, up to 256 points
  22. def read_data(self):
  23. dat = []
  24. if self._wf_len>=256:
  25. N=16
  26. self._wf_len = 256
  27. else:
  28. N = int(self._wf_len/16+1)
  29. ## add an error message in case wf_len/16 is not an integer?
  30. self.set_transf(1)# to remove
  31. for i in range(0,N):
  32. block = self.bus_pi.read_i2c_block_data(self._addr,i,32)
  33. buff = pack("32B",*block)
  34. dat = np.append(dat,unpack("<16H",buff))
  35. self.set_transf(0) #to remove
  36. dat=np.uint16(dat)
  37. return dat[0:self._wf_len]
  38. #
  39. def get_text(self):
  40. dat = []
  41. for i in range(0,16):
  42. block = self.bus_pi.read_i2c_block_data(self._addr,i+50,32)
  43. buff = pack("32B",*block)
  44. dat = np.append(dat,unpack("32c",buff))
  45. return ''.join(dat.astype(str))#''.join(str((dat[0:3]).tostring()))
  46. # sets DACX where X is the channel ch to the voltage V (in the range 0 to 4095)
  47. # Make sure you are in a mode where the voltage is not being inmediately overwritten
  48. def set_Vout(self,ch,V):
  49. self.bus_pi.write_word_data(self._addr,100+ch,V)
  50. #execute the setting commande on the chip
  51. self.bus_pi.read_i2c_block_data(self._addr,105,1)
  52. return
  53. def get_Vout(self,ch):
  54. #execute the reading commande on the chip
  55. self.bus_pi.read_i2c_block_data(self._addr,104,1)
  56. block = self.bus_pi.read_i2c_block_data(self._addr,100+ch,2)
  57. buff = pack("2B",*block)
  58. dat = unpack("<H",buff)
  59. dat=np.uint16(dat)
  60. return dat[0]
  61. # Set the input offset (in the range 0 to 4095)
  62. def set_offset(self, V):
  63. set_Vout(0, V)
  64. def get_offset(self):
  65. return get_Vout(0)
  66. # sets the value of the coarse output voltage when the box is in learn mode
  67. def set_Vlearn(self,V):
  68. self.bus_pi.write_word_data(self._addr,110,V)
  69. return
  70. def get_Vlearn(self):
  71. block = self.bus_pi.read_i2c_block_data(self._addr,110,2)
  72. buff = pack("2B",*block)
  73. dat = unpack("<H",buff)
  74. dat=np.uint16(dat)
  75. return dat[0]
  76. # reads the height of the last measured signal
  77. def get_Vin(self):
  78. block = self.bus_pi.read_i2c_block_data(self._addr,111,8)
  79. buff = pack("8B",*block)
  80. dat = unpack("<d",buff)
  81. dat=np.float64(dat)
  82. return dat[0]
  83. # reads the height of the last measured ground
  84. def get_Vin_gnd(self):
  85. block = self.bus_pi.read_i2c_block_data(self._addr,112,8)
  86. buff = pack("8B",*block)
  87. dat = unpack("<d",buff)
  88. dat=np.float64(dat)
  89. return dat[0]
  90. #
  91. def get_ID(self):
  92. block = self.bus_pi.read_i2c_block_data(self._addr,120,1)
  93. self._addr = block[0]
  94. return block[0]>>1
  95. def set_ID(self,ID):
  96. self._addr = ID
  97. return self.bus_pi.write_byte_data(self._addr,120,ID<<1)
  98. #
  99. def get_channel(self):
  100. block = self.bus_pi.read_i2c_block_data(self._addr,121,2)
  101. buff = pack("2B",*block)
  102. dat = unpack("<H",buff)
  103. dat=np.uint16(dat)
  104. return dat[0]
  105. def set_channel(self,channel):
  106. return self.bus_pi.write_word_data(self._addr,121,channel)
  107. #
  108. def set_transf(self,status):
  109. return self.bus_pi.write_byte_data(self._addr,122,status)
  110. # Sets the remote_trigg flag. Set to 0 so that the microcontroller uses the trigger
  111. # input, set it to 1 so that it continuously triggers
  112. def set_remote_trigg(self,status):
  113. return self.bus_pi.write_byte_data(self._addr,115,status)
  114. def get_remote_trigg(self):
  115. block = self.bus_pi.read_i2c_block_data(self._addr,115,1)
  116. self._addr = block[0]
  117. return block[0]
  118. # Sets the number of recorded points, up to a maximum of 256. Sampling frequency is approx. 1MHz.
  119. def set_wf_len(self,wf_len):
  120. self._wf_len = wf_len
  121. if wf_len>256:
  122. print( "sorry, it is not possible to have more than 256 point per waveform.\n")
  123. self._wf_len = 256
  124. return self.bus_pi.write_word_data(self._addr,123,self._wf_len)
  125. def get_wf_len(self):
  126. block = self.bus_pi.read_i2c_block_data(self._addr,123,2)
  127. buff = pack("2B",*block)
  128. dat = unpack("<H",buff)
  129. dat=np.uint16(dat)
  130. self._wf_len = dat[0]
  131. return dat[0]
  132. #
  133. def get_trigg_cnt(self):
  134. block = self.bus_pi.read_i2c_block_data(self._addr,124,4)
  135. buff = pack("4B",*block)
  136. dat = unpack("<I",buff)
  137. dat=np.uint32(dat)
  138. return dat[0]
  139. #
  140. def get_wf_cnt(self):
  141. block = self.bus_pi.read_i2c_block_data(self._addr,113,8)
  142. buff = pack("8B",*block)
  143. dat = unpack("<I",buff)
  144. dat=np.uint32(dat)
  145. return dat[0]
  146. #
  147. def get_v_cnt(self):
  148. block = self.bus_pi.read_i2c_block_data(self._addr,114,8)
  149. buff = pack("8B",*block)
  150. dat = unpack("<I",buff)
  151. dat=np.uint32(dat)
  152. return dat[0]
  153. #
  154. def set_test(self,tmp):
  155. self.bus_pi.write_word_data(self._addr,141,tmp)
  156. self.bus_pi.read_i2c_block_data(self._addr,105,1)
  157. return
  158. def get_test(self):
  159. self.bus_pi.read_i2c_block_data(self._addr,104,1)
  160. block = self.bus_pi.read_i2c_block_data(self._addr,141,2)
  161. buff = pack("2B",*block)
  162. dat = unpack("<H",buff)
  163. dat=np.uint16(dat)
  164. return dat[0]
  165. #
  166. def set_erase(self):
  167. #self.bus_pi.read_i2c_block_data(self._addr,106,1)
  168. self.bus_pi.write_byte_data(self._addr,106,0)
  169. time.sleep(0.04)
  170. return
  171. #
  172. def get_probe(self):
  173. block = self.bus_pi.read_i2c_block_data(self._addr,142,2)
  174. buff = pack("2B",*block)
  175. dat = unpack("<H",buff)
  176. dat=np.uint16(dat)
  177. return dat[0]
  178. #
  179. def set_probe(self,tmp):
  180. self.bus_pi.write_word_data(self._addr,142,tmp)
  181. return
  182. # Set the value we are aiming to achieve in the signal when in lock mode
  183. def set_Vset(self,Vset):
  184. return self.bus_pi.write_word_data(self._addr,125,Vset)
  185. def get_Vset(self):
  186. block = self.bus_pi.read_i2c_block_data(self._addr,125,2)
  187. buff = pack("2B",*block)
  188. dat = unpack("<H",buff)
  189. dat=np.uint16(dat)
  190. return dat[0]
  191. # Set the number of waveforms to average before stabilizing
  192. def set_N(self,N):
  193. return self.bus_pi.write_word_data(self._addr,126,N)
  194. def get_N(self):
  195. block = self.bus_pi.read_i2c_block_data(self._addr,126,2)
  196. buff = pack("2B",*block)
  197. dat = unpack("<H",buff)
  198. dat=np.uint16(dat)
  199. return dat[0]
  200. #
  201. def get_FEE_addr(self):
  202. block = self.bus_pi.read_i2c_block_data(self._addr,140,2)
  203. buff = pack("2B",*block)
  204. dat = unpack("<H",buff)
  205. dat=np.uint16(dat)
  206. return dat[0]
  207. def set_FEE_addr(self,FEE_addr):
  208. return self.bus_pi.write_word_data(self._addr,140,FEE_addr)
  209. # Set the point at which we start measuring the signal
  210. def set_start(self,start):
  211. return self.bus_pi.write_word_data(self._addr,127,start)
  212. def get_start(self):
  213. block = self.bus_pi.read_i2c_block_data(self._addr,127,2)
  214. buff = pack("2B",*block)
  215. dat = unpack("<H",buff)
  216. dat=np.uint16(dat)
  217. return dat[0]
  218. # Set the point at which we stop measuring the signal
  219. def get_stop(self):
  220. block = self.bus_pi.read_i2c_block_data(self._addr,128,2)
  221. buff = pack("2B",*block)
  222. dat = unpack("<H",buff)
  223. dat=np.uint16(dat)
  224. return dat[0]
  225. def set_stop(self,stop):
  226. return self.bus_pi.write_word_data(self._addr,128,stop)
  227. # Set the point at which we start measuring the background
  228. def set_start_gnd(self,start_gnd):
  229. return self.bus_pi.write_word_data(self._addr,131,start_gnd)
  230. def get_start_gnd(self):
  231. block = self.bus_pi.read_i2c_block_data(self._addr,131,2)
  232. buff = pack("2B",*block)
  233. dat = unpack("<H",buff)
  234. dat=np.uint16(dat)
  235. return dat[0]
  236. # Set the point at which we stop measuring the background
  237. def set_stop_gnd(self,stop_gnd):
  238. return self.bus_pi.write_word_data(self._addr,132,stop_gnd)
  239. def get_stop_gnd(self):
  240. block = self.bus_pi.read_i2c_block_data(self._addr,132,2)
  241. buff = pack("2B",*block)
  242. dat = unpack("<H",buff)
  243. dat=np.uint16(dat)
  244. return dat[0]
  245. # Set whether the microcontroller should automatically select the best offset
  246. # and gain when in learn mode. auto_set_pga=0 to turn off the functionality and
  247. # to do it manually using set_pga and set_Vout(0, x)
  248. def set_auto_set_pga(self,auto_set_pga):
  249. return self.bus_pi.write_word_data(self._addr,129,auto_set_pga)
  250. def get_auto_set_pga(self):
  251. block = self.bus_pi.read_i2c_block_data(self._addr,129,2)
  252. buff = pack("2B",*block)
  253. dat = unpack("<H",buff)
  254. dat=np.uint16(dat)
  255. return dat[0]
  256. # Set the ratio of sensitivities of the fine to coarse voltage outputs of the board
  257. # This is 20 as per circuit design, but can be tuned more precisely
  258. def set_coarse_fine_ratio(self,coarse_fine_ratio):
  259. return self.bus_pi.write_word_data(self._addr,130,coarse_fine_ratio)
  260. def get_coarse_fine_ratio(self):
  261. block = self.bus_pi.read_i2c_block_data(self._addr,130,2)
  262. buff = pack("2B",*block)
  263. dat = unpack("<H",buff)
  264. dat=np.uint16(dat)
  265. return dat[0]
  266. # Set whether the microcontroller should subtract the background when measuring.
  267. # status=0 to disable this. status=1 to enable it.
  268. def set_enab_gnd(self,status):
  269. return self.bus_pi.write_byte_data(self._addr,133,status)
  270. def get_enab_gnd(self):
  271. block = self.bus_pi.read_i2c_block_data(self._addr,133,2)
  272. buff = pack("2B",*block)
  273. dat = unpack("<H",buff)
  274. dat=np.uint16(dat)
  275. return dat[0]
  276. # Set the pga_state, this is defined via state = g*16+8 where g is such that the gain G
  277. # in the input measurements is G=2^g and G is one of {1, 2, 4, 8, 16, 32, 64, 128}
  278. # i.e. 0<g<7
  279. def set_pga_state(self,state):
  280. self.bus_pi.write_byte_data(self._addr,136,state)
  281. #execute set on the chip
  282. self.bus_pi.read_i2c_block_data(self._addr,137,1)
  283. return
  284. def get_pga_state(self):
  285. block = self.bus_pi.read_i2c_block_data(self._addr,136,2)
  286. buff = pack("2B",*block)
  287. dat = unpack("<H",buff)
  288. dat=np.uint16(dat)
  289. return dat[0]
  290. def read_pga_state(self):
  291. #execute set on the chip
  292. self.bus_pi.read_i2c_block_data(self._addr,138,1)
  293. return
  294. def set_input_gain(self, gain):
  295. state = int(math.log2(gain))*16 + 8
  296. self.set_pga_state(self, state)
  297. def get_input_gain(self):
  298. state = self.read_pga_state(self)
  299. return (state-8)//16
  300. # Set the feedback gain
  301. def set_Gain(self,Gain):
  302. tmp = (Gain)
  303. buff = pack("<f",Gain)
  304. #print buff
  305. dat = unpack("4B",buff)
  306. #print dat
  307. return self.bus_pi.write_i2c_block_data(self._addr,134,[dat[0],dat[1],dat[2],dat[3]])
  308. def get_Gain(self):
  309. block = self.bus_pi.read_i2c_block_data(self._addr,134,4)
  310. #print block
  311. buff = pack("4B",*block)
  312. dat = unpack("<f",buff)
  313. dat=np.float32(dat)
  314. return dat[0]
  315. # Set the maximum step step_max, allowed in one iteration of the loop
  316. def set_step_max(self,step_max):
  317. return self.bus_pi.write_word_data(self._addr,135,step_max)
  318. def get_step_max(self):
  319. block = self.bus_pi.read_i2c_block_data(self._addr,135,2)
  320. buff = pack("2B",*block)
  321. dat = unpack("<H",buff)
  322. dat=np.uint16(dat)
  323. return dat[0]
  324. # Read whether we are in learn (0) or lock mode (1)
  325. def get_mode(self):
  326. block = self.bus_pi.read_i2c_block_data(self._addr,139,2)
  327. buff = pack("2B",*block)
  328. dat = unpack("<H",buff)
  329. dat=np.uint16(dat)
  330. return dat[0]
  331. # Set the relative sensitivities of the coarse and fine output
  332. def set_coarse_fine_ratio(self,status):
  333. return self.bus_pi.write_byte_data(self._addr,140,status)
  334. def get_coarse_fine_ratio(self):
  335. block = self.bus_pi.read_i2c_block_data(self._addr,140,2)
  336. buff = pack("2B",*block)
  337. dat = unpack("<H",buff)
  338. dat=np.uint16(dat)
  339. return dat[0]
  340. # Read whether we are out of lock
  341. def get_out_of_lock(self):
  342. block = self.bus_pi.read_i2c_block_data(self._addr,141,2)
  343. buff = pack("2B",*block)
  344. dat = unpack("<H",buff)
  345. dat=np.uint16(dat)
  346. return dat[0]
  347. # Debugging
  348. def read_all_param(self):
  349. print( "start = %d" %self.get_start())
  350. print( "stop = %d" %self.get_stop())
  351. print( "Vset = %d" %self.get_Vset())
  352. print( "wf_len = %d" %self.get_wf_len())
  353. print ("step = %d" %self.get_step())
  354. print( "N = %d" %self.get_N())
  355. print( "Channel = %d" %self.get_channel())
  356. print( "ID = %d" %self.get_ID())
  357. '''def set_test_all_param(self):
  358. self.set_start(0)
  359. self.set_stop(10)
  360. self.set_Vset(20)
  361. self.set_wf_len(30)
  362. self.set_step(40)
  363. self.set_N(60)'''