title: Send serial command and wait for reply

text:
# Question
Title: Send serial command and wait for reply
I am new to Arduino and have tried all kinds of code for attempting to achieve this. None with any luck, however. I feel that it should be a relatively easy task and therefore, figured that someone out there with more proficiency with an Arduino than me, would be able to help.

Essentially, I have two commands sent to a device via the Leonardo serial port. One is the single character "R", and the other is the single character "O". The device then sends back 8 binary bytes (non ASCII) in floating point format per command. So if I send O, it will return 8 binary bytes, and then the same goes for if I sent R.

The commands O and R need to be simultaneously sent via the serial every 250ms and wait for their respective responses before sending the next command.

I also need to store the device's response to O and the device's response to R in respective variables that will have a new value every 250ms. I am not familiar with single point format and therefore am unaware of what variable system to use.

Here is my best, yet unsuccessful attempt:

```
unsigned long previousMillis = 0;
const long interval = 250;
int responseO;
int responseR;

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

    while(!Serial);
}

void loop()
{
    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis >= interval) { //timer for every 250ms
        previousMillis = currentMillis;
        Serial.println("R");               //Figured that "println" with a string for the character R should be ok

        if(Serial.available() > 0) {          //Don't know if I am correct here, I was hoping that the serial would only be read if the device responded to the command R
            responseR = Serial.read();       //Read serial for device's response to command R and save it in a variable
        }

        Serial.println("O");               //Do the same thing for the command O

        if(Serial.available() >0) {
          responseO = Serial.read();
          }
    }
}

```

However, whenever I test this, it appears that the program is unable to differentiate between which responses are due to one command, and treats one response as if both commands requested it when only one did. Also is a floating point format variable just a float?

Thank you so so much, I really need some help this has been burning away at me for days........

Cheers, Harry

# Answer
> 1 votes
The code shown in two previous answers is problematic.

For example, in Look Alterno's code, `Serial.println("R")` will trigger an `R` response. The `while(!Serial.available());` construct will wait for the first byte of the response. Then `responseR = Serial.read();` will read one byte. Next, `Serial.println("O")` will attempt to trigger an `O` response. The second `while(!Serial.available());` will wait for a byte to be available, which should happen when the second byte of the `R` response arrives. Then `responseO = Serial.read()` will read that byte.

In ratchet freak's code, each quarter second `bytesToReadFromR` and `bytesToReadFromO` are set to 8. In the next several passes through `loop()`, `if(bytesToReadFromR)` and `if(bytesToReadFromO)` are satisfied, so `while(bytesToReadFromR && Serial.available())` and `while(bytesToReadFromO && Serial.available())` will be controlled by whether a character is available. At 9600 bps, about one character per millisecond will become available, so most of the time we are just spinning through `loop()` dozens of times per millisecond, waiting for characters. The `if` statement for `bytesToReadFromR` has a slightly higher chance of catching fresh characters, but which buffer (`responseR` or `responseO`) gets any given character still is left to chance.

Instead of the code previously shown, consider something like the following:

```
enum { dataBytes = 8, interval=250 };

float getResult (char trigger) {
  union { byte d[dataBytes], float f[2] } u;
  byte rin=0;
  Serial.print(trigger);
  while (rin < dataBytes) {
    if(Serial.available())
      u.d[rin++] = Serial.read();
  }
  return u.f[0];        // Assumes bytes in forward order
}

unsigned long prevMillis = millis();
float RValue, OValue;

void loop() {
  if(millis() - prevMillis >= interval) {
    prevMillis = millis();
    RValue = getResult ('R');
    OValue = getResult ('O');
    // put code here to consume the results
    // ...
  }
}

```

Note, this code will get stuck if too-few characters arrive from the R&O device, or if some characters get lost for any reason. One could add a timeout to the loop in `getResult()`; it could check for `millis() - prevMillis >= interval` and if so, break the loop and return a NAN.

Note, this code assumes the byte-order of floats from the R&O device matches that of the Arduino. That will be so if both are big-endian, or if both are little-endian. If they differ, store bytes in reverse order into the `u.d` array, and return `u.f[1]` instead of `u.f[0]`.

Note, `union` is a C / C++ technique for accessing data multiple ways. The declaration `union { byte d[dataBytes], float f[2] } u` says that `u` is a structure where the array `d` starts at the same address as the array `f`. Thus, the float `u.f[0]` corresponds to the first four bytes of `u.d`, and `u.f[1]` to the next four.

Note, if the R&O device requires an end-of-line character, change `Serial.print(trigger)` to `Serial.println(trigger)`.

# Answer
> 0 votes
After printing a char in the Serial, you have to wait until some response is received. For that, you use a `while`

```
void loop()
{
    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis >= interval) { //timer for every 250ms
        previousMillis = currentMillis;

        Serial.println("R");               //Figured that "println" with a string for the character R should be ok
        while(!Serial.available());
        responseR = Serial.read();       //Read serial for device's response to command R and save it in a variable

        Serial.println("O");               //Do the same thing for the command O
        while(!Serial.available());
        responseO = Serial.read();
    }
}

```

Now, you have to tell us which *floating point format* are you using.

# Answer
> 0 votes
each call to Serial.read will read a single byte. So to read multiple bytes it needs to be called multiple times.

```
int bytesToReadFromR;
int bytesToReadFromO;

void loop()
{
    unsigned long currentMillis = millis();

    if(currentMillis - previousMillis >= interval) { //timer for every 250ms
        previousMillis = currentMillis;

        Serial.println("R");
        bytesToReadFromR = 8;              //mark that there is data to read from Serial for R

        Serial.println("O");
        bytesToReadFromO = 8;              //Do the same thing for the command O
    }

    if(bytesToReadFromR){
        while(bytesToReadFromR && Serial.available()){
           responseR[--bytesToReadFromR] = Serial.read();       //Read serial for device's response to command R and save it in a char array
        }
        if(bytesToReadFromR){
             //finished transfer, trigger what you need
        }
    }
    if(bytesToReadFromO){
        while(bytesToReadFromO && Serial.available()){
           responseO[--bytesToReadFromR] = Serial.read();       //Read serial for device's response to command O and save it in a char array
        }
        if(bytesToReadFromO){
             //finished transfer, trigger what you need
        }
    }
}

```

# Answer
> 0 votes
As others have mentioned, you have to read the serial input byte by byte. 4 bytes means you have to read it four times and store the values in an array. Then do your calculations with the array.

After a little googling I found this: https://stackoverflow.com/questions/3991478/building-a-32bit-float-out-of-its-4-composite-bytes-c

Which is basically what you want to do. Try this code:

```
unsigned long previousMillis = 0;
const long interval = 250;

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

void loop() {

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) //timer for every 250ms
  {

    previousMillis = currentMillis;

    Serial.println("R");               //maybe substitute with
    if(Serial.available() >0)          //Serial.println('R'); or
    {                                  //Serial.write("R");   or
      byte buff1[4];                   //Serial.write('R');
      byte buff2[4];
      float firstNumber;
      float secondNumber;

      for(int i=3; i>=0; i--){
        buff1[i] = Serial.read();
      }
      for(int i=3; i>=0; i--){
        buff2[i] = Serial.read();
      }

      memcpy(&firstNumber, &buff1, sizeof(firstNumber));
      memcpy(&secondNumber, &buff2, sizeof(secondNumber));

      Serial.print("first number is: ");
      Serial.println(firstNumber);
      Serial.print("second number is: ");
      Serial.println(secondNumber);

    }

    //do the same thing with your "O" command, or write a function

  }

}

```

There are two things to consider though:

* As you can see I am looping the `buff1` and `buff2` arrays backwards. This is because the endianness of the float depends on how your device sends them. If you were receiving gibberish change the loops to count from 0 to 4.
* You said your device expects a single 'R' **character** but what you are doing is sending a "R" **string** and then a new line character after that(because you are using **println()**). It's possible that you will have to substitute that with one of the options I mentioned in the code comment.

---
Tags: serial, arduino-leonardo, code-review, variables, float
---


# Question
Title: Did I fry my DUE by powering it from a external source and USB at the same time? If so, why?
I guess I just fried my second DUE in a week. The first I didn't really see what happened, but I couldn't upload any sketches, even if the computer could recognize it, and the SAM would get really hot.

Now, I had it powered by a 12V External supply, through a regulator bringing it down to 9V, and in the exact moment I plugged the USB, with power still on, I got a lot of smoke, smelling of fried electronics :p. Afterwards, I have the same symptoms as I had in the other boards: Green and orange LEDs on, chip very hot, computer recognizing it as a Arduino DUE but not being able to upload any sketches.

What just happened?

# Answer
> 1 votes
If it was the same sketch involved in the destruction of both it may be a good idea to check to make sure the sketch that is involved as well to make sure there are no logical shorts to ground or other pins. Rugged-Circuits has a list of some common ways the Arduino can get shorted. It is showing the Uno but I am sure all similar rules apply with the exception of total power requirements and other differences between the boards.

# Answer
> 0 votes
As Majenko said you should check these voltages.

Arduino DUE uses the LM2734Y DC/DC converter and according to datasheet it works up to 20V so there is no need to use your 9V regulator.

Also on DUE there is comparator which should turns off a USB power supply when external power supply is used. Look for 2 transistors on board (FDN340P) called T1 and T2. There both are turning on/off power from USB source. Also check them. There can be also problem with all components around USB power. For more info check Arduino schematic.

---
Tags: power, arduino-due
---


title: NodeMCU access point for MQTT broker

text:
# Question
Title: NodeMCU access point for MQTT broker
Is it possible to publish and subscribe using MQTT, when the mqtt broker is connected to a network which is created by a NodeMCU?

Can a NodeMCU connect to its own created network?

# Answer
The devices conected via an NodeMCU acting as an WiFi Access Point can communicate between with the NodeMCU and between themselves.

So, if all devices involved are connected to the same NodeMCU, then they can communicate as you asked.

NodeMCU also works as an Access Point + Station. Beside being an AP, then NodeMCU can simultaneously be a client in another WiFi network.

I doubt NodeMCU can route between his client and the external WiFi network.
> 1 votes

---
Tags: nodemcu
---


# Question
Title: SD card fails to write when used with another SPI device
I have an ADXL355 accelerometer attached to an Adafruit Feather Adalogger. I can configure and read the sensor. I can also write binary values to the SD card. The problem occurs when I try to read from the sensor and then write that data to the SD card. The only thing I can think of is I'm somehow messing up the SPI communication but I can't see where. I looked through `pins_arduino.h` for my board and the SD Card (pin 4) is on a different register than pin 10 so I don't see how I'm breaking things.

