# Question
Title: Boolean function call with character pointer input - dont understand how to get updated pointer value
**Thank you for everyone's help in trying to find a solution. This library I'm working with was prewritten and is one of the most buggy hardware libraries I've had the misfortune to use. I have now solved to problem by reusing the response parsing code from the library and rewriting my own sequence to return the number using a completely different approach. Many Thanks again!**

I am currently attempting to understand how this function works and am struggling. I want to be able to access the 'number' variable in my main function but currently when I do that I get nothing (as in "") when I try to printout the variable with:

```
Serial.println(incomingNumber);

```

I am currently preassigning the number as:

```
char incomingNumber[14];

```

at the top of my project file. With a class initial setup of:

```
DFRobot_SIM808 sim808(&Serial);

```

I'm then later calling the function like this:

```
if(sim808.isCallActive(incomingNumber)){Serial.println(incomingNumber);}

```

This seems like I'm currently making a fundamental error in understanding data types but I'm a bit lost so any help would be really appreciated.

I havent included my entire project here because its currently quite long and spread across both the main and some library files but if anyone needs more info please ask and I'll upload the extras.

The function from the library I'm working with is included below:

```
bool DFRobot_SIM808::isCallActive(char *number)
{
char gprsBuffer[46];  //46 is enough to see +CPAS: and CLCC:
char *p, *s;
int i = 0;

sim808_send_cmd("AT+CPAS\r\n");
/*Result code:
    0: ready
    2: unknown
    3: ringing
    4: call in progress

  AT+CPAS   --> 7 + 2 = 9 chars
            --> 2 char
  +CPAS: 3  --> 8 + 2 = 10 chars
            --> 2 char
  OK        --> 2 + 2 = 4 chars

  AT+CPAS

  +CPAS: 0

  OK
*/

sim808_clean_buffer(gprsBuffer,29);
sim808_read_buffer(gprsBuffer,27);
//HACERR cuando haga lo de esperar a OK no me har閾哸 falta esto
//We are going to flush serial data until OK is recieved
sim808_wait_for_resp("OK\r\n", CMD);
//Serial.print("Buffer isCallActive 1: ");Serial.println(gprsBuffer);
if(NULL != ( s = strstr(gprsBuffer,"+CPAS:"))) {
  s = s + 7;
  if (*s != '0') {
     //There is something "running" (but number 2 that is unknow)
     if (*s != '2') {
       //3 or 4, let's go to check for the number
       sim808_send_cmd("AT+CLCC\r\n");
       /*
       AT+CLCC --> 9

       +CLCC: 1,1,4,0,0,"656783741",161,""

       OK

       Without ringing:
       AT+CLCC
       OK
       */

       sim808_clean_buffer(gprsBuffer,46);
       sim808_read_buffer(gprsBuffer,45);
        //Serial.print("Buffer isCallActive 2: ");Serial.println(gprsBuffer);
       if(NULL != ( s = strstr(gprsBuffer,"+CLCC:"))) {
         //There is at least one CALL ACTIVE, get number
         s = strstr((char *)(s),"\"");
         s = s + 1;  //We are in the first phone number character
         p = strstr((char *)(s),"\""); //p is last character """
         if (NULL != s) {
            i = 0;
            while (s < p) {
                number[i++] = *(s++);
            }
            number[i] = '\0';
         }
         //I need to read more buffer
         //We are going to flush serial data until OK is recieved
         return sim808_wait_for_resp("OK\r\n", CMD);
       }
     }
  }
}
return false;
}

```

# Answer
> -1 votes
You can't use `Serial.println(array);`. In fact, I'm not even sure how the compiler even let you do this...

A better approach would be to use `Serial.write(array, sizeof(array));`

Also, in order to ensure the function is even executing that portion of the code in the first place, you should but some debugging prints in the code. Like this:

```
     if (NULL != s) {
        i = 0;
        while (s < p) {
            number[i++] = *(s++);
            Serial.write(number[i++]); //-------- debug
            Serial.print(' '); //-------- debug
        }
        number[i] = '\0';
        Serial.println(); //-------- debug
     }

```

Also, proper use of whitespace is your friend ;)

---
Tags: data-type, pointer, functions
---


# Question
Title: Why when I pull an EEPROM index the value returned is garbage?
I have an array of colors for my tft screen:

```
const uint16_t colorTheme [] PROGMEM = {BLACK, WHITE, NAVY, CYAN, RED, GREEN, VERDEAQ, PINK, ORANGE, PURPLE, GRAY, YELLOW};

```

When I try to use `colorTheme [EEPROM.read (2500)]` I am returned with a value of any garbage, or a value of 0, and I checked it in read\_eeprom and the value of `EEPROM.read (2500)` is equal to 4, and 4 in mine vector is cyan color, not black or 0 number, why does this go so wrong?

# Answer
Your array is in PROGMEM, but you are accessing it as if it were in RAM.

You must use `pgm_read_word()` to access the data in your array.

```
pgm_read_word(&(colorTheme[EEPROM.read(x)]))

```

BTW - what Arduino board has more than 2kB of EEPROM?
> 1 votes

---
Tags: programming, array
---


title: Arduino Nano (clone) not recognized

text:
# Question
Title: Arduino Nano (clone) not recognized
Asking here cause I ran out of options in searching. My Arduino Nano clone isn't recognized by my computer anymore. It was, until I plugged into a Windows machine, that did not recognize it... and now even my Linux Mint distro doesn't detect the Nano at all. Here's the thing, though: the green power LED still lights up and, if I connect my DC motor to it like I used to before, the LED turns off and the motor is powered only a little bit, with less speed than if it were powered by a 1.5V battery.

My voltimeter reads a 2.18V out of the 5V pin.

Here's all I did: uploaded a sketch to power a 5v motor, it worked, unplugged the Arduino, took it home to my Windows machine on the casing I got it from my school, plugged it there, then it didn't detect anything. Go back to the lab today, plug it in, doesn't detect it there either.

From there, I've replaced USB cables, tried different USB ports, checked with lsusb and dmesg, tried finding it using the FTDI tool (the chip underneath is FTDI), then tried powering it from a phone charger, but the voltage readings at the 5v pin still are around 2.18V with that. Nothing seems to give this little thing an output greater than 2.18V. The only thing I haven't tested is powering it through the VIN pin.

I came across other questions of similar problems but nothing that seems quite like mine... since they all either are able to detect the device but it is displayed as an unknown device or can't recognize the device at all but their power LED does not turn on.

Any ideas on what is going on?

# Answer
> 3 votes
It sounds like a blown protection diode MBR0520 in between USB and +5V of the nano.

# Answer
> 1 votes
Apart from 5V pin, the rest sounds like your FTDI clone chip might be bricked. Check your device VID (under Device Manager -\> Device Properties -\> Details tab -\> under Property select Hardware Ids). If VID and/or PID is 0000 than it is.

It is possible restore the original VID/PID (thus recover the Arduino). Google for "Fix bricked FTDI", there are many instructions like this: http://internetofhomethings.com/homethings/?p=987

Most of these cheap Arduino Nano clones have also fake FTDI IC and at some point FTDI (the vendor) released new driver which bricks such clones by setting VID/PID of the chip to 0. This effectively makes the IC undetectable / incompatible with original FTDI drivers. That is why it is not recognized on a PC where it was working earlier.

http://hackaday.com/2016/02/01/ftdi-drivers-break-fake-chips-again/

After recovery, make sure to use older FTDI driver.

# Answer
> 0 votes
What was your schema? did you try to control 5V motor from arduino directly.
Now assuming that

```
$ lsusb

```

doesn't show something like:

```
Bus 002 Device 005: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

```

It is generaly a bad idea to control any mechanical (magnetic) device without using transistor and maybe a diode to protect against current in an opposite direction
standard DC motors can generate quite a nice voltage if turned mechanically (during transport) or even current increase if motor is blocked when powered.
TO me it sounds like you have burned your chip. USB on most computers has got an over-current protection resulting in lover voltage if something you connect has very low resistance. 2.8volt is more then enough to lit-up green LED on a damage MCU, but probably not to power the FTDI chip wired for 5V

# Answer
> -1 votes
Standards compliant USB ports will only supply 100mA unless a higher current is negotiated by USB.

I suspect that you problem is the USB serial (Chinese Nano clones often have cheap chips). This happened to one of my Nano clones.

# Answer
> -1 votes
It may be caused by the cable. In my case it was. Not all cables have data wires.

---
Tags: arduino-nano, usb, uploading, ftdi, port-mapping
---


# Question
Title: HTTP POST from Arduino/ESP8266/ESP32 How to send parameters (x-www-form-urlencoded)
---

EDIT: Thank you for the answer, also we had figured out how to do it **Micropython** too - I believe that it is relevant for the Arduino/ESP8266/ESP32 community to share this too.

## https://github.com/46elks/46elks-getting-started/blob/master/code-examples/MicroPython/https\_post\_with\_micropython.py

How should I include parameters from, to and message to http.post?

Is this the correct way to do it? http.POST("'from:+XXXXX','to:+XXXXX','message:Hej'");

```
#include <M5StickC.h>
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>

#include <HTTPClient.h>

#define USE_SERIAL Serial

WiFiMulti wifiMulti;

void setup() {

    USE_SERIAL.begin(115200);

    USE_SERIAL.println();
    USE_SERIAL.println();
    USE_SERIAL.println();

    for(uint8_t t = 4; t > 0; t--) {
        USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
        USE_SERIAL.flush();
        delay(1000);
    }

    wifiMulti.addAP("YYYY", "ZZZZZ");

}

void loop() {
    // wait for WiFi connection
    if((wifiMulti.run() == WL_CONNECTED)) {

        HTTPClient http;

        USE_SERIAL.print("[HTTP] begin...\n");
        // configure traged server and url

          http.begin("https://api.46elks.com/a1/sms");
          http.addHeader("Content-Type", "application/x-www-form-urlencoded");
          http.setAuthorization("XXXXX", "YYYYYY");
          int httpCode = http.POST("'from:+XXXXX','to:+XXXXX','message:Hej'");

        USE_SERIAL.print("[HTTP] GET...\n");
        // start connection and send HTTP header
         httpCode = http.GET();

        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                String payload = http.getString();
                USE_SERIAL.println(payload);
            }
        } else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
        }

        http.end();
    }

    delay(10000);
}

```

