text:
Servomotor and Bluetooth module block each other
For a small project, I aim to connect a digital temperature sensor (KY-028), a Bluetooth module (HC-05) and a servomotor (SG90). The problem is it seems I can't connect the Bluetooth module and the servomotor together at the same time. The Bluetooth module together with the temperature sensor works fine. The servo with the sensor, again, all fine. But it seems these two don't agree with each other: as soon as I upload the code on the board (Arduino UNO), the servo starts vibrating (not even rotating), altough I made sure no command that asks it to do so is reached. Also while doing this, the Bluetooth module's led is turned off and it is unrecognizable by other devices.
When I upload the program to the board, I disconnect the RX and TX pins of the Bluetooth module from the pins 0 & 1 of the Arduino board, (otherwise I get errors and the program is not uploaded - if needed, I will get the error codes I get and edit the post), but after upload, the servo starts behaving weird, as described before. As I read on another article (if I manage to find the link again I will post it here), it might behave like this because there are unconnected pins in my whole circuit (which is true, but otherwise I can't connect the Bluetooth module). How could I possibly connect both of them on the same board?
I tested the code segments, they act as they should, I tried switching the pins so that I did not miss anything by mistake, as I am a total beginner (for instance I tried putting the signal wire of the servo on both PWM and not PWM supporting pins, tried connecting the Bluetooth module and the servo to different grounds etc.) but no success.
Any help would be much appreciated. If the layout of my circuit is needed, I will try to make one in a simulator. Thank you very much!
Edit
Here is the code:
#include <Servo.h>
#include <SoftwareSerial.h>

int txPin = 1;
int rxPin = 0;
int digitalPin = 7; // KY-028 digital interface
int analogPin = A2; // KY-028 analog interface
int angle = 0;
int temp;
bool incTemp = false, decTemp = false;

Servo servo;
SoftwareSerial BT(txPin,rxPin);

void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  servo.attach(11);
  delay(100);

  BT.begin(9600);
  Serial.begin(9600);
}

void loop() {
  temp = analogRead(analogPin);
  Serial.println(temp);

  if (BT.available())
  {
    char bytesToSend[2];
    bytesToSend[0] = 101;
    bytesToSend[1] = temp;
    bytesToSend[2] = 110;
    BT.println(bytesToSend);
  }

  if(incTemp)
  {
    servo.write(90);
    delay(100);
    servo.write(135);
    delay(100);
    servo.write(180);
    delay(100);
    servo.write(135);
    delay(100);
  }
  else if(decTemp)
  {
    servo.write(90);
    delay(100);
    servo.write(45);
    delay(100);
    servo.write(0);
    delay(100);
    servo.write(45);
    delay(100);
  }

  delay(2000);
}

For the incTemp and decTemp variables I will use an interrupt to detect when the Bluetooth paired device is sending a command to activate the servomotor. But for now, as it can be seen, the blocks that ask the servo to rotate cannot be reached. For the layout I will try to find a simulator that provides the components I use and I will come back with the design.
Later edit, after following Majenko's advice
Here is the currently working code. An answer with the full implementation will come when the project is complete.
#include <Servo.h>

int txPin = 1;
int rxPin = 0;
int digitalPin = 7; // KY-028 digital interface
int analogPin = A2; // KY-028 analog interface
int angle = 0;
int temp;
bool incTemp = false, decTemp = false;

Servo servo;

void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  Serial.begin(9600);
}

void loop() {
  temp = analogRead(analogPin);
  Serial.print("T");
  Serial.print(temp);
  Serial.println();

  if(incTemp)
  {
    servo.attach(11);
    delay(100);

    servo.write(90);
    delay(100);
    servo.write(135);
    delay(100);
    servo.write(180);
    delay(100);
    servo.write(135);
    delay(100);

    servo.detach();
    delay(100);
  }
  else if(decTemp)
  {
    servo.attach(11);
    delay(100);

    servo.write(90);
    delay(100);
    servo.write(45);
    delay(100);
    servo.write(0);
    delay(100);
    servo.write(45);
    delay(100);

    servo.detach();
    delay(100);
  }

  delay(2000);
}

Please show your code and your wiring.

@Majenko I provided the code. But for the simulator I am not quite sure what to use. Neither Tinkercad nor Fritzing provide all the components I use...

Maybe this: https://arduino.stackexchange.com/questions/57584/does-softwareserial-and-the-servo-library-produce-interrupt-conflicts

I had a hunch I might see this: SoftwareSerial BT(txPin,rxPin); ...  NEVER use SoftwareSerial on pins 0/1 as they are the HARDWARE UART. You are using the right pins, but DO NOT use SoftwareSerial. Use Serial.

@Majenko Somehow it works but I am not quite sure how the Bluetooth communication is covered by the Serial interface. I edited the post with the currently working code (I also attach the servo only when needed and detach it after). Do you have any link where I can get a better understanding of why the Serial interface actually sends data over Bluetooth? When the whole project is complete, I will eventually post an answer with the fully working code.

The Serial sends data over pins 0 and 1. Those pins are also connected directly to the USB interface chip. Which is also why you have to disconnect bluetooth to upload your code.

So, I got carried away with my exams and I forgot to come back with an update and a solution. To take it short, I added a new source of power to the circuit and I am only turning the servo on when needed to rotate, then turn it off again. The code can be seen below:
#include <Servo.h>
#include <SoftwareSerial.h>

int rxPin = 2;
int txPin = 3;
int digitalPin = 7; // KY-028 digital interface
int analogPin = A2; // KY-028 analog interface
int servoPin = 11;

int angle = 0;
int temp;

const int minTemp = 150;
const int maxTemp = 350;
const int minAngle = 0;
const int maxAngle = 180;
const char sendDataPackageStartByte = 'T';
const int receiveDataPackageStartByteVal = 83; //"S"
const int receiveDataPackageEndByteVal = 13;
const int communicationDelay = 1000;
const int servoDelay = 100;

SoftwareSerial BT(rxPin,txPin);

Servo servo;
void setup() {
  pinMode(digitalPin, INPUT);
  pinMode(analogPin, INPUT);

  Serial.begin(9600);
  BT.begin(9600);
}

void loop() {
  if(BT.available() <= 0)
  {
    temp = analogRead(analogPin);
    BT.print(sendDataPackageStartByte);
    BT.print(temp/100);
    BT.print(temp/10%10);
    BT.print(temp%10);
    BT.println();
    delay(communicationDelay);
  }
  else
  {
    readData();
  }
}

void readData()
{
  if (BT.available())
  {
    char temp[3];
    while(BT.available() > 0)
    {
      char crtByte = BT.read();
      if (crtByte == receiveDataPackageStartByteVal)
      {
        temp[0] = BT.read();
        temp[1] = BT.read();
        temp[2] = BT.read();

        if(BT.read() != receiveDataPackageEndByteVal)
        {
          return;
        }

        break;
      }
    }

    int desiredTemp = atoi(temp);
    int desiredAngle = map(desiredTemp, minTemp, maxTemp, minAngle, maxAngle);
    printDataToSerial(desiredTemp, desiredAngle);

    turnServo(desiredAngle); //attach servo, write value, dettach
  }
}

void printDataToSerial(int desiredTemp, int desiredAngle)
{
  Serial.println("Desired Temperature:");
  Serial.println(desiredTemp);

  Serial.println("Desired Angle:");
  Serial.println(desiredAngle);
}

void turnServo(int angle)
{
  servo.attach(servoPin);
  delay(servoDelay);
  servo.write(angle);
  delay(servoDelay);
  servo.detach();
  delay(servoDelay);
}

Also, here would be the layout of my final circuit:

Basically what I wanted to achieve was sending and displaying the current temperature from an Arduino device to an Android one, then allow the user to adjust the temperature, simulating this with a servo commanded over Bluetooth. For those interested in the Android part as well (and the whole project actually), here is the link to the project repository on GitHub. The Android part is written with C# in the Xamarin Android framework. I hope this helps anyone landing here, good luck! :D


text:
ATTiny13 Interrupt Issue
I have recently been working on a project that I had initially been designing with an Arduino Nano, and I was able to create functioning code for my application, but for cost / space reduction I decided to port the application to an ATTiny13 (because I had a few on hand). The problem is that for some reason, I cannot get the interrupt on the device to behave properly, and I was wondering if anybody could possibly give me a hand. I already performed a few experiments to narrow the problem down, and I think I understand the nature of the problem, but I have no idea on how to mitigate it.
Here is a rough schematic of my setup:

And here is the code I started with:
// Pin defines
#define ALERT_LED 4

// Variables
bool LED_STATE = false;

ISR(PCINT0_vect) {
  LED_STATE = true;
}

void setup() {
  pinMode(ALERT_LED, OUTPUT);

  // Configure the button-pin to have a pull-up
  DDRB |= (1<<DDB3);
  PORTB |= (1<<PORTB3);

  // Enable a pin-change interrupt on the PCINT3 (falling-edge)
  MCUCR |= (1 << ISC01);  // This and following line setup for falling-edge
  MCUCR &= ~(1 << ISC00);
  GIMSK |= (1 << PCIE);   // Enable pin-change interrupts
  PCMSK |= (1 << PCINT3); // Setup the pin-mask so that PB3 triggers the interrupt
  sei();                  // enable all interrupts

}

void loop() {
  if(LED_STATE == true) {
    digitalWrite(ALERT_LED, HIGH);
    delay(2000);
    digitalWrite(ALERT_LED, LOW);
    delay(2000);
    LED_STATE = false;
  }
}

In theory, this should setup the pin that the button is on to have a pull-up resistor internally, and when the button is pressed, it should trigger a falling-edge interrupt which would thus set "LED_STATE" equal to 1. When the code returns to the main loop, it should see the flag and blink the LED before clearing the flag.
Now before I go any further, here is what I validated up to this point:
1.) The LED circuit is definitely wired up properly because I can manually set the "LED_STATE" flag to true in the main loop, and it will constantly blink at a rate of about once a second (given the clock frequency of 600kHz)
2.) The pull-up is definitely being configured properly, as I can see the voltage sitting at 5V until I press the button at which point the voltage falls to 0V.
So I decided to experiment a bit, and I set the LED high inside the interrupt, and removed that line from the main loop to see if the interrupt was even working, and to my surprise the LED was actually turning on, but it was not turning off:
// Pin defines
#define ALERT_LED 4

// Variables
bool LED_STATE = false;

ISR(PCINT0_vect) {
  LED_STATE = true;
  digitalWrite(ALERT_LED, HIGH);
}

