It would seem from the pin states that it gets permanently stuck in
while(!gpio_get(ULTRASONIC_IN))
;
Can anyone cast any light on this one?
Or suggest a bug hunting methodology?
On Sat, 23 Mar 2024 17:45:05 +0000
The Natural Philosopher <tnp@invalid.invalid> wrote:
It would seem from the pin states that it gets permanently stuck in
while(!gpio_get(ULTRASONIC_IN))
;
Can anyone cast any light on this one?
Or suggest a bug hunting methodology?
Assuming you have access to the source of gpio_get() instrument the inside of it with tracers (I'd use printf if there's anything listening to stdout - otherwise find somewhere to put breadcrumbs that you can see in
real time (in ancient times I'd just watch the blinkenlights). Wait for it
to lock up and see what it's doing.
Alternatively run it under strace or similar and wait for it to
lock up or wait for it to lock up and attach gdb (you'll want to compile
with -g for that).
There's three - hopefully one of them will shed some light.
On 23/03/2024 18:37, Ahem A Rivet's Shot wrote:
Assuming you have access to the source of gpio_get() instrument
the inside of it with tracers (I'd use printf if there's anything
listening to stdout - otherwise find somewhere to put breadcrumbs that
you can see in real time (in ancient times I'd just watch the blinkenlights). Wait for it to lock up and see what it's doing.
Well I did. That's how I got this far.
I know it enters the routine, but never leaves, and the lack of GPIO
voltage suggest it is being stuck where it is.
Alternatively run it under strace or similar and wait for it to
lock up or wait for it to lock up and attach gdb (you'll want to compile with -g for that).
AIUI those are linux tools.
We are running bare metal-ish here.
Back in the day I would have used a chip emulator with hardware break
points.
It's odd, it may be something to do with short ultrasonic distances. I
have the PCB just lolling around on the desk, and facing a wall a few
inches away seemed to make it crash moire predictably
It would seem from the pin states that it gets permanently stuck in
while(!gpio_get(ULTRASONIC_IN))
;
Which as understand it is waiting for the module (HCSR04) to *start* to
send a pulse.
On Sat, 23 Mar 2024 22:20:34 +0000gpio_get (X) for presumably memory mapped IO is going to be little more
The Natural Philosopher <tnp@invalid.invalid> wrote:
On 23/03/2024 18:37, Ahem A Rivet's Shot wrote:
Assuming you have access to the source of gpio_get() instrumentWell I did. That's how I got this far.
the inside of it with tracers (I'd use printf if there's anything
listening to stdout - otherwise find somewhere to put breadcrumbs that
you can see in real time (in ancient times I'd just watch the
blinkenlights). Wait for it to lock up and see what it's doing.
Instrument /Inside/ gpio_get().
I know it enters the routine, but never leaves, and the lack of GPIO
voltage suggest it is being stuck where it is.
Right so the next step is the inside of the routine.
Alternatively run it under strace or similar and wait for it toAIUI those are linux tools.
lock up or wait for it to lock up and attach gdb (you'll want to compile >>> with -g for that).
Unix tools but yes.
We are running bare metal-ish here.
Ah - no way to attach a debugger via the SDK ?
Back in the day I would have used a chip emulator with hardware break
points.
An ICE is always nice if someone else is paying :)
It's odd, it may be something to do with short ultrasonic distances. I
have the PCB just lolling around on the desk, and facing a wall a few
inches away seemed to make it crash moire predictably
Hmm is there a minimum range spec ?
The Natural Philosopher <tnp@invalid.invalid> wrote:
It would seem from the pin states that it gets permanently stuck in
while(!gpio_get(ULTRASONIC_IN))
;
Which as understand it is waiting for the module (HCSR04) to *start* to
send a pulse.
Can you scope it to see if the module is actually sending a pulse?
Is the pulse perhaps too short for the Pico to detect? eg if the loop or gpio_get() function took some time, it could be the signal goes 0-1-0 in the middle of a loop iteration and so the gpio_get() never sees it go 1.
Theo
My choice tree is between the GPIO out signal never being received by
the ultrasonic module, or the GPIO in signal is being missed by the Pi
PICO on account of possibly some interrupt masking its appearance until
it is too late and its gone low again.
We are running bare metal-ish here.
Back in the day I would have used a chip emulator with hardware break
points.
And a cost of hundreds of thousands.
...unless, thinking a bit more, the pulse is so short it comes *and*
goes inside that loop, as you suggested.. it certainly should *not* be,
as even on a few cm of target distance, its hundreds of microseconds (i
make it 58µs per cm roughly)
As you can see from my last reply that is roughly where I am headed. Or similar. Lacking full ICE., its all a bit 'poke the black box with
different sized sticks, and try and infer from what it does, what is happening inside it'
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that *sleep_us(x)* was highly inconsistent for certain (small) values of x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep' with
the processor being put in low power mode and requiring an interrupt to
'wake it up'.
On 24/03/2024 11:13, The Natural Philosopher wrote:
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values of x.
Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep' with
the processor being put in low power mode and requiring an interrupt
to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than sleep.
But looking at PICO code samples, they commonly use sleep, so I'd be surprised if it was that bad.
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values of x.
Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep' with
the processor being put in low power mode and requiring an interrupt
to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
But looking at PICO code samples, they commonly use sleep, so I'd beI am veering away from that explanation, as with the test board located
surprised if it was that bad.
at some distance from any target, the problem has not reappeared.
I am beginning to think that it may be possible for the echo pulse to
'come *and* go' before the high level PICO code has got round to
actually looking for it in the first place.
That is, some asynchrounous event in this sequence
gpio_put(ULTRASONIC_OUT,1);
sleep_us(10);
gpio_put(ULTRASONIC_OUT,0); //reset the input
//if asynch event lasting more than 100uS occurs here...
// wait for echo pulse start
while(!gpio_get(ULTRASONIC_IN))
;
//then the low-high-low echo pulse will never be detected.
It is also not clear from the documentation whether it is the low to
high, or the high to low sequence, that triggers the ultrasonic board.
If it is low to high, then there is an opportunity for an occasional
very long delay in the
sleep_us(10);
to delay resetting the pulse until Elvis has left the building,. so to >speak...
So I have tow things to do. Understand how the ES module works in terms
of timings, and replace that sleep_us with a different delay mechanism.
It's now been 24 hours with no lockup with a distant target...
OIL-SENSOR
OIL-TANK
-85dBm
57.60cm
23.7C
4.6V
I have noticed that with absoluteley no change in sensor location I get
up to 0.5cm variation in delay.
On Mon, 25 Mar 2024 15:57:25 +0000, in <uts6t5$163q2$1@dont-email.me>,
The Natural Philosopher <tnp@invalid.invalid> wrote:
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values of x. >>>> Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep' with >>>> the processor being put in low power mode and requiring an interrupt
to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
But looking at PICO code samples, they commonly use sleep, so I'd beI am veering away from that explanation, as with the test board located
surprised if it was that bad.
at some distance from any target, the problem has not reappeared.
I am beginning to think that it may be possible for the echo pulse to
'come *and* go' before the high level PICO code has got round to
actually looking for it in the first place.
That is, some asynchrounous event in this sequence
gpio_put(ULTRASONIC_OUT,1);
sleep_us(10);
gpio_put(ULTRASONIC_OUT,0); //reset the input
//if asynch event lasting more than 100uS occurs here...
// wait for echo pulse start
while(!gpio_get(ULTRASONIC_IN))
;
//then the low-high-low echo pulse will never be detected.
It is also not clear from the documentation whether it is the low to
high, or the high to low sequence, that triggers the ultrasonic board.
If it is low to high, then there is an opportunity for an occasional
very long delay in the
sleep_us(10);
to delay resetting the pulse until Elvis has left the building,. so to
speak...
So I have tow things to do. Understand how the ES module works in terms
of timings, and replace that sleep_us with a different delay mechanism.
It's now been 24 hours with no lockup with a distant target...
OIL-SENSOR
OIL-TANK
-85dBm
57.60cm
23.7°C
4.6V
I have noticed that with absoluteley no change in sensor location I get
up to ± 0.5cm variation in delay.
Assuming the "oil" you're talking about is kerosene/heating fuel, the
speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec. I don't
know the specs for the PICO, but perhaps comparing that to the time it
takes to execute your code will give you an answer. I'd guess
(emphasis on guess) that +/- 0.5 cm is doing fairly well.
Assuming the "oil" you're talking about is kerosene/heating fuel, the
speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec.
On Tue, 26 Mar 2024 17:33:50 +0000
Jim H <invalid@invalid.invalid> wrote:
Assuming the "oil" you're talking about is kerosene/heating fuel, the
speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec.
I would have thought it's measuring the distance to the surface of
the oil from above the oil so it would be the speed of sound in air that matters 300m/s.
On 26/03/2024 18:16, Ahem A Rivet's Shot wrote:
On Tue, 26 Mar 2024 17:33:50 +0000 Jim H <invalid@invalid.invalid> wrote:
Assuming the "oil" you're talking about is kerosene/heating fuel, the speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec.
I would have thought it's measuring the distance to the surface of
the oil from above the oil so it would be the speed of sound in air that matters 300m/s.
Correct, Mrs Shot. Anyway it's died within 30 minutes of going back on
'short echo'... So its definitely sensitive to that in some way.
I'll add more debug code tomorrow
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values of
x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep'
with the processor being put in low power mode and requiring an
interrupt to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
On 25/03/2024 15:57, The Natural Philosopher wrote:
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values of
x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep'
with the processor being put in low power mode and requiring an
interrupt to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
A timer isn't complicated, just a call back routine, and a semaphore. Interrupts are something an OS does, not me :o). I hate multithread
code, but async handling of an external resource is one of the two main places I would use another thread.
I had a look at your code, it looks extraordinarily like a python
example on Tom's hardware.
I'm not clear how many times it is succeeding vs failing, but I suspect
you really need to bite the bullet and introduce timeouts/error
handling, if it fails try again, average out multiple results. i.e.
accept it as flawed and that results are statistical, like GPS.
In many ways the resilience code will be simple, because it is just
normal code, rather than cargo culting a novel ultrasonic device.
You can investigate further, by recording fail stats, as well as
distance stats.
In message <utv5e7$29onh$2@dont-email.me>
The Natural Philosopher <tnp@invalid.invalid> wrote:
On 26/03/2024 18:16, Ahem A Rivet's Shot wrote:
On Tue, 26 Mar 2024 17:33:50 +0000 Jim H <invalid@invalid.invalid> wrote: >>>Correct, Mrs Shot. Anyway it's died within 30 minutes of going back on
Assuming the "oil" you're talking about is kerosene/heating fuel, the
speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec.
I would have thought it's measuring the distance to the surface of
the oil from above the oil so it would be the speed of sound in air that >>> matters 300m/s.
'short echo'... So its definitely sensitive to that in some way.
I'll add more debug code tomorrow
Are you sure the sensor isn't malfunctioning as a result of being in
oil vapour?
David
I am slightly curious as to how the PICO could miss what is a several hundred microsecond wide pulse.
In message <uu0rh5$2pcls$1@dont-email.me>
The Natural Philosopher <tnp@invalid.invalid> wrote:
I am slightly curious as to how the PICO could miss what is a several
hundred microsecond wide pulse.
AFAICS there are many pitfalls:
1) An interrupt can be being serviced, so the pulse is over before you
get to see it.
2) If you're looking for a pulse, you should be looking edge triggered
rather than level triggered, but even then you may not get to react to
the edge immediately because of an interrupt being serviced, so you'd
get an anomalous result.
3) You can look level triggered, but you need to turn off all interrupts
to ensure you really are loking at it in real time.
4) I had a play with an ultrasonic ranger a couple of years or so ago.
I couldn't understand why I wasn't getting any return pulses at all.
I eventually realised that I was sending another start pulse before
the current cycle had finished.
Regardless, you need an escape from any and every potential infinite
loop. Whatever you're doing.
If you can use a hardware timer in the chip, that's a much more reliable solution.
David
On 26/03/2024 19:16, David Higton wrote:
In message <utv5e7$29onh$2@dont-email.me>Since it is operating on the desk in front of me, fairly sure :-)
The Natural Philosopher <tnp@invalid.invalid> wrote:
On 26/03/2024 18:16, Ahem A Rivet's Shot wrote:
On Tue, 26 Mar 2024 17:33:50 +0000 Jim H <invalid@invalid.invalid> wrote: >>>>Correct, Mrs Shot. Anyway it's died within 30 minutes of going back on
Assuming the "oil" you're talking about is kerosene/heating fuel, the >>>>> speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec.
I would have thought it's measuring the distance to the surface of
the oil from above the oil so it would be the speed of sound in air that >>>> matters 300m/s.
'short echo'... So its definitely sensitive to that in some way.
I'll add more debug code tomorrow
Are you sure the sensor isn't malfunctioning as a result of being in
oil vapour?
I haven't let it anywhere near the oil tank yet. The plan is to have it installed by the fall. ready for next winter.
So it is being hammered to check for problems *before* it gets to a cold
wet inaccessible oil tank.
On 2024-03-27, The Natural Philosopher <tnp@invalid.invalid> wrote:
On 26/03/2024 19:16, David Higton wrote:
In message <utv5e7$29onh$2@dont-email.me>Since it is operating on the desk in front of me, fairly sure :-)
The Natural Philosopher <tnp@invalid.invalid> wrote:
On 26/03/2024 18:16, Ahem A Rivet's Shot wrote:
On Tue, 26 Mar 2024 17:33:50 +0000 Jim H <invalid@invalid.invalid> wrote: >>>>>Correct, Mrs Shot. Anyway it's died within 30 minutes of going back on >>>> 'short echo'... So its definitely sensitive to that in some way.
Assuming the "oil" you're talking about is kerosene/heating fuel, the >>>>>> speed of sound is 1330 m/sec so 0.5cm takes 3.76 micro-sec.
I would have thought it's measuring the distance to the surface of >>>>> the oil from above the oil so it would be the speed of sound in air that >>>>> matters 300m/s.
I'll add more debug code tomorrow
Are you sure the sensor isn't malfunctioning as a result of being in
oil vapour?
I haven't let it anywhere near the oil tank yet. The plan is to have it
installed by the fall. ready for next winter.
So it is being hammered to check for problems *before* it gets to a cold
wet inaccessible oil tank.
On the off chance an alternative sensing architecture might be of
some use: Instead of using sound to measure distance, have you
considered possibly using fluid pressure to measure the height of
the stack of liquid above a pressure sensor? If you put a
pressure sensor near the bottom of the tank, and if the air space
above the liquid is at atmospheric pressure, the gauge pressure
reading will be directly proportional to the height of liquid
above the sensor.
For water, the pressure reading will be ~0.43 psi per foot of
height. Oil is almost certainly less dense, so you might need a
very sensitive pressure sensor--unless the tank is very large.
Anyway, just in case you hadn't considered that idea...
That is, some asynchrounous event in this sequence
gpio_put(ULTRASONIC_OUT,1);
sleep_us(10);
gpio_put(ULTRASONIC_OUT,0); //reset the input
//if asynch event lasting more than 100uS occurs here...
// wait for echo pulse start
while(!gpio_get(ULTRASONIC_IN))
;
//then the low-high-low echo pulse will never be detected.
On 26/03/2024 21:58, Pancho wrote:
On 25/03/2024 15:57, The Natural Philosopher wrote:Oh. The manufacturers sample code is the source of ALL the 'examples'
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation with
someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values of
x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep'
with the processor being put in low power mode and requiring an
interrupt to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than sleep. >>>>
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
A timer isn't complicated, just a call back routine, and a semaphore.
Interrupts are something an OS does, not me :o). I hate multithread
code, but async handling of an external resource is one of the two
main places I would use another thread.
I had a look at your code, it looks extraordinarily like a python
example on Tom's hardware.
that other people publish as their own., I am just being honest :-)
I'm not clear how many times it is succeeding vs failing, but IWell the averaging out will happen anyway at the server side. I make the clients as simple as possible for resilience. In practice oil levels
suspect you really need to bite the bullet and introduce
timeouts/error handling, if it fails try again, average out multiple
results. i.e. accept it as flawed and that results are statistical,
like GPS.
only change quickly if you have had the oil stolen overnight or if a
supplier has filled the tank up, so gross deviations can have code exceptions, the rest would be the running average of maybe 20 samples.
BUT it isn't inaccuracy that worries me per se, it's that it may be an indication of underlying timing issues.
In many ways the resilience code will be simple, because it is justIn fact the code in either case is simple.
normal code, rather than cargo culting a novel ultrasonic device.
It is: send a 10µs pulse to the unit, wait for the echo pulse start ,
get the time, wait for the echo pulse end, get the time, subtract the difference.
What appears to be happening is that at short range the echo pulse never starts, or ends before the code is aware of it.
You can investigate further, by recording fail stats, as well asFailure is very very rare. I am sampling for test purposes once a
distance stats.
second, and its usually an hour or more before it locks up.
I could simply turn the while loop into a for loop with a counter so
that even if I got a null result it wouldn't lock up. Missing one sample
is no big deal: just take another!
I am slightly curious as to how the PICO could miss what is a several hundred microsecond wide pulse.
So far I have managed to get stuff reliable without having to unpick the
ARM interrupt pandora's box. I am keen to leave it closed. The LWIP
stack was bad enough...:-)
Obviously interrupt on GPIO pin state would be the thing, but it would
take some research to find out what the ISR was allowed to do in terms
of library code that was re-entrant..
On 27/03/2024 10:13, The Natural Philosopher wrote:
On 26/03/2024 21:58, Pancho wrote:
On 25/03/2024 15:57, The Natural Philosopher wrote:Oh. The manufacturers sample code is the source of ALL the 'examples'
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation with >>>>>> someone else *on here* (c.s.r-pi) last year, who was finding that
*sleep_us(x)* was highly inconsistent for certain (small) values
of x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep'
with the processor being put in low power mode and requiring an
interrupt to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than
sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
A timer isn't complicated, just a call back routine, and a semaphore.
Interrupts are something an OS does, not me :o). I hate multithread
code, but async handling of an external resource is one of the two
main places I would use another thread.
I had a look at your code, it looks extraordinarily like a python
example on Tom's hardware.
that other people publish as their own., I am just being honest :-)
I'm not clear how many times it is succeeding vs failing, but IWell the averaging out will happen anyway at the server side. I make
suspect you really need to bite the bullet and introduce
timeouts/error handling, if it fails try again, average out multiple
results. i.e. accept it as flawed and that results are statistical,
like GPS.
the clients as simple as possible for resilience. In practice oil
levels only change quickly if you have had the oil stolen overnight or
if a supplier has filled the tank up, so gross deviations can have
code exceptions, the rest would be the running average of maybe 20
samples.
BUT it isn't inaccuracy that worries me per se, it's that it may be an
indication of underlying timing issues.
In many ways the resilience code will be simple, because it is justIn fact the code in either case is simple.
normal code, rather than cargo culting a novel ultrasonic device.
I understood the idea of a ping delay time. It is just my experience
that things rarely work exactly as I expect them to.
FWIW, I'd also massively underestimated the difficulty of coding the
PICO, I'd assumed it was running a multitasking OS, like busybox, but I
see it isn't. I guess there are a whole bunch of gotchas there too.
It is: send a 10µs pulse to the unit, wait for the echo pulse start ,
get the time, wait for the echo pulse end, get the time, subtract the
difference.
I'm unclear on terms, but that sounds like the length of the pulse,
10µs. Not the distance travelled by the pulse. Surely, you should be measuring the time between sending the pulse and receiving the pulse.
I've probably misunderstood something, if the code is giving a sensible distance.
What appears to be happening is that at short range the echo pulse
never starts, or ends before the code is aware of it.
You can investigate further, by recording fail stats, as well asFailure is very very rare. I am sampling for test purposes once a
distance stats.
second, and its usually an hour or more before it locks up.
I could simply turn the while loop into a for loop with a counter so
that even if I got a null result it wouldn't lock up. Missing one
sample is no big deal: just take another!
I am slightly curious as to how the PICO could miss what is a several
hundred microsecond wide pulse.
Maybe ultrasound is everywhere. Maybe a bird sings, or a walwart noise interferes. The device may just move in mysterious ways.
So far I have managed to get stuff reliable without having to unpick
the ARM interrupt pandora's box. I am keen to leave it closed. The
LWIP stack was bad enough...:-)
Yeah, I went off the idea of getting a PICO the moment I realised it
didn't have a proper OS. I have spare rPi3s I could use, and I'm willing
to accept high power usage of a couple of watts.
Obviously interrupt on GPIO pin state would be the thing, but it would
take some research to find out what the ISR was allowed to do in terms
of library code that was re-entrant..
To be fair, the ISR wouldn't need to do much. But the problem might be inherent in the ultrasonic device. The device interrupt/event may suffer
the same problem you are seeing.
On 29/03/2024 00:52, Pancho wrote:
On 27/03/2024 10:13, The Natural Philosopher wrote:No.
On 26/03/2024 21:58, Pancho wrote:
On 25/03/2024 15:57, The Natural Philosopher wrote:Oh. The manufacturers sample code is the source of ALL the 'examples'
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation
with someone else *on here* (c.s.r-pi) last year, who was finding >>>>>>> that *sleep_us(x)* was highly inconsistent for certain (small)
values of x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a 'sleep' >>>>>>> with the processor being put in low power mode and requiring an
interrupt to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than
sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was a
learnning curve I preferred not to negotiate if i didnt need to
A timer isn't complicated, just a call back routine, and a
semaphore. Interrupts are something an OS does, not me :o). I hate
multithread code, but async handling of an external resource is one
of the two main places I would use another thread.
I had a look at your code, it looks extraordinarily like a python
example on Tom's hardware.
that other people publish as their own., I am just being honest :-)
I'm not clear how many times it is succeeding vs failing, but IWell the averaging out will happen anyway at the server side. I make
suspect you really need to bite the bullet and introduce
timeouts/error handling, if it fails try again, average out multiple
results. i.e. accept it as flawed and that results are statistical,
like GPS.
the clients as simple as possible for resilience. In practice oil
levels only change quickly if you have had the oil stolen overnight
or if a supplier has filled the tank up, so gross deviations can have
code exceptions, the rest would be the running average of maybe 20
samples.
BUT it isn't inaccuracy that worries me per se, it's that it may be
an indication of underlying timing issues.
In many ways the resilience code will be simple, because it is justIn fact the code in either case is simple.
normal code, rather than cargo culting a novel ultrasonic device.
I understood the idea of a ping delay time. It is just my experience
that things rarely work exactly as I expect them to.
FWIW, I'd also massively underestimated the difficulty of coding the
PICO, I'd assumed it was running a multitasking OS, like busybox, but
I see it isn't. I guess there are a whole bunch of gotchas there too.
It is: send a 10µs pulse to the unit, wait for the echo pulse start
, get the time, wait for the echo pulse end, get the time, subtract
the difference.
I'm unclear on terms, but that sounds like the length of the pulse,
10µs. Not the distance travelled by the pulse. Surely, you should be
measuring the time between sending the pulse and receiving the pulse.
I've probably misunderstood something, if the code is giving a
sensible distance.
Maybe ascii art will help
CONTROL=10µs
____| |________
RETURN = wahatever
_____|^^^^^^^^^^^^|____________
What appears to be happening is that at short range the echo pulse
never starts, or ends before the code is aware of it.
You can investigate further, by recording fail stats, as well asFailure is very very rare. I am sampling for test purposes once a
distance stats.
second, and its usually an hour or more before it locks up.
I could simply turn the while loop into a for loop with a counter so
that even if I got a null result it wouldn't lock up. Missing one
sample is no big deal: just take another!
I am slightly curious as to how the PICO could miss what is a
several hundred microsecond wide pulse.
Maybe ultrasound is everywhere. Maybe a bird sings, or a walwart noise
interferes. The device may just move in mysterious ways.
No, I'ts definitely all associated with a short return pulse
Well this has to be battery powered.So far I have managed to get stuff reliable without having to unpick
the ARM interrupt pandora's box. I am keen to leave it closed. The
LWIP stack was bad enough...:-)
Yeah, I went off the idea of getting a PICO the moment I realised it
didn't have a proper OS. I have spare rPi3s I could use, and I'm
willing to accept high power usage of a couple of watts.
You can get some sort of Free BSD RTOS port to a Pico, but in fact
mostly what you tend to be doing is just one thing at a time and so
linear code with callbacks works pretty well
On 29/03/2024 10:49, The Natural Philosopher wrote:
On 29/03/2024 00:52, Pancho wrote:
On 27/03/2024 10:13, The Natural Philosopher wrote:No.
On 26/03/2024 21:58, Pancho wrote:
On 25/03/2024 15:57, The Natural Philosopher wrote:Oh. The manufacturers sample code is the source of ALL the
On 25/03/2024 11:31, Pancho wrote:
On 24/03/2024 11:13, The Natural Philosopher wrote:Good point Pancho, but I was really looking for the simplest code
However on trawling the internet I discovered a conversation
with someone else *on here* (c.s.r-pi) last year, who was
finding that *sleep_us(x)* was highly inconsistent for certain >>>>>>>> (small) values of x. Sometimes taking a day to end.
Further investigation reveals that in fact it really is a
'sleep' with the processor being put in low power mode and
requiring an interrupt to 'wake it up'.
Why not use threads/timers, wait on a lock/semaphore rather than >>>>>>> sleep.
possible. Interrupts can be tricky things on a platform whose
architecture you do not understand completely. In any case it was
a learnning curve I preferred not to negotiate if i didnt need to
A timer isn't complicated, just a call back routine, and a
semaphore. Interrupts are something an OS does, not me :o). I hate
multithread code, but async handling of an external resource is one
of the two main places I would use another thread.
I had a look at your code, it looks extraordinarily like a python
example on Tom's hardware.
'examples' that other people publish as their own., I am just being
honest :-)
I'm not clear how many times it is succeeding vs failing, but IWell the averaging out will happen anyway at the server side. I make
suspect you really need to bite the bullet and introduce
timeouts/error handling, if it fails try again, average out
multiple results. i.e. accept it as flawed and that results are
statistical, like GPS.
the clients as simple as possible for resilience. In practice oil
levels only change quickly if you have had the oil stolen overnight
or if a supplier has filled the tank up, so gross deviations can
have code exceptions, the rest would be the running average of maybe
20 samples.
BUT it isn't inaccuracy that worries me per se, it's that it may be
an indication of underlying timing issues.
In many ways the resilience code will be simple, because it is justIn fact the code in either case is simple.
normal code, rather than cargo culting a novel ultrasonic device.
I understood the idea of a ping delay time. It is just my experience
that things rarely work exactly as I expect them to.
FWIW, I'd also massively underestimated the difficulty of coding the
PICO, I'd assumed it was running a multitasking OS, like busybox, but
I see it isn't. I guess there are a whole bunch of gotchas there too.
It is: send a 10µs pulse to the unit, wait for the echo pulse start >>>> , get the time, wait for the echo pulse end, get the time, subtract
the difference.
I'm unclear on terms, but that sounds like the length of the pulse,
10µs. Not the distance travelled by the pulse. Surely, you should be
measuring the time between sending the pulse and receiving the pulse.
I've probably misunderstood something, if the code is giving a
sensible distance.
Maybe ascii art will help
CONTROL=10µs
____| |________
RETURN = wahatever
_____|^^^^^^^^^^^^|____________
Yeah, I know what a ping is supposed to do. It is the time interval
between sending a ping and receiving the echo, simples. But... that
isn't what your code looks like.
You have:
while(!gpio_get(ULTRASONIC_IN));
//read clock and store
start=get_absolute_time ();
Which is presumably waiting for silence, no echo, it might work if that
is the default start state, i.e. if it does nothing, but it is
redundant. You should start the time interval when the ping is sent.
A short pulse always fails? I wasn't clear if it just made it more
vulnerable to failure. Failure caused by something else? Maybe
wavelength? Interference. I really don't know. I don't know how you can
rule stuff out. Apart from empirically, test reliability, in which case
you need to record failure stats as well as success.
You can get some sort of Free BSD RTOS port to a Pico, but in fact
mostly what you tend to be doing is just one thing at a time and so
linear code with callbacks works pretty well
Yeah, you say that, but virtually all my experience is based upon a multitasking OS: VMS, Unix, Windows NT, Linux. I can't remember stuff I
did in the early 1980s. I have a huge store of experience, intuition, in
the multitasking Posix like world, none in single process.
I'm a little paranoid, pessimistic, I think the world is out to mess me
up. If things can go wrong, they will go wrong, which is why I'm
unwilling to step into such a different paradigm.
I have noticed that with absoluteley no change in sensor location I get
up to ± 0.5cm variation in delay.
On 2024-03-25, The Natural Philosopher <tnp@invalid.invalid> wrote:
I have noticed that with absoluteley no change in sensor location I get
up to ± 0.5cm variation in delay.
Sounds reasonable (or even quite good) for such a cheap sensor. Does yours come with a datasheet that specifies accuracy limits?
The datasheet on the Sparkfun website claims "the ranging accuracy can reach to 3mm", but does not give any guaranteed limits - and I believe there are lots of clone parts that may be even worse.
FWIW, I'd also massively underestimated the difficulty of coding the
PICO, I'd assumed it was running a multitasking OS, like busybox, but I
see it isn't. I guess there are a whole bunch of gotchas there too.
Maybe ascii art will help
CONTROL=10s
____| |________
RETURN = wahatever
_____|^^^^^^^^^^^^|____________
On Fri, 29 Mar 2024 10:49:13 +0000, in <uu66b9$83pi$3@dont-email.me>,
The Natural Philosopher <tnp@invalid.invalid> wrote:
Maybe ascii art will help
CONTROL=10µs
____| |________
RETURN = wahatever
_____|^^^^^^^^^^^^|____________
Assuming my bleary-eyed math is correct, 10µs is the length of one
cycle of ultrasound at 100,000 Hz.
So what frequency is your ultrasound? Maybe some ASCII art - to scale
- of the waveform going down and back will reveal something.
I admit total ignorance to whether your devices can send sound and
receive at the same time, etc, etc, so this is my last potentially
annoying input. Good luck.
Spent many an evening with Z-80 assembler back in the late 70s. Good
times.
On 30/03/2024 02:04, Jim H wrote:
On Fri, 29 Mar 2024 10:49:13 +0000, in <uu66b9$83pi$3@dont-email.me>,The width of that pulse is pretty much immaterial - its only a digital trigger, It doesn't send anything directly.
The Natural Philosopher <tnp@invalid.invalid> wrote:
Maybe ascii art will help
CONTROL=10µs
____| |________
RETURN = wahatever
_____|^^^^^^^^^^^^|____________
Assuming my bleary-eyed math is correct, 10µs is the length of one
cycle of ultrasound at 100,000 Hz.
The unit does that, and senses a high to the output. Then it transmits a squawk., When it receives an echo it switches that to low.
Its a smart device .
https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf
On 30/03/2024 09:17, The Natural Philosopher wrote:
On 30/03/2024 02:04, Jim H wrote:
On Fri, 29 Mar 2024 10:49:13 +0000, in <uu66b9$83pi$3@dont-email.me>,The width of that pulse is pretty much immaterial - its only a digital
The Natural Philosopher <tnp@invalid.invalid> wrote:
Maybe ascii art will help
CONTROL=10µs
____| |________
RETURN = wahatever
_____|^^^^^^^^^^^^|____________
Assuming my bleary-eyed math is correct, 10µs is the length of one
cycle of ultrasound at 100,000 Hz.
trigger, It doesn't send anything directly.
The unit does that, and senses a high to the output. Then it transmits
a squawk., When it receives an echo it switches that to low.
Its a smart device .
I think that is the part I was missing. I assumed it was like an analog device, out pin was for send and the in pin signalled it was receiving.
On reflection, the code makes sense if it is a smart device. The in pin
just goes high (or low) for the period between sending and receiving a
few micro seconds of the echo.
https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf
Not the most precise wording.
Having taken the trouble to understand. I might buy one to tell me if my garage door is open. Buy an echo device that is, not a PICO.
Sysop: | Coz |
---|---|
Location: | Anoka, MN |
Users: | 2 |
Nodes: | 4 (0 / 4) |
Uptime: | 140:34:10 |
Calls: | 166 |
Files: | 5,389 |
Messages: | 223,239 |