body:
I am working with some sensors and sending data to a public web server via http, I was thinking this server can be possibly used by more people to send their data and server displays a chart.

I was wondering if there is a IOT industry standard when sending certain type of data, so that in future I don't need to rename this or change documentation to be more compatible or more intuitive.

For example when sending a "motion detected" ping, do I go with `pir=true`, `pir=1`, `motion_detect=true` ?

Then for example when sending temperature, it would be much better `temp_celsius=30` then just `temp=30`.

It should also make developers job much easier if there is a certain standard. Is there one ?

title: variable name standards, e.g best method to send motion_detect=true

Answers: 3

body:
No, there is no "industry standard". You are free to choose what you like.

If you want to be completely generic you could choose to do something like:

```
p1name=Temperature&p1units=celcius&p1value=23.4&p2name=Humidity&p2units=%&p2value=43.8
```

(`%` is a `%` when URL encoded)

Or you could use:
```
p1=Temperature/Celcius/23.4&p2=Humidity/%/43.8
```

That's just two examples. There is no end to how you could do it.

body:
I don't think there is. It also kind of depends on how you are going to store the data.

I'd go with `motion=true` instead of `pir=true`, as it describes what you are detecting, instead of what sensor type you used. What if you decide to change the PIR sensor to a radar-based sensor. Now the variable name doesn't make sense.

Secondly, what happens if you add a second motion sensor somewhere else? I'd add something unique to the request. Something like a node-id. That way, you can differentiate between the two. Something like `?nodeid=1&motion=1`. You can that also add additional info like the battery voltage for that node; `?nodeid=1&motion=1&voltage=3.1`.

I don't think differentiating between C and F makes a lot of sense. But if it does you'd store this somewhere on the server, as it should never really change. Something like; the `temperature` value coming from `nodeid` 6, is the temperature in the "livingroom", and is specified in "C", and should be shown on a graph with Y-axis of "10 C" to "30 C".

body:
Yes, there are systems designed to continuously receive such data and the data exchange is standardized, even some Units are standardized.

### OPC DA