void setup() {
  pinMode(ALERT_LED, OUTPUT);

  // Configure the button-pin to have a pull-up
  DDRB |= (1<<DDB3);
  PORTB |= (1<<PORTB3);

  // Enable a pin-change interrupt on the PCINT3 (falling-edge)
  MCUCR |= (1 << ISC01);  // This and following line setup for falling-edge
  MCUCR &= ~(1 << ISC00);
  GIMSK |= (1 << PCIE);   // Enable pin-change interrupts
  PCMSK |= (1 << PCINT3); // Setup the pin-mask so that PB3 triggers the interrupt
  sei();                  // enable all interrupts

}

void loop() {
  if(LED_STATE == true) {
    //digitalWrite(ALERT_LED, HIGH);
    delay(2000);
    digitalWrite(ALERT_LED, LOW);
    delay(2000);
    LED_STATE = false;
  }
}

At this point, I started to think that the ISR was not returning to the main loop or something, but by adding an 'else' case to shut the LED off in the main loop, I could see that the loop was definitely running after the ISR, because the LED would not turn on (implying that the main loop had to be shutting it off the moment the ISR returned to the loop).
// Pin defines
#define ALERT_LED 4

// Variables
bool LED_STATE = false;

ISR(PCINT0_vect) {
  LED_STATE = true;
  digitalWrite(ALERT_LED, HIGH);
}

void setup() {
  pinMode(ALERT_LED, OUTPUT);

  // Configure the button-pin to have a pull-up
  DDRB |= (1<<DDB3);
  PORTB |= (1<<PORTB3);

  // Enable a pin-change interrupt on the PCINT3 (falling-edge)
  MCUCR |= (1 << ISC01);  // This and following line setup for falling-edge
  MCUCR &= ~(1 << ISC00);
  GIMSK |= (1 << PCIE);   // Enable pin-change interrupts
  PCMSK |= (1 << PCINT3); // Setup the pin-mask so that PB3 triggers the interrupt
  sei();                  // enable all interrupts

}

void loop() {
  if(LED_STATE == true) {
    //digitalWrite(ALERT_LED, HIGH);
    delay(2000);
    digitalWrite(ALERT_LED, LOW);
    delay(2000);
    LED_STATE = false;
  }
  else {
    digitalWrite(ALER_LED, LOW);
  }
}

At this point, I can really only think that there must be a problem with how I am defining the "LED_STATE" parameter, because all signs point towards this variable not actually holding the information properly when traversing from the ISR back to the loop. I don't see what would be the problem though since I defined the parameter globally. Can anybody lend a hand here, this is honestly the last thing I need to finish this part of the project, and I am honestly at a bit of a loss at this point.

You would want your bool LED_STATE = false; to be volatile qualified like volatile bool LED_STATE = false; otherwise the compiler's optimizer may assume that the value cannot be changing between loads and this can cause bugs in the generated code.  This sounds like the principal problem you're having.
The ISC01 and ISC00 in MCUCR are for controlling edges detected on the "external interrupt" INT0 pin, which is PB1, package pin 6.  This is essentially what attachInterrupt() does, which should be available to you in your board support package.  If you can, it's probably best to just use that.  In the case of using attachInterrupt() the use of volatile would still apply.
The other pins, like the one you've chosen, only only do Pin Change interrupts, hence PCINTn rather than INTn.  Pin change interrupts only fire to tell that a pin changed, but not which pin (out of the group) or in what direction it changed.  That is, it's ignoring what you've set in MCUCR.
If you want an external interrupt's ability to detect falling or rising edges using PCINTn interrupts, you must effectively synthesize this in software by tracking the old and new states of the pins, XORing them to determine what changed, and then either looking at the old or new state to determine what direction.  NicoHood's PinChangeInterrupt library does this for you, and appears to support the ATTiny13.  Likewise, volatile usage applies here as well.

Holy crap, that’s actually crazy! I never knew the compiler would do me so dirty like that! I really appreciate it man, that literally fixed it!

Good deal.  I will probably add in the above later that if you use attachInterrupt() or the PinChangeInterrupt library, everything said about volatile stands.  Because with those. whatever callback function you give is likewise executing in the context of an interrupt, no different from your more direct ISR() code.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Why am I getting a "SendCommand was not declared" error?

#include <Adafruit_Fingerprint.h>
#include  <SoftwareSerial.h>
#include <LiquidCrystal.h>

uint8_t id;
int getFingerprintIDez();
//pin #16 is IN from sensor (GREEN wire)
//pin #15 is OUT from arduino (WHITE wire)
int Contrast = 100;
SoftwareSerial mySerial(52, 16);
LiquidCrystal lcd(13, 12, 11, 10, 9, 8); // initialize the library with the numbers of the interface pins
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
#define S1 22 //Button candidate A
#define S2 24 // Button candidate B
#define S3 26 // Button candidate c
#define S4 28 // Button candidate D
#define S5 30 // Button Result
#define S6 2 // Button submit
#define S7 32 // Button to cast vote
int can1 = 0;
int can2 = 0;
int can3 = 0;
int can4 = 0;
int total;
SoftwareSerial ESP8266(50, 18);// RX, TX

void setup() {
  Serial.begin(9600); // initialize the serial communications:
  lcd.begin(16, 2); lcd.clear();
  lcd.print("  Polling Day  ");
  lcd.setCursor(0, 1);
  lcd.print("      UPM      ");
  delay(2000);

  mainpage();

  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(A0, INPUT);

  finger.begin(57600); // set the data rate for the sensor serial port

  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  pinMode(S3, INPUT);
  pinMode(S4, INPUT);
  pinMode(S5, INPUT);
  pinMode(S6, INPUT);
  pinMode(S7, INPUT);

  ESP8266.begin(9600);

  digitalWrite(S1, HIGH);
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  digitalWrite(S4, HIGH);
  digitalWrite(S5, HIGH);
  digitalWrite(S6, HIGH);
  digitalWrite(S7, HIGH);

  SendCommand("AT+RST", "Ready");
  delay(5000);
  SendCommand("AT+CWMODE=1", "OK");
  SendCommand("AT+CIFSR", "OK");
  SendCommand("AT+CIPMUX=1", "OK");
  SendCommand("AT+CIPSERVER=1,80", "OK");
}

void loop() { // run over and over again
  getFingerprintID();
  delay(100);
  digitalWrite (13, HIGH);
  if (digitalRead(S5) == 0) { // To view the result for admin only
    int total = can1 + can2 + can3 + can4;
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("1");
    lcd.setCursor(1, 1);
    lcd.print(can1);
    lcd.setCursor(5, 0);
    lcd.print("2");
    lcd.setCursor(5, 1);
    lcd.print(can2);
    lcd.setCursor(9, 0);
    lcd.print("3");
    lcd.setCursor(9, 1);
    lcd.print(can3);
    lcd.setCursor(13, 0);
    lcd.print("4");
    lcd.setCursor(13, 1);
    lcd.print(can4);
    delay(4000);
    if (total) {
      if ((can1 > can2 && can1 > can3 && can1 > can4)) {
        lcd.clear();
        lcd.print("Can A is Winner");
        delay(3000);
        lcd.clear();
      } else if ((can2 > can1 && can2 > can3 && can2 > can4)) {
        lcd.clear();
        lcd.print("Can B is Winner");
        delay(3000);
        lcd.clear();
      } else if ((can3 > can1 && can3 > can2 && can3 > can4)) {
        lcd.clear();
        lcd.print("Can C is Winner");
        delay(3000);
        lcd.clear();
      } else if (can4 > can1 && can4 > can2 && can4 > can3) {
        lcd.setCursor(0, 0);
        lcd.clear();
        lcd.print("Can D is Winner");
        delay(3000);
        lcd.clear();
      } else if (can4 > can1 && can4 > can2 && can4 > can3) {
        lcd.setCursor(0, 0);
        lcd.clear();
        lcd.print("Can D is Winner");
        delay(3000);
        lcd.clear();
      } else {
        lcd.clear();
        lcd.print(" Tie Up Or ");
        lcd.setCursor(0, 1);
        lcd.print(" No Result ");
        delay(3000);
        lcd.clear();
      }
    } else {
      lcd.clear();
      lcd.print("No Voting....");
      delay(3000);
      lcd.clear();
    }
    can1 = 0; can2 = 0; can3 = 0; can4 = 0, total = 0;
    lcd.clear();
    adminpage();
  }

  if (digitalRead(S7) == 0) { //To cast avote for user
    voterpage();
  }

  if (digitalRead(S1) == 0) {
    can1++;
    votereceived();
    mainpage();
  }

  while (digitalRead(S1) == 0);
  if (digitalRead(S2) == 0) {
    can2++;
    votereceived();
    mainpage();
  }
  while (digitalRead(S2) == 0);
  if (digitalRead(S3) == 0) {
    can3++;
    votereceived();
    mainpage();
  }
  while (digitalRead(S3) == 0);
  if (digitalRead(S4) == 0) {
    can4++;
    votereceived();
    mainpage();
  }
  while (digitalRead(S4) == 0);
  if (digitalRead(S6) == 0) {
    lcd.clear();
    lcd.print("Submitting...");
    delay(1000);
    ESP8266.println("AT+CIPSEND=0,23");
    delay(1000);
    SendCommand("AT+CIPCLOSE=0", "OK");
  }
  String IncomingString = "";
  boolean StringReady = false;

  while (ESP8266.available()) {
    IncomingString = ESP8266.readString();
    StringReady = true;
  }

  if (StringReady) {
    Serial.println("Received String: " + IncomingString);

    if (IncomingString.indexOf("LED=ON") != -1) {
      digitalWrite(LED, HIGH);
    }

    if (IncomingString.indexOf("LED=OFF") != -1) {
      digitalWrite(LED, LOW);
    }
  }

  boolean SendCommand(String cmd, String ack) {
    ESP8266.println(cmd); // Send "AT+" command to module
    if (!echoFind(ack)) // timed out waiting for ack string
      return true; // ack blank or ack found
  }

  boolean echoFind(String keyword) {
    byte current_char = 0;
    byte keyword_length = keyword.length();
    long deadline = millis() + TIMEOUT;
    while (millis() < deadline) {
      if (ESP8266.available()) {
        char ch = ESP8266.read();
        Serial.write(ch);
        if (ch == keyword[current_char])
          if (++current_char == keyword_length) {
            Serial.println();
            return true;
          }
      }
    }
    return false; // Timed out
  }
}

