title: How to decrease a variable every second

text:
# Question
Title: How to decrease a variable every second
I am trying to count down the variable "bankValue" with a certain costfactor The code I tried will perfectly count down the bankValue..but..

```
#define INTERVAL_MESSAGE1 1000

unsigned long time_1 = 0;

const float CostFactor = 1.0;
float bankValue = 10.00;
const float CostButton1 = 0.004167;

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

void loop() {
    if(millis() >= time_1 + INTERVAL_MESSAGE1){
        bankValue = bankValue - (CostButton1 * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        print_time(time_1);
        Serial.print("€");
        Serial.println(bankValue);
    }
   }

```

I want this the use in an if. IF button1 is pressed then bankValue will be decreased by a costfactor every second.

I tried this in an if

```
  if(Pushed == HIGH){
    if(Pushed != StatePushed){
    Serial.println("Button1 OFF");
    }

    digitalWrite(relayPin, LOW);
  }else{
    if(Pushed != StatePushed){
    Serial.println("Button1 ON");
    }
                if(millis() >= time_1 + INTERVAL_MESSAGE1){
        bankValue = bankValue - (Button1Value * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        print_time(time_1);
        Serial.print("€");
        Serial.println(bankValue);
        }
    digitalWrite(relayPin, HIGH);
     }

```

If the button is pressed, bankValue will decrease. But when the button is not active....the millis timer keeps on running. When switching on the button again, I see the bankValue decrease rapidly and not every second.

So the main question: How can I decrease a variable every second when a button is active.

# Answer
Your basic main problem is that you don't know when the button was pressed. Your timing algorithm always works from the "last time the value was decremented" - and that could be hours ago. When you press the button the difference between `millis()` and `time_1` could be massive, and it has to count up one second at a time until `time_1` passes `millis()`.

What you really need to do is separate out the button from the action. That makes it easier to manage. You need to find the times when the button transitions from HIGH to LOW (pressed) and from LOW to HIGH (released). You're almost doing that right now, but not quite. Then when you find the moment of being pressed you can say "From this moment forth you shall count."

For example you might change the first part of your code to be:

```
if (Pushed != StatePushed) {
    StatePushed = Pushed; // Remember the current state for the next time round
    if (StatePushed == HIGH) { // Released
        Serial.println("Button1 OFF");
    } else { // Pressed
        Serial.println("Button1 ON");
        time_1 = millis(); // Remember what the time is right now
    }
}

```

That then is a single atomic operation and you can now at any time examine `StatePressed` to see if the button is pressed or not, and also at the moment of pressing `time_1` is set to the current `millis()` value, so you now know when the button was pressed.

Now you can add your second part using `StatePressed` as the trigger:

```
if (StatePressed == LOW) { // Button pressed
    if(millis() >= time_1 + INTERVAL_MESSAGE1){
        bankValue = bankValue - (Button1Value * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        print_time(time_1);
        Serial.print("€");
        Serial.println(bankValue);
    }
}

```

However your method of comparing the time is not good. It doesn't handle the *millis rollover* problem. Instead you should be using something more like:

```
if (millis() - time_1 >= INTERVAL_MESSAGE1) {
    time_1 = millis();
    ... etc ...
}

```
> 1 votes

# Answer
I tried to use the solution post by Majenko and came up with something like this:

```
  if(Pushed != StatePushed) {
    if(Pushed == HIGH){
      if(Pushed != StatePushed){
        Serial.println("LED OFF");
        }
        digitalWrite(ledPin, LOW);  // turn LED OFF
        }else{
        if(Pushed != StatePushed){
        Serial.println("LED ON");
        time_1 = millis();
        }
        digitalWrite(ledPin, HIGH);  // turn LED OFF
        }
  }
         StatePushed = Pushed;

  delay(100);

  if(Pushed == LOW){
    if(millis() >= time_1 + INTERVAL_MESSAGE1){
      time_1 = millis();
        bankValue = bankValue - (coinValueB * CostFactor);
        time_1 +=INTERVAL_MESSAGE1;
        Serial.print("€");
        Serial.println(bankValue);
                Serial.println(INTERVAL_MESSAGE1);
    }
  }

```

Pretty much how you suggested it... but I realize I absolutely do not understand how millis() exactly works.

I have no idea what this does:

```
if(millis() >= time_1 + INTERVAL_MESSAGE1)

```

In a way, the loop works. But the timing is really off. With my settings, every second subtracting 0.004167, should be 0,25 is one minute. But it was only around half...0,13 or so
> 0 votes

# Answer
This answer is in response to Niles's answer based on Majenko's answer (phew! that was a bit of a mouthful).

**millis()** returns how many milliseconds have passed since your program started.

