body:
> My questions are, where is the saving location of Arduino constant variables? Is it same to Microchip PIC? Those two compilers are same or not in this case?

how compilers handle "const" declarations varies greatly. "const" does nothing but telling that compiler that no modification to that variable is possible.

in the embedded world, that's typically done by putting that variable in flash / rom.

however, that treatment isn't universal. gcc-avr (my winavr from 2009) for example treats "const" just as any other ram types, putting it in either data section or bss section, depending on their initialization (or lack of).

PROGMEM attributes can forcefully change that, however.


sender: user

message:
why there is errorneous output on start up and how to avoid it?

I wrote an Arduino code to get the latitude,longitude,speed,date and time using the GPS SKG 13BL at every 5 secs and sent it to the database with the help of a php code using GSM 900A.The code is as follows :

    #include <NeoSWSerial.h>

    #include <AltSoftSerial.h>
    #include <NMEAGPS.h>

    NeoSWSerial GSM(2, 3); // RX, TX: Connect TXD to RX & RXD to TX

    static const int RXPin = 8, TXPin = 9;
    AltSoftSerial gpsPort(RXPin, TXPin);
    static const uint32_t GPSBaud = 9600;

    NMEAGPS gps;
    gps_fix fix;
    uint8_t fixCount = 0;
    char dt[15],tm[15],lati[10],longi[10];

    enum _parseState {
      PS_DETECT_MSG_TYPE,

      PS_IGNORING_COMMAND_ECHO,

      PS_HTTPPARA_RESPONSE,

      PS_HTTPACTION_TYPE,
      PS_HTTPACTION_RESULT,
      PS_HTTPACTION_LENGTH,

      PS_HTTPREAD_LENGTH,
      PS_HTTPREAD_CONTENT
    };

    enum _actionState {
      AS_IDLE,
      AS_WAITING_FOR_RESPONSE
    };

    byte actionState = AS_IDLE;
    unsigned long lastActionTime = 0;

    int s;

    byte parseState = PS_DETECT_MSG_TYPE;
    char buffer[160],url[160];
    byte pos = 0;

    int contentLength = 0;

    void resetBuffer() {
      memset(buffer, 0, sizeof(buffer));
      pos = 0;
    }

    void sendGSM(const char* msg, int waitMs = 500) {
      GSM.println(msg);
      while(GSM.available()) {
        parseATText(GSM.read());
      }
      //delay(waitMs);
    }

    void setup()
    {
      GSM.begin(9600);
      Serial.begin(9600);
      gpsPort.begin(GPSBaud);

      Serial.println(F("Hinder LOADING....."));
      Serial.println(F("obtain gps and store data to database"));
      Serial.println(F("Testing by : "));
      Serial.println(F("Nikhil,Muthumani and Mathews"));
      Serial.println();

      sendGSM("AT+SAPBR=3,1,\"APN\",\"vodafone\"");
      delay(500);
      sendGSM("AT+SAPBR=1,1",3000);
      delay(500);
      sendGSM("AT+HTTPINIT");
      delay(500);
      sendGSM("AT+HTTPPARA=\"CID\",1");
      delay(500);
    }

    void loop()
    {
      unsigned long now = millis();
      while (gps.available( gpsPort )) {
        fix = gps.read();
         //Serial.println(F("b"));
        // Once every 5 seconds...
        if (++fixCount >= 5) {
           //Serial.println(F("a"));
          displayInfo();

          //send the next report if previous one is finished
          if ( actionState == AS_IDLE ) {
          sprintf(url, "AT+HTTPPARA=\"URL\",\"http://********.com/***er.php?lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",lati,longi,s,dt,tm );
          sendGSM(url);
         // lastActionTime = now;
          parseState = PS_HTTPPARA_RESPONSE; // a new state
          actionState = AS_WAITING_FOR_RESPONSE;
          fixCount = 0;
        }

        }
      }

    /*  if ((gps.statistics.chars < 10) && (millis() > 5000)) {
         Serial.println( F("No GPS detected: check wiring.") );
         while(true);
         block=1;
        }*/

      while(GSM.available()) {
        //lastActionTime = now;
        parseATText(GSM.read());
      }
     }

    void displayInfo()
    {
      Serial.print(F("Location: "));
      if (fix.valid.location) {
        dtostrf( fix.latitude(),7,5,lati);
        //sprintf(lati,"%d",fix.latitude(),5);
        Serial.print(lati);
        Serial.print( ',' );
        dtostrf( fix.longitude(),8,5,longi);
        //sprintf(longi,"%d",fix.longitude(),5);
        Serial.print(longi);
      } else {
        Serial.print(F("INVALID"));
      }

      Serial.print(F("  Speed: "));
      if (fix.valid.speed) {
        s=fix.speed_kph();
        Serial.print(s);
        Serial.print(F(" KMPH "));
      } else {
        Serial.print(F("INVALID"));
      }

      // Shift the date/time to local time
      NeoGPS::clock_t localSeconds;
      NeoGPS::time_t  localTime;
      if (fix.valid.date && fix.valid.time) {
        using namespace NeoGPS; // save a little typing below...

        localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
        localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
        localTime = localSeconds;              // convert back to a structure
      }

      Serial.print(F("  Date : "));
      if (fix.valid.date) {
        sprintf(dt,"d/d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
        Serial.print(dt);
      } else {
        Serial.print(F("INVALID"));
      }

      Serial.print(F("  Time : "));
      if (fix.valid.time) {
        if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
        sprintf(tm,"d:d:d",localTime.hours,localTime.minutes,localTime.seconds);
        Serial.print(tm);
        //block=1;
      } else {
        Serial.print(F("INVALID"));
      }

      Serial.println();
    }

    void parseATText(byte b) {

      buffer[pos++] = b;

      if ( pos >= sizeof(buffer) )
        resetBuffer(); // just to be safe

      /*
       // Detailed debugging
       Serial.println();
       Serial.print("state = ");
       Serial.println(state);
       Serial.print("b = ");
       Serial.println(b);
       Serial.print("pos = ");
       Serial.println(pos);
       Serial.print("buffer = ");
       Serial.println(buffer);*/

      switch (parseState) {

      case PS_HTTPPARA_RESPONSE:
        {
          parseState = PS_DETECT_MSG_TYPE;
          sendGSM("AT+HTTPACTION=0");
         /*  while(GSM.available()) {
        //lastActionTime = now;
        parseATText(GSM.read());
      }*/

        }
        break;

      case PS_DETECT_MSG_TYPE:
        {
          if ( b == '\n' )
            resetBuffer();
          else {
            if ( pos == 3 && strcmp(buffer, "AT+") == 0 ) {
              parseState = PS_IGNORING_COMMAND_ECHO;
            }
            else if ( b == ':' ) {
              //Serial.print("Checking message type: ");
              //Serial.println(buffer);

              if ( strcmp(buffer, "+HTTPACTION:") == 0 ) {
                Serial.println("Received HTTPACTION");
                parseState = PS_HTTPACTION_TYPE;
              }
              else if ( strcmp(buffer, "+HTTPREAD:") == 0 ) {
                Serial.println("Received HTTPREAD");
                parseState = PS_HTTPREAD_LENGTH;
              }
              resetBuffer();
            }
          }
        }
        break;

      case PS_IGNORING_COMMAND_ECHO:
        {
          if ( b == '\n' ) {
            Serial.print("Ignoring echo: ");
            Serial.println(buffer);
            parseState = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPACTION_TYPE:
        {
          if ( b == ',' ) {
            Serial.print("HTTPACTION type is ");
            Serial.println(buffer);
            parseState = PS_HTTPACTION_RESULT;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPACTION_RESULT:
        {
          if ( b == ',' ) {
            Serial.print("HTTPACTION result is ");
            Serial.println(buffer);
            parseState = PS_HTTPACTION_LENGTH;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPACTION_LENGTH:
        {
          if ( b == '\n' ) {
            Serial.print("HTTPACTION length is ");
            Serial.println(buffer);

            // now request content
            GSM.print("AT+HTTPREAD=0,");
            GSM.println(buffer);

            parseState = PS_DETECT_MSG_TYPE;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPREAD_LENGTH:
        {
          if ( b == '\n' ) {
            contentLength = atoi(buffer);
            Serial.print("HTTPREAD length is ");
            Serial.println(contentLength);

            Serial.print("HTTPREAD content: ");

            parseState = PS_HTTPREAD_CONTENT;
            resetBuffer();
          }
        }
        break;

      case PS_HTTPREAD_CONTENT:
        {
          // for this demo I'm just showing the content bytes in the serial monitor
          Serial.write(b);

          contentLength--;

          if ( contentLength <= 0 ) {

            // all content bytes have now been read

            parseState = PS_DETECT_MSG_TYPE;
            resetBuffer();

            Serial.print("\n\n\n");

            actionState = AS_IDLE;
          }
        }
        break;
      }
    }

When I test the code it shows the output as : [![enter image description here][1]][1] as you can see after `Ignoring echo: AT+HTTPREAD=0,0`
the GPS output is printed out at every sec (not at 5 sec interval) and also does not perform rest of the actions (i.e Sending to database is not performed). And I press reset button  and the output is : [![enter image description here][2]][2]Even though it prints the GPS output at every sec it inserted the values into database.And once again I press reset button then it works fine.So why do this error occurs and is there a way to solve this.And can I make the program run only when GPS data is available (because now if GPS data is not available it shows some error nature ).

  [1]: https://i.stack.imgur.com/IeKJJ.jpg
  [2]: https://i.stack.imgur.com/d4M0j.jpg

sender: assistant

body:
:)

> Why does this error occur, and is there a way to solve this?

Because the GSM operations take time, the GPS data has time to accumulate.  Then the `while (gps.available` loop will execute multiple times without breaking.  It calls `displayInfo` every time because `fixCount >= 5`.  `fixCount` is 6, 7, 8, etc. in consecutive seconds.

To solve this problem, you need to be more restrictive about starting the sending process:

    void loop()
    {
      while (gps.available( gpsPort )) {
        fix = gps.read();
         //Serial.println(F("b"));

        //send a report once every 5 seconds if previous one is finished
        if ((++fixCount >= 5) && (actionState == AS_IDLE)) {

          //Serial.println(F("a"));
          displayInfo();

          sprintf(url, "AT+HTTPPARA=\"URL\",\"http://********.com/***er.php?lat=%s&lng=%s&speed=%d&date=%s&time=%s\"",lati,longi,s,dt,tm );
          sendGSM(url);
          parseState  = PS_HTTPPARA_RESPONSE; // a new state
          actionState = AS_WAITING_FOR_RESPONSE;
          fixCount    = 0;
        }
      }

      while(GSM.available()) {
        parseATText(GSM.read());
      }
    }

The combined `if` test displays GPS info only when the GSM process begins.  Then it will continue to read fixes, keeping the queue emptied.  When the state goes back to AS_IDLE, it can send another update.  Notice how this loop structure will continue counting fixes while the GSM process is completing.  If the GSM process takes 5 seconds or more, it will immediately send another update when the previous GSM send has completed.

If you want it to wait an *additional* 5 seconds between each GSM update, don't increment the `fixCount` until the GSM process has completed (AS_IDLE).  Then the updates will be sent once every 5 + (GSM send time) seconds, perhaps once every 15 seconds.

> can I make the program run only when GPS data is available (because now if GPS data is not available it shows some error nature ).

Yes, make the `if` test even *more* restrictive by testing the valid flags:

        //send a report once every 5 seconds if the data is valid
        //   and the previous one is finished
        if ((fix.valid.location && fix.valid.date && fix.valid.time) &&
            (++fixCount >= 5) &&
            (actionState == AS_IDLE)) {

This only counts valid fixes; the `fixCount` will not increment unless those 3 pieces are valid.

NOTE: You probably don't have to test `fix.valid.speed`, as it will be marked as invalid when you are stationary.  Testing the valid flags could be removed from `displayInfo()`:

    void displayInfo()
    {
      Serial.print(F("Location: "));
      dtostrf( fix.latitude(),7,5,lati);
      Serial.print(lati);
      Serial.print( ',' );
      dtostrf( fix.longitude(),8,5,longi);
      Serial.print(longi);

      Serial.print(F("  Speed: "));
      if (fix.valid.speed) {
        s=fix.speed_kph();
      } else {
        s=0;
      }
      Serial.print(s);
      Serial.print(F(" KMPH "));

      // Shift the date/time to local time
      NeoGPS::clock_t localSeconds;
      NeoGPS::time_t  localTime;
      {
        using namespace NeoGPS; // save a little typing below...

        localSeconds = (clock_t) fix.dateTime; // convert structure to a second count
        localSeconds += 5 * SECONDS_PER_HOUR + 30 * SECONDS_PER_MINUTE; // shift timezone
        localTime = localSeconds;              // convert back to a structure
      }

      Serial.print(F("  Date : "));
      sprintf(dt,"d/d/20%d",fix.dateTime.date,fix.dateTime.month,fix.dateTime.year);
      Serial.print(dt);

      Serial.print(F("  Time : "));
      if (localTime.hours>12)localTime.hours-=12;//To convert 24 hr format to 12 hr format
      sprintf(tm,"d:d:d",localTime.hours,localTime.minutes,localTime.seconds);
      Serial.print(tm);
      //block=1;

      Serial.println();
    }

`displayInfo` still checks `fix.valid.speed` and uses `0` when there is no speed (i.e., when you're stationary).


message:
How to get my water pump to turn off and on with the moisture level?

I am trying to built an automatic plant watering system with my arduino. I have an LCD display screen that outputs the moisture level, a moisture sensor and a water pump with a relay. I have been trying to get the water pump to read the moisture data and if it reads lower that 60 to turn on the pump for 10 seconds and then turn the pump off until it reads the moisture again to see if it needs more water. However I am unable to get my water pump to turn off. Is it not reading the moisture sensor?

    String writeAPIKey = "dCFFuwutXLRoHKQNqbIXrP";  //Put your ThingSpeak Write API key here.
    unsigned int interval = 60000;  //Update every Minute
    long int now=0, previous=-50000; //Used to hold time variables.
    #define DST_IP "maker.ifttt.com"  //Thingspeak Server

    //LCD display
    //Load libraries
    #include <Wire.h>
    #include <LCD.h>
    #include <LiquidCrystal_I2C.h>

     //Define address for the Serial LCD display.
    #define I2C_ADDR  0x27  //If 0x3f doesn't work change this to 0x27
    #define BACKLIGHT_PIN  3

    //Initialise the Serial LCD.
    LiquidCrystal_I2C lcd(I2C_ADDR, 2,1,0,4,5,6,7); //These pin numbers are hard coded in on the serial backpack board.

    // Moisture sensor
    int moistureSensor = A3; // moisture sensor is plugged into A3 on the arduino
    int data; // Used to store data from user
    int waitTime = 1000;

    // water pump
    int pumpPin = 8; // water pump
    int waterTime = 10; // 10 seconds watering time

    void setup() { // put your setup code here, to run once:
      // Moisture Sensor
        Serial.begin(9600);

    // LCD display
    lcd.begin (16,2);     //Initalize the LCD.
    lcd.setBacklightPin(3,POSITIVE);//Setup the backlight.
    lcd.setBacklight(HIGH); //Switch on the backlight.
    lcd.clear();
    lcd.setCursor(0,0);   //go to first column  and first line (0,0)
    lcd.print("Hello - Arnold");     //Print at cursor Location
    lcd.setCursor(5,1);   //goto first column and second line
    delay(1000);

    // pump
    pinMode(pumpPin, OUTPUT);

     // Wifi
      Serial.begin(9600);  // Open serial Connection to Computer
      Serial1.begin(115200);  // Open serial Connection to ESP8266
      Serial.println("IFTTT Maker");
      Serial1.println("AT+RST");  //Issue Reset Command
      Serial.println("AT+RST");
      delay(1000);

      //DEBUG LOOP- display ESP output to serial Monitor.
      while (Serial1.available()) {
      Serial.println(Serial1.read());
      }
      Serial.println("AT+CWMODE=1");
      Serial1.println("AT+CWMODE=1");  //Set single client mode.
      delay(5000);

      Serial.println("AT+CIFSR");
      Serial1.println("AT+CIFSR"); //Display IP Information

      //DEBUG LOOP- display ESP output to serial Monitor.
      while (Serial1.available()) {
      Serial.println(Serial1.read());
      }
      delay(1000);

      Serial.println("AT+CIPMUX=0");
      Serial1.println("AT+CIPMUX=0");  //Sets up Single connection mode.
      delay(1000);

      //DEBUG LOOP- display ESP output to serial Monitor.
      while (Serial1.available()) {
        Serial.write(Serial1.read());
      }
      delay(1000);

    }
    void loop() { // put your main code here, to run repeatedly:

        // Moisture
        delay(waitTime);
        data = analogRead(moistureSensor);
        data = map(data, 0, 1023, 0, 100);
        Serial.println(data);

        // LCD
        for(int count = 0; count < 15; count++) {
        lcd.clear();
        lcd.setCursor(7,0);
        lcd.print(data);
        delay(500);
          }

        // pumpPin
        if (moistureSensor <= 60) {
        digitalWrite(pumpPin, HIGH);
        delay(waterTime*1000); // on for 10 seconds
        digitalWrite(pumpPin, LOW);
        delay(waitTime);

        } else if (moistureSensor >=65) {
            digitalWrite(pumpPin, LOW);
            delay(waitTime);

        }

    // IFTTT
      now=millis(); //Get the current time.
    //Check to see if it's time to run.
    if(now - previous >= interval){
      previous = now;
      Serial.println("Running Update");
      updateThingSpeak();
       }
    }

    void updateThingSpeak(){

      int moisture = analogRead(moistureSensor); //Read the moisture

       //Builds the connection string for the ESP8266
        String cmd = "AT+CIPSTART=\"TCP\",\"";
        cmd += DST_IP;
        cmd += "\",80";
        Serial1.println(cmd);  //Run the command
        Serial.println(cmd);    //Print this to the debug window
        delay(1000);

        //DEBUG LOOP- display ESP output to serial Monitor.
        while (Serial1.available()) {
        Serial.write(Serial1.read());
        }

       //I NEED TO UPDATE THIS IF STATEMENT TO MAKE SURE CONNECTION WORKED
      //if (client.connect(thingSpeakAddress, 80)){
        String httpcmd="GET/trigger/arnold_the_plant/with/key/dCFFuwutXLRoHKQNqbIXrP?";
        httpcmd += "value1=";
        httpcmd += moisture;
        httpcmd += " HTTP/1.1\r\n";
        httpcmd += "Host: maker.ifttt.com\n";
        httpcmd += "Connection: close\r\n\r\n";

        Serial.print("AT+CIPSEND=");
        Serial.println(httpcmd.length());

        Serial1.print("AT+CIPSEND=");
        Serial1.println(httpcmd.length());
        delay(1000);

        Serial.print(">");
        Serial1.println(httpcmd);
        Serial.println(httpcmd);
        delay(3000);

        //DEBUG LOOP- display ESP output to serial Monitor.
         while (Serial1.available()) {
          Serial.write(Serial1.read());
          }

        Serial.println("AT+CIPCLOSE");
        Serial1.println("AT+CIPCLOSE"); //Close the Web Connection

       } // end of void loop

body:
 Invert logical level on the pin that controls water pump.

    // pumpPin
    if (moistureSensor <= 60)
     { digitalWrite(pumpPin, LOW );
     delay(waterTime*1000);
     // on for 10 seconds
     digitalWrite(pumpPin, HIGH);
     delay(waitTime); }
    else if (moistureSensor >=65)
     { digitalWrite(pumpPin, HIGH);
     delay(waitTime); }


message:
Function is executing when I try to store it in an array

I am trying to store a set of functions with different parameter in an array. When the code enters the function `songlearn` with `tune==1` I want the functions with set parameters to be stored in the array without executing. What am I doing wrong? Here's my code:

    const int x=100;
    int (*SongSeq[x])();
    int note[x];
    int playNote(int midi, int row, int col, int len, bool short_led = false);
    void songlearn(int tune);
    int tune;

    void songlearn (int tune){
      if (tune==1){
        state=1;
       lcd.clear();
      lcd.setCursor(4,0);
      lcd.print("Learning Song :");// Print a message to the LCD.
      lcd.setCursor(1, 1);
      lcd.print(menuP1);
    // if (songpage==1){
    // if (BackState==HIGH){//leaving song
    //     posP=0;
    //     Page=2;
    //    Play(posP);
    //    }
    // }
      //Plays Mary Had a Little Lamb on a loop at 145 BPM
    //Bar 1
    SongSeq[0]= playNote(0x40, 3, 1, 414); //Quarter note: E
    note[0]=0x40;
    SongSeq[1]=playNote(0x3e, 2, 4, 414); //Quarter note: D
    note[1]=0x3e;
    SongSeq[2]=playNote(0x3c, 2, 2, 414); //Quarter note: C
    note[2]=0x3c;
    SongSeq[3]=playNote(0x3e, 2, 4, 414); //Quarter note: D
    note[3]=0x3e;
    //Bar 2
    SongSeq[4]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
    note[4]=0x40;
    SongSeq[5]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
    note[5]=0x40;
    SongSeq[6]=playNote(0x40, 3, 1, 828,1); //Half note: E
    note[6]=0x40;
    //Bar 3
    SongSeq[7]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
    note[7]=0x3e;
    SongSeq[8]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
    note[8]=0x3e;
    SongSeq[9]=playNote(0x3e, 2, 4, 828,1); //Half note: D
    note[9]=0x3e;
    //Bar 4
    SongSeq[10]=playNote(0x40, 3, 1, 414); //Quarter note: E
    note[10]=0x40;
    SongSeq[11]=playNote(0x43, 3, 4, 414,1); //Quarter note: G
    note[11]=0x43;
    SongSeq[12]=playNote(0x43, 3, 4, 828,1); //Half note: G
    note[12]=0x43;
    //Bar 5
    SongSeq[13]=playNote(0x40, 3, 1, 414); //Quarter note: E
    note[13]=0x40;
    SongSeq[14]=playNote(0x3e, 2, 4, 414); //Quarter note: D
    note[14]=0x3e;
    SongSeq[15]=playNote(0x3c, 2, 2, 414); //Quarter note: C
    note[15]=0x3c;
    SongSeq[16]=playNote(0x3e, 2, 4, 414); //Quarter note: D
    note[16]=0x3e;
    //Bar 6
    SongSeq[17]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
    note[17]=0x40;
    SongSeq[18]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
    note[18]=0x40;
    SongSeq[19]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
    note[19]=0x40;
    SongSeq[20]=playNote(0x40, 3, 1, 414,1); //Quarter note: E
    note[20]=0x40;
    //Bar 7
    SongSeq[21]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
    note[21]=0x3e;
    SongSeq[22]=playNote(0x3e, 2, 4, 414,1); //Quarter note: D
    note[22]=0x3e;
    SongSeq[23]=playNote(0x40, 3, 1, 414); //Quarter note: E
    note[23]=0x40;
    SongSeq[24]=playNote(0x3e, 2, 4, 414); //Quarter note: D
    note[24]=0x3e;
    //Bar 8
    SongSeq[25]=playNote(0x3c, 2, 2, 1656); //Whole note: C
    note[25]=0x3c;

    //End song
      }
     }
     int playNote(int midi, int row, int col, int len, bool short_led = false)
    {
        int len1, len2;
        if (short_led) {
            len1 = len * 3 / 4;
            len2 = len * 1 / 4;
        } else {
            len1 = len;
            len2 = 0;
        }
        noteOn(0x90, midi, 100);
        digitalWrite(LedR[row], HIGH);
        digitalWrite(LedC[col], LOW);
        delay(len1);
        digitalWrite(LedR[row], LOW);
        digitalWrite(LedC[col], HIGH);
        delay(len2);
        noteOff(0x90, midi, 0);
    }

body:
What you have done will certainly call the function. Since it is always the same function, just store the *arguments* into an array. Something like this:

    const int COUNT = 100;

    struct
      {
      int midi;
      int row;
      int col; int len;
      bool short_led;
      } notes [COUNT] = {
      { 0x40, 3, 1, 414 },  //Quarter note: E
      { 0x3e, 2, 4, 414 },  //Quarter note: D
      { 0x3c, 2, 2, 414 },  //Quarter note: C

      // and so on
      };

    int playNote(int midi, int row, int col, int len, bool short_led = false);

    void setup()
      {
      // put your setup code here, to run once:
      }

    void loop()
      {
      for (int i = 0; i < COUNT; i++)
        {
        if (notes [i].midi)
          playNote (notes [i].midi, notes [i].row, notes [i].col,
                    notes [i].len, notes [i].short_led);
        }
      }

    int playNote(int midi, int row, int col, int len, bool short_led)
    {
        int len1, len2;
        if (short_led) {
            len1 = len * 3 / 4;
            len2 = len * 1 / 4;
        } else {
            len1 = len;
            len2 = 0;
        }
        noteOn(0x90, midi, 100);
        digitalWrite(LedR[row], HIGH);
        digitalWrite(LedC[col], LOW);
        delay(len1);
        digitalWrite(LedR[row], LOW);
        digitalWrite(LedC[col], HIGH);
        delay(len2);
        noteOff(0x90, midi, 0);
    }

---

> yeah but i want to be able to store the function in an array with the set parameters

Do you? I wonder why.

Anyway, you can do that by making an array of lambda functions like this:

    const int COUNT = 100;

    int playNote(int midi, int row, int col, int len, bool short_led = false);

    void (*SongSeq[COUNT])() =
     {
     [] { playNote(0x40, 3, 1, 414); } ,
     [] { playNote(0x3e, 2, 4, 414); } ,
     [] { playNote(0x3c, 2, 2, 414); } ,
     [] { playNote(0x3e, 2, 4, 414); } ,

     // ... and so on

     };

    void setup()
      {
      Serial.begin (115200);
      }

    void loop()
      {
      for (int i = 0; i < COUNT; i++)
        {
        if (SongSeq [i])
          SongSeq [i] ();
        }
      }

    int playNote(int midi, int row, int col, int len, bool short_led)
    {
      Serial.print ("Playing note ");
      Serial.println (midi);
      delay (100);
    }


body:
Calling or entering a function _means_ executing it -- that is just how the language is defined. A 'function' is not a construct you can manage, i.e., store or otherwise mess-with (technical term!) in the ways you might do with other kinds of data. But:

You _can_ store a function's address (i.e., a pointer to the function) and use the pointer to call the function, and you can store its parameters just as you would store any data. So, if I understand correctly what you want to do, try something like this crude outline based on my quick read of your code. It uses stored function pointers and song-numbers and shows how to call one of those functions with the associated, stored song number as a parameter:

    // Ptr to a function and a song number
    typedef struct {
       void (*pfunc)(int tune);
       int tuneNum;
    } SONG_T;

    #define COUNT 12

    void songlearn(int);
    void othersongfunc(int);
    // void moresongfunctions(int);
    // void moresongfunctions(int);

    // Table of songs & functions:
    SONG_T Songs[COUNT] = {
       {songlearn, 2},
       {othersongfunc, 1},
       {songlearn, 7},
       {othersongfunc, 3},
       // etc
    };

    void songlearn(int)
    {
     ; // does whatever it does
    }

    void othersongfunc(int)
    {
     ; // does whatever it does
    }

    void somefunc(uint8_t whichSong)
    {
       if( whichSong < COUNT )
          (*Songs[whichSong].pfunc)(Songs[whichSong].tuneNum);
    }

    void setup(void)
    {
       somefunc(3);
    }

    void loop(void)
    {
       ;
    }


message:
How to read CPU temperature into Arduino?

I'm not sure about this and if it is possible. I need to read CPU (normal computer) into an Arduino. This could be possible (at least I think) by connecting some kind of sensor that can be placed between the heatsink and the CPU, where the thermal paste is placed. Or, the second option is to read values from the system somehow, or from the motherboard. I hope I'm not talking about stupid things. I need some advice about this.

body:
Here is a simple way to send CPU temperature reading data via serial port, under Windows.

As answered in the question [Batch-file get CPU temperature in °C and set as variable][1], it is possible to build batch file (*.BAT) to get the readings and output to console. I took following option and built the BAT file.

    wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature

Now, to redirect the console to serial port, use `>` symbol. Try following and receive it in your Arduino or use serial port monitor to check (in my case it works):

    mybatfile.bat > COM1

Alternatively, you can use

    wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature > COM1

inside your BAT file.

Next, we have to specify the serial configuration, make it EXE file so it can run under Administrative account. I used [Advanced BAT to EXE converter][2]. In the tool, specify the commands:

    @echo off
    mode COM1 BAUD=38400 PARITY=n DATA=8
    wmic /namespace:\\root\wmi PATH MSAcpi_ThermalZoneTemperature get CurrentTemperature > COM1

Convert it to EXE using File->Build EXE...

[![enter image description here][3]][3]

And finally, you can [create Scheduled Task][4] to run your newly built EXE application periodically.

BTW, [WMI][5] is a powerful interface, it is possible to retrieve many other metrics and configuration data.

  [1]: https://stackoverflow.com/questions/24004300/batch-file-get-cpu-temperature-in-c-and-set-as-variable
  [2]: http://www.battoexeconverter.com/
  [3]: https://i.stack.imgur.com/JY76A.png
  [4]: https://technet.microsoft.com/en-us/library/cc748993(v=ws.11).aspx
  [5]: https://msdn.microsoft.com/en-us/library/aa394582(v=vs.85).aspx


message:
Interfacing TRRS headphone to Arduino Uno

I have been working in a Arduino project lately which requires human voice input to Arduino with some processing Arduino need to perform specific task. Simple sampling of incoming signal and calculating average amplitude from it nothing complex.

My problem is I have tried using electret microphone to receive human voice input but failed since the Elec Mic is not sensitive to detect the voice even though i hooked up with LM386 amplifier circuit. So that option is out of the picture. Then i intend to use Android mobile headphones (TRRS) to receive the human voice which will provide great sensitivity for our voice.

Starting through simple internet searches i bought a product [3.5mm breakout module from Ebay][1]. But am unsure of how to connect them to Arduino. Different sources in internet giving different information i couldn't figure out how to connect the headphone to arduino and read it's Mic output from headphone.

Seeing the pin out of TRRS headphones
[![TRRS headphone jack connection][2]][2]
i can't understand how could i possibly power my headphones with only GND pin available. I tried several wiring connections given in the internet to read the Mic output of my headphones through Analog pin A0 of Arduino but no luck so far. So my question is

**1) How do i power the TRRS headphone using Arduino?

2) How can i read the MIC output of my headphone using Arduino? Is it even possible?

3) I have read somewhere the audio out from headphones will be of FSK modulated is it true?**

Any help will be much appreciated. Please do provide if you have any links that might answer my questions.

Thanks in advance.

  [1]: http://www.ebay.in/itm/M314-3-5mm-Jack-Breakout-Board-Headset-Audio-Stereo-Socket-Extension-Module-DIY-/111937904531?
  [2]: https://i.stack.imgur.com/K2X7G.png

body:
TRRS relates to the style of the jack plug used: Tip Ring Ring Sleeve. You still need to amplify the signal with a microphone preamp the same as your electret (in fact it will be an electret in there anyway).

And then the Arduino cannot process human speech. You may be able to use [a voice recognition module](https://www.sparkfun.com/products/13316) to get it to respond to specific commands, but the Arduino by itself has no hope of even thinking about it.


body: It sounds to me as if your project is really more about what you do with the audio once you're sampling it into the Arduino and this whole "how do I get a usable signal out of a microphone" thing is not your main interest. In that case, I suggest just going with something like [this MEMS microphone breakout board](https://www.sparkfun.com/products/9868) which includes the microphone and all the circuitry necessary to get a proper signal to an analog input on the Arduino.


message:
Arduino IDE compiling for non-arduino AVR boards

Using:

- Arduino IDE 1.8.2
- the board manager from https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
- an ATmega168P MCU in TQFP

I was able to run my code successfully by modifying the file

`[ardunoIDE]\hardware\arduino\avr\variants\standard\pins_arduino.h`

building and then flashing the MCU with `avrdude`.

Is there any way to have Arduino IDE build system pick its `pins_arduino.h` file from somewhere else ?

body: Yes, MiniCore is a self-contained hardware package. After installing MiniCore select one of the MiniCore boards in the Arduino IDE's **Tools > Board** menu and the Arduino IDE will automatically use the pins_arduino.h file included with MiniCore. There is no need to modify any file in the Arduino IDE folder or any other folder.


message:
Can I connect an SD card shield to Digispark ATtiny85 board?

I have a Digispark ATtiny85 Arduino board (as shown in the picture). Can I connect a SD card shield to this board as a normal Arduino? How can I do that I'm new to this field?

[![Board im using][1]][1]

  [1]: https://i.stack.imgur.com/z5CeU.jpg

body:
In short I am going to say NO.

The flash is too small to adequately run the SD library as well as the rest of your Arduino code.

The RAM is also underpowered for what is needed to properly access files on an SD card.

Having said this, I am sure there are some clever software engineers that could write a cut down SD card library to do limited commands. Overall this is too hard for the beginner - Just buy an Arduino Uno/Mega/Due and avoid the unnecessary hassle.


body:
Yes you can connect it: http://elm-chan.org/fsw/ff/00index_p.html
Your happiness depends on what you want to accomplish. Simple streaming, like feeding an FPGA with a bitstream is achievable. Logging an incoming data stream to the SD card filesystem is probably not.


body:
    #include <SPI.h>
    #include <SD.h>

    File file;
    int const pinCS = 2;

    void setup()

    {
    SD.begin(pinCS);
    file = SD.open("Test.txt", FILE_WRITE);
    file.println("anything");
    file.close();}

    void loop()
    {}

This Arduino(ATmega) code creates to SD card a file "Test.txt" and records there a text "anything".

Dear Arduino experts, pls kindly, let me ask you, rewrite this code to ATtiny85.
It can helps to many Arduino hobby men.
Josef


message:
Multiple 3-wire SPI sensor interfacing with Arduino

I want to connect 4 MAX6675 thermocouple to Arduino.
[MAX 6675 description](https://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/MAX6675.html).

It comes with its own Arduino library. [library link](https://github.com/adafruit/MAX6675-library).

I tested the example code for one sensor and it works perfectly. Now I want to connect all the four sensors to Arduino using minimum GPIO pins possible.

I connected - (for 2 sensors only for initial testing):

    D7 -> clk (slave 1) ->clk (slave 2)
    D3 -> so (slave 1) ->so (slave 2)
    D4 -> cs (slave 1)
    D5 -> cs (slave 2)

My code (I modified the original example code a bit):

    // this example is public domain. enjoy!
    // www.ladyada.net/learn/sensors/thermocouple

    #include "max6675.h"

    int thermoCLK = 7;
    int thermoDO = 3;
    int thermoCS = 4;
    int thermoCS2 = 5;
    MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
    MAX6675 thermocouple2(thermoCLK, thermoCS2, thermoDO);

    void setup() {
      Serial.begin(9600);
      Serial.println("MAX6675 test");
      // wait for MAX chip to stabilize
      delay(500);
    }

    void loop() {
      // basic readout test, just print the current temp
      Serial.print("C = ");
      Serial.println(thermocouple.readCelsius());
      Serial.print("F = ");
      Serial.println(thermocouple.readFahrenheit());
      Serial.print("C 2= ");
      Serial.println(thermocouple2.readCelsius());
      Serial.print("F 2= ");
      Serial.println(thermocouple2.readFahrenheit());
      delay(1000);
    }

I am able to read only one sensor information correctly. The other output is *nan*. Am I wiring the circuit wrong or is my code incorrect or both?

body:
First off ditch that library. It's completely pointless and actually makes things harder.

Secondly connect your sensors to the SPI pins, selecting a new CS pin for each sensor.

* Arduino SCK (pin 13) to all the SCK pins.
* Arduino MISO (pin 12) to all the SO pins.
* Individual GPIO pins to individual CS pins (use pin 10 for one of them).

Then just use a simple function to read the data using the SPI library (adapted from the library you link to). For instance with CS on 10 an 9:

    #include <SPI.h>

    double readCelsius(uint8_t cs) {
        uint16_t v;

        digitalWrite(cs, LOW);
        v = SPI.transfer(0x00);
        v <<= 8;
        v |= SPI.transfer(0x00);
        digitalWrite(cs, HIGH);

        if (v & 0x4) {
            // uh oh, no thermocouple attached!
            return NAN;
        }

        v >>= 3;

        return v*0.25;
    }

    void setup() {
        SPI.begin();
        pinMode(10, OUTPUT);
        pinMode(9, OUTPUT);
        digitalWrite(10, HIGH);
        digitalWrite(9, HIGH);

        Serial.begin(115200);
    }

    void loop() {
        Serial.print(readCelsius(10));
        Serial.print(" ");
        Serial.println(readCelsius(9));
        delay(1000);
    }


message:
How to connect gyro to Arduino Uno via I2C

**parts**

 1. Three-axis rate gyro on breakout board: [gyro datasheet][1], [breakout board "datasheet"][2]
 2. Arduino Uno: [pinout][3]

**goal**: I want to periodically read a single axes' angular rate. As rvbarreto pointed out, Adafruit built an Arduino [library][4] for this sensor, so I'm playing around with its example file.

**configuration**:
[![poor man's EE schematic][5]][5]

I have a 5600 Ohm pull-up connected to the SDA and SCL pins each on the Arduino. The internal pull-ups of the Arduino are too weak according to [this][6] thread.

**code:** (Adafruit library's sensorapi example)

    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_FXAS21002C.h>

    /* Assign a unique ID to this sensor at the same time */
    Adafruit_FXAS21002C gyro = Adafruit_FXAS21002C(0x0021002C);
    //Adafruit_FXAS21002C gyro = Adafruit_FXAS21002C(0x21);

    void displaySensorDetails(void)
    {
      sensor_t sensor;
      gyro.getSensor(&sensor);
      Serial.println("------------------------------------");
      Serial.print  ("Sensor:       "); Serial.println(sensor.name);
      Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
      Serial.print  ("Unique ID:    0x"); Serial.println(sensor.sensor_id, HEX);
      Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" rad/s");
      Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" rad/s");
      Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" rad/s");
      Serial.println("------------------------------------");
      Serial.println("");
      delay(500);
    }

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

      /* Wait for the Serial Monitor */
      while (!Serial) {
        delay(1);
      }

      Serial.println("Gyroscope Test"); Serial.println("");

      /* Initialise the sensor */
      if(!gyro.begin())
      {
        /* There was a problem detecting the FXAS21002C ... check your connections */
        Serial.println("Ooops, no FXAS21002C detected ... Check your wiring!");
        while(1);
      }

      /* Display some basic information on this sensor */
      displaySensorDetails();
    }

    void loop(void)
    {
      /* Get a new sensor event */
      sensors_event_t event;
      gyro.getEvent(&event);

      /* Display the results (speed is measured in rad/s) */
      Serial.print("X: "); Serial.print(event.gyro.x); Serial.print("  ");
      Serial.print("Y: "); Serial.print(event.gyro.y); Serial.print("  ");
      Serial.print("Z: "); Serial.print(event.gyro.z); Serial.print("  ");
      Serial.println("rad/s ");
      delay(500);
    }

NOTE: I noticed that Adafruit's Github had [removed][7] a line of code (line 67) in their library's main .cpp file. I edited my library code to reflect that change.

**problem**: I keep getting the "Ooops, no FXAS21002C detected ... Check your wiring!" error message.

**questions**:

 1. Am I connecting my pull-up resistors correctly?
 2. Should I not power VDD and VDD_IO on the same rail? Can they even be powered by the Uno?

  [1]: http://www.nxp.com/assets/documents/data/en/data-sheets/FXAS21002.pdf
  [2]: http://cache.freescale.com/files/sensors/doc/support_info/BRKT-STBC-AGM01-QRC.pdf
  [3]: http://makezine.com/wp-content/uploads/2013/02/arduino_uno_pinout_web.png
  [4]: https://github.com/adafruit/Adafruit_FXAS21002C
  [5]: https://i.stack.imgur.com/ZK59Q.jpg
  [6]: https://electronics.stackexchange.com/questions/102611/what-happens-if-i-omit-the-pullup-resistors-on-i2c-lines
  [7]: https://github.com/adafruit/Adafruit_FXAS21002C/commit/18d4d331a8626bd1f5e21f58c835fba2d0d5ecc7

body: I needed to connect the gyro's reset input to V_DD_IO. See gyro datasheet, table 1, pin 4. This corresponds to pin 7/RST_21002 on the breakout board. The gyro works like a charm now!


message:
Char Array Buffers String UINT8

So, I have an ATTiny85 sending data, awesome.
I would like to have it send a message that consists of a few concatenated parts.

I have been reading about strings, buffers, chars, toCharArray and more for about 6 hours now and am completely puzzled by this.

Below, the variable `deze` will no transmit, but `msg` will.
So I tried to do something like `char *deze = "hello" + "world";` but that also fails.

What would be the best way to construct a piece of data that will be send by my 433MHz transmitter. I need to combine INT, String and float before sending it as uint8_t (bytes?).

    #include <RH_ASK.h>

    #define R_PIN PB4
    #define T_PIN PB1
    #define L_PIN PB3

    RH_ASK driver(2000, R_PIN, T_PIN);

    void setup()
    {
      if (!driver.init()){
        pinMode(L_PIN, OUTPUT);
        digitalWrite(L_PIN, HIGH);
        delay(500);
        digitalWrite(L_PIN, LOW);
        delay(500);
      }
    }

    void loop()
    {
      char deze[5];
      char *msg = "gewonechar";

      String thijs = "thijs";
      thijs.toCharArray(deze, sizeof(deze)-1);

      driver.send((uint8_t *)deze, strlen(msg));
      driver.waitPacketSent();
      delay(200);
    }

**[edit]**
This is the working code on the receiver side.

    struct data {
      uint16_t id;
      uint16_t pin;
      uint16_t value1;
      uint16_t value2;
    } myData;

    void loop()
    {
        uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
        uint8_t buflen = sizeof(buf);

        if (driver.recv(buf, &buflen)) {

          memcpy(&myData, buf, buflen);

          Serial.print("ID: ");
          Serial.println(myData.id);

          Serial.print("Pin: ");
          Serial.println(myData.pin);

          Serial.print("Value1: ");
          Serial.println(myData.value1);

          Serial.print("Value2: ");
          Serial.println(myData.value2);

          Serial.println("");
        }
        server.handleClient();
        yield;
    }

And the transmitter

    #include <RH_ASK.h>

    #define BAUD 2000
    #define RX 11
    #define TX 12

    RH_ASK driver(BAUD, RX, TX);

    struct data {
      uint16_t id;
      uint16_t pin;
      uint16_t value1;
      uint16_t value2;
    } myData;

    void setup() {
        Serial.begin(9600);   // Debugging only
        if (!driver.init())
             Serial.println("init failed");
    }

    void loop()
    {
        struct data myData;

        myData.id = 1001;
        myData.pin = 4;
        myData.value1 = analogRead(4);
        myData.value2 = analogRead(5);

        driver.send((uint8_t *)&myData, sizeof(myData));
        driver.waitPacketSent();
        delay(2000);
    }

Library used: http://www.airspayce.com/mikem/arduino/RadioHead/

body:
First off you never want to use `String` - especially on a chip with a mere 512 bytes of SRAM.

You should really be learning about `struct` for sending of data in the most efficient way.  A `struct` is a complex data type that combines multiple bits of data into one single variable - a bit like a record in a database.

You should avoid sending text as it is generally wasteful. The odd character, yes, but not whole strings of text.

For instance, you might want to send temperature, humidity and pressure:

    struct data {
        int8_t temperature;
        uint8_t humidity;
        uint16_t pressure;
    };

    void sendData() {
        struct data myPacket;

        myPacket.temperature = 23;
        myPacket.humidity = 72;
        myPacket.pressure = 1016;

        driver.send((uint8_t *)&myPacket, sizeof(myPacket));
        driver.waitPacketSent();
    }

With a `struct`, if you want to send text, you need to allocate enough space in the struct for your text. For instance, enough room for 9 characters plus NULL:

    struct data {
        int8_t temperature;
        uint8_t humidity;
        uint16_t pressure;
        char weather[10];
    };

Then, to get data into it, you (for example):

    strcpy_P(myData.weather, (PGM_P)F("fog"));


message:
No message got sent

I used this code:

    void setup() {
      Serial.begin(4800); //Baud rate of the GSM/GPRS Module
      Serial.print("\r");
      delay(1000);
      Serial.print("AT+CMGF=1\r");
      delay(1000);
      Serial.print("AT+CMGS=\"+918281537478\"\r");
      //Number to which you want to send the SMS
      delay(1000);
      Serial.print("Test SMS -Jay\r");
      //The text of the message to be sent
      delay(1000);
      Serial.write(0x1A);
      delay(1000);
    }

    void loop() { }

In the serial monitor AT commands were printed but no message was sent. Someone please help.

body:
Serial.print is designed to print out to the serial (programming) port.

If you are seeing these commands there then that means they are not being sent to the GSM module.


body:
I have the same code and it's working fine. But in my code, I set my baud rate `9600` means you have to change

    Serial.begin(4800);

to

    Serial.begin(9600);

And few question... which GSM Model you used? GMS SIM 300 or someone else. Becuase mine is GSM SIM 300. If you have someone else then maybe you have received some document with it, in that specific baud rate is defined. Just set it.

And then fist of all, check your GSM board is really working or not? Becuase I have this problem but that time my GSM module is not working. So, I replace and then everything working fine.

Put your SIM CARD on GSM and then make a call. If the buzzer is ringing that mean your GSM board working fine. Be sure about your arduino connection with GSM shield.

I hope this will help you.


message:
Implement Visible Light communication using Arduino

I want to implement a simple VLC based communication system using two Arduinos and send messages/data/files between two PCs. For that I have a simple transmitter circuit with an LED on Tx side and a photo-transistor on the receiver side. The codes im using for transmission and reception are attached below, also the circuit image is attached below, but im unable to bring about any communication between the two PCs, the transmitter side works fine as the LED flickers indicating data is being transferred, but its not being received by the photo transistor. I don't know what im doing wrong. Any help would be appreciated, I am doing this as a part of my academics.
Transmitter Code :

    void setup()
    {
      pinMode(9, OUTPUT);
      pinMode(10, OUTPUT);

      // Clear Timer on Compare Match (CTC) Mode
      bitWrite(TCCR1A, WGM10, 0);
      bitWrite(TCCR1A, WGM11, 0);
      bitWrite(TCCR1B, WGM12, 1);
      bitWrite(TCCR1B, WGM13, 0);

      // Toggle OC1A and OC1B on Compare Match.
      bitWrite(TCCR1A, COM1A0, 1);
      bitWrite(TCCR1A, COM1A1, 0);
      bitWrite(TCCR1A, COM1B0, 1);
      bitWrite(TCCR1A, COM1B1, 0);

      // No prescaling
      bitWrite(TCCR1B, CS10, 1);
      bitWrite(TCCR1B, CS11, 0);
      bitWrite(TCCR1B, CS12, 0);

      OCR1A = 210;
      OCR1B = 210;

      Serial.begin(2400);
    }

    void loop()
    {
      Serial.println("testing testing testing");
      delay(500);
    }

Receiver Code:

    void setup()
    {
      Serial.begin(2400);
      pinMode(13, OUTPUT);
    }

    void loop()
    {
      // if incoming serial
      if (Serial.available()) {
        readSerial();
        digitalWrite(13, HIGH);
      }
      else {
        digitalWrite(13, LOW);
      }
      delay(500);
    }
    void readSerial() {
      char val = Serial.read();
      Serial.print(val);
    }

the transmitter works fine, but the receiver is not receiving anything, I don't know what i'm doing wrong.

body: The amplitude of the signal at the photodetector is small. Better use ADC for reading.


body:
Your receiver(ldr) might not be accurate enough, rather try using an led as a receiver as well. You will just need to boost the signal then with something like a 1Mohm resistor in parallel with the receiving led.

You can use something like this as well, haven't tried it but it looks like it will work: http://www.instructables.com/id/Arduino-Communication/
maybe just a 1Mohm resistor instead of the 1Kohm one


body:
I think you have problem with your hardware side. I would like to suggest a few things; maybe it will work.

**Transmitter**

Instead of a normal LED use an IR LED because it has advantages over normal led for transmission of data like it is more secure, support max transmission speed,
less power consumption, and much more. For transmitter of signal use the following circuit. Ihave used TSOP1738 for receiver, so we need to generate the modulated IR of 38 kHz. You can use any TSOP, but you need to generate IR of respective frequency as TSOP. So using 555 timer in Astable mode to oscillate the IR at 38KHz frequency. As we know oscillation frequency of 555 timer is decided by resistor R1, R2 and capacitor C1. We have used a 1k R1, 20K R2 and 1nF capacitor to generate a frequency of approx. 38 KHz. It can be calculated using this formula: 1.44/((R1+2*R2)*C1)

 [![enter image description here][1]][1]

and instead of a push button you can use a transistor or mosfet as switch, which will be controlled with a controller.

**Receiver**

I don't know which phototransistor you are using but I'll suggest to use a **TSOP17XX**. TSOP17XX receives the modulated Infrared waves and changes its output. TSOP is available in many frequency ranges like TSOP1730, TSOP1738, TSOP1740 etc. The last two digits represent the frequency (in Khz) of modulated IR rays, on which TSOP responds. Like for example TSOP1738 reacts when it receives the IR radiation modulated at 38Khz. Means it detects the IR which is switching On and Off at the rate of 38Khz. TSOP’s output is active low, means its output is remains HIGH when there is no IR, and becomes low when it detects IR radiation. TSOP operates on particular frequency so that other IRs in the environment can’t interfere, except the modulated IR of particular frequency.

To receive the data here is some simple circuitry:

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

Instead of LED connect that pin to your receiver controller; you will get the signal properly. Hope this works for you.

Please try to perform our experiment in a noiseless (IR free) environment to get the correct output.

Reference: https://circuitdigest.com/electronic-circuits/ir-transmitter-and-receiver-circuit

  [1]: https://i.stack.imgur.com/bV6iB.gif
  [2]: https://i.stack.imgur.com/cU9q2.gif


message:
ESP8266 cannot handle struct

The following code works on a range of Arduino's but not on ESP. It returns random data for ID and Pin. The other two fields are always empty.

I use the Arduino IDE for both the ESP and the Arduino's. It looks like the ESP has it's own idea when it comes to struct.

    #include <RH_ASK.h>
    #include <SPI.h>

    #define BAUD 2000
    #define RX 2
    #define TX 5

    RH_ASK driver(BAUD, RX, TX);

    struct data {
      int id;
      int pin;
      int value1;
      int value2;
    } myData;

    void setup()
    {
        Serial.begin(9600);
        Serial.println("Starting..");
        if (!driver.init())
             Serial.println("init failed");
    }

    void loop()
    {
        uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
        uint8_t buflen = sizeof(buf);

        if (driver.recv(buf, &buflen)) {

          memcpy(&myData, buf, buflen);

          Serial.print("ID: ");
          Serial.println(myData.id);

          Serial.print("Pin: ");
          Serial.println(myData.pin);

          Serial.print("Value1: ");
          Serial.println(myData.value1);

          Serial.print("Value2: ");
          Serial.println(myData.value2);

          Serial.println("");
        }
        yield;
    }

**Bad Data**

    ID: 263145
    Pin: 18350364
    Value1: 0
    Value2: 0

**Should be**

    ID: 1001
    Pin: 4
    Value1: 267
    Value2: 843

body:
The issue is that Arduino boards (8 bit ones at least), an `int` is 16 bits, where as the ESP's (8266 and 32) and possibly other non-arduino hardware, an int is 32bits

The safest way to declare structs in any case is to use variable types with known sizes, in your case, for signed 16bit ints

    struct data {
      int16_t id;
      int16_t pin;
      int16_t value1;
      int16_t value2;
    } myData;

or for unsigned 16bit ints

    struct data {
      uint16_t id;
      uint16_t pin;
      uint16_t value1;
      uint16_t value2;
    } myData;

Note: there's also `short int` which I believe is "guaranteed" to be 16bit (and "long int" is always 32 bit) - but having the bit size in the declaration is a far better (future proof) solution


message:
Moving wiring.c functions from timer0 to timer1

I am using an Arduino Leonardo (ATmega32U4) and need to use timer0 for PWM. Since by default in the wiring.c file the functions `micros()` and `millis()` use timer0, I decided that, since timer1 isn't being used, I could set up timer1 exactly how timer0 is set up for the `micros()` and `millis()` functions and modify their code so that it all uses timer1 instead of timer0.

I think in theory this should work. I read the datasheet and timer1, while being a 16-bit timer, can run in an 8-bit fast PWM mode (which is what timer0 is set up for). So I modified wiring.c to do as above: adjusted the prescaler to match the original for timer0 (f/64) and put timer1 into fast-pwm 8-bit mode.

I modified all functions in wiring.c that used any register from timer0 and changed them to use the corresponding registers in timer1.

However, the problem is that it seems like I did everything right, but when I try to run a simple program that calls `Serial.println("hello world")`, it is messed up. The output instead shows a repeated 'h' character to the serial console. I'm not really sure what's wrong and wondering if anyone can help.

Here is my re-written wiring.c file that essentially moves all the functionalities from timer0 to timer1:

    #include "wiring_private.h"

    // the prescaler is set so that timer0 ticks every 64 clock cycles,
    // and the overflow handler is called every 256 ticks.
    #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
    // the whole number of milliseconds per timer0 overflow
    #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
    // the fractional number of milliseconds per timer0 overflow. we shift right
    // by three to fit these numbers into a byte. (for the clock speeds we care
    // about - 8 and 16 MHz - this doesn't lose precision.)
    #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
    #define FRACT_MAX (1000 >> 3)

    volatile unsigned long timer0_overflow_count = 0;
    volatile unsigned long timer0_millis = 0;
    static unsigned char timer0_fract = 0;

    #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ISR(TIM0_OVF_vect)
    #else
    /*************************** Modified wiring.c TIMER1 ISR ***********************/
    ISR(TIMER1_OVF_vect)
    #endif
    {
     // copy these to local variables so they can be stored in registers
     // (volatile variables must be read from memory on every access)
     unsigned long m = timer0_millis;
     unsigned char f = timer0_fract;

     m += MILLIS_INC;
     f += FRACT_INC;
     if (f >= FRACT_MAX) {
      f -= FRACT_MAX;
      m += 1;
     }
     timer0_fract = f;
     timer0_millis = m;
     timer0_overflow_count++;
    }
    /************************** End TIMER1 ISR **************************************/

    unsigned long millis() {
     unsigned long m;
     uint8_t oldSREG = SREG;
     // disable interrupts while we read timer0_millis or we might get
     // an inconsistent value (e.g. in the middle of a write to timer0_millis)
     cli();
     m = timer0_millis;
     SREG = oldSREG;
     return m;
    }

    /************************ Modified micros() function ****************************/
    unsigned long micros() {
     unsigned long m;
     uint8_t oldSREG = SREG, t;
     cli();
     m = timer0_overflow_count;
    #if defined(TCNT1)
     t = TCNT1;
    #else
     #error TIMER 1 not defined
    #endif

    #ifdef TIFR1
     if ((TIFR1 & _BV(TOV1)) && (t < 255))
      m++;
    #else
     #error TIFR 1 not defined
    #endif
     SREG = oldSREG;
     return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
    }
    /************************ End micros() ******************************************/

    void delay(unsigned long ms) {
     uint32_t start = micros();
     while (ms > 0) {
      yield();
      while ( ms > 0 && (micros() - start) >= 1000) {
       ms--;
       start += 1000;
      }
     }
    }

    /* Delay for the given number of microseconds.  Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */
    void delayMicroseconds(unsigned int us) {
     // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
     // calling avrlib's delay_us() function with low values (e.g. 1 or
     // 2 microseconds) gives delays longer than desired.
     //delay_us(us);
    #if F_CPU >= 24000000L
     // for the 24 MHz clock for the aventurous ones, trying to overclock
     // zero delay fix
     if (!us) return; //  = 3 cycles, (4 when true)
     // the following loop takes a 1/6 of a microsecond (4 cycles)
     // per iteration, so execute it six times for each microsecond of
     // delay requested.
     us *= 6; // x6 us, = 7 cycles

     // account for the time taken in the preceeding commands.
     // we just burned 22 (24) cycles above, remove 5, (5*4=20)
     // us is at least 6 so we can substract 5
     us -= 5; //=2 cycles

    #elif F_CPU >= 20000000L
     // for the 20 MHz clock on rare Arduino boards
     // for a one-microsecond delay, simply return.  the overhead
     // of the function call takes 18 (20) cycles, which is 1us
     __asm__ __volatile__ (
      "nop" "\n\t"
      "nop" "\n\t"
      "nop" "\n\t"
      "nop"); //just waiting 4 cycles
     if (us <= 1) return; //  = 3 cycles, (4 when true)

     // the following loop takes a 1/5 of a microsecond (4 cycles)
     // per iteration, so execute it five times for each microsecond of
     // delay requested.
     us = (us << 2) + us; // x5 us, = 7 cycles

     // account for the time taken in the preceeding commands.
     // we just burned 26 (28) cycles above, remove 7, (7*4=28)
     // us is at least 10 so we can substract 7
     us -= 7; // 2 cycles

    #elif F_CPU >= 16000000L
     // for the 16 MHz clock on most Arduino boards
     // for a one-microsecond delay, simply return.  the overhead
     // of the function call takes 14 (16) cycles, which is 1us
     if (us <= 1) return; //  = 3 cycles, (4 when true)
     // the following loop takes 1/4 of a microsecond (4 cycles)
     // per iteration, so execute it four times for each microsecond of
     // delay requested.
     us <<= 2; // x4 us, = 4 cycles

     // account for the time taken in the preceding commands.
     // we just burned 19 (21) cycles above, remove 5, (5*4=20)
     // us is at least 8 so we can subtract 5
     us -= 5; // = 2 cycles,
    #elif F_CPU >= 12000000L
     // for the 12 MHz clock if somebody is working with USB

     // for a 1 microsecond delay, simply return.  the overhead
     // of the function call takes 14 (16) cycles, which is 1.5us
     if (us <= 1) return; //  = 3 cycles, (4 when true)

     // the following loop takes 1/3 of a microsecond (4 cycles)
     // per iteration, so execute it three times for each microsecond of
     // delay requested.
     us = (us << 1) + us; // x3 us, = 5 cycles

     // account for the time taken in the preceeding commands.
     // we just burned 20 (22) cycles above, remove 5, (5*4=20)
     // us is at least 6 so we can substract 5
     us -= 5; //2 cycles

    #elif F_CPU >= 8000000L
     // for the 8 MHz internal clock

     // for a 1 and 2 microsecond delay, simply return.  the overhead
     // of the function call takes 14 (16) cycles, which is 2us
     if (us <= 2) return; //  = 3 cycles, (4 when true)

     // the following loop takes 1/2 of a microsecond (4 cycles)
     // per iteration, so execute it twice for each microsecond of
     // delay requested.
     us <<= 1; //x2 us, = 2 cycles

     // account for the time taken in the preceeding commands.
     // we just burned 17 (19) cycles above, remove 4, (4*4=16)
     // us is at least 6 so we can substract 4
     us -= 4; // = 2 cycles

    #else
     // for the 1 MHz internal clock (default settings for common Atmega microcontrollers)

     // the overhead of the function calls is 14 (16) cycles
     if (us <= 16) return; //= 3 cycles, (4 when true)
     if (us <= 25) return; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22)

     // compensate for the time taken by the preceeding and next commands (about 22 cycles)
     us -= 22; // = 2 cycles
     // the following loop takes 4 microseconds (4 cycles)
     // per iteration, so execute it us/4 times
     // us is at least 4, divided by 4 gives us 1 (no zero delay bug)
     us >>= 2; // us div 4, = 4 cycles
    #endif
     // busy wait
     __asm__ __volatile__ (
      "1: sbiw %0,1" "\n\t" // 2 cycles
      "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
     );
     // return = 4 cycles
    }

    void init() {
     // this needs to be called before setup() or some functions won't
     // work there
     sei();

     // on the ATmega168, timer 0 is also used for fast hardware pwm
     // (using phase-correct PWM would mean that timer 0 overflowed half as often
     // resulting in different millis() behavior on the ATmega8 and ATmega168)
    #if defined(TCCR0A) && defined(WGM01)
     sbi(TCCR0A, WGM01);
     sbi(TCCR0A, WGM00);
    #endif

     // set timer 0 prescale factor to 64
    #if defined(__AVR_ATmega128__)
     // CPU specific: different values for the ATmega128
     sbi(TCCR0, CS02);
    #elif defined(TCCR0) && defined(CS01) && defined(CS00)
     // this combination is for the standard atmega8
     sbi(TCCR0, CS01);
     sbi(TCCR0, CS00);
    #elif defined(TCCR0B) && defined(CS01) && defined(CS00)
     // this combination is for the standard 168/328/1280/2560
     sbi(TCCR0B, CS01);
     sbi(TCCR0B, CS00);
    #elif defined(TCCR0A) && defined(CS01) && defined(CS00)
     // this combination is for the __AVR_ATmega645__ series
     sbi(TCCR0A, CS01);
     sbi(TCCR0A, CS00);
    #else
     #error Timer 0 prescale factor 64 not set correctly
    #endif

     // enable timer 0 overflow interrupt
    #if defined(TIMSK) && defined(TOIE0)
     sbi(TIMSK, TOIE0);
    #elif defined(TIMSK0) && defined(TOIE0)
     sbi(TIMSK0, TOIE0);
    #else
     #error Timer 0 overflow interrupt not set correctly
    #endif

     // timers 1 and 2 are used for phase-correct hardware pwm
     // this is better for motors as it ensures an even waveform
     // note, however, that fast pwm mode can achieve a frequency of up
     // 8 MHz (with a 16 MHz clock) at 50% duty cycle

    /******************** Modified Code for Timer 1 *********************************/
    #if defined(TCCR1B) && defined(CS11) && defined(WGM10)
     // set timer 1 prescale factor to 64
     sbi(TCCR1B, CS11);
     sbi(TCCR1B, CS10);

     // put timer 1 in 8-bit fast pwm mode
     sbi(TCCR1B, WGM12);
     sbi(TCCR1A, WGM10);

     // enable timer 1 overflow interrupt
     sbi(TIMSK1, TOIE1);
    #endif
    /********************* End Timer 1 **********************************************/

     // set timer 2 prescale factor to 64
    #if defined(TCCR2) && defined(CS22)
     sbi(TCCR2, CS22);
    #elif defined(TCCR2B) && defined(CS22)
     sbi(TCCR2B, CS22);
    //#else
     // Timer 2 not finished (may not be present on this CPU)
    #endif

     // configure timer 2 for phase correct pwm (8-bit)
    #if defined(TCCR2) && defined(WGM20)
     sbi(TCCR2, WGM20);
    #elif defined(TCCR2A) && defined(WGM20)
     sbi(TCCR2A, WGM20);
    //#else
     // Timer 2 not finished (may not be present on this CPU)
    #endif

    /************** Modified Code for Timer 3 ***************************************/
    #if defined(TCCR3B) && defined(CS31) && defined(WGM30)
     // set timer 3 prescale factor to 64
     sbi(TCCR3B, CS31);
     sbi(TCCR3B, CS30);

     // put timer 3 in 8-bit fast pwm mode
     sbi(TCCR3B, WGM32);
     sbi(TCCR3A, WGM30);

     // enable timer 3 overflow interrupt
     sbi(TIMSK3, TOIE3);
    #endif
    /************** End Timer 3 *****************************************************/

    #if defined(TCCR4A) && defined(TCCR4B) && defined(TCCR4D) /* beginning of timer4 block for 32U4 and similar */
     sbi(TCCR4B, CS42);  // set timer4 prescale factor to 64
     sbi(TCCR4B, CS41);
     sbi(TCCR4B, CS40);
     sbi(TCCR4D, WGM40);  // put timer 4 in phase- and frequency-correct PWM mode
     sbi(TCCR4A, PWM4A);  // enable PWM mode for comparator OCR4A
     sbi(TCCR4C, PWM4D);  // enable PWM mode for comparator OCR4D
    #else /* beginning of timer4 block for ATMEGA1280 and ATMEGA2560 */
    #if defined(TCCR4B) && defined(CS41) && defined(WGM40)
     sbi(TCCR4B, CS41);  // set timer 4 prescale factor to 64
     sbi(TCCR4B, CS40);
     sbi(TCCR4A, WGM40);  // put timer 4 in 8-bit phase correct pwm mode
    #endif
    #endif /* end timer4 block for ATMEGA1280/2560 and similar */

    #if defined(TCCR5B) && defined(CS51) && defined(WGM50)
     sbi(TCCR5B, CS51);  // set timer 5 prescale factor to 64
     sbi(TCCR5B, CS50);
     sbi(TCCR5A, WGM50);  // put timer 5 in 8-bit phase correct pwm mode
    #endif

    #if defined(ADCSRA)
     // set a2d prescaler so we are inside the desired 50-200 KHz range.
     #if F_CPU >= 16000000 // 16 MHz / 128 = 125 KHz
      sbi(ADCSRA, ADPS2);
      sbi(ADCSRA, ADPS1);
      sbi(ADCSRA, ADPS0);
     #elif F_CPU >= 8000000 // 8 MHz / 64 = 125 KHz
      sbi(ADCSRA, ADPS2);
      sbi(ADCSRA, ADPS1);
      cbi(ADCSRA, ADPS0);
     #elif F_CPU >= 4000000 // 4 MHz / 32 = 125 KHz
      sbi(ADCSRA, ADPS2);
      cbi(ADCSRA, ADPS1);
      sbi(ADCSRA, ADPS0);
     #elif F_CPU >= 2000000 // 2 MHz / 16 = 125 KHz
      sbi(ADCSRA, ADPS2);
      cbi(ADCSRA, ADPS1);
      cbi(ADCSRA, ADPS0);
     #elif F_CPU >= 1000000 // 1 MHz / 8 = 125 KHz
      cbi(ADCSRA, ADPS2);
      sbi(ADCSRA, ADPS1);
      sbi(ADCSRA, ADPS0);
     #else // 128 kHz / 2 = 64 KHz -> This is the closest you can get, the prescaler is 2
      cbi(ADCSRA, ADPS2);
      cbi(ADCSRA, ADPS1);
      sbi(ADCSRA, ADPS0);
     #endif
     // enable a2d conversions
     sbi(ADCSRA, ADEN);
    #endif

     // the bootloader connects pins 0 and 1 to the USART; disconnect them
     // here so they can be used as normal digital i/o; they will be
     // reconnected in Serial.begin()
    #if defined(UCSRB)
     UCSRB = 0;
    #elif defined(UCSR0B)
     UCSR0B = 0;
    #endif
    }

body:
My suggestion would be to keep the Arduino code as is and write your own micro() and millis() utilizing timer1.

It should be fairly simple.


body:
Although I am not sure this would completely make all your changes correct, I see a potential issue in one existing line of code, that may be bad due to using a 16bits timer instead of 8bits:

    unsigned long micros() {
        unsigned long m;
        uint8_t oldSREG = SREG, t;

        cli();
        m = timer0_overflow_count;
    #if defined(TCNT1)
        t = TCNT1;
    #else
        #error TIMER 1 not defined
    #endif

    #ifdef TIFR1
        if ((TIFR1 & _BV(TOV1)) && (t < 255))
            m++;
    #else
        #error TIFR 1 not defined
    #endif

        SREG = oldSREG;

        return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
    }

Here, `t` is declared as `uint8_t` and initialized with `TCNT1`, which is a `uint16_t` (actually it is a **reference** to a `volatile uint16_t`), that may be an issue here.

I'd suggest replacing the line

    t = TCNT1

with

    t = TCNT1L

where `TCNT1L` is now a reference to `volatile uint8_t` accessing the low byte of TCNT1.


body:
Just for the record, I posted this question before I made an account by mistake, so that is why I cannot select best answer; BUT, I found the solution for anyone wondering.

I had the interrupt enabled for more than one timer (forgot to disable interrupts on the timer0 code). Once, i did that the code worked! I was able to move the millis, micros, delay, and delayMicros functions to the 16-bit timer 1!


message:
Need to set an output pin without it going LOW during initalization

For a control system I am using a relay module that controls a larger relay for high-current electrical stuff, as part of a battery protection circuit for my solar plant.  This module switches 120 VAC for the larger one.  The larger one is set up to latch the power off until a button is pressed manually.

I have several Adafruit relays, (single, dual, quad) and they all seem to be active-LOW.  I am using one of them for this project.

My problem is that I can't seem to prevent my Arduino Nano code from briefly setting the output pin LOW in setup, setting in motion the cascade involving latching the power off.

If at all possible with this hardware, I would like to prevent the need to manually reset the latch when uploading code changes.

Here is how I am initializing that pin in my setup code:

    pinMode(12,OUTPUT); digitalWrite(12,HIGH);

All in one line.  The LOW pulse is just long enough to trigger the other relay.

I know I can probably find parts like an inverter chip or maybe a different relay, but really want this working yesterday.

So my question is:  Is there any way to prevent it from pulling it LOW during initialization?  Or, is there a different approach I should take in relation to this relay output?

Thanks in advance

body:
Arduino sketches are actually (somewhat constrained) C programs.  As such, what is true for C is usually true for sketches.  In C, a segment of code usually ends with a ";".  It matters not if there are two (or more) of these on a single line.  The computer will execute the segment before the first ";" first and the segment after the first ";" second.

In this case you are setting a register inside the Atmel processor on the Nano to the "out" direction.  So it will force the associated pin to what ever the data in already set up in that pin's data register.  Then you are setting that pin's data register to high or 1.

Instead, try setting the data register to 1 before setting the direction register to "out".  Do this by switching the order of the code segments.

In case this does not work.  Or in case you find the relays acting randomly on power up, consider the relay driver inputs to be high impedance and susceptible to any noise prior to the Nano taking control of the relay driver control pins.  In such a case, consider adding pull up resistors small enough to ensure the inputs of the relay drivers are held at a known voltage but high enough such that the Atmel processor in the Nano can easily over power the pull up resistor when necessary.


message:
Yún vs Uno with Yún Shield

What are the **differences** between an Arduino Yún and a Arduino Uno with an added Yún Shield? And is there a way to expand the storage of the Yún / Yún Shield?

body:
The differences are manifold.

The biggest difference is that the Yun employs an ATMega32U4 as the MCU, whereas the Uno employs the ATMega328P. This has big ramifications with the Yun shield.

* The ATMega32U4 uses a dedicated USB connection to the USB socket, and a dedicated UART connection to the MIPS SoC.
* The ATMega328P has only a UART connection which is shared between the USB interface and the MIPS SoC.

This means that the Yun shield can interfere with the operation of the USB connection. You cannot communicate between the MIPS SoC and the Uno whilst at the same time using the USB connection, like you can with the full blown Yun. Uploading sketches can be an issue - you may want to remove the Yun shield while uploading.

The Yun is closer in operation to an Yun Shield + Arduino Leonardo than an Uno.


body:
As Majenko wrote: the Arduino Yún = Leonardo + Yún shield. You get into a lot of trouble with the Arduino Uno, and the Yún shield has already enough troubles on its own.

Maybe the Arduino Mega 2560 can be used when both the hardware and software is changed to use another hardware serial port for the Yún shield. If you start with the Yún shield, then use the Leonardo. Don't even try the Arduino Uno.

It is possible to upload a sketch via Ethernet or WiFi, but that often fails. Therefor you need the usb-serial connection to the computer to upload a sketch.

Even when you use a Arduino Leonardo, the communication between the Yún shield and the Arduino board (the 'Bridge') can cause troubles. In OpenWRT a Python script is used to read the serial data from the 'Bridge', which causes a lot of CPU usage.

The Yún shield is not fully compatible with the Arduino Yún. I think a few GPIO pins are different and maybe some other things. That means you are stuck to the firmware of the Yún shield, which can have issues and is not fully compatible with the Arduino Yún firmware.

When installing software in OpenWRT, the rootfs is filled quickly. You can type `df` or `df -h` to see the disk usage. I have read about ways to add a SD memory card or a USB flash drive to the rootfs. I have not tried that because I want OpenWRT to run even without a SD memory or USB drive.

An SD memory or USB drive can be used to store a website on it, or scripts, or music files, and so on.

When you need more memory, you might want to try the Raspberry Pi. The Raspberry Pi Zero W is very cheap and has WiFi.


message:
Common ground serial communication trouble SIM800L

I have a trouble when i'm using SIM800L module with common ground with combinaison with : FTDI232+ARDUINO PRO and Li-po battery. I use common ground to allow Arduino see the serial of SIM800L.

I use battery (lipo) to power the SIM800L to allow 2A peak current.

Serial work but sometime the module reset(i think) and i see strange character. The SIM800L no work correctly.

I meet the same trouble when i use the FTDI's VCC, every time I use the common ground i have this problem.

Look the gif you can see the problem :
[![gif trouble sim800L][1]][1]

I'm using this wiring [![Wiring sim800L][2]][2]

It's strange because when i connect the SIM800L directly with FTDI232 i have no problem all work fine.

I use this code to debug the Serial communication :

    #include <SoftwareSerial.h>
    SoftwareSerial serialSIM800(RX,TX)
    [..]
    //On Setup
     Serial.begin(115200);
      while(!Serial);

      //Being serial communication witj Arduino and SIM800
      serialSIM800.begin(115200);
      delay(1000);
      serialSIM800.print("AT\r");
      //[..]
    void loop(){

     if (serialSIM800.available())
         Serial.write(serialSIM800.read());

     if (Serial.available()) {
        while(Serial.available()){
          Serial.print(">");
          char test=Serial.read();
          Serial.print(test);
          Serial.println();
          serialSIM800.write(test);
     }

  [1]: https://i.stack.imgur.com/O7YCD.gif
  [2]: https://i.stack.imgur.com/F4eeV.jpg

There are a few things that escape me that's why I need your lights, thanks by advance.
Regards

body:
I finally fixed my issue.
I disable the auto baud rate of SIM800L trough FTDI232, with these at commands:

    AT + IPR = 9600
    AT & W

AT + IPR: Fix the baud rate at 9600
AT & W: Save in SIM800L

Then when i use with SoftwareSerial i have no issue anymore. When i reset the module with short connect RST with GND i have a good reply from SIM800L :

    RDY

    +CFUN: 1

    +CPIN: READY

    Call Ready

    SMS Ready

Thanks for your help.

Note : And be sure you are a good power supply and good wire.


message:
Switch Statement Alternative

I am working on a project where I've mapped an IR remote control to certain functions. I am currently using a massive switch statement to control the program based on the IR remote button pressed.

Is there a an alternative to using a switch statement, or is a switch the best way to go?

    decode_results results; // Initialize the results

    IRrecv irrecv(irPin); // Initialize the IR sensor

    int buttonPressed;

    void setup()
    {
      Serial.begin(115200);
      Serial.println("Tile Controller");
      analogReference(DEFAULT);
      irrecv.enableIRIn(); // Start the receiver

      Wire.begin(); // Join the I2C network
    }

    void loop()
    {
      if (irrecv.decode(&results))
      {
        if(results.value != buttonHeld)
        {
          buttonPressed = results.value;
          Serial.println(buttonPressed,HEX);
        }

        switch(buttonPressed)
        {
          case 0x3AC5: // 11 - Brightness Up
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Brightness Up Held");
              brightnessUpHeld();
            }
            else
            {
              Serial.println("Brightness Up Pressed");
              brightnessUpPressed();
            }
            break;
          }

          case 0xFFFFBA45: // 12 - Brightness Down
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Brightness Down Held");
              brightnessDownHeld();
            }
            else
            {
              Serial.println("Brightness Down Pressed");
              brightnessDownPressed();
            }
            break;
          }

          case 0xFFFF827D: // 13 - Pause
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Pause Held");
              pauseHeld();
            }
            else
            {
              Serial.println("Pause Pressed");
              pausePressed();
            }
            break;
          }

          case 0x2FD: // 14 - Power
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Power Held");
              powerHeld();
            }
            else
            {
              Serial.println("Pause Pressed");
              powerPressed();
            }
            break;
          }

          case 0x1AE5: // 21 - Red
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red Held");
              redHeld();
            }
            else
            {
              Serial.println("Red Pressed");
              redPressed();
            }
            break;
          }

          case 0xFFFF9A65: // 22 - Green
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green Held");
              greenHeld();
            }
            else
            {
              Serial.println("Green Pressed");
              greenPressed();
            }
            break;
          }

          case 0xFFFFA25D: // 23 - Blue
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue Held");
              blueHeld();
            }
            else
            {
              Serial.println("Blue Pressed");
              bluePressed();
            }
            break;
          }

          case 0x22DD: // 24 - White
          {
            if(results.value == buttonHeld)
            {
              Serial.println("White Held");
              whiteHeld();
            }
            else
            {
              Serial.println("White Pressed");
              whitePressed();
            }
            break;
          }

          case 0x2AD5: // 31 - Red 1
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red One Held");
              redOneHeld();
            }
            else
            {
              Serial.println("Red One Pressed");
              redOnePressed();
            }
            break;
          }

          case 0xFFFFAA55: // 32 - Green 1
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green One Held");
              greenOneHeld();
            }
            else
            {
              Serial.println("Green One Pressed");
              greenOnePressed();
            }
            break;
          }

          case 0xFFFF926D: // 33 - Blue 1
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue One Held");
              blueOneHeld();
            }
            else
            {
              Serial.println("Blue One Pressed");
              blueOnePressed();
            }
            break;
          }

          case 0x12ED: // 34 - White 1
          {
            if(results.value == buttonHeld)
            {
              Serial.println("White One Held");
              whiteOneHeld();
            }
            else
            {
              Serial.println("White One Pressed");
              whiteOnePressed();
            }
          }

          case 0xAF5: // 41 - Red 2
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red 2 Held");
              redTwoHeld();
            }
            else
            {
              Serial.println("Red 2 Pressed");
              redTwoPressed();
            }
            break;
          }

          case 0xFFFF8A75: // 42 - Green 2
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green 2 Held");
              greenTwoHeld();
            }
            else
            {
              Serial.println("Green 2 Pressed");
              greenTwoPressed();
            }
            break;
          }

          case 0xFFFFB24D: // 43 - Blue 2
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue 2 Held");
              blueTwoHeld();
            }
            else
            {
              Serial.println("Blue 2 Pressed");
              blueTwoPressed();
            }
            break;
          }

          case 0x32CD: // 44 - White 2
          {
            if(results.value == buttonHeld)
            {
              Serial.println("White 2 Held");
              whiteTwoHeld();
            }
            else
            {
              Serial.println("White 2 Pressed");
              whiteTwoPressed();
            }
            break;
          }

          case 0x38C7: // 51 - Red 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red 3 Held");
              redThreeHeld();
            }
            else
            {
              Serial.println("Red 3 Pressed");
              redThreePressed();
            }
            break;
          }

          case 0xFFFFB847: // 52 -  Green 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green 3 Held");
              greenThreeHeld();
            }
            else
            {
              Serial.println("Green 3 Pressed");
              greenThreePressed();
            }
            break;
          }

          case 0x7887: // 53 - Blue 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue 3 Held");
              blueThreeHeld();
            }
            else
            {
              Serial.println("Blue 3 Pressed");
              blueThreePressed();
            }
            break;
          }

          case 0xFFFFF807: // 54 - White 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("White 3 Held");
              whiteThreeHeld();
            }
            else
            {
              Serial.println("White 3 Pressed");
              whiteThreePressed();
            }
            break;
          }

          case 0x18E7: // 61 - Red 4
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red 4 Held");
              redFourHeld();
            }
            else
            {
              Serial.println("Red 4 Pressed");
              redFourPressed();
            }
            break;
          }

          case 0xFFFF9867: // 62 - Green 4
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green 4 Held");
              greenFourHeld();
            }
            else
            {
              Serial.println("Green 4 Pressed");
              greenFourPressed();
            }
            break;
          }

          case 0x58A7: // 63 - Blue 4
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue 4 Held");
              blueFourHeld();
            }
            else
            {
              Serial.println("Blue 4 Pressed");
              blueFourPressed();
            }
            break;
          }

          case 0xFFFFD827: // 64 - White 4
          {
            if(results.value == buttonHeld)
            {
              Serial.println("White 4 Held");
              whiteFourHeld();
            }
            else
            {
              Serial.println("White 4 Pressed");
              whiteFourPressed();
            }
            break;
          }

          case 0x28D7: // 71 - Red DIY Up
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red DIY Up Held");
              redDIYUpHeld();
            }
            else
            {
              Serial.println("Red DIY Up Pressed");
              redDIYUpPressed();
            }
            break;
          }

          case 0xFFFFA857: // 72 - Green DIY Up
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green DIY Up Held");
              greenDIYUpHeld();
            }
            else
            {
              Serial.println("Green DIY Up Pressed");
              greenDIYUpPressed();
            }
            break;
          }

          case 0x6897: // 73 - Blue DIY Up
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue DIY Up Held");
              blueDIYUpHeld();
            }
            else
            {
              Serial.println("Blue DIY Up Pressed");
              blueDIYUpPressed();
            }
            break;
          }

          case 0xFFFFE817: // 74 - Quick
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Quick Held");
              quickHeld();
            }
            else
            {
              Serial.println("Quick Pressed");
              quickPressed();
            }
            break;
          }

          case 0x8F7: // 81 - Red DIY Down
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Red DIY Down Held");
              redDIYDownHeld();
            }
            else
            {
              Serial.println("Red DIY Down Pressed");
              redDIYDownPressed();
            }
            break;
          }

          case 0xFFFF8877: // 72 - Green DIY Down
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Green DIY Down Held");
              greenDIYDownHeld();
            }
            else
            {
              Serial.println("Green DIY Down Pressed");
              greenDIYDownPressed();
            }
            break;
          }

          case 0x48B7: // 73 - Blue DIY Down
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Blue DIY Down Held");
              blueDIYDownHeld();
            }
            else
            {
              Serial.println("Blue DIY Down Pressed");
              blueDIYDownPressed();
            }
            break;
          }

          case 0xFFFFC837: // 84 - Slow
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Slow Held");
              slowHeld();
            }
            else
            {
              Serial.println("Slow Pressed");
              slowPressed();
            }
            break;
          }

          case 0x30CF: // 84 - DIY 1
          {
            if(results.value == buttonHeld)
            {
              Serial.println("DIY 1 Held");
              diyOneHeld();
            }
            else
            {
              Serial.println("DIY 1 Pressed");
              diyOnePressed();
            }
            break;
          }

          case 0xFFFFB04F: // 84 - DIY 2
          {
            if(results.value == buttonHeld)
            {
              Serial.println("DIY 2 Held");
              diyTwoHeld();
            }
            else
            {
              Serial.println("DIY 2 Pressed");
              diyTwoPressed();
            }
            break;
          }

          case 0x708F: // 84 - DIY 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("DIY 3 Held");
              diyThreeHeld();
            }
            else
            {
              Serial.println("DIY 3 Pressed");
              diyThreePressed();
            }
            break;
          }

          case 0x708F: // 84 - DIY 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("DIY 3 Held");
              diyThreeHeld();
            }
            else
            {
              Serial.println("DIY 3 Pressed");
              diyThreePressed();
            }
            break;
          }

          case 0xFFFFF00F: // 84 - DIY 3
          {
            if(results.value == buttonHeld)
            {
              Serial.println("Auto Held");
              autoHeld();
            }
            else
            {
              Serial.println("Auto Pressed");
              autoPressed();
            }
            break;
          }

        }
        irrecv.resume(); // Receive the next IR value
      }
    }

