-1

I have a sketch that calculates simple distance from the device to the nearest preset GPS coordinate (there are 3 in total) and I would like to have LEDs in the neopixel strip light up according to the proximity of the location.

I managed to make it work with only one 5mm led and a simple if (shortestDist < 10) then digitalWrite(ledPin, HIGH); - else ledpin low. But I want to use a neopixel strip with 7 leds to light up according to various distance criteria.

In my attempt here, I tried to make specific leds light up when 50, 30 and 10m away but it doesn't work properly, and it's a pretty crude approach, as are my coding "skills" :D

I would also like some help on how to make some kind of shorthand for specific led strip setup depending on distance - for example at 50m distance, 2 leds red, 5 leds off, at 30m distance 5 leds red, 2 leds off and so on.

Hope someone can assist the newb :D Currently the leds don't all shut off when the distance is higher than 50.

void loop()
{
while (ss.available() > 0)
 gps.encode(ss.read());
if (gps.location.isUpdated())
{
 Serial.print(F("Lat Lon = "));
 Serial.print(gps.location.lat(), 6);
 Serial.print(", ");
 Serial.println(gps.location.lng(), 6);
}
else if (millis() - last > 1000)
{
 Serial.println();
 if (gps.location.isValid())
 {
 double shortestDist;
 for (int i = 0; i < 3; ++i)
 {
 double distanceToDest =
 TinyGPSPlus::distanceBetween(
 gps.location.lat(),
 gps.location.lng(),
 positions[i].lat,
 positions[i].lon);
 if (!i || distanceToDest < shortestDist)
 shortestDist = distanceToDest;
 }
 Serial.print(F("Next in range = "));
 Serial.print(shortestDist, 2); // decimal
 Serial.println(" m");
 
 if (shortestDist < 50) 
 {
 pixels.clear();
 pixels.setPixelColor(0, pixels.Color(0, 250, 0));
 pixels.setPixelColor(1, pixels.Color(0, 0, 0));
 pixels.setPixelColor(2, pixels.Color(0, 0, 0));
 pixels.setPixelColor(3, pixels.Color(0, 0, 0));
 pixels.setPixelColor(4, pixels.Color(0, 0, 0));
 pixels.setPixelColor(5, pixels.Color(0, 0, 0));
 pixels.setPixelColor(6, pixels.Color(0, 250, 0));
 pixels.show();
 delay(50); 
 }
 else if (shortestDist < 30)
 { 
 pixels.clear();
 pixels.setPixelColor(0, pixels.Color(0, 250, 0));
 pixels.setPixelColor(1, pixels.Color(250, 250, 0));
 pixels.setPixelColor(2, pixels.Color(0, 0, 0));
 pixels.setPixelColor(3, pixels.Color(0, 0, 0));
 pixels.setPixelColor(4, pixels.Color(0, 0, 0));
 pixels.setPixelColor(5, pixels.Color(250, 250, 0));
 pixels.setPixelColor(6, pixels.Color(0, 250, 0));
 pixels.show();
 delay(50); 
 } 
 else if (shortestDist < 10)
 { 
 pixels.clear();
 pixels.setPixelColor(0, pixels.Color(250, 0, 0));
 pixels.setPixelColor(1, pixels.Color(0, 250, 0));
 pixels.setPixelColor(2, pixels.Color(0, 0, 0));
 pixels.setPixelColor(3, pixels.Color(250, 0, 250));
 pixels.setPixelColor(4, pixels.Color(0, 0, 0));
 pixels.setPixelColor(5, pixels.Color(0, 250, 0));
 pixels.setPixelColor(6, pixels.Color(250, 0, 0));
 pixels.show();
 delay(50); 
 } 
 else
 { 
 pixels.clear();
 pixels.setPixelColor(0, pixels.Color(0, 0, 0));
 pixels.setPixelColor(1, pixels.Color(0, 0, 0));
 pixels.setPixelColor(2, pixels.Color(0, 0, 0));
 pixels.setPixelColor(3, pixels.Color(0, 0, 0));
 pixels.setPixelColor(4, pixels.Color(0, 0, 0));
 pixels.setPixelColor(5, pixels.Color(0, 0, 0));
 pixels.setPixelColor(6, pixels.Color(0, 0, 0));
 pixels.show(); 
 delay(50); 
 } 
 }
 if (gps.charsProcessed() < 10)
 Serial.println(F("No GPS data."));
 last = millis();
 Serial.println(); 
}

}

