Hello,
I've been using the HC-SR04 ultrasonic sensor with RaspberryPi, the code is pretty simple:
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
try:
GPIO.setmode(GPIO.BOARD)
PIN_TRIGGER = 7
PIN_ECHO = 11
GPIO.setup(PIN_TRIGGER, GPIO.OUT)
GPIO.setup(PIN_ECHO, GPIO.IN)
GPIO.output(PIN_TRIGGER, GPIO.LOW)
print "Waiting for sensor to settle"
time.sleep(2)
print "Calculating distance"
GPIO.output(PIN_TRIGGER, GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(PIN_TRIGGER, GPIO.LOW)
while GPIO.input(PIN_ECHO)==0:
pulse_start_time = time.time()
while GPIO.input(PIN_ECHO)==1:
pulse_end_time = time.time()
pulse_duration = pulse_end_time - pulse_start_time
distance = round(pulse_duration * 17150, 2)
print "Distance:",distance,"cm"
finally:
GPIO.cleanup()
Now, I want to use the same sensor but with a normal PC and an U12.
However, I have no idea which funktion to use.
I've tried Counter, eCount and eDigitalIN funktions but without success. How to count these pulses from the sensor?
Could you please help me, I would be really grateful. Thanks in advance!
On the T-series devices there are likely slicker options, but for the U12 you can use AIBurst:
https://forums.labjack.com/index.php?showtopic=323
Thanks for a quick answer, however I am still not getting it to work. I've attached my code.
I am getting the following if I use aiBurst (not AIBurst):
{'idnum': 0, 'scanRate': 8185.5390625, 'voltages': <u12.c_float_Array_4096_Array_4 object at 0x000000000456D248>, 'stateIOout': <u12.c_long_Array_4096 object at 0x000000000456D2C8>, 'overVoltage': 0}
How to parse such object types?
How to pass a pointer of a variable voltages and stateIOout (it was in the description)?
Thank you in advance.
The voltages and stateIO are returned by the aiBurst call in Python. So something like this to retrieve them.
ret = lj.aiBurst(idNum = -1, updateIO = 1, ledOn = 1, numChannels = 1, channels = [0, 0, 0, 0], scanRate = 8192, numScans = numscans)
voltages = ret["voltages"]
stateIO = ret["stateIOout"]
The "pass a pointer of a variable" is how it is done in C/C++, but in the Python call that is setup in the call and returned as lists/arrays. Pointers to those arrays not used in Python.
There seems to be a problem with the returned 2D voltages list when I was trying it out, and I will need to investigate that further.
Yes, I found the definition of this command in u12.py:
def aiBurst(self, numChannels, channels, scanRate, numScans, idNum=None, demo=0, stateIOin=0, updateIO=0, ledOn=0, gains=[0, 0, 0, 0], disableCal=0, triggerIO=0, triggerState=0, timeout=1, transferMode=0):
"""
Name: U12.aiBurst(numChannels, channels, scanRate, numScans, idNum=None, demo=0, stateIOin=[0, 0, 0, 0], updateIO=0, ledOn=0, gains=[0, 0, 0, 0], disableCal=0, triggerIO=0, triggerState=0, timeout=1, transferMode=0)
Args: See section 4.7 of the User's Guide
Desc: Reads a specified number of scans (up to 4096) at a specified scan rate (up to 8192 Hz) from 1,2, or 4 analog inputs
>>> dev = U12()
>>> dev.aiBurst(1, [0], 400, 10)
{'overVoltage': 0, 'scanRate': 400.0, 'stateIOout': <u12.c_long_Array_4096 object at 0x00DB4BC0>, 'idnum': 1, 'voltages': <u12.c_float_Array_4096_Array_4 object at 0x00DB4B70>}
"""
# Check id number
if idNum is None:
idNum = self.id
idNum = ctypes.c_long(idNum)
# check list sizes
if len(channels) < numChannels: raise ValueError("channels must have atleast numChannels elements")
if len(gains) < numChannels: raise ValueError("gains must have atleast numChannels elements")
# Convert lists to arrays and create other ctypes
channelsArray = listToCArray(channels, ctypes.c_long)
gainsArray = listToCArray(gains, ctypes.c_long)
scanRate = ctypes.c_float(scanRate)
arr4096_type = ctypes.c_float * 4096
voltages_type = arr4096_type * 4
voltages = voltages_type()
stateIOout = (ctypes.c_long * 4096)()
overVoltage = ctypes.c_long(999)
ecode = staticLib.AIBurst(ctypes.byref(idNum), demo, stateIOin, updateIO, ledOn, numChannels, ctypes.byref(channelsArray), ctypes.byref(gainsArray), ctypes.byref(scanRate), disableCal, triggerIO, triggerState, numScans, timeout, ctypes.byref(voltages), ctypes.byref(stateIOout), ctypes.byref(overVoltage), transferMode)
if ecode != 0: raise U12Exception(ecode)
return {"idnum":idNum.value, "scanRate":scanRate.value, "voltages":voltages, "stateIOout":stateIOout, "overVoltage":overVoltage.value}
The method you gave me previously doesn't really help because I get his as an output:
'voltages': <u12.c_float_Array_4096_Array_4 object at 0x000000000456D248>
In this format is it unusable because I cannot parse it or count the pulses that I need.
"voltages" is accessible like a 2D list, and "stateIOout" like a 1D list. When accessing individual readings the data types are float and int respectively. For example:
voltages = ret["voltages"]
stateIO = ret["stateIOout"]
print("1st voltages reading = %f", voltages[0][0])
print("1st states reading = %d", stateIO[0])
I need to look into the returned "voltages" as it seems like readings aren't in the correct locations in the list/array.
LabJackPython has been updated to fix the returned voltages. It can be accessed like a 4096 x 4 list.
Download LabJackPython from the GitHub repo. and install it for the fix:
https://github.com/labjack/LabJackPython
Thanks for the update.
I am able to access the voltages and stateIOout list but I'm still not getting my sensor to work, which is pretty confusing.
I literally took the code from the following post (VB.net code):
https://forums.labjack.com/index.php?showtopic=323&p=1824
and just adjusted it in python3 (the code in the attachment).
The function argument "channels" is used to select the wanted channel to read, right?
ret = lj.aiBurst(updateIO = 1,
ledOn = 1,
numChannels = 1,
channels = [1, 0, 0, 0],
scanRate = scanrate,
numScans = numscans)
In the the for loop:
counter = 0
for x in range(0, numscans):
if voltages[x][0] > 1:
print(voltages[x][0])
counter = counter + 1
print(counter)
I am always getting the same result, it's always counter == numscans.
I would rather use some other LabJack device but we already have operating 5-6 U12's in our company and it would be easier to use the same card in this case too.
It looks like you are always getting a value greater than 1. What values are you getting?
Here are a couple things to look into: