# Question
Title: ESP12E Soft WDT reset stack trace leads to libraries
Im using **ESP12E DevKit v2** (esp8266 wifi module) board for controlling relays and displaying DHT22 temp,humidity on web server. It runs smoothly when the web client is closed but when i leave the website on for like a 20mins it crashes. I have installed the ESPdecoder and the stack trace always leads mostly to libraries. I tried using ***ESP.wdtDisable(); ESP.wdtEnable(WDTO\_8S);*** commands and ***yield();*** function but doesnt make any difference.

How can i fix this or what am i doing wrong in the code?

```
Soft WDT reset

>>>stack>>>

ctx: sys
sp: 3fffed40 end: 3fffffb0 offset: 01b0
3fffeef0:  3ffe93dc c84524b8 60000600 4020ea06
3fffef00:  00000000 3ffeda08 00000000 00000000
3fffef10:  4022d488 3ffeda08 3ffee9c0 60000600
3fffef20:  4022fdd1 3ffeda08 3ffee9c0 c84550ad
3fffef30:  4022fe16 3fffdab0 00000000 3fffdcb0
3fffef40:  3ffee9d0 3fffdab0 00000000 40206223
3fffef50:  40000f49 40000f49 3fffdab0 40000f49
3fffef60:  40000e19 40001878 00000002 00000000
3fffef70:  3fffff10 aa55aa55 000000f0 40104ba0
3fffef80:  40104ba6 00000002 00000000 3715d4f6
3fffef90:  4010000d 0e060f10 942b6d57 69e0d507
3fffefa0:  40100b40 3fffef3c 40100aed 3ffffea8
3fffefb0:  3fffffc0 00000000 00000000 feefeffe
3fffefc0:  feefeffe feefeffe feefeffe feefeffe
3fffefd0:  feefeffe feefeffe feefeffe feefeffe
3fffefe0:  feefeffe feefeffe feefeffe feefeffe
3fffeff0:  feefeffe feefeffe feefeffe feefeffe
3ffff000:  feefeffe feefeffe feefeffe feefeffe
3ffff010:  feefeffe feefeffe feefeffe feefeffe
3ffff020:  feefeffe feefeffe feefeffe feefeffe
3ffff030:  feefeffe feefeffe feefeffe feefeffe
3ffff040:  feefeffe feefeffe feefeffe feefeffe
3ffff050:  feefeffe feefeffe feefeffe feefeffe
3ffff060:  feefeffe feefeffe feefeffe feefeffe
3ffff070:  feefeffe feefeffe feefeffe feefeffe
3ffff080:  feefeffe feefeffe feefeffe feefeffe
3ffff090:  feefeffe feefeffe feefeffe feefeffe
3ffff0a0:  feefeffe feefeffe feefeffe feefeffe
3ffff0b0:  feefeffe feefeffe feefeffe feefeffe
3ffff0c0:  feefeffe feefeffe feefeffe feefeffe
3ffff0d0:  feefeffe feefeffe feefeffe feefeffe
3ffff0e0:  feefeffe feefeffe feefeffe feefeffe
3ffff0f0:  feefeffe feefeffe feefeffe feefeffe
3ffff100:  feefeffe feefeffe feefeffe feefeffe
3ffff110:  feefeffe feefeffe feefeffe feefeffe
3ffff120:  feefeffe feefeffe feefeffe feefeffe
3ffff130:  feefeffe feefeffe feefeffe feefeffe
3ffff140:  feefeffe feefeffe feefeffe feefeffe
3ffff150:  feefeffe feefeffe feefeffe feefeffe
3ffff160:  feefeffe feefeffe feefeffe feefeffe
3ffff170:  feefeffe feefeffe feefeffe feefeffe
3ffff180:  feefeffe feefeffe feefeffe feefeffe
3ffff190:  feefeffe feefeffe feefeffe feefeffe
3ffff1a0:  feefeffe feefeffe feefeffe feefeffe
3ffff1b0:  feefeffe feefeffe feefeffe feefeffe
3ffff1c0:  feefeffe feefeffe feefeffe feefeffe
3ffff1d0:  feefeffe feefeffe feefeffe feefeffe
3ffff1e0:  feefeffe feefeffe feefeffe feefeffe
3ffff1f0:  feefeffe feefeffe feefeffe feefeffe
3ffff200:  feefeffe feefeffe feefeffe feefeffe
3ffff210:  feefeffe feefeffe feefeffe feefeffe
3ffff220:  feefeffe feefeffe feefeffe feefeffe
3ffff230:  feefeffe feefeffe feefeffe feefeffe
3ffff240:  feefeffe feefeffe feefeffe feefeffe
3ffff250:  feefeffe feefeffe feefeffe feefeffe
3ffff260:  feefeffe feefeffe feefeffe feefeffe
3ffff270:  feefeffe feefeffe feefeffe feefeffe
3ffff280:  feefeffe feefeffe feefeffe feefeffe
3ffff290:  feefeffe feefeffe feefeffe feefeffe
3ffff2a0:  feefeffe feefeffe feefeffe feefeffe
3ffff2b0:  feefeffe feefeffe feefeffe feefeffe
3ffff2c0:  feefeffe feefeffe feefeffe feefeffe
3ffff2d0:  feefeffe feefeffe feefeffe feefeffe
3ffff2e0:  feefeffe feefeffe feefeffe feefeffe
3ffff2f0:  feefeffe feefeffe feefeffe feefeffe
3ffff300:  feefeffe feefeffe feefeffe feefeffe
3ffff310:  feefeffe feefeffe feefeffe feefeffe
3ffff320:  feefeffe feefeffe feefeffe feefeffe
3ffff330:  feefeffe feefeffe feefeffe feefeffe
3ffff340:  feefeffe feefeffe feefeffe feefeffe
3ffff350:  feefeffe feefeffe feefeffe feefeffe
3ffff360:  feefeffe feefeffe feefeffe feefeffe
3ffff370:  feefeffe feefeffe feefeffe feefeffe
3ffff380:  feefeffe feefeffe feefeffe feefeffe
3ffff390:  feefeffe feefeffe feefeffe feefeffe
3ffff3a0:  feefeffe feefeffe feefeffe feefeffe
3ffff3b0:  feefeffe feefeffe feefeffe feefeffe
3ffff3c0:  feefeffe feefeffe feefeffe feefeffe
3ffff3d0:  feefeffe feefeffe feefeffe feefeffe
3ffff3e0:  feefeffe feefeffe feefeffe feefeffe
3ffff3f0:  feefeffe feefeffe feefeffe feefeffe
3ffff400:  feefeffe feefeffe feefeffe feefeffe
3ffff410:  feefeffe feefeffe feefeffe feefeffe
3ffff420:  feefeffe feefeffe feefeffe feefeffe
3ffff430:  feefeffe feefeffe feefeffe feefeffe
3ffff440:  feefeffe feefeffe feefeffe feefeffe
3ffff450:  feefeffe feefeffe feefeffe feefeffe
3ffff460:  feefeffe feefeffe feefeffe feefeffe
3ffff470:  feefeffe feefeffe feefeffe feefeffe
3ffff480:  feefeffe feefeffe feefeffe feefeffe
3ffff490:  feefeffe feefeffe feefeffe feefeffe
3ffff4a0:  feefeffe feefeffe feefeffe feefeffe
3ffff4b0:  feefeffe feefeffe feefeffe feefeffe
3ffff4c0:  feefeffe feefeffe feefeffe feefeffe
3ffff4d0:  feefeffe feefeffe feefeffe feefeffe
3ffff4e0:  feefeffe feefeffe feefeffe feefeffe
3ffff4f0:  feefeffe feefeffe feefeffe feefeffe
3ffff500:  feefeffe feefeffe feefeffe feefeffe
3ffff510:  feefeffe feefeffe feefeffe feefeffe
3ffff520:  feefeffe feefeffe feefeffe feefeffe
3ffff530:  feefeffe feefeffe feefeffe feefeffe
3ffff540:  feefeffe feefeffe feefeffe feefeffe
3ffff550:  feefeffe feefeffe feefeffe feefeffe
3ffff560:  feefeffe feefeffe feefeffe feefeffe
3ffff570:  feefeffe feefeffe feefeffe feefeffe
3ffff580:  feefeffe feefeffe feefeffe feefeffe
3ffff590:  feefeffe feefeffe feefeffe feefeffe
3ffff5a0:  feefeffe feefeffe feefeffe feefeffe
3ffff5b0:  feefeffe feefeffe feefeffe feefeffe
3ffff5c0:  feefeffe feefeffe feefeffe feefeffe
3ffff5d0:  feefeffe feefeffe feefeffe feefeffe
3ffff5e0:  feefeffe feefeffe feefeffe feefeffe
3ffff5f0:  feefeffe feefeffe feefeffe feefeffe
3ffff600:  feefeffe feefeffe feefeffe feefeffe
3ffff610:  feefeffe feefeffe feefeffe feefeffe
3ffff620:  feefeffe feefeffe feefeffe feefeffe
3ffff630:  feefeffe feefeffe feefeffe feefeffe
3ffff640:  feefeffe feefeffe feefeffe feefeffe
3ffff650:  feefeffe feefeffe feefeffe feefeffe
3ffff660:  feefeffe feefeffe feefeffe feefeffe
3ffff670:  feefeffe feefeffe feefeffe feefeffe
3ffff680:  feefeffe feefeffe feefeffe feefeffe
3ffff690:  feefeffe feefeffe feefeffe feefeffe
3ffff6a0:  feefeffe feefeffe feefeffe feefeffe
3ffff6b0:  feefeffe feefeffe feefeffe feefeffe
3ffff6c0:  feefeffe feefeffe feefeffe feefeffe
3ffff6d0:  feefeffe feefeffe feefeffe feefeffe
3ffff6e0:  feefeffe feefeffe feefeffe feefeffe
3ffff6f0:  feefeffe feefeffe feefeffe feefeffe
3ffff700:  feefeffe feefeffe feefeffe feefeffe
3ffff710:  feefeffe feefeffe feefeffe feefeffe
3ffff720:  feefeffe feefeffe feefeffe feefeffe
3ffff730:  feefeffe feefeffe feefeffe feefeffe
3ffff740:  feefeffe feefeffe feefeffe feefeffe
3ffff750:  feefeffe feefeffe feefeffe feefeffe
3ffff760:  feefeffe feefeffe feefeffe feefeffe
3ffff770:  feefeffe feefeffe feefeffe feefeffe
3ffff780:  feefeffe feefeffe feefeffe feefeffe
3ffff790:  feefeffe feefeffe feefeffe feefeffe
3ffff7a0:  feefeffe feefeffe feefeffe feefeffe
3ffff7b0:  feefeffe feefeffe feefeffe feefeffe
3ffff7c0:  feefeffe feefeffe feefeffe feefeffe
3ffff7d0:  feefeffe feefeffe feefeffe feefeffe
3ffff7e0:  feefeffe feefeffe feefeffe feefeffe
3ffff7f0:  feefeffe feefeffe feefeffe feefeffe
3ffff800:  feefeffe feefeffe feefeffe feefeffe
3ffff810:  feefeffe feefeffe feefeffe feefeffe
3ffff820:  feefeffe feefeffe feefeffe feefeffe
3ffff830:  feefeffe feefeffe feefeffe feefeffe
3ffff840:  feefeffe feefeffe feefeffe feefeffe
3ffff850:  feefeffe feefeffe feefeffe feefeffe
3ffff860:  feefeffe feefeffe feefeffe feefeffe
3ffff870:  feefeffe feefeffe feefeffe feefeffe
3ffff880:  feefeffe feefeffe feefeffe feefeffe
3ffff890:  feefeffe feefeffe feefeffe feefeffe
3ffff8a0:  feefeffe feefeffe feefeffe feefeffe
3ffff8b0:  feefeffe feefeffe feefeffe feefeffe
3ffff8c0:  feefeffe feefeffe feefeffe feefeffe
3ffff8d0:  feefeffe feefeffe feefeffe feefeffe
3ffff8e0:  feefeffe feefeffe feefeffe feefeffe
3ffff8f0:  feefeffe feefeffe feefeffe feefeffe
3ffff900:  feefeffe feefeffe feefeffe feefeffe
3ffff910:  feefeffe feefeffe feefeffe feefeffe
3ffff920:  feefeffe feefeffe feefeffe feefeffe
3ffff930:  feefeffe feefeffe feefeffe feefeffe
3ffff940:  feefeffe feefeffe feefeffe feefeffe
3ffff950:  feefeffe feefeffe feefeffe feefeffe
3ffff960:  feefeffe feefeffe feefeffe feefeffe
3ffff970:  feefeffe feefeffe feefeffe feefeffe
3ffff980:  feefeffe feefeffe feefeffe feefeffe
3ffff990:  feefeffe feefeffe feefeffe feefeffe
3ffff9a0:  feefeffe feefeffe feefeffe feefeffe
3ffff9b0:  feefeffe feefeffe feefeffe feefeffe
3ffff9c0:  feefeffe feefeffe feefeffe feefeffe
3ffff9d0:  feefeffe feefeffe feefeffe feefeffe
3ffff9e0:  feefeffe feefeffe feefeffe feefeffe
3ffff9f0:  feefeffe feefeffe feefeffe feefeffe
3ffffa00:  feefeffe feefeffe feefeffe feefeffe
3ffffa10:  feefeffe feefeffe feefeffe feefeffe
3ffffa20:  feefeffe feefeffe feefeffe feefeffe
3ffffa30:  feefeffe feefeffe feefeffe feefeffe
3ffffa40:  feefeffe feefeffe feefeffe feefeffe
3ffffa50:  feefeffe feefeffe feefeffe feefeffe
3ffffa60:  feefeffe feefeffe feefeffe feefeffe
3ffffa70:  00000000 00000000 0000001f 40105379
3ffffa80:  4000050c feefeffe feefeffe feefeffe
3ffffa90:  40222216 00000030 00000010 ffffffff
3ffffaa0:  40218973 3fff0884 00000000 00000000
3ffffab0:  00000a43 00000000 00000a43 3fff07b4
3ffffac0:  00000a43 00000000 00000020 000000fd
3ffffad0:  00000005 00000000 00000020 40101696
3ffffae0:  3ffe96b5 40104a97 3ffed118 40101696
3ffffaf0:  401023ad 3ffed118 3ffed118 40101696
3ffffb00:  00000005 00000000 00000020 40101696
3ffffb10:  3ffe96b5 40104a97 3ffed0f0 4010257e
3ffffb20:  00000002 00000000 00000020 40101696
3ffffb30:  3ffe96b2 40104a7c 3ffece48 4010257e
3ffffb40:  00000001 40103c9f 3ffed878 00000001
3ffffb50:  40104102 c047a314 401029be 00000100
3ffffb60:  00000000 00000000 0000001f 40105379
3ffffb70:  40103be6 00000023 7fffffff 00000002
3ffffb80:  00000123 3ffed118 3ffe9801 00000008
3ffffb90:  40102a5b 00080000 3ffedb88 4010257e
3ffffba0:  00000000 00000000 00002200 4000050c
3ffffbb0:  3fffc278 40102758 3fffc200 00000022
3ffffbc0:  3ffffbd0 3ffe9f6c 3ffe9f6c 00000001
3ffffbd0:  4021bddb 00000030 00000010 ffffffff
3ffffbe0:  4021bddb 00000001 00000000 0000c005
3ffffbf0:  0000024e 00000001 ffff7f72 0000888e
3ffffc00:  000005e0 00000020 401038a1 3ffed830
3ffffc10:  0000013a 00000000 3fff0c70 000000fd
3ffffc20:  0000005a 00000001 401049e2 3ffed830
3ffffc30:  00000000 00000000 00000020 40101696
3ffffc40:  3ffe96b0 40104a7c 3fff034c 3ffed830
3ffffc50:  00000001 40103c9f 3ffed830 40101696
3ffffc60:  40104102 00040000 40229be3 00000001
3ffffc70:  ffffffff 00000000 3ffe9801 00000008
3ffffc80:  40229c32 3ffecdd0 3ffefa4c 00000001
3ffffc90:  40229d3e 3ffecdd0 3ffefa4c 3ffecdd0
3ffffca0:  00000002 00000000 00000020 40101696
3ffffcb0:  3ffe96b2 40228cef 3ffecdd0 3fff0c54
3ffffcc0:  00000000 4021bf97 3ffee2d8 40105379
3ffffcd0:  00000000 00000002 00000000 3ffecdd0
3ffffce0:  3fff1882 4010511f 3fff0c54 3fff01dc
3ffffcf0:  3fff184c 0000002f 00000000 00000001
3ffffd00:  00000004 4020e2d9 3ffef418 3fff01dc
3ffffd10:  3fff1882 00000045 00000001 3ffeefc8
3ffffd20:  3fffff20 3fffff20 0000000a 00000000
3ffffd30:  3ffef83c 3ffef804 3fff184c 4020e55b
3ffffd40:  00000002 3ffef804 3fff184c 4020e94c
3ffffd50:  3ffef6a8 4bc6a7f0 94bc6a7f 00000001
3ffffd60:  00000001 00000000 4bc6a7f0 3ffef6ac
3ffffd70:  3ffef83c 00000003 3ffef804 40216024
3ffffd80:  00000000 3ffee998 8d04d0fb 00000000
3ffffd90:  00000002 3fff184c 3ffef294 00000000
3ffffda0:  3ffee9c0 3ffef294 3ffe851c 3fff184c
3ffffdb0:  00000001 4bc6a7f0 deb851eb 00000001
3ffffdc0:  00000001 00000000 4bc6a7f0 00000000
3ffffdd0:  3ffef2bc 000001d3 000001d3 40100664
3ffffde0:  00000001 00000000 3fff0774 40100aa8
3ffffdf0:  3b172b21 000001d3 3ffe851c 4020e175
3ffffe00:  00000001 3ffffe8f 40206268 402036f7
3ffffe10:  00000001 00000000 3fff0774 40203e3f
3ffffe20:  00000002 3ffffeae 3fff0774 40203ec5
3ffffe30:  00000001 4bc6a7f0 8083126e 3fffff40
3ffffe40:  00000030 0000000a 3fffff40 402057ed
3ffffe50:  3ffffe8f 000001d3 000001d3 40100664
3ffffe60:  00000001 4bc6a7f0 3c6a7efa 00000001
3ffffe70:  00000001 00000000 4bc6a7f0 00000000
3ffffe80:  00000001 00000000 401001c0 00334411
3ffffe90:  00000000 000001d3 000001d3 40100664
3ffffea0:  3b46b3ee 00000000 3ffe851c 00000000
3ffffeb0:  00000002 3ffe9259 40206268 3fffefa0
3ffffec0:  00000002 00000000 3fff0774 40203e73
3ffffed0:  0000000b 00000000 3fff0774 40203ec5
3ffffee0:  3fffff40 3fe0004f 3fff0774 41cccccd
3ffffef0:  423c999a 00000000 3fffff40 402057ed
3fffff00:  3ffe9259 3ffef020 3fffff40 402057ed
3fffff10:  3ffe8be4 3ffef020 3fffff40 40205818
3fffff20:  423c999a 3ffef020 3fffff40 40205864
3fffff30:  429a0000 3ffef020 3ffef03c 40202cc9
3fffff40:  40206988 00000000 00001388 40206738
3fffff50:  00000000 3fff0774 00000000 00000000
3fffff60:  00000000 00000000 00000000 00000000
3fffff70:  3fff0ccc 0000007f 00000000 feefeffe
3fffff80:  429c28f6 00000000 42473333 feefeffe
3fffff90:  00000000 00000000 00000001 3ffef238
3fffffa0:  3fffdad0 00000000 3ffef208 40206314
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)

```

