# Question
Title: How to allow cross-domain requests with ESP8266WebServer.h ? - CORS policy: Access-Control-Allow-Origin
With an nodeMCUv2 I want:

* to start a wifi server with ESP8266WebServer.h
* serve a root html page which will interact with the ESP and fetch external data

**Issue:** CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.'

Tried to make CORS happy, by either one of the followings, but didn't help:

.sendHeader("Access-Control-Allow-Origin", "\*");

.enableCORS(true);

```
#include <ESP8266WebServer.h>
ESP8266WebServer srvAmb(80);
void handleRoot(){
// srvAmb.sendHeader("Access-Control-Allow-Origin", "*");
   srvAmb.enableCORS(true);
   srvAmb.send(200,"text/html; charset=utf-8", myRootWebPagWithJSExternalFetch);
}
void setup(){
...
    srvAmb.on("/", handleRoot);
...

```

Part of the served root html page:

```
try{
  const Qresponse = await fetch( "https://zenquotes.io/api/random" );
  const Qdata = await Qresponse.json();
  console.log(Qdata);
  ...
} catch (error) {
  console.error(error);
}

```

Console log in Chromium:

> Access to fetch at 'https://zenquotes.io/api/random' from origin '192....' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

So, how does one fetch external data from the browser running on PC, smartphone, etc?

Thanks

P.S. One could ask the server to fetch the data, prior to supplying the html page, but that's not esp server's job.

P.P.S. I hadn't the credit to create tag keywords such as: fetch, CORS, Allow-Origin, policy

REM: under How to allow cross-domain requests on ESP8266WebServer

it is suggested that .sendHeader("Access-Control-Allow-Origin", "\*") could be deprecated, very well but ArduinoIDE does not raise any warning; anyway suggested solution fails.

Looking at the source code https://github.com/esp8266/ESPWebServer/blob/master/src/ESP8266WebServer.cpp, the method sendHeader() on line 238, has a 3rd parameter(a boolean) that if set to true, puts before the passed name & value before the already passed header, otherwise puts it after, aka the declarative order is important.

Viz, what's the valid header the esp server needs to send?? Especially, has Chromium details, states:

> Request URL: zenquotes.io/api/random

> Request Method: GET

> Status Code: 200

> Referrer Policy: strict-origin-when-cross-origin

See also: https://javascript.info/fetch-crossorigin

# Answer
> 1 votes
The issue is URL specific.

Indeed, if I change API, namely

```
const Qresponse = await fetch( "https://zenquotes.io/api/random" );

```

by for example:

```
const Qresponse = await fetch( "https://api.open-meteo.com/v1/meteofrance?latitude=49.71&longitude=4.16&daily=sunset&timezone=Europe%2FBerlin" );

```

then it works.

I presume that I comes from network developper tools info in Chromium:

> Referrer Policy: strict-origin-when-cross-origin

claiming a strict origin for zenquotes.io's API. My esp server code being:

```
void handleRoot(){
    srvAmb.sendHeader("Access-Control-Allow-Origin", "*", 1);
    srvAmb.send(200,"text/html; charset=utf-8", myRootWebPagWithJSExternalFetch);
}

```

Remark, with or without the additional 3rd param of sendHeader() it works.

---
Tags: json, esp8266webserver, security
---


# Question
Title: PWM with a TRANSISTOR on flexible LED filament
I would like to create a custom lighting, with **PWM** capability, powered **from battery**. I would like to use **flexible led filaments**, and since those **consumes more than 40mA**, I can't use them directly on a board. I found a link explaining to use a **MOSFET** transistor, to dim my leds. So the transistor that I need would be one with a 5v power supply, and a 5v Voltage input.

The problem is that I can't find any transistor matching those specs. I also noticed that they have a heatsink, which mean that they need to dissipate heat, and are therefore not power efficient (which i do not like). Am I missing something ?

Any help will be apreciated, thanks !

# Answer
> 0 votes
You cannot find a MOSFET with that exact rating, because transistors can be used with all voltages inside of their specific limits. Most MOSFETs can be used with way higher voltages than 5V.

What you need is a logic level MOSFET, which means, that it will be in saturation (aka being fully ON) at the typical logic level of 5V on its gate. In the datasheet of a MOSFET you will find a diagram which shows the drain current depending on the gate-source voltage. At your logic level (5V in this case) you want the curve approaching a plateau.

Another important value is `R_DS(on)`. That is the resistance of the MOSFET when its on. The lower the resistance, the lower will the power lost to heat.

> I also noticed that they have a heatsink, which mean that they need to dissipate heat, and are therefore not power efficient (which i do not like).

Every MOSFET dissipates some energy as heat, since no MOSFET can have `R_DS(on)` of zero. The typical heat sink flap is meant to dissipate the heat for keeping the MOSFETs temperature in the specified range, even when drawing the maximum specified current. The datasheet of a MOSFET has a section with maximum ratings. There you should see the maximum drain current `I_D` with its corresponding needed temperatures. For example have a look at this datasheet of a random logic level MOSFET from mouser. There is no specification of how hot the case gets with a specific current, since this depends on the suroundings, but the datasheet states, that it will support up to 80A, when you keep the case to a temperature of 25°C.

It also states what electrical power it can dissipate with its package: `P_D`. You should look at how much current you need for your LED filament. You can calculate the dissipating power with `P = R * I²` (P being power, R the resistance R\_DS(on) and I the current through the MOSFET).

# Answer
> 0 votes
Welcome! You are missing some information. A transistor will work but you will lose about 0.7 Volts when it is on. That voltage times the current will tell you how many watts it needs to dissipate. The data sheet will give you all this information. The transistor is a current controlled device so there will not be a Base voltage rating. You can determine the current for the base by dividing the load current by the HFE then adding a bit.

By connecting more than 20 mA to the port pins especially more than 1 may destroy the Arduino. Surprise the LED is also a current device so you need to limit the current into it. This can easily be done with a resistor.

The MOSFET would be the easiest solution. Put a resistor maybe 10K from the port pin to ground. The reason is the port pins are floating from power on until your software defines and sets there level. Then connect the port of the Arduino to the gate of the MOSFET which has its source grounded. Connect the LED(s) to the drain and place a resistor in series with the LED and + voltage. It can be 12 Volts or whatever you like. You will need to size the current limiting resistor to the LED(S) appropriately and be sure the voltage rating of the MOSFET is at least 10% higher then the voltage.

There is a great book available called the Arduino Cookbook, getting that and reading it will be a big help to you.

---
Tags: arduino-uno, led, pwm, transistor
---


# Question
Title: Ability to calculate bearing related distance with Arduino GPS
Pardon if there's a more precise/technical way of formulating this question :)

What I'm currently working on is a proximity warning with Arduino. There's a preset GPS location in the sketch and if I'm moving closer to it, once I cross a set distace threshold, action is triggered.

I think picture will do better explaining on what challenge I wish to overcome here. Calculating simple "straight line" distance between my current geolocation and the preset destination is easy, but as you can see in the illustration I made, it works from all directions.

100 meter from the target is valid here from any point, or any bearing that the subject might be approaching, which is tedious and not what I want to achieve.

Lower illustration shows what I'd wish to achieve - achieve the trigger criteria only if approaching the destination from certain "bearings"...if that's the right way to phrase it. Hope someone understands what I'm trying to do, if you have some pointers where to start looking and if this can even be achieved on Arduino - do let me know :) Thanks a lot

# Answer
Before suggesting a possible solution consider these aspects of the problem:

1. The question assumes a "flat earth". For small distances this assumption likely contributes an error that can be ignored. For larger distances consider calculating the great circle distance.
2. Consider not every GPS module populates all NMEA fields. If bearing is supplied consider it is not valid unless the GPS module has moved more than the current accuracy of that GPS module.

While the criteria is simple (only alarm when approaching a given latitude and longitude (or MGRS coordinate) while traveling on a certain bearing), the implementation can be troublesome and / or tedious. Consider noise. The position of the GPS module might vary 10 meters while stationary. Resulting in a false bearing. The person carrying the GPS may not walk a straight line. This additional noise may result in never raising an alarm. If the GPS is carried in a car, roads may not exist for direct travel to the given latitude and longitude. Again, the alarm may never be given.

As it turns out, the assumptions made here indicate bearing is not a good criteria when determining direction of approach to a given latitude and longitude. Rather, it may be simply the relation between the current latitude and longitude and the given latitude and longitude that offers the best solution.
> 0 votes

---
Tags: gps, tinygps
---


# Question
Title: How "fast" could GPS data be refreshed while moving and does it depend on the mcu?
I'm using Nano Every and SIM33EAU GPS module for my project and today I went riding shotgun to test how it works when moving on the road. I am using u8g2 library and one of the things that I have printed on the screen is gps.course.deg - which is as the name suggest, course of the GPS module's movement in degrees.

Next to my Arduino device I had a phone with some compass app, and the course was somewhat correct while we were moving at normal traffic speed, but the update rate was vastly different and I don't know why. The only "delay" in the sketch I have is this;

```
  if (gps.location.isUpdated())
  {
    Serial.print(F("Lat Lon = "));
    Serial.print(gps.location.lat(), 6);
    Serial.print(", ");
    Serial.println(gps.location.lng(), 6);
  }

  else if (millis() - last > 500)
  ...

```

I wasn't able to check the Serial Monitor as I didn't have a laptop, so only reading from GPS module was what was being printed on the small OLED screen. So is the lagging update something on the GPS module side and how it works, or is it perhaps OLED not being able to refresh?

# Answer
> 1 votes
GPS modules deliver position updates in very different frequencies, depending on model and configuration (where changeable). Cheaper modules only provide an update every 1 second, while better ones have 5 or 10 Hz position update. Check the documentation for your module to get that information.

Additionally, it is of course possible to "cheat", by calculating an extrapolation, using the last position, direction and speed. Since speed and direction don't typically change very quickly, that works quite well and can give position updates at arbitrary rates.

---
Tags: arduino-ide, arduino-nano, gps, tinygps, u8glib
---


# Question
Title: Does ADXL 345 accelerometer not wirk with Arduino Uno without soldering?
I followed the Adafruit tutorials to wire the ADXL 345 with Ardiuno Uno, but it is not able to detect the sensor. It did not mention that I need to solder the ADXL 345. Is soldering necessary?

# Answer
Some boards and wires are built so that plugging them together should work fine. For example the following picture from embedded.com of an Arduino, ready made wires with pins at the ends and a bread board should connect with no soldering:

And if your Analog Devices ADXL-350 chip is already soldered onto a PCB with 1/10 inch headers as in this picture from Adafruit.com:

... you should be able to connect the Arduino to the accelerometer with out soldering.

However, if the header and ADXL-450 PCB from Adafruit are not soldered together, as is the case in this picture:

... you will have to solder them as outlined on this Adafruit web page.
> 0 votes

---
Tags: arduino-uno
---


title: Passing variable into catch() exception

text:
# Question
Title: Passing variable into catch() exception
I'm working with a try{} catch(){} exception right now and I want to change a Variable. For this my board has to connect to the Internet and with a try{} statement it will try to do so. If it fails I simply want to set the variables to 0.