uint8_t getFingerprintID() {
  uint8_t p = finger.getImage();
  switch (p) {
    case FINGERPRINT_OK:
      lcd.clear();
      lcd.print(" Image taken... ");
      delay(1000);
      break;
    case FINGERPRINT_NOFINGER:
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      return p;
    case FINGERPRINT_IMAGEFAIL:
      return p;
    default:
      return p;
  }

  // OK success!
  p = finger.image2Tz();
  switch (p) {
    case FINGERPRINT_OK:
      break;
    case FINGERPRINT_IMAGEMESS:
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      return p;
    case FINGERPRINT_FEATUREFAIL:
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      return p;
    default:
      return p;
  }

  // OK converted!
  p = finger.fingerFastSearch();
  if (p == FINGERPRINT_OK) {
    if (finger.fingerID == 26) {
      lcd.clear();
      lcd.setCursor(1, 0);
      lcd.print("Redirecting to");
      lcd.setCursor(1, 1);
      lcd.print("Admin process");
    } else {
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print("Valid Voter!");
      lcd.setCursor(2, 1);
      lcd.print("ID : ");
      lcd.print(finger.fingerID);
    }

    digitalWrite(11, HIGH);
    delay(1000);
    digitalWrite(11, LOW); // turn on green LED to indicate match
  } else if (p == FINGERPRINT_NOTFOUND) {
    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("Unregistered");
    lcd.setCursor(3, 1);
    lcd.print("Voter!");
    delay(1000);
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("scan finger");
    lcd.setCursor(6, 1);
    lcd.print("again");
    return p;
  } else {
    return p;
  }

  // IF FOUND A MATCH............
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Found ID #");

  if (finger.fingerID == 26) {
    adminpage();
  } else {
    voterpage();
  }
}

// returns -1 if failed, otherwise returns ID #
int getFingerprintIDez() {
  uint8_t p = finger.getImage();
  if (p != FINGERPRINT_OK) return -1;
  p = finger.image2Tz();
  if (p != FINGERPRINT_OK) return -1;
  p = finger.fingerFastSearch();
  if (p != FINGERPRINT_OK) return -1;
  // found a match!
  digitalWrite(13, LOW);
  delay(10);
  digitalWrite(13, HIGH);
  delay(10);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Found ID # ");
  lcd.print(finger.fingerID);
  lcd.setCursor(0, 1);
  lcd.print("confidence ");
  lcd.print(finger.confidence);
  return finger.fingerID;
}

void voterpage() {
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Candidate 1");
  lcd.setCursor(1, 1);
  lcd.print("Mohd Faiz");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Candidate 2");
  lcd.setCursor(1, 1);
  lcd.print("Siti Nur Ila");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Candidate 3");
  lcd.setCursor(1, 1);
  lcd.print("Muhammad Aus");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Candidate 4");
  lcd.setCursor(1, 1);
  lcd.print("Wan zakaria");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Choose 1 only");
  lcd.setCursor(1, 1);
  lcd.print("1");
  lcd.setCursor(5, 1);
  lcd.print("2");
  lcd.setCursor(9, 1);
  lcd.print("3");
  lcd.setCursor(13, 1);
  lcd.print("4");
}

void votereceived() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Vote Received");
  lcd.setCursor(2, 1);
  lcd.print("Thank You :)");
  delay(2000);
}

void adminpage() {
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("1");
  lcd.setCursor(1, 1);
  lcd.print("Result");
  lcd.setCursor(11, 0);
  lcd.print("2");
  lcd.setCursor(8, 1);
  lcd.print(" Submit");
  delay(2000);
}

void mainpage() {
  lcd.clear(); lcd.setCursor(0, 0); lcd.print("Scan your finger");
}

I guess you don't have a SendCommand() function in your code. Though we cannot know. Please show the complete code as text (by copy&pasting it). Also copy the complete error output into the question, including the line, where the error happens

@chrisl Hi here my complete code. appreciated if you could detect where my error was.

Please no text as images. You can copy the text inside the compilation output field (where the error message show up) and copy it in your question as text. That makes it way better to read

The problem is, that you try to define functions inside of other functions. The SendCommand() function is currently definied inside the loop() function, which is not allowed. Move all function definitions at the lowest level (alongside the loop() function, not in it). BTW: The autoformat function of the Arduino IDE is your friend. I formatted your code, so that you can easier see, where the functions are placed.

Though, this is a pure programming error. As I wrote the solution in the comments, I'm now voting to close this question, as it is not about Arduino. Have fun with your project :)

Both boolean SendCommand() and boolean echoFind() are defined inside loop(), and they shouldn't be; it is not allowed to define functions inside functions.
Take them out of loop() and define them at (move them to) the same level as uint8_t getFingerprintID(), etc.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Error while burning bootloader
I am trying to burn bootloader on Arduino UNO using MEGA2560 as the programmer,
I followed the steps stated here but still get the error below:
avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/arduino/arduino-nightly/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/home/webdev/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/ttyUSB0
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000 (retrying)

Error while burning bootloader.
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

Note: The Arduino UNO stopped responding when I mistakenly short-circuited a connection, I mistakenly passed 12v to one of the header pins of sensor shield mounted on the board.
How it was connected

You note about short circuiting needs more explanation.  Depending on what you did the device may be damaged.

Clearly, however, the MEGA is not communicating with the Uno.  Please share how you have this hooked up.

@jwh20 I have included a connection diagram to the question.

Based on this:

Note: The Arduino UNO stopped responding when I mistakenly
short-circuited a connection, I mistakenly passed 12v to one of the
header pins of sensor shield mounted on the board.

There are no I/O pins on the Arduino that are 12V tolerant.  You have almost certainly "fried" your Uno board.  It's possible the only casualty is the ATMega chip itself and replacements are available from a number of sources or you can purchase a "raw" one from an electronics reseller and use your programmer setup above to burn your own boot loader.
It's also quite likely that your sensor board is damaged as well.
From the Microchip datasheet:

You want something like this:
Adafruit Pre-programmed ATMega168p
Buy several, accidents happen!

If it's any consolation, I've put 30VDC onto a pin of a Arduino Leonardo, just being sloppy with leads on a table.  Strangely, it "worked" after that, though not the GPIO pin. But, it was rather hot and bothered about it and so untrustworthy thereafter; I mean it ran code, but you could fry an egg on it while it was doing so.  I replaced the chip on it and now it's fine.  It is entirely possible that only the AVR on your UNO is dead and with some work may be replaced.  If it's a DIP based UNO as pictured, this is comparatively easy.

Anyone who has experimented with electronics for any length of time has experience "smoke".  I've lost track of how many expensive chips I've fried due to one oversight or another.

Or an Adafruit Pre-programmed ATMega328P rather.


text:
The PCM libary won't work on an Arduino Nano
I'm using the PCM(http://highlowtech.org/?p=1963) library on the Arduino nano, I'm plugging the speaker(https://www.amazon.com/gp/product/B07WZP4QFK/ref=ox_sc_act_title_3?smid=A2O4FZXIRZDLHA&psc=1) into pin 11 and ground, but the example file won't work.

They don't say much about their wiring on that site.  And you haven't shown your wiring.  It seems likely that the code is fine but what you have attached to pin 11 isn't.  Description, diagram, pictures etc would be helpful.

added a diagram

I have a sense of what the answer will be when someone posts it.  It probably won't be me, unless on one else does.  For their sake, show the actual speaker, and in particular, any writing on it.  It may be useful for them in writing a more complete answer of what you need to do.

Ok I'll get a picture of the actual speaker

By the way, you have said pin 11 but you have drawn a diagram showing a connection to D3.

oh thats my mistake I'll fix that when I upload the photos

what brought you to the conclusion that the PCM library does not work on the nano?

You can see my wiring and I used the example sketch provided in the library, but no sound will come out. I have also tried it on the uno and it works.

test the pin ... replace the speaker with an LED

it didn't work, does that mean the board is faulty?

Perhaps.  If you were testing it with the LED (and resistor) instead of speaker using the example sketch, you might as well go a step further and test that same pin by substituting its number into the blink sketch.  I have some reservations about how you're hooking a 4 ohm speaker directly to an Arduino pin.  It's possible that doing this killed the pin.  Normally, I'd say likely, but that you "tried it on the uno and it works" casts some doubt on that theory.  It seems like a bad idea in any case, and until you know differently I'd avoid hooking it directly to your pins.

I guess the Nano had a sketch which was setting pin 11 HIGH (using SPI?) as you turned it on with a 4 Ohm speaker attached without any other resistance. It created a short circuit and damaged the pin's circuit.
Using tone() or the PCM library with a speaker connected without additional resistor doesn't damage the pin immediately because it is then HIGH only for very short moments, but it stresses the pin circuit too.
The linked page recommends to use direct speaker connection because it is much louder then with a resistor in series, but this is a wrong advice. It should recommend an amplifier module for example with LM386 IC.
A piezo speaker has higher resistance so it can be connected directly to Arduino pin, but a piezo sounds loud only in high frequencies so with the PCM library the sound is like whispering.

so what can I do?

the thing you gain if you gain nothing, is experience

is there really nothing I can do here, because I have more nano boards

use a 100 Ohm resistor in series with the speaker to test the library, but the sound will be weak. for good results use an amplifier module. shops have small amplifier modules for Arduino

ok, thank you! If this project didn't work out, my dad might never buy me parts again so this really helps

just to confirm, the board I used to test the speaker is dead so I can't use it anymore

And do you know any good tutorials?


text:
How do I transform data for a column to data for a row, for a led matrix
I have a 8x8 led matrix. I'm using LedControl.h library to control the matrix, which has 3 ways to light up the leds: setLed, setRow and setColumn. I've found that setColumn it's really slow, it's using setLed to print columns. With all my code, I can only print 3 times a second with setColumn. The function setRow is way faster, I'm guessing that the design of the matrix is allowing to print the rows directly. I can print more than 10 times a second with setRow, so I have to use it, since speed is crucial to my project. In my code, the data i have to print is stored in an array of 8 bytes. This is how it looks like when I use setColumn
for(int i = 7; i >= 0; i--)
    lc.setColumn(0, i, vector[i]);

i is the row to be printed, and vector[i] is a byte value, indicating which leds to be on or off. Column 0 is the left-most one, while column 7 is the right-most one, so i go from 7 to 0 to print from right to left, because that's what I have to do. My goal is to transform somehow to data in vector[i], to data that I can use it using setRow. So that's what I've done so far.
byte mask = 128, x;
for (int j = 0; j < 8; j++){
  x = 0;
  for(int p = 0; p < 8; p++){
    x = x | (valueVector[p] & mask);
    if (p != 7)
      x = x >> 1;
  }
  if (j != 7)
  mask = mask >> 1;
  lc.setRow(0, j, x);
}

Now i print the rows from row 0 to row 7, from top to bottom. Since I'm printing from top to bottom, this means I have to take the last bit of every column (last bit of every element in vector), and put it in a byte variable. I was thinking to make a byte mask = 128 (b1000000, do a AND logic between to mask and the vector value in order to take the bit I'm looking for, and then making a OR to put the bit in the x byte. After every mask operation, I shift the x variable to the right, in order to make space for the next bit. After i'm done with a row, I shift the mask to the right, in order to take the second bit from the value in the vector. The result I get, is quite odd, I can't explain it, it's not good at all. What I'm i doing wrong with the mask and shifts? I hope I explained well what I'm trying to do. If necessary, I can provide more information. Thanks.

please post the entire code

why can't you physically rotate the square matrix?

You use a mask 10000000. With each iteration of the outer loop the 1 in the mask is shifted to the right. 01000000 -> 00100000 -> 00010000. Let's say we are in the 2nd iteration the mask is 01000000. x = x | (valueVector[p] & mask); takes the 2nd bit (counted from left) and sets it at the 2nd position in the x value. But this position contains the bit from the last iteration (as you shifted it to this position).
Possible solution: (I have no compiler at hand. So hopefully it is correct. ;-)
byte x;

for ( int j=0; j<8; j++ )
{
   x = 0;

   for ( int p=0; p<8; p++ )
     x = x | ((valueVector[p] & (1 << p)) >> p);

   lc.setRow(0, j, x);
}


text:
Arduino fade to color change
I am making a fun LED Christmas tree project using this code:
// Source location \\adam\U_DRIVE\_BACKED_UP\_Documents\Electronics\XmasTree
#include <FastLED.h>
#define NUM_LEDS 102
#define DATA_PIN 6
CRGB leds[NUM_LEDS];
void setup() {
  Serial.begin(9600);
  Serial.println("Boot");
  // put your setup code here, to run once:
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  //  SetRandomLight;
  SetAllOff();
  delay(10); //Delay before getting going.
  BootUp();
  randomSeed(analogRead(0) + analogRead(1) + analogRead(2) + analogRead(3) + analogRead(4) + analogRead(5) + analogRead(6));
}

void loop() {
  // put your main code here, to run repeatedly:
  SingleDrift();
  FastLED.show();
  //delay(random(50));
}

void FadeAll(int x)
{
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i].subtractFromRGB(x);
  }
}