**My code:**

```
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#define DHTTYPE DHT22

const char* ssid = "ID";
const char* password = "pass";
const char* ssid2 = "ID2";
const char* password2 = "pass2";

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

WiFiServer server(80); // Set web server port number to 80
String header; // Variable to store the HTTP request

// Decode HTTP GET value
String valueString = "0";
int pos1 = 0;
int pos2 = 0;

// Variables to store the current output state
int relay0State = 0;
int relay1State = 0;
int relay2State = 0;
String brightness = "0";

// Variables to save date and time
String formattedDate;
String dayStamp;
String timeStamp;

// Variables assigned to pins
const int relay0 = 16;
const int relay1 = 5;
const int relay2 = 4;
const int DHT1Pin = 0;
const int DHT2Pin = 2;

// Initialize DHT sensors
DHT dht1(DHT1Pin, DHTTYPE);
DHT dht2(DHT2Pin, DHTTYPE);

void setup() {
  //Watchdog timer settings
  ESP.wdtDisable();
  ESP.wdtEnable(WDTO_8S);

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

  dht1.begin();
  dht2.begin();

  // Connect to available Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  int n = WiFi.scanNetworks();
  if (n == 0)
    Serial.println("No networks found!");
  else {
    for(int i=0;i<n;i++) {
      if(WiFi.SSID(i)==ssid) {
        WiFi.begin(ssid,password);
        ssid = ssid;
      } else if (WiFi.SSID(i)== ssid2) {
        WiFi.begin(ssid2,password2);
        ssid = ssid2;
      }
    }
  }
  Serial.println(ssid);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi CONNECTED with IP: ");
  Serial.println(WiFi.localIP());
  server.begin();
  timeClient.begin(); // Initialize a NTPClient to get time
  timeClient.setTimeOffset(7200); // Setting offset time in seconds to adjust for current timezone -> GMT +1 = 3600
}

void loop(){
  ESP.wdtFeed(); //Feed the watchdog timer
  WiFiClient client = server.available();   // Listen for incoming clients

   while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
  formattedDate = timeClient.getFormattedDate(); // The formattedDate comes with the following format 2018-05-28T16:00:13Z
  // Extract date
  int splitT = formattedDate.indexOf("T");
  dayStamp = formattedDate.substring(0, splitT);
  // Extract time
  timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-1);

  if (client) {
    String currentLine = "";               // 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
        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();

            // Read humidity
            float h1 = dht1.readHumidity();
            float h2 = dht2.readHumidity();
            // Read temperature as Celsius (the default)
            float t1 = dht1.readTemperature();
            float t2 = dht2.readTemperature();
            // Read temperature as Fahrenheit (isFahrenheit = true)
            float f1 = dht1.readTemperature(true);
            float f2 = dht2.readTemperature(true);

            // Calculating average temp and humidity from DHT22 sensors
            float temperature = (t1 + t2)/2;
            float temperaturef = (f1 + f2)/2;
            float humidity = (h1 + h2)/2;

            if(header.indexOf("GET /1/") | header.indexOf("GET /0/") < 0){
                if(humidity < 50){
                relay1State = 1;
                digitalWrite(relay1, HIGH);
              } else {
                relay1State = 0;
                digitalWrite(relay1, LOW);
              }
              if(temperature < 23) {
                relay0State = 1;
                digitalWrite(relay0, HIGH);
              } else {
                relay0State = 0;
                digitalWrite(relay0, LOW);
              }
            }

            if (header.indexOf("GET /0/on") >= 0) {
              relay0State = 1;
              digitalWrite(relay0, HIGH);
            } else if (header.indexOf("GET /0/off") >= 0) {
              relay0State = 0;
              digitalWrite(relay0, LOW);
            } else if (header.indexOf("GET /1/on") >= 0) {
              relay1State = 1;
              digitalWrite(relay1, HIGH);
            } else if (header.indexOf("GET /1/off") >= 0) {
              relay1State = 0;
              digitalWrite(relay1, LOW);
            }

            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta http-equiv=\"refresh\" content=\"1\" name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js\"></script>");
            client.println("<style> html {font-family: Helvetica; display: inline-block; margin: 0px; text-align: center; height: auto; box-sizing: border-box;} h1, h2{width: 100%; color: #444444; font-size: 55px;} h2 {font-size: 30px;} h3, h4 {width: 50%; font-size: 24px; color: #444444; padding: 18px; margin: 10px; border-radius: 35px; margin: 4px auto;} h4 {padding: 5px;} .button {background-color: #4CAF50; border: none; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;} .button2 {background-color: #555555;} .content {width: 100%; } .light {border-radius: 35px; width: 50%; margin: 4px auto;} .slider {-webkit-appearance: none; width: 30%; height: 10px; border-radius: 5px; margin-bottom: 20px; background: #d3d3d3; outline: none; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; border-radius: 50%; background: #444444; cursor: pointer;} @media (max-width: 1000px) {h1{font-size: 40px;} h2{font-size: 25px;} h3,h4{width: 75%; font-size: 20px;} .light{ width: 75%;}}</style><title>Smart TERA</title> </head> ");
            client.println("<body><div class=\"header\"> <h1>Smart TERA</h1><h2>");
            client.println(timeStamp);
            client.println(" / " + dayStamp);
            client.println("</h2> </div> <div class=\"content\"><h3 style =\"background-color: #ff8000;\">Temperature: ");
            client.println(temperature);
            client.println("℃ /  ");
            client.println(temperaturef);
            client.println("℉ </h3><h3 style =\"background-color: #4da6ff;\">Humidity: ");
            client.println(humidity);
            client.println("%</h3><div class=\"light\" style=\"background-color: #ffff33;\"><h3>Light Brightness: <span id=\"lightPos\"></span> %</h3> <input class=\"slider\" type=\"range\" min=\"0\" max=\"100\" step=\"25\" value="+brightness+" id=\"myRange\">");
            client.println("<script> var slider = document.getElementById(\"myRange\"); var lightP = document.getElementById(\"lightPos\"); lightP.innerHTML = slider.value; $.ajaxSetup({timeout:1000}); slider.oninput = function() { slider.value = this.value; lightP.innerHTML = this.value; $.get(\"/?value=\" + this.value + \"&\"); {Connection: close};}</script> </div>");

            if(header.indexOf("GET /?value=")>=0) {
                pos1 = header.indexOf('=');
                pos2 = header.indexOf('&');
                valueString = header.substring(pos1+1, pos2);
                if(valueString == "0" ){
                  brightness = "0";
                  analogWrite(relay2, 0);
                } else if (valueString == "25"){
                  brightness = "25";
                  analogWrite(relay2, 256);
                } else if (valueString == "50"){
                  brightness = "50";
                  analogWrite(relay2, 512);
                } else if (valueString == "75"){
                  brightness = "75";
                  analogWrite(relay2, 768);
                } else if (valueString == "100"){
                  brightness = "100";
                  analogWrite(relay2, 1024);
                }
           }
            // Display current state, and ON/OFF buttons for controlling relays, If the relay0State is off, it displays the ON button
            client.println("<h4>Rock Heater - State ");
            if (relay0State == 0) {
              client.println("off</h4><p><a href=\"/0/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("on</h4><p><a href=\"/0/off\"><button class=\"button button2\">OFF</button></a></p>");
            }

            client.println("<h4>Humidifier - State ");
            if (relay1State == 0) {
              client.println("off </h4><p><a href=\"/1/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("on </h4><p><a href=\"/1/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</div></body></html>");

            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            yield();
            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 and close the connection
    header = "";
    client.stop();
   }
}

```