My operations proceed like this. Global sensor creation, `Serial.begin`, `SD.begin`, `SPI.begin`, Test sensor connection, Create file for output on SD card, Initialize sensor, Read sensor FIFO, Write to file, repeat last 2 forever.

The file is created but remains at 0 file size, ie nothing is actually written to the card.

The sensor can operate at 4 kHz which was hard to achieve using the `digitalWrite` functions so I switched to using the port registers on the Feather. I do it like this:

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

#define cardSelect 4

ADXL355_SPIF adxl355(&DDRB, &PORTB, _BV(6)); // values taken from pins_arduino.h, tested and working on pin 10
void setup() {
  Serial.begin(57600);
  while(!Serial){
    // wait for Serial
  }
  SD.begin(cardSelect);
  SPI.begin();
  while(!adxl355.TestConnection()){
    delay(1000);
  }
  adxl355.OpenFile("TestSPI.bin");
  adxl355.Initialize(1, 10, 0); // set range to 2g's, frequency to 4 Hz and filter to off
}

void loop() {
  while(true){ // avoid Arduino overhead of their loop function
    adxl355.ReadFIFO();
    adxl355.WriteFIFOToFile();
  }
}

```

Here is the ADXL constructor

```
ADXL355_SPIF::ADXL355_SPIF(volatile uint8_t * outReg, volatile uint8_t * outPort, uint8_t bitValue) : sensorOutReg(outReg), sensorPort(outPort), sensorBitValue(bitValue){
    *sensorOutReg |= sensorBitValue;
    *sensorPort |= sensorBitValue;
    sensorWriteCount = 0;
}

```

`TestConnection` tests that the DeviceID reads `0xAD`. `Initialize` sets the G range, sample rate in Hz and filter. I have tested these with serial output and they work properly.

`OpenFile` looks like this:

```
bool ADXL355_SPIF::OpenFile(const String& fileName){
    sensorFile = SD.open(fileName, FILE_WRITE);
    if (!sensorFile){
        Serial.print("Could not create file: ");
        Serial.println(fileName);
        return false;
    }
    return true;
}

```

After running this a file does get created on the SD card called "TESTSPI.BIN" with 0 file size.

`ReadFIFO` reads the numbers of entries in FIFO, stored as `fifoCount` and then populates a buffer (`sensorFIFO[32][3]`) with the values from the FIFO. I've printed this buffer to Serial to show that it's working. Here is that function

```
void ADXL355_SPIF::ReadFIFO(){
    ReadRegister(ADXL355_RA_FIFO_ENTRIES, 1);
    fifoCount = buffer[0];
    ReadFIFOInternal();
    return;
}

void ADXL355_SPIF::ReadFIFOInternal(){
    SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
    *sensorPort &= ~sensorBitValue;
    uint8_t spiCommand = ADXL355_RA_FIFO_DATA << 1 | ADXL355_READ;
    SPI.transfer(spiCommand);
    int i = 0;
    unsigned long tempV;
    unsigned long value;
    while(i < fifoCount){
        for (int ptr = 0; ptr < 3; ++ptr){
            buffer[0] = SPI.transfer(0x0);
            value = buffer[0];
            value <<= 12;
            tempV = SPI.transfer(0x0);
            tempV <<= 4;
            value |= tempV;
            tempV = SPI.transfer(0x0);
            tempV >>=4;
            value |= tempV;
            if (buffer[0] & 0x80) {
                value |= 0xFFF00000;
            }
            long lValue = static_cast<long>(value);
            sensorFIFO[i][ptr] = scaleFactor * lValue;
        }
        i += 3;
    }
    SPI.endTransaction();
    *sensorPort |= sensorBitValue;
    return;
}

```

Here is `WriteFIFOToFile`:

```
void ADXL355_SPIF::WriteFIFOToFile(){
    if (fifoCount > 0){
        sensorFile.write(reinterpret_cast<const char *>(&sensorFIFO), 4 * fifoCount);
    }
    sensorWriteCount += fifoCount;
    if (sensorWriteCount >= 100){
        sensorFile.flush();
        sensorWriteCount = 0;
    }
}

```

After allowing this to run for a while the file size is always 0. I tried a simple binary write function just to test the card. It looks like this and it worked.

```
#include <SD.h>

#define cardSelectPin 4

const float pi=3.14159;

File oFile;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while(!Serial){
    // wait for serial
  }
  SD.begin(cardSelectPin);
  oFile = SD.open("Test.bin", FILE_WRITE);
  Serial.println(sizeof(int));
  Serial.println(sizeof(float));
  float testFloat[32][3];
  for (int i = 0; i < 32; ++i){
    for (int j = 0; j < 3; ++j){
      testFloat[i][j] = pi * (i + 1) + j;
    }
  }
  oFile.write(reinterpret_cast<const char *>(&testFloat), sizeof(float) * 96);
  oFile.close();
  Serial.println("Finished writing file.");
}

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

}

```

# Answer
The problem here was caused by `flush` never being called within `WriteFIFOToFile`. The variable `sensorWriteCount` was defined incorrectly. Changing to call `flush` directly after each `write` statement fixed the problem. This lead to the debugging of the `if` statement and variable.
> 1 votes

---
Tags: spi, sd-card
---


# Question
Title: Ethernet shield and sd card not working togather on arduino mega
I am making a web-client with an Arduino mega and Ethernet Shield. I am trying to receive data from a web-server running a php script and saving that data to the SD card located in the Arduino Ethernet shield. I have separately tested to read and write to SD and to Get data from the the php script using the Ethernet. But when i tried to merge those two code into one, i found that Ethernet is unable to connect to the web-server(php Script).But the Ethernet connects fine when i remove the SD Card from its slot. During my research i found that Arduino mega has different SPI pin configuration that the uno. And the libraries are supposed to handle the SPI data-line independently. But i still tried to manually controlled the SPI bus, but it did not work. As far as i know, i am now unable to change the SPI bus using the D4 pin for SD card and D10 pin for Ethernet.

I am using native Ethernet library and SDFat library.(I Even used the native SD library but the result is the same).

```
#include <Ethernet.h>
#include <SPI.h>
#include <SdFat.h>
#define Ethernet_ss_pin 53
#define Sd_ss_pin 4

// On the Ethernet Shield, CS is pin 4. SdFat handles setting SS
/////////////////////////////////////////////////////////////////////////////////
////////SD Config
/////////////////////////////////////////////////////////////////////////////////

SdFat sd;
SdFile myFile;
//const int chipSelect = 4;
const char* fileName="database.txt";

/////////////////////////////////////////////////////////////////////////////////
////////Ethernet Config
/////////////////////////////////////////////////////////////////////////////////
//String server = "rfid.unisec-bd.org"; //ip Address of the server you will connect to

//The location to go to on the server
//make sure to keep HTTP/1.0 at the end, this is telling it what type of file it is
String location = "/getData.php HTTP/1.0";

// if need to change the MAC address (Very Rare)
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
////////////////////////////////////////////////////////////////////////

EthernetClient client;

char inString[3200]; // string for incoming serial data
int stringPos = 0; // string index counter
boolean startRead = false; // is reading?

