Hi, I am building a IR light sensor for chemical engineering purposes using an IR transistor and arduino uno(controlled by python). One of my designs uses capacitor discharge to measure the conductivity of the transistor. I used a infinite while loop to contiuously check whether the capacitor voltage is below a threshold, and then the discharge time can be found. Although the while loop can circulate and execute analog read() once per 5 us, I noticed that the values read using analog read() function only updates once per 20 ms. So the output I received is like: 5,5,5,5....(20ms)..,4,4,4,4......(20ms)..,3,3,3,....2,2,2....
Part of the code I use is:
a = True
while i<5:
board.digital[12].write(1)
time.sleep(3)
board.digital[12].write(0)
t1 = time.time()
while a:
read =analog_red.read()
c_data[i][0].append(time.time()-t1)
c_data[i][1].append(read)
if read<0.5/5:
a = False
i = i+1
a= True
I know arduino has a internal latency not larger than 100 us, so how do I achieve this? I still have to use python and not the arduino IDE because there are some other devices I need to control.
Post the full Python code, where is the data printed out?
I am not familiar with the board interface you seem to be using, does it add delays or timeout for communications?
import pyfirmata
import time
board = pyfirmata.Arduino('/dev/cu.usbmodem144101')
it = pyfirmata.util.Iterator(board)
it.start()
a = True
c_data = [[[],[]],[[],[]],[[],[]],[[],[]],[[],[]]]
i = 0
analog_red = board.get_pin('a:1:i')
time.sleep(6)
while i<5:
board.digital[12].write(1)
time.sleep(3)
board.digital[12].write(0)
t1 = time.time()
while a:
read =analog_red.read()
c_data[i][0].append(time.time()-t1)
c_data[i][1].append(read)
if read<0.5/5:
a = False
i = i+1
a= True
This is just the code that I use to test the capacitor discharge time. It will charge and discharge the capacitor 5 times and store the voltage and time reading in 5 lists embedded in "c_data". After I run the code I found that in c_data, the voltage reading stays constant for about 20ms and suddenly changes to a new value and stay there for about 20ms too. This means I only get 5 different voltage values during 100ms of time.
The loop will end when voltage reading is below 0.5 V, but due to the large latency, when i use a capacitor with small capacitance( 50 uF or lower), I cant get its discharge time because the error is larger than the discharge time. Arduino simply does not update value at the instant when capacitor has discharged.
I don’t know much about pyfirmata - I came across it by helping out here - but it Is not highly regarded from what I have read.
I notice that you use an iterator thread - may be that’s reading way too much information (all the pins’ status?) - you would have to dig in the details and check if enable_reporting() might not be a alternate choice
pyfirmata probably does the basics OK but it’s such an overhead with a slow and obscure Serial communication that it might not be fit for your purpose.
If I had to do this, i would write custom code on the arduino for the experiment and custom Python code to get the data…