**Decoded error:**

# Answer
First, take out the wdt.feed all that does is delay the real problem and/or shift it somewhere else. As a rule of thumb, if you even THINK you have to use / touch / play with / cancel the WDT, your code is already wrong. The root problem is your code is "blocking" longer than the underlying WiFI stack is happy with. A culprit is: while(!timeClient.update()) How long does that take? If it "blocks" then your code will fail. "Multiple" / "Parallel" tasks must run asynchronously and yield() to the backgound WiFi if they are long-running. If you mix old fashioned, blocking code with modern asynchronous code, THIS is exactly what you will get.

Other points: all that println stuff in the main loop is horribly inefficient and won't be helping. Setup the main body of text once and edit / resend the bits that change.

Also I believe DHT11 can sometimes take a while to settle / read. If the library you are using is not optimised for ESP8266 and / or non-blocking, there's another potential source of error. I believe DHT11 can also sometimes return NaN rather than a valid value - how do you cope with that?

There's an async webserver library that does all that side of things properly - you are reinventing a wheel and yours is square. You need to find an async NTP library too. "But I found it in the library examples!" Is NOT a guarantee / justification that the code is a) useful b) any good c) well-written d) functional for any other purpose. In my experience its usually the opposite of all four, especially if you mix two libraries together. It's an "example" - it's not production code.

Final takeaway:

1. Use the right library for the right job
2. NEVER mess with the WDT
3. NEVER mix sync + async code
4. Most example ESP8266 code assumes a single function, not needing to cooperate with any other. If you mix / blend separate examples / functions (e.g. DHT11 AND NTP AND WEBSERVER), YOU must provide the co-operation between functions + ESP8266 background WiFi. If you don't (and you haven't) you will cause a WDT reset, 100% guaranteed.
> 2 votes

# Answer
i had look like this problem before. for me , when i much used of " Serial.print " this RST fault occur for me.. so i use of a function:

```
void Serial_Show() {
    Serial.println();
}

```

maybe your problem is this. you can test it by deleting all Serial.print() function and next add one by one...
> 1 votes

---
Tags: esp8266, library, web-server, reset, watchdog
---


title: Rounding float number

text:
# Question
Title: Rounding float number
I want to enable user to change the duration of PWM from 0 to 255, the number should be in minute and increase/decrease with two push buttons.

```
(X) x 255 / 60000 = minute

```

In above example each time plus button pressed value (X) will multiple by the numbers of button pressed.

```
if (plusButton == HIGH) {
    PWMduration += (X);
}

```

The nearest number i found is 235.29 which equals to almost 1 minute:

```
235.29 x 255 / 60000 = 0.9999

```

How can i round that number to 1? or is there any other alternative solution to calculate this?

# Answer
You can cast it to an integer after adding an offset.

Casting to an int will lower the value to the lowest integer value (e.g. 0.9975 will become 0). However, if you want an accuracy of 0.5 (e.g. all values from 0.5 \<= x \< 1.5 should be 1.0), than add 0.5, thus:

```
int roundedValue = (int)(0.9975 + 0.5);

```

If you use constants and want to calculate with it, either add .0 to it, or use a f(loat) or d(ouble) postfix, e.g.:

```
float f = 12.0 / 3.0;

```

or

```
float f = 12f / 3f;

```

Than calculate the rounded value:

```
int roundedValue = (int)(f + 0.5);

```
> 1 votes

---
Tags: programming, c, float, calculation
---


# Question
Title: How to set CS pin on Beetle BLE/Bluno Beetle to Adafruit SD Card Breakout - Initialization Failed!
Hi I have a Beetle BLE (https://www.dfrobot.com/wiki/index.php/Bluno\_Beetle\_SKU:DFR0339) and I am trying to connect an Adafruit MicroSD card breakout board+ (https://www.adafruit.com/product/254) via SPI connections. I am trying the following code, but I am having trouble selecting the CS pin using D4 since the Beetle has no D10. Does anyone know if I am selecting D4 correctly, while keeping pin 10 as an output. I keep getting initialization failed! My setup is on the ICSP 6 pin configuration:

5V --\> 5V

MISO --\> DO

SCK --\>CLK

GND --\> GND

MOSI --\> DI

D4 --\> CS

RST is left out

Here is my code:

```
#include <SPI.h>

#include <SD.h>

File myFile;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output
  // or the SD library functions will not work.
//   pinMode(4, OUTPUT);
   pinMode(10, OUTPUT);
//   digitalWrite(4, HIGH); // Add this line

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.

  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
  // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop()
{
  // nothing happens after setup
}

```

# Answer
The correct ICSP was on the right, ICSP1. However, the orientation of those pins were from left to right on the TOP: SCK, 5V, MISO; left to right on the BOTTOM: MOSI, RESET, GND. In the Wiki they had the ICSP labels 1 and 2 reversed, but correct in the text below. https://www.dfrobot.com/wiki/index.php/Bluno\_Beetle\_SKU:DFR0339

Therefore, there was nothing wrong with the code, only the wiring to the correct pins!
> 1 votes

# Answer
The ICSP header **labels on the Wiki page are wrong**. In the schematic here the ICSP header has the same pinout as other Arduinos. The legend doesn't match the picture on the Wiki page but is true:

* ICSP1: Atmega 328P
* ICSP2: CC2540

The ICSP header is the inner one. Is right on the pictures. At pin 1 on board the corner of the white square around pins is skewed. The pins are from left to right first row Eeset, CLK, MISO, second row Ground, MOSI, 5 V.

pdf schematic for the board
> 1 votes

# Answer
This is what I'm seeing with my multitester:

The cc2540 is the SMD chip on the same side as the ICSP pads. The atmega328p is on the opposite side of the PCB
> 0 votes

---
Tags: arduino-uno, sd-card, adafruit
---


# Question
Title: Problem with passing string pointer from child to parent
I am trying to pass a pointer to a const char * from a child to its parent, but I am clearly not understanding how to do this correctly. Here is the code which contains three classes: 1) parent 2) Alpha (child) 3\_ Beta (child)

```
#pragma once
class Parent {
protected:
    char *childName;

public:
    Parent ( char* _childName ) {
        childName = _childName;
    }

    char *getChildName () {
        return childName;
    }
};

class Alpha: public Parent {
protected:
    const char* alphaName = "ALPHA";

public:
    Alpha (): Parent ( alphaName ) {
        Serial.print ( F ( "My name is " ) );
        Serial.println ( getChildName () );
    }
};

class Beta: public Parent {
protected:
    const char* betaName = "BETA";

public:
    Beta (): Parent ( betaName ) {
        Serial.print ( F ( "My name is " ) );
        Serial.println ( getChildName () );
    }
};

Alpha *alpha;
Beta *beta;
void setup () {
    Serial.begin ( 115200 );
    while (!Serial.availableForWrite ()) {}

    alpha = new Alpha ();
    beta = new Beta ();
}

void loop() {}

```

And here is the output I get: My name is �

My name is �˵

# Answer
The problem here is that `alphaName` and `betaName` are member variables. That means they are initialized during the `Alpha` and `Beta` constructors. However, the superclass constructor of `Parent` is always called first, before calling the child class constructors. Result: `Parent::Parent(char *)` is called with an uninitialized pointer.

Here is your code on the Compiler Explorer: https://godbolt.org/z/otAuQU As you can see, `Alpha::Alpha()` compiles to the following:

```
call Parent::Parent(char*)
ldd r24,Y+1
ldd r25,Y+2
ldi r18,lo8(.LC0)
ldi r19,hi8(.LC0)

```

`.LC0` is the string "ALPHA".

The solution here is to make the names static. That way, they are initialized before the parent constructor is called.

```
class Parent {
  protected:
    const char *const childName;

  public:
    Parent(const char* childName) : childName(childName) {}

    const char *getChildName () const {
        return childName;
    }
};

class Alpha : public Parent {
  protected:
    constexpr static const char *alphaName = "ALPHA";

  public:
    Alpha() : Parent(alphaName) {
        Serial.print(F("My name is "));
        Serial.println(getChildName());
    }
};

```

This compiles to:

```
ldi r22,lo8(.LC0)
ldi r23,hi8(.LC0)
call Parent::Parent(char const*)

```

As others have mentioned, pointers to string literals should always be const. The only reason this doesn't give an error is because the Arduino folks decided that it was a good idea to compile everything with `-fpermissive` ...
Mutating a string literal is undefined behavior, so an error.
> 2 votes