# Answer
What format of message does the server expect?
As you send "x-www-form-urlencoded" it should probably look like:

```
 "from=+XXXXX&to=+XXXXX&message=Hej"

```

where the different parts are

```
 "param1=paramValue1&param2=paramValue2&param3=paramValue3"

 param .... Name of the expected parameter
 = .... divides the param pair
 paramValue .... Content/value of the parameter
 & .... links the param pairs

```

so in your case

```
 int httpCode = http.POST("from=+XXXXX&to=+XXXXX&message=Hej");

```
> 2 votes

---
Tags: arduino-ide, esp32, http
---


# Question
Title: Activating a defined macro in a class from main.cpp
Sorry if this question been asked. I'm trying to activate certain function in a class using a macro defined in the class from main.cpp. I'm using jrowberg MPU6050 library if that matters.

main.cpp

```
#include "gyro.h"
gyro gyro(Serial);
#define OUTPUT_READABLE_EULER

void setup(){
...
}
void loop(){
...
}

```

gyro.cpp

```
  #include "gyro.h"
  #ifdef OUTPUT_READABLE_EULER
      // display Euler angles in degrees
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetEuler(euler, &q);
      serial_.print("euler\t");
      serial_.print(euler[0] * 180/M_PI);
      serial_.print("\t");
      serial_.print(euler[1] * 180/M_PI);
      serial_.print("\t");
      serial_.println(euler[2] * 180/M_PI);
  #endif

```

If I define `OUTPUT_READABLE_EULER` in `gyro.h`, it works. But I want to do it from main.cpp.

# Answer
> 1 votes
You cannot not, but also you should not try to define a macro in a cpp file and use it in another cpp file.

Instead, you have to define it in a h (header) file, which is included in both cpp files.

Why would you define it in `main.cpp` or `main.h` anyway if you don't use it in those files?

You have mainly three options:

* Define it in `gyro.h` so you include it in `gyro.cpp` where you use it. You can later use it in other files as well.
* Define it in `gyro.cpp` so you can use it only in that file. This prevents the macro being used in other files (which can be safer).
* Define it in a separate file, e.g. `euler.h` and include this header file everywhere you need it.

See also Juraj's comments below.

---
Tags: c++, atmega2560
---


# Question
Title: HC-SR04 ultrasonic sensor: How to check voltage on the ECHO pin
I'm using and ESP8266 with HC-SR04 ultrasonic sensor. The sensor requires 5v input and will also output to the GPIO pins at 5V.

ESP8266 has a strong recommendation to use 3.3V into the GPIO pins. I've found some setups online with people using voltage dividers to bring the ECHO pin voltage down.

Example on a PI: https://tutorials-raspberrypi.com/raspberry-pi-ultrasonic-sensor-hc-sr04/

I'm using a basic multimeter that i've found to be pretty accurate. When I put the BLACK cord on the ECHO and RED on the GROUND (of sensor pins), I get variable voltage readings. I'm trying to ensure a 3.3V coming from the ECHO into my ESP. Questions:

1. Am I putting the black and red cords on the appropriate areas?
2. If yes to question 1, then why am i get such a variable of readings?
3. How can I test to ensure only 3.3V coming out of ECHO?

# Answer
> 0 votes
As Majenko already wrote, the black cord goes always to ground, so you have the leads backwards (though this just means, that your multimeter will report a negative voltage, if it is able to do so).

But besides that you cannot easily measure the echo pulse with a multimeter. A multimeter is build to measure either a DC voltage or a constant AC voltage. It is not build to measure the peak signal of a pulsed line. Some good multimeters may be able to do that, but it most of them (an definitely the basic ones) cannot do this. They are measuring the voltage over a relatively long period of time (longer than an echo pulse) with multiple measurements (to average out the noise). Also you cannot control, when exactly each measurement is taking place. So depending on the exact timing, the multimeter might have multiple pulses in the measurement (reading 5V there) or even missing pulses completely. That's the meaning of the Nyquist frequency, which states, that the measurement frequency must be higher than double of the signal frequency, or you will not be able to measure the signal correctly.

The echo pulse - if you receive one - will be rather short. With the maximum distance of most ultrasonic sensor boards of 3m, you will get a maximum pulse length of

```
3m / (300 m/s) = 0,01s = 10ms

```

You won't be able to correctly read that pulse with a multimeter. You would need an oscilloscope for that.

**What to do now?** If you want to make sure, that the used voltage divider divides 5V input to 3.3V output, you can connect the input to the 5V pin (but disconnect the echo pin first). Then measure the voltage at the output (which is now HIGH all the time, not just for the time of a pulse). If it's 3.3V, you can be sure, that the divider works correctly. As the ultrasonic sensor is provided with 5V, it won't output more than that. So you can be sure, that the ESP will only see 3.3V.

# Answer
> 1 votes
You have your leads backwards. But that doesn't matter, since there's nothing to measure. You'll only see a voltage (and even then only a brief pulse) when an echo is actually received.

You would need an oscilloscope to be able to read that voltage.

---
Tags: esp8266, voltage-level, hc-sr04
---


# Question
Title: Unable to understand the acquisition of data from Magnetometer HMC5883L and Accelerometer ADXL345
Below are the X,Y,Z registers for HMC5883L.

while this is the Arduino code for HMC5883L to acquire X,Y,Z reading. If you look at this code, we do not mention the X, Y, Z address specifically.

```
  Wire.beginTransmission(0x1E);
  Wire.write(0x02);
  Wire.write(0b00000001);
  Wire.endTransmission();
  delay(10);

  Wire.requestFrom(0x1E,6);
  if (Wire.available() > 5)
  {
    x = readValue();
    y = readValue();
    z = readValue();
  }
  else
  {
    Serial.println("No data found");
  }
int readValue()
{
  int val = Wire.read()<<8;
      val |= Wire.read();

  return val;
}

```

We only write `Wire.request()` and do not mention X,Y,Z addresses specifically for HMC5883L. While in the case of ADXL345 we mention every register of X,Y,Z separately to acquire data. Which is exactly my question like why not simply use `Wire.requestFrom()` for ADXL345 too. When will we access each X,Y,Z register separately? and when will we do not?

Below is Arduino ADXL345 code for reading X axis data.

```
  Wire.beginTransmission(0x53);
  //Ask the particular registers for data
  Wire.write(0x32);
  Wire.write(0x33);
  Wire.endTransmission();
  Wire.requestFrom(0x53,2);
  if(Wire.available()<=2) {
    X0 = Wire.read();
    X1 = Wire.read();
    X1=X1<<8;
    X_out =X0+X1;
    Xa=X_out/256.0;
  }

```

Datasheets for both sensors are available on the link.

The code above is not mine. https://drive.google.com/open?id=1AswNTdBz55Rfg3nu4-YsLFj4ANrsCL5I

# Answer
> 1 votes
If you read the datasheet for the mentioned magnetometer, it is clearly mentioned that the data is to be read at once. Below is the implementation of pseudo code mentioned in the datasheet.

```
void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  //send 0x3C 0x00 0x70 (8-average, 15 Hz default, normal measurement)
  Wire.begin();
  Wire.beginTransmission(0x1E);
  Wire.write(0x00);
  Wire.write(0x70);
  Wire.endTransmission();
  delay(10);
  //send 0x3C 0x01 0xA0 (Gain=5, or any other desired gain)
  Wire.beginTransmission(0x1E);
  Wire.write(0x01);
  Wire.write(0xA0);
  Wire.endTransmission();
  delay(10);
  //send 0x3C 0x02 0x00 (Continuous-measurement mode)
  Wire.beginTransmission(0x1E);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(10);

}
void loop()
{

  Wire.requestFrom(0x1E,6);
  if (Wire.available() > 5)
  {
    x = readValue();
    y = readValue();
    z = readValue();
  }
  else
  {
    Serial.println("No data found");
  }
  data = String(x) + "   ,   " + String(y) + "   ,   " + String(z);
  //Send 0x3C 0x03 (point to first data register 03)
  Serial.println(data);
  Wire.beginTransmission(0x1E);
  Wire.write(0x03);
  Wire.endTransmission();
  delay(100);
}

```

Similarly, it is mentioned in the datasheet for ADXL345 as well that the data should be read separately from each axis register separately.

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


# Question
Title: Arduino Mega keep states after reprogramming
Based on:

https://forum.arduino.cc/index.php?topic=440978.0

And some previous experience with Arduinos. What I would like to accomplish here is that I have a 8 channel relay board with the relays in different states. The Arduino is connected to a RaspberryPI via USB.

The first problem is well known the automatic reset of the Arduino which can be taken care of with a resistor or desoldering a pin on the Mega board so you can reconnect your Arduino as many time as you wish (while running on an external +5V power source) to the Raspberry and it will never reset.

However I also remember that doing this to the boards will also make them impossible to program because they cannot reset at the end when the sketch is uploaded.

I have think of a workaround:

1, Create a programming command on the arduino which is when it's received from the RPI it will connect that cut off pin with a relay which will make resetting possible again

2, Save all relay states to the EEPROM

3, After reset the Arduino always checks this programming flag in it's EEPROM and if it's present it either does not touch the relays or set them to the same position ON/OFF depending on the value it read back from the EEPROM

The last guy claims that: When the Arduino is in reset, all pins act like they aren't connected to anything. If you have an output which must be in a specific state during that period, you must add an external resistor to pull it up or down as required.

Is there any other solution for this problem? Like using a newer Arduino board which can keep pin states over reprogramming?

# Answer
> 1 votes
I had to solve a problem similar to this for an ESP32 based system. The solution I came up with was to use external D-type latches (flipflops) to store the state independently of the Arduino.

The Arduino has to actively load a new relay state into a latch in order for the relay to change state, and that state is retained regardless of what the Arduino does.

The outputs of the latches can also be connected to other input pins so the Arduino can find the current state of the relays at boot time.

simulate this circuit – Schematic created using CircuitLab

The Arduino keeps track of what the outputs should be (reading the current state at boot) and then changes a state when needed. It then loads *all* the states onto the output pins and pulses the LOAD pin (CLK on the chip) high to load those states into the latches.

I used the 74HC374 chip for this since it contains 8 latches tied to a single CLK pin.

# Answer
> 1 votes
You have basically 2 distinct problems here. The problem to somewhat automatically enable/disable the reset from USB and the problem to keep the relays at their set states over reprogramming.

* **Enable/disable reset:** The easiest way is to use a jumper, that you disconnect everytime you want to program the board. If you want to do it remotely, you already described a valid way, though I think, that you don't need a relay for that. A transistor or MOSFET should be sufficient for it.
* **Keep the relay states:**

> Like using a newer Arduino board which can keep pin states over reprogramming?

I don't think, that something like that exists. It does not make sense for general purpose microcontrollers to do that; they all start from a clean state. So you need to save the state of the relays outside of the Arduino. What type of device you want to use for that is up to you. Majenko mentioned flipflops, which gives you the most basic functionality for this. You could also use devices, which are interfaces serially, like shift registers or even port expanders. Using flipflops will be the easiest way, since the programming does not change much. There are many examples how to use each of these devices with an Arduino on the web.

# Answer
> 0 votes
I use for this purpose (model railroading switching turnouts/signals with relays and coils) a simple and pin saving solution.
An I2C bus shield/module with 16 I/O ports (and its daisy chainable - up to 64 modules theoretically, 16 practically due to address encoding pins)
The 16-channel PCA9685/PCF8574 I/O extender module cost around 4-5 euro and requires beside GND/VCC only two data pins (SDA & SCL) to control the module. The I2C header has extra 10K pullup resistors and onboard of the module is a 25 MHz typical internal oscillator.
So after reseting, I first read the EEPROM/SPIFFS/SD-values and based on that stored set I work on. The Module(s) has(ve) a seperate power source which is not affected by the reset of the Arduino controlling them. The operating range of 2.3V to 5.5V allows the module to be powered from a range of power supplies and also used with 3.3V devices.
The green terminal block in the picture is for use with servos - the extra power supply attaches to the I2C header (but common ground with Arduino).
Of course you have to use a lib (or like me write the functions you need) but once your into it its easy to use and also usable for other scenarios (LEDs, PWM generator, servos).

> The PCA9685 is a 'free running' PWM controller. Tell it what to do, and it will keep doing that until you tell it to do something else. If you wanted to set the relays to a specific state and keep them there, you could disconnect the Arduino until you wanted the relays to do something else.

---
Tags: arduino-mega, eeprom, reset
---


# Question
Title: restart counter of elapsed millis willingly with read
When I trigger high it will count for as long as I ask it while I am high then shut off. I am able to start counting again whenever I want by triggering low and going back to high and it starts from the beginning as long as the time in low is not within the time I asked it to be high. The problem is I go low mid count then quickly back to high the count picks up where millis left off without starting from the beginning. Is there a way to make this better.

```
unsigned long induceTime = 0;
unsigned long elapseTime;
long setTime = 10000;
int openClose;
int openClosePin = 2;
int writeToPin = 3;
void setup() {
Serial.begin(9600);
}

void loop() {
  int openClose = digitalRead(openClosePin);
  elapseTime = millis();
  if (openClose == HIGH && elapseTime < induceTime + setTime){
    digitalWrite(writeToPin, HIGH);
    Serial.println(' ');
    Serial.println(elapseTime);
    Serial.println(' ');
    Serial.println(induceTime);
    Serial.println(' ');
}
  if (openClose == LOW && elapseTime > induceTime + setTime){
    induceTime = elapseTime;
    Serial.println(elapseTime);
    Serial.println(induceTime);
}

delay(500);
}

```

# Answer
Thanks for the help, this code is closer to what I was looking for. This is for a water level pump, when the trigger is high it turns on, when the water rises the trigger goes low and stays on during the timer as a failsafe and then turns off with when the elapsed time is greater than the set time and also not in my code it turns off with a additional trigger. Here is my working code.

```

unsigned long induceTime = 0;
unsigned long elapseTime;
long setTime = 10000;
int openClose;
int openClosePin = 2;
int writeToPin = 3;
void setup() {
Serial.begin(9600);
}

void loop() {
  int openClose = digitalRead(openClosePin);
  elapseTime = millis();
  if (openClose == HIGH){                //reset count
    induceTime = millis();
    digitalWrite(writeToPin, HIGH);
    Serial.println(induceTime);
}
  if (openClose == LOW){
    elapseTime = millis() - induceTime;  //induceTime is set when leave high
    if (elapseTime < setTime){
      digitalWrite(writeToPin, HIGH);
      Serial.println(elapseTime);
      Serial.println("within setTime high");
}
    if (elapseTime > setTime){
      digitalWrite(writeToPin, LOW);
      Serial.println(elapseTime);
      Serial.println("within setTime for low");
}
    Serial.println(' ');
    Serial.println(elapseTime);
    Serial.println(' ');
    Serial.println(induceTime);
    Serial.println(' ');
}
delay(1000);                              //so that I can see serial monitor
}

```
> 1 votes

# Answer
First make your code rollover safe and second add an other condition:
So as I understood LOW/HIGH changes should start a timer from zero irrelevant if a running timer is over or not - so timer is still running HIGH/LOW -\> and LOW/HIGH should restart

```
// repalce / paste before setup
unsigned long startTime = 0;
bool timerIsOn = false;
//unsigned long elapseTime;

 // replace your loopwith this
void loop() {
  int openClose = digitalRead(openClosePin);
//  elapseTime = millis();
  if (openClose == HIGH && timerIsOn = false){
       timerIsOn = true;
       startTime = millis();
       digitalWrite(writeToPin, HIGH);
       Serial.print(' ');
       Serial.print(millis());
       Serial.print(' ');
       Serial.print(startTime);
        Serial.println(' ');
   }
   // This condition is for time is up
  if (timerIsOn = true && millis() - startTime > setTime){
     digitalWrite(writeToPin, LOW);
     timerIsOn = false;
     Serial.print(setTime);
     Serial.print(' ');
     Serial.println(millis()-startTime);
  }
   // This condition is for going low before time is up
  if (openClose == LOW && timerIsOn = true){
    digitalWrite(writeToPin, LOW);
    timerIsOn = false;
    Serial.print('timerIsOn = ');
    Serial.println(timerIsOn);
    Serial.print(' ');
    Serial.println(millis()-startTime);
  }
 // If you go LOW after time is up it does nothing waits for the next HIGH
}

```
> 0 votes

# Answer
For starters, millis should be used relatively to avoid rollover. Simple fix is to subtract the induceTime over to the same side of the comparison. Example: elapseTime - induceTime \> setTime

This also brings up the issue that your 'counter' is always elapseTime aka millis instead of (elapseTime - induceTime) so it never truly stops counting.

You are also never calling digitalWrite(writeToPin, LOW); So it goes high and stays high. I suspect you meant to set it to low in an else statement somewhere.

Now for the issue regarding quickly changing signals:

Beyond that you could use an interrupt and timer so that your sample rate (determined by the delay(500)) doesn't come into play. This will give the best possible timing at the cost of restricting which pins you can use for openClosePin and you should also check that you sufficiently debounce the signal (in hardware).

Alternatively you can reduce the 500 to an acceptable #. But you would then want to have another counter to prevent spamming your serial output.

Below example only implements ISR and reduction of 500. Does not implement timer (which would be required for precise use of setTime to shut the writeToPin off to LOW).

```
volatile unsigned long induceTime = 0;
volatile unsigned long elapsedTime;
unsigned long setTime = 10000;
//volatile int openClose; //may want to toggle this in isr...
int openClosePin = 2;
int writeToPin = 3;

void pinChangedISR(){
  if(digitalRead(openClosePin)){ //rising
    digitalWrite(writeToPin, HIGH);
    induceTime = millis();
  }
  else{//falling
    digitalWrite(writeToPin, LOW);
    elapsedTime = millis() - induceTime;
  }
}

void setup() {
  pinMode(writeToPin, OUTPUT);
  pinMode(openClosePin, INPUT); //may want INPUT_PULLUP depending on hardware
  attachInterrupt(digitalPinToInterrupt(openClosePin), pinChangedISR, CHANGE);
  Serial.begin(9600);
}

void loop() {
  static int frameCount = 0;
  unsigned long delayTime = 100;
  openClose = digitalRead(openClosePin);
  if (openClose == HIGH){
    elapsedTime = millis() - induceTime;
    if(elapsedTime >= setTime) digitalWrite(writeToPin, LOW);
    else if(setTime - elapsedTime < 100) delayTime = setTime - elapsedTime;
  }
  if(framecount >= 5){ //time to print...
    framecount = 0;
    if(digitalRead(writeToPin) == HIGH){
      Serial.println(' ');
      Serial.println(elapsedTime);
      Serial.println(' ');
      Serial.println(induceTime);
      Serial.println(' ');
    }
    else{ //this part's a bit different
      Serial.println(elapsedTime); //reporting duration of last pulse when pulse inactive
      Serial.println(millis()); //reporting current time for inducetime comparison
    }
  } else ++framecount;
  delay(delayTime);
}

```
> 0 votes

---
Tags: millis
---


# Question
Title: If Arduino connected to computer and opened up Serial Monitor, will Tx and Rx pin still be working?
Suppose one connected two of the Arduino Uno boards through Rx and Tx pins. Then, if one or both of the Arduino boards were connected to computer, and possibly opened up Serial Monitors, will Tx and Rx pin still be working? i.e. will Arduino still communicate through Rx and Tx pin when it's communicating to computer? If not how to make them working while connect to computer?

