message:
How to add if condition in RFID example?

Using an Arduino Mega 2560 and PN532 NFC/RFID module, I want to be able to scan a card and see if its value is (0xF0, 0x21, 0x5D, 0xA7). It should print `"accepted"` in the serial monitor.

However during compilation it keeps telling me:

    iso14443a_uid:99:11: error: expected primary-expression before ']' token

    if (uid[] = {0xF0, 0x21, 0x5D, 0xA7}){
            ^

    exit status 1 expected primary-expression before ']' token

This is my code:

/**************************************************************************/
    /*!
        This example will attempt to connect to an ISO14443A
        card or tag and retrieve some basic information about it
        that can be used to determine what type of card it is.

        Note that you need the baud rate to be 115200 because we need to print
        out the data and read from the card at the same time!

        To enable debug message, define DEBUG in PN532/PN532_debug.h

    */
    /**************************************************************************/

    /* When the number after #if set as 1, it will be switch to SPI Mode*/
    #if 0
      #include <SPI.h>
      #include <PN532_SPI.h>
      #include "PN532.h"

      PN532_SPI pn532spi(SPI, 10);
      PN532 nfc(pn532spi);

    /* When the number after #elif set as 1, it will be switch to HSU Mode*/
    #elif 0
      #include <PN532_HSU.h>
      #include <PN532.h>

      PN532_HSU pn532hsu(Serial1);
      PN532 nfc(pn532hsu);

    /* When the number after #if & #elif set as 0, it will be switch to I2C Mode*/
    #else
      #include <Wire.h>
      #include <PN532_I2C.h>
      #include <PN532.h>
      #include <NfcAdapter.h>

      PN532_I2C pn532i2c(Wire);
      PN532 nfc(pn532i2c);
    #endif

    void setup(void) {
      Serial.begin(115200);
      Serial.println("Hello!");

      nfc.begin();

      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata) {
        Serial.print("Didn't find PN53x board");
        while (1); // halt
      }

      // Got ok data, print it out!
      Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
      Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
      Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

      // Set the max number of retry attempts to read from a card
      // This prevents us from waiting forever for a card, which is
      // the default behaviour of the PN532.
      nfc.setPassiveActivationRetries(0xFF);

      // configure board to read RFID tags
      nfc.SAMConfig();

      Serial.println("Waiting for an ISO14443A card");
    }

    void loop(void) {
      boolean success;
      uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
      uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

      // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
      // 'uid' will be populated with the UID, and uidLength will indicate
      // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
      success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);

      if (success) {
        Serial.println("Found a card!");
        Serial.print("UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
        Serial.print("UID Value: ");
        for (uint8_t i=0; i < uidLength; i++)
        {
          Serial.print(" 0x");Serial.print(uid[i], HEX);
        }
        Serial.println("");
        // Wait 1 second before continuing
        delay(1000);
      }
      else
      {
        // PN532 probably timed out waiting for a card
        Serial.println("Timed out waiting for a card");
      }
      if (uid[] = {0xF0, 0x21, 0x5D, 0xA7}){
        Serial.println("Success");
        }
    }

body:
As has been noted in the comments you can't compare arrays like that. Instead you have to iterate through each entry and compare the individual elements.

If it's just a few entries, then you can do it manually:

    if ((uid[0] == 0xF0) && (uid[1] == 0x21) && (uid[2] == 0x5D) && uid[3] == 0xA7) {
        // ...
    }

If your values are both in arrays then you can use the `memcmp()` function to compare them:

    uint8_t compare[] = {0xf0, 0x21, 0x5d, 0xa7};

    if (memcmp(uid, compare, 4) == 0) {
        // ...
    }

`memcmp` returns 0 if the two arrays match up to the number of bytes given (4 in this case), or a negative or positive number if the one is "less than" or "more than" the other.


sender: user

message:
Programming a switching AC current?

I tried using this code to output AC power from one H-bridge and then another, switching every second, but when I connected a motor to it, it just seemed to output direct current. This is the code I was using (by the way, the motor controller I'm using has a max frequency of 20 kHz, so that's not the problem as far as I know):

    int EnablePin = 8;
    int duty;
    int PWMPinA;
    int PWMPinB;

    const byte CPin = 0;  // analog input channel
    int CRaw;      // raw A/D value
    float CVal;    // adjusted Amps value

    void setup() {
      pinMode(EnablePin, OUTPUT);
      pinMode(PWMPinA, OUTPUT);
      pinMode(PWMPinB, OUTPUT);
    }

    void loop() {

      digitalWrite(EnablePin, HIGH);

      for(duty = 0; duty <= 20000; duty += 1){

        PWMPinA=11;  // Timer2
        PWMPinB=3;
        analogWrite(PWMPinA, 255);
        analogWrite(PWMPinB, 0);
        delayMicroseconds(50);

        if(PWMPinA == 11) {
          PWMPinA = 3;
          PWMPinB = 11;
        } else {
          PWMPinA = 11;
          PWMPinB = 3;
        }

      }
      for(duty = 20000; duty>=0; duty -= 1){

        PWMPinA=6;  // Timer2
        PWMPinB=5;
        analogWrite(PWMPinA, 255);
        analogWrite(PWMPinB, 0);
        delayMicroseconds(50);

        if(PWMPinA == 6) {
          PWMPinA = 5;
          PWMPinB = 6;
        } else {
          PWMPinA = 6;
          PWMPinB = 5;
        }
      }
    }

sender: assistant

body:
Sounds like you have it sorted already but the first major problem with your original code is that you use `PwmPinA` and `PwmPinB` in `setup()`, before they are assigned any values.

I'd be surprised if the compiler didn't warn about that. Never ignore compiler warnings! :-)


message:
vk2828u7g5lf GPS module over SoftwareSerial