---
Tags: c++, pointer
---


# Question
Title: PIR sensor and hex inverter open collector
the M7404 Hex inverter is used to send an active low signal from a PIR sensor to a microcntroller pin

However the reset is being constantly sent some signal keeping it set to on. You can tell because the reset light is on in the picture

Thanks to ST2000 I was able to figure out I need a hex inverter open collector to change the high signal from high to low because the reset pin on the microcontroller is active low. However, Whenever I use the active low reset pin (number 3 on the esp32) it goes into a state of holding down the reset button. Or constantly being high. Here is the thread where ST2000 was able to provide me the solution I am working on: esp32 cam and PIR sensor

**My question is: how do i get the pir sensor to send an active low signal to the microcontroller?**

here is a schematic of the esp32 board https://i.redd.it/yv050peu22p21.png

# Answer
> 0 votes
I wouldn't have chosen a hex inverter for this job. I'd have just used a transistor and a resistor:

simulate this circuit – Schematic created using CircuitLab

When OUT is HIGH, M1 is ON, which connects D3 to GND. When OUT is LOW, M1 is OFF, which allows R1 to pull D3 up to 3.3V.

---

As to why you have a boot loop, now you have shown a slightly (though still confusing) clearer schematic I can tell you that it is because you are using pin D3.

Don't use pin D3.

D3 is the RX pin and is held HIGH at boot. That means that when the board resets D3 goes HIGH which then pulls reset LOW through your inverter, which then lets D3 float, so RESET goes HIGH, and that makes D3 then go HIGH which means the RESET is pulled LOW... ad infinitum.

You should read this page and choose a different GPIO pin that isn't going be doing things at bootup.

---
Tags: esp32
---


# Question
Title: Which sources of randomness are available?
I need a souce of randomness to generate a seed to pass to `randomSeed`. Where can I get this randomness from?

Well, I hear I can read random noise from an unconnected pin.

But I need to connect 9 LEDs and 9 buttons to the board. There seem to be enough pins for this purpose: digital pins 2-13 + analog pins 0-5 makes a total of 18 pins. But does this leave any free pin for a source of randomness?

There are digital pins 0 and 1 left free but I'm reading these should be left free if the board's USB socket is connected and I'm planning to power the whole device by connecting it to a computer through USB. Does this mean I'm supposed to just left pins 0 and 1 unconnected or is it also forbidden to read noise from them?

Or are there any other available sources of randomness? Can I use any other pins for this purpose?

I remember when I was showing this project to the instructor I specifically asked if I have enough pins, noting that I need a source of randomness in addition to 9 LEDs and 9 buttons. He said there are enough pins. Only sadly I forgot to ask how can I read random noise then...

What are my options to somehow obtain a random seed?

# Answer
Whether you need a source of random noise depends on whether your project needs to *not* run repeatably. Most experiments - Monte-Carlo simulations, for example, benefit by being able to be re-run. In those cases, you need to be able to re-use the seed, and having an non-reproducible seed (and thus, experiment) is a disadvantage.

If you really need something that runs differently each time you run it, then a seed derived from user reaction time, or from some kind of electrical noise, even reading analog values from a floating input pin, should give you plenty of non-reproducibility.
> 1 votes

---
Tags: arduino-uno, pins
---


title: why arduino can not write to server?

text:
# Question
Title: why arduino can not write to server?
i write a code for Arduino + SIM800 for connecting to server. but it don't work!

```
SerialGsm.println("AT+CIPSEND=63\r\n");
delay( 1000 );
receive_message();
SerialGsm.print( "GET http://sasasas.ir.ir/hadi/signal.php?value=10" );
delay( 10000 );
receive_message();

```

all thing is true but "GET" can not retrun "OK". it is arduino response:

---

AT

OK

Call Ready

SMS Ready AT+CSTT="mtnirancell"

OK AT+CIICR

OK AT+CIFSR

100.65.157.141 AT+CIPSTART="TCP","sasasas.ir",80

OK

CONNECT OK AT+CIPSEND=63

> GET http://sasasas.ir/hadi/signal.php?value=10
>
> ---

"get" dont have response.what is wrong in this code?

# Answer
Firstly you only have half of the first line of a GET request. Secondly the half you do have is badly formatted.

A GET request does *NOT* look like this:

```
GET http://jalambadani.ir/hadi/signal.php?value=10

```

A GET request *DOES* look like this:

```
GET /hadi/signal.php?value=10 HTTP/1.1
Host: jalambadani.ir
Connection: close
[extra blank line]

```

If you don't send the correct data you can't expect to get any response back. You should learn the basics of what you are trying to do instead of just throwing random text a a web server.

---

Here is a full transcript of a GET request to your URL:

```
$ telnet jalambadani.ir 80
Trying 185.211.56.148...
Connected to jalambadani.ir.
Escape character is '^]'.
GET /hadi/signal.php?value=10 HTTP/1.1
Host: jalambadani.ir
Connection: close

HTTP/1.1 200 OK
Date: Tue, 25 Jun 2019 22:47:07 GMT
Server: Apache/2
X-Powered-By: PHP/5.6.35
Upgrade: h2,h2c
Connection: Upgrade, close
Vary: User-Agent
Content-Length: 31
Content-Type: text/html; charset=UTF-8

New record created successfullyConnection closed by foreign host.

```

In code that would be:

```
SerialGsm.print("AT+CIPSEND=83\r\n");
delay(1000); // I hate that. Look for a proper OK instead.
SerialGsm.print("GET /hadi/signal.php?value=15 HTTP/1.1\r\n");
SerialGsm.print("Host: jalambadani.ir\r\n");
SerialGsm.print("Connection: close\r\n");
SerialGsm.print("\r\n);

```
> 1 votes

---
Tags: arduino-uno, web-server
---


# Question
Title: Getting a truly random number in Arduino
What is the best method to get a truly (as opposed to pseudo) random number in Arduino, or at least the best possible approximation? From my understanding, the function randomSeed(analogRead(x)) it's not random enough.

If possible the method should leverage the basic Arduino setup alone (no additional sensors). Solutions with external sensors are welcome if they improve significantly the randomness over the basic setup.

# Answer
> 9 votes
`randomSeed(analogRead(x))` will only produce 255 sequences of numbers, which makes it trivial to try all combos and produce an oracle that can couple to your output stream, predicting all the output 100%. You are on the right track however, it's just a numbers game, and you need a LOT more of them. For example, taking 100 analog reads from 4 ADCs, summing them all, and feeding that to `randomSeed` would be much better. For max security, you need both unpredictable input and non-deterministic mixing.

I'm not a cryptographer, but I've spent thousands of hours researching and building hardware and software random generators, so let me share some of what I've learned:

**Unpredictable Input:**

* analogRead() (on floating pins)
* GetTemp()

**Potentially Unpredictable Input:**

* micros() (w/ a non-deterministic sample period)
* clock jitter (low-bandwidth, but usable)
* readVCC() (if not battery-powered)

**External Unpredictable Input:**

* temp, humidity, and pressure sensors
* microphones
* LDR voltage dividers
* reverse-bias transistor noise
* compass/acceleration jitter
* esp8266 wifi hotspot scan (ssid, db, etc)
* esp8266 timing (the background wifi tasks make scheduled micros() fetches indeterminate)
* esp8266 HWRNG - `RANDOM_REG32` -extremely fast and unpredictable, a 1-stop

**collecting** The last thing you want to do is spit out entropy as is comes along. It's easier to guess a coin flip than a bucket of coins. Summing is good. `unsigned long bank;` then later `bank+= thisSample;` is good; it will roll-over. `bank[32]` is even better, read on. You want to collect at least 8 samples of input for each chunk of output, ideally much more.

**Guarding against poisoning** If heating the board causes a certain max clock jitter, that's an attack vector. Same with blasting RFI towards the analogRead() inputs. Another common attack simply unplugging the unit thus dumping all the accumulated entropy. You should not output numbers until you know it's safe to do so, even at the cost of speed.

This is why you want to keep some entropy around long-term, using EEPROM, SD, etc. Look into the Fortuna PRNG, which uses 32 banks, each one updated half as often as the one before it. That makes it difficult to attack all 32 banks in a reasonable amount of time.

**Processing** Once you collect "entropy", you have to clean it up and divorce it from the input in a hard-to-reverse way. SHA/1/256 is good for this. You can use SHA1 (or even MD5 really) for speed since you don't have a plaintext vulnerability. To harvest, never use the full entopy bank, and ALWAYS ALWAYS add a "salt" to the output that's different each time to prevent identical outputs given no entropy bank changes: `output = sha1( String(micros()) + String(bank[0]) + [...] );` The sha function both conceals inputs and whitens output, protecting against weak seeds, low accumulated ent, and other common issues.

To use timer inputs, you need to make them indeterministic. This is a simple as `delayMicroseconds(lastSample % 255)`; which pauses an unpredictable amount of time, making "successive" clock reads non-uniform in difference. Do that semi-regularly, like `if(analogRead(A1)>200){...}`, provided A1 is noisy or hooked to a dynamic input. Making each fork of your flow rather difficult to determine will prevent cryptoanalysis on decompiled/ripped output.

Real security is when the attacker knows your whole system and is still helpless to overcome it.

Lastly, check your work. Run your output through ENT.EXE (also available for nix/mac) and see if it's any good. Most important is the chi square distribution, which should usually be between 33% and 66%. If you get 1.43% or 99.999% or something edgy like that, more than one test in a row, your random is crap. You also want the entropy ENT reports as close to 8 bits per byte as possible, \> 7.9 for sure.

TLDR: The simplest fool-proof way is to the uthe ESP8266's HWRNG. It's fast, uniform, and unpredictable. Run something like this on an ESP8266 running the Ardunio core, and use serial to talk to the AVR:

```
// ESP8266 Arduino core code:
void setup(){
 Serial.begin(9600); // or whatever
}

void loop() {
  // Serial.write((char)(RANDOM_REG32 % 256)); // "bin"
  Serial.print( String(RANDOM_REG32, HEX).substring(1)); // "hex"
}

```

---

\** edit

here is a bare-board HWRNG sketch I wrote a while back, operating as a not just a collector, but a whole CSPRNG spitting out of the serial port. It's built for a pro-mini but should be easily adaptable to other boards. You can use just floating analog pins, but it's better to add stuff to them, prefereably different things. Like microphones, LDRs, thermistors (trimmed to max spread around room temp), and even long wires. It does pretty well in ENT if you have even moderate noise.

The sketch integrates several notions I've mentioned in my answer and follow-up comments: accumulating entropy, stretching by over-sampling less-than-ideal entropy (von neumann said it's cool), and hashing to uniformity. It forgoes entropy quality estimation in favor of "gimme anything possibly dynamic" and mixing using a cryptographic primitive.

