body:
 1. **Why “Strings” are bad for Arduino?**
 2. **Which is the most efficient and fastest solution to read and store the data from Accelerometer and GPS?**

----------

***Stings are evil for Arduino***
----------------------------------

----------

An Uno or other ATmega328-based board only has 2048 bytes SRAM.

The SRAM is composed by three parts:

 1. The Static
 2. The Heap
 3. The Stack

**The Heap is where, randomly, a C++ string information is allocated.**

If I add an information to my C++ String the system copies itself and deletes the old copy leaving a hole in the heap, that grows up with the cycles.

When I wrote my first sketch for reading and writing the information from an MPU6050 and stored on a SD (whithout connecting to a GPS) I noticed that the sampling time was not constant.

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

Thanks to the feedback obtained in [this question][2] on StackOverflow, I understood that the problem was my excessive use of strings, and now i understand why.

So I started to dig into this issue.

This was one of the first version of the code:

    /******************************************************************************
      CSV_Logger_TinyGPSPlus.ino
      Log GPS data to a CSV file on a uSD card
      By Jim Lindblom @ SparkFun Electronics
      February 9, 2016
      https://github.com/sparkfun/GPS_Shield

      This example uses SoftwareSerial to communicate with the GPS module on
      pins 8 and 9, then communicates over SPI to log that data to a uSD card.

      It uses the TinyGPS++ library to parse the NMEA strings sent by the GPS module,
      and prints interesting GPS information - comma separated - to a newly created
      file on the SD card.

      Resources:
      TinyGPS++ Library  - https://github.com/mikalhart/TinyGPSPlus/releases
      SD Library (Built-in)
      SoftwareSerial Library (Built-in)

      Development/hardware environment specifics:
      Arduino IDE 1.6.7
      GPS Logger Shield v2.0 - Make sure the UART switch is set to SW-UART
      Arduino Uno, RedBoard, Pro, Mega, etc.
    ******************************************************************************/

    #include <SPI.h>
    #include <SD.h>
    #include <TinyGPS++.h>
    #include<Wire.h>
    #define ARDUINO_USD_CS 10 // uSD card CS pin (pin 10 on SparkFun GPS Logger Shield)

    /////////////////////////
    // Log File Defintions //
    /////////////////////////
    // Keep in mind, the SD library has max file name lengths of 8.3 - 8 char prefix,
    // and a 3 char suffix.
    // Our log files are called "gpslogXX.csv, so "gpslog99.csv" is our max file.
    #define LOG_FILE_PREFIX "gpslog" // Name of the log file.
    #define MAX_LOG_FILES 100 // Number of log files that can be made
    #define LOG_FILE_SUFFIX "csv" // Suffix of the log file
    char logFileName[13]; // Char string to store the log file name
    // Data to be logged:
    #define LOG_COLUMN_COUNT 15
    char * log_col_names[LOG_COLUMN_COUNT] = {
      "longitude", "latitude", "altitude", "speed", "course", "date", "time", "satellites","Acc.X","Acc.Y","Acc.Z","Gy.X","Gy.Y","Gy.Z","Temp"
    }; // log_col_names is printed at the top of the file.

    //////////////////////
    // Log Rate Control //
    //////////////////////
    #define LOG_RATE 1000 // Log every 1 seconds
    unsigned long lastLog = 0; // Global var to keep of last time we logged

    /////////////////////////
    // TinyGPS Definitions //
    /////////////////////////
    TinyGPSPlus tinyGPS; // tinyGPSPlus object to be used throughout
    #define GPS_BAUD 9600 // GPS module's default baud rate

    /////////////////////////////////
    // GPS Serial Port Definitions //
    /////////////////////////////////
    // If you're using an Arduino Uno, Mega, RedBoard, or any board that uses the
    // 0/1 UART for programming/Serial monitor-ing, use SoftwareSerial:
    #include <SoftwareSerial.h>
    #define ARDUINO_GPS_RX 9 // GPS TX, Arduino RX pin
    #define ARDUINO_GPS_TX 8 // GPS RX, Arduino TX pin
    SoftwareSerial ssGPS(ARDUINO_GPS_TX, ARDUINO_GPS_RX); // Create a SoftwareSerial

    // Set gpsPort to either ssGPS if using SoftwareSerial or Serial1 if using an
    // Arduino with a dedicated hardware serial port
    #define gpsPort ssGPS  // Alternatively, use Serial1 on the Leonardo

    // Define the serial monitor port. On the Uno, Mega, and Leonardo this is 'Serial'
    //  on other boards this may be 'SerialUSB'
    #define SerialMonitor Serial
    const int MPU=0x68;  // I2C address of the MPU-6050
    int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

    void setup()
    {
       Wire.begin();
      Wire.beginTransmission(MPU);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);
      SerialMonitor.begin(9600);
      gpsPort.begin(GPS_BAUD);

      SerialMonitor.println("Setting up SD card.");
      // see if the card is present and can be initialized:
      if (!SD.begin(ARDUINO_USD_CS))
      {
        SerialMonitor.println("Error initializing SD card.");
      }
      updateFileName(); // Each time we start, create a new file, increment the number
      printHeader(); // Print a header at the top of the new file
    }

    void loop()
    {
     Wire.beginTransmission(MPU);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
    {
      if ((lastLog + LOG_RATE) <= millis())
      { // If it's been LOG_RATE milliseconds since the last log:
        if (tinyGPS.location.isUpdated()) // If the GPS data is vaild
        {
          if (logGPSData()) // Log the GPS data
          {
            SerialMonitor.println("GPS logged."); // Print a debug message
            lastLog = millis(); // Update the lastLog variable
          }
          else // If we failed to log GPS
          { // Print an error, don't update lastLog
            SerialMonitor.println("Failed to log new GPS data.");
          }
        }
        else // If GPS data isn't valid
        {
          // Print a debug message. Maybe we don't have enough satellites yet.
          SerialMonitor.print("No GPS data. Sats: ");
          SerialMonitor.println(tinyGPS.satellites.value());
        }
      }

      // If we're not logging, continue to "feed" the tinyGPS object:
      while (gpsPort.available())
        tinyGPS.encode(gpsPort.read());
    }
    }

    byte logGPSData()
    {
      File logFile = SD.open(logFileName, FILE_WRITE); // Open the log file

      if (logFile)
      { // Print longitude, latitude, altitude (in feet), speed (in mph), course
        // in (degrees), date, time, and number of satellites.
        logFile.print(tinyGPS.location.lng(), 6);
        logFile.print(',');
        logFile.print(tinyGPS.location.lat(), 6);
        logFile.print(',');
        logFile.print(tinyGPS.altitude.feet(), 1);
        logFile.print(',');
        logFile.print(tinyGPS.speed.mph(), 1);
        logFile.print(',');
        logFile.print(tinyGPS.course.deg(), 1);
        logFile.print(',');
        logFile.print(tinyGPS.date.value());
        logFile.print(',');
        logFile.print(tinyGPS.time.value());
        logFile.print(',');
        logFile.print(tinyGPS.satellites.value());
        logFile.print(AcX);
        logFile.print(',');
        logFile.print(AcY);
        logFile.print(',');
        logFile.print(AcZ);
        logFile.print(',');
        logFile.print(GyX);
        logFile.print(',');
        logFile.print(GyY);
        logFile.print(',');
        logFile.print(GyZ);
        logFile.print(',');
        logFile.print(Tmp);
        logFile.println();
        logFile.close();

        return 1; // Return success
      }

      return 0; // If we failed to open the file, return fail
    }

    // printHeader() - prints our eight column names to the top of our log file
    void printHeader()
    {
      File logFile = SD.open(logFileName, FILE_WRITE); // Open the log file

      if (logFile) // If the log file opened, print our column names to the file
      {
        int i = 0;
        for (; i < LOG_COLUMN_COUNT; i++)
        {
          logFile.print(log_col_names[i]);
          if (i < LOG_COLUMN_COUNT - 1) // If it's anything but the last column
            logFile.print(','); // print a comma
          else // If it's the last column
            logFile.println(); // print a new line
        }
        logFile.close(); // close the file
      }
    }

    // updateFileName() - Looks through the log files already present on a card,
    // and creates a new file with an incremented file index.
    void updateFileName()
    {
      int i = 0;
      for (; i < MAX_LOG_FILES; i++)
      {
        memset(logFileName, 0, strlen(logFileName)); // Clear logFileName string
        // Set logFileName to "gpslogXX.csv":
        sprintf(logFileName, "%s%d.%s", LOG_FILE_PREFIX, i, LOG_FILE_SUFFIX);
        if (!SD.exists(logFileName)) // If a file doesn't exist
        {
          break; // Break out of this loop. We found our index
        }
        else // Otherwise:
        {
          SerialMonitor.print(logFileName);
          SerialMonitor.println(" exists"); // Print a debug statement
        }
      }
      SerialMonitor.print("File name: ");
      SerialMonitor.println(logFileName); // Debug print the file name
    }

Then I started:

 1. Studying how  Arduino Memory works
 2. Breaking the problem, focusing only to learn how to read and write on a SD the accelerometer information (the device is not connected to the PC)

The following code is my latest version:

     void Read_Write()
     // function that reads the MPU and writes the data to the SD.
      {
       // Local variables:
    int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ; // Variables read from MPU6050

    // Read data:
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
    AcX = Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
    AcY = Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    AcZ = Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)

    GyX = Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
    GyY = Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
    GyZ = Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

    // Data preparation for file saving:
    String dataString = ""; // string for assembling the data to log:

    // Add time tag:
    dataString += String(Time0); dataString += ",";

    // Append the MPU6050 data to the string:
    dataString += String(AcX); dataString += ",";
    dataString += String(AcY); dataString += ",";
    dataString += String(AcZ); dataString += ",";
    dataString += String(GyX); dataString += ",";
    dataString += String(GyY); dataString += ",";
    dataString += String(GyZ);

    // Open the file in append mode:
    File dataFile = SD.open("datalog.txt", FILE_WRITE);

    // If the file is available, write to it:
    if (dataFile)
    {
    dataFile.println(dataString);
    dataFile.close();
    if (Serial_plus_SD)
      Serial.println(dataString);
    }
    // if the file does not open, pop up an error:
    else
    errorFW();

    return;
    }