void SetRandomLight() {
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i].r = random(128);
    leds[i].g = random(128);
    leds[i].b = random(128);
    Serial.println(i);
  }
}

void SetAllOff()
{
  Serial.println("Blanking all.");
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i] = 0x000000;
    leds[i].r = 0;
    leds[i].g = 0;
    leds[i].b = 0;

    //Serial.println(i);
  }
  FastLED.show();
}

void SingleDrift() {
  int mini = 5;
  int maxi = 255;
  FastLED.setBrightness(maxi);
  for (int i = 0; i < NUM_LEDS; i++)
  {
    if (leds[i].r > 64) leds[i].r = leds[i].r - 8;
    if (leds[i].g > 64) leds[i].g = leds[i].g - 8;
    if (leds[i].b > 64) leds[i].b = leds[i].b - 8;

    int rnd = random(10);
    if (rnd == 1 && leds[i].r >= 2) leds[i].r = leds[i].r - 1;
    if (rnd == 2 && leds[i].g >= 2) leds[i].g = leds[i].g - 1;
    if (rnd == 3 && leds[i].b >= 2) leds[i].b = leds[i].b - 1;
    if (rnd == 4) leds[i].fadeToBlackBy(2);
    if (rnd == 5) leds[i].g++;
    //if (rnd == 6 && leds[i].g < 240) leds[i].g = leds[i].g + 1;
    //if (rnd == 7 && leds[i].b < 240) leds[i].b = leds[i].b + 1;
    if (leds[i].g < 2) leds[i].g = 2;
  }

  int i = random(NUM_LEDS);
  Serial.println(i);
  if (leds[i].r + leds[i].g + leds[i].b > 10) return; //If the LED is still bright, do not change it.
  if (random(100) > 80)
  {
    //Choose a colour
    int r = random(20);
    switch (r)
    {
      case 99:
        for (i = 0; i < NUM_LEDS; i++)
        {
          int x = leds[i].r;
          leds[i].r = leds[i].b;
          leds[i].b = x;
        }

      case 1:
      case 2:
      case 3:
        leds[i] = CRGB::Red;
        break;
      case 4:
      case 5:
      case 6:
        leds[i] = CRGB::Green;
        break;
      case 7:
        leds[i] = CRGB::Blue;
        break;
      case 8:
        leds[i].r = random(128, 255);
        leds[i].g = random(128, 255);
        leds[i].b = random(128, 255);
      case 9:
        leds[i] = CRGB::Yellow;
        break;
      case 10:
        leds[i] = CRGB::Crimson;
        break;
      case 12:
        leds[i] = CRGB::Aqua;
        break;
      case 13:
        leds[i] = CRGB::BlueViolet;
        break;
      case 14:
        leds[i] = CRGB::MidnightBlue;
        break;
      case 15:
        leds[i].setRGB( 255, 255, 255);
        break;
    }
  }
}

void BootUp()
{
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i].b = map(i, 0, NUM_LEDS, 0, 255);
    leds[i].r = map(i, NUM_LEDS, 0, 0, 255);
  }
  for (int pc = 0; pc < 100; pc++)
  {
    FastLED.setBrightness(pc);
    FastLED.show();
    delay(3);
  }
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i] = -leds[i];
    FastLED.show();
    delay(10);
  }

  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i].setRGB( 0, 10, 0);

    FastLED.show();
    delay(10);
  }
}

The LED cycle currently fades to green every time, so I would like to add different color fades. However, I could not figure out how to change the color/timing after poking around. Could someone please point me in the right direction for what I changes to the code I need to make?

why don't you look at the example code in the fastLED library? ... you should be able to find it in the example sketches in the arduino IDE

