body:
I am trying to store some variables in a text file which is saved in a SD card, using the SD library. Every time my program runs, it load the values of those variables from the file. After a few minutes, my program will attempt to change the value of some variables (not all).

This is what I would in a C program. I would locate the position (using position()) where the values to be edited is present, and then using the seek() function I would write at the given position thus overwriting the file.

Each variable is stored in a separate row. But for some reason the program only writes at the end of the file, even if I have moved the file pointer elsewhere. **How can I do the above task?**

A simple example of the code is as follows:

    #include <SD.h> //Load SD library

    int chipSelect = 53;
    File file;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(chipSelect, OUTPUT); // chip select pin must be set to OUTPUT mode

      Serial.print("Welcome!");
      Serial.println();

      bool initialization_state = SD.begin(chipSelect);
      delay(400); // SD card needs sometime to intialize

      if (!initialization_state) { // Initialize SD card
        Serial.println("Could not initialize SD card."); // if return value is false, something went wrong
      } else {  // if return value is true
        Serial.println("SD card initialized");
      }

      SD.remove("misc.txt");
      file = SD.open("misc.txt",FILE_WRITE);
      file.print("Once you know the central idea and a rough plan for your paragraphs, you need to arrange them in a certain manner to get your story across.");
      file.println();
      file.print("Following are some possible ways of organizing your paragraphs.");
      file.println();
      file.print("Narration: Tell a story. Go chronologically, from start to finish. Description: Provide specific details about what something looks, smells, tastes, sounds, or feels like.");
      file.println();
      file.print("Organize spatially, in order of appearance, or by topic. Process: Explain how something works, step by step. Perhaps follow a sequence—first, second, third.");
      file.close();
      read_file();
      Serial.print("Read?");
      Serial.println();

      update_file();
      read_file();
    }

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

    void read_file() {
      Serial.println("--- Reading file ---");
      file = SD.open("misc.txt", FILE_READ);

      char character;
      while( (character = file.read()) != -1) {
        Serial.print(character);
      }
      Serial.println();
      file.close();
    }

    void update_file() {
      file = SD.open("misc.txt", FILE_READ);
      char character;
      while( (character = file.read()) != '\n') {}
      byte pos = file.position();
      file.close();

      file = SD.open("misc.txt", FILE_WRITE);
      file.seek(pos);
      file.print(" Love, love, love.");
      file.close();
    }

In this program I am attempting to overwrite the second line. The while loop breaks at the first newline character. I store the location of the first character in the second line in a variable pos. Then I open the file object for writing, I seek the position where I want to write (using file.seek(pos) ) and then I print into the file. But when I read the file, the text "Love, love, love." is written at the end.

I am using the linux Arduino IDE 1.8.9.

title: Editing a particular position in a file stored in SD card

Answers: 1

body:
The problem is that you are opening the file with `FILE_WRITE`.  That is a combined macro that is made up of:

    #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