# Answer
> 3 votes
> Suppose one connected two of the Arduino Uno boards through Rx and Tx pins.

I assume you will connect the TX of one Arduino to the RX of the other one and vice versa, which is the right way to connect them. As theSealion explained in his answer, you shouldn't connect two TX Pins together.

> if one or both of the Arduino boards were connected to computer, and possibly opened up Serial Monitors

If you do that, the Arduino won't even notice.

Well, to be more accurate... there is a small chip on the Uno, near the USB connector, labeled “MEGA16U2”. This chip is used as a USB/serial converter, and it *will* notice when you connect the USB link and when you open the port. However, the main chip (the big PDIP28), which is the microcontroller that runs your sketch, will neither know nor care.

> will Tx and Rx pin still be working?

Absolutely.

> will Arduino still communicate through Rx and Tx pin when it's communicating to computer?

The RX will not communicate with the computer. What will happen is:

* Whatever your Arduino writes to its serial port will be received by both the other Arduino and the serial monitor.
* Whatever you send through the serial monitor will be lost.
* When you `Serial.read()`, you will get whatever was set by the other Arduino.

The reason of this behavior is a 1 kΩ resistor that sits between the Mega16U2's TX and the main microcontroller's RX. When you connect this RX to the other Arduino's TX, which is low impedance (≈ 25 Ω), that TX will “win”: a low impedance output overwhelms a high impedance one.

# Answer
> 2 votes
> how to make \[two Arduinos communicating with each other\] working while connect to computer?

There are a variety of ways for 2 Arduinos to directly communicate with each other while one or both are communicating with the Serial Monitor of a laptop computer over USB.

* Use a UART for the Arduinos to communicate that is independent of the USB connection. (See https://www.arduino.cc/reference/en/language/functions/communication/serial/ )

+ Several Arduino-compatible boards such as the Arduino Mega 2560, Arduino Due, Arduino Uno Wifi Rev.2, etc. have 4 hardware UARTs; the pins of Serial1 (note the "1") could be used to communicate with another Arduino without interfering with the Serial (without a "1") UART communication over USB to a laptop. (Alas, the Arduino Uno has only 1 hardware UART).
    + The ATmega32u4-based Arduino Micro and Arduino Leonardo and ATmega32u4-based Arduino derivatives such as FLORA and many of the ARM-based Arduino derivatives such as the Teensy series have a USB interface that doesn't use *any* of the UART pins; so the pins of Serial1 (note the "1") could be used to communicate with another Arduino without interfering with the Serial (without a "1") non-UART communication over USB to a laptop. (Alas, the Arduino Uno has a USB interface that *does* use its only hardware UART pins).
    + Even the Arduino Uno, which has only 1 hardware UART whose pins are hard-wired to the USB interface chip, can bit-bang a slow simulation of a UART on other pins. See What's the difference between all the Software Serial Libraries? Which one is Arduino Nano compatible? .
* Rather than try to simulate a UART in software (the timing is kind of tricky), it may be easier/faster to use some other less time-sensitive ways of communicating between Arduino Unos or other Arduinos, such as

# Answer
> 1 votes
I got exactly the same problem! I was using the Arduino Uno board with an Jtag ICE mkii for debugging which was working nice. As I begann to use the UART it was a heavy mess. The transmitting from Arduino to an external TTL-USB adapter was working but not in the other direction. I played hours before I saw this thread and that gave me the idea for looking into the shematic -\> Bang! I saw the two resistors. Lesson learned: Do not use the Arduino hardware without the rest of the tools! Thought it was a good idea to use the hardware for rapid development. Now it costs me more time that I thought...

# Answer
> 0 votes
You should't connect two TX Pins together. The Arduino has some protection resistors but even it is not recommended to connect two output pins.

The only save way to use the RX / TX pins directly is to remove the protection resistors (RN4A and RN4B in the reference design) or at least the RN4A and use only one connection at a time. It doesn't help if you do not use the PC connection or doesn't open the Serial Monitor since the pins is still an output.

(Multiple RX Pins are no problem since they are inputs)

(And of course I know it could work with multiple TX pins together most of the time, but I would recommend it)

---
Tags: serial, uart
---


title: F() messes with program

text:
# Question
Title: F() messes with program
I'm working on command-handler library and I have a big problem with `F()` function. Example sketch for library uses quite a lot of RAM, because it has to print a lot of text over UART. As before, I've used `F()` to lower RAM usage. It worked on first!

Lib works with help of `strtok` function. Command fomar is:

> cmd1,..,paramN;..;cmdN,..,paramN

Commands are separated with `;` while command parameters(params) are separated with `,` Library works without any problems, it returns memory address(`char*`) of any command and every param.

When I try to compare parameter/command with `strcmp` it works only if all commands are in uppercase. Let's take `LED` command for example: It works only with `Led`, `LED` or any case where is letter d in uppercase. `led` won't work, and it will say that command `le` doesn't exist. Yes, `le`, it won't print `led`. But, after `DURATION` command, it somehow start working.

Memory for serial buffer is dynamicly allocaed in object constructor, in global scope. Why? All those problems are because `F()`. Can someone explain why? Here's the code and screenshot of serial monitor.

```
void execCmd(const char *set)
{
char *cmdParam = CMDHandler.find(set, CMD_PARAM);

if (!strcmp(cmdParam, "LED"))
{
    // ONE WAY TO CHECK IF COMMAND HAS PARAM(S) - BEFORE GETTING PARAM(S) == BETTER WAY
    if (!CMDHandler.count(CMDHandler.getNext(CMD_PARAM), CMD_PARAM))
    {
        Serial.print(F("->> Command LED: Current LED status is "));
        Serial.println(digitalRead(LED_PIN));
        return;
    }

    cmdParam = CMDHandler.find(nullptr, CMD_PARAM);
    LEDStatus = 0;
    uint8_t status = atoi(cmdParam);

    digitalWrite(LED_PIN, status);
    Serial.print(F("->> Command led: LED Status is "));
    Serial.println(status, DEC);
}
else if (!strcmp(cmdParam, "LOOP"))
{
    cmdParam = CMDHandler.find(nullptr, CMD_PARAM);

    // SECOND WAY TO CHECK IF COMMAND HAS PARAM(S) - AFTER GETTING EVERY PARAM
    if (cmdParam == nullptr)
    {
        Serial.println(F("->> Command LOOP: Expected one parameter!"));
        return;
    }

    uint8_t status = atoi(cmdParam);
    if (status)
    {
        LEDStatus = 2;
        digitalWrite(LED_PIN, HIGH);
        Serial.println(F("->> Command LOOP: LED Blink Loop is on!"));
        delay(blinkDuration);
    }
    else
    {
        LEDStatus = 0;
        digitalWrite(LED_PIN, LOW);
        Serial.println(F("->> Command LOOP: LED Blink Loop is off!"));
    }
}
else if (!strcmp(cmdParam, "DURATION"))
{
    if (!CMDHandler.count(CMDHandler.getNext(CMD_PARAM), CMD_PARAM))
    {
        Serial.print(F("->> Command DURATION: Current blink duration is "));
        Serial.print(blinkDuration, DEC);
        Serial.println("ms");
        return;
    }

    cmdParam = CMDHandler.find(nullptr, CMD_PARAM);
    blinkDuration = atoi(cmdParam);

    Serial.print(F("->> Command DURATION: New blink duration is "));
    Serial.print(blinkDuration, DEC);
    Serial.println("ms!");
}
else if (!strcmp(cmdParam, "HELP"))
{
    Serial.println(F("------ HELP ------\n-> LED [0/1] - Turns off/on LED on pin 13\n-> LOOP [0/1] - Stops/starts blink loop with LED on pin 13\n-> DURATION [X] - Changes duration of LED loop blink. Recommended values is 50-500ms\n"));
}
else
{
    Serial.print(F("->> Command "));
    Serial.print(cmdParam);
    Serial.println(F(" does not exist!"));
}

```

}

```
char *CMDHand::find(const char *input, uint8_t const type)
{
    char *found = nullptr;
    char separator = delimiter[type];

    if (input != nullptr) // FIRST CALL
    {
        constrain[type] = input + strlen(input) - 1;
        next[type] = input;
    }
    else if (next[type] > constrain[type]) return (nullptr);

    found = strtok(next[type], &separator); // FOR SOME REASON IT DOES NOT WORK IF I PUT &delimiter[type] INSTEAD OF &separator
    last[type] = next[type];
    next[type] += strlen(found) + 1;

    return (found);
}

```

# Answer
> 5 votes
To compare with `F()` macro encased strings you have to use special forms of the string functions that are suffixed with `_P`. You also need to cast the string literals to the right type (`PGM_P`).

To do a case-insensitive comparison you should use `strcasecmp` instead of `strcmp`.

To put those together you end up with:

```
if (strcasecmp_P(cmdParam, (PGM_P)F("help")) == 0) {
    ...
}

```

---

There is a problem here:

```
found = strtok(next[type], &separator)

```

`strtok` takes a C string as a list of separators (must be NULL terminated). You're passing it the address of a single character. There may or may not (probably not) be a NULL in the next byte in memory, but everything else up to the first NULL found in memory will be taken as delimiter characters.

---
Tags: serial
---


title: EspMQTTClient inside a class

text:
# Question
Title: EspMQTTClient inside a class
I'm trying to use `EspMQTTClient` inside a class, called `myIOT32`.

An error, which I don't find the reason for is generated.