I recived other suggestions such as ***"create a Buffer", but without a technical description and motivation I am having difficulties understand how to do it***.

(I don’t want to simply copy&paste the code as i have done intitially with the first version)

I have to use C Strings instead of C++ Strings?

I have a civil engineer background, so is my first time with coding.

***Thank you for your patience.***

  [1]: https://i.stack.imgur.com/sdSXy.png
  [2]: https://stackoverflow.com/questions/42351949/mpu-6050-sd-writing-frequency-arduino-is-not-constant-how-to-have-a-constant-w

title: Understanding why should avoid “String” and alternative solutions

Answers: 7

body:
For fixed strings (which do not change), use e.g. F("Text") ... this will place the string in flash instead of heap space. Note that the Uno has 32 KB of flash and 2 KB of SRAM (which is used for heap space among others).

If you need variable sized strings but one or few at a time, make a dedicated buffer (of e.g. 64 bytes) and use that buffer for all string operations. It will take up 64 bytes all time, but will leave no heap gaps.
You can create it as a global variable (simple):

    char string_buffer[64];

and use that string_buffer for string operations.

Note that heap gaps are bad for all devices/operating systems, however since the Arduino has very little builtin SRAM, it is filledup quickly when using strings without thinking about memory management.

body:
A chat system I used to use "back in the day" used a fixed "stack" based string buffer.

Basically a single `char *` buffer of a fixed size was created at the beginning of the program and initialised to 0.

Then strings were appended to that buffer using whatever functions were appropriate at that time. A pointer was kept pointing to the start of the "free" space in the buffer. This is the pointer which was used for placing new text into that buffer.

The entire buffer was then printed to the output stream in one block, the first byte cleared, and the pointer reset to the start of the buffer.

This made a very efficient and simple string buffer which didn't fragment memory in any way and still allowed the use of standard C string functions such as `sprintf()`, `strcpy()`, etc.

For example:

    char strbuf[128] = { 0 };
    char *strptr = strbuf;

    strcpy_P(strptr, (PGM_P)F("Temp = "));
    strptr += strlen(strptr);
    itoa(temperature, strptr, 10);
    strptr += strlen(strptr);

    Serial.println(strbuf);
    strbuf[0] = 0;
    strptr = strbuf;

body:
I would use [sprintf][1], with a statically allocated buffer.

**E.g.**

substitute

    // Data preparation for file saving:
    String dataString = ""; // string for assembling the data to log:

    // Add time tag:
    dataString += String(Time0); dataString += ",";

    // Append the MPU6050 data to the string:
    dataString += String(AcX); dataString += ",";
    dataString += String(AcY); dataString += ",";
    dataString += String(AcZ); dataString += ",";
    dataString += String(GyX); dataString += ",";
    dataString += String(GyY); dataString += ",";
    dataString += String(GyZ);

with

    static char pippo[PIPPO_SIZE];
    int ret = sprintf(pippo, "%lu,%d,%d,%d,%d,%d,%d",
                             (uint32_t) Time0, AcX, AcY, AcZ, GyX, GyY, GyZ);

    // This is just for debugging purposes to test the code
    if (ret < 0) {
        // failure: no byte written
    } else if (ret >= PIPPO_SIZE) {
        // failure: too many bytes written, I did some mistake :(
    } else {
        // ok
    }

---

The size of the buffer `pippo` is computed as follows:

- `1 byte` for each comma, you have 6
- `6 bytes` for each `int16_t` variable (`5 bytes` for the digits plus `1 byte` for the sign, which however you might not need)
- `10 bytes` for `Time0`, which I assume is of type `unsigned long` which in *Arduino* is 32 bits.
- `1 byte` for closing `\0`

So it should be `1 * 6 + 6 * 6 + 10 + 1 = 53` unless I did some mistake. Add the following at the top of your program:

    #define PIPPO_SIZE 53

---

The motivation for using statically allocated memory is simple, and is already stated in your question: the concatenation of `String` objects results in repeated calls to `new` and `delete` with subsequent *allocation* and *de-allocation* of *dynamic memory*, which gets fragmented. More over, the `String`-based approach is intuitively *slower* because it requires many more steps to accomplish basically the same simple task.

`String` aren't bad *per se*, but in your application you want to squeeze every last fragment of performance that you can, so there's that.

  [1]: http://www.cplusplus.com/reference/cstdio/sprintf/

body:
First, let me point out a problem in your code, completely unrelated to
your question:

    AcX = Wire.read()<<8|Wire.read();

The C++ standard does not specify in which order the two reads will be
performed. This may work well with the particular version of the
particular compiler you are using, but it can break the day you (or an
update to the Arduino IDE) changes the compiler version or a compiler
flag. You should instead do a single read per statement, e.g.:

    AcX  = Wire.read() << 8;
    AcX |= Wire.read();

Next, I would like to say that the simplest Arduino way of doing what
you are trying to do is to use neither a `String` nor a character array.
Instead, open the file first, then format and send the data on the fly
using `print()` or `println()`:

    dataFile.print(Time0); dataFile.print(",");
    dataFile.print(AcX);   dataFile.print(",");
    [...]

This way you never need to store the whole string in memory. It is then
a very memory-friendly solution.

Now, I realize this seems inconvenient if you want to print the data to
both the SD file and the serial port. In such a case you could put the
printing code inside a function that can print to any `Print` object
(for instance the data file and `Serial`), and you can then call the
function twice:

    static void printImuData(Print &printer, int16_t Time0,
            int16_t AcX, int16_t AcY, int16_t AcZ,
            int16_t GyX, int16_t GyY, int16_t GyZ)
    {
        printer.print(Time0); printer.print(",");
        printer.print(AcX);   printer.print(",");
        [...]
    }

    [...]

    printImuData(dataFile, Time0, AcX, AcY, AcZ, GyX, GyY, GyZ);
    if (Serial_plus_SD)
        printImuData(Serial, Time0, AcX, AcY, AcZ, GyX, GyY, GyZ);

Alternatively, you could use a kind of [tee][] to duplicate the data to
both streams. See for example [this implementation][].

[tee]: https://en.wikipedia.org/wiki/Tee_(command)
[this implementation]: https://arduino.stackexchange.com/a/26453

**Edit**: A more elegant way to achieve the same would be to wrap all
the IMU data into a `struct` (or a `class`), and then make the whole
thing [printable][]:

    struct ImuData : public Printable
    {
        uint16_t Time0, AcX, AcY, AcZ, GyX, GyY, GyZ;
        size_t printTo(Print& p) const;
    };

    size_t ImuData::printTo(Print& p) const
    {
        size_t bytes = 0;
        bytes += p.print(Time0); bytes += p.write(',');
        [...]
        bytes += p.print(GyZ);
        return bytes;
    }

The you can print the `struct` like you would print the string:

    ImuData imu;
    imu.Time0 = ...;
    imu.AcX   = Wire.read() << 8;
    imu.AcX  |= Wire.read();
    [...]

    dataFile.println(imu);
    if (Serial_plus_SD)
        Serial.println(imu);

[printable]: https://arduino.stackexchange.com/a/30552

body:
Edgar answers your first question about `String` and printing very nicely.  Majenko also has a nice description [here](https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/) of the pitfalls.

Regarding your **second** question about GPS/efficiency/speed:

 1. use NeoGPS,
 2. use AltSoftSerial,
 3. use the MPU FIFO,
 4. use the up-to-date SdFat,
 5. watch out for SD write delays, and
 6. `close` the log file at some point.