```
  try {
    timeClient.update();
    ntp_seconds  = timeClient.getSeconds();
    ntp_minutes = timeClient.getMinutes();
    ntp_hours = timeClient.getHours();
  }
    catch () {
     ntp_seconds = 0;
     ntp_minutes = 0;
     ntp_hours = 0;
  }

```

I am getting this error: Compilation error: expected type-specifier before ')' token I know that I somehow have to pass my variables into the catch() "function" but somehow I can't pass variables in like I would with normal functions.

# Answer
> 1 votes
You might want to refresh your knowledge about the `try`-`catch` statement by reading the respective chapter in your C++ book.

You need to declare an exception parameter in `catch`, which you can ignore:

```
  try {
    timeClient.update();
    ntp_seconds  = timeClient.getSeconds();
    ntp_minutes = timeClient.getMinutes();
    ntp_hours = timeClient.getHours();
  }
  catch (exception& ignored) {
    ntp_seconds = 0;
    ntp_minutes = 0;
    ntp_hours = 0;
  }

```

# Answer
> 0 votes
The Arduino IDE does not support the C++ try/catch exception handling construct and explicitly disables this feature. See: https://forum.arduino.cc/t/try-catch/180063 for a fuller explanation.

---
Tags: esp8266, ntpclient
---


title: LEDs controlled by PHONE on ESP32

text:
# Question
Title: LEDs controlled by PHONE on ESP32
I am having doubts with a project I'm making. My project involves a **sets of LEDs stripes, among which some are controlled from a smartphone, and some automated**. The LED strips are connected to an **Arduino**, that would receive commands from a phone. Here is a scheme, with essentials elements I marked for my project :

* **A development board, with wifi** support
* a framework/program allowing the smartphone to **communicate with the board**
* And an **Android app** with a color interface, to change LEDs colors

I made some research:

1. I found a lot of boards, and eventually choose **ESP32 boards** (Good ones).
2. I found a **WLED** system, that meet my requirements
3. I know **Home assistant**, that offers **more possibility** than WLED
4. I **won't** use **local server**, since it is not easy to use for other people (family members for example).

**WLED** seems to be very useful, and easy to use. But, *from what I understood*, if I installed WLED on my board, I would have to dedicate the entire board to the WLED program, and therefore i wouldn't be able to upload any other custom code to my board. Since **I want some LEDs to be remotely controlled, and the others to run on an programmed loop**, I don´t know if it´s a good idea

**Home assistant** is more complete, and shouldn't have the problem mentioned above. It can also support several devices, and can have many boards registered on it. I would like, later, to expand Home Assistant to other projects, this is why starting Home assistant now is a good idea. Thus, **I believe I will go for Home Assistant**

---

**I now struggle with the following issues:**

1. I am unsure if i understood correctly, but **I read some people complaints about certains ESP32 boards which need complete wifi configuration (networking stack)**, and are complicated to install. This is why I wanted adafruit boards, supposing that their chip has already an uploaded code. Is that right ?
2. I also read on the internet that after compiling the networking stack on ESP8266 boards, there isn't much space left for the program to run. **Given that I choose the ESP32, with more space, do I have plenty of space for my code, or is it still limited ?**
3. WLED seemed fine, but as I said, I'm not sure if I can upload code. **Can I upload custom code and WLED system to the board, or is it entirely focused on WLED ?**

Thanks to anyone who could bring some clarification to me, I will appreciate it !

# Answer
> -1 votes
> I am unsure if i understood correctly, but I read some people complaints about certains ESP32 boards which need complete wifi configuration (networking stack), and are complicated to install. This is why I wanted adafruit boards, supposing that their chip has already an uploaded code. Is that right ?

I don't know what complaints you have seen (since you didn't like to them), so that I cannot talk about the context. I have used several different ESP boards. The ones, that are a bit difficult to program, were the boards without a USB interface. That is mostly the case with the very small boards.

Yes, Adafruit is a reputable source for such boards. Though I also never had problems with typical ESP dev boards from other sources, like the company named like the big river in south america. Install the ESP32 core in the Arduino IDE, connect the board via USB and program it.

> I also read on the internet that after compiling the networking stack on ESP8266 boards, there isn't much space left for the program to run. Given that I choose the ESP32, with more space, do I have plenty of space for my code, or is it still limited ?

The ESP8266 is smaller, yes, but I still used it and could still write quite big programs while using Wifi. Here one fact is also important: The number after the ESP describes the chip itself, but most boards use an external flash memory chip. Thus the maximum program size depends on how big of a flash chip the board manufacturer uses for the board. You can find that information wherever you buy your board.

Either way, with an ESP32 you are in every case good to go and you will have plenty of resources for whatever you want to do (including enough free pins). If you want to use WLED, you can check for compatible boards in their wiki at github.

> WLED seemed fine, but as I said, I'm not sure if I can upload code. Can I upload custom code and WLED system to the board, or is it entirely focused on WLED ?

Only one program can run at the ESP at a time (technically the ESP has 2 cores, so executes 2 things simultaneously, but one core is used for handling Wifi, so for user code only one core is left). WLED is meant as a ready to use firmware, so no writing of custom code.

You should first think about, what you would want to do with your code. You haven't specified, what exactly your custom code should do while WLED handles the LED strips. Maybe the functionality of WLED is enough for you.

Otherwise you can loop for 2 things with WLED:

* Search in the WLED code/documentation for a place to plug your own code into a function. WLED might give you that possibility (cannot search that myself now, since the official documentation site fails with a certificate problem for me and I cannot open it, even if I accept the risk in my browser).
* If the above is not possible, you can try changing the source code of WLED to also handle your own code. That might be rather difficult, especially for a beginner. Digging in someone elses code while being a beginner is a very steep learning curve.

If both of this is not fitting for you and you still want to execute your own code, then you will have to write the code yourself entirely.

---

Besides my answers above, I would suggest, that you think about what features you need and which you don't need exactly. The options, that you listed, are vastly different.

Home Assistent especially is a very big project, which is powerful, but also complex and difficult to setup. Also keep in mind, that Home Assistent is a program, that needs to run somewhere, and it will not run on the ESP. So you need something like a Raspberry Pi (or any other small home server, which you run 24/7), where you install and configure Home Assistent, before you can even start with the ESPs.

If all you want to do is controlling some LED strips, then Home Assistent is overkill. If you plan to automate your home further, then Home Assistent can be a good choice. Though then your project isn't only about LED strips.

---
Tags: arduino-uno, led, wifi, home-automation
---


# Question
Title: FastLED EVERY_N_SECONDS - does it generate static code?
I realize my question is not precise, so I have a simple contrived example to illustrate better what I am asking.

I am trying to use EVERY\_N\_SECONDS inside a member function of a class that is invoked in the sketch's loop() method. And this works fine, but when I have two instances of the class, each has its member function called in the loop(), but one instance seems to "win" and the other instance never seems to hit the inside of the EVERY\_N\_SECONDS block.

For example, the following code produces this output (I expected both a2 and a1 to appear in "a2 is in the EVERY\_N\_SECONDS loop"):

```
a1 is in the loop
a1 is in the EVERY_N_SECONDS loop
a2 is in the loop
a1 is in the loop
a1 is in the EVERY_N_SECONDS loop
a2 is in the loop
a1 is in the loop
a1 is in the EVERY_N_SECONDS loop
a2 is in the loop

```

Here is the code, a silly little program to illustrate the question:

```
#include <Streaming.h>
#include <FastLED.h>

class A {
public:
 String tag;
 void loop()
 {
   Serial << tag << " is in the loop" << endl;
   EVERY_N_SECONDS(2) {
      Serial << tag << " is in the EVERY_N_SECONDS loop" << endl;
   }
 }
};

A a1, a2;

void setup() {
  Serial.begin(9600);
  a1.tag = "a1";
  a2.tag = "a2";
}

void loop() {
  a1.loop();
  a2.loop();
  FastLED.delay(5000);
}

```

# Answer
> 1 votes
Assuming that the link of chrisl points to the relevant source...

Your source code:

```
    EVERY_N_SECONDS(2) {
        Serial << tag << " is in the EVERY_N_SECONDS loop" << endl;
    }

```

expands to (line split for readability):

```
    static CEveryNSeconds PER__COUNTER__(2);
    if( PER__COUNTER__ ) {
        Serial << tag << " is in the EVERY_N_SECONDS loop" << endl;
    }

```

So, yes, the instance controlling the conditional statement is `static`.

This is the definition of `CEveryNSeconds`:

```
template<typename timeType,timeType (*timeGetter)()>
class CEveryNTimePeriods {
public:
    timeType mPrevTrigger;
    timeType mPeriod;
    CEveryNTimePeriods() { reset(); mPeriod = 1; };
    CEveryNTimePeriods(timeType period) { reset(); setPeriod(period); };
    void setPeriod( timeType period) { mPeriod = period; };
    timeType getTime() { return (timeType)(timeGetter()); };
    timeType getPeriod() { return mPeriod; };
    timeType getElapsed() { return getTime() - mPrevTrigger; }
    timeType getRemaining() { return mPeriod - getElapsed(); }
    timeType getLastTriggerTime() { return mPrevTrigger; }
    bool ready() {
        bool isReady = (getElapsed() >= mPeriod);
        if( isReady ) { reset(); }
        return isReady;
    }
    void reset() { mPrevTrigger = getTime(); };
    void trigger() { mPrevTrigger = getTime() - mPeriod; };
    operator bool() { return ready(); }
};
typedef CEveryNTimePeriods<uint16_t,seconds16> CEveryNSeconds;

```

Its `operator bool()` returns only **once** the value `true`, if the period is elapsed. The first instance of your `A` receives this `true`, but never the second instance.

These are the relevant methods, sorted and formatted for better understanding:

```
    operator bool() {
        return ready();
    }

    bool ready() {
        bool isReady = (getElapsed() >= mPeriod);
        if ( isReady ) {
            reset();
        }
        return isReady;
    }

    timeType getElapsed() {
        return getTime() - mPrevTrigger;
    }

    void reset() {
        mPrevTrigger = getTime();
    }

```

---
Tags: led-strip
---


# Question
Title: slower clock frequency than expected on attiny202
I am programming an attiny202 which as per datasheet can run up to 20Mhz, but after compiling/uploading this simple code to the attiny202 and watch the PA2 pin on the oscilloscope, I see that the pin oscilates at ~2.5MHz which is around 10x slower than I would expect, this is even I disable prescaling, am I missing something? (I am new into programming microcontrollers)

> note: VCC is 5V (from lab bench PSU)

main.c

```
#include <avr/io.h>

int main(void)
{
  // no prescaling (if lesss than 4.5V, this is overclocking)
  _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);

  PORTA_DIR = _BV(2);

  while(1)
  {
    PORTA_OUTTGL = _BV(2);
  }
}

```

Makefile

```
PRG = main

CC = avr-gcc
MCU_TARGET = attiny202
OPTIMIZE = -Os

OBJCOPY = avr-objcopy
UART = /dev/ttyUSB0

all: $(PRG).elf $(PRG).hex

$(PRG).elf: $(PRG).c                                                                                »       $(CC) -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(PRG).c -o $(PRG).elf

%.hex: %.elf
»       $(OBJCOPY) -j .text -j .data -O ihex $< $@

clean:
»       rm *.elf *.hex

burn: $(PRG).hex
»       pymcuprog -t uart -d $(MCU_TARGET) -u $(UART) write -f $(PRG).hex --erase --verify

```