And your timing is off because you are adding **INTERVAL\_MESSAGE1** with **time\_1** i.e. instead of waiting for one second you are actually subtracting after every two seconds. Hence, you got half the value you expected. Remove that line. (And also don't use delay).

I have isolated your substracting part of the code. Run this and you should see the result (button is connected to D4):

```
unsigned long PreviousTime = 0;
const unsigned long THRESHOLD = 1000;
const float CostFactor = 1.0;
float bankValue = 10.00;
const float CostButton1 = 0.004167;

void setup()
{
  Serial.begin(9600);
  pinMode(4, INPUT_PULLUP);
}

void loop()
{
  if(digitalRead(4) == 0)
  {
    if((unsigned long)(millis() - PreviousTime) >=  THRESHOLD) // You need to check time like this to avoid overflow
    {
      PreviousTime = millis();
      bankValue = bankValue - (CostButton1 * CostFactor);
      Serial.println(bankValue);
    }
  }
}

```
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: NodeMCU ESP8266 disconnected from WiFi after several hours running
I tried to test NodeMCU ESP8266 with this code from here

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

                /* Set these to your desired credentials. */
                const char *ssid = "dummy";  //ENTER YOUR WIFI SETTINGS
                const char *password = "12345678";

                //Web/Server address to read/write from
                const char *host = "192.168.43.128";   //https://circuits4you.com website or IP address of server

                //=======================================================================
                //                    Power on setup
                //=======================================================================

                void setup() {
                  delay(1000);
                  Serial.begin(115200);
                  WiFi.mode(WIFI_OFF);        //Prevents reconnection issue (taking too long to connect)
                  delay(1000);
                  WiFi.setSleepMode(WIFI_NONE_SLEEP);
                  WiFi.mode(WIFI_STA);        //This line hides the viewing of ESP as wifi hotspot

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

                  Serial.print("Connecting");
                  // Wait for connection
                  while (WiFi.status() != WL_CONNECTED) {
                    delay(500);
                    Serial.print(".");
                  }

                  //If connection successful show IP address in serial monitor
                  Serial.println("");
                  Serial.print("Connected to ");
                  Serial.println(ssid);
                  Serial.print("IP address: ");
                  Serial.println(WiFi.localIP());  //IP address assigned to your ESP
                }

                //=======================================================================
                //                    Main Program Loop
                //=======================================================================
                void loop() {
                  HTTPClient http;    //Declare object of class HTTPClient

                  String ADCData, station, postData;
                  int adcvalue=analogRead(A0);  //Read Analog value of LDR
                  ADCData = String(adcvalue);   //String to interger conversion
                  station = "A";

                  //Post Data
                  postData = "status=" + ADCData + "&station=" + station ;

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

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

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

                  http.end();  //Close connection

                  delay(5000);  //Post Data at every 5 seconds
                }

```

It was running well and posted data to Database after a few hours. Then It was disconnected from WiFi somehow . Of course I reset power supply again It's connected.

How should I do to fix with that code to reconnect WiFi right after that accident Or any other Solution for that ? Thank you

# Answer
> 1 votes
What you need to do is leave the board connected to your computer and watch the serial monitor to capture the output during the crash. If the board has a true crash it will output a bunch of information which may tell you why you it is crashing. It could be a strings/heap problem or maybe a memory issue since you are declaring a new http object every 5 seconds. Maybe try putting the HTTPClient http; line up where you declare the host variable so that it is a global variable and not a local variable.

Since your loop doesn't test to make sure the wifi connection is still good then if you get a disconnection then the program will just fail and never try to re-connect. So at the start of your main loop put the same wifi testing logic that is also in the setup function. If the connection is down then reset and start from the very beginning to re-establish the wifi connection.

```
if (WiFi.status() != WL_CONNECTED) {
    ESP.reset()
  }

```

# Answer
> 1 votes
I also had the same issues. I've looked for some posting like here. You can try these codes

```
void loop()
 {
 WiFiClient client;

 Serial.printf("\n[Connecting to %s ... ", host);
if (client.connect(host, 80))
{
Serial.println("connected]");

Serial.println("[Sending a request]");
client.print(String("GET /") + " HTTP/1.1\r\n" +
             "Host: " + host + "\r\n" +
             "Connection: close\r\n" +
             "\r\n"
            );

Serial.println("[Response:]");
while (client.connected() || client.available())
{
  if (client.available())
  {
    String line = client.readStringUntil('\n');
    Serial.println(line);
  }
}
client.stop();
  Serial.println("\n[Disconnected]");
 }
 else
 {
  Serial.println("connection failed!]");
  client.stop();
 }
 delay(5000);
 }

```

The seconds thing as @tavis said you can try from here. It sounds ESP.restart(); is recommended rather than ESP.reset(); It seems our issue is very hard.

---
Tags: esp8266, nodemcu, iot
---


title: Running commands from string

text:
# Question
Title: Running commands from string
I have a string:

```
string s="digitalWrite(8,LOW);"

```

Is there any way to run it as a code?

# Answer
> 2 votes
This is actually pretty simple:

```
if (s == "digitalWrite(8,LOW);") {
    digitalWrite(8,LOW);
}

```

Obviously, it will not work is `s` contains any other string... If you want something more general, that is able to interpret a wide range of possible commands, you will have to define a language, and write an interpreter for that language. From the example you give, it seems you would like your language to look like C++. This is most likely a bad design choice. If you want an interpreter that understands the whole C++ language: forget it. You will never fit something this big into an Arduino Uno.

Here is, for inspiration, a very simple interpreter I wrote that understand the following commands:

```
mode <pin> <mode>: pinMode()
read <pin>: digitalRead()
aread <pin>: analogRead()
write <pin> <value>: digitalWrite()
awrite <pin> <value>: analogWrite()
echo <value>: set echo off (0) or on (1)

```

You can use it a basis for writing your custom interpreter. Otherwise you can do a Web search for “Arduino interpreter”: you should be able to find interpreters implementing a wide variety of languages, including compact binary languages (Firmata), Forth (another one), Lisp, Basic, and even a C-like language.

---
Tags: arduino-uno, string, functions
---


# Question
Title: How do I make a character array scanner properly?
I start with this:

```
char delay_chars[10];

```

then I have a stream of incoming characters that I need to assign like this:

```
['I', ' ', 'l', 'o', 'v', 'e', ' ', 'p', 'i', 'e']

```

I can do that, but then more characters come in so I need it like this:

```
[' ', 'l', 'o', 'v', 'e', ' ', 'p', 'i', 'e', ' ']
['l', 'o', 'v', 'e', ' ', 'p', 'i', 'e', ' ', 'a']
['o', 'v', 'e', ' ', 'p', 'i', 'e', ' ', 'a', 'n']
['v', 'e', ' ', 'p', 'i', 'e', ' ', 'a', 'n', 'd']
['e', ' ', 'p', 'i', 'e', ' ', 'a', 'n', 'd', ' ']
[' ', 'p', 'i', 'e', ' ', 'a', 'n', 'd', ' ', 'c']
['p', 'i', 'e', ' ', 'a', 'n', 'd', ' ', 'c', 'a']
['i', 'e', ' ', 'a', 'n', 'd', ' ', 'c', 'a', 'k']
['e', ' ', 'a', 'n', 'd', ' ', 'c', 'a', 'k', 'e']

```

You get the idea. I don't know how I can remove the first character of a char array (like I do with a String, `remove(0, 1)`) and I don't know how to add a new element at the end.

If I had to guess, I'd make a loop that will reassign the index of each character one step back or something like that but I'm not sure if that's how I should do it.

# Answer
> If I had to guess, I'd make a loop that will reasign the index of each character one step back or something like that but I'm not sure if that's how I should do it.

Yep, that's pretty much it...

Here's how I do it:

```
char data[10];

if (Serial.available()) {
    char inch = Serial.read();
    for (int i = 0; i < 9; i++) {
        data[i] = data[i+1];
    }
    data[9] = inch;
}

```

Every incoming character gets added to the end of the array after everything else has been shuffled down one place.
> 1 votes

# Answer
You can use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace. The library is installable through the Arduino IDE and includes many examples.

Here are the library's features:

> This library:
>
> * can be downloaded via the Arduino IDE's Libraries Manager (search "SerialTransfer.h")
> * works with "software-serial" libraries
> * is non blocking
> * uses packet delimiters
> * uses consistent overhead byte stuffing
> * uses CRC-8 (Polynomial 0x9B with lookup table)
> * allows the use of dynamically sized packets (packets can have payload lengths anywhere from 1 to 255 bytes)
> * can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';

  myTransfer.sendData(3);
  delay(100);
}

```

Example RX Arduino Sketch:

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

```

You can easily edit the above example code to transfer `['I', ' ', 'l', 'o', 'v', 'e', ' ', 'p', 'i', 'e']` instead of `['h', 'i', '\n']`.
> 0 votes

---
Tags: array, signal-processing, data
---


# Question
Title: Reliably duplicate custom IR remote control with ATTiny85
This is something I'm struggling with for a while and fail to find solid solution. The Arduino IR library provides method for recording arbitrary IR code and re-sending it. This gave me different results every time I recorded the IR remote, so I wrote a little code, based on interrupts, that try to record the IR rise/fall as accurately as possible. I am working with ATTiny85 running at 8Mhz on internal oscillator.

Here is the code:

```
#include <SoftwareSerial.h>

SoftwareSerial mySerial(4,3);

const int dataSize = 40;
int data[dataSize];
int dataLength[dataSize];

void setup() {
  pinMode(0, OUTPUT); // 0 is IR receiver pin
  mySerial.begin(9600);
  mySerial.println("Start");
  attachInterrupt(0,IR_ISR,CHANGE);
  mySerial.println("Registered");
  sei();
}
volatile unsigned long prev = micros();
volatile unsigned long curr = -1;
volatile unsigned short index = 0;
volatile bool rising = true;
void IR_ISR()
{
  if (!rising)
  {
    dataLength[index] = micros() - curr;
    rising = !rising;
    return;
  }

  curr = micros();

  data[index++] = (int)curr-prev;

  prev = curr;
  rising = !rising;
}

void loop() {

  delay(5000);
  for (int i=1; i<dataSize; i++)
  {
    mySerial.print(data[i]);
    mySerial.print("(");
    mySerial.print(dataLength[i]);
    mySerial.print(")");
    mySerial.print("; ");
  }
  mySerial.println();
  index = 0;
}

```

Problem is that the milliseconds alter on each record of the remote control, here is an example of the output of 3 attempts of clicking at the same button of the remote control (I pasted only the first 5 IR modulations to avoid too much text, total is about 39):

> Start
> Registered
>
> 14104(9496); 1184(672); 1184(616); 1160(656); 1176(672); ...
>
> 14096(9480); 1184(664); 1208(568); 1136(616); 1184(664); ...
>
> 14096(9384); 1216(576); 1136(616); 1184(664); 1208(560); ...

The format is: \[microseconds from previous falling edge\](microseconds from rise to fall);

As you can see, the results vary. According to the arduino.cc website, the micros() function has a 8 microseconds resolution on 8Mhz AVR's, but the difference between reads is bigger than that.

This is not reliable enough for me to solidly duplicate a remote control, and I'm looking for a resolution that will provide accurate results, as the magnitude of every deviation increases when the voltages are low (for example, with a 3v 2032 coin battery half discharged).

# Answer
> 4 votes
The exact duration of the pulses don't matter much. In your example, you see that in all three recorded samples that's

```
about 14000 (about 9400); about 1200 (about 600); about 1200 (about 600) etc.

```

What matters is that nowhere you have pulses of about 900 : in other words if the receiver detects a 672 pulse it will know that it's definitely a 600, not a 1200.

So if you send exactly those values, the receiver will recognize it.

# Answer
> 0 votes
I often see where people have problems with decoding IR signals from time to time, but very few say how they are attempting to do that? The first thing you really need to know is what is the carrier frequency? if you are using a TSOP IR DEMODULATOR, They come in several flavors and if you have the wrong one your results may not be all that rock solid. There are one or two ways to determine this. have a digital storage scope and a fast photo diode (photo transistors are slow) which does no demodulation, just gives you raw IR . Once you determine your carrier frequency, then purchase a IR demodulator TSOP that is closest to your carrier frequency, then your results will be more stable no doubt.

---
Tags: attiny, ir
---


# Question
Title: Summarizing a repetitive code in a void loop function
How can I summarize dozens of code lines for blinking a red LED in Arduino Rich Shield? Is there a way or method to eliminate at least half of the code for repetitive scenarios?

```
const int redPin = 4;

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

void loop()
{
  digitalWrite(redPin, HIGH);
  delay(250);
  digitalWrite(redPin, LOW);
  delay(250);
  digitalWrite(redPin, HIGH);
  delay(250);
  digitalWrite(redPin, LOW);
  delay(250);
  digitalWrite(redPin, HIGH);
  delay(250);
  digitalWrite(redPin, LOW);
}

```

# Answer
```
void loop()
{
  digitalWrite(redPin, HIGH);
  delay(250);
  digitalWrite(redPin, LOW);
  delay(250);
}

```

I'm not quite sure what you're after but this is shorter and would get you equivalent results. Since loop is going to repeat anyway, there's no need to repeat yourself inside loop.

Per the comments, not that this is particularly useful...

```
const int redPin = 4;

int counter = 0;

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

void loop()
{
  if(counter < 4) {
     digitalWrite(redPin, HIGH);
     delay(250);
     digitalWrite(redPin, LOW);
     delay(250);
     counter++;
  }
}

```
> 1 votes

---
Tags: arduino-uno, arduino-ide
---


title: ESP32: Disable Brownout Detector

text:
# Question
Title: ESP32: Disable Brownout Detector
I have an ESP-WROOM-32 and I'm using Arduino IDE to push code on it. My ESP is powered via 2 AA batteries and got one power supply problem.

It works well on new battery but after a bit, I will always get this error repeatedly:

> ets Jun 8 2016 00:22:57
>
> rst:0xc (SW\_CPU\_RESET),boot:0x13 (SPI\_FAST\_FLASH\_BOOT) configsip: 0, SPIWP:0xee clk\_drv:0x00,q\_drv:0x00,d\_drv:0x00,cs0\_drv:0x00,hd\_drv:0x00,wp\_drv:0x00 mode:DIO, clock div:2 load:0x3fff0018,len:4 load:0x3fff001c,len:812 load:0x40078000,len:0 load:0x40078000,len:11584 entry 0x40078a60
>
> Brownout detector was triggered

**So, I know that it's possible to disable that feature in ESP32. My question is how to do it?**

**What I have done that didn't work:**

Add this code in my Arduino IDE:

```
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
setup(){
    WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
}

```

Change Arduino\hardware\espressif\esp32\tools\sdk\sdkconfig with:

```
CONFIG_BROWNOUT_DET=                //previous was "=y"
CONFIG_BROWNOUT_DET_LVL_SEL_0=      //previous was "=y"
CONFIG_BROWNOUT_DET_LVL_SEL_1=
CONFIG_BROWNOUT_DET_LVL_SEL_2=
CONFIG_BROWNOUT_DET_LVL_SEL_3=
CONFIG_BROWNOUT_DET_LVL_SEL_4=
CONFIG_BROWNOUT_DET_LVL_SEL_5=
CONFIG_BROWNOUT_DET_LVL_SEL_6=
CONFIG_BROWNOUT_DET_LVL_SEL_7=
CONFIG_BROWNOUT_DET_LVL=           //previous was "=0"

```

# Answer
> 2 votes
For me brownout issue was solved by removing the esp32 from Arduino IDE board manager + removing files from disk and use install procedure "Using Arduino IDE with the development repository" - https://github.com/espressif/arduino-esp32/

I guess it will use newer version of arduino-esp32 that has some brownout protection due to CONFIG\_REDUCE\_PHY\_TX\_POWER being activated by default. Also you should probably learn how to decrease wifi power + deep sleep for longer battery usage.

# Answer
> 0 votes
Maybe it's silly but I added a delay to my script before I got the error.

```
Serial.println("Delay 5s Brownout detector was triggered");
delay(5000);

```

---
Tags: esp8266, esp32
---


# Question
Title: I am not able to use ESP8266 12E with Arduino
I am doing my engineering degree. I want to make a project connecting multiple ESP8266 with a router and control multiple relay boards. I am unable to use ESP8266 12E with Arduino. I used this connection shown in the link below, but it didn't work. So please help me with the solution. I also referred to all possible posts, but it didn't help. Please help me as soon as possible.

Connection:

post: How to connect ESP8266 12e directly to Arduino Uno (without shields)

# Answer
I agree with Paul, you shouldn't use the Arduino, you can get break out boards at £1 for 10, but that's not what your problem is...

You are using a couple of resistors to do the level shifting taking the 5V to 3.3V. This is a bad plan, you need a proper bidirectional level shifter, particularly at higher baud rates, i.e. above 1000.

You are supplying the top VCC rail with both 3V from the batteries and 3.3V from the Arduino, not the best plan IMO.

You are not supplying the Arduino with any power, I guess this is a drawing error but just in case it isn't I though I best mention it.

You have no level shifting on the Arduino's Rx line. Its not technically needed, but you might require it particularly when the batteries are going flat.

You are using batteries and that's not a great plan.

Have you configured the ESPs using the AT command set, since you won't program them.

Just for the record the ESP has more memory it has a faster processor (80MHz) and you can still use the Arduino IDE. You should be able to pick up boards to mount the ESPs so you can use them more easily for less that the price of the level shifters, but its your call.
> 2 votes

# Answer
I am the author of the linked question. Just to clarify, the image you're using has the old connection, which wasn't working for me. Please refer to the updated version of that connection, embed below:

The main changes were: the GPIO15 pin needs to be grounded, and the RESET pullup is now wired to the battery's 3.3v. Also the resistors were changed from 220ohms to 10k, but since it's a voltage divider it shouldn't make much of a difference.

Hope this helps anyone out there!
> 2 votes

# Answer
There is also a library which can help you communicating with ESP2866 through Arduino called WiFiEsp.

It's like WiFi library for Arduino but instead for ESP8266.
> 1 votes

# Answer
Bruh that ain't even an esp8266 12e that is a different esp board. The esp8266 12e is basically an Arduino with an added wifi feature which increases the number of tasks you can do. If you are using an esp8266 12e then you can connect it directly to your laptop and start programming on the Arduino IDE software. It is super awesome and I have worked with it once for my plans home automation system. With a bit of research, you can find out which esp board that is if you really want to work with that circuit diagram.
> 0 votes

---
Tags: esp8266, wifi
---


# Question
Title: Interrupting a servo sweep with a force sensor
this is my first time dealing with arduinos and I have a school assignment. I have a servo and a force sensor. When **"1"** (a character, not an integer) is typed in the serial monitor, the servo needs to rotate 180 degrees but can be interrupted when the force sensor sends a value over let's say 300. And when **"0"** is typed in, the servo goes back to its initial position. I have been trying really hard figuring this out.

I basically need to exit a loop when the analog value exceeds 300.

here's my code:

```
#include <Servo.h>
Servo myservo;

int initpos; //initial position of the servo before the sweep (this doesn't change)
int angle; //used to store the servo angle value (this changes)
char code; //the value entered in the serial monitor
int force; //value of the analog force sensor

void setup()
{
  initpos = 10;
  Serial.begin(9600);
  myservo.attach(4);

  myservo.write(170); // makes the servo sweep(absolutelly useless for my project but I left it there)
  delay(500);         //
  myservo.write(10);  //
  delay(500);         //

  code = Serial.read();

}

void loop()
{

  if(Serial.available())
  {

    angle = initpos;
    force = analogRead(A1);
    Serial.println(force);

    for(angle = 0; angle < 180; angle += 1)
    {
      if (code == "1" and force <= 300)
      {
        angle += 1;
        Serial.print(code);
        myservo.write(angle);
      }

      else if(code == "0")
      {
        myservo.write(initpos);
      }
    }

  }
}

```

any help is deeply appreciated and if there is already a topic on this please redirect me to it

# Answer
I've written this code without access to a compiler, so there might be errors. Use it as an idea how to solve the quest. Hopefully the comments are helpful. Don't hesitate to ask if you do not understand or correct me if you see an error.

```
#include <Servo.h>

Servo myservo;

// end positions of the servo
// declared as constant values
const int minPos = 10;
const int maxPos = 180;

int servoAngle;

int force;
char code;

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

  myservo.attach(4);
  // move the servo to minPos
  // or whatever you want/need
  servoAngle = minPos;
  myservo.write( servoAngle );

  // PPK: keep code as simple as possible -> sweep removed

  // PPK: removed - this makes no sense here
  // code = Serial.read();
}