I think line 84 that keeps the leds green instead of going black. I think line 81 is there to create some kind of shimmer effect on some of the green leds and to skew the color to a bit more green. So I removed those. To prevent the leds from going to black instead of green, I added an if statement that stops any further fading out, if the total "brightness" is 16 or lower. I have no idea how this will look. You might have to tweak this 16-value a bit.
That's the best I could do without a full rewrite of the code.
void SingleDrift() {
  int mini = 5;
  int maxi = 255;
  FastLED.setBrightness(maxi);
  for (int i = 0; i < NUM_LEDS; i++)
  {
    if (leds[i].r > 64) leds[i].r = leds[i].r - 8;
    if (leds[i].g > 64) leds[i].g = leds[i].g - 8;
    if (leds[i].b > 64) leds[i].b = leds[i].b - 8;

    if ( (leds[i].r + leds[i].g + leds[i].b) > 16) // prevent fading to black
    {
      int rnd = random(10);
      if (rnd == 1 && leds[i].r >= 2) leds[i].r = leds[i].r - 1;
      if (rnd == 2 && leds[i].g >= 2) leds[i].g = leds[i].g - 1;
      if (rnd == 3 && leds[i].b >= 2) leds[i].b = leds[i].b - 1;
      if (rnd == 4) leds[i].fadeToBlackBy(2);
      //if (rnd == 5) leds[i].g++;
      //if (rnd == 6 && leds[i].g < 240) leds[i].g = leds[i].g + 1;
      //if (rnd == 7 && leds[i].b < 240) leds[i].b = leds[i].b + 1;
      //if (leds[i].g < 2) leds[i].g = 2; // I think this line kept the leds green
    }
  }
  ...

That code is a bit of a mess. It has some code that will never execute, as well as very confusing structure.
If it were me I would throw away that code and start over with code that does some other animation. You won't break anything, so play.
As to the code you posted:
It looks to me like the first for loop that cycles through all the LEDs is set to first fade all the LEDs down towards 0 brightness by 8 while their value is > 64.
After the global fade, it then uses a random number 0-9 to decide what to do next for each LED.

If the random value is 1, 2, or 3, it reduces the red, green, or blue channels by 1.
If the random value is 4, it drives the current LED to black.
If the random value is 5, it increases the green channel of the current LED by 1.
finally, it sets the green channel of the current LED back to 2 if it drops below 2. That means that every LED will end up with flicker with a dim green color unless the next section changes that LED's color to something different.

I added "**this" comments to the lines that drive the LEDs towards green.
  for (int i = 0; i < NUM_LEDS; i++)
  {
    if (leds[i].r > 64) leds[i].r = leds[i].r - 8;
    if (leds[i].g > 64) leds[i].g = leds[i].g - 8;
    if (leds[i].b > 64) leds[i].b = leds[i].b - 8;

    int rnd = random(10);
    if (rnd == 1 && leds[i].r >= 2) leds[i].r = leds[i].r - 1;
    if (rnd == 2 && leds[i].g >= 2) leds[i].g = leds[i].g - 1;
    if (rnd == 3 && leds[i].b >= 2) leds[i].b = leds[i].b - 1;
    if (rnd == 4) leds[i].fadeToBlackBy(2);
    if (rnd == 5) leds[i].g++;  //**This will tend to make this LED flicker green.
    //if (rnd == 6 && leds[i].g < 240) leds[i].g = leds[i].g + 1;
    //if (rnd == 7 && leds[i].b < 240) leds[i].b = leds[i].b + 1;
    if (leds[i].g < 2) leds[i].g = 2; //**This will make each LED stop at dim green.
  }

If you want the LEDs to end up at some color other than green, you might want to change those last lines of the first for loop You could change that first section to something like this:
  for (int i = 0; i < NUM_LEDS; i++)
  {
    if (leds[i].r > 64) leds[i].r = leds[i].r - 8;
    if (leds[i].g > 64) leds[i].g = leds[i].g - 8;
    if (leds[i].b > 64) leds[i].b = leds[i].b - 8;

    int rnd = random(11);
    if (rnd == 1 && leds[i].r >= 2) leds[i].r = leds[i].r - 1;
    if (rnd == 2 && leds[i].g >= 2) leds[i].g = leds[i].g - 1;
    if (rnd == 3 && leds[i].b >= 2) leds[i].b = leds[i].b - 1;
    if (rnd == 4) leds[i].fadeToBlackBy(2);

    if (rnd == 5) leds[i].g++;  //**This will tend to make this LED flicker green.
    if (rnd == 6) leds[i].r++;  //**This will tend to make this LED flicker red.
    if (rnd == 7) leds[i].b++;  //**This will tend to make this LED flicker blue.

    if (rnd == 8) && (leds[i].g < 2) leds[i].g = 2; //**This will make the LED go dim green
    if (rnd == 9) && (leds[i].r < 2) leds[i].r = 2; //**This will make the LED go dim red
    if (rnd == 10) && (leds[i].b < 2) leds[i].b = 2; //**This will make the LED go dim blue
  }

Then it picks one random LED, and 20% of the time, does more random stuff to the color of that LED if it is dim enough. It uses a random value from 0-19 to decide what to do in the next switch statement. The first case is case 99:, which can never execute because the random value will never be greater than 19. For other values, it forces that LED to be a bright primary color, or maybe white, or maybe a color with random RGB values ranging from 128 to 255.


text:
Coding of arduino and ZEDF9P GNSS module
I have ZEDF9P AND ARDUINO and connected them Via UART.
I have written program which is showing that NMEA strings are coming in arduino and arduino is filtering out if GPS jamming is taking place. Now once GPS signals are coming LCD show GPS:ok. oNCE GPS is jammed it is giving output as GPS:INVALID
.During this time it converts to GLONASS. I want to write GLONASS ENABLED on LCD once I get signals. But my problem is that I am unable to write code for the time once GLONASS is enabled. I want that once I switch on another system The system name should come on LCD automatically but I don't know where the code is wrong. Kindly help me with the code. (I am doing it with NEO6M as well so kindly ignore baudrate)
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// Choose two Arduino pins to use for software serial
 int RXPin = 6;
 int TXPin = 7;

//Default baud of NEO-6M is 9600
int GPSBaud = 9600;

// Create a software serial port called "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);

#define GPSENABLE 2
byte GPSBuffer[82];
byte GPSIndex=0;
#define MAX_NMEA 200 // Max characters in NMEA Sentence to accumulate

float gpsSpeed;
void processGGA(char *nmea)
{
// TODO
}
void processGLL(char *nmea)
{
// TODO
}
void processRMC(char *nmea)
{
char *token = strtok(nmea, ",");  // Split NMEA string with ',' delimiter
if (token) // Is Token NULL?
{
int i;
for(i=0; i<7; i++) // Process Fields, truncated
{
 token = strtok(NULL, (i < 11) ? "," : "*"); // delimit based on expected termination
  if (!token) break; // NULL Token
  if (i == 1) // Field 1 Fix
  {
  lcd.clear();
    lcd.setCursor(0,0);
    if (token[0] == 'A')
     { lcd.print("GPS:OK");
    digitalWrite(9, HIGH);
    digitalWrite(8, LOW);}
    else if (token[0] == 'V')
      {delay(100);
        lcd.print("GPS:INVALID");
    for (int i = 0; i <= 100; i++) {
  digitalWrite(8, HIGH);
  delay(100);
  digitalWrite(8, LOW);
  delay(100);
  };
  uint8_t ubx_cfg_gnss[] = {
0xB5,0x62,0x06,0x3E,0x2C,0x00, // UBX-CFG-GNSS
0x00,0x00,0x10,0x05, // 16-Channels, 5-Constellations in list
0x00,0x08,0x10,0x00,0x01,0x00,0x01,0x01, // GPS
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01, // SBAS
0x03,0x08,0x10,0x00,0x00,0x00,0x01,0x01, // GALILEO
0x05,0x00,0x03,0x00,0x00,0x00,0x01,0x01, // BEIDOU
0x06,0x08,0x0E,0x00,0x00,0x00,0x01,0x01, // GLONASS
0xE8,0xFE }; // compute checksum
 Serial.write(ubx_cfg_gnss,sizeof(ubx_cfg_gnss));

      }
    else
      lcd.print("GPS:UNKNOWN");
  }
  if (i == 6) // Field 6 Speed Knots (Basically a Nautical Mile, or One Arc Minute)
   { gpsSpeed = atof(token) / (3600.0 / 1852.0); // Pull as a floating point (in knots, convert to
  m/s)
  }
  }

  }
  }
  void ProcessGPSLine()
  {
     if ((GPSBuffer[1] == 'G') && (GPSBuffer[2] == 'L') && (GPSBuffer[3] == 'G') && (GPSBuffer[4] ==
        'G') && (GPSBuffer[5] == 'A'))
   {
     lcd.print("GLGGA Detected!");
      }

    }
    void readSerialGPS()
   {
     static char receivedGPSChars[MAX_NMEA]; // buffer for received GPS data
   static int ndx = 0; // buffer index
    static boolean newGPSData = false;

    while((gpsSerial.available() > 0) && (newGPSData == false)) // Drop out at each complete line
  {
   char rc = gpsSerial.read();

Serial.write(rc); // Feed byte from GPS to the console

if (rc != '\r') { // Terminate line, CR,LF pair
  if (rc == '$') // Resync on leading '$'
    ndx = 0;
  if (rc != '\n') // Don't copy LF
    receivedGPSChars[ndx++] = rc;
  if (ndx >= MAX_NMEA) // Constrain length
    ndx = MAX_NMEA - 1;
  }
   else { // '\r'
  receivedGPSChars[ndx] = '\0'; // Terminate the string
  ndx = 0;
  newGPSData = true;
   }
 } // while
 if (newGPSData) // One new line available
 {
   static boolean gpsAlert = false;

if (gpsAlert == false)
{
  lcd.setCursor(0,0);
  lcd.print("GPS:ENABLED");

  gpsAlert = true;
}
 if (strncmp(receivedGPSChars, "$GPGGA", 6) == 0)
  processGGA(receivedGPSChars);
else if (strncmp(receivedGPSChars, "$GPGLL", 6) == 0)
  processGLL(receivedGPSChars);
else if (strncmp(receivedGPSChars, "$GPRMC", 6) == 0)
  processRMC(receivedGPSChars);

newGPSData = false;
 }
 }
  void setup()
 {
 // Start the Arduino hardware serial port at 9600 baud
 Serial.begin(9600);
 // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

  pinMode(9, OUTPUT);
  // Start the software serial port at the GPS's default baud
  gpsSerial.begin(GPSBaud);
  }
  void loop()
  {
     readSerialGPS(); // Consume data, process sentences
  }

Your question is very unclear.  Please edit the question and clearly state what you are attempting to do, what is happening, what you expect, what you are getting.  As it is, there is little anyone can do to help you.

I have edited it.


text:
SSD1306 shows static when I try to display an XBM image
This is my circuit.

This is the code.
    #include "U8glib.h" // include the universal graphcs library

    U8GLIB_SSD1306_128X64 u8g(12, 11, 10, 9, 8);  // initialise a u8g display object

    const uint8_t flux_xbm[] PROGMEM = {
       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x56, 0x6D, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xEF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5F, 0x69, 0x92,
  0x6E, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xC1, 0xFF, 0xFE, 0xFF, 0xFF,
  0xFF, 0x3F, 0x80, 0x01, 0xF5, 0x7E, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, 0xC2,
  0x3F, 0x21, 0xF4, 0xFF, 0xFF, 0xFF, 0x36, 0x6C, 0xBE, 0x7F, 0xFC, 0xFF,
  0xFF, 0xFF, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x86, 0x61,
  0xDE, 0x4F, 0xFE, 0xFF, 0xFF, 0xFB, 0x64, 0xE4, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x20, 0x04, 0xFC, 0x63, 0xFA, 0xFF, 0xFF, 0xFD, 0x24, 0xCD,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x95, 0xA9, 0x7F, 0x08, 0xFC, 0xFF,
  0xFF, 0xF7, 0x27, 0xDA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x00, 0x00,
  0x04, 0x50, 0xFC, 0xFF, 0xFF, 0xFF, 0xD9, 0xC9, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x10, 0x01, 0x21, 0x90, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x02, 0x84, 0x08, 0x02, 0xFC, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x04, 0x00,
  0x00, 0x28, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
  0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
  0x00, 0x00, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x00, 0x00, 0x80, 0x07, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xC0, 0x05, 0xF8, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00,
  0xB8, 0x0F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x00, 0xE0, 0xFB, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0xF0, 0xFF, 0x0F, 0xF8, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0xBC,
  0xFE, 0x1F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x00, 0xDF, 0x49, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x4B, 0xA8, 0x1F, 0xF8, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x00,
  0x40, 0x7A, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x80, 0x00, 0xA0, 0xFD, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x40, 0x00, 0x00, 0x7A, 0xFC, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00,
  0xA2, 0xF5, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x70, 0x00, 0x00, 0xF9, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x30, 0x00, 0xA0, 0xFC, 0xFD, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00,
  0x00, 0xE2, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x10, 0x00, 0x00, 0xD8, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xD2, 0xB7, 0xFB, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xD0, 0x02,
  0x60, 0x5F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x08, 0x35, 0xF4, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x08, 0xDC, 0xD4, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x20, 0x36,
  0x16, 0x9F, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x1F, 0x42, 0xEC, 0xB7, 0xAB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xA0, 0x67, 0xAB, 0xBC, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x40, 0x66,
  0xB4, 0x6A, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x34, 0x49, 0x06, 0x95, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x0B, 0x20, 0x5C, 0x0A, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1D, 0x10,
  0x5C, 0xE4, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0x1E, 0x08, 0xB8, 0xD5, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4A, 0x15, 0x64, 0x29, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x0E, 0x10,
  0xAA, 0x91, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x7F, 0x9E, 0x00, 0xB4, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x0F, 0x12, 0xED, 0x6A, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1F, 0x80,
  0x7E, 0x99, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x9F, 0x5F, 0x14, 0xBA, 0xD4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0x5F, 0x41, 0xE4, 0x69, 0xFE, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, 0xBF, 0x05,
  0xAA, 0x7B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0x3F, 0x7F, 0xD8, 0xF9, 0xD5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0x2A, 0xFA, 0xA8, 0xFD, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x4D,
  0x6A, 0xB7, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0x27, 0x90, 0xDA, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0xFF, 0xFE, 0xF8, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F,
  0x6A, 0x7F, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xF7, 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x43, 0xD8, 0x7D, 0xFF, 0xDF,
  0xBF, 0x9B, 0xEF, 0xFF, 0x5F, 0xAF, 0xAF, 0xAF, 0xAF, 0xAF, 0xBF, 0x43,
  0x88, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFE, 0xFB, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xEF, 0x41, 0xA8, 0xFF, 0x5D, 0x77, 0x9F, 0xBF, 0xE6, 0x77,
  0xFF, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xF7, 0xEF, 0xFE, 0xEF, 0xFF, 0xFF,
  0xFF, 0xDB, 0xBF, 0xF7
    };

    void setup(void) {
    }

    void loop(void) {
      u8g.drawXBMP( 0, 0, 128, 64, flux_xbm); // send the xbm image to the display, specifying position and size
      while (1==1) {} // set the loop to only run once
    }