The key one there is `O_APPEND`.  In the source code ([SdFile.cpp](https://github.com/arduino-libraries/SD/blob/master/src/utility/SdFile.cpp#L427)) t says:

> **O_APPEND** - If set, the file offset shall be set to the end of the file prior to each write.

So the seek does nothing if `O_APPEND` is set, since it is overridden.

So instead you need to open the file without `O_APPEND`.  In fact you don't need to close and open the file at all, since if opened correctly you can hop around at will reading and writing.  The flag `O_RDWR` is a combination of `O_READ` and `O_WRITE`.

For example:

    void update_file() {
      file = SD.open("misc.txt", O_RDWR);
      char character;
      while( (character = file.read()) != '\n') {}
      file.print(" Love, love, love.");
      file.close();
    }

The `O_CREAT` flag that is part of `FILE_WRITE` will create a new file if you try and open one that doesn't exist. By omitting that `SD.open` will fail if the file you are trying to modify doesn't exist.


body:
I have developed an application with a SunFounder Mega2560 with a W5100 Ethernet shield that acts as a server and successfully parses TCP message packets from a client sending in updates. I am now trying to add HTTP GETs into the mix by sending off my data to update an XAMPP server, which I am treating as a client in my code.

For some reason, I can't seem to connect to the XAMPP's Apache service on my machine for it to receive the HTTP message to update the MariaDB table through a PHP script I created. The Apache service seems to be listening on port 80, which I am attempting to initiate the connection on.

You can mostly just pay attention to the postData() command below, but I'm including everything for completeness.

    #include <stdlib.h>
    #include <string.h>
    #include <SPI.h>
    #include <Ethernet.h>

    #define MAX_CLIENTS 1
    #define MAX_LINE_LEN 100
    char inputs[MAX_CLIENTS][MAX_LINE_LEN] = {0}; // Instantiate 2D array of client/received data
    int msg_array[] = {0,0,0,0};

    EthernetServer server(1174);                  // Create server object on port of server, which will be used to respond to commands
    EthernetClient *client = NULL;                // Create client objects limited to size of MAX_CLIENTS
    EthernetClient db;                            // Create a client object just for posting HTTP commands to the database

    byte mac[] = {0x24,0x0A,0xC4,0xAC,0xC1,0x78}; // Arduino's physical MAC
    byte ip[] = {192,168,1,23};                   // IP of this controller
    byte gateway[] = {192,168,1,77};              // Router address (internet)
    byte myDns[] = {192,168,1,77};                // Router dns
    byte subnet[] = {255,255,0,0};                // Subnet mask
    byte dbserver[] = {192,168,1,77};             // IP address of SQL server

    unsigned long wd_Dside, wd_Cside;             // Gather current Arduino pgm ms timestamp
    unsigned long wd_Delap, wd_Celap = 0;         // Create an elapsed time counter
    int dside_prev, cside_prev = 0;       // Create a previous state for each AV to determine code execution
    char rId[3] = {0};
    int avSide = 0;

    // --------------------------------------------------------------------------------------------------------

    void setup(){

    // initialize the ethernet device
    //  Ethernet.begin(mac, ip, myDns, gateway, subnet);
      Ethernet.begin(mac, ip);

      // Open serial communications and wait for port to open:
      Serial.begin(9600);
      while (!Serial) {
      ; // wait for serial port to connect. Needed for native USB port only
      }

      // Check for Ethernet hardware present
      if (Ethernet.hardwareStatus() == EthernetNoHardware) {
        Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware.");
        while (true) {
          delay(1); // do nothing, no point running without Ethernet hardware
            }
      }

      if (Ethernet.linkStatus() == LinkOFF) {
        Serial.println("Ethernet cable is not connected.");
      }

      pinMode(22, OUTPUT);                          // pin selected to control AV D SIDE
      pinMode(23, OUTPUT);                          // pin selected to control AV C SIDE

      // wait 5 seconds for connection:

      delay(5000);
      server.begin();                                // Start server
      Serial.print("Server started on ");
      Serial.println(Ethernet.localIP());
      delay(1000);

      wd_Dside, wd_Cside = millis();

    }

    // --------------------------------------------------------------------------------------------------------

    void loop() {

      delay(100);
      int i=0;

      EthernetClient newClient = server.available();
      if (newClient) {
        if (client==NULL){
        client = new EthernetClient(newClient);
      }
      }

      if (client != NULL && client->available()){                     // If the data isn't garbage and the data is available..
        Serial.print("Client's IP address: ");
        Serial.println(client->remoteIP());
        Serial.print("Client sent: ");
        char newChar = client->read();                                // Read the data
        Serial.println(newChar);

        if (newChar == '\0') {                                        // Check for a termination character for separation
          Serial.println("Client terminated message.");
          char delimiters[] = ",";                                    // Use a string parser in order to get command parameterization
          char* valIndex;
          valIndex = strtok(inputs[i], delimiters);
          for (int j=0; j<4; j++){                                    // Expand later to largest anticipated character count
            msg_array[j] = atoi(valIndex);
            //Serial.print(msg_array[j]);
            valIndex = strtok(NULL, delimiters);
          }

          switch(msg_array[0]) {                                      // Determine type of message received via Ethernet (Character 0 parsed as Message Type)

            case 3:                                                   // Examine string for instructions to turn AVs on or off.

            char cstr[16];
            strcat(rId, itoa(msg_array[2],cstr,10));              // Build rId string prior to any potential HTTP post (which refs rId)
            strcat(rId, itoa(msg_array[3],cstr,10));
            Serial.print("R ID: ");
            Serial.println(rId);

            if(msg_array[1] == 1)                                     // Msg type 3, Instruction 1: Turn D side AV ON
              {
                avSide = 0;
                if (dside_prev != msg_array[1]){
                  Serial.println("Dside AV is OPEN.");
                  digitalWrite(22, HIGH);                             // Set pin 4 low
                  postData();                                         // Call the HTTP POST function
                }

                dside_prev = msg_array[1];
                wd_Delap = 0;                                         // Reset elapsed time watchdog time value for D side.
                wd_Dside = millis();                                  // Last good heartbeat received from client device on D side.
              }
            if(msg_array[1] == 2)                                     // Msg type 3, Instruction 2: Turn Dside AV OFF
              {
                avSide = 0;
                if (dside_prev != msg_array[1]){
                  Serial.println("Dside AV is CLOSED.");
                  digitalWrite(22, LOW);                              // Set pin 4 low
                  //postData();                                         // Call the HTTP POST function
                }

                dside_prev = msg_array[1];
                wd_Delap = 0;                                         // Reset elapsed time watchdog time value for D side.
                wd_Dside = millis();                                  // Last good heartbeat received from client device on D side.
              }
            if(msg_array[1] == 3)                                     // Msg type 3, Instruction 3: Turn Cside AV ON
              {
                avSide = 1;
                if (cside_prev != msg_array[1]){
                  Serial.println("Cside AV is OPEN.");
                  digitalWrite(23, HIGH);                             // Set pin 5 high
                  //postData();                                         // Call the HTTP POST function
                }

                cside_prev = msg_array[1];
                wd_Celap = 0;                                         // Reset elapsed time watchdog time value for C side.
                wd_Cside = millis();                                  // Last good heartbeat received from client device on C side.
              }
            if(msg_array[1] == 4)                                     // Msg type 3, Instruction 4: Turn Cside AV OFF
              {
                avSide = 1;
                if (cside_prev != msg_array[1]){
                  Serial.println("Cside AV is CLOSED.");
                  digitalWrite(23, LOW);                              // Set pin 5 high
                  //postData();                                         // Call the HTTP POST function
                }

                cside_prev = msg_array[1];
                wd_Celap = 0;                                         // Reset elapsed time watchdog time value for C side.
                wd_Cside = millis();                                  // Last good heartbeat received from client device on C side.
              }

            rId[0]='\0';                                          // Clear the array
            break;

            case 6:
                                                                      // Examine string for EA status messages
            break;

            default:
              Serial.println("Default break encountered. Received gibberish.");
            break;

          }

        inputs[0][0] = '\0';                                      // Clear out this array element for the next message
        //client->stop();                                         // By default, kill the client session and just wait for a new TCP open
        //delete client;                                          // Remove client element's data
        //client = NULL;                                          // Reset to NULL
        Serial.println(inputs[0]);

        }

        else {

           if (strlen(inputs[i]) > MAX_LINE_LEN) {                     // Append it to the message content string, but first check for size compliance
            Serial.println("Max line length exceeded from client.");
            inputs[0][0] = '\0';                                       // Clear out this array element for the next message
           }
           else {
            size_t l = strlen(inputs[0]);
            inputs[0][l] = newChar;
            inputs[0][l + 1] = 0;
            // strcat(inputs[i], newChar);                             // Add character to the received string
           }

          Serial.print("inputs[0]: ");
          Serial.println(inputs[0]);

        }
      }

    /* Update watchdog timers

    wd_Delap = (millis()-wd_Dside);
    wd_Celap = (millis()-wd_Cside);

    if (wd_Delap>=60000)
          {
            Serial.print("Elapsed time on watchdog, D side: ");
            Serial.println(wd_Delap);
            Serial.print("Last message recieved: ");
            Serial.println(wd_Dside);
            digitalWrite(4, LOW);    // set pin 4 low
            Serial.println("Dside AV didn't hear from anyone in 60s; defaulting to OFF.");
          }

    if (wd_Celap>=60000)
          {
            Serial.print("Elapsed time on watchdog, C side: ");
            Serial.println(wd_Celap);
            Serial.print("Last message recieved: ");
            Serial.println(wd_Cside);
            digitalWrite(5, LOW);    // set pin 5 low
            Serial.println("Cside AV didn't hear from anyone in 60s; defaulting to OFF.");
          }
      */
    }

    // Section to update database via HTTP
    void postData() {
      Serial.println("Hit postData");
      client->stop();

      delay(250);
      Serial.println("Stopping and reconnecting.");

      if (db.connect(dbserver, 80)) {
        Serial.println("Connected to DB host machine.");
        db.print("GET /write_data.php?");

        db.print("RID=");
        db.print(rId);
        db.print("&");

        db.print("side=");
        db.print(avSide);
        db.print("&");

        db.print("state=");
        db.print("1");

        db.println(" HTTP/1.1");
        db.println("Host: localhost");
        db.println("User-Agent: Arduino/1.0");
        db.println("Connection: close");
        db.println();
        db.println();
        db.stop();

      }
      else {
      Serial.println("Connection failed to DB host machine.");
      }

      delay(5000);
    }

This is the output:

    Client's IP address: 192.168.1.77
    Client sent: ,
    inputs[0]: ,
    Client's IP address: 192.168.1.77
    Client sent: 3
    inputs[0]: ,3
    Client's IP address: 192.168.1.77
    Client sent: ,
    inputs[0]: ,3,
    Client's IP address: 192.168.1.77
    Client sent: 1
    inputs[0]: ,3,1
    Client's IP address: 192.168.1.77
    Client sent: ,
    inputs[0]: ,3,1,
    Client's IP address: 192.168.1.77
    Client sent: 3
    inputs[0]: ,3,1,3
    Client's IP address: 192.168.1.77
    Client sent: ,
    inputs[0]: ,3,1,3,
    Client's IP address: 192.168.1.77
    Client sent: 7
    inputs[0]: ,3,1,3,7
    Client's IP address: 192.168.1.77
    Client sent:
    Client terminated message.
    R ID: 37
    Dside AV is OPEN.
    Hit postData
    Connecting...
    Connection failed to DB host machine.

Am I maybe initializing something incorrectly, or am I becoming a victim to one of the commonly references issues with the Ethernet library not being able to handle multiple connections on the Arduino?

Thanks!

EDIT:
Well with some troubleshooting of the HTTP methods and formats to address the URI, I didn't turn up much; But I did by chance notice that changing my semicolons to ampersands for the value fields are what did the trick! I have achieved communication to my MariaDB! The issue I'm having now is that the client disconnects after dumping the information to the database, and does not re-enter the normal loop to wait on another message.

My postData() routine above has been edited to show what I am doing. The main loop is looping, but does not show that the server() receives anything like it would previously.

title: Arduino Mega failing to connect to XAMPP database/php server to send HTTP requests

Answers: 0


body:
I am making a 6-axis robotic arm that uses multiple servo motors.The goal is to create a program that accepts degree values from the serial monitor to control multiple servo motors.

I have just started programming with the Arduino, so I need help debugging a program that I have piece together from guides throughout the internet. The program will compile and upload, but when I input values into the serial monitor the servo will not move like I would like it to. At the moment, the servo motor will move 50 degrees. I have calibrated my servo but it still won't work properly. Furthermore, I kept the program for one servo just for testing I know that I will have to create an int motorA=0; motorB=1; etc. Any help will be appreciated

reference links:
https://forum.arduino.cc/index.php?topic=242458.0
https://www.youtube.com/watch?v=y8X9X10Tn1k

Hardware:
Arduino Uno
16 channel Arduino Servo shield
5v external power supply
MG995 Servo

Notes:
No connectivity issues
Motor is connected properly
No hardware issues

Program:

    enter code here
    String readString;
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>

    #define SERVOMIN  650
    #define SERVOMAX  2350
    #define FREQUENCY 60

    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

    int motorA = 0;
    int motorB = 1;

    void setup()
    { // put your setup code here, to run once:
      Serial.begin(9600);
      pwm.begin();
      pwm.setPWMFreq(FREQUENCY);
    }

    void moveMotor(int ang, int motorOut)
    {

     int angle = map(ang,0, 180, SERVOMIN,SERVOMAX);
     for ( uint16_t pulse_width = 0; pulse_width < angle; pulse_width++)
     {
       pwm.setPWM(motorOut, 0, pulse_width);

     }
    }

    void loop()
    {
     //expect single strings like 30c, or 90a, or 180d,
    //or combined like 30c,180b,70a,120d,

    if (Serial.available())
    {
      char c = Serial.read();  //gets one byte from serial buffer
      if (c == ',')
      {
        if (readString.length() >1)
        {
         Serial.println(readString); //prints string to serial port out

         int angle = readString.toInt();  //convert readString into a number

         Serial.print("writing Angle: ");
         Serial.println(angle);
         if (readString.indexOf('a') >0) moveMotor(angle, motorA);

         readString=""; //clears variable for new input
       }
     }
    else {
      readString += c; //makes the string readString
      }
     }
    }

title: Issues controlling servo motors with serial monitor while using 16 channel servo Shield

Answers: 0


body:
I'm new to the Arduino and I asked some questions around here and they were really helpful so I'm hoping I will get help once more
```
#define maxLen 800

volatile  unsigned int irBuffer[maxLen]; //stores timings - volatile because changed by ISR
volatile unsigned int x = 0; //Pointer thru irBuffer - volatile because changed by ISR

void setup() {
  Serial.begin(9600); //change BAUD rate as required
  attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//set up ISR for receiving IR signal
}

void loop() {

  Serial.println(F("Press the button on the remote now - once only"));
  delay(5000); // pause 5 secs
  if (x) { //if a signal is captured
    Serial.println();
    Serial.print(F("Raw: (")); //dump raw header format - for library
    Serial.print((x - 1));
    Serial.print(F(") "));
    detachInterrupt(0);//stop interrupts & capture until finshed here
    for (int i = 1; i < x; i++) { //now dump the times
      if (!(i & 0x1)) Serial.print(F(" "));
      Serial.print(irBuffer[i] - irBuffer[i - 1]);
      Serial.print(F(", "));
    }
    x = 0;
    Serial.println();
    Serial.println();
    attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//re-enable ISR for receiving IR signal
  }

}

void rxIR_Interrupt_Handler() {
  if (x > maxLen) return; //ignore if irBuffer is already full
  irBuffer[x++] = micros(); //just continually record the time-stamp of signal transitions

}
```
I would like to modify the code above to write to an SD file instead of printing it on the serial port. I've tried to use myFile.write or myFile.print but it won't work. Maybe I am just not that aware of how the SD functions work. Any tips?
This is a function to capture IR signals. I require them for a Arduino remote.
The modified code:
```
//you may increase this value on Arduinos with greater than 2k SRAM
#define maxLen 800

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

File myFile;

volatile  unsigned int irBuffer[maxLen]; //stores timings - volatile because changed by ISR
volatile unsigned int x = 0; //Pointer thru irBuffer - volatile because changed by ISR

void setup() {
  Serial.begin(9600); //change BAUD rate as required
  attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//set up ISR for receiving IR signal
}

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

  Serial.print("Initializing SD card...");

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

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  Serial.println(F("Press the button on the remote now - once only"));
  delay(5000); // pause 5 secs
  if (x) { //if a signal is captured
    Serial.println();
    myFile.print(F("Raw: (")); //dump raw header format - for library
    myFile.print((x - 1));
    myFile.print(F(") "));
    detachInterrupt(0);//stop interrupts & capture until finshed here
    for (int i = 1; i < x; i++) { //now dump the times
      if (!(i & 0x1)) myFile.write(F(" "));
      myFile.print(irBuffer[i] - irBuffer[i - 1]);
      myFile.print(F(", "));
    }
    x = 0;
    Serial.println();
    Serial.println();
    attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//re-enable ISR for receiving IR signal
  }

}

void rxIR_Interrupt_Handler() {
  if (x > maxLen) return; //ignore if irBuffer is already full
  irBuffer[x++] = micros(); //just continually record the time-stamp of signal transitions

}
```

title: Write an array to SD

Answers: 1

body:
You are never closing the file.  The SD library (owing to how SD cards work) operates around a 512 byte buffer. Only when that buffer is full, or the library is manually instructed, will that buffer ever get written to the SD card.

The two ways of forcing the buffer to be written to the card are:

* Close the file with `myFile.close()` or
* Flush the file with `myFile.flush()`

Unless you do one of those after storing your data, since you are writing less than 512 bytes, the data will be lost when you power off (or reset) or remove the SD card.


body:
I'm trying to send arduino data to my online web server using a Arduino Uno and a Ethernet shield. I used POST method for sending data and tried sending data to my sever (add.php) using a online POST request generating  site (https://www.codepunker.com/tools/http-requests) . That works perfect and it updated my database with sent data. But my database doesn't get any data when I try to send data with Arduino and Ethernet shield. Any suggestions to make this work? What changes should I do to my arduino code?

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

**Serial Out**

    Initialize Ethernet with DHCP:
    DHCP assigned IP 192.168.1.102
    connected to 145.14.145.94
    still working here
    temp1=10&hum1=24
    Successfull
    Client Stopped

**Arduino Code**

      #include <SPI.h>
      #include <Ethernet.h>

      byte mac[] = { 0x00, 0xAB, 0xBA, 0xBC, 0xDD, 0x02 };
      EthernetClient client;
      String data;
      int t;
      int h;
      IPAddress ip(192, 168, 1, 177);
      IPAddress myDns(192, 168, 1, 1);
      char server[] = "lattalottaroom2.000webhostapp.com";

      void setup() {
        Serial.begin(9600);
        Serial.println("Initialize Ethernet with DHCP:");
        if (Ethernet.begin(mac) == 0) {
          Serial.println("Failed to configure Ethernet using DHCP");
          // Check for Ethernet hardware present
          if (Ethernet.hardwareStatus() == EthernetNoHardware) {
            Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
            while (true) {
              delay(1); // do nothing, no point running without Ethernet hardware
            }
          }
          if (Ethernet.linkStatus() == LinkOFF) {
            Serial.println("Ethernet cable is not connected.");
          }
          // try to congifure using IP address instead of DHCP:
          Ethernet.begin(mac, ip, myDns);
        } else {
          Serial.print("  DHCP assigned IP ");
          Serial.println(Ethernet.localIP());
        }

        // if you get a connection, report back via serial:
        if (client.connect(server, 80)) {
          Serial.print("connected to ");
          Serial.println(client.remoteIP());
        } else {
          // if you didn't get a connection to the server:
          Serial.println("connection failed");
        }

        Serial.println("still working here");

      }

      void loop() {
      t = 10;
      h = 24;

      data = "temp1=";

      data.concat(t);

      data.concat("&hum1=");

      data.concat(h);

        if (client.connect("lattalottaroom2.000webhostapp.com",80)) {
          Serial.println(data);
          client.print("POST /add.php HTTP/1.1");
          client.print("Host: lattalottaroom2.000webhostapp.com");
          client.print("Connection: close");
          client.print("Content-Type: application/x-www-form-urlencoded");
          client.print("Content-Length: ");
          client.println(data.length());
          client.println();
          client.print(data);
          Serial.println("Successfull");

        }

        if (client.connected()) {
          client.stop();
          Serial.println("Client Stopped");

        }

        delay(20000);
      }

**connect.php**

    <?php

      function Connection(){
          $server="localhost";
          $user="id10666900_arduinodata";
          $pass="thunder";
          $db="id10666900_arduinodata";

          $connection = mysqli_connect($server,$user,$pass,$db);

          if (!$connection) {
              die('MySQL ERROR: ' . mysqli_connect_error());
          }

          return $connection;
      }
  ?>

**add.php**

    <?php
          include("connect.php");

          $link=Connection();

          $query = "INSERT INTO `tempLog` (temp, hum) VALUES ('".$_POST["temp1"]."','"$_POST["hum1"]."')";

                  if (mysqli_query($link, $query)) {
                     echo "New record created successfully";
                  } else {
                     echo "Error: " . $query . "" . mysqli_error($link);
                  }

                  $link->close();

          header("Location: index.php");
      ?>

  [1]: https://i.stack.imgur.com/G57M0.png
  [2]: https://i.stack.imgur.com/ry5Kt.png

title: Send Arduino data to PHP inorder to upload in MySQL database

Answers: 0


body:
I am reading from two MPU6050 sensors using Arduino Uno but it give trouble in squence. The code is perfect and also sensors reading is done.
See image of serial monitor.

>[![Reading of sensors data][1]][1]

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

You can see the above image in which the output data of serial monitor is not lining up. It breaks the lines after some time interval. I want to expect the serial data in lining. Here is the code:

    // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
    // for both classes must be in the include path of your project
    #include "I2Cdev.h"

    #include "MPU6050_6Axis_MotionApps20.h"
    //#include "MPU6050.h" // not necessary if using MotionApps include file

    // Arduino Wire library is req1uired if I2Cdev I2CDEV_ARDUINO_WIRE implementation
    // is used in I2Cdev.h
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif

    // class default I2C address is 0x68
    // specific I2C addresses may be passed as a parameter here
    // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
    // AD0 high = 0x69
    //MPU6050 mpu;
    MPU6050 mpu1(0x68);
    MPU6050 mpu2(0x69); // <-- use for AD0 high

    // uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
    // pitch/roll angles (in degrees) calculated from the q1uaternions coming
    // from the FIFO. Note this also req1uires gravity1 vector calculations.
    // Also note that yaw/pitch/roll angles suffer from gimbal lock (for
    // more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
    #define OUTPUT_READABLE_YAWPITCHROLL

    int pre_count = 0;

    #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
    bool blinkState = false;

    // MPU control/status vars
    bool dmpReady1 = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus1;   // holds actual interrupt status byte from MPU
    uint8_t devStatus1;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize1;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount1;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer1[64]; // FIFO storage buffer

    // MPU control/status vars
    bool dmpReady2 = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus2;   // holds actual interrupt status byte from MPU
    uint8_t devStatus2;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize2;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount2;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer2[64]; // FIFO storage buffer

    // orientation/motion vars
    Quaternion q1;           // [w, x, y, z]         q1uaternion container
    VectorInt16 aa1;         // [x, y, z]            accel sensor measurements
    VectorInt16 aa1Real1;     // [x, y, z]            gravity1-free accel sensor measurements
    VectorInt16 aa1World1;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity1;    // [x, y, z]            gravity1 vector
    float euler1[3];         // [psi, theta, phi]    euler1 angle container
    float ypr1[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

    // packet structure for InvenSense teapot demo
    uint8_t teapotPacket1[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

    Quaternion q2;           // [w, x, y, z]         q1uaternion container
    VectorInt16 aa2;         // [x, y, z]            accel sensor measurements
    VectorInt16 aa1Real2;     // [x, y, z]            gravity1-free accel sensor measurements
    VectorInt16 aa1World2;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity2;    // [x, y, z]            gravity1 vector
    float euler2[3];         // [psi, theta, phi]    euler1 angle container
    float ypr2[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

    // packet structure for InvenSense teapot demo
    uint8_t teapotPacket2[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

    // ================================================================
    // ===               INTERRUPT DETECTION ROUTINE                ===
    // ================================================================

    volatile bool mpuInterrupt1 = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady1() {
      mpuInterrupt1 = true;
    //  Serial.println("Mpu interrupt true");
    }

    volatile bool mpuInterrupt2 = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady2() {
      mpuInterrupt2 = true;
    }

    // ================================================================
    // ===                      INITIAL SETUP                       ===
    // ================================================================

    void setup() {
      // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
      Wire.begin();
      TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
      Fastwire::setup(400, true);
    #endif

      // initialize serial communication
      // (115200 chosen because it is req1uired for Teapot Demo output, but it's
      // really up to you depending on your project)
      Serial.begin(115200);
      while (!Serial); // wait for Leonardo enumeration, others continue immediately

      // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
      // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
      // the baud timing being too misaligned with processor ticks. You must use
      // 38400 or slower in these cases, or use some kind of external separate
      // crystal solution for the UART timer.

      // initialize device
      Serial.println(F("Initializing I2C devices 1..."));
      mpu1.initialize();

       // initialize device
      Serial.println(F("Initializing I2C devices 2..."));
      mpu2.initialize();

      // verify connection
      Serial.println(F("Testing device 1 connections..."));
      Serial.println(mpu1.testConnection() ? F("MPU6050 1 connection successful") : F("MPU6050 1 connection failed"));

      // verify connection
      Serial.println(F("Testing device 2 connections..."));
      Serial.println(mpu2.testConnection() ? F("MPU6050 2 connection successful") : F("MPU6050 2 connection failed"));

      // wait for ready
      Serial.println(F("\nSend any character to begin DMP programming and demo: "));
      while (Serial.available() && Serial.read()); // empty buffer
      while (!Serial.available());                 // wait for data
      while (Serial.available() && Serial.read()); // empty buffer again

      // load and configure the DMP
      Serial.println(F("Initializing DMP 1..."));
      devStatus1 = mpu1.dmpInitialize();

      // load and configure the DMP
      Serial.println(F("Initializing DMP 2..."));
      devStatus2 = mpu2.dmpInitialize();

      // supply your own gyro offsets here, scaled for min sensitivity
      mpu1.setXGyroOffset(220);
      mpu1.setYGyroOffset(76);
      mpu1.setZGyroOffset(-85);
      mpu1.setZAccelOffset(1788); // 1688 factory default for my test chip

      // supply your own gyro offsets here, scaled for min sensitivity
      mpu2.setXGyroOffset(74);
      mpu2.setYGyroOffset(14);
      mpu2.setZGyroOffset(-19);
      mpu2.setZAccelOffset(253); // 1688 factory default for my test chip

      // make sure it worked (returns 0 if so)
      if (devStatus1 == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP 1..."));
        mpu1.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady1, RISING);
        mpuIntStatus1 = mpu1.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP 1 ready! Waiting for first interrupt..."));
        dmpReady1 = true;

        // get expected DMP packet size for later comparison
        packetSize1 = mpu1.dmpGetFIFOPacketSize();
      } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP 1 Initialization failed (code "));
        Serial.print(devStatus1);
        Serial.println(F(")"));
      }

      // make sure it worked (returns 0 if so)
      if (devStatus2 == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP 2..."));
        mpu2.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady2, RISING);
        mpuIntStatus2 = mpu2.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP 2 ready! Waiting for first interrupt..."));
        dmpReady2 = true;

        // get expected DMP packet size for later comparison
        packetSize2 = mpu2.dmpGetFIFOPacketSize();
      } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP 2 Initialization failed (code "));
        Serial.print(devStatus2);
        Serial.println(F(")"));
      }

      // configure LED for output
      pinMode(LED_PIN, OUTPUT);
    }

    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================

    void loop() {

      // if programming failed, don't try to do anything
      if (!dmpReady1) return;

      // if programming failed, don't try to do anything
      if (!dmpReady2) return;

    // Serial.println("code access here 1");
      // wait for MPU interrupt or extra packet(s) available
      while (!mpuInterrupt1 && fifoCount1 < packetSize1) {
        // other program behavior stuff here
        // .
        // .
        // .
        // if you are really paranoid you can freq1uently test in between other
        // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
        // while() loop to immediately process the MPU data
        // .
        // .
        // .
         break;

    //    Serial.println("code access here 2");
      }

      // wait for MPU interrupt or extra packet(s) available
      while (!mpuInterrupt2 && fifoCount2 < packetSize2) {
        // other program behavior stuff here
        // .
        // .
        // .
        // if you are really paranoid you can freq1uently test in between other
        // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
        // while() loop to immediately process the MPU data
        // .
        // .
        // .
        break;
      }

      // reset interrupt flag and get INT_STATUS byte
      mpuInterrupt1 = false;
      mpuIntStatus1 = mpu1.getIntStatus();

      // reset interrupt flag and get INT_STATUS byte
      mpuInterrupt2 = false;
      mpuIntStatus2 = mpu2.getIntStatus();

      // get current FIFO count
      fifoCount1 = mpu1.getFIFOCount();

      // get current FIFO count
      fifoCount2 = mpu2.getFIFOCount();

      // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus1 & 0x10) || fifoCount1 == 1024) {
        // reset so we can continue cleanly
        mpu1.resetFIFO();
        Serial.println(F("FIFO overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
      } else if (mpuIntStatus1 & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount1 < packetSize1) fifoCount1 = mpu1.getFIFOCount();

        // read a packet from FIFO
        mpu1.getFIFOBytes(fifoBuffer1, packetSize1);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount1 -= packetSize1;

    #ifdef OUTPUT_READABLE_YAWPITCHROLL
        // display euler1 angles in degrees
        mpu1.dmpGetQuaternion(&q1, fifoBuffer1);
        mpu1.dmpGetGravity(&gravity1, &q1);
        mpu1.dmpGetYawPitchRoll(ypr1, &q1, &gravity1);
        int count = 0;
        count++;
        pre_count += count;
        Serial.print(pre_count);
        Serial.print("\t");
        Serial.print(ypr1[0] * 180 / M_PI);
        Serial.print("\t");
        Serial.print(ypr1[1] * 180 / M_PI);
        Serial.print("\t");
        Serial.print(ypr1[2] * 180 / M_PI);
        Serial.print("\t");
    #endif

    //    // blink LED to indicate activity
    //    blinkState = !blinkState;
    //    digitalWrite(LED_PIN, blinkState);
      }

       // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus2 & 0x10) || fifoCount2 == 1024) {
        // reset so we can continue cleanly
        mpu2.resetFIFO();
        Serial.println(F("FIFO 2 overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
      } else if (mpuIntStatus2 & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount2 < packetSize2) fifoCount2 = mpu2.getFIFOCount();

        // read a packet from FIFO
        mpu2.getFIFOBytes(fifoBuffer2, packetSize2);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount2 -= packetSize2;

    #ifdef OUTPUT_READABLE_YAWPITCHROLL
        // display euler1 angles in degrees
        mpu2.dmpGetQuaternion(&q2, fifoBuffer2);
        mpu2.dmpGetGravity(&gravity2, &q2);
        mpu2.dmpGetYawPitchRoll(ypr2, &q2, &gravity2);
        Serial.print("\t");
        Serial.print(ypr2[0] * 180 / M_PI);
        Serial.print("\t");
        Serial.print(ypr2[1] * 180 / M_PI);
        Serial.print("\t");
        Serial.println(ypr2[2] * 180 / M_PI);
    #endif

    //    // blink LED to indicate activity
    //    blinkState = !blinkState;
    //    digitalWrite(LED_PIN, blinkState);
      }

       // blink LED to indicate activity
        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }

What is the problem?
Thanks in advance!

title: Trouble in sensor data reading sequence

Answers: 1

body:
Both printing codes are inside of different if statements, which involve testing `mpuIntStatus1` and `mpuIntStatus2`. This works good, as long as in one `void loop()` iteration both of these if statements are executed. But that's a timing issue and you cannot assume, that these things happen regularly and always this way. Without completely analyzing your code, the variables `mpuIntStatus1/2` seem to indicate, that new data arrived. There is no reason, why this should be synchronized with the `void loop()` iterations.

To solve this you should rewrite your code to include all these print statements into one single if statement at the end of `void loop()`. In the if statements from above you can set a flag to indicate, that data arrived. This flag will be tested by the if statement at the end of loop. It is up to you to decide, how this should behave, when only data from 1 sensor arrived. You can only print the values from this sensor, or you can print both and using dummy values, that can be distinguished by humans (for example all values zero). Or you can choose to only print out values, if both sensors have given you results.


body:
I have one Ir temperature mlx90615 sensor based of this connection only used for mega2560 RX1&TX1) :

[![enter image description here][1]][1]
Which is connected to one Arduino 2560 mega with one LCD TFT 2.4 like this (Arduino mega2560 RX1 TX2 instead of Uno for mlx90615 connection and UNO 3.5V and Ground used to power supply the MLX90615):
[![enter image description here][2]][2]

So my problem is when i insert some new object in the seen area of Ir sensor the output halt for some second delay and don't show new value  via serial point or LCD output.

it characteristic table via [datasheet of mlx90615][3] sensor is :

[![enter image description here][4]][4]

[![enter image description here][5]][5]

I have use this source code on library for mlx90615 into my codes by this function:
```

or(i=0;i<8;i++){
  i=1;
 serialEvent();
  if(sign)
  {
     sign=0;
     for(i=0;i<8;i++)
      sum+=Re_buf[i];
     if(sum==Re_buf[i] )
     {
           TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
//           Serial.print("TO:");
//           Serial.println(TO);
//           TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
//           Serial.print("TA:");
//           Serial.println(TA);

             tft.fillScreen(BLACK);
             tft.setTextColor(WHITE);
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);

            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);
            tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
   }
  }

 }

void serialEvent(){
  char i;
  Serial1.write(0XA5);
  Serial1.write(0X15);
  Serial1.write(0XBA);
  for (i=0;i<30;i++)
  {
    while (Serial1.available()) {

    Re_buf[counter]=(unsigned char)Serial1.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;i=600;
       sign=1;
    }
  }
  }
}
```

The total codes are here:

```
#include "LiquidCrystal.h"

 #include <Adafruit_GFX.h>    // Adafruit's core graphics library
#include <Adafruit_TFTLCD.h> // Adafruit's hardware-specific library
#include <TouchScreen.h>     //Touchscreen library
///#include <Fonts/Org_01.h>    //Include a different font
#include <EEPROM.h>         //Include the EEPROM library to score the highscore
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#include <TimeLib.h>

bool backsensed = false;
bool resetsensed = false;

// most mcufriend shields use these pins and Portrait mode:
uint8_t YP = A1;  // must be an analog pin, use "An" notation!
uint8_t XM = A2;  // must be an analog pin, use "An" notation!
uint8_t YM = 7;   // can be a digital pin
uint8_t XP = 6;   // can be a digital pin

#define TS_MINX 100
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
//Create the touchscreen object
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);  //(data,data,data,data,sensitivity);

//Some of the tft pins
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// Optional, used to reset the display
#define LCD_RESET A4

#define REDBAR_MINX 80
#define GREENBAR_MINX 130
#define BLUEBAR_MINX 180
#define BAR_MINY 30
#define BAR_HEIGHT 250
#define BAR_WIDTH 30

//Create the tft object
//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

// Define some TFT readable colour codes to human readable names
#define BLACK   0x0000
int BLUE = tft.color565(50, 50, 255);
#define DARKBLUE 0x0010
#define VIOLET 0x8888
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
int GREY =  tft.color565(64, 64, 64);
#define GOLD 0xFEA0
#define BROWN 0xA145
#define SILVER 0xC618
#define LIME 0x07E0

int currentpcolour;

//Minimum and maximum pressure to sense the touch
#define MINPRESSURE 10
#define MAXPRESSURE 1000

#define DRAW_LOOP_INTERVAL 50  //The interval used instead of delay();

//Define the address used in the eeprom memory to store highscores
#define addr 0
int currentpage;

int currentWing;        //Used to flap the wings
int flX, flY, fallRate; //Used to calculete and store the bird's position
int pillarPos, gapPosition;  //Used tho draw the pillars
int score;              //Store the score
int highScore = 0;      //Store the highscore
bool running = false;   //Store weather flying or not
bool crashed = false;   //Store weather crashed or not
bool scrPress = false;  //Store weather sensed some touch and store
long nextDrawLoopRunTime;
int redval;
int greenval;
int blueval;

int redpos = BAR_MINY + 12;
int greenpos = BAR_MINY + 12;
int bluepos = BAR_MINY + 12;

int oldrpos = redpos;
int oldgpos = greenpos;
int oldbpos = bluepos;
int x, y;

int lastDay = 0;
int lastMonth = 0;
int lastYear = 0;
int lastHour = 0;
int lastMinute = 0;
int lastSecond=0;
int movementTimer = 0;
int menuOptions = 4;
int menuOption = 0;
int alarmHours = 0;
//int Heater_alarmMinutes = 0;
//int Heater_alarmSecond=10;
//int Motor_alarmSecond=10;
//int Motor_alarmMinutes=0;

byte Heater_alarmMinutes_end ;
byte Heater_alarmSecond_end;
byte Motor_alarmSecond_end;
byte Motor_alarmMinutes_end;

bool heater_key = 0;
bool backLightOn = 1;
int fadeValue = 255;

byte address=0;
byte value;

bool state=1;

//#$############# MLX9615 ##################

 unsigned char Re_buf[11],counter=0;
 char sign=0;
float TO=0,TA=0;
void serialEvent();

//########################################
void DrawTriangle() {
 int n, i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1;

 tft.fillScreen(BLACK);
 n = min(cx, cy);

 for (i = 0; i < n; i += 15) {
 tft.drawTriangle(
 cx , cy - i, // peak
 cx - i, cy + i, // bottom left
 cx + i, cy + i, // bottom right
 tft.color565(0, 0, i));
 }
}
void drawHome()
{

  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game

  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);

  tft.fillRoundRect(60, 80, 200, 40, 8, RED);
  tft.drawRoundRect(60, 80, 200, 40, 8, WHITE); //Oscilloscope

  tft.setCursor(60, 20);
  tft.setTextSize(2);
///  tft.setFont();
  tft.setTextColor(WHITE);
  tft.print("Select on Option");
  tft.setCursor(70, 50);
  tft.setTextSize(2);
  tft.setTextColor(LIME);
  tft.print("GSH.ir");
  tft.setTextColor(BLACK);

  tft.setCursor(80, 95);
  tft.print("Heater Setting");

  tft.setCursor(80, 145);
  tft.print("Motor  Setting");

  tft.setCursor(70, 195);
  tft.print("     Start");

  //tft.drawCircle(30, 30, 20, RED);
  //tft.fillCircle(111, 111, 30, WHITE);
  //  delay(500);
  //tft.drawRoundRect(120, 192, 60, 64, 15, YELLOW);
  // tft.fillRoundRect(0, 192, 60, 64, 15, CYAN);

   // tft.drawRect(0, 0, 60, 64, CYAN);

   //  tft.fillRect(180, 192, 60, 64, GREY);
     //DrawTriangle();

}

void drawstart(bool k)
{

  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

//  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
//  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game
//
//  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
//  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);
//
  tft.fillRoundRect(90, 60, 160, 60, 18, RED);
  tft.drawRoundRect(90, 60, 160, 60, 18, WHITE); //Oscilloscope

  tft.setCursor(40, 180);
  tft.setTextSize(3);
///  tft.setFont();
  tft.setTextColor(WHITE);

  if (k) {
    tft.print("Motor on time");
  }else{
    tft.print("Heater on time");
  }

}
void drawMenu(bool k)
{
   tft.fillScreen(BLACK);

  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

//  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
//  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game
//
//  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
//  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);
//
//  tft.fillRoundRect(75, 80, 160, 60, 18, BLUE);
 // tft.drawRoundRect(700, 60, 160, 80, 18, WHITE); //Oscilloscope

  //tft.fillTriangle(60,60,20,120,180,180,RED);
  tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
   //tft.fillTriangle(42, 20, 42, 60, 90, 40, RED);
   tft.fillTriangle(260,90, 260, 130, 300, 110, RED);
   tft.fillTriangle(60,90, 60, 130, 20, 110, RED);

  tft.setCursor(45, 180);
  tft.setTextSize(2.95);
///  tft.setFont();
  tft.setTextColor(WHITE);
  if (k) {
    tft.print("Motor Timer Setting");
  }else{
    tft.print("Heater Timer Setting");
  }
//  tft.fillRoundRect(5, 5, 80, 60, 8, WHITE);
//  delay(70);

  tft.setTextSize(4);
  tft.fillRoundRect(5, 5, 80, 60, 8, RED);
  tft.drawRoundRect(5, 5, 80, 60, 8, WHITE);
  tft.setCursor(20,20);
  tft.print("<-");

   tft.fillRoundRect(230, 5, 85, 60, 8, BLUE);
  tft.drawRoundRect(230, 5, 85, 60, 8, WHITE);
  tft.setCursor(250, 20);
  tft.print("OK");

}

void start(){
  tft.fillScreen(BLACK);
   drawstart(0);
   setTime(0, 0, 1, 20, 1, 2013); // hour, min, sec, day, month, year
  lastHour = hour();

          //check for heater key pressed

   heater_key=1;state =1;
 while (state ){

   if ( lastSecond!=second())
   {
       lastMinute = minute();
       lastSecond=second();
       tft.setTextSize(6);
       tft.fillRoundRect(60, 60, 200, 100, 18, RED);
       //tft.fillScreen(BLACK);
       tft.setTextColor(WHITE);
       tft.setCursor(110, 85);
       tft.print(lastMinute);
       tft.setCursor(140,85);
       tft.print(":");
       tft.setCursor(170, 85);
       tft.print(lastSecond);
       //delay(1000);
   }
   if (heater_key)
    {
      // alarm set
      if ((Heater_alarmSecond_end <= lastSecond) && (Heater_alarmMinutes_end == lastMinute))
      {
         state=0;
         digitalWrite(A5, LOW);

      }
       if ((Heater_alarmSecond_end >= lastSecond) || (Heater_alarmMinutes_end >= lastMinute))
         {
          //sound alarm
          digitalWrite(A5, HIGH);
          //setOffAlarm();
         }
     }
   }

    drawstart(1);
    state =1;
   setTime(0, 0, 0, 20, 1, 2013); // hour, min, sec, day, month, year
   while (state){
   if ( lastSecond!=second())
   {
       lastMinute = minute();
       lastSecond=second();
       tft.setTextSize(6);
       tft.fillRoundRect(60, 60, 200, 100, 18, RED);
       //tft.fillScreen(BLACK);
       tft.setTextColor(WHITE);
       tft.setCursor(110, 85);
       tft.print(lastMinute);
       tft.setCursor(140,85);
       tft.print(":");
       tft.setCursor(170, 85);
       tft.print(lastSecond);
       //delay(1000);
   }
   if (1)
    {
      // alarm set
      if ((Motor_alarmSecond_end <= lastSecond) && (Motor_alarmMinutes_end == lastMinute))
      {
         state=0;
         digitalWrite(A6, LOW);

      }
       if ((Motor_alarmSecond_end >= lastSecond) || (Motor_alarmMinutes_end >= lastMinute))
         {
          //sound alarm
          digitalWrite(A6, HIGH);
          //setOffAlarm();
         }
     }
   }

//########### MLX90615 @#############
   char i=0,sum=0;

//  for (i=0;i<100;i++){
   score=1;
    while(score==1){
    serialEvent();
    if(sign)
    {
       sign=0;
       for(i=0;i<8;i++)
        sum+=Re_buf[i];
       if(sum==Re_buf[i] )
       {
             TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
             if ((int)TO>=30){
              score=0;
             }
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);
            tft.fillScreen(BLACK);
            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
     }
    }
  }
//####################
   delay(100);
   drawHome();
   return;

}

void menu(){

// drawMenu();

 TSPoint p = ts.getPoint();     // Read touchscreen
 state =1;
// while(state){
// if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
if (p.z > 10 && p.z < 1000)
    {
     tft.setTextSize(3);
            tft.setTextColor(RED);
            tft.setCursor(10, 10);
            tft.print(p.x);
            delay(500);
      /* if (p.y > 743 && p.x < 247 && p.x > 150 && p.y < 875)
        {
          tft.fillRoundRect(5, 5, 50, 30, 8, WHITE);
          delay(70);
          tft.fillRoundRect(5, 5, 50, 30, 8, BLUE);
          tft.drawRoundRect(5, 5, 50, 30, 8, WHITE);
          tft.setCursor(15, 15);
          tft.print("<-");
          delay(70);
          tft.fillRoundRect(5, 5, 50, 30, 8, BLACK);
          currentpage = 0;
          drawHome();
          p.x = 160;
          p.y = 760;
          return;
        }
      if (p.x > 736 && p.x < 855 && p.y > 255 && p.y < 725  )
      {
        tft.setTextSize(3);
            tft.setTextColor(WHITE);
            tft.setCursor(10, 10);
            tft.print("UP2");
            delay(500);

      }
      x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
      y = map(p.y, TS_MINY, TS_MAXY,  tft.height(), 0) + 30;
//tft.fillTriangle(250,90, 250, 130, 290, 110, RED);
//   tft.fillTriangle(60,90, 60, 130, 20, 110, RED);
    if (y > 70 && y < 130)
      {
        if (x > 20 && x < 120)
        {
            tft.setTextSize(3);
            tft.setTextColor(WHITE);
            tft.setCursor(50, 140);
            tft.print("DOWN");
        }
        if (x > 220 && x < 320)
        {
            tft.setTextSize(3);
            tft.setTextColor(WHITE);
            tft.setCursor(50, 140);
            tft.print("UP");
        }

      }
      */
  }
// }
}
////########## MLX90615    #############
//void serialEvent(){
//  while (Serial1.available()) {
//    Re_buf[counter]=(unsigned char)Serial1.read();
//    if(counter==0&&Re_buf[0]!=0x5A) return;
//    counter++;
//    if(counter==9)
//    {
//       counter=0;
//       sign=1;
//    }
//  }
//}
////########################

// initialize the library by providing the nuber of pins to it
LiquidCrystal lcd(8,9,4,5,6,7);

void setup()
{

  time_t t = now(); // store the current time in time variable t
  pinMode(A5, OUTPUT);pinMode(A6, OUTPUT);

  tft.reset();
  tft.begin(tft.readID());
//  Serial.begin(9600);
//  Serial.println();
//  Serial.print("reading id...");
//  delay(500);
//  Serial.println(tft.readID(), HEX);

  tft.fillScreen(BLACK);
  tft.setRotation(1);

  currentpage = 0;

  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.setCursor(50, 140);
  tft.print("Loading...");

  tft.setTextColor(tft.color565(255, 255, 0));
  tft.setCursor(30, 70);
  tft.print("By:");

  tft.setCursor(30, 100);
  tft.print("NotesPoint.com GSH.IR");

  for (int i; i < 250; i++)
  {
    tft.fillRect(BAR_MINY - 10, BLUEBAR_MINX, i, 10, RED);
    delay(0.000000000000000000000000000000000000000000000000001);
  }

  tft.fillScreen(BLACK);
  score=14;
  if (EEPROM.read(1)==score){
  address=2;
  tft.setCursor(300, 100);
  tft.print("eeprom writed beffor");
  Heater_alarmSecond_end = EEPROM.read(address);
  Heater_alarmMinutes_end= EEPROM.read(address+1);
  Motor_alarmSecond_end = EEPROM.read(address+2);
  Motor_alarmMinutes_end = EEPROM.read(address+3);
  }
  else{
    tft.setCursor(300, 100);
  tft.print("new eeprom");
    address=1;
  EEPROM.write(address,14);
  EEPROM.write(address+1,10);
  EEPROM.write(address+2,4);
  EEPROM.write(address+3,10);
  EEPROM.write(address+4,0);
  address=1;

  Heater_alarmSecond_end = EEPROM.read(address);
  Heater_alarmMinutes_end= EEPROM.read(address+1);
  Motor_alarmSecond_end = EEPROM.read(address+2);
  Motor_alarmMinutes_end = EEPROM.read(address+3);
  }
  delay(100);
  drawHome();
  setTime(0, 0, 0, 20, 1, 2013); // hour, min, sec, day, month, year
  //########### MLX90615 ############

Serial1.begin(115200);Serial.begin(115200);
  delay(1);
//  Serial1.write(0XA5);
//  Serial1.write(0X45);
//  Serial1.write(0XEA);
  Serial.write(0XA5);
  Serial1.write(0XA5);
  Serial1.write(0X15);
  Serial1.write(0XBA);
//buadrate 115200
  Serial1.write(0XA5);
  Serial1.write(0XAF);
  Serial1.write(0X54);

//#############################

}
//void setup() {
//
//lcd.begin(16,2);
//
//// set cursor position to start of first line on the LCD
//lcd.setCursor(0,0);
////text to print
//lcd.print("   16x2 LCD");
//// set cusor position to start of next line
//lcd.setCursor(0,1);
//lcd.print("   DISPLAY");
//   Serial1.begin(115200);
//   Serial.begin(115200);
//  delay(1);
//  Serial1.write(0XA5);
//  Serial1.write(0X45);
//  Serial1.write(0XEA);
//}

void loop() {

//
//
//
   char cc,i=0,sum=0;

   //  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();     // Read touchscreen
//  digitalWrite(13, LOW);

  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

//   score=1;
//   while(score==1){
for(i=0;i<8;i++){
  i=1;
 serialEvent();
  if(sign)
  {
     sign=0;
     for(i=0;i<8;i++)
      sum+=Re_buf[i];
     if(sum==Re_buf[i] )
     {
           TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
//           Serial.print("TO:");
//           Serial.println(TO);
//           TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
//           Serial.print("TA:");
//           Serial.println(TA);

             tft.fillScreen(BLACK);
             tft.setTextColor(WHITE);
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);

            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);
            tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
   }
  }

 }

}
void serialEvent(){
  char i;
  Serial1.write(0XA5);
  Serial1.write(0X15);
  Serial1.write(0XBA);
  for (i=0;i<30;i++)
  {
    while (Serial1.available()) {

    Re_buf[counter]=(unsigned char)Serial1.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;i=600;
       sign=1;
    }
  }
  }
}
```

 So has anybody this problem with this kind of sensors or other sensors?and why this happened?

***Update:***

Based of [this site][6] i have combined the blinky and mlx90615 uart sample code, and it's working without freeze, the code is shown below:

```

unsigned char Re_buf[11],counter=0;
unsigned char sign=0;
float TO=0,TA=0;
void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   Serial.begin(115200);
  delay(1);
  Serial.write(0XA5);
  Serial.write(0X45);
  Serial.write(0XEA);
}

void loop() {
  unsigned char i=0,sum=0;
 digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(50);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(50);
  if(sign)
  {
     sign=0;
     for(i=0;i<8;i++)
      sum+=Re_buf[i];
     if(sum==Re_buf[i] )
     {
           TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
           Serial.print("TO:");
           Serial.println(TO);
           TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
           Serial.print("TA:");
           Serial.println(TA);
   }
  }

}
void serialEvent() {
  while (Serial.available()) {
    Re_buf[counter]=(unsigned char)Serial.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;
       sign=1;
    }
  }
}
```

I have read this queston: [Hardware Serial causes hang-up][7] and i think its related to I2C comunication with TFT LCD by this:

> I think I found the solution. As you can see on the photo above, I
> used unscreened wires in comparison with the Breadboard. I2C is
> definitely very sensitive against EMP, which causes the bus freezes. I
> now use screened wires and don´t use the Breadboard anymore. The issue
> now occurs very rarely. Unfortunately I still don´t understand the
> interdependency to the UART interface. I will now improve the
> screening of my wireing. Hopefully, the breakdowns will totaly
> diappear.
>
>
> Re: Hardware Serial causes hang-up
> Summary: My final solution, after weeks of detective work is, to use another sensor board.  :smiley-fat:
> Obviously the ADXL 345 together with connected UART, provoked by EMP
> is the problem. I still don´t know why, but now, using the 10DOF GY-86
> board with the MCU5060 IMU, it runs stable in a longtime test, for
> over 60 hours! No more freeze!!! I hope this will help someone having
> similar problems!

Now it the end of week and i will go to holiday so i wil try newx two days by 16X2 Crystal LCD and printed board to check will it happen again?

Until next two days i will appriciate any sugestion or help.

Thanks a lot.

  [1]: https://i.stack.imgur.com/1uCJS.png
  [2]: https://i.stack.imgur.com/VYnYJ.png
  [3]: https://www.melexis.com/-/media/files/documents/datasheets/mlx90615-datasheet-melexis.pdf
  [4]: https://i.stack.imgur.com/3eruh.png
  [5]: https://i.stack.imgur.com/rZyuZ.png
  [6]: http://epc-project.ir/temp-mlx90615/
  [7]: https://forum.arduino.cc/index.php?topic=159870.0

title: I2C LCD TFT with UART serial communication for MLX90615 IR thermometer freezing IR output

Answers: 1

body:
TBH, I've read your question many times but I still do not understand, what your problem is. What I can see is:

 - You provided picture with wiring for Arduino Uno, not Arduino Mega. If you are using LCD TFT shield intended for I2C and Arduino Uno, it will not work on Mega – this board has I2C on pin 20 (SDA) and 21 (SCL), not like Uno on pin A4 (SDA) and A5 (SCL). But I guess the LCD TFT shield uses SPI, not I2C. Even if it is SPI, it will not work either (again, different pinout).
 - You are using HW Serial #1 for debug and also for communication with the sensor. This may be the source of your problems. Use different HW Serial for debug (#1 is recommended) and different for communication with the sensor (e.g. Serial #2). Arduino Mega has 3 HW Serial interfaces. If you are using Uno and not Mega, use SoftwareSerial (but I recommend using smaller baud rate, if possible).


body:
I trying to create an Arduino avoiding obstacle car. Using Arduino Uno +shield (sensor sheild v5.0). The problem is that when I upload the code, the servo moves randomly (it doesn't rotate to the right) and becomes hot quickly, it is an SG90 with 5v. I have already checked several times and the hardware seems all right.

I have tried to change the angle of the servo, checked the pins several times - uploaded the code many times I have also used serial.prints. researched on the internet.
<!-- language-all: lang-cpp -->

    #include <NewPing.h>        //Ultrasonic sensor function library. You must install this library

    //our L298N control pins
    const int LeftMotorForward = 5;
    const int LeftMotorBackward = 4;
    const int RightMotorForward = 1;
    const int RightMotorBackward = 0;

    //sensor pins
    #define trig_pin A1 //analog input 1
    #define echo_pin A2 //analog input 2

    #define maximum_distance 200
    boolean goesForward = false;
    int distance = 100;

    NewPing sonar(trig_pin, echo_pin, maximum_distance); //sensor function
    Servo servo_motor; //our servo name

    void setup(){

      pinMode(RightMotorForward, OUTPUT);
      pinMode(LeftMotorForward, OUTPUT);
      pinMode(LeftMotorBackward, OUTPUT);
      pinMode(RightMotorBackward, OUTPUT);

      servo_motor.attach(11); //our servo pin

      servo_motor.write(90);
      delay(2000);
      distance = readPing();
      delay(100);
      distance = readPing();
      delay(100);
      distance = readPing();
      delay(100);
      distance = readPing();
      delay(100);
    }

    void loop(){

      int distanceRight = 0;
      int distanceLeft = 0;
      delay(50);

      if (distance <= 20){
        moveStop();
        delay(300);
        moveBackward();
        delay(400);
        moveStop();
        delay(300);
        distanceRight = lookRight();
        delay(300);
        distanceLeft = lookLeft();
        delay(300);

        if (distance >= distanceLeft){
          turnRight();
          moveStop();
        }
        else{
          turnLeft();
          moveStop();
        }
      }
      else{
        moveForward();
      }
        distance = readPing();
    }

    int lookRight(){
      servo_motor.write(10);
      delay(500);
      int distance = readPing();
      delay(100);
      servo_motor.write(90);
      return distance;
    }

    int lookLeft(){
      servo_motor.write(170);
      delay(500);
      int distance = readPing();
      delay(100);
      servo_motor.write(90);
      return distance;
      delay(100);
    }

    int readPing(){
      delay(70);
      int cm = sonar.ping_cm();
      if (cm==0){
        cm=250;
      }
      return cm;
    }

    void moveStop(){

      digitalWrite(RightMotorForward, LOW);
      digitalWrite(LeftMotorForward, LOW);
      digitalWrite(RightMotorBackward, LOW);
      digitalWrite(LeftMotorBackward, LOW);
    }

    void moveForward(){

      if(!goesForward){

        goesForward=true;

        digitalWrite(LeftMotorForward, HIGH);
        digitalWrite(RightMotorForward, HIGH);

        digitalWrite(LeftMotorBackward, LOW);
        digitalWrite(RightMotorBackward, LOW);
      }
    }

    void moveBackward(){

      goesForward=false;

      digitalWrite(LeftMotorBackward, HIGH);
      digitalWrite(RightMotorBackward, HIGH);

      digitalWrite(LeftMotorForward, LOW);
      digitalWrite(RightMotorForward, LOW);

    }

    void turnRight(){

      digitalWrite(LeftMotorForward, HIGH);
      digitalWrite(RightMotorBackward, HIGH);

      digitalWrite(LeftMotorBackward, LOW);
      digitalWrite(RightMotorForward, LOW);

      delay(500);

      digitalWrite(LeftMotorForward, HIGH);
      digitalWrite(RightMotorForward, HIGH);

      digitalWrite(LeftMotorBackward, LOW);
      digitalWrite(RightMotorBackward, LOW);

    }

    void turnLeft(){

      digitalWrite(LeftMotorBackward, HIGH);
      digitalWrite(RightMotorForward, HIGH);

      digitalWrite(LeftMotorForward, LOW);
      digitalWrite(RightMotorBackward, LOW);

      delay(500);

      digitalWrite(LeftMotorForward, HIGH);
      digitalWrite(RightMotorForward, HIGH);

      digitalWrite(LeftMotorBackward, LOW);
      digitalWrite(RightMotorBackward, LOW);
    }

Expected to the servo to rotate 90 degrees, but right now the servo is moving randomly.

title: Issue with Arduino car bot, the servo motor moves randomly also it turns hot pretty quickly

Answers: 1

body:
I think you need to do some rigorous testing of the individual functions of your bot.

Step 1: rename your loop function to "loop_temp" which means it won't run, but it will be retained for later.

Step 2: write a new "loop" function, which sets the LeftMotorForward for 1 second, then stop for 1 second.  And observe the results.

Step 3: repeat Step 2 with LeftMotorBackward, RightMotorForward, etc

Step 4: using serial print, experiment with the output from the sonar to make sure it's delivering the expected results.

Step 5: one at a time introduce your functions and ensure they are each working properly.

Step 6: hopefully you've discovered a bug/fault somewhere, and you can re-introduce your original "loop" function.  Otherwise that function may be the issue.

I've had a look at your code, but don't see anything obviously amiss.  So I'm afraid it may be a process of elimination.


body: I’m doing a project where you have to detect a lightbulb coming on through the electrical current and was wondering what Hardware and what the program is? Can y’all help? Very much appreciated if y’all do.

title: What hardware do I use to detect an electric current going to a lightbulb and tell if it is turning on and off

Answers: 1

body:
A suitable piece of hardware would be a ACS712 Current Sensor which can be used with any Arduino which runs on 5 volts -for instance an Arduino Uno.

You may find [this guide][1] useful in writing the program.

  [1]: https://www.electronicshub.org/interfacing-acs712-current-sensor-with-arduino/#A_Brief_Note_on_ACS712_Current_Sensor


body:
I'm trying to use a flow meter with Wemos Mini.
Most tutorials are using Arduino boards ( which code and HW work OK ), but since I want this device to send alerts over the internet when abnormal usage/leakage is detected, I want to use Wemos Mini using [How to Use Water Flow Sensor - Arduino Tutorial][1]. On top of if will add my code for notifications using Telegram.

BUT - after uploading the original code (before adding Telegram changes ), an error occurs during code run : `ISR not in IRAM!`

I tried to change Pin - but still getting this error,

  [1]: https://www.instructables.com/id/How-to-Use-Water-Flow-Sensor-Arduino-Tutorial/

title: Flow meter using Wemos Mini - ISR not in IRAM!

Answers: 2

body:
This happens because of conflicts between Serial and external interrupts
Put ICACHE_RAM_ATTR before your interrupt function, like this ``` ICACHE_RAM_ATTR void ISR()```

body:
For WEMOS or NODEMCU you must predefine  interupt routine for example

**void ICACHE_RAM_ATTR ServiceLimitSwitchUpperShield_12_D6();**

//it is solve problem for ATTACHINTERRUPT - you must predefine this method **before use setup (very important )**
Then this message error ISR not IRAM will be not displayed .

In a setup you can for example define
attachInterrupt(digitalPinToInterrupt(12), **ServiceLimitSwitchUpperShield_12_D6** , FALLING );

Look for page
 https://community.blynk.cc/t/error-isr-not-in-iram/37426/23


body:
I am doing a data logger with an Arduino Mega2560 and I want to use a code to make it sleep when no measure is needed and wake it up with an RTC when time comes. The reason I want this is because I intend to run the code on a Pro Mini later so I need to save as much energy as I can. I am able to put the arduino to sleep using the alarm interrupt when a minute is passed but it doesn't wake up from sleep afterwards.

Here is the code I am using:
<!-- language-all: lang-cpp -->

    #include <Wire.h>
    #include <RtcDS3231.h>
    #include <avr/sleep.h>

    const byte interruptPin = 2;
    volatile bool alarm = 0;
    volatile byte counter = 0;

    RtcDS3231<TwoWire> rtcObject(Wire);

    void setup() {

      Serial.begin(9600);
      Serial.println("Initialisation");
      pinMode(interruptPin, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);

      rtcObject.Begin();

      RtcDateTime timestamp = RtcDateTime(__DATE__, __TIME__);
      rtcObject.SetDateTime(timestamp);

      rtcObject.Enable32kHzPin(false);
      rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmOne);

      DS3231AlarmTwo alarm2(
        0,
        0,
        0,
        DS3231AlarmTwoControl_OncePerMinute);

      rtcObject.SetAlarmTwo(alarm2);
      rtcObject.LatchAlarmsTriggeredFlags();

    }

    void loop() {
      if (alarm == true){
        handleAlarm();
        if (counter == 1){
          mesure();
          counter = 0;
          delay(100);
          sleepNow();
        }
      }
    }

    void handleInterrupt() {
      alarm = true;
      counter ++;
      Serial.println(counter);
    }

    void handleAlarm() {
      alarm = false;
      rtcObject.LatchAlarmsTriggeredFlags();
    }

    void mesure(){
      RtcDateTime timestamp = rtcObject.GetDateTime();

      Serial.print("time interrupt at: ");
      char time[10];

      sprintf(time, "%d:%d:%d",
              timestamp.Hour(),
              timestamp.Minute(),
              timestamp.Second()
             );
    Serial.println(time);
    }

    void sleepNow() {
      Serial.println("Entering sleeping");
      delay(100);
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // sleep mode is set here
      sleep_enable();                         // enables the sleep bit in the mcucr register
      attachInterrupt(digitalPinToInterrupt(interruptPin),wakeUpNow, FALLING);  // use interrupt 0 (pin 2) and run function
      sleep_mode();                           // here the device is actually put to sleep!!
      // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

      sleep_disable();         // first thing after waking from sleep: disable sleep...
      detachInterrupt(digitalPinToInterrupt(interruptPin));      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
    }

    void wakeUpNow() {
      // execute code here after wake-up before returning to the loop() function
      // timers and code using timers (serial.print and more...) will not work here.
      // we don't really need to execute any special functions here, since we
      // just want the thing to wake up
    Serial.println("Woke up");
    delay(100);
    }

I want to understand how to wake it up properly so I can later make it sleep first in the loop and wake it up only if an interrupt is detected from the rtc.

Thank you for your help !

title: How to wake up Arduino with an rtc?

Answers: 2

body:
If you use the [DS3232RTC library][1] then you can setup an alarm which is like an alarm. I have put a good tutorial on how to do that below.

https://thekurks.net/blog/2018/2/5/wakeup-rtc-datalogger

There is also other threads on arduino.cc you should check out. They might have additional work-arounds.

https://forum.arduino.cc/index.php?topic=333654.0

https://forum.arduino.cc/index.php?topic=99588.0

  [1]: https://github.com/JChristensen/DS3232RTC

body:
You may not need to use an RTC to wake up. Jeelabs has done extensive work on low-power consumption maybe you just need to use the jeelib library from Github. They even sold (not anymore) ultra low power optimized UNO compatible devices (https://jeelabs.org/202x/jnc/). You find jeelib on github on the linked page.

Look at the Sleepy class. It does some low level power saving magic directly with the hardware. It would be interesting to extract that class from Ports.h and Ports.cpp and try if it works standalone.

You simply use it with: Sleepy::loseSomeTime(32); and it will power down the whole MCU for some time. https://github.com/jeelabs/jeelib/blob/635113edea74b1290713360649679c3a13016304/Ports.h#L346

It uses the watchdog timer of the MCUs:

    ISR(WDT_vect) { Sleepy::watchdogEvent(); }


body:
I´m using

    public abstract void write(int b) throws IOException;

from class OutputStream on Android Studio to sent Integer (degrees from 0 to 360) to the Serial Port of my Arduino over HC06 Bluetooth module.

Degrees from 0 to 256 are read well by using

     int angle = Serial.read();

Values over 256 (1 Byte) are received as 0 are something weird.

I tried using

     Serial.parseInt();
as it should return an long int but all I get is one digit mostly 0.

I also tried using

    Serial.readBytes(threeDigitsInt, 3);
    angle = (threeDigitsInt[0] * 100) + (threeDigitsInt[1] * 10) + threeDigitsInt[2];

but I cannot tell what ends up in the array. Definitly not the correct single digit. I tried char[] and byte[] but I´m not able to reconstruct my send Integer value.

Summary: I want to send 360 as Integer from Android and have it as Integer on Arduino.

Appreciate your help!

title: Sending Integer > 1 Byte from Android to Arduino over Serial

Answers: 1

body:
First off, you are only sending one byte from Android:

> `public abstract void write (int b)`
>
> Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. **The 24 high-order bits of b are ignored.**

OutputStream.write(byte) can *never* write more than one byte.

Also it's clear you have no clue about what format the data is sent in if you are trying to then read 3 bytes and use Binary Coded Decimal to reconstruct it.

Instead I suggest you work in a purely ASCII format. Forget bytes. Bytes are not what you want, unless you feel like spending some extra time defining, and then implementing, your own protocol.

Start by formatting your data into an ASCII printable string.  If Android Java is anything like normal Java I'd start by turning your integer into a string with proper line endings.  Something like:

    String val = String.format("%d\n", angle);

Then get the bytes that represent that formatted string:

    byte[] valBytes = val.getBytes();

Now you have a valid byte array containing your textual representation of the data that you can send with `OutputStream.write(byte[])`.

Now your task is to read that data on the Arduino.  That means reading each byte that arrives in turn storing it away in some form until you receive the `\n` line ending.  At that point you can take each byte as a string and convert them into an integer again.

It's possible to do that on the fly:

    static int angle = 0;

    if (Serial.available()) {
        char c = Serial.read();
        if (c == '\n') {
            Serial.print("I got: ");
            Serial.println(angle);
            angle = 0;
        } else if ((c >= '0') && (c <= '9')) {
            angle *= 10;
            angle += (c - '0');
        }
    }

Basically, have a variable that stores the incoming angle. For each character that arrives on the serial port - if it's a line ending `\n` then do whatever with the angle value. If it's a character between 0 and 9 then multiply your angle by 10 (decimal shift left), convert your character to the equivalent integer by subtracting character '0', and add it to your angle.


body:
<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/2H0XB.png)

<!-- End schematic -->

This is the code that I'm using to get the temperature:

    #define COEFF_A 0.8662984364E-03
    #define COEFF_B 2.780704551E-04
    #define COEFF_C -0.9395108479E-07

    float VRT, Temp;
    float Vref = 2.52;

    void setup() {
      Serial.begin(9600);
      analogReference(EXTERNAL);
    }

    void loop() {
      long Resistance;
      VRT = analogRead(A3);
      Resistance = 10000 / ((1023.0 / VRT) - 1);
      Temp = log(Resistance);
      Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
      Temp += -273.15;
      Serial.println(Temp);
      delay(500);
    }
I know that the calculation should be: `V = Vref × VRT ÷ 1023` but i don't know how to implant it in this code, any help appreciated.
___________
# Update

After Edgar Bonet [answer][1], the edited code is:

    #define COEFF_A 0.8662984364E-03
    #define COEFF_B 2.780704551E-04
    #define COEFF_C -0.9395108479E-07

    float VRT, Temp, VR;

    void setup() {
      Serial.begin(9600);
      analogReference(EXTERNAL);
    }

    void loop() {
      long Resistance;
      VRT = analogRead(A3);
      VR = 2.52 * VRT / 1024;
      Resistance = 10000 * VR / (2.52 - VR);
      Temp = log(Resistance);
      Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
      Temp += -273.15;
      Serial.println(Temp);
      delay(500);
    }

But the temperature reading is 2 centigrade less than what it should be, when i remove the `analogReference(EXTERNAL);` it shows the normal/correct temperature readings.

  [1]: https://arduino.stackexchange.com/a/68288/57281

title: How to include Vref in thermistor temperature calculation?

Answers: 2

body:
Note: I formulated this answer on your previous, deleted question.

Whether the voltage increases or decreases with rising temperature depends on your circuit: if you use the ntc with R1 as a pull-down, the voltage will increase on rising temperature. If R1 is a pullup the voltage will fall respectively.

Concerning your calculation: I highly recommend using a look-up table instead. Those are some hard calculations, and at the arduinos resolution you'll be fine with a LUT with about 64 entries. There're tools out there which generate LUTs for a given NTC setup (I personally like [this tool][1]).

  [1]: http://www.sebulli.com/ntc/index.php?lang=en

body:
The formula to get the analog voltage from the ADC reading is:

    V = Vref × reading ÷ 1024

(yes, it's 1024, not 1023). The formula to get the thermistor resistance
from the measured voltage is:

    R = Rref × V ÷ (Vref − V)

where Rref is your 10 kΩ pull-up. You can combine these
two formulas in order to get the resistance directly from the ADC
reading:

    R = Rref × reading ÷ (1024 − reading)

You may notice that, while doing this simplification, Vref
cancels out. It's not an error. The readings you get with this setup are
indeed independent of your reference voltage.

------------------------------------------------------------------------

**Update 1**: After the OP's edit, we now have a _completely different_
question. The question is now: how come the readings do depend on the
reference voltage that is used, whereas in theory they should not.

The answer lies most likely in the ADC calibration. If high accuracy is
a requirement, the correct formula for the measured voltage is

    V = Vref ×
(reading + Eoff) ÷ (1024 + Egain)

where Eoff and Egain are the offset error and the
gain error respectively. These errors are not knows _a priori_, and they
are usually neglected when the accuracy requirement is low. The
datasheet only gives constraints on how big these errors can be. The
actual values depend on the specific microcontroller and can somewhat
depend on the reference voltage. The only solution to get rid of these
errors is to calibrate your own ADC. See [Response of the Arduino
ADC][adc] for an example on how this could be done.

[adc]: https://wiki.logre.eu/index.php/Réponse_de_l'ADC_d'un_Arduino/en

------------------------------------------------------------------------

**Update 2**: If I had to program this in an Arduino, I would rather
simplify the calculations as much as possible before coding:

* do _not_ compute the measured analog voltage, nor the resistance, as
  they are not needed
* compute instead the ratio R/Rref directly from the analog
  reading
* rewrite the calibration polynomial as a function of
  log(R/Rref) instead of log(R) (which actually means
  log(R/(1 Ω)))
* optimize the evaluation of the polynomial by using
  [Horner's method][].

With these optimizations, we get:

```c++
// Coefficients of polynomial fit of log(R/Rref) -> 1/T.
const float c0 = 3.3540165e-3;
const float c1 = 2.5416075e-4;
const float c2 = -2.5959644e-6;
const float c3 = -9.3951087e-8;

// Convert ADC reading to temperature in deg. C.
static float temperature(int reading)
{
    float R_ratio = reading / (1024.0 - reading);  // = R / Rref
    float x = log(R_ratio);
    float inverse_T = c0 + x*(c1 + x*(c2 + x*c3));
    return 1/inverse_T - 273.15;
}

void loop()
{
    int reading = analogRead(A3);
    Serial.println(temperature(reading));
    deay(500);
}
```

[Horner's method]: https://en.wikipedia.org/wiki/Horner's_method


body:
Apologies if the title is not very well worded. I'm new to electronics and trying to learn more about embedded systems too. I have a small project that requires recording an analog audio input at 8-bit at 40kHz and saving it every second in a SD card.

Although I know that I can do that with an ATmega328P chipset, I'm not sure if the processing power of ATmega328P will be good enough for further extension of the project.

Ideally I would like to be able to record two sound sources at the same time at around 40kHz -- 16 or 24-bit would be perfect, and capture two sensory data also every second.

This device should be able to run on a reasonably sized battery for at least two hours, but ideally up to eight hours.

I do like the idea of working on a AT91SAM3X8E chipset, but I'm afraid this might be an overkill for such a small project and the current draw of a Cortext-M3 series might be too much for this project too.

My question therefore is would a ATmega328P or ATmega2560 be suitable for such requirements -- in terms of processing power, or do I have to upgrade to something like the AT91SAM3X8E?

title: Which Arduino-compatible microcontroller for 2 continuous analog audio recording and 2 digital pin snapshots every second?

Answers: 1

body:
> My question therefore is would a ATmega328P or ATmega2560 be suitable for such requirements

No. Not in the slightest.

Your primary requirement of sampling audio at, basically, CD quality (or better) requires the use of a proper CODEC chip - and to drive that you require a microcontroller that has I2S. None of the 8-bit AVR chips have that.

On top of that you will need a LOT of memory. Far far more than an 8 bit Arduino has.  Two channels of 16 bit audio at 44100Hz (CD quality) requires 176400 bytes *per second*.

You will need double that.

To both continuously record and save the data you will require DMA to do the recording.  The DMA reads the incoming data from I2S and stores it in one buffer. When that buffer is full you generate an interrupt and switch to a second buffer. You can then save the first buffer to SD - *assuming that it can be done in under a second*.  Note that SD cards, when controlled by SPI as they generally are on microcontrollers, are generally quite slow.

So with all that in mind:

> I do like the idea of working on a AT91SAM3X8E chipset, but I'm afraid this might be an overkill for such a small project

Overkill? No. Not suitable since it is not up to the task. Yes, it has I2S. Yes, it has DMA. But it doesn't have anywhere near enough memory.  You need for the audio alone 350 kilobytes (the SAM3X8E has up to 100 kilobytes) - not to mention memory required by the SD card's buffers.

So you're looking for a microcontroller that has full I2S support, DMA, and around half a megabyte of memory.  And those aren't small and cheap like the Arduino's 8-bit AVRs.


body:
I'm trying to create a command interpreter. Allowed commands are stored in a JSON document inside SPIFFS. If I send an allowed command, it doesn't print the field associated with that value (end of receiveMsg function), can someone help me to figure out what the problem is? Here's the full code.

EDIT: added minimal code

EDIT 2: solved, but not entirely. I fixed readFile function, but I cannot print out the first field, it appears to be empty. Json is { "ssid"="aaa", "password":"bbb"}, password is printed out, but not ssid. Changing position, password is empty, ssid is printed out. I can resolve by adding a first empty field, but why it happens?
<!-- language-all: lang-cpp -->

    #include<ESP8266WiFi.h>
    #include<ArduinoJson.h>
    #include<stdio.h>
    #include<string.h>
    #include "FS.h"

    DynamicJsonDocument* functions;

    DynamicJsonDocument* readFile(String filename) {
      File file = SPIFFS.open(filename, "r");
      if (!file) {
        Serial.println("Failed to open the file");
      }
      size_t size = file.size();
      if (size > 1024) {
        Serial.println("File size is too large");
      }
      std::unique_ptr<char[]> buf(new char[size]);
      file.readBytes(buf.get(), size);
      DynamicJsonDocument* jsonBuffer = new DynamicJsonDocument(200);
      DeserializationError error = deserializeJson(*jsonBuffer, buf.get());
      if (error) {
        Serial.println("Failed to parse file");
      }
      return jsonBuffer;
    }

    int connection() {
      DynamicJsonDocument *settings = readFile("/wifiSettings.json");
      const char* ssid = (*settings)["ssid"];
      Serial.println("Printing ssid");
      Serial.println(ssid);
      const char* psw = (*settings)["password"];
      Serial.println("Printing password");
      Serial.println(psw);
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, psw); //Connect to wifi
      Serial.println("Connecting to Wifi");
      while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
      }
      return WiFi.status();
    }

    void setup() {
      Serial.begin(115200);
      if (!SPIFFS.begin()) {
        Serial.println("Failed to mount file system");
        return;
      }
      if (connection() != WL_CONNECTED)
        Serial.println("Not connected");
      else
        Serial.println("Connected");
    }

title: Can't print out a field with ArduinoJSON

Answers: 0


body:
How can I stop my following code using a key?

Basically the code should run the servo in a loop if "t" is pressed and stop the loop if "s" is pressed.

    #include <Servo.h>

    Servo myservo;  // create servo object to control a servo
    // twelve servo objects can be created on most boards

    int pos = 0;    // variable to store the servo position
    int servodata;

    void setup() {
      myservo.attach(8);  // attaches the servo on pin 9 to the servo object

      Serial.begin(9600);

    }

    void loop() {
      if (Serial.available()>0){
        servodata = Serial.read();
        while (servodata == 't'){
               for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
        // in steps of 1 degree
           myservo.write(pos);              // tell servo to go to position in variable 'pos'
           delay(3);                       // waits 15ms for the servo to reach the position
      }
        for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
           myservo.write(pos);              // tell servo to go to position in variable 'pos'
           delay(3);                       // waits 15ms for the servo to reach the position
        }
        }
      }
      while (servodata == 's'){
        break;
      }
    }

thank you for help.

title: How can I stop a loop when using a servo with a Key input?

Answers: 1

body:
Here is a quick and dirty solution, where each `loop()` iteration
corresponds to one “start sweeping”/“stop sweeping” cycle:

* wait for the “start” command
* then sweep back and forth in an infinite loop
* stop at any point if you receive the “stop” command

```c++
void loop() {
    // Wait for the 'start' command.
    while (Serial.read() != 't')
        continue;

    // Repeatedly sweep back and forth.
    for (;;) {
        for (int pos = 0; pos <= 180; pos += 1) {
            myservo.write(pos);
            delay(3);
            if (Serial.read() == 's') // check for 'stop' command
                return;
        }
        for (pos = 180; pos >= 0; pos -= 1) {
            myservo.write(pos);
            delay(3);
            if (Serial.read() == 's') // check for 'stop' command
                return;
        }
    }
}
```

Note that this approach has a couple of drawbacks:

1. As this is blocking code, you cannot easily extend the program to do
   other things.
2. The sweeping runs always start at position 0, instead of resuming
   from the position that was current on the last “stop” command.

If you need anything more sophisticated, you should go to a non-blocking
approach based on a [Finite State Machine][fsm] (c.f. jsotola's
comment). Note that you can get away with `delay(3);`, as it is a quite
short delay, but you would have to break the sweeps into one step per
`loop()` iteration.

I suggest you give the FSM approach a try: read the tutorial I linked
to, then try to implement it. If you cannot get it to work, you can
always post another question here.

[fsm]: https://majenko.co.uk/blog/finite-state-machine