void setup() {
  Serial.begin(9600);
  pinMode(53,OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(10,OUTPUT);
  ChipSelect(0);
  Ethernet.begin(mac);
  String pageValue;
  pageValue=connectAndRead(); //connect to the server and read the output
  Serial.println(pageValue); //print out the findings.
  ChipSelect(1);
  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
  if (!sd.begin(Sd_ss_pin, SPI_HALF_SPEED)) {
    sd.initErrorHalt("Sd initialization failed");
  }else{
    Serial.println("Sd card Initialized");
  }
  ChipSelect(0);

}

void loop() {
  Serial.println("Type any character to start");
  while (Serial.read() <= 0) {}
  delay(1000);  // catch Due reset problem
  ChipSelect(2);
  String pageValue = connectAndRead(); //connect to the server and read the output
  Serial.println(pageValue); //print out the findings.
  ChipSelect(1);
  writeSd(pageValue);
  readSd();
  ChipSelect(0);
}
void readSd(){
  //const char path=(const char)fileName;
  if (!myFile.open(fileName, O_READ)) {
    sd.errorHalt("file read error");
  }
  Serial.println(fileName);
  // read from the file until there's nothing else in it:
  char data;
  int c=0;
  while ((data = myFile.read()) >= 0) {
    data=char(data);
    Serial.print(data);
    //Serial.println(c);
    c++;
  }
  // close the file:
  myFile.close();
}

void writeSd(String storeData){
  // open the file for write at end like the Native SD library
  if (!myFile.open(fileName, O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening database.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to database.txt...");
  myFile.println(storeData);

  // close the file:
  myFile.close();
  Serial.println("done.");
}

String connectAndRead(){
   ///////// Pin 10,11,12,13 are used as SPI Bus of the ethernet Shield
/// MOSI-         pin 11
/// MISO-         pin 12
/// CLK-          pin 13
/// CS for sdCard-pin 4
/// ss-           pin 10
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.
        //digitalWrite(Sd_ss_pin,HIGH); //SD is not active

 /*       USE THIS CODE FOR PROXY SERVER IN BRAC UNIVERSITY
        // if you get a connection, report back via serial:
  if (client.connect("192.168.1.5", 8080)) {  // This is connecting to the proxy
    Serial.println("connected");
    // Make a HTTP request through proxy:
    client.println("GET rfid.unisec-bd.org/getData.php HTTP/1.0");
    client.println();
  }
*/
  //connect to the server
  Serial.println("connecting...");
  while(!client){;}
  //port 80 is typical of a www page
  if (client.connect("rfid.unisec-bd.org", 80)) {
    Serial.println("connected");
    client.print("GET ");
    client.println(location);
    client.println("Host: rfid.unisec-bd.org"); // SERVER ADDRESS HERE TOO
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println();
    //Connected - Read the page
    return readPage(); //go and read the output
  }else{
    return "connection failed";
  }
}

String readPage(){
  //read the page, and capture & return everything between '<' and '>'
  stringPos = 0;
  memset( &inString, 0, 3200 ); //clear inString memory
  while(true){
    if (client.available()) {
      char c = client.read();
      if (c == '!' ) { //'!' is our begining character
        startRead = true; //Ready to start reading the part
      }else if(startRead){
        if(c != '@'){ //'@' is our ending character
          inString[stringPos] = c;
          stringPos ++;
        }else{
          //got what we need here! We can disconnect now
          startRead = false;
          client.stop();
          client.flush();
          Serial.println("disconnecting.");
          return inString;
        }
      }
    }
  }
}
void ChipSelect(int s){
  if(s=0){                              //Both Device is off
    //digitalWrite(53,HIGH);
    digitalWrite(10,HIGH);
    digitalWrite(4,HIGH);
  }else if(s=1){                        //Only SD is active
    //digitalWrite(53,HIGH);
    digitalWrite(10,HIGH);
    digitalWrite(4,LOW);
  }else if(s=2){                        //Only Ethernet is Active
    //digitalWrite(53,HIGH);
    digitalWrite(10,LOW);
    digitalWrite(4,HIGH);
  }
  Serial.print("Ethernet SS:");
  Serial.println(digitalRead(10));
  Serial.print("SD SS:");
  Serial.println(digitalRead(4));
}

```

# Answer
> -1 votes
You have to switch off and then on pin 2 (connected to Vcc on SD reader) using `digitalWrite`

```
https://stackoverflow.com/questions/41277010/how-to-connect-rc522-rfid-module-and-sd-card-adapter-to-one-arduino-board/46797716#46797716

`//HEADER FILES##################################
#include <SPI.h>
#include <MFRC522.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <SD.h>
//ARDUINO MEGA
//MISO 50
//MOSI 51
//SCK 52
//ON/OFF SD CARD READER 2
//SD Card DEfinitions###########################
File root;
const int chipSelect = 4;
const int chipONOFF = 2;
//RF_ID Definitions#############################
#define SS_PIN 7
#define RST_PIN 6
MFRC522 mfrc522(SS_PIN, RST_PIN);

void setup()
{
Serial.begin(9600);
SPI.begin();
pinMode(chipONOFF,OUTPUT);
digitalWrite(chipONOFF, LOW);
tc_03_rfIDbasicTest();
digitalWrite(chipONOFF, HIGH);
tc_02_SDcardConnectTest();
digitalWrite(chipONOFF, LOW);
tc_03_rfIDbasicTest();
}

void loop()
{ }

void tc_02_SDcardConnectTest()
{
Serial.println("");
Serial.println("");
Serial.println("-----TEST 2: FUNCIONAMIENTO BASICO DE SD-----");
Serial.println("");
if (!SD.begin(chipSelect))
{
Serial.println("Falla en comunicacion, asegurate que la uSD esté insertada e intenta de nuevo");
Serial.println("FAIL");
}
else
{
Serial.println("Tarjeta uSD Detectada");
Serial.println("PASS");
root = SD.open("/");
printDirectory(root, 0);
}
}

int tc_03_rfIDbasicTest()
{
Serial.println("-----TEST 3: FUNCIONAMIENTO BASICO DE RFid-----");
mfrc522.PCD_Init(); // Init MFRC522 chip again per each write attemp
mfrc522.PCD_DumpVersionToSerial(); // Show details of PCD - MFRC522 Card Reader details

if ( ! mfrc522.PICC_IsNewCardPresent())
    Serial.println("Targeta fuera de alcance");
else
    Serial.println("Targeta dentro de alcance");
if ( ! mfrc522.PICC_ReadCardSerial())
    Serial.println("Falla en lectura de tarjeta");
else
{
    Serial.println("RFid OK :) !");
    Serial.println("PASS");
    String nuid="";
    for (byte i = 0; i < 4; i++)
        nuid+=mfrc522.uid.uidByte[i];
    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
    Serial.println(nuid);
}
}

void printDirectory(File dir, int numTabs)
{
while (true)
{
File entry = dir.openNextFile();
if (! entry)
break;
for (uint8_t i = 0; i < numTabs; i++)
{
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory())
{
Serial.println("/");
printDirectory(entry, numTabs + 1);
}
else
{
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}`

```

and this what you get on serial monitor.

```
`-----TEST 3: FUNCIONAMIENTO BASICO DE RFid-----
Firmware Version: 0x92 = v2.0
Targeta dentro de alcance
RFid OK :) !
PASS
215103959

-----TEST 2: FUNCIONAMIENTO BASICO DE SD-----

Tarjeta uSD Detectada
PASS
BIO/
D70A273B.DB 44
ENROLADO.DB 57
F683B22D.DB 40
A6DE1E49.DB 38
080732DC.DB 38
08D1EF01.DB 38
08267788.DB 38
XWIFI.DB    47
CP0101.DB   26
XFEC.DB 4
CP0102.DB   26
CP0201.DB   26
SYSTEM1/
WPSETT1.DAT 12
INDEXE~1    76
CP0301.DB   26
GP01.DB 33
GP02.DB 33
GP03.DB 33
GP04.DB 32
GP05.DB 32
GS06.DB 35
GS07.DB 37
GS08.DB 36
GS09.DB 36
GS10.DB 36
GE03.DB 24
GE02.DB 20
GE01.DB 23
GS11.DB 38
AP010101.DB 69
AP010102.DB 83

-----TEST 3: FUNCIONAMIENTO BASICO DE RFid-----
Firmware Version: 0x92 = v2.0
Targeta dentro de alcance
RFid OK :) !
PASS
215103959`

```

---
Tags: arduino-mega, ethernet, sd-card, spi
---


title: How to leak function addresses?

text:
# Question
Title: How to leak function addresses?
I'm doing some security research on FreeRTOS embedded systems and I don't have much information about Arduino. Is there any way to leak function or variable addresses on serial console? I can use `avr-nm` and `avr-objdump` but, I may need it for dynamically allocated memory.

It gives:

```
call of overloaded 'println(void (*)(void*))' is ambiguous

```

When I try to pass function pointers to serial console.

UPDATE: With using (unsigned char) I can leak something and it is 68 in serial console my code below. I have

```
000004d0 l     F .text  000000e0 _Z9TaskBlinkPv

```

from symbols if it is related with TaskBlink.

```
#include <Arduino_FreeRTOS.h>

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *)"Blink"   // A name just for humans
    ,  128  // Stack size
    ,  NULL
    ,  2  // priority
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  (const portCHAR *) "AnalogRead"
    ,  128 // This stack size can be checked & adjusted by reading Highwater
    ,  NULL
    ,  1  // priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
  Serial.println((unsigned char) &TaskBlink,HEX);
  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
  }
}

void TaskAnalogRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  for (;;)
  {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);
    // print out the value you read:
    //Serial.println(sensorValue);
    vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
  }
}

```

UPDATE 2: When I'm using (unsigned int) it is giving 268 and dissassembling 268 gives:

```
     262:       9b 8d           ldd     r25, Y+27       ; 0x1b
     264:       8c 8d           ldd     r24, Y+28       ; 0x1c
     266:       98 13           cpse    r25, r24
     268:       05 c0           rjmp    .+10            ; 0x274 <_ZN14HardwareSerial5writeEh+0x24>
     26a:       e8 89           ldd     r30, Y+16       ; 0x10
     26c:       f9 89           ldd     r31, Y+17       ; 0x11
     26e:       80 81           ld      r24, Z
     270:       85 fd           sbrc    r24, 5
     272:       24 c0           rjmp    .+72            ; 0x2bc <_ZN14HardwareSerial5writeEh+0x6c>
     274:       f6 2e           mov     r15, r22

```

It is not my function nor a tramboline. It is at:

```
000004d0 <_Z9TaskBlinkPv>:
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
     4d0:       cf 93           push    r28
     4d2:       df 93           push    r29
     4d4:       cd b7           in      r28, 0x3d       ; 61
     4d6:       de b7           in      r29, 0x3e       ; 62
     4d8:       a1 97           sbiw    r28, 0x21       ; 33
     4da:       0f b6           in      r0, 0x3f        ; 63
     4dc:       f8 94           cli
     4de:       de bf           out     0x3e, r29       ; 62
     4e0:       0f be           out     0x3f, r0        ; 63
     4e2:       cd bf           out     0x3d, r28       ; 61

```

What am I doing wrong?

# Answer
> 2 votes
The error you have is exactly a factor 2: Your `Serial.print()` gave 0x0268, whereas `TaskBlink(void *)` is at address 0x04d0, which is twice 0x0268. Both addresses are correct: it all depends on what you mean by “address”.

Functions live in the microcontroller's flash. At the hardware level, and for the purpose of fetching instructions, the flash is addresses by 16-bit words. This means that address 1 is one word (two bytes) past address 0. Note that for fetching constant “PROGMEM” data, the `lpm` instruction addresses the flash byte-wise. This may seem inconsistent, but it's the way the hardware is designed. Function pointers are addresses intended to be put into the program counter by means of the `icall` (indirect call) instruction. This instruction expects a word-wise address, thus function pointers are word-wise addresses.

For some reason – presumably for consistency with other platforms – the authors of the GNU binutils package chose to always use byte-wise addresses. When `avr-nm` and `avr-objdump` tell you that `TaskBlink(void *)` is at address 0x04d0, they mean it starts 0x04d0 *bytes* after the start of the flash. When `Serial.print()` tells you it's at 0x0268, it means the address used at the hardware level is 0x0268, and that's because the function starts 0x0268 *words* after the start of the flash.

# Answer
> 1 votes
What you need is

```
  Serial.println((unsigned int) &TaskBlink, HEX);