bitmaps from oscilloscope:

-

same picture with more measurement information:

# Answer
> 3 votes
Just as a complement to chrisl's answer, if you disassemble the compiled program, you should see that your infinite loop looks like this:

```
1:  sts  0x0407, r24  ; write to PORTA_OUTTGL
    rjmp 1b           ; jump back to previous instruction

```

These instructions take two cycles each, for a total of four cycles per loop iteration. The loop is thus expected to run at F\_CPU÷4 = 5 MHz. Since a cycle of the output waveform takes two toggles, you expect to see 2.5 MHz on the oscilloscope.

You should be able to speed this up by writing to the virtual port register `VPORTA_IN` instead of `PORTA_OUTTGL`. Virtual port registers are equivalent to regular port registers, but they are mapped into the I/O space of the microcontroller. This allows the compiler to replace the `sts` instruction by the shorter and faster `out` instruction. The loop should then complete in only 3 CPU cycles and output a waveform at 3.33 MHz.

# Answer
> 1 votes
You are constantly toggling a pin in software. This involves copying the register data to the working register, toggling the bit and writing the result back.

This takes way more than only 1 clock cycle. So the resulting frequency is way lower. With only software you just cannot get near the clock frequency of the microcontroller.

---
Tags: attiny, avr, oscillator-clock, avr-gcc
---


# Question
Title: How to properly use volatile variables in Arduino?
I was doing a small project with an Arduino Uno. It involved interrupts as I am using encoders to measure how much the differential wheel system moves forward. My robot moves only forward. So I use only a single channel from each encoder. Here are my two interrupt routines:

```
ISR (INT0_vect){

      encoderRPos = encoderRPos + 1;

}

ISR (INT1_vect){

  encoderLPos = encoderLPos + 1;

}

```

The variables `encoderRPos` and `encoderLPos` are of type `volatile int`. I understand that the variables which undergoes change in any interrupt routine need to be of type volatile. This is to warn other parts of the code that use these variables that it may change anytime.

But what happened in my code was a bit strange and I could not explain it. Here is how I compute the distance moved by the left wheel:

```
  #define distancePerCount 0.056196868
  float SR = distancePerCount * (encoderRPos - encoderRPosPrev);
  float SL = distancePerCount * (encoderLPos - encoderLPosPrev);

  encoderRPosPrev = encoderRPos;
  encoderLPosPrev = encoderLPos;

```

But when I print the following on my serial monitor, I notice an anomaly:

If you look at the third column, (SL) it's value is too high just for some time. This is upsetting all my calculations.

The only clue I can get it, if I take the value of SL that I got (3682), which is always a constant, and calculate back `(encodeLPos - encoderLPosPrev)`, I will get 65519.66, which is close to the max value of `unsigned int`. Which means `(encoderLPos - encoderLPosPrev)` is causing an overflow while both the values whose difference is taken is somewhere around 5000 only!

And I managed to solve it. It was by luck. This is how I modified the code:

```
  static int encoderRPosPrev = 0;
  static int encoderLPosPrev = 0;

  int diffL = (encoderLPos - encoderLPosPrev);
  int diffR = (encoderRPos - encoderRPosPrev);

  float SR = distancePerCount * diffR;
  float SL = distancePerCount * diffL;

  encoderRPosPrev = encoderRPos;
  encoderLPosPrev = encoderLPos;

```

I can't comprehend what has happened. Is there something about volatile variables that I should have known about?

**Update:** Here is the entire code if you ever want to take a look. And it's working very well after changing it to what was suggested in the accepted answer.

# Answer
> 9 votes
You need to learn about *critical sections*.

What is probably happening is that the variables are being changed by the interrupt routines mid-way through the calculations. Your 'fix' reduces the time spent doing the calculation with the volatile variables thus making it less likely that there is a collision.

What you should do is copy the volatile variables to local variables with interrupts disabled for that brief period.

```
cli();
int l = encoderLpos;
int r = encoderRpos;
sei();

```

Because the Arduino is an 8 bit CPU it takes multiple assembly instructions to perform mathematical operations on 16 bit values. Floating point is even worse using many many instructions for a simple addition. Division and multiplication use considerably more. An interrupt has plenty of opportunity to fire during that list of instructions. By doing an assignment like that and then using the new local variables in your calculations the instructions needed to deal with the volatile variables is kept to an absolute minimum. By turning off interrupts during the assignment you guarantee that the variables can't ever be changed while you are using them. This snippet of code is called a *critical section*.

# Answer
> -1 votes
/\* Hi all and thanks for sharing. From my personal experience here is what I found useful

"A DTMF decoder stores the last DTMF code in bytes in its memory It's STQ pin goes HIGH every time a a new DTMF is detected This is just part of the code focused on ISR (Interrupt) "

```
   Tips when using ISR with Arduino nano and IDE 18.19

```

1: HIGH or LOW only, RISING of FALLING will not get triggered properly with Nano using external digital interrupt.

2: Watch out when using LOW. As per using HIGH in example you need to use flags(event bytes) and possible counters.

3: When you type the attachInterrupt don't use brackets for the void of function you are you are calling, or every time the ISR is triggered it will go from begging of code re-initializing/resetting all global variables no matter if you declare them volatile or static!

4: Delay doesn't work only delayMicroseconds()

5: Keep it short, byte size variables and no complex math if possible

6: Arduino nano external digital ISR pins are 2,3

7: Don't run the void you call in your ISR in the loop().

8: Keep in mind all other comments posted from the other programmers.

\*/

```
/////////////////    Example /////////////////////////////

byte CFlag;     // GLOBAL

byte Counter;   // GLOBAL

#define STQ  3  // GLOBAL

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

pinMode(STQ, INPUT);

attachInterrupt(digitalPinToInterrupt(), DragonBalls, HIGH);
//WhenSTQ PIN GOES HIGH it runs a void function called DragonBalls()

}//end setup

void DragonBalls()

{
    Dpin = digitalRead(STQ);
    delayMicroseconds(10000);
    if      (Dpin == HIGH &&  CFlag ==LOW) {
                                                CFlag=HIGH;
                                                Counter++ ;
                                            }//end if

    else if  (Dpin == LOW  &&  CFlag == HIGH) {
                                                CFlag=LOW;
                                                DragonPrint();//Serial.print staff

                                                }//end else if

}// end DragonBalls(void)

void DragonPrint()

{
    Serial.print(CFlag);
    Serial.print(" = CFlag, Counter = ");
    Serial.println(Counter);

}//end void DragonPrint

```

---
Tags: arduino-uno, interrupt
---


# Question
Title: float miscalculation when int32_t variable is divided by 10
i want to ask, how to get correct float value from uint32\_t or long variable is devided by 10??

```
long var3 = 1139399025;
int a = 3;
int b = 10;
void setup() {
  Serial.begin(9600);
  Serial.println((float)a/b,2);
  Serial.println((float)var3/b,2);
}
void loop() {
}

```

result

```
0.3
113939904.00

```

it give 113939904.00 instead of 113939902.50, plase how to fix that?

# Answer
> 2 votes
1139399025 is not a floating point number: the largest odd integer that can be exactly represented as a `float` is 224 − 1 = 16777215. Then, when `var3` is cast to `float`, it gets rounded to the closest float, which is 1139399040. This is quite a small error, especially considering that, in this range, only multiples of 128 can be exactly represented as floats.

Dividing 1139399040 by 10 gives 113939904, which happens to be a float. The floating point division gives then the *exact* result, which is what gets printed. Indeed, floating point operations do not always give inexact results: sometimes they are exact. However, unless you know what you are doing, exact results only happen by luck. In general, expect each floating point operation to make a *relative* rounding error in the range of 10−7.

A highly recommended read: What Every Programmer Should Know About Floating-Point Arithmetic.

**Edit**: If you want to print the value of an integer divided by 10, you can divide the number using Euclidean division. Print the quotient, then the decimal point, then the remainder:

```
Serial.print(var3 / 10);  // quotient
Serial.print('.');
Serial.println(var3 % 10);  // remainder

```

As these are all integer operations, there is no rounding error involved. Obviously this trick doesn't work for arbitrary divisors.

---
Tags: float, convert
---


# Question
Title: If Arduino digital pins can be used as power supply pins then why do we need VCC pins?
If Arduino digital pins can be used as power supply pins then why do we need VCC pins? VCC pins work the same as digital outputs , don't they? So why do we still need VCC pins to power components

# Answer
> 4 votes
Digital IO pins and Vcc are very different.

When using the digital IO functionality of a pin, the pin is connected to the digital IO hardware inside the microcontroller. This hardware is a driver, that can drive the pin to either LOW or HIGH (0V or Vcc) depending on a bit in a register. Though this driver can only provide a very limited amount of current. The absolute maximum is specified as 40mA peak, but you should not exceed 20mA continuously. So technically you can power a component from a digital pin (just like you can drive an LED through a digital pin), but only if it does NOT draw over 20mA. That is a rather small current. So in general nobody would recommend doing that. If you draw too much current from a digital pin, you can destroy its IO hardware.

The Vcc pin is the power **input** for the microcontroller on the board. The microcontroller needs this to be at the right voltage (5V for the Arduino Uno), to work properly. This power can come from different sources: The voltage regulator (via barrel jack or Vin), USB or directly provided through the Vcc pin. As long as the voltage stays in the correct range, it will work.

You can utilize the Vcc pin to power external components. Though this is just connecting these components to the power supply in parallel with your microcontroller. The current for the components will not be drawn through the microcontroller, but only through the copper traces on the board from your power source. That is also the reason why the power output of the Vcc pin cannot be controlled via software: It is just directly electrically connected to the power source of the microcontroller. Nothing in between.

---

So: Don't power anything other than components with really small current draw from IO pins. If you do it, always make sure beforehand that the current will be small enough (below 20mA).

If the components need more current, you can power them through the Vcc pin. Only use the IO pins for control in that case. For some components (like motors, bright LED lights, etc) you might need additional hardware for controlling them (like a transistor/MOSFET/driver chip).

And keep in mind, that the current through the Vcc pin is also limited. Depending on your power source you can draw up to 1A (including the Arduino itself) from the voltage regulator on a genuine Arduino. If you need to draw more current than that, you need to connect the components to a power source outside of the Arduino. For example you can connect them to the power source, that you connected to the Arduino directly, so that the high current doesn't need to flow through the Arduino, but can directly go to the high power components.

---
Tags: power, pins, digital
---


# Question
Title: ESP8266 module doesn't respond to commands and sends garbage to serial on boot
I bought a ESP8266 module (like this). I connected the module like on the following scheme:

I use a USB to TTL converter (cp2102) that I've connected to RX&TX pins of the module. It works. It successfully transmits data in both ways when I test it with a MCU. I often use it to send debug messages to my PC from a MCU.

I use linux and CuteCom as a program for monitoring the data sent through the serial port.

I supply 3.3V to the module (as required by the manufacturer) from the cp2102 converter (it has both 5V and 3.3V outputs).

**The problem**

The module does not respond to any command I send to it (AT, AT+GMR, AT+RST, ATE0, etc). But it sends to the PC some data on boot (when I attach Vcc to CP\_PD). Most of the data look like garbage, but at the very end I get meaningful data:

```
Ai-Thinker Technology Co.,Ltd.

invalid

```

The baud rate is 115200. No parity, 8-bit characters, 1 stop bit. The full output from CuteCom:

The red LED on the module is always lightning while the power is supplied. During the boot process (approximately first 500 milliseconds) also a blue LED blinks a few times (probably due to sending that mostly-garbage data to the PC I mentioned earlier).

**What have I tried?**

I experimented with the resistor R1, tried: no resistor, 1k, 3k, 10k. I also tried other baud rates (1200, 2400, 4800, 9600, 19200, 38400, 57600). And tried using all the parity types, 2 stop bits and other character lengths. Nothing helped.

Why the module does not respond to any command? Hope for your help! Thanks in advance!

# Answer
> 2 votes
The ESP8266 bootloader outputs messages at that 74880 bits per second. At other speeds the bootloader's messages will look like garbage. Set your terminal speed to 74880 to see them.

On the ESP8266 it can be helpful to also use 74880 bits per second for the `Serial` speed in your program so that you can easily see both your programs output and the boot loader information when your program crashes.

---
Tags: serial, esp8266, uart
---


# Question
Title: Use Arduino MEGA generate 40kHz multiple square wave signal with 10 phase
I want to use Arduino-mega generate multiple square wave signal,the siganl is 40kHz and it can be used to drive ultrasonic transducer.

So,I use the trategy in article "Ultraino: An Open Phased-Array System for Narrowband Airborne Ultrasound Transmission",which apply 10 bit signal with sequence of '0' or '1' in PORTA,PORTC...etc to get a square wave signal like Fig 1.

Fig.1 square wave signal

---

Then I change the sequence pattern to shift phase,and just only 10 phases,some problem happen.

I am curious about the principle of this method:

1. Why the sequence can generate signal with 40kHz?Does it mean Arduino will cost serval microseconds executing command like `POTRA=0x1`. I try to change the length of the array,it will no longer generate the square wave well.
2. When I execute the shift function `shiftPhase`,it have 10 phase.In 5 phase it will move the square wave like Fig.2,the other 5 phase will be like Fig3,the duty of square wave is changed,just like inverted.So,how does it happen,just with change the sequence of 0,1?

Fig.2 shift wave success

---

Fig.3 shift wave failed

---

the code I use is:

```
#include <avr/sleep.h>
#include <avr/power.h>
#define N_PATTERNS 1
#define N_PORTS 10
#define N_DIVS 10
#define COMMAND_SWITCH 0b00000000
#define COMMAND_DURATION 0b00110000
#define MASK_DURATION 0b00111111
#define COMMAND_COMMITDURATIONS 0b00010000

#define WAIT(a) __asm__ __volatile__ ("nop")
#define OUTPUT_WAVE(pointer, d)  PORTA = pointer[d*N_PORTS + 0]; PORTC = pointer[d*N_PORTS + 1]; PORTL = pointer[d*N_PORTS + 2]; PORTB = pointer[d*N_PORTS + 3]; PORTK = pointer[d*N_PORTS + 4]; PORTF = pointer[d*N_PORTS + 5]; PORTH = pointer[d*N_PORTS + 6];  PORTD = pointer[d*N_PORTS + 7]; PORTG = pointer[d*N_PORTS + 8]; PORTJ = pointer[d*N_PORTS + 9]
static byte bufferA[N_PATTERNS * N_DIVS * N_PORTS];
static byte bufferB[N_PATTERNS * N_DIVS * N_PORTS];
static byte animation[100] = {
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
                            };

String str="";
void shiftPhase(byte* p,int len,int inter,int stepsize,byte id)
{
  byte mask=0xff-id;
  byte q[10]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
  for(int i=0;i<10;i++)
  {
    q[i]=p[i*inter];
  }
  for(int i=0;i<10;i++)
  {
    p[i*inter]=(q[(i+stepsize+10)%10]&id)|(mask&q[i]);
  }
}

void setup()
{
  //set as output ports A C L B K F H D G J
  DDRA = DDRC = DDRL = DDRB = DDRK = DDRF = DDRH = DDRD = DDRG = DDRJ = 0xFF;
  //low signal on all of them
  PORTA = PORTC = PORTL = PORTB = PORTK = PORTF = PORTH = PORTD = PORTG = PORTJ = 0x00;
  //clear the buffers
  for (int i = 0; i < (N_PATTERNS * N_DIVS * N_PORTS); ++i) {
    bufferA[i] = bufferB[i] = 0;
  }
   for (int i = 0; i < 100; ++i)
   {
      bufferA[i] =  animation[i];
   }

  // disable everything that we do not need
  ADCSRA = 0;  // ADC
  power_adc_disable ();
  power_spi_disable();
  power_twi_disable();
  power_timer0_disable();
  power_usart1_disable();
  power_usart2_disable();

  Serial.begin(9600);

  byte bReceived = 0;
  bool byteReady = false;
  bool emittingA = true;
  byte* emittingPointerH = & bufferA[0];
  byte* emittingPointerL = & bufferA[N_PORTS * N_DIVS / 2];

LOOP:
  OUTPUT_WAVE(emittingPointerH, 0);
  OUTPUT_WAVE(emittingPointerH, 1);
  OUTPUT_WAVE(emittingPointerH, 2);
  OUTPUT_WAVE(emittingPointerH, 3);
  OUTPUT_WAVE(emittingPointerH, 4);
  OUTPUT_WAVE(emittingPointerL, 0);
  OUTPUT_WAVE(emittingPointerL, 1);
  OUTPUT_WAVE(emittingPointerL, 2);
  OUTPUT_WAVE(emittingPointerL, 3);
  OUTPUT_WAVE(emittingPointerL, 4);

  byteReady = Serial.available();
  if(byteReady!=0)
  {
      str="";
      str=char(Serial.read());
      Serial.println(str);
      if(str=="1")
      {
        shiftPhase(bufferA,10,10,1,0x1);
      }
      if(str=="2")
      {
        shiftPhase(bufferA,10,10,-1,0x1);
      }
    }
 while(Serial.read()>=0){}
  goto LOOP;

}

void loop() {}

```

Thanks a lot!

The code of the article can be see in link.

# Answer
> 1 votes
Shiny100 asked:

> Does it mean Arduino will cost several microseconds executing command like `POTRA=0x1`.

I tried compiling `POTRA=0x1` and I got this:

```
ldi r24, 0x01  ; load 0x1 into register r24
out 0x02, r24  ; output register r24 to PORTA (I/O address 0x02)

```

These are both single cycle instructions, so the sequence takes 2 cycles, i.e. 0.125 µs at 16 MHz. Your code, however, does a lot more that that. The macro `OUTPUT_WAVE()` involves reading ten values from RAM and writing them to ten different ports. The first call to this macro gets compiled into this:

```
lds r24, 0x028D ; r24 = bufferA[0]
out 0x02, r24   ; PORTA = r24
lds r24, 0x028E ; r24 = bufferA[1]
out 0x08, r24   ; PORTC = r24
lds r24, 0x028F ; r24 = bufferA[2]
sts 0x010B, r24 ; PORTL = r24
lds r24, 0x0290 ; r24 = bufferA[3]
out 0x05, r24   ; PORTB = r24
lds r24, 0x0291 ; r24 = bufferA[4]
sts 0x0108, r24 ; PORTK = r24
lds r24, 0x0292 ; r24 = bufferA[5]
out 0x11, r24   ; PORTF = r24
lds r24, 0x0293 ; r24 = bufferA[6]
sts 0x0102, r24 ; PORTH = r24
lds r24, 0x0294 ; r24 = bufferA[7]
out 0x0b, r24   ; PORTD = r24
lds r24, 0x0295 ; r24 = bufferA[8]
out 0x14, r24   ; PORTG = r24
lds r24, 0x0296 ; r24 = bufferA[9]
sts 0x0105, r24 ; PORTJ = r24

```

The `out` instruction is still single cycle, but `lds` (load from memory) and `sts` (store to memory) take two cycles each. You may notice that only ports A through F are accessed with the `out` instruction. This is because they are mapped in the I/O address space of the microcontroller. The other four ports are accessed using the slower `sts` instruction on memory-mapped addresses.

If you count your cycles, you should get 34 cycles for the whole sequence, which is 2.125 µs at 16 MHz. Ideally, you would like this to take 2.5 µs (1/10 of a cycle of a 40 kHz signal). You may notice that the code you took inspiration from has a few instructions between successive calls to `OUTPUT_WAVE()`. It looks to me like those were carefully timed to get as close as possible to 2.5 µs per phase. This approach is obviously fragile: any tiny change in the code, or even a compiler upgrade, can throw off your carefully timed code.

**Edit**: The second question, if I understand it correctly, is about the change in duty cycle. The waveforms have a *nominal* duty cycle of 50%: the signal is LOW over 5 time slots (5/10 of the cycle), then HIGH for the next 5 time slots. The time slots, however, do not have all the same length. The first nine last 2.125 µs each. The last one, however, is somewhat longer, because it takes the duration of the code handling the serial port, and the two cycles of `goto LOOP;`. If the longer time slot happens when the output is HIGH, you get an actual duty cycle higher than 50%. If it happens when it is HIGH, you get a shorter duty cycle, like in your “shift wave failed” example.

---
Tags: arduino-mega
---


# Question
Title: How to reset flow control that prevents me from reading data from ESP8266?
I have a ESP8266 module (like this). I ran a command `AT+UART_DEF=115200,8,1,0,3` as mentioned in documentation of ESP8266 SDK to change the baud rate of my ESP8266 module. It seems like by running this command I bricked my ESP because now the module does not respond to any command (tried 9600, 74880, 115200 baud rates) and all the data that is sent after the bootloader messages on 74880 baud rate is garbage. The last argument of the above command sets the flow control to "both RTS and CTS" (3), but I don't have those pins. The module's pinout:

So I suppose on my ESP I can't use hardware flow control. (Or I can?)

I still can receive bootloader's message that is sent on boot on baud rate 74880 bps:

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

load 0x40100000, len 6960, room 16
tail 0
chksum 0x4f
load 0x3ffe8008, len 24, room 8
tail 0
chksum 0xc6
load 0x3ffe8020, len 3196, room 8
tail 4
chksum 0x3a
csum 0x3a
user code done

```

But all the data that is sent after the bootloader is garbage:

To clarify, before running the `AT+UART_DEF` command I could receive meaningful data and execute commands on baud rate 115200 bps.

I'm not sure if the command I ran is the problem, so please point me out if I'm wrong. As per documentation:

```
The configuration changes will be saved in the NVS area, and will still be valid when the chip is powered on
again.

```

The new UART settings along with the flow control settings are stored in NVS area. Is it possible to reset it? Or any other way to reset the flow control?

**What have I tried?**

I tried to erase all the flash memory of the module using `esptool`: `erase_region 0x0 0x1000000` and then tried to flash the latest AT firmware again. Didn't help. It still receives bootloader messages and some garbage data.

How can I unbrick my ESP? Hope for your help! Thanks in advance!

# Answer
You can't brick an ESP8266 through software.

You can confirm this by flashing a different, very simple program to it, like this:

```
#include <Arduino.h>