So my goal was simple. Trying to get a GPS speed, and show it on a display (later use it to control a stepper motor). I am using the vk2828u7g5lf GPS module from Banggood, which after days of tinkering and trying several tutorials, I managed to make it work with ONLY the following code:

        boolean gpsStatus[] = {false, false, false, false, false, false, false};
    unsigned long start;

    #include <SoftwareSerial.h>
    SoftwareSerial gpsSerial(3,2); // RX, TX

    void setup()
    {
      gpsSerial.begin(9600);
      // START OUR SERIAL DEBUG PORT
      Serial.begin(19200);
      //
      //Settings Array contains the following settings: [0]NavMode, [1]DataRate1, [2]DataRate2, [3]PortRateByte1, [4]PortRateByte2, [5]PortRateByte3,
      //[6]NMEA GLL Sentence, [7]NMEA GSA Sentence, [8]NMEA GSV Sentence, [9]NMEA RMC Sentence, [10]NMEA VTG Sentence
      //NavMode:
      //Pedestrian Mode    = 0x03
      //Automotive Mode    = 0x04
      //Sea Mode           = 0x05
      //Airborne < 1G Mode = 0x06
      //
      //DataRate:
      //1Hz     = 0xE8 0x03
      //2Hz     = 0xF4 0x01
      //3.33Hz  = 0x2C 0x01
      //4Hz     = 0xFA 0x00
      //
      //PortRate:
      //4800   = C0 12 00
      //9600   = 80 25 00
      //19200  = 00 4B 00  **SOFTWARESERIAL LIMIT FOR ARDUINO UNO R3!**
      //38400  = 00 96 00  **SOFTWARESERIAL LIMIT FOR ARDUINO MEGA 2560!**
      //57600  = 00 E1 00
      //115200 = 00 C2 01
      //230400 = 00 84 03
      //
      //NMEA Messages:
      //OFF = 0x00
      //ON  = 0x01
      //
      byte settingsArray[] = {0x03, 0xFA, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //
      configureUblox(settingsArray);
    }

    void loop()
    {
      while(1) {
        if(gpsSerial.available())
        {
        // THIS IS THE MAIN LOOP JUST READS IN FROM THE GPS SERIAL AND ECHOS OUT TO THE ARDUINO SERIAL.
        Serial.write(gpsSerial.read());
        }
      }
    }

    void configureUblox(byte *settingsArrayPointer) {
      byte gpsSetSuccess = 0;
      Serial.println("Configuring u-Blox GPS initial state...");

      //Generate the configuration string for Navigation Mode
      byte setNav[] = {0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, *settingsArrayPointer, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      calcChecksum(&setNav[2], sizeof(setNav) - 4);

      //Generate the configuration string for Data Rate
      byte setDataRate[] = {0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, settingsArrayPointer[1], settingsArrayPointer[2], 0x01, 0x00, 0x01, 0x00, 0x00, 0x00};
      calcChecksum(&setDataRate[2], sizeof(setDataRate) - 4);

      //Generate the configuration string for Baud Rate
      byte setPortRate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, settingsArrayPointer[3], settingsArrayPointer[4], settingsArrayPointer[5], 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      calcChecksum(&setPortRate[2], sizeof(setPortRate) - 4);

      byte setGLL[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B};
      byte setGSA[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32};
      byte setGSV[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39};
      byte setRMC[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40};
      byte setVTG[] = {0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46};

      delay(2500);

      while(gpsSetSuccess < 3)
      {
        Serial.print("Setting Navigation Mode... ");
        sendUBX(&setNav[0], sizeof(setNav));  //Send UBX Packet
        gpsSetSuccess += getUBX_ACK(&setNav[2]); //Passes Class ID and Message ID to the ACK Receive function
        if (gpsSetSuccess == 5) {
          gpsSetSuccess -= 4;
          setBaud(settingsArrayPointer[4]);
          delay(1500);
          byte lowerPortRate[] = {0xB5, 0x62, 0x06, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0x08, 0x00, 0x00, 0x80, 0x25, 0x00, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xB5};
          sendUBX(lowerPortRate, sizeof(lowerPortRate));
          gpsSerial.begin(9600);
          delay(2000);
        }
        if(gpsSetSuccess == 6) gpsSetSuccess -= 4;
        if (gpsSetSuccess == 10) gpsStatus[0] = true;
      }
      if (gpsSetSuccess == 3) Serial.println("Navigation mode configuration failed.");
      gpsSetSuccess = 0;
      while(gpsSetSuccess < 3) {
        Serial.print("Setting Data Update Rate... ");
        sendUBX(&setDataRate[0], sizeof(setDataRate));  //Send UBX Packet
        gpsSetSuccess += getUBX_ACK(&setDataRate[2]); //Passes Class ID and Message ID to the ACK Receive function
        if (gpsSetSuccess == 10) gpsStatus[1] = true;
        if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
      }
      if (gpsSetSuccess == 3) Serial.println("Data update mode configuration failed.");
      gpsSetSuccess = 0;

      while(gpsSetSuccess < 3 && settingsArrayPointer[6] == 0x00) {
        Serial.print("Deactivating NMEA GLL Messages ");
        sendUBX(setGLL, sizeof(setGLL));
        gpsSetSuccess += getUBX_ACK(&setGLL[2]);
        if (gpsSetSuccess == 10) gpsStatus[2] = true;
        if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
      }
      if (gpsSetSuccess == 3) Serial.println("NMEA GLL Message Deactivation Failed!");
      gpsSetSuccess = 0;

      while(gpsSetSuccess < 3 && settingsArrayPointer[7] == 0x00) {
        Serial.print("Deactivating NMEA GSA Messages ");
        sendUBX(setGSA, sizeof(setGSA));
        gpsSetSuccess += getUBX_ACK(&setGSA[2]);
        if (gpsSetSuccess == 10) gpsStatus[3] = true;
        if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
      }
      if (gpsSetSuccess == 3) Serial.println("NMEA GSA Message Deactivation Failed!");
      gpsSetSuccess = 0;

      while(gpsSetSuccess < 3 && settingsArrayPointer[8] == 0x00) {
        Serial.print("Deactivating NMEA GSV Messages ");
        sendUBX(setGSV, sizeof(setGSV));
        gpsSetSuccess += getUBX_ACK(&setGSV[2]);
        if (gpsSetSuccess == 10) gpsStatus[4] = true;
        if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
      }
      if (gpsSetSuccess == 3) Serial.println("NMEA GSV Message Deactivation Failed!");
      gpsSetSuccess = 0;

      while(gpsSetSuccess < 3 && settingsArrayPointer[9] == 0x00) {
        Serial.print("Deactivating NMEA RMC Messages ");
        sendUBX(setRMC, sizeof(setRMC));
        gpsSetSuccess += getUBX_ACK(&setRMC[2]);
        if (gpsSetSuccess == 10) gpsStatus[5] = true;
        if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
      }
      if (gpsSetSuccess == 3) Serial.println("NMEA RMC Message Deactivation Failed!");
      gpsSetSuccess = 0;

      while(gpsSetSuccess < 3 && settingsArrayPointer[10] == 0x00) {
        Serial.print("Deactivating NMEA VTG Messages ");
        sendUBX(setVTG, sizeof(setVTG));
        gpsSetSuccess += getUBX_ACK(&setVTG[2]);
        if (gpsSetSuccess == 10) gpsStatus[6] = true;
        if (gpsSetSuccess == 5 | gpsSetSuccess == 6) gpsSetSuccess -= 4;
      }
      if (gpsSetSuccess == 3) Serial.println("NMEA VTG Message Deactivation Failed!");

      gpsSetSuccess = 0;
      if (settingsArrayPointer[4] != 0x25) {
        Serial.print("Setting Port Baud Rate... ");
        sendUBX(&setPortRate[0], sizeof(setPortRate));
        setBaud(settingsArrayPointer[4]);
        Serial.println("Success!");
        delay(500);
      }
    }

    void calcChecksum(byte *checksumPayload, byte payloadSize) {
      byte CK_A = 0, CK_B = 0;
      for (int i = 0; i < payloadSize ;i++) {
        CK_A = CK_A + *checksumPayload;
        CK_B = CK_B + CK_A;
        checksumPayload++;
      }
      *checksumPayload = CK_A;
      checksumPayload++;
      *checksumPayload = CK_B;
    }

    void sendUBX(byte *UBXmsg, byte msgLength) {
      for(int i = 0; i < msgLength; i++) {
        gpsSerial.write(UBXmsg[i]);
        gpsSerial.flush();
      }
      gpsSerial.println();
      gpsSerial.flush();
    }

    byte getUBX_ACK(byte *msgID) {
      byte CK_A = 0, CK_B = 0;
      byte incoming_char;
      boolean headerReceived = false;
      unsigned long ackWait = millis();
      byte ackPacket[10] = {0xB5, 0x62, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      int i = 0;
      while (1) {
        if (gpsSerial.available()) {
          incoming_char = gpsSerial.read();
          if (incoming_char == ackPacket[i]) {
            i++;
          }
          else if (i > 2) {
            ackPacket[i] = incoming_char;
            i++;
          }
        }
        if (i > 9) break;
        if ((millis() - ackWait) > 1500) {
          Serial.println("ACK Timeout");
          return 5;
        }
        if (i == 4 && ackPacket[3] == 0x00) {
          Serial.println("NAK Received");
          return 1;
        }
      }

      for (i = 2; i < 8 ;i++) {
      CK_A = CK_A + ackPacket[i];
      CK_B = CK_B + CK_A;
      }
      if (msgID[0] == ackPacket[6] && msgID[1] == ackPacket[7] && CK_A == ackPacket[8] && CK_B == ackPacket[9]) {
        Serial.println("Success!");
        Serial.print("ACK Received! ");
        printHex(ackPacket, sizeof(ackPacket));
        return 10;
            }
      else {
        Serial.print("ACK Checksum Failure: ");
        printHex(ackPacket, sizeof(ackPacket));
        delay(1000);
        return 1;
      }
    }

    void printHex(uint8_t *data, uint8_t length) // prints 8-bit data in hex
    {
      char tmp[length*2+1];
      byte first ;
      int j=0;
      for (byte i = 0; i < length; i++)
      {
        first = (data[i] >> 4) | 48;
        if (first > 57) tmp[j] = first + (byte)7;
        else tmp[j] = first ;
        j++;

        first = (data[i] & 0x0F) | 48;
        if (first > 57) tmp[j] = first + (byte)7;
        else tmp[j] = first;
        j++;
      }
      tmp[length*2] = 0;
      for (byte i = 0, j = 0; i < sizeof(tmp); i++) {
        Serial.print(tmp[i]);
        if (j == 1) {
          Serial.print(" ");
          j = 0;
        }
        else j++;
      }
      Serial.println();
    }

    void setBaud(byte baudSetting) {
      if (baudSetting == 0x12) gpsSerial.begin(4800);
      if (baudSetting == 0x4B) gpsSerial.begin(19200);
      if (baudSetting == 0x96) gpsSerial.begin(38400);
      if (baudSetting == 0xE1) gpsSerial.begin(57600);
      if (baudSetting == 0xC2) gpsSerial.begin(115200);
      if (baudSetting == 0x84) gpsSerial.begin(230400);
    }

However, this one doesn't have a simple getSpeed() function, so I've tried to move to a library like TinyGPS that does have said function. Everything compiles fine, but it seems I am not getting a GPS signal with this script, while I have an accurate reading with about 7 satellites of the first script. I've triple checked the baud rates, and they all match, so I am stuck here.

        #include <SoftwareSerial.h>

    #include <TinyGPS.h>

    /* This sample code demonstrates the normal use of a TinyGPS object.
       It requires the use of SoftwareSerial, and assumes that you have a
       4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
    */

    TinyGPS gps;
    SoftwareSerial ss(3,2);

    static void smartdelay(unsigned long ms);
    static void print_float(float val, float invalid, int len, int prec);
    static void print_int(unsigned long val, unsigned long invalid, int len);
    static void print_date(TinyGPS &gps);
    static void print_str(const char *str, int len);

    void setup()
    {
      Serial.begin(19200);

      Serial.print("Testing TinyGPS library v. "); Serial.println(TinyGPS::library_version());
      Serial.println("by Mikal Hart");
      Serial.println();
      Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
      Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
      Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");

      ss.begin(9600);
    }

    void loop()
    {
      float flat, flon;
      unsigned long age, date, time, chars = 0;
      unsigned short sentences = 0, failed = 0;
      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

      print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
      print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
      gps.f_get_position(&flat, &flon, &age);
      print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
      print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
      print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
      print_date(gps);
      print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
      print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
      print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
      print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
      print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
      print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
      print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

      gps.stats(&chars, &sentences, &failed);
      print_int(chars, 0xFFFFFFFF, 6);
      print_int(sentences, 0xFFFFFFFF, 10);
      print_int(failed, 0xFFFFFFFF, 9);
      Serial.println();

      smartdelay(1000);
    }

    static void smartdelay(unsigned long ms)
    {
      unsigned long start = millis();
      do
      {
        while (ss.available())
          gps.encode(ss.read());
      } while (millis() - start < ms);
    }

    static void print_float(float val, float invalid, int len, int prec)
    {
      if (val == invalid)
      {
        while (len-- > 1)
          Serial.print('*');
        Serial.print(' ');
      }
      else
      {
        Serial.print(val, prec);
        int vi = abs((int)val);
        int flen = prec + (val < 0.0 ? 2 : 1); // . and -
        flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
        for (int i=flen; i<len; ++i)
          Serial.print(' ');
      }
      smartdelay(0);
    }

    static void print_int(unsigned long val, unsigned long invalid, int len)
    {
      char sz[32];
      if (val == invalid)
        strcpy(sz, "*******");
      else
        sprintf(sz, "%ld", val);
      sz[len] = 0;
      for (int i=strlen(sz); i<len; ++i)
        sz[i] = ' ';
      if (len > 0)
        sz[len-1] = ' ';
      Serial.print(sz);
      smartdelay(0);
    }

    static void print_date(TinyGPS &gps)
    {
      int year;
      byte month, day, hour, minute, second, hundredths;
      unsigned long age;
      gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
      if (age == TinyGPS::GPS_INVALID_AGE)
        Serial.print("********** ******** ");
      else
      {
        char sz[32];
        sprintf(sz, "d/d/d d:d:d ",
            month, day, year, hour, minute, second);
        Serial.print(sz);
      }
      print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
      smartdelay(0);
    }

    static void print_str(const char *str, int len)
    {
      int slen = strlen(str);
      for (int i=0; i<len; ++i)
        Serial.print(i<slen ? str[i] : ' ');
      smartdelay(0);
    }

The result of the last script looks like this:

    Testing TinyGPS library v. 13
    by Mikal Hart

    Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum
              (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail
    -------------------------------------------------------------------------------------------------------------------------------------
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   0     0         0
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   52    0         0
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   104   0         0
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   169   0         0
    **** **** ********* ********** **** ********** ******** **** ****** ****** ***** ***   *******  ****** ***   221   0         0

A list of libraries I've tried:
 - NeoGPS
 - NeoGPS (customized version of a forum)
 - TineGPS
 - AdafruitGPS

And some more random (video) tutorials online. If anyone could help me out on this one, I would be highly grateful! (and perhaps keep some hair on my head)

body:
The clue lies in this part of your first sketch:

    //NMEA Messages:
    //OFF = 0x00
    //ON  = 0x01
    //
    byte settingsArray[] = {0x03, 0xFA, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //
    configureUblox(settingsArray);

The final entry in your configuration is `0x00` which is "turn off NEMA messages".

There's two things to note here:

1. You are not configuring the GPS receiver in your second code, and
2. All other GPS libraries of note parse NEMA messages, which your first code turns off.

You will need to replicate the configuration code from your first sketch in your second sketch, but *turning ON NEMA messages*.


message:
WS2812B LED strip + Arduino First Pixel keeps dying/breaking

I am trying too hook up a WS2812B LED strip to an arduino nano. The current strip consists of 6 pixels, and the whole thing is powered via a 5.26V Pc power supply.

The problem is that the first pixel keeps dying after about 1 minute. This means i have to cut the strip and re-solder the connections. Before the failure, the strip runs the correct examples from the FastLED package.

[![The initial setup.][1]][1]

As this happened I looked for solutions. https://learn.adafruit.com/adafruit-neopixel-uberguide/best-practices suggested:
1) adding a 1000 µF capacitor between ground and  +5v to cancel power peaks
2) adding a 300-500Ohm resistor between the strip_Data_in and D5

I had no 1000µF+ Capacitor, so i used what i had, a 470µF, and installed it with the resistor.
[![The 470µF Capacitor between Ground and +5v][2]][2]

This did not solve the problem. Another recommendation was to place a diode between the data and +5. ( I think this is to remove any power spikes in the data connection. With a good power supply this should not be necessary i guess, but it couldn't hurt.) Another tip was to add a 100kOhm resistor between data and ground.

putting all mentioned above together gives something like this:
[![Variations on this setup i experimented with][3]][3]

But in the end nothing changed. I tried alot of variations of solutions:

- With and without condensator between ground and Vin.

- With and without resistor between data and arduino, and varied it between 220 Ohm to 1kOhm.

- With and without the diodes. I tried connecting data with a diode to ground, +5v, to both, and to none.

- I have tried using a 3.7V power source to see wether i could avoid burning the pixel. The Leds had too little power to light up.

- I have tried powering via the USB->Arduino->Arduino +5v pin -> strip +5v

[![My soldering work, for checking][4]][4]

Any Idea where i might be fucking up?

 I have burnt 30 pixels so far, with all the same result: blinking, tripping, and eventually failure. Removing the first LED always fixed the problem. This brand of LEDStrip did work on some other premade controller.

Some of my own ideas, of causes:

- There really needs to be a 1000µF Capacitor. (i have never had trouble with voltage peaks with this powersupply, and this does not explain why the system fails after some time, instead of at plugin.)

EDIT 1):
I did some additional tests.

- Raised the resistor before the data pin, from the recommended 470 Ohm, as high as possible. I reached 8kOhm (higher did not work). -> Same result, burned pixel

- Lowered the voltage on the Data input pin, with two resistances, one connected to ground. The LedStrip only recognised data input when the ''Din_High'' was above 3.5 volts. Running at a bit lower voltage stopped the leds from recognising data. Yet still, Same result -> Burned pixel.

- Changing the power supply: I changed the PC power supply to a 5V Power bank for loading celphones. The voltage this device was regulated to was between 5.2 and 4.8V. The behaviour was the same -> Burned pixel.

I would guess that IF:

- the 5V is stable and within 5.5 and 4.5V And

- The Din is within 0 and 5V

The cable should be unable to break itself right?

  [1]: https://i.stack.imgur.com/VuY9B.jpg
  [2]: https://i.stack.imgur.com/05xbD.jpg
  [3]: https://i.stack.imgur.com/zLDZf.jpg
  [4]: https://i.stack.imgur.com/K0evj.jpg

body:
To my understanding, anything connected to the `data` line (resistors, diodes, etc) is there to protect to data pin from either sourcing too much current to the LEDs or receive a too high voltage.

The capacitor, on the other hand, is there to provide a buffer and maintain the voltage at the right value when current absorption increases with a spike.

If your LEDS burn up and it's always the first one, assuming they are all programmed to lit up of the same color, the most reasonable reason IMHO is you are feeding too much current, in particular in the form of higher voltage through the resistors on the strip.

I suggest you double check the source voltage with no load and with a light load, then try a different power supply and, as last resort, try to lower the brightness intensity of the LEDS: set brightness to 50% and check if it takes like 3 or 4 times longer to burn the LED, which will be a confirmation about my statement.

The first LED is the one receiving the highest voltage in the strip as the strip itself has a non trivial resistance, especially the cheap ones. Lowering the brightness you are actually lowering the amount of time the LED is on and it should prolong the LED life in a non linear way.

If my assumption is correct, this also means you have already partially damaged all the LEDS on the strip, the closer to the power, the more damaged they are.


body:
https://www.kitronik.co.uk/pdf/WS2812B-LED-datasheet.pdf

Check the power supply. It is likely too high a voltage. 5.3V is the absolute max. The resistor is only to prevent signal reflections on long wire runs. Neither it or the diodes are needed for your setup.

For comparison, here are 4 rings of 43 WS2812B each, with only a 0.1uF cap per chip, each ring driven from a different data pin on an Uno, which is off screen, and a 10A power supply (4 rings x 43 LEDs/ring * 60mA/LED = 10.3A max current).
https://www.youtube.com/watch?v=CGOxbehyoM4
You can see the wires are much longer than yours.  Unfortunately the camera doesn't self adjust to the brightness changes too well, so the video can be a bit glary at times.


body:
**I found (a part of) the problem:**

**The soldered pin connections at start of the ribbon had leaking current. This was due to the soldering flux remaining around the pins. Rinsing the connection with water carefully solved the problem.**

In earlier runs I soldered with flux and simply wiped it off afterwards. Also note that I am generous in flux usage. I do not know how people can make neat solderingwork without it.
Just scraping, and wiping with tissues between the connections is apparently unreliable. The flux is water solutable, said the package, so I used tap water for cleaning, but I also tried alcohol at times. Of course by taking care not to make anything wet besides the connection, and drying careful afterwards.

Obviously I checked the look of my soldering earlier as well, and it looked quite neat in my opinion. Yet measuring resistance between pins gave varying results, also compared with unsoldered, which made me wonder why.
Cleaning the area around the soldered pins seemed to remove this, which indicates that this may be due to the soldering flux that was remaining. I also heard that flux tends to start flowing again as it heats up under operation, which indicates why the connection seemed good right after soldering, but changed trough time.
Perhaps this is why people use these ultrasonic cleaning baths or something.

About the led strips:
They were one of the cheapest ones available.

About the power supplies:
The first power supply is the 5v line from a PC power supply, which should be able to give quite some amps. ( i forgot how much exactly, but way more than I needed)
The second power supply was a Lithion battery with regulator. The thing says it is able to supply 2 amps, but I stayed far away from this limit.

Thank you for your tips. You help me keep improving myself.

Any more tips on cleaning soldered connections are welcome.


message:
Will this sensor work with arduino?

I'm building an electronic gate. I'm needing a photoelectric sensor to detect cars. This one in the link looks decent. it runs on 12v so I will need to power it separately from the arduino. But does this mean it also puts 12v back to the signal wire? Will that work with ardunio without burning the circuit? How many V can i send into an arduino pin?

thanks

[photo electric sensor][1]

  [1]: https://www.amazon.com/dp/B001LFPB0M/ref=sspa_dk_detail_4?psc=1&pd_rd_i=B001LFPB0M&pd_rd_w=31dko&pf_rd_p=21517efd-b385-405b-a405-9a37af61b5b4&pd_rd_wg=GnWLo&pf_rd_r=GZNSN2T78V7ZGG30D30W&pd_rd_r=007b2314-fb08-11e8-a3aa-179e546e9753

body:
The sensor you specified states:

    Output: SPDT Relay Output
If accurate, it may be inferred that the output is simply 3 contacts where one is normally open and the other is normally closed and the 3rd is the common.  If true then you can treat the output as if it were an ordinary [Single Poll Double Throw (SPDT) switch][1].  Note, with regard to processors, an ordinary switch may need to [de-bounced][2].  This depends on how the state of the switch is used.

  [1]: https://en.wikipedia.org/wiki/Switch#Contact_terminology
  [2]: https://www.arduino.cc/en/Tutorial/Debounce


message:
Intermittent jittering servo

I'm controlling a Hitech HS-625MG servo from a 10k slider via a Nano. For a while the motion tracks the slider position even when moved quickly.

Then, for no reason I can find, it will stop following smoothly & only move in jittery steps & then move as expected again!

The code is cut & paste from the pot-servo example..

    #include <Servo.h>

    Servo myservo_1;  // create servo object to control a servo

    int potpin_1 = A0;  // analog pin used to connect the potentiometer

    int val_1;    // variable to read the value from the analog pin

    void setup() {
      myservo_1.attach(7);  // attaches the servo on pin 9 to the servo object
    }

    void loop() {
      val_1 = analogRead(potpin_1);             // reads the value of the potentiometer (value between 0 and 1023)

      val_1 = map(val_1, 0, 1023, 0, 180);      // scale it to use it with the servo (value between 0 and 180)

      myservo_1.write(val_1);                   // sets the servo position according to the scaled value

      delay(15);                             // waits for the servo to get there
               // have tried values ranging from 5 to 25 same behaviour
    }

[YouTube vid of the behaviour][1]

Anyone seen this kinda thing before?

EDIT: That is the full code listing & here's the circuit diagram, the same as the knob example frome the Servo examples page except the servo is not being powered by the Nano but is sharing the same power supply. (sorry not next to it at the moment)

[![enter image description here][2]][2]

  [1]: https://youtu.be/qBQzK6pM0r8
  [2]: https://i.stack.imgur.com/RCd9F.png

body:
A servo motor requires a lot of current.
========================================

Many have problems when using a servo motor. Sometimes it works a few seconds and then it starts to jitter or it moves a little and then stops or it does nothing and makes a small click noise.

The problem is that servo motors requires a lot of current. Even the small servo motors can require a peak current of 0.5 A. Larger, stronger, and faster servo motors can easily request a peak of a few Amps.

To find the maximum current for the servo motor, look at the stall current of the servo motor.
When a servo starts to turn, it needs a short peak current. That peak current can be near the stall current.

Don't buy a "strong" and "fast" servo motor.
That may sound appealing, but it is better to start with a humble and timid servo motor.
*The servo motors have a DC motor with gears inside. Because of the gears it is already strong.*

Use a power supply of 5V with enough Amps to be able to supply the stall current of the servo motor.
Use that power supply to power the servo motor (the red wire).
Connect the GND of the power supply to the GND of the servo motor (the black wire) and the GND of the Arduino board.

**The 5V pin of the Arduino board can not supply enough power for a servo motor.**
It is in the official Arduino examples, but many run into problems with not enough power.


message:
threshold voltage level and blinking problem

I am using arduino pro mini 3.3 V,8 Mhz.vcc of the this arduino is coming from AC-DC converter with regulator 3.3 volt.I am listening analog data from voltage divider approximately 250 milivolts.

I want to basically,If analog voltage will reach 250 milivolts then led on.Otherwise led off.I am using avarage 100 ms for voltage data.

But,I have seen led on blinking for threshold voltage.Such as,The voltage level is changing 248-254.led on,led of,led on...I don't want to blink.

What can you do in such situations?Voltage level and slightly variable voltage?

Thanks

body:
As Jot mentioned in his comment you can write code to follow a hysteresis. This means, that the LED is only turned on, when the analog value is a bit above the threshold, and only turned off, when it's a bit below the threshold. You can see this behavior in Schmitt Triggers, which work that way (though they are getting the hysteresis via a corresponding electrical circuit, not through code). You wrote, your voltage readings are noisy in the range of about 10mV.

Depending on how your current code is structured, you can reach this goal by using if statements:

    if( value > threshold + margin ){
        digitalWrite(LED_pin, HIGH);
    } else if( value < threshold - margin ) {
        digitalWrite(LED_pin, LOW);
    }

You can choose a good value for margin (this depends on the desired behavior). Start with a margin of 7mV (which should filter out the noise of 10mV) and change it, until it works as intended.


body:
> What is the sensetive ac voltage stabilization method coming from
> voltage divider and it contains noise filter capacitor and take
> avarage?

Calculating an average by using 3/4 of the current average and 1/4 of the new measurement (exponential average) works well for me in a lot of situations. You can adjust the constants as you see fit, as long as they add to 1.0. I use powers of 2 and shifting for maximum performance:

    // Exp. average: 3/4 old avg + 1/4 new data, with rounding
    int16_t xpavg(int16_t newdat, int16_t avg){

       // (3 * avg + 1 * newdat) / 4
       return( (((avg<<2) - avg + newdat) + 2) >> 2 );
    }


message:
Arduino MEGA with RTOS

I've been coding for FreeRTOS on the MEGA 2560, and was using some LEDs to determine activity per task by toggling each individual LED each time through the task, and monitoring the time using a scope on the LED pin(s). All worked fine until I added the code for the last task.

Only the LED for the last task showed activity, and I assumed I screwed up in the new code, and spent a full day re-doing the code and troubleshooting. Well, it turns out that the code was working just fine. The problem appears to be RTOS is not manipulating the appropriate LED for each task, but using some other pin. The same configuration but with simple test code works fine.

I've tried just about everything I know, with negative results. The 3 tasks are running OK (I still need to do much more testing) so it's not like there is an issue with stack overflow, plus I decided to make ALL the variables as global variables to minimze stack use, and possible conflicts with the variables, which were the same on two of the original programs. I'm using about 600 bytes of RAM for those variables, and have tons of spece in the MEGA in all aspects. The code only uses 14K of the 256K available.

So, I'm officially stumped, and I assume that there's a problem with the task switching somehow, but I'd expect the code to crash eventually if that were the case, but it runs for hours and hours.

Does anyone have any real experience with FreeRTOS that have experienced similar issues related to simple digitalRead and/or digitalWrite problems similar to what I'm seeing?

body:
Well, DUMBO (that would be me) found the problem, and it was a real bonehead error.

When I applied the stand-alone code to the RTOS environment, I did not reallocate pin assignments, so there were multiple I/O events writing to the same port that was using the Test LEDs.

I knew that FreeRTOS couldn't be that bad, as if the I/O went to the incorrect pins, the code would be useless.

So, don't take shortcuts, even if you're not ready to complete all segments of the project. Check for duplicate definitions or they will bite you in the ass.......


message:
How to find the difference between two timestamps

I'm using [this time library][1] to access the properties of unix timestamps like hours / minutes / etc. What I want to do is get the current time, and an estimated arrival time, and find the difference between them in minutes.

Here's my code: (My estimated time is coming from an API as an INT)

    time_t timeEstimated = timeInt;
    time_t timeNow = now();

But how do I find the difference between these two timestamps in minutes? I'd like to try and avoid all of the conditionals / math that would come with converting to hours / minutes / seconds / dates and subtracting each component if possible.

  [1]: https://github.com/PaulStoffregen/Time

body:
Unix timestamps are just a count of seconds since [a standard
origin][epoch] (1970.0 UTC), thus a simple subtraction, followed by a
conversion from seconds to minutes:

<!-- language: lang-c++ -->

    float minutes_remaining = (timeEstimated - timeNow) / 60.0;

[epoch]: https://en.wikipedia.org/wiki/Unix_time


message:
Why does it skip the first index - shift register issue

So, I wrote this code myself and I'm a noob on the issue. I did get my code working, but cannot understand why it has to be the way it is.

    int counter;
    int ledValue[] = {
      1,0,1,1,1,1,1,1
    };

    void setup()
    {
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(5, OUTPUT);
    }

    void loop(){
      digitalWrite(5, HIGH);
      for (counter = 8; counter >= 0; --counter) {
      // turn the pin on:
       digitalWrite(2, ledValue[counter - 1]);
       digitalWrite(3, 1);
        digitalWrite(4, 1);
       digitalWrite(2, 0);
       digitalWrite(3, 0);
        digitalWrite(4, 0);
        delay(100);
      // turn the pin off:
      }
      delay(1000);
      digitalWrite(5, LOW);
    }

Now, I am puzzled by both the `counter = 8` and the `[counter -1]`. To me it looks like I am loop-ing this 9 times, though I only got 8 items in the array

A. If I make it `counter = 7` and `[counter -1]` my output is 10111110. This loops 8 times (I think), but gives me 7 leds.

B. If I make it `counter = 7` and `[counter]` my output is 01111110. This loops 8 times (I think), gives me 7 leds but also an extra led burning up front, hence braking the prescribed pattern.

C. If I make it `counter = 7; counter >= -1` my output is 10111111.(as it should). But how can it be -1?

My guess is that I am doing something wrong at the beginnen, but I can't find what. Tried several tutorials and explanations, but it still puzzles me why the correct running code is that way.

Just to be sure, I am familiar with an array being 0-indexed.

Please helpt me understand my code  ;-)

Edit:
Small addition:

 - pin 2 is connected to ShiftRegister pin 14
 - pin 3 is connected to ShiftRegister pin 12
 - pin 4 is connected to ShiftRegister pin 11
 - pin 5 is connected to ShiftRegister pin 10

Thanks for the feedback. My lack of understanding does not concern the loop or array. What I can't get my head around is why the shift registers outputs the loop as it does. Would a picture of the setup help?

body:
The correct way to loop through an array of length 8 is:

<!-- language-all: lang-c++ -->

    for (int counter = 0; counter < 8; ++counter) {
        digitalWrite(2, ledValue[counter]);
        // ...
    }

If you want to loop through the array backwards, then:

    for (int counter = 7; counter >= 0; --counter) {
        digitalWrite(2, ledValue[counter]);
        // ...
    }

This loop will visit, in this order, the indices 7, 6, 5... 1 and 0.

For extra clarity, you could define a constant that holds the length of
the array, then replace the numbers `8` and `7` above by `VALUES_COUNT`
and `VALUES_COUNT-1` respectively.

You wrote:
> If I make it [...] my output is [...]

Not sure what you mean by that. This code should not have much visible
output, as the LEDs are turned off only microseconds after being turned
on. How do you determine what the program's "output" is? Maybe there is
an issue with the way you are trying to diagnose the problem.


body:
Make the problem as small as possible. For example:

    void setup() {
      Serial.begin(9600);

      for( int i=8; i>=0; --i) {
        Serial.println(i);
      }
    }

    void loop() {
    }

The output is:

    8
    7
    6
    5
    4
    3
    2
    1
    0

Those are indeed nine numbers. An array in c++ starts at zero. Your array is from ledValue[0] up to (inclusive) ledValue[7]. See the answer by Edgar Bonet how the for-statements are used.


body:
The problem is in the directions the ShiftRegister gets.

This way, it works

    ...
    digitalWrite(2, ledValue[counter - 1]);
    digitalWrite(4, 1); //clock pin high
    digitalWrite(4, 0);
    digitalWrite(3, 1); //latch pin high
    digitalWrite(3, 0);
    digitalWrite(2, 0);
    ...

The clock and latch have to be low again before switching the signal back to 0.

In the upgraded version I put the clock and latch in a function.


message:
Program is working wrong while melody playing

My robot working fine but when I added buzzer and melody into code then is something wrong. Melody is playing when accelerometer is activated but rest of the code need to wait to end of melody. I want to play melody in background when program works. How to do it? There is my code:

    #include <RedBot.h>
    #include <RedBotSoftwareSerial.h>
    RedBotAccel accel;
    RedBotMotors motors;
    int CM;
    long CZAS;
    bool started = false;
    const int buzzer = A0;

    int shortTone = 80;
    int longTone = 200;
    int standardDelay = 50;
    int delayBetweenBars = 50;

    void setup()
    {
       Serial.begin(9600);
       accel.enableBump();
       accel.setBumpThresh(150);
       pinMode(A2, OUTPUT);  //Trig
       pinMode(A3, INPUT);   //Echo
       pinMode(buzzer, OUTPUT);  //Buzzer
    }

    void pomiar_odleglosci()
    {
       digitalWrite(A2, HIGH);
       delayMicroseconds(10);
       digitalWrite(A2, LOW);
       CZAS = pulseIn(A3, HIGH);
       CM = CZAS / 58;
    }

    void loop(){

       while (!accel.checkBump() && !started) delay(100);
       started = true;

       if(started = true)
       {   DarudeSandstorm();
       }

       pomiar_odleglosci();
       Serial.print("Odleglosc: ");
       Serial.print(CM);
       Serial.println(" cm");

       if(CM>10)
       {
          motors.drive(100);
       }
       else
       {
          motors.drive(-100);
          delay(400);
          motors.stop();

          delay(400);

          motors.rightMotor(100);
          delay(700);
          motors.stop();

          motors.drive(100);
       }

    }
    //melody

body:
You are using delay() in many parts of your code, which makes it very trick. I see a couple of possibilities here:

1 - if you have extra time and patience, get rid of all delays and find your around it counting millis() or some similar technique.

2 - if you have some extra bucks, get another controller just to play the melody, an ATtiny85 should be cheap and practical for this.

There is also the super-lazy, almost-no-work-at-all, relatively cheap solution: use a small media/MP3 player module, which also would allow you to have more than one melody and eventually adtiional noises.


message:
Setting Fuse Bits From Arduino IDE?

I've come to understand fuse bits in the last few weeks. I'm working on a bitbanging project on an Arduino Pro Micro, and the signals I'm working with are around 30uS each. For this reason, I think I'll need to unset the CKDIV8 to unlock the full 16MHz speed of my micro controller.

Regardless, I can't figure out how to even do that. Is it possible to modify fuse bits through the Arduino IDE? If so, where?

The only other info I've found on this subject so far is that I can do it by chaining two micro controllers together, but at that point we're getting into application specific stuff and I'm nervous to play with the fuse bits by myself until after I've followed a step-by-step guide. I'd hate to, say, erase the bootloader.

body:
The Arduinos are shipped without `CKDIV8` enabled.

New chips without bootloader and the chips after chip erase are having `CKDIV8` active.

And you can change the clock prescaller in software, but it mess up everything that depends on it. Delays, serial baud rate and USB as well.

However fuse setings are stored in boards.txt definition file. None of the bootloaders would work with default settings. They are usually compiled for `16MHz @5V` and  `8MHz @3.3V` with xtal or resonator. But the custom boards may have much more options.


message:
ets Jan 8 2013,rst cause:4, boot mode:(1,7)

I am facing a issue with the ESP8266-01 as the following below:

chksum 0x42
csum 0x42
~ld
ets Jan 8 2013,rst cause:4, boot mode:(1,0)
wdt reset

Anyone has the solution please help!!

    #include <LiquidCrystal.h>  //Load liquid Crystal Library
    LiquidCrystal LCD(12, 11, 5, 4, 3, 2);  //Create Liquid Crystal Object called LCD
    #include <ESP8266WiFi.h>

    const char* ssid     = "your-ssid";
    const char* password = "your-password";
    const char* host = "your-localhost";

    #define in 7
    #define out 8
    #define trigPin 10
    #define echoPin 13
    #define relay 2
    #define led 6            //red color
    #define led2 A0           //yellow color
    #define led3 9           //green color

    int count = 0;

    int distanceCm;
    long duration;

    void IN()
    {
        count++;
        LCD.clear();
        LCD.print("Number of Item:");
        LCD.setCursor(0,1);
        LCD.print(count);
        delay(10);
        LCD.setCursor(3,1);
        LCD.print(distanceCm);
        delay(10);
        LCD.setCursor(6,1);
        LCD.print(" cm");
        if(distanceCm <= 3){
         delayMicroseconds(10);
         LCD.setCursor(10,1);
         LCD.print("Full");
         digitalWrite(led, HIGH);
      }else{
        digitalWrite(led, LOW);
      }

      if(distanceCm > 3 && distanceCm <= 5){
         delayMicroseconds(10);
         LCD.setCursor(10,1);
         LCD.print("Enable");
         digitalWrite(led2, HIGH);
      } else{
        digitalWrite(led2, LOW);
      }

      if(distanceCm > 5){
         delayMicroseconds(10);
         LCD.setCursor(10,1);
         LCD.print("Empty");
         digitalWrite(led3, HIGH);
      } else {
        digitalWrite(led3, LOW);
      }
      delay(500);
    }

    void OUT()
    {
      count--;
      LCD.clear();
      LCD.print("Number of Item:");
      LCD.setCursor(0,1);
      LCD.print(count);
      delay(10);
      LCD.setCursor(3,1);
      LCD.print(distanceCm);
      LCD.setCursor(6,1);
      LCD.print(" cm");
       if(distanceCm <= 3){
         delayMicroseconds(10);
         LCD.setCursor(10,1);
         LCD.print("Full");
         digitalWrite(led, HIGH);
      }else{
        digitalWrite(led, LOW);
      }

      if(distanceCm > 3 && distanceCm <= 5){
         delayMicroseconds(10);
         LCD.setCursor(10,1);
         LCD.print("Enable");
         digitalWrite(led2, HIGH);
      } else{
        digitalWrite(led2, LOW);
      }

      if(distanceCm > 5){
         delayMicroseconds(10);
         LCD.setCursor(10,1);
         LCD.print("Empty");
         digitalWrite(led3, HIGH);
      } else {
        digitalWrite(led3, LOW);
      }
      delay(500);
    }

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(115200);
      delay(10);

      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);

      pinMode(led, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(led3, OUTPUT);

      LCD.begin(16,2);
      LCD.print("Item Counter");
      delay(2000);

      pinMode(in, INPUT);
      pinMode(out, INPUT);
      pinMode(relay, OUTPUT);

      LCD.clear();
      LCD.print("Item In Box:");
      LCD.setCursor(0,1);
      LCD.print(count);

      // We start by connecting to a WiFi network

      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
         // ESP.wdtFeed();
      }

      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());

     // ESP.restart();
    }

    int value = 0;

    void loop() {

     delay(0);
     delay(5000);
      ++value;

      digitalWrite(trigPin, LOW);
      delayMicroseconds(10);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(50);
      digitalWrite(trigPin, LOW);

      duration = pulseIn(echoPin, HIGH);
      distanceCm = duration * 0.034/2;

    //******************************************************//
    //IR Sensor Counting Object
      if(digitalRead(in))
      IN();
      if(digitalRead(out))
      OUT();

      if(count<=0)
      {
        LCD.clear();
        digitalWrite(relay, LOW);
        LCD.clear();
        LCD.print("No Item in box");
        LCD.setCursor(0,1);
        LCD.print("box is empty");
        delay(200);
      }
       else{
        digitalWrite(relay, HIGH);
       }

      Serial.print("connecting to ");
      Serial.println(host);

      // Use WiFiClient class to create TCP connections
      WiFiClient client;
      const int httpPort = 8095;
      if (!client.connect(host, httpPort)) {
        Serial.println("connection failed");
        return;
      }
      if(WiFi.status() != WL_CONNECTED){
        WiFi.begin(ssid,password);
        while (WiFi.status()!= WL_CONNECTED)
        {
          Serial.println("Waiting for connection");
          delay(0);
        }
      }

      String IRCount, myDistance;
      IRCount = String(count);
      myDistance = String(distanceCm);
      // We now create a URI for the request
      String url = "/Registration/write_data.php";
      url += "?item=";
      url += IRCount;
      url += "&distance=";
      url += myDistance;

      Serial.print("Requesting URL: ");
      Serial.println(url);

      // This will send the request to the server
      client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                   "Host: " + host + "\r\n" +
                   "Connection: close\r\n\r\n");
      int timeout = millis() + 5000;
      while (client.available() == 0) {
        if (timeout - millis() < 0) {
          Serial.println(">>> Client Timeout !");
          client.stop();
          return;
        }
      }

      // Read all the lines of the reply from server and print them to Serial
      while(client.available()){
        String line = client.readStringUntil('\r');
        Serial.print(line);
      }

      Serial.println();
      Serial.println("closing connection");
      delay(0);
    }

  [1]: https://i.stack.imgur.com/38sPR.png