**1.** [NeoGPS](https://github.com/SlashDevin/NeoGPS) is the smallest, fastest and most accurate GPS parser available.  The example programs are structured properly, and there is an example for SD logging.

NeoGPS has a FIFO of fixes, unlike other libraries.  This avoids "sampling" the GPS at some rate defined by `millis()`.  The Arduino crystal is not as accurate as the atomic GPS clock, so your logging rate should be based off a fix becoming available, at exactly one per second.  Your sketch will "drift" against the GPS updates, losing a fix periodically (depending on the accuracty of the crystal).

**2.**  Perhaps the single greatest improvement you could achieve is **NOT** to use `SoftwareSerial`.  It is very inefficient, because it disables interrupts for long periods of time.  At 9600, it disables interrupts for 1ms while each character from the GPS device is received.  The Arduino could have executed ~10000 instructions during that time, but instead it twiddles its thumbs while *waiting exclusively* for each bit of a byte to arrive... -_-

Instead, you should use `AltSoftSerial`, as you have connected the GPS device to the required pins, 8 & 9.  If you were using two other pins, you could have used my [NeoSWSerial](https://github.com/SlashDevin/NeoSWSerial).  Both of these libraries are *much, much* more efficient than `SoftwareSerial`.

**3.**  If you want evenly-spaced MPU samples, put the device in the FIFO mode.  It will write the selected registers into a FIFO at a selected sampling time.  This also gives you a little flexibility in reading the sample: you just have to read it before the 1024-byte FIFO fills up.

**4.**  You are using an old version of the SD library.  I strongly suggest that you use the latest [SdFat library](https://github.com/greiman).  It has many improvements and bug fixes.

**5.**  Some SD cards will occasionally take a longer time to write.  The 47ms write time is not unusual.  In fact, 100ms is fairly common.  As long as the MPU FIFO does not overflow during this time, you will not lose any MPU samples.

If you find that an SD write occasionally causes the FIFO to overflow, you may have to modify the SDFat library to call a `yield` function while it's waiting for the write to complete.  This `yield` function can read from the FIFO during that time, saving the samples into an Arduino RAM area.

**6.**  I would recommend that you `close` the logFile when some event occurs.  Perhaps a button press?  You can use the LED to indicate that logging is active or inactive.  You could also watch for inactivity for some period of time (no speed, MPU zero values).

With those suggestions, here is a NeoGPS/AltSoftSerial/SdFat version of your original sketch (GPS tested, MPU/SD untested but compiles):

    #include <SPI.h>
    #include <SdFat.h>
    #include <NMEAGPS.h>
    #include <Wire.h>
    #define ARDUINO_USD_CS 10 // uSD card CS pin (pin 10 on SparkFun GPS Logger Shield)

    /////////////////////////
    // Log File Defintions //
    /////////////////////////
    // Keep in mind, the SD library has max file name lengths of 8.3 - 8 char prefix,
    // and a 3 char suffix.
    char logFileName[13] = "gpslogXX.csv";
    // Our log files are called "gpslogXX.csv, so "gpslog99.csv" is our max file.
    #define MAX_LOG_FILES 100 // Number of log files that can be made

    // Data to be logged:
    #define LOG_COLUMN_HEADER \
      "longitude," "latitude," "altitude," "speed," "course," "date," "time," \
      "satellites," "Acc.X," "Acc.Y," "Acc.Z," "Gy.X," "Gy.Y," "Gy.Z," "Temp"
      // printed at the top of the file.

    SdFat SD;
    File  logFile;

    /////////////////////////
    // NeoGPS Definitions //
    /////////////////////////
    NMEAGPS gps; // NeoGPS object to be used throughout
    gps_fix fix; // The latest GPS information received from the gpsPort
    #define GPS_BAUD 9600 // GPS module's default baud rate

    /////////////////////////////////
    // GPS Serial Port Definitions //
    /////////////////////////////////
    // If you're using a Mega, Leo or Due, use Serial1 for the GPS:
    //#define gpsPort Serial1

    // If you're using an Arduino Uno or other ATmega328 board that uses the
    // 0/1 UART for programming/Serial monitor-ing, use AltSoftSerial:
    #include <AltSoftSerial.h>
    AltSoftSerial gpsPort; // Always on pins 8 & 9
    //If you can't use pins 8 & 9, use this:
    //#include <NeoSWSerial.h>
    //NeoSWSerial gpsPort( 2, 3 ).

    // Define the serial monitor port. On the Uno, Mega, and Leonardo this is 'Serial'
    //  on other boards this may be 'SerialUSB'
    #define SerialMonitor Serial

    //#define USE_MPU
    const int MPU=0x68;  // I2C address of the MPU-6050
    int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

    void setup()
    {
      Wire.begin();
      Wire.beginTransmission(MPU);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)
      Wire.endTransmission(true);

      SerialMonitor.begin(9600);
      gpsPort.begin(GPS_BAUD);

      SerialMonitor.println( F("Setting up SD card.") );

      updateFileName(); // Each time we start, create a new file, increment the number
      // see if the card is present and can be initialized:
      if (!SD.begin(ARDUINO_USD_CS))
      {
        SerialMonitor.println( F("Error initializing SD card.") );
      } else {
        logFile = SD.open( logFileName, FILE_WRITE );
        // Print a header at the top of the new file
        logFile.println( F(LOG_COLUMN_HEADER) );
      }

    }

    void loop()
    {
      Wire.beginTransmission(MPU);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
      GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

      while (gps.available( gpsPort )) {
        fix = gps.read();  // get the entire fix structure, once per second

        if (logGPSData()) { // Log the GPS data
          SerialMonitor.println( F("GPS logged.") ); // Print a debug message
        } else {// If we failed to log GPS
          // Print an error, don't update lastLog
          SerialMonitor.println( F("Failed to log new GPS data.") );
        }
      }
    }

    byte logGPSData()
    {
      if (logFile.isOpen())
      { // Print longitude, latitude, altitude (in feet), speed (in mph), course
        // in (degrees), date, time, and number of satellites.

        if (fix.valid.location)
          logFile.print(fix.longitude(), 6);
        logFile.print(',');
        if (fix.valid.location)
          logFile.print(fix.latitude(), 6);
        logFile.print(',');
        if (fix.valid.altitude)
          logFile.print(fix.altitude() * 3.2808, 1);
        logFile.print(',');
        if (fix.valid.speed)
          logFile.print(fix.speed_mph(), 1);
        logFile.print(',');
        if (fix.valid.heading)
          logFile.print(fix.heading(), 1);
        logFile.print(',');

        if (fix.valid.date) {
          logFile.print( fix.dateTime.full_year() );
          if (fix.dateTime.month < 10)
            logFile.print( '0' );
          logFile.print( fix.dateTime.month );
          if (fix.dateTime.date < 10)
            logFile.print( '0' );
          logFile.print( fix.dateTime.date );
        }
        logFile.print(',');

        if (fix.valid.time) {
          if (fix.dateTime.hours < 10)
            logFile.print( '0' );
          logFile.print( fix.dateTime.hours );
          if (fix.dateTime.minutes < 10)
            logFile.print( '0' );
          logFile.print( fix.dateTime.minutes );
          if (fix.dateTime.seconds < 10)
            logFile.print( '0' );
          logFile.print( fix.dateTime.seconds );
        }
        logFile.print(',');

        if (fix.valid.satellites)
          logFile.print(fix.satellites);
        logFile.print(',');
        logFile.print(AcX);
        logFile.print(',');
        logFile.print(AcY);
        logFile.print(',');
        logFile.print(AcZ);
        logFile.print(',');
        logFile.print(GyX);
        logFile.print(',');
        logFile.print(GyY);
        logFile.print(',');
        logFile.print(GyZ);
        logFile.print(',');
        logFile.print(Tmp);
        logFile.println();
        logFile.flush(); // make sure the file contains at least this much

        return 1; // Return success
      }

      return 0; // If we failed to open the file, return fail
    }

    // updateFileName() - Looks through the log files already present on a card,
    // and creates a new file with an incremented file index.
    void updateFileName()
    {
      for (uint8_t i; i < MAX_LOG_FILES; i++)
      {
        // Set logFileName to "gpslogXX.csv":
        logFileName[6] = (i/10) + '0';
        logFileName[7] = (i) + '0';

        if (!SD.exists(logFileName))
          break; // We found our index

        SerialMonitor.print(logFileName);
        SerialMonitor.println( F(" exists") );
      }
      SerialMonitor.print( F("File name: ") );
      SerialMonitor.println(logFileName);
    }

Your original sketch used 24114 bytes of program space and 1690 bytes of RAM.
The NeoGPS version uses 21198 bytes of program space and 1400 bytes of RAM, **a significant savings**.

Minor points:

*  It uses the F macro to save RAM
*  It opens the log file in `setup` and flushes after every GPS update.  You should investigate when to `close` the log file.
*  It reads IMU samples as fast as possible, but you should switch this to the FIFO approach
*  It doesn't use `sprintf` to compose the log filename (this saves program space)
*  The column header does not need to be an array of character strings.  It can be one `#define`. The F macro is applied when it is printed.
*  It only prints GPS fields if they have a valid value.
*  Comments in the GPS port section were wrong about using `SoftwareSerial` on a Mega.
*  Obvious comments deleted.  The `else` of an `if` statement does not deserve an `// otherwise` comment.  -_-

body:
There is now as SafeString library available for Arduino, via the Library Manager (mine :-) )

**SafeStrings are GOOD for Arduino**

They are only ever placed in Static or Stack memory and so completely avoid heap fragementation and small transient object construction and unnecessary data coping, NEVER causes your sketch to reboot and has extensive debugging and error messages.

SafeStrings are designed to be uses by Beginners and includes extensive error checking and detailed error messages to help you find the errors and correct your code.  SafeStrings also corrects a number of errors that are in the String code.

There is a detailed tutorial at

https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html

and extensive examples include in the library, including parsing/tokenizing

In this case because SafeString implement almost all of String functionallity it is easy to replace EVIL Strings with GOOD SafeStrings

        #include "SafeString.h"
        createSafeString(dataString,60); // allocate global 60 byte safestring, just once,
    //  for assembling the data to log
    // You could also use createSafeString within the method if you want a local SafeString
        .. .. ..
        void setup() {
        Serial.begin(9600);
        // ....
        SafeString::setOutput(Serial); // enable sending debug/error msgs to Serial
        // So you will get a message if dataString runs out of space (but no reboots)
        // ....
        }

        // Data preparation for file saving:

        // Add time tag:
        dataString = Time0; dataString += ","; // or ',';

        // Append the MPU6050 data to the string:
        // no new strings created here!!!
        dataString += AcX; dataString += ",";
        dataString += AcY; dataString += ",";
        dataString += AcZ; dataString += ",";
        dataString += GyX; dataString += ",";
        dataString += GyY; dataString += ",";
        dataString += GyZ;

        // etc ....

        // SafeStrings are printable so can use println(dataString)
        // you can also print TO a SafeString so you could use, for example
        // dataString.print(AcX);
        // to access all the formatting print provides

body:
***Which is the most efficient and fastest solution to read and store the data from Accelerometer and GPS?***

You don't state how fast is fast enough nore how long you want to record the data for.  Particularly for the Accelerometer data.

This suggested solution will log ~800 Accelerometer samples/sec  (7 x 16bit ints) continually for 30 days.

There are two problems
i) reading and parsing the GPS and reading the Accelerometer
ii) storing the data on the SD card.

