message:
Error message - help needed

As many of you know (if you read my bio or simply read my previous questions), I'm trying to build a rocket. The code was going well, but once I split my objects into 2 files, a `.h` and `.cpp` file, this error message appeared.

[The full code is on GitHub because it is simply too long!][1]

Here is the error message :

    Arduino: 1.8.1 (Windows 7), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpInitialize()'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpPacketAvailable()'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetAccel(long*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetAccel(int*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetAccel(VectorInt16*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(long*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(int*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetQuaternion(Quaternion*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetGyro(long*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetGyro(int*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetGyro(VectorInt16*, unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccel(VectorInt16*, VectorInt16*, VectorFloat*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetLinearAccelInWorld(VectorInt16*, VectorInt16*, Quaternion*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetGravity(VectorFloat*, Quaternion*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetEuler(float*, Quaternion*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetYawPitchRoll(float*, Quaternion*, VectorFloat*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpProcessFIFOPacket(unsigned char const*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpReadAndProcessFIFOPacket(unsigned char, unsigned char*)'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    sketch\vehicle.ino.cpp.o (symbol from plugin): In function `Fins':

    (.text+0x0): multiple definition of `MPU6050::dmpGetFIFOPacketSize()'

    sketch\Gyroscope.cpp.o (symbol from plugin):(.text+0x0): first defined here

    exit status 1
    Error compiling for board Arduino Pro or Pro Mini.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

  [1]: https://github.com/datha13/Rocket

body:
The problem is the way the author of the MPU6050 library wrote MPU6050_6Axis_MotionApps20.h is not compatible with the way you're using the library. Multiple proposals for fixing the issue have been submitted but they are all outdated to some extent:

https://github.com/jrowberg/i2cdevlib/pull/174

download at https://github.com/martinjos/i2cdevlib/archive/master.zip

https://github.com/jrowberg/i2cdevlib/pull/162

download at https://github.com/cgel/i2cdevlib/archive/master.zip

https://github.com/jrowberg/i2cdevlib/pull/268

download at https://github.com/onliner10/i2cdevlib/archive/master.zip


sender: user

sender: assistant

body:
This is 3 years way too late, but here's what I did

 1. In my own `mpu_sensor.h` file, I only included
```
#ifndef MPU_SENSOR_H
#define MPU_SENSOR_H

#include "MPU6050.h"
#include "helper_3dmath.h"
....
#endif
```

Note that I don't include `MPU6050_6Axis_MotionApps20`, since most datatypes are declared in `MPU6050` and `helper_3dmath`

 2. In my `mpu_sensor.cpp` file, here's my includes:
```
#include "MPU6050_6Axis_MotionApps20.h"
#include "mpu_sensor.h"
```

Please note that `MPU6050_6Axis_MotionApps20.h` must be before the line that includes `mpu_sensor.h`.

It works now.
I agree that the library itself should be updated, but it seems like the author is not updating for the past few years.


message:
How do I accelerate a stepper motor?

I have a 24BYJ48 stepper motor, and my main problem is that I cannot make it rotate quickly. I've understood that in order to achieve a high speed I must start at a low speed and carefully accelerate the motor to higher speeds.

I'm not quite sure how this acceleration ought to be done, though. My idea is to execute the control sequences with an initially long delay, and then decrease the delay between each time I change the sequence for the motor wires.

Below is the code I have written. When I run it, the motor accelerates for a little while, but then all of a sudden it just stops and makes a high pitched noise.
[![code][1]][1]

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

body:
The basic technique is as you have tried to program. The time between stepper pulses if shortened to cause acceleration and lengthened to slow down. A real solution typically uses an "S" curve type acceleration profile that starts out with a slow ramp up to the acceleration rate and then as it nears the target rotational speed it slows the acceleration rate back down.

In your case you may be getting to the point where you have increased the acceleration rate too much and the motor cannot respond to it.


body:
There are several things going on here....

1.  If the load is purely inertial and small (~ equal to the rotor inertia), acceleration typical takes only a few steps.  No need to drag it out.  Try some different delays after the first step.

2.  If you have a torque load (you are pushing something), at some point, during acceleration, the currents in the winding will be too small to generate the required torque.  As the speed increases, the currents will decay, due to the motor back-EMF and inductance (which is very significant).

3.  Sometimes, at particular speeds, step motors exhibit a dynamic instability.  That is, they start hunting...faster, slower, faster, slower, etc. until the motor "stalls".  The resistance seen by the motor, looking back into the drive circuit, is the key factor here.  At high speeds, the current regulator runs out of voltage and the effective resistance drops...leading to instability.

So, do some experimentation!!!


message:
Arduino analog input protection

I've been trying to find a way to protect my analog input pins (for my Leonardo and Pro micro). I'm basically using them to read an amplified piezo sensor output. The output is amplified because I'm using it to measure very low signal (heartbeats). The normal level of the sensor's output doesn't exceed 5V when I'm measuring heartbeats or chest movement, yet when the sensor is moved rapidly or lifted, I can expect a 5v+ voltage. I know that Arduino has an internal protection circuit, will that be enough to combat those sudden movements?
If not, I've read so many posts on this topic including this one:
http://www.thebox.myzen.co.uk/Tutorial/Protection.html

If I wanted to add a series resistor by itself as a protection will it be okay? and also, my signal is already small, wouldn't adding a resistor attenuate it even more?

Most circuits seem to have a capacitor, my signal is DC shifted upward (to avoid -ve voltage), wouldn't the capacitor remove that offset?

Finally, if I wanted to use the diode clamping diodes, which diodes should I use (i.e 1n4148 or 1n4002)?

Thank you

body:
If you amplified with an op-amp powered by 5V then it couldn't produce more than 5V output, so that could be your solution. Failing that, I think a resistor and a couple of clamping diodes would help. The resistor is to current-limit the clamping diodes. I don't think you need to worry about dropping the voltage through the resistor because the analog input is high impedance.

I think the 1n4148 would be OK, I don't see why not.


body: Use a voltage comparator to buffer the input to analog pin . E.g.  a cheap lm 393. If the signal is less than 5v in buffer circuit is stored and passed on- if its more than 5v voltage comparator blocks the , more than 5v, voltage to the arduino.


body:
> I know that Arduino has an internal protection circuit, will that be enough to combat those sudden movements?

it depends on the voltage your pin may see. the pins have clamp diodes - the reset pins may not have, so check the datasheet for sure.

those diodes can sustain some current - check the datasheet on that - absent of it, I wouldn't go more than 10ma on those little guys.

So if you think you may see 10v on the input, put a resistor of (10v-5v) / 10ma = 500ohm resistor there, where 5v is (assumed by me) the supply voltage of your mcu - use the real figure if yours has a different supply voltage.

the same calculation with the negative rail /ground.

and pick the larger of the two.

I typically put a 1k resistor there. I try to be careful if i need to go over 10k, especially for adc pins.

a safer route is to use a (dual directional) buffer. but it does add cost + board real estate.


message:
Arduino + UltraSensor - Serial Monitor outputs garbage

I am trying to connect an HC-SR04 to an Arduino Uno. For some reason when I run this code on the serial monitor it outputs wingdings in a straight line.

ýòøÿüÿøÿüòý÷ÿ÷ýÿÿúýÿýúÿòý÷ûòûòû÷ýÿøÿøÿÿ÷øÿüÿýÿþòøòÿÿøûüÿøÿÿòÿ÷ûòûòý÷ûòûòûöû÷ÿûû÷øÿÿ÷øÿüÿýÿüÿûöþÿý÷ûòûòûòûöûûûûûò

No breaks. Sometimes when I hit "Tools/Fix Encoding and Reload" it outputs

Ping: 0 cm
Ping: 0 cm
Ping: 0 cm

followed by more wingdings.

I've looked up some similar problems and it was usually fixed by changing baud to a lower value, 9600. I've done this and I still have problems.

Would you be able to help me out? I'd very much appreciate it.

    const int trigpin = 9;
    const int echopin = 10;
    long duration;
    int distance;

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

    void loop() {
      pinMode(trigpin, OUTPUT);
      pinMode(echopin, INPUT);
      digitalWrite(trigpin,LOW);
      delayMicroseconds(2);
      digitalWrite(trigpin, HIGH);
      delayMicroseconds(5);
      digitalWrite(trigpin,LOW);
      duration = pulseIn(echopin,HIGH);
      distance = duration *0.034/2;
      Serial.print("Distance: ");
      Serial.println(distance);
    }

**Updated Solution**

After testing out Joel's code to check the sensor was in order, I found some new sample code which worked to display the distance in inches of a HC SR04 sensor.

      // set up variables

      int trigpin = 13; // Trig Pin is connected to Arduino pin 13
      int echopin = 11; // Echo Pin is connected to Arduino pin 11

     // now we need variables which we will be measuring

     float pingtime; // Time for ping to travel to target and return
     float targetdistance; // Distance from sensor to target
     float speedofsound = 776.5; // speed of sound in miles per hour at 77 F

    void setup() {
    Serial.begin(9600); // Turn on serial port
    pinMode(trigpin, OUTPUT); // Sensor trig pin is output
    pinMode(echopin, INPUT); // input is reading from echopin

     }

    void loop() {
    digitalWrite(trigpin, LOW);// set trigger pin low
    delayMicroseconds(2000); // pause to let signal settle
    digitalWrite(trigpin, HIGH); // set trigger pin high
    delayMicroseconds(15); // pause in high state, make sure sensor reads
    digitalWrite(trigpin, LOW); // bring trigpin back low

       pingtime = pulseIn(echopin, HIGH);

    // sensor will be sending HIGH pulse, measure pingtime at echopin
    // ping time is in microseconds

      pingtime = pingtime / 1000000.;

    // converts pingtime to seconds because speed of sound is miles per hour

      pingtime = pingtime / 3600.;
      // converts pingtime to hours
      // add a period to make float to avoid int mistakes

      targetdistance = speedofsound * pingtime;
      // calculates distance in miles traveled by ping

      targetdistance = targetdistance / 2;
      // accounts for roundtrip of ping to target

      targetdistance = targetdistance * 63360.;
      // convert target distance to inches
      // 63360 inches in a mile

    Serial.print("The distance to the target is:");
    Serial.print(targetdistance);
    Serial.println("inches");
    delay(1000);

     }

body:
Check your serial monitor baud rate. This is definitely caused by your serial monitor being set to a different baud rate than the 9600 you specified in the program.

If it had anything to do with the sensor than this line would be printed properly `Serial.print("Distance: ");`

Once you change the serial monitor baud rate then try running this program, to verify that it is set properly:

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

    void loop() {
      Serial.println("Hi There!");
    }

If that prints "Hi There!" then the program your serial monitor is set up properly.


message:
Trying to explain strange behavior when attempting to do a digitalWrite to A7 on a pro mini?

I found out the hard way today that pins `A6` and `A7` can't be used as digital outputs, but what actually happens when you try to read/write them?

**Some backstory:** I soldered some headers onto a pro mini and I wanted to test all the pins to make sure they worked.  I wrote a test program that looped through all the digital pins once a second and toggled their state by doing `digitalWrite(pin, !digitalRead(pin);`.  I then added a second loop that went through pins `A0` through `A7` and toggled them using the same method.  After adding this loop the built in LED on pin 13 no longer toggled on and off every second.  Instead, it would just flicker on very briefly.  At first I assumed there was something wrong with my loops (like an off by one) that was causing the strange issue, so I completely rewrote things to use a single loop that iterated over all the pins.  The resulting code should have been effectively equivalent to the original code, but now pin 13's LED was toggling properly again.

After much experimenting, I was able to whittle it down to the following test program to demonstrate the strangeness:

    #define WORKS_CORRECTLY 1

    int pins[] = {13, A7};
    #define SIZE (sizeof(pins) / sizeof(int))

    void setup()
    {
    #if WORKS_CORRECTLY
     for(int i = 0; i < SIZE; i++)
      pinMode(pins[i], OUTPUT);
    #else
      pinMode(pins[0], OUTPUT);
      pinMode(pins[1], OUTPUT);
    #endif
    }

    void loop()
    {
     for(int i = 0; i < SIZE; i++)
     {
      int pin = pins[i];
      int pinVal = digitalRead(pin);
      digitalWrite(pin, !pinVal);
     }

     delay(1000);
    }

With `WORKS_CORRECTLY` defined as `1` the LED on pin 13 toggles state every second like one would expect.  With it defined as `0`, however, it just flickers on very briefly every second.  This is very perplexing.

Ultimately the answer is to not try to do a `digitalWrite` to `A7` (or `A6`), but I'd like to understand why the behavior changes based on seemingly irrelevant differences.

body:
You are calling `digitalWrite` and `digitalRead` with argument `A7`.

According to the file [pins_arduino.h](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/variants/standard/pins_arduino.h), `A7` is defined as 21.

Now, the two functions are defined in file [wiring_digital.c](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_digital.c), and the most important part is that both of them use this code to understand which register and bit to use:

    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);

Those two are not functions, but macros defined in the [Arduino.h](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Arduino.h) file:

    #define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
    #define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )

This means that the positions are stored into two arrays, and each pin data is an offset from the beginning of the array itself. This means that the pin 0 is located on register digital_pin_to_port_PGM[0] (i.e. port D) and is in position digital_pin_to_bit_mask_PGM[0] (so bit 0).

Now, what about pin A7? It is in index 21. But look at the file pins_arduino.h:

    const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
     PD, /* 0 */
     PD,
     PD,
     PD,
     PD,
     PD,
     PD,
     PD,
     PB, /* 8 */
     PB,
     PB,
     PB,
     PB,
     PB,
     PC, /* 14 */
     PC,
     PC,
     PC,
     PC,
     PC,
    };

The array has only 20 entries! This means that A6 and A7 are NOT mapped. When you call the function with A7, you are going beyond the array limits.

This means that this leads to an unexpected behavior. In THIS particular case you are getting

    PORT: _BV(1) = 2 which is equal to PB in Arduino.h
    BIT: NOT_ON_TIMER = 0

So when you read from bit A7 you will check for

    *portInputRegister(port) & bit
    *portInputRegister(PB) & 0 => 0 for every value

so it always reads a LOW.

When you write any value to it, you will apply this code:

    if (val == LOW) {
        *out &= ~bit;
    } else {
        *out |= bit;
    }

`bit` is always 0, so if you write a `LOW` value you will write a `HIGH` on ALL bits connected to port B, otherwise you will write a `LOW` on all of them.

Different is the access to A6: the port will be mapped to 0, which is translated to NOT_A_PORT when detecting the register. This will try to read and write from/to register #0, which I admit I do not know what means. According to the ATMEGA328P register map it is reserved, so better not to use it.

Short answer: never try to use values which are not supposed to be used, otherwise you will incur in strange behaviors


body:
> pins A6 and A7 can't be used as digital outputs.

that shows the importance of reading the datasheet (and the schematic): there is no port / pins associated ADC6/A6 and ADC7/A7 on the chip. Absolutely no way of writing to / reading from those pins digitally.

None whatsoever.


message:
Load website from SD card

I combined two different codes together, a captive portal and a SD card web server. I encountered a problem which the website in the SD card doesn't load when I connect to the AP (captive portal page). Here's the code..

    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #include "./DNSServer.h"
    #include <SPI.h>
    #include <SD.h>

    const byte        DNS_PORT = 53;          // Capture DNS requests on port 53
    IPAddress         apIP(10, 10, 10, 1);    // Private network for server
    DNSServer         dnsServer;              // Create the DNS object
    ESP8266WebServer server(80);
    String responseHTML = ""
                          "<title>Captive Portal Test</title>"
                          "
TEST
";

    static bool hasSD = false;
    File uploadFile;

    void returnOK() {
      server.send(200, "text/plain", "");
    }

    void returnFail(String msg) {
      server.send(500, "text/plain", msg + "\r\n");
    }

    bool loadFromSdCard(String path) {
      String dataType = "text/plain";
      if (path.endsWith("/")) path += "index.htm";
      if (path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
      else if (path.endsWith(".htm")) dataType = "text/html";
      else if (path.endsWith(".css")) dataType = "text/css";
      else if (path.endsWith(".js")) dataType = "application/javascript";
      else if (path.endsWith(".png")) dataType = "image/png";
      else if (path.endsWith(".gif")) dataType = "image/gif";
      else if (path.endsWith(".jpg")) dataType = "image/jpeg";
      else if (path.endsWith(".ico")) dataType = "image/x-icon";
      else if (path.endsWith(".xml")) dataType = "text/xml";
      else if (path.endsWith(".pdf")) dataType = "application/pdf";
      else if (path.endsWith(".zip")) dataType = "application/zip";

      File dataFile = SD.open(path.c_str());
      if (dataFile.isDirectory()) {
        path += "/index.htm";
        dataType = "text/html";
        dataFile = SD.open(path.c_str());
      }

      if (!dataFile)
        return false;

      if (server.hasArg("download")) dataType = "application/octet-stream";

      if (server.streamFile(dataFile, dataType) != dataFile.size()) {
      }

      dataFile.close();
      return true;
    }

    void handleNotFound() {
      if (hasSD && loadFromSdCard(server.uri())) return;
      String message = "SDCARD Not Detected\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += (server.method() == HTTP_GET) ? "GET" : "POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";
      for (uint8_t i = 0; i < server.args(); i++) {
        message += " NAME:" + server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
      }
      server.send(404, "text/plain", message);
    }

    void setup(void) {
      WiFi.mode(WIFI_AP);
      WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
      WiFi.softAP("TEST AP");
      dnsServer.start(DNS_PORT, "*", apIP);
      //PROBLEM HERE/
      server.onNotFound([]() {
      server.send(200, "text/html", responseHTML);
      });

      server.begin();

      if (SD.begin(SS)) {
        hasSD = true;
      }
    }

    void loop(void) {
      dnsServer.processNextRequest();
      server.handleClient();
    }

This code replies the `responseHTML` as a Captive portal page which immediately pop-ups when I connect to the AP:

    server.onNotFound([]() {
          server.send(200, "text/html", responseHTML);
          });
The `void handleNotFound()` handles the page/file request from the browser but if I use it on

    server.onNotFound(handleNotFound);

The captive portal won't show but if I type the server address `10.10.10.1`, the page will appear. What seems to be the problem?

body:
Remove `hasSD &&` from `void handleNotFound()` function.

It worked for me.


message:
Getting a fixed sampling rate

Ultimately I will move to a generic smart phone for this project.
I'm trying to read 4 analog inputs from my arduino with a fixed 1kHz sampling frequency. I managed to set it to read at 1kHz as you can see from this [link][1]. The issue is that after running several times, I kept testing the frequency by logging the time vector (produced by arduino to the serial terminal) into Excel and calculating the frequency using the equation:
f=1/(t2-t1)

I did this to the entire column and I noticed that I got a changing frequency. The difference is very big as it ranges from 780 to 1kHz. I need a fixed sampling rate because we will be applying some digital signal processing on the obtained results which obviously requires a sampling frequency. My code to send the data is the following:

    #define INTERVAL_LENGTH_US 1000UL

    unsigned long previousMicros;
    #define FASTADC 1
    int recValue;
    // defines for setting and clearing register bits
    #ifndef cbi
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #endif
    #ifndef sbi
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #endif
    double t = 0;

    void setup() {
      int start ;
      int i ;

    #if FASTADC
      // set prescale to 16
      sbi(ADCSRA, ADPS2) ;
      cbi(ADCSRA, ADPS1) ;
      cbi(ADCSRA, ADPS0) ;
    #endif

      Serial.begin(115200) ;
    }

    void loop()
    {
      unsigned long currentMicros = micros();

      if ((currentMicros - previousMicros) >= INTERVAL_LENGTH_US)
      {
        previousMicros += INTERVAL_LENGTH_US;

        int val_a0 = analogRead(A0);
        int val_a1 = analogRead(A1);
        int val_a2 = analogRead(A2);
        int val_a3 = analogRead(A3);

        Serial.print(((double)currentMicros) / 1000000UL, 5 ); // 1 is the number of decimals to print
        Serial.print('\t');

        Serial.print(val_a0);
        Serial.print(',');

        Serial.print(val_a1);
        Serial.print(',');

        Serial.print(val_a2);
        Serial.print(',');

        Serial.println(val_a3);

      }
    }

Ps. I'm using Arduino Leonardo,
What's the right way to achieve this?

EDIT: Thank you all for responding, As you wanted to see my data, here is a screenshot of the results after I applied Jwpat7's suggestion:
[![enter image description here][2]][2]

The yello shaded column is the frequency calculated, the first and 2nd columns represent T1 and T1 (T2 is just T1 shifted upward for easier calculation). You may notice the Matlab section, this is because I'm trying to plot the data in Matlab and use it to do the digital signal processing after transmission. The plotting will be real time (I'll the data in txt files for later processing). the bottom potion of the figure shows the frequency after a while....as you can see it's decreasing!

Thanks

  [1]: https://arduino.stackexchange.com/questions/33716/delay-between-multiple-analogreads
  [2]: https://i.stack.imgur.com/z7WsV.png

body:
You can speed your code up slightly by sending a raw microseconds reading, rather than divided by 1000000.  Floating arithmetic on typical Arduino devices can be quite slow.  Also, the time to complete a divide is data dependent, so may occasionally but not always delay the next reading; that is, the division may contribute to jitter as well as overall slowness.

Another source of jitter is polling via `loop()` rather than *within* loop [see below].  However, this probably adds only a few microseconds of jitter.

To test if too-slow serial transmission is the problem, you could comment out all the serial printing and substitute `Serial.println(currentMicros)`.  (Or print the low two bytes of `currentMicros`.)

---

**Polling within `loop()`:** You could replace

    currentMicros = micros();
    if ((currentMicros - previousMicros) >= INTERVAL_LENGTH_US)
      {  ...  }

with

    while (micros() - previousMicros < INTERVAL_LENGTH_US) ;
    currentMicros = micros();
    ...

This would tighten up the busy-wait loop and reduce jitter slightly.

If small changes as suggested above don't resolve the problem, you might need to use timer-based interrupts interrupt flags to schedule trigger ADC reads (as suggested in comments) and/or create a circular data buffer to make data collection timing less dependent upon data transmisssion timing.

The **ADC Auto Trigger Source Selections** table in the ATmega32U4 datasheet shows the ADTS bit settings to select various ADC trigger sources, which include Free Running, Analog Comparator, External Interrupt Request 0, and various Compare/Overflow/Capture events on Timer/Counter0, 1, and 4.  Your ADC conversion-complete interrupt handler would need to read the ADC, store the reading, set a volatile flag to tell `loop()` which reading is ready, and set the ADC input selection to the next channel.

---

*Edit 2:* **Where the code spends its time:** In the version that busy-waits until the next time-mark arrives, and then takes four ADC readings, the process sits and waits for the ADC to complete.  With a standard prescale factor of 128 and 104 μs per conversion, about 416 microseconds are spent waiting on ADC completion.  If FASTADC is set and prescale is 16, giving 13 μs per conversion, then only 52 μs is spent in that waiting.  In brief: use of a standard prescale factor will probably use up too much time if the polling method is used.  But if readings are timer-interrupt triggered and ADC-ready-interrupt stored, a standard prescale factor is ok.

**Serial transmission rate estimates:**
As noted in Edgar Bonet's  answer, 115200 bps isn't fast enough to support 1000 Ascii-data serial transmissions per second.  If working at 100% throughput, that data rate allows only 115 bits per transmission, or 11.5 characters, which typically is not enough for the data you are sending.  Additionally, sending the time in Ascii adds another digit to the transmission length at the 10 second and 100 second marks, which may account for the observed slowdown in the "Test ARDUINO" scenario.  (The slowdown in the Matlab case may be due to rapidly-growing memory use by Matlab; possibly try less-accurate plotting, or narrower plots, or a specialized graphing program.)

Edgar Bonet's code sidesteps this problem by transmitting data from a fixed-length (8 byte) buffer in binary, hence the 80000 bps figure he mentions (8 bytes times 10 bits per serially-transmitted byte times 1000 readings per second).  Since ADC readings are timer-triggered, there probably is no real need to transmit a clock time with each reading, but resynchronization (in case of lost bytes) might need to be added somehow.  Possibly one could send a 9-byte packet at each transmission; the extra byte would allow use of a protocol to support error-detection, resynchronization, periodic clock readings, and packet counts.


body:
Expanding on my previous comments...

The only reliable way to get jitter-free ADC readings is to trigger the
ADC from a timer event. I wrote the following program to demonstrate the
approach on an Arduino Uno, as I don't have a Leonardo. The program
configures the Timer 1 to set it's overflow flag every 250 µs, and
the ADC to start a conversion on every rising edge of that flag. When
the conversion is done (104 µs after it started), the ADC ISR
fires. It's job is to retrieve the conversion result and set the analog
multiplexer for the next channel, switching round-robin through channels
0 – 3.

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

    volatile int adc_readings[4];
    volatile bool fresh_readings;

    // Used only to clear the interrupt flag.
    EMPTY_INTERRUPT(TIMER1_OVF_vect);

    ISR(ADC_vect)
    {
        static int buffered_readings[3];
        static uint8_t channel;

        if (channel == 3) {

            // "Export" the 4 readings at once.
            adc_readings[0] = buffered_readings[0];
            adc_readings[1] = buffered_readings[1];
            adc_readings[2] = buffered_readings[2];
            adc_readings[3] = ADC;
            fresh_readings = true;
        } else {

            // Buffer the current reading.
            buffered_readings[channel] = ADC;
        }

        // Move to next channel.
        channel = (channel + 1) % 4;
        ADMUX = _BV(REFS0)  // reference = Vcc
              | channel;
    }

    void setup()
    {
        Serial.begin(115200);
        Serial.write("================");

        // Configure the ADC.
        ADMUX  = _BV(REFS0)   // reference = Vcc
               | 0;           // channel = ADC0
        ADCSRA = _BV(ADEN)    // enable
               | _BV(ADSC)    // start first conversion
               | _BV(ADPS0)   // prescaler = 128
               | _BV(ADPS1)   // ...ditto
               | _BV(ADPS2);  // ...ditto
        ADCSRB = _BV(ADTS1)   // trigger source = Timer 1 overflow
               | _BV(ADTS2);  // ...ditto

        // Wait for and discard the first conversion.
        loop_until_bit_is_set(ADCSRA, ADIF);

        // Configure Timer 1 to overflow every 250 us.
        TCCR1A = _BV(WGM11);  // fast PWM mode, TOP = ICR1
        TCCR1B = _BV(WGM12)   // ...ditto
               | _BV(WGM13)   // ...ditto
               | _BV(CS11);   // clock at F_CPU/8
        TIMSK1 = _BV(TOIE1);  // enable overflow interrupt
        ICR1   = 500 - 1;     // period = 500 * 8 CPU cycles

        // Set the ADC to auto-trigger mode.
        ADCSRA |= _BV(ADATE)  // enable auto-trigger
                | _BV(ADIF)   // clear interrupt flag
                | _BV(ADIE);  // enable interrupt
    }

    void loop()
    {
        if (fresh_readings) {
            Serial.write((uint8_t *) adc_readings, sizeof adc_readings);
            fresh_readings = false;
        }
    }

A few comments:

* The Timer 1 overflow interrupt is used only to clear the timer
  interrupt flag. The flag has to be cleared because the ADC is
  triggered only on it's rising edges. Alternatively, that flag could be
  cleared inside the ADC ISR.

* I choose to deliver the readings by batches of 4 (one reading per
  channel), thus the buffering inside the ADC ISR. The choice is
  arbitrary: you can, if you wish, transmit the readings as they come,
  as suggested in jwpat's answer.

* The very first ADC reading is manually started and discarded. The only
  reason for this is that it takes longer (200 µs instead of 104).

* The readings are transmitted in binary form at 115.2 kb/s. The
  effective data rate is 80 kb/s. ASCII would not be possible at
  this sampling rate.

* The `loop()` function must never take more than 1 ms to execute,
  otherwise there is a risk of it reading the `adc_readings` array while
  the ADC ISR is updating it, which would lead to corrupt data.
  Protecting the access to `adc_readings` inside a `cli()`/`sei()` pair
  would not significantly ease the timing constraint, as a long `loop()`
  execution would still carry the risk of loosing data points.

From a cursory look at the [ATmega32u4
datasheet](http://www.atmel.com/Images/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf)
it would seem it's Timer 1 is identical to the one of the ATmega328P
powering the Uno, save for an extra PWM channel. The ADC, however, is
slightly different, but similar enough to make porting fairly
straightforward. At least the setting of `ADMUX` would be different.


body:
What you have here is a classic case of the measurement of something changing what is measured.

I guessed when I saw your question that the time taken to transmit all that serial data would be longer than 1 ms. If you really were transmitting at 115200 baud then it would take 2.6 ms to send the 30-odd bytes you are sending (30 * 1/11520). Since you are using a Leonardo you get USB speeds which is faster but not infinitely fast.

I could reproduce your figures when I tested.

However if I comment out the two lines that send the time:

    //    Serial.print(((double)currentMicros) / 1000000UL, 5 ); // 1 is the number of decimals to print
    //    Serial.print('\t');

And also measure separately by toggling pin 13:

      if ((currentMicros - previousMicros) >= INTERVAL_LENGTH_US)
      {
        previousMicros += INTERVAL_LENGTH_US;
        digitalWrite (13, !digitalRead (13));

Then I found that pin 13 toggled at exactly once per millisecond.

(edit) Close enough. See screenshot of logic analyser (0.996 ms):

[![Logic analyser][1]][1]

That is only 4 µs out - within error range for the processor clock.

Uncommenting the timing code I found that for a short time I still got 1 ms per iteration, but it then dropped down to around 1.04 ms (ie. 960 Hz). I am guessing that some USB buffer, somewhere, is filling up and not being emptied as fast as you would like.

Here is the screenshot of the code which sends the time (1.0366 ms):

[![Logic analyser - with debugging code][2]][2]

Notice how simply sending the number of microseconds has increased the time between toggling the pin?

---

It is helpful to have extra hardware to hand to measure things like this. Using the processor that you are trying to time, to send its own timing information is fraught with problems.

  [1]: https://i.stack.imgur.com/SDpgG.png
  [2]: https://i.stack.imgur.com/966hC.png


message:
What's the difference between all the Software Serial Libraries? Which one is Arduino Nano compatible?

There are so many Software Serial Libraries, what are the differences between them? And which one I can use with my Arduino Nano? For my Arduino Nano I need one Hardware Serial Port and one Software Serial port at a baud rate of 115200.

On which pins of the Arduino Nano can I use the software serial library?

body:
[This answer](https://arduino.stackexchange.com/questions/26240/which-pins-of-an-arduino-uno-can-be-used-as-tx-and-rx-pins-for-connecting-to-gsm/26277#26277) lists the 4 basic choices:

* `HardwareSerial`, always the best.  Simply use the pre-defined `Serial` variable.  On some Arduinos, there are extra HardwareSerial ports, called `Serial1`, `Serial2`, etc.  The Nano only has `Serial`.

* [`AltSoftSerial`](https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html), the best of the software serial libraries.  Only one instance is allowed, and it is must be used on one of the Input Capture pins (pins 8 & 9 for a Nano).

*  My [`NeoSWSerial`](https://github.com/SlashDevin/NeoSWSerial) is next best.  It works on any two pins, but only at baud rates 9600, 19200 and 38400.

*  `SoftwareSerial` is the worst choice.  It works on any two pins, but it is very inefficient.  It disables interrupts for the entire time that a character is being sent **OR** received, and it cannot do both at the same time (unlike all the other serial choices).  This can interfere with other parts of your sketch, other device communications, or with libraries.

If you could use a slower baud rate, you could keep your debug prints on `Serial`, and use either `AltSoftSerial` or `NeoSWSerial` for your device.

But if you have to use 115200, the only reliable choice is `Serial`.  Although `AltSoftSerial` and `SoftwareSerial` allow that baud rate, they may not send/receive data correctly.

In that case, I would suggest using `Serial` for the 115200 device.  Unless you are using an ISP, you will have to disconnect the device to upload a new sketch over USB.

Then use `AltSoftSerial` or `NeoSWSerial` for your debug statements.  You will need a TTL Serial-to-USB adapter (aka FTDI) on the selected pins to connect to the PC.  The `Serial Monitor` or other [Terminal emulator program](https://en.wikipedia.org/wiki/Terminal_emulator) will read from that USB COM port.


message:
I2C conflict with 2 Arduinos

I am having some trouble connecting my 2 Arduino Nanos with I2C. I have this configuration:

* SLAVE RECEIVER Nano with DS1037 and LCD 16x02 on I2C.
* MASTER SENDER Nano.

After some time the Slave receiver prints on LCD random chars. If I delete the line including library RTCLIB.h everything is working except the clock. Thanks for your help :D

Slave receiver code:
<!-- language-all: lang-cpp -->

    #include <Wire.h> // include la libreria
    #include <LiquidCrystal_I2C.h>
    #include "RTClib.h"

    LiquidCrystal_I2C lcd(0x3E, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    RTC_DS1307 RTC; // orologio

    static int anno;
    static int giorno;
    static int mese;
    static int ora;
    static int secondo;
    static int oldSecondo;
    static int minuto;
    static int oldMinuto;
    static int annoGrezzo;

    //------------------------------------------------------------
    // si ripete la union esattamente come nel master
    union Scomp_float {
      // si utilizza union x float
      float temp;
      char byte_s[4];
    } S_float;

    //------------------------------------------------------------
    // si ripete la union esattamente come nel master
    union Scomp_long {
      // si utilizza union x long
      long int mioL;
      char byte_sL[4];
    } S_long;

    //------------------------------------------------------------
    //------------- byte temporanei
    byte f0 = 0;   // contengono i byte ricevuti
    byte f1 = 0;
    byte f2 = 0;
    byte f3 = 0;
    byte a1 = 0;
    //-------------------------------------------------------------
    //  qui si introdurranno i dati ricomposti dopo la trasmissione
    long int masterLong = 0;
    float masterFloat = 0;
    int masterInt = 0;
    //--------------------------------------------------------------

    void setup() {
      Wire.begin(80);                // join i2c bus with address #4
      Wire.onReceive(receiveEvent); // register event
      lcd.begin(16, 2);
      Serial.begin(9600);           // start serial for output
      //-----------orologio-----------
      RTC.begin();
      // Check to see if the RTC is keeping time.  If it is, load the time from your computer.
      if (! RTC.isrunning()) {
        Serial.println("RTC is NOT running!");
        // This will reflect the time that your sketch was compiled
        RTC.adjust(DateTime(__DATE__, __TIME__));
      }
      //-----------fine orologio-----------
    }

    void loop() {
      //------------------------------------------------------------
      //   si stampano i dati ricevuti e ricomposti
      //------------------------------------------------------------
      Serial.println(masterInt);
      Serial.println(masterLong);
      Serial.println(masterFloat);
      DateTime now = RTC.now();
      annoGrezzo = now.year();
      anno = ( annoGrezzo % 100);
      mese = now.month();
      giorno = now.day();
      ora = now.hour();
      minuto = now.minute();
      lcd.setCursor(0, 0);
      lcd.print(masterInt);
      lcd.setCursor(0, 1);
      lcd.print(giorno);
      lcd.print(" ");
      lcd.print(mese);
      lcd.print(" ");
      lcd.print(anno);
      lcd.print("  ");
      lcd.print(ora);
      lcd.print(":");
      lcd.print(minuto);
      delay (1000);
      lcd.clear();
    }

    // function that executes whenever data is received from master
    // this function is registered as an event, see setup()
    void receiveEvent(int howMany) {
      if (howMany == 2) {
        // se in arrivo due dati
        f0 = Wire.read(); // si leggono i byte
        f1 = Wire.read();
        masterInt =  ((f1 << 8) | f0); // si ricompone l'intero
      }

      if (howMany == 4) {
        // se in arrivo 4 dati è un float
        f0 = Wire.read();  // si leggono i byte
        f1 = Wire.read();
        f2 = Wire.read();
        f3 = Wire.read();
        S_float.byte_s[0] = f0; // si ricompone il float
        S_float.byte_s[1] = f1;
        S_float.byte_s[2] = f2;
        S_float.byte_s[3] = f3;
        masterFloat = S_float.temp;
      }

      if (howMany == 5) {
        // se in arrivo 5 dati è un long
        f0 = Wire.read();  // si leggono i byte
        f1 = Wire.read();
        f2 = Wire.read();
        f3 = Wire.read();
        a1 = Wire.read();
        S_long.byte_sL[0] = f0;  // si ricompone  il long
        S_long.byte_sL[1] = f1;
        S_long.byte_sL[2] = f2;
        S_long.byte_sL[3] = f3;
        masterLong = S_long.mioL;
      }
    }

Master sender code:

    #include <Wire.h> // si include la libreria
    //---------------------------------------------------------
    union Scomp_float {
     // si utilizza union x float
      float temp;
      char byte_s[4];
    } S_float;
    //---------------------------------------------------------
    union Scomp_long {
     // si utilizza union x long
      long int mioL;
      char byte_sL[4];
    } S_long;
    //----------------------------------------------------------
    // questi sono i dati che si vogliono trasmettere

    long int mioLong = 1234567801;
    float mioFlo = 123456.29;
    //----------------------------------------------------------
    byte a1 = 0; // conterrà i primo byte dell'int
    byte a2 = 0; // conterrà il secondo byte dell'int
    byte f0 = 0; // contengono i byte del float e del long
    byte f1 = 0;
    byte f2 = 0;
    byte f3 = 0;
    void setup() {
      Wire.begin(); // join i2c bus (address optional for master)
    }

    void loop() {
      int mioInt = random(30000);
     //-----------------------------------------------------
     // trasmissione di un intero ( 2 byte)
     //-----------------------------------------------------
      a1 = byte(mioInt); // si scompone l'intero in 2 byte
      a2 = byte( mioInt >> 8);
      Wire.beginTransmission(80); // inzia trasmissione allo slave

      Wire.write(a1); //  invia un byte
      Wire.write(a2); //  invia il secondo byte
      Wire.endTransmission(); // stop transmitting
     //------------------------------------------------------
      delay (2000);
     //------------------------------------------------------
     // trasmissione intero lungo 4 byte
     //------------------------------------------------------
      S_long.mioL = mioLong; // si scompone in 4 byte
      f0 = S_long.byte_sL[0];
      f1 = S_long.byte_sL[1];
      f2 = S_long.byte_sL[2];
      f3 = S_long.byte_sL[3];
      a1 = 1; // si trasmette questo byte solo per segnalare allo slave
     // che stiamo trasmettendo un long
     // una volta scomposto si trasmettono i 4 byte
      Wire.beginTransmission(80); // trasmette allo slave
      Wire.write(f0); // invia un byte
      Wire.write(f1); //
      Wire.write(f2); //
      Wire.write(f3); //  invia un byte
      Wire.write(a1);
      Wire.endTransmission(); // fine trasmissione
     //-------------------------------------------------------
      delay (2000);
     //------------------------------------------------------
     //   trasmissione di un float 4 byte
     //------------------------------------------------------
      S_float.temp = mioFlo; // si scompone in 4 byte
      f0 = S_float.byte_s[0];
      f1 = S_float.byte_s[1];
      f2 = S_float.byte_s[2];
      f3 = S_float.byte_s[3];
     // una volta scomposto si trasmettono i 4 byte
      Wire.beginTransmission(80); // trasmette allo slave
      Wire.write(f0); // invia un byte
      Wire.write(f1); //
      Wire.write(f2); //
      Wire.write(f3); //  invia un byte
      Wire.endTransmission(); // fine trasmissione
     //-------------------------------------------------------
      delay (3000);
    }
    //------ end master ----------------------------------

body:
i partially resolve the problem with this:

MASTER RECEIVER code:

    #include <Wire.h> // include la libreria
    #include <LiquidCrystal_I2C.h>
    #include "RTClib.h"

    LiquidCrystal_I2C lcd(0x3E, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    RTC_DS1307 RTC; // orologio

    static int anno;
    static int giorno;
    static int mese;
    static int ora;
    static int secondo;
    static int oldSecondo;
    static int minuto;
    static int oldMinuto;
    static int annoGrezzo;
    char t[10] = {};
    char v[10] = {};

    void setup()
    {
      Wire.begin();                // join i2c bus with address #4
      lcd.begin(16, 2);
      Serial.begin(9600);           // start serial for output

      //-----------orologio-----------

      RTC.begin();
      // Check to see if the RTC is keeping time.  If it is, load the time from your computer.
      if (! RTC.isrunning())
      {
        Serial.println("RTC is NOT running!");
        // This will reflect the time that your sketch was compiled
        RTC.adjust(DateTime(__DATE__, __TIME__));
      }
      //-----------fine orologio-----------

    }

    void loop()
    {
      //------------------------------------------------------------
      //   si stampano i dati ricevuti e ricomposti
      //------------------------------------------------------------
      Wire.requestFrom(8, 3);
      int i = 0;
      while (Wire.available()) {
        t[i] = Wire.read(); // every character that arrives it put in order in the empty array "t"
        i = i + 1;
      }
      Wire.requestFrom(8, 3);
      i=0;
      while (Wire.available()) {
        v[i] = Wire.read(); // every character that arrives it put in order in the empty array "v"
        i = i + 1;
      }
      Serial.println(t);
      DateTime now = RTC.now();
      annoGrezzo = now.year();
      anno = ( annoGrezzo % 100);
      mese = now.month();
      giorno = now.day();
      ora = now.hour();
      minuto = now.minute();
      lcd.setCursor(0, 0);
      lcd.print(t);
      lcd.setCursor(5,0)
      lcd.print(v);
      lcd.setCursor(0, 1);
      lcd.print(giorno);
      lcd.print(" ");
      lcd.print(mese);
      lcd.print(" ");
      lcd.print(anno);
      lcd.print("  ");
      lcd.print(ora);
      lcd.print(":");
      lcd.print(minuto);

      delay (1000);
      lcd.clear();
    }

    // function that executes whenever data is received from master
    // this function is registered as an event, see setup()

SLAVE SENDER code:

    #include <Wire.h> // si include la libreria
    //---------------------------------------------------------

    char t[10];
    char v[10];

    void setup()
    {
      Wire.begin(8); // join i2c bus (address optional for master)
       Wire.onRequest(requestEvent);
    }

    void loop()
    {
     int mioInt = random(30000);
     int mioInt2 = 1234;
      dtostrf(mioInt, 3, 2, t); //convers the float or integer to a string. (floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, empty array);
      dtostrf(mioInt2, 3, 2, v);
    //------------------------------------------------------
    delay (500);
    }
    void requestEvent() {
      Wire.write(t);
      Wire.write(v);
    }
    //------ end slave    ----------------------------------

now my problem is the second variable T im unable to receive it on Master. Thanks for help


body:
I don't know what your problem is, but you have a gross error at `LiquidCrystal_I2C lcd(0x3E, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);`. You have a I2C LCD display but you are using it as an old-style LCD initialization.

The correct initialization for and I2C LCD display is

    LiquidCrystal(0x2A, 16, 2);

You have to replace 0x2A for the correct I2C address of your LCD display (Use a I2C scanner sketch for that).

You have to check the API of your libraries first (usually a .h file):

        /**
      * Constructor
      *
      * @param lcd_addr I2C slave address of the LCD display. Most likely printed on the
      *     LCD circuit board, or look in the supplied LCD documentation.
      * @param lcd_cols Number of columns your LCD display has.
      * @param lcd_rows Number of rows your LCD display has.
      * @param charsize The size in dots that the display has, use LCD_5x10DOTS or LCD_5x8DOTS.
      */
    LiquidCrystal_I2C(uint8_t lcd_addr, uint8_t lcd_cols, uint8_t lcd_rows, uint8_t charsize = LCD_5x8DOTS);


message:
I2C wire.h send 2 variables

I am trying to send 2 variables with `wire.h`. I tried with  this code:

MASTER RECEIVER:
<!-- language-all: lang-cpp -->

    #include <Wire.h> // include la libreria
    #include <LiquidCrystal_I2C.h>
    #include "RTClib.h"

    LiquidCrystal_I2C lcd(0x3E, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
    RTC_DS1307 RTC; // orologio

    static int anno;
    static int giorno;
    static int mese;
    static int ora;
    static int secondo;
    static int oldSecondo;
    static int minuto;
    static int oldMinuto;
    static int annoGrezzo;
    char t[10] = {};
    char v[10] = {};

    void setup() {
      Wire.begin(); // join i2c bus with address #4
      lcd.begin(16, 2);
      Serial.begin(9600); // start serial for output
      //-----------orologio-----------
      RTC.begin();
      // Check to see if the RTC is keeping time. If it is, load the time from your computer.
      if (! RTC.isrunning()) {
        Serial.println("RTC is NOT running!");
        // This will reflect the time that your sketch was compiled
        RTC.adjust(DateTime(__DATE__, __TIME__));
      }
      //-----------fine orologio-----------
    }

    void loop() {
      //------------------------------------------------------------
      //   si stampano i dati ricevuti e ricomposti
      //------------------------------------------------------------
      Wire.requestFrom(8, 6);
      int i = 0;
      while (Wire.available()) {
        Serial.println(i);
        t[i] = Wire.read();
        // every character that arrives it put in order in the empty array "t"
        i = i + 1;
      }
      Serial.println(t);
      DateTime now = RTC.now();
      annoGrezzo = now.year();
      anno = (annoGrezzo % 100);
      mese = now.month();
      giorno = now.day();
      ora = now.hour();
      minuto = now.minute();
      lcd.setCursor(0, 0);
      lcd.print(t);
      lcd.setCursor(5,0);
      lcd.print(v);
      lcd.setCursor(0, 1);
      lcd.print(giorno);
      lcd.print(" ");
      lcd.print(mese);
      lcd.print(" ");
      lcd.print(anno);
      lcd.print("  ");
      lcd.print(ora);
      lcd.print(":");
      lcd.print(minuto);
      delay (1000);
      lcd.clear();
    }

SLAVE SENDER

    #include <Wire.h> // si include la libreria
    //---------------------------------------------------------
    char t[10];
    char v[10];

    void setup() {
      Wire.begin(8);
      // join i2c bus (address optional for master)
      Wire.onRequest(requestEvent);
    }

    void loop() {
      int mioInt = random(30000);
      int mioInt2 = 1234;
      dtostrf(mioInt, 3, 2, t);
      //convers the float or integer to a string. (floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, empty array);
      dtostrf(mioInt2, 3, 2, v);
      //------------------------------------------------------
      delay (500);
    }

    void requestEvent() {
      Wire.write(t);
      Wire.write(v);
    }

I'm unable to receive `v` in my master receiver. Thanks for your help.

body:
I2C is 8-bit data bus, where address can be 7 bit or 10 bit, you can't send more than 8 bit at a time, if you want to send data more than 8 bit you will be sending them like this, for example let you need to send 16 bit data then you send 8 bit LSB first and then 8 bit MSB or vice versa as per your configuration.

Secondly I had noticed you code and noticed many errors, the major one is that **you hadn't followed the rules of I2C protocol** in your code. I am here attached a link for sample program of [arduino i2c slave and master](https://circuitdigest.com/microcontroller-projects/arduino-i2c-tutorial-communication-between-two-arduino). Go through it you will get your answer.


message:
In ESP-12E NodeMCU, what's the pin number of A0?

In ESP-12E NodeMCU, all digital pins can be called with a number. Here is the list:

 static const uint8_t D0   = 16;
 static const uint8_t D1   = 5;
 static const uint8_t D2   = 4;
 static const uint8_t D3   = 0;
 static const uint8_t D4   = 2;
 static const uint8_t D5   = 14;
 static const uint8_t D6   = 12;
 static const uint8_t D7   = 13;
 static const uint8_t D8   = 15;
 static const uint8_t D9   = 3;
 static const uint8_t D10  = 1;

So these two lines of code will do the same:

    pinMode (D0, INPUT)
    pinMode (16, INPUT)

What's the corresponding number for A0 (the only analog input of this board)?

body:
The numeric value of `A0` is 17, as defined [here](https://github.com/esp8266/Arduino/blob/2.3.0/variants/generic/common.h#L45).

But unlike on an Arduino board, you can't use it as a digital pin. [It only work for pin numbers 0-16](https://github.com/esp8266/Arduino/blob/2.3.0/cores/esp8266/core_esp8266_wiring_digital.c#L79).

If you are using as a parameter for `analogRead`, the numeric values would be 0 and 17, as seen [here](https://github.com/esp8266/Arduino/blob/2.3.0/cores/esp8266/core_esp8266_wiring_analog.c#L32).

And as such, these three calls would do the same:

<!-- language: lang-cpp -->

    analogRead(A0);
    analogRead(17);
    analogRead(0);


message:
Reverting Arduino Environment on OS X

I am using Arduino environment 1.6.17 on OS X, 10.12.2. In this version, all of the core avr library stuff is located in ~/Library/Arduino15.

I was told by a vendor that in order for their program to compile properly, I needed to compile it under 1.6.4 of the Arduino environment. I dowloaded that version and compiled the program again. I could tell though, by the compiler messages, that while the IDE may be version 1.6.4, the program was still compiling with version 1.6.17 tools and avr libraries. Is there anyway to change that so I can get it to actually compile with all tools and libs from 1.6.4?

body:
Try removing the Arduino app with [AppCleaner][1] or a similar application remover. AppCleaner should find any related files not contained within the app. Let it remove them. Then reinstall Arduino 1.6.4.

  [1]: http://freemacsoft.net/appcleaner/


body: I didn't try the total removal of the environment and then a re-installation as JRobert suggested, because I didn't really want to nuke my current environment. But his post did inspire me to try and run the 1.6.4 environment from another user account that had never run any Arduino stuff before. This seemed functionally equivalent to his or her suggestion. That seemed to work. Although, I still have a feeling that there is a more convenient solution out there.


body:
When you run a recent-ish version of the Arduino IDE, it installs stuff in `~/Library/Arduino15`, unless it already exists. So when you installed 1.6.4, it saw the `~/Library/Arduino15` folder and proceeded without installing its own version of the tools.

The only way to have your 1.6.4 running alongside a newer version is to have copies of the `~/Library/Arduino15` folder, by renaming them when appropriate.


message:
How to select arduino 101 in ubuntu?

How to I select arduino 101? I  have ubuntu.
[![enter image description here][1]][1]

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

body:
In that ancient version of the IDE? You don't.

You download and install the latest version of the IDE from the Arduino website, then use the Boards Manager to install the packages that include the Ardiuno 101.


body:
The default serial port it shows up in for me is *ttyACM0*

You can set this as your default port, so when you open the IDE with `sudo arduino`

    ~ $ vim ~/.arduino/preferences.txt

change the value for `serial.port`

    serial.port=ttyACM0


message:
How to compile a sketch using arduino-builder?

How do you compile a sketch with a custom library path using [arduino-builder][1]? The docs are a little light.

I have my source code organized like this:

    lib
        SomeLib
            somelib.h
            somelib.cpp
    src
        otherfile.h
        main.ino

I've installed Arduino 1.8.1 into /usr/share/arduino.

I'm trying to compile this for an Arduino Uno from my project root directory with:

    arduino-builder -compile -hardware /usr/share/arduino/hardware -tools /usr/share/arduino/hardware/tools -libraries lib -fqbn arduino:avr:uno -build-path .build src/main.ino

But it returns this error:

    fork/exec {runtime.tools.ctags.path}/ctags: no such file or directory

What's causing this error?

  [1]: https://github.com/arduino/arduino-builder

body:
You need to specify the path to the `tools-builder` folder, which is where `ctags` is. Try this:

    arduino-builder \
      -compile \
      -hardware /usr/share/arduino/hardware \
      -tools /usr/share/arduino/hardware/tools \
      -tools /usr/share/arduino/tools-builder \
      -libraries lib \
      -fqbn arduino:avr:uno \
      -build-path .build \
      src/main.ino


message:
Will M2.5 screws fit the holes in the Arduino Uno?

I'm developing a sump pump monitor/alarm setup that will include an Arduino Uno as well as a Raspberry Pi. Both boards will be mounted to a piece of wood. The Arduino is designed to take M3 screws, but the Pi is designed to take M2.5 screws. The difference in these two screw sizes is 0.5mm (2.4mm M2.5 vs 2.9mm M3). Is this going to be close enough to be able to use the smaller M2.5 screws for both? Due to cost reasons, I want to avoid having to purchase two different sizes of screws and standoffs.

body: With the screw holes for the Arduino being the larger screw holes, the 2.9mm screws would fit, but would probably need a nut and/or a washer to properly secure things. In the end if you intend to be doing more work with Arduinos and Pis in the future that require screwing things together then just go and get proper screw sizes, you won't regret it.


message:
How to set limits in Arduino of pin x to remain in high state?

I am working on this thermostat, which has a predefined int that sets pin high and low. But now I want to give it a particular range on which the pin 7 stays high, let's say from 24°C to 26°C, because I don't want my relay clicking every second.

    const int sensor=A1; // Assigning analog pin A1 to variable 'sensor'
    int relay=7;
    float tempc;  //variable to store temperature in degree Celsius
    float vout;  //temporary variable to hold sensor reading

    void setup() {
        pinMode(sensor,INPUT); // Configuring pin A1 as input
        Serial.begin(9600);
    }

    void loop() {
        vout=analogRead(sensor);
        vout=(vout*500)/1023;
        tempc=vout; // Storing value in Degree Celsius
        vout=analogRead(sensor);
        vout=(vout*500)/1023;
        tempc=vout; // Storing value in Degree Celsius
        Serial.print("temprature in C is ");
        Serial.print(tempc);
        Serial.println();
        delay(2000);
        if (tempc <24) {
          digitalWrite(7,HIGH);
          Serial.print("heating is on as " );
        } else {
          digitalWrite(7,LOW);
          Serial.print("heating is off as ");
        }

body:
Your question is not very clear, but I assume, like Mark Smith, that you
want your thermostat to be
[hysteretic](https://en.wikipedia.org/wiki/Hysteresis) between 24°C and
26°C. The algorithm is as follows:

* If the heater is OFF and you get a temperature reading below 24°C,
  then you switch it ON.

* If the heater is ON and you get a reading above 26°C, then you switch
  it OFF.

* In any other case, you leave the heater alone: it will stay in
  whatever state you have previously set it.

Translated to C++:

    // Pinout.
    const uint8_t sensor = A1;  // temperature sensor
    const uint8_t heater = 7;   // heater connected through a relay

    void setup()
    {
        pinMode(sensor, INPUT);
        pinMode(heater, OUTPUT);
        Serial.begin(9600);
    }

    void loop()
    {
        static bool heaterOn;
        float temperature = 500.0 / 1024 * analogRead(sensor);

        // Switch ON if the temperature drops below 24 Celsius.
        if (!heaterOn && temperature < 24) {
            Serial.println(F("Switching the heater ON."));
            digitalWrite(heater, HIGH);
            heaterOn = true;
        }

        // Switch OFF if the temperature rises above 26 Celsius.
        else if (heaterOn && temperature > 26) {
            Serial.println(F("Switching the heater OFF."));
            digitalWrite(heater, LOW);
            heaterOn = false;
        }
    }


message:
Wemos D1R2 - Onewire 2 DS18B20 passing to variable

I'm a beginer, did some tests with Uno and now have a Wemos D1R2 on my hands...
I'm building a sort of weather station that will send data to thingspeak.com and log this data there.
I managed to merge 2 examples together (1 to send data to thingspeak) and (1 to read 1 DS18B20 with onewire)
I now need to connect 2 or more DS18B20 sensors on the same Onewire BUS (I also managed to do this using this tutorial  http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#mult ), the readings come alright on serial monitor but when I try to send the readings to thingspeak a get a error:

> temp_logger_multime_sensors_2:174:  error: statement cannot resolve
> address of overloaded function

Serial.print printTemperature(Probe01);

My piece of code:
<!-- language-all: lang-cpp -->

    /* References
        DHT11 sensor data to Thingspeak using a Wemos D1
        http://www.esp8266learning.com/dht11-sensor-data-to-thingspeak-using-a-wemos-d1.php#codesyntax_3

       Rui Santos - Complete project details at http://randomnerdtutorials.com

       YourDuino Multiple DS18B20 Temperature Sensors on 1 wire
       http://arduino-info.wikispaces.com/Brick-Temperature-DS18B20#mult
       V1.01  01/17/2013 ...based on examples from Rik Kretzinger
    */

    #include <ESP8266WiFi.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>

    // replace with your channel’s thingspeak API key and your SSID and password
    String apiKey = "THINGSPEAKKEY";
    const char* ssid = "WIFINAME";
    const char* password = "WIFIPASSWORD";
    const char* server = "api.thingspeak.com";

    /*-----( Declare Constants and Pin Numbers )-----*/
    #define ONE_WIRE_BUS_PIN 5

    /*-----( Declare objects )-----*/
    // Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(ONE_WIRE_BUS_PIN);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    DeviceAddress Probe01 = { 0x28, 0xFF, 0x51, 0xA5, 0x61, 0x16, 0x03, 0x92 }; // probe 1
    DeviceAddress Probe02 = { 0x28, 0xFF, 0xF8, 0x99, 0x52, 0x16, 0x04, 0xB1 }; // probe 2

    WiFiClient client;

    void setup()   /****** SETUP: RUNS ONCE ******/
    {
      // start serial port to show results
        Serial.begin(115200);
      delay(10);

    /*  Serial.begin(9600);
      Serial.print("Initializing Temperature Control Library Version ");
      Serial.println(DALLASTEMPLIBVERSION);
      */
      // Initialize the Temperature measurement library
      sensors.begin();

     WiFi.begin(ssid, password);

      // Connecting to WiFi network
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected on IP ...");
      // Printing the ESP IP address
      Serial.println(WiFi.localIP());
    }

    /*-----( Declare User-written Functions )-----*/
      void printTemperature(DeviceAddress deviceAddress)
      {
      float tempC = sensors.getTempC(deviceAddress);
         if (tempC == -127.00)
         {
         Serial.print("Error getting temperature  ");
         }
         else
         {
         Serial.print(tempC);
         }
      }// End printTemperature

    void loop()   /****** LOOP: RUNS CONSTANTLY ******/
    {
      delay(1000);
      Serial.println();
      Serial.print("Number of Devices found on bus = ");
      Serial.println(sensors.getDeviceCount());
      Serial.print("Getting temperatures... ");
      Serial.println();

      // Command all devices on bus to read temperature

      sensors.requestTemperatures();

    float StrProbe01 = printTemperature(Probe01); //THINK PROBLEM IS HERE
    float StrProbe02 = printTemperature(Probe02); //AND HERE

      Serial.print("Probe 01 temperature is:   ");
        printTemperature(Probe01);  //<-- THIS PART WORKS
      Serial.println();

      Serial.print("Probe 02 temperature is:   ");
        printTemperature(Probe02);

      Serial.println();

    if (client.connect(server,80)) {
      String postStr = apiKey;
      postStr +="&field1=";
      postStr += float(StrProbe01);
      postStr +="&field2=";
       postStr += float(StrProbe02);
      postStr += "\r\n\r\n";

      client.print("POST /update HTTP/1.1\n");
      client.print("Host: api.thingspeak.com\n");
      client.print("Connection: close\n");
      client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
      client.print("Content-Type: application/x-www-form-urlencoded\n");
      client.print("Content-Length: ");
      client.print(postStr.length());
      client.print("\n\n");
      client.print(postStr);

      Serial.print("Temperature: ");
      Serial.print printTemperature(Probe01);
      Serial.print(" degrees Celsius Humidity: ");
      Serial.print printTemperature(Probe02);
      Serial.println("Sending data to Thingspeak");
      }
      client.stop();

      Serial.println("Waiting 20 secs");
      // thingspeak needs at least a 15 sec delay be een updates
      // 20 seconds to be safe
      delay(20000);

    }//--(end main loop )---

I suspect I have to transform `printTemperature(Probe01);` into a variable first (as you can see on the code) and use this variable on `postStr += StrProbe01;` as  but I tried as you can see on the code and it didnt work either.

*** UPDATE *** The code below works sending data to thingspeak and serial monitor fine with 1 DS18B20

    #include <ESP8266WiFi.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>

    // replace with your channel’s thingspeak API key and your SSID and password
    String apiKey = "THINGSPEAKKEY";
    const char* ssid = "WIFINAME";
    const char* password = "WIFIPASSWORD";
    const char* server = "api.thingspeak.com";

    const char* t2 = "5";
    const char* h2 = "12.34";

    //START DS18B20 Stuff
    // Data wire is plugged into pin D1 on the ESP8266 12-E - GPIO 5
    #define ONE_WIRE_BUS 5  // DS18B20 pin

    // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    OneWire oneWire(ONE_WIRE_BUS);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature DS18B20(&oneWire);
    char temperatureCString[6];
    char temperatureFString[6];

    //END DS18B20 stuff

    WiFiClient client;

    void setup()
    {
    Serial.begin(115200);
    delay(10);

    // dht.begin();
    DS18B20.begin(); // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement

    WiFi.begin(ssid, password);

    // Connecting to WiFi network
    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED)
    {
    delay(500);
    Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected on IP ...");
    // Printing the ESP IP address
    Serial.println(WiFi.localIP());
    }

    void getTemperature() {
      float tempC;
      float tempF;
      do {
        DS18B20.requestTemperatures();
        tempC = DS18B20.getTempCByIndex(0);
        dtostrf(tempC, 2, 2, temperatureCString);
        tempF = DS18B20.getTempFByIndex(0);
        dtostrf(tempF, 3, 2, temperatureFString);
        delay(100);
      } while (tempC == 85.0 || tempC == (-127.0));
    }

    // runs over and over again
    void loop()
    {

     getTemperature();

    if (client.connect(server,80)) {
    String postStr = apiKey;
    postStr +="&field1=";
    postStr += String(temperatureCString);
    postStr +="&field2=";
    postStr += String(temperatureFString);
    postStr += "\r\n\r\n";

    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(postStr.length());
    client.print("\n\n");
    client.print(postStr);

    Serial.print("Temp in C: ");
    Serial.print(temperatureCString);
    Serial.print(" and Temp in F: ");
    Serial.print(temperatureFString);
    Serial.println("Sending data to Thingspeak");
    }
    client.stop();

    Serial.println("Waiting 20 secs");
    // thingspeak needs at least a 15 sec delay be een updates
    // 20 seconds to be safe
    delay(20000);
    }

And this code works fine displaying 2 DS18B20 on serial monitor connected to 1 Onewire BUS, but I need to implement (uncomment) the thingspeak part now.

    #include <ESP8266WiFi.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>

    // replace with your channel’s thingspeak API key and your SSID and password
    String apiKey = "THINGSPEAKKEY";
    const char* ssid = "WIFINAME";
    const char* password = "WIFIPASSWORD";
    const char* server = "api.thingspeak.com";

    /*-----( Declare Constants and Pin Numbers )-----*/
    #define ONE_WIRE_BUS_PIN 5

    /*-----( Declare objects )-----*/
    // Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(ONE_WIRE_BUS_PIN);

    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);

    DeviceAddress Probe01 = { 0x28, 0xFF, 0x51, 0xA5, 0x61, 0x16, 0x03, 0x92 }; // probe 1
    DeviceAddress Probe02 = { 0x28, 0xFF, 0xF8, 0x99, 0x52, 0x16, 0x04, 0xB1 }; // probe 2

    WiFiClient client;

    void setup()   /****** SETUP: RUNS ONCE ******/
    {
      // start serial port to show results
        Serial.begin(115200);
      delay(10);

      // Initialize the Temperature measurement library
      sensors.begin();

     WiFi.begin(ssid, password);

      // Connecting to WiFi network
      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

      while (WiFi.status() != WL_CONNECTED)
      {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.println("WiFi connected on IP ...");
      // Printing the ESP IP address
      Serial.println(WiFi.localIP());

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

    /*-----( Declare User-written Functions )-----*/
      void printTemp(DeviceAddress deviceAddress)
      {
      float tempC = sensors.getTempC(deviceAddress);
         if (tempC == -127.00)
         {
         Serial.print("Error getting temperature  ");
         }
         else
         {
         Serial.print(tempC);
         }
      }// End printTemp

    void loop()   /****** LOOP: RUNS CONSTANTLY ******/
    {
      delay(1000);
      Serial.println();
      Serial.print("Number of Devices found on bus = ");
      Serial.println(sensors.getDeviceCount());
      Serial.print("Getting temperatures... ");
      Serial.println();

      // Command all devices on bus to read temperature

      sensors.requestTemperatures();

      Serial.print("Probe 01 temperature is:   ");
        printTemp(Probe01);
      Serial.println();

      Serial.print("Probe 02 temperature is:   ");
        printTemp(Probe02);

      Serial.println();

    /*
    if (client.connect(server,80)) {
      String postStr = apiKey;
      postStr +="&field1=";
      postStr += float(StrProbe01);
      postStr +="&field2=";
       postStr += float(StrProbe02);
      postStr += "\r\n\r\n";

      client.print("POST /update HTTP/1.1\n");
      client.print("Host: api.thingspeak.com\n");
      client.print("Connection: close\n");
      client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
      client.print("Content-Type: application/x-www-form-urlencoded\n");
      client.print("Content-Length: ");
      client.print(postStr.length());
      client.print("\n\n");
      client.print(postStr);

      Serial.print("Temperature: ");
      Serial.print printTemp(Probe01);
      Serial.print(" degrees Celsius Humidity: ");
      Serial.print printTemp(Probe02);
      Serial.println("Sending data to Thingspeak");
      }
      client.stop();

      Serial.println("Waiting 20 secs");
      // thingspeak needs at least a 15 sec delay be een updates
      // 20 seconds to be safe
      delay(20000);
     */
    }//--(end main loop )---

It has all to do on generate a sort of variable (perhaps float , im not sure) and passing it as a http string

Thanks

body:
Since the DeviceInformation variables are not POD (Plain Old Data) it would be slightly more efficient to use references or pointers, this will avoid copying them around.  If you do that you could make you global variables Probe01 and Probe02 const variables.

In loop around line 98 you call printTemperature() and assign the return value to a float.  Which is very strange, because around line 72 you define `void printTemperature()`.  So I suspect there may be a function in the Dalas library call printTemperature that returns a float and this is the overloaded function it is talking about.

So to fix it change the name of you printTemperature function and change the two lines it is called on.  Hopefully that will fix this problem.


body:
Re your edit : I'd create a new project and put just the commented out code in setup (and the minimum you need to get it working) and then post the problems you have with that.

I can't see any compile problems, but the data you are sending to thingspeak doesn't look right.  I think you are sending:

    String postStr = apiKey + "&field1=" + float(StrProbe01) + "&field2=" + float(StrProbe02) + "\r\n\r\n";

And I think you should be sending:

    String postStr = "field1=" + float(StrProbe01) + "&field2=" + float(StrProbe02) + "\r\n\r\n";

(Based on this example [Arduino.cc][1])

  [1]: https://www.arduino.cc/en/Tutorial/WiFi101ThingSpeakDataUploader


body:
In the code that works, you have:

    if (client.connect(server,80)) {
    String postStr = apiKey;
    postStr +="&field1=";
    postStr += String(temperatureCString);
    postStr +="&field2=";
    postStr += String(temperatureFString);
    postStr += "\r\n\r\n";

In the code that does not work you are doing this:

    if (client.connect(server,80)) {
      String postStr = apiKey;
      postStr +="&field1=";
      postStr += float(StrProbe01);
      postStr +="&field2=";
       postStr += float(StrProbe02);
      postStr += "\r\n\r\n";

Print out the both the Strings that you are sending, postStr, using Serial.print. Compare the result. I'm not at home at the moment to try it out, but I'm sure the float(StrProbe01) and float(StrProbe02) is wrong. Thingspeak explains in their guidelines what the string that you are sending should look like.


body:
Try returning float from printTemp:

     /*-----( Declare User-written Functions )-----*/
      float printTemp(DeviceAddress deviceAddress)
      {
      float tempC = sensors.getTempC(deviceAddress);
         if (tempC == -127.00)
         {
         Serial.print("Error getting temperature  ");
         }
         /* else
         {
         Serial.print(tempC);
         }
         */ you won't be needing this
         return tempC;
      }// End printTemp

And call it as you would in your commented example.
I suspect that it is not the most efficient way, but it should work.


message:
Can't get deep sleep to work on Wemos D1 ESP8266

I have a Wemos D1 (ver. 2015-08) and I am trying to get it to sleep. I've managed to get it generally up and running/got wifi to work etc, but the deep sleep function is beyond me.

I tried connecting RX<-D0 pin to RESET, also tried with a 10k resistor. Neither worked. I then tried D2 (listed as gpi016 on the back of the board) to RESET, this also didn't work. Any ideas? It seems like this would be an incredible chip if I could get it to sleep. The example sketch below uploads fine and contacts the serial monitor, up until the point it sleeps.

     /* Deep Sleep - Blink
     *
     * Blinks the onboard LED, sleeps for 10 seconds and repeats
     *
     * Connections:
     * D0 -- RST
     *
     * If you cant reprogram as the ESP is sleeping, disconnect D0 - RST and try again
     */

    // sleep for this many seconds
    const int sleepSeconds = 5;

    void setup() {
      Serial.begin(9600);
      Serial.println("\n\nWake up");
      pinMode(BUILTIN_LED, OUTPUT);
      // Connect D0 to RST to wake up
      pinMode(D0, WAKEUP_PULLUP);
      // LED: LOW = on, HIGH = off
      Serial.println("Start blinking");
      for (int i = 0; i < 20; i++) {
        digitalWrite(BUILTIN_LED, LOW);
        delay(100);
        digitalWrite(BUILTIN_LED, HIGH);
        delay(100);
      }
      Serial.println("Stop blinking");
      Serial.printf("Sleep for %d seconds\n\n", sleepSeconds);
      // convert to microseconds
      ESP.deepSleep(sleepSeconds * 1000000);
      Serial.println("sleep finished");
    }

    void loop() {
    }

body: I had to physically connect D0 to RST to wake up the wemos.


body:
In fact it works well using a wire between D2 and RESET pins. But sending the program to the board, you must first disconnect these pin (the arduino IDE will send a hard reset during process, so this D2 reset must not be in place). When the program is uploaded to the ESP and start running, you connect D2 and RESET and it works well, ESP will go to deep sleep mode as expected.

Because it is not a mini, the board has another chip (usb) that will not got to sleep mode, so on my board it will use about 17mA in deep sleep (compare with 80mA in wifi normal operation). Still worth the trick.


message:
decomposition long number to byte and recomposition With FRAM

I'm using Adafruit FRAM for my little project and have some trouble with recomposition of LONG Variable , right now the recomposition on INTEGER it's fine.
Where I'm wrong with recomposition of LONG number? Thank's for reply :D

    #include <SPI.h>
    #include "Adafruit_FRAM_SPI.h"

    /* Example code for the Adafruit SPI FRAM breakout */
    uint8_t FRAM_CS = 10;

    //Adafruit_FRAM_SPI fram = Adafruit_FRAM_SPI(FRAM_CS);  // use hardware SPI

    uint8_t FRAM_SCK = 13;
    uint8_t FRAM_MISO = 12;
    uint8_t FRAM_MOSI = 11;
    //Or use software SPI, any pins!
    Adafruit_FRAM_SPI fram = Adafruit_FRAM_SPI(FRAM_SCK, FRAM_MISO, FRAM_MOSI, FRAM_CS);

    uint16_t          addr = 0;

    #if defined(ARDUINO_ARCH_SAMD)
    // for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
    #define Serial SerialUSB
    #endif

    void setup(void) {
    #ifndef ESP8266
      while (!Serial);     // will pause Zero, Leonardo, etc until serial console opens
    #endif

      Serial.begin(9600);

      if (fram.begin()) {
        Serial.println("Found SPI FRAM");
      } else {
        Serial.println("No SPI FRAM found ... check your connections\r\n");
        while (1);
      }
      int interoDaScrivere = 12345;
      long longDaScrivere = 123456789;
      byte a1 = 0;
      byte a2 = 0;
      byte intPt0 = 0;
      byte intPt1 = 0;
      byte longPt1 = 0;
      byte longPt2 = 0;
      byte longPt3 = 0;
      byte longPt4 = 0;
      a1 = byte(interoDaScrivere);        // si scompone l'intero in 2 byte
      a2 = byte( interoDaScrivere >> 8);
      //decomposition Long

      byte b1 = (longDaScrivere);
      byte b2 = (longDaScrivere >> 8);
      byte b3 = (longDaScrivere >> 16);
      byte b4 = (longDaScrivere >> 24);

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

      // Read the first byte
      uint8_t test = fram.read8(0x0);
      Serial.print("Restarted "); Serial.print(test); Serial.println(" times");

      // Test write ++
      fram.writeEnable(true);
      fram.write8(0x0, test + 1);
      fram.writeEnable(false);
      /*
        fram.writeEnable(true);
        fram.write(0x1, (uint8_t *)"FTW!", 5);
        fram.writeEnable(false);
      */

      fram.writeEnable(true);
      fram.write8(1, a1);
      fram.writeEnable(false);
      fram.writeEnable(true);
      fram.write8(2, a2);
      fram.writeEnable(false);

      fram.writeEnable(true);
      fram.write8(3, b1);
      fram.writeEnable(false);
      fram.writeEnable(true);
      fram.write8(4, b2);
      fram.writeEnable(false);
      fram.writeEnable(true);
      fram.write8(5, b3);
      fram.writeEnable(false);
      fram.writeEnable(true);
      fram.write8(6, b4);
      fram.writeEnable(false);

      //ricomposizione INT
      int interoRicomposto = 0;
      intPt0 = fram.read8(1);
      intPt1 = fram.read8(2);
      //INT RECOMPOSITION
      interoRicomposto =  ((intPt1 << 8) | intPt0);
      // ricomposizione LONG
      long longRicomposto = 0;
      longPt1 = fram.read8(3);
      longPt2 = fram.read8(4);
      longPt3 = fram.read8(5);
      longPt4 = fram.read8(6);
     //LONG RECOMPOSITION
      longRicomposto = ((longPt4 << 0) + (longPt3 << 8) + (longPt2 << 16) + (longPt1 << 24));

      Serial.print("A1 F0 ");
      Serial.print(a1);
      Serial.print(" ");
      Serial.println(intPt0);
      Serial.print("A2  F1 ");
      Serial.print(a2);
      Serial.print(" ");
      Serial.println(intPt1);
      Serial.println(interoRicomposto);

      Serial.print("b1 LongPt1 ");
      Serial.print(b1);
      Serial.print(" ");
      Serial.println(longPt1);
      Serial.print("b2 LongPt2 ");
      Serial.print(b2);
      Serial.print(" ");
      Serial.println(longPt2);
      Serial.print("b3 LongPt3 ");
      Serial.print(b3);
      Serial.print(" ");
      Serial.println(longPt3);;
      Serial.print("b4 LongPt4 ");
      Serial.print(b4);
      Serial.print(" ");
      Serial.println(longPt4);

      Serial.println(longRicomposto);

    }

    void loop(void) {

    }

body:
There is one very obvious error in your code: You are writing the `long`
number LSB (least significant byte) first: the LSB goes at address 3 of
the FRAM, while the MSB (most significant byte) goes at address 6. You
reconstruct the number with

    longRicomposto = ((longPt4 << 0) + (longPt3 << 8) + (longPt2 << 16) + (longPt1 << 24));

which puts `longPt1` (contents of address 3) as the most significant
byte. Thus you are swapping all the bytes around.

Then there is a more subtle error. `longPt1` is a `byte`. According to the
C++ promotion rules, it is implicitly promoted to `int` before any
arithmetic or logical operation. But since an `int` is 16-bits, you are
shifting _all the bits out_ when you do `longPt1 << 24`. You should cast
the numbers to a 32-bit type before shifting, as follows:

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

    long longRicomposto = (uint32_t) longPt1 <<  0
                        | (uint32_t) longPt2 <<  8
                        | (uint32_t) longPt3 << 16
                        | (uint32_t) longPt4 << 24;

Note that I am casting to an _unsigned_ type. Shifting a 1 into the bit
sign of an integer is undefined behavior in C++: the shift must be done
with an unsigned type, _then_, if needed, cast to a signed type.


body:
Let's cut out all the rubbish from your code and just look at the relevant lines:

    byte b1 = (longDaScrivere);
    byte b2 = (longDaScrivere >> 8);
    byte b3 = (longDaScrivere >> 16);
    byte b4 = (longDaScrivere >> 24);

    fram.write8(3, b1);
    fram.write8(4, b2);
    fram.write8(5, b3);
    fram.write8(6, b4);

    longPt1 = fram.read8(3);
    longPt2 = fram.read8(4);
    longPt3 = fram.read8(5);
    longPt4 = fram.read8(6);

    longRicomposto = ((longPt4 << 0) + (longPt3 << 8) + (longPt2 << 16) + (longPt1 << 24));

If we now compress it even more by removing the fram stuff and just assigning direct from b? to the equivalent longPt? you can see even better what is happening:

    byte b1 = (longDaScrivere);
    byte b2 = (longDaScrivere >> 8);
    byte b3 = (longDaScrivere >> 16);
    byte b4 = (longDaScrivere >> 24);

    longPt1 = b1;
    longPt2 = b2;
    longPt3 = b3;
    longPt4 = b4;

    longRicomposto = ((longPt4 << 0) + (longPt3 << 8) + (longPt2 << 16) + (longPt1 << 24));

Now if we remove the b? variables completely and just assign direct to longPt? we get:

    longPt1 = (longDaScrivere);
    longPt2 = (longDaScrivere >> 8);
    longPt3 = (longDaScrivere >> 16);
    longPt4 = (longDaScrivere >> 24);

    longRicomposto = ((longPt4 << 0) + (longPt3 << 8) + (longPt2 << 16) + (longPt1 << 24));

And if we then split the last line up so it looks more like the first block:

    longPt1 = (longDaScrivere);
    longPt2 = (longDaScrivere >> 8);
    longPt3 = (longDaScrivere >> 16);
    longPt4 = (longDaScrivere >> 24);

    longRicomposto  = (longPt4 << 0);
    longRicomposto |= (longPt3 << 8);
    longRicomposto |= (longPt2 << 16);
    longRicomposto |= (longPt1 << 24);

Hopefully from that it is now clear where you have gone wrong.

You take the lowest 8 bits `(longDaScrivere)` and shift them 24 places to the left (`(longPt1 << 24)`), and apply that to the recombined long.

In effect, you start with 4 bytes `ABCD` and reverse them through bit shifting - 0 goes to 24, 8 to 16, 16 to 8 and 24 to 0, to end up with `DCBA`.


body:
There is actual a member function in the [Adafruit_FRAM_SPI][1] library that solves all of this. There is no need for all this shifting.

    int interoDaScrivere = 12345;
    long longDaScrivere = 123456789;

    fram.write(1, (const uint8_t*) &interoDaScrivere, sizeof(interoDaScrivere));
    fram.write(3, (const uint8_t*) &longDaScrivere, sizeof(longDaScrivere));

And

    fram.read(1, (uint8_t*) &interoDaScrivere, sizeof(interoDaScrivere));
    fram.read(3, (uint8_t*) &longDaScrivere, sizeof(longDaScrivere));

Cheers!

PS: Might need to adjust depending on the number of bytes/bits and address.

  [1]: https://github.com/adafruit/Adafruit_FRAM_SPI/blob/master/Adafruit_FRAM_SPI.h#L66


message:
Using multiple HC-SR04: sharing trigger pin and interference between HC-SR04

If I have four HC-SR04 detectors, can they share the same trigger pin on the Arduino?  This would reduce the number of pins needed from eight to five.

Even if they can share the same trigger, maybe this doesn't make sense because the emitted signal from one HC-SR04 will give a false reading to the others.  If this will occur, how much time should the sketch pause before triggering/reading the next HC-SR04?

Thanks.

body:
No, you can't really share the same trigger pin, for the reasons you have already worked out. You can, though, share the same echo pin, since you know which HC-SR04 has been activated by the trigger.

To do that you will need a "wired or" circuit. The simplest method is a diode per ECHO signal and a pull-down resistor:

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

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

<!-- End schematic -->


message:
Is there anything special about Arduinos?

I've been using the stm32f4 discovery up until now but I've heard Arduinos are easier to use. While looking for an Arduino Genuino Uno Rev3 board, I was told to get a knock off instead.

Is there any real difference between Arduino boards and other knock off micros with similar specs?
I really just want to get a feel for what it's like using an 'easier' micro. It doesn't need to be extra special.

body:
I think the reason why people say Arduino is **easier** to use is because it has a nice IDE and code upload is rarely troublesome.

Especially, the IDE allows the user to code hardware related functions with simplified functions.

For example, when coding an Arduino Sketch, the user doesn't really have to bother about registers.

The Arduino family are based on Atmel chips, so when it comes to raw hardware performance, Arduino performances are identical to Atmel chips.

If you are familiar with what you have(STM32F4) and don't want to make things easier but rather challenging, you don't have to move to Arduino.

Of course, if you want a simple & fast prototyping, nothing beats Arduino. (<- my personal opinion)


body:
Arduino have "standardized connectorss" for witch are many shields created. Also many manufacturers marks anything vaguely in power range of 5V as "for Arduino", because Arduino is so popular. And that is main reason, that Arduino is so popular. (This and that it came in the righ time with equipement targeting to be easy for beginners and a lot of educational materials).

I am using Arduino just because I start with it and bought a lot of AVR based boards and chips, but I may switch to STM for higher computing power, more pins and better equipement.

And the Arduino IDE is easy for beginners (and popular between them), because it have nearly nothing in it and it can compile+upload code to Arduino with just 2 buttons. (But it is like notepad with few more buttons - if you are a little more advanced you will run away for better editor/IDE/whatever at all cost. I use Vim + Make to create and run Arduino code and avoid the IDE totally, many do that too.)

So if you are used to STM32F4 kit, it would be big step back for you and it would satisfy you only if you need something cheap for work, where your STM is total overkill.


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

This is Google Trend of Arduino (blue) versus four other boards: STM32 (red), Teensy (green), MSP430 (yellow) and PIC32 (magenta).

That means lot of people using Arduino, making hardware and software, writing blogs, answering questions. That's the biggest plus of Arduino.

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


message:
How to connect an industrial sensor to Arduino Uno?

I want to use a sensor to read pressure in rooms. But sensor like MPX series isn't capable to read air pressure change under 100 Pa. So I want to use industrial sensor like Dwyer 607 Series, and dont have a clue how to connect it to arduino. Anyone can help?
Thanks :)
Fyi, this is the manual instruction for the sensor http://www.dwyer-inst.com/PDF_files/E_76_low.pdf

body:
That uses the industry standard 4-20mA current loop system. For that you really need a special chip to interface it.

You can [buy shields](https://www.cooking-hacks.com/documentation/tutorials/4-20ma-sensor-board-shield-tutorial-for-arduino-raspberry-pi-intel-galileo/) that interface to 4-20mA current loops.


message:
How to increase life of EEPROM?

I want to store a few (8 as of now) IR codes into my Board's EEPROM.
It would be great if someone could suggest a few tips to maximize the lifetime.

The IR codes in my sketch are saved in array of unsigned longs.

I know that the count of times that I will be writing to EEPROM will << 100,000 times, but still would like to optimize my sketch. + would help in future projects

body:
I can think of a few:

1. don't power it on unless you have to;
2. don't write to it unless you have to;
3. write as little data to you as you can - compress the data; only write to it during brown out or power down, ...;
4. level the writes to as many cells as possible - increment the write address with subsequent writes;
5. use a big eeprom;
6. use fram;
7. use sram + battery back-up;

...

3 - 7 are really examples of implementating #2.


body:
The other answer mentioned some general ideas; here are a couple of more-specific notes.

• You can direct your writes of single bytes through a routine that reads the EEPROM cell before writing to it, and if its value isn't changing, doesn't write.

• For load-leveling, you can divide the EEPROM address space into k buckets, where k =⌊E/(n+1)⌋, with n = data array size and E = EEPROM size.  Initialize a directory, an array of m bytes all set to k, with m = E-n·k.  When your device starts up, it reads through the directory until it finds current entry, a byte not equal to k. [If all directory entries equal k, initialize the first to 0, and go on from there.]  If the current directory entry contains j, then bucket j contains current data.  When you need to write new data, you store j+1 into the current directory entry; if that makes it equal to k, initialize the next directory entry to 0, and go on from there.  Note that directory bytes get about the same amount of wear as bucket bytes because 2·k > m ≥ k.


body:
If your data occupies only a small fraction of your EEPROM, you could use one of the [wear leveling](https://en.wikipedia.org/wiki/Wear_leveling) algorithms. The essence of these algorithms is to write to a different location each time, so writes are spread across several locations while each location stays below the 100,000 writes limit.

There are several such algorithms discussed [here](https://arduino.stackexchange.com/questions/16663/how-do-you-write-to-a-free-location-on-an-external-eeprom), which you could implement yourself. Alternatively, you could just use a library like [this one](https://github.com/PRosenb/EEPROMWearLevel/).