```

The operator "&" gives you an address. In Arduino (ATMega MCU), that is a 16 bit value, that fits inside an unsigned int.

The cast operator "`(unsigned int)`" means "I will use that value as an `unsigned int`".

Serial knows how to print numerical values (but not funtion addresses).

---
Tags: serial, memory
---


# Question
Title: How does Arduino digital input pin measure its input voltage?
Just starting with my first Arduino project. In order to measure voltage in a circuit I connected my multimeter to two points in the circuit (for example before and after a resistor).

I am interested to know how an input pin can measure its voltage (for example 5v or 0v).

# Answer
Assuming you are asking about digital input pins on an Arduino:

Digital logic operates at the saturation and cut off regions of the transistor logic used. Most modern day processors use CMOS transistors. The logic levels are Low: 0 V to 1/3 VDD and High:2/3 VDD where VDD is the supply voltage. This information can be found here.

So, if your processor is designed to operate at 5 volts and is likely made of CMOS logic gates, the low level voltage is from 0 to 1.67 volts and the high level voltage is from 3.33 to 5 volts.

But to address your question specifically: Digital input pins do not measure the voltage. Not like an ADC input. Instead, it is agreed that nothing operating normally that is to interface with a digital pin will produce (linger at) a voltage other than those designed to force the transistors into cut-off or saturation.

So do be careful not to do this. It could result in unexpected behavior.

Now, if you can not avoid voltage between the designated upper limit of the low logic signal and the lower limit of the high logic signal you man need to buffer your signal with a device called a Schmitt Trigger. This device adds hysteresis to your signal and converts it into either a low or high logic state. Examples of hysteresis include the thermostat control for your furnace.

A final word, do not exceed the voltage at a digital input to that which is supplied at the power pin of that digital circuit. This can cause all kinds of problems. Usually this is not a problem as most devices / projects are powered off of one power source. But in case multiple power supplies are used, keep this in mind.
> 3 votes

# Answer
The implementation of the digital inputs may depend on what kind of microcontroller you are using. On AVR microcontrollers (most common Arduinos are AVR-based), the inputs go through Schmitt triggers. This means that the voltage seen by the logic downstream is always a valid logic level. You should then not worry about an invalid input causing “unexpected behavior”.

It should be noted, though, that the characteristics of the Schmitt trigger are very loosely specified. If I take the ATmega328P at Vcc = 5 V as an example (the MCU powering the Arduino Uno), the thresholds are expected to be “typically” around 2.1 V (for the HIGH → LOW transition) and 2.6 V (LOW → HIGH). But these are only typical values. The only thing that is really specified is that the input reads LOW when the pin voltage is below 0.3 Vcc and it reads HIGH above 0.6 Vcc. At 5 V this means that the thresholds could be anywhere between 1.5 V and 3 V).
> 1 votes

---
Tags: voltage
---


# Question
Title: State Machine Logic problem with added states monitoring safety switches
I have been working on getting a state machine to work correctly but am having trouble with adding in the last bit of logic. What it needs to do is several things:

* Read two button inputs.
* Make sure they are pressed and held within a certain amount of time of each other as defined by "PushTimeWindow" and if not wait til both are released.
* Wait for a certain period as defined by "PushSafetyWindow".
* Turn on a relay for an amount of time as specified by "RelayOnTime".
* After the relay is off wait for both buttons to be released before they can be read again.
* If at any time one or both released turn off the relay and wait for both to be released to be pushed again.
* Count the number of successful relay periods and display them

Almost everything is doing what I had hoped it would do with the exception that I can't get the program to only allow the two switches to be pushed within a certain time frame as defined by the PushTimeWindow. Either button one needs to be pushed and held and then the second button pressed within the specified time. This window of time is intended to only allow the relay to be turned on if both buttons have been pushed within the set time. I have two states that I am trying to use to handle it but it seems to ignore them. Cases ONE\_PUSHED and PUSHED\_WINDOW are intended to handle this and seem to be ignored by the program. These two were added to handle that additional logic but otherwise the rest of the program works great and handles the other functions fine. I can't figure out what I am doing wrong with that logic. This is an added function to a previous question answered by user Jot here. I suspect that the two new cases might be redundant and true no matter what and that is why they seem to be ignored, or is it that they are never called on to be tested as true or not?

The sketch uses the Bounce2 library to debounce the noisy switches and each button has pull down resistors and otherwise works well.

Here is the sketch *(Updated 10/17/17)*:

```
// A state machine is used, only to make it more clear what is going on.
//
// When a button is pressed, the input turns HIGH.
//
// Normally only one 'enum' is used for the state, that controls the code.
// This sketch has also a 'enum' for the buttons, which is called the input state.
// define the different states for this sketch.
// An 'enum' is like a number of #define with increasing numbers.

// include the library code:
#include <Bounce2.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

enum
{
  WAIT_FOR_BOTH_OFF,
  WAIT_FOR_BOTH_ON,
  ONE_PUSHED,
  PUSHED_WINDOW,
  SAFETY_WINDOW,
  RELAY_ON,
} state;       // an 'enum' is automatically an integer.

// define the different input states.
enum
{
  BOTH_OFF,        // no buttons are pressed.
  BOTH_ON,         // both buttons are pressed.
  SOMETHING_ELSE,  // probably one of the buttons is pressed.
};

const int ButtonPin1 = 2;
const int ButtonPin2 = 3;
const int RelayPin = 5;

// The previousMillis is used twice for two different things.
// That is okay in this state machine.
unsigned long previousMillis;

const unsigned long RelayOnTime = 1750;    // Length of time for relay
const unsigned long PushTimeWindow = 300; // Length of time to allow two pushes
const unsigned long PushSafetyWindow = 50; // Safety Delay after push

// Counters for the number of failed relay triggers and successful cycles.
// They can probably be normal integers as well.
unsigned long failed = 0;
unsigned long success = 0;

Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();

void setup()
{
  lcd.begin(16, 2);
  lcd.print("Press Count");
  Serial.begin(9600);
  Serial.println("Unit Online");

// Set up first button
  pinMode(ButtonPin1, INPUT);
  debouncer1.attach(ButtonPin1);
  debouncer1.interval(5); //Debounce time

// Set up second button
  pinMode(ButtonPin2, INPUT);
  debouncer2.attach(ButtonPin2);
  debouncer2.interval(5); //Debounce time

  pinMode(RelayPin, OUTPUT);  // OUTPUT to Relay

  Serial.println("Going to WAIT_FOR_BOTH_OFF state");
  state = WAIT_FOR_BOTH_OFF;
}

void loop()
{

  unsigned long currentMillis = millis();

// Update the bounce instances
  debouncer1.update();
  debouncer2.update();

  int inputState = getInputState();

  // Process the data in a state machine.
  // The output part is also in the state machine.
  switch(state)
  {
    case WAIT_FOR_BOTH_OFF:
      // Both buttons must be released to be able to continue.
      if(inputState == BOTH_OFF)
      {
        // Prepare to go to the next state.
        Serial.println("Going to WAIT_FOR_BOTH_ON state");
        state = WAIT_FOR_BOTH_ON;
      }
      break;
   case ONE_PUSHED:
      //One button is pushed
      if(inputState == SOMETHING_ELSE)
      {
        //One button was pushed
        Serial.println("One button Pushed");
        previousMillis = currentMillis;
        state = PUSHED_WINDOW;
      }
      break;
    case WAIT_FOR_BOTH_ON:
      // This is the state when everything is idle and no buttons are pressed.
      // Normally both buttons are released,
      // but when both are pressed, then go to the next state.
      if(inputState == BOTH_ON)
      {
        // Prepare to go to the next state.
        Serial.println("Going to SAFETY_WINDOW state");
        previousMillis = currentMillis;
        state = SAFETY_WINDOW;
      }
      break;

    //Check to see if the other button is pushed, if not wait for both off
    case PUSHED_WINDOW:
      if(currentMillis - previousMillis >= PushTimeWindow)
      {
        Serial.println("Going to WAIT_FOR_BOTH_ON state 2");
        state = WAIT_FOR_BOTH_OFF;
        previousMillis = currentMillis;
      }
      //If window to push has expired go to WAIT_FOR_BOTH_OFF state
      else if(inputState == BOTH_ON)
      {
        Serial.println("Going to SAFETY_WINDOW 2");
        state = SAFETY_WINDOW;
      }
    case SAFETY_WINDOW:
      if(inputState != BOTH_ON)
      {
        // During the safety time window, a button was released.
        // Return to idle.
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        state = WAIT_FOR_BOTH_OFF;
      }
      else if(currentMillis - previousMillis >= PushSafetyWindow)
      {
        // The buttons are still pressed.
        // The time window has reached the end.
        // Prepare to go to the next state.
        Serial.println("Going to RELAY_ON state");
        previousMillis = currentMillis;
        digitalWrite(RelayPin, HIGH);  // Turn ON RelayPin
        state = RELAY_ON;
      }
      break;
    case RELAY_ON:
      if(inputState != BOTH_ON)
      {
        // One of the buttons was released.
        // Stop the relay and return to idle.
        // Although the relay was triggered, it was not succesful.
        failed++;
        Serial.print("Failed=");
        Serial.println(failed);
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        digitalWrite( RelayPin, LOW);  // Turn Off RelayPin
        state = WAIT_FOR_BOTH_OFF;
      }
      else if(currentMillis - previousMillis >= RelayOnTime)
      {
        // Everyting was okay.
        // The buttons are still pressed.
        // It was complete and succesful.
        // It is time to turn off the relay and return to idle.
        success++;
        Serial.print("Success=");
        Serial.println(success);
        Serial.println("Going to WAIT_FOR_BOTH_OFF state");
        lcd.setCursor(0,1);
        lcd.print(success);
        digitalWrite(RelayPin, LOW);  // Turn Off RelayPin
        state = WAIT_FOR_BOTH_OFF;
      }
      break;
    default:
      Serial.println("Error, unknown state");
      break;
  }
}

// This function returns the input state.
// There is no StateChangeDetection, because a state machine is used.
int getInputState()
{
  int returnInputState;

  // Read the debounce state and create a input state according to the 'enum' values.
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();

  if(value1 == LOW && value2 == LOW)
  {
    returnInputState = BOTH_OFF;
  }
  else if(value1 == HIGH && value2 == HIGH)
  {
    returnInputState = BOTH_ON;
  }
  else
  {
    // Not both on, not both off, so it must be something else.
    returnInputState = SOMETHING_ELSE;
  }

  return(returnInputState);
}

```

The part of the sketch that doesn't seem to run are these two cases that should be called when one button is pressed:

```
case ONE_PUSHED:
      //One button is pushed
      if(inputState == SOMETHING_ELSE)
      {
        //One button was pushed
        Serial.println("One button Pushed");
        previousMillis = currentMillis;
        state = PUSHED_WINDOW;
      }
      break;

```

The sketch should then run the case PUSHED\_WINDOW to check if the inputState goes to BOTH\_ON within the window defined in PushTimeWindow. If that time has been exceeded the sketch should then wait until both buttons are released again and then wait for another try.

```
case PUSHED_WINDOW:
      if(currentMillis - previousMillis >= PushTimeWindow)
      {
        Serial.println("Going to WAIT_FOR_BOTH_ON state 2");
        state = WAIT_FOR_BOTH_OFF;
        previousMillis = currentMillis;
      }
      //If window to push has expired go to WAIT_FOR_BOTH_OFF state
      else if(inputState == BOTH_ON)
      {
        Serial.println("Going to SAFETY_WINDOW 2");
        state = SAFETY_WINDOW;
      }