Reading/parsing the GPS data takes time.  This tutorial, [Arduino Serial I/O for the Real World][1] covers buffering serial input, parsing GPS data and buffering serial (text/debug) output.
Reading the accelerometer data is much faster, leave it in binary form.

Storing data on the SD card can be very slow.
Bill Greiman's AnalogBinLogger example in an earlier version of his SdFat Arduino library, uses a pre-allocated and erased SD file and special block writes to minimize the SD latency.
https://github.com/greiman/SdFat  ([code for the earlier version with AnalogBinLogger][2])

This project, [High Frequency, Long Duration Datalogging][3], uses an Uno/Mega to store 512byte blocks of data to an SD card in less then 1mS each block, continually for 30days.
It uses an interrupt to collect the ADC data and two 512byte buffers it for collecting the incoming data and writing to the SD card.

Applying these two projects to your situation you could
1) use on Mega2560 to read/buffer/filter/parse the GPS data and interleave it with the Accelerometer data and buffer it for binary transfer to
the second Mega2650 via Serial (115200baud) i.e. ~11.5Kbytes/sec. For 7 x int16_t accelerometer variables that would be about 800 samples/sec over the serial connection in binary format.
The standard Mega2560 64byte TX Serial buffer should be sufficient.

2) In the second Mega265 you need to modify the UART interrupt handler for one of the UARTs to fill the current SD buffer instead of the normal receive buffer.
When the buffer is full the interrupt swaps it for a second buffer as in the high speed logger project above.

The second Mega would also have a command and control Serial input to prepare the SD card and start/stop the storage.

**A single board apporach**

Since the SD write of the 512 block takes <1mS you could also look a combining these two processes into on board.

Read/buffer/parse fill the 512 block. When it is full, block for 1ms while the SD writes that buffer.  This approach will reduce accelerometer sampling frequency.  See [Simple Multitasking Arduino][4] for how to interleave the tasks for reading/parsing the GPS with sampling the accelerometer and writing the SD card

  [1]: https://www.forward.com.au/pfod/ArduinoProgramming/Serial_IO/index.html
  [2]: https://www.forward.com.au/pfod/ArduinoProgramming/DataRate/SD_logging/SdFat-master.zip with AnalogBinLogger
  [3]: https://www.forward.com.au/pfod/ArduinoProgramming/DataRate/SD_logging/UnoMega_HighFreqLongDur.html
  [4]: https://www.forward.com.au/pfod/ArduinoProgramming/RealTimeArduino/index.html


body: I'm doing a project and I want to get the amount of time between two sensor inputs.  i.e. the sensor detects something, and it triggers a timer, and when the sensor picks up something else, it stops the timer and stores the amount of time the passed in a variable.  Is there a library or a specific function that exists?

title: Is there some kind of timer function that returns the amount of time passed?

Answers: 4

body:
Yes, you can use millis() or micros() which give the milliseconds resp microseconds since the board started up.

However by substracting two values taken close within time you can measure a time period (for example for your sensors).
With this functionality you can program the timer yourself.

See https://www.arduino.cc/en/Reference/HomePage and search for micros/millis.

body: Yes, read and store the value from millis() at the first event. Then read millis() again at the second event. Subtract the stored value and you'll have the time, in milliseconds, between the events. millis() returns a long unsigned int and your memory variables for storing its value need to be of the same type.

body:
Just adding a few notes to the perfectly valid answers you already got:

On your typical AVR-based Arduino, `micros()` has a resolution of
4 µs and `millis()` is updated every 1024 µs. This last point
implies that `millis()` increments most times by 1 ms, but
occasionally by 2 ms. Keep this in mind if time resolution is an
issue.

Both `millis()` and `micros()` return 32-bit unsigned numbers. This
implies that `millis()` overflows (it rolls-over to zero) roughly every
49.7 days and `micros()` every 71.6 min. This limits the
maximum interval length you can measure with each of those functions. It
does **not** limit the maximum run time of your program, since
[subtracting two timestamps does work fine across a rollover
event](https://arduino.stackexchange.com/a/12588).

body:
It's simple enough to make a "helper" function to give you the number of milliseconds between each call of the function:

    uint32_t millisSince() {
        static uint32_t lastMillis = millis();
        uint32_t now = millis();
        uint32_t diff = now - lastMillis;
        lastMillis = now;
        return diff;
    }

Every time you call that it will return the amount of time that has passed since you last called it. The first time it will return 0 since it has never been called before.


body: I have code I am happy to share under a GNU GPL License and which is marked accordingly. Before I upload it to Arduino Create Web Editor I want to check whether in doing so I inadvertently grant additional license rights. I have searched for any terms and conditions which may inform me but not found any as yet.

title: Does sharing code on Arduino Create automatically grant any license rights?

Answers: 2

body:
You should read the [GPL License terms][1] with respect to any rights you are concerned about, but in general, GPL licensed software is available to anyone to do anything with, as long as they keep it public and perpetuate the GPL License. Note: IANALawyer. If you wish to protect any specific rights, you should probably consult one.

  [1]: https://www.gnu.org/licenses/gpl.html

body:
Arduino Create doesn't assume any licensing of any form. Sharing isn't a public thing. You have to specifically provide someone with a link to your sketch. If you choose to post that link publicly then that is your concern.

Any licensing should be included with your sketch.


body:
I'm intending to try a LP621024D70LL (128 KB SRAM memory, 32 pins) on an Arduino Mega.

However, I now see there is no library for it ... I wonder how hard it is to access it? I can miss 32 digital pins (the Mega has enough), however, I'm a bit worried about having to write a library, especially since I do not have any gear like an oscilloscope.

Would it be easy to use the library of the more knwn 32K256 or 23LC1024 as basis? (where I also have no experience with btw).

title: Arduino Mega and LP621024D70LL

Answers: 1

body:
That's so old I can't find a datasheet for it. If you know the pinout then you know more than me at the moment. Chances are it's a standard 8-bit CPU interface.

* Writing:

Set the address on the address pins, set the data to write on the data pins, enable the chip, and pulse WR.

* Reading:

Set the address on the address pins, enable the chip, and while pulsing the OE pin read the data pins.

And no, you can't really use a serial SRAM chip library as a basis - the operation is completely different.


body: I'm doing research into if the Arduino Uno has enough power pin slots to power multiple components, and I'm unsure if it's possible to convert some of the pins from the Digital and Analogue sections to be power/ground. Anyone know>

title: Can Digital/Analogue pins double as power supplies?

Answers: 2

body:
Only for very light loads (a few mA).

But why would you want to? The number of power pins doesn't dictate the number of devices you can power. Power pins can have as many things connected to one pin as you like. As long as you stay within the board's total power budget you are fine.

body:
Yes, for most modules that use modest power, it can be handy to treat modules as shields, in cases where pins can align. You just set each pin on the common 4-pin module connector as needed and plug them in.  I've done this several times with DHT22 modules, and it's fun "plug and play"ing on such a low-level.

With an UNO, you [get a generous 40ma per output][1], though I would use a real power rail for anything over 100mw or so.

To make a pin act as VCC:

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

To make a pin act as ground:

    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);

  [1]: http://playground.arduino.cc/Main/ArduinoPinCurrentLimitations

the other advantage to this is being able to switch the module on/off with `digitalWrite()` (from `HIGH` to `LOW`) to save power or reset flaky sensors.


body:
To burn a bootloader to the Arduino Micro (ATMega32u4), I'm using an Arduino Uno with the ArduinoISP program uploaded to it.

### 1st case: Arduino IDE ###

Very straightforward, using the ArduinoISP sketch included in the IDE.

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

From clicking on "Burn Bootloader" to the output window displaying "Done burning bootloader", it takes **61 seconds**.

### 2nd case: avrdude ###

I'm running `avrdude` directly from the Arduino IDE's folder like so (line breaks added for your reading pleasure):

    D:\Programme\Arduino\hardware\tools\avr\bin>avrdude.exe -v -v -c arduino
    -p atmega32u4 -P com4 -b 19200
    -U flash:w:"..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex"

From pressing Enter to `avrdude.exe done.  Thank you.` displaying on stdout, it only takes **11 seconds**. Full output is posted below.

     D:\Programme\Arduino\hardware\tools\avr\bin>avrdude.exe -v -v -c arduino -p atmega32u4 -P com4 -b 19200 -U flash:w:"..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex"

    avrdude.exe: Version 6.3, compiled on Sep 12 2016 at 17:24:16
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "D:\Programme\MHV AVR Tools\bin\avrdude.conf"

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

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

             Programmer Type : Arduino
             Description     : Arduino
             Hardware Version: 2
             Firmware Version: 1.18
             Topcard         : Unknown
             Vtarget         : 0.0 V
             Varef           : 0.0 V
             Oscillator      : Off
             SCK period      : 0.1 us

    avrdude.exe: AVR device initialized and ready to accept instructions

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

    avrdude.exe: Device signature = 0x1e9587 (probably m32u4)
    avrdude.exe: safemode: hfuse reads as D8
    avrdude.exe: safemode: efuse reads as CB
    avrdude.exe: NOTE: "flash" memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
    avrdude.exe: erasing chip
    avrdude.exe: reading input file "..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex"
    avrdude.exe: input file ..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex auto detected as Intel Hex
    avrdude.exe: writing flash (32730 bytes):

    Writing | ################################################## | 100% 0.25s

    avrdude.exe: 32730 bytes of flash written
    avrdude.exe: verifying flash memory against ..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex:
    avrdude.exe: load data flash data from input file ..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex:
    avrdude.exe: input file ..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex auto detected as Intel Hex
    avrdude.exe: input file ..\..\..\arduino\avr\bootloaders\caterina\Caterina-Genuino-Micro.hex contains 32730 bytes
    avrdude.exe: reading on-chip flash data:

    Reading | ################################################## | 100% 0.35s

    avrdude.exe: verifying ...
    avrdude.exe: 32730 bytes of flash verified

    avrdude.exe: safemode: hfuse reads as D8
    avrdude.exe: safemode: efuse reads as CB
    avrdude.exe: safemode: Fuses OK (E:CB, H:D8, L:FF)

    avrdude.exe done.  Thank you.