```
/home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp: In lambda function:
/home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:25:5: error: 'this' was not captured for this lambda function
     client.publish("mytopic/test", "This is a message sent 5 seconds later");
     ^
/home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:25:5: error: invalid use of non-static data member 'myIOT32::client'
In file included from /home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.cpp:1:0:
/home/guy/Documents/git/Arduino/libraries/myIOTesp32/myIOTesp32.h:20:19: note: declared here
     EspMQTTClient client;
                   ^
Multiple libraries were found for "WiFi.h"
 Used: /home/guy/.arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/WiFi
 Not used: /home/guy/arduino-1.8.12/libraries/WiFi
exit status 1
Error compiling for board LOLIN D32.

```

`.h` file:

```
#ifndef myIOT32_h
#define myIOT32_h

// OTA libraries
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#include "secrets.h"
#include "EspMQTTClient.h"
#include "Arduino.h"

class myIOT32
{
private:
    void onConnectionEstablished();  // <--- this is a must have function ( was taken as is from lib's built-in example

public:
    EspMQTTClient client;
    myIOT32(char *ssid, char *wifi_p, char *mqtt_broker, char *mqttU, char *mqttP, char *devTopic, int port = 1883);
};

#endif

```

`.cpp` file:

```
#include "myIOTesp32.h"

myIOT32::myIOT32(char *ssid, char *wifi_p, char *mqtt_broker, char *mqttU, char *mqttP, char *devTopic, int port)
    : client(ssid, wifi_p, mqtt_broker, mqttU, mqttP, devTopic, port)
{
}

void myIOT32::onConnectionEstablished()
{
  // Subscribe to "mytopic/test" and display received message to Serial
  client.subscribe("mytopic/test", [](const String & payload) {
    Serial.println(payload);
  });

  // Subscribe to "mytopic/wildcardtest/#" and display received message to Serial
  client.subscribe("mytopic/wildcardtest/#", [](const String & topic, const String & payload) {
    Serial.println(topic + ": " + payload);
  });

  // Publish a message to "mytopic/test"
  client.publish("mytopic/test", "This is a message"); // You can activate the retain flag by setting the third parameter to true

  // Execute delayed instructions
  client.executeDelayed(5 * 1000, []() {
    client.publish("mytopic/test", "This is a message sent 5 seconds later");
  });
}

```

Appreciate any help in constructing such a class

# Answer
> 1 votes
For the fix, just add the reference capture and it should compile fine:

```
   // Execute delayed instructions
  client.executeDelayed(5 * 1000, [&]() {   // [&] instead []
    client.publish("mytopic/test", "This is a message sent 5 seconds later");
  });

```

I could not test, but you will have to apply to other functions as well.

```
[] Capture nothing
[&] Capture any referenced variable by reference
[=] Capture any referenced variable by making a copy

```

---
Tags: class
---


title: RTC interrupts and coin batteries

text:
# Question
Title: RTC interrupts and coin batteries
# Summary

I'm having problems with my RTC draining its coin cells quickly - fresh batteries are drained in a few months. The RTC is set to signal an interrupt every 5 minutes, and I wonder - if there is no other power attached to the circuit, is that enough to drain the coin cell?

# Details and my troubleshooting:

Problems with my RTC - if I leave the circuit unpowered for a few days (so that the only power to the RTC is from the coin cell backup), the time resets to 00:00 January 1, 2000. This doesn't happen immediately when I unplug it. If I disconnect it from the computer, plug it back in the next day, the time is ok. If I leave it unplugged for a few days, then plug it in, the date is reset.

This suggests the battery is bad. So I tested it with my meter (and an 100 ohm load, as described here: https://www.youtube.com/watch?v=HcikzMG7mMU). And sure enough, the batter has dropped quite a bit from its 3V start value.

That's all good, except that this battery is only a few months old, and it should last for years in an RTC. I've got two batteries purchased in the last year and used in RTC modules, and both are now drained.

My current hypothesis is that, after I unplug my circuit from the computer, the RTC continues to run on the coin cell, firing interrupts every 5 minutes, and it is these interrupts that are causing the drain. Does this make sense? If not, what else could I check?

# Setup

Breadboard arduino, DS3231 RTC on a breakout, connected

* RTC SDA -\> Arduino A4
* RTC SCL -\> Arduino A5
* RTC GND -\> Common GND
* RTC VCC -\> Common 5V (from ftdi/USB cable, when plugged in)
* RTC SQW -\> Arduino D2

The RTC is 'active-low', and the SQW pin is held at 5V between interrupts. With my multimeter, the brief drop to 'LOW' is undetectable. I also can't detect any current flow from the SQW pin with my multimeter.

# Sketch

Including only the code related to the RTC (SD card and temperature bits removed).

```
/*-(Import required libraries)-*/
#include <Time.h>
#include <DS3232RTC.h> //source: https://github.com/JChristensen/DS3232RTC

/*-( Declare Constants )-*/
const int wakeUpPin = 2;
#define resolution 5 // frequency in minutes to wake from sleep

/*-(Declare Variables)-*/
time_t t;
int nextLoop;

/****** SETUP: RUNS ONCE ******/
void setup()
{
  Serial.begin(9600);

  Serial.println();
  pinMode(wakeUpPin, INPUT);

  t = RTC.get();

  nextLoop = ((minute(RTC.get()) / resolution) + 1) * resolution;
  if (nextLoop >= 60) {
    nextLoop -= 60;
  }
  Serial.print(RTC.temperature());
  Serial.print(",");
  Serial.print(RTC.oscStopped());
  Serial.print(",");
  Serial.println(nextLoop); // the minutes when the next reading will be taken

}

/****** LOOP: RUNS CONSTANTLY ******/
void loop()
{
  t = RTC.get();

  Serial.print(year(t), DEC);
  Serial.print("/");
  Serial.print(month(t), DEC);
  Serial.print("/");
  Serial.print(day(t), DEC);
  Serial.print(",");
  Serial.print(hour(t), DEC);
  Serial.print(",");
  Serial.print(minute(t), DEC);
  Serial.print(",");
  Serial.print(second(t), DEC);
  Serial.print(",");

  goToSleep();
}

void goToSleep(void) {
    Serial.print("Sleeping until: ");
    Serial.println(nextLoop);
    Serial.flush();
    RTC.setAlarm(ALM2_MATCH_MINUTES, nextLoop, 1, 1);
    RTC.alarmInterrupt(ALARM_2, true);
    attachInterrupt(0, wakeUp, LOW);

    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
    detachInterrupt(0);
    RTC.alarm(ALARM_2);
    nextLoop += resolution;
    if (nextLoop >= 60) {
         nextLoop -= 60;
    }
}

void wakeUp(){
  // Handler for the pin interrupt.
}

```

# Answer
Check your battery, it is behaving like a rechargeable one without a charger. Mine have the letter "R" at the end of the part number. There are a lot of RTC modules that charge the battery. Conversely they are some that do not charge the battery. Are you powering it with something other then the coin cell.
> 1 votes

# Answer
1) Could be a short in your PCB. As suggested, try another module if possible.

2) Shouldn't you somehow program SQW pin to be an interrupt? By default I remember it outputs a squarewave.

3) Try calling `clearAlarm();` for your RTC to see how it goes.

4) Having the RTC sitting there, by connecting GND and a digital input from an Arduino, can you `digitalRead();` the pin? That way you'll see if it keeps firing interrupts.
> -1 votes

---
Tags: battery, rtc
---


# Question
Title: How to manage two alarms with one interrupt?
I have a datalogger using the RTC DS3231 as an interrupt generator. I am able to have the interrupts work but here is my problem. I would like to take 2 separate measures from 2 different sensors (one for humidity, temperature and the other for accelerations), one every 30 min et one every hour, the thing is that because I use the same pin (only one pin from the DS3231) for both of these alarms I cannot use a simple counter in my interrupt function otherwise one measure will not be taken when both of the alarms will trigger...

For example I just did a quick test with one alarm each min when seconds are 00 and an other alarm each minute when seconds are 20. The problem as I said is that I cannot increment counters for each since I use the same interrupt function (because of the single pin). Here is my loop function and interrupt handling function :

```
void loop() {
  delay(1000);
  sleepNow();
  if (alarm == true){
    handleAlarm(); // reset the possibility to trigger alarm
    if (counter_dtphl == COUNT_DTPHL){
      take_measure_DTPHL();
      counter_dtphl = 0;
    }
    else if (counter_accel == COUNT_ACCEL){
      take_measure_ACCEL();
      counter_accel = 0;
    }
  }
}

void wakeUpNow() {
  Serial.println("In wake up now");
  delay(100);
  alarm = true;
  //Serial.println(counter);
  sleep_disable();//Disable sleep mode
  byte sec = get_date(SEC);
  Serial.println(sec);
  if (sec == 0){
  counter_dtphl +=1;
  }
  else if (sec == 30){
  counter_accel +=1;
  }
  detachInterrupt(digitalPinToInterrupt(interruptPin)); //Removes the interrupt from pin 2;
}

void handleAlarm() {
  alarm = false;
  rtcObject.LatchAlarmsTriggeredFlags();
}

```

COUNT\_ACCEL and COUNT\_DTPHL are constant having the value of minutes corresponding to the trigger for the measure.

Has anybody an idea how to manage this situation ? For the acceleration I need to save the data for a period of 30 sec. One solution I tried is to increment the counter according to the time in second that corresponds each minute but I cannot put it in the wakeUpNow function since only fast processing should be done there (it is the function executed by the interrupt).

Thank you for your time !

# Answer
> 3 votes
Consider it is good practice to leave as little code in an interrupt as possible. In this case, as the time in question is much greater then how often the loop() function is called, setting a single flag indicating an interrupt occurred would be sufficient.

Each time in your loop() function test for this flag. If TRUE, immediately set it to FALSE so as not forget to do so later. Next, while still in the scope of the IF statement, assuming the RTC DS3231 has been configured to create an interrupt every 30 minutes, take your "30 minute sample". Next, while still in the scope of the IF statement, increment a counter. Make sure this counter is defined as a global variable in order to persist between calls to the loop() function. If this counter has reached the value of 2, clear this counter to zero and take your "60 minute sample".

Consider the following **pseudo code**:

```
// Global variable defined outside of functions to track state & time.
bool state_interrupts;
int counter_interrupts;

void setup()
{
  // Initialize RTC to generate an interrupt once every 30 minutes.
  <RTC initialization code.>
  // Call attach interrupt to identify interrupt function name "wakeUpNow".
  attachInterrupt(...)
  // Initialize state & counter;
  interrupts_state = false;
  interrupts_counter = 0;
}

void loop()
{
  // Check if interrupt occurred.
  if(interrupts_state)
  {
    interrupts_state = false;
    interrupts_counter++;
    // Sample 30 minute sensor.
    <Sample 30 minute sensor code.>
    if(interrupts_counter >= 2)
    {
      interrupts_counter = 0;
      // Sample 60 minute sensor.
      <Sample 60 minute sensor code.>
    }
  }
}

void wakeUpNow()
{
    interrupts_state = true;
}

```

# Answer
> 2 votes
The typical solution to this type of problem is:

1. In the ISR set a flag to indicate an RTC interrupt has occurred.
2. In the loop check the flag and if the set: a) Read the alarm flags from the RTC, b) Check the alarms, return value from LatchAlarmsTriggeredFlags(), and do the appropriate action.

What you should not do is write a lot of code in the ISR. Especially code that is also interrupt driven or depend on interrupts such as Wire, Serial, millis(), delay(), etc.

Cheers!

# Answer
> 1 votes
After the interrupt read the time from the RTC and then do the correct thing based on the result.

# Answer
> 0 votes
Try this: bool x = true; This is before setup bool done = false;

x = !x; Do this in the interrupt function. done = true; this is in your loop! if done == true{ // Determine if you have been here before if X !true do both functions else do the 30 second one I use the !X as it is faster. done = false;} This should give you an idea, I did not actually code this but i use code similar to this all the time. My goal is to do no more then 1 or two instructions in the interrupt service routine (ISR).

---
Tags: rtc, datalogging, ds3231-alarms
---


# Question
Title: Esp8266: Linux - fatal: No names found and undefined reference to `app_entry_custom()'
as Gentoo user I build everything from sources, but I have problem with building toolchain for esp8266. I came up with this script:

```
#!/bin/sh

# note: eselect python2 before, because of gcc

# prepare board
mkdir -p ~/Arduino/hardware/esp8266com
cd ~/Arduino/hardware/esp8266com
git clone --recursive --depth 1 https://github.com/esp8266/Arduino.git esp8266

# use system python3
mkdir esp8266/tools/python3
ln -s /usr/bin/python3 esp8266/tools/python3/python3

# build toolchain
cd ~/Arduino
git clone --recursive --depth 1 https://github.com/pfalcon/esp-open-sdk.git
cd esp-open-sdk
sed -i "193s/.*/                     |\$EGREP '^GNU bash, version (3\\.[1-9]|4|5)')/" crosstool-NG/configure.ac # add bash5 support
echo CT_DEBUG_gdb=n >> crosstool-config-overrides # don't build gdb
make STANDALONE=n

# "install" esp-open-sdk
ln -sf ~/Arduino/esp-open-sdk/xtensa-lx106-elf ~/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf

```

It builded successfully, but I get errors during building project:

```
(…)
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/python3/python3 /home/urhen/Arduino/hardware/esp8266com/esp8266/tools/makecorever.py --build_path /tmp/arduino_build_179995 --platform_path /home/urhen/Arduino/hardware/esp8266com/esp8266 --version unix-2.7.0-dev
fatal: No names found, cannot describe anything.
(…)
Linking everything together...
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -CC -E -P -DVTABLES_IN_FLASH /home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.app.v6.common.ld.h -o /tmp/arduino_build_179995/local.eagle.app.v6.common.ld
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -fno-exceptions -Wl,-Map -Wl,/tmp/arduino_build_179995/sketch_apr19a.ino.map -g -Wall -Wextra -Os -nostdlib -Wl,--no-check-sections -u app_entry -u _printf_float -u _scanf_float -Wl,-static -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lib -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lib/NONOSDK22x_190703 -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/ld -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/libc/xtensa-lx106-elf/lib -Teagle.flash.4m2m.ld -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,spi_flash_read -o /tmp/arduino_build_179995/sketch_apr19a.ino.elf -Wl,--start-group /tmp/arduino_build_179995/sketch/sketch_apr19a.ino.cpp.o /tmp/arduino_build_179995/core/core.a -lhal -lphy -lpp -lnet80211 -llwip2-536-feat -lwpa -lcrypto -lmain -lwps -lbearssl -laxtls -lespnow -lsmartconfig -lairkiss -lwpa2 -lstdc++ -lm -lc -lgcc -Wl,--end-group -L/tmp/arduino_build_179995
/tmp/arduino_build_179995/core/core.a(core_esp8266_main.cpp.o):(.text.app_entry+0x0): undefined reference to `app_entry_custom()'
/tmp/arduino_build_179995/core/core.a(core_esp8266_main.cpp.o): In function `app_entry':
/home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp:318: undefined reference to `app_entry_custom()'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.

```

What am I missing?

Log:

```
/usr/share/arduino/arduino-builder -dump-prefs -logger=machine -hardware /usr/share/arduino/hardware -hardware /home/urhen/Arduino/hardware -tools /usr/share/arduino/hardware/tools/avr -libraries /home/urhen/Arduino/libraries -fqbn=esp8266com:esp8266:d1_mini:xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 -ide-version=10807 -build-path /tmp/arduino_build_418955 -warnings=all -prefs=build.warn_data_percentage=75 -verbose /tmp/untitled878766377.tmp/sketch_apr19a/sketch_apr19a.ino
/usr/share/arduino/arduino-builder -compile -logger=machine -hardware /usr/share/arduino/hardware -hardware /home/urhen/Arduino/hardware -tools /usr/share/arduino/hardware/tools/avr -libraries /home/urhen/Arduino/libraries -fqbn=esp8266com:esp8266:d1_mini:xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 -ide-version=10807 -build-path /tmp/arduino_build_418955 -warnings=all -prefs=build.warn_data_percentage=75 -verbose /tmp/untitled878766377.tmp/sketch_apr19a/sketch_apr19a.ino
Using board 'd1_mini' from platform in folder: /home/urhen/Arduino/hardware/esp8266com/esp8266
Using core 'esp8266' from platform in folder: /home/urhen/Arduino/hardware/esp8266com/esp8266
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/python3/python3 /home/urhen/Arduino/hardware/esp8266com/esp8266/tools/makecorever.py --build_path /tmp/arduino_build_418955 --platform_path /home/urhen/Arduino/hardware/esp8266com/esp8266 --version unix-2.7.0-dev
Detecting libraries used...
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-g++ -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lwip2/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/libc/xtensa-lx106-elf/include -I/tmp/arduino_build_418955/core -c -w -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=gnu++11 -ffunction-sections -fdata-sections -fno-exceptions -w -x c++ -E -CC -DNONOSDK22x_190703=1 -DF_CPU=80000000L -DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DARDUINO=10807 -DARDUINO_ESP8266_WEMOS_D1MINI -DARDUINO_ARCH_ESP8266 "-DARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"" -DFLASHMODE_DIO -DESP8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/variants/d1_mini /tmp/arduino_build_418955/sketch/sketch_apr19a.ino.cpp -o /dev/null
Generating function prototypes...
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-g++ -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lwip2/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/libc/xtensa-lx106-elf/include -I/tmp/arduino_build_418955/core -c -w -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=gnu++11 -ffunction-sections -fdata-sections -fno-exceptions -w -x c++ -E -CC -DNONOSDK22x_190703=1 -DF_CPU=80000000L -DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DARDUINO=10807 -DARDUINO_ESP8266_WEMOS_D1MINI -DARDUINO_ARCH_ESP8266 "-DARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"" -DFLASHMODE_DIO -DESP8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/variants/d1_mini /tmp/arduino_build_418955/sketch/sketch_apr19a.ino.cpp -o /tmp/arduino_build_418955/preproc/ctags_target_for_gcc_minus_e.cpp
/usr/bin/arduino-ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /tmp/arduino_build_418955/preproc/ctags_target_for_gcc_minus_e.cpp
Compiling sketch...
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/python3/python3 /home/urhen/Arduino/hardware/esp8266com/esp8266/tools/signing.py --mode header --publickey /tmp/untitled878766377.tmp/sketch_apr19a/public.key --out /tmp/arduino_build_418955/core/Updater_Signing.h
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-g++ -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lwip2/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/libc/xtensa-lx106-elf/include -I/tmp/arduino_build_418955/core -c -Wall -Wextra -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=gnu++11 -MMD -ffunction-sections -fdata-sections -fno-exceptions -DNONOSDK22x_190703=1 -DF_CPU=80000000L -DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DARDUINO=10807 -DARDUINO_ESP8266_WEMOS_D1MINI -DARDUINO_ARCH_ESP8266 "-DARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"" -DFLASHMODE_DIO -DESP8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/variants/d1_mini /tmp/arduino_build_418955/sketch/sketch_apr19a.ino.cpp -o /tmp/arduino_build_418955/sketch/sketch_apr19a.ino.cpp.o
Compiling libraries...
Compiling core...
Using previously compiled file: /tmp/arduino_build_418955/core/cont.S.o
Using previously compiled file: /tmp/arduino_build_418955/core/umm_malloc/umm_info.c.o
Using previously compiled file: /tmp/arduino_build_418955/core/umm_malloc/umm_integrity.c.o
Using previously compiled file: /tmp/arduino_build_418955/core/umm_malloc/umm_local.c.o
Using previously compiled file: /tmp/arduino_build_418955/core/umm_malloc/umm_poison.c.o
Using previously compiled file: /tmp/arduino_build_418955/core/Esp-frag.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/core_esp8266_postmortem.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/WMath.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/heap.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/core_esp8266_sigma_delta.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/WString.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/libc_replacements.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/core_esp8266_si2c.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/gdb_hooks.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/core_esp8266_timer.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/spiffs_api.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/Stream.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/abi.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/Esp.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/Esp-version.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-g++ -D__ets__ -DICACHE_FLASH -U__STRICT_ANSI__ -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lwip2/include -I/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/libc/xtensa-lx106-elf/include -I/tmp/arduino_build_418955/core -c -Wall -Wextra -Os -g -mlongcalls -mtext-section-literals -fno-rtti -falign-functions=4 -std=gnu++11 -MMD -ffunction-sections -fdata-sections -fno-exceptions -DNONOSDK22x_190703=1 -DF_CPU=80000000L -DLWIP_OPEN_SRC -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DARDUINO=10807 -DARDUINO_ESP8266_WEMOS_D1MINI -DARDUINO_ARCH_ESP8266 "-DARDUINO_BOARD=\"ESP8266_WEMOS_D1MINI\"" -DFLASHMODE_DIO -DESP8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266 -I/home/urhen/Arduino/hardware/esp8266com/esp8266/variants/d1_mini /home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266/Updater.cpp -o /tmp/arduino_build_418955/core/Updater.cpp.o
Using previously compiled file: /tmp/arduino_build_418955/core/core_esp8266_spi_utils.cpp.o
[cut due to characters limit]
Using previously compiled file: /tmp/arduino_build_418955/core/Schedule.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Esp-frag.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Esp-version.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Esp.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/FS.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/FSnoop.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/FunctionalInterrupt.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/HardwareSerial.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/IPAddress.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/MD5Builder.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Print.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Schedule.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/StackThunk.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Stream.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/StreamString.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Tone.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/Updater.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/WMath.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/WString.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/abi.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/base64.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/cbuf.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/cont.S.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/cont_util.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_app_entry_noextra4k.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_eboot_command.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_features.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_flash_utils.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_i2s.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_main.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_noniso.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_phy.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_postmortem.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_si2c.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_sigma_delta.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_spi_utils.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_timer.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_waveform.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_wiring.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_wiring_analog.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_wiring_digital.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_wiring_pulse.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_wiring_pwm.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/core_esp8266_wiring_shift.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/crc32.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/debug.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/flash_hal.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/gdb_hooks.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/heap.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/libb64/cdecode.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/libb64/cencode.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/libc_replacements.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/sntp-lwip2.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/spiffs/spiffs_cache.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/spiffs/spiffs_check.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/spiffs/spiffs_gc.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/spiffs/spiffs_hydrogen.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/spiffs/spiffs_nucleus.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/spiffs_api.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/sqrt32.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/time.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/uart.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/umm_malloc/umm_info.c.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/umm_malloc/umm_integrity.c.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/umm_malloc/umm_local.c.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/umm_malloc/umm_malloc.cpp.o
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru /tmp/arduino_build_418955/core/core.a /tmp/arduino_build_418955/core/umm_malloc/umm_poison.c.o
Linking everything together...
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -CC -E -P -DVTABLES_IN_FLASH /home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/ld/eagle.app.v6.common.ld.h -o /tmp/arduino_build_418955/local.eagle.app.v6.common.ld
/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -fno-exceptions -Wl,-Map -Wl,/tmp/arduino_build_418955/sketch_apr19a.ino.map -g -Wall -Wextra -Os -nostdlib -Wl,--no-check-sections -u app_entry -u _printf_float -u _scanf_float -Wl,-static -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lib -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/lib/NONOSDK22x_190703 -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/ld -L/home/urhen/Arduino/hardware/esp8266com/esp8266/tools/sdk/libc/xtensa-lx106-elf/lib -Teagle.flash.4m2m.ld -Wl,--gc-sections -Wl,-wrap,system_restart_local -Wl,-wrap,spi_flash_read -o /tmp/arduino_build_418955/sketch_apr19a.ino.elf -Wl,--start-group /tmp/arduino_build_418955/sketch/sketch_apr19a.ino.cpp.o /tmp/arduino_build_418955/core/core.a -lhal -lphy -lpp -lnet80211 -llwip2-536-feat -lwpa -lcrypto -lmain -lwps -lbearssl -laxtls -lespnow -lsmartconfig -lairkiss -lwpa2 -lstdc++ -lm -lc -lgcc -Wl,--end-group -L/tmp/arduino_build_418955
/tmp/arduino_build_418955/core/core.a(core_esp8266_main.cpp.o):(.text.app_entry+0x0): undefined reference to `app_entry_custom()'
/tmp/arduino_build_418955/core/core.a(core_esp8266_main.cpp.o): In function `app_entry':
/home/urhen/Arduino/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp:318: undefined reference to `app_entry_custom()'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.

```

# Answer
You did a shallow copy of the git repo:
The solution is to ensure that the initial clone of the repo in the build environment was not a shallow clone (i.e. the git clone command was not used with --depth, --shallow-since or --shallow-exclude parameters). so change your

```
git clone --recursive --depth 1 https://github.com/esp8266/Arduino.git esp8266
....
git clone --recursive --depth 1 https://github.com/pfalcon/esp-open-sdk.git

```

to

```
git clone --recursive https://github.com/esp8266/Arduino.git esp8266
....
git clone --recursive https://github.com/pfalcon/esp-open-sdk.git

```

and make sure your \*.ino contains at least

```
 setup(){}

```

AND

```
loop(){}

```
> 1 votes

---
Tags: esp8266, compilation-errors, linux
---


# Question
Title: Correct position for buttonState in my FSM
I wrote a FSM with the help of some tutorials through out the world wide web and so far it does what I want to do with it.

But one thing that is not the way I want to be, is to exit the state noLightPause during the non blocking delay with the button to enter the yellowLight state again. I cannot figure out where to put the buttonState inside my code, if it should be that simple to exit that state, because it was hard enought for me to get my machine going to that point :D.

Do not get confused, I soldered the button from ground to the pin, so LOW gets the input :).

Hope you guys can help me with that problem to get me further with my machine.

Thanks in advance for all your help, here is my code:

```
#include <FastLED.h>

#define NUM_LEDS 16

CRGB ledStrip [NUM_LEDS];

const int buttonPin = 4;
const int ledStripPin = 8;
const int ledOnBoard = 13;
const int interval = 100;

int buttonState = 0;
int lastButtonState = 0;

int ledOnBoardState = LOW;

unsigned long previousMillis = 0;
static unsigned long noDelayPause;

enum statusType {whiteLight, yellowLight, noLightPause, noLight};

statusType currentStatus = whiteLight;

void setup() {

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledStrip, OUTPUT);
  pinMode(ledOnBoard, OUTPUT);

  FastLED.addLeds<NEOPIXEL, 8>(ledStrip, NUM_LEDS).setCorrection(DirectSunlight);
  FastLED.show();
}