void setup() {
  Serial.begin(74880);
  delay(1000);
  Serial.println("hello world");
}

loop() {
}

```

With the serial monitor set to 74880 bits per second, you should see the bootloader messages as well as a single line of "hello world".

You also should completely erase the contents of the flash chip, not just a particular region.

```
esptool.py erase_flash

```

Afterwards you'll need to reinstall the firmware you were trying to run.
> 0 votes

---
Tags: esp8266, uart, reset
---


# Question
Title: Touching a capacitive button, non-mechanically
This is not about using a capacitive button to control an Arduino; it is the opposite. I would like to "touch" a capacitive button on another conventional device. There could be a way like actually moving a finger-like stick and touch the button, but that is too much work. Can't it be done non-mechanically?

According to this page ( https://scienceline.org/2012/01/okay-but-how-do-touch-screens-actually-work/ ), "Instead, they work with anything that holds an electrical charge – including human skin.". Then, can I emulate "touching" the button by sending some small electrical current?

If so, what module/parts do I need to send such small current?

# Answer
> -1 votes
The simply way is making a little capacitor. Cut 2 circle with aluminium from a can and put a paper between them, then solder one one to one circle and other to the other side. One wire goes to the positive and the other to the I/O. When you set to 1 it should create a capacitive charge and "touch" de button.

---
Tags: electricity
---


# Question
Title: Arduino Uno "WiFi Developer Edition" - How to disable WiFi?
I'm using Arduino Uno "Wifi Developer Edition". I made my Arduino to get connected with my local network based on http://www.arduino.org/learning/getting-started/getting-started-with-arduino-uno-wifi

Now I would like to disable it and work with USB serial communication to upload sketches. But now I'm unable to upload sketches even if I select the serial port. I'm getting an AVRDUDE : seropen() Access is disabled error. I could perfectly do uploading if I select the networked port of the same Arduino.

Can I know why ?

# Answer
> 1 votes
You don't need to disable the Wi-Fi. The serial works with the Wi-Fi enabled. You need to first install the driver and then select the Serial port on the Arduino IDE.

# Answer
> 0 votes
The reason why "Arduino WiFi Dev Ed" USB upload sometimes doesn't work, is the esp8266 connected to UART of Atmega for the OTA upload. If esp8266 doesn't boot, it doesn't set pin 4 to disconnect from Atmega UART and the connection to UART stays and disturbs the upload from IDE.

The esp8266 hangs sometimes, because it has pin 2 floating on this board, but there is a trace and a soldering point on the bottom of the board for pin 2. If it is touched or otherwise grounded the esp8266 doesn't boot until the potential on the pin rises.

More about Uno WiFi Dev Ed hardware here.

---
Tags: communication, avrdude, arduino-uno-wifi-dev-ed
---


# Question
Title: How do I wake the ESP8266 from deep sleep on a specific date and time?
I'd like to put my ESP8266 into deep sleep and then wake it up at at specific date and time, \[roughly\] to the second.

Edit: Unfortunately, ESP8266 deep sleep doesn't support values greater than about 3.5 hours. I tried sleeping for an hour at a time until the desired time is reached, but found that it's not very accurate; often dozens seconds of drift on each wake, adding up to many minutes of drift after several hours.

Edit: I want to wake every 24 hours at a specific time. A few seconds per week drift is more than acceptable, as I'll be re-syncing the clock every 24 hours or so.

Edit: I'm using `WAKE_RF_DISABLED` to disable WiFi to save power on wake, so when it wakes up, there is usually no internet connection to check the time (I want to connect to WiFi only once every 24h).

# Answer
Since the ESP8266 doesn't have a *real* onboard RTC (i.e. it's not capable of keeping very accurate time while in deep sleep) and is limited to a short time period, one solution is to use an external RTC (real time clock) but there is a way of doing it without.

Below are 3 approaches, the first two involve a DS3231 RTC (quite easy to get as a module). For low power, I prefer DS3231 over DS1307, since DS3231 modules seem to work fine at 2.6V (whereas DS1307 modules seem to require at least 3.3V... or more like 4.5V according to the datasheet). The 3rd approach is useful if you don't want to add an external RTC.

> "The DS3231 is a low-cost, extremely accurate I2C real-time clock (RTC)". The DS3231 "maintains the RTC to within ±2 minutes per year accuracy from -40°C to +85°C"

**Solution 1: Periodically wake the MCU and check the external RTC**

Probably, the most energy efficient solution (compared to using the alarm solution below) would be to wake the ESP8266 from deep sleep periodically to check the time on the external RTC and depending on desired accuracy, deep sleep for shorter periods as you approach the target wake time (e.g. wake and check the RTC every minute once you're about 10 mins away from the target time).

To save power, before sleeping the ESP8266, you can simply use a transistor connected to GPIO to turn off the Vcc power supply on the DS3231 module (it'll use the onboard 2032 battery while no power is supplied). Don't forget to turn off the I2C pull-ups too, as they can provide parasite power to the RTC. You can also just disconnect GND.

If restarted with WiFi off (`ESP.deepSleep(1e6, WAKE_RF_DISABLED)`), the ESP8266 only needs to wake for about 200 ms consuming 20 mA to check the DS3231 if it's time to wake up fully. This is probably the most energy efficient you can get with wanting to keep accurate time.

**Solution 2: Set an alarm on the external RTC to wake the MCU**

Using the DS3231, the SQW pin can be connected to the ESP8266 RST pin via a monostable circuit. The monostable circuit is important because the RST pin can't stay low, as it won't boot. The monostable circuit creates a pulse on the RST pin when the DS3231 SQW pin goes low.

A note on power consumption: The ESP8266 should consume only 20 µA in deep sleep, but DS3231 modules actually tend to use about **1 mA** when powered on (which is required to trigger the alarm), probably because of the EEPROM on the module. That power consumption is significant if you're designing a low power system. This is why this 2nd solution is less energy efficient compared to the 1st solution.

The following code will set an alarm to a specific time, and when the RST pin is pulled low (based on the SQW output of the DS3231), the ESP8266 then wakes up. Make sure you uncomment `SLEEP_DT` and set a date and time to wake at a specific date and time (of course, you can set this programmatically to any date and time), otherwise it'll wake up every *n* seconds (value of `SLEEP_SECONDS`) but that might also be useful (ESP8266 deep sleep time isn't very accurate).

```
#include <ESP8266WiFi.h>

// TODO: NTPClient is redundant; replace with native
// ESP8266 NTP functions (configTime and localtime)
#include <NTPClient.h>
#include <WiFiUdp.h>

#include <RTClib.h>

#define WIFI_SSID "Your WiFi SSID"
#define WIFI_PASS "Your WiFi password"

// uncomment to wake up at specific date and time
//#define SLEEP_DT
#define SLEEP_DT_YEAR 2022
#define SLEEP_DT_MONTH 12
#define SLEEP_DT_DAY 02
#define SLEEP_DT_HOUR 15
#define SLEEP_DT_MINUTE 50
#define SLEEP_DT_SECOND 25

#define SLEEP_SECONDS 10 // easier for testing

RTC_DS3231 rtc;
WiFiUDP udp;
NTPClient ntp(udp);

void print_date(const DateTime& dt);

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

  Serial.println('\n');
  Serial.println("Hello RTC wake deep sleep");

  Serial.println("Init DS3231");
  if(!rtc.begin()) {
    Serial.println("DS3231 failed");
    while (true) { delay(1); }
  }

  // not needed
  rtc.disable32K();

  // not used
  rtc.disableAlarm(2);

  // apparently can lead to problems if not cleared
  rtc.clearAlarm(1);
  rtc.clearAlarm(2);

  // stop oscillating; allows alarm to work
  rtc.writeSqwPinMode(DS3231_OFF);

  Serial.println("Init WiFi");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  Serial.println("Connecting to " WIFI_SSID);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  Serial.print("Connected, IP: ");
  Serial.println(WiFi.localIP());

  ntp.begin();
  bool ntpOk = ntp.update();

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, setting time");
    if (ntpOk) {
      Serial.println("Using time from NTP client");
      rtc.adjust(DateTime(ntp.getEpochTime()));
    }
    else {
      // untested code
      Serial.println("NTP unavailable, using time of build");
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }
  }

  Serial.print("Date and time set to: ");
  print_datetime(rtc.now());

#ifdef SLEEP_DT

  DateTime alarm(
    SLEEP_DT_YEAR,
    SLEEP_DT_MONTH,
    SLEEP_DT_DAY,
    SLEEP_DT_HOUR,
    SLEEP_DT_MINUTE,
    SLEEP_DT_SECOND);

  Serial.print("Setting alarm for date: ");
  print_datetime(alarm);

  if (!rtc.setAlarm1(alarm, DS3231_A1_Date)) {
    Serial.println("Failed to set alarm");
  }

#else

  // sleep for set seconds for the purposes of testing
  Serial.print("Setting alarm for seconds: ");
  Serial.print(SLEEP_SECONDS);
  Serial.println(" seconds");
  if (!rtc.setAlarm1(rtc.now() + TimeSpan(SLEEP_SECONDS), DS3231_A1_Second)) {
    Serial.println("Failed to set alarm");
  }

#endif // SLEEP_DT

  Serial.println("Going into deep sleep (wake on RST low)");
  Serial.flush();
  ESP.deepSleep(0);
}

void print_datetime(const DateTime& dt) {
  char df[] = "YYYY-MM-DD hh:mm:ss";
  Serial.println(dt.toString(df));
}

void loop() { }

