Need help with PI PICO...

Mar 23, 2024 Last reply: 2 years ago 36 Replies

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

Thanks David

All make sense.

I think the next stage is to provide an escape from the infinite loops, that documents itself and see where its hanging.

If interrupts are buggering it up, I am not sure how using an interrupt would not also be buffered up by an interrupt.

The LWIP stack is all interrupt driven and I am loath to mess around for fear of breaking comms.

In the end the pragmatic answer may be to simply abort a failed reading and try again.

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...

Never thought of that. Cute.

I hadn't. Actually it looks like this idea is going to work fine, I just need to zero in on what the problem actually is, and get some form or reliability at short range. The sensor appears to work at far greater distances than its rated for, so against an orthogonal flat oil surface it should be just fine

I won't be able to get much done in the next few days so will attack the code again next week.

if you change the wait body to include a counter then you could realize that when the counter had reached a high number - you missed the pulse. Just try again then. Getting a reading is not that time sensitive - or?

:START int cnt = 0; 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(TRUE) {

if (! gpio_get(ULTRASONIC_IN)) { cnt++ } else { break; }

if (cnt >= TOO_HIGH_VALUE) { goto START; }

}

That will be the next strategy.

I need to isolate exactly which bit is failing, and can remove all the other debug code. If it turns out to be a one in a thousand issue it probably isn't worth trying to avoid it, as you say, simply take another sample

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.

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 ultrasound is everywhere. Maybe a bird sings, or a walwart noise interferes. The device may just move in mysterious ways.

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.

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.

No. Maybe ascii art will help

CONTROL=10µs ____| |________

RETURN = wahatever _____|^^^^^^^^^^^^|____________

No, I'ts definitely all associated with a short return pulse

Well this has to be battery powered.

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

That of course is what we are here to establish.

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.

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.

That is what the code does. You send a trigger pulse,. The board farts around, waits, sets its output high to mark the pulse start, and then low when it ends

That code is waiting for the pulse to *start*

The shorter pulses failed *sometimes*, the longer ones never did.

New code is in and it hasn't failed yet...

static float get_distance() { int i; absolute_time_t start; absolute_time_t end; static int64_t us_delay; //set output pin high gpio_put(ULTRASONIC_OUT,1); busy_wait_us(10); //sleep_us() possibly unreliable here gpio_put(ULTRASONIC_OUT,0); //reset the input // wait for echo pulse start for (i=0;i<100000;i++) { if(gpio_get(ULTRASONIC_IN)) //pulse start { //read clock and store start=get_absolute_time (); //wait for echo pin to go low; while(gpio_get(ULTRASONIC_IN)) ; end=get_absolute_time (); //get clock difference us_delay=absolute_time_diff_us(start,end); //convert to float and return it as cm return (((float)(us_delay))*0.034/2); } } //we ran out of time here. return(0.0); }

Well I cut my teeth on assembler on Z80s and 8080s and bare metal programming LONG before Unix was part of my knowledge

It's like going back to the days spent messing around in BASIC on 6800 kits my friend had built.

Its just another way of doing stuff. Like a coder friend once said 'it's all just bits, in silicon'

:-)

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 thay may be even worse.

cu Michael

It *is* the Sparkfun module.

In general I am getting *repeatibility* now to a lot less than that, and it has been known, (pointed out of the window) to detect large objects at many many metres.

It is certainly more than good enough for measuring from 0-1.5 metres or so. to a sorta 10% accuracy.

With a single core things might get tricky, but the PICO has dual cores. So you can run code on one core that just sits in a tight loop taking measurements if you need to, and the other core can take care of everything else, such as comms with the outside world.

---druck

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.

The width of that pulse is pretty much immaterial - its only a digital 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 .

formatting link

40Khz allegedly. see datasheet

Ive no idea either, Its got two things that might be transducers,

Yes. I finally connected the dots between hardware and higher level languages

Anyway the unit now appears to be stable, i've watched it fail to connect, and recover, I've watched it detect it had lost wifi and reconnect after that, and it hasn't crashed or locked up yet, so I think that's as far as the code needs to go right now.

Next step is to concert to battery and check if the battery saver works, and see how long it lasts on batterries

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.

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.

Well hook it to a pico and tell a server via wifi that the door is/isn't open!

It seems reiable so far.

Now running of 3 dry cells to see at what point the voltage gets too low for reliable pinging.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required