The image that it holds in XBM is this.

The output is this.

What is it that I am doing wrong?
Edit 1- As reported by user timemage. The xbm array was 64x128 instead of 128x64 I have changed the image added a more simpler one but that still does not solve the problem,

The image you included in the question is JPEG formatted, colored, 1920x1080 pixels and 155KB in size. How is that supposed to work with a 32KB Arduino and a 128x64 monochrome display? How did you convert the image to the format you put in your code? Does it work with much simpler and/or much smaller images?

@StarCat If you see the size of the image I have input into the code in an array of type uint8_t called flux_xbm it would be 164x64. I used these two online apps https://image.online-convert.com/convert-to-bmp to convert to a grayscale 128x64 Bitmap and then used https://www.online-utility.org/image/convert/to/XBM to convert to a hex 2-D array.

Did you try this conversion tool with simpler monochrome images? Are you able to display other things besides XBM bitmaps i.e. is the display initialized correctly and are you able to control it from your code using the U8glib?

@StarCat Yeah. I have used the same OLED display to depict three waveforms taken from 3 different sensors simul0taneously and individually displaying an image is the problem now. I was thinking about adding a menu connected to a rotary encoder or something to choose which waveform you want to see and add an image or something while the hardware calibrated.

@StarCat but as of now. Wrt the  display plus  this image no sensor is attached to the OLED and this is the code which I have used .

I'm not sure exactly what I'd do with this information, but: is the configuration of pixels you get the same each time you attempt to display the image or is the dot pattern stable?  What happens if you try to draw a solid rectangle over top of this static, does it do that successfully?

NOTE: This refers to an problem in the initial posting.  The question has since been edited.  This may be deleted later.

One problem, perhaps the problem, is that your given image appears to be 64x128 rather than 128x64:

That said, I'm not sure exactly why the screen is showing precisely what it does.
When you do get this showing in the correct resolution, I expect you'll be a bit unimpressed with the result though.

thank you for pointing that out. It was a fault at my end. I have rectified it. But still the output is the same static I see. Should I change the CBM hex array in the question? or what is the procedure?

the problem is still no resolved. I tried other images. Everything from the drivers own constructors is working just these images are being difficult to show.

I misread the your first comment above.  I don't know for sure what the correct procedure is, but I would say since the image dimensions and distortion aren't your primary problem, then yes, it makes sense for you to update your question with the corrected image array.  You may want to add a note just saying that a previous edit had incorrect image data but it wasn't the principal problem.  I may make a similar note in this answer or I may delete it. I will have to think about that.


text:
Why I can't exit this while loop by reading from the Serial?
I'm trying to work with the FastLed libraries and i'm controlling a Led Stip via a WEMOS D1 MINI based on the ESP8266, what I'm trying to achieve is to jump from fastled animation to another one..those animations are inside a While loop as shown in the code, so , i thought to just read again from the serial in order to change an integer to exit those while loop, but for some reason is not working as expected. Anyone can help me to uderstand?
CRGB leds[NUM_LEDS];
int incomingByte = 0;
int exit = 0;
void setup() {
    Serial.begin(115200);
    delay( 1000 );
    FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
}

void loop()
{
    while (Serial.available()>0)
    {
      Serial.write("Serial.available");
       incomingByte = Serial.read();

       switch (incomingByte)
        {
          case '1':
            GreenYellow();
            break;

          case '2':
            Sparkle();
            break;
        }
    }
}

void Sparkle() {
    while(exit = 0){
        int Pixel = random(NUM_LEDS);
        setPixel(Pixel,random(255),random(255),random(255));
        FastLED.show();
        delay(50);
        setPixel(Pixel,0,0,0);
        if(Serial.available()>0){
            incomingByte = Serial.read();
            if(incomingByte != '2'){
                exit = 1;
            }
        }
    }
  }
}
void GreenYellow()
{
  for(int x =0; x< NUM_LEDS/2; x++){
    leds[x]= CRGB::Green;
  }

  for(int x =NUM_LEDS/2; x< NUM_LEDS; x++){
    leds[x]= CRGB::Yellow;
  }
  FastLED.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue)
{
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
   FastLED.show();
}
void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}

Bonus question: I read that there is no thread programming on the ESP2866 via the Arduino IDE, am I right?

The problem is that you check inside the two functions Sparkle and GreenYellow for another serial byte. Then when it's unequal, you move back to the while loop where you wait for the next serial byte, but I think you need to use the same one to decide to go to the correct function instead of waiting for a next serial byte.
Probably the easiest is to not read serial in the while loop but check the incomingByte global variable  (containing the last read byte, and e.g. 1 initially), and ONLY in the two functions set that global variable. Then, when returning to the while loop, you check that global variable to jump to the correct function.
So you make a setup function that sets the global variable to 1 (or you do it in the initialization itself):
int incomingByte = 1; // Start with GreenYellow

Then, in the loop function, you use:
void loop()
{
       switch (incomingByte)
        {
          case '1':
            GreenYellow();
            break;

          case '2':
            Sparkle();
            break;
        }
}

If you don't want to start in either one, then use 3 values (0, 1, 2), and ONLY in the loop function read the Serial byte, but don't read it in the functions.
This way it's a bit more cleaner as it separates the LED functionality with the Serial functionality.
The result (using the last method), results in the following code (compiles, not checked).
Comments:

Used an enumeration for the mode

Split functionality of serial data, processing the mode and RGB routines

I added some initialization lines (i.e. constants) to make it compile.
#include <FastLED.h>

#define NUM_LEDS 60 // number of led present in your strip
#define LED_PIN 6
#define BRIGHTNESS 100

enum EMode
{
  ModeNone,
  ModeSparkle,
  ModeGreenYellow
};

CRGB leds[NUM_LEDS];
EMode mode;

void ParseSerialData();
void ProcessMode();
void GreenYellow();
void Sparkle();
void setPixel(int Pixel, byte red, byte green, byte blue);

void setup()
{
    Serial.begin(115200);
    delay( 1000 );
    FastLED.addLeds<WS2811, LED_PIN, EOrder::RGB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
    FastLED.setBrightness(  BRIGHTNESS );
    mode = EMode::ModeNone;
}

void loop()
{
  ParseSerialData();
  ProcessMode();
}

void ParseSerialData()
{
  while (Serial.available() > 0)
  {
    Serial.write("Serial.available");
    char incomingByte = Serial.read();

    switch (incomingByte)
    {
    case '1':
      mode = EMode::ModeGreenYellow;
      break;

    case '2':
      mode = EMode::ModeSparkle;
      break;

    default:
      // Ignore
      break;
    }
  }
}

void ProcessMode()
{
  switch (mode)
  {
  case EMode::ModeNone:
    // Do nothing
    break;

  case EMode::ModeGreenYellow:
    GreenYellow();
    break;

  case EMode::ModeSparkle:
    Sparkle();
    break;

  default:
    // Ignore
    break;
  }
}

void Sparkle()
{
    int Pixel = random(NUM_LEDS);
    setPixel(Pixel,random(255),random(255),random(255));
    FastLED.show();
    delay(50);
    setPixel(Pixel,0,0,0);
}

void GreenYellow()
{
  for(int x =0; x< NUM_LEDS/2; x++)
  {
    leds[x]= CRGB::Green;
  }

  for(int x =NUM_LEDS/2; x< NUM_LEDS; x++)
  {
    leds[x]= CRGB::Yellow;
  }
  FastLED.show();
}

void setPixel(int Pixel, byte red, byte green, byte blue)
{
   leds[Pixel].r = red;
   leds[Pixel].g = green;
   leds[Pixel].b = blue;
   FastLED.show();
}

void setAll(byte red, byte green, byte blue)
{
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  FastLED.show();
}

thanks for the replay, can you modify my piece of code? I'm have difficulties to understand your solution, so maybe reading the code will help. Thanks.

I'd go the other way. Leave all the serial reads inside the loop function. Remove the while loop inside the Sparkle function. Store the current mode that was selected in a variable. Then, in loop, call the function based on the current mode.

@Gerben Me too, but the first was the most 'easiest', not the most clean solution.

I tried to modify the code (it compiles)... I removed the exit code and tried to clean up things.


text:
Arduino nano IoT antenna broke
I have an Arduino Nano 33 IoT and have used it for a good time now. I was using it when the antenna snapped off. Is there any way to fix it by either an external antenna or some other method? I tried to just hold the antenna in place as I tried to connect to wifi but it failed to connect.

Please show some good pictures of the damage. You can edit your question to include them

The problem that I see in the photo is that the pads from the PCB are pulled off and attached to the antenna. So now there is nothing to solder the antenna back to.
While it's possible to rework this with some solder rework tools, I suspect you don't have those.  There is really not much else you can do but replace the Nano with a new one.  You should still be able to use this one for an application that doesn't need WiFi.
It looks like the two active leads (the two in the upper right-hand side of the green module may be those) are still intact.  If you have a small tip soldering iron and a steady hand you may be able to put a tiny drop of solder on both of them and then resolder the antenna to them.  You could support the antenna with some silicone caulk or other non-conductive adhesive after you get it attached.
Keep in mind, that this is tricky to solder by hand but there is little to lose since that part of the module is not non-functional anyway.

So the 2 pads that got ripped off don't matter much other than support?

That's what it looks like but, as you now know, supporting the antenna is important!

Okay, I will try that.

It is still possible to get work. I see the copper pads have been pulled off so you need to use extra amount of solder and hopefully it attaches to the remained copper wire.
My case is even worse because the antenna is lost, so I have to remade one.

And it works.


text:
using a digital pin on node mcu as an analog
i want to use volte and current sensors (ZMPT101B and ACS712) on node MCU these sensors are analog but node mcu has on analog pin can i use digital D0 pin for voltage sensor?

yes, but the resolution is one bit.

@dandavis I was about to respond with NO but yours is better.

@dandavis lol ... your comment stirred a few memory cells ... more than one bit resolution is possible ... google 1-bit ADC

@mohamedmansour you can use one digital input if you use some external circuitry ... monitor the output of a comparator ... the two comparator inputs would be, the voltage input and an programmable reference voltage ... for example, suppose full scale is 6 V and you have an input of 4 V ... first you compare the input to 3 V and record  1 ... next compare to 3 + 1.5 V and record a 0 ... next you roll back the 1.5 V and compare to 3 + 0.75 V and record a 1  ... next compare 3 + 0.75 + 0.375 V and record a 0  ....... so far the digital data is 1010 .... you can keep going for more bits