```

Here it is in action...

Note: The time jumps because I chopped out a few frames to save you from being bored (no smoke and mirrors, I promise).

**Solution 3: Use only the internal RTC**

Keeping with the low power theme: to use the internal RTC in deep sleep, you have to keep sleeping for *n* seconds until desired seconds elapse. You can keep track of how many seconds have elapsed by using the RTC memory. This approach allows you to implement time keeping without having to add an external RTC, and without having to reconnect connect to WiFi every hour. However, I have found the drift to be quite substantial (many seconds per hour), so this is probably useful only when accuracy is not a major concern.
> 3 votes

---
Tags: esp8266
---


# Question
Title: Anyone had Digispark Attiny85 not SEEN by some USB controllers but seen via HUB or DOCK on same device?
I have purchased a couple of different types of DigiSpark Attiny85 clones (couldn't find originals available) and they have worked great except some devices (so far, just laptops) don't see the device AT ALL.

It's not that they don't recognise it and so is a driver issue - there is nothing to apply the driver to, no indication that the thing is even plugged in other than the light comes on (so I know it has power).

More frustratingly, if I plug the Digisparks in to any problematic device via a docking station, USB hub, etc. everything works as expected (confirming the drivers are ok) and I can write scripts to the digispark.

I've tried updating the Nucleous bootloader but the problem persists. I get this problem on three modern laptops (HP & 2 Dells) but my older Lenovo laptops have no problems. Not sure if here is an issue with modern USB controllers?

UPDATE: Everything points towards it just being an issue with Digispark's and some USB 3.0 controllers. The clock is correctly set at 16.5Mhz so not sure what else to do other than write these-off as a reliable device.

Anyone had any experience of this or have any suggestions?

Thanks!

# Answer
> 0 votes
It appears the problem is down to issues around Attiny85 timing with USB 3.0 chipsets and so isn't something that can be solved.

# Answer
> 0 votes
The four USB traces on the digistump board are NOT to perfect specification and don't work with 4/5 conductor USB3 ports. Use a dremel or band saw and cut about 2/3 of the end off the digistump Printed Circuit Board USB plug. Leave enough of the original four traces to solder to. Cut off the plug end from an older USB cord. After carefully cutting away and cleaning off the plastic and old wires on the actual USB plug, it fits perfectly to line up to the old (now shorter) traces on the digistump. Be sure trace sides are the same direction on old and new plug and solder all four connections. Add some superglue and/or silicone for strength and it should work every time with any USB port.

WZ

---
Tags: attiny85, digispark
---


# Question
Title: Slow WiFi reconnection after deep sleep (6 to 10 seconds)
With my ESP8266, I need to make a simple GET request to a server, and then go to deep sleep (the goal is 1 year battery powered)... until a signal comes on `RST` and then it starts again.

The following code works, but **it takes 6 to 10 seconds on each `RST` to get connected to my home WiFi using "WPA2 Personal"** (when it stops blinking in my code).

**Is this 6 to 10 seconds delay normal, do you have the same order of magnitude?** Or can we go down to 1 second, after a wake-up from deep sleep?

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
WiFiClient client;
HTTPClient http;
void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
    if (WiFi.SSID() != WIFI_SSID) {     // don't do begin if not necessary, see tutorial link after
        WiFi.begin("MySSID", "MyPassword");
        WiFi.persistent(true);
        WiFi.setAutoConnect(true);
        WiFi.setAutoReconnect(true);
    }
    while(WiFi.status() != WL_CONNECTED) {
      digitalWrite(LED_BUILTIN, LOW); delay(10); digitalWrite(LED_BUILTIN, HIGH); delay(200);  // blinking
    }
    http.begin(client, "http://example.com/request.php");
    http.GET();
    http.end();
    digitalWrite(LED_BUILTIN, LOW); delay(500); digitalWrite(LED_BUILTIN, HIGH); delay(500);
    ESP.deepSleep(0);
}
void loop() {
}

```

Note: I have read and carefully respected this useful information about low power / battery-powered ESP8266:
Power Saving tips for the ESP8266 (especially this paragraph):

> Do not call WiFi.begin() in setup().
> The ESP8266 chip saves the last known wifi settings. Calling WiFi.begin() wipes those out. By calling WiFi.begin() only when it was needed, I shaved more than 2 seconds from the average amount of time it takes to associate with the AP. WiFi.begin() should be called only if the saved SSID does not match the configured SSID. You can check the configured SSID with the WiFi.SSID() call. Also, it is good practice to clear the saved WiFi settings if the timer expires. (See next section "Use watchdog timers")

# Answer
> 4 votes
It is in general take around 6s for the ESP to scan all the 2.4GHz Wi-Fi channels to find the SSID and the associated BSSID (i.e. Mac Address), you can eliminate the scanning time by connecting using BSSID.

Using a static IP instead of rely on DHCP server to assign an IP would further reduce the WiFi connecting time by another 500ms.

See one of my project (under the "ESP8266 WiFi - How to speed up connection" section) where I cut the connection time from 6s down to about 2s.

Code signature for WiFi.begin with BSSID here:

```
    const byte WIFI_BSSID[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD, 0, WIFI_BSSID);

```

For calculating IoT battery consultion, use IoT battery life calculator.

---
Tags: esp8266, wifi, battery
---


# Question
Title: How to bring WiFi back up if woken from deepSleep(WAKE_RF_DISABLED)
I'm trying to build a sensor that should update an MQTT broker only if something changes. So every few seconds it's supposed to wake up just enough to check a few inputs, compare them with the last time it woke up, and only if there has been a change should it connect to the broker and write the updates. I don't expect many updates per day, but if I sleep more than 10 seconds, I might miss them.

I'm using `WiFi.forceSleepBegin()` and `WiFi.forceSleepWake()`, mainly based on these articles. But there is this tempting option of `ESP.deepSleep(n, WAKE_RF_DISABLED)`

The API that I found only mentions this:

> If you implement deep sleep with WAKE\_RF\_DISABLED and require WiFi functionality on wake up, you will need to implement an additional WAKE\_RF\_DEFAULT before WiFi functionality is available.

Do I read this correct if I understand that I would need to make another `deepSleep` just to wake up again with WiFi back active? Or is there an easier way to boot up the WiFi after such a sleep?

Thank you

# Answer
```
WiFi.forceSleepBegin();
delay(1);
WiFi.forceSleepWake();
delay(1);

```

Source: GitHub

That also works, I tested it December 2020. Thanks to Erik Bakke for finding it. It's a bit more clean than another Deep Sleep boot with the modem enabled. Igrr and I both struggled to find a way to wake the modem, and Erik mixed the magic sauce. Hopefully it still works today with the changes to the core WiFi files.
> 3 votes

# Answer
Yes, you understood correctly; after using `ESP.deepSleep(n, WAKE_RF_DISABLED)` to disable WiFi, the most reliable method to re-enable it is to call `ESP.deepSleep(1, WAKE_RF_DEFAULT)`. Then connect to WiFi on the next wake (which should be in 1 second). Apparently, `WAKE_RFCAL` and `WAKE_NO_RFCAL` also result in WiFi working.

A cheap way to approach this, is to normally sleep with `WAKE_RF_DISABLED` but when your WiFi connection fails, sleep with `WAKE_RF_DEFAULT` to make the next connection more likely to be successful.

If you want a more elegant, but slightly more complex solution, you can use the RTC memory to store the known WiFi state when you sleep; so when you sleep with `WAKE_RF_DISABLED`, you'll know that you'll have to reset with `WAKE_RF_DEFAULT` before trying to connect. And, when you wake again, you'll know the WiFi has been enabled.

As mentioned in another answer, after using `WAKE_RF_DISABLED`, you could call `WiFi.forceSleepBegin()` and then immediately call `WiFi.forceSleepWake()` to try to bring the WiFi back up without resetting. While I have actually found this to work, sadly it seems to be unreliable. Seems like it might work while on USB power, but when changing to another power source, it stops working. I'm not sure why. When using that approach, sometimes the MCU will consume only 40 mA when it's supposed to consume 70 mA with WiFi on, so this suggests to me that the WiFi doesn't properly initialize.

All that being said, I would suggest that using `WAKE_RF_DISABLED` is quite extreme. Like in your original solution, I have found that you can avoid using `WAKE_RF_DISABLED` altogether if you call `WiFi.forceSleepBegin()` immediately when the device starts (i.e. at the top of your `setup()` function), and then `WiFi.forceSleepWake()` when you want to use WiFi. When the device starts, there is only perhaps 50-100ms when the device is using 70mA before WiFi is turned off. This is probably acceptable for most low power designs.
> 2 votes

---
Tags: esp8266
---


# Question
Title: What is the best (fastest and most robust) way to send messages back and forth between Python on a PC and an Arduino, over serial?
I am trying to communicate between a PC running Python using PySerial and an Arduino. The Arduino itself has a CAN shield, and is responsible for interfacing with a motor. My goal is for the PC to construct the desired CAN frame (8 bytes), send it over Serial to the Arduino, which then itself uses a CAN library to speak to the motor. The motor then send a return frame of the same size, which the Arduino copies to an array, and also prints it to serial.

This works in some cases, although I'm struggling to make it robust. As an example, I am driving the motor in torque control mode (Command 37 in this datasheet). For an arbitrary forward torque of '50', the sending frame should be:

```
[161, 0, 0, 0, 50, 0, 0, 0]

```

And for a command of '-50', the frame should be:

```
[161, 0, 0, 0, 206, 255, 255, 255]

```

I didn't appreciate this would be an issue, but my guess is that because this actually requires more characters, it takes longer to send. Positive torque commands are sent with no issues, while the negative ones cause the motor to skip or judder. I can see that the Arduino isn't actually receiving the correct command at times, see below (left is sent frame from Python, and right is what the Arduino receives printed straight back).

I have tried:

1. Flushing serial buffers before and after sending messages, on both devices
2. Adding delays to try and slow the communication down
3. Changing baudrates
4. Trying to use Serial.write() instead of Serial.print() as I assumed it might be faster (?)

I have attached my code below, but in general, ***what is the best way to communicate over serial between Python and Arduino, robustly and quickly? Even if my current application is ignored, what might ideal scripts for each look like?***

Python:

```
    def serial_begin(self, baud, com):
        self.ser = serial.Serial(com, baud)
        self.ser.flushInput()
        self.ser.flushOutput()
        print("Connected to Serial Port " + com)
        t.sleep(1)

    def send_cam_frame(self, frame):

        self.send_frame = frame
        string_to_send = "<" + str(int(frame[0])) + "," + \
                         str(int(frame[1])) + "," + \
                         str(int(frame[2])) + "," + \
                         str(int(frame[3])) + "," + \
                         str(int(frame[4])) + "," + \
                         str(int(frame[5])) + "," + \
                         str(int(frame[6])) + "," + \
                         str(int(frame[7])) + ">"

        self.ser.write(string_to_send.encode('UTF-8'))
        self.receive_can_frame()

    def receive_can_frame(self):
        get_data = self.ser.readline().decode('UTF-8', errors='ignore')[0:][:-2]
        self.receive_frame = np.fromstring(get_data, dtype='int', count=8, sep=' ')

    def set_torque(self, torque):

        self.command = self.command_list["SET_TORQUE"]

        torque = int(self.constrain(torque * 2000 / 32, -2000, 2000))
        frame = [self.command, 0, 0, 0, torque & 0xFF, (torque >> 8) & 0xFF, (torque >> 16) & 0xFF,
                 (torque >> 24) & 0xFF]
        self.send_cam_frame(frame)

def main():

    arduino_port = "COM5"  # Default COM port
    baud_rate = 57600  # Default Baud Rate

    rmd = Motor()
    rmd.serial_begin(baud=baud_rate, com=arduino_port)

    set_torque = 0

    while True:
        try:

            if keyboard.is_pressed('w'):
                set_torque += 0.001
            if keyboard.is_pressed('s'):
                set_torque -= 0.001

            rmd.set_torque(set_torque)

        except KeyboardInterrupt:
            rmd.disable_motor()
            print("Keyboard Interrupt")

```

Arduino:

```

byte recvFrame[8] = {0, 0, 0, 0, 0, 0, 0, 0};
byte sendFrame[8] = {0, 0, 0, 0, 0, 0, 0, 0};

// Serial Read Parameters
const byte numChars = 32;  // Length of received char array from Serial
char receivedChars[numChars];  // Received char array from Serial
char tempChars[numChars];        // Temporary array for use when parsing
bool newData = false;  // Flag to check if newData has been received

void setup() {
  Serial.begin(57600);
  delay(1000);

}

void loop() {

  CANMessage frame;

  frame.id = 0x140 + 1;
  frame.len = 8;

  // Do not touch this section
  recvWithStartEndMarkers();  // Check Serial and receive data if there is newData
  if (newData == true) {
      strcpy(tempChars, receivedChars);  // Copy variables to prevent them being altered
      parseData();  // Parse data (split where there are commas)

      for (int i = 0; i  < 8; i++){
        frame.data[i] = sendFrame[i];
      }

      can.tryToSend(frame);

      newData = false;  // Set to false
  }

  if (can.available()){
    can.receive(frame);
  }

  for (int i = 0; i < 8; i++){
    recvFrame[i] = frame.data[i];
  }

  printFrame();

}

// Do not touch this function
void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

// Only touch this function if more data is being sent from Python code
void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempChars,",");
    sendFrame[0] = atoi(strtokIndx);

    strtokIndx = strtok(NULL,",");
    sendFrame[1] = atoi(strtokIndx);

    strtokIndx = strtok(NULL,",");
    sendFrame[2] = atoi(strtokIndx);

    strtokIndx = strtok(NULL,",");
    sendFrame[3] = atoi(strtokIndx);

    strtokIndx = strtok(NULL,",");
    sendFrame[4] = atoi(strtokIndx);

    strtokIndx = strtok(NULL,",");
    sendFrame[5] = atoi(strtokIndx);

    strtokIndx = strtok(NULL,",");
    sendFrame[6] = atoi(strtokIndx);

    strtokIndx = strtok(NULL, ",");
    sendFrame[7] = atoi(strtokIndx);

    // How to add a new variable
    // Currently, data is sent as <0, 0, 0, 0>
    // If a fourth parameter was to be sent (<0, 0, 0, 0, 1>), the following lines need to be added

    // strtokIndx = strtok(NULL, ", "); This reads the string, from where it was previously cut, up until the next comma
    // newVariableName = atoi(strtokIndx); atoi is 'to integer'. If newVariable is a float, atof is needed etc

}

void printFrame(){

  for (int i = 0; i < 8; i++){
    Serial.print(sendFrame[i]);
    Serial.print(" ");
  }
  Serial.println();
  //Serial.write(sendFrame, 8);
  //delay(3);

}

```

N.B: I have removed some of the unnecessary functions from both scripts (e.g: the rest of the Motor class for the Python, and the CAN Shield setup from the Arduino) for clarity.

# Answer
There is no best way, but there is a better way (and more efficient way).

> For an arbitrary forward torque of '50', the sending frame should be:
>
> \[161, 0, 0, 0, 50, 0, 0, 0\]
>
> And for a command of '-50', the frame should be:
>
> \[161, 0, 0, 0, 206, 255, 255, 255\]

Most of the programmers who are new to embedded program, prepare their data to be send via communication as string instead of sending raw binary data, the problem is that

1. to send a value of 215, you are sending 3 bytes of ASCII('2', '1', '5') while the data can actually sent by one single byte.
2. both integer 256 (`0x0100`) and 32766 (`0x7FFE`) only took up two bytes, but when you encode it as ASCII, you are dealing with various length from 3 chars to 5 chars. This not only take more bytes to send the data but also make parsing of the data more difficult unless you had some delimiter to separate the data, e.g. ("256,32766" separated by comma).

Looking at your data set and datasheet, it is clear that the each data point is represented by a 4-byte signed data with small endian (i.e. the lower byte get send first), so decimal `50` is `0x00000032`, it is store in memory as `0x32, 0x00, 0x00, 0x00` with small endian.

A negative value is represented in two's compliment of the positive value, so `-50` in decimal is `0xFFFFFFCE` and stored as `0xCE, 0xFF, 0xFF, 0xFF`.

In python, the struct library allows you to converts between Python values and C structs represented as Python bytes objects.

```
form struct import *

torque = -50

data = pack('<i', torque) # pack torque as a 4-byte integer with little endian
ser.write(torque)         # send over serial as bytes

```

On the Arduino side, read the data from Serial as `byte`(i.e. `uint8_t`) and store it in an array. You can then convert it back to a `int32`.

```
// assuming you had read these 4 bytes of data from Serial and add them into an array
uint8_t data[4]{0xCE, 0xFF, 0xFF, 0xFF};

// Convert received data bytes to int32_t
int32_t torque = static_cast<int32_t> (data[3]<< 24 | data[2] << 16 | data[1] << 8 | data[0]);

// This will return result of -50
Serial.println(torque);

```

This should reduce the code and improve the efficiency of the sending the data significantly.

The code along however does not improve the reliability, one advantage of sending data as string is that you could determine the end of data stream by detecting the `\0` terminator at end of the string. When sending raw binary, ideally you need to have the mechanism to signify the number of bytes the data of bytes that you are going to send over.
> 2 votes

---
Tags: serial, motor, communication, python, serial-data
---


# Question
Title: ESP32- Sporadic slow receive of MQTT messages
**Problem description:** Every ~20+ published messages (using terminal), MCU receives that message in a very noticeable delay (mostly ~10 sec, few time it got up to 1 min). Upon receive (printed in Serial monitor), MCU is working as expected.

**Hardware:** ESP32 DEVKIT MCU, `PubSubClient.h` for MQTT and `WiFi.h` for WiFi.

**Important remark:** Code is same for ESP8266 and ESP32.This behavior happens **only** on ESP32.

**Question:** Does ESP32 has a know issue regarding receiving MQTT messages? is there a workaround? or perhaps- bug in code?

What did I do to try isolating the problem:

1. Tried on 3 different ESP32s (2 DEVkit MCU, and 1 with relays on board) - same behavior - it is not an specific MCU hardware problem.
2. Used another PC to publish MQTT messages (via terminal. MAC and Linux, and a 3rd party MQTT App)- no change. It has nothing to do with publishing platform.
3. To rule out it may be a MQTT broker's fault (Local RPI3 connected using LAN cable)- Subscribing to that topic in order to see if the delay repeats . MQTT server receive pubs on time. Broker responds on time (while waiting to see when publish is received in Serial monitor).
4. adding a flashing LED every 200ms in `loop()`, to verify that MCU is not get stuck in a process. `loop()` is looping as expected (see in code below).
5. Spitting heap free memory to Serial monitor, in order to see if there is some memory issue, degradation. Nothing suspicious.
6. Code simplification- used code segments from ESP32 wifi and MQTT pubsub's example, while disabling every functionality of original code(with and without). Delay still happens sporadically.

**OUTPUT1**\- sending "0" and "1" almost simultaneously, almost 15 sec delay

```
13:31:21.516 -> Message arrived [myHome/test] 0 <--- right after this, "1" was sent
13:31:22.510 -> 278616 <---- free heap size (send every 1000 ms. non-blocking)
13:31:23.570 -> 278616
13:31:24.630 -> 278616
13:31:25.657 -> 278616
13:31:26.718 -> 278616
13:31:27.778 -> 278616
13:31:28.805 -> 278616
13:31:29.866 -> 278616
13:31:30.926 -> 278616
13:31:31.954 -> 278616
13:31:33.014 -> 278616
13:31:34.075 -> 278616
13:31:35.102 -> 278616
13:31:35.964 -> Message arrived [myHome/test] 1 <--- received 15 sec later

```

**OUTPUT-2:** Code

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

WiFiClient espClient;
PubSubClient client(espClient);

const char *mqtt_server = "192.168.2.100";

void setup_wifi()
{

        delay(10);
        // We start by connecting to a WiFi network
        Serial.println();
        Serial.print("Connecting to ");
        // Serial.println(ssid);

        WiFi.mode(WIFI_STA);
        WiFi.begin("iot", "GdS");

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

        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
}

void callback(char *topic, byte *payload, unsigned int length)
{
        Serial.print("Message arrived [");
        Serial.print(topic);
        Serial.print("] ");
        for (int i = 0; i < length; i++)
        {
                Serial.print((char)payload[i]);
        }
        Serial.println();

        // Switch on the LED if an 1 was received as first character
}

void reconnect()
{
        // Loop until we're reconnected
        while (!client.connected())
        {
                Serial.print("Attempting MQTT connection...");
                // Create a random client ID
                String clientId = "ESP8266Client-";
                clientId += String(random(0xffff), HEX);
                // Attempt to connect
                if (client.connect(clientId.c_str()),"guy","kupelu9e")
                {
                        Serial.println("connected");
                        // Once connected, publish an announcement...
                        client.publish("myHome/log", "hello world");
                        // ... and resubscribe
                        client.subscribe("myHome/test");
                }
                else
                {
                        Serial.print("failed, rc=");
                        Serial.print(client.state());
                        Serial.println(" try again in 5 seconds");
                        // Wait 5 seconds before retrying
                        delay(5000);
                }
        }
}

void setup()
{
        Serial.begin(115200);
        setup_wifi();
        client.setServer(mqtt_server, 1883);
        client.setCallback(callback);
        reconnect();
}
void loop()
{
        loop_buttons();
        if (!client.connected())
        {
                reconnect();
        }
        client.loop();
        static unsigned long lastentry = 0;
        static unsigned long lastentry2 = 0;
        if (millis() - lastentry > 200)
        {
                pinMode(2, OUTPUT);
                digitalWrite(2, !digitalRead(2));
                lastentry = millis();
        }
        delay(50);
        if (millis() - lastentry2 > 1000)
        {
                Serial.println(ESP.getFreeHeap());
                lastentry2 = millis();
        }
}

```

# Answer
In case somebody finds this when faced with the same issue: I had a similar problem on a Pico W. Turned out that the Serial.println()s in the MQTT callback clobbered the MQTT+WiFi stack. Something did not multitask nicely. Not accessing the Arduino Serial port in the MQTT callback fixed it.
> 0 votes

---
Tags: esp32, mqtt
---


# Question
Title: Need help ATtiny85 not working as standalone
I have ATTiny85 that I want to drive a servo. Burned bootloader to the ATTiny85 and I am using HW-260 development board to program and to test the code. While the ATTiny85 works perfectly on the HW-260 development board, I cant get it to work as a standalone on a breadboard when testing with the servo by using the Adafruit\_SoftServo library and with the blink example. Tried adding 4.7kOhm pull-up resistor to PB5 to prevent the ATTiny85 from resetting but I get the same result. Tried powering the standalone layout with 3V coin cell, USB 5V, powerbank 5V and nothing. This is the servo code I am using:

```
Adafruit_SoftServo myservo;
int pos = 0;
void setup() {
  myservo.attach(PB0);
}
void loop() {
  for (pos = 0; pos <= 180; pos += 1) {
    myservo.write(pos);
    myservo.refresh();
    delay(15);
  }
  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    myservo.refresh();
    delay(15);
  }
}

```

The blink code I am using is from the examples, I just change the output pin as PB1. If I connect the PB5 briefly to ground, I get the servo to turn a bit in random direction. Measured and the breadboard is not the problem, everything seems to be connected correctly.

This is the bootloader I used https://github.com/ashishchoudhary9998/ATtiny85-Boot-loader

**Edit:** This is the schematic of the HW-260 board

This is my layout

# Answer
> 1 votes
After adding the schematics, a difference can be spotted:

PB3 needs a pull-up, on the development board it has 1,5 kΩ. This resistor is part of the USB standard and signals "low speed device". Presumably (because the source of it is not provided) the bootloader needs this to start at all, too.

The delay mentioned in a comment is typical for ATtiny85 development. Because of the low number of pins, the bootloader starts and waits for some seconds for a PC to connect. If no connection is established, the user program is started. It can then use all pins for its own purposes.

---
Tags: arduino-ide, attiny, electronics, attiny85
---


title: IsTimeSet library - Assign variables

text:
# Question
Title: IsTimeSet library - Assign variables
i get the current time with the example code istimneforset, everything works fine.

now i want to get the current time from the function "Serial.println(timeClient.getFormattedTime());" and i am trying to cache the first character of the array.

code:

```
#include <NTPClient.h>
// Change the next line to use with a different map/shield
#include <ESP8266WiFi.h>
//#include <WiFi.h> // for WiFi shield
//#include <WiFi101.h> // for WiFi 101 shield or MKR1000
#include <WiFiUdp.h>