body:
esp-01 has 4 io pins: RX, TX, io 0 and io 2. other pins are not accessible. io 6 to io 11 are wired to on-board flash memory and can't be used.

what are you thinking by using other pins then 0 and 2? how did you wire those sensors and leds to esp-01?


message:
What bootloader is present by default on Arduino Uno?

Or where can i find information of default bootloaders present on each Arduino board. All I could look up was it could be one of these bootloaders on the atmega chip :-

.Atmega
.Atmega8
.bt
.caterina
.caterina-Arduino_Robot
.caterina-LilyPadUSB
.gemma
.lilypad
.optiboot
.stk500v2

This was the list present in the folder ~\Arduino\hardware\arduino\avr\bootloaders.

body:
Optiboot Bootloader for Arduino and Atmel AVR

https://github.com/Optiboot/optiboot/wiki

Take a look at this information.


body:
It is defined in the file "boards.txt" (`arduino-1.8.7\hardware\arduino\avr\boards.txt`).

For example the Arduino Uno is called "Arduino/Genuino Uno" and it has the bootloader: `uno.bootloader.file=optiboot/optiboot_atmega328.hex`

You can find that hex file in the folder `arduino-1.8.7\hardware\arduino\avr\bootloaders\optiboot`.

The official Arduino boards are shipped with the newest bootloaders.
Sometimes the bootloaders are improved or changed. That is mentioned in the Release Notes.
For example the latest change to a bootloader is that the Arduino Nano has now the same optiboot bootloader as the Arduino Uno.