void loop()
{
  // PPK: here you check if data is available (I added "> 0")
  if( Serial.available() > 0 )
  {
    // PPK: but you did not read the data
    // Let's do it
    char newCode = Serial.read();
    If ( newCode == '0' || newCode == '1' )
    {
      // only "0" and "1" are valid codes
      code = newCode;
    }
  }

  if ( code == '0' && servoAngle > minPos )
  {
    servoAngle--;
    myservo.write( servoAngle );
  }
  else if ( code == '1' && servoAngle < maxPos )
  {
    force = analogRead( A1 );
    Serial.println( force );
    if ( force > 300 )
    {
      servoAngle--;

      // PPK: the next line is only necessary if you want the
      // servo to go towards the min position
      // if a force > 300 is detected
      // remove the line if you wish to
      // hold the servo at the position where
      // the force exceeds 300
      code = '0':
    }
    else
    {
      servoAngle++;
    }
    myservo.write( servoAngle );
  }
  // a little delay to slow down the servo
  // remove it if you want
  delay( 10 );
}

```

**EDIT**

If you intend to stop the servo if `force > 300`, you can add a flag that indicates the exceptional state.

```
#include <Servo.h>

Servo myservo;

const int minPos = 10;
const int maxPos = 180;

int servoAngle;

int force;
char code;
int flagServoStopped = 0;

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

  myservo.attach(4);
  servoAngle = minPos;
  myservo.write( servoAngle );
}

void loop()
{
  if( Serial.available() > 0 )
  {
    char newCode = Serial.read();
    If ( newCode == '0' || newCode == '1' )
    {
      code = newCode;
    }
  }

  if ( flagServoStopped == 1 && code == '1' )
  {
    // The servo is frozen as long as the stop flag is set and
    // you have not entered a '0'.
    // leave the loop
    return;
  }

  // in case `code = '0'`, reset the flag if it is set.
  flagServoStopped = 0;

  if ( code == '0' && servoAngle > minPos )
  {
    servoAngle--;
    myservo.write( servoAngle );
  }
  else if ( code == '1' && servoAngle < maxPos )
  {
    force = analogRead( A1 );
    Serial.println( force );
    if ( force > 300 )
    {
      flagServoStopped = 1;
    }
    else
    {
      servoAngle++;
      myservo.write( servoAngle );
    }
  }
  delay( 10 );
}

