TinyGPSPlus icon indicating copy to clipboard operation
TinyGPSPlus copied to clipboard

Anything inside void loop if statement does not work...WHYYYY?

Open Garretto123 opened this issue 2 years ago • 2 comments

Below is my code. The code is suppose to record speed (mph) and print it to the serial monitor using an arduino uno. Also, using the fastLED library, 50 leds will do a red wave. This code works ONLY when it is outside of the if statement "if (gps.encode(gpsSerial.read())) {". When the code is pasted inside, the led code works but very very slow. The red wave happens at 1/100th of real time. Is this a hardware issue? A bug in my code? I have no idea? Please help!

//library for GPS #include <TinyGPS++.h> #include <TinyGPSPlus.h> #include <SoftwareSerial.h>

//Library for LED #include <FastLED.h>

// Set the LED parameters #define LED_PIN 3 #define LED_TYPE WS2812B #define COLOR_ORDER GRB #define NUM_LEDS 50 float topSpeed = 50; CRGB leds[NUM_LEDS];

SoftwareSerial gpsSerial(8,9); //rx => pin 9 , tx => pin 8 TinyGPSPlus gps; float lattitude,longitude; float speed; unsigned long age;

void setup() {

gpsSerial.begin(9600); Serial.begin(9600); // Initialize the LED strip FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS); // Set the brightness of the LED strip FastLED.setBrightness(150);

} void loop() { while (gpsSerial.available()) { if (gps.encode(gpsSerial.read())) { if (gps.speed.isValid()) { speed = gps.speed.mph(); age = gps.speed.age(); Serial.print("Speed: "); Serial.print(speed); Serial.println(" mph"); //*******************************Led functions inside static uint8_t hue = 0; // Starting hue value static uint8_t wavePosition = 0; // Current position of the wave

  // Calculate color for each LED based on wave position
  for (int i = 0; i < NUM_LEDS; i++) {
    uint8_t color = sin8(i * 8 + wavePosition); // Use sine function for color intensity
    leds[i] = CHSV(hue, 255, color); // Set color based on hue and intensity
  }
  wavePosition++; // Increment wave position for the next frame
  FastLED.show();
  delay(10); 

  //*******************************Led functions inside
} else {
  Serial.println("No speed data");

  // Slowly pulses blue when "No speed data" is presented.
  uint8_t blue = 0; // Blue color value
  for (int i = 0; i < 255; i++) {
    blue = sin8(i);
    fill_solid(leds, NUM_LEDS, CRGB(0, 0, blue));
    FastLED.show();
    delay(10);
  }
  // Set all LEDs to off
  fill_solid(leds, NUM_LEDS, CRGB(0, 0, 0)); // Off
  FastLED.show();
}

} } }

Garretto123 avatar May 20 '23 00:05 Garretto123

gps.encode() processes the data one byte at a time. You really don't want to be testing the return for every byte.

The best bet is to separate the serial reading & gps encoding from everything else. Also, don't use delay(10); This stops all processing for 10 milliseconds. Instead, use millis(). This will cause the loop to continue running, and reading the GPS data. Then every 10 milliseconds, it will jump into the code that actually updates the LEDs.

Try this. (NOTE: I did not build or run this, so it might have errors. But it should be at least 95% correct)

loop()
{
	uint16_t GPSbytesAvailable;
	uint32_t LED_Update;
	uint8_t BlueCounter = 1;

	GPSbytesAvailable = GPS_Serial.available();
	while(GPSbytesAvailable--)
	{
		gps.encode(GPS_Serial.read());
	}
	
	if((millis() - LED_Update) >= 10))
	{
		LED_Update = millis();
		if (gps.speed.isValid()) 
		{
			BlueCounter = 1;
			age = gps.speed.age();
			Serial.print("Speed: ");
			Serial.print(gps.speed.mph());
			Serial.println(" mph");
	
			static uint8_t hue = 0; // Starting hue value
			static uint8_t wavePosition = 0; // Current position of the wave
	
			// Calculate color for each LED based on wave position
			for (int i = 0; i < NUM_LEDS; i++) 
			{
				uint8_t color = sin8(i * 8 + wavePosition); // Use sine function for color intensity
				leds[i] = CHSV(hue, 255, color); // Set color based on hue and intensity
			}
			wavePosition++; // Increment wave position for the next frame
		}
		else
		{
			Serial.println("No speed data");
	
			// Slowly pulses blue when "No speed data" is presented.
			uint8_t blue = 0; // Blue color value
			if(BlueCounter)
			{
				blue = sin8(BlueCounter);
				fill_solid(leds, NUM_LEDS, CRGB(0, 0, blue));
				BlueCounter++
			}
			else
			{
				// Set all LEDs to off
				fill_solid(leds, NUM_LEDS, CRGB(0, 0, 0)); // Off
			}
		}
		FastLED.show();
	}
}

JasonPittenger avatar Oct 27 '23 20:10 JasonPittenger

If this is complete, please close it

svdrummer avatar Nov 09 '23 04:11 svdrummer