When buying a Arduino clone board, anything is possible.

Some companies make there own Arduino-compatible boards with their own bootloaders.


message:
Arduino RGB LED not working all the time?

I was creating an RGB LED System with one 1 RGB LED controlled by an IR Remote. I wanted to assign a button to trigger a mood-light which cycles through the rainbow, and that works fine. But when I try to make a mode where you can change RGB Values directly, it doesn't work properly. I assigned numbers on the remote to switch the colour that you are changing (e.g 1 is red, 2 is green etc.), and the volume controls how much light is coming but when I have two colors with positive values it only displays one. I have no idea why because the moodlight works fine and even transitions smoothly.

    //www.elegoo.com
    //2016.12.9

    #include "IRremote.h"

    // Define Pins
    int BLUE = 3;
    int GREEN = 5;
    int RED = 6;

    int addValue = 10;

    int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

    int blueValue = 0;
    int greenValue = 0;
    int redValue = 0;

    bool isMoodLightOn = false;
    bool isBlueModeOn = false;
    bool isGreenModeOn = false;
    bool isRedModeOn = true;

    /*-----( Declare objects )-----*/
    IRrecv irrecv(receiver);     // create instance of 'irrecv'
    decode_results results;      // create instance of 'decode_results'

    /*-----( Function )-----*/
    void translateIR() // takes action based on IR code received

    // describing Remote IR codes

    {

      switch(results.value)

      {
      case 0xFFA25D: Serial.println("POWER"); break;
      case 0xFFE21D: Serial.println("FUNC/STOP"); break;
      case 0xFF629D: Serial.println("VOL+"); break;
      case 0xFF22DD: Serial.println("FAST BACK"); break;
      case 0xFF02FD: Serial.println("PLAY/PAUSE");
                     isMoodLightOn = !isMoodLightOn;
                     if (isMoodLightOn == false) {
                      isBlueModeOn = true;
                      isGreenModeOn = false;
                      isRedModeOn = false;

                      setColor(redValue, greenValue, blueValue);
                     } else {
                      isBlueModeOn = false;
                      isGreenModeOn = false;
                      isRedModeOn = false;
                     }
                     break;
      case 0xFFC23D: Serial.println("FAST FORWARD"); break;
      case 0xFFE01F: Serial.println("DOWN");
                     if (isBlueModeOn) {
                      if (blueValue > 0) {
                        blueValue = blueValue - addValue;
                        Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                        setColor(redValue, greenValue, blueValue);
                      }
                     }
                     if (isGreenModeOn) {
                      if (greenValue > 0) {
                        greenValue = greenValue - addValue;
                        Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                        setColor(redValue, greenValue, blueValue);
                      }
                     }
                     if (isRedModeOn) {
                      if (redValue > 0) {
                        redValue = redValue - addValue;
                        Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                        setColor(redValue, greenValue, blueValue);
                      }
                     }
                     break;
      case 0xFFA857: Serial.println("VOL-"); break;
      case 0xFF906F: Serial.println("UP");
                     if (isBlueModeOn) {
                      if (blueValue < 100) {
                        blueValue = blueValue + addValue;
                        Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                        setColor(redValue, greenValue, blueValue);
                      }
                     }
                     if (isGreenModeOn) {
                      if (greenValue < 100) {
                        greenValue = greenValue + addValue;
                        Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                        setColor(redValue, greenValue, blueValue);
                      }
                     }
                     if (isRedModeOn) {
                      if (redValue < 100) {
                        redValue = redValue + addValue;
                        Serial.println("Red: " + String(redValue) + "Green: " + String(greenValue) + "Blue: " + String(blueValue));
                        setColor(redValue, greenValue, blueValue);
                      }
                     }
                     break;
      case 0xFF9867: Serial.println("EQ"); break;
      case 0xFFB04F: Serial.println("ST/REPT"); break;
      case 0xFF6897: Serial.println("0"); break;
      case 0xFF30CF: Serial.println("1"); isRedModeOn = true; isGreenModeOn = false; isBlueModeOn = false; break;
      case 0xFF18E7: Serial.println("2"); isRedModeOn = false; isGreenModeOn = true; isBlueModeOn = false; break;
      case 0xFF7A85: Serial.println("3"); isRedModeOn = false; isGreenModeOn = false; isBlueModeOn = true; break;
      case 0xFF10EF: Serial.println("4"); break;
      case 0xFF38C7: Serial.println("5"); break;
      case 0xFF5AA5: Serial.println("6"); break;
      case 0xFF42BD: Serial.println("7"); break;
      case 0xFF4AB5: Serial.println("8"); break;
      case 0xFF52AD: Serial.println("9"); break;
      case 0xFFFFFFFF: Serial.println("REPEAT"); break;

      default:
        Serial.println(" other button   ");

      }// End Case

      delay(500); // Do not get immediate repeat

    } //END translateIR
    void setup()   /*----( SETUP: RUNS ONCE )----*/
    {
      Serial.begin(9600);
      Serial.println("IR Receiver Button Decode");

      pinMode(RED, OUTPUT);
      pinMode(GREEN, OUTPUT);
      pinMode(BLUE, OUTPUT);

      setColor(redValue, greenValue, blueValue);

      isBlueModeOn = true;
      isGreenModeOn = false;
      isRedModeOn = false;

      irrecv.enableIRIn(); // Start the receiver

    }/*--(end setup )---*/

    void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
    {
      setColor(redValue, greenValue, blueValue);

      if (irrecv.decode(&results)) // have we received an IR signal?

      {
        translateIR();
        irrecv.resume(); // receive the next value
      }

      setColor(redValue, greenValue, blueValue);

      if (isMoodLightOn == true) {
          int delayTime = 10; // fading time between colors

          redValue = 255; // choose a value between 1 and 255 to change the color.
          greenValue = 0;
          blueValue = 0;

          // this is unnecessary as we've either turned on RED in SETUP
          // or in the previous loop ... regardless, this turns RED off
          // analogWrite(RED, 0);
          // delay(1000);

          for(int i = 0; i < 255; i += 1) // fades out red bring green full when i=255
          {
            redValue -= 1;
            greenValue += 1;
            // The following was reversed, counting in the wrong directions
            // analogWrite(RED, 255 - redValue);
            // analogWrite(GREEN, 255 - greenValue);
            setColor(redValue, greenValue, blueValue);
            delay(delayTime);
          }

          redValue = 0;
          greenValue = 255;
          blueValue = 0;

          for(int i = 0; i < 255; i += 1) // fades out green bring blue full when i=255
          {
            greenValue -= 1;
            blueValue += 1;
            // The following was reversed, counting in the wrong directions
            // analogWrite(GREEN, 255 - greenValue);
            // analogWrite(BLUE, 255 - blueValue);
            setColor(redValue, greenValue, blueValue);
            delay(delayTime);
          }

          redValue = 0;
          greenValue = 0;
          blueValue = 255;

          for(int i = 0; i < 255; i += 1) // fades out blue bring red full when i=255
          {
            // The following code has been rearranged to match the other two similar sections
            blueValue -= 1;
            redValue += 1;
            // The following was reversed, counting in the wrong directions
            // analogWrite(BLUE, 255 - blueValue);
            // analogWrite(RED, 255 - redValue);
            setColor(redValue, greenValue, blueValue);
            delay(delayTime);
          }
      }
      setColor(redValue, greenValue, blueValue);
    }/* --(end main loop )-- */

    void setColor(int red, int green, int blue) {
      analogWrite(BLUE, blue);
      analogWrite(GREEN, green);
      analogWrite(RED, red);
    }