An example is [OPC Data Access](https://en.wikipedia.org/wiki/OPC_Data_Access) for real time values. It seems you want to build a graph, so [OPC Historical Data Access](https://en.wikipedia.org/wiki/OPC_Historical_Data_Access) is more what you're looking for.

One would set up the data points on the server side once, i.e. configure the type and unit that you're gonna receive on that "channel" or "port" or whatever you call it.

Unfortunately, OPC DA and OPC HDA use XML and building XML is not trivial. It's not very suitable for IoT devices.

*Lessons learned*: configure the unit on server side and let the client send data only. Do not use XML for data transfer.

### OPC UA

Then there is [OPC Unified Architecture](https://en.wikipedia.org/wiki/OPC_Unified_Architecture). They also learned their lesson and removed XML and added security. They now use a binary protocol. The specification is more than 1000 pages, so understanding it will be difficult and is in fact so difficult that even OPC UA implementations of different companies do not work together well.

OPC UA defines 25 data types and ways of defining other data types.

The address space in OPC UA is hierarchical - and probably a device can exist in multiple hierarchies, e.g. physical topology like floors and rooms or logical topology that fits into the structure of the machine.

*Lessons learned*: make the protocol simple and think about security, i.e. if you want to do URL encoding (`GET`), then use HTTP**S** at least. AFAIK, devices ESP32 support encryption, so it's no longer a problem for tiny devices. People will use very strange data types, like 18 bit integers. Also, do not only provide a flat list of devices, but let them arrange stuff as needed.

### MQTT and NodeRed

Now these were quite heavy protocols and models driven by companies. Of course there are also protocols better suited for IoT, like [MQTT](https://mqtt.org/). MQTT is widely known and uses the also well known [Node Red](https://nodered.org/) software for handling it. You can define workflows how the data should be handled, converted, stored and whether alarms shall be triggered above or below thresholds.

They already think of connection loss, reconnect and how to send all the data that was already recorded but could not be sent.

*Lessons learned*: People want more than just data storage and a graphics.

## Units

openHAB tries to come up with a [List of units](https://www.openhab.org/docs/concepts/units-of-measurement.html#list-of-units). I am a radio amateur. I am measuring electromagnetic fields. I am still missing

* SWR (standing wave ratio)
* dBu (dB µW)
* dBc (dB relative to the strongest signal)
* dBV, dBmV (dB for Volts instead of Watts)

### Personal experience

I was working for a company that made software for industry. There are devices that send a measurement value every 100 ms. Let's say this is a simple temperature value of just 1 byte, that's still 315'000'000 records per year.

How do you display such data? On a Full HD screen you would still need to combine 150'000 measurement values on a single column of pixels.

*Lessons learned*: you need sophisticated data crunching skills to generate the graphics. The users probably want some control over the time span they are viewing. They want zooming and panning.

### Conclusion

> I was thinking this server can be possibly used by more people to send their data and server displays a chart.

IMHO, sorry, it's hardly needed. People do not want to send their data to a random HTTP server. Some want to set it up at home only, so that no data ever reaches the Internet. Some people want to do more than just displaying a grpahics (especially alarms). MQTT and Node Red runs locally, on a Raspberry, on a server and even in the cloud, whatever you want.

You do not only need `pir=true, pir=1, motion_detect=true`, you also need

* an ID for the device,
* a timestamp when the data was recorded
* potentially a way to send bulk data after the server was offline for an hour of maintenance
* a system for units
* encryption

That's quite an effort. Node Red has > 4000 commits.


body:
So basically I'm working on a project that uses an Atmega328 like on the Arduino Uno. I need to receive both DMX (with max485) and E131 (Not both at the same time, I'll decide which with a boolean in the sketch) and then use that to control 16 channels. I need the TX and RX pins (UART) for the max485 (DMX), 16 outputs for the triacs, and 1 pin for zero-cross detection. If I use the Analog pins as digital outputs, that lets 3 pins to connect the ethernet module. Most of them use 4 pins, I believe it's SPI. I only have 3 available. Is this possible? Also, I may need a second zero-cross detector, so is it possible with 2 pins then?
Thanks!

title: 3 pin ethernet module?

Answers: 0


body:
I am having trouble getting my Arduino Uno to run my code when I disconnect it from my computer.

I have a 9V battery to power it and it is turning on, however, it is not doing anything at all. What can I do to make it run the code when it is using the battery and not connected to the computer?

title: Running an Arduino without the computer

Answers: 2

body:
And Arduino should run the last program installed to it when you apply power to the barrel connector. IT powers up, does a reset, and begins executing the sketch that's installed.

As others have mentioned, the small rectangular 9V batteries have very low current output and total power storage. You will run a fresh 9V battery down to nothing in a short time with just an Arduino, and with other components also drawing power it will happen even faster. I suggest getting a ≥ 1 amp 7V - 9V DC transformer and plugging that into the barrel connector.

You need to tell us what components you are using in your project and their current requirements.

If you are just running a "bare" arduino and very little else then you should get like 24 hours out of a fresh 9V battery, as mentioned by @ocrdu

body:
Use a fresh 9V battery, or better, a proper power supply or some AA batteries in series, just to make sure the power supply isn't the problem.

BTW on some Arduinos (though probably not yours) it often pays off to check if there is a `while (!Serial);` or some such in the code. If there is, it is blocking code execution until the USB is connected and the serial monitor is opened.


body:
I want to change or declare a constant in the `setup()` and then, I want to access it in the `loop()`.

I have searched a lot, but the only questions I found could be solved by declaring the constant in the beginning of the program. That doesn't work for me because I am using the Adafruit BMP388 and I can't use the pressure before `setup()`.

I also tried declaring the variable before `setup()` and changing it inside `setup()`, but it didn't change when I used it in `loop()`.

How can I solve this?

title: Change/declare a constant in setup and use it in loop

Answers: 1

body:
You are not going to get good answers without showing your code, but maybe this is a good guess of what you want:

why not try something roughly like this (untested and incomplete)?

    Adafruit_BMP3XX bmp;
    float startPressure;
    float difference;

    void setup() {
      bmp.begin_I2C();
      startPressure = bmp.readPressure();
    }

    void loop() {
      difference = startPressure - bmp.readPressure();
    }

Or, better:

    Adafruit_BMP3XX bmp;

    void setup() {
      bmp.begin_I2C();
    }

    void loop() {
      static const float startPressure = bmp.readPressure();
      static float difference;
      difference = startPressure - bmp.readPressure();
    }


body: I am wanting to have a display where I can design the GUI on a program and then somehow transfer it to the display. For the graphics I want to make, it would be really hard to manually write the code. I heard that the Nextion displays do this but they are quite costly. Is there some cheaper alternative? If not, can you make a normal display do all of that?

title: Alternatives to Nextion display

Answers: 1

body:
We work with [Proculus][1] displays, and we are a distributor of this display here in Brazil ([Victor Vision][2]). The display is great, very professional. Used in medical equipments, and cheaper than Nextion.
They are starting now in the web and selling in Alibaba.

  [1]: https://proculustech.en.alibaba.com/
  [2]: https://victorvision.com.br/


body:
I wanted to make a buzzer go off when the distance measured by the ultrasonic sensor becomes more than 100cm. The things used in this project are a 4x4 keypad, an hc-sr04 ultrasonic sensor, and a passive buzzer all connected to a keyestudio mega 2560.

What happens is that the moment I upload the code/turn on the Arduino, the buzzer turns on despite a solid object being within a 100cm range. And the buzzer almost randomly stops for a couple of seconds and continues. It won't turn off, even when I press the appropriate key on the keypad.

This is the code I have written, thanks

        #include <Key.h>
        #include <Keypad.h>

        const int trigPin = 11;    //output to sensor
        const int echoPin = 12;    //input from sensor
        const int buzzPin = 13;    //output to buzzer

        const byte ROWS = 4;
        const byte COLS = 4;

        long duration;    //travel time of sound waves
        int distance;    //distance at which an object is

        char hexaKeys[ROWS][COLS] = {
          {'1', '2', '3', 'A'},
          {'4', '5', '6', 'B'},
          {'7', '8', '9', 'C'},
          {'*', '0', '#', 'D'}
        };

        byte rowPins[ROWS] = {9,8,7,6};
        byte colPins[COLS] = {5,4,3,2};

        Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

        void setup() {
          // put your setup code here, to run once:
          pinMode(trigPin, OUTPUT);
          pinMode(echoPin, INPUT);
          pinMode(buzzPin, OUTPUT);
          Serial.begin(9600);
        }

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

          char customKey = customKeypad.getKey(); // gets key values from keypad

          if(customKey) {
            Serial.println(customKey);
           }

          digitalWrite(trigPin, LOW);    //reset the sensor by turning it off for 2 microseconds
          delayMicroseconds(5);

          digitalWrite(trigPin, HIGH);    //generate ultrasound wave by turning it on for 10 microseconds
          delayMicroseconds(50);
          digitalWrite(trigPin, LOW);

          duration = pulseIn(echoPin, HIGH);    //time it takes for sound to get back
          distance = duration*0.034/2;    //plug into formula for distance

          Serial.println(distance);

        if (distance <= 100){
         digitalWrite(buzzPin, LOW);
          }
        if (distance >= 100){
          digitalWrite(buzzPin, HIGH);
          if (customKey != 7){
            digitalWrite(buzzPin, HIGH);
            delay(2000);
            digitalWrite(buzzPin, LOW);
            delay(1000);
          if (customKey == 7){
            digitalWrite(buzzPin, LOW);
    }
    }
    }
     }

title: Why is my buzzer always on?

Answers: 0


body:
SOLVED:
after may hours of testing i have solved the problem.
it turned out to not be a software issue. the power supply i was using did not have a flyback diode and thus caused large voltage spikes that would crash the esp. the solution was to add a diode on the inductive load to remove those voltage spikes.

I have an esp-01 running some code that checks for a rf remote signal using the rc-switch library, it is also running some blynk and ota code.

when i press one of the buttons on my rf remote the *buzzer* pin keeps being triggered but will not shut off, eventually the esp will crash..

the device is in a permanent location thus the reason for the ota updates and i cant easily hookup a serial monitor to see what the esp crash code is.

the troublesome code is,

```

    void newloop() {
      if (mySwitch.available()) {
        // int recieved = mySwitch.getReceivedValue();
        if (mySwitch.getReceivedValue() == 5099665) {
          digitalWrite(buzzer, LOW);
          delay(200);
          digitalWrite(buzzer, HIGH);
          mySwitch.resetAvailable();
        }
        else if (mySwitch.getReceivedValue() == 5099666) {
          digitalWrite(buzzer, LOW);
          delay(2000);
          digitalWrite(buzzer, HIGH);
          mySwitch.resetAvailable();
        }
      }
      // Blynk.run();
    }

```

the full code, with redacted passwords/keys is,

```
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>

#define BLYNK_PRINT Serial
#include <RCSwitch.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define buzzer 2
char auth[] = "<blynk auth>";
RCSwitch mySwitch = RCSwitch();

const char* ssid = "HansenHome";
const char* password = "<wifi password>";
ESP8266WebServer server;

bool ready = false;
bool ota_flag = true;
uint16_t time_elapsed = 0;

void setup() {

  Serial.begin(115200);
  Serial.println("Booting");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer, HIGH);
  Blynk.begin(auth, ssid, password);
  mySwitch.enableReceive(0);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }

  // Hostname defaults to esp8266-[ChipID]
  ArduinoOTA.setHostname("lock");

  // No authentication by default
  ArduinoOTA.setPassword("<uploading password>");

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_SPIFFS
      type = "filesystem";
    }

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/restart",[](){
    server.send(200,"text/plain", "Restarting...");
    delay(1000);
    ESP.restart();
  });

  server.on("/setflag",[](){
    server.send(200,"text/plain", "Setting flag...");
    ota_flag = true;
    time_elapsed = 0;
  });

  server.begin();
}

void loop() {
  if(ota_flag)
  {
    uint16_t time_start = millis();
    while(time_elapsed < 10000)
    {
      ArduinoOTA.handle();
      time_elapsed = millis()-time_start;
      delay(10);
    }
    ota_flag = false;
  }
  if(ready == false) {
    ready = true;
    digitalWrite(buzzer, LOW);
    delay(20);
    digitalWrite(buzzer, HIGH);
    delay(20);
    digitalWrite(buzzer, LOW);
    delay(20);
    digitalWrite(buzzer, HIGH);
    delay(20);
    digitalWrite(buzzer, LOW);
    delay(20);
    digitalWrite(buzzer, HIGH);
    delay(20);
    digitalWrite(buzzer, LOW);
    delay(20);
    digitalWrite(buzzer, HIGH);
    ready = true;
  }
  server.handleClient();
  newloop();
}

BLYNK_WRITE(V1) {
  digitalWrite(buzzer, LOW);
  delay(200);
  digitalWrite(buzzer, HIGH);
}

void newloop() {
  if (mySwitch.available()) {
    // int recieved = mySwitch.getReceivedValue();
    if (mySwitch.getReceivedValue() == 5099665) {
      digitalWrite(buzzer, LOW);
      delay(200);
      digitalWrite(buzzer, HIGH);
      mySwitch.resetAvailable();
    }
    else if (mySwitch.getReceivedValue() == 5099666) {
      digitalWrite(buzzer, LOW);
      delay(2000);
      digitalWrite(buzzer, HIGH);
      mySwitch.resetAvailable();
    }
  }
  // Blynk.run();
}
```

EDIT:

so after so further testing it appears to be a power supply issue, the power supply i was using was hooked up to a large inductive load. once that load is turned off there is a huge power spike and for some reason causing the esp to crash.

the board the esp is on has 2 voltage regulators and a few input caps

i added a large cap to the main supply and a 100uf to the 3.3v rail directly on the esp. it is still crashing..

title: esp-01 with rf receiver keeps crashing

Answers: 0


body:
I have tried to send all the variables to both the webpage and to myphpadmin. I seperated
the code into two functions and put the functions inside the void loop() function under the
impression that it will loop both but it seems if I put both then the device will only send
data to phpmyadmin. However, if I delete void logs() which is the function that sends data to
phpmyadmin then the void page() which sends the data to the webpage starts working. I can't find a solution for these two functions to work together, I really don't understand what I'm doing wrong, your guidance would be much appreciated

this is my code:

```
String header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";

String html_1 = R"=====(
<!DOCTYPE html>
<html>
 <head>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'/>
  <meta charset='utf-8'>
  <style>
    body {font-size:100%;}
    #main {display: table; margin: auto;  padding: 10px 10px 10px 10px; }
    #content { border: 5px solid blue; border-radius: 15px; padding: 10px 0px 10px 0px;}
    h2 {text-align:center; margin: 10px 0px 10px 0px;}
    p { text-align:center; margin: 5px 0px 10px 0px; font-size: 120%;}
    #time_P { margin: 10px 0px 15px 0px;}
  </style>

  <script>
    function updateTime()
    {
       var d = new Date();
       var t = "";
       t = d.toLocaleTimeString();
       document.getElementById('P_time').innerHTML = t;
    }

    function updateTemp()
    {
       ajaxLoad('getTemp');
    }

    var ajaxRequest = null;
    if (window.XMLHttpRequest)  {
      ajaxRequest =new XMLHttpRequest();
      }
    else   {
      ajaxRequest =new ActiveXObject("Microsoft.XMLHTTP");
      }

    function ajaxLoad(ajaxURL)
    {
      if(!ajaxRequest){ alert('AJAX is not supported.'); return; }

      ajaxRequest.open('GET',ajaxURL,true);
      ajaxRequest.onreadystatechange = function()
      {
        if(ajaxRequest.readyState == 4 && ajaxRequest.status==200)
        {
          var ajaxResult = ajaxRequest.responseText;
          var tmpArray = ajaxResult.split("|");
          document.getElementById('Temperature').innerHTML = tmpArray[0];
          document.getElementById('Humidity').innerHTML = tmpArray[1];
          document.getElementById('Pressure').innerHTML = tmpArray[2];
          document.getElementById('Altitude').innerHTML = tmpArray[3];
        }

      }
      ajaxRequest.send();
    }

    var myVar1 = setInterval(updateTemp, 1000);
    var myVar2 = setInterval(updateTime, 1000);

  </script>

  <title>Temperature & Humidy Monitor</title>
 </head>

 <body>
   <div id='main'>
     <h2>Temperature & Humidity Monitor</h2>
     <div id='content'>
       <p id='P_time'>Time</p>
       <h2>Temperature</h2>
       <p> <span id='Temperature'>--</span> ℃ </p>
       <h2>Humidity</h2>
       <p> <span id='Humidity'>--</span> % </p>
       <h2>Pressure</h2>
       <p> <span id='Pressure'>--</span> hPs </p>
       <h2>Altitude</h2>
       <p> <span id='Altitude'>--</span> m </p>
     </div>
   </div>
 </body>
</html>
)=====";

#ifdef ESP32
  #include <WiFi.h>
  #include <HTTPClient.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESP8266HTTPClient.h>
  #include <WiFiClient.h>
#endif
#include <Wire.h>
#include "HTTPSRedirect.h"
#include "DebugMacros.h"
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <ESP8266WebServer.h>
#include <DHT.h>

#define SEALEVELPRESSURE_HPA (1013.25)
#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT11   // DHT 11

Adafruit_BME280 bme;

const char* ssid = "fl";  // Enter SSID (WiFi Name) here
const char* password = "99110233";  //Enter Password here
const char* serverName = "http://192.168.101.17/sensordata/post-esp-data.php";
ESP8266WebServer server(80);

String apiKeyValue = "tPmAT5Ab3nnn9";
String sensorName = "BME280";
String sensorLocation = "Office";

float Temperature;
float Humidity;
float Pressure;
float Altitude;
String request = "";
int pin = 2;

void setup() {
  // initialize GPIO 2 as an output.
  pinMode(pin, OUTPUT);

  Serial.begin(115200);

  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  Serial.println("Connecting to ");
  Serial.println(ssid);

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

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

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

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

}

void loop() {

  page();
  logs();

}

void page(){
  //sends data to webpage
  server.handleClient();

  WiFiClient client = server.client();     // Check if a client has connected
    if (!client)  {  return;  }

    request = client.readStringUntil('\r');     // Read the first line of the request

    Serial.println(request);
    Serial.println("");

    if ( request.indexOf("getTemp") > 0 )
     {
          Serial.println("getTemp received");

          // Reading temperature or humidity takes about 250 milliseconds!

         Temperature = bme.readTemperature();
         Pressure = bme.readPressure() / 100.0F;
         Altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
         Humidity = bme.readHumidity();    // Read temperature as Fahrenheit (isFahrenheit = true)

          if ( !isnan(Temperature) && !isnan(Humidity) && !isnan(Pressure) && !isnan(Altitude) )
          {
              client.print( header );
              client.print( Temperature );   client.print( "|" );
              client.print( Humidity );   client.print( "|" );
              client.print( Pressure ); client.print( "|" );
              client.print( Altitude ); client.print( "|" );
              Serial.println("data sent");
          }
          else
          {
              Serial.println("Error reading the sensor");
          }
     }

     else
     {
        client.flush();
        client.print( header );
        client.print( html_1 );
        Serial.println("New page served");
     }

    delay(5);

    if (Temperature > 20.0){
    digitalWrite(pin, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(50);               // wait for a second
    digitalWrite(pin, LOW);    // turn the LED off by making the voltage LOW
    delay(1);
  }
}

void logs(){
  //sending to database
  //Check WiFi connection status
  if(WiFi.status()== WL_CONNECTED){
    HTTPClient http;

    // Takes Domain name with URL path or IP address with path
    http.begin(serverName);

    // Specifies content-type header
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");

    // Prepare HTTP POST request data
    String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName
                          + "&location=" + sensorLocation + "&value1=" + String(bme.readTemperature())
                          + "&value2=" + String(bme.readHumidity()) + "&value3=" + String(bme.readPressure()/100.0F) + "";
    Serial.print("httpRequestData: ");
    Serial.println(httpRequestData);

    //String httpRequestData = "api_key=tPmAT5Ab3nnn9&sensor=BME280&location=Office&value1=24.75&value2=49.54&value3=1005.14";

    // Send HTTP POST request
    int httpResponseCode = http.POST(httpRequestData);

    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }

    http.end();
  }
  else {
    Serial.println("WiFi Disconnected");
  }
  //Send an HTTP POST request every 30 seconds
  delay(30000);
}

void handle_OnConnect(){

  Temperature = bme.readTemperature();
  Pressure = bme.readPressure() / 100.0F;
  Altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
  Humidity = bme.readHumidity();

}

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

title: esp8266 sending to both webserver and myphpadmin

Answers: 0


body:
On an `ESP32` board I am trying this simple code to control the onboard led.

But if I set it to `HIGH`, led is **OFF**, if I set it to `LOW`, led is **ON** (fully bright).
What could cause this ?

The board has one red and one blue leds, the blue one is the one that can be controlled.

```
#define onboard_led 2

void setup() {
  pinMode(onboard_led, OUTPUT);
}

void loop() {
    digitalWrite(onboard_led, HIGH);
    // digitalWrite(onboard_led, LOW);
}
```

**Edit:** it was a board like this ("Geekcreit" I think):

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

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

title: Onboard led HIGH and LOW seems reversed

Answers: 1

body:
As this image from [Okdo Page on LED Driving][1] shows, there are two ways to drive an LED from a GPIO output pin:

[![https://www.okdo.com/project/gpio-led/?ok_ts=1605113937103][2]][2]

In the Active HIGH case, a HIGH output on the GPIO will turn the LED on since that will source current out of the pin and through the LED into ground.

In the Active LOW case, a LOW output on the GPIO will sink current from the +V supply into the pin.

In your case the LED is hooked up in the Active LOW configuration and so to turn it ON you must set the pin to LOW.

I'll add that these ESP32 boards are made by many different manufacturers and they are not all identical.

  [1]: https://www.okdo.com/project/gpio-led/?ok_ts=1605113937103
  [2]: https://i.stack.imgur.com/SRvCl.png


body:
The LDR sensor gives a range of values to show whether a LED is OFF/ON, let's say above LDR range 400, the led is ON. When a LED is ON, after reading the sensor values it shows above LDR range 800, because the LDR sensor measuring in ms, a single LED blink shows six LDR 800+ values. Is there any way to count all the six  LDR 800+ values to increase counter by 1?

Here's my output in serial monitor. 314 to 322 is led OFF state and 816 to 851 is led ON state.
```
LED : 314
LED : 314
LED : 314
LED : 321
LED : 322
LED : 322
LED : 816
LED : 817
LED : 818
LED : 817
LED : 817
LED : 815
LED : 351
LED : 329
LED : 323
LED : 327
LED : 326
LED : 339
```

title: Count specific range of output as 1 single output

Answers: 3

body:
By my understanding you want to count the values where your LED is on (800+ values in your case).

For this you can simply create an if condition where in you say if the value is greater than 800 increase counter by 1

    int count = 0;

    if(value>=800):
        count++

Here the variable value is the data you are printing on your serial monitor and count is your counter.

Also add the if condition inside the loop function and the declare the variable count = 0 outside the loop function

body:
I'm not sure what the value 400 is used for exactly, but the code below is for increasing the counter when at least 6 consecutive values above 800 are occurred.

The key is to use a state machine.
I don't have a compiler at hand so forgive possible syntax errors.
First we define a state. In your case, there are only two possibilities, so a boolean (`bool`) is used, normally an `enum` is used.

    bool _counting = FALSE;

We also need a constant (or define) and a counter to see how many ON values are needed before incrementing the counter, which counts downwards to 0 (and can go negative when more ON values occur).

    const int MIN_FLASH_LENGTH = 6;
    int _onBeforeIncrementing = MIN_FLASH_LENGTH;

However, we can use the last variable to see if counting is occurring, so we do not have to use the boolean above.

Then we need a counter for the amount of flashes itself:

    int _amountOfFlashes = 0;

Both of these are global variables.

Furthermore, in the loop, we need to check for the LED value.

Thus the entire code will be:

    const int MIN_FLASH_LENGTH = 6;

    int _onBeforeIncrementing = MIN_FLASH_LENGTH;
    int _amountOfFlashes = 0;

    void loop()
    {
        int ledValue = getLedValue(); // Use your code here
        if (ledValue >= 800)
        {
            _onBeforeIncrementing --;
            if (_onBeforeIncrementing == 0)  // Flash of enough length occurred
            {
                _amountOfFlashes++;
            }
        }
        else // Restart counting
        {
            _onBeforeIncrementing = MIN_FLASH_LENGTH;
        }
    }

The code fragment

    if (_onBeforeIncrementing == 0)
    {
        _amountOfFlashes++;
    }

can be reduced to:

     _amountOfFlashes += (_onBeforeIncrementing == 0) : 1 : 0;

Also note if you have more code to add, to use the name LED or LDR into the global variables for clearity.

body:
There are two distinct problems here.

The first problem is to convert the analog reading into a binary value.
You measure a value between 314 and 856, and you want to know whether
the LED is ON or OFF. The simplest solution is to compare the reading to
a threshold that is roughly in the middle of the range you measure. You
could say, for example, that the LED of OFF if the reading is below 580,
and is ON otherwise:

```c++
bool led_is_on = analogRead(ldr_pin) >= 580;
```

If the readings are noisy while they cross the threshold (does not seem
to be the case in the short span of data you show), you may want to use
some noise cancelling techniques. You could, as suggested by Michel
Keijzers, require multiple consecutive “ON” reading before deciding the
LED is actually ON. Or you may research the technique of using
_hysteresis_, which would be my favorite solution, as it is extremely
simple. However, if your readings are always as clean as what you are
showing us (never fluctuating mid-range), you can stick with the simple
threshold solution shown above.

The second problem is called _edge detection_. You want to count the
blinks. For this, you need to count how many times the LED _turns_ ON,
which is not the same as how many times the LED _is_ ON. You know that
the LED turned ON if you just detected it is ON and, _on the previous
iteration_ it was OFF. So you have to remember whether the LED was ON
last time you looked at it. This means you have to store this
information (whether the LED was ON) in a `static` (or, if you prefer,
global) variable. Which leads to the following program:

```c++
int blink_count;

void loop() {
    static bool led_was_on = false;
    bool led_is_on = analogRead(ldr_pin) >= 580;
    if (!led_was_on && led_is_on) {
        blink_count++;
    }
    led_was_on = led_is_on;
}
```

Note the condition: `!led_was_on && led_is_on` means “The LED was _not_
ON and now it is ON”.


body:
Good day All,

This is my first time posting to this forum and kind off my last resort as I would've liked to figure it out myself. I am trying to create a soil moisture probe which can be used on farms to determine soil moisture at different depths. The project consists of a Arduino Nano, a DIY capacitive moisture reading setup (schematic attached- My setup is the same except for the LED moisture indicator)) and an LCD screen to display the required value.

My initial setup was a Arduino Nano (328P Old Bootloader) with a resistive soil moisture sensor. However, these sensors (as they are resistive) do not give reliable readings when measuring at different spots in a field. I believe it is largely influenced by pH, salt content etc.

My next approach was to build a DIY capacitive soil moisture sensor. After searching the web I came across a setup on hackster.io ( https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72 ) where a signal is sent via a ESP 32 microcontroller to a probe in the soil and a signal is returned. I implemented the same setup with the same components however I only used optimization of the timers on the Nano to generate the PWM wave (Once again this code was also obtained from another website and I am still a bit confused on how the code works).

I seem to get a reading from the sensor but the zero value seems to very volatile. Even if the wire is only picked up, the output reading changes. Is there a way to get around this and can someone please help me to get my system working optimally.

It would be highly appreciated.

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

     /

        /The setup uses a Chinese Arduino Nano, a 10M ohm, a 10k ohm, a 1N4007 diode and a 1 microfarrad capacitor as shown in the schematic.
        //The LED moisture indicator in the schematic can be ignored

        //#include <LiquidCrystal_I2C.h>
        //#include <LcdBarGraphRobojax.h>
        #include <Wire.h>

        //LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
        //LcdBarGraphRobojax lbg(&lcd, 16, 0, 0);

        float Moistlevel = 0;
        float Moistpin = A1;
        float Moisture = 0;
        float RESET;
        float factor;
        const byte CLOCKOUT = 9;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);

      TCCR1A = bit (COM1A0);                  //Code which I obtained to initiate the onboard timer 1 to give a signal through D9
      TCCR1B = bit (WGM12) | bit (CS10);
      OCR1A =  0;                             // Apparently this should be changed for prescaling. Is it necessary?

      RESET = analogRead(Moistpin);           // Take a initial reading to zero the setup

      for (int j = 1; j < 5 ; j++)            // Take another 5 readings of which the average will be determined
      {
        RESET = RESET + analogRead(Moistpin);
        delay(200);
      };

      RESET = RESET / 6;

      Serial.print(RESET);
      Serial.println();

      Serial.print("Moistlevel");
      Serial.print("\t");
      Serial.print("\t");
      Serial.print("Moisture");
      Serial.println();
    }

    void loop() {

      Moistlevel = analogRead(Moistpin);                  //Take an average reading every second

      for (int i = 1; i < 5 ; i++)
      {
        Moistlevel = Moistlevel + analogRead(Moistpin);
        delay(200);
      };

      Moistlevel = Moistlevel / 6;
      Moisture = (RESET - Moistlevel) / (RESET / 100);    //Conversion to go from a voltage reading to a percentage reading

      if (Moisture < 0)                                   //Moves the initial if a negative moisture is obtained.
      {
        RESET = Moistlevel;
      };

      Moisture = (RESET - Moistlevel) / (RESET / 100);    //Obtains the new moisture value and prints it.

      Serial.println(Moistlevel);
      Serial.print("\t");
      Serial.print("\t");
      Serial.print("\t");
      Serial.print(Moisture);
      Serial.println();
      delay (500);
    }

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

title: Programming Questions / Capacitive Soil Moisture Sensor

Answers: 2

body:
Calling this a `capacitive` sensor may be inaccurate. And that could be the least of its problems. The "fritzing" schematic is unclear, and seems to be at odds with the explanation in [Step 4 of the description](https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72#toc-step-4--the-electronic-set-up-1). Fortunately, a [legible schematic was derived here](https://forum.arduino.cc/index.php?topic=713146.0).

The author of the [hackster.io article](https://www.hackster.io/Pedro52/arduino-capacitive-soil-moisture-sensor-diy-with-esp32-d7ad72) cites Andreas Speiss' well-known YouTube video on ["Why Most Moisture Sensors Suck"](https://www.youtube.com/watch?v=udmJyncDvw0&feature=youtu.be)... and then proceeds to design a moisture sensor that... sucks! This design seems to "miss the point": ***dc current causes an [electrolytic reaction](https://opentextbc.ca/chemistry/chapter/17-7-electrolysis/) when the conductor is in direct contact with an electrolyte (like water and damp soil).***

Wrt the OP's comment that touching the wire changes the output reading: It's almost certain that there is more capacitance in the lead wire than there is in the "fondue forks". According to the article, audio cable was the author's choice for transfer of a 600 kHz signal from his breadboard to the sensor. The *long-ish* lead wires to the sensor strike me as an odd choice.

I've been more than a little critical of this hackster.io project. But of course I may have overlooked something important - I make mistakes each and every day. If someone cares to point out any mistakes I've made here, I'll be glad to revise or delete this post. Until then, ***my proposed answer is to find a better DIY project.***

Nevertheless - you **are** on the right track by deciding to build a ***capacitive*** moisture sensor. Unless the "fondue forks" are insulated to render them non-conductive when immersed in the soil/water electrolyte, this is not a capacitive sensor - it is resistive. And its flaws may go even deeper. Another DIY guide may yield better results.

For anyone interested, an [LTspice](https://www.analog.com/en/design-center/design-tools-and-calculators/ltspice-simulator.html) simulation of the [sensor circuitry](https://forum.arduino.cc/index.php?topic=713146.0) may provide insights into its operation. In one case, the sensor is modeled as a purely capacitive device (i.e. the "Fondue Forks" are insulated to prevent dc current from flowing through the soil), and in the second case as an R-C circuit (i.e. the "Fondue Forks" are un-insulated, and dc current flows through the soil). The values for Rw2 and C2/C1 were based on measurements I made with a similar sensor:

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

I made the following observations using this model of the sensor:

1. the time constant for the RC filter on the sensor output may be substantially longer than necessary.

2. Note the dc current flow through Rw2 averages ~ 0.18mA. Knowledge of this value will allow use of [Faraday's Law of Electrolysis](https://www.finishing.com/faqs/faradayslaw.shtml) to estimate how much of the [chrome plating](https://hcsplating.com/about/plating-faq/) will be dissolved in your soil over time.

3. The value of Rw2 largely determines the value of the output voltage; the value of the capacitance plays a much smaller role. Thus, this sensor is mostly *resistive* rather than *capacitive*.

The LTspice `.asc` file follows; all feedback welcomed:

```
Version 4
SHEET 1 908 720
WIRE 336 32 288 32
WIRE 352 32 336 32
WIRE 512 32 432 32
WIRE 288 80 288 32
WIRE 336 80 336 32
WIRE 416 80 336 80
WIRE 512 80 512 32
WIRE 512 80 480 80
WIRE 512 96 512 80
WIRE 160 208 128 208
WIRE 288 208 288 144
WIRE 288 208 240 208
WIRE 480 208 288 208
WIRE 288 288 288 272
WIRE 288 288 128 288
WIRE 480 288 288 288
WIRE 288 304 288 288
WIRE 320 368 272 368
WIRE 336 368 320 368
WIRE 512 368 416 368
WIRE 272 400 272 368
WIRE 320 416 320 368
WIRE 416 416 320 416
WIRE 512 416 512 368
WIRE 512 416 480 416
WIRE 512 432 512 416
WIRE 160 528 128 528
WIRE 272 528 272 464
WIRE 272 528 240 528
WIRE 384 528 272 528
WIRE 464 528 384 528
WIRE 272 608 272 592
WIRE 272 608 128 608
WIRE 384 608 272 608
WIRE 464 608 384 608
WIRE 272 624 272 608
FLAG 288 304 0
FLAG 272 624 0
FLAG 480 208 Vsensor1
FLAG 464 528 Vsensor2
FLAG 512 96 0
FLAG 512 432 0
FLAG 288 32 Vout-insul
FLAG 272 368 Vout-unins
SYMBOL voltage 128 192 M0
WINDOW 3 -172 139 Left 0
SYMATTR Value PULSE(0 3.3 0 20n 20n 833.5n 1667.0n)
SYMATTR InstName V1
SYMBOL voltage 128 512 M0
WINDOW 3 -140 138 Left 0
SYMATTR Value PULSE(0 3.3 0 20n 20n 833.5n 1667.0n)
SYMATTR InstName V2
SYMBOL cap 256 528 R0
SYMATTR InstName C2
SYMATTR Value 80.0p
SYMBOL res 368 512 R0
SYMATTR InstName Rw2
SYMATTR Value 5000
SYMBOL res 256 192 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName Rs1
SYMATTR Value 10k
SYMBOL res 256 512 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName Rs2
SYMATTR Value 10k
SYMBOL cap 272 208 R0
SYMATTR InstName C1
SYMATTR Value 80.0p
SYMBOL diode 304 144 R180
WINDOW 0 24 64 Left 2
WINDOW 3 24 0 Left 2
SYMATTR InstName D1
SYMATTR Value 1N4007
SYMBOL diode 288 464 R180
WINDOW 0 24 64 Left 2
WINDOW 3 24 0 Left 2
SYMATTR InstName D2
SYMATTR Value 1N4007
SYMBOL res 448 16 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R1
SYMATTR Value 1Meg
SYMBOL res 432 352 R90
WINDOW 0 0 56 VBottom 2
WINDOW 3 32 56 VTop 2
SYMATTR InstName R2
SYMATTR Value 1Meg
SYMBOL cap 480 64 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C3
SYMATTR Value 10.0n
SYMBOL cap 480 400 R90
WINDOW 0 0 32 VBottom 2
WINDOW 3 32 32 VTop 2
SYMATTR InstName C4
SYMATTR Value 10.0n
TEXT 96 696 Left 1 !* .tran 0 2m 1.99m\n.tran 0 50.0m 49.99m
TEXT 312 168 Left 2 ;Insulated "Fondue Forks"
TEXT 288 488 Left 2 ;Non-insulated "Fondue Forks"
RECTANGLE Normal 256 184 640 316 2
RECTANGLE Normal 256 508 640 628 2
```

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

body:
Thanks to all for the advice,

I have chosen to divert the whole system and rather make use of a 555 timer to sent a frequency to the measuring pins. It has been tested and seems to resolve the issue completely.


body: A DC motor is operated using an L298n driver and Arduino UNO. How can I get to know whether the Motor is ON or OFF? Using a code in Arduino.

title: How can we know the status of the DC Motor whether it is ON or OFF

Answers: 2

body:
Unfortunately, the L298N does not return a status, so you are going to have to add sensors to detect motor movement.

Here are a few options you can try:

- Current sense. Add a small resistor to the output of the L298N and measure the voltage differential across that resistor. If there is current being supplied to the motor then you will have a voltage differential.
- Rotation sensor. This can be in the form of a quadrature encoder wheel, tooth sensor or Hall effect sensor detecting a magnet on the shaft. If you see pulses from the sensor then you know the motor is spinning.
- Optical sensor. A camera system or other optical sensor to detect motor movement. Probably too complex for a simple application. There are however off the shelf sensors that will turn on an output if they see movement in their field of view. Alternatively you could use a PIR sensor from a home alarm system if the movement is course enough.

body:
This may be too simple, but for completeness: You *can* read back the state of the output bit, in case your code doesn't save its current state. That will tell you if the motor is literally "on" or "off". Not rotating despite being "on" is another matter; an error.

If you need error detection then you need additional hardware support.
Some possibilities:
 - Sense rotation with a cam and a micro-switch or an optical sensor and a slotted disk;
 - Sense the motor current - a stalled motor will draw a high current;
 - Sense vibration in the motor platform;
 - (apply imagination here...  ;-)


body:
[![serial monitor showing the connected network][1]][1]I am replicating a project that will read the RFID card or tag data, store that into a mysql database and display the data via PHP.

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

Below is the Arduino code. It successfully connects with WiFi (that I can see via serial monitor) but gives no response when I touch the RFID card to the reader and there is no display of the card UID in the PHP web app.

I can't find the error.
The owner of the project suggested that the nodeMCU might be faulty which isn't the case and now i am at loss. Please help.

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

    //NodeMCU and RFID libraries--------------------------
    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>
    #include <SPI.h>
    #include <MFRC522.h>

    #define SS_PIN  D2  //D2
    #define RST_PIN D1  //D1

    MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

    /* Set these to your desired credentials. */
    const char *ssid = "TECNO CAMON 15";
    const char *password = "d6364e300f59";
    const char* device_token  = " 4c9fc9995e7f9c6d ";

    String URL = "http://192.168.43.40/school_project/getdata.php"; //computer IP or the server domain
    String getData, Link;
    String OldCardID = "";
    unsigned long previousMillis = 0;

    void setup() {
      Serial.begin(115200);
      SPI.begin();  // Init SPI bus
      mfrc522.PCD_Init(); // Init MFRC522 card
      WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
        delay(1000);
        WiFi.mode(WIFI_STA);
        Serial.print("Connecting to ");
        Serial.println(ssid);
        WiFi.begin(ssid, password);

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

        Serial.print("IP address: ");
        Serial.println(WiFi.localIP());  //IP address assigned to your ESP

        delay(1000);
    }
    //************************************************************************
    void loop() {

      if (millis() - previousMillis >= 15000) {
        previousMillis = millis();
        OldCardID="";
      }
      delay(50);
      //---------------------------------------------
      //look for new card
      if ( ! mfrc522.PICC_IsNewCardPresent()) {
        return;//got to start of loop if there is no card present
      }
      // Select one of the cards
      if ( ! mfrc522.PICC_ReadCardSerial()) {
        return;//if read card serial(0) returns 1, the uid struct contians the ID of the read card.
      }
      String CardID ="";
      for (byte i = 0; i < mfrc522.uid.size; i++) {
        CardID += mfrc522.uid.uidByte[i];
      }
      //---------------------------------------------
      if( CardID == OldCardID ){
        return;
      }
      else{
        OldCardID = CardID;
      }
      //---------------------------------------------
    //  Serial.println(CardID);
      SendCardID(CardID);
      delay(1000);
    }
    //************send the Card UID to the website*************
    void SendCardID( String Card_uid ){
      Serial.println("Sending the Card ID");
      if(WiFi.isConnected()){
        HTTPClient http;    //Declare object of class HTTPClient
        //GET Data
        getData = "?card_uid=" + String(Card_uid) + "&device_token=" + String(device_token); // Add the Card ID to the GET array in order to send it
        //GET methode
        Link = URL + getData;
        http.begin(Link); //initiate HTTP request   //Specify content-type header

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

    //    Serial.println(Link);   //Print HTTP return code
        Serial.println(httpCode);   //Print HTTP return code
        Serial.println(Card_uid);     //Print Card ID
        Serial.println(payload);    //Print request response payload

        if (httpCode == 200) {
          if (payload.substring(0, 5) == "login") {
            String user_name = payload.substring(5);
        //  Serial.println(user_name);

          }
          else if (payload.substring(0, 6) == "logout") {
            String user_name = payload.substring(6);
        //  Serial.println(user_name);

          }
          else if (payload == "succesful") {

          }
          else if (payload == "available") {

          }
          delay(100);
          http.end();  //Close connection
        }
      }
      }
    //=======================================================================`

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

title: NodeMCU unable to communicate with MFRC522 RFID reader even though the nodeMCU is successfully connected to a mobile hotspot

Answers: 0


body:
I want to generate a 1khz square signal with an Arduino Mega.

I have read the MCU contains several timers.
What i want to do is to configure one of this timers.

My first question is: Is there a way to automatically control an output pin from the timer, without having to execute any line of code in my arduino program ? Look at my code: i need to write a line in ISR(TIMER1_OVF_vect). Some MCU can do that but i did not find any information about it on documentation. (Some pins are connected on timer outputs, by hardware conception).

My second question is: What is wrong on my calculation on my code ?
I want 1khz and i get 990Hz

Here is what i've done:
 - Arduino Mega runs at 16Mhz = 16000Khz
 - I have set a /8 prescaler, so timer's frequency is 8000Khz
 - The frequency should by divide by two because i have 2 states (HIGH and LOW): 4000Khz
 - The interupt is fired when the counter reach 65536. So if i load 65536-1000 in TCNT1, the timer should count 1000 times in order to fire the interupt. So my frequency is 4000khz/1000 = 1khz.

What is wrong ?

Thanks a lot

    void setup() {
      pinMode(14,OUTPUT);

      noInterrupts();
      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1 = 65536 - 1000;
      TCCR1B |= (1 << CS11);    // Prescaler clock / 8
      TIMSK1 |= (1 << TOIE1);
      interrupts();
    }

    ISR(TIMER1_OVF_vect)
    {
      TCNT1 = 65536 - 1000;
      digitalWrite(14, digitalRead(14) ^ 1);
    }

    void loop() {

    }

title: Generate 1khz square signal with Arduino Mega

Answers: 2

body:
> My first question is: Is there a way to automatically control an output pin from the timer, without having to execute any line of code in my arduino program ?

Yes. It's called PWM with a 50% duty cycle.

You need to read up on **19. Output Compare Modulator (OCM1C0A)** in the datasheet.

> My second question is: What is wrong on my calculation on my code ? I want 1khz and i get 990Hz

You have to take into account the number of CPU cycles it takes to start executing your ISR. There's a short bit of code *before* your code is run that preserves any used registers on the stack and allocates any room needed for local variables. That takes time, and must be calculated into your timing factor.

body:
As explained in the previous answer, you forgot to account for the time
taken by the CPU to handle the interrupt prologue. As a general rule, if
you want consistent timing, you should _never_ reset the timer by
software after the initialization.

If you want to run the timer in normal mode, and use it to schedule
interrupts at a period that is not the timer's own period, it is
possible, but you should not use the overflow interrupt for this
purpose. You should instead use any of the “compare match” interrupts,
and adjust the compare register in the IRS in order to schedule the next
interrupt. For example:

```c++
void setup() {
    pinMode(14,OUTPUT);

    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS11);    // clock @ F_CPU/8
    TCNT1  = 0;            // clear timer
    OCR1A  = 1000;         // first COMPA match in 1000 cycles
    TIFR1  = _BV(OCF1A);   // clear interrupt flag
    TIMSK1 = _BV(OCIE1A);  // enable TIMER1_COMPA interrupt
}

ISR(TIMER1_COMPA_vect) {
    OCR1A += 1000;      // schedule next interrupt
    PINJ   = _BV(PJ1);  // toggle PJ1 = digital 14
}
```

Note that the line `OCR1A += 1000;` can cause a wrap around, but this is
no problem, as the addition wraps around in exactly the same way as the
timer itself.

The advantage of this technique is that you can schedule up to three
different tasks, having different periods, with only one timer. And you
can even schedule tasks in a non-periodic fashion.

That being said, if you do not need the timer for anything else other
than scheduling a single periodic task (or up to four tasks sharing the
same period), then a better solution is to let the timer handle the
period all by itself. Configure the timer in mode 12 or 14 (CTC or fast
PWM, with TOP = ICR1), and set the period with `ICR1 = 999;`. Then the
ISR is reduced to:

```c++
ISR(TIMER1_COMPA_vect) { PINJ = _BV(PJ1); }
```

and you save a few cycles. This would be my preferred solution if I
absolutely had to output the signal on pin 14.

Note that this solution should give you the right _average_ frequency,
but you will still have some jitter, because the interrupt can
occasionally be delayed by other interrupts. If you are free to choose
the output pin, then the best solution is to let the timer handle the
PWM generation all by itself. Set the timer to any PWM mode (fast PWM is
the simplest) and use one of the waveform generators in order to
generate the PWM signal. Only the PWM-capable pins (those marked with a
“~” symbol) can be used this way. For example, Timer 1 can output to
pins 11 (OC1A), 12 (OC1B) and 13 (OC1C).

**Edit** answering the question:

> what is the goal of `TIFR1 = _BV(OCF1A); // clear interrupt flag`?

Whenever the timer value matches the contents of the compare register
`OCR1A`, the interrupt flag `OCF1A` (Output Compare Flag of timer 1,
channel A) is raised. This flag controls the interrupt request when the
`OCIE1A` bit (Output Compare Interrupt Enable 1A) is set. The flag is
automatically cleared when the ISR runs, and can be manually cleared by
writing a logic 1 to it (yes, it is kind of backwards).

It is quite likely that the flag raises early in the start process,
while the Arduino library is initializing. If the flag is up when you
enable the interrupt, an interrupt request is immediately triggered. In
order to avoid that, the common practice is to clear the flag before
enabling the interrupt.


body:
I am currently working on a project, where I need to send data from first unit to the second unit which is a few km apart, so I decided to go with **hc-12 RF module** as it covers upto 5km. Then the data received in the second unit is again to be transmitted to the last unit which is several km apart from each other, so I decided to go with **sx-1278 RF module** which can easily transmit data up to 30kms. I am trying to get the received data to print on the serial monitor. So, **how do I transmit the received HC-12 data in the second unit using the sx-1278 RF module to the third unit? Is this operation even possible? Are these two boards compatible with each other?**

If the answer is yes, please do help me out with the coding part on how to interface these two RF-modules.

Thanks in advance

title: How can I interface, received HC-12 data and transmit the received data using sx-1278 RF-module in arduino-UNO?

Answers: 0


body:
I am working on a project where I read 8 MAX31856 thermocouple sensors using the Adafruit Library. This works just fine and prints the read outs to serial.

I want to also save the readings to a microSD card. And this is where I hit a snag.

I am trying to use the ```SdFat.h``` library. I can loop through my MAX31856 thermocouples, and write once to my SD card, but after that it hangs the SPI bus.

the MAX31856 works on SPI_MODE1 (as per [Adafruit Library][1]) and the microSD card works on SPI_MODE0, I believe. I am trying to switch SPI bus modes before and after writing to the SD card but I think there is something wrong after first successful write to the SD card. After the first loop iteration, it seems like all data is basically noise on the SPI bus.

I am using the [Adafruit ADA254 microSD breakout Board][2], which has a card detect pin, so I first check to see if an SD card is inserted, and then write to the file.

**Question:** Is there another or better way to switch SPI_MODES on each loop? is there anything more I need to consider so I end up back to SPI_MODE1 appropriately for the MAX31856 thermocouples?

Below is the pertinent code for what I have going on...
```
void setup(){
   int sdCard = 36;
   char filename[10] = "test.txt";
}

void loop(){
....code to read thermocouples ...

///THEN THIS

  //lets confirm SD card is still in socket before writing
  CardDetect = digitalRead(37);
  if(CardDetect == HIGH){

     SPI.setDataMode(SPI_MODE0);
     SPI.setClockDivider(SPI_CLOCK_DIV4);
     SPI.setBitOrder(LSBFIRST);
     digitalWrite(sdCard, LOW);
     sd.begin(sdCard, SD_SCK_MHZ(1));
    //LETS START SAVING DATA
          myFile.open(filename, O_WRONLY | O_CREAT | O_EXCL);
          myFile.write(now.unixtime());
          myFile.write(",");
            for(int i = 0; i<8; i++){
              myFile.print(TEMP[i]);
              myFile.write(",");
            }
          myFile.println();
          myFile.close();
          digitalWrite(sdCard, HIGH);
          SPI.setDataMode(SPI_MODE1);
          SPI.setClockDivider(SPI_CLOCK_DIV16);
          SPI.setBitOrder(MSBFIRST);
          delay(200);
    }

}
```

  [1]: https://github.com/adafruit/Adafruit_MAX31856/blob/master/Adafruit_MAX31856.cpp
  [2]: https://www.adafruit.com/product/254

title: 2 SPI Slaves with 2 different SPI modes on one Arduino Mega

Answers: 1

body:
For anyone who has a similar issue with the SPI Bus, `SdFat` library has a Software SPI option built in (example [here][1]).

You need to modify your `SdFat/SdFatConfig.h` file, but that is minimal. Once you have the microSD card module on a separate bus, it will not corrupt the main SPI Bus.

Switching the SD Card module to it's own bus rectified the issue. Keep in mind that Software SPI comes with a speed penalty.

  [1]: https://github.com/greiman/SdFat/blob/master/examples/SoftwareSpi/SoftwareSpi.ino


body:
I don't know whether this is possible or not but is there any way that I can run something similar to Android on a normal TFT. I want to make complex graphics but can't program those complex programs using the Adafruit TFT library.

Arduino Mega 2560 with Elegoo TFT 2.8"

title: Use Android on Arduino TFT

Answers: 1

body: No. Not even remotely. Android runs on a powerful computer not a tiny embedded microcontroller.


body:
I'm initializing my strips as an array:

    // Declare NeoPixel strip array:
    Adafruit_NeoPixel strip[] = {
      Adafruit_NeoPixel(LED_COUNT[0], LED_PIN[0], NEO_RGBW + NEO_KHZ800),
      Adafruit_NeoPixel(LED_COUNT[1], LED_PIN[1], NEO_RGBW + NEO_KHZ800),
      Adafruit_NeoPixel(LED_COUNT[2], LED_PIN[2], NEO_RGBW + NEO_KHZ800),
      Adafruit_NeoPixel(LED_COUNT[3], LED_PIN[3], NEO_RGBW + NEO_KHZ800),
      Adafruit_NeoPixel(LED_COUNT[4], LED_PIN[4], NEO_RGBW + NEO_KHZ800)
    };

and when I pass Color to a function, I'm arbitrarily using my first strip to create the Color:

      everyother( strip[0].Color( 0, 255, 0), strip[0].Color( 255, 0, 0), 500);

but in the subroutine I use those colors to set pixels to every strip of the array in a loop:

    // set every other color to color1 or color2
    void everyother( uint32_t color1, uint32_t color2, int wait) {
      for(int k=0; k<NUM_STRIPS; k++) {
        for( int j=0; j<LED_COUNT[k]; j++) {
          if( j%2 == 0) strip[k].setPixelColor(j, color1);
          else strip[k].setPixelColor(j, color2);
        }
      }
      for(int k=0; k<NUM_STRIPS; k++) strip[k].show();
      delay(wait);
    }

Is there another way to define Color that isn't using a real Adafruit_NeoPixel? Yes, it works this way but it feels sloppy.

title: Pass Color to a function without using a specific Adafruit_NeoPixel

Answers: 1

body:
Looking at the library at https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h, you can see that the Color method is static (see line 307):

    static uint32_t   Color(uint8_t r, uint8_t g, uint8_t b) {
      return ((uint32_t)r << 16) | ((uint32_t)g <<  8) | b;

This means instead of

    strip[0].Color( 0, 255, 0)

You can use:

    Adafruit_NeoPixel::Color( 0, 255, 0)

Your call to `everyother` will be:

    everyother(Adafruit_NeoPixel::Color( 0, 255, 0),
               Adafruit_NeoPixel::Color( 255, 0, 0),
               500);

And since `everyother` is now not a good name, you can think of a better one, e.g. `fillLeds` (always start a method name with a verb).

Offtopic:

- A subroutine is barely used anymore, I think the last time I heard it, is from the Basic programming language
- A function is now used instead
- But when a function is inside a class, it's not called a function, but called method.


body: So I have an ESP8266 board that I am using to control some LED lights. I wasn't a fan of the needing to reflash my board everytime I wanted to try a new light pattern, so I decided to send the light data over wifi (UDP), and that works for certain light patterns, but any pattern that has leds that turn on/off starts to stutter and stop after a while. If every light is on, there's no problem with the speed I'm sending data, but if there are some that are on and some off, without fail it will always stop receiving data at a certain point. I've got a couple points of failure and this is my first time messing with an arduino so I'm not sure whether the problem could be on my local program, on the program for the board, the data, my wifi, or something else.

title: ESP8266 occasionally stops receiving data

Answers: 1

body: dandavis helped me find the answer! Turns out it was a memory leak, due to some poor math on my end. All I had to do was fix that up and it worked fine.


body:
I'm fairly new to Arduino so I used a sample code before integrating this into my main code. I'm printing my value in a JSON format over serial. My Arduino outputs this and the python receives this and prints it in the same format

    {

    "value" : 5

    }

but when I use python to try writing to a JSON file on my computer, I'm not getting the same JSON format. Can anyone figure out what's wrong? I need to write to my JSON file in JSON format, but instead, I'm getting this format written in my JSON file `"  \"value\": 5\r\n"` instead of `{"value: 5"}`. Another problem I'm getting is that sometimes the values I get in my JSON get cut off so sometimes I end up with `\r\n"` or other parts of the current output. My goal is to get the python code to overwrite the JSON file in real-time, so whenever I open the JSON file, the entire output should be there in the correct JSON format. Any help is appreciated, thank you.

Arduino Code:

    #include <ArduinoJson.h>

    int analogPin = 3;
    int data = 0;
    char userInput;

    StaticJsonDocument<100> testDocument;
    char buffer[100];

    void setup(){

      Serial.begin(9600);          //  setup serial

      StaticJsonDocument<100> testDocument;

      testDocument["sensorType"] = "Temperature";
      testDocument["value"] = 10;

      char buffer[100];

      serializeJsonPretty(testDocument, buffer);

      Serial.println(buffer);

    }
    int(i)=1;
    void loop(){

        testDocument["value"] = i;

        serializeJsonPretty(testDocument, buffer);

        Serial.println(buffer);

        i=i+1;
     }

Python Code:

    import serial
    import json
    import time

    ser = serial.Serial('COM4', baudrate = 9600, timeout=1)

    while 1:

        data = (ser.readline().decode('ascii')) #split('\r\n')

        #j = json.loads(data)

        file = "C:/Users/Mike/Desktop/test.json"

        my_data_file = open(file, 'w')

        with open(file1, "w") as my_data_file :
            json.dump(data, my_data_file)

        print(data)

title: Reading JSON from Arduino over serial in python and writing to a JSON file on computer

Answers: 0


body:
I have three TFMini sensors I need all of them to detect. I only got one to work , pins 4,5 . My info in coding is basic . I really appreciate your help . Thanks in advance.

I think the problem is with Library I can't add TFMini_1.

Here is my code,

```
#include <SoftwareSerial.h>
#include "TFMini.h"
TFMini tfmini;
TFMini tfmini1;

//Declaring variables and constants
TFMini TFFront;
TFMini TFRight;
TFMini TFLeft;
SoftwareSerial SerialTFMini (4,5);    //(RX, TX)
SoftwareSerial SerialTFMini_1 (6,7);    //(RX, TX)
SoftwareSerial SerialTFMini_2(8,9);     //(RX, TX)

void getTFminiData(int* distance, int* strength) {
  static char i = 0;
  char j = 0;
  int checksum = 0;
  static int rx[9];
  if(SerialTFMini.available())

  {
    // Serial.println( "tfmini serial available" );
    rx[i] = SerialTFMini.read();

    if(rx[0] != 0x59) {
      i = 0;
    } else if(i == 1 && rx[1] != 0x59) {
      i = 0;
    } else if(i == 8) {
      for(j = 0; j < 8; j++) {
        checksum += rx[j];
      }
      if(rx[8] == (checksum % 256)) {
        *distance = rx[2] + rx[3] * 256;
        *strength = rx[4] + rx[5] * 256;
      }
      i = 0;
    } else
    {
      i++;
    }
  }
}

       //Threshold distance in "cm"; speak only when any object is nearer than this distance

void setup()
{

  //Initializing Baud Rates
  Serial.begin (115200);
  while(!Serial);                     //Wait for USB Serial Port to connect
  Serial.println("Initializing...");
  SerialTFMini.begin (TFMINI_BAUDRATE);

  //Initializing TFMini Sensors
tfmini.begin(&SerialTFMini);
}

void loop()
{
   int distance = 0;
  int strength = 0;

  getTFminiData(&distance, &strength);
  while(!distance) {
    getTFminiData(&distance, &strength);
    if(distance) {
      Serial.print(distance);
      Serial.print("cm\t");
      Serial.print("strength: ");
      Serial.println(strength);
    }
   }

delay(100);

}
```

title: TFMini Sensors with Arduino

Answers: 1

body:
First: Why are you including, declaring and initializing the library's tfmini object, if you then don't use it for reading the sensor?

Your problem will be, that you can only listen to exactly 1 `SoftwareSerial` interface at a time. If you listen to the first interface and the sensor on the second interface is sending something, you will miss that data.

I suggest, you switch the Uno for a board with more hardware Serial interfaces (which work via hardware, thus can work in parallel). The Arduino Mega for example has a total of 4 hardware Serial interfaces.

Though you might get away with the Uno when working with the external trigger mode. The TFMini library has an example named `SingleReading`. It sets the `SingleScanMode` in `setup()`. Then it issues an external trigger and then reads the sensor. I suggest trying the following: In your code you initiate all 3 TFMini objects with their respective `SoftwareSerial` object. Then in `loop()` you go through these 3 items, first calling `listen()` on the corresponding `SoftwareSerial` object. Then you issue the external trigger on the corresponding `TFMini` object and read the data from it. Then you go to the next `SoftwareSerial` interface and call `listen()` on it, and so on. The idea is, that with an external trigger you can control, when you will get a valid data frame. I'm not sure, if the sensor will also send some data between the triggers, but that data should just be discarded without any problem.

Note: I cannot test this idea, because I don't have the corresponding hardware. You will have to test that yourself.


body: I m connect it with my IDE software and its work perfectly yesterday, but today morning I'm connected it to software to upload another sketch but its didn't detect the port and the charge led is not on yesterday but today is on. I tried every resolution which is given on website but its didn't work. please help me through this I'm new to this board.

title: MKR ZERO is not detected in IDE / MKR ZERO not showing up in windows 8.1/

Answers: 1

body:
A few possibilities come to mind:

 1. Your USB cable is bad.  Try a known good one.
 2. Your USB port has failed.  Try a different port or try plugging something else into this one to verify that it's still OK.
 3. Your MKR ZERO has become damaged somehow.


body: I've bought an [Arduino speaker module](https://aliexpress.com/item/1005001728930766.html?spm=a2g0o.productlist.0.0.29d8b723i5oVcV&algo_pvid=2b423ecb-737d-4cfb-aa5b-d9bf775acb1c&algo_expid=2b423ecb-737d-4cfb-aa5b-d9bf775acb1c-31&btsid=0b8b15f516051880750104598e2019&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_). How should I connect the module, if I want to use it with DFPlayer Mini? The problem is that the speaker module has 3 pins: `GND`, `VCC`, and `IN`; though the DFPlayer Mini has 2 pins for connecting a speaker: `SPEAKER +` and `SPEAKER -`.

title: How to use an Arduino Speaker module with DFPlayer Mini?

Answers: 1

body:
The DFPlayer already has an amplifier on it, so you can connect the speaker directly.

You can just leave out the board you bought from AliExpress, and only use the speaker.


body:
My goal is to have an Arduino Due (96 KB RAM) write a +-1MB bitmap to an SD card.

I have an array of a several coordinates on my Arduino Due and I would like to generate the bitmap where all the coordinates have a certain color and all the other pixels/background have another color.

I do have code to write a bitmap to an SD card (see below) but the problem is that the bitmap is dynamically generated and allocated in ram and then written to the SD card. So as soon as the bitmap I do want to write to the SDcard becomes bigger than the RAM available I get an error:
 "xx.elf section '.bss' is not within region 'ram'.

Could anyone advice me on how to put parts of the bitmap in ram and write them to the sdcard one after another. Or would there maybe be another better approach?

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

    const int chipSelect = 10;

    char name[] = "9px_0000.bmp";       // filename convention (will auto-increment)
    const int w = 800;                   // image width in pixels
    const int h = 400;                    // " height
    const boolean debugPrint = true;    // print details of process over serial?

    const uint32_t imgSize = w*h;
    int px[w*h];                        // actual pixel data (grayscale - added programatically below)

    File file;

    const int amount_CT_samples = 20;
    int Yarr[amount_CT_samples];
    int Xarr[amount_CT_samples];

    void setup() {

      // SD setup
        SerialUSB.begin(9600);
      while (!SerialUSB) {
        ; // wait for serial port to connect. Needed for native USB port only
      }

      SerialUSB.print("Initializing SD card...");

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

      // if name exists, create new filename
      for (int i=0; i<10000; i++) {
        name[4] = (i/1000) + '0';    // thousands place
        name[5] = (i/100) + '0';     // hundreds
        name[6] = (i/10) + '0';      // tens
        name[7] = i + '0';           // ones
        file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
        if (file) {
          break;
        }
      }

      // set fileSize (used in bmp header)
      int rowSize = 4 * ((3*w + 3)/4);      // how many bytes in the row (used to create padding)
      int fileSize = 54 + h*rowSize;        // headers (54 bytes) + pixel data

      // create image data; heavily modified version via:
      // http://stackoverflow.com/a/2654860
      unsigned char *img = NULL;            // image data
      if (img) {                            // if there's already data in the array, clear it
        free(img);
      }
      img = (unsigned char *)malloc(3*imgSize);

      for (int y=0; y<h; y++) {
        for (int x=0; x<w; x++) {
          int colorVal = px[y*w + x];                        // classic formula for px listed in line
          img[(y*w + x)*3+0] = (unsigned char)(colorVal);    // R
          img[(y*w + x)*3+1] = (unsigned char)(colorVal);    // G
          img[(y*w + x)*3+2] = (unsigned char)(colorVal);    // B
          // padding (the 4th byte) will be added later as needed...
        }
      }

      // create padding (based on the number of pixels in a row
      unsigned char bmpPad[rowSize - 3*w];
      for (int i=0; i<sizeof(bmpPad); i++) {         // fill with 0s
        bmpPad[i] = 0;
      }

      // create file headers (also taken from StackOverflow example)
      unsigned char bmpFileHeader[14] = {            // file header (always starts with BM!)
        'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0   };
      unsigned char bmpInfoHeader[40] = {            // info about the file (size, etc)
        40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0   };

      bmpFileHeader[ 2] = (unsigned char)(fileSize      );
      bmpFileHeader[ 3] = (unsigned char)(fileSize >>  8);
      bmpFileHeader[ 4] = (unsigned char)(fileSize >> 16);
      bmpFileHeader[ 5] = (unsigned char)(fileSize >> 24);

      bmpInfoHeader[ 4] = (unsigned char)(       w      );
      bmpInfoHeader[ 5] = (unsigned char)(       w >>  8);
      bmpInfoHeader[ 6] = (unsigned char)(       w >> 16);
      bmpInfoHeader[ 7] = (unsigned char)(       w >> 24);
      bmpInfoHeader[ 8] = (unsigned char)(       h      );
      bmpInfoHeader[ 9] = (unsigned char)(       h >>  8);
      bmpInfoHeader[10] = (unsigned char)(       h >> 16);
      bmpInfoHeader[11] = (unsigned char)(       h >> 24);

      // write the file (thanks forum!)
      file.write(bmpFileHeader, sizeof(bmpFileHeader));    // write file header

    }

    void loop() { }

**UPDATE**

With the following code my problem was solved.
Credits to those who answered my question below!

    #include <SPI.h>
    #include <SD.h>
    const int chipSelect = 10;

    struct Pixel {
        uint8_t r, g, b;
    };

    char name[] = "CT_0000.bmp";       // filename convention (will auto-increment)
    const int w = 800;                   // image width in pixels
    const int h = 400;                    // " height
    const boolean debugPrint = true;    // print details of process over serial?

    const uint32_t imgSize = w*h;
    int px[w*h];                        // actual pixel data (grayscale - added programatically below)

    File file;

    const int amount_CT_samples = 50;
    int Xarr[amount_CT_samples];
    int Yarr[amount_CT_samples];

    Pixel getPixel(int x, int y) {
        const Pixel black = {0, 0, 0},
                    green = {0, 255, 0};

        for(int i=0; i < amount_CT_samples; i++){
          if(Xarr[i] == x && Yarr[i] == (h - y))return green;
        }
        return black;
    }

    void writeBitmap(File &file, int w, int h) {
        size_t rowSize = 4 * ((3*w + 3)/4);  // padded to multiple of 4
        size_t fileSize = 54 + h*rowSize;    // includes header

        // Write image header.
        uint8_t header[54] = {
            // File header.
            'B','M',
            (uint8_t)(fileSize >>  0),
            (uint8_t)(fileSize >>  8),
            (uint8_t)(fileSize >> 16),
            (uint8_t)(fileSize >> 24),
            0,0, 0,0, 54,0,0,0,

            // Image info header.
            40,0,0,0,
            (uint8_t)(w >>  0),
            (uint8_t)(w >>  8),
            (uint8_t)(w >> 16),
            (uint8_t)(w >> 24),
            (uint8_t)(h >>  0),
            (uint8_t)(h >>  8),
            (uint8_t)(h >> 16),
            (uint8_t)(h >> 24),
            1,0, 24,0
        };
        file.write(header, sizeof header);

        // Write image data.
        uint8_t row[rowSize];
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                Pixel pix = getPixel(x, y);
                row[3*x + 0] = pix.b;
                row[3*x + 1] = pix.g;
                row[3*x + 2] = pix.r;
            }
            file.write(row, sizeof row);
        }

        file.close();
    }

    void setup() {
        Serial.begin(9600);
        Serial.print("Initializing SD card...");

        //create dummy X and Y points
        for(int i = 0; i < amount_CT_samples; i++){
            Xarr[i] = i;
            Yarr[i] = i;
        }

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

      // if name exists, create new filename
      for (int i=0; i<10000; i++) {
        name[3] = (i/1000) + '0';    // thousands place
        name[4] = (i/100) + '0';     // hundreds
        name[5] = (i/10) + '0';      // tens
        name[6] = i + '0';           // ones
        file = SD.open(name, O_CREAT | O_EXCL | O_WRITE);
        if (file) {
          break;
        }
      }

      Serial.println("start writing bitmap.");
      writeBitmap(file, w, h);
      Serial.println("done writing bitmap.");

    }

    void loop() { }

title: Writing a 1Mb bitmap to an SDcard with only 96kB RAM

Answers: 2

body:
Normally I'd write this a differently, but I've kept in relatively simple just to illustrate the basic idea:

````cpp
struct point {
  int x;
  int y;
};

const point points_of_interest[] = {
  { 7, 11},
  {23, 17},
  {13, 19},
  { 3,  5},
  {17,  3},
};

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

void loop() {
  delay(4000);
  Serial.println("\n\n\n");

  for (int i = 0; i < 24; ++i) {
    for (int j = 0; j < 24; ++j) {
      bool coordinate_of_interest = false;

      for (const auto poi: points_of_interest) {
        coordinate_of_interest = j == poi.x && i == poi.y;
        if (coordinate_of_interest) {
          break;
        }
      }

      if (coordinate_of_interest) {
        Serial.print("XX");
      } else {
        Serial.print("..");
      }
    }

    Serial.println();
  }
}
````

It's printing a 24x24 or 576 "pixel" grid.  But only five coordinates are stored.
It would matter if it were a 2400x2400 grid, but it would not print nicely on a maximized Serial Monitor for example purposes.

With your bitmap, you could get more sophisticated.  E.g. checking that distance (or more efficiently distance squared; no sqrt() operation) from the pixel under consideration (i, j) to any point in the list is less than or equal to some amount, and coloring based on that.  This would result in solid circles centered on your points in your bitmap.  Or color gradient around the point if you base the color on the distance.

If you have a lot of points you will need to do something like sort them by their vertical coordinates and advance an index that represents the points on or below your horizontal sweep line, etc.  That is, if you have a lot of points you don't want to have to be taking the distance to all of them for every pixel under consideration.

body:
You can write the file in chunks. As suggested by ocrdu in a comment,
writing line by line is a good strategy. In order to keep the complexity
of the code manageable, I would put the logic of deciding the color of a
pixel in its own function, and use another function for managing writing
the bitmap. For example:

```c++
struct Pixel {
    uint8_t r, g, b;
};

// Dummy example. Replace with your own logic.
Pixel getPixel(int x, int y) {
    const Pixel black = {0, 0, 0},
                green = {0, 255, 0};
    if (((x - y) & 0x0f) == 0) return green;
    return black;
}

void writeBitmap(File &file, int w, int h) {
    size_t rowSize = 4 * ((3*w + 3)/4);  // padded to multiple of 4
    size_t fileSize = 54 + h*rowSize;    // includes header

    // Write image header.
    uint8_t header[54] = {
        // File header.
        'B','M',
        (uint8_t)(fileSize >>  0),
        (uint8_t)(fileSize >>  8),
        (uint8_t)(fileSize >> 16),
        (uint8_t)(fileSize >> 24),
        0,0, 0,0, 54,0,0,0,

        // Image info header.
        40,0,0,0,
        (uint8_t)(w >>  0),
        (uint8_t)(w >>  8),
        (uint8_t)(w >> 16),
        (uint8_t)(w >> 24),
        (uint8_t)(h >>  0),
        (uint8_t)(h >>  8),
        (uint8_t)(h >> 16),
        (uint8_t)(h >> 24),
        1,0, 24,0
    };
    file.write(header, sizeof header);

    // Write image data.
    uint8_t row[rowSize] = {0};
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            Pixel pix = getPixel(x, y);
            row[3*x + 0] = pix.b;
            row[3*x + 1] = pix.g;
            row[3*x + 2] = pix.r;
        }
        file.write(row, sizeof row);
    }
}
```

Then after opening the file, you just have to:

```c++
writeBitmap(file, 800, 400);
```

Note that the `getPixel()` function above is just a dummy example that
draws green diagonal lines across the image. See timemage's answer for
ideas on how to implement your own pixel-generating function.


body: For my proyect, I need to conect my NodeMCU to a servo motor as well as a push button, the thing is, the distance from the NodeMCU and both components has to have a distance of around 6.10 meters (or 20.0131 feet), I dont know if it is possible to do this connection, I worry if the pwm signal or the voltage would drop by the time it reached either component. I havent been able to try this because I dont have long enough cables to do the connections. In the case that it would be possible, what type of cable should I use and should I add something extra to the circuit to make it work better? Thanks.

title: Is it possible to have long wire connections from an NodeMCU to a servo motor or button?

Answers: 2

body:
A push button won't be a problem. That is a very simple change in resistance from open circuit to a few ohms. You just need a low enough resistance to force the voltage coming through weak internal pullup resistor down to ground. It looks like 22 gauge wire has about 52.7 ohms / 1000 meters.

I don't think 6 meters of 22 gauge wire will be a problem for a 5V PWM signal either. If it's a very electrically noisy environment you might want to use shielded or twisted pair cable, but it seems unlikely that would be needed.

body: I would suggest a pull up resistor forcing at least 1 mA or more of current through the switch contact. This helps keep the switch contact clean if it is not rated for dry switching. Then from the junction of the pull up resistor put a 20 - 100K resistor in series with your input pin. You can also add a 100nF cap between the input and ground to kill noise. This forms a low pass filter and denounces some of the switch noise. The other wire to the switch will be ground.  I did this a lot with 12/24VDC control systems. If you do several inputs check your currents and be sure you do not over power the Arduino. This will forward bias the top input protection diode pushing current into the Arduino VCC. The inputs are typically rated at 20mA but check to be sure yours is rated properly.


body:
I've never used arduino before but am using one for a school project. I am using an arduino leonardo and I've uploaded the sample code below

```
#include "Adafruit_CCS811.h"
Adafruit_CCS811 ccs;

void setup() {
    Serial.begin(9600);
    Serial.println("CCS811 test");
    if(!ccs.begin()){
        Serial.println("Failed to start sensor! Please check your wiring.");
        while(1);
    }

    //calibrate temperature sensor
    while(!ccs.available());
    float temp = ccs.calculateTemperature();
    ccs.setTempOffset(temp - 25.0);
}

void loop() {
    if(ccs.available()){
        float temp = ccs.calculateTemperature();
        if(!ccs.readData()){
            Serial.print("CO2: ");
            Serial.print(ccs.geteCO2());
            Serial.print("ppm, TVOC: ");
            Serial.print(ccs.getTVOC());
            Serial.print("ppb Temp:");
            Serial.println(temp);
        } else {
            Serial.println("ERROR!");
            while(1);
        }
    }
    delay(500);
}
```
But when I upload it, all I see a message that states

```
Sketch uses 8830 bytes (30%) of program storage space. Maximum is 28672 bytes.
Global variables use 487 bytes (19%) of dynamic memory, leaving 2073 bytes for local variables. Maximum is 2560 bytes.
```
Does this mean there is not enough storage in my computer or is there not enough space in the arduino? This arduino was given to me second hand.

I'm unsure if it is now appropriate to be able to see results show up on the serial monitor? Because nothing is showing up.

title: Arduino sketch uses too much memory storage space?

Answers: 2

body:
There is no problem here, please read the message carefully!

It says you are ONLY using 30% of the available program memory and 19% of the dynamic memory.

You have a LOT more room left.

body:
What you are seeing there is not an error message, it is only for information. It shows how much memory you have left on the Arduino.

> Sketch uses 8830 bytes (30%) of program storage space. Maximum is 28672 bytes.

This is about the program storage, also known as flash storage (which is the type of storage technology used here). It is, where the actual program is saved, and is non-volatile (which means, that it holds the data/your code even during power loss). The message tells you, that the Arduino Leonardo has a total of 28672 bytes of storage for your program. When you write bigger programs, you will also use more of the flash/program storage. That means, that the size of the flash/program storage (which is a hardware limit in the microcontroller) gives you an upper limit to the size of the compiled program, as it cannot be more than 100% of the maximum given there and still upload. Though note, that the compiler does a lot of optimization to your code, so there is no easy relation between C/C++ code size and compiled code size. **You need to actually compile your code to see, what size it will be and if it fits onto your Arduino.** And that is exactly, what this message is meant for.

The message tells you, that you are using 30% of the flash/program storage. Thus you are very well inside the limits.

> Global variables use 487 bytes (19%) of dynamic memory, leaving 2073 bytes for local variables. Maximum is 2560 bytes.

The second line is about the memory, where variables are stored, aka dynamic memory aka RAM. Of course this means the RAM inside of the Arduino. The RAM is volatile, which means, that every data in it will vanish, when the Arduino is powered off or reset.

Every time, that you declare a variable in your code, this variable is put into the RAM. Calculating the maximum amount of RAM, that will be used in your code, is rather complex, as variables are created and destroyed very often, when calling functions or other programming constructs. But global variables (the ones declared outside of any function) are created right at the start of the program, thus the compiler can easily calculate their size.

This message gives you a hint, if you are going to run out of RAM with your program. It is only a hint. Because of that, the compiler will show a warning at that point, if you are going in the realm of 75% or higher of the available RAM, that this might not leave enough room for local variables and thus risks instability in the program. (Note, that I'm not sure about the exact limit, from which on the warning is displayed. You may try to research this detail).

When you program runs out of RAM, it will fail or producing instability. So you want to prevent that from happening. Currently you are at 19%. Also you are using few local variables, so you are save here.

> I'm unsure if it is now appropriate to be able to see results show up on the serial monitor? Because nothing is showing up.

You should at least be able to see the message `CCS811 test` on the Serial monitor. If not, please make sure, that you really uploaded the code (by clicking on the upload button, not on the verify button). In the preferences you can turn on verbose output for compilation and upload, to find possible problem sources. Also make sure, that you chose the correct port and that your Serial Monitor is configured for the same baudrate as your sketch (in this case 9600 baud).

If that still doesn't give any output at all, try to upload the `Blink` example, that you can find in the Arduino IDE in the menu under examples -> Basics. If it uploads successfully, watch, if the buildin LED starts to blink. If yes, that code is working correctly.

If the init message is showing up, but the temperature values are not, you need to first check for your connections. Then you could try to upload the standard [I2C scanner sketch][1], that shows you, what devices can be found on the I2C bus and what addresses they have.

  [1]: https://playground.arduino.cc/Main/I2cScanner/


body:
i tried compiling a program to upload sensor readings that i connected with my ESP8266 to cloud (in my case, Antares) but i keep getting this error message. Can anyone tell me where the problem is, and what do i need to do to get it fixed ?

At first i thought it was because come incompatibility with my older version of Arduino IDE, so i updated to the latest version of it, but nothing changed.

Im kinda new here, so any suggest might help. Thank you!

Arduino: 1.8.13 (Windows Store 1.8.42.0) (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, 115200, 4M (3M SPIFFS)"

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::get(String, String)':

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:202:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'

     bool res = client.setCACert_P(caCert, caCertLen);

                       ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:222:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'

     if (client.verifyCertChain(_serverNoHttp)) {

                ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'String AntaresESP8266HTTP::getRaw(String, String)':

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:274:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'

     bool res = client.setCACert_P(caCert, caCertLen);

                       ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:294:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'

     if (client.verifyCertChain(_serverNoHttp)) {

                ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::send(String, String)':

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:439:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'

     bool res = client.setCACert_P(caCert, caCertLen);

                       ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:459:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'

     if (client.verifyCertChain(_serverNoHttp)) {

                ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::sendRaw(String, String, String)':

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:512:23: error: 'class WiFiClientSecure' has no member named 'setCACert_P'

     bool res = client.setCACert_P(caCert, caCertLen);

                       ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:532:16: error: 'class WiFiClientSecure' has no member named 'verifyCertChain'

     if (client.verifyCertChain(_serverNoHttp)) {

                ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp: In member function 'void AntaresESP8266HTTP::getLatestTest(String, String)':

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:688:40: error: no matching function for call to 'WiFiClient::connect(String&, uint16_t&)'

     if(client.connect(_server, _portNum)) {

                                        ^

C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:688:40: note: candidates are:

In file included from C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:39:0,

                 from C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.h:5,

                 from C:\Users\LENOVO\Documents\Arduino\libraries\antares-esp8266-http-master\src\AntaresESP8266HTTP.cpp:1:

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:47:15: note: virtual int WiFiClient::connect(IPAddress, uint16_t)

   virtual int connect(IPAddress ip, uint16_t port);

               ^

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:47:15: note:   no known conversion for argument 1 from 'String' to 'IPAddress'

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:48:15: note: virtual int WiFiClient::connect(const char*, uint16_t)

   virtual int connect(const char *host, uint16_t port);

               ^

C:\Users\LENOVO\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiClient.h:48:15: note:   no known conversion for argument 1 from 'String' to 'const char*'

exit status 1

Error compiling for board NodeMCU 1.0 (ESP-12E Module).

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

title: Error compiling for board NodeMCU 1.0

Answers: 0


body:
The basic example for ESP32 NTP is very rough:

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

      //connect to WiFi
      Serial.printf("Connecting to %s ", ssid);
      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
          delay(500);
          Serial.print(".");
      }
      Serial.println(" CONNECTED");

      //init and get the time
      configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
      printLocalTime();

      //disconnect WiFi as it's no longer needed
      WiFi.disconnect(true);
      WiFi.mode(WIFI_OFF);
    }

But it tells nothing about the success of the operation.

I need to know if it was able to update the time from the NTP server. Is there a method to know that?

I can't rely on the time struct because I must init it manually at startup, say to 1st Jan 2020 00:00.

title: ESP32 feedback from NTP

Answers: 2

body:
Did you follow that manual?

https://lastminuteengineers.com/esp32-ntp-server-date-time-tutorial/

The `printLocalTime();` function does all you ask for.

    void printLocalTime()
    {
      struct tm timeinfo;
      if(!getLocalTime(&timeinfo)){
        Serial.println("Failed to obtain time");
        return;
      }
      Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
    }

`getLocalTime`returns false on failure. Let the `printLocalTime` do the same.

    boolean printLocalTime()
    {
      struct tm timeinfo;
      if(!getLocalTime(&timeinfo)){
        Serial.println("Failed to obtain time");
        return false;
      }
      Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
      return true;
    }

Now the print function tells you if it failed (returns false) or not (returns true).

body:
I'm not entirely sure there is a good solution for that with the normal ESP32 library, as it only checks to see if a valid year has been set, and the user has already set a valid year.

You could try using the [NTPClient library][1] or a similar one to get the time; its functions do a different check and actually return TRUE or FALSE.

On success, you can then use the newly retrieved time value to update the ESP32's RTC.

  [1]: https://github.com/arduino-libraries/NTPClient