body:
Your switch statement isn't that big - I've seen bigger.

However, as @MarkSmith says, using an array of structs with key codes and function pointers would be a way to go.  For instance, you may have the struct:

    struct button {
        uint32_t keycode;
        void (*press)();
        void (*hold)();
    };

Populated with data it would look like:

    const struct button buttons[] = {
        { 0x3AC5, brightnessUpPressed, brightnessUpHeld },
        { 0xFFFFBA45, brightnessDownPressed, brightnessDownHeld },
        ... etc ...
        { 0xFFFFF00F, autoPressed, autoHeld },
        { 0, 0, 0 }
    };

Note the last entry of `{ 0, 0, 0 }` - this is being used as an "end of list" marker. An alternative is to keep track of how many entries are in the list, but this makes adding / removing entries easier.

Then you can iterate through the list until you find a keycode that matches or the special keycode `0`:

    for (int i = 0; buttons[i].keycode != 0; i++) {
        if (buttons[i].keycode == buttonPressed) {
            if (results.value == buttonHeld) {
                buttons[i].held();
            } else {
                buttons[i].press();
            }
            break; // We found the button, no need to continue
        }
    }

This method decreases the amount of code you have, but has the adverse effect of increasing the amount of RAM you use. It's a tradeoff between making the code simpler and using more RAM. If you can afford the RAM usage it can make things so much easier to read, since you have a simple table for the commands and a simple loop for finding the right entry in the table.