body:
I will formulate my comment as a longer answer.

Inside your `loop()` function, you use `setColor()` twice, directly in the lowest level. When you are not in the moodlight mode, the whole if statement after it will not be executed, so there isn't much happening inside one iteration of the function and it will cycle through very fast, setting the colors again and again.

THe `setColor()` function only consists of calls to `analogWrite()`. It configures the Atmegas hardware, so that a PWM signal will be generated at the pin. For doing so, the corresponding hardware registers (for one of the timers). This also let's the PWM wave start again. If you are doing this very fast (meaning in the range of the PWM signal itself or faster), you will destroy the complete PWM waveform by starting over and over again. Image it as if you wait press the replay button on your music player again and again very fast. You would be able to recognize the music, as it is chopped up due to the replaying.

The aforementioned two lines are not necessary either, since the output of the PWM wave is done by hardware and does not require any code after it has been turned on by `analogWrite()`. So you can simply delete those two lines.


message:
Power on reset with arduino uno can never happen. Can this be fixed?

When an Arduino Uno is powered on, the USB chip's DTR output pin may (is, in fact) low for a while.  This means that the capacitor C5 is connected from the 328p reset pin to ground.  Thus, when power is applied, the reset pin is held low for 10's of milliseconds after power up (while C5 charges) .

