body:
I use an MQTT to communicate with an ESP8266. I'm using cloudmqtt.com and PubSubClient. Sometimes the ESP disconnects from the MQTT and reconnects.
I checked the log from cloud and I got this data

    2019-02-18 20:11:18: New connection from 89.64.15.184 on port 18127.

    2019-02-18 20:11:22: New connection from 89.64.15.184 on port 18127.

    2019-02-18 20:11:35: New connection from 89.64.15.184 on port 18127.

    2019-02-18 20:11:35: New client connected from 89.64.15.184 as ESP8266Client-80:7D:3A:69:6C:2E (c1, k15, u'userName').

    2019-02-18 20:11:53: Client <unknown> has exceeded timeout, disconnecting.

    2019-02-18 20:11:53: Socket error on client <unknown>, disconnecting.

    2019-02-18 20:11:56: Saving in-memory database to /var/lib/mosquitto/18127/db.

    2019-02-18 20:11:58: Client ESP8266Client-80:7D:3A:69:6C:2E has exceeded timeout, disconnecting.

in setup I have this method:

    void setupMQTT() {

      while (!client.connected()) {
        Serial.println("Connecting to MQTT...");
        String clientId = "ESP8266Client-";
        clientId += WiFi.macAddress();
        if (client.connect(clientId.c_str(), mqttUser, mqttPassword )) {

          Serial.println("connected");

        } else {

          Serial.print("failed with state ");
          Serial.print(client.state());
          delay(2000);

        }
      }
      client.publish("esp/blind/out", "hello world");
      client.subscribe("esp/blind/in");
    }

and in loop I have

    client.loop();

without any delay.

I think that the ESP id in MQTT cloud is unique, because I use the MAC address.

title: ESP8266 MQTT periodically disconnecting

Answers: 0