```

Unfortunately the sketch never seems to run either of the cases which is where I am having trouble debugging.

The sketch will run on an Arduino Nano with an ATmega328P programmed with Arduino 1.8.5. The two input buttons are Rees mushroom head momentary industrial switches that are software debounced and have smoothing capacitors to hardware debounce as well. Inputs have 1K pull down resistors and the system is powered by a 9V power supply. The output to the relay pin drives the base of a NPN TIP31C transistor that powers the input of a relay with 9V. The relay has a capacitor with a resistor across it on its input to smooth out back spikes that occur when the relay triggers. The hardware all seems to be working fine and as intended.

*Edit 10/20/2017* The solution to the question is included in the below code. The problem was with the state machine seeming to skip the window required to press the button. Some of the enum names were also changed as per suggested but if possible will be renamed again if better names come to me to be more clear what they are to do.

*Edit 10/23/2017* Tried to name everything as clearly as possible and include documentation as to source and function of sketch.

Here is the final sketch:

```
// This sketch reads inputs from two buttons to turn on a relay
// It requires that both buttons be pressed within a certain time of each other and held
// A relay pin is then turned on for a specified period of time
// Both buttons must then be released again for another cycle to begin
// A state machine is used, only to make it more clear what is going on.
// Used with an Arduino Nano board on Arduino 1.8.5
// Found on https://arduino.stackexchange.com/questions/45584/state-machine-logic-problem-with-added-states-monitoring-safety-switches/
// Uses the Bounce2 library: https://github.com/thomasfredericks/Bounce2
//
// When a button is pressed, the input turns HIGH.
//
// Normally only one 'enum' is used for the state, that controls the code.
// This sketch has also a 'enum' for the buttons, which is called the input state.
// define the different states for this sketch.
// An 'enum' is like a number of #define with increasing numbers.

// include the library code:
#include <Bounce2.h>
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

enum
{
  WAIT_FOR_BOTH_LOW,
  WAIT_FOR_BUTTON,
  ONE_PUSHED_WAIT_FOR_OTHER_BUTTON,
  SAFETY_WINDOW,
  RELAY_ON,
} state;       // an 'enum' is automatically an integer.

// define the different input states.
enum
{
  BOTH_BUTTONS_LOW,      // no buttons are pressed.
  BOTH_BUTTONS_HIGH,     // both buttons are pressed.
  ONE_BUTTON_HIGH,       // probably one of the buttons is pressed.
};

const int ButtonPin1 = 2;
const int ButtonPin2 = 3;
const int RelayPin = 5;
const int IndicatorPin = 4;

// The 'previousMillis' is exclusively for the state machine portion only.
// It is used for different software timers in different states.
// That is okay, because within the state machine the states are seperated from each other.
// Funtions outside the state machine would require a separate timer.
unsigned long previousMillis;

const unsigned long RelayOnTime = 1750;    // Length of time for relay
const unsigned long TimeFrameForSecondButton = 300; // Length of time to allow two pushes
const unsigned long PushSafetyWindow = 50; // Safety Delay after push

// Counters for the number of failed relay triggers and successful cycles.
// They can probably be normal integers as well.
unsigned long failed = 0;
unsigned long success = 0;

// Instantiate Bounce objects
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();

void setup()
{
  lcd.begin(16, 2);
  lcd.print("Press Count");
  Serial.begin(9600);
  Serial.println("Unit Online");

// Set up first button
  pinMode(ButtonPin1, INPUT);
  debouncer1.attach(ButtonPin1);
  debouncer1.interval(5); //Debounce time

// Set up second button
  pinMode(ButtonPin2, INPUT);
  debouncer2.attach(ButtonPin2);
  debouncer2.interval(15); //Debounce time

  pinMode(RelayPin, OUTPUT);  // OUTPUT to Relay
  pinMode(IndicatorPin, OUTPUT); // OUTPUT to Indicator LED
  Serial.println("Going to WAIT_FOR_BOTH_LOW state");
  state = WAIT_FOR_BOTH_LOW;
}

void loop()
{

  unsigned long currentMillis = millis();

// Update the Bounce instances
  debouncer1.update();
  debouncer2.update();

  int inputState = getInputState();

// Process the data in a state machine.
// The output part is also in the state machine.
  switch(state)
  {
    case WAIT_FOR_BOTH_LOW:
      // Both buttons must be released to be able to continue.
      if(inputState == BOTH_BUTTONS_LOW)
      {
        // Prepare to go to the next state.
        Serial.println("Going to WAIT_FOR_BUTTON state");
        state = WAIT_FOR_BUTTON;
      }
      break;
    case WAIT_FOR_BUTTON:
// This is the state when everything is idle and no buttons are pressed.
// Normally both buttons are released.
// Waiting for the first button to be pressed.
// Both buttons could be pressed at the same time !
      if(inputState == ONE_BUTTON_HIGH || inputState == BOTH_BUTTONS_HIGH)
      {
// At least one button is pressed.
// Prepare to go to the next state.
// Start a timer, because there is a timeout.
        Serial.println("Going to ONE_PUSHED_WAIT_FOR_OTHER_BUTTON state");
        previousMillis = currentMillis;
        state = ONE_PUSHED_WAIT_FOR_OTHER_BUTTON;
       }
      break;
    case ONE_PUSHED_WAIT_FOR_OTHER_BUTTON:
      if(inputState == BOTH_BUTTONS_LOW)
      {
// The button was released. That's not what we want.
// Return to the state to wait for both off.
        Serial.println("Going to WAIT_FOR_BOTH_LOW state");
        state = WAIT_FOR_BOTH_LOW;
      }
      else if(currentMillis - previousMillis >= TimeFrameForSecondButton)
      {
// The timeout has ended.
// The second button was not pushed after the first button
// within the timeout. That's too bad.
        Serial.println("Too Long Going to WAIT_FOR_BOTH_LOW state");
        state = WAIT_FOR_BOTH_LOW;
      }
      else if(inputState == BOTH_BUTTONS_HIGH)
      {
// The timeout has not ended and is still running.
// And now both buttons are pressed.
// We can continue.
// Start the timer for the SAFETY_WINDOW state.
        Serial.println("Going to SAFETY_WINDOW state");
        previousMillis = currentMillis;
        state = SAFETY_WINDOW;
      }
      break;
    case SAFETY_WINDOW:
      if(inputState != BOTH_BUTTONS_HIGH)
      {
// During the safety time window, a button was released.
// Return to idle.
        Serial.println("Going to WAIT_FOR_BOTH_LOW state");
        state = WAIT_FOR_BOTH_LOW;
      }
      else if(currentMillis - previousMillis >= PushSafetyWindow)
      {
// The buttons are still pressed.
// The time window has reached the end.
// Prepare to go to the next state.
        Serial.println("Going to RELAY_ON state");
        previousMillis = currentMillis;
        digitalWrite(RelayPin, HIGH);  // Turn ON RelayPin
        digitalWrite(IndicatorPin, HIGH); // Turn ON IndicatorPin
        state = RELAY_ON;
      }
      break;
    case RELAY_ON:
      if(inputState != BOTH_BUTTONS_HIGH)
      {
// One of the buttons was released.
// Stop the relay and return to idle.
// Although the relay was triggered, it was not succesful.
        failed++;
        Serial.print("Failed=");
        Serial.println(failed);
        Serial.println("Going to WAIT_FOR_BOTH_LOW state");
        digitalWrite( RelayPin, LOW);  // Turn Off RelayPin
        digitalWrite(IndicatorPin, LOW); // Turn Off IndicatorPin
        state = WAIT_FOR_BOTH_LOW;
      }
      else if(currentMillis - previousMillis >= RelayOnTime)
      {
        // Everyting was okay.
        // The buttons are still pressed.
        // It was complete and succesful.
        // It is time to turn off the relay and return to idle.
        success++;
        Serial.print("Success=");
        Serial.println(success);
        Serial.println("Going to WAIT_FOR_BOTH_LOW state");
        lcd.setCursor(0,1);
        lcd.print(success);
        digitalWrite(RelayPin, LOW);  // Turn Off RelayPin
        digitalWrite(IndicatorPin, LOW); // Turn Off IndicatorPin
        state = WAIT_FOR_BOTH_LOW;
      }
      break;
    default:
        Serial.println("Error, unknown state");
      break;
    }
}

// This function returns the input state.
// There is no StateChangeDetection, because a state machine is used.
  int getInputState()
{
  int returnInputState;

// Read the debounce state and create a input state according to the 'enum' values.
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();

    if(value1 == LOW && value2 == LOW)
    {
      returnInputState = BOTH_BUTTONS_LOW;
    }
    else if(value1 == HIGH && value2 == HIGH)
    {
      returnInputState = BOTH_BUTTONS_HIGH;
    }
    else
    {
    // Not both on, not both off, so it must be something else.
    returnInputState = ONE_BUTTON_HIGH;
    }

  return(returnInputState);
}

