message:
Control LED strip via serial monitor

I've been struggling with writing a code for Arduino UNO so that I could use my phone and change the colour of the LED strip via terminal.

    #include <FastLED.h>
    #include <SoftwareSerial.h>

    SoftwareSerial btSerial(2, 4); // RX, TX

    #define NUM_LEDS 22
    #define DATA_PIN 6
    CRGB leds[NUM_LEDS];

    void setup() {

      btSerial.begin(9600);
      btSerial.println("Connected to Arduino");
      FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);
    }

    char a;

    void loop()
    {
        if (btSerial.available())
        {
          a= (char)btSerial.read();

          if(a=="b")
          {
            btSerial.println("Turning LED blue");
            leds[0] = CRGB::Blue; // Turns 1 LED to blue
            FastLED.show();
          }
        }
    }

So basically I'd like to be able to change LED colours with my phone. If you enter "r", the LEDS turn red, if you enter "b", leds turn blue etc. Maybe even add some patterns. Brightness controller would be nice too to save some battery.

EDITED. Serial works.

    #include <FastLED.h>
    #include <SoftwareSerial.h>

    SoftwareSerial btSerial(2, 4); // RX, TX

    #define NUM_LEDS 22
    #define DATA_PIN 6
    CRGB leds[NUM_LEDS];

    void setup() {
      Serial.begin(9600);
      btSerial.begin(9600);
      btSerial.println("Connected to Arduino");
      FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);}

    char a;

    void loop(){
        if (btSerial.available())
        Serial.write(btSerial.read());
        if (Serial.available())
        btSerial.write(Serial.read());}

3.

    #include <FastLED.h>
    #include <SoftwareSerial.h>

    SoftwareSerial btSerial(2, 4); // RX, TX

    #define NUM_LEDS 22
    #define DATA_PIN 6
    CRGB leds[NUM_LEDS];

    void setup() {
      Serial.begin(9600);
      btSerial.begin(9600);
      btSerial.println("Connected to Arduino");
      FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);}

    char a;

    void loop(){
        if (btSerial.available())
        Serial.write(btSerial.read());
        if (Serial.available())
        btSerial.write(Serial.read());}

        if (a=='b'){
          btSerial.println("Turning LED blue");
          leds[0] = CRGB::Blue;
          FastLED.show();}

RECENT:

    #include <FastLED.h>
    #include <SoftwareSerial.h>

    SoftwareSerial btSerial(2, 4); // RX, TX

    #define NUM_LEDS 28
    #define DATA_PIN 6
    CRGB leds[NUM_LEDS];

    void setup()
    {
      Serial.begin(9600);
      btSerial.begin(9600);
      btSerial.println("Connected to Arduino");
      FastLED.addLeds<WS2812, DATA_PIN>(leds, NUM_LEDS);
    }

    char a;

    void loop()
    {
      if (btSerial.available())
      {
        a= (char)btSerial.read();

        if( a == 'b' )
        {
          btSerial.println("Sinine"); //All LEDs are blue
          fill_solid( leds, NUM_LEDS, CRGB::Blue);
          FastLED.show();
        }

        if( a == 'r' )
        {
          btSerial.println("Punane"); //All LEDs are red
          fill_solid( leds, NUM_LEDS, CRGB::Green);
          FastLED.show();
        }

        if( a == 'g' )
        {
          btSerial.println("Roheline"); //All LEDs are green
          fill_solid( leds, NUM_LEDS, CRGB::Red);
          FastLED.show();
        }

        if( a == 'y' )
        {
          btSerial.println("Sinine"); //All LEDs are yellow
          fill_solid( leds, NUM_LEDS, CRGB::Yellow);
          FastLED.show();
        }

        if( a == 'w' )
        {
          btSerial.println("Sinine"); //All LEDs are white
          fill_solid( leds, NUM_LEDS, CRGB::White);
          FastLED.show();
        }

        if( a == 'o' )
        {
          btSerial.println("Väljas"); //All LEDs are turned off
          fill_solid( leds, NUM_LEDS, CRGB::Black);
          FastLED.show();}

        if ( a == 'z' ) //1 blue LED from start to finish
        {
          int i= 2;
          while (i > 0)
          {
            for (int dot = 0; dot < NUM_LEDS; dot++)
            {
                leds[dot] = CRGB::Blue;
                FastLED.show();
                leds[dot] = CRGB::Black;
                delay(100);
            }
          }
        }

         if ( a == 'x' ) //1 red LED from start to finish
         {
          int i= 2;
          while (i > 0)
          {
            for (int dot = 0; dot < NUM_LEDS; dot++)
            {
                leds[dot] = CRGB::Green;
                FastLED.show();
                leds[dot] = CRGB::Black;
                delay(100);
            }
          }
         }
      }
    }

body:
You seem to lack the basic understanding, how Serial (UART) communication works. So I will explain the basic principles. From there you should be able to implement, what you want.