const char *ssid =" *";
const char *password = "*";

WiFiUDP ntpUDP;
// initialized to a time offset of 10 hours
NTPClient timeClient(ntpUDP, "pool.ntp.org", 36000, 60000);
// HH:MM:SS
// timeClient is initialized to 10:00:00 if it does not receive an NTP packet
// before the timeout of 100ms is received.
// Without isTimeSet(), the LED would be lit even though the time was
// was not yet set correctly.

const int hour = 10;
const int minute = 0;

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

  WiFi.begin(ssid, password);

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

  timeClient.begin();
}

void loop() {
  timeClient.update();

 //Serial.println(timeClient.getFormattedTime());

 int stund2  = (timeClient.getFormattedTime()[0]);

Serial.println(stund2);

}

```

unfortunately it always gives me a wrong value. my goal is to have the current hour in a variable. can someone help me? thanks!

# Answer
There are a number of post in threads here and here that suggest using the NTPClient here.

Also, if we inspect that GIT repository's copy of NTPClient.cpp starting a line 155 we see the function for getFormattedTime():

```
String NTPClient::getFormattedTime(unsigned long secs) {
  unsigned long rawTime = secs ? secs : this->getEpochTime();
  unsigned long hours = (rawTime % 86400L) / 3600;
  String hoursStr = hours < 10 ? "0" + String(hours) : String(hours);

  unsigned long minutes = (rawTime % 3600) / 60;
  String minuteStr = minutes < 10 ? "0" + String(minutes) : String(minutes);

  unsigned long seconds = rawTime % 60;
  String secondStr = seconds < 10 ? "0" + String(seconds) : String(seconds);

  return hoursStr + ":" + minuteStr + ":" + secondStr;
}

```

...we see that this function returns a String resembling "hh:mm:ss" where hh is hours, mm is minutes and ss is seconds.

To extract only hours we would have to "cut" the string or parse the string using the ":" character, use only the "hh" portion of the string and convert that back into a number.

This is complex. Instead, consider using the function getHours():

```
int NTPClient::getHours() {
  return ((this->getEpochTime()  % 86400L) / 3600);
}

```

... this uses the epoch time after taking off the date (modulo 86400) and taking off the minutes and seconds (divide by 3600) leaving only the hours.
> 0 votes

# Answer
While st2000 gave a good answer about how to do it instead, I wanted to explain what actually went wrong with your first solution.

You are seeing the difference between binary and ASCII encoded data. Using `timeClient.getFormattedTime()` will give you an ASCII encoded string. Such a string is an array of `char`s, each one representing one character (according to the ASCII table) until the string gets terminated with the null character `\0`.

You are taking the first character and assign it to an integer variable. The value will be directly copied into that variable. But the first element in that `char` array is the ASCII digit `0`, which is the equivalent of decimal `48`. And that is what you get from your code. Also the hour field of that string is 2 characters wide, so you need to read both of them, not just the first character.

If you want to extract numbers from a string, you cannot just assign them. You need to parse the data correctly. For that you would tokenize the string (split it in individual parts with data) (for example with `strtok()`) and then parse each token with a corresponding function. To parse an integer value from a string you can use `atoi()`. This function will read the string, until a non-digit character appears, and convert that to an integer.

So - since we are only interested into the first number/token in that string, you can leave out the tokenizing and just parse that string (since after the number of hours there is always the `:` character, which is a non-digit character):

```
int stund2 = atoi(timeClient.getFormattedTime());

```

I have not tested this, but it should also work, though not that efficient as the solution of st2000, since parsing string data is commonly more complex than working directly with integer numbers.
> 0 votes

---
Tags: variables
---


# Question
Title: Run encoder code simultaneously with other code in Arduino
```
volatile unsigned int temp, counter = 0;
int county=0;
void setup()
{

  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(0, ai0, RISING);
  attachInterrupt(1, ai1, RISING);
}

void loop()
{
  county= (counter);
  if (counter>2000){
county=0;
  }
  temp = counter;

  Serial.println(county); // Encoder step counter

}

  void ai0() {if(digitalRead(3)==LOW) {counter++;}else{counter--;}}
  void ai1() {if(digitalRead(2)==LOW) {counter--;}else{counter++;}}

```

Dear all, **above arduino code is used for encoder as counter** and **code is quoted** from here, the above simple code works fine. However, if I were to **add some code lines below the `Serial.println(county);`which actually delays execution time**, the counter will actually **skip steps and mess up the counter** which I am very dissapointed.

May I ask how to solve this issue, my thought is can arduino actually run 2 void loop simultaneously so that the c**ounter code can be run simultaneously and not be affected by other code lines which introduces delay time that mess up the counter**. Any help will be appreciated :)

```
volatile unsigned int temp, counter = 0;
void setup()
{

  Serial.begin(9600);   pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(0, ai0, RISING);attachInterrupt(1, ai1, RISING);
}

void loop()
{
noInterrupts();
unsigned int county = counter;
interrupts();

  if (counter>2000){county=0;}

  Serial.println(county); // Encoder step counter

}

  void ai0() {if(digitalRead(3)==LOW) {counter++;}else{counter--;}}
  void ai1() {if(digitalRead(2)==LOW) {counter--;}else{counter++;}}

```

**PID code**

```
#include <PID_v1.h>
double Setpoint ;  double Input; double Output ;
volatile unsigned int temp, counterrr = 0;
int county=0;

double Kp=0, Ki=2, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{

  Serial.begin(9600);
  Setpoint = 120;
  myPID.SetMode(AUTOMATIC);
  myPID.SetTunings(Kp, Ki, Kd);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(0, ai0, RISING);
  attachInterrupt(1, ai1, RISING);
}

void loop()
{

}

  void ai0() {
    if(digitalRead(3)==LOW) {
    counterrr++;}
    else{
      counterrr--;}

        county= (counterrr);
  Serial.println(county);
  Input = map(county, 0, 1024, 0, 1200);  // photo senor is set on analog pin 5
  myPID.Compute();
  analogWrite(9,Output);
  Serial.print(Input);
  }
  void ai1() {
    if(digitalRead(2)==LOW) {
      counterrr--;}
      else{
        counterrr++;
        }

          county= (counterrr);
  Serial.println(county);
  Input = map(county, 0, 1024, 0, 1200);  // photo senor is set on analog pin 5
  myPID.Compute();
  analogWrite(9,Output);
  Serial.print(Input);
        }

```

# Answer
> can arduino actually run 2 void loop simultaneously

No, it cannot. All AVR based Arduinos (like Uno, Nano, Mega) have only one core, thus they can only execute one thing at a time.

The typical way to go is to just not introduce delays and divide up complex things into smaller parts. That way you can rapidly switch between different parts of the code, without blocking for a longer time. For humans it will then seem as if the parts are executed simultaneously, though they are actually executed successively.

To do timed things, you would use the non-blocking coding style from the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It uses the `millis()` function as a stop watch, on each loop iteration checking if enough time has passed since the last execution and executing again only if enough time passed. Much like you wouldn't bake a pizza and sitting in front of the oven until it is ready. You would regularly look at your clock to check, if enough time passed, doing other things in between.

---

That said, you changed the code after copying and mangled it in a weird way, so that it doesn't make much sense. Also the original code is not interrupt-safe.

The code in `loop()` has to do an atomic access to the volatile variable `counter`. This is to prevent the variable from changing in between reading it. Reading a single-byte variable (like one of type `byte`) is always atomic and cannot be interrupted, since this is one instruction, that will be finished before calling any interrupt service function (ISR). But `unsigned int` is 2 bytes big. So in rare cases the following might happen:

* First byte gets read from volatile variable into the non-volatile variable
* the ISR triggers and changes the volatile variable
* Second byte (which is now changed) gets read into the non-volatile variable

This can lead to occasionally corrupt data.

The typical way to do this is to temporarily disable interrupts, copy the volatile variable to a local variable and then enable interrupts again. Then you can use the local variable as a snapshot of the volatile variable without corrupting the data.

```
noInterrupts();
unsigned int local_counter = counter;
interrupts();
if(local_counter > 2000)
    ...

```

For your code you should also use the same mechanism as in the original code and only send the value over serial, if it really changed. Otherwise you will spam your serial connection, which automatically will slow down your code (since you are filling up the serial buffer faster, than it is send out, so that further calls to `Serial.println()` will block until enough space is available in the buffer).
> 3 votes

---
Tags: arduino-uno, arduino-mega, programming, arduino-ide, arduino-nano
---


# Question
Title: Issue communicating with ESP32 (WT32-S1) with my USB FTDI (hw-417-v1.2)
Basically im trying to communicate bewtween my ESP32 (WT32-S1) and my USB FTDI (hw-417-v1.2) when I run it in the Arduino IDE I get the error "***Failed to connect to ESP32: Serial data stream stopped: Possible serial noise or corruption.***" Not too sure why this happens, I've plugged in the WT32 to the FTDI as follows:

WT32 RXD - FTDI TXD

WT32 TXD - FTDI RXD

WT32 GND - FTDI GND

WT32 5V - FTDI 5V

The FTDI is directly plugged into my PC and I've installed the necessary drivers as far as I know. Fair to mention its communicating serially with my arduino uni using SoftwareSerial. Here is the code ESP32 side:

```
#include <SoftwareSerial.h>
#define MYPORT_TX 15
#define MYPORT_RX 14

SoftwareSerial myPort(MYPORT_RX, MYPORT_TX);

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

void loop(){
  Serial.println(myPort.read()); // read from software serial interface, write to hardware serial
  myPort.println(Serial.read()); // read from hardware serial interface, write to software serial
}

```

Code Arduino uno side:

```
#include <SoftwareSerial.h>

SoftwareSerial serial2(5, 6); // choose pins that are not being used by anything else

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

void loop(){
  Serial.println(serial2.read()); // read from software serial interface, write to hardware serial
  serial2.println(Serial.read()); // read from hardware serial interface, write to software serial
}

```

The connection from WT32 to Arduino Uno is as follows:

WT32 GND - Uno GND

WT32 IO15 - Uno 5

WT32 IO14 - Uno 6

Main issue as said is the "***Failed to connect to ESP32: Serial data stream stopped: Possible serial noise or corruption.***", mentioning the rest to give you a full picture.

Cheers!

# Answer
Ive solved my problem, to any other people who have this problem, make sure you use a CP2102 instead, and plug according to this:

```
CP2101    WT32
TXD ----- RX0
RXD ----- TX0
GND ----- GND
5V  ----- 5V

```

Then plug the WT32 IO0 pin to GND to enter download mode, I'm personally using an external 5v PS as the WT32 needs quite a lot of power.
> -1 votes

---
Tags: arduino-uno, esp32, softwareserial
---