## Question: ##

Where does this discrepancy come from? The baud rate is hard coded to be 19200 in the ArduinoISP sketch, so that can't be it.

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

title: How does avrdude burn a bootloader much quicker than the Arduino IDE?

Answers: 1

body:
In the Arduino IDE do this:

- File > Preferences > Show verbose output during: > upload (check) > OK
- Tools > Burn Bootloader

After it finishes examine the output in the black console window at the bottom of the Arduino IDE window. If you look carefully you'll see that the Arduino IDE actually runs two separate AVRDUDE commands when you **Burn Bootloader**. The first sets the fuses according to the settings in boards.txt for the selected board, the second actually burns the bootloader. So your comparison is not really fair unless you run both commands in your test of using AVRDUDE directly.

## Edit by OP:

Full output in the Arduino IDE:

    D:\Programme\Arduino\hardware\tools\avr/bin/avrdude -CD:\Programme\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega32u4 -cstk500v1 -PCOM4 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0xcb:m -Uhfuse:w:0xd8:m -Ulfuse:w:0xff:m

    avrdude: Version 6.3, compiled on Sep 12 2016 at 17:24:16
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "D:\Programme\Arduino\hardware\tools\avr/etc/avrdude.conf"

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

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

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

    avrdude: AVR device initialized and ready to accept instructions

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

    avrdude: Device signature = 0x1e9587 (probably m32u4)
    avrdude: erasing chip
    avrdude: reading input file "0x3F"
    avrdude: writing lock (1 bytes):

    D:\Programme\Arduino\hardware\tools\avr/bin/avrdude -CD:\Programme\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega32u4 -cstk500v1 -PCOM4 -b19200 -Uflash:w:D:\Programme\Arduino\hardware\arduino\avr/bootloaders/caterina/Caterina-Micro.hex:i -Ulock:w:0x2F:m
    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of lock written
    avrdude: verifying lock memory against 0x3F:
    avrdude: load data lock data from input file 0x3F:
    avrdude: input file 0x3F contains 1 bytes
    avrdude: reading on-chip lock data:

    Reading | ################################################## | 100% 0.01s

    avrdude: verifying ...
    avrdude: 1 bytes of lock verified
    avrdude: reading input file "0xcb"
    avrdude: writing efuse (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of efuse written
    avrdude: verifying efuse memory against 0xcb:
    avrdude: load data efuse data from input file 0xcb:
    avrdude: input file 0xcb contains 1 bytes
    avrdude: reading on-chip efuse data:

    Reading | ################################################## | 100% 0.01s

    avrdude: verifying ...
    avrdude: 1 bytes of efuse verified
    avrdude: reading input file "0xd8"
    avrdude: writing hfuse (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of hfuse written
    avrdude: verifying hfuse memory against 0xd8:
    avrdude: load data hfuse data from input file 0xd8:
    avrdude: input file 0xd8 contains 1 bytes
    avrdude: reading on-chip hfuse data:

    Reading | ################################################## | 100% 0.01s

    avrdude: verifying ...
    avrdude: 1 bytes of hfuse verified
    avrdude: reading input file "0xff"
    avrdude: writing lfuse (1 bytes):

    Writing | ################################################## | 100% 0.01s

    avrdude: 1 bytes of lfuse written
    avrdude: verifying lfuse memory against 0xff:
    avrdude: load data lfuse data from input file 0xff:
    avrdude: input file 0xff contains 1 bytes
    avrdude: reading on-chip lfuse data:

    Reading | ################################################## | 100% 0.01s

    avrdude: verifying ...
    avrdude: 1 bytes of lfuse verified

    avrdude done.  Thank you.

    avrdude: Version 6.3, compiled on Sep 12 2016 at 17:24:16
             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "D:\Programme\Arduino\hardware\tools\avr/etc/avrdude.conf"

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

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

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

    avrdude: AVR device initialized and ready to accept instructions

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

    avrdude: Device signature = 0x1e9587 (probably m32u4)
    avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
    avrdude: erasing chip
    avrdude: reading input file "D:\Programme\Arduino\hardware\arduino\avr/bootloaders/caterina/Caterina-Micro.hex"
    avrdude: writing flash (32730 bytes):

    Writing | ################################################## | 100% 35.65s

    avrdude: 32730 bytes of flash written
    avrdude: verifying flash memory against D:\Programme\Arduino\hardware\arduino\avr/bootloaders/caterina/Caterina-Micro.hex:
    avrdude: load data flash data from input file D:\Programme\Arduino\hardware\arduino\avr/bootloaders/caterina/Caterina-Micro.hex:
    avrdude: input file D:\Programme\Arduino\hardware\arduino\avr/bootloaders/caterina/Caterina-Micro.hex contains 32730 bytes
    avrdude: reading on-chip flash data:

    Reading | ################################################## | 100% 19.92s

    avrdude: verifying ...
    avrdude: 32730 bytes of flash verified
    avrdude: reading input file "0x2F"
    avrdude: writing lock (1 bytes):

    Writing | ################################################## | 100% 0.02s

    avrdude: 1 bytes of lock written
    avrdude: verifying lock memory against 0x2F:
    avrdude: load data lock data from input file 0x2F:
    avrdude: input file 0x2F contains 1 bytes
    avrdude: reading on-chip lock data:

    Reading | ################################################## | 100% 0.01s

    avrdude: verifying ...
    avrdude: 1 bytes of lock verified

    avrdude done.  Thank you.


body: I made a programmable Arduino that measures an input voltage. The Arduino will close or open an inverter using a relay to prevent the set of batteries from dropping below 50% to keep the batteries healthy. I currently have a set of 8 6V batteries configured to supply a total of 12V to one inverter. I used a set of 10k ohm and 100k ohm to safely measure the 12 volt input from the batteries. In the current configuration the total Amperage provided by the set of batteries is 400 amps. Is it safe to measure the voltage from a 12V/400A input or do I need some kind of protection?

title: Arduino voltmeter maximum amp input

Answers: 1

body:
It is perfectly safe.

The Arduino will see the voltage reduced by the divider you have. It will see whatever current it needs to see in order to sense the voltage - which is a tiny amount.

Remember: Current is drawn on demand by the load. It is never pushed by a supply.


body:
In my project I need to convert a string to a char array. From various examples I concluded that `toCharArray()` will convert a string to a char array. But I failed to do so. The error is:

> 'a' does not name a type

The code I am using is:

    String a = "45317";
    char b[6];
    a.toCharArray(b,6);

Resources are https://www.arduino.cc/en/Reference/StringToCharArray and http://forum.arduino.cc/index.php?topic=199362.0

title: String to char array conversion

Answers: 2

body:
If you're trying to use a method of `a` in the global scope, that's doomed to failure. You can only call methods within functions.

If all you want is a char array with "45317" in it then just use:

    char *b = "45317";

If you want to convert a string that is built at runtime into a char array, then your current method is correct - you just have to do it in the right place.

body:
There's a built in conversion which will return the underlying string-contents as a NULL terminated character array:

     String foo = "Steve was here"
     char *text = foo.c_str();

That is probably all you need, unless you do want to copy into a buffer.  In that case you can use the standard C library to do that:

     // Declare a buffer
     char buf[100];

     // Copy this string into it
     String foo = "This is my string"
     snprintf( buf, sizeof(buf)-1, "%s", foo.c_str() );

     // Ensure we're terminated
     buf[sizeof(buf)] = '\0';

(You might prefer `strcpy`, `memcpy`, etc to `snprintf`.)


body:
I am currently working an automatic home gardening system. There are two moisture sensors and two solenoid valves to allow water to plant two different zones. Preferably, I want to water the plants for x amount of time. I started programming this and I noticed that with my code below, if one solenoid valve goes off, the entire program will delay **until one** of the solenoid valves **closes** and thus the **other** solenoid valve **will not open until the other one is closed**.

However, I want to prevent this from happening and I want the program to continue reading the moisture readings while one of the solenoid valves is open so that the other solenoid valve can open whenever the zone needs water as well.

    int solenoidPin1 = 1; //connected to Digital 1
    int solenoidPin2 = 2; //connected to Digital 2
    void setup(){
      pinMode(solenoidPin1, OUTPUT);
      pinMode(solenoidPin2, OUTPUT);
    }
    void loop(){
      int moisture1 = analogRead(moisturePin1);
      int moisture2 = analogRead(moisturePin2);
      if (moisture1 <= 250){ //if moisture is less than reading 250
      digitalWrite(solenoidPin1, HIGH); //switch solenoid ON
      delay(300000); //water for five minutes
      digitalWrite(solenoidPin1, LOW); //switch solenoid OFF
      }
      else {
      digitalWrite(solenoidPin1, LOW); //switch solenoid OFF
      }

      if (moisture2 <= 250){ //if moisture is less than reading 250
      digitalWrite(solenoidPin2, HIGH); //switch solenoid ON
      delay(300000); //water for five minutes
      digitalWrite(solenoidPin2, LOW); //switch solenoid OFF
      }
      else {
      digitalWrite(solenoidPin2, LOW); //switch solenoid OFF
      }
    }

I was thinking that I should do the following for the conditioning part. Will this work instead for what I'm trying to do?

      if (moisture1 <= 250){ //if moisture is less than reading 250
      digitalWrite(solenoidPin1, HIGH); //switch solenoid ON
      }
      else if (moisture1 >= 550){
      digitalWrite(solenoidPin1, LOW); //switch solenoid OFF
      }

      if (moisture2 <= 250){ //if moisture is less than reading 250
      digitalWrite(solenoidPin2, HIGH); //switch solenoid ON
      }
      else if (moisture2 >= 550){
      digitalWrite(solenoidPin2, LOW); //switch solenoid OFF
      }

_**Note:**_ I'm using a capacitive moisture sensor, so the output voltage/reading is **higher** the drier the dirt is.

title: Two solenoid valves, both independent

Answers: 1

body:
The essence of your problem is that the `delay()` function _blocks_
your program until the delay is over. This is only acceptable if the
program is doing one single things at a time. If you need to do multiple
things in parallel, like monitoring two moisture sensors, this approach
does not work.

Then, the first thing is to get read of `delay()` and instead use
`millis()` for managing time in a _non blocking_ fashion. The essence of
this approach is to never wait. Instead, if it is time to do something
_right now_, you do it. If not, you just don't do it this time, but you
don't wait. This is nicely covered in the [Blink without delay][]
Arduino tutorial. You should get familiar with this technique, as it is
essential for many Arduino projects.

Your problem is slightly more complex than blinking an LED though, as
the valve can be in two different states, and the action to perform
depends on that state. This is managed by a software construct called a
[finite state machine][]. Essentially you have to remember the current
state and, depending on it, you decide what to do and what the next
state should be. Here is how you could do the timed watering with this
approach:

    static enum { OFF, ON } stateValve1, stateValve2;
    static uint32_t startedValve1, startedValve2;  // time when started

    if (stateValve1 == OFF && analogRead(moisturePin1) <= 250) {
        digitalWrite(solenoidPin1, HIGH); //switch solenoid ON
        startedValve1 = millis();
        stateValve1 = ON;
    } else if (stateValve1 == ON
            && millis() - startedValve1 >= WATERING_TIME) {
        digitalWrite(solenoidPin2, LOW); //switch solenoid OFF
        stateValve1 = OFF;
    }

    // and the same for valve 2.

For more in-depth coverage of the subject, I recommend you read the
[Majenko's tutorial on finite state machines][Majenko on FSM]

At this point, the next step would be to throw in some modularization in
order to make the code less repetitive. I suggest making a class for
representing a “timed valve”. The valve has a `turnOn()` method that
turns it on, but does nothing if the valve is actually already on. The
class takes care of turning the valve off when the time has elapsed. But
since it cannot do that all by itself, you have to call an `update()`
method periodically to give it a chance to check whether it's time to go
off. Here is my implementation of that class:

    const uint32_t WATERING_TIME = 100000;  // for example

    class TimedValve
    {
    public:
        TimedValve(uint8_t pin) : valvePin(pin), state(OFF) {}
        void turnOn() {
            if (state == ON) return;  // do nothing if already ON
            digitalWrite(valvePin, HIGH);
            state = ON;
            timeStarted = millis();
        }
        void update() {
            if (state == ON && millis() - timeStarted >= WATERING_TIME) {
                digitalWrite(valvePin, LOW);
                state = OFF;
            }
        }
    private:
        uint8_t valvePin;
        enum { OFF, ON } state;
        uint32_t timeStarted;
    };

And you would use it like this:

    const int solenoidPin1 = 1;
    const int solenoidPin2 = 2;
    const int moisturePin1 = A1;
    const int moisturePin2 = A2;

    void setup(){
        pinMode(solenoidPin1, OUTPUT);
        pinMode(solenoidPin2, OUTPUT);
    }

    void loop()
    {
        static TimedValve valve1(solenoidPin1), valve2(solenoidPin2);

        // Turn the valves ON if needed.
        if (analogRead(moisturePin1) <= 250)
            valve1.turnOn();
        if (analogRead(moisturePin2) <= 250)
            valve2.turnOn();

        // Let them turn OFF if it's time.
        valve1.update();
        valve2.update();
    }

[Blink without delay]: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
[finite state machine]: https://en.wikipedia.org/wiki/Finite_state_machine
[Majenko on FSM]: https://hackingmajenkoblog.wordpress.com/2016/02/01/the-finite-state-machine/


body: I am new to arduino . I went through the basics . I want to receive message from arduino uno r3 in my laptop(ubuntu) . I have esp8266 wifi module . Arduino and esp8266 connection done . How do I proceed further ?

title: Receiving message from arduino through wifi

Answers: 1

body: Download the ESP8266 extension for the Arduino board in Arduino IDE,desktop. Then select the example code for ESP8266, use the Server example. If you wanna access your board outside your home then you need to open a port in your router.


body:
I'm having trouble trying to get my two Arduino Unos to communicate with each other over i2c. I'm trying to have the master request for analog values from the slave by sending a request to the slave device for one of the six ADC pin values.

**Master Code**

    #include <Wire.h>

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

    void loop()
    {
      Wire.beginTransmission(0x22); // Start communication with Arduino slave at address 0x22

      for(byte i=0;i<4;i++)
      {
        Wire.write(i);              // Request data from analog pin 'i'
        delay(5);                   // Give the slave a moment to sample ADC and respond
        while(Wire.available())
        {
          byte c = Wire.read();
          Serial.println(c);        // Print returned value to serial window
        }
      }

      Wire.endTransmission();       // End communication with Arduino slave
      delay(500);
    }

**Slave Code**

    #include <Wire.h>

    void setup() {
      Wire.begin(0x22);
      Wire.onReceive(receivedHandler);
    }

    void loop() {
    }

    void receivedHandler() {
      byte data = Wire.read();
      byte analogValue;

      if(data == 0) analogValue = analogRead(A0)>>2;
      else if(data == 1) analogValue = analogRead(A1)>>2;
      else if(data == 2) analogValue = analogRead(A2)>>2;
      else if(data == 3) analogValue = analogRead(A3)>>2;
      else analogValue = 0;

      Wire.write(analogValue);
    }

I can see that the data is being received by the slave, but the slave is not sending any data back, so I'm a bit confused how to send data back to the master. For the master there is "Wire.requestFrom(address, num of bytes)" to request a specific number of bytes, and for the slave "Wire.onRequest()" which will call a handler function to send back the number of bytes requested by the master, but for my application I won't be able to return more than 1 byte at a time.

title: Arduino as Slave to Return Multiple Values

Answers: 1

body:
Bidirectional communication in I2C is a two stage thing.

First you have to tell the slave which pin (or register) you want to read. Then you have to read it.

A typical master sequence would be:

    Wire.beginTransmission(0x22);
    Wire.write(1);
    Wire.endTransmission();
    Wire.requestFrom(0x22, 2);
    byte b1 = Wire.read();
    byte b2 = Wire.read();

And of course your slave has to respond to the `write()` and remember which pin is being selected, then separately respond to the `requestFrom()` and return the data corresponding to the pin that was selected earlier.


body:
I have just taken the code from

https://learn.adafruit.com/adafruit-ds3231-precision-rtc-breakout/wiring-and-test

to get DS3231 AT24C32 IIC to work fine with my Aduino and its working fine.

I have then taken
https://learn.adafruit.com/adafruit-arduino-lesson-4-eight-leds
and expanded it to work with three 74HC595 Shift Register. And this is working fine with all three sets of LEDS lighting up one after an other like in the demo.

So I do not think there is anything wrong with my wiring.

When I merge the two demos together, all the output pins on my this shirt register just give out positive current constantly.

I have walked through each line of the code and the problem is caused by

    if (! rtc.begin()) {

if I take out that if statement everything works.  But since that is the bit that starts the clock I want that.

So how do I get the DS3231 started and not have all the pins on the third shift register high?

Also if it matter it is an official Leonardo board.

    #include <Wire.h>
    #include "RTClib.h"

    RTC_DS3231 rtc;

    int latchPinOne = 5;
    int clockPinOne = 6;
    int dataPinOne = 4;

    int latchPinTwo = 11;
    int clockPinTwo = 10;
    int dataPinTwo = 8;

    int latchPinThree = 3;
    int clockPinThree = 13;
    int dataPinThree = 2;

    byte leds = 0;

    void setup()
    {
    #ifndef ESP8266
      while (!Serial); // for Leonardo/Micro/Zero
    #endif

      pinMode(dataPinOne, OUTPUT);
      pinMode(latchPinOne, OUTPUT);
      pinMode(clockPinOne, OUTPUT);

      pinMode(dataPinTwo, OUTPUT);
      pinMode(latchPinTwo, OUTPUT);
      pinMode(clockPinTwo, OUTPUT);

      pinMode(dataPinThree, OUTPUT);
      pinMode(latchPinThree, OUTPUT);
      pinMode(clockPinThree, OUTPUT);

      Serial.begin(9600);
      Serial.println("Start");

      delay(3000); // wait for console opening
      if (! rtc.begin()) {
        Serial.println("Couldn't find RTC");
        while (1);
      }
    }

    void loop()
    {
      leds = 0;
      for (int i = 0; i < 8; i++)
      {
        bitSet(leds, i);
        updateShiftRegister();
        delay(500);
      }
    }

    void updateShiftRegister()
    {

      digitalWrite(latchPinOne, LOW);
      shiftOut(dataPinOne, clockPinOne, LSBFIRST, leds); // send the data
      digitalWrite(latchPinOne, HIGH);

      digitalWrite(latchPinTwo, LOW);
      shiftOut(dataPinTwo, clockPinTwo, LSBFIRST, leds); // send the data
      digitalWrite(latchPinTwo, HIGH);

      digitalWrite(latchPinThree, LOW);
      shiftOut(dataPinThree, clockPinThree, LSBFIRST, leds); // send the data
      digitalWrite(latchPinThree, HIGH);
    }

title: DS3231 AT24C32 IIC making digital outputs not work

Answers: 1

body:
This looks like a classical case of pin conflicts when merging several sketches.

In this case it is hidden by the fact that TWI SDA and SCL are separate pins on the [Arduino Leonardo][1]. But they are also connected to pins 2 and 3 (not A4 and A5 as on Arduino Uno).

Selecting other pins (latch/data) for the third shift register should help.

Cheers.

  [1]: https://www.arduino.cc/en/main/arduinoBoardLeonardo


body:
I am trying to send and receive data with the **TCP** server but I am not receiving data.

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>

    // Parametros de conexion a red WIFI.
    const char* ssid = "bits";
    const char* password = "12345";

    // Start a TCP Server on port 5000
    WiFiServer server(5000);

    void setup() {
      Serial.begin(115200);
      WiFi.begin(ssid,password);
      Serial.println("");
      //Wait for connection
      while(WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
     Serial.println(WiFi.localIP()); // IP

      // Start the TCP server
      server.begin();
    }

    void loop() {
      TCPServer();
    }

    void TCPServer () {
       WiFiClient client = server.available();
        if (client) {
          Serial.println("We have a new client");
          Serial.println("Hello, client!");
            if (client.available() > 0) {
                char thisChar = client.read();
                Serial.println("We got data");
                Serial.println(thisChar);
                delay(200);
            }
        }
    }

**Test Capture**: In the capture it is seen that the code is executed until the following instruction.

    Serial.println("We have a new client");
    Serial.println("Hello, client!");

[![Test rec][1]][1]

[![Test sen][2]][2]

  [1]: https://i.stack.imgur.com/TIgBT.png
  [2]: https://i.stack.imgur.com/t1jTS.png

title: Arduino TCP Server establishes connection with client but does not receive data

Answers: 2

body: You have created a TCP server. You need to connect other clients to it to start data send and receive process between them. If you just simply run this and wait, then you probably won't get anything because nobody is attempting to connect to it.

body:
I found the solution by modifying the code

    void TCPServer () {
       WiFiClient client = server.available();
      if (client)
      {
        Serial.println("New Client");

        while(!client.available()&&client.connected())
        {
        delay(1);
        }

        String linea1 = client.readStringUntil('r');
        Serial.println(linea1);
      }
    }

[![test2][1]][1]

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


body:
All the guides I've found suggest to use an external PSU to power an [RGB matrix like this][1].

However I know it is possible to blink the LEDs at high rates (eg. 2ms) and still give the impression to the eyes they are fully on. I've verified this myself on a small 4x4 matrix, but I am not sure if the same can be done with these bigger matrices.

In my case I could tolerate reduced brightness and color space, but I'd like to power the matrix with the Arduino's 5V pin directly.

  [1]: https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/powering

title: Directly powering a single 32x16 RGB LED matrix (without external PSU)

Answers: 2

body:
When powered through USB, the total current consumption is limited to 500mA by the USB interface. If you are using the power connector, the total current is limited by the on board 5V regulator to 1A.

The board will also require some current, so you can draw around **400mA**, if powered through USB or **900mA**, if powered through the connector; from the 5V pin.

While the matrix on average may not draw than 300 - 400mA, the voltage regulator can overheat and shut off temporarily, and you will never be able to reach 900mA. The regulator is linear, so any extra voltage you supply will result in waste heat.

It is best to get a buck converter or power the matrix externally. You won't be wasting as much power, and avoiding possible thermal shutoff.

body:
I've received yesterday [the 32x16 LED matrix I've ordered from AliExpress][1] and I've done some measurements with a multimeter in series with the power wire.

[LED multiplexing][2] does not seem a good idea as [the matrix is already doing that internally][3].

Instead I've found that using the **minimum color intensity** helps a lot reducing the current usage.

E.g. for blue use `matrix.Color333(0, 0, 1)` instead of `matrix.Color333(0, 0, 7)`; for white use `matrix.Color333(1, 1, 1)` instead of `matrix.Color333(7, 7, 7)`, etc.

With the minimum brightness I've measured:

 - All blue LEDs lit = ~170mA
 - All LEDs lit as white (red+blue+green) = ~400mA

In the average case (not all LEDs are lit) I am getting around **250mA**, so I should definitely be fine powering the matrix directly from the 5V pin if I keep the brightness as low as possible.

  [1]: https://www.aliexpress.com/store/product/P10-Indoor-1-8-Scan-SMD3528-3in1-RGB-Full-color-LED-display-module-320-160mm-32/314096_1615047851.html
  [2]: https://en.wikipedia.org/wiki/Multiplexed_display
  [3]: https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/how-the-matrix-works


body:
[![Pulldown at Q1 added][1]][1][![New Modified Circuit][2]][2][![Old Sketch][3]][3]I am developing a circuit with atmega328, the MCU is powered by a LM7805.
The input of 7805 is given by a variable supply. Till the input of 7805 is 7volts, the output voltage is 4.9volts and current is around .75amps. Now if the input voltage of 7805 is increased, the current also increases and the MCU stops working(sometimes work with being reset after a few seconds), please help me out guys... i need to connect those circuits to my car battery, so it must work with 12volts.

I added capacitors and diodes as per Majenko mentioned. Now the situation is a) The circuit is working at 12V, b) With single C817 , output voltage of mcu is 3.5V, c)I used 56 ohms resistance, which is giving 1.2V to the input of C817, d) The Collector to Emitter resistance of C817 is 1520 ohms when turned on, this is creating a voltage drop of 3volts. e) This output is turning the led on, but being unable to switch the relay.

