I am having trouble getting a reading from the Devantech SRF04 (2-wire) with my ATOM Pro 28 running 8.0.
The Pulsout command seems to work fine and a I can hear the sonar click which makes me think it is sending the ping.
The Pulsin command seems buggy. First, it appears to reset the cpu if I don’t include a timeout lable/scaler. When I include the timeout lable, it immediately returns a zero value.
Anyone have this working? Are there specific pins that work better for pulsin, pulsout? (Like a hardware timer/IC/OC)
Here is the code:
convfac con 74 ' use inches
SONAR_INIT con p10
SONAR_ECHO con p11
sonar_dist var word
input SONAR_ECHO
main
low SONAR_INIT
pulsout SONAR_INIT, 20 '10us pulse to init reading
pulsin SONAR_ECHO, 1, sonar_error, 1, sonar_dist
debug [dec sonar_dist, 13]
sonar_dist = sonar_dist / convfac
if (sonar_dist = 0 ) then
low p4
elseif (sonar_dist < 24 )
high p4
low p5
else
high p4
high p5
endif
pause 250
goto main
sonar_error
toggle p4
pause 250
goto sonar_error
end
First pulsin and pulsout are software based. A different pin will not change anything. igf you want to use hardware to calulate the pulse width you would need to setup the “capture” hardware on one of the FTIO capable pins.
Second, I am assuming you are using 8.0.0.0. If not you need to specify the AtomPro software version.
Third, your timeout is too short. The AtomPro Pulsin timeout is in .5us(microsecond) increments.
Fourth, Pulsin wants a high/low/high OR a low/high/low transition. It counts the time between the highs or the lows depending on the second argument(0 = active low, 1 = active high). I don’t know much about the sonar sensor you are using so I would recomend you check the pulse received. If the pulse received starts when you activate the sonar(eg pulsout) and ends when the reflection is received then pulsin is not the command to use(because by the time you start pulsin after doing the pulsout you’ve already missed the starting edge of the pulse). If however a pulse is generated after the sonar receives the reflection and the pulse is proportional to the time it took to receive the reflection then pulsin is what you want to use. The first case you’d use rctime instead. Make sure you have the right edge type in the second case, otherwise you could get a return of 0(no pulse received).
Also, I have found a “bug” in the pulsin command(also rctime). The max time either will read a pulse(when not using a timeout label and timeout value) is 65535 * .5us.
If you change the hbasic.ini definitions for pulsin and rctime to this:
PULSIN _EXP,_EXP,{_ADDRESS|$FFFF,_EXP|$FFFFFFFF,}_VAR _EXEC:
RCTIME _EXP,_EXP,{_ADDRESS|$FFFF,_EXP|$FFFFFFFF,}_VAR _EXEC:
when not using a timeout label and value the max pulse width can be 2^32-1 *.5us.
This of course doesn’t apply when using a timeout label and value. But in your above code you need a timeout value greater than the max possible pulse width from the sonar.
Check out the Atom Pro and Ping thread. The code is almost identical. Yes pulsin is buggy. 
It is 8.0.
So the pulsin timeout is just val*.5us?
The documentation states the timeoutmultiplier is multiplied by 655350 us…
The SRF04 outputs a return pulse shortly after the falling edge of the input, so I think pulsin should work…
Let me play…
another point:
The pulsin is not timing out, i.e. it’s not branching to sonar_error, it’s just returning 0 immediately…regardless of timeout value…
Like I said, pulsin is buggy, use rctime instead.
If rctime works for this then that tells me pulsin CAN’T work for this.
RCTime measures the time a pin stays in a specified state. Pulsin is waiting for a pin to get into a state and then measures the time it is in that state. If the pin is already in the state to be measured pulsin will wait until it isn’t and then wait until it is and then start measuring(of course the timeouts will kick in if it waits too long in either case).
Since RCTime works that means the front edge of the pulse generated by the SRF04 has already been received by the time the rctime command is running. This means pulsin is not going to get the front edge of the pulse, hence it won’t measure the pulse correctly.
Also RCTime and Pulsin use the same under lying code. If RCTime timeouts work pulsin timeouts work. If not then not.
It’s actually two RCTime calls that are used, one for the rising edge and one for the falling edge. It fixed the problem immediately. I tried both 7.x and 8.0 and Pulsin does not seem to work correctly. Here is the code that works:
PULSOUT SONAR_INIT, 20
RCTIME SONAR_ECHO, 1, sonar_dist
RCTIME SONAR_ECHO, 0, sonar_dist
It seems there is a problem with PULSIN because trying to substitute it for the two RCTIME routines should work…and, again, PULSIN was NOT timing out, it simply exits with the variable set to 0.
I have a workaround and that’s the important thing. What I think would help is a bug list so people don’t spend time with known issues. Most people will tolerate bugs if they are acknowledged and know they will be addressed in the future.
I assume you are not using the timeout option in the rctime commands(as your code above doesn’t). If they are broken in pulsin they are also broken in rctime(it’s the same code, pulsin just does the equivilent of 3 rctimes(one for the same state as the pulse, so if the pin is already in that state then it will wait until it isn’t, one for when it’s not in the state of the pulse, waiting for the starting edge of the pulse, and one for the pulse itself. If any of these states take longer than the timeout(65535/2 useconds when no timeout argument is given, unless the hbasic.ini file was edited as I mentioned above, then it would be (2^32-1)/2 useconds) then it will return 0 or (if a label is given) it is supposed to jump to the label specified in the timeout label argument. I’ve looked at the code and I can’t see any reason why it wouldn’t. I’ll have to setup a fast pulse generator to test it fully though. We tested with a 1khz 50% duty pulse before we released 8.0.