message:
Arduino with OV7670 - a buffer

I have an Arduino UNO and OV7670 camera sensor without FIFO. I wanted to build a device, that would take frame once in a while, and would send it through bluetooth (HC-05) or wi-fi (esp-01). I didn't know though, that the microcontroller inside Uno has so little RAM memory, that the frame doesn't fit inside. Moreover, even Arduino Mega has too little memory...

My question is- **is there anything I could do to take a VGA-resolution photo (circa 1MB) and send it through any serial medium**?

I suppose it'd be some kind of a buffer or memory- I'm asking for references to concrete chips or solutions (like- would it be possible to encode or compress an image on-the-fly)?

body: You need to add a FIFO buffer to the camera, or work out a scheme for streaming data from the camera over the network, because you don't have anywhere enough memory to store the image.


body:
If you're okay with grayscale, you don't need 1 MB buffer space. With the YUV422 colour space, you can extract only the Y component and need only 640*480 = 307kB buffer for a VGA grayscale image.

However, according to [this][1], you can set the hardware serial baud rate to 1M-baud and transmit the image bytes as you receive them without buffering. `main()` shows how to set up the serial port and you can also see how they received each VGA pixel byte in Bayer-RGB and transmitted immediately; notice that all interrupts are disabled first, given the high-speed nature of the transfer. But instead of Bayer, I'd recommend you use YUV422 instead, meaning the camera sends 2 bytes per pixel. Because you're only interested in the Y byte, you can place that in the UART buffer and use the time spent in receiving (and discarding) the second U/V byte to give the UART peripheral some additional breathing room to send the Y byte, before you send the next one.