**Circuit Upate**

This the modified circuit, which solves the problem. But i have some questions, in the modified circuit if BC547 is used then its not working because the collector voltage which should be around 0.2 remains 1.8 volts, but replacing the BC547 with BC337 solves the problem(Collector voltage becomes around 0.3).
[![The Modified Circuit][4]][4]

  [1]: https://i.stack.imgur.com/qjlq6.png
  [2]: https://i.stack.imgur.com/o1eu2.png
  [3]: https://i.stack.imgur.com/hlrCX.png
  [4]: https://i.stack.imgur.com/bvXUX.png

title: 7805 powered Atmega328 Stops working when input of 7805 exceeds 7volts

Answers: 2

body:
It looks like the reason for the MCU drawing high current is operating the LEDs in half a dozen optical isolators without current-limiting resistors.  The part number of your isolators apparently is PC817, for which the suggested LED current is 5 to 20 mA at about 1.2 to 1.4 forward volts.  But if you don't limit the current, they are likely to draw 50 to 100 mA each when turned on.  Add a series resistor, say 220 to 330 Ω, in series with each isolator.

At this point, it's possible you may have damaged your ATmega328 by overheating it, due to drawing too much current from its outputs.  You probably should run some tests with simple sketches to see if they all work ok.

Note, it probably would make sense to use a buck regulator rather than a linear regulator in the 12 V environment.  MP1584-based buck regulator boards (“Mini DC 4.5~28V to DC 3.3V MP1584 3A Step-down Converter Regulator Module”), about 2x2 cm, are about a dollar on ebay and handle 2 amps typically.