asked Nov 19, 2022 at 13:23
6
  • you have a logic error in your code ... else if (shortestDist < 10) will never execute ... think about what you are telling your program to do Commented Nov 19, 2022 at 17:25
  • I rearranged the "else if shortestDist" by going "if shortestDist biggest value", else if smaller value and it works, as far as I can see it behaves properly Commented Nov 19, 2022 at 18:39
  • then you did not post your real code... think about this ... which if statement will execute when shortestDist = 5 ? Commented Nov 19, 2022 at 19:04
  • put serial.print statements inside the if blocks for debugging purpose Commented Nov 19, 2022 at 19:07
  • @jsotola I don't know how to post full code here other than pastebin - pastebin.com/BWVjdr1S - this works and leds turn on and off as they should. Take a look if you have the time, let me know if there's a better way to format it, as you can pretty much tell I'm not very well versed at this :D Commented Nov 19, 2022 at 22:12

1 Answer 1

0
  • Common inexpensive GPS modules are likely to report positions that appear to jump around by perhaps 5 meters in good conditions. Many factors affect GPS accuracy and this uncertainty. Some are listed here. It might be problematic to implement a 10 meter distance threshold feature unless conditions are favorable.

  • Consider constraining your "if" tests more. For example, use "if ((shortestDist <= 50) && (shortestDist > 30))" instead of "if (shortestDist < 50)". Continue similarly with the other "if" tests. Otherwise, once shorttestDist is less then 50 only the 1st "if" test is executed as it will become true and stay true and none of the other "it" tests will be considered.

  • Consider only using mills(). The posted code uses delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided.

  • The logic in the code might be incorrect. It appears GPS data is only process and the LEDs updated when GPS information is unavailable (not new).

  • When writing embedded firmware, always consider hardware problem sources. Many find small batteries problematic during momentary current demands. Batteries with small Amp-Hour ratings are more prone to dropping their voltage during a high current events. Such as when a processor operates a relay or activates a sensor.

answered Nov 19, 2022 at 15:09
4
  • Thank you for the input - I will use this with 10m increments on a RC boat, it's just a concept test and the RC moves so slow, it should be good. I can maybe try with 15m, I think it should be ok as I did the walking test and GPS coordinates on the street and was pretty satisfactory. One thing that I noticed with my current IF "solution" - the leds I call up on the strip in the specific IF criteria do light up, but they blink, and in rhythm, so it might be something with else if (millis() - last > 1000) Commented Nov 19, 2022 at 15:37
  • For the LEDs. I would recommend creating a version of your code that changes the LED at a fixed & expected rate. You need to separate out any unexpected GPS affects that may be leading you astray. For the GPS. To get an understanding of GPS noise in your setting (trees, buildings, location, weather, ect) log the data of a stationary GPS for a day. This will give you a good idea of what you might expect and perhaps ideas as to how to mitigate any noise for your given application. Commented Nov 20, 2022 at 13:46
  • Going on, a few here will write code and post it. I feel that doesn't help as much as the O.P. figuring out the code for them selves. That said, here are a few items I noticed. You are using delay() & millis(). Calling delay() is fine but using millis() is almost always better. Mixing the 2, though, should be avoided. Your logic might be incorrect. It looks like you only process GPS info & update the LEDs when the GPS info is unavailable (not new). When writing embedded firmware, always consider HW problem sources. Many find small batteries problematic during momentary current demands. Commented Nov 20, 2022 at 14:08
  • I decided to add a few of these comments to the answer since it might help others who happen across this question / answer. Commented Nov 20, 2022 at 14:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.