Serial (aka UART) transmits the data serially, byte after byte (thus it's name). When you type in a text in the Serial Monitor of the Arduino IDE and send it, you have no influence, when exactly each byte will be transmitted. As the UART interface doesn't know messages or "chunks of data", only bytes, it will transmit each byte, when it is ready. There might be a short pause inbetween the bytes. This is an important fact to know, if you want to implement commands longer than 1 byte.

The normal `Serial` interface is mostly implemented in the Uno's hardware, thus it doesn't depend on the running software that much. `SoftwareSerial` does all the hard communication work in software, thus it comes with some caveats (blocking write operations, more limited baudrate, only possible to receive on one `SoftwareSerial` interface at once, ...). But both mostly share the same code interface.

`Serial.available()` returns the number of received bytes, that are still in the internal buffer. You are already using this to only read from the buffer, when there is actually data to read in it (with the if statement). Then you read one byte from the buffer by `Serial.read()`. Currently you are giving the return value (the read data) directly to the other serial interface for sending. Thus the value is not saved anywhere in your sketch. Doing a `Serial.read()` will remove the read byte from the buffer and return it. Thus the read byte will no longer be in the buffer.

The code with the 2 if statements and serial functions is mostly used to forward the data between the two serial interfaces. For your use case you don't need this. Instead you should read the data into a local variable like you did in your first sketch:

    if (btSerial.available())
    {
      a= (char)btSerial.read();

      if(a=="b")
      {
        btSerial.println("Turning LED blue");
        leds[0] = CRGB::Blue; // Turns 1 LED to blue
        FastLED.show();
      }
    }

Here you are first checking, if there is data to read in the `btSerial` buffer. If yes, you read it into the variable `a`. This variable now holds a single character. If you also want to forward this character to `Serial`, you can now use `Serial.write(a);` to do so. Then you want to check the value of the received character. Here we are doing a little excourse:

---

In C/C++ 2 different kinds of quotes are used: The double quotes `"` and the single quotes `'`. Double quotes mark string literals, which consists of a series of characters. Single quotes mark single character values - only one character. In your if statement you check for equality. If you think about it, you see, that checking if 2 single characters are equals is a lot easier, than checking if two strings are equal (checking 1 character on each side versus checking multiple characters on each side). Thus it is a difference, if you compare string literals or single characters. Comparing a single character variable with a string literal doesn't work - they are two completely different things. Instead you should compare the character variable to a single character:

    if( a == 'b' )

---

As you are adding more commands for your project, you will see, that if statements don't order the code very good. In this case a switch statement is better:

    switch(a){
        case 'b':
            // Doing what you want to do with the LEDs here
            break;
        case 'c':
            ...
            break;
    }

This will execute the corresponding code part depending on the value of `a`. You can read more about this construct on the web (google something like "C switch").

---

Now you should be able to implement simple 1 byte/character commands in your code. Also review and understand the examples from the Arduino IDE about Serial.

If you need more complex commands (maybe with some payload data in addition to the command), you have to introduce a communication protocol onto the Serial interface. The simplest way is to define whole messages by using a delimiter character at the end of every message. Mostly the newline `'\n'` character is used for this purpose. You basically read the data from Serial and save it on a `char`-array/string until you received the newline character. Then you know, that you have received a complete message, and you can start to process it as a whole. When finished, you clear your message buffer and again wait for a new message. For this to work, you of course have to ensure, that the delimiter character is never part of your send data (as the code would think, that it marks the end of the message).

You can see this in the `SerialEvent` example in the Arduino IDE. Try to understand, what happens there. There are also many tutorials on the web.

I hope, I could enlighten you a bit. Good luck with your project.


sender: user

message:
Serial loopback not working with jumper wires connected

I'm a beginner to Arduino programming. Before attempting anything more complex I'm trying to get some very basic functionality first, so using some of the sketchbook examples I'm trying to get the most basic serial loopback working. I used the `SerialEvent` sketch as a reference point to come up with this:

```
String inputString = "";
bool stringComplete = false;
int inByte = 0;

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // wait for serial port to connect. Needed for native USB port only
  while (!Serial) {
    ;
  }
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
  Serial.println("Hello world\n");
}

void loop() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  if (stringComplete) {
    Serial.println(inputString);
    inputString = "";
    stringComplete = false;
  }
}
```

When I flash that image to the Arduino and then open the Serial monitor, everything appears to work fine. As pictured below, whatever I type gets echoed back to me after pressing Enter:

[![successful loopback][1]][1]

However, it's a different story when I connect the TX and RX pins on the board, as pictured here:

[![arduino][2]][2]

As soon as I do that, the serial communication becomes totally non-responsive. It still prints out "Hello world" at the beginning, but it no longer echoes back the messages that get sent in, as you can see here:

[![non-responsive loopback][3]][3]

I should say that even when it is no longer echoing messages back, the yellow "RX" light on the board does still briefly light up when I press Enter. But the "TX" light doesn't. Note that both lights light up if I unplug the jumper wire.

It seems to me that what I'm trying to do here is a very simple thing, that really shouldn't be this hard. Is there something obvious I'm missing? Any advice?

  [1]: https://i.stack.imgur.com/NXnBP.gif
  [2]: https://i.stack.imgur.com/9BiIb.jpg
  [3]: https://i.stack.imgur.com/vP8cP.gif

sender: assistant

body: I can not comment, it turns out that this example that you are working is not very suitable, since the RX and TX are directly connected to the USB connection (for Arduino UNO), that is, you can only use these pins as long as it is loaded from Sketch uses An external power supply to connect the Arduino, my recommendation is to work if you have a sensor to verify the transmission of data by serial port. Greetings


body:
You are trying to use the serial port connected to two devices at a
time:

* to the on-board serial/USB bridge that allows communication with your
  computer
* some unspecified external serial device.

Connecting your TX (transmit pin) to two receivers is fine: whatever you
write will be received by both.

Connecting your RX to two transmitters doesn't work, you can at most
read the data sent by one transmitter.

On the Uno board, there are resistors along the serial connection
between the main MCU and the serial/USB bridge. Thanks to the resistor
on the RX line, you can connect an external device to the MCU's serial
port: The device's TX will override the USB bridge. This means the main
MCU can no longer receive what you send it from the serial monitor.


message:
Arduino Uno still boots and runs but no serial communication over USB

After having the Arduino Uno running for a short period of time, it seems to no longer communicate over the USB port when connected to the computer. It still seems to turn on and run the program uploaded. However, it no longer receives or outputs any data and any attempts to re-upload code are met with timeout errors in the Arduino IDE. The TX/RX lights do not blink at all, but the "L" light always flashes right after the Arduino is plugged in.

I have the Arduino/Genuino Uno board selected in the Arduino IDE.

This is a legitimate board that I bought directly from Arduino.

Loopback test fails.

Nothing is connected to any of the pins on the Arduino whatsoever.

I have an Arduino Nano that communicates fine with my Windows 10 PC so that rules out the drivers and the PC itself.

My computer still recognizes the USB device as an Arduino Uno and assigns it to COM5.

Leaving it plugged in for a solid 15 minutes shows no chips on the board getting hot to the touch.

I have tried resetting the board before, during, and after attempting to upload code, no dice.

Are there other steps that I can take to try to fix the board, or am I going to have to accept that I fried the ATMEL16 chip on my Uno?

body:
try changing the baud rate according to the code...

the standard baud rate is 9600


body:
As @Juraj mentioned, if it's enumerating as a serial port, the atmega16u2 is fine.

You may be able to replace the atmega328p/au. It will take some doing; you'll need to remove the chip, insert a new one, and use another Arduino as an ArduinoISP to program the bootloader into your new blank atmega328p.

Any chance you might have uploaded a sketch that is spamming the serial port on startup? If so, try this procedure (h/t to the Arduino forums, it has saved my bacon a number of times):

 - Disconnect the usb connection
 - Begin holding the Reset button
 - Connect the Arduino
 - Initiate upload (while still holding Reset continuously)
 - As soon as you see the RX light flash, release the Reset button.
 - The first attempt to upload will fail, but with luck, the second try will occur before the 2-second bootloader delay ends (and your sketch begins to execute).

If this works, I'd suggest including a `delay(3000);` or similar in your `setup()`.


body: it happened to me. Try reinstalling the arduino board, that is, enter the board manager, remove the board and the link from your board, restart the computer and then enter the link and update the board, it is a driver problem. Greetings.


message:
Multiple variant.cpp entries for same physical pin

Some `variant.cpp` files have more than one entry that points to the same physical pin. For example (from Arduino Zero's file):

```
// 14..19 - Analog pins
// --------------------
{ PORTA,  2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0]

...

// 43..45 - Alternate use of A0 (DAC output), 44 SWCLK, 45, SWDIO
{ PORTA,  2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT
```

The first entry sets up the pin as a regular analog input pin on A0. The second entry sets it up as a DAC on pin IDE pin 43.

The corresponding `variant.h` file defines the DAC pin and A0 as entry 14, rather than 43. I also have seen plenty of examples online that use the DAC via A0 when working with an Arduino Zero.

```
/*
 * Analog pins
 */
#define PIN_A0               (14ul)
#define PIN_A1               (15ul)
#define PIN_A2               (16ul)
#define PIN_A3               (17ul)
#define PIN_A4               (18ul)
#define PIN_A5               (19ul)
#define PIN_DAC0             (14ul)
```

Finally, I see other variants, like [this one](https://github.com/sparkfun/SparkFun_Qwiic_Micro_SAMD21E/blob/master/Firmware/Arduino_Board_Files/SparkFun_Qwiic_Micro/variant.cpp) that don't even bother to create a DAC-specific entry. So presumably it doesn't actually matter? If not, then why is it in the Arduino Zero `variant.cpp` file at all?

A related question: How does using a pin for multiple purposes work? For instance, if I had a pin I've configured for SPI MOSI (in `variant.cpp`), and I wanted to also use it for PWM (given the datasheet says the pin is on a SERCOM and a timer), do I actually need two entries in `variant.cpp` and thus two different IDE pins to use in my sketches (one that has a pin type of `PIO_SERCOM` and another with `PIO_PWM`)? I can think of plenty of times working with an Arduino UNO, for instance, where I've just used the same IDE pin number for general IO as well as SPI (MOSI).

body:
The `analogWrite` function checks the `PIN_ATTR_ANALOG` attribute from pin description in variant.cpp to determine if the pin has DAC capability. Then it checks if the pin is `ADC_Channel0` or `DAC_Channel0`. This is unnecessary and redundant. There is no other use for `DAC_Channel0`.

In Arduino SAMD core and derived cores the pin 'map' in variant.cpp defines pin capabilities used by Arduino core. It is not a complete copy of the mux table from the datasheet. In some variant.cpp files comments contain the additional mux options of the pin.

For PWM the analogWrite function configures the pin and for SPI, the SPI library configures the pin.

If you want to use the pin for other SERCOM function, the function `pinPeripheral` is used to set up the pin. Here is [a tutorial][1].

Arduino core doesn't support a configuration of a different wave output then analogWrite. To configure a different wave output or capture, a third party library or direct registers configuration is necessary.

The Arduino `pinPeripheral(pin, peripheral)` function uses the variant.cpp mapping and the possible parameters are:

    PIO_EXTINT=0,     /* The pin is controlled by the associated signal of peripheral A. */
    PIO_ANALOG,       /* The pin is controlled by the associated signal of peripheral B. */
    PIO_SERCOM,       /* The pin is controlled by the associated signal of peripheral C. */
    PIO_SERCOM_ALT,   /* The pin is controlled by the associated signal of peripheral D. */
    PIO_TIMER,        /* The pin is controlled by the associated signal of peripheral E. */
    PIO_TIMER_ALT,    /* The pin is controlled by the associated signal of peripheral F. */
    PIO_COM,          /* The pin is controlled by the associated signal of peripheral G. */
    PIO_AC_CLK,       /* The pin is controlled by the associated signal of peripheral H. */
    PIO_DIGITAL,      /* The pin is controlled by PORT. */

If you are good with the Arduino variant.cpp configuration, then for direct registers access configuration the pin 'map' from variant.cpp and the `pinPeripheral` function can be at help if the pin should not be hardcoded. Example from peripherals setup for 'phase cutting' with a Triac [in my project][2]:

    const PinDescription& pinDesc = g_APinDescription[triacPin]; // Arduino pin description
    TCC = (Tcc*) GetTC(pinDesc.ulPWMChannel);
    uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel);
    bool periF = (pinDesc.ulPinAttribute & PIN_ATTR_TIMER_ALT);

    // setup the pin as TCC wave out pin
    pinPeripheral(triacPin, periF ? PIO_TIMER_ALT : PIO_TIMER);

    TCC->CC[tcChannel].reg = PULSE_PERIOD;

  [1]: https://www.arduino.cc/en/Tutorial/SamdSercom
  [2]: https://github.com/jandrassy/Regulator/blob/master/TriacLib/TriacLib.h


message:
How long will program stay in memory without power?

Let's say we program an arduino uno or nano and then stop using it for a while. How long can we expect the program to last on the arduino?

body:
More than 20 years, and probably more than 100 years.

That's the guaranteed minimum:

>  Data retention: 20 years at 85°C/100 years at 25°C(1)
>
> (1)  Reliability Qualification results show that the projected data retention failure rate is much less than 1 PPM over
20 years at 85°C or 100 years at 25°C.


body: upto 20 years at 85°C and upto 100 years at 25°C


body:
Practically forever. Rather make sure the contacts don't become too rusty.
( 83.7 % of Arduino problems are mechanical and contact issues :) )

Will your grandchildren still have a legacy USB cable and be interested in that thing and your c++ coding skills then?


message:
Arduino not writing full NMEA sentence to SD-card file

I'm currently building a small GPS-box that's supposed to track my location and write the full NMEA sentence to an sd card.
(I want to pars it afterwards at my pc)
I'm using the Arduino Nano and the [NEO-6M GPS Module][1] to get the data.

What works: getting the NMEA data from the module, writing to the SD-card.
Outputting the data to the serial output over Serial.write works fine.

Now I have the problem that it looks like the Arduino can't write the data fast enough to the SD-card and desyncs with the GPS module. This occasionally produces things like this: `$G3,3,09,32,20,248,*4D`

I have some ideas on how to fix this:
1. write the data faster
2. always wait till the data is fully written before acquiring the next fix
3. only write every second GPS fix

I tried to implement these but failed every time (sorry I'm new to this).

Here is my current code:

```C
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>

SoftwareSerial GPS_Serial(4, 3); // GPS Module’s TX to D4 & RX to D3
File GPS_File;
int NBR = 1;  //file number

void setup() {
  Serial.begin(9600);
  GPS_Serial.begin(9600);
  SD.begin(5);                  //SD Pin

  //write data to a new file
  bool rn = false;
  while (rn == false) {
    if (SD.exists(String(NBR) + ".txt")) {
      NBR = NBR + 1;
    }
    else {
      GPS_File = SD.open(String(NBR) + ".txt", FILE_WRITE);
      GPS_File.write("START\n");
      GPS_File.close();
      rn = true;
    }
  }
}

int x = 0;
int temp = 0;
char gpsData;
char buff[300];

void loop() {

  //collect data and write to buffer
  while (GPS_Serial.available() > 0) {
    gpsData = GPS_Serial.read();
    x++;
    buff[x] = gpsData;
  }

  temp = x;
  x = 1;

  GPS_File = SD.open(String(NBR) + ".txt", FILE_WRITE);

  //copy from buffer to sd
  while (x <= temp) {
    GPS_File.print(buff[x]);
    x++;
  }

  GPS_File.close();

  x = 0;
  temp = 0;
}
```

  [1]: https://www.electroschematics.com/neo-6m-gps-module/

body:
After trying different approaches I decided to dumb it down to its most basic level.
Without any fancy coding or buffers, I'm now just writing the data directly to the SD-card and flushing every 15 seconds which has the risk to loose up to 15 seconds of data i.e. 15 GPS-fixes (1 per second) when cutting off power.

The only other time where a potential data loss can happen is observed when the program flushes the accumulated data to the SD. This doesn't happen every time though.

To pars the NMEA-sentences into usable data I use GPSBabel. It automatically ignores the broken lines. After converting to .gpx I view it with Google Earth.

This is the "finished" code:

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

SoftwareSerial GPS_Serial(4, 3);  // GPS Module’s TX to D4 & RX to D3
File GPS_File;
int NBR = 1;                      //file number

unsigned long TimerA;             //save timer
bool sw = false;                  //save timer switch

void setup() {
  Serial.begin(9600);
  GPS_Serial.begin(9600);
  SD.begin(5);                    //SD Pin

  //write data to a new file
  bool rn = false;
  while (rn == false) {
    if (SD.exists(String(NBR) + ".txt")) {
      NBR = NBR + 1;
    }
    else {
      GPS_File = SD.open(String(NBR) + ".txt", FILE_WRITE);
      GPS_File.write("START\n");
      rn = true;
    }
  }
}

void loop() {
  while (GPS_Serial.available() > 0) {
    GPS_File.write(GPS_Serial.read());
  }

  //set up timer
  if ( sw == false) {
    TimerA = millis();
    sw = true;
  }

  //save every 15 seconds
  if (millis() - TimerA >= 15000UL) {
    GPS_File.flush();
    sw = false;
  }
}
```


message:
How do I code delay inside a ISR?

I have built a basic obstacle avoidance robot. When the sensor senses an obstacle it gives a RISING interrupt to pin 2. At this moment I want the robot to come back for 2 seconds and turn right for 2 seconds.

I have code to turn back and rotate right but I cannot use the delay() function inside the ISR so how do I code this?

body:
An ISR should be kept as short as possible, since while it runs, no other interrupts can be handled (including the one powering the `delay()` function. Thus you cannot delay that easy inside an ISR and you shouldn't do it either.

Instead you should set a simple flag variable in the ISR and then check this flag inside your `loop()` function. If the flag is set, you can execute the corresponding code inside the main code instead of inside an ISR.

A typical flag definition is a single byte (since then every read/write action is atomic and cannot be interrupted by an ISR). Be sure to set it volatile, so that the compiler knows, that this variable may change any time.

    volatile byte interrupt_flag = 0;

In the ISR you can set this variable to 1 for example and then in your main `loop()` function:

    if(interrupt_flag){
        // Do whatever you need to do here
        interrupt_flag = 0; // reset the flag variable
    }


message:
Unreliable communication with low baudrate on Leonardo

I am using an Arduino Leonardo (more precisely [this product][plc]), to communicate with [servo-motors][servo-motors]) using RS485.

Everything works fine as long as I don't go below a baud rate or 115200bps. If I go below, as 57600 or 9600, I start to get ill-formed packets from my motors: the 4 first bytes are usually correct, but the end of the packet contains incoherent data, and the checksum is obviously wrong.

I am using IndustrialShields (my PLC/Arduino vendor) [library for RS485][industrialshields-package], and I don't see any mention of this problem.
I am using Half-duplex communication, with U2X if I correcly understand the source code of the library.

Note that the [documentation][servo-documentation] of the servo-motors mentions there is a small error margin on the clock for low baud rates, but since it works with 115200bps, which has the highest error margin, it shouldn't be a problem.

Also the motors seems to understand the packet I send, but I do not receive their packet correctly.

Is there an edge-case I am not aware of? Sorry for the lack of details, I am not sure what else I can say.

[plc]: https://www.industrialshields.com/shop/product/plc-arduino-ardbox-20-i-os-analog-hf-modbus-17
[servo-motors]: https://www.generationrobots.com/en/401088-dynamixel-mx-28r-actuator-robotis.html
[industrialshields-package]: http://apps.industrialshields.com/main/arduino/boards/industrialshields-boards-avr-1.0.0.tar.bz2
[servo-documentation]: http://emanual.robotis.com/docs/en/dxl/mx/mx-28/#baud-rate-4

body:
I suspect that the RS-485 interface in your servo is what is at fault.  Nothing to do with the Arduino or your communication, or software.

Without knowing more about the servos and how they are wired internally it's hard to be certain, but I can assume:

* The servo has some kind of controller in it which communicates over the bus
* That controller may or may not directly control the direction pin on its interface

It's the latter that is critical. There is a way of wiring up a MAX485 that automatically controls the direction pin - immediately you start sending data it asserts it into TX mode. The trouble comes when switching back to RX mode - there's a few ways of doing that:

1. Shortly after the last bit of a certain value (0 or 1) has been sent (the bit stream keeps a capacitor charged)
2. A certain time after the start of communication.

The first method is usually more reliable across multiple baud rates, but can be sensitive to the values of the bytes sent - if it relies on a 1 being sent to keep the capacitor charged and a number of 0 bytes are being sent it won't see the 1 that keeps the transmit mode open, and it can close prematurely.

The second method is more reliable for fixed length packets, but will only work for a certain (or small range) of baud rates. If sending a packet takes longer than the allotted window then it will truncate regardless.

However if the controller in the servo is itself directly controlling the data direction pin then it could be that there is a bug in its firmware. Maybe it's working on a delay principle and they got the time calculations wrong.  Maybe it's working on a "queue being empty" principle and they forgot about there being a hardware buffer that also needs to empty, but high baud rates just manage to squeeze through in time.

It's impossible to be sure, but going by the symptoms you describe those seem to be the most logical scenarios.


message:
fixing drifting issue for elechouse voice recog module v3.1 and MPU6050 sensor for head mouse even after doing sensor calibration?

For my head mouse project which is based on the voice recognition module V3.1 for left click, double click, right click operations, MPU 6050 accelerometer and gyroscope for cursor movement, I am facing a problem. When I just use the MPU 6050 accelerometer and gyroscope sensor for cursor movement, the mouse cursor moves smoothly (calibration has been done). But when I integrate it with the voice recognition module, the cursor starts to drift. My code is given in this post too.

I have been using an arduino pro micro for this project. Please help. I have calibrated my MPU6050 , so it does not drift while working alone. But after integration with voice recog module (including calibration) , the drifting problem returns. I am powering the setup using a USB cable connected from the laptop to the arduino.

N.B: This is a project from a client. According to requirements, I need to make the head mouse wireless. I need suggestions for that too.

[![Circuit connnection][1]][1]

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

```
#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>

VR myVR(8,9);    // 9:RX 8:TX

uint8_t records[7]; // save record
uint8_t buf[64];

MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz, oax, oay, oaz, ogx, ogy, ogz;
int vx, vy;

#define leftRecord    (0)
#define rightRecord   (1)
#define doubleRecord  (2)

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len)
{
  int i;
  for(i=0; i<len; i++){
    if(buf[i]>0x19 && buf[i]<0x7F){
      Serial.write(buf[i]);
    }
    else{
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]aurav");
    }
  }
}

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized.
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");
  Serial.print(buf[2], DEC);
  Serial.print("\t\t");

  if(buf[0] == 0xFF){
    Serial.print("NONE");
  }
  else if(buf[0]&0x80){
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  }
  else{
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");

  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3]>0){
    printSignature(buf+4, buf[3]);
  }
  else{
    Serial.print("NONE");
  }
  Serial.println("\r\n");
}