```
// AVR (ardunio) HWRNG by dandavis. released to public domain by author.
#include <Hash.h>

unsigned long read[8] = {0, 0, 0, 0, 0, 0, 0, 0};
const int pincount = 9; // adjust down for non pro-mini boards
int pins[9] = {A0, A1, A2, A3, A4, A5, A6, A7, A0}; // adjust for board, name analog inputs to be sampled
unsigned int ticks = 0;
String buff = ""; // holds one round of derivation tokens to be hashed.
String cache; // the last read hash

void harvest() { // String() slows down the processing, making micros() calls harder to recreate
  unsigned long tot = 0; // the total of all analog reads
  buff = String(random(2147483647)) + String(millis() % 999);
  int seed =  random(256) + (micros() % 32);
  int offset =  random(2147483647) % 256;

  for (int i = 0; i < 8; i++) {
    buff += String( seed + read[i] + i + (ticks % 65), HEX );
    buff += String(random(2147483647), HEX);
    tot += read[i];
  }//next i

  buff += String( (micros() + ticks + offset) % 99999, HEX);
  if (random(10) < 3) randomSeed(tot + random(2147483647) + micros());
  buff = sha1( String(random(2147483647)) + buff + (micros()%64) + cache); // used hash to uniform output and waste time
  Serial.print( buff ); // output the hash
  cache = buff;
  spin();
}//end harvest()

void spin() { // add entropy and mix
  ticks++;
  int sample = 128;
  for (int i = 0; i < 8; i++) { // update ~6/8 banks 8 times
    read[ read[i] % 8] += (micros() % 128);
    sample = analogRead(  pins[i] ); // a read from each analog pin
    read[ micros() % 8] += ( read[i] % 64 ); // mix timing and 6LSBs from read
    read[i] += sample; // mix whole raw sample
    read[(i + 1) % 8] += random(2147483647) % 1024; // mix prng
    read[ticks % 8] += sample % 16; // mix the best nibble of the read
    read[sample % 8] += read[ticks % 8] % 2147483647; // intra-mix banks
  }

}//end spin()

void setup() {
  Serial.begin(9600);
  delay(222);
  int mx = 2028 + ((analogRead(A0)  + analogRead(A1) + analogRead(A2)  + analogRead(A3)) % 256);
  while (ticks < mx) {
    spin();
    delay(1);
    randomSeed(read[2] + read[1] + read[0] + micros() + random(4096) + ticks);
  }// wend
}// end setup()

void loop() {
  spin();
  delayMicroseconds((read[ micros() % 8] %  2048) + 333  );
  delay(random(10));
  //if (millis() < 500) return;
  if ((ticks % 16) == (millis() % 16) ) harvest();
}// end loop()

```

# Answer
> 9 votes
The Entropy library uses:

> the watchdog timer's natural jitter to produce a reliable stream of true random numbers

I like this solution because it doesn't use up any pins of your microcontroller and doesn't require any external circuitry. This also makes it less subject to external failures.

In addition to a library, they also provide a sketch that demonstrates the use of the same technique used to generate a random seed for the microcontroller's PRNG without the library: https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library/arduino-random-seed

# Answer
> 3 votes
From my experience, `analogRead()` on a floating pin has very low entropy. Maybe one or two bits of randomness per call. You definitely want something better. The watchdog timer's jitter, as proposed in per1234's answer, is a good alternative. However, it generates entropy at a pretty slow rate, which can be an issue if you need it right when the program starts. dandavis has quite a few good suggestions, but they generally require either an ESP8266 or external hardware.

There is one interesting entropy source that has not been mentioned yet: the contents of the uninitialized RAM. When the MCU is powered up, some of its RAM bits (those that happen to have the most symmetrical transistors) start up in a random state. As discussed in this hackaday article, this can be used as an entropy source. It is only available on a cold boot, so you can use it to fill an initial entropy pool, which you would then periodically replenish from another, potentially slow source. This way your program can start its work without having to wait for the pool to slowly fill up.

Here is a example of how this could be harvested on an AVR-based Arduino. The code snippet below XORs the whole RAM in order to build a seed that it later feeds to `srandom()`. The tricky part is that the harvesting has to be done *before* the C runtime initializes the .data and .bss memory sections, and then the seed has to be saved in a place the C runtime will not overwrite. This is done by using specific memory sections.

```
uint32_t __attribute__((section(".noinit"))) random_seed;

void __attribute__((naked, section(".init3"))) seed_from_ram()
{
    const uint32_t * const ramstart = (uint32_t *) RAMSTART;
    const uint32_t * const ramend   = (uint32_t *) RAMEND;
    uint32_t seed = 0;
    for (const uint32_t *p = ramstart; p <= ramend; p++)
        seed ^= *p;
    random_seed = seed;
}

void setup()
{
    srandom(random_seed);
}

```

Note that, on a *warm* reset, the SRAM is preserved, so it still has the whole contents of you entropy pool. This same code can then be used to preserve the collected entropy across a reset.

**Edit**: fixed an issue in my initial version of `seed_from_ram()` that worked on the global `random_seed` instead of using a local `seed`. This could lead to the seed being XORed with itself, destroying all the entropy harvested so far.

# Answer
> 0 votes
If you don't really need entropy and simply want to get a different sequence of pseudo-random numbers on every startup, you can use EEPROM to iterate through consecutive seeds. Technically the process will completely deterministic, but in practical terms it's much better than `randomSeed(analogRead(0))` on an unconnected pin, which will often make you start with the same seed of either 0 or 1023. Saving the next seed in EEPROM will guarantee that you start with a different seed each time.

```
#include <EEPROM.h>

const int seed_addr = 0;
unsigned long seed;

void setup() {
    seed = EEPROM.read(seed_addr);
    EEPROM.write(seed_addr, seed+1);
    randomSeed(seed);
}

```

If you need real entropy, you can collect it either from clock drift, or by amplifying external noise. And if you need a lot of entropy, external noise is the only viable option. Zener diode is a popular choice, especially if you have a voltage source above 5-6V (it will work with 5V too with an appropriate Zener diode, but will produce less entropy):

(source).

The amplifier output has to be connected to an analog pin, which will produce several bits of entropy with each `analogRead()` up to tens of MHz (faster than Arduino can sample).

---
Tags: programming
---


# Question
Title: Possible to have different torque levels on MG966R servo with Rotary Potentiometer?
I want to apologise first and foremost, and say that I am very new to Arduinos!

I wanted to control the torque on a MG966R servo so that I can separate it into 4 different torque levels. I read that by adjusting the input voltage, you can run the servo at different speed, hence, i was thinking if I could incorporate a rotary potentiometer to adjust the speed of the servo.

Also wondering if changing angle stepsize of MG966R servo will affect torque in anyway?

Thanks all!

# Answer
Generally it is not easy to control the torque of a standard servo, since mostly they aren't meant for that. A servo has an internal controller, which will read the input PWM signal and control the geared motor, so that the desired position will be reached. And to get there, the most servos will use the maximum torque. Also the torque of a servo motor depends on more variables, for example speed and type of load (See here for more information about this.

> I read that by adjusting the input voltage, you can run the servo at different speed

That's not really true. Most servos only support a rather small voltage range, where they will work. You can get more torque, if you use a higher voltage, but it is not a simple linear relationship, since the torque depends on way more variables. One way may be to always drive the servo to it's current maximum torque and change this maximum torque by changing the input voltage inside the working range. Though this might not get you 4 torque levels, that are different enough for you.

> Also wondering if changing angle stepsize of MG966R servo will affect torque in anyway?

It is unclear, what exactly you mean by "stepsize" here. If you mean to control the speed of the servo: Yes, it will affect the torque, but not in a linear way. And this greatly depends on the load, that you apply.

In the answer to this question, sensing the current of the servo is suggested as a measurement of (applied) torque. If you use a feedback loop with this, you might be able to control the (applied) torque. I haven't done this kind of thing, so I'm not sure, if this can really work.

---

That said, you should again think about wether a normal servo is really the best way to go here, since it controls electronics, that you don't control yourself. For example you may use a geared DC motor, which you can directly control without any other electronics getting in your way.
> 0 votes

---
Tags: servo, potentiometer
---


title: AC Voltage Sensing using Arduino Uno

text:
# Question
Title: AC Voltage Sensing using Arduino Uno
Is it possible to sense AC Voltage using analog input for Arduino Uno or can it only read DC?

I mean I've tried connecting an AC voltage source to analog and I'm reading some numbers. However, I don't know if these numbers are actually AC voltage values or something else.

Ultimately I’m trying to find the avg voltage value for a given time duration. I know that analogRead ( ) gives ADC values. However, in my block of code, I have the conversion ratio of 1023/5 to get a good estimate of the voltage. However, I’m not too sure if Arduino analog sensing is suited for AC voltage? I’m using it to sense voltages generated by piezoelectric PVDF film and the frequency is pretty high. All I want is to use avg. voltage value to calculate electrical energy produced by the PVDF film.

# Answer
> 0 votes
The AC voltage that you are trying to measure is about 50/60Hz depending on where you live. And the maximum effective sampling rate for a regular Arduino ADC is 9615Hz. This means you're not going to experience any aliasing as the sampling rate is well above the `2 * Signal Frequency`.

The values that are coming out of `analogRead()` are raw ADC values which you need to do, further calculation on if you want to have a correct voltage reading.

---
Tags: arduino-uno, analogread, hardware, voltage
---


title: expected unidentified id before 'if"

text:
# Question
Title: expected unidentified id before 'if"
```
#include <iostream>
using namespace std;
char board[3][3]={{'1','2','3'},{'4','5','6'},{'7','8','9'}};
char turn='X';
int draw=0;
int row,column;
void display_board()
{
    system("cls");
    cout<<"\n\n TIC TAC TOE GAME:";
    cout<<"\n\n PLAYER[1]==O\t\t\t PLAYER[2]==X";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t   "<<board[0][0]<<" |  "<<board[0][1]<<"  |  "<<board[0][2]<<"   \n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t_____|_____|_____\n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t  "<<board[1][0]<<"  |  "<<board[1][1]<<"  |  "<<board[1][2]<<"    \n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t_____|_____|_____\n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t  "<<board[2][0]<<"  |  "<<board[2][1]<<"  |   "<<board[2][2]<<"  \n";
    cout<<"\t\t     |     |     \n";
    cout<<"\t\t     |     |     \n";
}
void player_turn()
{
    int choice;
    if(turn=='X')
    {
        cout<<"\n\t  PLAYER[1]==O's turn";
    }
    if(turn=='O')
    {
        cout<<"\n\t  PLAYER[2]==X's turn";
    }
    cin>>choice;
    switch(choice)
    {
        case 1:row=0; column=0; break;
        case 2:row=0; column=1; break;
        case 3:row=0; column=2; break;
        case 4:row=1; column=0; break;
        case 5:row=1; column=1; break;
        case 6:row=1; column=2; break;
        case 7:row=2; column=0; break;
        case 8:row=2; column=1; break;
        case 9:row=2; column=2; break;
        default:
        cout<<"Invalid input";
        break;
    }
   if(turn=='X' && board[row][column]!='X' && board[row][column]!='O')
   {
       board[row][column]=='X';
       turn='O';
   }
   else if(turn=='O' && board[row][column]!='X' && board[row][column]!='O')
   {
       board[row][column]=='O';
       turn='X';
   }
   else
   {
       cout<<"Box already filled!\nplease try again!!";
       player_turn();
   }
   display_board();
}
int gameover()
{
    for(int i=0;i<3;i++)
    {
        if(board[i][0]==board[i][1] && board[i][0]==board[i][2] || board[0][i]==board[1][i] && board[0][i]==board[2][i])
        return 0;
        else if(board[0][0]==board[1][1] && board[0][0]==board[2][2] || board[0][0]==board[1][1] && board[0][0]==board[2][2])
        return 0;
    }
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            if(board[i][j]!='X' && board[i][j]!='O')
            return 1;
        }
    }
    draw=1;

    return 0;
}

int main()
{
    system("cls");
    while(gameover())
    {
    display_board();
    player_turn();
    gameover();
    }
    return 0;
}

if(turn=='X' && draw=0)
{
    cout<<"PLAYER[2] WINS!!!";
}
else if(turn=='O' && draw==0)
{
    cout<<"PLAYER[1] WINS!!!";
}
else
{
    cout<<"GAMEDRAW!!!";
}

```

# Answer
> 2 votes
This fragment is outside of a function:

```
if(turn=='X' && draw=0)
{
    cout<<"PLAYER[2] WINS!!!";
}
else if(turn=='O' && draw==0)
{
    cout<<"PLAYER[1] WINS!!!";
}
else
{
    cout<<"GAMEDRAW!!!";
}

```

Some other remarks:

1. Instead of multiple `return` statements, it is better to create a local variable, set it, and return that one at the end. So only use one `return` statement per function (that has a return value).
2. As chrisl mentions: Arduino does not have cin or cout. Use the Serial class for this.
3. You can replace the following code:

>