```

# Answer
**Intro**

You did not get any answers, because someone has to read the whole sketch and you have not explained which problem you want to solve with the two extra states and you did not fully explain what the extra states do.

I don't see a problem with my original example for the 'SAFETY\_WINDOW' state. As soon as one button is released, it bails out.
I can image that the state rushes through 'WAIT\_FOR\_BOTH\_OFF' and 'WAIT\_FOR\_BOTH\_ON' when there is a lot of noise. Slowing it down in the sketch or with Bounce2 is a good improvement.
I could have made a mistake that I don't see, but now it is up to you to investigate where the problem comes from.

**Software**

You already found Majenko about FSM. Good, I hope you have studied it.
Perhaps you should make a sketch, just for fun, with a simple state machine.

As you can see, the integer 'state' rules it all.
The large switch-case statement contains the seperate pieces of code for each state. The order of those pieces of code does not matter. The integer 'state' defines what will be executed.

You never set the variable 'state' to 'ONE\_PUSHED', therefor that piece of code will never be executed. However, please don't add that somewhere in the sketch. Explain why you want to detect if just one button is pushed.

Every piece of code of every state should make sense. I think that you have gone a little too far and the sketch is going haywire and is not going in a direction.

Is the problem that during the time that both buttons needs to be pressed (just before the relay turns on), the sketch thinks that both are pressed, even when one button is released ? Is that the problem ?

When that would be caused by a bug in the sketch, then the bug should be fixed. Trying to make a workaround around a bug is bad. If the workaround contains a bug itself, then fixing a bug with another bug is something you will never get out.

Please add a welcoming message to the display and the serial port. That way you can see if the Arduino was reset.

**The software thing to do**

There is a problem. Please describe it clearly. Then make the smallest possible test sketch to investigate that problem.
Perhaps a small sketch using the function "getInputState" and display it a number of times per second.

**Hardware**

The input impedance of an Arduino pin is very high. It could be a few hundred MegaOhms. That means if one pin is connected to something, and the pin next to it is open (not connected), then the open pin might read the same signal as its neighbour pin, just by sensing the nearby voltage through the air.

Can you make a photo of that button ?
Is there a spring inside the button ?
How long are the wires or cables to the Arduino ?
Are there other cables alongside that cable ?
Are there electrical devices nearby that could cause spikes ?
How is the button and the pullup/pulldown resistor connected ? Can you show it in a diagram ? You can even make a drawing and make a photo of that.
Are you sure it is like that, can you verify that ?
Verify it once more with a multimeter. Measure the Arduino pin with the button(s) pressed and released. Is the really going HIGH when the corresponding button is pressed ?
Can you try to connect the buttons to other pins of the Arduino board ? Perhaps an input is blown.
Is the GND of the Arduino connected to a computer, and the computer to earth ground ?
Are the wires to the buttons somehow connected to some kind of ground ?
Or to a metal enclosure or something like that ?
Is there another ground problem ?
Do you use a good and certified power supply for the Arduino ? I hope not a very cheap power supply that is leaking the mains voltage to the output.
I forgot which Arduino board you use. Which Arduino board and which Arduino IDE version do you use ?

**Common mistakes**

There are a number of common mistakes. I think you made a few of them. If you can recognize them, perhaps you can avoid them.

* The famous XY-problem: xyproblem.info.
This happens a lot. Someone is too focussed to fix a problem, and wandering away from the original problem.
* Trying to get a result right now.
No experienced software designer does that. Investigate the problem by excluding the rest. Make small tests.
* Make a good description/explanation.
If it is an art or a skill, describing something in a logical way is very important. It can be half the work.
* Ground problems.
Ground problems is a major problem. When everything is connected okay, the ground could be connected in the wrong place. This is a tough subject.
* Never trust your tools.
Once someone knows how to make something work, but there is a bug somewhere that is impossible to find, then perhaps there is no bug. It can be a broken Arduino board, or other bad hardware or a bug in the Arduino software. It happens.

**ADDED**

I understand now that both buttons should be pushed within a certain time. That is the third millis timer that will be needed. I have a problem with the names that you choose for this new situation. I hope you don't mind that I made my own names. You had most of the conditions and the timeout, but bailing out as soon as the one button was released was missing.
The possibility that both buttons are pressed at the same time should also be accepted.

I did test my previous sketch, but I did not test this code. I had to draw a time diagram on a piece of paper to see the sequence of the states. I suggest you do the same.
The states are still in sequential order, there is no need for a parallel path in the state machine, or wildly jumping to all kind of states. Everything flows in a logic way from one state to the next in a sequential way.

My diagram on my piece of paper tells me that the "WAIT\_FOR\_BOTH\_ON" has to be replaced by two other states. It needs other conditions and it should get a timeout. Let's call the new states "WAIT\_FOR\_BUTTON" and "ONE\_PUSHED\_WAIT\_FOR\_OTHER\_BUTTON".

You might give this next constant a better name (it is the time frame in which the second button has to be pushed after the first one is pushed):

```
const unsigned long TimeFrameForSecondButton = 200;

```

Waiting for both off is still the same. The next state is changed into "WAIT\_FOR\_BUTTON".

```
case WAIT_FOR_BOTH_OFF:
  // Both buttons must be released to be able to continue.
  if(inputState == BOTH_OFF)
  {
    // Prepare to go to the next state.
    Serial.println("Going to WAIT_FOR_BUTTON state");
    state = WAIT_FOR_BUTTON;
  }
  break;

```

Then wait for a button (just one or perhaps two at the same time).

```
case WAIT_FOR_BUTTON:
  // This is the state when everything is idle and no buttons are pressed.
  // Normally both buttons are released.
  // Waiting for the first button to be pressed.
  // Both buttons could be pressed at the same time !
  if(inputState == SOMETHING_ELSE || inputState == BOTH_ON)
  {
    // At least one button is pressed.
    // Prepare to go to the next state.
    // Start a timer, because there is a timeout.
    Serial.println("Going to ONE_PUSHED_WAIT_FOR_OTHER_BUTTON state");
    previousMillis = currentMillis;
    state = ONE_PUSHED_WAIT_FOR_OTHER_BUTTON;
  }
  break;

```

While waiting for the second button, if anything is wrong then return to the state to wait for both off.

```
case ONE_PUSHED_WAIT_FOR_OTHER_BUTTON:
  if(inputState == BOTH_OFF)
  {
    // The button was released. That's not what we want.
    // Return to the state to wait for both off.
    Serial.println("Going to WAIT_FOR_BOTH_OFF state");
    state = WAIT_FOR_BOTH_OFF;
  }
  else if(currentMillis - previousMillis >= TimeFrameForSecondButton)
  {
    // The timeout has ended.
    // The second button was not pushed after the first button
    // within the timeout. That's too bad.
    Serial.println("Going to WAIT_FOR_BOTH_OFF state");
    state = WAIT_FOR_BOTH_OFF;
  }
  else if(inputState == BOTH_ON)
  {
    // The timeout has not ended and is still running.
    // And now both buttons are pressed.
    // Hurray, we can continue.
    // Start the timer for the SAFETY_WINDOW state.
    Serial.println("Going to SAFETY_WINDOW state");
    previousMillis = currentMillis;
    state = SAFETY_WINDOW;
  }
  break;

```

Can you merge this in the code ? And remove the things that are not used ?

I'm still unhappy with the names of the variables and states and so. When you look at it a year later, you must know what is going on. Can you give that a thought, it does not matter if the names are very long.

**Reaction to 10/20/2017**

Awesome!
A medium-complex problem solved in a straightforward logical way without using delay.

A few tips:

The header should explain what it is; the date; which Arduino board; which Arduino IDE version; a link to this stackexange.com page and so on.

Your indents are not always the same. Can you get all the "case" blocks like the others ?

Normally, using three timers with millis() requires three 'previousMillis' variables. The 'previousMillis' is used three times. That needs some extra explanation:

```
// The 'previousMillis' is exclusively for the state machine only.
// It is used for different software timers in different states.
// That is okay, because the states are seperated from each other.
unsigned long previousMillis;

```

Now that I think of it, the state machine does not rule the sketch, it processes the buttons.
If you would add a buzzer, and it would need a timeout to turn off, then that timeout must be done outside the state machine. That timeout should also get it's own variable, for example: previousBuzzerMillis.

What about the names for the input states. Is "BOTH\_BUTTONS\_ON", "BOTH\_BUTTONS\_OFF, "JUST\_ONE\_BUTTON" better ? Or "BOTH\_BUTTONS\_PUSHED", "BOTH\_BUTTONS\_RELEASED", "ONLY\_ONE\_BUTTON" ?

I can't think of better names for other variables at the moment. Even the name "SAFETY\_WINDOW" seems obvious.

**Correction nov 3, 2017**
I just learned that 'enum' is **not** automatically an integer. An 'enum' is its own type.
> 1 votes

# Answer
It looks like you are correct that the ONE\_PUSHED and PUSHED\_WINDOW branches are being ignored, because you never set the state to ONE\_PUSHED.

I believe your just need to update the WAIT\_FOR\_BOTH\_OFF state:

```
  case WAIT_FOR_BOTH_OFF:
      // Both buttons must be released to be able to continue.
      if(inputState == BOTH_OFF)
      {
        // Prepare to go to the next state.
        Serial.println("Going to ONE_PUSHED state");
        state = ONE_PUSHED;
      }
      break;

```
> 0 votes

---
Tags: button, millis, debounce
---


# Question
Title: Can any Arduino Due pin be used for PWM?
Arduino Due has 54 pins. It says that it has 12 PWM pins. I know it uses a more powerful chip than other Arduinos.

Can the number of PWM be increased?

Can any of its pin be used for PWM?

# Answer
According to the manual:

"The Arduino Due supports analogWrite() on pins 2 through 13, plus pins DAC0 and DAC1. Unlike the PWM pins, DAC0 and DAC1 are Digital to Analog converters, and act as true analog outputs."

https://www.arduino.cc/en/Reference/AnalogWrite
> 2 votes

# Answer
You could do software pwm but the frequency will be several orders of magnitude less than the clock frequency.

The hardware pwm pins have a counter a register and a comparator where every tick it increments the counter, compares the value of the counter to the value in the register and setting the pin to the corresponding value.

If you need more analogue outputs then it's easier to use an external DAC module.
> 1 votes

---
Tags: pins, pwm
---


title: Help Improving Debouncing

text:
# Question
Title: Help Improving Debouncing
In short, I am attempting to debounce several buttons using something like a while loop instead of delays.

This code runs in a box with a series of buttons on it, if the correct sequence of buttons is pressed, then the arduino will run a flashing LED sequence and open a solenoid. There are two correct sequences, a "right" answer (Green LED), and a master code (Blue LED). Anything else results in the failed sequence (Red LED). The problem I am currently having is that my current debouncing system is very finicky, I would like to implement something allowing more flexibility for speed of button press etc.

The problem currently is I am relying on delay to debounce. If I delay long enough it becomes difficult to type the correct code in because the user has to know to wait a certain amount of time before pressing the next key. If I do not delay long enough my combination is regularly corrupted with extraneous button pushes.

Below is my code, The debouncing occurs on lines 128-160. Below that is a lot of LED flashing.

```
#define CPU_RESTART_ADDR (uint32_t *)0xE000ED0C
#define CPU_RESTART_VAL 0x5FA0004
#define CPU_RESTART (*CPU_RESTART_ADDR = CPU_RESTART_VAL);

const int button5 = 2;    //fifth  button is on pin 2
const int button4 = 3;    //fourth button is on pin 3
const int button3 = 4;    //third  button is on pin 4
const int button2 = 5;    //second button is on pin 5
const int button1 = 6;    //first  button is on pin 6
const int systemLED = 7;  //Red LED on front of Box (Power Indicator)
const int redLed1 = 8;    //red LED is on pin 7
const int greenLed1 = 9;  //green LED is on pin 8
const int blueLed1 = 10;   //blue LED is on pin 9
const int redLed2 = 11;   //red LED is on pin 10
const int greenLed2 = 12; //green LED is on pin 11
const int blueLed2 = 13;  //blue LED is on pin 12
const int solenoid = 14;  //activates solenoid Relay Circuit
const int relay2 = 15;     // >:-}

int code[] = {1,2,3,4,5}; //the desired code is entered in this array, separated by commas

int entered[5]; //create a new empty array for the code entered by the user (has 4 elements)