void setup()
{
  /** initialize */
  Wire.begin();
  if (!mpu.testConnection()) {
    while (1);
    }

  myVR.begin(9600);
  Serial.begin(115200);
  Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");

  if(myVR.clear() == 0){
    Serial.println("Recognizer cleared.");
  }else{
    Serial.println("Not find VoiceRecognitionModule.");
    Serial.println("Please check connection and restart Arduino.");
    while(1);
  }

  if(myVR.load((uint8_t)leftRecord) >= 0){
    Serial.println("leftRecord loaded");
  }

  if(myVR.load((uint8_t)rightRecord) >= 0){
    Serial.println("rightRecord loaded");
  }

  if(myVR.load((uint8_t)doubleRecord) >= 0){
    Serial.println("doubleRecord loaded");
  }

}

void loop()
{
  int ret;
  ret = myVR.recognize(buf, 50);

  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  oax = ax-265;
  oay = ay+387;
  oaz = az+474;
  ogx = gx-109;
  ogy = gy+35;
  ogz = gz+150;

  vx = gx/120;
  vy = -gz/120;

  Mouse.move(vx, vy);

  if(ret>0){

  switch(buf[1]){

    case leftRecord:
    Mouse.click(MOUSE_LEFT);
    delay(100);
    break;

    case rightRecord:
    Mouse.click(MOUSE_RIGHT);
    delay(100);
    break;

    case doubleRecord:
    Mouse.click(MOUSE_LEFT);
    Mouse.click(MOUSE_LEFT);
    delay(100);
    break;

    default:
    Serial.println("Record function undefined");
    break;
    }
    /** voice recognized */
    printVR(buf);
  }
}
```

body:
Your problem is most likely the use of SoftwareSerial for your VR module communication. SoftwareSerial is notorious for breaking things. It disables interrupts, and hogs the CPU.

You should be using the hardware serial port instead which, on the Pro Mini, is completely separate to USB communication.


message:
What sensors can measure 3-axis acceleration?

I'm currently measuring vibration, temp and noise using an Arduino and various inexpensive sensors. The acceleration sensor i found was sensors that measured the gravity on 3-axis of the sensor. But i'd like to measure acc, not gravity, as it moves in the direction of the sensor. For example, if an object is moving front-dir in a horizontal location, the x-directional acc is measured.

Could you tell me if you know the acc soensor i want.

body:
> The acceleration sensor i found was sensors that measured the gravity on 3-axis of the sensor

Gravity *is* acceleration.

An accelerometer measures acceleration - or more accurately, it senses the resistance to acceleration (inertia) and equates that to acceleration.

By holding an accelerometer still you are causing it to resist the pull of gravity, and it's that "resistance" that it measures - a constant 9.8m/s²

If you let the accelerometer freefall it won't be resisting gravity any more, and will measure 0 for the Z axis.

So you simply have to "ignore" gravity, by removing that constant 9.8m/s² ("1g") of acceleration from the Z axis.  And you do that by simply subtracting it.

It is normal to calibrate an accelerometer by keeping it at rest and reading the "idle" values. Those values are then subtracted from the readings to give you the actual value.


message:
How to exit while loop using keypad?

I can't seem to be able to escape a while loop using a keypad button. I've tried the solution from this thread: https://forum.arduino.cc/index.php?topic=79932.0

Here's my code:

    void alarm(){
      char customKey = customKeypad.getKey();

      while (customKey == NO_KEY){
        customKey = customKeypad.getKey();
        lcd.noDisplay();
        delay(750);// change for faster flash
        lcd.display();
        delay(750);// change for faster flash
      }
      lcd_home_screen();
    }

I tried both == and != for the while (customKey == NO_KEY)

Additional info:
I am calling this alarm function from another function inside my Loop.
Here's the complete code:

    void loop() {
      // keypad
      char customKey = customKeypad.getKey();
      if (customKey == 'A'){
        main_program(5);
      }
    }

    int main_program(int duration){
      timer(duration);
      alarm();
    }

body:
Because you're using `delay()` within your `while` loop you have to ensure that you are pressing the key at the precise moment it is read.

You should not use `delay()`.

Instead take a look at the *BlinkWithoutDelay* example in the IDE. And also consider implementing a [Finite State Machine](https://majenko.co.uk/blog/finite-state-machine) to know both if you're blinking and what state you're blinking currently is in.


body:
To elaborate on Majenko's answer,  you can create some enumeration types for the states, e.g.

    enum EAlarmState
    {
       On,
       Off
    };

    EAlarmState _alarmState = EAlarmState::Off;

    enum EBlinkState
    {
        BlinkOn,
        BlinkOff,
    };

    EBlinkState _blinkState = EBlinkState::BlinkOff;

    unsigned int long _lastBlinkTime = 0;

The `_blinkState` and `_lastBlinkTime` state will not be checked when `_alarmState` is off.

Now you can use something like this to check the states and the keypad (pseudo code):

    void loop()
    {
        checkKeypad();

        switch (_alarmState)
        {
        case EAlarmStateOn:
           if (millis() - _lastBlinkTime) >= 750)
           {
              `Blink off code`
              switch(_blinkState)
              {
              case EBlinkStateOn:
                 _lastBlinkTime = millis();
                 'Blink off code'
                 _blinkState = EBlinkState::Off;
                 break;

              `same for case EBlinkStateOff'
                 break;

              default: // Error
                 break;
              }
           }