use an I2C ADC module. they have usualy at least 4 ADC pins.


text:
How to stop the relay after it is getting on and let the sensor get the result
I want to provide a delay in the following iteration reading so that the sensor can read the condition after the pump starts.
void loop() {
  //-------------Fungsi Read sensor-----------
  // sensorAll();

  hasilec = (ppmcensor - inputec);
  ph = (phcensor - inputph);

  //  hasilec = random(-200, 0) / 100.0;
  //  ph = random(-200, 200) / 100.0;

  //  ph = -180/100.0;
  //  hasilec = -1.2;

  unsigned long now = millis();

  Serial.print("pH    ");
  Serial.print(ph);
  Serial.print("  ");
  Serial.print("EC ");
  Serial.print(hasilec);
  Serial.println("");
  Serial.print(ph); Serial.print(" ");
  Serial.print(hasilec); Serial.print(" ");
  Serial.println(" ");

  //  delay (500000);

  fuzzy->setInput(2, hasilec);
  fuzzy->setInput(1, ph);
  fuzzy->fuzzify();

  float pompa01 = fuzzy->defuzzify(1);//pHDOWN
  float pompa02 = fuzzy->defuzzify(2);//pHUP
  float pompa03 = fuzzy->defuzzify(3);//ABMIX

  Serial.println("Result= ");
  Serial.println("");
  Serial.print(" Pompa1 pHDOWN: ");
  Serial.println(pompa01);
  Serial.print(" pompa2 phUP  : ");
  Serial.println(pompa02);
  Serial.print(" pompa3 ABMIX : ");
  Serial.println(pompa03);
  Serial.println("");
  Serial.println("");
  Serial.println("");

  delay (2000);

  long int pompa1 = pompa01 * 1000;
  long int pompa2 = pompa02 * 1000;
  long int pompa3 = pompa03 * 1000;

  pump_periods[0] = pompa1; //PHdown
  pump_periods[1] = pompa2; //PHup
  pump_periods[2] = pompa3; //ABMIX

  for (int i = 0; i < jml_pump; i++) {
    if (now - pump_last_actuations[i] >= pump_periods[i]) {
      pump_states[i] = (pump_states[i] == LOW) ? HIGH : LOW;
      digitalWrite(pump_pins[i], pump_states[i]);
      pump_last_actuations[i] = now;
    }
  }
}

If I put the delay after millis iteration it causes the pump to only turn on based on the delay, not the timer millis. What should I do?

Sorry, I don't understand your question. What exactly keeps looping? The loop() function always loops, that is what is is meant for. Or what do you mean? And what does "not making space for my environment getting stabilize" mean?

why are you using fuzzy logic?

I mean let the wave pump mix all Ph and AB mix, and fet stabilize on set point, because im trying using fuzzy for it

sorry, i have no idea what you said

Please [edit] you question and provide some context. If would help if you translate your variables and texts, too.

You can't put a large delay() anywhere in the loop without messing up the millis() timing you use in your for loop when pump_periods[i] are smaller than your delay. Please explain what needs to wait for what; what sensor reads what condition; what makes the pump start and where in the code that happens.

i want to wait a couple of minute for let the liquid mixed after im adding some pH up or down and AB-mix, the sensor read a ppm and pH and i got the value of them,the pump start base on my fuzzy rules.

If all the pumps have to work for pump_periods[i] time on every loop, and you will have a long delay() anyway, you could replace the for loop with:
for (int i = 0; i < jml_pump; i++) { // For every pump:
  digitalWrite(pump_pins[i], 1);     // Start pump i
  delay(pump_periods[i]);            // Wait for pump_periods[i] ms
  digitalWrite(pump_pins[i], 0);     // Stop pump i
}
delay(120000);                       // Wait 2 minutes until mixed

This will block the loop, but you will have a long delay anyway. The pumps will work sequentially, and not at the same time.
Is that what you want?


text:
Nextion Display not getting updated data
I am using an Arduino Mega to display the readings of 4 pots on a Nextion Display as well as store them on an SD Card with a time stamp. I keep getting:
recvRetCommandFinished err
on the serial monitor and the display does not update with time.
I have attached my code below:
#include "Nextion.h"
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday","Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// Declare your Nextion objects - Example (page id = 0, component id = 1, component name = "b0")
NexText tDate = NexText(0, 1, "tDate");
NexText tPot1 = NexText(0, 6, "tPot1");
NexText tPot2 = NexText(0,7, "tPot2");
NexText tPot3 = NexText(0, 8, "tPot3");
NexText tPot4 = NexText(0, 9, "tPot4");

File myFile;

void setup(void) {
  Serial1.begin(9600);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2016, 11, 19, 19, 45, 0));   // <----------------------SET TIME AND DATE: YYYY,MM,DD,HH,MM,SS
  }

  delay(100);

  // You might need to change NexConfig.h file in your ITEADLIB_Arduino_Nextion folder
  // Set the baudrate which is for debug and communicate with Nextion screen
  nexInit();

  SPI.begin();

  int pot1 = 0;
  int pot2 = 0;
  int pot3 = 0;
  int pot4 = 0;

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");
  if (!SD.begin(53)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
}