void loop() {

  //----------------------------------------
  // just to see if the machine is blocking something

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    if (ledOnBoardState == LOW) {
      ledOnBoardState = HIGH;
    } else {
      ledOnBoardState = LOW;
    }
    digitalWrite(ledOnBoard, ledOnBoardState);
  }

  //----------------------------------------

  switch (currentStatus) {

    case whiteLight:
      currentStatus = whiteLightFunction();
      break;

    case yellowLight:
      currentStatus = yellowLightFunction();
      break;

    case noLightPause:
      noDelayPause = millis();
      currentStatus = noLightPauseFunction();
      break;

    case noLight:
      if (millis() - noDelayPause > 1000) {
        currentStatus = noLightFunction();
        break;
      }
  }
}

statusType whiteLightFunction() {

  if (digitalRead(buttonPin) == LOW) {

    return (yellowLight);

  } else {

    fill_solid(ledStrip, NUM_LEDS, CRGB::White);
    FastLED.setBrightness(100);
    FastLED.show();

    return (whiteLight);
  }
}

statusType yellowLightFunction() {

  if (digitalRead(buttonPin) == LOW) {

    fill_solid(ledStrip, NUM_LEDS, CRGB::Yellow);
    FastLED.setBrightness(100);
    FastLED.show();

    return (yellowLight);

  } else {

    return (noLightPause);
  }
}

statusType noLightPauseFunction() {

  fill_solid(ledStrip, NUM_LEDS, CRGB::Black);
  FastLED.show();

  if (digitalRead(buttonPin) == LOW) {

    return (yellowLight);

  } else {

    if (digitalRead(buttonPin) == HIGH) {

      return (noLight);
    }
  }
}

statusType noLightFunction() {

  if (digitalRead(buttonPin) == LOW) {

    return (yellowLight);

  } else {

    return (whiteLight);
  }
}

```

# Answer
> 0 votes
You should also introduce a button state to have the FSM working as a FSM

```
 bool buttonState = false;

```

in the loop you check for the press/release and change the state:

```
if (digitalRead(buttonPin) == LOW && buttonState == true) buttonState == false;
if (digitalRead(buttonPin) == HIGH && buttonState == false) buttonState == true;

```

inside your function you only go for buttonState eg

```
statusType noLightFunction() {
if (buttonState == false) {  // Button is NOT pressed

    return (yellowLight);

  } else {       // Button is pressed

    return (whiteLight);
  }
}