Regarding the high baud rate, the crystal frequency of the Arduino doesn't matter so much because you'll only be transmitting to your PC, which should be able to handle the speed even given the rate error. Note that in `main()`, double speed async is enabled, and UBRR is set to 500 kBaud to obtain 1-Mbaud. Also notice that an 8MHz PWM signal was used to clock the camera (`XCLK` signal) with no PLLs activated in the camera register settings. [This][2] is another tutorial related to the same code; may clear up a few things.

If you really want to use a chip solution, you can look up parallel SRAM like the HM628128; it's only 128kB though, you'll need to find a bigger one to hold an entire frame of 307kB. Parallel SRAM are great because you can attain really high write speeds because of the simple interface. You'll need some sort of counter connected to the SRAM address lines clocked by the `PCLK` line (divided by 2, since you only want every other byte) so that every pulse increments the address. This same clock will feed the `nW` signal to actually clock the data into the SRAM (after satisfying address setup times somehow). The camera data lines will be connected directly to the SRAM and you activate the SRAM's chip select signal based on your monitoring of the camera's `VSYNC` signal (to know when a new frame's about to start). When the frame's done, you read from the RAM and forward the bytes to your destination.

All this assumes you aren't trying for video, merely taking frames "once in a while". Though the first solution will work for video, albeit poor video.

  [1]: https://github.com/ComputerNerd/ov7670-no-ram-arduino-uno/blob/master/main.c
  [2]: http://privateblog.info/arduino-uno-i-kamera-ov7670-primer-ispolzovaniya/