void loop(void) {
  myFile = SD.open("testpot1.csv", FILE_WRITE);
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to testpot1.txt...");

    while(1) {
      DateTime now = rtc.now();
      myFile = SD.open("testpot1.csv ", FILE_WRITE);
      int pot1 = analogRead(A0);
      int pot2 = analogRead(A1);
      int pot3 = analogRead(A2);
      int pot4 = analogRead(A3);
      myFile.print(now.hour());
      myFile.print(":");
      myFile.print(now.minute());
      myFile.print(",");

      myFile.println(pot1);
      myFile.println(",");
      tPot1.setText(pot1);

      myFile.println(pot2);
      myFile.println(",");
      tPot2.setText(pot2);

      myFile.println(pot3);
      myFile.println(",");
      tPot3.setText(pot3);

      myFile.println(pot4);
      myFile.println(",");
      tPot4.setText(pot4);

      Serial.print(pot1);
      Serial.print(",");
      Serial.print(pot2);
      Serial.print(",");
      Serial.print(pot3);
      Serial.print(",");
      Serial.print(pot4);
      Serial.print(",");

      delay(2000);
      myFile.close();
    }
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

How do I get the pot values on my display? Any help or tips would be helpful!

I changed the text components to number components on the Nextion GUI Editor. That worked as I primarily wanted to show numerical readings from the pot.

recvRetCommandFinished err means something is wrong with the serial communication between the Arduino and the Nextion display; it is what recvRetCommandFinished() prints when there is an error.
Check if you are using the right pins (TX1 and RX1 for Serial1) for the serial connection to the display, the actual connections you made (RX1 to TX, TX1 to RX), the baud rate, and the cable.

Thanks. This worked and also, I changed the text components to number components on the Nextion GUI Editor.

Great! Please accept the answer (if you accept the answer), so the question doesn't stay open.


text:
Why is it I need transistors and resistors to turn a DC motor with an Arduino but I can connect it directly to a battery?
As the question says: I'm building a circuit to run a DC motor whenever motion is detected by a motion sensor. Now as this image suggests:

I need a diode + resistor + transistor to get this thing to turn with an Arduino, but I can do the same with a battery and connecting each of the terminals to the + and - of the battery. I understand this might be for speed control? Or turning the motor different ways?
But if I just need it to spin at 100%, would all this be needed?
I tried hooking up the motor directly with a resistor to the 5 V + GND of the board while it was on, but no joy. I am (obviously) doing something wrong but I want to use this problem as a way to learn circuits better.

For the resistor: https://electronics.stackexchange.com/questions/122312/why-is-a-resistor-put-before-the-gate-of-a-transistor ; the diode is a flyback diode, also for protection

Please draw a "real" schematic of this circuit, and do some research on the matter. Keywords are "voltage", "current", "inductive load", and/or "drive DC motor from microcontroller". Look up the documentations of motor and AVR, and compare needed current and provided current.

because the io pin is not a power supply. it can provide only limited current. it is for TTL logic state

One word: impedance.

Too get the maximum out your motor should use a MOSFET, you will eliminate t.7 or 1.4 volt collector emitter voltage drop.  If the MOSFET is logic level and avanchlated you do not need the diode. Although probably not necessary I would put a 50 ohm resistor in the gate circuit. As previously mentioned use a seperate power supply for the motor, the Arduino is not a power supply.

If you want the motor to rotate continuously, without using PWM, and without switching the motor on and off from the Arduino, you can connect the motor straight to 5 V and ground. If you then add a large resistor like you tried, not enough current will pass through the motor to rotate it; in the image the resistor is there to limit the current into the transistor, not to limit the current into the motor.
You can't connect a motor directly to an IO pin because an IO pin can only deliver about 20 mA, which isn't enough for a motor. So, if you want to control a motor from an IO pin, you need a transistor as a switch and you operate that transistor from the IO pin. The transistor does the heavy lifting and switches the larger current the motor needs. The resistor is there to limit the current into the transistor.
Note that it is generally better to wire a motor directly to a 5 V power source and not to the 5 V pin on the Arduino, as the current you can get from that pin is limited; it will do for small motors, though, if they don't pull more than, let's be safe, about 300 mA. In other words, it is preferred not to use the Arduino 5 V pin as a power source, but to use a 5 V power source directly.
Also note that you always need the diode across the motor, however you wire it. It keeps inductive spikes away from the rest of your circuit.


text:
detecting signal coming from another motion sensor that triggers camera's shutter
I have a motion sensor (used for camera trapping) that sends a signal to the camera to trigger the shutter. I am trying to use Arduino to turn on lights for 10 seconds by getting the signal from the motion sensor. I know there are ways to use motion sensor that can be used with Arduino. However, I need to know how I can detect a signal coming from the sensor to feed it to Arduino. I have tried connecting the cable from the sensor to A0, wrote a simple code to print the value of A0 but the serial monitor of Arduino shows nothing.

what motion sensor?

I guess the motion sensor is some third party product, which is not designed for the use with Arduinos. In that case you need to find out, what voltage levels and signal type the sensor uses. For the Uno the voltage has to be in the range of 5V. The type is most probable a digital signal. You need to find out, if it is active low or active high (active meaning the state, where the sensor is triggered). Amd whem the serial monitor doesm't show anything, then either your code or the setting of the serial monitor is wrong. Please look into this and then give more information in your question

What motion sensor? What code?

Thanks for the information. Here is the sensor:
Scout Trail Monitor
This a very advanced motion sensor which uses modulated IR beam and the only way for me to detect any signal (without taking the expensive equipment in parts) is to see what is coming from 3.5 mm shutter cable.
The very basic code to print:
    Serial.begin(9600);}

 void loop() {
  Serial.print("Value: ");
  Serial.println(analogRead(0));
  delay(1000);
}```

Please no code in the comments. You need to add all this information to your question by editing it. Also: you are trying to read from pin 0, which is the Serial interface. You need to read from A0

That's correct. I used A0.

Also, with multimeter set to 20k resistance, I can see some increase to about 16k

If you use the HC-SR501 motion sensor, see this tutorial

Almost all camera shutter cables are simple switches. They are an open circuit until you want to press the shutter, and then the switch closes. There is no voltage out of the shutter release, and so nothing for an analog pin to detect.
Many cameras have a shutter half-press switch that activates the light meter/auto-focus, and then a second switch that closes the shutter.
For a simple RCA plug shutter release or mono 3.5 mm plug shutter release, it's probably just a simple single pole switch. Wire one wire from the shutter release to a digital pin, and the other wire to ground. Set the pin to INPUT_PULLUP, and wait for it to go LOW. When it goes LOW the shutter is being pressed.
Be aware that a modulated IR shutter trap will be a little slow. It probably won't catch subjects like birds flying at high speed until the bird has moved past the point where the trap is pointed. For that you would want a laser beam and a fast phototransistor. Those can be fast enough and accurate enough to measure the speed of a bullet. (Although you need to read port registers directly in order to get fast enough response for that. DigitalRead() is too slow.)

Thanks for the great advise which helped me to detect the signal. Now I can see the output changes from 1 to 0 when. That's exactly what I needed.

If I've answered your question then you should accept my answer. (click the check mark.)

Sorry I am typing this here coz I don't have enough rep to comment. Anywho, most of the motion sensors involve PIR tech, so the best way is to connect your PIR Signal pin from your sensor to any analog pin of your arduino and test the kind of signal you're getting when the environment is idle and when movement is detected, Keep in mind of the region that the sensor covers too (ROI). That will tell you some things,

If the sensor works or not.
If the sensor value is analog or digital
If the sensor is active high or low
Trial and error on the actual ROI

After all that you can write your code around it.


text:
Speed data logging using arduino and GPS module
I am using a Quectel L80-R GPS Module coupled with an Arduino UNO to read and log my car's coordinates and speed. I am currently using TinyGPS++ library which works okay. It does spell out coordinates and speed but with some inaccuracies and delays. After some literature review I realized that NeoGPS library might be a better option. I found a thread over stackexchange where a code block is provided written by slash-dev who most possibly is the writer of NeoGPS library. However, when I am trying to compile the code, I get the following error
'class gps_fix' has no member named 'lat' .I can not get rid of the issue even tough I've tried a whole bunch of workarounds.

Have you looked at the NeoGPS library source code or one of the examples that come with the library to see what class members are available with gps_fix?

Looking at this documentation you might need fix.latitudeL() and fix.longitudeL() instead of fix.lat and fix.lon.

I was under the impression that latitude, longitude & speed (and many other values) were products of the GPS module.  Software like TinyGPS and NeoGPS mostly just configure the GPS module and parse the data stream.  What do you mean by inaccuracies and delays?  On a good day, a cheap (uncorrected) GPS module should be about +/- 10 meters latitude and longitude.  And much worse (maybe 5 to 10 times as bad) for altitude.

According to the NeoGPS documentation for the gps_fix class, it looks like .lat and .lon are no longer part of the gps_fix class.
It looks like instead you will have to use .latitudeL and .longitudeL for high precision (Long Integer scaled by 10,000,000) GPS coordinates.
The solution would be to replace fix.lat in your code with fix.latitudeL and fix.lon with fix.longitudeL.


text:
Looking to interface height and weight sensor based on I2C Protocol
I have interfaced a height sensor and a weight sensor. The I2C address of the height and weight sensors are 0x29 and 0x2A respectively. I have merged the example of both the sensors.
This is the first time I am working with I2C and need help on this.
Do let me know about any mistakes or any sort of example which can help me to learn coding different I2C addresses, sensors, and interfacing.
#include <Wire.h>
#include "SparkFun_VL53L1X.h"
#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h"

NAU7802 myScale;
SFEVL53L1X distanceSensor;

//Optional interrupt and shutdown pins.
#define SHUTDOWN_PIN 2
#define INTERRUPT_PIN 3

void setup() {
  Serial.begin(9600);
  Wire.begin(0x2A);
  if (myScale.begin() == false) {
    Serial.println("Scale not detected. Please check wiring. Freezing...");
    while (1);
  }
  Serial.println("Scale detected!");

  Wire.begin(0x29);
  if (distanceSensor.begin() != 0) { //Begin returns 0 on a good init
    Serial.println("Sensor failed to begin. Please check wiring. Freezing...");
    while (1) ;
  }
  Serial.println("Sensor online!");
}

// put your setup code here, to run once:

void loop() {
  distanceSensor.startRanging(); //Write configuration bytes to initiate measurement
  while (!distanceSensor.checkForDataReady()) {
    delay(1);
  }
  int distance = distanceSensor.getDistance(); //Get the result of the measurement from the sensor
  distanceSensor.clearInterrupt();
  distanceSensor.stopRanging();

  Serial.print("Distance(mm): ");
  Serial.print(distance);

  float distanceInches = distance * 0.0393701;
  float distanceFeet = distanceInches / 12.0;

  Serial.print("\tDistance(ft): ");
  Serial.print(distanceFeet, 2);

  Serial.println();
  if(myScale.available() == true) {
    long currentReading = myScale.getReading();
    Serial.print("Reading: ");
    Serial.println(currentReading);
  }
}

Do you have a specific question? Is your code not working? If it’s not working, please tell us what it’s doing wrong and what you expected it to do. There are a lot of tutorials on the web if you just need general information about I2C.

Yes the code is not working, I need help whether this is the way to use I2C protocol for two different sensor and if not then how should I proceed

What does “not working” mean? Please edit your question to include the output the program generates. Does it detect the devices? Does it not detect them? How are they wired to the CPU? What CPU are you using? You have both arduino-mega and nodemcu tags on your post. We’re not going to guess these things.

You really do need to edit your question to be more specific.  The whole point is for people searching with similar problems to find applicable answers.  If your title and question are not clear, then the stackexchange web sites may not be a good place for it.  Guess, by any chance are your I2C wires more than, say, 6 inches long.  I2C was designed to be used to connect devices on the same circuit board.  Not to go distances of say a foot or more.  Also, did you include pull up resistors on the I2C bus?


text:
Search for a certain combination of strings in serial and read the following characters until another set character stops the search
I have the following serial message that I'm receiving from an ESP32 running GRBL:
<Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc>

I want to check the value after SD: which in this case would be 0.21.
It is a value that represents the percentage of a file being read, so values between 100.00 and 0.00 are being sent.
My guess is to look for the SD: in the string and then read all characters until the , but I can't really find a way to realize that.
I found the startsWith() and the substring()function that are able to look for a set of characters in a string, but it seems like they can only check a set amount of characters which in this case doesn't work as 0.00 is 4 characters and 100.00 is 6 characters.
Any help is much appreciated!!

I'd split the string on | then for each substring split it on :. You then have key/value pairs that are easy to compare and work with. Use a C string not a String object and strtok_r and strcmp to do the job with minimal memory outlay. I'll write a proper answer later, I'm on my phone at the moment.

@Majenko thanks for the super quick reply! I 'll give it a try as far as I can!

Firstly you should really be working with a C string (char *) instead of a String object, otherwise you will be massively fragmenting your heap with the string manipulations to come.
Once you have your data in a C string (char array) you can use strtok_r to split the string on the | character, then for each substring further split it on the :.  You need the _r variant of strtok to make it "re-entrant" so you can have two tokenizations at once nested.
For example (untested):
char *data = "<Idle|MPos:158.500,0.000,0.000|FS:0,0|Pn:H|Ov:100,100,100|SD:0.21,/instruction.nc>";
char *pair; // Pointer to a K/V pair
char *pairptr = data; // Pointer for outer strtok

// Split the string on the first |
pair = strtok_r(data, "|", &pairptr);

// While we have a K/V pair
while (pair) {
    char *kvptr = pair;
    // Split the substring into two parts on the colon
    char *key = strtok_r(pair, ":", &kvptr);
    char *val = strtok_r(NULL, ":", &kvptr);
    if (val) { // If we split the data correctly:
        if (strcmp(key, "SD") == 0) { // If the key is "SD" then
            Serial.print("SD data: ");
            Serial.println(val);
        }
    }
    // Get the next string portion
    pair = strtok_r(NULL, "|", &pairptr);
}

Once you have your val you can further split that down on commas in the same way as it's been split on the colon.


text:
Are these GND connected resistors on the Arduino Due redundant?
Does anyone know why these 4 resistors are there (attachment)? It seems like they are useless since connected in a loop to GND.
Full schematics here: https://store.arduino.cc/arduino-due

Just guessing RN is for resistor network.  So they may have more than they needed to use.  I'd say probably "unused".  If that what you meant by "redundant?"  Hard to say with any certainty.  It may be better to ask the electronics stack exchange.

RN2B would be resistor network 2, resistor element B. There appear to be 4 resistors, A through D, inside one resistor-network package. You can see RN5 has the two unused resistors unconnected. The reason RN1 and RN2 have them connected to ground might have to do with noise. EDIT: looking at the eagle file, it seems like they connected them to ground to make the ground-plane flow better. My only question is why they didn't use a single resistor network here, instead of using only halve of two resistor networks.

Yes, they are redundant. They are elements of resistor arrays (multiple resistors in one package) that aren't used. They have just connected all unused pins of those packages to ground.
If you want to know why they would have unused elements, it's all to do with optimizing the manufacturing process. If you have, say some 100k arrays elsewhere in your design and you want to have maybe one or two other 100k resistors elsewhere, rather than adding another component of a discrete 100k resistor it's cheaper to use a 100k array and not use some of the elements. One of the factors in the cost of pick-and-place operations is the number of different components. By keeping the number of component types to a minimum they keep the manufacture costs to a minimum.

great thanks, so if I understand correctly I could just use 1 resistor network (consisting of 4 resistors) to apply pullups to JTAG_RESET, JTAG_TDI, JTAG_TCK and JTAG_TMS and then get rid of the other 4 resistors? I'm designing a board based on this, hence the question.

Sure. A resistor array is just four individual resistors in a convenient package.