```
 switch(choice)
 {
    case 1:row=0; column=0; break;
    case 2:row=0; column=1; break;
    case 3:row=0; column=2; break;
    case 4:row=1; column=0; break;
    case 5:row=1; column=1; break;
    case 6:row=1; column=2; break;
    case 7:row=2; column=0; break;
    case 8:row=2; column=1; break;
    case 9:row=2; column=2; break;

```

by

```
row    = (int) ((choice - 1) / 3);
column =        (choice - 1) % 3;

```
4. Use an enum as return type for function `gameover()` E.g. EGameState { Running, PlayerOneWon, PlayerTwoWon, Draw };

This removes also the global variable `draw`.
5. You call function `gamover` twice, one time within the while loop without checking the result.
6. Do not use a char for the variable `turn` but the player number, or a boolean (XPlayerHasTurn), or an enum.

---
Tags: programming, c++
---


title: Flashing ESP8266 ESP-12E/12F

text:
# Question
Title: Flashing ESP8266 ESP-12E/12F
I'm pretty new to Arduino programming and i'm trying to connect this ESP8266 module to my FTDI programmer but constantly getting this error on my ARDUINO IDE: **esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header**. My guess is that its not in flashing mode and that i have to connect GPIO0 to ground or sompthing else.

# Answer
> 1 votes
On my version of this "Adatper" adapter the io pins were not connected. I patched io 0 to the esp-01 like header, to be able to put the ESP in bootloader mode. On the picture you see a paperclip jumper connecting io 0 to ground for flashing mode.

Back then I could leave the jumper connected, because the esp8266 run the sketch after upload. In new versions of esp8266 arduino boards package the esptool hard resets the esp8266 so it returns into flashing mode. This can be changed in platform.txt.

I recommend you to buy an esp8266 dev board with USB (Wemos, NodeMcu and similar)

---
Tags: arduino-uno, esp8266, ftdi
---


title: Arduino Timer with increase time button