void setup(){ //run once at sketch startup
  Serial.begin(9600); //begin Serial
  pinMode(systemLED, OUTPUT);
  pinMode(button1, INPUT); //button 1 is an input
  pinMode(button2, INPUT); //button 2 is an input
  pinMode(button3, INPUT); //button 3 is an input
  pinMode(button4, INPUT); //button 4 is an input
  pinMode(button5, INPUT); //button 5 is an input
  pinMode(redLed1, OUTPUT); //the red LED is an output
  pinMode(redLed2, OUTPUT); //the red LED is an output
  pinMode(greenLed1, OUTPUT); // the green LED is an output
  pinMode(greenLed2, OUTPUT); // the green LED is an output
  pinMode(blueLed1, OUTPUT);
  pinMode(blueLed2, OUTPUT);
  pinMode(relay2, INPUT_PULLUP); //enable relay outputs as input_pullup in order to prevent triggering when initial power is provided
  pinMode(solenoid, INPUT_PULLUP);

  delay(500);

  pinMode(relay2, OUTPUT);   //convert pinmode for relay back to operable mode
  pinMode(solenoid, OUTPUT);//this prevents the relay and relay2 from triggering at startup

  digitalWrite(relay2, HIGH);
  digitalWrite(solenoid, HIGH);

  digitalWrite(blueLed1, HIGH); //turn both
  digitalWrite(greenLed1, HIGH);
  digitalWrite(blueLed2, HIGH);
  digitalWrite(greenLed2, HIGH); //LEDs on
  delay(100); //wait
  digitalWrite(blueLed1, LOW); //turn both
  digitalWrite(greenLed1, LOW);
  digitalWrite(blueLed2, LOW);
  digitalWrite(greenLed2, LOW); //LEDs off
  digitalWrite(systemLED, HIGH); //turn the red LED on
  delay(75); //wait

  for (int i = 0; i < 5;i++){ //work through numbers 0-4
    Serial.println(code[i]); //print each digit of the code
    Serial.println(entered[i]); //print each element of the entered[] array (this was for me to check that it started at 0)
  }
}

void checkEntered1(int button /* define the 1,2,3 or 4 as an integer called button */){ //check the first element of the entered[] array
  if (entered[0] != 0){ //if it is not a zero, i.e. it has already been input
    checkEntered2(button); //move on to checkEntered2, passing it "button"
  }

  else if(entered[0] == 0){ //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[0] = button; //set the first element as the button that has been pressed
    Serial.print("1: ");Serial.println(entered[0]); //for debugging
  }
}

void checkEntered2(int button){ //check the second element of the entered[] array
  if (entered[1] != 0){ //if it is not a zero, i.e. it has already been input
    checkEntered3(button); //move on to checkEntered3, passing it "button"
  }

  else if(entered[1] == 0){ //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[1] = button; //set the second element as the button that has been pressed
    Serial.print("2: ");Serial.println(entered[1]); //for debugging
  }
}

void checkEntered3(int button){  //check the third element of the entered[] array
  if (entered[2] != 0){ //if it is not a zero, i.e. it has already been input
    checkEntered4(button); //move on to checkEntered4, passing it "button"
  }

  else if (entered[2] == 0){ //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[2] = button; //set the third element as the button that has been pressed
    Serial.print("3: ");Serial.println(entered[2]); //for debugging
  }
}

void checkEntered4(int button){ //check the fourth element of the entered[] array
  if (entered[3] != 0){ //if it is not a zero, i.e. it has already been input
    checkEntered5(button); //set the final element as the button that has been pressed
  }

  else if (entered[3] == 0){ //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[3] = button; //set the fourth element as the button that has been pressed
    Serial.print("4: ");Serial.println(entered[3]); //for debugging
  }
}

```

This is where I need help debouncing, as can be seen I have attempted to debounce with `delay(75)` originally I had `delay(1000)` as the debounce which worked but required the user to wait or break normal rhythm while entering the code due to the long delay between inputs being accepted.

```
void checkEntered5(int button){ //check the fifth element of the entered[] array
  if (entered[4] == 0){ //if it is zero, i.e. if it hasn't been defined with a button yet
    entered[4] = button; //set the final element as the button that has been pressed
    Serial.print("5: ");Serial.println(entered[4]); //for debugging
    delay(100); //allow time for processing
    compareCode(); //call the compareCode function
  }
}
void loop(){ //run repeatedly
  if (digitalRead(button1) == HIGH){ //if button1 is pressed
    checkEntered1(1); //call checkEntered and pass it a 1
    //delay(1000); //wait
    while( digitalRead(button1) == HIGH) { } // do nothing
    delay(75);//wait, needed for correct functioning, otherwise
              //buttons are deemed to be pressed more than once
  }
  else if (digitalRead(button2) == HIGH){ //if button2 is pressed
    checkEntered1(2); //call checkEntered1 and pass it a 2
    //delay(1000); //wait
    while( digitalRead(button2) == HIGH) { } // do nothing
    delay(75); //wait
  }
  else if (digitalRead(button3) == HIGH){ //if button3 is pressed
    checkEntered1(3); //call checkEntered1 and pass it a 3
    //delay(1000); //wait
    while( digitalRead(button3) == HIGH) { } // do nothing
    delay(75); //wait
  }
  else if (digitalRead(button4) == HIGH){ //if button4 is pressed
    checkEntered1(4); //call checkEntered1 and pass it a 4
    //delay(1000); //wait
    while( digitalRead(button4) == HIGH) { } // do nothing
    delay(75); //wait
  }
  else if (digitalRead(button5) == HIGH){ //if button4 is pressed
    checkEntered1(5); //call checkEntered1 and pass it a 5
    //delay(1000); //wait
    while( digitalRead(button5) == HIGH) { } // do nothing
    delay(75); //wait
  }
}

```

Everything below this point is included simply to provide context for the check entered code seen above. Everything functions as is expected except that the debounce is imperfect.

```
void compareCode(){ //checks if the code entered is correct by comparing the code[] array with the entered[] array
  for (int i = 0; i<4;i++){
    Serial.write(entered[i]);
  }
  if ((entered[0]==code[0]) && (entered[1]==code[1]) && (entered[2]==code[2]) && (entered[3]==code[3]) && (entered[4]==code[4])){ //if all the elements of each array match the passcode

    //--. .-. . . -.

    digitalWrite(solenoid, LOW);
    digitalWrite(greenLed1, HIGH); //turn the green LED on
    digitalWrite(greenLed2, HIGH); //turn the green LED on
    delay(50); //wait for a bit
    digitalWrite(greenLed1, LOW); //turn the green LED off
    digitalWrite(greenLed2, LOW); //turn the green LED off
    delay(500);
    digitalWrite(solenoid, HIGH);
    delay(2500);

  }

  else if ((entered[0]==code[4]) && (entered[1]==code[2]) && (entered[2]==code[0]) && (entered[3]==code[3]) && (entered[4]==code[1])){

    //-... .-.. ..- .

    digitalWrite(blueLed1, HIGH);
    digitalWrite(blueLed2, HIGH);
    delay(1000);
    digitalWrite(solenoid, LOW);
    delay(4000);
    digitalWrite(blueLed1, LOW);
    digitalWrite(blueLed2, LOW);
    delay(50);
    digitalWrite(redLed1, HIGH);
    digitalWrite(redLed2, HIGH);
    delay(1000);
    digitalWrite(redLed1, LOW);
    digitalWrite(redLed2, LOW);
    delay(50);
    digitalWrite(solenoid, HIGH);
    delay(1000);
  }

  else { //if you (or the intruder) get the code wrong
    flash(); //call the flash function
    for (int i = 0; i < 4; i++){ //this next loop is for debugging
      entered[i] = 0;
      Serial.println(entered[i]);
    }
  }
}