```
> 1 votes

---
Tags: sensors, servo
---


# Question
Title: WiFi.begin doesn't work with ArduinoJson's const char* output
I'm using ArduinoJson to parse a file full of JSON strings that contain the SSID and password for the registered networks. I have a little web interface that runs in soft AP mode so you can scan for networks and add them to the file. Adding networks to the file works fine, but reading them back and using them as input for WiFi.begin doesn't work. It moves to status code 1, which means it failed to find a network with that SSID.

I have compared the value of the result of `const char* ssid = networks[network]["ssid"];` with `const char* _ssid = "MySSID";` using strcmp and it returns 0, so I can't figure out why it's not working. It works if I replace `networks[network]["ssid]` with my SSID (though I need to replace the password with the string literal as well, otherwise it stays on status code 6, disconnected).

I can't figure out what it is about ArduinoJson, but it seems that the result of grabbing a string doesn't return a string that is formatted correctly for WiFi.begin, but it satisfies strcmp?

**Edit:** I modified the code quite a bit in an effort to get it to work. I am no longer passing the ArduinoJson object, I'm now passing a struct with the data, and it still doesn't work. Is this the work of some advanced c++ constants/pointers stuff that I don't seem to understand?

main.cpp:

```
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
#include <vector>
#include <elapsedMillis.h>

#include "config.h"
#include "restserver.h"
#include "scanwifiserver.h"

AsyncWebServer *Server = new AsyncWebServer(80);

ScanWifiServer *scanWifi;
RestServer *restServer;

struct Network {
    const char* ssid;
    const char* password;
};

std::vector<Network> readAP(fs::FS &fs) {
    //fs.remove("/ap.txt");
    File file = fs.open("/ap.txt");
    std::vector<Network> networks;
    if (!file) {
#ifdef DEBUG
        Serial.println("Failed to open file for reading");
#endif
        return networks;
    }

    while (file.available()) {
        DynamicJsonDocument n(JSON_CAPACITY);
        auto s = file.readStringUntil('\n');
        deserializeJson(n, s);
        struct Network network = {n["ssid"], n["password"]};
        networks.push_back(network);
        Serial.println(networks.back().ssid);
    }

    file.close();
    return networks;
}

void setup() {
#ifdef DEBUG
    Serial.begin(BAUDRATE);
    delay(2000);
#endif

    SPIFFS.begin();
    auto networks = readAP(SPIFFS);
    if (networks.size() > 0) {
        Serial.println("Networks:");
        int network = 0;
        Serial.println(networks.size());
        while (WiFi.status() != WL_CONNECTED && network < networks.size()) {
            const char* ssid = networks[network].ssid;
            const char* password = networks[network].password;
            Serial.printf("%s, %s\n", ssid, password);

            WiFi.begin(ssid, password);

            while (WiFi.status() != WL_CONNECTED) {
                if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_NO_SSID_AVAIL)
                    break;
                delay(500);
                Serial.print(WiFi.status());
            }
            Serial.println("");
            network++;
        }
        if (WiFi.status() == WL_CONNECTED) Serial.println("Connected");
        else networks.clear();
    }
    if (networks.size() == 0) {
        Serial.println("Starting ScanWifiServer");
        WiFi.mode(WIFI_AP);

        scanWifi = new ScanWifiServer(Server);

        Server->begin();

        MDNS.begin("grow");
        MDNS.addService("http", "tcp", 80);
    }
}

void loop() {}

```

# Answer
I found the solution myself. I switched from using `struct Network network = {n["ssid"], n["password"]};` to declare the struct and const char pointers to using char arrays and `strcpy`

```
struct Network network;
strcpy(network.ssid, n["ssid"]);
strcpy(network.password, n["password"]);

```

Seems like the pointers were getting freed or something right at the same time that I tried to use the value to connect to the network?
> 1 votes

# Answer
`std::vector<JsonDocument>` doesn't store a copy of the complete document, but just a copy of the internal pointers of `JsonDocument`. Therefore, at the time you use the value, it points to an invalid location.

This is clearly a bug, that's why I removed the copy constructor of `JsonDocument`, but the change hasn't been published yet.

You can fix your program by replacing the `std::vector<JsonDocument>` with `std::vector<DynamicJsonDocument>`.
> -1 votes

---
Tags: esp32, json
---


title: Arduino String memory allocation

text:
# Question
Title: Arduino String memory allocation
When a String variable is declared and modified inside a function, where does it go? To the **heap**(as string declaration is a part of dynamic memory allocation) or to the **stack**(as it is a part of function)? And is the space regained after the function goes out of the scope? For example

```
void loop()
{
  Serial.println(foo("def"));
  while(1);
}

String foo(String arg1)
{
 String test = "abc";
 test = test + arg1;
 return test;
}

```

So, in this case, the variable "test" is declared in stack or heap? And this space is regained at the end or not?

**Modified:** What if inside loop variable is declared like below?

```
String foo_test = F("def");
Serial.println(foo(foo_test));

```

In this case what will be the status of variables?

# Answer
This is an excellent question to illustrate the amount of string copying and heap operations (malloc/free) going on when using the Arduino String class.

```
void loop()
{
  Serial.println(foo("def"));
  while(1);
}

```

The compiler will generate loop() something like this:

```
void loop()
{
  // String literal is stored in program memory. Needs to be copied
  // to temporary variable. This is done before main() is called.
  static const char temp0[4] PROGMEM = "def";
  static const char temp1[4];
  copy_from_program_memory(temp1, temp0);

  // The parameter to the call to foo() is actually a temporary String
  // variable constructed from the string literal. Storage is allocated
  // on the heap and the assigned from the value of the string literal.
  String temp2;
  temp2.constructor(temp1);

  // The return value of the call to foo() is a String that is passed
  // to Serial.println(). This is also a temporary String variable.
  String temp3;
  temp3.constructor(foo(temp2));
  Serial.println(temp3);

  // The String class destructor has to be called for the temporary
  // String variable so that the string values on heap are deallocated.
  temp2.destructor();
  temp3.destructor();
}

```

Note that each call to the constructor involves allocating and copying data to the heap.

```
String foo(String arg1)
{
 String test = "abc";
 test = test + arg1;
 return test;
}

```

The function foo() needs to copy strings several times to perform the string concatenation. The operator+ will require an intermediate String copy.

Cheers!

PS: For more details please see the assembly listing below with the calls to String member functions. The compiler reduces inline member functions and reuses temporary local variables. Also the call to foo() is inlined. The member function reserve() is part of the constructor.

```
00000198 <main>:
 1de:   60 df           rcall   .-320       ; 0xa0 <String::reserve(unsigned int)>
 1fc:   50 d2           rcall   .+1184      ; 0x69e <strcpy>
 212:   46 df           rcall   .-372       ; 0xa0 <String::reserve(unsigned int)>
 230:   36 d2           rcall   .+1132      ; 0x69e <strcpy>
 248:   62 df           rcall   .-316       ; 0x10e <String::operator=(String const&)>
 26a:   1a df           rcall   .-460       ; 0xa0 <String::reserve(unsigned int)>
 27e:   0f d2           rcall   .+1054      ; 0x69e <strcpy>
 28e:   3f df           rcall   .-386       ; 0x10e <String::operator=(String const&)>
 294:   60 df           rcall   .-320       ; 0x156 <String::~String()>
 29a:   5d df           rcall   .-326       ; 0x156 <String::~String()>
 2a0:   5a df           rcall   .-332       ; 0x156 <String::~String()>

```

Bottom-line is that the String class uses a lot of instruction cycles and memory, and there is a potential risk of heap fragmentation and allocation failure.
> 4 votes

# Answer
The truth here turns out to be a bit more complicated than the other answers express. **There's more than one implementation of the Arduino String library, and some are better than others.** Which one you get depends on which board you deploy to.

The newer code handles strings a whole lot more efficiently, particularly in terms of memory usage, and changes the whole dynamic around the answer to this question.

Compare the *original* version of the Arduino String library, the one for AVR, to the version for the ESP8266.
*(As of writing this answer, these were this snapshot and this snapshot, respectively.)*

Looking in particular at the functions like `changeBuffer` you can see that the ESP version contains something called "SSO" ("Small String Optimization") added with this PR here. Basically, for small strings—small enough to fit in the structure would otherwise be used to track the string buffer on the heap—it'll just store the string in that space (in the String object itself) instead.

In practice, this means strings smaller than 12 characters don't require memory allocation; they're stored on the stack inside the String object.

This is a pretty huge deal if you push around a lot of tiny strings, like in the example listed in the question. It means that the code works about as efficiently as you might hope, without problematic side-effects.
> 4 votes

# Answer
The string is an instance of an object, high likely keeping the administration like the offset and size (unless it is implemented as a 0-delimited string). This is a local variable and will be stored on the stack and will be nicely removed after finishing the function.

The characters itself ("abc" ...) will be stored on the heap since this needs to be dynamic. This data will be freed by the string object after returning from the function and possibly when needed to relocate the string.

Normally a string instance will keep some memory allocated, when it is increased (or increased too much) the string content will be copied. This all happens in heap and 'holes' in the heap can occur by this.

That's why in a memory/time critical process it's best to allocate the string before hand, of course this is only possible if you know the (maximum) string size.
> 1 votes

---
Tags: string, memory-usage, memory
---


# Question
Title: Having issue with a redeclaration as a different kind of symbol
Been struggling with this for a few days and I suspect that i have several issues but I cannot find them.

Project: Need a serial count that counts by 5-50 and a button interrupt should trigger a display of the current time and then continue counting.

Issue: Cannot complete compiling because my "void rtcTime()" is saying I am redeclared as different kind of symbol.

Any help the community can provide is greatly appreciated.

Code:

```
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include "RTClib.h"
#include <Wire.h>

RTC_DS1307 rtc;

int count = 5;
int rtcTime = 0;
int pin = 0;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup (){

  pinMode(2, INPUT);

  rtc.begin();

  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(9600);

  if (! rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
      }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
     }

     attachInterrupt(pin, rtcTime, RISING);
}

void loop()
{
  // Count X5 on Serial Monitor

  if (count > 50)
    {
    count=5;
    Serial.println(count);
    }

   else if (count<50)
    {
    count=count+5;
    Serial.println(count);
    delay(1000);
     }
  }

void rtcTime() {
    DateTime now = rtc.now();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    }

```

Error Message:

> Arduino: 1.8.10 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
>
> ds1307\_workingCopy\_Mod5:60:14: error: 'void rtcTime()' redeclared as different kind of symbol void rtcTime() { ^ /Users/kiko/Documents/Arduino/ds1307\_workingCopy\_Mod5/ds1307\_workingCopy\_Mod5.ino:9:5: note: previous declaration 'int rtcTime' int rtcTime = 0; ^~~~~~~ /Users/kiko/Documents/Arduino/ds1307\_workingCopy\_Mod5/ds1307\_workingCopy\_Mod5.ino: In function 'void setup()': /Users/kiko/Documents/Arduino/ds1307\_workingCopy\_Mod5/ds1307\_workingCopy\_Mod5.ino:38:42: warning: invalid conversion from 'int' to 'void (*)()' \[-fpermissive\] attachInterrupt(pin, rtcTime, RISING); ^ In file included from sketch/ds1307\_workingCopy\_Mod5.ino.cpp:1:0: /Users/kiko/Desktop/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/Arduino.h:150:6: note: initializing argument 2 of 'void attachInterrupt(uint8\_t, void (*)(), int)' void attachInterrupt(uint8\_t, void (\*)(void), int mode); ^~~~~~~~~~~~~~~ /Users/kiko/Documents/Arduino/ds1307\_workingCopy\_Mod5/ds1307\_workingCopy\_Mod5.ino: In function 'void rtcTime()': ds1307\_workingCopy\_Mod5:60:14: error: 'void rtcTime()' redeclared as different kind of symbol void rtcTime() { ^ /Users/kiko/Documents/Arduino/ds1307\_workingCopy\_Mod5/ds1307\_workingCopy\_Mod5.ino:9:5: note: previous declaration 'int rtcTime' int rtcTime = 0; ^~~~~~~ Multiple libraries were found for "RTClib.h" Used: /Users/kiko/Documents/Arduino/libraries/RTClib-1.3.3 Not used: /Users/kiko/Documents/Arduino/libraries/RTCLib\_by\_NeiroN Multiple libraries were found for "Wire.h" Used: /Users/kiko/Desktop/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire exit status 1 'void rtcTime()' redeclared as different kind of symbol
>
> This report would have more information with "Show verbose output during compilation" option enabled in File -\> Preferences.

# Answer
The Arduino builder doesn't create forward declarations of functions for functions used in code as callbacks. It has something to do with the occurrence of the name without the usual form of function call.

You could move the function rtcTime before setup() so it is visible for the use as parameter in attachInterrupt or you can create a forward declaration for the compiler. Your attempt to make the name of the function valid was to create a variable with this name. This way you created the error of duplicate name.

Add

```
void rtcTime();

```

before setup() function and remove `int rtcTime = 0;`
> 0 votes

---
Tags: arduino-mega, interrupt, button, rtc, compilation-errors
---


# Question
Title: Problem to Setting up i2c OLED wemos D1 mini shiled (64*24)
*Hi*

*I used this shield before well. But it didn't work when I wanted to work with him last night!*

# *this is my wireing :*

*Now I want to know how to **test** that it is healthy? Is **i2c address missing or not**?*

*I tried **this code** to **find i2c address** but no answer appeared on Arduino Serial monitor !! nothing ..*

*and i uploaded any more example code on Uno but OLED not worked .*

```
//     ~~~~~~~~~~~ i2c Address Scanner ~~~~~~~~~~~

#include <Wire.h>

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

while (!Serial) {}

Serial.println ();
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;

Wire.begin();
for (byte i = 8; i < 120; i++){
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0){
  Serial.print ("Found address: ");
  Serial.print (i, DEC);
  Serial.print (" (0x");
  Serial.print (i, HEX);
  Serial.println (")");
  count++;
  delay (1);
   }
  }
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
  }
  void loop() {}

```

. .

*What is the problem ?*

# Answer
The main problem is, that the module does not get any supply voltage. You connected the Unos 5V to the OLED boards 5V. But this pin doesn't seem to be connected on the OLED shield. It is marked with 5V there, because this board is a shield to be stacked onto the Wemos D1. When you do this, you have 5V on this pin from the Wemos and can access it on the OLED shield for adding further components. (This is the principle of shields. Making even unused pins available on the shield, so that these pins don't get covered by the shield)

The shield needs to be supplied through the 3.3V pin, as it is a 3.3V device and it does not have an own voltage regulator (see the schematics of the shield).

Thus the shield cannot be found, because it is not turned on. It does not have a supply voltage.

---

That said, you may also get into trouble because of the communication voltage. The Uno works with 5V on the I2C lines, while the OLED shield works with 3.3V. The shield might get damaged by the higher voltage. The schematics the shield don't mention part names, so I cannot know, if they are 5V tolerant (there are 2 ICs in the schematics).

If the shield is not 5V tolerant on the I2C lines, you need to use a bidirectional level converter for both lines (or you can build your own with 2 MOSFETS for each line).
> 0 votes

---
Tags: arduino-uno, i2c, hardware, electronics, oled
---


# Question
Title: How do I run a function every 10th time through a loop?
I currently have a function that poles all my sensors every time through it's loop, but I want to pole one of the sensors only every 10th time. Currently there is a 10 millisecond delay at the beginning of my function. I know I could increment a counter and use modulo, but is there a better practice for this?

# Answer
> 1 votes
```
for(int i=0; i < 9999; ++i)
{
    if(i % 10 == 0)
    {
         //my actions on i = 0, 10, 20, 30 ...
    }
}

```

# Answer
> 1 votes
Normally it's suboptimal to reduce the speed of loop just to be able to count them. Apply the BlinkWithoutDelay principle instead (which is not about Blink, but about **WithoutDelay**)

---
Tags: c++, loop
---


# Question
Title: Replacing large lookup table with switch statement
My arduino needs to take a 14-bit number and convert it to a 10-bit number. Can't use a formula for it since the data is quite random. So I created a lookup table with 2^14 elements, each containing a 10-bit value. But it's too big to fit on the arduino. So I thought of using a switch statement instead. Would this result in a significant speed decrease?

Say, for example, that the input value is 16383. How much longer would it take for the arduino to iterate through the 16384 cases compared to accessing index #16383 of an array?

EDIT: This code compiles fine and reports a program memory usage of 1000 bytes.

```
int xval;
int yval;

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  xval = random(0,16383);
  switch (xval) {
  case 0:
  yval = 0;
  break;
  case 1:
  yval = 4;
  break;
  case 2:
  yval = 4;
  break;
  case 3:
  yval = -60;
  ...
  case 16383:
  yval = 1023;
  break;
}
}

```

However, I haven't tried if it really works so maybe the compiler is optimizing away too much.

EDIT 2: Added the line `Serial.println(yval);` so that I'm actually doing something with yval as Majenko commented. And now it doesn't compile :'( :'( :'(

So, I'll tackle my problem in some other way.

# Answer
> 2 votes
214 is 16384 entries. Each entry takes 2 bytes. That's 32768 bytes. That's all the flash the ATMega328P has.

The most efficient storage will be an array in flash, and that will take 100% of it. Using a switch will take more space.

So in short: no. Just no. It won't work whatever you try. You need to come up with a radically different storage solution (external flash memory?) or use a larger chip.

---

As a side note, with "bit packing" you could reduce the storage to 20480 bytes, but doing a lookup of the data within that packed data (4 10-bit entries taking 5 bytes) will be slow to do since you have to work out exactly what combination of bits and bytes you need to reconstruct your 10-bit value.

# Answer
> 0 votes
### Almost certainly not

Compilers often optimise switch statements using **jump tables**. However the entries in the jump table basically make up a lookup table with 214 entries! So you don't gain anything.

### Some ideas for compression

* You can use bit packing

If your numbers aren't 8 bits in size, you can pack them together. For example, if you have managed to code things in 6 byte chunks, you can squash 4 of these chunks into 3 bytes, to shrink a table by 25% (at the expense of some bit shifts when retrieving entries.)

* Take advantage of frequency of duplicates

You say you have duplicates. But how many "very common" duplicates are there?

If, say, 90% of your values come from a group of 15 possible values, then you can pack 2 entries per byte, each one represented by a value from 0-14. If one of the entries is 15, then that that value is an "exception" and is looked up by binary search in a second table.

This would result in a table of size 8KB plus the size of the other table (say 4KB when you pack the 14 bit index and 10 bit value into 3 bytes.)

If you instead have a set of 254 possible "common" values, then your main table would be more like 16KB. That *might* be doable.

* Is there *any* relation between input and output?

Maybe there is no formula, but there might be properties of the input that affect the properties of the output. (For example, maybe most input values 0-1024 have an output that is similar plus or minus 30.)

* Write a program to find patterns in your data

Don't just use your eyes. Write a script (Python?) to count the frequency of each output value, or compare inputs to outputs, or evaluate your suspicions about the data. Graph input vs output.

---
Tags: arduino-uno, c++, atmega328, array
---


# Question
Title: Can someone help me decipher the code for the arduino? I am totally lost
The code is as follows:

```
void loop(){

    light = analogRead(5);
    Serial.println(light);
    analogWrite(3,light/4);

}

```

# Answer
> 3 votes
Not really a physics question, but I will answer anyway.

`loop()` is the standard Arduino function which contains code that the microprocessor runs repeatedly (as opposed to code in `setup()` which is only run once).

`light = analogRead(5);` takes an analogue voltage reading from pin 5, encodes it as an integer value (either 10 or 12 bits depending on the Arduino model) and stores the result in the variable `light`.

`Serial.println(light);` outputs the value of the variable `light` to the Arduino's serial port. This is a standard way of outputting data from the Arduino so that it can be displayed on a connected computer.

`analogWrite(3, light/4);` outputs the value of `light/4` as a phase-width modulated (PWM) signal to pin 3. Although Arduino output pins are either on (5 volts) or off (ground) at any point in time, PWM signals allow the Arduino to switch an output pin on and off rapidly so that the average voltage seen on that pin is an intermediate value. The duty cycle of the PWM signal which determines the average voltage on the pin is encoded as an 8 bit integer, so `light` is probably divided by 4 here to convert it from 10 bits to 8 bits.

So the Arduino will repeatedly read an input voltage from pin 5, output an integer representing this voltage to the serial port, and create a PWM signal on pin 3 that has an average voltage the same as that of the input voltage.

See the Arduino language reference page for more information.

---
Tags: electronics, software
---


# Question
Title: Arduino MySQL Connector Issues with Select only
first question i am doing so hope this is the right place.

I have an issue with an Arduino Uno and an Arduino ESP8266WiFi Shiald by WangTongze using this tutorial (https://www.instructables.com/id/ESP8266-ESP-12E-UART-Wireless-WIFI-Shield-TTL-Conv/) I have been able to connect to the my Wifi and host a small webserver.

Then with the Examples of the MySql Connector Library I have been able to do a simple Insert to a MySQL Database on a NAS Server. However, I want to be able to select a value from my DB and print it on the screen for some reason the Cursor always returns a null. I have been able to select from my PC using the same user. and created the user francis@% so that the host isn't an issue. Please note that this same code with a few tweaks worked to insert a record to the same table. Is there anything I am missing? Below is the code:

```
//#include <WiFi.h> // Use this for WiFi instead of Ethernet.h
#include <WiFiEsp.h> //use for ESP8266
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

// Emulate Serial1 on pins 2/3 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(2, 3); // RX, TX
#endif

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192,168,x,x); // IP of the MySQL server here
char user[] = "francis";
char password[] = "xxxxxx";

// WiFi card example
char ssid[] = "PintoLoco"; // your network SSID (name)
char pass[] = "xxxxxxxx"; // your network password

//WiFiClient client; // Use this for WiFi instead of EthernetClient
WiFiEspClient client; //Use this for ESP8266
MySQL_Connection conn((Client *)&client);
MySQL_Cursor cur = MySQL_Cursor(&conn);

char query[] = "SELECT Value FROM Peceras.Parameters ";

void setup() {

  Serial.println("Starting....");
  Serial.begin(115200);
  // initialize ESP module
  WiFi.init(&Serial);
  Serial.println("Connecting to WiFi");

  // Begin WiFi section
  int status = WiFi.begin(ssid, pass);
  while(status != WL_CONNECTED){
      status = WiFi.begin(ssid, pass);
    }
  // print out info about the connection:

  Serial.println("Connected to network");
  IPAddress ip = WiFi.localIP();
  Serial.print("My IP address is: ");
  Serial.println(ip);

  // End WiFi section

  Serial.println("Connecting...");
  if (conn.connect(server_addr,3306,user,password)) {
  delay(1000);
  }
  else
  Serial.println("Connection failed.");
}
MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
void loop() {
  row_values *row = NULL;
  long head_count = NULL;
column_names *cols = cur_mem->get_columns();
cur_mem->execute(query);
  // Execute the query
  do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
      for (int f = 0; f < cols->num_fields; f++) {
        head_count = atoi(row->values[f]);
          Serial.print("Ingestelde Temperatuur:  ");
          Serial.println(head_count);
        if (f < cols->num_fields-1) {
          Serial.println(',');

        }
      }
      Serial.println();
    }
  } while (row != NULL);
  // Deleting the cursor also frees up memory used
  delete cur_mem;
  delay(2000);
}

```

# Answer
I have no access to a compiler, so there might be errors.

```
#include <WiFiEsp.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(2, 3); // RX, TX
#endif

byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192,168,x,x);
char user[] = "francis";
char password[] = "xxxxxx";

char ssid[] = "PintoLoco";
char pass[] = "xxxxxxxx";

WiFiEspClient client;
MySQL_Connection conn( (Client *) &client );
MySQL_Cursor *cur_mem = null;

// PPK: some database systems are case sensitive
// so Peceras.Parameters is not the same as peceras.parameters
// check if the tables and fields are named correctly.
char query[] = "SELECT Value FROM Peceras.Parameters";

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

  Serial.println( "Connecting to WiFi" );
  WiFi.init( &Serial1 );
  int status = WiFi.begin( ssid, pass );
  while( status != WL_CONNECTED )
  {
    status = WiFi.begin(ssid, pass);
  }

  Serial.println( "Connected to network" );
  IPAddress ip = WiFi.localIP();
  Serial.print( "My IP address is: " );
  Serial.println( ip );

  Serial.println( "Connecting DB ..." );
  if ( conn.connect( server_addr, 3306, user, password ) )
  {
    Serial.println( "DB connected." );
    cur_mem = new MySQL_Cursor( &conn );
    row_values *row = NULL;
    long head_count = NULL;
    column_names *cols = cur_mem->get_columns();

    cur_mem->execute(query);

    do
    {
      row = cur_mem->get_next_row();
      if ( row != NULL )
      {
        for ( int f = 0; f < cols->num_fields; f++ )
        {
          head_count = atoi( row->values[f] );
          Serial.print( "Ingestelde Temperatuur:  ");
          Serial.println( head_count );
          if ( f < cols->num_fields - 1 )
          {
            Serial.println(',');
          }
        }
        Serial.println();
      }
    } while (row != NULL);

    // Deleting the cursor also frees up memory used
    // PPK: I'm not sure if this is a good idea, I don't know
    delete cur_mem;
  }
  else
  {
    Serial.println( "DB Connection failed." );
  }
}

void loop()
{
  // PPK: I would recommend to do the select in the setup section
  // It looks like you want to run it just once
}

```

**Edit**

Please note, that this code only works if you connect the software serial pins D2, D3 to the respective RX and TX pins on the Shield. You have to bend the pins (P0-P3) of the shield to disconnect them from the Arduino. Then you have to connect D2 and D3 to P0 and P1. This is described in step 1 of the instructables you linked to in the question. See the picture at the end of Step 1. https://www.instructables.com/id/ESP8266-ESP-12E-UART-Wireless-WIFI-Shield-TTL-Conv/
> 1 votes

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


# Question
Title: Difference in increment & decrement loop execution speed
I was experimenting with for loops when I noticed that a simple increment loop executes faster than a decrement loop. I can't think of any reason why it should be like that. Is there something in my code that is causing the different in execution speed?

The code is as follows:

```
// Global Variables
const int spk = 7;
const int led = 6;
int j = 0; // counter variable

void setup() {

  pinMode(spk, OUTPUT);
  pinMode(led, OUTPUT);
  Serial.begin(9600);
} // end of setup

void loop() {

  tone(spk, 300, 500); // first note with duration

  // increment loop
  for (j=0; j <= 500; j = j + 1) {
    digitalWrite(led, HIGH);
    Serial.println(j);
  } // end 1st note loop

  tone(spk, 100, 500); // second note with duration

  // decrement loop

  for (j = 500; j >= 0; j=j-1) {
    digitalWrite(led, LOW);
    Serial.print("the value is=");
    Serial.print("\t");
    Serial.println(j);
  } // end 2nd Note loop

} // end setup

```

# Answer
> 1 votes
Comment out these 2 lines

```
Serial.print("the value is=");
Serial.print("\t");

```

And report back on the speed difference. Why not add a reading of micros() before and after each loop and see how much difference there really is? All time variables are unsigned long.

```
startTime = micros();
// your loop
endTime =  micros();
duration = endTime - startTime;
Serial.println (" "); // line break
Serial.print ("duration in uS = ");
Serial.println (duration);

```

I edited to add some missing )s and a 2nd line break.

# Answer
> 0 votes
In the code you posted, the decrement loop has two more Serial.print() statements.

Serial.print() takes a lot of time and while it's useful for debugging, it sometimes can cause additional bugs because of the extra delay it introduces if you are running time-sensitive code.

Consider for using Serial.print("the value is=\t" + itoa(j,10));

"itoa" converts an integer to an array of characters (aka string). As Juraj said, it takes another two arguments which are the buffer to store the output string and the base to which it converts the incoming number to be represented by (eg: 10 is decimal, 16 is hexadecimal). It returns a pointer to the output string which is essentially the same as the second argument but AFAIR you can omit the second argument and use it's return value.

---
Tags: performance
---


title: connected between 2 arduino

text:
# Question
Title: connected between 2 arduino
i want to connect SPI 2 arduino master and slave through the MUX , to write and read in external memory , when the master write in memory slave read . pls help . code to master

```
#include <SPI.h>
//-------FM------------------
#define WENB 0x06
#define RDSR 0x05
#define WRSR 0x01
#define PPROGRAM 0x02
#define SERASE 0x20
#define BERASE 0xd8
#define READ 0x03
#define RDSCUR 0x2B
#define CERASE 0x60//or 0xC7

//------------Specify the address-----------
int address = 0x00ff0000;
byte x, Y;
int IN = 5;
int SS1 = 9;
/*char data[]=("don't be afraid ");
char recived[15];*/
//--------------------------
void setup() {
    //------------------------------------------
    // pinMode(EN,OUTPUT);
    pinMode ( SS, OUTPUT ); //ss pin 10
    pinMode ( SS1, OUTPUT );
    digitalWrite ( SS1, HIGH );
    pinMode ( IN, OUTPUT );
    digitalWrite ( IN, LOW ); // MUX connect A
    //digitalWrite(CS,low);
    Serial.begin ( 9600 );
    SPI.begin();//start the SPI connection with the flash memory
    SPI.setClockDivider ( SPI_CLOCK_DIV8 );
    SPI.setBitOrder ( MSBFIRST );
    digitalWrite ( SS, HIGH );
    delay ( 10 );
    //-------erase the sector--//-----------
    digitalWrite ( SS, LOW );
    SPI.transfer ( WENB );
    digitalWrite ( SS, HIGH );
    //-------------------------------------
    digitalWrite ( SS, LOW );
    SPI.transfer ( SERASE );
    SPI.transfer ( ( address >> 32 ) & 0xff );
    SPI.transfer ( ( address >> 16 ) & 0xff );
    SPI.transfer ( ( address >> 8 ) & 0xff );
    SPI.transfer ( address & 0xff );
    digitalWrite ( SS, HIGH );
    delay ( 5000 );
    //------------------------------------------
    //Serial.println("okay fine")
    //-----Program Data Into Memory Array-----.
    //-----------interrupts the slave----------
    /* digitalWrite(SS1,LOW);
     SPI.transfer(0xff);//are you there?
     digitalWrite(SS1,HIGH);
     delay(1000);

     digitalWrite(IN,HIGH);*/
}

void loop()

{
    char c;
    int i = 0;
    char data[] = "Hello!:";
    char recived[7];
    byte x;
    //----------Enable the write in the memory-----.
    digitalWrite ( SS, LOW );
    SPI.transfer ( WENB );
    digitalWrite ( SS, HIGH );
    delay ( 20 );
    //-----Program Data Into Memory Array-----.
    digitalWrite ( SS, LOW );
    SPI.transfer ( PPROGRAM );
    SPI.transfer ( ( address >> 32 ) & 0xff );
    SPI.transfer ( ( address >> 16 ) & 0xff );
    SPI.transfer ( ( address >> 8 ) & 0xff );
    SPI.transfer ( address & 0xff );

    for ( int i = 0; i < sizeof ( data ); i++ ) {
        SPI.transfer ( data[i] );
        // Serial.print(data[i]);
    }

    // disable Slave Select
    digitalWrite ( SS, HIGH );
    //--------------------------------------------
    delay ( 1000 );
    //--------------------------- ----------
    i = 0;
    Serial.print ( "It's okay saved: " );

    while ( data[i] != NULL ) {
        Serial.println ( data[i] );
        i++;
    }

    // delay(100);
    //-----------interrupts the slave----------
    digitalWrite ( SS1, LOW );
    SPI.transfer ( 0xff ); //are you there?
    digitalWrite ( SS1, HIGH );
    delay ( 1000 );
    digitalWrite ( IN, HIGH ); // MUX connect B
}

```

code to slave

```
#include <SPI.h>
//-------FM------------------
#define WENB 0x06
#define RDSR 0x05
#define WRSR 0x01
#define PPROGRAM 0x02
#define SERASE 0x20
#define BERASE 0xd8
#define READ 0x03
#define RDSCUR 0x2B
#define CERASE 0x60//or 0xC7

//------------Specify the address-------------
int address = 0x00ff0000;

int SS1 = 9;
char data[] = "Hello!:";
char buff[7];

byte slave;
volatile bool process;
//----------------config slave----------------
void setup() {
    //pinMode(IN,OUTPUT);
    pinMode ( SS, OUTPUT ); //SS pin 10
    pinMode ( MISO, OUTPUT );
    pinMode ( SS1, INPUT );
    pinMode ( MOSI, INPUT );
    //--------------------------------------------------
    Serial.begin ( 9600 );
    ///SPCR |= bit (SPE);
    SPI.begin();//start the SPI connection with the flash memory
    SPI.setClockDivider ( SPI_CLOCK_DIV8 );
    SPI.setBitOrder ( MSBFIRST );
    // digitalWrite(SS,HIGH);
    //-------------master interrupts the slave----------------------------------------------
    // now turn on interrupts
    // SPCR |=bit(SPIE);
    //SPCR |=bit(SPE); //set SPE bit at the SPCR(spi control register) to enable SPI
    SPI.attachInterrupt();
}

ISR ( SPI_STC_vect ) {
    slave = SPDR;

    if ( slave = 0xff ) {
        pinMode ( MISO, INPUT );
        // pinMode(SS1,INPUT);
        pinMode ( MOSI, OUTPUT );
        //digitalWrite(IN,HIGH);
        digitalWrite ( SS, LOW );
        SPI.transfer ( READ );
        SPI.transfer ( ( address >> 32 ) & 0xff );
        SPI.transfer ( ( address >> 16 ) & 0xff );
        SPI.transfer ( ( address >> 8 ) & 0xff );
        SPI.transfer ( address & 0xff );

        for ( int n = 0; n < sizeof ( data ); n++ ) {
            data[n] = SPI.transfer ( 0 );
            Serial.print ( data[n] );
        }

        digitalWrite ( SS, HIGH );
    }
}

```

# Answer
> 1 votes
Having a line from Arduino 1 to Arduino 2 to indicate that Arduino 2 should do something is sufficient.

Simple way: a line that is an input on both sides with internal pullups turned on. Both sides monitor it.

When Arduino 1 wants to write, it checks to make sure the line is high, then it makes its pin an output and pulls it low, and when done releases it by going back to an input (using pinMode() command).

When Arduino 2 see the low, it waits for it to go high, then makes its input and output and pulls it low until it is done reading.

Arduino 1 sees the low and holds off on any writing until it goes back high again.

This is known as arbitration, and is an example of one simple method.

---
Tags: serial, programming, arduino-ide, spi, multiplexer
---


# Question
Title: How to make an arduino button to forget his past purpose?
For my school project im making an arduino speedometer for a bicycle. I will be using a reed switch sensor to get the speed. There will also be an clock and a termometer, it will be on a 16x2 lcd screen. To get the speed I will need the user to type in his bike size, in zoll. I managed to let the user tap the button until his size and then double tap the button to confirm it. Alright, fine. Now I need the same button to FORGET his last purpose. Because I want to use the same button to change the screen between speed, clock and termometer. SPEED -\> tap -\> CLOCK -\> tap -\> TEMPERATURE -\> tap -\> SPEED ........

I hope you get the idea. After the user picks his size, if he keeps tapping the number it would just keep on growing. So, im trying to make the button forget, or make him go trough that loop only once.

Pick your size tap tap tap double tap, thank you. And stop! I want him to do that only once and never again. I will need the same principle when the user will adjust his clock, he will have to tap to set it, save the number but reset the buttons function.

```
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>
LiquidCrystal_I2C lcd(0x27, 16,2);
#define buttonPin 7
int a = 16;
int b = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("RADGROESSE IN");
  lcd.setCursor(0, 1);
  lcd.print("ZOLL EINGEBEN");

   // Set button input pin
   pinMode(buttonPin, INPUT);
   digitalWrite(buttonPin, HIGH );
}
void loop() {
   int b = checkButton();
   if (b == 1) clickEvent();
   if (b == 2) doubleClickEvent();
}
void clickEvent() {

   lcd.setCursor(14, 1);
    lcd.print(a);
    delay(100);
    lcd.print(" ");
    delay(100);
    a++;
    delay(100);
    if(a >= 23){
      a = 16;
      }
}
void doubleClickEvent() {
      b = a - 1;
      Serial.println("Button was idle for one second or more");
      lcd.clear();
      lcd.print("ZOLL = ");
      lcd.setCursor(7, 0);
      lcd.print(b);

}

//=================================================
//  MULTI-CLICK:  One Button, Multiple Events

// Button timing variables
int debounce = 20;          // ms debounce period to prevent flickering when pressing or releasing the button
int DCgap = 420;            // max ms between clicks for a double click event
// Button variables
boolean buttonVal = HIGH;   // value read from button
boolean buttonLast = HIGH;  // buffered value of the button's previous state
boolean DCwaiting = false;  // whether we're waiting for a double click (down)
boolean DConUp = false;     // whether to register a double click on next release, or whether to wait and click
boolean singleOK = true;    // whether it's OK to do a single click
long downTime = -1;         // time the button was pressed down
long upTime = -1;           // time the button was released

int checkButton() {
   int event = 0;
   buttonVal = digitalRead(buttonPin);
   // Button pressed down
   if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
   {
       downTime = millis();
       singleOK = true;
       if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true)  DConUp = true;
       else  DConUp = false;
       DCwaiting = false;
   }
   // Button released
   else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
   {
           upTime = millis();
           if (DConUp == false) DCwaiting = true;
           else
           {
               event = 2;
               DConUp = false;
               DCwaiting = false;
               singleOK = false;
           }
   }
   // Test for normal click event: DCgap expired
   if ( buttonVal == HIGH && (millis()-upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2)
   {
       event = 1;
       DCwaiting = false;
   }

   buttonLast = buttonVal;
   return event;
}

```

Thank you! I would really appreciate it!

# Answer
jsotola wrote a very important term in the comments: state.

You should implement your project as a Finite State Machine (FSM), a very important and powerful, yet easy principle. You divide your program into different states. Each state contains code, that only gets executed, when the program is in this state. Depending on input events (like the user pressing the button), you do transitions between the states.

I already wrote a rather detailed answer about FSMs for this question. You can read it to get a better understanding of FSMs.

For your case I would suggest these states: `INPUT_SIZE`, `DISPLAY_SPEED`, `DISPLAY_CLOCK` and `DISPLAY_TEMPERATURE`. `INPUT_SIZE` is the initial state (which you might skip after the first power on, after you saved the size in persistent memory like EEPROM). There you execute your current button code. When you sense a double tap on the button, you change to the `DISPLAY_SPEED` state. From there on a button press to the `DISPLAY_CLOCK` state and so on.

In my linked answer I used a simple integer variable as state variable, which holds the current state. In fact it is better (easier to read), when you define an `enum` for the cases (`enum`s are actually only named integer constants):

```
enum State {INPUT_SIZE, DISPLAY_SPEED, DISPLAY_CLOCK, DISPLAY_TEMPERATURE};

State state = INPUT_SIZE;

void loop(){
    switch(state){
        case INPUT_SIZE:
            // Button code here
            // on double tap use the following line
            state = DISPLAY_SPEED;
            break;
        case DISPLAY_SPEED:
            // code for displaying speed here
        ...
    }
}

```

That is just a little template for the structure. You need to fill it with life yourself.
> 3 votes

# Answer
What you likely need is a state machine. The behavior of the actions depends on the state the program is currently in.

In your case, the state machine might look like this:

What does it mean?

* black circle: this is where the system powers on
* rectangle: a state
* arrow: a transition from one state to another
* green text: action

For the problematic double click action, you can see:

* it changes the state from "set size" to "speed"
* in all other cases, it does not change the state (actually it changes the state to the same state)

I always recommend drawing the state machine before implementing it. It makes mistakes much more obvious.

There are several ways to implement it. The easiest one being a `switch/case`. More advanced implementations may use object orientation. When using `switch/case`, I prefer to have one method per state, like so:

```
void loop()
{
    switch(state):
        case setsize:
             setsize();
             break;
        case speed:
             speed();
             break;
        ...
}

```

If you know about function pointers, it gets even easier:

```
enum State {
  setsize = 0,
  speed,
  clock,
  temperature
};

State state;

void setup() {
  state = State::setsize;
}

typedef void (* functionPointer) ();
functionPointer process[] = {do_setsize, do_speed, do_clock, do_temperature};
void loop() {
  process[state]();
}

void do_setsize()
{
  state = State::speed;
}
void do_speed()
{
  state = State::clock;
}
void do_temperature()
{
  state = State::speed;
}
void do_clock()
{
  state = State::temperature;
}

```
> 4 votes

---
Tags: lcd, button
---


# Question
Title: How to measure ultrasonic sensor without pulsein method?
I am a front-end developer so I don't really know Arduino. Anyway, my teacher gave me a project.

In short, I have to measure distance with HC-SR04. But the problem is that the teacher wants me to use a timer. But I can't understand how can I do that.

Thank you for helping.

# Answer
Rather than give you the straight answer in code form, consider this approach. If you learn how the unit works, you will be better prepared to answer questions presented to you.

The background of an ultrasonic distance measuring device is that it sends out a signal, in the form of sound you cannot hear. The device then listens for any echoes (bounce-back) of that pulse within a certain time period. This time period represents the distance range that the device can register. If the electronics are of poor quality, the minimum distance will be larger than if the device was of higher quality, as the amount of time for the pulse to bounce from a close-in object is going to be very short. The electronics have to be very fast to read such a short period of time.

There are libraries for ultrasonic devices such as the one you note, but that's the "easy way" to use it. If you perform appropriate searches, you will find there are references how to use direct timing for this device, which will satisfy the requirement you have been given.

I could perform the search and provide you a link, but that's half the work. Consider to use terms including your device identifier along with code and timing and you may find useful links. It is also very possible that you will find someone's pre-written code using the timing method.
> 3 votes

# Answer
The solution is, You need to implement custome pulse in funtion

```
unsigned long rdPulseIn(int pin, int value, int timeout) { // the following comments assume that we're passing HIGH as value. timeout is in milliseconds

    unsigned long now = micros();
    while(digitalRead(pin) == value) { // wait if pin is already HIGH when the function is called, but timeout if it never goes LOW
        if (micros() - now > (timeout*1000)) {
            return 0;
        }
    }

    now = micros(); // could delete this line if you want only one timeout period from the start until the actual pulse width timing starts
    while (digitalRead(pin) != value) { // pin is LOW, wait for it to go HIGH befor we start timing, but timeout if it never goes HIGH within the timeout period
        if (micros() - now > (timeout*1000)) {
            return 0;
        }
    }

    now = micros();
    while (digitalRead(pin) == value) { // start timing the HIGH pulse width, but time out if over timeout milliseconds
        if (micros() - now > (timeout*1000)) {
            return 0;
        }
    }
    return micros() - now;
}

```

You can read distance

```
long mm = rdPulseIn(echoPin, HIGH, 37)/5.82; // distance in mm

```
> 0 votes

---
Tags: arduino-mega, sensors, pwm, timers, pulsein
---


title: Can't use millis() instead of delay

text:
# Question
Title: Can't use millis() instead of delay
I am making a home coming/leaving light for car. First I want that whenever I press the car key lock, a timer will start for 10 seconds. And if I press a button twice within 10 seconds, pin 13 will remain high for 10 seconds. If I don't press the button it returns to the void loop or condition may get false. I am working on it but I'm not getting the correct approach. I'm not able to use `millis` twice in this program.

```
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;
unsigned long previousMillis = 0;
const long interval = 5000;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT_PULLUP);
  pinMode(13, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  buttonState = digitalRead(8);
  if (buttonState != lastButtonState) {
    if (buttonPushCounter <= 2) {
      if (buttonState == LOW) {
        buttonPushCounter++;
        Serial.println("on");
        Serial.print("number of button pushes: ");
        Serial.println(buttonPushCounter);
        if (buttonPushCounter % 3 == 0) {
          if (currentMillis - previousMillis > 10000) {
            digitalWrite(13, HIGH);
            previousMillis = currentMillis;
          } else {
            digitalWrite(13, LOW);
          }
        } else {
          digitalWrite(13, LOW);
        }
      } else {
        digitalWrite(13, LOW);
      }
    } else {
      buttonPushCounter = 0;
    }
    lastButtonState = buttonState;
  }
}

```

# Answer
> 1 votes
Here is what you have asked for:

> I am making home coming/leaving light for car. First i want that whenver i press car key lock a timer will start for 10 second.And if i press button twice within 10 second pin 13 will high remain for 10 second and if i cant press the button it return to the void loop aor condition may get false. I am working on it but dont getting the correct approach . But i am not able to use millis twicely in this program.

So, I have refactored, and done my best to interpret your words, and the code that you wrote.

You will see that I broke down quite a bit the deep nesting of your code into separate methods. I hope that you see that it makes it more readable and understandable.

I have replaced the "magic numbers" like `10000` with more readable code like `tenSeconds`. And I hope the code does what you want now, but I'm not sure. Hopefully the readability has improved enough that you can massage and reshape the code into what you want it to do, as well as shown you what direction to head when you don't understand your own code because it has grown (deeper, longer, more complicated, etc.) as most code does.

In the professional coding world, allowing code to remain like that is called "not paying down your design debt" and you (or your organization) will pay the consequences, with interest, just like a credit card.

Finally, note that my comments don't restate the code, but tries to add something (mine often tries to finish sentences involving readable code). My comments also tend to be on the ends of lines to try to stay out of the way.

This code compiles, but has not been tested on an actual Arduino. Please let me know if this meets your need, and please choose this as the answer if it does answer your question, and at least please vote up the answer if it doesn't quite answer you... ...and give me a second chance, if possible. Thanks.

```
// pins defined and named
int pin_button = 8;         // button Pin
int pin_LED = 13;           // LED Pin

int currentButtonState = 0;         // current state of the button
int lastButtonState = 0;

int buttonPushCounter = 0;   // counter for the number of button presses
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
const unsigned int tenSeconds = 10000; // 10,000 milliseconds

void setup()
{
    pinMode(pin_button, INPUT_PULLUP);
    pinMode(pin_LED, OUTPUT);
}

void loop()
{
    currentMillis = GetCurrentMillis();
    if (ButtonIsToggled() == 1)
    {
        CountButtonPushes();
    }
}

int ButtonIsToggled()
{
    int isToggled = 0;
    currentButtonState = digitalRead(pin_button);
    if (currentButtonState != lastButtonState)
    {
        lastButtonState = currentButtonState;
        isToggled = 1;
    }
    return isToggled;
}

void CountButtonPushes()
{
    int valueToWrite = LOW; // LED-OFF is default value unless overridden

    if (currentButtonState == LOW) // we just toggled from HIGH to LOW...
    {
        buttonPushCounter++; // We've successfully completed another button-press
        if (buttonPushCounter % 3 == 0) // if (buttonPushCounter==3) should be faster
        {                               // because compare is faster than division
            buttonPushCounter = 0;  // Reset
            valueToWrite = HIGH; // LED-ON
        }
    }

    if (valueToWrite == HIGH) // LED is ON
    {
        digitalWrite(pin_LED, HIGH); // valueToWrite
        while (currentMillis - previousMillis < tenSeconds)
        {
            // do nothing -- wait while LED is on
            // busy wait. Consider sleeping instead.
            currentMillis = GetCurrentMillis();
        }
        previousMillis = currentMillis;
        digitalWrite(pin_LED, LOW);
    }
}

unsigned long GetCurrentMillis()
{
    return millis();
}

```

---
Tags: arduino-uno, timers, millis
---


# Question
Title: Arduino IDE gives elf but does not give hex file
Arduino IDE give .elf file but does not generate .hex file.

Show verbose output during: compilation is already selected.

/Users/username/Library/Arduino15/packages/Seeeduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-size -A /var/folders/\_6/5v2q3kbs09b7fhtpnxj\_zgt00000gn/T/arduino\_build\_274647/kuzu.ino.elf

Thanks...

# Answer
As I learnt, It does not generate .hex file for some board. If I change board in Arduino IDE it gives .hex file. It is something about CPU. Thanks for your answers
> 1 votes

# Answer
Arduino IDE can generate .hex file. The menu choice is Sketch:Export compiled binary.

Two files are created: your\_sketch\_name\_.ino.standard.hex your\_sketch\_name\_.ino.with\_bootloader.standard.

The second one contains the basic bootloader as well. Both are stored in the your\_sketch\_name directory that the IDE compiles and saves in to.

Edit: If you are using a non-AVR uC, I don't know if the command works - or exists even.
> 0 votes

# Answer
As I learned, It does not generate a .hex file for some board. If you change board in Arduino IDE it gives .hex file.
> -1 votes

---
Tags: arduino-ide
---


# Question
Title: Sleep mode and watchdog at the same time
Suppose we want to save battery power, and we use sleep mode and also prevent the Arduino from hanging and use the watchdog timer.

The problem is here that when the Arduino goes to sleep the watchdog timer never (or can't be) reset again because of sleep and it will overflow over and over and reset the Arduino over and over.

So what do you suggest to solve this problem, I mean running sleep mode and watchdog timer at the same time in a code?

# Answer
When you sleep the Arduino *is* locked up. So yes, the watchdog timer will time out and reset the Arduino.

But, since you're in sleep mode, it's not so much a "reboot" as a "wakeup".

The watchdog timer is one of the normal ways of waking up periodically to do things. If you want to use the watchdog for its other "anti-lockup" purpose then you will have to arrange some other way of waking up before the watchdog is due to expire so you can "kick" it.

Or you disable the watchdog entirely before going to sleep so that the only wakeup source is whatever source you have configured. Then you can turn the watchdog on again when you wake up.

However that probably means that the watchdog is useless, since chances are you won't be awake for long enough periods for the watchdog to have any effect.

Sleeping and using the internal watchdog as a watchdog are pretty much mutually exclusive. If you sleep, then the watchdog is a periodic wake-up source.
> 2 votes

# Answer
Either set the watchdog to 8s, and setup the WDT interrupt. And deal with the fact that the MCU wakes up every 8s. You could have it go back to sleep, unless a button is pressed, or something. The extra power usage for these short wakeups is negligible in most cases.

Or disable the watchdog right before sleeping, and enable right after waking up. And hope the MCU never hangs in between.
> 1 votes

---
Tags: arduino-uno, arduino-ide, power, electronics
---


# Question
Title: I am facing a problem of firing multiple interrupts on nodemcu 1.0 on single rising edge pulse.what is problem and what are the solutions?
I am working on a project which involves counting the drops falling in a drip chamber of a IV fluid gravity based therapy bottle(saline bottle).I am using IR trans-receiver at the drip chamber to detect a drop falling. I am using a comparator to generate a pulse when ir voltage drops below a certain threshold. The output of comparator is connected to D1 of nodemcu. The ISR is called at rising pulse of comparator .But the nodemcu calls the ISR 3 to 5 times on a single drop.what should I do?plz help.

# Answer
> 1 votes
The signal is probably "bouncing" between HIGH and LOW instead of performing a clean edge, just like it happens with buttons.

Two simple solutions:

1. Hardware solution: use a schmidt-trigger instead of a comparator
2. Software solution: define a dead-time for the signal aquisition (disable the interrupt when the desired edge has been detected and enable it again after "dead-time")

---
Tags: esp8266, nodemcu, ir, ide, op-amp
---


title: Image Processing

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

# Answer
> 0 votes
> However, an Arduino may not have the image processing capability is what I read online.

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

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

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

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

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

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

Probably. That all depends on how the PLC communicates.

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

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

# Answer
> -1 votes
I recommend using a Raspberry Pi or perhaps Arduino Yun for this project. They are both Linux computers and will have much more processing power to do image processing.

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

---
Tags: networking
---


# Question
Title: Interrupts inside a class attaching to the function of the class
Hello i have a class and i would like to attach an interrupt inside the class and attach it to a function of the class.

```
class counter{
  public:

  counter(int pin){
    Ipin=pin;
  }
  void startCounting(){
    attachInterrupt(digitalPinToInterrupt(Ipin),this.addCount,CHANGE);
  }
  void stopCounting(){
    detachInterrupt(digitalPinToInterrupt(Ipin));
  }

  void addCount(){
    count++;
  }

  private:
  int Ipin;
  unsigned long count= 0;
};

```

Some what of the code above. There can be multiple intialization of this class. hopefully depending on the user uses a different pin.

There is a way arround this where the attaching of pin is done in the loop or setup and just calling a public function of the class. But to me that kinda doesn't fit the spirit of classes like a properly made library is done.

Im not very good at programming if you could teach me how it would be greatly appreciated.

# Answer
> 3 votes
I have a post about this problem.

Basically you cannot attach a class function with attachInterrupt because of the hidden "this" pointer which needs to be supplied to a (non-static) class function, where "this" is the particular instance of the class. You can work around it like this:

```
class myClass
  {
  static volatile bool switchChanged;  // declare

  public:

  void begin ()
    {
    pinMode (2, INPUT_PULLUP);
    attachInterrupt (0, switchPressed, CHANGE);
    }  // end of myClass::begin

  static void switchPressed ()
    {
    switchChanged = true;
    }  // end of myClass::switchPressed

  };  // end of class myClass

volatile bool myClass::switchChanged;  // define

myClass foo;  // make an instance of myClass

void setup ()
  {
  foo.begin ();
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

```

But that isn't great because, as you observed, you are really downgrading the class to use a static boolean.

---

Another way of doing it is to write "glue" routines, like this:

```
class myClass
  {
  volatile bool switchChanged;

  static myClass * instances [2];

  static void switchPressedExt0 ()
    {
    if (myClass::instances [0] != NULL)
      myClass::instances [0]->switchPressed ();
    }  // end of myClass::switchPressedExt0

  static void switchPressedExt1 ()
    {
    if (myClass::instances [1] != NULL)
      myClass::instances [1]->switchPressed ();
    }  // end of myClass::switchPressedExt1

  public:

  void begin (const byte whichPin)
    {
    pinMode (whichPin, INPUT_PULLUP);
    switch (whichPin)
      {
      case 2:
        attachInterrupt (0, switchPressedExt0, CHANGE);
        instances [0] = this;
        break;

      case 3:
        attachInterrupt (1, switchPressedExt1, CHANGE);
        instances [1] = this;
        break;

      } // end of switch
    }  // end of myClass::begin

  void switchPressed ()
    {
    switchChanged = true;
    }

  };  // end of class myClass

myClass * myClass::instances [2] = { NULL, NULL };

// instances of our class
myClass foo;
myClass bar;

void setup ()
  {
  foo.begin (2);   // pin D2
  bar.begin (3);   // pin D3
  }  // end of setup

void loop ()
  {
  // whatever
  }  // end of loop

```

That's still not a great solution, but it might give you some ideas.

---

Your fundamental problem is that classes, by their nature, can be instantiated many times, however you only have a small, fixed, number of interrupts on the microprocessor.

---
Tags: programming, c++, interrupt, class
---


# Question
Title: Reading PROGMEM results in an incorrect hex value
I'm sure I'm doing something stupid here, but the code below is supposed to write the test hex values to a I2C EEPROM, however when I attempt to read the EEPROM it has the wrong values. Directly calling something like Wire.write(0xab) will write the 0xab as expected, so I know the EEPROM is being written to properly, just something seems to be getting lost in translation when writing test\[counter++\] .

```
#include <Wire.h>

const byte test[] PROGMEM = {
  0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x7f, 0x80, 0x7f, 0x80, 0x7f, 0x80, 0x80,
  0x7f, 0x7f, 0x81, 0x7f, 0x7e, 0x81, 0x80, 0x7f, 0x7f, 0x7f, 0x80, 0x7e,
  0x7e, 0x81, 0x7e, 0x7c, 0x7f, 0x7f, 0x7d, 0x7c, 0x7f, 0x7f, 0x80, 0x7e
};

unsigned int test_len = 36;

#define EEPROM_ADR 0x50

void setup()
{
  Wire.begin();

  int counter = 0;

  Wire.beginTransmission(EEPROM_ADR);

  Wire.write((int)(0x0 >> 8)); //msb
  Wire.write((int)(0x0 & 0xFF)); //lsb

  while (counter < test_len)
  {
    Wire.write(test[counter++]); //using page buffering to write the entire array
  }

  Wire.endTransmission();
}

```

The results look something like: 0x00 0x00 0x08 0x00 0x00 0x00 0x01 etc..

# Answer
> 2 votes
I needed to either remove PROGMEM from the array or use pgm\_read\_byte to read the array.

---
Tags: avr, progmem
---


title: Part identification

text:
# Question
Title: Part identification
This may be a dumb question but i would like to know what this part is. Anyone who knows?

# Answer
This looks like something out of an Arduino n-part “sensor kit”. It’s hard to tell because the quality of the image is not very good.

My guess is, this is an analog temperature sensor, like in this link, part number 18. You can also find an example sketch there.
> 3 votes

---
Tags: arduino-uno, sensors, power, usb, temperature-sensor
---


title: DHT11 analog or digital?

text:
# Question
Title: DHT11 analog or digital?
I saw some projects with DHT11, some connect it with analog pin, others connect with digital pin.

Is there any difference / advantage connecting to the analog?

# Answer
The DHT11 is a digital component with its own digital communication protocol.

Analog pins can be used for either analog input *or* digital input and output.

You can use a digital device like the DHT11 on *any* pin, whether it is labelled analog or digital (except on a couple of boards which have a few analog-only pins).
> 2 votes

---
Tags: analogread, temperature-sensor, digital, analog, dht22
---