text:
# Question
Title: Arduino Timer with increase time button
I have an Arduino project to do, which requires a countdown timer(which I've already done). I connected a push button, and when I press that button I need it to increase my countdown timer by +10 seconds.

Can anyone help me with adding the code for this button?

Here is the code so far(I declared the button, but I don't know if it's any good):

```
#include <LiquidCrystal.h>

int buttonPin = 7;
int buttonState = 0;
int seconds = 30; // count seconds
int minutes = 0; // count minutes
int hours = 0; // count hours
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
//initialize the library with the numbers of the interface pins
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // pins connected to LCD

void setup()
{
  lcd.begin(16, 2); //set up the LCD's number of columns and rows
  pinMode(buttonPin, INPUT);
}
void loop()
{
  buttonState = digitalRead(buttonPin);
  lcd.setCursor(1, 0);
  lcd.print ("Sosire in:");
  lcd.setCursor(6, 1);
  lcd.print(":");
  lcd.setCursor(9, 1);
  lcd.print(":");

  seconds--;
  delay(1000);

 if (seconds < 0)
  {
    minutes--;
    seconds = 59;
  }
 if (minutes < 0)
  {
    hours--;
    minutes = 59;
  }
 if (hours < 0)
  {
    hours = 0;
    minutes = 0;
    seconds = 30;
  }
 if (minutes > 9)
  {
    lcd.setCursor(7, 1);
    lcd.print(minutes);
  }
 else
  {
    lcd.setCursor(7, 1);
    lcd.print("0");
    lcd.setCursor(8, 1);
    lcd.print(minutes);
    lcd.setCursor(9, 1);
    lcd.print(":");
  }

 if (seconds > 9)
  {
    lcd.setCursor(10, 1);
    lcd.print(seconds);
  }
 else
  {
    lcd.setCursor(10, 1);
    lcd.print("0");
    lcd.setCursor(11, 1);
    lcd.print(seconds);
    lcd.setCursor(12, 1);
    lcd.print(" ");
  }

 if (hours > 9)
  {
    lcd.setCursor(4, 1);
    lcd.print(hours);
  }
 else
  {
    lcd.setCursor(4, 1);
    lcd.print("0");
    lcd.setCursor(5, 1);
    lcd.print(hours);
    lcd.setCursor(6, 1);
    lcd.print(":");
  }
 if (seconds == 0)
  {
    lcd.clear();
    lcd.print("Este in statie");
    delay(5000);
    lcd.clear();
  }

}

```

# Answer
I don't fully understand your program, but I hope to give some guidelines/tips:

* Instead of using all kind of different variables, with hour, minutes and seconds, with with only one variable that keeps the time. E.g. a long integer value that contains 24 * 60 * hours + 60 * minutes + seconds as one value. E.g. 12:34:56 will be 24 * 60 * 12 + 60 * 34 + 56 = 19,376.
* Subtracting one or 10 seconds will be as easy as subtracting a value 1 or 10.
* To calculate back to seconds, minutes and hours, use 3 formulas (assuming time is the time value):

> ```
> int hours   = (int) time / 60 / 24;
> int minutes = (int) (time - hours * 60 * 24) / 60;
> int seconds = time % 60;
>
> ```

* Keep the code to display the LCD separate, probably it's easier to update every digit every second. You probably change it every second, or when the button has been pressed, which is very slow for a MCU.
* When using a button (you already put it in a variable), just remove 10 seconds, and update the time.
* However, check also the Blink Without Delay example on the Arduino website, since when you press a button, high likely the button will bounce and one press may result in several times 10 seconds will be subtracted.
* And as said above, use good and English variable names, and English comments (except the GUI text to be displayed... O zi buna).
> 4 votes

---
Tags: arduino-uno, timers, button
---


title: writting to buffer from serial input

text:
# Question
Title: writting to buffer from serial input
Can some one explain this behaviour please, i have the following code

```
  byte buffer[512];
  byte block;
  byte len;

  Serial.setTimeout(60000L) ;     // wait until 20 seconds for input from serial
  // Ask personal data: Family name
  Serial.println(F("Type text followed by #"));
  len = Serial.readBytesUntil('#', (char *) buffer, 500) ; // read from serial
  Serial.print(len);
  for (byte i = len; i < 250; i++) buffer[i] = '#';     // pad with #
  Serial.print(len);

```

This works but if i change the "for" line to any thing higer then 250 it stops working and there is a "buffer out of memory condition)

My question is why can't the for loop say the below as the buffer size is 512?

```
for (byte i = len; i < 512; i++) buffer[i] = '#';

```

Am i right in thinking it has something to do with (Char \*), i did copy this code from the example ardunio code and was jsut trying to incress the lenth of input it accpeted.

# Answer
> 1 votes
A byte can only contain values from 0 to 255 (including).

So my guess it works for values until 255.

You should use a different type, e.g. unsigned int or unsigned short.

```
for (unsigned short i = len; i < 250; i++) buffer[i] = '#';     // pad with #

```

Also, I advise to use a constant or define for the buffer size, now you have 3 values (512, 500 and 250 in the loop, I assume they should be based on the same value).

About the char\*: Looking at StreamReadBytesUntil, it seems that the parameter wants a char\* instead of a byte\* (which is more or less the same), but it's better to cast to show the parameter is of type char\* since that is high likely the exact type (but the official Arduino documentation does not show the parameter types sadly).

---
Tags: programming, pointer, buffer
---


title: Update time in RTC over I2c fails

text:
# Question
Title: Update time in RTC over I2c fails
I am communicating two arduinos using the I2C protocol and sending from the slave to the master the integer value of UTC to update the time in the RTC module. When the master receives the UTC value from I2C and tries to set the time by the RTC.set () command the Arduino hangs and needs to be restarted, however, if I use RTC.set () in the loop () method it works perfectly. I do not understand why the system for when it is updated by I2c, is there any conflict?

This is the code with the `loop()` and `Wire.onReceive()`:

```
#include <Thread.h>
#include <ThreadController.h>
#include <SoftwareSerial.h>
#include <LinkedList.h>
#include <SPI.h>
#include <TimeLib.h>
#include <DS3232RTC.h>
#include <Wire.h>

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

  Wire.begin(1);
  Wire.onReceive(receiveEvent);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");

}

void loop() {

  digitalClockDisplay();
  delay(2000);

  // test only
  /*time_t t = processUTCFromI2c("1560810413");

  if (t != 0) {
    RTC.set(t);   // it's works
    setTime(t);
  }*/

}

// ================================ INIT ONRECEIVE ===========================================

void receiveEvent(int howMany) {
  char* vectorAction;
  char c;
  Serial.println(howMany);

  LinkedList<char> myLinkedList = LinkedList<char>();

  //while (1 < Wire.available()) { // loop through all but the last
  for (int i = 0; i < howMany; i++){
    c = Wire.read(); // receive byte as a character
    myLinkedList.add(c);
  }

  vectorAction = new char[myLinkedList.size()+1];

  for(int i=0; i < myLinkedList.size(); i++) {
    vectorAction[i] = myLinkedList.get(i);
  }

  vectorAction[myLinkedList.size()] = '\0';

  getParamsAndValues(vectorAction);

}

void getParamsAndValues(char* i2cValueString) {

  char* getValue;
  char* getParam;
  char* endValue;

  getValue = strchr (i2cValueString, '=');
  getParam = strchr (i2cValueString, '@');
  endValue = strchr (i2cValueString, '#');

  const size_t maxBuffLength = 15;

  char valueBuffer[maxBuffLength+1]; // allocate local buffer with space for trailing null char
  char paramBuffer[maxBuffLength+1];

  valueBuffer[0] = '\0';

  while(getValue && getParam && endValue && (getValue > getParam) && (endValue > getValue)) {
    Serial.println(i2cValueString);

    if (getValue && getParam && (getValue > getParam)) {
      size_t paramLength = getValue-getParam-1;
      valueBuffer[0] = '\0';

      if (paramLength <= maxBuffLength) {
        strncpy(paramBuffer, getParam+1, paramLength);// http://www.cplusplus.com/reference/cstring/strncpy/
        paramBuffer[paramLength] = '\0'; // properly terminate the c-string
      }
    } else {
      // handle Wrong Input
    }

    if (getValue && endValue && (endValue > getValue)) {
      size_t valueLength = endValue-getValue-1;
      valueBuffer[0] = '\0';

      if (valueLength <= maxBuffLength) {
        strncpy(valueBuffer, getValue+1, valueLength);// http://www.cplusplus.com/reference/cstring/strncpy/
        valueBuffer[valueLength] = '\0'; // properly terminate the c-string
      } else {
        // handle buffer too small
      }
    } else {
      // handle Wrong Input
    }

    getValue = strchr (getValue+1, '=');
    getParam = strchr (getParam+1, '@');
    endValue = strchr (endValue+1, '#');

    i2cActionReceived(paramBuffer, valueBuffer);
  }

}

void i2cActionReceived(char* param, char* value) {
  if(strcmp(param, "setTime") == 0) {
    time_t t = processUTCFromI2c(value);

    if (t != 0) {
      RTC.set(t);   // It's not works
      setTime(t);
    }
  }
}

// ================================ END ONRECEIVE ===========================================

// ================================ CONVERT UTC char* TO long ===============================
unsigned long processUTCFromI2c(char* utc) {
  unsigned long auxTime = 0L;

  if (strlen(utc)>0) {
    auxTime = atol(utc);
  }

  return auxTime;
}

```

The slave sends a string through I2C in the format `@setTime=1560810413#`.

In the `loop()` this commented the code that works onorata and on `i2cActionReceived (char* param, char* value)` is where the update fails by onReceive.

# Answer
The symptom you are describing is: The `RTC.set()` method blocks in the `onReceive` callback of the `Wire` library, but not when used in the `loop()` function.

That sounds like an interrupt issue. The `onReceive` callback function is called from an ISR (Interrupt Service Routine) of the I2C hardware. It is no good to use any code, which utilizes interrupts, inside an ISR, until you know, what you are doing.

In this case the `RTC.set()` function (which you can find here at line 152) will call the method `RTC.write()`, which will do multiple I2C transactions (both sending and receiving as master). Doing these inside an ISR may already block the code from executing further.

But there is another problem. You have 2 Arduinos connected by I2C. The master Arduino talks only to the slave Arduino, while the slave Arduino is also a master for the RTC (You initialize this Arduino as slave, but it will become a master for the time, when you try to do master transmissions). Your slave code and the RTC library both use the `Wire` library, meaning the hardware I2C port of the Uno. So you have 2 masters on the same I2C port.

While the I2C standard supports multi-master setups via bus arbitration, the `Wire` library does not. In the case, when both masters start to transmit at the same time, it will block the bus (due to some blocking loops inside the `Wire` library, that cannot handle bus arbitration). So the setup, that you use is either not going to work at all or being very risky, depending on the amount of send data (When the bus is filled with more data, it get's more probable, that a collision between the masters happens).

With I2C on Arduino you should stick to single-master setups. For example you can set the first Arduino as slave, keeping the second Arduino as single master on the bus, which handles both getting UTC from the first Arduino and communicating with the RTC. On the first Arduino you would set up an `onRequest` callback, that fills the I2C buffer with the current UTC time, which then get's transmitted to the master Arduino, so that it can update the RTC's time with it.

---

EDIT:

I2C has a fundamental master-slave principle. The master generates the clock signal and initiates/stops any transactions on the bus. A slave cannot send anything over the bus, when the master didn't request data from it, including "calling" the master. Any communication start's with the master.

The `Wire` library gives you the possibility to initialize the Arduino as slave and then do master transactions. For this the I2C hardware is configured as master for the time of the transactions. So you can initialize both Arduinos as slaves with an address and let them change to master mode for any master transaction, that you need. That is the way, that you are talking about in your comment and what you use in the code in your question.

**BUT** you get a big problem, when both Arduinos try to send at the same time. That is called data collision. The I2C specification has the bus arbitration for this (basically the master that first sends a 1 has to back down from the transaction), so that collisions can gracefully be resolved. The `Wire` library doesn't implement this, so it will block in case of a collision. Then you have to reset the Arduino to get it going again.

You should again analyse your requirements and check, if you really need I2C for communication between the Arduinos, or if you really need individual bidirectional communication. That is often also a design choice.

If you really need individual 2 way communication between the Arduinos, I see 2 possibilities:

1. You can do it the hacky way and add an extra line between both Arduinos. You would set the Arduino with the RTC as I2C master and the other Arduino as slave. The slave Arduino can pull the extra line with a digital output pin to LOW, so that the master Arduino can sense this as signal at one of it's digital input pins (configured with internal pullup resistor). When the master Arduino senses, that the extra line goes to LOW, it can request data from the slave. So you are using the extra line for signaling the master, that new data is available at the slave.
2. If you are not bound to I2C, other communication interfaces might be better suited. UART (in the Arduino framework called `Serial`) implements bidirectional bytewise communication. No master/slave relationship. That would be a lot easier.
> 1 votes

# Answer
As explained by chrisl, the fact that the Arduinos communicate with I2c and the update of the RTC is by I2C, the update fails and locks the system. To resolve this I declare the global variables `boolean updateRTC = false;` and `time_t setUTC;` and in the method that processes UTC I assign the value true to `updateRTC` and the numeric value of UTC to`setUTC` and do the verification in `void loop()`.

```
// global vars
boolean updateRTC = false;
time_t setUTC;

// RTC update inside loop()
void loop() {
  digitalClockDisplay();
  delay(1000);

  if (setUTC > 0 && updateRTC == true) {
    updateRTC = false;
    RTC.set(setUTC);
    setTime(setUTC);
    setUTC = 0;
  }

}

// Method executed at the end of the onReceive() event
void i2cActionReceived(char* param, char* value) {
  if(strcmp(param, "setTime") == 0) {
    setUTC = processUTCFromI2c(value);

    updateRTC = true;
  }
}

```
> 0 votes

---
Tags: arduino-uno, i2c, rtc
---


# Question
Title: http.POST is not sending data to local web page
I am using a nodeMCU to send data to my local web page developed using Spring boot but when I run the code I don't get an error the esp8266 connects to WiFi but I don't get anything on my spring boot app or any responses. Here is the rest controller used from spring boot

```
@RestController
@RequestMapping("/getallcadres")
public class cadreController {
    @Autowired
    cadreRepository cadre;

@PostMapping("/getnbpassage")
    public String getnbrpassage(@RequestBody String nb){
        System.out.println("nombre de passage = "+nb);
        return "received";

    }
}

```

and the Arduino code

```
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>

void setup() {

  Serial.begin(9600);//Serial connection
  WiFi.disconnect();
  WiFi.begin("Iphone de elaa", "27343550");   //WiFi connection

  while (WiFi.status() != WL_CONNECTED) {  //Wait for the WiFI connection completion

    delay(500);
    Serial.println("Waiting for connection");

  }
  Serial.println("Wifi is connected");
  Serial.println(WiFi.localIP());

}

void loop() {

 if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status
 Serial.println("here we start");
   HTTPClient http;    //Declare object of class HTTPClient

   http.begin("http://localhost:8080/getallcadres/getnbpassage");      //Specify request destination
   http.addHeader("Content-Type", "text/plain");  //Specify content-type header

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

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

   http.end();  //Close connection

 }else{

    Serial.println("Error in WiFi connection");

 }

  delay(30000);  //Send a request every 30 seconds

}

```

I am using Arduino IDE 1.6.5 here is what I get

# Answer
> 0 votes
Your URL has `localhost` as the host name. That cannot work. localhost means “self”, the computer initiating the request. In this case it would mean the ESP8266, if it even understood it. You need to use the name or the IP address of the computer running your spring boot app, not localhost.

---
Tags: esp8266, arduino-ide, nodemcu, web
---


# Question
Title: i2c slave write to ARM powered device master
I want to communicate to an ARM microprocessor via I2C protocol (Multitech mDot, which uses Mbed platform). I successfully receive data from it (and got it displayed on Arduino's serial monitor), but when I want to send data from the Arduino I don't receive nothing on the other end. This is my sketch:

```
#include <DHT.h>
#include <Wire.h>

// Sensor temperatura, humedad DHT11 (test).
#define DHTPIN 10
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);

// Comunicacion i2c con nodo lora. 7bitaddress 010 1001 (r/w)
#define SLAVE_ADDRESS 0x29

// Variables globales de sensores
float h;
float t;

void setup() {
  Wire.begin(SLAVE_ADDRESS);
  Wire.onReceive(receiveEvent);
  dht.begin();
  Serial.begin(9600);
}

void loop() {
  delay(5000);
  h = dht.readHumidity();
  t = dht.readTemperature();

  // Comprobamos si ha habido algún error en la lectura
  if (isnan(h) || isnan(t)) {
    Serial.println("Error obteniendo los datos del sensor DHT11");
    return;
  }

  Serial.print("Humedad: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperatura: ");
  Serial.print(t);
  Serial.println(" *C ");

  Wire.onReceive(receiveEvent);
}

// Total de bytes del arreglo de datos a transmitir: 28 bytes.
void receiveEvent(int howMany) {
  Serial.print("Mensaje recibido por i2c desde MDOT LoRa Node: ");
  while (Wire.available() > 0) {
    Serial.print(char(Wire.read()));
  }
  Serial.println();
  char enviar = "Cacatua";
  Wire.write(enviar);
  return;
}

```

I wanted to know if this schematic is correct and if the wire write as it is written is performed. If so, I will need to see what is wrong with the code on my ARM device.

# Answer
> 1 votes
It is important to understand, that `Wire.write()` will not actually send data over the I2C bus. It will only put the data bytes into the send buffer of the library.

The normal way of the `Wire` library to send data as a slave is to implement the `onRequest` callback function. It will be called from an I2C ISR when a master on the I2C bus requests data from this slave. In the callback, you use `Wire.write()` to fill the buffer with data, which then get's send out to the master.

I'm not quite sure about the following: My guess regarding your previous code is, that the `Wire` library clears the send buffer at some time during the send or read code. That would mean, that the data written in the `onReceive` callback will simply be lost, instead of used for transmission of requested data. That might be meant that way, so that the users will stick to implementing the `onRequest` callback, which is the correct way of doing it.

---

Note: In your code, you call `Wire.onReceive(receiveEvent)` on every `void loop()` iteration. That isn't necessary. The `Wire.onReceive()` method only set's a function pointer to the callback function. It does NOT execute this callback function, which only will be called by the corresponding I2C ISR, when data is actually received. You should use this line only once in `setup()` to setup the callback function. Though using it multiple times does not break things here. It's just useless.

---
Tags: i2c, mbed
---


title: Timestamping AnalogBinLogger data

text:
# Question
Title: Timestamping AnalogBinLogger data
I would like to timestamp the data collected from AnalogBinLogger.ino on an Arduino Uno. The sketch uses 512-byte buffers, and I have read that writing data in 512-byte chunks is 'better' in terms of write latencies.

The sketch uses this structure for the buffers:

```
// Data block for 10-bit ADC mode.
const size_t DATA_DIM16 = 254;
struct block16_t {
  unsigned short count;    // count of data values
  unsigned short overrun;  // count of overruns since last block
  unsigned short data[DATA_DIM16];
};

```

Since I want to add the timestamps which are of `unsigned long` type, I would have to modify the structure as follows:

```
// Data block for 10-bit ADC mode.
const size_t DATA_DIM16 = 254;
struct block16_t {
  unsigned short count;    // count of data values
  unsigned short overrun;  // count of overruns since last block
  unsigned short data[DATA_DIM16];
  unsigned long  milli[DATA_DIM16]; // time in milliseconds
};

```

Now, this structure exceeds 512 bytes and is **1528 bytes**. Due to unavailability of enough free stack, my program doesn't run (sketch reports FreeStack to be 1135 bytes). How can I go about this?

PS: My root problem is to achieve **time-synchronisation** among multiple data-collecting Arduinos which sample at high rates like 8kHz. Due to clock drifts, even if I sync the start times, the timestamps collected afterwards would not be relative to each other. Hence I plan to have a master Arduino send its time to the others in regular intervals.

# Answer
> 1 votes
The straightforward solution:

```
const size_t DATA_DIM16 = 84;
struct block16_t {
  unsigned short count;    // count of data values
  unsigned short overrun;  // count of overruns since last block
  unsigned short data[DATA_DIM16];
  unsigned long  milli[DATA_DIM16]; // time in milliseconds
  unsigned long padding;   // pad to 512 bytes
};

```

Now, I suggest to think again about your requirements. Do you really need a 32-bit timestamp for every data point? If they are closely spaced in time, a 16-bit, or even 8-bit timestamp should be enough. You could put a full 32-bit timestamp at the beginning of each block, then only 8-bit timestamps for every data point. This would allow you to store 168 samples per block. You could even pack a 6-bit timestamp with the data sample into an `uint16_t`, and have 252 samples per block.

# Answer
> 1 votes
Writing in 512 byte chunks is done by SD libraries, so you could rely on that layer and simply write and store single events

```
struct block_t {
  uint32_t  milli; // time in milliseconds
  uint16_t data;
  uint8_t  overrun;  // overrun status since last block
};

```

I do not know your `AnalogBinLogger.ino`. In other circumstances there's no such 512 byte limit, but a general and strict RAM limit. (You could decrease your DATA\_DIM to make it fit safely)

---
Tags: arduino-uno, sd-card, time, memory-usage
---


title: MQTT over serial

text:
# Question
Title: MQTT over serial
I'm planning to build a 32 relay IOT node next to my Raspberry Pi. The relays will be controlled by an Arduino Mega 2560. The Pi will run Home Assistant and Mosquitto so I would prefer to communicate with the arduino using MQTT. The Arduino and the Pi will be next to each other, the simplest connection would be over serial. I have found a library: https://github.com/vortex314/serial2mqtt it looks not easy to set up. Do you have any other ideas? Thank you!

# Answer
> 1 votes
Finally I have found the solution! Using mysensors (mysensors.org) I can use the Arduino Mega as a node and a serial gateway. So Home Assistant can control it directly.

# Answer
> 5 votes
As the author of the serial2mqtt gateway. Maybe it's time to have a new look. I've included the binaries for different platforms in the build : https://github.com/vortex314/serial2mqtt/tree/master/build So to get started : unzip the binary and update the serial2mqtt.json config. Should be piece of cake. Let me know otherwise via github.

---
Tags: serial, raspberrypi, home-automation, mqtt
---


# Question
Title: First time set up- permission denied to usb port- ubuntu 14.04
I just plugged my arduino in and the light is on, but the blink test failed to upload. here is my error:

Arduino: 1.6.7 (Linux), Board: "Arduino/Genuino Uno"

Sketch uses 1,030 bytes (3%) of program storage space. Maximum is 32,256 bytes. Global variables use 9 bytes (0%) of dynamic memory, leaving 2,039 bytes for local variables. Maximum is 2,048 bytes. avrdude: ser\_open(): can't open device "/dev/ttyUSB0": Permission denied ioctl("TIOCMGET"): Inappropriate ioctl for device Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

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

# Answer
> 41 votes
From the documentation:

> Open Terminal and type:
>
> ```
> ls -l /dev/ttyACM*
>
> ```
>
> you will get something like:
>
> ```
> crw-rw---- 1 root dialout 188, 0 5 apr 23.01 ttyACM0
>
> ```
>
> The "0" at the end of ACM might be a different number, or multiple entries might be returned. The data we need is "dialout" (is the group owner of the file).
>
> Now we just need to add our user to the group:
>
> ```
> sudo usermod -a -G dialout $USER
>
> ```
>
> then:
>
> ```
> sudo chmod a+rw /dev/ttyACM0
>
> ```
>
> You will need to log out and log in again for this change to take effect.

Note that the preceding is old Ubuntu instructions. On modern distros that use ConsoleKit create the file `/etc/udev/rules.d/01-ttyusb.rules` containing the following and then reload the udev rules and replug the Arduino device:

```
SUBSYSTEMS=="usb-serial", TAG+="uaccess"

```

# Answer
> 6 votes
All you need to do is add yourself to the dialout group as described in the answer by Ignacio Vazquez-Abrams. This is done in the terminal by typing:

```
sudo usermod -a -G dialout $USER

```

You do not need to use `chmod`. This gives read/write access to all users and not just members of the group. Before attempting to connect, however, you must **logout and log back in**. Once you log back in you will be recognized as a member of the dialout group and will be able to open the device.

# Answer
> 1 votes
On Ubuntu 18.04, the only way I found the Arduino IDE installation to work straight out of the box, was using the documentation steps described here:

https://www.arduino.cc/en/Guide/Linux/

No changing groups nor permissions required.

# Answer
> 0 votes
Nothing above have helped me. When I have installed from file, from official site, it doesnt even start. Then I have installed Arduino IDE from "linux app store" and was working but have a problem like our friend from top. So I have uninstalled it and installed via terminal `sudo apt install arduino`and now it\`s working. Cheers.

# Answer
> -1 votes
Or just use the chown command.

```
sudo chown <username> /dev/ttyACM*

```

This worked for me

---
Tags: usb, ubuntu
---


# Question
Title: Control relay with both Arduino and DAQ at the same time
I want to control a relay with both Arduino and DAQ. Arduino is used as an embedded device for the control, while the DAQ is hooked up with a computer and performs the control with a user interface. Here is below a schematic of the circuit wiring for the control:

The two signal pins of the relay are connected with the digital pins of Arduino and DAQ. For some reasons, when Arduino comes into play, the control via DAQ cannot be achieved. If only Arduino or DAQ is connected to the relay, there is no problems with the control.

My plan here is, mstly, to let Arduino to instruct some tasks. In some special cases, I want to have the control with DAQ. Anyone can debug my circuit above? Thanks!

# Answer
I guess, that you drive the digital pin of the Arduino directly with `digitalWrite()` for HIGH and LOW and that the DAQ does the same (I didn't researched this).

In that case your circuit is dangerous for the devices. As long, as they both output the same, everything is ok. But take the case, that the Arduino is driving it's pin HIGH, while the DAQ driving it LOW. That would be a short through the pin driving circuit's of both devices and most likely the flowing current will exceed the maximum current rating of the pin. This can fry the involved pins hardware or even the complete devices. You get some kind of race condition here: The device, that can handle drain/source more current will be the winner.

In general you have to implement rules, how the devices should work together. Do you need the actions from the DAQ to be executed no matter what the Arduino does? Or should the Arduino be the master here? Or something inbetween? It is not clear, what do you need here.

I will give you 2 suggestions about possible ways:

1. You could control the relay only with the Arduino. The DAQ can be connected to a digital input of the Arduino (so that it can sense the DAQ's output state) and in the Arduino code you can implement all the logic you need to drive the relay to your liking.
2. You could define an idle state of your relay input and set it with a pullup or pulldown resistor. It will ensure, that the relay input is at the defined idle state, as long as no device is driving the line to the opposite state. For this you need the devices outputs to be high impedance (on the Arduino this means the pin is configured as input; for the DAQ you need to know yourself or research it).

Let's say the idle state would be HIGH. We would connect the relay pin with 5V through a high resistor (this is the pullup resistor) (maybe 10k, the value is not critical). Both devices can be connected directly. If one device needs to change the state to LOW, it can drive it's output pin actively low, forcing the relay pin to also go to LOW. If it doesn't need the state to be LOW anymore, it should put it's pin into high impedance mode. The pullup resistor will pull the state to HIGH again. You can also add relatively low resistors between the devices to protect against damages from accidentally driving active HIGH while the other is LOW (These can be calculated from the maximum current rating for the pins; 20mA for the Arduino). This kind of logic is often called open drain logic.

simulate this circuit – Schematic created using CircuitLab

If the DAQ cannot put it's pins to high impedance, you can setup that circuit yourself with a single MOSFET:

simulate this circuit

If you use this circuit on both devices, you don't need the small resistors anymore.

---

The second possibility already implements a specific logic. You need to decide if this logic is good for you. You can invert it's logic (idle state LOW). Personally I would go with the first option, because it is easier and more flexible.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: analogRead Function AC Voltage Reading Capabilities
Usually when you sense AC voltage, you get a sinusoidal waveform. However, for AC voltage sources, Arduino analogRead ( ) only presents positive voltage values. So what's basically happening? Is it skipping half the cycle where the voltage is negative. If so, how can I account for that when I try to use the voltage values to calculate for total electrical energy generated by the source (piezoelectric film) and avg. power?

# Answer
> 1 votes
I guess that you are showing the voltages there directly calculated from `analogRead()` and that you connected the AC voltage directly to the analog input (and it's ground with the Arduino's ground).

The reference for every communication/voltage measurement/digital input is ground. Naturally the Arduino can only measure voltages inside of it's own supplied voltage range, meaning 0 to 5V for the Uno. If you apply a negative voltage (relative to ground), you will measure a voltage of 0V. You can even damage the microcontroller, if the negative voltage is too high.

If you have negative and positive voltages, you should offset the signal at the analog input pin, so that the resulting signal stays in the range from 0 to 5V. You can do this with a simple voltage divider. Use two resistors with the same value (for example 5kOhm), so that you will get a new zero point at 2.5V. The AC signal will then variate around that value.

---

For what is happening inside the microcontroller:

The ADC is responsible for measuring the voltage. For this the voltage on the analog input pin will first be sampled (loaded onto an internal condensator) and then step by step compared to the voltages, that the ADC generates by dividing the supply voltage range into 1024 distinct values (10 bit). Again the reference, to which the voltage is measured/compared, is ground. It cannot generate negative voltages, thus cannot compare them.

---
Tags: arduino-uno, analogread, voltage, project-critique
---


title: Serial Enable Maxim RS485 Pin

text:
# Question
Title: Serial Enable Maxim RS485 Pin
If I want to use a MAXIM 485 for a RS485 communication, is there any option to include the Control `DE` and `RE'` pin in a natural manner in the code, instead changing the control pin everytime I made a `Serial.print()`?

Should I overload the HardwareSerial object in order to add those pin operations everytime?

# Answer
No, there isn't - you have to do it manually. And don't forget to flush.

You *could* inherit HardwareSerial if you really wanted - or just write a couple of functions to do the sending and controlling of the DE pin.
> 1 votes

---
Tags: serial, rs485
---


# Question
Title: The current direction for digital output pins
I am new to Arduino. The digital pins can be configured as output (https://www.arduino.cc/en/Tutorial/DigitalPins) for triggering some sensors. I am now setting a digital (output pin), say no. 7,which is connected to the `in1` pin of a SRD relay (https://blog.siliconstraits.vn/relay-what-is-it-and-how-to-use-it/):

I am not very clear about the direction of current flowing in the wire connecting the arduino digital pin to `in1`. To my understanding, when `digitalWrite(pin, HIGH)`, no current flow into the arduino pin, the relay is not triggered, while `digitalWrite(pin, LOW)`, the current flow into the arduino, and the relay is triggered. Please correct me if I am wrong. Thanks.

# Answer
When you set a pin to HIGH then that pin will provide 5V. When you set a pin to LOW then that pin will be set to 0 volts. Which direction the current flows depends on what is at the other end of the wire. Current always flows from higher voltage to lower voltage. If you set a pin to HIGH and the thing it is connected to is at ground then current will flow out of the pin towards ground. If you set a pin to HIGH but the thing it is connected to is already at 5V then no current flows. If you set a pin to LOW and the thing it is connected to has some positive voltage then current will flow to the pin. If you set the pin to HIGH (5V) but the thing it is connected to has more voltage than that (say 10V) then current will flow towards the lower voltage and into the pin, probably damaging the Arduino in the process.
> 1 votes

---
Tags: relay
---


title: Program Arduino Mega Adk on linux

text:
# Question
Title: Program Arduino Mega Adk on linux
for a project my supervisor gave me a Arduino Mega ADK board (https://store.arduino.cc/arduino-mega-adk-rev3) and the usb-cable.

I only programmed a Atmega32 8 bit controller on linux ubuntu. I have no possibility to use windows (i heard it's easy to program the arduino using atmel studio). I can only use ubuntu 16.04. Is there a convient way to program the Arduino like a microcontroller?

I'm not aloud to use the highlevel Arduino libraries. I have to do a cascaded control for a dc-motor and sensor-fusion.

Thanks in advance.

If it's offtopic, could you transfer me to a suitable board?

# Answer
> 2 votes
You can use Eclipse, along with AVR-GCC and AVRDude and an AVR plug-in for Eclipse. Debugging may be a little painful since you don't have all the tools that Atmel Studio gives you. I'd question your employer if you aren't allowed to use the best (free) tools even if they do run on Windows.

Really all you need is the avr-gcc and avrdude to write software for it, you can use any text editor (although it isn't really convienent). Seems like they are pigeon-holing you into a difficult job. Good luck.

---
Tags: linux
---


# Question
Title: How to read a specific amount of data via serial?
I'm trying to send data via serial from my Arduino nano to my ESP. Its an integer from 1 to 4 digits so something like 0, 13, 1234, 123, ...

Every thing works fine but when the data comes too fast it stopps the output and then it print all the data on the screen.

I use this method to recieve data.

```
void loop() { // run over and over
        if (Serial.available()) {
                incomingByte = Serial.readString();
                Serial.println(incomingByte);
        }
}

```

# Answer
From what you have posted, assuming this is the ESP code in the question, it is clear that for every character the Arduino sends the ESP the ESP will send 3 back. So at some speed this will likly stop working
> 1 votes

---
Tags: arduino-uno, esp8266, arduino-nano
---