And also create state checking and changing for the alarm itself.

It looks like a lot of code (and it will be), so split it in sub functions. But the most important is that the code is fairly easy to read (and thus maintain).


message:
I2C OLED conflicts with Interrupt

I'm using Nmradcc.h in combination with a OLED I2C.

The nrmadcc.h is using a interrupt 0 on Pin 2, the OLED uses A4 and A5.

After initialisation of the OLED and the Function

The problem is, I can use the Funktion with the Interrupt or the OLED, Not together.
But i want to. Can I stop the interrupt function with nointerrupt and than I2C and otherwise, or is there a better war?

Thanks Bert

---

    #include <SPI.h>                  ////
    #include <Wire.h>                 ////
    #include <Adafruit_GFX.h>         ////
    #include <Adafruit_SSD1306.h>     ////
    #include <DCC_Decoder.h>
    #define kDCC_INTERRUPT 0

    Adafruit_SSD1306 display(128, 64, &Wire, -1);   ////

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Fill in the number of accessories / functions you want to control
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    const byte maxaccessories=1;
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    typedef struct {
      int               address;          // Address to respond to
      byte              mode;             // 0=continuous, 1=oneshot, 2=flasher
      byte              output;           // State of accessory: 1=on, 0=off (for internal use only)
      int               outputPin;        // Arduino output pin
      byte              highlow;          // State of outputpin: 1=HIGH, 0=LOW
      boolean           finished;         // Memory location that says the oneshot is finished
      int               durationonMilli;  // oneshot or flasher on time in ms
      int               durationoffMilli; // oneshot or flasher off time in ms
      boolean           isAnalog;         // false=digital, true=analog, sends analogValue to out pin.
      byte              analogValue;      // pulse with modulation (pwm) value that is written to pin. Range: 0 - 255
                                         // goto http://arduino.cc/en/Reference/AnalogWrite to see which pins support analog pwm output
      unsigned long     onMilli;          // for internal use
      unsigned long     offMilli;         // for internal use
    }
    DCCAccessoryAddress;
    DCCAccessoryAddress accessory[maxaccessories];

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Fill in the attributes for every accessory / function
    // COPY - PASTE as many times as you have functions. The amount must be same as in line 17 above!
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void ConfigureDecoderFunctions() // The amount of accessories must be same as in line 26 above!
    {
      accessory[0].address = 1;    // DCC address
      accessory[0].mode = 0;       // Continuous. HIGH until DCC switches the address off again.
      accessory[0].outputPin = 13; // Arduino pin where function is connected to.
      accessory[0].output = 0;     // Initial state (0 or 1) of output after startup.

      for(int i=0; i<maxaccessories; i++)
      {
        if (accessory[i].outputPin)
        {
          pinMode( accessory[i].outputPin, OUTPUT );
          // Set initial state (only for mode 0, continuous)
          if (!accessory[i].mode && accessory[i].output) digitalWrite(accessory[i].outputPin, HIGH);
          else digitalWrite (accessory[i].outputPin, LOW);
          }
        }
      }  // END ConfigureDecoderFunctions

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      // DCC accessory packet handler
      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
      {
        // Convert NMRA packet address format to human address
        address -= 1;
        address *= 4;
        address += 1;
        address += (data & 0x06) >> 1;

        boolean enable = (data & 0x01) ? 1 : 0;

        for (int i=0; i<maxaccessories; i++)
        {
          if (address == accessory[i].address)
          {
            if (enable) accessory[i].output = 1;
            else accessory[i].output = 0;
          }
        }
      } //END BasicAccDecoderPacket_Handler

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Setup (run once)
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void setup()
    {
      DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
      ConfigureDecoderFunctions();
      DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );
      pinMode(2,INPUT_PULLUP); //Interrupt 0 with internal pull up resistor (can get rid of external 10k)
      pinMode(13,OUTPUT);
      digitalWrite(13,LOW); //switch off Arduino led at startup
      for (int n=0; n<maxaccessories; n++) accessory[n].output = 0; //all servo's to min angle and functions to 0

      display.display();
      display.clearDisplay();

    } // END setup

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Main loop (run continuous)
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    void loop()
    {
      static int addr = 0;

      DCC.loop(); // Loop DCC library

      if( ++addr >= maxaccessories ) addr = 0; // Next address to test

      if (accessory[addr].output == 1)
      {
        if (accessory[addr].mode == 0) accessory[addr].highlow=1; // continuous

        if (accessory[addr].mode == 1) // oneshot
        {
          if (!accessory[addr].highlow && !accessory[addr].finished)
          {
            accessory[addr].highlow = 1;
            accessory[addr].offMilli = millis() + accessory[addr].durationonMilli;
          }
          if (accessory[addr].highlow && millis() > accessory[addr].offMilli)
          {
            accessory[addr].highlow = 0;
            accessory[addr].finished = true;
          }
        }

        if (accessory[addr].mode == 2) // flasher
        {
          if (!accessory[addr].highlow && millis() > accessory[addr].onMilli)
          {
            accessory[addr].highlow = 1;
            accessory[addr].offMilli = millis() + accessory[addr].durationonMilli;
          }
          if (accessory[addr].highlow && millis() > accessory[addr].offMilli)
          {
            accessory[addr].highlow=0;
            accessory[addr].onMilli = millis() + accessory[addr].durationoffMilli;
          }
        }

          display.setCursor(90, 50);  ////
          display.setTextSize(2);     ////
          display.print(F("ON")) ;    ////

      }
      else // accessory[addr].output == 0
      {
        accessory[addr].highlow=0;
        if (accessory[addr].mode == 1) accessory[addr].finished = false;

          display.setCursor(90, 50);  ////
          display.setTextSize(2);     ////
          display.print(F("OFF")) ;    ////

      }

      if (accessory[addr].highlow)
     {
       if (accessory[addr].isAnalog) analogWrite (accessory[addr].outputPin, accessory[addr].analogValue);
      else digitalWrite (accessory[addr].outputPin, HIGH);
     }
      else
     {
       if (accessory[addr].isAnalog) analogWrite (accessory[addr].outputPin, 0);
      else digitalWrite( accessory[addr].outputPin, LOW);
      }
      display.display();
    } //END loop

In this sample is the I2C OLED not working.
When I change the spot of

    Adafruit_SSD1306 display(128, 64, &Wire, -1);

and

    DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );

The DCC interrupt is not working, the OLED does work.

body: I2C requires precise timing to work. If interrupts fire while the Arduino is trying to read or write to the I2C bus, it will fail. I suspect you'll have to disable interrupts each time you read/write to the I2C bus and then re-enable them when you are done.


message:
My Arduino code is showing unidentified reference for 3 of my variables, I don't know how to fix it

Here's the code up to the error.

    const int R = 12;
    const int G = 10;
    const int Y = 8;

    const int PBR = 13;
    const int PBG = 11;
    const int PBY = 9;
    const int pinNum = 3;
    const int speaker = 2;

    int LED = 0;
    int gameStage = 0;

    const int winNum = 2;
    int gamePoint[winNum];
    int rounding = 0;

    unsigned long lastTime = 0;
    unsigned long pause = 1000;

    void ledState(int ledNum);
    void clue(int rounding);
    void begin_game();
    void play();
    void winning_sound();
    void win();
    void lose();
    void lose_sound();
    boolean inputWait(int buttonNum);

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

    pinMode(R, OUTPUT);
    pinMode(G, OUTPUT);
    pinMode(Y, OUTPUT);
    pinMode(PB1, INPUT);
    pinMode(PB2, INPUT);
    pinMode(PB3, INPUT);
    pinMode(speaker, OUTPUT);

    randomSeed(analogRead(0));
    }

    void loop() {

    if (gameStage == 0)
    {
    int PBvalue1 = digitalRead(PB1);
    int PBvalue2 = digitalRead(PB2);
    int PBvalue3 = digitalRead(PB3);
      if (PBvalue1 && PBvalue2 && PBvalue3 == 0)
      {
        begin_game();
      }
      else
      {
        Serial.println("button Pressed");
        ledState(-1);
        rounding = 0;
        delay(1500);
        gameStage = 1;
      }
    }
    if (gameStage == 1)
    {
      **play();** Error
    }

    if (gameStage == 2)
    {
      delay(750);
      winning_sound();
      **win();
      win();
      win();
      win();** Error
      delay(1500);
      gameStage = 0;
    }

    if (gameStage = 3)
    {
    delay(750);
    lose_sound();
    **lose();
    lose();
    lose();** Error
    delay(1500);
    gameStage = 0;
    }

    }

body:
Lines 5,6,7 you use PBR, PBG and PBY,

Lines 39,40 and 41 you use PB1, PB2 and PB3
Again in your void loop() you reference PB1, PB2 and PB3


body:
When I tried to compile it, I got (after editing `**Error**`):

     In function `loop':

    /sketch_jan15b.ino:55: undefined reference to `begin_game()'

    /sketch_jan15b.ino:60: undefined reference to `ledState(int)'

    /sketch_jan15b.ino:68: undefined reference to `play()'

    /sketch_jan15b.ino:74: undefined reference to `winning_sound()'

    /sketch_jan15b.ino:75: undefined reference to `win()'

    /sketch_jan15b.ino:76: undefined reference to `win()'

    /sketch_jan15b.ino:77: undefined reference to `win()'