Thus, when the 328p starts, the reason for reset (the MCU register) always is "external reset", not "power on reset", even when  power turns on.

This can be fixed by removing C5, or opening the "reset en" jumper, but then the chip is never reset by the falling of DTR,...that is, bootloading is disabled.

Is there a solution that allows POR and external reset for the bootloader?
Thanks!

body:
See 'DTR-reset' circuit of Arduino Uno below.

After powering-on, when DTR is set low (because a sketch is coming in) the falling edge causes a negative pulse on the 328P's external reset pin of ca. 3 ms (see here). The width of this reset pulse is independent of the time that DTR stays low.

During powering-on the 328P's reset pin is low until the capacitor C5 is sufficiently charged. How long this takes depends mainly on the start-up behavior of Vcc. When DTR is low the capacitor will charge faster because RN2D (from capacitor C5 to ground) is bypassed.

But the main thing is that the power-on reset and the external reset have the same effect (see datasheet): when the rising voltage passes a certain threshold a timer is started and after it times out program execution starts at 0x0000 or at the Boot Reset Address (depending on the setting of the fuses). So, in the powering-on situation it makes no sense to differentiate between Power On Reset and External Reset.

[![DTR-reset circuit of Arduino Uno][1]][1]

  [1]: https://i.stack.imgur.com/tOKqg.png


body:
I have answered my own question.
   I added a pull-UP resistor on the DTR line to VCC. Now capacitor C5 does not need to be charged up on power up: both sides of the capacitor start at VCC. Thus, the 328p recognizes a power-up as a "power-up reset", instead of an "external reset", and my sketch starts after 75-milliseconds or so on power up.
    Basically, my circuit is like PimV's diagram, but with the resistor RN2D to VCC, rather than to ground.  At least for the Uno, this fix seems to work.  I suspect this relies on the USB chip (mega16u) being in reset, and it's pins tri-stated, for a while after power up.


message:
Message Interpreter and Handler - How to store a function name in a struct?

For a project, I need to store an array of structures in PROGMEM. Array `MessageTable[]` will be composed of about ten `struct InMessage` elements. InMessage looks sort of like this:

    struct AvcInMessage {
      MessageHandler  msgHandler;
      byte            dataSize;
      byte            data[8];
      char            description[20];
    };
MessageHandler is not a data type... yet. I'm not really sure what data type to use. I want to be able to pick a message from the table and then call `MessageTable[x].msgHandler()` if that makes sense. I'm almost positive that this involves a pointer. Does someone here have an idea about what I'm looking for?

body:
    typedef void (*MessageHandler)(void);   // def messagehandler as pointer to func

    struct AvcInMessage {
      MessageHandler  msgHandler;
      byte            dataSize;
      byte            data[8];
      char            description[20];
    } InMessage[] = {
       {
          function1, <datasize>, {<byte0>, <byte1>, ..., }, "DescriptionHere"
       },
       // etc, for however many elements InMessage[] has.
    };

The `typedef` defines a "pointer to function of void returning void" - fix up the argument count and types, and the return type to your needs. We're assuming each element's function has the same kind of arglist and return type. (Update: Sorry for the bug in my first iteration).

The next statement both defines the array of struct and initializes N of them. Provide an element count in the `[]` if you don't have a full set of initializers at compile time.


message:
My Arduino Code but it will not compile, I cannot find what is wrong with it

I tried convining and LCD display, ultrasonic sensons, LEDs and an IR reciever code into one main code. Seperately they work fine, but when I put them toguether it gives me the following error: "Error compiling for board Arduino/Genuino Mega or Mega 2560."

