Ultrasonic Sensor - Program freezes during distance change

I have built a simple program to make an ultrasonic sensor detect whether it is too close to an object or not. If it is too close, it will light up an LED, else it will turn off the LED. The code I have does work as intended, but if I gradually change the distance it is detecting the program will freeze/seem to stop looping. If I change the distance abruptly (such as bringing my hand down in front of the sensor quickly or jerking it away) it continues to behave as expected… most of the time. It will freeze occasionally even if I do it quickly, but a slow change guarantees that it will freeze.

The problem seems to be crossing the “too close” threshold slowly, but I don’t understand why that would be the case. I have tried different delays, and that makes it a bit more reliable, but even at ~1s delays a detection near the threshold will freeze it.

Code is below. Any tips or insight would be greatly appreciated, as I’m very new to XOD. (I only just discovered it this morning but it’s perfect for my needs!).

The most likely issue reading your problem is that you have code for > and code for <, but no code for =, but that is not the case.

I do see several inefficiencies, but not an obvious problem.

The 1st is that there is an greater-or-equal node that could replace your greater, equal, and or nodes. This would simplify your code and reduce chance of errors (like input to equal and greater nodes not being the same).

The true/false output of the test will automatically convert to 1 or 0 if fed to the led-LUM pin, so the if-else isn’t really needed.

The 2nd delay should not be needed. Worst-case, you might need a defer node between ultrasonic-DONE and led-UPD to make sure comparison node finishes before led updates.

There is an issue with the ultrasonic hardware. It needs time to stabilize between pings. the 1st delay you have with 0.6 SHOULD be enough…1s delay should certainly be enough to handle this issue.

The only places I see where the train of pulses might get lost is the ultrasonic & led nodes. They have ERR pins, which would fire instead of the DONE pin if there was a problem. Ultrasonic node is certainly more likely to have occasional issues than the led node would be. You could expand the any node at the top and feed the ultrasonic-ERR pin into it to catch this failure case & restart the loop (since it causes a loop, another defer node will also be needed).

The alternative to catching errors would be a sort of watchdog reset timer. Add a new delay node and SET it every time the top delay node SETs, and have it run a little longer than the loop would ever run (so it should always get reset and never reach DONE…unless there is a problem). It’s DONE pin would feed back into the any node to restart the loop if it is ever interrupted. Note that starting a 2nd pulse in the loop might cause problems, so make sure delay on this new timer is long enough.

2 Likes

Thanks so much! Putting in a defer node at the Ultrasonic’s ERR fixed it right up. Posting a pic of the functional code for posterity.

Also, I do not seem to have a greater-or-equal node installed. Should it be in the default libraries?

1 Like

Have you used the search function looking for “greater”? I seldom look in the tree for any nodes, so I don’t know where it is.

nodes it in e/comparison, is an library of @evgenykochetkov

1 Like

Sorry. I assumed it was a built in node. It might not be worth including another library just to get that node.

1 Like

Perhaps we should bring less-or-equal and greater-or-equal to the standard library, but in most cases the following is enough:

  • Choose either less or greater and use it for the first condition
  • Add a not node and link it to the comparison output; use the new branch for the second condition
1 Like

“less” followed by “not” might not be as intuitive, but is probably less error-prone long-term than “greater”, “equal”, “or” combination since nothing needs repeated and there are fewer nodes & links. greater-or-equal certainly isn’t NEEDED, but it is more intuitive than less/not. It could even be implemented using less/not…

I even thought about having two comparison nodes producing the following outputs:

  • LT (less than) and GE (greater or equal, compliments LT)
  • LE and GT

Don’t know how to name them, and not sure whether they make sense at all :nerd_face:

Interesting thought. Seems most of the time a comparison just feeds a condition (or gets cast to a number), but there are times a “not” is added to get a 2nd output value. I would think greater-or-equal would get used more often than this, but maybe I’m wrong.

Possible names: compare-greater with GT & LE pins and compare-less with LT & GE pins. The pin labels do more to describe what exactly is happening than the node names, but giving a name with full description would be very wordy…

I guess you could just have a single compare node with GT, EQ, & LT pins…I’m guessing most of the time it would get used with an “or” node, but it would make it clear what you were doing without having to create multiple nodes to cover each possible test and still eliminate duplication of test values… EQ pin should be in the middle to make wiring “or” node easier/cleaner. It would be cool to be able to link one of the GT/LT pins to EQ pin without the extra “or” node, but I don’t see a way to do that with existing interface…I guess GE & LE pins could also be added, but that seems over-kill and would make for a huge node. Since you will be comparing floating-point numbers, EQ should probably equal (!GT && !LT) instead of doing 3 numeric compares.

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.