message:
HC-06 RX pin usefulness

I have a HC-06 bluetooth module. The module has an RX and TX pin (the RX pin receives data and TX transmits data) which connect to the TX and RX pin of an Arduino respectively (in my case an Arduino pro mini).

My question is in what scenario would someone use the RX pin of the module(basically for what purpose would the bluetooth module receive a signal from the Arduino)?

For example let's say i have a simple LED that i turn off and on. I just sent the signal from my phone to the module and the module sends the signal to the Arduino. So basically i've connected the TX pin of the module (which transmits the data) with the RX pin of the Arduino (which receives the data).

In order to connect the RX pin of the module with the TX pin of the Arduino i have to use a voltage divider as the module only accepts 3.3 volts of signal while the Arduino transmits 5 volts of signal. I want to avoid that because in my project i need the PCB to be quite small.

So if someone only wants to transmit data from the module to the Arduino, is there a reason on why would he connect the other two pins?

body:
If you never want to change the configuration of the module either, then no, you don't need to connect the module's RX pin.

However many people want bi-directional communication. Not only the ability to send a signal to turn the LED on or off, but also the ability to get the current state of the LED - is it on or off?

Or maybe to send an analog reading. Or the data from some sensor.

The HC-06 is a bi-directional module. If you choose to use only one direction then you only need to wire in one direction. However, tie the RX pin to 3.3V with a 10KΩ resistor to stop it floating and consuming extra power or causing random noise to be transmitted to your phone.

In fact, it's just like a phone. You can call someone up and just speak to them without listening to what they are saying. That's fine if all you want to do is call Mom and say "Pick me up in 5 minutes" and hang up. But if you want to ask your Mom "Can you pick me up in 5 minutes?" you have to actually listen for her answer "No, walk home you lazy oik!".