message:
How to implement brown out detector arduino ESP32?

We are using ESP32 with arduino sdk for developing our application. In our application we need to implement BOD to detect with specific voltage level.

Basically we want to set specific voltage level and when device goes to power off it will detect and trigger interrupt. How I can set interrupt for brown out detect?

we have only this code:

```
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"

void setup() {
  Serial.begin(115200);
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1); //enable brownout detector
}

void loop() {
  Serial.println("Start BOD");
  delay(1000);
}
```

body:
The ESP32's on-board BOD is mainly intended to inhibit operations that might cause corruption if they happened with too low a voltage.  There is a very unpredictable amount of time for the code in the ESP32 to do anything but effectively halt.

If that's what you want, then you have enabled it in your code above.

If you want to detect a power outage, for example, and log something, then you need two things:

1. A reliable detector that the power has failed.
1. A battery or capacitor-based circuit that will continue the ESP32's power for long enough for you to do what you need to do.

So when "1" happens you set a GPIO pin on the ESP32 which triggers your interrupt and you do what you need to do while the power remains stable.


sender: user

message:
Connecting the cathode of a diode to the output of a multiplexer

From the image, the diodes share the same anode which is driven by 'Do Something'. My question is: through using Arduino IDE, what code should I write that connects the output of the multiplexer (Z) to a specific diode's cathode (Y0 or Y1 or ... or Y7), which in turn is connected to 'Do Something' that drives the cathode probably? In this code, I want the ESP32 microcontroller to connect this cathode to 'Do Something' for say 3 seconds and then switch to the next diode's cathode with a delay of 0.1 seconds [where no diodes' cathodes are connected to Z]       (and so on: in a continuous loop).

Here some code I found online but not sure what needs to be added to get the proper functionality:

    int outputs[4] = {4,0,2}; // pins for selecting LED
    int inhibit_pin = 15; // pin for turning off all LEDs

    void setup() {
      for(int i;i<3;i++){
        pinMode(outputs[i],OUTPUT); // output selection for LED control
      }
      pinMode(inhibit_pin,OUTPUT);
      digitalWrite(inhibit_pin,LOW); // raise high to disable all

    }

    void loop() {
      // looping through all 8 LEDs
      for (int j=0;j<8;j++){
        // turn on LEDs based on bit conversion
        for(int i=0;i<3;i++){
          digitalWrite(outputs[i],bitRead(j,i));
        }
        delay(100); // delay .1 sec
      }
    }

I don't think that "digitalWrite(outputs,bitRead(j,i));" is actually needed and I am not quite sure of what it does.

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

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

sender: assistant

body:
The code you have posted should loop through the 8 possible MUX in/out pins (Y0...Y7) connecting one at a time to pin 3.

Assuming your Y0 through Y7 are each connected to a pin on your "do something" block, the mux should connect each of the 7 pins on your "do something" to Z.

One problem I see is that your code changes the pin select values on the MUX while the MUX is enabled. As you execute your `for(int i=0;i<3;i++)` loop and toggle the different select bits to S0...S2, the MUX will connect different Y0...Y7 pins to Z, until it settles on the final set of values for S0...S2. You should really set inhibit_pin to HIGH (disabling the mux before entering your `for(int i=0;i<3;i++)` loop, and then set it to LOW again at the end of the `i` loop and before the delay. (to re-enable the MUX at the now-completely-selected pin.)

Your description is a little hard to follow, but it sounds like that is what you want.

If you want each pin to be connected for 3 seconds, then not connected to any pin for .1 seconds before moving on to the next pin, you might rewrite your loop like this:

```
void loop() {
  // looping through all 8 LEDs
  for (int j=0;j<8;j++){

    // disable the mux while selecting a pin
    digitalWrite(inhibit_pin,HIGH);

    // select a MUX pin
    for(int i=0;i<3;i++){
      digitalWrite(outputs[i],bitRead(j,i));
    }
    // re-enable the mux now that we've selected a pin
    digitalWrite(inhibit_pin,LOW);

    delay(3000); // leave the pin active for 3 seconds.

    // disable the mux for .1 seconds
    digitalWrite(inhibit_pin,HIGH);
    delay(100);
  }
}
```


message:
Grove Base Kit Multiple I2C Connection

I tried to connect two modules that require I2C connection and they won't work at the same time.

I used the [Arduino Sensor Kit - Base][1]. This kit does not need any connection, you just have to code to get your desired output. I wanted to display the Air Pressure (BMP280) module values to the 0.96" OLED Display, however, it is refusing to run both the air pressire and the OLED display at the same time. Only running one module (either Air pressure or OLED) at a time makes it work. Does it have something to do with how the I2C connection is wired on the board?

    #include "Arduino_SensorKit.h"

    void setup() {
      // put your setup code here, to run once:
      Oled.begin();
      Oled.setFlipMode(true);
      Oled.setFont(u8x8_font_7x14B_1x2_r);

      Pressure.begin();
    }

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

      Oled.setCursor(0, 10);
      Oled.print("Temp: ");
      Oled.print(Pressure.readTemperature());
      Oled.print(" C");
      Oled.setCursor(0, 20);
      Oled.print("Pres: ");
      Oled.print(Pressure.readPressure());
      Oled.print(" Pa");
      Oled.setCursor(0, 30);
      Oled.print("Alti: ");
      Oled.print(Pressure.readAltitude());
      Oled.print(" m");

      delay(1000);
    }

What I did:

 1. Test to see if Air Pressure will still work while both Air Pressure and OLED is connected by using `Serial.begin()`. Now I know that only the OLED does not work when both modules are connected.
 2. Changed order of initialization. Same result: Air Pressure works but not OLED

  [1]: https://www.seeedstudio.com/Arduino-Sensor-Kit-Base-p-4743.html

body:
About two weeks ago there was a change in the Arduino_SensorKit Library that introduced an error with the instanciation of the Oled object.

I found the error in the release (v1.0.6) of the library. The previous release (v1.0.5) could cause another issue, as it uses a software I2C. I doubt the hardwired sensores are connected with the correct pins. But I have no hardware, so I can not check this.

I propose a workaround to see, if the identified issue caused your observations.

    #include "Arduino_SensorKit.h"

    U8X8_SSD1306_128X64_NONAME_HW_I2C Oled2;
    // if the line above does not work
    // comment it and uncomment the following line.
    // U8X8_SSD1306_128X64_NONAME_HW_I2C Oled2(U8X8_PIN_NONE);

    void setup()
    {
      Oled2.begin();
      Oled2.setFlipMode(true);
      Oled2.setFont(u8x8_font_7x14B_1x2_r);

      Pressure.begin();
    }

    void loop()
    {
      Oled2.clear();

      Oled2.setCursor(0, 10);
      Oled2.print("Temp: ");
      Oled2.print(Pressure.readTemperature());
      Oled2.print(" C");

      delay(1000);
    }

Could you please try out and report your experience.
If it would work, I can support the fixing of the issue.


message:
I am making heated socks with adjustments by Nano and want to extend batterty life?

I want to set a temperature and have Nano turn on for 2 minutes then off for 2 minutes and repeat using the same temperature originally set and have the ability to change temperature settings and do the same.

The following sketch works along with displaying battery voltage using MIT Inventor 2 app via Bluetooth HC-05 to my Android phone (without the on/off sequence I am looking to do).

I hope to keep my feet warm but also extend the battery life.  Can you tell me what methods I should research to figure out how to do this? I have looked at millis(), blink without delay, and my own limited programming skills without success.  Thanks.

```c++
#define right 5
#define left 6

int leftval = 0;
int val=0;
int vg=0;

void setup() {
  Serial.begin(9600);
  pinMode(left, OUTPUT);
  pinMode(right, OUTPUT);
  pinMode(A0, INPUT);
}

void loop() {
  int vg = analogRead(A0);
  Serial.println(vg / 82.049, 1);
  delay(200);
  if (Serial.available() >= 2) {
    unsigned int a = Serial.read();
    unsigned int b = Serial.read();
    unsigned int val = (b * 256) + a;

    if (val >= 0 && val <= 255) {
      analogWrite(right,val);
      delay(200);
    }

    if (val >= 1000 && val <= 1255) {
      leftval = val - 1000;
      analogWrite(left, leftval);
      delay(200);
    }
  }
}
```

body:
With an electrical heating element powerful enough to warm your feet, the power to the heating element is hundreds or thousands of times greater than the power to your Arduino. Anything you do to reduce the power consumed by your Arduino will have no meaningful effect on your total power consumption. It's like trying to stop a drip in your faucet to save water while the main water pipe has water gushing out of a gaping hole.

Heating elements convert watts of power to calories of heat. The more watts you put in, the more heat you get.

Current • duty cycle • on-time = total power consumed AND total heat generated.

If you reduce the duty cycle to the heating element, you will reduce the power consumed, but you will also reduce the amount of heat generated.

Given that you already have the ability to vary the duty cycle to your heating element (via your analogWrite to `right` and `left`) the only meaningful way to reduce power consumption is to lower the heat setting. It looks like you already have that ability. Turn down the heat setting and have slightly colder feet, or use a higher capacity battery.

All that said, if you turn the heat setting down to 0, the heating element completely stops using power. At that point the Arudino will slowly drain your battery while your electric socks sit in your sock drawer. It would be worth putting your Arduino in ultra-low-power sleep mode (or even turning it off entirely) to avoid draining it while you're not using it.

## Edit:

If you want to run the heating element on for 2 minutes, off for 2 minutes, that would give exactly the same power savings as running it at half the current power level, but constantly.

If you really want to implement the 2 minutes on, 2 minutes off approach, you will need to use millis() to keep track of the time when you last turned the elements on/off. I suggest refactoring your current code to remove delay and use millis as well.

Take a look at the "BlinkWithoutDelay" sketch (which I believe is included with the IDE, and is certainly available online) for an idea of how to handle timing things without using `delay()`.


message:
How to put Arduino Nano in low power sleep mode (<0.05mA)

I'm trying to put an Arduino Nano in low-power mode using this guide: [Arduino Low Power - How To Run ATmega328P For a Year On Coin Cell Battery](http://www.home-automation-community.com/arduino-low-power-how-to-run-atmega328p-for-a-year-on-coin-cell-battery/).

The article suggests 3 things: use the Low-Power library from Rocketscream, cut the power to the power LED, and remove the voltage regulator.

So far I've only done the first two and reduced the clock speed to 8 MHz.

The important part of the source code that puts the Arduino in deep sleep looks like this:

```c++
void setup() {
  CLKPR = 0x80; // (1000 0000) enable change in clock frequency
  CLKPR = 0x01; // (0000 0001) use clock division factor 2 to reduce the frequency from 16 MHz to 8
}

void loop() {
  // Go to sleep until the next scheduled wake up
  int32_t waitSeconds = 60;
  while (waitSeconds > 0) {
    period_t waitFor = SelectWaitTime(waitSeconds);
    LowPower.powerDown(waitFor, ADC_OFF, BOD_OFF);
    waitSeconds -= PeriodToSeconds(waitFor);
  }
}

period_t SelectWaitTime(int32_t secondsToWait) {
  if (secondsToWait >= 8)
    return SLEEP_8S;
  else if (secondsToWait >= 4)
    return SLEEP_4S;
  else if (secondsToWait >= 2)
    return SLEEP_2S;
  else if (secondsToWait >= 1)
    return SLEEP_1S;
}
```

In essence, sleep for up to 8 seconds, remove the seconds from the counter, then sleep again.

So far I've only scratched off the trace to the power LED and haven't removed the voltage regulator. According to the article above, this should reduce the power consumption to around 0.05 mA but I get around 1.7 mA, which is over 30 times more!

Electrically, I only have a MOSFET as a power switch connected to one of the analog pins (I use it as a digital output) and another controller, connected to the I2C pins (the Arduino acts as Slave). The other controller is turned off through the MOSFET when I take the measurements. Physically removing the connections doesn't change the consumption, so I don't think any of that is related.

Is there something I did wrong? What can I do to achieve power consumption similar to the one in the article?

body: Turns out the voltage regulator was AMS1117 - not MIC5205-KB50/KB33/KBAA like the one in the article. Ripping it off gave me the 0.026 mA idle current which is even better than what I was hoping for.


message:
Error 101 Server Did Not Report Size from OTA Upgrade framework via git hub

I have tried [this video][1]:

[ESP8266 Self Update OTA from GitHub][1]

Instruction and made [this GitHub repo][2]:

And changed [the main code][3] to [this type][4], but I get this error:

```
HTTP_UPDATE_FAILD Error (-101): Server Did Not Report Size
```
[![enter image description here][5]][5]
 when the `   FirmwareUpdate();` code is running.
So I don't know why GitHub don't answer to the esp8266, as said [here][6]:

> The error has nothing to do with your sketch. Also, the error code is
> not a HTTP 101 error. The problem is that your server does not send
> the response header 'Content-Length'

I have some dupt about the bin URL file address which have many dot on the end of it (`https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay.ino.esp8285.bin`) on it, could it be the reason for none answering and giving the 101 code form GitHub server!

Any suggestion would be good help to fix this bug.

**Update 1:**

> I have changed the bin file name to this kind :
>
>      BlinkWithoutDelay.ino.esp8285.bin  ---->      BlinkWithoutDelay_ino_esp8285.bin
>
>  But I have again the same GitHub 101 error.

**Update 2:**

Based on the [timemage][7] answer, I have changed the address of `bin` and `TXT` file by finding the download link of those files form the GitHub. And it has been working by changing the `blob` part of address to `raw`, so the bin address changed form `https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin` to `https://github.com/soheilpaper/ota_github_blink/raw/main/BlinkWithoutDelay_ino_esp8285.bin` And the `https://github.com/soheilpaper/ota_github_blink/blob/main/version.txt`to  `https://raw.githubusercontent.com/soheilpaper/ota_github_blink/main/version.txt`

And now that error has been fixed as you can see below:

[![enter image description here][8]][8]

Although I gave some dupt about upgrading the main code by getting this output via serial port:

```
Device already on latest firmware version

```
And I would check it after some resting!.

Thanks.

  [1]: https://www.youtube.com/watch?v=FuY6BobS-1k
  [2]: https://github.com/soheilpaper/ota_github_blink
  [3]: https://github.com/programmer131/ESP8266_ESP32_SelfUpdate/blob/master/esp8266_ota/esp8266_ota.ino
  [4]: https://github.com/soheilpaper/ota_github_blink/blob/main/ESP_OTA_Github.ino
  [5]: https://i.stack.imgur.com/ZI74L.png
  [6]: https://github.com/esp8266/Arduino/issues/5131
  [7]: https://arduino.stackexchange.com/users/70020/timemage
  [8]: https://i.stack.imgur.com/z6cw8.png

body:
The ESP8266httpUpdate library [wants to know in advance][1] how large the file is before it starts downloading it.  It wants to know this so it can tell, before trying to download (and program), [whether or not there's enough space][2] for it. If the size of the file isn't provided by the server it will [report the error][3] that you are seeing.

The size of the file is provided by the web server by means of the [Content-Length][4] HTTP response header [read by HTTPClient][5].  This header is received in advance of the file content.

Your main code appears to contain a correct link to raw .bin file,
`#define URL_fw_Bin "https://raw.githubusercontent.com/programmer131/otaFiles/master/firmware.bin"`, and reports the following headers:

```
cache-control: max-age=300
content-security-policy: default-src 'none'; style-src 'unsafe-inline'; sandbox
content-type: application/octet-stream
etag: "b2ecfb5dc91587c089acdaace446b0d7b00863c9f42dffb36c7983c103d3a98a"
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
x-frame-options: deny
x-xss-protection: 1; mode=block
via: 1.1 varnish (Varnish/6.0), 1.1 varnish
x-github-request-id: 8728:2B67:9AFD3:AD0EC:6008FCFF
accept-ranges: bytes
date: Thu, 21 Jan 2021 04:03:32 GMT
x-served-by: cache-bos4651-BOS
x-cache: MISS, HIT
x-cache-hits: 0, 1
x-timer: S1611201812.154162,VS0,VE1
vary: Authorization,Accept-Encoding
access-control-allow-origin: *
x-fastly-request-id: bfc9702929b91be55d7aa040465a230436918e01
expires: Thu, 21 Jan 2021 04:08:32 GMT
source-age: 20
content-length: 270016
```

The **content-length: 270016** at the bottom shows that this should work.  But your changed code that uses `#define URL_fw_Bin "https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin` is to the HTML page for downloading the file, which does **not** report `Content-length`, for me anyway, but then it's the wrong URL anyway.

Regarding the "101 error", it's `-101` (negative) [defined here][6], and like they said, it is not an [HTTP status code][7],  it is just a value used by the ESP8266httpUpdate library.

  [1]: https://github.com/esp8266/Arduino/blob/2.7.4/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp#L293
  [2]: https://github.com/esp8266/Arduino/blob/2.7.4/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp#L326
  [3]: https://github.com/esp8266/Arduino/blob/2.7.4/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp#L418
  [4]: https://www.rfc-editor.org/rfc/rfc2616#section-14.13
  [5]: https://github.com/esp8266/Arduino/blob/2.7.4/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp#L1361
  [6]: https://github.com/esp8266/Arduino/blob/2.7.4/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h#L52
  [7]: https://www.rfc-editor.org/rfc/rfc2616#section-6.1.1


message:
Not able to upload code to NodeMCU

Im now working on a Node MCU based project but the problem is that i cannot upload the code to the board. Further more whenever i connect the usb to the NodeMCU my keyboard stops working and only works again after i turn off and on my pc this happens whenever i disconnect and connect the Node MCU. The error is COM port is not found or board is not connected and sometimes after i disconnect the Node MCU my system gives a message The Last USB device malfunctioned
Can anyone help I'm using a basic NodeMCU 12E CP2021??

body:
I'd check 3 things:

1. If it's a specific USB port/cable problem, not related to the NodeMCU itself (your said it interacted with your USB keyboard, what makes sense if it's a computer-usb issue). Try to connect the NodeMCU to a different USB port/hub in your computer using another USB cable.

2. Of course it could be a USB-Serial driver issue. Please make sure what chip is used on your NodeMCU (CH340 or CP1202) and make sure the correct driver is installed.

3. Most important - you must make sure your Serial pins on the NodeMCU (TX, RX) are not connected to anything during program upload. They are bridged to the Serial connection that is coming from the computer (through the USB-to-Serial chip) and interact and interfere with them.

Good luck!


message:
ESP8266-01E is not responding after successful flash

I have flashed an ESP8266 with the ESP8266 flash downloader that said my flashing had succeeded.

But when I sent an AT command from the serial monitor it didn't respond and the TX/RX LED from the ESP8266 didn't respond either. I checked all baudrates from 300-200000, but nothing.

I was using CH340 USB to TTL for flashing wired like this:

```
USB -> ESP8266
3,3v ->CH_PD and VCC
GND -> GND and GPI0 (only when flashing)
TX -> RX
RX -> TX
```

I was flashing to downgrade the firmware; the default firmware from shop was SDK 1.5.4, AT VERSION 1.1.0.0.

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

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

I have been frustrated with this, because this is my second module.

body:
SOLVED

My module is esp8266-01S, i need to set the SPI MODE to DOUT, BAUDRATES=115200, SPI SPEED 40MHz and the software is NODEMCU FLASHER.

The important keyword is "DOUT".

I have been flash many times but with not DOUT SPI METHOD. I thought change it will not fix that. I was using QIO SPI MODE but it doesn't work.


message:
Cannot display a chr string using Wire.read() and u8g2.drawStr()

I'm still getting myself acquainted with C++, so I expect this is a very basic issue I'm facing. I've got an OLED screen connected to a Teensy LC and can display text on it just fine. The Teensy receives bytes via I2C, and I want to reassemble those bytes into strings and display them on the OLED.

My relevant code:

```
#define I2C_ADDRESS 4
char buf[16];

void setup(void) {
  Serial.begin(9600);
  Wire.begin(I2C_ADDRESS);
  Wire.onReceive(receiveData);
  u8g2.begin();
}
void loop(void) {
  // U8G2 setup code snipped
  // This line doesn't output anything on the screen:
  u8g2.drawStr(0, 0, buf);
  // This line does:
  u8g2.drawStr(0, 20, "Foobar!");
  u8g2.sendBuffer();
  delay(1000);
}

void receiveData(int byteCount){
  Serial.print("Data received: ");
  int i;
  for (i=0; i<byteCount; i++)
  {
    buf[i] = Wire.read();
    Serial.println(buf[i]);
  }
  buf[i] = '\0';
  Serial.println(buf);
}
```

In the receiveData() function, the Serial.println() within the for loop prints out each letter of the payload as it's received, one after the other - but the Serial.println() below the for loop, which in my estimation should print out the whole message, prints out a blank line. I presume that's related to the fact that the received string doesn't show up on the OLED display.

body:
This is kind of convoluted to put as a comment and it is *sort of* an answer, so I'm making it *an* answer.  Just to warn you, I have not tried to compile any of the code snippets here.

`Wire.onReceive(receiveData);` registers your function so that it can be later called back in the context of the interrupt service routine used for handling I2C ("Wire") data.  Or at least this is how it usually works.  So when your `receiveData` function is running you are in the middle of handling an interrupt associated with the I2C peripheral.

Using `Serial.print()`, `.println()`, `.write()`, and many other things, including non-serial related things like `delay()` inside of an interrupt service is usually a no-no.  On the AVR Arduino core, if the outbound serial buffer happens to fill, your code will deadlock with the underlying `.write()` waiting for there to be room in the outbound serial buffer and the serial transmit interrupt waiting for `.write()` to get done waiting for it.  I don't know how the Teensy LC and its MCU are configured, whether or not it prioritizes interrupts, etc, but it is likely that you're still not supposed to call functions like these inside the interrupt context.

There's really not a lot you're supposed to do in an ISR except:
* communicate with hardware (which is being done for you here)
* manage the non-`volatile` variables that belong to the ISR itself.
* set global `volatile` qualified variables to communicate with the main line of execution.
* call functions that have no shared state with the main line of execution.
* call functions that have shared state but are carefully designed to be called from both ISR contexts and main line of execution.

That said, I don't know precisely why you're seeing what you're seeing, but I'm not overly surprised either.  The above *may* be related to it, but I haven't drawn that connection yet.

The way you currently have `receiveData`, it may overflow `buf`.  All that's required for that is for the sending side to send more than 15 bytes.  Any number of weird things can happen if you manage to overflow.  Is it related? Maybe.

For communicating between the `receiveData` running in the ISR context and the main line of execution in `loop`, `buf` should be `volatile` qualified.  Without that the main line of execution can behave as though `buf` never changes after it is first seen.  Because of how you're using it and familiarity with the compiler, I'm going to guess that this isn't manifesting as a bug, but I don't *know* that; it *could* be related.

So I'd recommend updating something like your `buf` declaration to `volatile` qualified and removing the Serial `print` calls from the `receiveData` function, and preventing overflow:

```c++
volatile char buf[16];

/// ...

void receiveData(int byteCount){
  static const size_t room_for_non_null_chars = sizeof buf - 1;
  const size_t read_amount = min(byteCount, room_for_non_null_chars);

  int i;
  for (i = 0; i < read_amount; ++i) {
    buf[i] = Wire.read();
  }

  buf[i] = '\0';
}
```

If it weren't for the fact that we need to read into something `volatile` qualified the above loop could really just be a `read` call taking the buffer and size.  You can see that's updated to prevent overflow.

Part of `loop` would then become something like:

```c++
void loop() {
  char non_volatile_buf[sizeof buf];
  size_t write_index = 0;

  noInterrupts();
  for (char c: buf) {
    non_volatile_buf[write_index++] = c;
  }
  interrupts();

  // U8G2 setup code snipped
  // This line doesn't output anything on the screen:
  u8g2.drawStr(0, 0, non_volatile_buf);

  // ...
```

We're turning off interrupts while copying the data into a local buffer so that the onReceive handler cannot interrupt the use of the `buf`, updating while you're in the middle of using it in `drawStr`.

If you care about losing messages there's more that would need to be done.  Surrounding what to do if you've got a call to `receiveData` while there's a message currently in `buf`.  The way the above is written it just drops whatever is in there whether it's been seen by `loop()` or not.


body:
I didn't get a load of sleep last night but I finally figured it out, thanks to [timemage's post](https://arduino.stackexchange.com/a/80906/71831). I'm concerned that my solution is hyper-specific, but I'd rather share it to save someone the trouble in future.

1. timemage was right in that the buffer should really be `volatile` qualified and that as little processing as possible should happen in what I now understand is an ISR. I couldn't get their code to work, but I eventually stumbled on [i2c_t3](https://github.com/nox771/i2c_t3), an enhanced I2C library specifically for Teensy 3.0/3.1/LC. Looking at the library's code and especially its [basic peripheral example](https://github.com/nox771/i2c_t3/blob/master/examples/basic_slave/basic_slave.ino), it looks like it implements similar techniques to those timemage recommended.
2. The other thing I didn't consider was the way the controller was communicating. I was using the smsbus2 Python library, and at one point I changed the address offset from `0x00` to `0x01`. This mysteriously seemed to make the Teensy code work, but I don't know why!
```
data = [1, 2, 3, 4, 5, 6, 7, 8]
bus.write_i2c_block_data(0x21, 0x01, data)
```
3. Lastly, from reading forum posts about saving data to variables from I2C, it looks like a lot of quite simple code that does work on other Arduino devices doesn't work on the Teensy.1 I'd have to get an Arduino device to test this theory, though.

Because I'm a bad scientist, I haven't checked whether any of my original code or timemage's improved code works when I offset the address in the smbus2 code. But for what it's worth, these are the things I did to solve my problem!

----

1. See for example: https://forum.arduino.cc/index.php?topic=570597.0; https://forum.arduino.cc/index.php?topic=619902.0.


message:
7 segment displays are not working whatsoever

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

  [1]: https://i.stack.imgur.com/g2aVx.png
```
/*
MODIFIED TRAFFIC LIGHT SYSTEM W/ A COUNTDOWN TIMER FUNCTION
BY JOHN SEONG

THIS IS A QUITE ACCURATE SIMULATION OF TORONTO'S TRAFFIC LIGHT SYSTEM
WHICH INCLUDES TWO 7-SEGMENT DISPLAYS THAT SHOW THE SECONDS LEFT
TILL THE PEDESTRIAN LIGHT SWITCHES BACK TO RED.

ENJOY!
*/

const int redLED = 4;
const int yellowLED = 5;
const int greenLED = 6;
const int pedestrianRedLED = 13;
const int pedestrianGreenLED = A5;
const int buzzer = 12;
const int button = 7;

int segmentPins[] = {11, 10, 9, 8};

int buttonHitCount = 0;

void setup() {

  Serial.begin(9600);

  // Car Traffic LEDs
  pinMode(redLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);
  pinMode(greenLED, OUTPUT);

  // Pedestrian Traffic LEDs
  pinMode(pedestrianRedLED, OUTPUT);
  pinMode(pedestrianGreenLED, OUTPUT);

  // 7-Segment Display Pins
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);

  // Piezo Speaker Pin
  pinMode(buzzer, OUTPUT);

  // Pedestrian Push Button
  pinMode(button, INPUT_PULLUP);

  displayNumber(9, 2);
  displayNumber(9, 3);
}

void loop() {

  // Read the state of the button
  int buttonState = digitalRead(button);

  Serial.println(buttonState);

  if (buttonState == LOW) {
    buttonHitCount = 1;
  }

  if (buttonHitCount == 1) {
    switchToRed();

  } else if (buttonHitCount == 0) {
    defaultState();
  }
}

void displayNumber(int num, int displayPin) {

  bool binaryValue[][4] = {
    {0, 0, 0, 0}, // 0
    {0, 0, 0, 1}, // 1
    {0, 0, 1, 0}, // 2
    {0, 0, 1, 1}, // 3
    {0, 1, 0, 0}, // 4
    {0, 1, 0, 1}, // 5
    {0, 1, 1, 0}, // 6
    {0, 1, 1, 1}, // 7
    {1, 0, 0, 0}, // 8
    {1, 0, 0, 1}, // 9
  };

  for(int i = 0; i < 4; i++) {
    digitalWrite(segmentPins[i], binaryValue[num][i]);
  }

  digitalWrite(displayPin, HIGH);
  delayMicroseconds(10);

  digitalWrite(displayPin, LOW);
}

void switchToRed() {

  delay(5000);

  // YELLOW
  digitalWrite(yellowLED, HIGH);
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // RED
  digitalWrite(redLED, HIGH);
  digitalWrite(greenLED, LOW);
  digitalWrite(yellowLED, LOW);

  // GREEN
  digitalWrite(pedestrianGreenLED, HIGH);
  digitalWrite(pedestrianRedLED, LOW);

  switchToGreen();
}

void switchToGreen() {

  // 15
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(5, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 14
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(4, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 13
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(3, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 12
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(2, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 11
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(1, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 10
  noTone(buzzer);
  displayNumber(1, 2);
  displayNumber(0, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 9
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(9, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 8
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(8, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 7
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(7, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 6
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(6, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 5
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(5, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 4
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(4, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 3
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(3, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 2
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(2, 3);
  tone(buzzer, 1000);
  delay(1000);

  // 1
  noTone(buzzer);
  displayNumber(0, 2);
  displayNumber(1, 3);
  tone(buzzer, 1000);
  delay(1000);

  noTone(buzzer);

  // YELLOW
  digitalWrite(yellowLED, HIGH);
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, LOW);
  delay(2000);

  // GREEN
  digitalWrite(redLED, LOW);
  digitalWrite(greenLED, HIGH);
  digitalWrite(yellowLED, LOW);

  // PEDESTRIAN - RED
  digitalWrite(pedestrianGreenLED, LOW);
  digitalWrite(pedestrianRedLED, HIGH);

  // Reset the value
  buttonHitCount = 0;
}

void defaultState() {

   // GREEN
    digitalWrite(greenLED, HIGH);
    digitalWrite(yellowLED, LOW);
    digitalWrite(redLED, LOW);

   // PEDESTRIAN - RED
    digitalWrite(pedestrianRedLED, HIGH);
   digitalWrite(pedestrianGreenLED, LOW);
}
```

Clearly something is wrong with my code and the 7-segment displays are off the whole time the program is running. I also posted a link below which directs to the tinkercad project I made.

https://www.tinkercad.com/things/7pnnbXoaqrG-improved-stop-light-john-seong/editel?sharecode=jR86i_srV7QgP11u1CxOFzeVwehzjIRr8wCC7vbbLaY

body:
Not really a solution, but changing the code for the `displayNumber` function as shown below, will make it more apparent where the real problem is.

```lang-cpp
void displayNumber(int num, int displayPin) {

  bool binaryValue[][4] = {
    {0, 0, 0, 0}, // 0
    {0, 0, 0, 1}, // 1
    {0, 0, 1, 0}, // 2
    {0, 0, 1, 1}, // 3
    {0, 1, 0, 0}, // 4
    {0, 1, 0, 1}, // 5
    {0, 1, 1, 0}, // 6
    {0, 1, 1, 1}, // 7
    {1, 0, 0, 0}, // 8
    {1, 0, 0, 1}, // 9
  };

  // turn off both displays
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);

  for(int i = 0; i < 4; i++) {
    digitalWrite(segmentPins[i], binaryValue[num][i]);
  }

  digitalWrite(displayPin, HIGH);
  /* // remove these two lines
  delayMicroseconds(10);
  digitalWrite(displayPin, LOW);
  */
}
```


message:
Push button restarts the arduino

I have linked an external push red colored button to my arduino but when I press it, instead of giving me HIGH or LOW, it resets the arduino. I am a beginner to this stuff so could someone help?

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

If your button creates a short circuit between 5V and GND pins... it will certainly act like a RESET.  Let's try to make sure you are not creating a dead short on an Arduino pin so you avoid prematurely killing your controller.

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


message:
Can we have 2 HC12 on a single Arduino (1 to receive and other to transmit)?

I'm working on a project and I need to send 2 datas and receive them at the same time.

My question is: Is it possible to have 2 Arduinos both have 2 HC12 (total 4), because I want each Arduino to send and receive data at the same time.

It's hard for me to have 4 Arduinos.

body:
Yes you can - one on `Serial` pins 0/1 and the other using `SoftwareSerial` on any other pins. Note that the one on `SoftwareSerial` will interfere with the one on `Serial` as it disables interrupts while sending or receiving.

It may be better to use an Arduino which has multiple hardware serial ports. Maybe one of the Teensy boards would be better for your needs.

Alternatively if (and I am not familiar with the modules enough to know if this is right or not) they operate as a transparent serial bridge then you could connect one module to the TX pin for transmission and the other to the RX pin for reception - reading from serial receives from one, and writing to serial transmits through the other.

Also note that you will have to ensure that both pairs of modules are running on different channels to prevent interference between them.


body:
Yes, you just need to connect your TX pin on the RX pin of one HC-12, and your RX pin on the TX pin of the other HC-12, and use separate channels for both HC-12. And then you do the same thing on the otherside, but you need of course, to reverse the channels - Et voila.

However, you might need to take precautions (distancing / shielding) to avoid your emitting HC-12 to parasite the channel of the nearby receiver.

By the way, it seems that one should refrain as much as possible to use SoftwareSerial, which is not robust enough for high speed and seems to cause data distortion.


message:
How to add the previous value to current value from sensor

```c++
const byte interruptPin = 4;
void ICACHE_RAM_ATTR count();
void setup() {
  Serial.begin(115200);

  // Set up our digital pin as an interrupt
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), count, RISING);
}

void loop() {

}

void count() {
  volatile float rainrate = 3;
  volatile float rate;
  volatile float total;

  rate = rainrate * 0.1;
  Serial.println(rate);

```
Every time it tips, it returns 0.3.  How do I add the previous value(0.3) to a new tip, to make it 0.6, and save it into a variable.

Thanks!

body:
Btw, you can make the `volatile` variables global, by putting them above `void Setup`.

To put the total (new) value, use:

    total += <sensorValue>;

where `<sensorValue>` is a call to get the sensorValue (or the value that has the sensor value stored in it), but I cannot see that in your sketch.

    total += 0.3;

is the same as writing:

    total = total + 0.3;

The value right of the '='sign is copied (assigned) to the left part of the '=' sign.


body:
Why bother doing that arithmetic at every tip, when you could just count tips, and multiply the count by 0.3 whenever a result is needed?

`tips += 1;                    // each time the bucket tips.`

and

`Serial.println(0.3 * tips);   // each time you want a result`


message:
How to make an arduino webserver over USB? without ethernet shield nor wifi chip

I would like to begin to understand ethernet handshakes by integrating an Ethernet over USB protocol within an arduino mega or nano. Is there something about the ethernet protocol that requires more  components? I know that USB to ethernet adapters exist. In this scenario, it would be more like a USB to arduino webserver experiment, except the arduino webserver would also be providing the IP address to the laptop during the initial handshake.

Shouldnt it be possible to create a simple router from an ATMega2560, where you plug in an arduino to a computer, and the computer is assigned an IP address on the ATMega's network?

Likewise, couldnt you then serve small files from the ATMega to a web browser through this IP connection?

I know this sounds dumb and like over engineering. But i promise i am not crazy and that this could be useful. USB to Ethernet adapters and drivers exist, so i am not sure that there is a hardware limitation. In other words, while ethernet normally requires 4 data lines and USB 2.0 has only 2 data lines, there are still kernel drivers that allow USB to work fine in this way. Likewise the ATMega has only 2 available data lines. So couldnt you begin by simulating a USB to Ethernet device firmware using the ATMega?

A new avenue here that isnt available with Serial connections would be that you could access the ATMega from a web browser, whereas in other driver modes the browser doesnt have the permission to communicate with the Mega.

Why or why not? / How could this be done?

body:
You cannot change what the Arduino's USB does. The USB is not provided by the ATMega2560, but by the USB to UART interface chip.

On a genuine Arduino that may be an ATMega16U2 which could be reprogrammed, but on Chinese clones it most often isn't.

You would need to start with a board that has a real "native" USB connection, such as the Arduino Leonardo (ATMega32U4) or the much more capable (though deprecated) Arduino Due.

Then you would need to create not only the USB "CDC/ECM" device profile, but also the IP stack on top of it to handle the IP data, then a TCP later on top of that to handle the socket data.

The actual CDC/ECM device itself is very simple - much like the CDC/ACM (USB serial) device it's really just a dumb pipe that sends and receives raw Ethernet frames. Interpreting those frames and managing TCP/IP sessions and streams is a far more involved process and would be the bulk of the work. You'd probably want to take an existing standalone IP stack implementation and replace the existing layer 2 code with the CDC/ECM interface instead.

An alternative, as advocated by @Juraj, is to use [IP over Serial](https://playground.arduino.cc/Code/SerialIP/). This uses a serial protocol ([SLIP](https://en.wikipedia.org/wiki/Serial_Line_Internet_Protocol)) to encapsulate the IP frames and has a rudimentary cut-down IP stack in it. However this is old technology and is not well supported by operating systems any more. For example the home versions of Windows no longer have any SLIP support (it used to be provided through "DUNS" - the Dial UP Network Server - which no longer exists).


message:
HTTP-POST returns 400 when posting a value from the sensor

I'm trying to POST the data of `total`, but it returns 400. but when I try a sample data like

`int httpResponseCode = http.POST("{\"amount\":\"total\"}");` (400)

into

`int httpResponseCode = http.POST("{\"amount\":\"15\"}");` it works (201).

How to make it work? Thanks!

```c++
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>

const byte interruptPin = 4;
const int interval = 500;
volatile unsigned long tiptime = millis();
volatile float rainrate = 0.3;
volatile float total;
void ICACHE_RAM_ATTR count();

void loop() {
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if (WiFi.status()== WL_CONNECTED) {
      HTTPClient http;

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

      // Specify content-type header
      http.addHeader("Content-Type", "application/json");

      // Data to send with HTTP POST
      int httpResponseCode = http.POST("{\"amount\":\"total\"}");

      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);

      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
    lastTime = millis();
  }
}

void count() {
  // Grab the current ms count for common calculations
  unsigned long curtime = millis();

  // Make sure we don't record bounces
  if ((curtime - tiptime) < interval) {
    return;
  }

  // How long since the last tip?
  unsigned long tipcount = curtime - tiptime;
  tiptime = curtime;

  total += rainrate;
  Serial.println(total);
}
```

body:
Your line

```c++
int httpResponseCode = http.POST("{\"amount\":\"total\"}");
```

is not doing what you think it's doing. You're not placing the contents of the variable called `total` in the string, you're placing the *word* `total` in the string.

Instead you need to build up the string from components before sending. I'd use something like:

```c++
char temp[32];
snprintf(temp, 32, "{\"amount\":\"%.2f\"}", total);
int httpResponseCode = http.POST(temp);
```

That is assuming the `http.POST()` function will take a `char *` parameter. If not you may need to resort to a `String`:

```c++
String temp = "{\"amount\":\"";
temp += String(total, 2);
temp += "\"}";
```

However it is best to avoid `String` as it can cause heap fragmentation causing your code to become unstable over time.


message:
INA219 with L298N POWER LOGGER

[![enter image description here][1]][1]I Have been working on a power logger with INA219 and L298N
the thing is, the voltage and current displayed on Serial Monitor is not the same on my multimeter.
the Arduino is connected to the pc to view the result on the serial

    #include <Wire.h>
    #include <Adafruit_INA219.h>

    Adafruit_INA219 ina219;

    //Adafruit_INA219 ina219_A;
    //Adafruit_INA219 ina219_B(0x41);

    void setup(void)
    {
      Serial.begin(115200);
      while (!Serial) {
          // will pause Zero, Leonardo, etc until serial console opens
          delay(1);
      }

      uint32_t currentFrequency;

      Serial.println("Hello!");

      if (! ina219.begin()) {
        Serial.println("Failed to find INA219 chip");
        while (1) { delay(10); }
      }
      ina219.setCalibration_32V_1A();

      Serial.println("Measuring voltage and current with INA219 ...");
    }

    void data(void)
    {
      float shuntvoltage = 0;
      float busvoltage = 0;
      float current_mA = 0;
      float loadvoltage = 0;
      float power_mW = 0;
        delay(2000);
      shuntvoltage = ina219.getShuntVoltage_mV();
      busvoltage = ina219.getBusVoltage_V();
      current_mA = ina219.getCurrent_mA();
      power_mW = ina219.getPower_mW();
      loadvoltage = busvoltage + (shuntvoltage / 1000);

      Serial.print("Bus Voltage:   "); Serial.print(busvoltage); Serial.println(" V");
      Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
      Serial.print("Load Voltage:  "); Serial.print(loadvoltage); Serial.println(" V");
      Serial.print("Current:       "); Serial.print(current_mA); Serial.println(" mA");
      Serial.print("Power:         "); Serial.print(power_mW); Serial.println(" mW");
      Serial.println("");

      delay(2000);
    }

    void loop() {

        analogWrite(9, 245); //ENA pin
        digitalWrite(8, HIGH);
        digitalWrite(7, LOW);
        data();
        delay(5000);

        analogWrite(9, 200); //ENA pin
        digitalWrite(8, HIGH);
        digitalWrite(7, LOW);
        data();
        delay(5000);

        analogWrite(9, 150); //ENA pin
        digitalWrite(8, HIGH);
        digitalWrite(7, LOW);
        data();
        delay(5000);

        analogWrite(9, 0); //ENA pin
        digitalWrite(8, LOW);
        digitalWrite(7, LOW);
        data();
        delay(5000);

    }

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

body:
The INA219 gives you the instantaneous current and voltage at a given moment in time, whereas your DMM shows you the *average* over a period.

The L298N is giving out a PWM waveform that is rapidly being turned on and off.

You see where this is going?

Your Arduino detection will be giving you either full power or no power (or somewhere in between owing to the low-pass filter effect of the motor), pretty much randomly, whereas the DMM will give you the average over a number of samples.

You would need to rapidly sample the PWM signal over a period of time and calculate the average to get an idea of what the current and voltage might be.


message:
Built-in LED lighs up spontaneously

I'm trying to connect my [ESP32][1] to [this CO2 measurement][2] device. I admit I am clueless about connecting devices with independent power sources to one another.

I connected ground to ground and CLK to PIN2. Just to be on the safe side, I put a resistor between CLK and PIN2.

I started with 4.8KOhm of resistance. ESP's ADC measured 2.1V and it seemed fine. But when I switched to 1K resistor, trying to get closer to the level of "logical 1" (the way I understand it), something unexpected happened. ADC measured 2.65V, which is still beyond 3.3V ESP should be able to handle, and the built-in LED lit up, although nothing in my sketch called for it.

Though the configuration worked stably for some minutes while I was testing it, and no smoke appeared, I am afraid the LED lighting spontaneously might be a sign of an electrical breakdown.

The both devices are sitting on the same USB hub.

Here is the sketch I am using:

```c++
#define PIN_CLOCK  2

void setup() {
  pinMode(PIN_CLOCK, INPUT);
  Serial.begin(4800);
}

bool last = 0;

void loop() {
  int x = analogRead(PIN_CLOCK);
  bool val = x > 1500;
  if (last != val)
    Serial.println(x*3.3/4095);
    last = val;
  }
```
Can someone explain why the LED lights up?

Can someone recommend a good article/video on basic rules about interconnecting such devices?

[1]: https://docs.zerynth.com/latest/reference/boards/doit_esp32/docs/
[2]: https://revspace.nl/CO2MeterHacking

body:
You do not need a resistor in the circuit. Just connect the devices together directly as shown in the tutorial you link to. They are both 3.3V devices and operate perfectly together with no additional components.

Reading an analog value from a clock signal is pretty meaningless anyway, so there's really no point in your experiments at the moment. They prove nothing.

As to why the light came on - that is most likely because the ESP is configured to use that LED to indicate the WiFi status or something similar.  The thing with an ESP32 is there is a whole lot more going on than just your code. Your code is just one thread in a complex system.


message:
Is this class declaration wrong? " Declaration has no storage class or type specifier" error

While trying to setup  an ESP32 as mqtt publisher I am getting strange errors. Here is my code:

    #include "mqttSetup.h"
    #include <WiFi.h>
    #include <PubSubClient.h>

    static byte httpFailCounter = 0;
    byte counter = 0;

    const char *ssid = "SSID";
    // const char *password = "xxxxx";
    const char *passphrase = "xxxxx";

    WiFiClient espClient;

    const char *mqtt_server = "192.168.1.39";
    const int mqttPort = 1883;
    const char *mqttUser = "xxxx";
    const char *mqttPassword = "xxxxx";

    PubSubClient pubClient(espClient);

    pubClient.setServer(mqtt_server, mqttPort);

    void checkConnection()
    {
        if (WiFi.status() == WL_CONNECTED)
        {
            counter = 0; //reset counter
        }
        else if (WiFi.status() != WL_CONNECTED)
        {
            WiFi.begin(ssid, passphrase);
        }
        while (WiFi.status() != WL_CONNECTED)
        {
            delay(500);
            Serial.print(".");

            counter++;
            if (counter >= 60)
            {
                ESP.restart();
            }
        }
    }

    void reconnect()
    {

        while (!pubClient.connected())
        {
            Serial.print("Attempting MQTT connection...");
            // Create a random client ID
            const char *clientID = "ESP32D-MQTT";
            // Attempt to connect
            if (pubClient.connect(clientID))
            {
                Serial.println("connected");
                // Once connected, publish an announcement...
                pubClient.publish("outTopic", "Hello from ESP");
                // ... and resubscribe
                //   client.subscribe("inTopic");
            }
            else
            {
                Serial.print("failed, rc=");
                Serial.print(pubClient.state());
                Serial.println(" try again in 5 seconds");
                // Wait 5 seconds before retrying
                delay(5000);
            }
        }
    }

I don't understand why the compiler is spitting out the following two errors:

    this declaration has no storage class or type specifier (referring to my pubClient declaration)

    expected a ';'

It doesn't have any issue when I declare the pubClient but at the line :

   `pubClient.setServer(mqtt_server, mqttPort);`

where I use the pubClient it gives the error.

Besides I don't see any ; missing in the code.

Could you please help me figure out the source of error?

---------------------------
Header file for this code chunk

    #ifndef MQTTSETUP_H
    #define MQTTSETUP_H

    void checkConnection();
    void reconnect();

    #endif

------------ Main sketch---------

    #include <Arduino.h>
    #include "Wire.h"
    #include "tempSensor.h"
    #include "mqttSetup.h"

    void setup()
    {
      Wire.begin();

      Serial.begin(115200);
      while (!Serial)
        ;

      shtBegin();
      checkConnection();
    }

    void loop()
    {
      uint32_t newTime = millis();
      static uint32_t oldTime = 0;
      static uint32_t t2 = 0;

      float temp = 0.0;
      float humid = 0.0;

      char senVals[50];

      if (newTime - oldTime >= 10000)
      {
        oldTime = newTime;

        readsht(temp, humid);
        snprintf(senVals, 50, "Temp: %.2f Humid: %.2f", temp, humid);
        Serial.println(senVals);

      }
    }

body:
Code goes in functions, not the global scope.

Your line

```c++
pubClient.setServer(mqtt_server, mqttPort);
```

should be inside a function. Most probably `setup()` so it gets called when your program starts.

Incidentally - where are `setup()` and `loop()` - the two functions that are required by Arduino code?


message:
What is the best way to power the ESP32 from a battery?

I am making a temperature sensor that can go in a freezer and I am trying to figure out what the best method is.

My research has taken me all over the place an I can't seem to find a straight answer. Some sites recommend using LiFePo4, while others say absolutely not, because it needs to be regulated.

One question I have is: could I use more voltage, say 6V from a series of batteries and connect it to the 5V pin since it is regulated, or is it better to go with an external regulator for the 3.3V pin with less voltage?

body: Since it is a freezer (operating temperature unknown) I am assuming it is connected to the mains why not do the same with the electronics. This will save you a lot work and time and when you find out it will not work in a  Faraday cage as stated by timemage.  Leave the sensor wire long enough to mount the electronics outside just in case. Also consider packaging, it will be cold, possibly below the operating range of some of the components requiring you to keep them warm (above minimum temperature). I would assume your freezer like ours has moisture concerns as ice will form when opened then removed by a defrost cycle. You will also have to protect for that. Then there is the operating temperature range of the batteries, are they capable of operating at your freezer temperatures. I would suggest you redefine your problem before starting the design, this process saves me a lot of grief.


message:
ESP8266 wakeup from deep sleep: Both by timer and button?

In a project powered by batteries, the ESP8266 should go to deep sleep for long time, having RF disabled. After some number of sleep cycles, it shall restart with RF enabled, synchronize time via NTP, and again go to sleep. Think this could work with a counter saved in RTC Memory or SPIFFS.

Additionally, s.o. should be able to wake up via push button (at any time), which should result in different behaviour (running as WiFi AP, allowing for configuration of new WiFi credentials).

The question is: Is it possible to find out what did wake the ESP (timer or pushbutton)?

**Edit**: Using external circuitry this might be possible. To avoid this, we switch to ESP32, which is an overkill for the project, but easy to find out the source of the wakeup (and with the possibility to use touch sensors). Additionally, ESP32 allows for easy use of "Preferences" in NVR and variables in RTC memory (when using the Arduino IDE), which will survive deep sleep (RTC) and even reset/power loss (NVR).

body:
Place a capacitor on the ESP side of the button to one power rail or the other (my preference is to ground, but either should work), and have the setup() routine reads the state of the pushbutton switch as it's first instruction.  You probably don't even need the capacitor, but if you don't have it, you'll have to read the switch state multiple times to account for possible contact bounce.

If the ESP wakes up due to a timer, there will be no activity on the PB line; if it wakes up due to the PB being pressed, there will be activity on the PB line for several 10's of millisec no matter how quickly it is pressed and released.


body:
The capacitor solution works, but I wanted to expand on what I did in particular and why I found it beneficial. Here's my circuit:
[![enter image description here][1]][1]

At wakeup, the first thing I do is read D1. After that, I then set D1 to an output and set it high to keep the capacitor charged. That prevents a second button press from resetting the ESP.

Then, when going to sleep, I set the pin low for a few ms to *discharge the capacitor*.

I picked the smallest capacitor possible because there's no downside to charging quickly.

Note that the ESP will reset as the button is pressed down - the pin will go low, and soon after go high as the capacitor charges, all before the button is released. This is ideal in circumstances where you want the act of pushing the button to cause the wake up, not the *release*.

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


message:
How to shorten this code (because my sensor reads slowly)?

I'm making a fare meter for our school project. I have too much `lcd.print` code. This code is not finished yet. My only concern is how to minimize the usage of `lcd.print`. I think it's the one that makes my sensor reading slow.

I'm new at Arduino; sorry if I have too many mistakes. I appreciate any of your answers. Thank you!

```cpp
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <virtuabotixRTC.h>

virtuabotixRTC myRTC(6, 7, 8);
float d[4] = {};
int x = 0;
int f = 0;
int dis = 0;
const uint8_t disBut = 13;
int input = A0;
int state = 0;
int disF = 0;
int buttonstate = 0;
LiquidCrystal_I2C lcd(0x27, 20, 4);
LiquidCrystal_I2C lcd1(0x26, 20, 4);

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd1.init();
  lcd1.backlight();
  pinMode(disBut, INPUT);
  pinMode(buttonstate, OUTPUT);
}

void loop() {
  myRTC.setDS1302Time(18, 10, 10, 7, 18, 9, 2020);

  Serial.print("Current Date / Time: ");
  Serial.print(myRTC.dayofmonth);
  Serial.print("/");
  Serial.print(myRTC.month);
  Serial.print("/");
  Serial.print(myRTC.year);
  Serial.print("  ");
  Serial.print(myRTC.hours);
  Serial.print(":");
  Serial.print(myRTC.minutes);
  Serial.print(":");
  Serial.println(myRTC.seconds);
  delay(500);

  d[0] = (x * 1.73);
  d[1] = (x * 1.73);
  d[2] = (x * 1.73);
  d[3] = (x * 1.73);

  lcd.setCursor(8, 0);
  lcd.print(d[0]);
  lcd.setCursor(8, 1);
  lcd.print(d[1]);
  lcd.setCursor(8, 2);
  lcd.print(d[2]);
  lcd.setCursor(8, 3);
  lcd.print(d[3]);

  lcd.setCursor(0, 0);
  lcd.print(F("P1"));
  lcd.setCursor(0, 1);
  lcd.print(F("P1"));
  lcd.setCursor(0, 2);
  lcd.print(F("P1"));
  lcd.setCursor(0, 3);
  lcd.print(F("P1"));

  lcd.setCursor(6, 0);
  lcd.print(F("D="));
  lcd.setCursor(6, 1);
  lcd.print(F("D="));
  lcd.setCursor(6, 2);
  lcd.print(F("D="));
  lcd.setCursor(6, 3);
  lcd.print(F("D="));

  lcd1.setCursor(0, 0);
  lcd1.print(F("W="));
  lcd1.setCursor(0, 1);
  lcd1.print(F("W="));
  lcd1.setCursor(0, 2);
  lcd1.print(F("W="));
  lcd1.setCursor(0, 3);
  lcd1.print(F("W="));

  lcd1.setCursor(6, 0);
  lcd1.print(F("dscnt="));
  lcd1.setCursor(6, 1);
  lcd1.print(F("dscnt="));
  lcd1.setCursor(6, 2);
  lcd1.print(F("dscnt="));
  lcd1.setCursor(6, 3);
  lcd1.print(F("dscnt="));

  lcd1.setCursor(15, 0);
  lcd1.print(F("F="));
  lcd1.setCursor(15, 1);
  lcd1.print(F("F="));
  lcd1.setCursor(15, 2);
  lcd1.print(F("F="));
  lcd1.setCursor(15, 3);
  lcd1.print(F("F="));

  int counter=digitalRead(A0);
  if (state == 0) {
    switch (counter) {
      case 1:
        state = 1;
        lcd.setCursor(11, 0);
        x = x + 1; lcd.print(x);
        break;
      case 0:
        state = 0;
        break;
    }
  }

  if (counter == LOW)
    state = 0;
  if (state == 0) {
    switch (counter) {
      case 1:
        state = 1;
        x = x + 1;
        break;
      case 0:
        state = 0;
        break;
    }
  }

 if (counter == LOW)
   state = 0;
}
```

body:
Your slowness is because on every single iteration of `loop()` you are updating the entirety of the display.  That's bad and wasteful.

You need to do two things:

1. Only display static information (the labels) once. Do that in `setup()`.
2. Only display the variable data if it actually changes.

The first is simple: move any static text to `setup()`. That means things like `lcd1.print(F("dscnt="));`. It never changes, and the display doesn't "forget" it, so doesn't need constantly reminding.

The second is slightly harder. You need to keep two copies of the data. One that is the data at this moment, and one that is the data that is being displayed. Then you compare one with the other and for any items where they differ display them and update your saved copy.

So something like:

```c++
if (d[0] != d_saved[0]) {
    d_saved[0] = d[0];
    lcd.setCursor(8, 0);
    lcd.print(d[0]);
}
```

You can of course make that easier to program with a loop:

```c++
for (uint8_t i = 0; i < 4; i++) {
    if (d[i] != d_saved[i]) {
        d_saved[i] = d[i];
        lcd.setCursor(8, i);
        lcd.print(d[i]);
    }
}
```

Of course `d_saved[4]` needs creating in either the global scope or as a local `static` variable and initialising with some suitable "can never be" values (like -1 or something) so that the first time through it will always be different from the real values and display everything properly.


message:
How to remove Arduino Due and Mega shields without bending pins?

What's your suggested technique for reliably removing Arduino Due and Mega shields while minimizing the chance of bending the [strip header pins][1]?

For example, there's a similar discussion [here][2] where the asker ended up building a jig to keep everything parallel, but the main PCB was screwed down into the jig (a disadvantage). There is a heap of [PCB Pullers/Extractors][3] on the web, but they all seem to relate to edge connected cards.

I'm hoping for multiple answers / techniques. Interested to hear how you do it, or for you to upvote an answer you like. Maybe everybody is just doing the best they can with finger wriggling and manual pin straightening?

  [1]: https://www.arduino.cc/documents/datasheets/Strip40x1.pdf
  [2]: https://talk.dallasmakerspace.org/t/how-to-remove-a-shield-cape-head-without-bending-pins-arduino-like/4293
  [3]: https://www.google.com/search?q=pcb+extractor&tbm=isch&ved=2ahUKEwieoZSo_rHuAhVu53MBHSUsCPUQ2-cCegQIABAA&oq=pcb+extractor&gs_lcp=CgNpbWcQAzICCAA6BAgAEEM6BggAEAgQHjoECAAQGFD4qQhY2bIIYLK6CGgAcAB4AIABtQGIAbgLkgEDMC45mAEAoAEBqgELZ3dzLXdpei1pbWfAAQE&sclient=img&ei=PQ0MYN6OFO7Oz7sPpdigqA8&bih=1250&biw=2415&rlz=1C5CHFA_enAU934AU934&safe=off

body:
@Majenko's comment suggesting using a toothbrush handle as a lever reminded me of [auto trim levers][1]. I remembered I had some, and have done some quick testing. They give a little more strength I would say, but not much (if any) more control than using fingers.

  [1]: https://www.google.com/search?q=auto trim levers&tbm=isch&ved=2ahUKEwiAk87XhbLuAhWZxHMBHdjtAIQQ2-cCegQIABAA&oq=auto trim levers&gs_lcp=CgNpbWcQA1CKkwFYwJgBYO6nAWgAcAB4AIABogGIAYQGkgEDMC41mAEAoAEBqgELZ3dzLXdpei1pbWfAAQE&sclient=img&ei=9xQMYMC7NpmJz7sP2NuDoAg&bih=1250&biw=2415&rlz=1C5CHFA_enAU934AU934&safe=off


body:
You could modify a couple of wooden clothes pegs to act as reverse pliers.

[![enter image description here][1]][1]
<sub>(source: [niceshops.com](https://cdn-bo.niceshops.com/upload/image/product/large/default/buerstenhaus-redecker-wooden-clothes-pegs-with-coil-spring-20-pieces-loose-191199-en.jpg))</sub>

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


body:
It's an indirect answer to my original question, but having made a number of Due/Mega shields over the year or so since then, I've started making the side pins ~3mm longer than the double row end pins. This helps.

[![Pin Heights][1]][1]

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


body:
I think I've found a nearly perfect tool in [Knipex 45 10 170][1] reverse pliers. The only downside I can currently see is that they're conductive. The (unmodified) wooden clothes peg idea I found did not have enough grip or leverage.

[![Reverse pliers in use][2]][2]

  [1]: https://www.knipex.com/products/circlip-pliers/special-retaining-ring-pliers-for-retaining-rings-on-shafts/special-retaining-ring-pliersfor-retaining-rings-shafts/4510170
  [2]: https://i.stack.imgur.com/SihlA.jpg


body:
Here's the easiest solution. Spend $10 on Amazon and buy one of these "hose pliers".  Put the tips on the double pin end. Gently squeeze. Simple!

https://www.amazon.com/dp/B07G5QSQFQ?ref_=cm_sw_r_apan_dp_Q2FM8GDW6EPGVSNA5XDZ_1

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

  [1]: https://i.stack.imgur.com/8oRvJ.png


message:
Play audio on an ESP32 or an Arduino

I am in the process of making a talking robot and I have linked my ESP32 to a Google text-to-speech service. The service returns me a base64 8-bit audio response.

I need to play this audio and I can't figure out how to do it. I know that an audio playing library exist for PCM but the data that it requires is not base64.

body:
Base64 has nothing to do with audio. It is merely a way of encapsulating binary data into ASCII text so that it can safely be included in text-based structures like JSON, or transmitted over a text-based communication channel.

There is no library to "play" base64 simply because base64 is not something you play.

First you decode the base64 text into raw 8-bit binary. It's then *that* data that you play through whatever library is most suitable for your hardware.

For example on the ESP32 you have the function `base64_decode()` available. You can read up on how to use it in [this tutorial](https://techtutorialsx.com/2018/11/27/esp32-arduino-base64-decoding/).


message:
Need help with millis () function for two linear actuators

Last week I was grateful to receive help programming the Arduino to control two linear actuators.

I need help re-writing the code using the millis () function. I am more than happy to reimburse for time spent on this project. This is my first experience with Arduino and millis () is too involved for me.

The actuators control a set of barn doors in my house. The actuators are programmed to open and close with the push of a button (z-wave relay programmed as 6 second momentary switch). The actuators do not give feedback, so the program is used to control the speed from 0-255 using the PWM ports to make the actuators appear somewhat in sync. They move at three different speeds so that they don't slam when opening and closing. This is where millis () comes in. Right now I am using a delay to control the speed for various amounts of time, but using a delay creates a safety issue since the Arduino cannot do anything during this time.

The reason I need to utilize the millis () function is that I need to be able to make the doors stop and reverse in the event that there is something blocking their path. To accomplish this I will be using a garage door electric eye wired through a homemade circuit board. The output will go low any time the beam is broken and otherwise it will remain high. I'd like the Arduino program to utilize this signal any time the doors are closing and if the beam is broken - make the actuators reverse direction. I realize that without feedback I cannot make the doors open all the way depending on when the beam is broken. I am really not too concerned about that. As long as they stop and reverse for at least a little bit I will be happy. I don't want to crush my kids or pets.

Again, I am more than happy to reimburse anyone willing to help write the code for this. Here is the code I am using now which utilizes the delay function. I'd like this code to be changed to utilize the millis function and also add in programming for the sensor as described above.

    /* Program enables momentary direction control of actuator using push button
     */

    int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
    int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
    int RPWM2 = 5; //connect Arduino pin 5 to IBT-2 pin RPWM
    int LPWM2 = 6; //connect Arduino pin 6 to IBT-2 pin LPWM
    int downPin = 12;
    int upPin = 13;
    int speed1 = 0; // Top speed you can change it between [0-255]
    int speed2 = 0; // Low speed you can change it between [0-255]
    int speed3 = 0; // Low speed you can change it between [0-255]

    void setup() {
      pinMode(RPWM, OUTPUT);
      pinMode(LPWM, OUTPUT);
      pinMode(RPWM2, OUTPUT);
      pinMode(LPWM2, OUTPUT);
      pinMode(downPin, INPUT_PULLUP);
      pinMode(upPin, INPUT_PULLUP);
    }

    void loop() {
      if(digitalRead(upPin)==LOW){ //check if extension button is pressed
        analogWrite(RPWM, 0);
        analogWrite(RPWM2, 0);
        analogWrite(LPWM, 255); // rotate motor with top speed
        analogWrite(LPWM2, 245); // rotate motor with top speed
        delay(3000);               // wait for x sec
        analogWrite(LPWM, 180); // rotate motor with low speed
        analogWrite(LPWM2, 176); // rotate motor with low speed
        delay(1500);               // wait for x sec
        analogWrite(LPWM, 80); // rotate motor with low speed
        analogWrite(LPWM2, 80); // rotate motor with low speed
        delay(1500);               // wait for x sec
        analogWrite(LPWM, 0);     // uncomment if you want to stop motor now
        analogWrite(LPWM2, 0);     // uncomment if you want to stop motor now
      }

      else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
        analogWrite(LPWM, 0);
        analogWrite(LPWM2, 0);
        analogWrite(RPWM, 250); // rotate motor with top speed
        analogWrite(RPWM2, 255); // rotate motor with top speed
        delay(3000);               // wait for x sec
        analogWrite(RPWM, 165); // rotate motor with low speed
        analogWrite(RPWM2, 165); // rotate motor with low speed
        delay(1500);               // wait for x sec
        analogWrite(RPWM, 80); // rotate motor with low speed
        analogWrite(RPWM2, 80); // rotate motor with low speed
        delay(1500);               // wait for x sec
        analogWrite(RPWM, 0);     // uncomment if you want to stop motor now
        analogWrite(RPWM2, 0);     // uncomment if you want to stop motor now
      }

      else{ //if no button is pushed, remain stationary
        analogWrite(RPWM, 0);
        analogWrite(LPWM, 0);
        analogWrite(RPWM2, 0);
        analogWrite(LPWM2, 0);
      }
    }

body:
You've come to the requirement called non-blocking programming. The gist of it is that your loop() function does little other than call a number of "maybe-do" functions - my name for functions that assess the need to act, and act or not, and return, as quickly as possible. So in pseudo-code, your loop might look something like:

    void loop(){
       maybeStartMotor1();
       maybeSlowMotor1();
       maybeStartMotor2();
       maybeSlowMotor2();
       maybeStopMotor1();
       maybeStopMotor2();
       // Call maybe-do()s for ... whatever else might need to happen
    }

Your maybe functions would probably look like, e.g.:

maybeSlowMotor1(){
   if( millis() - millis_at_motor1_start > DECELTIME2 )
      set motor1 to slow speed;

   else if( millis() - millis_at_motor1_start > DECELTIME1 )
      set motor1 to medium speed;

   return;
}

Note that my understanding of your mechanical system is limited and the above is meant to describe a software technique, not a solution.

Also note my complete agreement with @timemage's caution against depending on software for your safety interlocks. Your 3rd comment under your question - to directly reverse the doors with photocells and relays - in addition to the software detection and control - provides a necessary redundancy.

I'd also like to refer you to [this somewhat more complete description][1] I wrote to answer another, similar, question.

  [1]: https://arduino.stackexchange.com/questions/60759/how-to-rotate-two-or-more-steppers-simultaneously-by-giving-array-of-angles/66380#66380


message:
Problem with sending IR with at ATMega328P-PU

[![S[![Another angle with arduino][1]][1]Sorry the wiring is messy, I only have small breadboards. The far top left row is ground and the front left is 5v][2]][2]I have a sketch that sends an IR code every second. It works fine (the correct code is received by my receiving Arduino next to it) on the Arduino but when I try to move the sketch to an ATMega328P-PU, the IR no longer sends (the serial monitor output still works).

I have used a camera to look at the IR LED and it just doesn't flash on the ATMega328 but does on the Arduino (and I have tested my LED, it does work). It uses pin 3 on the Arduino, so I use pin 5 on the ATMega328.

Are there extra components that are needed to make PWM work without the Arduino board? I am honestly stumped so any help would be appreciated. Thanks in advance.

Sketch:

```c++
#include <IRremote.h>

IRsend irsend; //Setup the IR transmitter

int codeToSend;
int team = 1;
int damage = 0;

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

void loop()
{
    team++;
    if (team > 8) team = 1;
    damage++;
    if (damage > 99) damage = 0;

    if (damage > 9) codeToSend = (String(team) + String(damage)).toInt();
    else codeToSend = (String(team) + "0" + String(damage)).toInt();

    Serial.println("sent");
    irsend.sendNEC(codeToSend, 32);
    delay(500);
}
```

  [1]: https://i.stack.imgur.com/LKsDG.jpg
  [2]: https://i.stack.imgur.com/9z2nB.jpg

body:
NOTE: The following comment was left on this answer (below) and indicates the principal problem the original poster was having above and beyond not having a resistor, etc.

> **SOLVED - my breadboard was broken on that rail. :/**

Current limiting
----------------

What you have pictured looks alright for the most part with the exception of there appearing to be no current limiting resistor for the IRED.  It is possible that you've damaged the IRED by setting the pin HIGH for an extended period of time.  It is also technically possible to have damaged the AVR (or just the one pin) by doing that, though this wouldn't be my first guess.

Typical forward voltages for an IRED around around a volt.  An AVR pin's **maximum** rating current is 40mA.  To get proper logical levels out of it, it should be less than 20mA.  You *could* perhaps operate near 30mA, since you're not doing much else with the AVR's ports and you're not trying to get logic level voltages out of the pin.  For that you'd need a resistor in series with the IRED that is something like  (5V - 1V) / 0.030A, approximately 133 ohms.

[![Modified image of board showing where/how a resistor might be connected.][1]][1]

Transistors
-----------

When people use IRED to make remotes, it is normal to use a transistor to offload the current requirement from the MCU.  And also to operate the IRED above its continuous operation current, closer to it's rated peak/pulse current.  Operating in the low tens of mA often only gets you a meter or so.

That arrangement might look something like the following for higher current pulses around 80mA:

[![Using a transistor to switch an IRED][2]][2]

Asides
------

* I'm not able to read your reset resistor well.  If you're not, do measure it to make sure it's 10K.  If in doubt, remove it.  There is a weaker internal pullup on the AVR reset and it's *usually* enough.  If you wanted you could wire the reset signal over to the UNO reset pin to take advantage of the external pullup, reset switch, and DTR reset mechanism of the UNO itself.

* You may want to add .1uF capacitors from your VCC and AVCC pins to ground.  You can often go without while experimenting, but when you're switching higher currents they'll become more important.

* I have a bunch of those jumpers with the rounded (cylindrical) ends.  They often don't make good connections on breadboard.  You can save some trouble sometimes with "Dupont" type jumpers or just making your own out of solid 22awg hookup wire.

  [1]: https://i.stack.imgur.com/aBOzt.jpg
  [2]: https://i.stack.imgur.com/2yYUZ.png


message:
HTTP_GET not clarified in scope

I'm trying to do an async webserver with access point using an ESP32.

It's a little bit of a mix between [This tutorial][1] for AP and async and [this tutorial][2] since it's also with an async webserver and it uses inputs which I desperately need.

The part I don't understand is I included all the necessary libraries and I still got this error. If I copy-paste the code in one block everything is fine. It was never necessary to declare `HTTP_GET` since it should be a variable from a library.

So what's wrong?

These are my errors:

```
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\Async Webserver ESP32\main\main.ino:3:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    In file included from C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:467:0,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.h:5,
                     from C:\..\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp:1:
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h: In constructor 'AsyncCallbackWebHandler::AsyncCallbackWebHandler()':
    C:\..\Arduino\libraries\ESPAsyncWebServer-master\src/WebHandlerImpl.h:76:49: error: 'HTTP_ANY' was not declared in this scope
         AsyncCallbackWebHandler() : _uri(), _method(HTTP_ANY), _onRequest(NULL), _onUpload(NULL), _onBody(NULL), _isRegex(false) {}
                                                     ^
    C:\Users\Valentin\AppData\Local\Temp\arduino_build_497972\sketch\webserver.cpp: In function 'void setup_server(AsyncWebServer)':
    webserver.cpp:6:18: error: 'HTTP_GET' was not declared in this scope
       server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
                      ^
    Multiple libraries were found for "WiFi.h"
     Used: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
     Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
    Using library ESPAsyncWebServer-master at version 1.2.3 in folder: C:\..\Arduino\libraries\ESPAsyncWebServer-master
    Using library FS at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\FS
    Using library WiFi at version 1.0 in folder: C:\..\Arduino15\packages\firebeetle32\hardware\esp32\0.1.1\libraries\WiFi
    Using library AsyncTCP-master at version 1.1.1 in folder: C:\..\Arduino\libraries\AsyncTCP-master
    exit status 1
    'HTTP_GET' was not declared in this scope
```

I already tried to use the standard Arduino WiFi library which resulted just in more errors so I switched it back.

I split up the code into three pieces for better visibility.

**main.ino**

```c++
#include <Arduino.h>
#include "webserver.h"

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "blabla";
const char* password = "blabla";

void setup() {
  Serial.begin(115200);
  WiFi.softAP(ssid, password);
  IP = WiFi.softAPIP();

  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(IP);

  setup_server(server);
}

void loop() {}
```

**webserver.cpp**

```c++
#include "webserver.h"

void setup_server(AsyncWebServer server) {
  // Send web page with input fields to client
  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/html", index_html);
  });

  // Send a GET request to <ESP_IP>/get?input1=<inputMessage>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {
    // GET input1 value on <ESP_IP>/get?input1=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      inputParam = PARAM_INPUT_1;
    }
    // GET input2 value on <ESP_IP>/get?input2=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      inputParam = PARAM_INPUT_2;
    }
    // GET input3 value on <ESP_IP>/get?input3=<inputMessage>
    else if (request->hasParam(PARAM_INPUT_3)) {
      inputMessage = request->getParam(PARAM_INPUT_3)->value();
      inputParam = PARAM_INPUT_3;
    }
    else {
      inputMessage = "No message sent";
      inputParam = "none";
    }
    Serial.println(inputMessage);
    request->send(200, "text/html", "HTTP GET request sent to your ESP on input field ("
      + inputParam + ") with value: " + inputMessage +
      "<br><a href=\"/\">Return to Home Page</a>");
    });
    server.onNotFound(notFound);
    server.begin();
  }

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}
```

**webserver.h**

```c++
#ifndef WEBSERVER_H
#define WEBSERVER_H

#include "Arduino.h"
#include "ESPAsyncWebServer.h"
#include "AsyncTCP.h"
#include <WiFi.h>

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";

AsyncWebServer server(80);

String music_state;
IPAddress IP;

String inputMessage;
String inputParam;

// HTML web page to handle 3 input fields (input1, input2, input3)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>ESP Input Form</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input2: <input type="text" name="input2">
    <input type="submit" value="Submit">
  </form><br>
  <form action="/get">
    input3: <input type="text" name="input3">
    <input type="submit" value="Submit">
  </form>
</body></html>)rawliteral";

void setup_server(AsyncWebServer server);

void notFound(AsyncWebServerRequest *request);

#endif
```

Thanks for the input, I will check back tomorrow and answer all questions and test every suggestion.

  [1]: https://techtutorialsx.com/2018/01/07/esp32-arduino-http-server-over-soft-ap/
  [2]: https://randomnerdtutorials.com/esp32-async-web-server-espasyncwebserver-library/

body:
Macro Conflict
--------------
You have two basic problems here.  The more significant one is that your use of SERVER_H in your include guard:

```c++
#ifndef WEBSERVER_H
#define WEBSERVER_H
```

conflicts with a usage in [ESPAsyncWebServer.h][1]:

```c++
#ifndef WEBSERVER_H
typedef enum {
  HTTP_GET     = 0b00000001,
  HTTP_POST    = 0b00000010,
  HTTP_DELETE  = 0b00000100,
  HTTP_PUT     = 0b00001000,
  HTTP_PATCH   = 0b00010000,
  HTTP_HEAD    = 0b00100000,
  HTTP_OPTIONS = 0b01000000,
  HTTP_ANY     = 0b01111111,
} WebRequestMethod;
#endif
```

and that explains why your `HTTP_GET` etc are not found.  They're not being defined because of your include guard macro.

Changing your code to:
```c++
#ifndef XENOSHELL_WEBSERVER_H
#define XENOSHELL_WEBSERVER_H
```

or something similar will get you past that problem.

Multiply Defined Variables
--------------------------

You also have some non-static variables defined in your webserver.h that will also need to be changed somehow.  A simple change just being to make them static:

```c++
static const char* PARAM_INPUT_1 = "input1";
static const char* PARAM_INPUT_2 = "input2";
static const char* PARAM_INPUT_3 = "input3";
```

`IPAddress IP;` is only used in main.ino, and should be moved there as a local `const IPAddress IP = WiFi.softAPIP();`  If you leave it in the header you'll get multiple definitions because of that.

`String inputMessage;` and `String inputParam;`   Same problem, only these belong inside your lambda expression in `server.on("/get", HTTP_GET, [] (AsyncWebServerRequest * request) {`

I don't know why your server variable is in the header either.  The simplest thing to do is put it in webserver.cpp instead and don't pass it in to `setup_server`, in other word remove the parameter and use the variable defined in the same file as the function.

---

Having done that your code compiles fine.
Whether or not it works is another question.
I am unable to test that.

  [1]: https://github.com/me-no-dev/ESPAsyncWebServer/blob/f6fff3f91ebf45b91ca4cff2460d2febd61f1e27/src/ESPAsyncWebServer.h#L60


message:
What is the maximum frequency input signal that I can accurately track on a GPIO pin?

This all started with me wanting to use an Arduino to make a tachometer. This is all now working fine, but it got me wondering what the highest frequency digital signal that I could read?

So I built a simple test sketch and have run this on both a Nano and an ESP32. The result was about 6300Hz on both. Anything above this gives chaotic results. This is somewhat lower than I expected.

Has anybody done better than this?

body:
As Majenko wrote, when you only rely on software to measure the frequency on a IO pin, it will always be rather slow. And it also depends on the code, that you use. Functions like `digitalRead()` are always slower than directly working with the control registers of the pin ([Reference][1]). As you didn't show your code, we cannot say more about that.

If you need to measure higher frequencies or you want to do other things in between (like outputting the data somewhere), it is better to use the microcontrollers buildin hardware. There are multiple ways to measure the frequency. 2 immediately come to my mind:

- You could assign an ExternalInterrupt or a PinChangeInterrupt to the signal pin (limited choice of pins here), which triggers each time you see a rising (or falling) edge on the signal. In the ISR (Interrupt Service Routine) you could count up a variable. That value is the number of rising (or falling) edges, thus periods of the signal. The frequency is this value divided by the duration of the measurement. Every time you calculate the frequency, you reset the counter; reading it again after a defined duration. This should be better than just polling, but its not the best. (Note that a PinChangeInterrupt triggers on every edge, so you have to divide the frequency by 2)

- You could configure an unused Hardware Timer/Counter to use your signal as external clock source. Let it count up until it overflows (or up to a value defined by you) and let it trigger an interrupt. Since the Arduino framework already uses Timer0 for timekeeping, you could divide the max value of the Timer/Counter by the time passed and you will get the frequency. I think this can get you in the MHz range.(As with PinChangeInterrupt, the Counter will increment on every edge, so again a factor of 2 here)

Both ways will calculate the frequency as a mean over a specific time. If you have a changing frequency, you might wanna manipulate measurement frequency. In the first case you can change the interval, in which you read the counter variable. In the second case you can change the max value, to which the Timer/Counter will count.

> what the highest frequency digital signal that I could read?

(I assume you just want to read the frequency of the signal) That depends on many factors. If we use the second case from above (configuring a Hardware Timer as Counter connected to the signal) we have a limit on the maximum frequency, that we can provide. I found the relevant part in the datasheet of Atmega328p (which is the microcontroller on the Nano):

> Each half period of the external clock applied must be longer than one system clock cycle to ensure correct
sampling. The external clock must be guaranteed to have less than half the system clock frequency (f ExtClk < f clk_I/O /2) given a 50/50% duty cycle. Since the edge detector uses sampling, the maximum frequency of an
external clock it can detect is half the sampling frequency (Nyquist sampling theorem). However, due to
variation of the system clock frequency and duty cycle caused by Oscillator source (crystal, resonator, and
capacitors) tolerances, it is recommended that maximum frequency of an external clock source is less than
f clk_I/O /2.5.

So we should stay below the controllers clock frequency divided by 2.5, which would be `16MHz / 2.5 = 6.4MHz` for the Nano. But before you reach that, your code might introduce further delays, which make the measurement less accurate. That depends on the implementation.

[1]: https://www.arduino.cc/en/Reference/PortManipulation


body: My DaquinOscope <https://www.daqarta.com/dw_rroo.htm> can use burst sampling to grab 1024 samples at high sample rates, then send them to a host computer over USB for display and analysis. For digital-only inputs it can acquire over 400,000 samples per second on an UNO, with each sample being a reading of 8 pins to make one byte in the record.  It does this by reading a digital port (PIND or PINB) in a tight loop, with an optional delay on each read for slower sampling. DaquinOscope is free, and it uses the open-source DaqPort <https://www.daqarta.com/dw_rraa.htm>, both included with Daqarta, complete with code that you can modify as desired.


message:
Controlling LEDs with bit bang method

I'm doing a research for RGB LED chips that MCU can control with one pin. I found [this LED chip][1] and it seems controlling LEDs is not as I've tought. I understand hardware part, software side is a problem.

In chip's datasheet, on page 6, you can find chapter four `Data Transfer Format`.

**My questions are:** Why `D2` has only `second 24 bit`, `third 24 bit` while `D3` has only `third 24 bit` and why `D4` has no bits? What should I do when I'm done with "updating LEDs"?

I thought controlling LEDs can be done like this:

 - Lets say I have five LEDs to control. Every LED has Red, Green and Blue and every color is 8-bit. Five times three is 15 bytes array.
- First three bytes in array are for last LED chip. While sending the data, highest bit(bit 7) will go first.
- After first three bytes, MCU will stop for X microseconds. After delay, new three bytes will push old three bytes to second LED chip.
- After MCU is done with sending data, it will leave data pin low.

Thanks!

  [1]: https://mouser.com/datasheet/2/180/IN-PI55TAT(X)R(X)G(X)B_v1.3-1667473.pdf

body:
You need to send the 5x24 bits out without a pause. If you then keep the line low for over 80us, that is interpreted by all LED drivers as the reset signal. It is not stated explicitly in the datasheet (at least I haven't found it), but I guess the reset signal means, that at that time all drivers will output the received values on the LEDs. That way you can light up all LEDs at the same time with their respective data.

The picture, that you refer to, explains the automatic data cascading. The first row is what you actually send from your microcontroller and also what is seen by the first LED driver in the row. That driver will then consume the first 24 bits, that it sees. After that, it will forward the rest of the data to the next LED driver. That will now consume the first 24 bits that it sees (thus the second 24 bits, that you have send). The third LED driver will do the same. But since in that example you only send data for 3 LEDs, no data is forwarded. Then the reset pulse happens and at some point in time you send a new set of data.

So each row represents, what the corresponding LED driver will see of the data, that you send. D1 sees all the data. Each following LED driver will see 24 bits less. D4 will see nothing, since you send only 3x24 bits in that example.


message:
How to reset the count/data after HTTP.POST?

I have a project that records interrupts from a reed switch to nodemcu.

It records like this: 0.3,0.6,0.9,1.2 Then what I want to happen is to go back to zero when it successfully HTTP.POST to a webserver.

How can I do it? Thanks!

```c++
volatile float rainrate = 0.3;
volatile float total;

void count {
  total += rainrate;
}
```

body:
Try putting your `total` variable to `0`, like this:
`total = 0;`
It should work like this.


message:
arduino mega buzzer output

I have project by Arduino mega which have 22 inputs and 22 outputs and buzzer reset and output reset pushbuttons , it have two status

 1. if the input is high(not continuous ) the output will on and the buzzer will be on, if  output reset pushbutton is pressed  the output will off , if buzzer reset pushbutton  is pressed the buzzer will off.
 2. if the input is always high (continuous high signal on input ) the output will on and the buzzer will be on, in this case we will not reset the output even if the output  reset pushbutton is pressed , and we will be able to reset the(turn off) buzzer by the  buzzer reset pushbutton, and wait until  input state to change to high again to repeat procedure

help me with editing my code

```

    //int input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,23,24}; //input pins (23 for reset ,24 for buzzer reset)
//int output[] = {26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 24, 34, 44, 45, 46, 47, 48,49}; //output pins (49 for buzzer)

int in1 =     2;

int in25 =   26;// for output reset
int in26 =   27;// for buzzer reset

///////////////

int out1 = 28   ;

int out24= 51   ;
int out25= 52   ; // output for buzzer

////////////////////////////////////

int buttonState1 =  0;

int buttonState24 =  0;
int buttonState25 =  0; //for  reset
int buttonState26 =  0; //for buzzer reset

//unsigned long previousMillis = 0;        // will store last time buzzer was updated
//const long interval = 10000;           // interval at which to buzzer (milliseconds)
//int buzzerState = LOW;             // buzzerState used to set the buzzer

void setup() {

  pinMode(in1 , INPUT);

  pinMode(in24 , INPUT);
  pinMode(in25 , INPUT);
  pinMode(in26 , INPUT);

///////////////////////////

pinMode(out1, OUTPUT);
pinMode(out2, OUTPUT);

pinMode(out24, OUTPUT);
pinMode(out25, OUTPUT);

digitalWrite(out25, LOW); // buzzer LOW

}

void loop() {
  buttonState1 = digitalRead(in1);
  if (buttonState1 == HIGH) {
    digitalWrite(out1, LOW);
    //digitalWrite(out25, LOW);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState25 = digitalRead(in25); //read reset button state from input (25) pin 26
  if (buttonState25 == HIGH )

  {
    digitalWrite(out1, HIGH); //reset out1
    //digitalWrite(buzzer, LOW);
  }

  //else {
   // buttonState26 = digitalRead(in26); //read the buzzer reset button state from input (26)pin 27
   // if (buttonState26 == HIGH) {
    //  digitalWrite(out25, HIGH);

   // }
  //}

    //   while (digitalRead(input1) == HIGH);
    //digitalWrite(buzzerrelay, LOW);

    ////////////////////////////////////////////////////////////

 buttonState2 = digitalRead(in2);
  if (buttonState2 == HIGH) {
    digitalWrite(out2, LOW);
   // digitalWrite(out25, LOW);
    //delay(10000);
    //digitalWrite(buzzer, LOW);
  }

  buttonState25 = digitalRead(in25); //read reset button state
  if (buttonState25 == HIGH )

  {
    digitalWrite(out2, HIGH); //reset the output
    //digitalWrite(buzzer, LOW);
  }

 // else {
  //  buttonState26 = digitalRead(in26); //read the buzzer reset button state
    //if (buttonState26 == HIGH) {
    //  digitalWrite(out25, HIGH);

    //}
 // }

   //////////////////////////////////////////////////////////////

  //  }
 // }

  }

```

body:
Any time you have the same sequence of code repeated over and over with slight variations, that is a "code smell" (an indication that you may be using the wrong approach.)

You should use arrays of pin numbers as you have in the first couple of commented-out lines, and write code that loops through those arrays, as well as functions that take parameters and can do the same thing using different values that are passed in.

Don't try to tackle a problem like this without learning the skills and concepts you need. You said "...I am new to Arduino and arrays , and now I'm focusing on solving buzzer problem." That is a mistake. Code like you have posted is hard to write, hard to read, and **much harder** to maintain.


body:
Here is your code simplified. (untested)

Since the pins are sequential, you could calculate pin numbers, instead of using an array for pin number lookup.

For example, you could use a loop `for (int i = 1; i < 25; i++)` and first input pin would be referenced as `i + 1` and first output pin would be referenced as `i + 27`.

<!-- language-all: lang-cpp -->
```
// https://arduino.stackexchange.com/questions/80972/arduino-mega-buzzer-output

//  int in25 = 26;                           // for output reset
//  int in26 = 27;                           // for buzzer reset

//  int out25 = 52   ;                       // output for buzzer

//  int buttonState25 =  0;                  // for  reset
//  int buttonState26 =  0;                  // for buzzer reset

//  arrays are zero indexed (first element is at index zero)
//  array index      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26

    int in [27] = {255,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27};   // input  pin numbers (26 for reset, 27 for buzzer reset)
    int out[26] = {255, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 24, 34, 44, 45, 46, 47, 48, 49, 50, 51, 52    };   // output pin numbers (52 for buzzer)

    int buttonState[27];

//  unsigned long previousMillis = 0;        // will store last time buzzer was updated
//  const long interval          = 10000;    // interval at which to buzzer (milliseconds)
//  int buzzerState              = LOW;      // buzzerState used to set the buzzer

    void setup() {

      for (int i = 1; i < 27; i++) { buttonState[i] = 0;      }       // clear states of buttons 1 to 26
      for (int i = 1; i < 26; i++) { pinMode(out[i], OUTPUT); }       // configure outputs 1 to 25

      digitalWrite(out[25], LOW);                                     // buzzer LOW

    }

    void loop() {

      for (int i = 1; i < 25; i++) {                                  // loop buttons 1 to 24

        buttonState[i] = digitalRead(in[i]);

        if (buttonState[i] == HIGH) {
          digitalWrite(out[i], LOW);
//        digitalWrite(out[25], LOW);
//        delay(10000);
//        digitalWrite(buzzer, LOW);
        }

        buttonState[25] = digitalRead(in[25]);       // read reset button state

        if (buttonState[25] == HIGH ) {
          digitalWrite(out[i], HIGH);                // reset the output
//        digitalWrite(buzzer, LOW);
        }

//      else {
//        buttonState[26] = digitalRead(in[26]);     // read the buzzer reset button state
//        if (buttonState[26] == HIGH) {
//          digitalWrite(out[25], HIGH);
//        }
//      }
      }
    }
```