The full error when I compile is :

    Arduino: 1.8.5 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

    Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
    (.text+0x0): multiple definition of `__vector_13'
    libraries/IRremote/IRremote.cpp.o (symbol from plugin):(.text+0x0): first defined here
    /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld: Disabling relaxation: it will not work with multiple definitions
    collect2: error: ld returned 1 exit status
    exit status 1
    Error compiling for board Arduino/Genuino Mega or Mega 2560.

https://drive.google.com/file/d/1YNOqxE0mAZJsQrV7_zMbRZ_jkur19rXt/view?usp=sharing

body:
The processor has a fixed number of hardware devices such as timers and serial ports. If two libraries try to use the same device (in this case it looks like timer 2) then you won't be able to compile (let alone run) the code without resolving the issue. Possibly one of them could be altered to use a different timer, however this may not be trivial.

As an example, say you have one alarm clock, but you want to have it ring at both 5 a.m. and 7 a.m. You can't do that per se, you might need to get a second clock.

---

Looking at the source code in `(install directory)/hardware/tools/avr/avr/include/avriomxx0_1.h` I see that vector 13 is indeed for Timer 2;

    /* Timer/Counter2 Compare Match A */
    #define TIMER2_COMPA_vect_num 13
    #define TIMER2_COMPA_vect  _VECTOR(13)
    #define SIG_OUTPUT_COMPARE2A  _VECTOR(13)


message:
nodemcu esp8266 does not boot up when 5V pin is connected as a VIN source

Whenever I boot up the esp8266 or flash code via usb ,I have to remove vin pin otherwise it does not boot up.

If I remove vin pin then flash and boot up happens and then i am able connect vin with 5 V relay.(using VIN to power up relay) .

I dont understand what it has to do with VIN pin.please suggest.

I am using below pins for eight devices

    //relay pin setup for funct
    int relayOne = 5;
    int relayTwo = 4;
    int relayThree = 0;
    int relayFour = 2;
    int relayFive = 14;
    int relaySix = 12;
    int relaySeven = 13;
    int relayEight = 15;

body:
IO pins 0, 2 and 15 are boot configuration pins. 15 must be LOW at boot, 2 must not be LOW at boot and 0 determines the flashing mode. For normal run pin 0 must be HIGH. The NodeMcu board has necessary pull-up and pull-down circuits.

You can connect to pins 0, 2 and 15 only devices which don't change the boot state.


message:
Use a button on LCD shield to pause the code

I'm creating a Temperature logging device with thermocouple K and SD card breakout and a RGB LCD Shield Kit w/ 16x2 Character Display (with buttons).

Everything runs ok: temperature displaying on the LCD and logging on txt file on the micro SD card work well

Now I try to configure button on the shield

1. button UP to reset measurements and timer , it works
2. button Down to pause measurements, then when pushed again, continue measurements. I don't know how to do that (how to go out the while condition).

         if (buttons) {

        if (buttons & BUTTON_UP) {

          lcd.clear();
          lcd.print("RESET ");
          if (SD.exists("datalog.txt")) {

            SD.remove("datalog.txt");
            File dataFile = SD.open("datalog.txt", FILE_WRITE);
          }

          else {

            // open the file. note that only one file can be open at a time,
            // so you have to close this one before opening another.
            File dataFile = SD.open("datalog.txt", FILE_WRITE);
            // if the file is available, write to it:

          }
         StartTime = millis();

          delay(500);

        }
        if (buttons & BUTTON_DOWN) {
          lcd.clear();
          lcd.print("STOP");
          while (buttons & BUTTON_DOWN){

              ;
          }

      }

I already thank you for your help,

Vincent

body:
You are not saying much about how `buttons` is valorized or its data type, but assuming it is a numeric variable which gets somehow set by, let's say a `readButtons()` function, then consider the following snippet replacing your _while-loop_:

    do {
      delay(10);
      // re-evaluate whatever sets the buttons variable
      buttons = readButtons();
    while(!(buttons & BUTTON_DOWN));

The loop above will continue until the button down is pressed and it's a little resilient regarding contact bouncing, but not 100% reliable, so I assume the `readButtons()` performs also some debouncing.


message:
Syntax of binary Constants

I was trying to compile some Arduino code on the PC for testing when I noticed some strange syntax for numerical binary constants.

Convetion seems to be to declare them like so:

        static const uint8_t smiley[] = {
            B00111100,
            B01000010,
            B10100101,
            B10000001,
            B10100101,
            B10011001,
            B01000010,
            B00111100 };
However, when I try to compile this with g++ I get
> **error: ‘B00111100’** was not declared in this scope

Now when I exchange this for `B` for the standard C/C++ prefix `0B` it works, but I don't want to change the code that I want so simulate!

Is there some clever macro magic at play here?

body:
There is a file (binary.h) with every possible permutation of number between 0 and 255 represented as binary in it. They're stored as C-preprocessor macros:

    #define B0 0
    #define B00 0
    #define B000 0
    #define B0000 0
    #define B00000 0
    #define B000000 0
    #define B0000000 0
    #define B00000000 0
    #define B1 1
    #define B01 1
    #define B001 1
    #define B0001 1
    #define B00001 1
    #define B000001 1
    #define B0000001 1
    #define B00000001 1
    #define B10 2
    #define B010 2
    #define B0010 2
    #define B00010 2
    #define B000010 2
    #define B0000010 2
    #define B00000010 2
    ... etc ...

Quite why Arduino decided to do this is anyone's guess.  It makes, as you have seen, for non-portable code.

Personally, I *never* use (and would *never* recommend any one else should use) those macros, and instead use the GCC standard binary literal representation `0b....`.


message:
Converting hexadecimal string to floating point value

I am reading data from an energy meter over modbus protocol and I am getting hex values from there. I want to convert that hex string to floating point value.
For example - 0x416f0000 denotes a value of 14.9375.[Reference][1]

Can anyone please help me how to do it on Arduino IDE?

  [1]: https://gregstoll.dyndns.org/~gregstoll/floattohex/

body:
If you do indeed have an ASCII string of hexadecimal numbers (and not a
raw binary float), then your best option may be to do the conversion in
two steps:

1. convert the string to a 32 bit unsigned number using
  [`strtoul()`][strtoul]
2. reinterpret the binary pattern of this integer as a float.

For example, the following program:

<!-- language: lang-c++ -->

    void setup() {
        const char modbus_data[] = "416F0000";
        union {
            uint32_t i;
            float f;
        } data;
        data.i = strtoul(modbus_data, NULL, 16);

        Serial.begin(9600);
        Serial.println(data.f, 4);
    }

    void loop(){}

prints `14.9375`.

Note that for `strtoul()` to function properly, the hex string must be
followed by a character that is not a valid hex digit (a `\0` in the
example above).

[strtoul]: https://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#gaea44aa48bda8261f794dcb2d1e7ab2b2


message:
ESP8266 Stops Working if I don't provide Wifi during specifc step

To test the WiFi connection I'm sharing the WiFi of my cellphone.

If I stop the WiFi sharing during the command below, the ESP8266 stops working.
It only works if I do a hardware reset.

If I don't stop the WiFi it works normally.

        if(client->POST(urlCal, host, payload))
      { RetornoPost = client->getResponseBody(); }

* HTTPS Redirect (Version 2.0)
* ESP8266 library version 2.4.2

Does anyone know why ESP8266 stops working?

body:
If by "stops working" you mean it doesn't do whatever follows the `client->POST` method invocation, then your interpretation is correct and you could have found my [very same information][1] if you had read the open issues on the library **before** submitting your own.

If I were the author of the library I would be upset by such behavior.

  [1]: https://github.com/electronicsguy/ESP8266/issues/64


message:
Data loging while browsing a menu on LCD shield

I'm new in arduino and not particularly awaken when it comes to code ;) .
I'm developing a device SD logging Temperatures from 2 thermocouple .
Hardware works well and I'm now trying to refine use of the LCD with a menu.

I want to be able to, while logging data on the SD card (lets say every second), browsing a menu to:

- See current temperatures

- see the max value from the measurements

- see time already elapsed

- etc.

I've used a menu code from (https://www.instructables.com/id/Arduino-Uno-Menu-Template/)

The thing is when I enter a sub-menu(menuItem()), while I'm not out of this sub menu the code is not looping anymore, so data logging would be paused.

So my question is: how should I organize my code to be able to do a repetitive task in background(logging temperatures) while browsing a menu giving information and/or proposing actions (Stop datalogging, reset etc).

Here is the code from instructables modified to be used with adafruit LCD shield:

    /***************************************************************************************
        Name    : LCD Button Shield Menu
        Author  : Paul Siewert
        Created : June 14, 2016
        Last Modified: June 14, 2016
        Version : 1.0
        Notes   : This code is for use with an Arduino Uno and LCD/button shield. The
                  intent is for anyone to use this program to give them a starting
                  program with a fully functional menu with minimal modifications
                  required by the user.
        License : This program is free software. You can redistribute it and/or modify
                  it under the terms of the GNU General Public License as published by
                  the Free Software Foundation, either version 3 of the License, or
                  (at your option) any later version.
                  This program is distributed in the hope that it will be useful,
                  but WITHOUT ANY WARRANTY; without even the implied warranty of
                  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                  GNU General Public License for more details.
     ***************************************************************************************/
    /*
       This program is designed to get you as close as possible to a finished menu for the standard Arduino Uno LCD/button shield. The only required modifications
       are to add as menu items to the master menu (menuItems array) and then modify/adjust the void functions below for each of those selections.
    */

    // You can have up to 10 menu items in the menuItems[] array below without having to change the base programming at all. Name them however you'd like. Beyond 10 items, you will have to add additional "cases" in the switch/case
    // section of the operateMainMenu() function below. You will also have to add additional void functions (i.e. menuItem11, menuItem12, etc.) to the program.
    String menuItems[] = {"ITEM 1", "ITEM 2", "ITEM 3", "ITEM 4", "ITEM 5", "ITEM 6"};

    // Navigation button variables
    int readKey;

    // Menu control variables
    int menuPage = 0;
    int maxMenuPages = round(((sizeof(menuItems) / sizeof(String)) / 2) + .5);
    int cursorPosition = 0;

    // Creates 3 custom characters for the menu display
    byte downArrow[8] = {
      0b00100, //   *
      0b00100, //   *
      0b00100, //   *
      0b00100, //   *
      0b00100, //   *
      0b10101, // * * *
      0b01110, //  ***
      0b00100  //   *
    };

    byte upArrow[8] = {
      0b00100, //   *
      0b01110, //  ***
      0b10101, // * * *
      0b00100, //   *
      0b00100, //   *
      0b00100, //   *
      0b00100, //   *
      0b00100  //   *
    };

    byte menuCursor[8] = {
      B01000, //  *
      B00100, //   *
      B00010, //    *
      B00001, //     *
      B00010, //    *
      B00100, //   *
      B01000, //  *
      B00000  //
    };

    #include <Wire.h>
    #include <LiquidCrystal.h>

    // Setting the LCD shields pins
    #include <Adafruit_RGBLCDShield.h>
    #include <utility/Adafruit_MCP23017.h>

    Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

    void setup() {

      // Initializes serial communication
      Serial.begin(9600);

      // Initializes and clears the LCD screen
      lcd.begin(16, 2);
      lcd.clear();

      // Creates the byte for the 3 custom characters
      lcd.createChar(0, menuCursor);
      lcd.createChar(1, upArrow);
      lcd.createChar(2, downArrow);
    }
    //////////////////////////////////////////////
    void loop() {
      mainMenuDraw();
      drawCursor();
      operateMainMenu();

      Serial.print("Loop");
    }
    ///////////////////////////////////////////////
    // This function will generate the 2 menu items that can fit on the screen. They will change as you scroll through your menu. Up and down arrows will indicate your current menu position.
    void mainMenuDraw() {
      Serial.print(menuPage);
      lcd.clear();
      lcd.setCursor(1, 0);
      lcd.print(menuItems[menuPage]);
      lcd.setCursor(1, 1);
      lcd.print(menuItems[menuPage + 1]);
      if (menuPage == 0) {
        lcd.setCursor(15, 1);
        lcd.write(byte(2));
      } else if (menuPage > 0 and menuPage < maxMenuPages) {
        lcd.setCursor(15, 1);
        lcd.write(byte(2));
        lcd.setCursor(15, 0);
        lcd.write(byte(1));
      } else if (menuPage == maxMenuPages) {
        lcd.setCursor(15, 0);
        lcd.write(byte(1));
      }
    }

    // When called, this function will erase the current cursor and redraw it based on the cursorPosition and menuPage variables.
    void drawCursor() {
      for (int x = 0; x < 2; x++) {     // Erases current cursor
        lcd.setCursor(0, x);
        lcd.print(" ");
      }

      // The menu is set up to be progressive (menuPage 0 = Item 1 & Item 2, menuPage 1 = Item 2 & Item 3, menuPage 2 = Item 3 & Item 4), so
      // in order to determine where the cursor should be you need to see if you are at an odd or even menu page and an odd or even cursor position.
      if (menuPage % 2 == 0) {
        if (cursorPosition % 2 == 0) {  // If the menu page is even and the cursor position is even that means the cursor should be on line 1
          lcd.setCursor(0, 0);
          lcd.write(byte(0));
        }
        if (cursorPosition % 2 != 0) {  // If the menu page is even and the cursor position is odd that means the cursor should be on line 2
          lcd.setCursor(0, 1);
          lcd.write(byte(0));
        }
      }
      if (menuPage % 2 != 0) {
        if (cursorPosition % 2 == 0) {  // If the menu page is odd and the cursor position is even that means the cursor should be on line 2
          lcd.setCursor(0, 1);
          lcd.write(byte(0));
        }
        if (cursorPosition % 2 != 0) {  // If the menu page is odd and the cursor position is odd that means the cursor should be on line 1
          lcd.setCursor(0, 0);
          lcd.write(byte(0));
        }
      }
    }

    void operateMainMenu() {
      int activeButton = 0;
      while (activeButton == 0) {
        int buttons;

        buttons = lcd.readButtons();

        switch (buttons) {
          case 0: // When button returns as 0 there is no action taken
            break;
          case 2:  // This case will execute if the "forward" button is pressed
            buttons = 0;
            switch (cursorPosition) { // The case that is selected here is dependent on which menu page you are on and where the cursor is.
              case 0:
                menuItem1();
                break;
              case 1:
                menuItem2();
                break;
              case 2:
                menuItem3();
                break;

            }
            activeButton = 2;
            mainMenuDraw();
            drawCursor();
            break;
          case 8:
            buttons = 0;
            if (menuPage == 0) {
              cursorPosition = cursorPosition - 1;
              cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
            }
            if (menuPage % 2 == 0 and cursorPosition % 2 == 0) {
              menuPage = menuPage - 1;
              menuPage = constrain(menuPage, 0, maxMenuPages);
            }

            if (menuPage % 2 != 0 and cursorPosition % 2 != 0) {
              menuPage = menuPage - 1;
              menuPage = constrain(menuPage, 0, maxMenuPages);
            }

            cursorPosition = cursorPosition - 1;
            cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));

            mainMenuDraw();
            drawCursor();
            activeButton = 2;
            break;
          case 4:
            buttons = 0;
            if (menuPage % 2 == 0 and cursorPosition % 2 != 0) {
              menuPage = menuPage + 1;
              menuPage = constrain(menuPage, 0, maxMenuPages);
            }

            if (menuPage % 2 != 0 and cursorPosition % 2 == 0) {
              menuPage = menuPage + 1;
              menuPage = constrain(menuPage, 0, maxMenuPages);
            }

            cursorPosition = cursorPosition + 1;
            cursorPosition = constrain(cursorPosition, 0, ((sizeof(menuItems) / sizeof(String)) - 1));
            mainMenuDraw();
            drawCursor();
            activeButton = 2;
            break;
        }
      }
    }

    // If there are common usage instructions on more than 1 of your menu items you can call this function from the sub
    // menus to make things a little more simplified. If you don't have common instructions or verbage on multiple menus
    // I would just delete this void. You must also delete the drawInstructions()function calls from your sub menu functions.
    void drawInstructions() {
      lcd.setCursor(0, 1); // Set cursor to the bottom line
      lcd.print("Use ");
      lcd.print(byte(1)); // Up arrow
      lcd.print("/");
      lcd.print(byte(2)); // Down arrow
      lcd.print(" buttons");
    }

    void menuItem1() { // Function executes when you select the 1st item from main menu
      int activeButton = 0;

      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Sub Menu 1");

      while (activeButton == 0) {
        int buttons;

        buttons = lcd.readButtons();
        switch (buttons) {
          case 16:  // This case will execute if the "back" button is pressed
            buttons = 0;
            activeButton = 1;
            break;
        }
      }
    }

    void menuItem2() { // Function executes when you select the 2nd item from main menu
      int activeButton = 0;

      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Sub Menu 2");

      while (activeButton == 0) {
        int buttons;

        buttons = lcd.readButtons();
        switch (buttons) {
          case 16:  // This case will execute if the "back" button is pressed
            buttons = 0;
            activeButton = 1;
            break;
        }
      }
    }

    void menuItem3() { // Function executes when you select the 3rd item from main menu
      int activeButton = 0;

      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Sub Menu 3");

      while (activeButton == 0) {
        int buttons;

        buttons = lcd.readButtons();
        switch (buttons) {
          case 16:  // This case will execute if the "back" button is pressed
            buttons = 0;
            activeButton = 1;
            break;
        }
        }
      }

I thank you for your help, and hope it will be helpful for others

body:
The key is that the menu code must never wait as the `operateMainMenu()` function does. Instead, it has to test the buttons, do a required task, if any, quickly, and return. This means it depends on being called very frequently so it can respond to the buttons quickly, but also must return quickly when there is nothing to do. You make those calls from your `loop()` function, typically.

Look at the Arduino example, "BlinkWithoutDelay". In that example everything is decided by reading the time - millis(), where in your case, you'll be deciding by testing and reacting to the buttons. Just remember never to loop to wait for an input; just test for it once and act on it or just go away if it isn't there.

Your `loop()` function will do nothing but give each "worker" routine an opportunity to do something:

    void loop(){
       menuRun();
       dataLogRun();
    }

, for instance. Each of those functions gets a frequent opportunity to do one of its tasks - or not - and return, so the next one gets a chance. A loop like this one runs extremely frequently when there is nothing to do, meaning both the menu function and the data-logging function can be very responsive when something is needed.


message:
Get ESP32 Chip ID into a string variable (Arduino/C++ newbie here)

It's just a few days since I started using Arduino IDE ( programming an ESP32 ). As I learn, I am trying to write some snippets. I wanted to store the Chip ID of ESP32 into a variable (preferably string?) so that I can generate an unique device name. I looked through the ESP32 example programs and came across this program which just prints the Chip ID to the serial console.

      uint64_t chipid;

      chipid = ESP.getEfuseMac(); //The chip ID is essentially its MAC address(length: 6 bytes).
      Serial.printf("ESP32 Chip ID = X", (uint16_t)(chipid >> 32)); //print High 2 bytes
      Serial.printf("X\n", (uint32_t)chipid); //print Low 4bytes.

Now this works fine but I needed to store it into a variable in the following format "ESP32-0A1B3C4D5E6F" ( the last part of which is the Chip/MAC ID which is 6 bytes ). I went about some reading and currently reading and managed to get this far

      char ssid1[15];
      char ssid2[15];

      uint64_t chipid = ESP.getEfuseMac(); // The chip ID is essentially its MAC address(length: 6 bytes).
      uint16_t chip = (uint16_t)(chipid >> 32);

      snprintf(ssid1, 15, "X", chip);
      snprintf(ssid2, 15, "X", (uint32_t)chipid);

      Serial.print(ssid1);
      Serial.println(ssid2);

I am trying to read [this][1] which seems to be an [excellent article][1] on handling Arduino strings but just being a few days old with Arduino/c++ I am having some difficulty in wrapping my head around some of the concepts. I come from a Python, PHP, Javascript background so I guess this is gona take a little bit of a time. I am getting the output that I want in the serial console but now I would need this in this format (MCUDEVICE-0A1B3C4D5E6F). I am sure this code can be written in a much nicer, cleaner manner but for now I need this to proceed with another snippet (which relies on device name in the above mentioned format). Can anyone provide some pointers while I try check out the different ways I could achieve this? I just want to be sure that I am not writing ugly (and dangerous code - crashes, buffer overruns etc). Greatly appreciate any pointers. I guess I am starting to get a little paranoid about handling strings ( especially on low memory devices like typical mcus ).

  [1]: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/

body:
You can combine all your work into one single line with the snprintf. You aren't limited to just one variable, and you can add plain text:

    char ssid[23];

    snprintf(ssid, 23, "MCUDEVICE-XX", chip, (uint32_t)chipid);


body:
Why don't you simply use:

    char ssid[23];
    snprintf(ssid, 23, "MCUDEVICE-%llX", ESP.getEfuseMac());
This way no need to bit-shift and extra middle variables...

Just watch out for capital X for uppercase result and small 'l' for type indication. (meaning use either llX or llx and not LLX).


message:
Why won't my code play a tone for my arduino

I have the following code that I use to try to play a melody on my Arduino, but there is no melody just a tapping noise.

I am using the built in [`tone()`][1] function to play on a speaker/buzzer.

I know my hardware setup is correct because running [sample code online][2] plays a nice melody.

    void setup() { }
    void loop() {

        noTone(6);
      // C7 in eighth
        tone(6, 2093, 250); delay(250);
        noTone(6);
        //B7 in eighth
        tone(6, 3951, 250); delay(250);
        noTone(6);
        //G7 in fourth
        tone(6, 3136, 500); delay(500);
        noTone(6);
        //G7 in eighth
        tone(6, 3136, 250); delay(250);
        noTone(6);
        //F7 in eighth
        tone(6, 2794, 250); delay(250);
        noTone(6);
        //E7 in eighth
        tone(6, 2637, 250); delay(250);
        noTone(6);
        //E7 in fourth
        tone(6, 2637, 500); delay(500);
        noTone(6);
        //G7 in eighth
        tone(6, 3136, 250); delay(250);
        noTone(6);
        //G7 in halves
        tone(6, 3136, 1000); delay(1000);
        noTone(6);
        //C6 in fourth
        tone(6, 1047, 500); delay(500);
        noTone(6);
        //B6 in eighth
        tone(6, 1976, 250); delay(250);
        noTone(6);
        //G6 in eighth
        tone(6, 1566, 250); delay(250);
        noTone(6);
        //C6 in eighth
        tone(6, 1047, 250); delay(250);
        noTone(6);

    }

This is supposed to be the melody for poker face using the tone() function

  [1]: https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
  [2]: https://www.arduino.cc/en/Tutorial/ToneMelody?from=Tutorial.Tone

body:
I just downloaded it, and it works for me.

Hmmm.   Try downloading the other examples again, just to make sure you haven't moved a jumper.

Another way to check this out is to cut down the program to one or two lines, and see if that does or doesn't work.


body: What is the speaker/buzzer you are connecting to? It may need more current then the pin can support (a few tens of mA, absolute max of 40mA to prevent damaging the pin).