```

The button acts as a toogle switch as long as you keep it pressed (or released) nothing will change only the state changes caise an action to happen. I personally use "speaking" vars I still know years later so instead of `buttonState` I use `buttonIsPressed` but thats flavour

---
Tags: button, switch
---


# Question
Title: NodeMCU V2 ESP8266 - Use 5VIN as power for heater of a MQ-9 Sensor
Right now I'm trying to understand how I could (easily) power the heater of my MQ-9 carbon monoxid and gas sensor.

Here is the datasheet: http://www.haoyuelectronics.com/Attachment/MQ-9/MQ9.pdf

It needs 5V for some gases, so I thought I could maybe power the heater via the 5VIN pin (while plugged via usb), since the other output pins have a max. voltage of only 3.3 V?

And to control the power, I could then add a relay switch, which would cut the circuit between heater and VIN (if I only want to measure the gases)?

Or am I completely wrong?

P.S: And no - I don't want to add a 5V power supply additional to the normal USB plugging on VIN :)

# Answer
The VIN pin is **NOT** directly connected to the USB's 5V supply as it is an **VIN PIN** for powering the MCU from an external source other than the USB - this means the **pin cannot be used** as a 5V supply output.

* Never ever connect VIN to a power source **AND** connect the USB plug. That can destroy the USB port in your computer. There is zero back-powering protection on the MCU board.

According to the datasheet the sensor (heater) needs upto 350mW which IMHO makes powering via an extra power board (which can also power the MCU) a necessity.
> 1 votes

---
Tags: esp8266, sensors, nodemcu, voltage-level
---


title: ESP8266 to ESP8266 via home rooter

text:
# Question
Title: ESP8266 to ESP8266 via home rooter
I would like to ask how to build a star topology network with several ESP8266s, pc and a home wifi router? I would like to connect my computer (as a client) and ESP8266s (as clients) together via a wifi router and exchange data between them.

Thanks in advance,

Best,

# Answer
> 0 votes
The sending / receiving of data has nothing to do with the topology. In fact, when you have one ESP8266 as an access point and another as a station that is no different to having two ESP8266's as stations communicating through an access point. The topology is transparent to the communication of user data as that is a completely different (lower) layer of the OSI model and as such is hidden from the layers above.

You communicate in *exactly the same way* regardless of your topology. That is - one end opens a socket of some form and the other end connects to (for TCP) and sends data to (for both TCP and UDP) that socket. For TCP the "server" socket can then also send data back through the same connection. For UDP there is no "server" as such, but just two peers that send data to each other and for two-way communication both ends need to be a "server" to receive data.

What you need to do is define what data you want to send and what method of sending that data will be most suitable for your system - be that simple UDP packets, or something more complex like one of the many HTTP-based API systems.

---
Tags: esp8266, wifi
---


# Question
Title: Crash when serving static files width ESP8266WebServer
For the past two days, I've been trying to set up an ESP8266WebServer to serve my static web app files from SPIFFS. But as soon as I make a call to `serveStatic`, the ESP crashes. This is the exact code I'm running:

```
#include <FS.h>
#include <ESP8266WebServer.h>

ESP8266WebServer s;

void setup() {

    Serial.begin(115200);

    if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
    }

    s.serveStatic("/", SPIFFS, "/static/");
    s.begin();
}

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

```

I know that this is example does not allow me to access the files in any way because I don't have WiFi configured, but this is enough for me to crash the ESP. This is the error that I keep seeing:

```
SPIFFSImpl: allocating 512+240+1400=2152 bytes
SPIFFSImpl: mounting fs @100000, size=2fa000, block=2000, page=100
SPIFFSImpl: mount rc=0

Fatal exception 28(LoadProhibitedCause):
epc1=0x4021407a, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Exception (28):
epc1=0x4021407a epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffca0 end: 3fffffc0 offset: 01a0
3ffffe40:  3ffefaf8 00000000 3ffffea0 402127b1
3ffffe50:  00000001 ffffffff 4020a9dc 00000000
3ffffe60:  3ffe8304 00000000 0000000a 40216e21
3ffffe70:  402497e1 00000000 00000000 4020b414
3ffffe80:  3ffffee0 3ffffed0 00000008 402497e3
3ffffe90:  402497e2 3ffe8304 3ffefaf8 402171ec
3ffffea0:  00000000 ffffffff 00000000 00000000
3ffffeb0:  00000001 00000041 3f302073 40212d8e
3ffffec0:  3ffffee0 3ffffed0 00000004 40209c90
3ffffed0:  3fffff10 00000000 00000017 3fff0580
3ffffee0:  00308658 3fffff20 3ffef85c 4020a3e9
3ffffef0:  000018c0 3ffee6b0 00000000 40208120
3fffff00:  3fffff60 3fffff50 00000014 00000001
3fffff10:  00000009 00000001 00000001 40207c65
3fffff20:  40100b04 00001000 00002000 3fff0580
3fffff30:  3ffe8658 402497a4 3ffe8304 40212d8e
3fffff40:  3fffff60 3fffff50 00000004 40100476
3fffff50:  3ffe8658 3ffe8658 3ffe865f 00000000
3fffff60:  00000000 00000000 3fff056c 4020ffa5
3fffff70:  3fffdad0 3ffee690 3fff056c 40201325
3fffff80:  3ffe865f feefeffe feefeffe feefeffe
3fffff90:  feefeffe feefeffe feefeffe 3ffee610
3fffffa0:  3fffdad0 00000000 3ffee5d0 40206aa0
3fffffb0:  feefeffe feefeffe 3ffe84f4 40101245
<<<stack<<<

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

load 0x4010f000, len 1392, room 16
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld

```

I have also analyzed the stack trace using ESP exception decoder, which didn't get me any further though. Here is the output of that tool:

```

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
PC: 0x4021407a: pgm_read_byte_inlined at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/sys/xtensa/sys/pgmspace.h line 72
EXCVADDR: 0x00000000

Decoding stack results
0x402127b1: _printf_i at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/nano-vfprintf_i.c line 226
0x4020a9dc: spiffs_object_find_object_index_header_by_name_v(spiffs*, spiffs_obj_id, spiffs_block_ix, int, void const*, void*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_nucleus.cpp line 1664
0x40216e21: __sfputs_r at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/nano-vfprintf.c line 433
0x4020b414: spiffs_obj_lu_scan(spiffs*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_nucleus.cpp line 439
0x402171ec: _vfprintf_r at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/nano-vfprintf.c line 667
0x40212d8e: printf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/printf.c line 61
0x40209c90: SPIFFS_mount(spiffs*, spiffs_config*, u8_t*, u8_t*, u32_t, void*, u32_t, spiffs_check_callback) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_hydrogen.cpp line 138
0x4020a3e9: SPIFFS_stat(spiffs*, char const*, spiffs_stat*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs/spiffs_hydrogen.cpp line 769
0x40208120: spiffs_impl::SPIFFSImpl::_tryMount() at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs_api.h line 320
0x40207c65: spiffs_impl::SPIFFSImpl::exists(char const*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/spiffs_api.cpp line 80
0x40100b04: get_poisoned(void*, size_t) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/umm_malloc/umm_poison.c line 112
0x40212d8e: printf at /home/earle/src/esp-quick-toolchain/repo/newlib/newlib/libc/stdio/printf.c line 61
0x40100476: pvPortMalloc(size_t, char const*, int) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/heap.cpp line 267
0x4020ffa5: fs::FS::exists(char const*) at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/FS.cpp line 363
0x40201325: setup() at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 75
0x40206aa0: loop_wrapper() at /Users/alex/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_main.cpp line 177

```

These are my settings in the Arduino IDE:

To flash the data to the ESP, im using the latest version of this tool for the Arduino-IDE: https://github.com/esp8266/arduino-esp8266fs-plugin

I'm probably making a stupid mistake but I've been scratching my head for hours now and can't see where the issue could be. Any help would be greatly appreciated!

**EDIT #1:**

The data is definitely available on the ESP, since this snippet works fine:

```
#include <FS.h>
#include <ESP8266WebServer.h>

ESP8266WebServer s;

void setup() {

    Serial.begin(115200);

    if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
    }

    /*s.serveStatic("/", SPIFFS, "/static/");
    s.begin();*/
}

void loop() {
  //s.handleClient();

    delay(5000);

    File f = SPIFFS.open("/static/index.html", "r");

    String s = f.readString();

    Serial.println(s);

    f.close();
}

```

**EDIT #2**

Serving the files by registering the function below as a handler (`server.on("/", myHandler)`works:

```
void myHandler(){

    String file = "/static/index.html";

    Serial.println("[INFO] requested file " + file);

    if(!SPIFFS.exists(file)){

        server.send(404, "text/plain", "<h1>404: Not found</h1>");
        return;
    }

    String contentType = "text/plain";

    if(file.endsWith(".html")){
        contentType = "text/html";
    } else if(file.endsWith(".css")){
        contentType = "text/css";
    } else if(file.endsWith(".js")){
        contentType = "application/javascript";
    }

    File f = SPIFFS.open(file, "r");

    server.streamFile(f, contentType);

    f.close();
}

```

# Answer
> 4 votes
Turns out the ESP crash is caused by the debug settings in the Arduino IDE. As soon as the CORE-level is included, the error occurs. There seems to be a bug in the firmware somewhere. Including other levels seems to be fine.

A huge thanks to Juraj for helping me spot this one.

# Answer
> 0 votes
Probably you have no SPIFFS uploaded.
So after flashing the program you have to use ESP8266DataUpload and in your Dir containing the \*.ino there has to be a "data" directory in which the file you serve or the dir in your case "/static/" has to exist.

**EDIT** No the file is not existing ;-) use

```
 serveStatic("/", SPIFFS, "/static");  //=> no trailing '/'

```

or use (Be aware that serving dirs static is not working properly. I have every large file in a single static statement including the ageing

```
 serveStatic("/", SPIFFS, "/static/index.html");

```

Not knowing the size of your static files flash with 2MB FS / or 1MB FS / the problem is that if you don't need OTA you always waste space. I created my personal partition schemes with e.g. 2MB Spiffs/2MB flash/No OTA for the prog.
Your memory should be sized as follows prog size + var size (seen in IDE) + size of the largest (static) files * 1.2 (safety margin) should fill "App memory" around 80%.
As an example your usage is at the moment as follows:
You have at the moment max 400kb for the app AND serving (static) files. You use

* 3 MB for SPIFFS file system,
* 512 for OTA,
* min 100kb for your Debug level

=\> how could it keep/load e.g a 300kb file into flash?
Your error code 28 is normally connected to out of memory problems, the error message line two indicates that something should be loaded to memory and cant, We ruled out all other reasons so ...

---
Tags: esp8266, arduino-ide, spiffs
---