body:
There are a number of basic but vitally important components missing from your schematic. Namely input and output capacitors on the voltage regulators, which would result in oscillation and thus overheating (which would then shut them down through thermal overload), decoupling capacitors on the main chip, reverse biased diodes across the relay coils (maybe as well a small capacitor would be beneficial in parallel), and resistors to limit the current through your opto isolators.

Here is a version of your schematic with the missing components added in red. I have omitted the values - your job is to *read the datasheets* and work out the correct values to use.

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

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


body:
My project is based on a moving fan using DHT11 sensors. I have used 2 void loops and the IDE is showing an error

>"exit status 1
redefinition of 'void loop()'"

One doubt: Can we use 2 void loops in the code? Please see and identify the errors.

2nd doubt: `dht DHT;` shows error
>"exit status 1
'dht' does not name a type" for my version of Arduino 1.8.1

    #include <DHT.h>
    #include <DHT_U.h>
    #include <Adafruit_Sensor.h>

     // Including library for dht
    #include<LiquidCrystal.h>
    LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
    #define dht_dpin 12
    dht DHT;
    #define pwm 9

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

    void loop() {
      // put your main code here, to run repeatedly:
      // put your setup code here, to run once:
      lcd.begin(16, 2);
      lcd.clear();
      lcd.print(" Fan Speed");
      lcd.setCursor(0,1);
      lcd.print(" Controlling");
      delay(2000);
      analogWrite(pwm, 255);
      lcd.clear();
      lcd.print("Circuit Digest ");
      delay(2000);
    }

    void loop() {
      DHT.read11(dht_dpin);
      int temp=DHT.temperature;
      lcd.setCursor(0,0);
      lcd.print("Temperature:");
      lcd.print(temp);   // Printing temperature on LCD
      lcd.print("oC");
      lcd.setCursor(0,1);
      if(temp <26 ) {
        analogWrite(9,0);
        lcd.print("Fan OFF");
        delay(100);
      } else if(temp==26) {
        analogWrite(pwm, 51);
        lcd.print("Fan Speed: 20%");
        delay(100);
      } else if(temp==27) {
        analogWrite(pwm, 102);
        lcd.print("Fan Speed: 40%");
        delay(100);
      } else if(temp==28) {
        analogWrite(pwm, 153);
        lcd.print("Fan Speed: 60%");
        delay(100);
      } else if(temp==29) {
        analogWrite(pwm, 204);
        lcd.print("Fan Speed: 80%");
        delay(100);
      } else if(temp>29) {
        analogWrite(pwm, 255);
        lcd.print("Fan Speed: 100%");
        delay(100);
      }
      delay(3000);
    }
    }