body:
I'm totaly new to Arduino, I'm using ESP2866 NodeMCU and dht22 to display temperature and humidity in a web page, it is autorefresh (using AJAX) and it works perfectly, I wanted to add 2 buttons to it so I can control 2 Leds but when I tried that I couldn't control them and even the values of temperature and humidity stopped refreshing. Can you tell me what is wrong in the code ? here it is :

    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #include "DHT.h"
    #define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

     /*Put your SSID & Password*/
     const char* ssid = "xxx";  // Enter SSID here
     const char* password = "xxx";  //Enter Password here

      ESP8266WebServer server(80);

     // DHT Sensor
     uint8_t DHTPin = D6;

      // Initialize DHT sensor.
      DHT dht(DHTPin, DHTTYPE);

      float Temperature;
      float Humidity;
      float reading;
      float percentage;
      // Auxiliar variables to store the current output state
      String output5State = "off";
      String output4State = "off";

     // Assign output variables to GPIO pins
     const int output5 = 5;
     const int output4 = 4;
     void setup() {
     Serial.begin(115200);
     delay(100);

     pinMode(DHTPin, INPUT);
     dht.begin();

    // Initialize the output variables as outputs
      pinMode(output5, OUTPUT);
     pinMode(output4, OUTPUT);
     // Set outputs to LOW
     digitalWrite(output5, LOW);
     digitalWrite(output4, LOW);
     Serial.println("Connecting to ");
     Serial.println(ssid);

    //connect to your local wi-fi network
    WiFi.begin(ssid, password);

    //check wi-fi is connected to wi-fi network
    while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected..!");
    Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

    server.on("/", handle_OnConnect);
    server.onNotFound(handle_NotFound);

    server.begin();
    Serial.println("HTTP server started");

    }
    void loop() {

    server.handleClient();
    }

    void handle_OnConnect() {

    Temperature = dht.readTemperature(); // Gets the values of the temperature
    Humidity = dht.readHumidity(); // Gets the values of the humidity

    //Serial.println(reading);
    String header=SendHTML( Temperature,Humidity,percentage);

    server.send(200, "text/html",header);
    // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0) {
              Serial.println("GPIO 5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            } else if (header.indexOf("GET /5/off") >= 0) {
              Serial.println("GPIO 5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            } else if (header.indexOf("GET /4/on") >= 0) {
              Serial.println("GPIO 4 on");
              output4State = "on";
              digitalWrite(output4, HIGH);
            } else if (header.indexOf("GET /4/off") >= 0) {
              Serial.println("GPIO 4 off");
              output4State = "off";
              digitalWrite(output4, LOW);
            }

          }

       void handle_NotFound(){
       server.send(404, "text/plain", "Not found");
        }

       String SendHTML(float TempCstat,float Humiditystat, float  percentage){
        String ptr = "<!DOCTYPE html> \n";
        ptr +="<meta name=\"viewport\" content=\"width=device-width,
        initial-scale=1.0, user-scalable=no\">\n";
        // ptr +="<meta http-equiv=\"refresh\" content=\"2\" >\n";
       ptr +="<link href=\"https://fonts.googleapis.com/css?
        family=Open+Sans:300,400,600\" rel=\"stylesheet\">\n";
        ptr +="<title>ESP8266 Weather Report</title>\n";
        ptr +="\n";
         ptr +="\n";

         ptr +="\n";
         ptr +="\n";

         ptr +="
\n";

         ptr +="
ESP8266 Weather Report
\n";
         ptr +="
\n";
         ptr +="
\n";
         ptr +="<svg version=\"1.1\" id=\"Layer_1\"
         xmlns=\"http://www.w3.org/2000/svg\"
         xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n";
         ptr +="width=\"9.915px\" height=\"22px\" viewBox=\"0 0 9.915 22\"
         enable-background=\"new 0 0 9.915 22\" xml:space=\"preserve\">\n";
          ptr +="<path fill=\"#FFFFFF\" d=\"M3.498,0.53c0.377-0.331,0.877-
          0.501,1.374-0.527C5.697-0.04,6.522,0.421,6.924,1.142\n";
          ptr+=
           "c0.237,0.399,0.315,0.871,0.311,1.33C7.229,5.856,7.245,9.24,7.227,
            12.625c1.019,0.539,1.855,1.424,2.301,2.491\n";
          ptr +="c0.491,1.163,0.518,2.514,0.062,3.693c-0.414,1.102-1.24,2.038-
          2.276,2.594c-1.056,0.583-2.331,0.743-3.501,0.463\n";
          ptr +="c-1.417-0.323-2.659-1.314-3.3-2.617C0.014,18.26-
          0.115,17.104,0.1,16.022c0.296-1.443,1.274-2.717,2.58-3.394\n";
          ptr +="c0.013-3.44,0-6.881,0.007-
          10.322C2.674,1.634,2.974,0.955,3.498,0.53z\"/>\n";
          ptr +="</svg>\n";
          ptr +="
\n";
          ptr +="
Temperature
\n";
          ptr +="
";
          ptr +=(int)TempCstat;
          ptr +="°C
\n";
          ptr +="
\n";
          ptr +="
\n";
          ptr +="
\n";
          ptr +="<svg version=\"1.1\" id=\"Layer_2\"
          xmlns=\"http://www.w3.org/2000/svg\"
          xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\";
          width=\"12px\" height=\"17.955px\" viewBox=\"0 0 13 17.955\" enable-
          background=\"new 0 0 13 17.955\" xml:space=\"preserve\">\n";
          ptr +="<path fill=\"#FFFFFF\"
         d=\"M1.819,6.217C3.139,4.064,6.5,0,6.5,0s3.363,4.064,4.681,6.217c1.793,
          2.926,2.133,5.05,1.571,7.057\n";
         ptr +="c-0.438,1.574-2.264,4.681-6.252,4.681c-3.988,0-5.813-3.107-
         6.252-4.681C-0.313,11.267,0.026,9.143,1.819,6.217\"></path>\n";
         ptr +="</svg>\n";
         ptr +="
\n";
         ptr +="
Humidity
\n";
         ptr +="
";
         ptr +=(int)Humiditystat;
         ptr +="%
\n";
         ptr +="
\n";

        //Buttons

         ptr +="
\n";
         ptr +="
Button
\n";
         ptr +="
";
         ptr +="
<button class=\"button\">ON</button>

";
         // If the output5State is off, it displays the ON button
            if (output5State=="off") {
              ptr +="
<button class=\"button\">ON</button>

";
            } else {
              ptr +="
<button class=\"button
            button2\">OFF</button>
";
            }
             // If the output4State is off, it displays the ON button
            if (output4State=="off") {
              ptr +="
<button class=\"button\">ON</button>

";
            } else {
              ptr +="
<button class=\"button
              button2\">OFF</button>
";
              }
               ptr +="%
\n";
               ptr +="
\n";
               ptr +="
\n";
               ptr +="\n";
               ptr +="\n";
               return ptr;
              }

title: NodeMCU display temperature and control LED from an autorefresh web page

Answers: 1

body:
Write handlers for different URLs
```
server.on("/5/on", led5On);
server.on("/5/off", led5off);
```
do you get the concept?

or you could write one handler `server.on("/setLED", setLED);`, if you would send `"/setLED?num=5&state=on"`. and then in `setLED` function get the parameters values as

```
String num = sever.arg("num");
String state = sever.arg("state");
```

see the SimpleAuthentication example


body:
I am trying to send a char array using Arduino Uno board and nRF24L01 modules

Here is the code for both transmitter and receiver:

     #include <SPI.h> //~ #include <TMRh20nRF24L01.h> //~ #include <TMRh20RF24.h>
     #include <nRF24L01.h>
     #include <RF24.h>

     #define CE_PIN   9
     #define CSN_PIN 10

     // NOTE: the "LL" at the end of the constant is "LongLong" type //
     These are the IDs of each of the slaves const uint64_t slaveID[2] =
     {0xE8E8F0F0E1LL, 0xE8E8F0F0E2LL} ;

     RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

     char
    > dataToSend[64]="e7665072be018b6b58ea9e40cf38553d6dc293cda4c9d94cda6e91ca61b3a073";

     unsigned long currentMillis; unsigned long prevMillis; unsigned long
    > txIntervalMillis = 1000; int txVal = 0; float ackMessg[2]={1,2}; byte
     ackMessgLen = 4; // NB this 4 is the number of bytes in the 2 ints
     that will be recieved

     void setup() {

        Serial.begin(9600);
         Serial.println("Track Control Starting");
         radio.begin();
         radio.setDataRate( RF24_250KBPS );
         radio.enableAckPayload();
         radio.setRetries(3,5); // delay, count }

     //====================

     void loop() {

         currentMillis = millis();
         if (currentMillis - prevMillis >= txIntervalMillis) {

         radio.openWritingPipe(slaveID[0]); // calls the first slave
                                             // there could be a FOR loop to call several slaves in turn

         bool rslt;
         rslt = radio.write( dataToSend, sizeof(dataToSend) );
         Serial.print("\nRSLT (1 = success) ");
         Serial.println(rslt);
         Serial.print("Data Sent ");
         Serial.print(dataToSend[0]);
         Serial.print("  ");
         Serial.println(dataToSend[1]);
         if ( radio.isAckPayloadAvailable() ) {
             radio.read(ackMessg,ackMessgLen);
            Serial.print("Acknowledge received: ");
            Serial.print(ackMessg[0]);

>      #include <SPI.h>
>      #include <nRF24L01.h>
>      #include <RF24.h>
>
>
>      #define CE_PIN   9
>      #define CSN_PIN 10
>
>      // NOTE: the "LL" at the end of the constant is "LongLong" type
>
>      const uint64_t   deviceID = 0xE8E8F0F0E1LL; // Define the ID for this slave
>
>     int valChange = 1;
>
>      RF24 radio(CE_PIN, CSN_PIN);
>
>      char  dataReceived[64];
>      int ackData[2] = {12,23};
>
>      void setup() {
>
>          Serial.begin(9600);
>          delay(1000);
>          Serial.println("Hand Controller Starting");
>          radio.begin();
>          radio.setDataRate( RF24_250KBPS );
>          radio.openReadingPipe(1,deviceID);
>          radio.enableAckPayload();
>          radio.writeAckPayload(1, ackData, sizeof(ackData));
>          radio.startListening();
>      }
>
>      void loop() {
>
>          if ( radio.available() ) {
>              radio.read( dataReceived, sizeof(dataReceived) );
>               for (int x = 0; x <64; x++) {
>            //if (dataReceived[x] < 16) {
>            //  Serial.write('0');
>          // }
>            Serial.print(dataReceived[x]);}
>            Serial.println();
>              radio.writeAckPayload(1, ackData, sizeof(ackData));
>
>              ackData[0] += valChange; // this just increments so you can see that new data is being sent
>          }
>     }

And here is the output that I get

> Hand Controller Starting
>
> e7665072be018b6b58ea9e40cf38553d

title: Sending char arry via nRF24L01

Answers: 1

body:
TX code

    #include "sha256.h"
    #include <Arduino.h>
    #include "./printf.h"

    #include <SPI.h>
    //~ #include <TMRh20nRF24L01.h>
    //~ #include <TMRh20RF24.h>
    #include <nRF24L01.h>
    #include <RF24.h>

    #define CE_PIN   9
    #define CSN_PIN 10

    // NOTE: the "LL" at the end of the constant is "LongLong" type
    // These are the IDs of each of the slaves
    const uint64_t slaveID = 0xE8E8F0F0E1L  ;

    RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

    unsigned long currentMillis;
    unsigned long prevMillis;
    unsigned long txIntervalMillis = 1000;
    int txVal = 0;
    int ackMessg[6];
    byte ackMessgLen = 4;

    uint8_t* hash;
    uint8_t copy[32];
    void printHash(uint8_t* hash) {
      int i;
      for (i=0; i<32; i++) {
        Serial.print("0123456789abcdef"[hash[i]>>4]);
        Serial.print("0123456789abcdef"[hash[i]&0xf]);
          copy[i]=hash[i];
      }
      Serial.println();
    }

    void setup() {
      printf_begin();

      uint32_t a;
      unsigned long ms;

      Serial.begin(9600);

      radio.begin();
        radio.setDataRate( RF24_2MBPS );
        radio.enableAckPayload();
        radio.setRetries(3,5); // delay, count

      // SHA tests
      Serial.println("Test: FIPS 180-2 B.1");
      Serial.println("Expect:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad");
      Serial.print("Result:");
      ms = micros();
      Sha256.init();
      Sha256.print("abc");
      printHash(Sha256.result());
      Serial.println();
      for(int x=0;x<32;x++)
            {   Serial.print(copy[x]);
                Serial.print(" ");
                                      }
                Serial.println();

      Serial.print(" Hash took : ");
      Serial.print((micros() - ms));
      Serial.println(" micros");
      Serial.println();

      }

    void loop() {

      currentMillis = millis();
        if (currentMillis - prevMillis >= txIntervalMillis) {

        radio.openWritingPipe(slaveID);
        bool rslt,rsltt;
        rslt = radio.write( copy, 32 );

        if ( radio.isAckPayloadAvailable() ) {
            radio.read(ackMessg,ackMessgLen);
            Serial.print("Acknowledge received: ");
            Serial.print(ackMessg[0]);
            Serial.print("  ");
            Serial.println(ackMessg[1]);
        }
        prevMillis = millis();
     }

    }

Rx code

    // HandController - the slave or the receiver

        // http://tmrh20.github.io/RF24/

        //~ - CONNECTIONS: nRF24L01 Modules See:
        //~ http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
        //~ 1 - GND
        //~ 2 - VCC 3.3V !!! NOT 5V
        //~ 3 - CE to Arduino pin 9
        //~ 4 - CSN to Arduino pin 10
        //~ 5 - SCK to Arduino pin 13
        //~ 6 - MOSI to Arduino pin 11
        //~ 7 - MISO to Arduino pin 12
        //~ 8 - UNUSED

    #include <SPI.h>
    //~ #include <TMRh20nRF24L01.h>
    //~ #include <TMRh20RF24.h>
    #include <nRF24L01.h>
    #include <RF24.h>

    #define CE_PIN   9
    #define CSN_PIN 10

    // NOTE: the "LL" at the end of the constant is "LongLong" type

    const uint64_t   deviceID[2] ={ 0xE8E8F0F0E1LL,0xE8E8F0F0E1LL}; // Define the ID for slaves

    int valChange = 1;

    RF24 radio(CE_PIN, CSN_PIN);
    RF24 radioo(CE_PIN, CSN_PIN);
    uint8_t  dataReceived[32];

    int ackData[2] = {12,23};

    void setup() {

        Serial.begin(9600);
        Serial.println("Hand Controller Starting");
        radio.begin();
        radio.setDataRate( RF24_2MBPS );
        radio.openReadingPipe(1,deviceID[1]);
        radio.enableAckPayload();
        radio.writeAckPayload(1, ackData, sizeof(ackData));
        radio.startListening();

    }

    void loop() {

     unsigned long startTimer = millis();

        if ( radio.available() ) {
            radio.read( dataReceived, sizeof(dataReceived) );
            radio.writeAckPayload(1, ackData, sizeof(ackData));
            Serial.println();
            //Serial.println(startTimer);
            Serial.println();
            for(int x=0;x<32;x++)
            {Serial.print(dataReceived[x]);
            Serial.print(" ");}}
            ackData[0] += valChange; // this just increments so you can see that new data is being sent

        }

it is fully working now with both outputs on the same size


body:
I am finally ready to try setting fuse bits on my ATMega32u4-AU custom board (8Mhz Ceramic Resonators, 3.3V), however, after I set the fuse bits and plug my board to computer, the device manager appears nothing (seems there is no device been connected). I am not sure which step I did wrong, so I’d like to post the details, please kindly point out my mistake, thanks a lot!

- I used Fuse High Byte: 1001 1001 (0x99) Fuse Low Byte: 0101 1110 (0x5E) Extended Fuse Byte: 1111 0011 (0XF3)
- This is the command I entered into avrdude: avrdude –b 19200 –c usbasp –p m32u4 –v –e –U efuse:w:0XF3:m –U hfuse:w:0x99:m –U lfuse:w:0x5E:m
- I am able to see the result from command [![enter image description here][1]][1]
- But after setting the fuse, when I read the fuse in avrdude, I dont know what the reason is but I got different efuse data[![enter image description here][2]][2]

After all of these steps, I connected my board to windows 10 computer, the computer shows nothing...

Someone online told me that it could because the clock divider get changed. So, I added a step of setting lock bit to 0x2C through typing “avrdude –b 19200 –c usbasp –p m32u4 –v –e –U lock:w:0X2C:m” But it didn't fix the preblem.

Later, I was thinking maybe I set the low fuse wrong, because the bit0..3 (1110) in lfuse means "Low Power Crystal Oscillator"; So, I set bit0..3 to (1010) and CKDIV8 to 1, which means "Low Frequency Crystal Oscillator" and "unprogrammed divide clock".

All of these didn't fix the problem, please kindly point out which step I did wrong, your help would be greatly appreciated.

  [1]: https://i.stack.imgur.com/DtTCL.png
  [2]: https://i.stack.imgur.com/FnDeB.png

title: Atmega 32U4 doesn't show on device manager after fuse bits reset

Answers: 0


body:
I have an ESP-01 that I want to measure pool temperature with. It will send the data over MQTT to the broker.

I have connected RST to GPIO16 so I can use the deep sleep functionality. Currently I am testing sending a "hello world" to the MQTT broker, and everything works fine when booting up the first time, but it seems like the ESP never wakes up correctly after the first deep sleep.

My script looks like this:
<!-- language-all: lang-cpp -->
```
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Set ADC mode
ADC_MODE(ADC_VCC);

// WiFi settings
const char* ssid = "Network";
const char* password = "Password";
IPAddress ip(192, 168, 0, 100);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

// MQTT settings
const char* mqtt_server = "192.168.0.110";
const int mqtt_port = 1883;
const char* mqtt_user = "User";
const char* mqtt_pass = "Password";
const char* mqtt_client_name = "poolsensor";
const char* mqtt_topic = "pool";

// Data wire plugged into D1 on the ESP8266 ESP-01 - GPIO 5
#define ONE_WIRE_BUS 5

// Setup OneWire instance to communicate with any device
OneWire oneWire(ONE_WIRE_BUS);

// Pass our OneWire reference to Dallas Temperature
DallasTemperature DS18B20(&oneWire);

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
  delay(10);

  // Annuonce connection
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // Setup WiFi config and connect
  WiFi.mode(WIFI_STA);
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're connected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");

    // Attempt to connect
    if (client.connect(mqtt_client_name, mqtt_user, mqtt_pass)) {
      // Success
      Serial.println("connected");
    } else {
      // Fail
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");

      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

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

  // Start WiFi setup
  setup_wifi();

  // Set MQTT server
  client.setServer(mqtt_server, mqtt_port);

  // Set resolution to 0.25
  DS18B20.setResolution(10);

  // Start sensor
  DS18B20.begin();
}

void loop() {
  if (!client.connected()) {
    reconnect();
  } else {
    // Get temperature
    /*
    DS18B20.requestTemperatures();
    float temp = DS18B20.getTempCByIndex(0);

    if ((temp > -20) && (temp < 60)) {
      client.publish("pool/temperature", String(temp).c_str(), true);
    }
    */

    client.publish("pool/temperature", "hello world");
    Serial.println("published temperature");

    delay(1000);

    // Sleep
    ESP.deepSleep(60 * 1000000);

    delay(3000);
  }
}
```

Everything looks good in the serial monitor when compiling and uploading code, as the code runs the first time:

```
Connecting to Network
......
Connected, IP address: 192.168.0.100
Attempting MQTT connection...connected
published temperature
````

And I can see in my MQTT debugger that it receives `hello world`. After around 60 seconds, the following is shown in the serial monitor (lots of gibberish):

    {l�l��|��d�|�d�b<����s�c$�#��ng�lgn���cxp��${$sd�s��'�c�ncp��

This is the last message I ever receive from the ESP, so I assume it never deep sleeps again and runs over the code again.

Anyone experienced the same, or see a bug in my code?

title: ESP-01 not waking correctly up after deep sleep

Answers: 3

body:
You left io 0 floating. With io 0 not HIGH at boot, the esp8266 goes into flashing mode.

The wake-up from deep-sleep is boot startup. So your code doesn't start if io 0 is not pulled high. Add a pull-up for io 0.

If you set Serial Monitor to 74880 baud, you will see the boot-log readable. It will print 1 as first value in "boot mode". This value is set from state of io 15, 2 and 0. 15 should be LOW and io 2 and io 0 HIGH for normal boot. `1` indicates that only 2 is HIGH.

body:
Pretty sure you will need gpio 16 connected to reset in order for this to ever work, it’s tricky but not impossible. Have a read here:

https://randomnerdtutorials.com/esp8266-deep-sleep-with-arduino-ide/

body: I had the same problem and i found out, my CH_PD pin and RST pin were shorted together, when i was connecting wire from RST to GPIO_16. On the chip, the CH_PD pin is next to GPIO_16, so when you short them, the RST pin is always high, so esp cannot reboot anymore without external grounding. I fixed it and now deep sleep is working again!


body:
I'm trying to call an interrupt routine (let's call it handler() ) every second on my arduino DUE.
I thought the simplest way to do this was to use [this library][1]
but it seems that i don't know how to use it...

[![results][2]][2]

[![my code][3]][3]

  [1]: https://github.com/ivanseidel/DueTimer
  [2]: https://i.stack.imgur.com/9KUXI.png
  [3]: https://i.stack.imgur.com/4inEf.png

title: timer library on Arduino DUE

Answers: 1

body:
You are trying to print 6 characters ("test\r\n"), i.e. 60 bits
including the start and stop bits, 1000 times per second. This requires
a baud rate of at least 60 kbit/s, yet the serial port has been
configured for only 9.6 kbit/s. Something has to give...

As Mikael Patel wrote in a comment, it is generally inadvisable to
`Serial.print()` from within an ISR. It is supposed to work, though, as
long as you don't fill the `Serial` output buffer. The problem is that
your code does fill the buffer, as it is writing to it faster than the
UART can empty it. Once the buffer is full, the program will
malfunction.


body: Why is my INA219 current sensor gives a negative currentmA and Shunt voltage?  My sensor is connected in a glucose test strip connector. The current is from a glucose biosensor? Is it possible that my INA219 is damaged?

title: Negative currentmA and Shuntvoltage

Answers: 1

body:
The "sign" of the INA219 shows the direction of flow of the current. Current isn't either "positive" or "negative", it has a direction. The sign is just used to represent that direction.

It's like a car. It has a speed. That speed could be in the forward direction, or the reverse direction.  It could be going 5 miles per hour forwards, or 5 miles per hour backwards. Either way, it's 5 miles per hour. However the backwards direction could be represented as "minus 5 miles per hour". It doesn't mean that you're doing a negative speed (there is no such thing), but that your speed is in a "negative direction".

This "speed" and "direction" are combined together to create "velocity", which is "speed relative to some arbitrarily chosen 'normal' direction and speed".

At this point the "velocity" can be represented as a 2D vector, with forward velocity in the + direction, and reverse velocity in the - direction.

But that's all a bit of a digression. All it means is that the "-" is meaningless if you don't care about the direction of current flow. If all you care about is the quantity of current you can discard the "-" completely.  The simplest way is:

    current = abs(current);


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

  [1]: https://i.stack.imgur.com/lLTzc.png
I am trying to use nRF24L01 with antenna  in my project, but when I do test with getting start from rf24 master is showing a serial monitor like in the picture abov e. What is the problem here?

title: nRF24L01 with antenna transmitter and receiver

Answers: 1

body:
Search in the code for the line `Serial.begin(###)` where **###** is a number representing the serial speed, also known as *baud rate*.
This number must match with the baud rate of your serial monitor, otherwise all you get is garbage.

BTW, this has nothing to do with nRF24, this is plain Arduino serial connection.


body:
this is my first post here. Before I ask you my problem, I'm sorry if I'm wrong to write but my English is bad.

So, my problem is this: I'm developing a "client-server" system with serial communication between my computer and the NodeMCU. The PC will send a message (an integer) to the Node which makes certain things based on the number. At the end of the work the Node will send an ACK to the server (an integer).
I programmed the NodeMCU using the Arduino tool and in the first preliminary tests everything worked: the Node received and answered correctly. Then I wrote a script in Python to automate the thing and that's where the problems start. Communication takes place correctly but the messages that the Node sends to the PC are dirty. At the beginning of the buffer there are some illegible bits while at the end of the buffer there is the correct message. I did the same test with the Arduino Uno and this works perfectly.

Can you give me a reason for this problem and in case a solution?
Thanks in advance!

----------

NodeMCU:

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

 void loop( )
  {
   if( Serial )
    {
     Serial.write( (int)12 );
    }
  }

Python:

```
#!/usr/bin/python
import serial

port = '/dev/cu.wchusbserial1420'

ard = serial.Serial(port,9600,timeout=5)

x = ard.read(1)
x = int( x )

print x
```

----------

(I am attaching some screenshots)

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

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/eAYqV.png
  [2]: https://i.stack.imgur.com/b4B8w.png

title: Serial communication problem NodeMCU

Answers: 0


body:
I want to control a 12 V relay using an Arduino 5 V signal, but due to some unknown reason the relay does not work. I am using a BC548 transistor as a switch for relay.[![enter image description here][1]][1]
Please suggest where I go wrong.

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

title: 12 V relay using Arduino

Answers: 1

body:
If it's working with 12v on the input but not 5v, it sounds like the base resistor value
 (which is missing from the diagram) might be too high. A value of around 1k should ensure the transistor is fully switched on.


body:
I bought a 12-step "quadrature" incremental rotary encoder as an input device for a project I'm working on.

When I wrote the code to track "ticks" of rotation, I made it respond to any change in the "A" pin. As a result, I got 24 steps, not 12. They appear to be evenly spaced, and still correctly indicate clockwise or counter-clockwise rotation.

It occurs to me that if I track changes of state in both the "A" and "B" pins, as long as I reverse the logic for identifying clockwize vs. counterclockwise rotation, I could get a 48 step count from the same encoder.

Thus isn't it straightforward to get 2X or 4X the steps from a quadrature  rotary encoder simply by interpreting the signals differently?

title: Can't you easily use "quadrature" incremental rotary encoders at 2X or 4X their number of "stops"?

Answers: 2

body:
Maybe the encoder you got is being incorrectly described?  I have a handful of the little thru-hole rotary encoders popular in Arduino module kits and they have 12 detents for one rotation, but they are actually 48-position-per-rotation encoders. When I use them, I have to divide the tick count by 4 to have one physical "click" count as one tick in my code.

For some of these, it's fairly straightforward to open them up and remove the detent, and thus get a higher-resolution, smooth spinning encoder. Unfortunately, others, such as the ones I have, are difficult to open without destroying them, and since they physically *snap* to the detents, aren't usable at the proper resolution.

The method you note, where you track the high/low change in either direction of both outputs is the normal way to read quadrature encoders.

body:
The answer to my question is yes.

Normally you only count the falling edge of one of the outputs of an incremental encoder as a pulse. That gives you the specified number of ticks for that kind of encoder - 12 ticks per turn in the case of my encoder.

If you instead write your code to respond to either rising or falling edge changes on one of the pins, you get 24 ticks per revolution.

If you **instead** write your code to respond to rising or falling edge changes on **either** pin, you get 48 ticks per revolution.

The code I came up with looks like this:

    void setup() {
      //Use this setup code for 12 ticks/revolution
      attachInterrupt(digitalPinToInterrupt(rotaryPinA), encode, FALLING);

    /*
      Use this setup code for 24 ticks/revolution
      (trigger interrupt on rising and falling edge)
      attachInterrupt(digitalPinToInterrupt(rotaryPinA), encode, CHANGE);
    */

    /*
      Use this setup code for 48 ticks/revolution
      (trigger interrupts on rising and falling edge of either pin)
      attachInterrupt(digitalPinToInterrupt(rotaryPinA), encode, CHANGE);
      attachInterrupt(digitalPinToInterrupt(rotaryPinB), encodePinB, CHANGE);
    */

    //The rest of your setup code...
    }

And the interrupt service routines (ISRs):

    void encode() {
      rotaryValueChanged = true;
      //Read the PinA & PinB (Digital Pins 2 & 3) using port register PINE, 4th and 5th bit
      //Fast equivalent to pinAState = digitalRead(rotaryPinA) == LOW
      bool pinAState = (PINE & (1 << 4)) == 0;
      bool pinBState = (PINE & (1 << 5)) == 0;
      rotaryValue +=  (pinAState == pinBState) ? -1 : 1;
    }

    void encodePinB() {
      rotaryValueChanged = true;
      //Read the PinA & PinB (Digital Pins 2 & 3) using port register PINE, 4th and 5th bit
      bool pinAState = (PINE & (1 << 4)) == 0;
      bool pinBState = (PINE & (1 << 5)) == 0;
      rotaryValue +=  (pinAState != pinBState) ? -1 : 1;
    }

If you only set up one interrupt on rotaryPinA, the 2nd interrupt method never gets called.

The code above is specific to the Arduino Mega 2560 and other boards that have the same pin to register mappings. It uses interrupts so it doesn't miss state changes in the pins, and reads the pin states using port registers for speed.

Note that if you're only adding a falling edge interrupt you can skip the read of pin A (since when the pin state falls it will, by definition be at a logic 0 whenever the ISR gets called.)

To get this to work well I had to build the RC filter circuit described in the spec sheet for my encoder:

https://www.bourns.com/docs/Product-Datasheets/PEC12R.pdf

The diagram looks like this:

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

And I had to add Schmitt triggers between the filter outputs shown above and the input lines to the Arduino.

Without the Schmitt triggers it gets jitter when the voltage from the filter doesn't switch between HIGH and LOW values fast enough. The Schmitt triggers exclude spurious readings from those "dead zone" voltages.

With those changes the readings from the encoder are quite good, although it still measure ± 1 tick or so per revolution for some reason.

I wish now I had bought the version of the encoder that has detents so it rotates in discrete clicks.

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


body:
I'm trying to look through the Arduino core to find where "mySketch.ino" is included or implemented. In 'Arduino.h', the prototypes `void setup(void)` and `void loop(void)` are defined, in 'main.cpp', `setup(void)` and `loop(void)` are called, but I'm not sure where 'main.cpp' or any other related files makes a reference to the sketch.

Where does this occur?

title: Where does the Arduino core include the name of the sketch?

Answers: 1

body: Compilation doesn't start with the Arduino.h or the core files; rather, it starts with your own sketch, "whatever.ino". Your .ino file includes Arduino.h into the compilation which makes references to core modules. That compilation leaves many references to to be satisfied, and itself satisfies several - setup() and loop(), for two. At link time, the linker is told to read not only your compiled module(s), but also the compiled core files, from which it can extracts the modules required to satisfy references made by your compiled code. Then it combines your module, and those modules required by it, into the load file that avrdude uploads to the Arduino.


body:
In another words, is it possible to develop a custom bootloader so sketches can be uploaded via serial connection made using the RX/TX pins and not via the USB connector (I am using Pro Micro boards)?
Thanks!

title: Is it possible to upload an arduino sketch through the serial port (RX) instead of USB

Answers: 3

body:
Yes. You can develop a bootloader for the ATmega32u4 that will receive firmware over any interface (UART, SPI, I2C etc.).

Loading via UART is a solved problem. Look for the AVR109 bootloader.

body:
Yes, there is an [Optiboot fork supporting ATmega32U4](https://github.com/dmjlambert/optiboot) supporting hardware UART to upload Arduino sketches.

Also, a detailed [instructable post explaining how to use it](https://www.instructables.com/id/How-to-upload-sketches-to-Pro-MicroLeonardo-via-se/) with Arduino Pro Micro.

body:
No need to have a specific bootloader. The basic bootloader can do that (in Arduino that's the case so I hope this answer will apply in your case. But if not, the principle is certainly the same).

Once you perform a reset on the board, the bootloader look at the serial port during a short time. If something come, it checks if it's an hex file and if yes it send it to flash. The USB just use the RX input.

So you can send data using a direct connection or using for example a Bluetooh like HC-05. I do that for some project in order to update via Android: the Android app send an order to the Arduino, through Bluetooth.
Receiving this, the Arduino RESET itself, and then the Android App send immediatly data.

On Arduino side: connect for example A0 to RESET PIN and perform a digitalWrite(PIN_RESET,HIGH);
Have also a look at https://arduino.stackexchange.com/questions/1477/reset-an-arduino-uno-in-code

After the RESET, the board will reply with 0x14 0x10 (so it send this to TX and so if you have a bluetooh module, you'll received than on your Android App (eg))

You must then send  0x50 0x20 to the board to tell it you enter programming mode.
Then send 0x75 0x20 to get the id of the board in order to be sure you will send the HEX file for the right hardware.
You will receive 0x14 XXX 0x10 where XXX = id of the board

Then you can send the HEX file.

For that, you will send it by blocks of 128 bytes

So start by dividing the HEX to know the number of blocks then loop against this  number:
Start at ADR=0 (adresse dest in flash) and send:

For each block:

1) Send 0x55, low byte of ADR, high byte of ADR, 0x20

2) check reply (must be 0x14 0x10)

3) Send the 128 bytes: 0x64, 0x00, 0x80, 0x46 then the 128 bytes and finish by 0x20 (0x80 is the size)

4) check reply (must be 0x14 0x10)

5) update ADR. Take care: ADR is a word pointer (2 bytes). So ADR = ADR+0X40

Loop on num of blocks

Finish the job by sending 0x51 0x20 (exit programing mode)

Some details:

- 0x46 before the 128 bytes tells you want to write in flash. Other codes are available eg for checking, getting data etc..

 - It seems mandatory to send each time 128 bytes. So if your last block is smaller, you need to add some '\0' to get a total of 128. I've been unable to get good results trying to change the 0x80 value and send less bytes. :(

It's not very easy and need tests to get a good code but that really fine to be able to have an Arduino the user can update.

Hope this will help.


body:
I know that I2C devices are supposed to have unique addresses when used. What if I still use multiple devices with the same address, what can go wrong? Let me describe the situation:

I have multiple digital capacitors ([NCD2400M][1] by IXYS) and I would be using them so, that I always send the same command to every chip. I have no need of reading anything from those, which is the reason I was thinking why should I bother multiplexing my I2C line. I have no reason to identify them, only commanding. For the commanding I use Arduino (Nano currently, might change to some other Arduino model).

I have already tried commanding them simultaneously and it works like a charm. I tried so that I connected SDA and SCL of four chips and used RC circuit and square wave to check the rise time to verify that every chip indeed changes their capacitance.

[![enter image description here][2]][2]

However, I'm new to I2C protocol and I'm not yet aware of every detail. I guess there could be issues when one of the chips fail? Can I assume in this case that nothing goes wrong with the ACK/NACK bit since the chips are "identical"?

-RautSa

EDIT:
After using correct keywords for searching I found [this][3] previously asked question. Based on that I now understand at least there would be a problem when only one of the chips tries to send NACK bit.

  [1]: https://www.ixysiss.com/ncd2400
  [2]: https://i.stack.imgur.com/gQSjT.png
  [3]: https://electronics.stackexchange.com/questions/417263/multiple-instances-of-same-device-on-i2c-bus

title: Risks when commanding multiple chips with same address via I2C

Answers: 2

body:
There is no risk for damaging something, but the risk is the reliability.

The NCD2400M operates at 3.3V and 5V, so that will work with every Arduino board.

Your question is very similar to the question that you already found: [electronics.stackexchange.com/questions/417263/multiple-instances-of-same-device-on-i2c-bus][1].
There are a few specific Arduino things to mention.

During Arduino `setup()` a sensor is often checked if it is connected and if it is possible to communicate with a sensor. That would be impossible when the sensors share the I2C address.

The Arduino Wire library detects a bus error, for example when there are other I2C Masters on the bus, and returns with an error.
Since your NCD2400M are only Slaves, I think that they will not trigger a bus error.

You need some luck, and I can not guarantee that it will always work:

 1. When the NCD2400M behaves like a normal I2C Slave and it is not too
    smart, then it does not detect that another one pulls the SDA low
    for an acknowledge.
 2. Some sensors send a NACK when they are busy, I
    can not find such a note in the datasheet. You could write to the
    NCD2400M twice to be sure that they have received it.
 3. When they have an
    internal clock and respond with different timings on the I2C bus,
    then you can set the SCL clock lower. For example
    `Wire.setClock(50000);` after `Wire.begin()` for a 50kHz SCL clock.

When one of NCD2400M is blown, then you are not able to identify the bad one. However, when one of the NCD2400M is blown, perhaps the whole circuit is no longer reliable.

For a good design, you should know if you are actually communicating with a sensor or just talking into thin air. When you have made more Arduino projects, then you know that it is essential to know if a sensor is connected or not.

Trying this solution to make it "easy" for now, might cause a lot of troubles later.

**Conclusion:** It will work. You can use it for a test. When you use it in the final version, you take the risk that it can cause a lot of troubles.

More about the basics of the I2C bus: [http://www.gammon.com.au/i2c][2]

  [1]: https://electronics.stackexchange.com/questions/417263/multiple-instances-of-same-device-on-i2c-bus
  [2]: http://www.gammon.com.au/i2c

body: Could always add a switch like DG406, DG409, or equivalent to select which cap is connected to SDA so that only one is commanded at a time. Pullup SDA on the output side so it is not floating at the chip.


body:
Looking for some help on this please. It is a little long winded, but the point of it is I cannot retrieve a string response via my ESP8266 ESP-01S.

I connect my ESP to my Ardiuno using `SoftwareSerial esp8266(2,3)`.

I can quite happily send POST and GET commands to my server and process the request server side. This is done through the AT sequence below. My server uses a REST API to receive the request and responds with a simple string (for example 'HELLO'). If I attempt the same client side functionality through C# code or Python on my Pi I receive the response from the server no problem. But on my Arduino the response is always 32 when reading via `ESP.read()` (which I believe is in bytes and signals end of data). I have also tried `esp.readString()` and `esp.readStringUntil('\n')` all with no luck.

Is it not possible to access the response sent back to the ESP using my approach?

I see many examples go down the route of programming the ESP directly. I'm not really looking to do that on this attempt as I am creating some basic Arduino tutorials for family and friends and would prefer to not add that complexity.

Result server response

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

    esp8266.println(postRequest);
    while (esp8266.available() > 0) {
      Serial.println("." + esp8266.readString() + ".");
    }

So I guess in short, am I wrong in expecting the

    //* AT SEQUENCE*
    AT
    AT+RST
    AT+CWMODE
    AT+CWJAP
    AT+CIPMUX
    AT+CIPSTART
    AT+CIPSEND

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

    // CREATE DATA

    String data = "=DATA1";

    // POST

    String postRequest =
      "POST " + URI + " HTTP/1.1\r\n" +
      "Host: " + HOST + ":" + PORT + "\r\n" +
      "Accept: *" + "/" + "*\r\n" +
      "Content-Length: " + String(data.length()) + "\r\n" +
      "Content-Type: application/x-www-form-urlencoded\r\n" +
      "\r\n" +
      data;

    // GET

    String postRequest =
      "GET " + URI + "?data=" + data + " HTTP/1.1\r\n" +
      "Host: " + HOST + ":" + PORT + "\r\n" +
      "Accept: *" + "/" + "*\r\n" +
      "Connection: keep-alive\r\n" +
      "Content-Length: " + String(0) + "\r\n" +
      "Content-Type: text/plain\r\n" +
      "\r\n";

title: Arduino ESP8266 ESP-01S GET command

Answers: 0


body:
I'm new to wireless communication on Arduinos and doing research for a project. I'm looking at the [Arduino Leonardo][1] (which is like the Uno) which via its micro USB port can be automatically recognized as a mouse/keyboard. But also looking at a regular Uno wiFi Rev2.

I want to achieve the same result, but wirelessly via Bluetooth. Because I need to connect it to a device that only recognizes Bluetooth mice/keyboards and nothing else. If I buy something like the [HC-05][2] how would the chip report itself?

How is the Bluetooth stack handled with regards to identification and authentication? Does it somehow copy the USB mouse/keyboard setup?

PS: Can anyone tell me if the Wifi Arduinos (Uno WiFi rev2) also have Bluetooth embedded?

  [1]: https://store.arduino.cc/arduino-leonardo-with-headers
  [2]: https://www.intorobotics.com/pick-right-bluetooth-module-diy-arduino-project/

title: Can an Arduino (Leonardo) be recognized via Bluetooth as a mouse/keyboard?

Answers: 1

body:
> If I buy something like the HC-05 how would the chip report itself?

As an SPP. I.e., a serial port.

> How is the bluetooth stack handled with regards to identification and authentication?

By the firmware on the HC-05

> Does it somehow copy the usb mouse/keyboard setup?

No.

You need a USB device that can emulate a keyboard. That's not the HC-05. The host microcontroller has absolutely nothing to do with what capabilities the bluetooth interface has.


body:
In the code below I would like the stepper to bounce back and forward between two limit switches and while it is doing this it should turn and than wait for e.g. 1 second.

I thought I could achieve this with the `if ((unsigned long)(currentMillis - previousMillis) >= interval)` part, but it doesn't work.It won't turn. Any help would be great. Thank you.

    // defines pins numbers
    const int stepPin = 5;
    const int dirPin = 4;
    const int enPin = 12;
    const int homeSwitchPin = 9;
    const int homeSwitchPin2 = 11;

    unsigned long interval=1000; // the time we need to wait
    unsigned long previousMillis=0; // millis() returns an unsigned long.

    void setup() {

       Serial.begin(9600);

      // Sets the two pins as Outputs
      pinMode(stepPin,OUTPUT);
      pinMode(dirPin,OUTPUT);
      pinMode(homeSwitchPin , INPUT);
      pinMode(homeSwitchPin2 , INPUT);
      pinMode(enPin,OUTPUT);
      digitalWrite(enPin,LOW);

      // Set Dir to Home switch
      digitalWrite(dirPin,LOW); // Enables the motor to move in a particular direction

    }
    void loop() {

        int homeSw = digitalRead( homeSwitchPin);
        int homeSw2 = digitalRead( homeSwitchPin2);

        if( homeSw == HIGH && (digitalRead(dirPin) == LOW) ){
            unsigned long currentMillis = millis();

            if ((unsigned long)(currentMillis - previousMillis) >= interval) {
            motorStep(1);
            previousMillis = millis();
            }
        }
        else if( homeSw == LOW && (digitalRead(dirPin) == LOW) ){
              digitalWrite(dirPin,HIGH);
              delay(2000);
        }

        if( homeSw2 == HIGH && (digitalRead(dirPin) == HIGH)){

            motorStep(1);
            // motorStep(32000);
            //digitalWrite(dirPin,LOW);

            //delay(2000);
        }
        else if( homeSw2 == LOW && (digitalRead(dirPin) == HIGH) ){
              digitalWrite(dirPin,LOW);
              delay(2000);
        }

    }
    void motorStep( int MAX){

       for(int x = 0; x < MAX; x++) {
            digitalWrite(stepPin,HIGH);
            delayMicroseconds(100);
            digitalWrite(stepPin,LOW);
            delayMicroseconds(100);
          }
    }

title: Stepper wait for X seconds in a loop with millis (not delay)

Answers: 0


body:
I'm trying to write an interrupt service routine for an Arduino Mega 2560 to decode a quadrature rotary encoder. I've got an ISR (Interrupt Service Routine) that responds to the falling edge of digital pin 2.

I then need to look at the value of pin 3 and see if it is high or low to tell which direction the encoder is being turned.  I've built a simple debouncing circuit using a couple of resistors and a .01 μF capacitor per line from the encoder, so those signals are clean now.

Based on the reading I've done, it's best to read the pin states directly rather than using digitalRead in an ISR since the `digitalRead()` function is rather slow.

I am finding it hard to find and figure out the port mappings for the port registers to read the pins.

I believe that I should use

`(PIND & (1 << 3) != 0` to read digital pin 3, since I think pins 2-9 are on register PIND?

I found this chart https://www.arduino.cc/en/Hacking/PinMapping2560 that lists the pin mappings for the Mega 2560, but I'm not sure how to read it.

If I use `bool  pinBState =  digitalRead(rotaryPinB) == LOW` in my ISR it works, but it seems to miss state changes sometimes.

If instead I use the code `bool pinBState = (PIND & (1 << 3)) == 0;

The value of `pinBState` never changes.

Can somebody tell me what I'm doing wrong?
---

See the self-answer below. It seems that digital pins 0-7 are read from PINE, not PIND.

However, now I have a new problem:

With the code shown in my answer I am getting readings that increase for clockwise rotation, and decrease for counterclockwise rotation, as expected:

 If I rotate it very slowly through a full revolution, I can usually get exactly 12 steps in a rotation. If I rotate my encoder rapidly, or  through several full turns, it gives me values that aren't exact multiples of 12, and rotating it several turns clockwise, and then the same number of turns counterclockwise does not return the value to 0 like it should.

I'm using a simple debouncing circuit as recommended from the spec sheet for the encoder:

https://www.bourns.com/docs/Product-Datasheets/PEC11R.pdf

The circuit looks like this:

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

Shouldn't that circuit work? I wired it up on a breadboard, and have pretty long leads, and didn't cut the wires on the resistors or capacitors since this is still a test circuit. I wouldn't think this would be sensitive to RF noise though. The only other thing I've got on the project is an I2C LCD display. I've triple-checked my wiring and don't think I've made any mistakes.

I'm stumped as to why an interrupt-driven rotary encoder, with the recommended debouncing circuit,  that reads port registers to read the data from it's PIN B doesn't give reliable results for normal rates of turning on the control.

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

title: Reading a rotary encoder using digital pins of Mega 2560 directly using port registers?

Answers: 2

body:
Ok, it looks like digital pins 0-7 are read from the PINE (That's PIN E) register, not PIND.

I am setting up my pins as input using normal Arduino code:

    #define rotaryPinA 2
    #define rotaryPinB 3

    void setup() {
      attachInterrupt(digitalPinToInterrupt(rotaryPinA), encode, FALLING);

      pinMode(rotaryPinA, INPUT);
      pinMode(rotaryPinB, INPUT);
      //The rest of the setup function
    }

And then my encode method:

    void encode() {
      rotaryValueChanged = true;
      //Read my PinB (Digital Pin 3) using port register PINE, 5th bit
      bool pinBState = (PINE & (1 << 5)) == 0;
      //Here is the equivalent code using digitalRead:
      //bool  pinBState =  digitalRead(rotaryPinB) == LOW;
      rotaryValue +=  pinBState ? -1 : 1;
    }

That code seems to work, but the value I'm getting from my rotary encoder drifts.

body:
Have you tried some hardware denouncers - like [MC14490](https://www.onsemi.com/pub/Collateral/MC14490-D.PDF)?
Using Interrupts you can then detect all four phases of each encoder step.


body:
I have a sketch that uses two timers using millis() from a library I created to keep time. The timers seem to be working correctly, but when I print the start time of each timer, it is clearly wrong.

E.g. the timer is set to run for 3 seconds. When I start the timer the first time, it reads that it started at 0. The next time I start the timer, right after it has finished running once, it reads that it started at 2 seconds. This should not be possible.

I have even tried timing it on my phone, and have seen the timerStart value read 5 seconds, when the sketch has been running for 10.

Does anyone have any idea what could be going wrong? Code below.

Here is the library's .h file:

    #ifndef Timer_h
    #define Timer_h

    #include <Arduino.h>

    class Timer {
      public:
        Timer(unsigned long timerLength);
        unsigned long timerStart;
        unsigned long timeElapsed;
        boolean isFinished = true;
        boolean timerStarted = false;
        void startTimer();
        void checkTimer();
      private:
        unsigned long _timerLength;
    };

    #endif

Here is the library's .cpp file:

    #include <Arduino.h>
    #include <Timer.h>

    Timer::Timer(unsigned long timerLength) {
      _timerLength = timerLength;
    }

    void Timer::startTimer() {
      if (!timerStarted) {
        timerStart = millis();
        timerStarted = true;
      }
    }

    void Timer::checkTimer() {
      timeElapsed = millis() - timerStart;
      if (timeElapsed >= _timerLength) {
        isFinished = true;
        timerStarted = false;
      } else {
        isFinished = false;
      }
    }

And here is part of my sketch code, where the timerStart value is wrong:

    #include <Timer.h>

    Timer breathTimer(3000);
    Timer betweenTimer(1000);

    // this part determines if a turbine is spinning or not
    SIGNAL(TIMER0_COMPA_vect) {
      uint8_t x = digitalRead(FLOWSENSORPIN);

      //if the turbine is spinning
      if (x == HIGH) {

        //start the breath timer
        if (betweenTimer.isFinished) {
          if (breathTimer.isFinished) {
            Serial.print("Breath Timer Started @ ");
            Serial.println(breathTimer.timerStart);
          }
          breathTimer.startTimer();
        }
      }
    }

    void setup() {
       Serial.begin(9600);
       pinMode(FLOWSENSORPIN, INPUT);
       digitalWrite(FLOWSENSORPIN, HIGH);
       betweenTimer.isFinished = true;
    }

    void loop() {

      // check the breath timer
      if (breathTimer.timerStarted) {
        breathTimer.checkTimer();
        if (breathTimer.isFinished) {
          Serial.println("Breath Timer is Finished");
          betweenTimer.startTimer();
          Serial.println("Between Timer Started");
        }
      }

      if (betweenTimer.timerStarted) {
        betweenTimer.checkTimer();
        if (betweenTimer.isFinished) {
          Serial.println("Between Timer is Finished");
        }
      }
    }

title: Millis() is Not Working

Answers: 0


body:
I'm doing a project where my `Arduino` uses an external `ESP8266` wifi module (with `AT` firmware) to send http requests and receive server response.

I'm trying to get an NBA scoreboard, and here's what my Arduino sends to ESP:

```
> AT+CIPSTART=0,"TCP","data.nba.net",80
0,CONNECT

OK

> AT+CIPSEND=0,103
SEND OK

> GET /data/10s/prod/v1/20190214/scoreboard.json HTTP/1.1
Host: data.nba.net
Connection: keep-alive

+IPD,0,1460:HTTP/1.1 200 OK..
.............................
...here comes the response...
.............................
```

Now the code works fine, and I'm able to get the `json` file needed. The problem is that the response is sometimes too long and the file gets truncated, thus the response is incomplete. The file itself is sometimes pretty large, but I only need a few numbers from it (current teams + current score). So my questions are:

1. I use `readString()` method (of `SoftwareSerial` object instance) to read the response. Is there a way to parse the response chunk by chunk without loading everything in my ESP memory?
2. Is there a way to limit the response?
3. Are there any alternatives to the method I'm using? Maybe parsing the website (`nba.com` or `espn.com/nba`) directly? If so, how can I do that?
4. Maybe there's a way to write a separate (free) online API to parse `json`, constraint the response and send the small version upon request?

__PS.__ I tried doing the same without `AT` firmware, flashing the module with a code that used `HTTPClient` directly (with `ESP8266WiFi.h` and `ESP8266HTTPClient.h` libraries):
```
HTTPClient http;
http.begin(request);
if (http.GET() > 0) {
    response = http.getString();
}
http.end();
```
That didn't help much. I'm still running out of memory since I'm directly loading the response to memory with `getString()`.

__PPS.__ Just in case it matters, I'm using `ATmega2560` and a small `ESP-01` module (similar to [this][1]).

  [1]: https://cdn.instructables.com/FE9/58ZS/IJX7FON7/FE958ZSIJX7FON7.LARGE.jpg?auto=webp

title: Parse a large json response with ESP8266

Answers: 2

body:
Check out the [Streaming JSON Parser][1]. It's designed to parse large JSON objects on processors with little memory. You'll just read one character at a time from the HTTP connection rather than the whole response; pass the character to the library and it'll call code you provide every time it sees an array, object, key or value. Then you can extract just the pieces you want without the overhead of loading it all in memory at once.

The library has good examples that'll show you how to use it.

  [1]: https://github.com/squix78/json-streaming-parser

body:
Ok, so I was able to do this. Here's the workaround.

Let's say the `GET` response is a flat string containing large `.json` file with all the commas and curly brackets. The idea is to read it byte-by-byte and instead of storing it just find the `key` you need and extract its `value`.

We want to find the field containing, say, "97.5 FM" from `http://data.nba.net/data/10s/prod/v1/20190223/scoreboard.json` (that's at the very end), skip 3 bytes (which is just " | ") and then read and `Serial.print` 4 bytes (which is "1280")*. We would do something like this (of course make sure to connect to wifi and include `<ESP8266HTTPClient.h>`:

    HTTPClient http;
    http.begin("http://data.nba.net/data/10s/prod/v1/20190223/scoreboard.json");
    int httpCode = http.GET();
    if (httpCode == HTTP_CODE_OK)
      Serial.println(getValue(http, "97.5 FM", 3, 4));

where the `getValue()` function is defined as follows:

    String getValue(HTTPClient &http, String key, int skip, int get) {
      bool found = false, look = false;
      int ind = 0;
      String ret_str = "";

      int len = http.getSize();
      char char_buff[1];
      WiFiClient * stream = http.getStreamPtr();
      while (http.connected() && (len > 0 || len == -1)) {
        size_t size = stream->available();
        if (size) {
          int c = stream->readBytes(char_buff, ((size > sizeof(char_buff)) ? sizeof(char_buff) : size));
          if (len > 0)
            len -= c;
          if (found) {
            if (skip == 0) {
              ret_str += char_buff[0];
              get --;
            } else
              skip --;
            if (get <= 0)
              break;
          }
          else if ((!look) && (char_buff[0] == key[0])) {
            look = true;
            ind = 1;
          } else if (look && (char_buff[0] == key[ind])) {
            ind ++;
            if (ind == key.length()) found = true;
          } else if (look && (char_buff[0] != key[ind])) {
            ind = 0;
            look = false;
          }
        }
      }
      return ret_str;
    }

You can call this `getValue()` whatever many times you like, but the strings you're looking for need to be only after each other, because the response to `GET` is read byte-by-byte just once.

There is probably (i.e., most likely) a better way of doing this, but this approach works and it's pretty fast, so...

---
\* This, of course, is just an example, and you can overload this `getValue()` function definition to, say, read until it gets a curly bracket or whatever.


body:
I am using Arduino Uno as a Master Device and 3 Arduino Unos as slave devices.

I am sending data from each slave to master after every 3 seconds continuously, and is going to execute further logic accordingly.

I have been using a lot of libraries to test this scenario.
There are libraries which are using SoftwareSerial and HardwareSerial too, but these libraries are not working for me when i have multiple slaves and one master (It is only working with one master and one slave).

Please suggest me a better library which would be useful in my scenario.

**Wiring Diagram:**
[![Wiring Diagram][1]][1]

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

title: Arduino master/slave communication using RS485

Answers: 2

body:
First of all, your connection is just wrong, you should make the RS-485 bus as a straight line, with a 120 ohm resistor at the beginning and another one at the end. Each slave should tap into that line as close as possible to that line, look for datasheets and you will understand what I am talking about.

Second, you can use Modbus as a pretty good and easy to use communication protocol.

body:
RS485 module has resistor 120 Ohm inside

[![RS485 module diagram][1]][1]

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


body:
    #include<LiquidCrystal.h>
    LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

    #include <SoftwareSerial.h>
    SoftwareSerial gps(10,11); // RX, TX

    //String str="";
    char str[70];
    String gpsString="";

    char *test="$GPGGA";

    String latitude="No Range      ";
    String longitude="No Range     ";

    int temp=0,i;
    boolean gps_status=0;

    void setup()
    {
      lcd.begin(16,2);
      Serial.begin(9600);
      gps.begin(9600);

      lcd.print("Vehicle Tracking");
      lcd.setCursor(0,1);
      lcd.print("    System      ");
      delay(2000);
      gsm_init();
      lcd.clear();
      Serial.println("AT+CNMI=2,2,0,0,0");
      lcd.print("GPS Initializing");
      lcd.setCursor(0,1);
      lcd.print("  No GPS Range  ");
      get_gps();
      delay(2000);
      lcd.clear();
      lcd.print("GPS Range Found");
      lcd.setCursor(0,1);
      lcd.print("GPS is Ready");
      delay(2000);
      lcd.clear();
      lcd.print("System Ready");
      temp=0;
    }

    void loop()
    {
      serialEvent();
      if(temp)
      {
        get_gps();
        tracking();
      }
    }

    void serialEvent()
    {
      while(Serial.available())
      {
        if(Serial.find("Track Vehicle"))
        {
          temp=1;
          break;
        }
        else
        temp=0;
      }
    }

    void gpsEvent()
    {
      gpsString="";
      while(1)
      {
       while (gps.available()>0)            //checking serial data from GPS
       {
        char inChar = (char)gps.read();
         gpsString+= inChar;                    //store data from GPS into gpsString
         i++;
         if (i < 7)
         {
          if(gpsString[i-1] != test[i-1])         //checking for $GPGGA sentence
          {
            i=0;
            gpsString="";
          }
         }
        if(inChar=='\r')
        {
         if(i>65)
         {
           gps_status=1;
           break;
         }
         else
         {
           i=0;
         }
        }
      }
       if(gps_status)
        break;
      }
    }

    void gsm_init()
    {
      lcd.clear();
      lcd.print("Finding Module..");
      boolean at_flag=1;
      while(at_flag)
      {
        Serial.println("AT");
        while(Serial.available()>0)
        {
          if(Serial.find("OK"))
          at_flag=0;
        }

        delay(1000);
      }

      lcd.clear();
      lcd.print("Module Connected..");
      delay(1000);
      lcd.clear();
      lcd.print("Disabling ECHO");
      boolean echo_flag=1;
      while(echo_flag)
      {
        Serial.println("ATE0");
        while(Serial.available()>0)
        {
          if(Serial.find("OK"))
          echo_flag=0;
        }
        delay(1000);
      }

      lcd.clear();
      lcd.print("Echo OFF");
      delay(1000);
      lcd.clear();
      lcd.print("Finding Network..");
      boolean net_flag=1;
      while(net_flag)
      {
        Serial.println("AT+CPIN?");
        while(Serial.available()>0)
        {
          if(Serial.find("+CPIN: READY"))
          net_flag=0;
        }
        delay(1000);
      }
      lcd.clear();
      lcd.print("Network Found..");
      delay(1000);
      lcd.clear();
    }

    void get_gps()
    {
       gps_status=0;
       int x=0;
       while(gps_status==0)
       {
        gpsEvent();
        int str_lenth=i;
        latitude="";
        longitude="";
        int comma=0;
        while(x<str_lenth)
        {
          if(gpsString[x]==',')
          comma++;
          if(comma==2)        //extract latitude from string
          latitude+=gpsString[x+1];
          else if(comma==4)        //extract longitude from string
          longitude+=gpsString[x+1];
          x++;
        }
        int l1=latitude.length();
        latitude[l1-1]=' ';
        l1=longitude.length();
        longitude[l1-1]=' ';
        lcd.clear();
        lcd.print("Lat:");
        lcd.print(latitude);
        lcd.setCursor(0,1);
        lcd.print("Long:");
        lcd.print(longitude);
        i=0;x=0;
        str_lenth=0;
        delay(2000);
       }
    }

    void init_sms()
    {
      Serial.println("AT+CMGF=1");
      delay(400);
      Serial.println("AT+CMGS=\"+91**********\"");   // use your 10 digit cell no. here
      delay(400);
    }

    void send_data(String message)
    {
      Serial.println(message);
      delay(200);
    }

    void send_sms()
    {
      Serial.write(26);
    }

    void lcd_status()
    {
      lcd.clear();
      lcd.print("Message Sent");
      delay(2000);
      lcd.clear();
      lcd.print("System Ready");
      return;
    }

    void tracking()
    {
        init_sms();
        send_data("Vehicle Tracking Alert:");
        send_data("Your Vehicle Current Location is:");
        Serial.print("Latitude:");
        send_data(latitude);
        Serial.print("Longitude:");
        send_data(longitude);
        send_data("Please take some action soon..\nThankyou");
        send_sms();
        delay(2000);
        lcd_status();
    }![enter image description here](https://i.stack.imgur.com/S5fc6.jpg)

title: How can I use my sim808 as Both GPS and GSM module for this code

Answers: 0


body:
Just got a Arduino Leonardo (with headers) dropped in my lap this week. I've tried experimenting with the Arduino C++ IDE and find it awkward. I have some previous experience with Forth and would like to try loading amforth directly onto the ATmega32u4 microcontroller.

I found some "how to" information on the web but find it confusing and contradictory. Can anyone point to some easy to follow instructions? I'd greatly appreciate it!

In case it matters, my development box is a Fedora 29 workstation.

title: Trying to install amforth on Leonardo board

Answers: 0


body:
I'm newbie with Arduino and need to do a short task: read data from SPI (sent by another microcontroller) and send to WiFi (by ESP32-WROOM-32).

I can't understand how to initialize and read data from SPI. I'm using VSPI. I need to use VSPI class? Or a SPI class?

Any idea will help me a lot.

Thanks

title: Reading data from SPI on ESP32-WROOM-32

Answers: 0


body:
I've been hitting against a wall for over a week now.  My current project is to use a Teensy 3.6 to send data over an SPI bus to a chip which is effective going to be a signal generator.  I've made a GUI in Matlab to control this function generator in 'real-time' by sending over values such as frequency and amplitude.  For my initial case, I just want to output a sine wave.  to do this I am using the built in math function sin and just getting the amplitude and frequency from Matlab.  However, when I send over my data I'm getting nothing on the output, but when I hard program in the values, it works just fine.  From this I assume I am not sending the data over correctly OR not converting it correctly upon receiving it.

My order of operations are:

1.  send my variable to the Teensy 3.6 using fwrite in Matlab

        serialID = serial('COM5','BaudRate',115200);
        fopen(serialID);
        val = 2.55;
        fwrite(serialID, val, 'double');

2. receiving the data on the Teensy 3.6 using Serial.read()

        byte temp[8];

        for (int c = 0; c<8; c++){
            temp[c] =Serial.read();
        }

3. converting my byte array to a double using a union

        double byteToDouble(byte DoubleInBytes[8]) {
            //Receives 8 bytes values and return them into a double value

            union {
               double   Out;
               byte   In[8];
            } U ;

            for (int c = 0; c < 8; c++) {
                U.In[c] = DoubleInBytes[c];
            }

            return U.Out;
        }

I'm at a loss as to what I might be doing wrong.  I've tried to use the serial monitor to monitor variable states but I can't use that while Matlab is using the COM port.

Any helpful tips would be appreciated.

title: Sending double data from Matlab to the Teensy 3.6 via the microUSB

Answers: 1

body:
I got a bit more traction on this issue on the Arduino forums and was able to answer it over there.  I'm posting the link here to complete this post with a working answer.  Hope it helps!

https://forum.arduino.cc/index.php?topic=598595.new#new

Thanks!


body:
I have one problem with my code and I'm a beginner and I can't solve it. Can you help me? Thank you so much.

I have this problem:

    error: expected unqualified-id before '{' token

And this is my code:

    int trigPin = 12;
    int echoPin = 11;
    long timeperiod, cm;
    const int analogOutPin = 9;
    int brightness;

    void setup()
    {
      Serial.begin(9600);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    }

    void loop(){

      if (timeperiod > 50)
      analogWrite(analogOutPin,0);
    }
    {

      if (timeperiod 10 < 50){
      for(brightness = 0; brightness < 256; brightness++){
        analogWrite(led,brightness);
        delay(10);}
    }}
      if (timeperiod < 10)
      analogWrite(analogOutPin,0);

    {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(20);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(0);
      digitalWrite(trigPin, LOW);

      timeperiod = pulseIn(echoPin, HIGH);

      cm = microsecondsToCentimeters(timeperiod);
      Serial.print("dist=");
      Serial.print(cm);
      Serial.println();

      delay(10);
    }
    long microsecondsToInches(long microseconds)
    {
      return microseconds / 74 /2;
    }
      long microsecondsToCentimeters(long microseconds)
    {
      return microseconds / 29/ 2;
    }

title: Problem with a code

Answers: 3

body:
For example, the first 5 lines:

    void loop(){

      if (timeperiod > 50)
      analogWrite(analogOutPin,0);
    }
    {

Always align your braces, you can do it like this:

     xxx {
        yyy
     }

or

     xxx
     {
        yyy
     }

where xxx and yyy can be one or more statements.

If you align the first 5 lines correctly, you see you should add a {:

    if (timeperiod > 50)
    { // <- added
        analogWrite(analogOutPin,0);
    }

Also, if you have an if, for or while statement, ALWAYS add brackets, even if it is only one line. Thus:

    if (timeperiod > 50)
        analogWrite(analogOutPin,0);

should be written as

    if (timeperiod > 50)
    {
        analogWrite(analogOutPin,0);
    }

This is not a mandatory rule, but if you later misindent something, or add a new line in the body, it is easily forgotten to add the brackets, so you better can do it beforehand.

So (also), it is wise to

- align brackets (like explained above)
- always use brackets in if/while/loop statements.
- always use the same amount of spaces (or a tab) to indent a new level (e.g. after an if, while, loop, or the body of a function).
- use new lines between functions; this makes it much easier to read
- split up big functions with many brackets, in (sub) functions/methods (not in your case, yet)

body:
Your problems start here:

    void loop(){

      if (timeperiod > 50)
      analogWrite(analogOutPin,0);
    }
    {

You are missing an opening brace for your if statement, and then have an extra opening brace afterwords. Also, any code inside braces should be indented from the code before it:

    void loop(){

      if (timeperiod > 50) {
        analogWrite(analogOutPin,0);
      }

      if (timeperiod 10 < 50){
        for(brightness = 0; brightness < 256; brightness++) {
          analogWrite(led,brightness);
          delay(10);
        }
      }
      //And the rest of your loop function also needs cleanup...

The rest of your loop function needs cleanup as well. You've got bad indentation and mismatched braces all over the place. As @Majenko says in their comment, if you clean up your code formatting then your syntax problems will be obvious.

body: The only problem I can see in your code is that your code modules are starting and ending anywhere. See from where till where you want to run a particular line of code. If you writing this code on arduino IDE you will be able to see which the ending of a particular bracket when you keep the cursor on one.


body:
I'm trying to use ESP32 + Arduino IDE to control a relay.

I've started by using the <WiFi.h> library and the code below.

The problem I'm having:

after clicking on the button and activating the pin, if the browser is left like this, and then the page gets refreshed by mistake, the action will be repeated.

What I thought might help, is if for any click on the button, the pin activates, and then I get a redirect back to the root of the page. so refreshing will not pose any issue.

I've searched allover the internet and could not find anything conclusive, except for this piece of code, which doesnt seem to make any difference nomatter where I place it in the main code

    client.println("HTTP/1.1 307 Temporary Redirect");
    client.println("Location: /");
    client.println("Connection: Close");
    client.println();
    client.stop();

and this is the main code:

    // Load Wi-Fi library
    #include <WiFi.h>

    // Replace with your network credentials
    const char* ssid     = "WalrusnTiny";
    const char* password = "994483329I";

    // Set web server port number to 80
    WiFiServer server(80);

    // Variable to store the HTTP request
    String header;

    // Auxiliar variables to store the current output state
    String output26State = "off";
    String output27State = "off";

    // Assign output variables to GPIO pins
    const int output26 = 26;
    const int output27 = 27;

    void setup() {

      Serial.begin(115200);
      // Initialize the output variables as outputs
      pinMode(output26, OUTPUT);
      pinMode(output27, OUTPUT);
      // Set outputs to LOW
      digitalWrite(output26, LOW);
      digitalWrite(output27, LOW);

      // Connect to Wi-Fi network with SSID and password
      Serial.print("Connecting to ");
      Serial.println(ssid);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      // Print local IP address and start web server
      Serial.println("");
      Serial.println("WiFi connected.");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
      server.begin();
    }

    void loop(){
      WiFiClient client = server.available();   // Listen for incoming clients

      if (client) {                             // If a new client connects,
        Serial.println("New Client.");          // print a message out in the serial port
        String currentLine = "";                // make a String to hold incoming data from the client
        while (client.connected()) {            // loop while the client's connected
          if (client.available()) {             // if there's bytes to read from the client,
            char c = client.read();             // read a byte, then
            Serial.write(c);                    // print it out the serial monitor
            header += c;
            if (c == '\n') {                    // if the byte is a newline character
              // if the current line is blank, you got two newline characters in a row.
              // that's the end of the client HTTP request, so send a response:
              if (currentLine.length() == 0) {
                // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                // and a content-type so the client knows what's coming, then a blank line:
                client.println("HTTP/1.1 200 OK");
                client.println("Content-type:text/html");
                client.println("Connection: close");
                client.println();

                // turns the GPIOs on and off
                if (header.indexOf("GET /26/on") >= 0) {
                  client.println();
                  output26State = "on";
                  digitalWrite(output26, HIGH);

                } else if (header.indexOf("GET /26/off") >= 0) {
                  Serial.println("GPIO 26 off");
                  output26State = "off";
                  digitalWrite(output26, LOW);

                } else if (header.indexOf("GET /27/on") >= 0) {
                  Serial.println("GPIO 27 on");
                  output27State = "on";
                  digitalWrite(output27, HIGH);

                } else if (header.indexOf("GET /27/off") >= 0) {
                  Serial.println("GPIO 27 off");
                  output27State = "off";
                  digitalWrite(output27, LOW);
                }

                // Display the HTML web page
                client.println("<!DOCTYPE html>");
                client.println("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                client.println("<link rel=\"icon\" href=\"data:,\">");
                // CSS to style the on/off buttons
                // Feel free to change the background-color and font-size attributes to fit your preferences
                client.println("");

                // Web Page Heading
                client.println("
ESP32 Web Server
");
                // Display current state, and ON/OFF buttons for GPIO 26
                client.println("
GPIO 26 - State " + output26State + "
");
                // If the output26State is off, it displays the ON button
                if (output26State=="off") {
                  client.println("
<button class=\"button\">ON</button>
");
                } else {
                  client.println("
<button class=\"button button2\">OFF</button>
");
                }

                // Display current state, and ON/OFF buttons for GPIO 27
                client.println("
GPIO 27 - State " + output27State + "
");
                // If the output27State is off, it displays the ON button
                if (output27State=="off") {
                  client.println("
<button class=\"button\">ON</button>
");
                } else {
                  client.println("
<button class=\"button button2\">OFF</button>
");
                }
                client.println("");

                // The HTTP response ends with another blank line
                client.println();
                // Break out of the while loop
                break;
              } else { // if you got a newline, then clear currentLine
                currentLine = "";
              }
            } else if (c != '\r') {  // if you got anything else but a carriage return character,
              currentLine += c;      // add it to the end of the currentLine
            }
          }
        }
        // Clear the header variable

        header = "";
        // Close the connection

        Serial.println("Client disconnected.");
        Serial.println("");
      }
    }

Any help would be greatly appreciated.
Thank you in advance.

title: Arduino IDE + ESP32 Webserver - how to redirect to root after click on button

Answers: 2

body:
Solved:

Just needed to add this code to every button press,

     client.print("<HEAD>");
     client.print("<meta http-equiv=\"refresh\" content=\"0;url=/\">");
     client.print("</head>");

body:
First probably mention this is too much overhead for a webserver

adding

    include <WebServer.h>

you can handle those endpoints easily

See https://lastminuteengineers.com/creating-esp32-web-server-arduino-ide/

Basically:

```
setup() {
  ...
  server.on("/", handle_OnConnect);
  server.on("/led1on", handle_led1on);
  server.on("/led1off", handle_led1off);
  server.on("/led2on", handle_led2on);
  server.on("/led2off", handle_led2off);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP server started");
}

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

void handle_led1on() {
  LED1status = HIGH;
  Serial.println("GPIO4 Status: ON");
  server.send(200, "text/html", SendHTML(true,LED2status));
}

```

Anyway this is still wrong, as you end with same problem, `/led1on` renders as your main page

A better solution would be to use this endpoint handlers to set the variable and just redirect:

Here a complete solution

```
#include <WiFi.h>
include <WebServer.h>

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "password";

// Set web server port number to 80
WebServer server(80);

uint8_t led1Pin = 12;
uint8_t led2Pin = 13;

bool led1State = LOW;
bool led2State = LOW;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  // Set outputs to LOW
  led1State = LOW;
  led2State = LOW;
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", handle_root);
  server.on("/led/1/on", handle_led1on);
  server.on("/led/1/off", handle_led1off);
  server.on("/led/2/on", handle_led2on);
  server.on("/led/2/off", handle_led2off);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP Server started");
}

void handle_root() {
  server.send(200, "text/html", sendHTML());
}

void handle_led1on() {
  led1State = HIGH;
  Serial.println("led1 state: ON");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_led1off() {
  led1State = LOW;
  Serial.println("led1 state: OFF");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_led2on() {
  led2State = HIGH;
  Serial.println("led2 state: ON");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_led2off() {
  led2State = LOW;
  Serial.println("led2 state: OFF");
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_NotFound() {
  server.send(404, "text/html", sendPageUnknown());
}

String sendPageUnknown() {
    String ptr = "<!DOCTYPE html> <html>\n";

  ptr += "<head>";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  //ptr += "<meta http-equiv=\"refresh\" content=\"0;url=/\">";

  ptr += "<title>Page unknown</title>\n";

  ptr += "</head>\n";

  ptr += "<body>\n";
  ptr += "<h1>Page unknown</h1>\n";

  ptr += "<a href=\"/\">Return to main page</a>\n";

  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}

String sendHTML() {
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  String ptr = "<!DOCTYPE html> <html>\n";

  ptr += "<head>";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";

  ptr += "<title>LED Dashboard</title>\n";

  ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
  ptr += ".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
  ptr += ".button-on {background-color: #3498db;}\n";
  ptr += ".button-on:active {background-color: #2980b9;}\n";
  ptr += ".button-off {background-color: #34495e;}\n";
  ptr += ".button-off:active {background-color: #2c3e50;}\n";
  ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr += "</style>\n";
  ptr += "</head>\n";

  ptr += "<body>\n";
  ptr += "<h1>ESP32 Web Server</h1>\n";

  if (led1State)
  {
    ptr += "<p>LED1: ON</p><a class=\"button button-off\" href=\"/led/1/off\">OFF</a>\n";
  }
  else
  {
    ptr += "<p>LED1: OFF</p><a class=\"button button-on\" href=\"/led/1/on\">ON</a>\n";
  }

  if (led2State)
  {
    ptr += "<p>LED2: ON</p><a class=\"button button-off\" href=\"/led/2/off\">OFF</a>\n";
  }
  else
  {
    ptr += "<p>LED2: OFF</p><a class=\"button button-on\" href=\"/led/2/on\">ON</a>\n";
  }

  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}

void loop() {
  server.handleClient();
}
```

Even that is suboptimal, as led endpoints shouldn't be GET endpoints but POST (really PUT as it only updates info, but let's stick to POST for simplicity)

Here a version using POST and unique endpoint /led to handle any number of less to manage:

```
#include <WebServer.h>

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "password";

// Set web server port number to 80
WebServer server(80);

uint8_t led1Pin = 12;
uint8_t led2Pin = 13;

bool led1State = LOW;
bool led2State = LOW;

void setup() {
  Serial.begin(115200);
  // Initialize the output variables as outputs
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  // Set outputs to LOW
  led1State = LOW;
  led2State = LOW;
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", handle_root);
  server.on("/led", HTTP_POST, handle_led);
  server.onNotFound(handle_NotFound);

  server.begin();
  Serial.println("HTTP Server started");
}

void handle_root() {
  server.send(200, "text/html", sendHTML());
}

uint8_t evaluate_led_state(String ledState) {
  uint8_t state;
  if (ledState == "on") {
    Serial.println("led state: ON");
    state = HIGH;
  } else if (ledState == "off") {
    Serial.println("led state: OFF");
    state = LOW;
  } else {
    Serial.println("unknow led state: "+ledState);
  }
  return state;
}

void handle_led() {
  String ledPin = server.arg("ledPin");
  String ledState = server.arg("ledState");

  if (ledPin == "1") {
    Serial.println("setting led1");
    led1State = evaluate_led_state(ledState);
  } else if (ledPin == "2") {
    Serial.println("setting led2");
    led2State = evaluate_led_state(ledState);
  } else {
    Serial.println("led unknow: "+ledPin);
  }
  server.sendHeader("Location", "/",true);
  server.send(302, "text/plain", "");
}

void handle_NotFound() {
  server.send(404, "text/html", sendPageUnknown());
}

String sendPageUnknown() {
    String ptr = "<!DOCTYPE html> <html>\n";

  ptr += "<head>";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";

  ptr += "<title>Page unknown</title>\n";

  ptr += "</head>\n";

  ptr += "<body>\n";
  ptr += "<h1>Page unknown</h1>\n";

  ptr += "<a href=\"/\">Return to main page</a>\n";

  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}

String build_led_form(String ledPin, uint8_t ledState) {
  String ptr = "<form action=\"led\" method=\"post\">\n";
  ptr += "  <input type=\"hidden\" name=\"ledPin\" value=\""+ledPin+"\">\n";

  String ledStateStr;

  if (ledState)
  {
    ledStateStr = "off";
  }
  else
  {
    ledStateStr = "on";
  }

  ptr += "  <input type=\"hidden\" name=\"ledState\" value=\""+ledStateStr+"\">\n";
  ptr += "  <label>Led"+ledPin+"</label>\n";
  ptr += "  <input type=\"submit\" class=\"button button-"+ledStateStr+"\" value=\"";
  ledStateStr.toUpperCase();
  ptr += ledStateStr+"\">\n";

  ptr += "</form>\n";
  return ptr;
}

String sendHTML() {
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

  String ptr = "<!DOCTYPE html> <html>\n";

  ptr += "<head>";

  ptr += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";

  ptr += "<title>LED Dashboard</title>\n";

  ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;} form {margin-bottom: 30px;}\n";
  ptr += ".button {display: block;width: 80px;background-color: #3498db;border: none;color: white;text-decoration: none;font-size: 25px;margin: auto;cursor: pointer;border-radius: 4px;}\n";
  ptr += ".button-on {background-color: #3498db;}\n";
  ptr += ".button-on:active {background-color: #2980b9;}\n";
  ptr += ".button-off {background-color: #34495e;}\n";
  ptr += ".button-off:active {background-color: #2c3e50;}\n";
  ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
  ptr += "</style>\n";
  ptr += "</head>\n";

  ptr += "<body>\n";
  ptr += "<h1>ESP32 Web Server</h1>\n";

  ptr += build_led_form("1", led1State);
  ptr += build_led_form("2", led2State);

  ptr += "</body>\n";
  ptr += "</html>\n";
  return ptr;
}

void loop() {
  server.handleClient();
}
```

For non trivial management you probably want to use spiffs

https://randomnerdtutorials.com/esp32-web-server-spiffs-spi-flash-file-system/


body: I have a project I am working on where I need to check the pressure on a gauge using a camera. I am familiar with a little openCV programming using a laptop webcam. However, for this application, I need to use a camera and a micro-controller. The camera needs to take a picture of the pressure gauge and check if it is between certain values. If it is so, the micro-controller sends a true or a false to a PLC. The first thought I had was to use an Arduino because the software is easily available as well as easy to use. However, an Arduino may not have the image processing capability is what I read online. Can someone please suggest a micro-controller suitable for this application. Also, is it possible to send signals to a PLC from the micro-controller?

title: Image Processing

Answers: 3

body:
> However, an Arduino may not have the image processing capability is what I read online.

Correct. An 8-bit Arduino cannot store a big enough image and process it.

> Can someone please suggest a micro-controller suitable for this application.

One of the 32-bit offerings from Arduino or any of the many third-party board makers (Teensy, chipKIT, STM32, etc) may be up to the job.

Your main concern will be memory (RAM). The more memory you have the bigger the image you can store and process.

The actual processing will probably be simple enough if the colours of the different things are obvious enough - for instance if the pointer is red and the background (in the target area) is black, then if there is red within the target area the pointer is there.

> Also, is it possible to send signals to a PLC from the micro-controller?

Probably. That all depends on how the PLC communicates.

body:
If you want to use and Arduino (even if faster chip with more RAM would be better), there is an option: the small camera module Ov7670 is available in two versions. One just take pictures get them and send them immediatly which is a big challenge in terme of time and will certainly not give you enought time to analyse but the "FIFO" version of the Ov7670 has a buffer in which the module store the image.
So you can ask it to "take a photo" and then you have time to get the data.

Of course, it's impossible to retrieve the full picture and you'll have to check it pixel per pixel or maybe line per line.

body:
I recommend using a Raspberry Pi or perhaps Arduino Yun for this project. They are both Linux computers and will have much more processing power to do image processing.

I'm sure there's a way to send signals into a PLC, but I don't know how PLCs communicate, and you haven't provided any user manuals or data sheets for one, so I can't explain any details at this time.


body:
Poking through the example code of SDFS, I saw the following:

    static ArduinoOutStream cout(Serial);
    // F stores strings in flash to save RAM
    cout << F("\ntype any character to start\n");
What exactly is << doing in this case? Moreover, F seems to never be defined prior to this. This seems like a useful trick, but I don't understand how it works.

full code available here: https://github.com/greiman/SdFs/blob/master/examples/SdInfo/SdInfo.ino

title: Unusual use of << operator... not a bit shift?

Answers: 2

body:
> What exactly is << doing in this case?

It's directing the data into an output device (stream).

* http://www.cplusplus.com/doc/tutorial/basic_io/

Yes, it's confusing using the same symbols for more than one thing...

> Moreover, F seems to never be defined prior to this.

`F()` is a macro. It's defined by the Arduino core in WString.h:

    #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

body:
To address your confusion with the bitshift operator;

It indeed is commonly used as a the arithmetic operator for bitshift, but appears to be 'overloaded', so that when used with streams, it is an 'insertion operator'.

> In particular, stream insertion and stream extraction overloads of
> operator<< and operator>> return T&.

https://en.cppreference.com/w/cpp/language/operator_arithmetic

Basically there would be two definitions of the "<<" operator function:

    function <<(integer){//Shift bits}
    function <<(stream){//Join streams}