void flash(){ // this is basically the blink example
  //.-. . -..

  digitalWrite(relay2, LOW);
  digitalWrite(redLed1, HIGH);
  digitalWrite(redLed2, HIGH);
  delay(50);
  digitalWrite(redLed1, LOW);
  digitalWrite(redLed2, LOW);
  delay(250);
  digitalWrite(redLed1, HIGH);
  digitalWrite(redLed2, HIGH);
  delay(50);
  digitalWrite(redLed1, LOW);
  digitalWrite(redLed2, LOW);
  digitalWrite(relay2, HIGH);
  delay(2500);
  CPU_RESTART;

```

# Answer
> 0 votes
```
    while( digitalRead(button2) == HIGH) { } // do nothing

```

Doing that right after a digital read assumes there is only one bounce, That's highly unlikely. I would put the delay right after the read and before the delay. Depending on the type of switch bouncing varies, but shouldn't be over 150mS. Less for the little tactile push button used on pcboards.

```
    // read button
    delay(75); //wait
    while( digitalRead(button2) == HIGH) { } // do nothing

```

You can always use an RC filter to debounce each button, then you don't have to worry about the difficult key presses, just the extra parts and expense.

# Answer
> 2 votes
Many of the lines shown in the program box are superfluous – totally redundant and unnecessary. I suggest that you revise it \[see (a)-(d) below\], then replace all the stuff in the program box with the revised version.

(a) Use more subroutine parameters. In cases where you have four or five otherwise-identical routines that differ only in some constants, pass those values into one routine as parameters. Don't write out long lists of nearly-identical routines.

(b) Don't create artificial dependencies. Your code in the five `checkEntered-` routines is obscure, so I can't say without taking more time than I care to spend, but it appears that you have made tests for button 2 depend on tests for button 1, and so on down the line. That makes no sense. Test each button separately and in an identical manner, using a parameterized subroutine. To enforce an order of button presses, create an array P of 5 bytes (or however many you like) and initialize a counter Q to zero. Whenever your debounce routine detects a valid button press, if Q is small enough store the button number in P\[Q\] and then increase Q. (If Q is `(size P)` or more, don't store.)

(c) Don't nest subroutine calls more deeply than necessary. Your `checkEntered1()` can call `checkEntered2()`, which can call `checkEntered3()`, and so forth. Besides not making sense, that series of calls uses five times as much stack memory as necessary. (Generally, RAM is a scarce resource on AVR microcontrollers.) Just use five calls, one after another, to a properly parameterized subroutine.

(d) For repetitious sequences like the following,

```
digitalWrite(greenLed1, HIGH); //turn the green LED on
digitalWrite(greenLed2, HIGH); //turn the green LED on
delay(1000); //wait for a bit
digitalWrite(greenLed1, LOW); //turn the green LED off
digitalWrite(greenLed2, LOW); //turn the green LED off
delay(250); //wait for a bit

```

which seem to recur with minor variations about a dozen times, write a properly parameterized subroutine and call it as necessary. For example:

```
void flashPair(byte L1, byte L2, int del1, int del2) {
  digitalWrite(L1, HIGH);   // turn the green LED on
  digitalWrite(L2, HIGH);   // turn the green LED on
  delay(del1);          // wait a little
  digitalWrite(L1, LOW);    // turn the green LED off
  digitalWrite(L2, LOW);    // turn the green LED off
  delay(del2);          // wait a little
}
...
flashPair(greenLed1, greenLed2, 1000, 250);
flashPair(redLed1,   redLed2,     50, 2500);
...

```

There are, of course, other ways of handling those dozen tedious repetitions. For example, one could write a `for` loop that gets pin numbers and delays from an array and turns LEDs on or off as needed. For example, see an answer to question 17453 for a method of treating multiple buttons systematically using information in arrays along with a `for` loop.

# Answer
> 2 votes
I have used and know of many others who use the Bounce2 Library to provide an easy way to debounce the switch without using any delays so the user wouldn't have to pause between presses. Behind the scenes it uses the Millis function to provide the debounce which doesn't interrupt the sketch running at all. You could also write the Debounce with Millis function yourself.

---
Tags: arduino-nano, button, debounce
---


# Question
Title: Wiring when burning the bootloader of esp8266
I want to burn the bootloader of esp8266. Assume I have esp8266 on esp12 in hand and an USB ISP programmer (or any other programmer like USBTinyISP). I (think I) know how to use the Arduino IDE to burn the bootloader (mainly it's by selecting board and the programmer), but how to wire the esp8266? Precisely I mean, "do I use the pins 12, 13, 14, and 15 as these are for SPI connection"?

Edit: I have seen Arduino microcontroller board of which the bootloader was burned, so I was wondering why not do the same for esp8266.

# Answer
The ESP8266 already has a bootloader to upload new firmware over UART. You don't need to burn anything, and you don't use SPI to program it.

AVR microcontrollers are programmed (aka flashed, or uploaded) using ISP (in-system programming) over SPI. They don't support programming over UART out of the box. To receive new firmware over the serial port, a bootloader is used. It is a piece of software that receives data from the UART and writes it to flash, overwriting the previous firmware.

Before you can do this, you need to write (aka burn) the bootloader firmware to the microcontroller. This can only be done using ISP, because

1. if the chip is blank, there is no bootloader to receive the bootloader over UART
2. if there is a previous bootloader that you want to replace, you can't rely on the bootloader for programming over UART either, because the bootloader would be overwriting itself.

The situation on an ESP8266 is completely different. Whereas on an AVR, ISP is the default method to flash new firmware, on the ESP8266, it is UART flashing. The ESP8266 already has a system built-in for UART flashing (just like an AVR has a system for ISP flashing), so you don't need to flash a software UART bootloader.

There is no ISP system inside of the ESP8266, so trying to do ISP on the HSPI port won't flash anything.

Read this: A Beginner's Guide to the ESP8266
> 5 votes

---
Tags: esp8266, arduino-ide, wires, firmware
---


title: How can I detect a disconnected pin?

text:
# Question
Title: How can I detect a disconnected pin?
I'm trying to build a system where if a cable gets disconnected from a pin (any pin), an action is executed.

I am wondering how to set this up. Can I simply wire the 5V to a pin and read its status or will this mess up the Arduino? Should I use any resistors? How should I connect this to the GND?

Please bear in mind that I'm pretty new to all of this.

# Answer
> 9 votes
The way to do this, since there is no digital value in between HIGH and LOW, is to actively create a signal on the pin you can recognise. Note that if the signal coming in to the pin is a datastream (a sequence of HIGH and LOW) that runs all the time this may not work reliably, but it's good for things like buttons and other simple sensors.

Any signal on a wire has a *drive strength*. This is basically how powerful the signal is and how good it is at overriding other things happening on the same wire. It is closely related to the output impedance of the source (what is sending the signal). For things like buttons and switches that is basically the value of the pullup resistor used.

To actively sense if a pin is disconnected or not you need to temporarily connect it to a known signal level *at the same time* as it's connected to the wire (or not connected if it happens to be not connected). This known signal level has to be of a *weaker* drive than the source signal by several orders of magnitude. This ensures that if you try superimposing your test signal over the incoming signal the incoming signal swamps out the test signal and you don't see it at all. For instance, if your source has 10KΩ impedance (say a button with 10KΩ pullup resistor) then a test signal with source impedance of 1MΩ would be suitable.

Each pin to be tested can be connected to its own 1MΩ (in this example) resistor, and those resistors are all connected to the same extra IO pin:

In this example pin D2 is the test pin, and pins D4-D7 are your inputs.

So under normal circumstances pin D2 is set as an input and completely ignored. When you come to test the pins, though, you set it as an output.

You then set D2 to be HIGH and read each of D4 through D7. Any that read as HIGH are candidates for being not connected.

You then set D2 to be LOW and read the pins that read HIGH before. Any that now read as LOW are disconnected.

You then set D2 back to being an input again so it doesn't interfere with normal operations.

---

If you just want to know if current is flowing in a wire you can use what is called a *shunt resistor*. This is a small resistor (maybe 1Ω) that is placed in-line with the wire and you measure the voltage (using Arduino analog inputs) at both sides of the resistor. The voltage dropped across the resistor is directly proportional to the current flowing through it thanks to Ohm's Law:

> I=V/R

For instance:

If the voltage read by A1 should be 5V (the voltage the wire is connected to) and the voltage read by A0 should be 4.93V, the voltage *dropped* by the resistor would be 5-4.93 = 0.07v. With the 1Ω resistor the current would be 0.07/1 = 0.07A, or 70mA.

With the wire at OUT disconnected there will be zero current flowing since there is no circuit. So re-arranging the formula above we can prove that we can tell it's disconnected.

If I=V/R then V = RI. Therefore V = 1Ω × 0A = 0V. So the voltage dropped across the resistor would be 0V, so A0 and A1 would be equal (discounting any noise). A0 and A1 would both read 5V. Similarly, if the wire IN was disconnected instead then A0 and A1 would both read 0V.

For sensing higher currents you use a smaller resistance, and for sensing smaller currents you use a larger resistance - this allows for a voltage drop to be generated that is within a suitable range for the sensitivity of the ADC doing the reading. For the Arduino that's a 10-bit ADC, so it can sense (with a 5V VREF) 5/1024=4.882813mV per LSB.

Note that if you are working with voltages above that at which the Arduino operates you will need to separate or otherwise scale those voltages. There are special devices designed especially for this task called *high side current shunt amplifiers*. They also allow you to use a smaller resistance than you would otherwise need which is less intrusive to your circuit (less voltage drop).

# Answer
> 1 votes
You can connect all pins through a 1M resistor to a rail. Once in a while you set all your outputs to inputs and toggle the rail HIGH and LOW, if the inputs are HIGH and LOW in the sequence you toggled the rail, there is no wire. The same question was asked at Arduino Forums so read this thread.

This question's answer was provided by johnwasser@forum.arduino.cc.

# Answer
> 1 votes
Alternatively, if this is a digital input, you can just use a pull-up or pull-down resistor to give the input pin a default value. Let's say you use a pull-up resistor to make the default high. Then you connect a low cable to this input so that the input reads low. Now, if the cable goes high or if it is disconnected, you get a high value in the input pin.

I know this was not quite what you were asking but maybe such a solution could help with your original problem. In my case, I have a flame detection module that gives low output by default and turns high when there is a flame. I don't want to miss the flame because of my cable disconnecting, so I use a pull-up resistor that will make the input high not only when there is a flame, but also when there is a disconnection. This way I make sure that I don't miss a fire because of the sensor cable disconnecting.

---
Tags: pins, arduino-nano
---


# Question
Title: What is recommended color recognition sensor RGB for different cases?
What is recommended color recognition sensor in the following two cases:

* To determine the color of the floor while the robot is moving (multi-color line follower).
* To determine the color of an object in distance 10cm at least.

For both cases above, I am looking for a sensor so that I can get values like (R: 252 , G: 217 , B: 0) not only red, green or blue as an result, and no problem with small errors.

# Answer
> 1 votes
You have a conceptual error. You don't need *n* wires to transmite *n* bits of information. If you use a *serial protocol*, one wire or two is enough to transmit information of any size: you just send one bit after another.

Just think: you are downloading sketchs in your Arduino thru a cable with only 4 wires ...

Most sensors (and modules) for Arduino use I2C or SPI to transmit commands/information in digital format. You can learn a lot in this tutorial that covers I2C, SPI and USB.

A quick search on Aliexpress show me this APDS-9960 sensor

The sensor provide ambient light and color measurement, proximity detection and non-contact gesture detection. The APDS-9960 has built in UV and IR blocking filters, four separate diodes sensitive to different directions, and an I2C compatible interface.

Pins: VL (optional power to IR LED), GND (Ground), VCC (power to APDS-9960 sensor), SDA (I2C data), SCL (I2C clock), and INT (interrupt). Each APDS-9960 also has a detection range of 4 to 8 inches (10 to 20 cm).

It works with 3.3V.

---
Tags: sensors
---


title: HTTP PUT method on NodeMCU

text:
# Question
Title: HTTP PUT method on NodeMCU
I am trying to update values to Firebase. According to Firebase:

```
curl -X PUT -d '{ "first": "Jack", "last": "Sparrow" }' \
  'https://[PROJECT_ID].firebaseio.com/users/jack/name.json'

```

We can update using put command. Using curl works fine, but when I look at the header of `ESP8266HTTPClient`, I don't see any `put` or `patch` method there.

I can only see the following:

```
int GET();
int POST(uint8_t * payload, size_t size);
int POST(String payload);

```

Whereas in NodeMCU documentation, it is clearly stated it supports the `put` method too.

```
http.put(url, headers, body, callback)

```

`http.put()` documentation

I cannot find any example.

How can I implement the `put` method in NodeMCU?

# Answer
> 1 votes
pardon me if i asked too soon. I found the answer. all verb are supported. but `post` and `get` got their own names.

```
 int httpCode = http.sendRequest("PUT", String(data));

```

enven post method implement the sendRequest.

---
Tags: esp8266, c++, nodemcu, http
---


title: Equivalent to POSIX mmap() in AVR-libc

text:
# Question
Title: Equivalent to POSIX mmap() in AVR-libc
Is there an similar function in AVR-libc/Arduino C++ to mmap()? I'm looking for a way to place machine code in memory at runtime and make it executable.

# Answer
No.

First, mmap() makes almost no sense on an AVR, as there's no memory management unit or concept of process memory to configure. Some related concepts like sbrk() are occasionally implemented in a minimalist fashion to let library functions designed for larger computers work, but they typically only update a tracking variable or fail. For things that are physically realizable you can write your own mmap() if you really want, either allowing (assigning) or disallowing a region, and even if you really want automatically copying part of a file off an SD card or whatever...

But more importantly, your actual goal is entirely unachievable, as the AVR is a strict Harvard Architecture which **can only execute instructions from flash**, never from RAM.

If you want to execute from RAM, try one of the various small ARM Cortex M0/M4/M3 platforms (many of which have Arduino ports), or even consider a larger Embedded Linux system, which will not necessarily be any more expensive than an Arduino.
> 5 votes

---
Tags: c++, c, avr, core-libraries, avr-toolchain
---