title: Temperature sensor bugs

Answers: 1

body:
Here, below is updated version of your code.

Before running this code, you have to download DHT library. Just click on `Click Here` and you find good explanation & library of DHT11 Sensor. Becuase this library I usually preferred for my code. So, please download it and then run my code.

[Click Here][1]

And two void() loop never used. Put your all logic in one void() loop.

Note: This is not tested code. So if you face any problem then update me.

    #include <dht.h>                // DHT library
    #include<LiquidCrystal.h>       // LCD library

    LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

    dht DHT;

    #define DHT11_PIN 12

    #define pwm 9

    float temp;

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

      pinMode(pwm, OUTPUT); //Pin as OUTPUT
    }

    void loop()
    {

     int chk = DHT.read11(DHT11_PIN);
     temp = DHT.temperature;
     Serial.print("Temperature = ");
     Serial.print("\t");
     Serial.print(temp);
     delay(1000);

     lcd.begin(16, 2);
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("Fan Speed");
     lcd.setCursor(0, 1);
     lcd.print("Controlling");
     delay(2000);
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("Circuit Digest");
     delay(2000);
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("Temperature:");
     lcd.setCursor(10, 0);
     lcd.print(temp);

     lcd.setCursor(0, 1);

     if(temp < 26 )
     {
        analogWrite(pwm, 0);
        lcd.print("Fan OFF");
        delay(100);
     }
     else if(temp == 26)
     {
        analogWrite(pwm, 51);
        lcd.print("Fan Speed: 20%");
        delay(100);
     }
     else if(temp == 27)
     {
        analogWrite(pwm, 102);
        lcd.print("Fan Speed: 40%");
        delay(100);
     }
     else if(temp == 28)
     {
        analogWrite(pwm, 153);
        lcd.print("Fan Speed: 60%");
        delay(100);
     }
     else if(temp == 29)
     {
        analogWrite(pwm, 204);
        lcd.print("Fan Speed: 80%");
        delay(100);
     }
     else if(temp > 29)
     {
        analogWrite(pwm, 255);
        lcd.print("Fan Speed: 100%");
        delay(100);
      }
    }

  [1]: https://arduino-info.wikispaces.com/DHT11-Humidity-TempSensor


body:
I don't know if I am allowed to ask this question because really I could just look this up on google. The reason I'm asking here is because in google when you look up the definitions for the following commands, they treat you like you have good knowledge of arduino boards work. I however want to be treated as a beginner who just started learning arduino boards.

So I want to know the definitions of the following commands in a way that I could learn and teach new beginners without getting them confused.

So I want to know the clear definitions of these following commands:

**analogWrite and also why does it have a limit of 255? what does this 255 mean?**

**analogRead  and also why does this have a limit of 1023? what does this mean?**

**digitalWrite and also how does this differ from analogWrite?**

**digitalRead and also how does this differ from analogRead?**

**Loop and setup also what is the void before it?**

**Variables and also how they are declared?**

**Map and also what does it map and how?**

**Serial.write and also how does this differs from analogWrite and digitalWrite?**

**If/else commands and when they should and shouldn't be used?**

Like I said, I do not know whether the question is appropriate, but could be helpful to all the beginners learning Arduino.

title: What is the definition of these arduino commands, and how do they affect the circuit?

Answers: 1

body:
These are a lot of different questions. However, you can find most of the Arduino related answers in the official reference:
[Arduino reference Guide][1]

  [1]: https://www.arduino.cc/en/Reference/HomePage

Some other answers:

- how to declare variables:

<type> <variable_name>

e.g.

    int x;

SerialWrite sends data to the serial port/UART, analogWrite and digitalWrite puts a voltage to a pin (simplified).

AnalogWrite is normally used for a value that has a range (like the intensity of a led), digitalWrite for an On/Off state (can also be for a led but just on/off).

if/else commands can be used to make a program make a decision.

e.g.

    if (a == 10)
    {
        Serial.println("10");
    }
    else
    {
        Serial.println("Not 10");
    }

void means 'nothing' ... in principle it means the functions (setup and loop) do not return any value. You can also define functions which return a value, e.g.

    int add(int a, int b)
    {
        return a + b;
    }

Read in any C/C++ manual about the commands, get a beginner programmers handbook.

The limit of a pin, means the value cannot be more than 255 or 1023. This means that the range of the value you can get/set is between 0 and 255 or 1023.
The map command can be used to make a value within the range required.


body:
I am having issues to reproduce the remote control of my heater , this is the dump of one button:

    Encoding  : UNKNOWN
    Code      : A32AB931 (32 bits)
    Timing[23]:
         +1300, - 400     +1250, - 450     + 400, -1250     +1250, - 450
         +1250, - 450     + 400, -1250     + 400, -1300     + 400, -1250
         + 400, -1300     + 400, -1250     + 400, -1300     +1250
    unsigned int  rawData[23] = {1300,400, 1250,450, 400,1250, 1250,450, 1250,450, 400,1250, 400,1300, 400,1250, 400,1300, 400,1250, 400,1300, 1250};  // UNKNOWN A32AB931

I wonder why I cant just send the raw of this data, maybe because it doesnt run at 38khz? How do I find out what is the frequency ?

It worked fine to dump data from my tv and dvr so it is not an error n my code.

Note:
Opening the remote I found a BEC5104S which doesn't really tells me what frequency runs, not even the Chinese datahsheet

This is the spectrum which confirms that is working at 38khz
[![enter image description here][1]][1]

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

title: IR remote heater

Answers: 0


body:
This is for the servo motor:

    #include <Servo.h> //Servo library

    Servo servo_test;
    //initialize a servo object for the connected servo
    int angle = 0;

    void setup() {
      servo_test.attach(9);
    }

    void loop() {
      for(angle = 0; angle < 180; angle += 1) {
        servo_test.write(angle);
        delay(15);
      }
      delay(1000);
      for(angle = 180; angle>=1; angle-=5) {
        servo_test.write(angle);
        delay(5);
      }
      delay(1000);
    }

This is for the bldc motor with esc:

    #include <Servo.h>

    Servo esc_signal;

    void setup() {
      esc_signal.attach(12);
      esc_signal.write(30);
      delay(3000);
    }

    void loop() {
      esc_signal.write(55);
      delay(15);
    }

title: How can I add two different programs of bldc motor and servo motor in one so that they work in parallel?

Answers: 2

body: Depending on how the code is driven. The simplest would be to simply run loop1 and loop2 in the new loop.

body:
Try out this code. It may be helpful.

    #include <Servo.h> //Servo library

    Servo servo_test;  //initialize a servo object for the connected servo
    int angle = 0;

    Servo esc_signal;

    void setup()
    {
      servo_test.attach(9);

      esc_signal.attach(12);
      esc_signal.write(30);
      delay(3000);
    }

    void loop()
    {
      servoFun();
      bldcFun();
    }

    void servoFun()
    {
      for(angle = 0; angle < 180; angle += 1)
      {
          servo_test.write(angle);
          delay(15);
      }
      delay(1000);

      for(angle = 180; angle>=1; angle-=5)
      {
          servo_test.write(angle);
          delay(5);
      }
      delay(1000);
    }

    void bldcFun()
    {
      esc_signal.write(55);
      delay(15);
    }


body:
The problem I've been having is a little weird. I'm trying to set up audio for my Arduino project and have been playing around with the example included in the IDE. The problem is whenever I try to make the array of notes go into PROGMEM, it makes the outputted note higher than the one I put in. I don't want it to do that.
In case it is relevant, the code I have is as follows:

        #define tuneSize 2
        // notes in the melody:
        const int melody[tuneSize] PROGMEM /*This is what's screwing it up*/= {
          NOTE_AS3, 0
        };

        // note durations: 4 = quarter note, 8 = eighth note, etc.:
        int noteDurations[tuneSize] = {
          6, 16
        };

        void setup() {
          // no need to repeat the melody.
          // iterate over the notes of the melody:
          for (int thisNote = 0; thisNote < tuneSize; thisNote++) {

            // to calculate the note duration, take one second
            // divided by the note type.
            //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
            int noteDuration = 1000 / noteDurations[thisNote];
            tone(8, melody[thisNote], noteDuration);

            // to distinguish the notes, set a minimum time between them.
            // the note's duration + 30% seems to work well:
            int pauseBetweenNotes = noteDuration * 1.30;
            delay(pauseBetweenNotes);
            // stop the tone playing:
            noTone(8);
        }
    }
(Pitch.h can be found in the Arduino example tab under digital)

My circuit has an 8 ohm resistor on pin 8. That's it.

The only thing I can think is that since the PROGMEM is slower, the data doesn't get to the speakers as fast thus making the output weird. Does anyone know how to fix this issue? Also, just having it on SRAM is not ideal because I'm working with a display and the lib it uses uses a lot of SRAM.

title: Problem when using PROGMEM on array holding notes for speaker on Arduino

Answers: 1

body:
You can not directly dereference something ("access an array") that is in flash memory. You have to use pgm_read_xxx functions from <[avr/pgmspace.h][1]> .

In your case you should probably write something like this:

    tone(8, pgm_read_word(&melody[thisNote]), noteDuration);

Pgm_read_word reads two bytes. You could also call that inside your tone() function, the function would take the pointer in flash as an argument.

 I would also recommend you using integer types from <[stdint.h][2]>, because they have defined sizes. Pure int is most likely 32-bit on your PC, but 16-bit on the AVR (I have learned this the hard way when my algorithm ran fine on the PC but gave totally junk output on the AVR).

  [1]: http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html
  [2]: http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html