These are not variables, but functions which have been declared but not defined.

Changing these:

    void ledState(int ledNum);
    void clue(int rounding);
    void begin_game();
    void play();
    void winning_sound();
    void win();
    void lose();
    void lose_sound();
    boolean inputWait(int buttonNum);

to read:

    void ledState(int ledNum){}
    void clue(int rounding){}
    void begin_game(){}
    void play(){}
    void winning_sound(){}
    void win(){}
    void lose(){}
    void lose_sound(){}
    boolean inputWait(int buttonNum){}

Allowed the code to compile successfully.


message:
SoftwareSerial data being corrupted - looking for suggestions

I'm having problems running a serial communication between a NodeMCU ESP8266 and an Arduino Uno. I'm using the "standard" SUART setup, i.e. pins D1&D2 on the ESP are hooked up with GPIOs 2&3 on the UNO; the tx from UNO to ESP is fed through a voltage divider to step it down to 3.3V.

The setup used to work fine; suddently - yeah I've read it before, *my setup suddently doesn't work*, but honestly that's what happened - data is being corrupted.
The devices exchange a json formatted string:

    {"action":"position","lat":123,"lon":123}

and it just worked. Now what I receive is something like:

    {"⸮⸮⸮⸮⸮⸮":"pos⸮⸮⸮onb,"l⸮tF:0,"lo⸮":0,"⸮⸮s⸮⸮":0⸮
Both SUART are on 115200 baudrate, physical connections have been checked and are fine, both devices are grounded on the same reference level.

I've tried swapping the ESP with another one and changing TX/RX pins on the UNO - no results.

So I'm looking for suggestions what to do next to debug the issue, what to check and what could be wrong. Thank you in advance.

Below are UNO and ESP code snippets.

**ESP8266**

    SoftwareSerial SUART(4, 5);

    int16_t last_fetch = 0;
    int16_t last_serial = 0;

    double azimut, elevation;

    #define DATA_FETCH_TIME_INT 3
    #define SERIAL_TRASMISSION_TIME_INT 5

    void setup() {
      Serial.begin(115200);  //enable Serial Monitor
      SUART.begin(115200);   //enable SUART Port

      WiFi.begin(ssid, password);

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

      Serial.println();
      Serial.println(WiFi.localIP());
    }

    void loop() {
      if (secs() - last_fetch >= DATA_FETCH_TIME_INT) {
        last_fetch = secs();
        fetchData();
      }

      if (secs() - last_serial >= SERIAL_TRASMISSION_TIME_INT) {
        last_serial = secs();
        sendDataViaSerial();
        }
    }

    void fetchData() {
      //connects to server and fetches data
    }

    void sendDataViaSerial() {
      int lat_i = (int) elevation;
      int lon_i = (int) azimut;
      int checksum = lat_i + lon_i;

      const int capacity = 200;
      StaticJsonDocument<capacity> doc;

      doc["action"] = "position";
      doc["lat"] = lat_i;
      doc["lon"] = lon_i;
      doc["cksum"] = checksum;

      Serial.println("Sending data via serial: ");
      serializeJson(doc, Serial);

      //SUART.flush();
      //serializeJson(doc, SUART);
      // works the same

      String outstring;
      serializeJson(doc, outstring);
      SUART.println(outstring);
    }

**ARDUINO UNO**

    SoftwareSerial SUART(2, 3);
    #define arraySize 150
    char inData[arraySize];

    void setup() {
      pinMode(STATUS_LED, OUTPUT);
      digitalWrite(STATUS_LED, HIGH);

      Serial.begin(115200);
      SUART.begin(115200);

      Serial.println("Ready to go.\n");
    }

    void loop() {
      readSerial();
    }

    void readSerial() {
      short index = 0;
      char inChar;

      if (SUART.available() > 0) {
        while (SUART.available() > 0 && index < arraySize - 1) {
          inChar = SUART.read();
          inData[index] = inChar;

          index++;
          inData[index] = '\0';  // Add a null at the end
        }

        SUART.flush();
        String myData = (String)inData;
        Serial.println(myData);

        // consume data
        //parseIncomingData(inData);
      }
    }

body:
As @Juraj mentions in the comments, don't use 115200 baud with SoftwareSerial.

The problem is that the AVR isn't fast enough to handle incoming data at that speed reliably.  Yes, it can receive a byte fine at that speed, but what it can't necessarily do is store that byte away in the receive buffer in time to be ready to receive the next byte - so it misses the first few bits and corruption ensues.

Running at a lower baud rate (such as 9600 baud) simply gives it more time to process the data as it arrives.


message:
Establishing wireless comm. between PC and arduino pro micro to exchange speech and gyro data

I have a client project to make a wireless head-mounted mouse. What wireless module should I use so that I can exchange data between my laptop and the arduino pro micro through the USB port like a wireless mouse? I am using an MPU6050 accelero+gyroscope sensor for cursor movement and Electrohouse Voice Recognition module V3.1 for speech recognition. To exchange such data between PC and arduino, I found a lot of options. Hence, I am confused. Please help me decide what to use so that cost efficiency and effectiveness can be acheived. Should I use bluetooth, RF shield , XBEE or any other module?

body:
The wireless medium you choose is largely irrelevant.  The important thing to realise is that it's not (in most cases) the wireless medium that is communicating with the computer.

Most wireless mice use the nRF24L01+ (or rather the integrated SoC equivalent) to communicate. They use a USB dongle plugged into the computer for that communication. The computer has no clue what an nRF24L01+ is, but it does know what a USB mouse is. So there is a microcontroller in the dongle which receives data from the nRF24L01+ and interprets it, and sends the right instructions over USB to make the computer think it's a USB mouse.

What the data is that's sent over the wireless, and exactly what form that wireless connection takes, is completely irrelevant as far as the computer is concerned.  In general one if the SoC equivalent to the nRF24L01+ (such as the nRF52810) is chosen because it's a single chip solution with a simple to use wireless protocol, which makes for cheap and easy development and implementation.

The only exception to this general rule (and there is always an exception to every rule) is Bluetooth. This is because there is the concept (as far as the computer is concerned) of a Bluetooth mouse. So it is possible, using the right Bluetooth adaptor on your Arduino, for the computer itself to see the Arduino as a Bluetooth mouse. This can be harder to implement using small microcontrollers, but results in a potentially lower cost solution with fewer components.

The simplest solution for you, though, is probably:

* One Arduino that has a native USB connection (Pro Micro, Leonardo, etc - anything ATMega32U4 based)

This will be connected directly to the computer and programmed to emulate a USB mouse

* One Arduino that best suits your sensors (probably doesn't really matter what for this. Mini? Micro? Nano? Uno? They would probably all do fine).

To this you attach your sensors, your voice recognition, etc.

* A pair of wireless connectivity modules of some form

I'd recommend the nRF24L01+ - simple to use, has a very convenient packet-based protocol, cheap, and there's plenty of examples and libraries out there.  These are connected to both Arduinos and are used to communicate between them.

Then it's up to you to decide what information gets sent between the Arduinos to make the one connected directly to the PC send the right mouse movements.


message:
Refreshing a web-page hangs after few times

I'm using a Nucleo F429ZI board and I wrote a sketch that enables a simple web-server:

    #include <LwIP.h>
    #include <STM32Ethernet.h>

    const int WEB_PORT = 80;
    EthernetServer server(WEB_PORT);
    char buffer[1024];

    void setup()
    {
        Serial.begin(115200);
        // define variables
        Ethernet.begin(localIP, netmask, dns, gateway);
        server.begin();
    }

    void loop()
    {
        processServer();
    }

    void processServer()
    {
      String readString;
      EthernetClient client = server.available();
      if (client)
      {
        while (client.connected())
        {
          if (client.available())
          {
            char c = client.read();
            readString += c;

            if (c == '\n')
            {
              if (readString.startsWith("GET"))
              {
                readString.remove(0, 4);
                int pos = readString.indexOf(' ');
                String path = readString.substring(0, pos);

                if (path == "/status") pageStatus(client);
                break;
              }
            }
          }
        }
        delay(1);
        client.stop();
      }
    }

    void pageStatus(EthernetClient client)
    {
        sectionHeader(client, 2);
        client.println("");
        client.println("");
        client.println("
");
        client.println("
Servo	Position	Running	Initialized
");

        for (int i = 0; i < getParamUInt8(P_SERVO_SIZE); i++)
        {
            sprintf(buffer, "
%u	%d	%s	%s
", i + 1, (int16_t) _servo[i].current, _servo[i].ended ? "NO" : "YES", _servo[i].initialized ? "YES" : "NO" );
            client.println(buffer);
        }
        client.println("
");

        client.println("

");

        client.println("
");
        client.println("
Led	PWM	Running
");

        for (int i = 0; i < getParamUInt8(P_LED_SIZE); i++)
        {
            sprintf(buffer, "
%u	%d	%s
", i + 1, (int16_t) _led[i].pwm, _led[i].ended ? "NO" : "YES");
            client.println(buffer);
        }
        client.println("
");

        client.println("

");

        client.println("
");
        client.println("
Stepper	Position	Running
");

        for (int i = 0; i < getParamUInt8(P_STEPPER_SIZE); i++)
        {
            sprintf(buffer, "
%u	%d	%s
", i + 1, (int16_t) _stepper[i].stepper.getCurrentPositionInMillimeters(), _stepper[i].stepper.motionComplete() ? "NO" : "YES");
            client.println(buffer);
        }
        client.println("
");
        client.println("");
    }

    void sectionHeader(EthernetClient client, int refresh)
    {
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.println("Connection: close");
        if (refresh) client.println("Refresh: 2");
        client.println();
        client.println("<!DOCTYPE HTML>");
    }

As you can see in the `sectionHeader()` I want to refresh the page every 2 seconds. It works, but after 3 or 4 refreshes it hangs and I have to reset the whole board.

Of course with an embedded system I would use Ajax... here I thought reloading the page should be enough.

What might cause such a hang?

body:
The code you have that says `readString += c` has to allocate a whole new string whenever it runs out of space for more characters. All those allocations are filling up memory.

Instead of the String class, use a single C character array, e.g.

char s[128];

that is big enough for whatever you put in it.

If it helps, I wrote a simple arduino web server for my own project, and if you look at the code [here](https://github.com/jspolsky/branchController2/blob/master/lib/WebServer/WebServer.cpp) that may give you ideas for how to implement this.


message:
NodeMCU unable to communicate with MFRC522 RFID reader

I am creating a project that will read the RFID card or tag data, store that into a mysql database and display the data via PHP.

I am using NodeMCU, RC522 RFID reader and Ardunio IDE to do that.

Below is my Arduino code.  It successfully connects with WiFi (that I can see via serial monitor) but gives no response when I touch the RFID card to the reader.

I can't find the error.

    /*
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # RFID MFRC522 / RC522 Library : https://github.com/miguelbalboa/rfid #
    #                                                                     #
    #                 Installation :                                      #
    # NodeMCU ESP8266/ESP12E    RFID MFRC522 / RC522                      #
    #         D2       <---------->   SDA/SS                              #
    #         D5       <---------->   SCK                                 #
    #         D7       <---------->   MOSI                                #
    #         D6       <---------->   MISO                                #
    #         GND      <---------->   GND                                 #
    #         D1       <---------->   RST                                 #
    #         3V/3V3   <---------->   3.3V                                #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

    #include <ESP8266WebServer.h>
    #include <ESP8266HTTPClient.h>
    #include <SPI.h>
    #include <MFRC522.h>

    #define SS_PIN D2  //--> SDA / SS is connected to pinout D2
    #define RST_PIN D1  //--> RST is connected to pinout D1
    MFRC522 mfrc522(SS_PIN, RST_PIN);  //--> Create MFRC522 instance.

    #define ON_Board_LED 2  //--> Defining an On Board LED, used for indicators when the process of connecting to a wifi router

    //----------------------------------------SSID and Password of your WiFi router-------------------------------------------------------------------------------------------------------------//
    const char* ssid = "apiece solution";
    const char* password = "apiece@123";
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

    ESP8266WebServer server(80);  //--> Server on port 80

    int readsuccess;
    byte readcard[4];
    char str[32] = "";
    String StrUID;

    //-----------------------------------------------------------------------------------------------SETUP--------------------------------------------------------------------------------------//
    void setup() {
      Serial.begin(115200); //--> Initialize serial communications with the PC
      SPI.begin();      //--> Init SPI bus
      mfrc522.PCD_Init(); //--> Init MFRC522 card

      delay(500);

      WiFi.begin(ssid, password); //--> Connect to your WiFi router
      Serial.println("hello");

      pinMode(ON_Board_LED,OUTPUT);
      digitalWrite(ON_Board_LED, HIGH); //--> Turn off Led On Board

      //----------------------------------------Wait for connection
      Serial.print("Connecting");
      while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        //----------------------------------------Make the On Board Flashing LED on the process of connecting to the wifi router.
        digitalWrite(ON_Board_LED, LOW);
        delay(250);
        digitalWrite(ON_Board_LED, HIGH);
        delay(250);
      }
      digitalWrite(ON_Board_LED, HIGH); //--> Turn off the On Board LED when it is connected to the wifi router.
      //----------------------------------------If successfully connected to the wifi router, the IP Address that will be visited is displayed in the serial monitor
      Serial.println("");
      Serial.print("Successfully connected to : ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());

      Serial.println("Please tag a card or keychain to see the UID !");
      Serial.println("");
    }
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

    //-----------------------------------------------------------------------------------------------LOOP---------------------------------------------------------------------------------------//
    void loop() {
      // put your main code here, to run repeatedly
      readsuccess = getid();

      if(readsuccess) {
      digitalWrite(ON_Board_LED, LOW);
        HTTPClient http;    //Declare object of class HTTPClient

        String UIDresultSend, postData;
        UIDresultSend = StrUID;

        //Post Data
        postData = "UIDresult=" + UIDresultSend;

       // http.begin("http://192.168.1.6/NodeMCU_RC522_Mysql/getUID.php");  //Specify request destination
        //http.addHeader("Content-Type", "application/x-www-form-urlencoded"); //Specify content-type header

        int httpCode = http.POST(postData);   //Send the request
        String payload = http.getString();    //Get the response payload

        Serial.println(UIDresultSend);
        Serial.println(httpCode);   //Print HTTP return code
        Serial.println(payload);    //Print request response payload

        http.end();  //Close connection
        delay(1000);
      digitalWrite(ON_Board_LED, HIGH);
      }
      else
      {
        Serial.println("hi");
         delay(1000);
      }
    }
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

    //----------------------------------------Procedure for reading and obtaining a UID from a card or keychain---------------------------------------------------------------------------------//
    int getid() {
      if(!mfrc522.PICC_IsNewCardPresent()) {
        return 0;
      }
      if(!mfrc522.PICC_ReadCardSerial()) {
        return 0;
      }

      Serial.print("THE UID OF THE SCANNED CARD IS : ");

      for(int i=0;i<4;i++){
        readcard[i]=mfrc522.uid.uidByte[i]; //storing the UID of the tag in readcard
        array_to_string(readcard, 4, str);
        StrUID = str;
      }
      mfrc522.PICC_HaltA();
      return 1;
    }
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

    //----------------------------------------Procedure to change the result of reading an array UID into a string------------------------------------------------------------------------------//
    void array_to_string(byte array[], unsigned int len, char buffer[]) {
        for (unsigned int i = 0; i < len; i++)
        {
            byte nib1 = (array[i] >> 4) & 0x0F;
            byte nib2 = (array[i] >> 0) & 0x0F;
            buffer[i*2+0] = nib1  < 0xA ? '0' + nib1  : 'A' + nib1  - 0xA;
            buffer[i*2+1] = nib2  < 0xA ? '0' + nib2  : 'A' + nib2  - 0xA;
        }
        buffer[len*2] = '\0';
    }
    //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//

body: your code is OK, I've made a very similar project and... got the same issue. Solution was not in code only in power supply. RFID need very efficient current source and stable voltage. Check the power source, if you used 7805 as linear voltage stabilizer your project will don't work.


message:
Controling L298n with interrupts

I'm working on my first arduino project, Sumo Robot, therefore i dont know much about programming yet.  We are supposed to use two IR sensors one on the front of the robot other on its back to avoid crossing the black line of the arena.
I wrote this simple code to control the motors.
But i have been  asked to use interrupts to raise the efficiency of my code.

So do you guys have an idea of how i can use interrupts with the L298n motor driver to move my dc motors forward and backward.

Here is my code

    int fIR=7;
    int bIR=8;
    int fIR_value;
    int bIR_value;
    const int trigPin = 9;
    const int echoPin = 11;

    long duration;
    int distance;

    int IN1 = 4;
    int IN2 = 5;
    int IN3 = 6;
    int IN4 = 12;

    void setup() {
      Serial.begin(9600);
      pinMode(fIR,INPUT);
      pinMode(fIR,INPUT);
      pinMode(trigPin,OUTPUT);
      pinMode(echoPin,INPUT);
      pinMode(IN1,OUTPUT);
      pinMode(IN2,OUTPUT);
      pinMode(IN3,OUTPUT);
      pinMode(IN4,OUTPUT);

    }

    void loop() {

      fIR_value = digitalRead(fIR);
      Serial.print("Front IR:");
      Serial.print(fIR_value);
      Serial.print(" , ");

      bIR_value = digitalRead(bIR);
      Serial.print("Back IR:");
      Serial.print(bIR_value);
      Serial.print(" , ");

      digitalWrite(trigPin, LOW);
      delayMicroseconds(10);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      distance = duration*0.034/2;
      Serial.print("Distance: ");
      Serial.println(distance);
      delay (500);

      if(distance<30&&fIR_value==HIGH&&bIR_value==LOW){
        STOP();
        delay(50);
        BACKWARD();
    //    Serial.print("1");
      }
      else if(distance<30&&fIR_value==LOW&&bIR_value==HIGH){
        STOP();
        delay(50);
        FORWARD();
    //    Serial.print("2");

      }
      else if(distance<30&&fIR_value==LOW&&bIR_value==LOW){
        STOP();
        delay(50);
        FORWARD();
    //    Serial.print("3");

      }
        else if(distance>30&&fIR_value==LOW&&bIR_value==LOW){
        STOP();
        delay(50);
        ROTATE();
    //    Serial.print("4");

      }
       else if(distance>30&&fIR_value==HIGH&&bIR_value==LOW){
        STOP();
        delay(50);
        BACKWARD();
    //    Serial.print("5");

      }
       else if(distance>30&&fIR_value==LOW&&bIR_value==HIGH){
        STOP();
        delay(50);
        FORWARD();
    //    Serial.print("6");

      }
    }

    void FORWARD(){

      digitalWrite(IN1,200);
      digitalWrite(IN2,0);
      digitalWrite(IN3,0);
      digitalWrite(IN4,200);
    }
    void BACKWARD(){

      digitalWrite(IN1,0);
      digitalWrite(IN2,200);
      digitalWrite(IN3,200);
      digitalWrite(IN4,0);
    }
    void ROTATE(){

      digitalWrite(IN1,200);
      digitalWrite(IN2,0);
      digitalWrite(IN3,200);
      digitalWrite(IN4,0);
    }
    void STOP(){

      digitalWrite(IN1,0);
      digitalWrite(IN2,0);
      digitalWrite(IN3,0);
      digitalWrite(IN4,0);
    }

body:
As jsotola already suggested in the comments, using interrupts for driving the motors does not make sense. With a L298N you simply set the outputs and then leave them alone until you think they should stop.

Instead you could use interrupts for your sensors.

Though I would argue, that using interrupts would not be really necessary, when you implement your code the right way, means non-blocking. You use a lot of `delay()` calls. where the Arduino does not do anything, just twiddling thumbs. Instead you could use the principle from the `BlinkWithoutDelay` example, that comes with the Arduino IDE, to write the code non-blocking. In that case every bit of code would only do something, if it needs to, and otherwise return fast. That would make your code run way faster. You would also need to set a lower timeout for the `pulseIn()` function, as it's standard timeout is 1s (ultrasonic sensors like you are using one normally can only sense up to 3m, would would correspond to 20ms max pulse duration, if I'm doing the math correctly).

If using interrupts is a mandatory part of your excercise, you can decide, where to use interrupts:

- The simplest way would be for the **IR sensors**. You could use the `attachInterrupt()` function to set up an Interrupt Service Routine (ISR) for the corresponding pin. If you want the interrupt to trigger, when the IR sensors go HIGH, you can use `RISING`, otherwise you can use `FALLING`. Keep in mind, that ISRs should be as small and fast as possible. You cannot use `delay()` there. Normally one would only set simple (1 byte) variables in the ISR, and then react with longer actions in the main code by checking these variables. You have you set every variable, that can be changed in an ISR, as volatile:

        volatile byte flag;

- For the ultrasonic sensor, you have more than one way to go. I will outline 2 ways. For both of them you need to either directly manipulate the Special Function Registers of the microcontroller, or find a library, that does that for you (don't know, if such libraries exist, but you can search for them):

    1. You could use the Pin Change Interrupt. It triggers everytime, when a pin from a full pin port (group of up to 8 pins) changes it's state. You can mask away unused pins, so that they will not influence the interrupt. In the ISR you can check the state of the pin. If it is high, the start of the pulse just happened. Save a timestamp of that moment with the `micros()` function. The next ISR (where the pin will be LOW) will mark the end of the pulse. Now you can calculate the time difference between the timestamp and the current `micros()` value. You should use a 1-byte variable as flag, to trigger the processing the the pulse duration in the main function (or, if you want to directly use the time difference variable, you need to turn of the interrupt, while you are using the variable).

    2. If you want to show off, you could use a hardware Timer in Input Capture mode (this is the more complex, then the other possibilities). The timer is a counter, that is connected to the system clock (through a prescaler, where you can change the count frequency in a coarse way). The timer starts and when the Input Capture pin ICP1 (in case of Timer1) changes it's state, the current value of the timer will be saved in an extra register and an interrupt is fired. This timer value is like a timestamp. If you record the timestamps for the rising and the falling edge of the pulse, you can take the difference and calculate the time difference/distance from this. This part works similar to the first way above. The notes about interrupts also apply here.


message:
FlexyStepper: set current position leads to reach the old target

I'm using the [FlexyStepper][1] library.Unfortunately there's no way to write an issue to the author so I'm going to ask my question here.

The documentation says about the `setCurrentPosition*()` functions:

> set current position of the motor in millimeter, this does not move the motor

But I see a different behavior.
Looking at the code, it seems it just update the *current* position, leaving unchanged the *target* position. This leads to an expected movement of the motor. Example:

1. set the target position to, say: 1000
2. the motor reach that position
3. set the current position to, say: 1500
4. now the motor come back to 1000

Instead, I want the *current* position from now is 1500, but because it has already reached the target, it shouldn't move further.

Of course a workaround is to set both current position and target to the same value.

I wonder if I'm wrong about the documentation or this might be considered a bug.

  [1]: https://github.com/Stan-Reifel/FlexyStepper

body:
The point of `setCurrentPosition()` is to calibrate the stepper. It would normally be used in association with a limit switch of some form.

If you set the motor to go to 1000 and then tell it that the motor is actually at 1500 then of course it will then try and go back to 1000 - you have told it that is where you want it, but you also told it that's not where it is.

The normal usage would be:

1. Step the motor constantly in one direction until it hits a limit switch or similar
2. Set the current position to whatever that actual position is
3. Start going to actual positions that are relative to that reference point.

For example

* Move the motor anti-clockwise
* Motor triggers limit switch
* Stop moving the motor
* Set the current position to 0
* Start using the motor normally


message:
Can the ESP-1 use SPI to communicate with sensors?

I wonder if I can use SPI to communicate between ESP-1  ESP8266 module and SPI sensors and other slaves.

If so, do I need to install a library?

body:
ESP-01 was designed as WiFi network adapter, not as a controller board. The are 4 pins on esp-01. RX (io 3), TX (io 1), io 0 and io 2.

SPI requires 3 pins: clock, MISO, MOSI plus one pin for every device connected to the bus. So you could in theory use one SPI device on this 4 pins. The esp8266 Arduino SPI library works only with hardware SPI on esp8266 pins io 12, 13, 14 so you would have to use some software SPI implementation for esp8266.

To connect sensors, actuators or display to the esp-01, I2C is a feasible option. It requires only two digital pins and the esp8266 Arduino Wire library can work on any pair of io pins.

To use esp8266 as MCU with Arduino, there are many development boards with all usable pins broken out (9 pins) and USB chip for simple connection to computer and flashing (Wemos, NodeMCU). Or you can use an esp8266 module with more or all pins of the esp8266 (esp-07, esp-12).


message:
Why does my circuit work only when I do not use the Serial port?

I am a newcomer to working with Arduinos (and circuits in general) so when I was tasked with making a simple push-button circuit to control an LED's state, and to send a message back using ```Serial.println()``` to show the button had been pressed, I noticed that the LED is dimly lit when I press the button to give it power. However, when I do not use the Serial port at all in my code, then it works perfectly as expected.

My code:

```cpp
const int ledPort = 8;
const int detPort = 7;
void setup() {
  pinMode(ledPort, OUTPUT);
  pinMode(detPort, INPUT);
  digitalWrite(ledPort, HIGH);
  Serial.begin(9600);
}

void loop() {

  if (digitalRead(detPort) == HIGH) {
    digitalWrite(ledPort, LOW);
    Serial.println("9");
    delay(500);
  }
  else {
    digitalWrite(ledPort, HIGH);

```
My circuit:

https://i.stack.imgur.com/mYUYf.jpg

My Board: MEGA2560

body:
Your circuit doesn't make sense to me, either :) I can't see where the LED is getting its ground from, in particular.

Try starting with the circuit shown [here](https://www.arduino.cc/en/Tutorial/Pushbutton) and report back!

Good luck!


body:
Your circuit is wired improperly.
It will be easiest for you to simply follow this official tutorial that will show you [how to use a push button to turn on an LED][1]. Even though you have a mega, it will work fine for you.

You will see a wiring picture there that is simplified:
[![wiring pic][2]][2]

Plus, the correct code is there:

    /* Basic Digital Read
     * ------------------
     *
     * turns on and off a light emitting diode(LED) connected to digital
     * pin 13, when pressing a pushbutton attached to pin 7. It illustrates the
     * concept of Active-Low, which consists in connecting buttons using a
     * 1K to 10K pull-up resistor.
     *
     * Created 1 December 2005
     * copyleft 2005 DojoDave <http://www.0j0.org>
     * http://arduino.berlios.de
     *
     */

    int ledPin = 13; // choose the pin for the LED
    int inPin = 7;   // choose the input pin (for a pushbutton)
    int val = 0;     // variable for reading the pin status

    void setup() {
      pinMode(ledPin, OUTPUT);  // declare LED as output
      pinMode(inPin, INPUT);    // declare pushbutton as input
    }

    void loop(){
      val = digitalRead(inPin);  // read input value
      if (val == HIGH) {         // check if the input is HIGH (button released)
        digitalWrite(ledPin, LOW);  // turn LED OFF
      } else {
        digitalWrite(ledPin, HIGH);  // turn LED ON
      }
    }

**Schematic Is Quite Important**
also, as you attempt to look at the picture and build the circuit you discover how difficult it is to see how things are connected.
That leads you to understand how important a simple schematic can be.
I've attempted to turn the pic from the arduino site into a schematic and my interpretation may be wrong or the actual circuit that the Arduino site has built may be wrong.  If anyone has comments I will take them into account.

Trying to build from a picture of a circuit is terribly difficult and trying to debug your circuit from a picture is also. That's why when you submit a question you should submit a drawn schematic of how you have wired it up.

<!-- 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/1h7eh.png)

<!-- End schematic -->

  [1]: https://www.arduino.cc/en/Tutorial/Pushbutton
  [2]: https://i.stack.imgur.com/zsGDc.jpg


message:
What is the correct way to interpret the built-in Analog-to-Digital Converter output?

When using the built-in analog to digital converter of the Arduino Uno Rev 3's Atmega328P with a reference voltage of 5V, what is the appropriate function to interpret the output? There is conflicting information on the Arduino website and in the datasheet for the Atmega328P (Arduino Uno Rev 3's chipset).

A lot of code examples on the internet indicate that the appropriate conversion factor is 5V/1023 (including the [Arduino website][1]: `float voltage= sensorValue * (5.0 / 1023.0);`).

Per the [Atmega328P's datasheet][2], it indicates the conversion factor is 5V/102**4**:
[![enter image description here][3]][3]

If Vin and Vref are 5V, then the ADC reading would need to be 1024 in order to have a true reading of 5V, which is not possible since 1023 is the max output of the ADC. The closest reading to 5V we can get from this equation is ~4.9951 (5V*1023/1024).

With the Arduino example's conversion factor of 5V/1023, we get 5V for an ADC output of 1023.

Additionally, since the information from both sources is in conflict, it got me thinking a little more: The ADC is inherently sampling, and I am not sure if the ADC rounds up/down to the nearest value, so perhaps the closest approximation of Vin is an equation like the following that splits the difference:

`Vin = (ADC+(ADC+1))/2 * 1024/Vref`

Using the above equation, an ADC reading of 0 with Vref=5V would give `Vin = (0 + (0+1))/2 *1024/5V = ~0.00244`. This equation never gives a reading of 5V or 0V, but rather a value that splits the difference between samples.

Perhaps I am splitting hairs since the absolute accuracy of the ADC is ["±2 LSB absolute accuracy"][2], but I would still like to know which is the best equation to convert an output from the ADC into a voltage measurement.

  [1]: https://www.arduino.cc/en/Tutorial/ReadAnalogVoltage
  [2]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
  [3]: https://i.stack.imgur.com/YYmtM.png

body:
As others have said, the difference between 1023 and 1024 is quite small.

However, the fact is that your input range for the ADC is 0 to 1023. (That's 1024 steps, but since it starts at 0, it won't go up to 1024)

You'll get 0 at the minimum input, and **1023** at the maximum value.

If you're using a 5.0V reference voltage and no voltage dividers, that means you will get 1023 at 5V (ignoring measurement error.) If you want your output value to be the VOLTAGE measured, you would want `Vin / 1023.0 * 5.0`. That would give you a value of 5.0 at the max input of 1023 (representing 5.0 volts) and 0 at 0 volts input.

## Edit:

Since my posting, I read the threads on this, and there is a raging debate on the subject. I am now less clear that there is "right" way to do this.

The issue is that the ADC value doesn't give you a certain reading, it indicates a range. When you get a value of 1024, the ADC is tellling you that the measured voltage is in the top 1/1024th of voltages, from about 4.995V to 5V (or above, for that matter.)

The steps are actually in 1024ths. That argues that you should divide the measured value by 1024, and then return a range of possible voltages:

    value = analoglRead(pin);
    float lower_value = value / 1024.0 * 5.0;
    float upper_value = (value + 1) / 1024.0 * 5.0;

For an analog reading of 0, that would give you a range of 0.0v. to 0.0048828125v.

For an analog value of 1023, that would give you a range of 4.9951171875v to 5.0v


body:
> the Atmega328P's datasheet, it indicates the conversion factor is
> 5V/1024 [...]

Indeed. And the datasheet is _the only authoritative source_. All the
other sources are second-guessing.

> If Vin and Vref are 5V, then the ADC reading would need to be 1024 in
> order to have a true reading of 5V

You can't get a true reading of 5 V. As per the datasheet (emphasis
mine): “_0x000 represents analog ground, and 0x3FF represents the
selected reference voltage **minus one LSB**_”.

Any input voltage larger that the maximum representable voltage will
read as 0x3ff (i.e. 1023), just like any negative voltage (within
the forward voltage of the protection diode) will read as zero. Thus,
reading either 0 or 1023 should be interpreted as a saturation
of the ADC, meaning the actual voltage is unknown.

> The ADC is inherently sampling, and I am not sure if the ADC rounds
> up/down to the nearest value

In principle it should round to the nearest value. The transition in the
reading from 0 to 1 should ideally happen at
Vref/2048. C.f., again, the datasheet, subsection “ADC
Accuracy Definitions”: “_Offset: The deviation of the first transition
(0x000 to 0x001) compared to the ideal transition (**at 0.5 LSB**)._”

A little bit further in the page it is stated that the ideal position of
the last transition (1022 to 1023) is “_at 1.5 LSB below maximum_”.

> Perhaps I am splitting hairs since the absolute accuracy of the ADC is
> "±2 LSB absolute accuracy"

Indeed. If you really care you should probably calibrate your ADC. See
[Response of the Arduino ADC](https://wiki.logre.eu/index.php/Réponse_de_l'ADC_d'un_Arduino/en).

**Edit**: in a comment you mention that the factor 1024 could
conceivably be “a persistent typo that it appears in multiple AVR
chipset datasheets”. It may be an error, but certainly not a typo, as
the datasheet contains multiple independent statements that confirm the
factor 1024.


body:
*After reading through various arguments for use of different transfer functions, this is my summary:*

In order to achieve the manufacturer-stated absolute accuracy of ±2 LSB, you should use the manufacturer's equations and published guidelines on usage to ensure that accuracy (e.g. ensuring appropriate ADC clock speed / sampling time and implementing noise reduction techniques).

It may be possible to achieve better results using another transfer function by calibrating specific to each individual circuit. If you go this route, all of the responsibility of ensuring accurate calibration across the range of expected operating conditions (including offset/gain drifts due to environmental factors) are your responsibility to characterize and account for when developing the transfer function. This is where the transfer function `Vin = 5V/1023 * ADC` fits in. This transfer function may in fact be a better representation of the actual outputs for a specific chip. However, use of this transfer function shifts responsibility onto its user to verify that it actually produces better results.

*A couple of important notes:*

 - *Manufacturer's claims are not always accurate. However, they are likely based on a large statistical sample size and if the manufacturer's published statements are wrong, this potentially opens the manufacturer up to lawsuits depending on the impact of an incorrect published specification. For this reason, I tend to trust manufacturer datasheets from large chip makers until proven otherwise.*
 - *The question assumed a perfect 5V reference for simplicity of discussion, however the actual value of a real voltage reference is almost impossibly a true 5V and has some degree of noise affecting its stability which should also be considered when attempting to read a true voltage value. Ideally, if you are trying to read a sensor value and can create a circuit in which the voltage reference cancels out of the final measurement, that will help with accuracy of the sensor reading.*


message:
Arduino Temperature Sensor

We are doing a project and we need to build a thermo sensor and read the voltage and the temperature but we also have to have the temperature correspond to LEDs that will give a blue for cold green for mild and red for hot we are using a DS18b20 thermo sensor.

How should we write the code or where could we find code that would work for this purpose?

We both have a very surface level understanding of code at the moment, however our time constraints have made learning it difficult.

body:
This forum isn't great for detailed solutions to vague problems. If you don't have much experience with programming, you'll have a lot to figure out. It will take you a while (realistically probably a couple of weeks if you work at it every day, and have a knack for it, assuming you're starting from scratch.)

The first step is to define your problem. It sounds like you want to build a project that uses colored LEDs to indicate the measured temperature in different ranges.

So lets say you want:

    Temp <10°C light Blue LED
    Temp 10°C - 30°C light green LED
    temp >30°C light red LED.

Break the problem into bite-sized pieces and solve them one at a time.

Pick an Arduino model. Install the IDE. Run a sketch that will blink the built-in LED. Then do a google search on "Arduino Blink without delay" and rewrite your blink code to not use the `delay()` function. Forget the `delay()` function exists and never use it again, since it will usually get in the way of what you need to do.

Then figure out how to wire separate LEDs (including current limiting resistors) to 3 separate pins. Make your code blink all 3 LEDs at the same time by toggling the appropriate pins' output states.

Modify your app to blink first one LED, the 2nd, and then the third. Now get tricky and modify your app to blink the first LED on and off once a second, the next LED once every 1/3 of a second, and the fourth LED to blink once every 1/4 second, all at the same time. (That will force you to really understand how to do timing without delay.)

Now look up a sample project that uses your temp sensor. (Try [**this one I found**][1], for example) Run that and get it to send the temp to your serial port once every few seconds. (again not using `delay()`.)

Now write a loop that reads the temp sensor, decides which range the temp is in, and lights the appropriate LED based on those ranges. Note that you may only be able to read the temp every 2 seconds or so (the DHT22 and DHT11 temp sensors I've used have that limitation.)

  [1]: https://create.arduino.cc/projecthub/TheGadgetBoy/ds18b20-digital-temperature-sensor-and-arduino-9cc806


message:
ESP32 documentaiont for "time.h"

I am working from the example sketch in that [installed][1] with the ESP32 Dev Module into the Arduino IDE.  It includes `<WiFi.h>` and `"time.h"`.  I have a number of questions about how to use the clock that is set up with `configTime` using NTP. I am trying to find the documentation, but I'm having difficulty identifying exactly who is providing me the `"time.h"` header file, and of course, there are a lot of different `time.h` header files out there so googling is difficult.

Where can I find the documentation for this particular header?

-----

Example questions:

* Can the time be set manually without a WiFi connection?
* Can the timezone be changed without connecting to NTP again?
* Can I get the time as a Unix Time Stamp?  ([Yes][2])
* Can I arrange for a function callback at a certain time? (I'm aware I can use the timer library for this but I'm hoping for something like a callback at 4:20p every Saturday)

  [1]: https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/
  [2]: https://arduino.stackexchange.com/questions/71453/esp32-seconds-from-epoch

body:
`time.h` is provided by the compiler (more specifically the C library in use in the compiler).

I believe the xtensa-esp32 compiler uses *newlib* as the C library. If that is the case, the documentation is here: https://sourceware.org/newlib/libc.html#Timefns


message:
ESP web server calling Javascript function

Is there a way to call Javascript functions from an ESP?

I don't want to call AJAX requests every few seconds; I want to update my values only when they change.

Can it by done?

body:
If you want server-push, you can use Server Sent Events or a Websocket instead of polling with XMLHttpRequest.

So yes, it can be done, and I have implemented both using a Nano 33 IoT at one end and Javascript in a browser on the other. Some example code is here: https://github.com/ocrdu/arduino-webinterface-sse and here: https://github.com/ocrdu/arduino-webinterface-websocket.

I don't know if there are convenient libraries for the ESPs to do this, though.


body:
I assume that you misunderstand how JavaScript works. JS is executed on the client side and therefore the esp can easily serve JS code the same way it would provide any html content. Take a look at the Webserver examples and embed your JavaScript code into the html content that the examples use.

The important thing to note is that the esp does not execute JavaScript, from its perspective the content is just an ordinary string without functionality.

The easiest and fastest way to update values on a web interface is probably using a websocket: the esp is a websocket server (using [link2004‘s websocket library][1]) and the JavaScript binds to the esp‘s websocket as a client (this has nothing to do with the esp/arduino/C++, but you’ll find examples out there).

  [1]: https://github.com/Links2004/arduinoWebSockets


message:
Will bootloader communicate via TX0 / RX0

I'm fairly new to Arduino programming but have a good deal of experience with  low-level programming early processors, having originally cut my teeth on Z80, 8088, etc. I'm looking at developing a sizeable project using a Mega 2560. The project includes quite a lot of off-board logic, leds, and an RPi. Thus I don't want to overload the 2560 voltage regulator and really want to use common rail 5v power with a switch-mode supply. However, I also need debugging / console access, so this gives me the immediate problem of direct 5v driving whilst the board is being driven with 5v from the USB port, which is a no - no. The solution appeared to be fairly simple - use a CH340 - based USB to serial converter and connect it to RX0, TX0 and Reset (DTR output connected via a blocking capacitor) but with its 5v output disconnected. With this setup, the Arduino communicates quite happily with the IDE-based serial monitor (the sketch was downloaded via the on-board usb port), but on trying to download a new sketch via this route, AVRDude fails with a timeout. At the commencement of the download the processor is being reset, but the bootloader doesn't appear to hansdshake with AVRDude (properly). Is this a known feature or have I missed something?

body: Problem solved. The standalone CH340-based converter for whatever reason isn't man-enough to reliably pull down the RX0 line when connected to the Mega 2560 (also with a CH340 converter on board). I've seen suggestions posted in various places that this can be a problem with respect to DTR (though I don't have a problem with it). My solution is to insert a 7417 open-collector non-inverting buffer between the output of the stand-alone converter and the RX0 input on the 2560 board. I've not been able to find a schematic for the Mega 2560 board to determine its pull-up resistor size but imagine it must be relatively small. Thanks to those who made suggestions.


message:
Adafruit Circuit Playground Express fails to upload

When uploading code to the Adafruit Circuit Playground Express, I have found that most of the time it fails to upload saying that the port is busy. There seems to be no logical reason behind this, as it uploads perfectly to an Arduino Uno (Yes, I did switch the board types). What am I doing wrong?
Here is the error:
```´
processing.app.debug.RunnerException
 at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
 at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
 at processing.app.SketchController.upload(SketchController.java:732)
 at processing.app.SketchController.exportApplet(SketchController.java:703)
 at processing.app.Editor$UploadHandler.run(Editor.java:2075)
 at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port '/dev/ttyACM1'.
 at processing.app.Serial.touchForCDCReset(Serial.java:107)
 at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
 ... 5 more
Caused by: jssc.SerialPortException: Port name - /dev/ttyACM1; Method name - openPort(); Exception type - Port busy.
 at jssc.SerialPort.openPort(SerialPort.java:164)
 at processing.app.Serial.touchForCDCReset(Serial.java:101)
 ... 6 more
```

Operating system: kubuntu linux 64 bit

**EDIT:** Never mind. In the end I used `chmod a-x /usr/sbin/ModemManager` to remove execute permissions from every user, and that worked without any noticeable repercussions to my system. For anyone who wants to do the same, make note of the original permissions, so you can change it back if you have to.

body:
The actual error part of that stack trace is:

    Port name - /dev/ttyACM1; Method name - openPort(); Exception type - Port busy.

You have something else using `/dev/ttyACM1`.  If you don't yourself have something open, such as a serial terminal or the Arduino serial monitor, then the most likely culpret is `modemmanager`.

* https://majenko.co.uk/blog/diagnosing-arduino-problems-linux