title: ARDUINO expected ';' before 'delay'

text:
# Question
Title: ARDUINO expected ';' before 'delay'
I want to shine LED in 64 of 255 duty cycles = level of brightness but it pops up this error (see picture). Can anybody tell me why and help me ? Thank you.

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

}

void loop() {

  analogWrite(11, 64)
  delay{1000};
  analogWrite(11, 0)
  delay(1000);

  // put your main code here, to run repeatedly:

}

```

# Answer
You should write ";" end of each lines.

```
analogWrite(11, 64);
delay(1000);
analogWrite(11, 0);
delay(1000);

```
> 1 votes

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


title: Problem loading sketch to Leonardo

text:
# Question
Title: Problem loading sketch to Leonardo
Today I got Arduino Leonardo to replace my Uno. I've tried running one of sketches I use on the Uno, but with no luck. When I start the upload, RX LED on the Leonardo flashes few times, and after several seconds, L LED pulsates and I get this message:

```
avrdude: ser_open(): can't open device "\\.\COM9": The system cannot find the file specified.

avrdude: ser_send(): write error: sorry no info avail

```

I've checked in *Device Manager*, where it says that Arduino Leonardo is on COM3, and COM3 is also set in Arduino IDE.

However, when I change COM port to 9 in *Device Manager* and also in Arduino IDE and then try to upload the sketch, things start to roll out like above, but this time IDE freezes for 5-10 mins on "Uploading..." part, and finally unfreezes with this message:

```
Found programmer: Id = "B¨J"; type =
    Software Version =
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?

```

Several more infos:

```
- OS: Win7 64-bit
- Arduino IDE: 1.0.5-r2
- Other serial devices: Only Bluetooth that I've manually assigned to COM200, to avoid possible conflicts.

```

# Answer
Per imjosh's suggestion, I've installed IDE version 1.5.7 BETA and that solved my problem.
Thanks!
> 1 votes

# Answer
I had my Olimexino 32u4 connected to Axagon USB 3.0 hub and had problems not only to flash but also to find a board. Then plugged it directly to USB 2.0 port on my laptop and it worked. If you have problems with board communicating with PC try to change USB port it is connected to and also try different USB cables.
> 0 votes

---
Tags: serial, uploading, bootloader, arduino-leonardo, avrdude
---


# Question
Title: inconsistent digital output on simple code
so im new on arduino coding, and i made this code, where i input from serial monitor and then use it as a command for digital write. the problem is, sometimes the code work perfectly but then when i input 4, both D3 ad D4 is high and that also happens in D5 and D6. but its inconsistent, and i also print the 'out' value and also which digital pin is high to make it easier.

```
byte b;
int out;
int D3 = 3;int D4 = 4;int D5 = 5;int D6 = 6;int D7 = 7;int D8 = 8;
void setup() {
  Serial.begin(9600);
  pinMode(out, OUTPUT);
  digitalWrite(D3, LOW);digitalWrite(D4, LOW);digitalWrite(D5, LOW);digitalWrite(D6, LOW);digitalWrite(D7, LOW);digitalWrite(D8, LOW);

}

void loop() {
  while (Serial.available() == 0) {}
  b = Serial.read() - 48;
  out = b;
  Serial.print("\n Out is ");
  Serial.println(out);
  digitalWrite(out, HIGH);
  delay(600);
 if (digitalRead(D3) == HIGH)
{
   Serial.print("D3 HIGH");
}
 if (digitalRead(D4) == HIGH)
{
   Serial.print("D4 HIGH");}
 if (digitalRead(D5) == HIGH)
{
   Serial.print("D5 HIGH");
}
 if (digitalRead(D6) == HIGH)
{
   Serial.print("D6 HIGH");
   }
 if (digitalRead(D7) == HIGH)
{
   Serial.print("D7 HIGH");
}
 if (digitalRead(D8) == HIGH)
{
   Serial.print("D8 HIGH");
   }
  digitalWrite(out, LOW);
  delay(1000);

}

```

does anyone know why this happens? or can anyone recommend another method to do what im tryinng to do? thank you guys!!!

# Answer
> 0 votes
If I look at the first 5 lines:

```
byte b;
int out;
int D3 = 3;int D4 = 4;int D5 = 5;int D6 = 6;int D7 = 7;int D8 = 8;
void setup() {
  Serial.begin(9600);
  pinMode(out, OUTPUT);

```

You see that `pinMode`out, OUTPUT)`uses a variable`out`which is not initialized (it's only declared in`int out\`'.

I assume `D3` to `D8` are all output pins, so you have to replace the last line with:

```
pinMode(D3, OUTPUT);
pinMode(D4, OUTPUT);
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);

```

Also, since you are using all pins in the same way, I suggest you use two variables: `startPin` and `endPin`. Then you can use a `for` loop to iterate through all pins. Also

* always initialize variables.
* use '0' instead of 48 when you convert from a byte value to a character (since you don't need to know the ASCII value of '0').

I don't have an Arduino compiler at hand, but it should look something like:

```
byte b = 0;
int out = 0;
const byte startPin = 3;
const byte endPin = 8;

void setup() {
  Serial.begin(9600);
  for (byte pin = startPin; pin <= endPin; pin++)
  {
      pinMode(pin, OUTPUT);
      digitalWrite(pin, LOW);
  }
}

void loop() {
  while (Serial.available() == 0) {}
  b = Serial.read() - '0';
  out = b;
  Serial.print("\n Out is ");
  Serial.println(out);
  digitalWrite(out, HIGH);
  delay(600);

  ...

```

However, from here you are using the pins as INPUT pins. You cannot change those on the fly, you might change them manually (by using `pinMode(pin, INPUT)`), but it does not seem normal to switch input and output pins, so maybe you should explain what you are intending with your application.

---
Tags: serial, programming, communication, code-review, digitalwrite
---


# Question
Title: WeMos D1 ESP-Wroom-02 Mother Board ESP8266 - where is reset pin for deep-sleep
This item was bought for battery use with deep sleep purposes. For doing so in ESP8266 `reset` pin must be connected to `Gnd` pin in order to wake up. This board lacks a `reset` on- board pin. Since spec states it has a such capabilities - I wonder if someone has succeeded with putting it to sleep ( and wake it back on ).

PS - I know that on-chip `gpio16` can be soldered to on-chip `gnd` \- I'm hoping there is a more elegant, not soldering invloved, solution. Guy

# Answer
> 3 votes
This support page has the instructions for enabling deep sleep:

Support for WeMos D1 ESP-Wroom-02 Nodemcu

edit by Guy: in short, solder/connect pins as shown circled in red:

---
Tags: esp8266, pins, sleep
---


# Question
Title: Can analog pins be defined as either their analog name (A0) or their digital pin number?
Can analog pins be defined by their digital pin number, and be used for analog purposes?

For example, instead of defining `A0` for a pinout with the Uno, it could be `14`?

Where is this documented? Is there a PDF type manual related to this, but not so low level to get into the ATmega chip?

https://www.arduino.cc/en/Hacking/PinMapping2560

# Answer
> For example, instead of defining A0 for a pinout with the Uno, it could be 14?

Yes. In fact A0 is just a placeholder for the number 14.

For all these things you should look in the `pins_arduino.h` file (Arduino\variants\wifio) for any variant you are interested in. That's where most of these symbols are defined. For example:

```
#define PIN_A0   (14)
#define PIN_A1   (15)
#define PIN_A2   (16)
#define PIN_A3   (17)
#define PIN_A4   (18)
#define PIN_A5   (19)
#define PIN_A6   (20)
#define PIN_A7   (21)

static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;
static const uint8_t A6 = PIN_A6;
static const uint8_t A7 = PIN_A7;

```

Incidentally, on the Uno you can also just use `0` for A0 with `analogRead()`.
> 4 votes

---
Tags: port-mapping
---


# Question
Title: Best way to ask Arduino for data from Python?
I'm trying to send numerical data from inertial sensors from my Arduino to a Python script via serial (PySerial). I found that if I continuously send the data from the Arduino without stopping, the serial buffer fills up quickly and the sensor measurements that the Python reads becomes delayed.

To fix this, I thought of having the Python script send over a transmit command to the Arduino when it needs data. I'm sending a char 't' to signify this command, but the delay between Python sending the command and the Arduino sending the data is too large.

I'm wondering if there's a 'proper' way of doing this, as I'm sure it's probably been done before?

# Answer
> 1 votes
This is not a complete answer to your problem, but currently you seem to have some misconceptions, that prevent you from pin pointing the actual problem.

The data transmission from the sensor, over the Arduino to your python script on the PC has multiple places, where a bottleneck can appear. The total data rate will then be at maximum as large, as the smallest bottleneck allows it to be.

First you have a potential bottleneck in the communication between sensor and Arduino. You haven't stated, what kind of IMU chip you have and how it communicates. Typical IMU chips like the MPU series are interfaces via I2C or SPI. SPI can be sped up rather greatly, while I2C is not that easy to speed up. But it depends greatly on the capabilities of the used chip. You can find information about that in the corresponding datasheet of the chip.

---

The next interface is the Serial (UART) interface between Arduino and PC. This interface has a fixed baudrate. When you use `Serial.write()` or its siblings, you simply fill the send buffer of the `Serial` library. The data will then be send out automatically at the correct timing for your baudrate. The transmission always happens, if the python script is reading or not. The transmission also happens, when the serial buffer of the script is full. The Arduino does not know about the buffer being full. So in this case the data is not delayed, but lost.

---

The last - and probably most important - potential bottleneck is how you read and send the data on Arduino and in the python script. Here I'm covering the Arduino side.

You should not use functions like `Serial.readString()`, as they work with a timeout, which will slow down your code drastically. Instead you should read the Serial data byte by byte into a buffer, delimiting your message with a special character (for example the newline character `\n`). You check, if there is any data `Serial.available()`, and if yes, you read one byte into a `char` array, which is your own buffer. You are doing that repeatedly, until you read the delimiting character. Then you process the complete message. That way will give you some important improvements:

* You can do things in the meantime (for example reading new data from your sensor)
* It works without any arbitrary timeout, thus not slowing down your code unnecessaryly
* The delimiting character frames a full message, so that you can distinguish two different messages from each other and thus easier process them

---

Considering the above, you should make the requirements clearer:

* How much latency between the actual sensor measurements and the receiving in the python script is ok for you, meaning: How old can the measurements be, that the python script gets? (You just stated, that it is too large, but you have not mentioned how large)
* Do you need continuous data transmission, or just one or a few sets of the IMU data?

Then you can check for the needed speed and data rate. Check, if all involved interfaces and codes can really handle your requirements.

Also it would be easier for us to help you, when you show your current code in your question.

---
Tags: arduino-nano, python
---


# Question
Title: Extremely unstable analogRead() on Arduino Nano when powered from an external source
I'm doing a really simple project with an Arduino Nano and found a problem. The circuit is a simple temperature sensor and a tension read from an analog pin everything showed on a Nokia 5110 LCD.

When the Nano is connected to the USB everything works and the reads are perfect.

When I install the circuit on my car taking the 12V to the Vin and the GND from the centraline everything goes bad: I certainly know that the 12V is obviously not stable and oscillates a lot (between 12V and 14V).

What can be the solution? Should I add some ref or should I regulate the input tension to maintain it stable to a certain quantity?

# Answer
You can use a branded 5 V charger made for cars. You can directly connect this to 5 V pin of the Arduino.

By doing this:

1. you are protecting the Arduino from the noise as well as high voltage spikes coming from the car 12 V supply
2. protecting yourself and others coming in contact with the Arduino or the sensors connected to the Arduino.

You can also

1. consider filtering the analog data read
2. protection circuits such as surge protection diodes or a 5.7 V Zener across 5 V and Ground of Arduino
> 2 votes

---
Tags: arduino-nano, power, analogread, analogreference
---


# Question
Title: What Minimum Value Can I Measure With ACS712 30A Current Sensor?
I am making an Arduino multimeter for current measurement. I first thought about using a shunt but that fails to work since I need to measure current in the mA range.

# Answer
That model has a sensitivity of 66mV/A which means for every 1A of current passing through it outputs 66mV.

The Arduino's ADC when running at 5V has a resolution of (5/1024) 4.88mV per LSB.

That means that 4.88/66 gives you 0.074 - or 74mA per LSB.

Since 1LSB is considered to be in the noise area of the signal you can expect the minimum usable value to be double that - 148mA

Which is pretty useless for measuring currents in the mA range.

You would get better results with the 5A variant, but still not great.
> 2 votes

# Answer
The datasheet for the ACS712 shows the following:

This means the 30A variant has a sensitivity of 66mV/A. This means a reading of 1A will show 66mV plus some bias voltage. The Arduino ADC is 10-bit, meaning it has 2^10 = 1024 increments across a default 5V voltage reference for the Uno, Nano, etc. This gives it a measuring resolution of 5V/1024 increments = 4.88mV voltage resolution. 4.88mV / 66mV/A = 0.074A, or 74mA.

So, the default *resolution* of an Arduino Uno, Nano, etc, is **74mA.** Realistically it will bounce around this value, so your *precision* might be about 3~4x this, or around **300mA**, and your accuracy is as good as you calibrate it, which could easily be around this value too if you calibrate it well.

74mA resolution isn't bad, but there are several tricks to improve this. Here are a few:

**1. External hardware solutions:**

1. **Use the 20A or 5A version instead of the 30A version of the ACS712.** The 5A version has a sensitivity of 185mV/A, which automatically improves your resolution to 4.88mV / 185mV/A = 0.026A, or **26mA**, which is 74mA/26mA = **2.8x better**.
2. **Buy an external ADC with high-resolution.** This Adafruit ADS1115 16-Bit ADC (datasheet) will improve your resolution on the 30A version of the ACS712 as follows. Minimum resolution of the ADC is now 5V/2^16 = 5V/65535 = 0.0763mV instead of 4.88mV, and 0.0763mV / 66mV/A = 0.001156A, or **1.156mA**.

**2. Software solutions (freebies!):**

1. **Change your voltage reference to use the internal 1.1V internal reference.** This is easy: call `analogReference(INTERNAL)` in your `setup()` function. Done! See: https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/. If I recall correctly, this is a diode-based internal voltage reference (see the ATmega328 datasheet), and can be off by as much as 10% from part to part, so calibrate it for each individual Arduino you have and you will get good results! Now, your ADC resolution is 1.1V/1024 = 1.07mV instead of the Arduino's default 4.88mV, so your current resolution is 1.07mV / 66mV/A = **16.2mA**, which is 74mA/16.2mA = **4.6x better**.
2. **Use oversampling to increase the Arduino's 10-bit ADC to up to ~16 bits or so.** Atmel Application Note AVR121: Enhancing ADC resolution by oversampling explains this very well, albeit it requires some serious study. There are libraries which exist to do this for you which you can Google for. I wrote one of them. Here is a link to my website where I present one such library I wrote. The gist is this: to get an 11-bit reading (which is 1-bit better than your hardware ADC resolution of 10-bits) you need to take 4^1 = 4 10-bit readings, sum them, then divide by 2^1 = 2. Your max value will be 1023 x 2 = 2046. To get a 16-bit reading (which is 6-bits better than your hardware ADC resolution of 10-bits) you need to take 4^6 = 4096 10-bit readings, sum them, and divide by 2^6 = 64. Your max value will be 1023 x 64 = 65472. Your voltage resolution will be improved from 4.88mV to ~0.0764mV *at best*. It won't be as good as a true 16-bit ADC, like the Adafruit one above, but it's good enough for many uses. Keep in mind that 4096 10-bit readings takes some time, so I also recommend you speed up the ADC clock to improve reading rate at 10-bits from ~10kHz to ~50kHz. This is also where a library comes in handy to make this easy to do. Free and open source solutions already exist. Here's a table I made back when I first read the AVR121 application note and practiced oversampling. Consider the resolution values beyond ~16-bits to be purely theoretical. Oversampling has its limits.
    1.

What would I do? I'd use the 1.1V internal voltage reference and oversampling with increased ADC clock speed on the ACS712 part which provides the minimum acceptable max current (ie: choose the 5A version not the 20A or 30A version if 5A is enough, or the 20A version not the 30A version if 20A is enough). **Just be sure that your max voltage now at the analog pins will not exceed the 1.1V Vref value**. If it will, use the standard 5V reference for the ADC, and just do oversampling alone. My current resolution would end up being a few mA in the end. If I can't sample at the desired frequency using oversampling (I don't know what dynamic effects you may be trying to measure), then I'd use an external high-resolution ADC which can sample faster than oversampling at high resolutions would allow.

---

And if that's not good enough, what would I do? I'd use a precision shunt, ie: "current resistor" with the right value such that I can measure values at the right range. If I need amplification I'd buy an external ADC and/or op-amp from Adafruit until I have everything sized just right. Remember, if your shunt (current resistor) is too small to measure the low currents you need, do the following:

1. Use a higher resistance value. V = IR (Voltage = Current x Resistance), so increase R to increase the V across it for a given current, I.
2. Use an op-amp to amplify the voltage drop across the resistor (go for an Adafruit one since Adafruit makes it easy and has the world's best examples).
3. Use a high-resolution ADC, and/or oversampling to increase your sensitivity to measure small voltage changes.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: What does "Update of OCR1x at" mean in the WGM table of ATMEGA328?
I just finished a reading a couple of online guides on how to use timer registers with pulse width modulation, so I'm still new to its concept. When I looked in the ATMEGA328 specification sheet, I see this table:

The column that I'm not completely clear on is the "Update of OCR1x at". I circled row 14 as an example. If you're operating in mode 14 (ie. setting WGM 13, 12 and 11 to high), then you'll be in Fast PWM. By setting a value for ICR1, you are effectively setting the TOP value, which will control the period of the pulse waves. And the overflow flag on the timer will be set when the timer reaches the TOP value.

So does "Update of OCR1x at" mean that only when when the pulse wave form has reached the value of BOTTOM (or the end of a period), that's when the value of OCR1x will be passed on to the OCx pins if COMx bits are set?

# Answer
> So does "Update of OCR1x at" mean that only when when the pulse wave form has reached the value of BOTTOM (or the end of a period), that's when the value of OCR1x will be passed on to the OCx pins...

Yes, that's what it means. To prevent glitches in the PWM output, you frequently do NOT want the PWM waveform to change immediately the instant you update an OCR1A value, for instance, to change the PWM output on output pin A. So, the PWM value you set is double-buffered and only updates the inner buffer used by the output pins once it finishes its current PWM period and reaches the BOTTOM value again, which would be a counter value of 0 in this case. Now, by allowing a previous PWM period to finish before the hardware reads the latest value from the OCR1A/B register (outer buffer) to its inner buffer (which inner buffer actually determines the pin state), you have a nice, clean, glitch-free PWM transition from one value to the next regardless of when you updated the `OCR1A` or `OCR1B` output register.
> 3 votes

---
Tags: pwm, atmega328, timers
---


# Question
Title: What sensors do I need to detect magnetic "take off"?
I want to build a sensor using arduino (or any other esp) measuring the release of a leg on a floor panel. I've build a prototype using copper plates and a BBC Micro:bit, which works fairly well. But I want to use magnetic sensors, determining release of the leg.

My education on magnetic is - simple. I know it exists. I know it's one of four basic forces in nature (ha!). But I don't know how to measure it using electronic circuits (I'm new to this topic).

Imagine one person stands on a plate, wearing magnets on his foot (say "magnetic socks"). I want to immediately detect when the person raises his leg. What kind of sensors do I need?

# Answer
You have two options here, either a Hall Effect sensor or an Inductive Sensor. The hall effect sensor is probably the best option. This will likely need some calibration on your end to identify the exact value you record at "Take Off" for your setup.
> 1 votes

---
Tags: sensors
---


# Question
Title: Can I use an internal clock on Wemos D1 Mini?
I have a working Wemos D1 Mini setup measuring temperature and sending it over wifi to my server. Now I'm using a battery powered unit, and playing around with power consumption optimization and how to reduce it.

One thing I need is time (current, either epoch or DST) - so I implemented NTP, but everytime my ESP is waking up after deep-sleep, it needs to reconnect to wifi, gather time, measure temperature, send results.

This pdf states that ESP8266 has an internal clock. I'm having troubles finding anything beside "RTC shields on Wemos/Arduino" or "NTP on ESP8266" on the internet about something that is like an internal clock. There must be something, because otherwise it could not work (my understanding about clock and hardware is limited by now).

My question is: can I use NTP to update my internal clock, using it for some minutes (I think it will drift after some minutes), updating via NTP once in a while - to simply reduce network traffic and still use deep-sleep mode?

Any hints are welcome!

# Answer
I think the answer to your question can best be summed up by one word: "Kinda".

The best reasoning is the NodeMCU Lua documentation which states:

> Time keeping on the ESP8266 is technically quite challenging. Despite being named RTC, the RTC is not really a Real Time Clock in the normal sense of the word. While it does keep a counter ticking while the module is sleeping, the accuracy with which it does so is highly dependent on the temperature of the chip. Said temperature changes significantly between when the chip is running and when it is sleeping, meaning that any calibration performed while the chip is active becomes useless mere moments after the chip has gone to sleep. As such, calibration values need to be deduced across sleep cycles in order to enable accurate time keeping. \[...\]

So while it's called RTC it's not an RTC in the traditional sense - it's merely a timer that runs even when sleeping, but not with any degree of accuracy.

You can access the current RTC count with the Non OS SDK function

```
uint32_t system_get_rtc_time()

```

You can combine that with

```
uint32_t system_rtc_clock_cali_proc()

```

which gives you the number of uS per tick of the RTC timer.

There's no way to change the RTC timer count, so you will have to work out some "delta magic" to update your own internal time value (an epoch value is simplest) from the difference between successive calls to get the RTC count.

All somewhat tricky and the accuracy won't be great anyway, so you'll be wanting to use NTP to update that epoch value regularly.

But it could give you a "rough idea" of how long you've been asleep for, etc.

You would have to run some experiments to know how much the time drifts compared to the NTP value in real usage.
> 3 votes

---
Tags: esp8266, power, wifi
---


# Question
Title: Can Bluetooth HC-05 Module detect other modules and relay data back to phone?
I want the following to happen:

1. The HC-05 is paired to a phone. The module is called "Amy". The module is worn, say, as a wristband by a person.
2. Amy passes another wristband-with-HC-05-module called "Bob".
3. Amy inquires about Bob, and if the RSSI signal received is strong, it relays the name "Bob" to the phone which will somehow store the information in an app.
4. The HC-05 will pass many other modules, each with different usernames. A list of names will be stored by the phone app.
5. All other HC-05 modules, i.e. Bob and co. , would be doing the same thing with their own phones.

How feasible is this?

# Answer
> 0 votes
Correction - BLE devices give off RSSI, but not Bluetooth. BLE devices can be used as iBeacons. I have settled on the HM-19 Bluetooth 5.0 module. A phone acts as an iBeacon scanner.

---
Tags: bluetooth, hc-05
---


# Question
Title: How to post image using Arduino HTTPClient
I am using arduino HTTPClient to do the post request in ESP32. Can anyone help me with the part where I will be able to post an image file along with some data.

The below code works perfectly fine with only sending user\_name and image\_type-

```
#include <HTTPClient.h>

http.begin("https://www.somelink.com/post-image");

http.addHeader("Content-Type", "application/x-www-form-urlencoded");

String httpRequestData = "user_name=Shidhartha&image_type=Outdoor";

int httpResponseCode = http.POST(httpRequestData);
if(httpResponseCode > 0){
  String response = http.getString();
  Serial.println(response);
}else{
  Serial.print("Error on sending POST: ");
  Serial.println(httpResponseCode);
}

```

# Answer
Below is the perfectly working code I got from here.

```
#include <Arduino.h>
#include <WiFi.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_camera.h"

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

String serverName = "192.168.1.XXX";   // REPLACE WITH YOUR Raspberry Pi IP ADDRESS
//String serverName = "example.com";   // OR REPLACE WITH YOUR DOMAIN NAME

String serverPath = "/upload.php";     // The default serverPath should be upload.php

const int serverPort = 80;

WiFiClient client;

// CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

const int timerInterval = 30000;    // time between each HTTP POST image
unsigned long previousMillis = 0;   // last time image was sent

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
  Serial.begin(115200);

  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println();
  Serial.print("ESP32-CAM IP Address: ");
  Serial.println(WiFi.localIP());

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;

  // init with high specs to pre-allocate larger buffers
  if(psramFound()){
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 10;  //0-63 lower number means higher quality
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_CIF;
    config.jpeg_quality = 12;  //0-63 lower number means higher quality
    config.fb_count = 1;
  }

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    delay(1000);
    ESP.restart();
  }

  sendPhoto();
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= timerInterval) {
    sendPhoto();
    previousMillis = currentMillis;
  }
}

String sendPhoto() {
  String getAll;
  String getBody;

  camera_fb_t * fb = NULL;
  fb = esp_camera_fb_get();
  if(!fb) {
    Serial.println("Camera capture failed");
    delay(1000);
    ESP.restart();
  }

  Serial.println("Connecting to server: " + serverName);

  if (client.connect(serverName.c_str(), serverPort)) {
    Serial.println("Connection successful!");
    String head = "--RandomNerdTutorials\r\nContent-Disposition: form-data; name=\"imageFile\"; filename=\"esp32-cam.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n";
    String tail = "\r\n--RandomNerdTutorials--\r\n";

    uint16_t imageLen = fb->len;
    uint16_t extraLen = head.length() + tail.length();
    uint16_t totalLen = imageLen + extraLen;

    client.println("POST " + serverPath + " HTTP/1.1");
    client.println("Host: " + serverName);
    client.println("Content-Length: " + String(totalLen));
    client.println("Content-Type: multipart/form-data; boundary=RandomNerdTutorials");
    client.println();
    client.print(head);

    uint8_t *fbBuf = fb->buf;
    size_t fbLen = fb->len;
    for (size_t n=0; n<fbLen; n=n+1024) {
      if (n+1024 < fbLen) {
        client.write(fbBuf, 1024);
        fbBuf += 1024;
      }
      else if (fbLen%1024>0) {
        size_t remainder = fbLen%1024;
        client.write(fbBuf, remainder);
      }
    }
    client.print(tail);

    esp_camera_fb_return(fb);

    int timoutTimer = 10000;
    long startTimer = millis();
    boolean state = false;

    while ((startTimer + timoutTimer) > millis()) {
      Serial.print(".");
      delay(100);
      while (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (getAll.length()==0) { state=true; }
          getAll = "";
        }
        else if (c != '\r') { getAll += String(c); }
        if (state==true) { getBody += String(c); }
        startTimer = millis();
      }
      if (getBody.length()>0) { break; }
    }
    Serial.println();
    client.stop();
    Serial.println(getBody);
  }
  else {
    getBody = "Connection to " + serverName +  " failed.";
    Serial.println(getBody);
  }
  return getBody;
}

```
> 3 votes

---
Tags: esp32
---


# Question
Title: Arduino MKR GSM 1400 fails to start up without Serial Monitor
This question is similar to another question, but I have added more details. See: MKR GSM 1400 Works only when connected to computer.

I have designed and built a custom board into which I plug an Arduino MKR GSM 1400. It's a basic IO abstraction level shifter as the system I am integrating to run on 24 V logic (done via opto-couplers). Everything is working perfectly and as-designed. I've added an I2C EEPROM.

When I boot the board from an external ATX supply +12 V line it doesn't complete setup. After I've left it for some time, I connect it to my PC USB port and open the serial monitor in the Arduino IDE and it simply completes the setup process and enters loop successfully.

Voltages are perfect. The 12-24 V supply is first fed through a standard 7810 (since I need +10 V for the analog lines of the controlled system) and then a 7805. The +5 V output of the 7805 is sent into the Vin of the Arduino. Measuring VIN with a DMM reads +5.07 V and VCC reads +3.33 V. I have a 3.7 V, 300 mAh 25C Li-Po connected to the battery port on the Arduino, to deal with the current requirements as specified in the documentation.

I thought this could be a power issue, so I also tried booting it with a 10 Ah USB Power bank that has 2 x 5 V, 2 A (3 A max) USB ports. Same result, until I connect the PC with the serial monitor.

Simplified Arduino Code:

```
#include <MKRGSM.h>
#include <Wire.h>

GSM gsm;
GPRS gprs;
GSMServer server(80);
GSMSSLClient client;
GSM_SMS sms;

void setup() {
  //Initialise Serial
  Serial.begin(9600);
  while(!Serial)
  {}
  Serial.println("Gineer.Industrial.GSM.Controller");
  Serial.println("www.gineer.co.za");
  Serial.print("Hardware Version: ");
  Serial.println(hwVersion);
  Serial.print("Software Version: ");
  Serial.println(swVersion);
  Serial.println();

  Serial.print("Connecting");

  bool connected = false;

  while (!connected) {

```

\>\>\> Here is where it gets stuck until I plug in the USB Serial Monitor, and then it continues happily.

```

    if ((gsm.begin(SIMpinNumber) == GSM_READY) &&
        (gprs.attachGPRS(SIMgprsAPN, SIMgprsLogin, SIMgprsPassword) == GPRS_READY)) {
      connected = true;
    } else {
      Serial.print(".");
      delay(1000);
    }
  }
.
.
.

```

Interestingly, the +5 V output pin on the Arduino measures 4.68 V when not connected to the PC. I don't however use this pin as I have the 7805 on my board. All other voltages measure as above at all times.

# Answer
`while(!Serial) {}` will wait for a serial connection and in your program will block execution until it gets one.

Remove it and your program should continue without the serial monitor.
> 3 votes

---
Tags: gsm, arduino-setup
---


# Question
Title: Why does my Wemos D1 Mini stops working while charging via solar?
I'm using an battery shield to recharge my battery. I want to use a solar panel, so I bought one (5V 240mA). I'm pretty sure, it won't recharge my battery fully, but that's not the point. I've assembled my board with my shield, soldered the solar panel together with an schottky-diode and put it on USB (since the shield allows charging via USB). All fine, I get some electric power in the sun - yeah!

But my Wemos D1 Mini only runs for say 2-3 minutes and than ... dead? Restarting works, but only lasts again 2-3 minutes. This only happens while the battery shield is charging via solar. I already tested using any USB charging (my computer) - this simply works.

Basically I rebuild the circuit like described on TheAustrian/Wemos-D1-Mini-BME280-Weather-Station but only one solar panel attached and using the Wemos D1 Mini Battery Shield instead of the TP4056.

Any hints what's going on? Why can't I run the board while charging via solar? Did I miss something?

# Answer
The TP4056 Module will output a max of 4.2V which is less than the 5V the Wemos D1 Mini is expecting on its 5V connection (Assuming you have connected the circuit as shown in the Github guide). When the solar panel is charging it's likely that the TP4056 is causing a driving issue on the supply of the Wemos causing it to potentially Brownout .

I would not connect the solar panel to the Wemos like this, I would have it connected to the battery then the battery connected to a 5V Step Up Power Converter like shown below (This reduces efficiency but give the MCU a stable supply),

My recommendation for the wiring,
> 1 votes

---
Tags: esp8266, solar
---


# Question
Title: Unable to read Arduino+ESP8266 full get Response
Using below code I am able to invoke HTTP Get request, but I am not able to read full HTTP Response. Observing only output like( +IPD,0,141:HTTP/1.7. ). Please let me know how can I read full response? Any Idea what is the issue?

```
#include <SoftwareSerial.h>

#define RX 2
#define TX 3
String WIFI_SSID = "xyz";       // Your WiFi ssid
String PASSWORD = "xys";         // Password

String HOST = "192.168.0.156";
String PATH = "/test";
String PORT = "8080";

int countTrueCommand;
int countTimeCommand;
boolean found = false;

SoftwareSerial esp8266(RX, TX);

void setup() {
  Serial.begin(9600);
  esp8266.begin(9600);
  esp8266.println("AT");
  Serial.println(esp8266.read());
  sendCommandToESP8266("AT", 5, "OK");
  sendCommandToESP8266("AT+CWMODE=1", 5, "OK");
  sendCommandToESP8266("AT+CWJAP=\"" + WIFI_SSID + "\",\"" + PASSWORD + "\"", 20, "OK");
}

void loop() {
  String postRequest = "GET " + PATH  + " HTTP/1.1\r\n" +
                       "Host: " + HOST + "\r\n" +
                       "Accept: *" + "/" + "*\r\n" +
                       "\r\n";

  sendCommandToESP8266("AT+CIPMUX=1", 5, "OK");
  sendCommandToESP8266("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
  String cipSend = "AT+CIPSEND=0," + String(postRequest.length());
  sendCommandToESP8266(cipSend, 4, ">");
  sendData(postRequest);
  readESP8266(8000);
  sendCommandToESP8266("AT+CIPCLOSE=0", 5, "OK");
}

void sendCommandToESP8266(String command, int maxTime, char readReplay[]) {
  Serial.print(countTrueCommand);
  Serial.print(". at command => ");
  Serial.print(command);
  Serial.print(" ");
  while (countTimeCommand < (maxTime * 1))
  {
    esp8266.println(command);
    if (esp8266.find(readReplay))
    {
      found = true;
      break;
    }

    countTimeCommand++;
  }

  if (found == true)
  {
    Serial.println("Success");
    countTrueCommand++;
    countTimeCommand = 0;
  }

  if (found == false)
  {
    Serial.println("Fail");
    countTrueCommand = 0;
    countTimeCommand = 0;
  }

  found = false;
}

void sendData(String postRequest) {
  Serial.println(postRequest);
  esp8266.println(postRequest);
  delay(1500);
  countTrueCommand++;
}

void readESP8266(const int timeout)
{
  String reponse = "";
  long int time = millis();
  while( (time+timeout) > millis())
  {
    while(esp8266.available())
    {
      reponse+=esp8266.readString();
    }
  }
  Serial.print(reponse);
}

```

Output:

```
Success
1. at command => AT+CWMODE=1 Success
2. at command => AT+CWJAP="xyz","xys" Success
3. at command => AT+CIPMUX=1 Success
4. at command => AT+CIPSTART=0,"TCP","192.168.0.156",8080 Success
5. at command => AT+CIPSEND=0,56 Success
GET /test HTTP/1.1
Host: 192.168.0.156
Accept: */*

busy s...

Recv 56 bytes

SEND OK

+IPD,0,141:HTTP/1.7. at command => AT+CIPCLOSE=0 Success

```

# Answer
Finally the HTTP Get request with Arduino Uno + ESP8266 Wifi shield which is working is below:

// This is a demo example using a public http server for testing both GET and POST requests

```
#include <Arduino.h>
#include <LiteESP8266Client.h>

#define PACKET_MTU 1500    // Standard network MTU is 1500 bytes

LiteESP8266 radio;

const char ssid[] PROGMEM = "xyz";    //change it to your wifi SSID
const char password[] PROGMEM = "abc";    //change it to your wifi password
const char host[] PROGMEM = "192.168.0.156";
const int port = 8080;

const char http_get_request[] PROGMEM = "GET /test HTTP/1.1\r\n";
const char http_useragent[] PROGMEM = "User-Agent: Arduino-stm32/0.1\r\n";
const char http_content_type_json[] PROGMEM = "Content-Type: application/json\r\n";
const char http_host[] PROGMEM = "Host: 192.168.0.156\r\n";
const char http_close_connection[] PROGMEM = "Connection: close\r\n\r\n";
const char http_content_length_header[] PROGMEM = "Content-Length: ";
const char success[] PROGMEM = "success";
const char failed[] PROGMEM = "failed";
const char CRLF[] PROGMEM = "\r\n";
const char error_data_null[] PROGMEM = "Error: data came back null.";

void setupStationMode() {
  Serial.print("Setup station mode... ");
  if (radio.set_station_mode()) {
    Serial.println("success");
  } else {
    Serial.println("failed");
  }
}

void joinAP() {
  Serial.print("Join AP ");
  Serial.print(ssid);
  Serial.print("... ");
  if (radio.connect_to_ap(ssid, password)) {
    Serial.println("Success");
  } else {
    Serial.println("Failed");
  }
}

void establishTcpConnect() {
  Serial.print("Establish TCP Connection... ");
  if (radio.connect_progmem(host, port)) {
    Serial.println( "Success");
  } else {
    Serial.println( "Failed");
  }
}

void getHttpPacket() {
  char *data;
  while ((data = radio.get_response_packet(PACKET_MTU, 5000))) {
    if (data) {
      Serial.println("Packet Received...");
      Serial.println(data);
    } else {
      Serial.println(error_data_null);
    }
  }
  free(data);
}

void httpGet() {
  Serial.println("Sending GET request... ");
  radio.send_progmem(http_get_request);
  radio.send_progmem(http_useragent);
  radio.send_progmem(http_host);
  radio.send_progmem(http_close_connection);
}
void setup() {
  delay(2000);
  radio.begin(9600,2,3);
  Serial.begin(9600);
  while (!Serial) {};

  setupStationMode();
  joinAP();
}

void loop() {
  establishTcpConnect();

  httpGet();
  getHttpPacket();
  }

```

Output:

```
Setup station mode... success
Join AP ⸮... Success
Establish TCP Connection... Success
Sending GET request...
Packet Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 27
Date: Fri, 07 Aug 2020 13:04:03 GMT
Connection: close

Greetings from Spring Boot!

```

But one issue I am facing is after few call the HTTP invocation is getting stopped probably memory being full. Will check this.
> 1 votes

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


# Question
Title: Why is their need of response time needed in esp8266 AT commands?
I am writing an AT commands firmware for esp8266 via connecting it to atmega2560. Now the question is how will I come to know the response time for AT commands for writing its firmware to read the response? in fact prior to this thought, the question comes why is their need of response time in AT commands? does response time concept is there in all modules where AT commands are used like gsm modules, HC05,etc.

# Answer
Your esp8266 firmware isn't required to wait before responding to the atmega2560, but the reality is that it simply *can't* respond in zero-time. The esp will take some processing to interpret the command that was sent to it and to create the reply to the atmega. And that is even if it doesn't have to wait for some distant server.

If the esp has to send a WiFi request to a server (which has the same constraints of processing time, plus other requests ahead of yours), that only adds to the esp's delay in responding to the atmega.

The bottom line is that the esp isn't required to wait any amount of time to respond; its just however much time it takes to acquire any data it needs, plus processing time to format it and send it back to the atmega.
> 1 votes

---
Tags: esp8266, programming, wifi, atmega2560, firmware
---


# Question
Title: Is it possible to use Adafruit's Circuit Playground Express's 2MB storage in Arduino IDE?
I understand that the extra 2MB of memory is for circuit python. However, I wouldn't mind having access to 2MB of storage and using the Arduino IDE/low level C to access it. Is that possible? If so, how?

# Answer
In their guided tour of the Adafruit Circuit Playground Express, it specifically states:

> You can use this in Arduino or CircuitPython to store files.

So yes, it is possible. As far as the how, according to this guide (also from Adafruit), that they have also made a library, Adafruit SPI Flash, which has a bunch of examples showing how to read from, write to, and format the SPI flash whilst retaining compatibility with CircuitPython, among other things.
> 3 votes

---
Tags: adafruit
---


# Question
Title: Arduino ESP8266 Wifi Shield GET request with LiteESP8266Client stops after few HTTP request
Below HTTP Get request is working but after few GET request(5-6) the code stops and once I press Arduino reset button then only it start working. Probably looks like something is causing OOM:

```
// This is a demo example using a public http server for testing both GET and POST requests

#include <Arduino.h>
#include <LiteESP8266Client.h>

#define PACKET_MTU 1500    // Standard network MTU is 1500 bytes

LiteESP8266 radio;

const char ssid[] PROGMEM = "abcd";    //change it to your wifi SSID
const char password[] PROGMEM = "abcd";    //change it to your wifi password
const char host[] PROGMEM = "192.168.0.156";
const int port = 8080;

const char http_get_request[] PROGMEM = "GET /getLedStatus HTTP/1.1\r\n";
const char http_useragent[] PROGMEM = "User-Agent: Arduino-stm32/0.1\r\n";
const char http_content_type_json[] PROGMEM = "Content-Type: application/json\r\n";
const char http_host[] PROGMEM = "Host: 192.168.0.156\r\n";
const char http_close_connection[] PROGMEM = "Connection: close\r\n\r\n";
const char http_content_length_header[] PROGMEM = "Content-Length: ";
const char success[] PROGMEM = "success";
const char failed[] PROGMEM = "failed";
const char CRLF[] PROGMEM = "\r\n";
const char error_data_null[] PROGMEM = "Error: data came back null.";
const int ledPin=11;
void setupStationMode() {
  Serial.print("Setup station mode... ");
  if (radio.set_station_mode()) {
    Serial.println("success");
  } else {
    Serial.println("failed");
  }
}

void joinAP() {
  Serial.print("Join AP ");
  Serial.print("... ");
  if (radio.connect_to_ap(ssid, password)) {
    Serial.println("Success");
  } else {
    Serial.println("Failed");
  }
}

void establishTcpConnect() {
  Serial.print("Establish TCP Connection... ");
  if (radio.connect_progmem(host, port)) {
    Serial.println( "Success");
  } else {
    Serial.println( "Failed");
  }
}

void getHttpPacket() {
  char *data;
  while ((data = radio.get_response_packet(PACKET_MTU, 5000))) {
    if (data) {
      Serial.println("Response Received...");
      Serial.println(data);
      if(strstr(data, "ON") != NULL) {
        digitalWrite(ledPin, HIGH);
      }else{
        digitalWrite(ledPin, LOW);
      }
    } else {
      Serial.println(error_data_null);
    }
  }
  free(data);
}

void httpGet() {
  Serial.println("Sending GET request... ");
  radio.send_progmem(http_get_request);
  radio.send_progmem(http_useragent);
  radio.send_progmem(http_host);
  radio.send_progmem(http_close_connection);
}
void setup() {
  delay(2000);
  pinMode(ledPin, OUTPUT);
  radio.begin(9600,2,3);
  Serial.begin(9600);
  while (!Serial) {};

  setupStationMode();
  joinAP();
}

void loop() {
  establishTcpConnect();

  httpGet();
  getHttpPacket();
  }

```

Complete OUTPUT(See Last TCP call when it stopped):

```
Setup station mode... success
Join AP ... Success
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 3
Date: Fri, 07 Aug 2020 13:47:47 GMT
Connection: close

OFF
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 3
Date: Fri, 07 Aug 2020 13:47:53 GMT
Connection: close

OFF
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 3
Date: Fri, 07 Aug 2020 13:47:58 GMT
Connection: close

OFF
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 3
Date: Fri, 07 Aug 2020 13:48:04 GMT
Connection: close

OFF
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 3
Date: Fri, 07 Aug 2020 13:48:10 GMT
Connection: close

OFF
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
Date: Fri, 07 Aug 2020 13:48:16 GMT
Connection: close

ON
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
Date: Fri, 07 Aug 2020 13:48:21 GMT
Connection: close

ON
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
Date: Fri, 07 Aug 2020 13:48:27 GMT
Connection: close

ON
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200
Content-Type: text/plain;charset=UTF-8
Content-Length: 2
Date: Fri, 07 Aug 2020 13:48:33 GMT
Connection: close

ON
Establish TCP Connection... Success
Sending GET request...
Establish TCP Connection...

```

Probably looks like memory is not getting freed. I am using Arduino UNO + ESP8266 sheild

**Update 2** Tried with other REST Server and same issue is observed:

```
// This is a demo example using a public http server for testing both GET and POST requests

#include <Arduino.h>
#include <LiteESP8266Client.h>

#define PACKET_MTU 1500    // Standard network MTU is 1500 bytes

LiteESP8266 radio;

const char ssid[] PROGMEM = "abc";    //change it to your wifi SSID
const char password[] PROGMEM = "abc";    //change it to your wifi password
const char host[] PROGMEM = "httpbin.org";
const int port = 80;

const char http_get_request[] PROGMEM = "GET /get HTTP/1.1\r\n";
const char http_useragent[] PROGMEM = "User-Agent: Arduino-stm32/0.1\r\n";
const char http_content_type_json[] PROGMEM = "Content-Type: application/json\r\n";
const char http_host[] PROGMEM = "Host: httpbin.org\r\n";
const char http_close_connection[] PROGMEM = "Connection: close\r\n\r\n";
const char http_content_length_header[] PROGMEM = "Content-Length: ";
const char success[] PROGMEM = "success";
const char failed[] PROGMEM = "failed";
const char CRLF[] PROGMEM = "\r\n";
const char error_data_null[] PROGMEM = "Error: data came back null.";
const int ledPin=11;
void setupStationMode() {
  Serial.print("Setup station mode... ");
  if (radio.set_station_mode()) {
    Serial.println("success");
  } else {
    Serial.println("failed");
  }
}

void joinAP() {
  Serial.print("Join AP ");
  Serial.print("... ");
  if (radio.connect_to_ap(ssid, password)) {
    Serial.println("Success");
  } else {
    Serial.println("Failed");
  }
}

void establishTcpConnect() {
  Serial.print("Establish TCP Connection... ");
  if (radio.connect_progmem(host, port)) {
    Serial.println( "Success");
  } else {
    Serial.println( "Failed");
  }
}

void getHttpPacket() {
  char *data;
  while ((data = radio.get_response_packet(PACKET_MTU, 5000))) {
    if (data) {
      Serial.println("Response Received...");
      Serial.println(data);
      if(strstr(data, "ON") != NULL) {
        digitalWrite(ledPin, HIGH);
      }else{
        digitalWrite(ledPin, LOW);
      }
    } else {
      Serial.println(error_data_null);
    }
  }
  free(data);
}

void httpGet() {
  Serial.println("Sending GET request... ");
  radio.send_progmem(http_get_request);
  radio.send_progmem(http_useragent);
  radio.send_progmem(http_host);
  radio.send_progmem(http_close_connection);
}
void setup() {
  delay(2000);
  pinMode(ledPin, OUTPUT);
  radio.begin(9600,2,3);
  Serial.begin(9600);
  while (!Serial) {};

  setupStationMode();
  joinAP();
}

void loop() {
  establishTcpConnect();

  httpGet();
  getHttpPacket();
  }

```

Output:

```
Setup station mode... success
Join AP ... Success
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200 OK
Date: Fri, 07 Aug 2020 13:57:45 GMT
Content-Type: application/json
Content-Length: 238
Connection: close
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Response Received...
{
  "args": {},
  "headers": {
    "Host": "httpbin"origin": "106.51.29.214",
  "url": "http://httpbin.org/get"
}
CLOSED
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
Establish TCP Connection... Success
Sending GET request...
Response Received...
HTTP/1.1 200 OK
Date: Fri, 07 Aug 2020 13:57:57 GMT
Content-Type: application/json
Content-Length: 238
Connection: close
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

Response Received...
{
  "args": {},
  "headers": {
    "Host": "httpbin"origin": "106.51.29.214",
  "url": "http://httpbin.org/get"
}
CLOSED
⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
Establish TCP Connection... Success
Sending GET request...
Establish TCP Connection...

```

Server side code

```
package com.test.iot;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
    private String ledStatus="OFF";
    @RequestMapping("/test")
    public String index() {
        logger.info("invoked");
        return "Greetings from Spring Boot!";
    }
    @RequestMapping("/getLedStatus")
    public String getLedStatus() {
        logger.info("ledStatus");
        return ledStatus;
    }
    @RequestMapping("/toggleLedStatus")
    public String toggleLedStatus(){
        if(ledStatus.equals("ON")){
            ledStatus="OFF";
        } else {
            ledStatus="ON";
        }
        return String.format("New LED Status: %s", ledStatus);
    }
}

```

# Answer
> 2 votes
There is a bug on the library example webclient.ino on `getHttpPacket()` and `getHttpResponse()` that it didn't free the memory correctly, causing memory leak. I've updated the code on github repo.

Specifically on your `getHttpPacket()`, here is the corrected code:

```
void getHttpPacket() {
  char *data;
  while ((data = radio.get_response_packet(PACKET_MTU, 5000))) {
    if (data) {
      Serial.println(F("Response Received..."));
      Serial.println(data);
      if(strstr(data, "ON") != NULL) {
        digitalWrite(ledPin, HIGH);
      }else{
        digitalWrite(ledPin, LOW);
      }
      free(data);  // free the memory in every packet as Arduino does not have enough memory
    } else {
      Serial.println(error_data_null);
    }
  }
  // free(data);
}

```

If you have further issue regarding the library, you can raise an "issue" on the github, and I will take a look.

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


title: radio.write () always returns 0

text:
# Question
Title: radio.write () always returns 0
I'm trying to send a char \[\] through an NRF2401 but the radio.write () method always return 0. Check that msg contains the message read from str.

```
#define TAM 50

RF24 radio(9,10);

const uint64_t pipe = 0xE8E8F0F0E1AA;

char  msg[TAM];

void setup() {

  Serial.begin(9600);

  radio.begin();

  radio.openWritingPipe(pipe);
}

void loop() {
    if(Serial.available() > 0){
      String str = Serial.readString();
      str.toCharArray(msg,TAM);
      if(!radio.write(msg, TAM)){
        Serial.println("Message not send");
      }
      else
        Serial.println(msg);
    }
}

```

What am I doing wrong?

**Edit1:** What I have noticed, is that the first time I was allowed to send it but the others no longer.

**Edit2:** Remove the keyboard input by a char \[\] and sent it to without problems. Why can this be? Anything else happen when I make a keyboard entry?

# Answer
I hope you resolved your issue by now, but I had the same problem with an Arduino UNO/nRF24l01+ combination and this question was one of the search results.

In my case, the write() call returned false, but the receiver received the message.

As soon as I added one of the ubiquitous Adapter Boards into the mix the write() call started returning true.

My uneducated guess is that the sending and then the switch from transmit to receive and then waiting to receive the ACK used a bit too much power or something like that.

In any case, even though everyone recommends adding a capacitor and I had the adapter boards on hand, I had thought to tough it out without one and see how far I could get.

I kicked myself for the wasted time, but I learned a lot in the process and I'm having a lot of fun with the transceiver boards now. I'm glad that I didn't just shrug and say "well the message got through so who cares?"
> 3 votes

---
Tags: arduino-uno
---


# Question
Title: Which board to select in PlatformIO for ESP Wroom 32?
I'm quite new in this microcontroller topic and my next step is to make use of a wlan module, which is a ESP WROOM 32. As IDE I'm using Visual Studio + PlatformIO and I can't figure out how to access the module. Atm I use these parameters:

```
[env:esp12e]
platform = espressif8266
board = esp12e
framework = arduino
monitor_speed = 74880

```

but I receive:

```
(...)
CURRENT: upload_protocol = esptool
Looking for upload port...
Auto-detected: /dev/ttyUSB0
Uploading .pio/build/esp12e/firmware.bin
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting......
Chip is ESP8266EX
Features: WiFi
WARNING: Detected crystal freq 20.45MHz is quite different to normalized freq 26MHz. Unsupported crystal in use?
Crystal is 26MHz
MAC: 00:08:ff:00:00:00
Uploading stub...
Running stub...

A fatal error occurred: Invalid head of packet (0x46)
*** [upload] Error 2
============================================================================= [FAILED] Took 3.27 seconds =============================================================================
The terminal process "platformio 'run', '--target', 'upload'" terminated with exit code: 1.

```

edit: The ESP WROOM 32 is a NodeMCU 32 and the board config now is:

```
[env:espwroom32]
platform = espressif32
board = nodemcu-32s
framework = arduino
monitor_speed = 115200

```

and to check if everything works:

```
void setup() {
  pinMode(2, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(2, HIGH);
  delay(1000);
  digitalWrite(2, LOW);
  delay(1000);
}

```

I also had problems that `I received Failed to connect to ESP32: Timed out waiting for packet header` nevertheless but here is a nicely explained workaround for that. Solution is, either you hold the `BOOT` button pressed while uploading the code or you sold a capacitor to specific pins on the board. I just tried to hold the boot button and it's blinking now. Finally :) I'm sure, a lot of further issues are only waiting on the way ^

# Answer
> 5 votes
The ESP WROOM32 is an ESP32, not an ESP8266. You have PlatformIO configured for an ESP8266, specifically the ESP12e, and there's no way that's going to work.

You'll want something more along these lines:

```
[env:espwroom32]
platform = espressif32

```

To choose the board - if you're using a breakout board, you'll need to be more specific about it - what model is it? ESP WROOM32 is just the name of the CPU module; PlatformIO needs to know the size of the flash storage in order to upload properly. Your link is to the entire Espressif ESP32 site. Otherwise, look through PlatformIO's list of ESP32 boards and find one that matches the amount of flash storage your board has.

You might want to read PlatformIO's ESP32 documentation.

---
Tags: esp8266, esp32
---


title: Why is this looping?

text:
# Question
Title: Why is this looping?
I am trying to do something very simple. I want the LED to fade from full brightness to off. This works... However, the LED turns back on to full brightness and fades again, in a loop. I am not sure why. I think I am missing something obvious. Once the legThreeBrightness decrements to 0, nothing should happen...

```
int legThreeBrightness = 255;

void setup() {

    pinMode(3, OUTPUT);

}

void loop() {

    if (legThreeBrightness = 255){
        do {
              analogWrite(3, legThreeBrightness);
              delay(30);
              legThreeBrightness = legThreeBrightness -5;
           } while (legThreeBrightness >= 0);
    }
}

```

# Answer
This line:

```
if (legThreeBrightness = 255){

```

assigns the value 255 to legThreeBrightness. That is non-zero so it enters the block and runs the fade now that the variable has been set to 255.

If you just want to compare the value to 255 then use:

```
if (legThreeBrightness == 255){

```

and that way when the loop function repeats it isn't there setting the value back to 255. This way it will stay at 0.
> 9 votes

---
Tags: code-review
---


# Question
Title: Weird effect of AVR C on USB-serial communication
I recently decided to learn direct port manipulation instead of builtin arduino routines.

First I tried this piece of code

```
void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("on");
delay(500);
digitalWrite(LED_BUILTIN, LOW);
Serial.println("off");
delay(500);
}

```

This program on running instantly established connection with the serial monitor on my arduino IDE.

But when I try this code

```
int main(void)
{
Serial.begin(9600);
DDRB = B11111111;
while(1)
{
PORTB = PORTB | 0x20;
Serial.println("off");
_delay_ms(500);
PORTB = PORTB & 0xDF;
Serial.println("on");
_delay_ms(500);
}
}

```

But this program is taking some time, about 5-10 seconds to establish serial connection. Also delay() is not working too. When I use delay() instead of \_delay\_ms(), the entire arduino board freezes like a computer and stops blinking the LED instead LED is fully ON.

I tried is on several programs, while "setup-loop" program connects instantly, AVR C programs does not.

why does it happen?

# Answer
> 2 votes
By defining your own `main()` you are circumventing the Arduino startup procedures.

Normally with Arduino code `main()` first runs an `init()` function before `setup()` and (repeatedly) `loop()`. This `init()` function will configure, amongst other things, the timer for `millis()` and `delay()`.

This is the normal `main()` for a basic AVR-based board:

```
int main(void)
{
    init();

    initVariant();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }

    return 0;
}

```

It first initializes common functions, then board-specific ones (normally nothing), and if applicable, the USB interface (for ATMega32U4 based boards, like the Leonardo).

Only then does it go on to run your sketch.

If you want to use both your own `main()` and Arduino functions like `delay()` then you will have to call those initialization routines before running the rest of your code.

---
Tags: serial, atmega328
---


title: More effecient datalogging code

text:
# Question
Title: More effecient datalogging code
# Background:

I am using a Teensy 3.6 to data log over a dozen sensors. I am printing to Serial1 for local Serial access, Serial3 for remote access (via xbee, same data is on Serial1 as on Serail3, just different physical connection) as well as datalog to SDCard (CSV format). My code is expanding and is incredibly repetitive, and I am looking for a more efficient way of writing the following. I am trying to move a lot of the rest of my code to classes using this and this tutorial, but I'm not sure this is the best option for the datalogging as there are many more strings in this portion.

The variables we are dealing with:

* Live sensor value (eOilTempF)
* A visual flag for if the sensor is out of bounds (checkEngine)
* A auditory alarm if it's further out of bounds (eOilTempAlarm)
* The max value we've recorded (engineOilStats.maximum())
* The minimum value (engineOilStats.minimum())

As well as all the little bits to make it attractive and human readable for the Serial stuff.

# Code:

## Local serial:

```
Serial.print("Engine Oil Temp:\t");
Serial.print(eOilTempF);
Serial.print("F\t   ");
Serial.print("Flag: ");
Serial.print(checkEngine);
Serial.print("\t Alarm:");
Serial.print(eOilTempAlarm);
Serial.print("\tMAX: ");
Serial.print(engineOilStats.maximum());
Serial.print(" F");
Serial.print("\t\t\t\tAVG: ");
Serial.print(engineOilStats.average());
Serial.println(" F");

```

## Xbee serial:

```
Serial3.print("Engine Oil Temp:\t");
Serial3.print(eOilTempF);
Serial3.print("F\t   ");
Serial3.print("Flag: ");
Serial3.print(checkEngine);
Serial3.print("\t Alarm:");
Serial3.print(eOilTempAlarm);
Serial3.print("\tMAX: ");
Serial3.print(engineOilStats.maximum());
Serial3.print(" F");
Serial3.print("\t\t\t\tAVG: ");
Serial3.print(engineOilStats.average());
Serial3.println(" F");

```

## SD Card Logging:

```
logfile.print(eOilTempF);
logfile.print(",");
logfile.print(checkEngine);
logfile.print(",");
logfile.print(engineOilStats.maximum());
logfile.print(",");
logfile.print(engineOilStats.average());
logfile.print(",");

```

# tl;dr

My datalogging section of my sketch is 567 lines of mostly repeated code, and I'm new at programming and need some tutorials/terms to google to make it more effecient.

# Answer
> 1 votes
You can combine the Streaming library with a wrapper class that sends data to multiple serial destinations.

Here's a little example:

```
#include <Streaming.h>

class DualSerial : public Print {
    private:
        Print *_dev1;
        Print *_dev2;

    public:
        DualSerial(Print &s1, Print &s2) : _dev1(&s1), _dev2(&s2) {}

        size_t write(uint8_t c) {
            _dev1->write(c);
            _dev2->write(c);
        }
};

DualSerial remote(Serial, Serial3);

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

void loop() {
    // Both Serial and Serial3 will receive this
    remote << "The time is: " << millis() << endl;
    delay(1000);
}

```

The Streaming class will work with anything that inherits from the `Print` class, which includes the SD card's `File` class, so you can also use it for writing to the SD card:

```
logfile << eOilTempF << ","
        << checkEngine << ","
        << engineOilStats.maximum() << ","
        << engineOilStats.average() << endl;

```

---
Tags: programming, c++, datalogging
---


# Question
Title: digitalwrite with function parameter as parameter
Firstly, excuse my poor English, this is not my native langage.

I'm trying to use an Arduino Uno to drive an 8 relay board from an MQTT Subscription. I ask for help because i'm some kind of beginner in arduino, i'm just a Linux addict.

The idea is to get a payload from PubSubclient and use it to manage relays. For example, the payload '71' ask the relay 7 to turn on and '42' make the relay 4 to turn off.

All works fine until I wanted to write a function with two parameters : 'relay\_number' and 'Action'

All parameters are received but the relay never goes up or down.

My code :

```
void callback(char* topic, byte* payload, unsigned int length) {

  Relay_Nb = (char)payload[0];
  Action = char(payload[1]);

  Serial.println(Relay_Nb);
  Serial.println(Action);

  RelayControl(Relay_Nb, Action);
}

void RelayControl(char Relay_Nb, char Action) {
  Serial.println(Relay_Nb);   // for debugging purpose
  Serial.println(Action);

  if ( Action == '0') {
    Serial.print("Bringing down Relay ");
    Serial.println(Relay_Nb);
    digitalWrite(Relay_Nb, LOW);
  } else if (Action == '1') {
    Serial.print("Bringing up Relay ");
    Serial.println(Relay_Nb);
    digitalWrite(Relay_Nb, HIGH);
  } else if (Action == '2') {
    // Relay temporisé (ouverture portail par ex)
    Serial.println("Bringing up, and down Relay ");
    digitalWrite(Relay_Nb, HIGH);
    delay(750);
    digitalWrite(Relay_Nb, LOW);
  }
}

```

I'm sure an old maker have the solution i'm searching for hours now.

Please help and don't hesitate to show me others ways. Thanks.

# Answer
You are sending the parameter `Relay_Nb` as a character, and then using it as an integer.

You need to turn the character into an integer - and the simplest way is to subtract the ASCII value of `0` from it:

```
Relay_Nb = payload[0] - '0';

```

But with that said, a note on how you have written your callback:

* You aren't checking the data is valid.

You should really be doing, at the very least, the following:

1. Check that the `length` parameter is at least `2`,
2. Check that the two data values are within the correct range for your function
> 1 votes

---
Tags: digitalwrite
---


title: How to wire L293D chip to a nodeMCU?

text:
# Question
Title: How to wire L293D chip to a nodeMCU?
How do I wire an L293D motor controller chip to a nodeMCU?
I have tried to follow the instructions from this tutorial: lastminuteengineers.com

One problem. I don't have a 5v pin? Are there any alternative ways to wire this?

All of the other tutorials i see, only say to use a special other motor driver board with an L293D embedded in it, and with extras connected to the board.

# Answer
> 0 votes
I figured it out. I am putting a logic level converter On the 3v pin to step it up to 5v

---
Tags: nodemcu, l293d
---


# Question
Title: Why are the Do While loops not stopping?
Ive been staring at this for a while now and I am going cross-eyed. I am writing a simply program to change colors of a 3 color LED. It is working, but then I noticed the LED would sometimes flash. I did a variety of tests and eventually, using the serial monitor, found out the issue. The brightness should count down to a brightness level of 0 and up to a level of 255. However, *sometimes* it counts below 0 to -1 and *sometimes* it continues infinitely past 255. I cant figure out why. Below is the code and the serial monitor outputs. The only way I can stop is by manually setting the value outside the loop. You can see those lines commented out to allow for the error.

```
int randLeg;  // var to pick a random leg

// set all 3 legs to max brightness at start
int legThreeBrightness = 255;
int legFiveBrightness = 255;
int legSixBrightness = 255;
int delayTime = 15;
int increment = 1;

void setup() {

    Serial.begin(9600);

    // set pins as output
    pinMode(3, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);

    // turn all the LEDs on
    analogWrite(3, legThreeBrightness);
    analogWrite(5, legFiveBrightness);
    analogWrite(6, legSixBrightness);

    randomSeed(analogRead(0));  // seed rand num generator

}

void loop() {

    randLeg = random(4, 7);  // pick a random leg

    switch (randLeg) {
    case 4:  //-1 for pin 3
        if (legThreeBrightness == 255){
          do {
                Serial.println(legThreeBrightness);
                analogWrite(3, legThreeBrightness);
                delay(delayTime);
                legThreeBrightness = legThreeBrightness - increment;
             } while (legThreeBrightness >= 0);
             //legThreeBrightness = 0;
        }
        else {
         do {
                Serial.println(legThreeBrightness);
                analogWrite(3, legThreeBrightness);
                delay(delayTime);
                legThreeBrightness = legThreeBrightness + increment;
             } while (legThreeBrightness <= 255);
             //legThreeBrightness = 255;
        }
      break;

    case 5:
        if (legFiveBrightness == 255){
          do {
                ////Serial.println(legFiveBrightness);
                analogWrite(5, legFiveBrightness);
                delay(delayTime);
                legFiveBrightness = legFiveBrightness - increment;
             } while (legFiveBrightness >= 0);
             //legFiveBrightness = 0;
        }
        else {
         do {
                ////Serial.println(legFiveBrightness);
                analogWrite(5, legFiveBrightness);
                delay(delayTime);
                legFiveBrightness = legFiveBrightness + increment;
             } while (legFiveBrightness <= 255);
             //legFiveBrightness = 255;
        }
      break;
    case 6:
        if (legSixBrightness == 255){
          do {
                ////Serial.println(legSixBrightness);
                analogWrite(6, legSixBrightness);
                delay(delayTime);
                legSixBrightness = legSixBrightness - increment;
             } while (legSixBrightness >= 0);
             //legSixBrightness = 0;
        }
        else {
         do {
                ////Serial.println(legSixBrightness);
                analogWrite(6, legSixBrightness);
                delay(delayTime);
                legSixBrightness = legSixBrightness + increment;
             } while (legSixBrightness <= 255);
             //legSixBrightness = 255;
        }
      break;
   }

}

```

> 10 9 8 7 6 5 4 3 2 1 0 -1

and

> 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265

# Answer
change `>=` and `<=` to `>` and `<` respectively.

You want it to stop at 0, but your do-while will do another round, since `0>=0` is true. So your code only stops at `-1` and `256`.

When `legThreeBrightness` is 256 it should be counting down, but your `if (legThreeBrightness == 255){` doesn't detect this, so the code will continue counting up. I'd probably change this line to `if (legThreeBrightness >= 255){` to prevent this from ever happening (which it shouldn't, but still).
> 6 votes

# Answer
You have two issues related to bounds checking. For the sake of brevity, since all there LED branches of the switch statement are the same, I will refer to `legNumBrightness` instead of the individual `legThreeBrightness`, `legFiveBrightness`, `legSixBrightness` variables since this applies to all three (individually).

Because `do while` loops always run once before testing the condition, you have an issue with the value of `legNumBrightness` going out of bounds. i.e. when it is equal to 255, it decrements by one, until it is zero, and then because `0>=0` is still true (0 *is* equal to 0, after all), it decrements once more, so `legNumBrightness` is now `-1`. So on the next visit of that `legNumBrightness = 255`, the increments up by one branch is taken, until it reaches `255 <= 255`, which is again true, and hence will go to 256. As the if bounds test used is only that of `legNumBrightness == 255`, it will only decrement if the value is exactly 255. Thus if it is not 255, it will keep incrementing until the maximum value of an `int` is reached (32767), overflow to -32768, and probably keep toggling between -32768 and 32767.

So to fix this, you need to change the `if (legNumBrightness == 255)` bound checking to `if (legNumBrightness >= 255)`. Now, because of the `do while` loop, `legNumBrightness` will still sometimes go to `-1` and `256`, but can no longer overrun past 256. To fix the `-1` and `256` overrun, remove the `=` from the do while tests so they become `while (legNumBrightness > 0)` and `while (legNumBrightness < 255)` and thus will not try to increment or decrement when the boundary has been reached.

I would also recommend using a `while()` loop in preference to a `do while()` loop, so the condition is checked *before* running the loop content, but it does not appear necessary from brief testing of this logic.

e.g. for legThreeBrightness

```
 case 4:  //-1 for pin 3
        if (legThreeBrightness >= 255){
          do {
                //Serial.println(legThreeBrightness);
                analogWrite(3, legThreeBrightness);
                delay(delayTime);
                legThreeBrightness = legThreeBrightness - increment;
             } while (legThreeBrightness > 0);
             //legThreeBrightness = 0;
        }
        else {
         do {
                //Serial.println(legThreeBrightness);
                analogWrite(3, legThreeBrightness);
                delay(delayTime);
                legThreeBrightness = legThreeBrightness + increment;
             } while (legThreeBrightness < 255);
             //legThreeBrightness = 255;
        }
      break;

```
> 1 votes

# Answer
I agree with @Gerben that you need to change `>=` and `<=` to `>` and `<` respectively, for the `do-while` loop check.

Secondly, your `if` statement expects `legThreeBrightness` (et al) to be 255 in order to decrement the brightness. Because of your `while` statement is over-running 255 because of `<= 255`, the `if` statement will always execute the `else` part and because it is a `do-while` it will execute the loop once, incrementing `legThreeBrightness`.

To fix this, change the `if` statement to check for a value above 250:

```
case 4:  //-1 for pin 3
    if (legThreeBrightness > 250){  // <---- Notice the > 250
      do {
            //Serial.println(legThreeBrightness);
            analogWrite(3, legThreeBrightness);
            delay(delayTime);
            legThreeBrightness = legThreeBrightness - increment;
         } while (legThreeBrightness > 0);
         //legThreeBrightness = 0;
    }
    else {
     do {
            //Serial.println(legThreeBrightness);
            analogWrite(3, legThreeBrightness);
            delay(delayTime);
            legThreeBrightness = legThreeBrightness + increment;
         } while (legThreeBrightness < 255);
         //legThreeBrightness = 255;
    }
  break;

```

This is easy to check and you should see the problem disappear straight away.
> 0 votes

---
Tags: code-review, loop
---


title: ESPTool 3-run stub fail error

text:
# Question
Title: ESPTool 3-run stub fail error
I'm trying to program my NodeMCU ESP8266 ESP-12E module with AT commands. However, whenever I try and flash to my ESP8266 using ESPTool, I get a 3-run stub fail error. Can anyone tell me why I get this error and how to fix it? I have my suspicions that it might be the fact that I haven't pulled any of the pins, but I've been told that GPIO0, GPIO2, GPIO15, and CH\_PD are all already pulled to the proper positions by default. If that may be the reason behind this error, could someone explain to me how exactly I should pull the pins, whether it be with a circuit or through code? If it helps, I'm trying to follow along with this resource. The only thing the ESP is connected to is the computer with USB.

# Answer
> 2 votes
Just wanted to update and let anyone who had a similar issue learn how I solved the problem. My baud rate was set to 1152000 rather than 115200. Setting it to 115200 solved my problem.

---
Tags: esp8266, error
---


title: wdt reset cause:4, boot mode:(3,6)

text:
# Question
Title: wdt reset cause:4, boot mode:(3,6)
I'm working on Python and nodeMCU with websocket connection.

So, I send a string from Python to nodeMCU and nodeMCU collects the string and decodes to set values to a stepper motor. Initial code worked fine before updating with stepper motor code. Now it triggers watchdog resets.

Here's my full code:-

```
#include <ESP8266WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 8  // clk+
#define stepPin 9  // cw+
#define motorInterfaceType 1

AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

const char ssid[] PROGMEM ="PencoNetwork2";    //change it to your wifi SSID
const char password[] PROGMEM ="Penco1234567890";    //change it to your wifi password

AsyncWebServer server(80);
AsyncWebSocket ws("/test");

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

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println(WiFi.localIP());

  ws.onEvent(onWsEvent);
  server.addHandler(&ws);

  server.begin();

}

void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){

  if(type == WS_EVT_CONNECT){

    Serial.println("Websocket client connection received");

  } else if(type == WS_EVT_DISCONNECT){
    Serial.println("Client disconnected");

  } else if(type == WS_EVT_DATA){

    Serial.println("Data received: ");

    for(int i=0; i < len; i++) {
//          Serial.print((char) data[i]);
           String data_String = (String) data[i];

          int commaIndex = data_String.indexOf(',');
          int secondCommaIndex = data_String.indexOf(',', commaIndex+1);
          String firstValue = data_String.substring(0, commaIndex);
          String secondValue = data_String.substring(commaIndex+1, secondCommaIndex);
          String thirdValue = data_String.substring(secondCommaIndex+1); //To the end of the string

          int mDist = firstValue.toInt();
          int mspeed = secondValue.toInt();
          int mAccel = thirdValue.toInt();

          stepper.setMaxSpeed(mspeed);
          stepper.setAcceleration(mAccel);

          stepper.moveTo(mDist);
          stepper.runToPosition();
          delay(1000);
          stepper.moveTo(0);
          stepper.runToPosition();
          delay(1000);

    }

//    Serial.println();
  }
}

void loop(){

  }

```

It would be a great help pointing out my mistakes.

# Answer
You're calling `delay()` in the `onWsEvent()` callback. The ESPAsyncWebServer documentation specifically says not to do that in the '**Important things to remember'** section:

> You can not use yield or delay or any function that uses them inside the callbacks

When you call `delay()` or loop inside an async web server callback, you block its event task from doing any other processing. This can interfere with a variety of housekeeping functions that HTTP, TCP and the Arduino Core need to perform. In general you should do as little as possible during a callback and return as quickly as possible.

The correct way to structure this code is to set a flag in the callback and inspection the flag and do the work in `loop()`.

For instance,

```
AsyncWebServer server(80);
AsyncWebSocket ws("/test");

boolean flag_move_stepper = false;

void setup(){

```

and

```
void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len){

  if(type == WS_EVT_CONNECT){

    Serial.println("Websocket client connection received");

  } else if(type == WS_EVT_DISCONNECT){
    Serial.println("Client disconnected");

  } else if(type == WS_EVT_DATA){
    flag_move_stepper = true;

    // you'll need to rewrite this code to share variables with `loop()` and do the work there

```

and

```
void loop(){
  if(flag_move_stepper) {
    flag_move_stepper = false;

    // do the work formerly in onWsEvent() here
  }

}

```

You'll need to make the variables you stored data in in the event handler available to `loop()` and move the stepper code there for this to work.
> 2 votes

---
Tags: esp8266, nodemcu, python, watchdog
---


# Question
Title: Which are the unused digital pins after L293D motor shield is installed on a Arduino Uno board?
I have just started my first project on Arduino. I have an Arduino Uno and an L293D motor shield.

I have installed the motor shield on the Arduino Uno board and the motor shield covers all pins of the Arduino Uno board. The motor shield is connected with four gear motors and one servo motor.

Can I use digital pins 2-13 to make some LED flashing circuit?

Which digital pins are used by the Motor shield and which pins are not used?

---

It is L293D motor shield. A0 and A5 are used in the code. Four DC motors and one servo motor is used.

# Answer
If this is the same board as seen on Banggood Which may also be seen at Adafruit The schematic shows most of the digital pins in use

```
D3  - PWM2B
D4  - DIR_CLK
D5  - PWM0B
D6  - PWM0A
D7  - DIR_EN
D8  - DIR_SER
D9  - PWM1A
D10 - PWM1B
D11 - PWM2A
D12 - DIR_LATCH

```

The analogue pins A0-A5 are still free - these can be used as digital pins.
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: Problems Sending Signals to the Arduino-Uno via Keyboard
I have an Arduino Uno and a usb 2.0 shield in which I connected a keyboard to. I have all the necessary libraries installed but what I am trying to figure out is how to light an led when I press a specific key.

I am new to codding Arduino boards and I have done a lot of reading but I cant figure out my issue I feel like if I get this figured out I will be a lot better off in my future projects.

```
#include <hidboot.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

int SKEY = 8;

class KbdRptParser : public KeyboardReportParser
{
    void PrintKey(uint8_t mod, uint8_t key);

  protected:

    void OnKeyDown  (uint8_t mod, uint8_t key);
    void OnKeyUp    (uint8_t mod, uint8_t key);
    void OnKeyPressed            (uint8_t key);
};

void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
{
  MODIFIERKEYS mod;
  *((uint8_t*)&mod) = m;
  Serial.print((mod.bmLeftCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmLeftShift  == 1) ? "S" : " ");
  Serial.print((mod.bmLeftAlt    == 1) ? "A" : " ");
  Serial.print((mod.bmLeftGUI    == 1) ? "G" : " ");

  Serial.print(" >");
  PrintHex<uint8_t>(key, 0x80);
  Serial.print("< ");

  Serial.print((mod.bmRightCtrl   == 1) ? "C" : " ");
  Serial.print((mod.bmRightShift  == 1) ? "S" : " ");
  Serial.print((mod.bmRightAlt    == 1) ? "A" : " ");
  Serial.println((mod.bmRightGUI  == 1) ? "G" : " ");
};

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
{
  Serial.print("DN ");
  PrintKey(mod, key);
  uint8_t c = OemToAscii(mod, key);

}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
{
  Serial.print("UP ");
  PrintKey(mod, key);
}

void KbdRptParser::OnKeyPressed(uint8_t key)
{
  Serial.print("ASCII: ");
  Serial.println((char)key);
};

USB Usb;
HIDBoot<USB_HID_PROTOCOL_KEYBOARD>    HidKeyboard(&Usb);

KbdRptParser Prs;

void setup() {

 Serial.begin(9600);
#if !defined(__MIPSEL__)
  while (!Serial);
  Serial.println("Start");

  if (Usb.Init() == -1)
    Serial.println("OSC did not start.");

  delay( 1 );

  HidKeyboard.SetReportParser(0, &Prs);

}

void loop() {
 Usb.Task();
}

```

Anyways I know how to make if statements and how to activate pins on the Arduino but I cant figure it out in this keyboard library. For now I just made it print "TRUE" since there is not need to get complicated if I cant get the first step to work. Before I made that if statement the serial monitor would show the value assigned to the key and label it DN # and when I let up on the key it would say UP # but how can I translate that to sending a pulse to whatever pin when I push a key and stop sending a pulse when I let up on the key?

Also in my if statement that I made I know I need something before == sign but I tried multiple things and they did not work so I just left it blank and the reason I used the number 16 was because that was the value assigned to the S key in which I wanted to use to light an led. Anyways any help would be greatly appreciated!

# Answer
Keyboards cannot be used quite like you wish - the keyboard will send a key (scan) code when a key is pressed and then repeat that code if the button continues to be pressed. There is a different code sent when the same key is released.

> The scancode for key release is obtained from it by setting the high order bit (adding 0x80 = 128). Thus, Esc press produces scancode 01, Esc release scancode 81 (hex). For sequences things are similar: Keypad-/ gives e0 35 when pressed, e0 b5 when released. Most keyboards will repeat the make code (key down code) when the key repeats.

From: https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
> 1 votes

---
Tags: arduino-uno, led, usb, shields, keyboard
---


# Question
Title: Why is my CNC shield smoking? Is it safe to keep on for long periods of time?
I am working on a project that involves moving stepper motors, and the device will have to be on for upwards of hours. I am moving the bipolar NEMA17 stepper motors using a Protoneer CNC shield V3 on top of an Arduino UNO and DRV8825 stepper drivers. Though I haven't left the motors on for too long, whenever I do for longer periods, maybe 5 minutes or more, smoke starts being emitted around the 4 pins I connect my motors with. My question is that, if anyone has had a similar issue before, if they could explain why this occurs. I would also like to know if the stepper drivers are actually being protected by the heatsinks, because they can get ridiculously hot even after a few minutes and I'm worried that they wouldn't be able to last more than 15 minutes before exploding. Hopefully there's enough information here for someone to understand what's going on, but I'd glad to give more if that helps get a better idea of what's going on here. Thank you!

# Answer
> 3 votes
Those NEMAs are big ones - i suspect too big for the little A4988 chips - which can only provide 2A when actively cooled and generally only for short periods. I wouldn't try to push more than 1.7ish Amps for any length of time.

You will also need to set the vREF correctly for the motors you are using - if this is not set you will either provide too little current or too much current.

Look up the specifications for the NEMAs you have - and upgrade the Stepper controller to something more like a TB6600 that can handle greater current.

Also when the Steppers are not being used - disable (if you dont need them to hold) this will turn off the drivers and let them cool between runs/moves.

---
Tags: arduino-uno, stepper
---


title: Arduino ESP8266 GPS integration issue

text:
# Question
Title: Arduino ESP8266 GPS integration issue
I am facing issue in using 2 Serial communication device with Arduino uno. I am trying to use ESP8266, Neo 6M GPS module with Arduino UNO, but only one of device is working at a time. Is there any solution available to make this work? When I comment processGPS() and uncomment TCP related API and vice-versa then either of the device working. Any idea how we can make work both?

My code:

```
// This is a demo example using a public http server for testing both GET and POST requests

#include <Arduino.h>
#include <LiteESP8266Client.h>
#include "TinyGPS++.h"
#include "SoftwareSerial.h"

#define PACKET_MTU 500    // Standard network MTU is 500 bytes

LiteESP8266 radio;

const char ssid[] PROGMEM = "xyz";    //change it to your wifi SSID
const char password[] PROGMEM = "xyz";    //change it to your wifi password
const char host[] PROGMEM = "192.168.0.156";
const int port = 8080;

const char http_get_request[] PROGMEM = "GET /getLedStatus HTTP/1.1\r\n";
const char http_useragent[] PROGMEM = "User-Agent: Arduino-stm32/0.1\r\n";
const char http_content_type_json[] PROGMEM = "Content-Type: application/json\r\n";
const char http_host[] PROGMEM = "Host: 192.168.0.156\r\n";
const char http_close_connection[] PROGMEM = "Connection: close\r\n\r\n";
const char http_content_length_header[] PROGMEM = "Content-Length: ";
const char success[] PROGMEM = "success";
const char failed[] PROGMEM = "failed";
const char CRLF[] PROGMEM = "\r\n";
const char error_data_null[] PROGMEM = "Error: data came back null.";
const int ledPin=11;
// Choose two Arduino pins to use for software serial
int RXPin = 5;
int TXPin = 4;

int GPSBaud = 9600;

// Create a TinyGPS++ object
TinyGPSPlus gps;

// Create a software serial port called "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);

void setupStationMode() {
  Serial.print(F("Setup station mode... "));
  if (radio.set_station_mode()) {
    Serial.println(F("success"));
  } else {
    Serial.println(F("failed"));
  }
}

void joinAP() {
  Serial.print(F("Join AP "));
  Serial.print(F("... "));
  if (radio.connect_to_ap(ssid, password)) {
    Serial.println(F("Success"));
  } else {
    Serial.println(F("Failed"));
  }
}

boolean establishTcpConnect() {
  Serial.print(F("Establish TCP Connection... "));
  if (radio.connect_progmem(host, port)) {
    Serial.println(F("Success"));
    return true;
  } else {
    Serial.println(F("Failed"));
    return false;
  }
}

void readHttpPacketAndProcessLEDStatus() {
  char *data;
  while ((data = radio.get_response_packet(PACKET_MTU, 5000))) {
    if (data) {
      Serial.println(F("Response Received..."));
      Serial.println(data);
      if(strstr(data, "ON") != NULL) {
        digitalWrite(ledPin, HIGH);
      }else{
        digitalWrite(ledPin, LOW);
      }
      free(data);//Mandatory
    } else {
      Serial.println(error_data_null);
    }
  }
}

void httpGetLedStatus() {
  Serial.println(F("Sending GET request... "));
  radio.send_progmem(http_get_request);
  radio.send_progmem(http_useragent);
  radio.send_progmem(http_host);
  radio.send_progmem(http_close_connection);
}
void setupGPS(){
  // Start the software serial port at the GPS's default baud
  gpsSerial.begin(GPSBaud);
  Serial.println("GPS Start");//Just show to the monitor that the sketch has started
}
void setup() {
  delay(2000);
  pinMode(ledPin, OUTPUT);
  radio.begin(9600,2,3);
  Serial.begin(9600);
  while (!Serial) {};
  //setupStationMode();
  //joinAP();
  setupGPS();
}
void displayInfo()
{
  if (gps.location.isValid())
  {
    Serial.print("Latitude: ");
    Serial.println(gps.location.lat(), 6);
    Serial.print("Longitude: ");
    Serial.println(gps.location.lng(), 6);
    Serial.print("Altitude: ");
    Serial.println(gps.altitude.meters());
    Serial.println("Speed MPH:");
    Serial.println(gps.speed.mph());
  }
  else
  {
    Serial.println("Location: Not Available");
  }

  Serial.print("Date: ");
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print("/");
    Serial.print(gps.date.day());
    Serial.print("/");
    Serial.println(gps.date.year());
  }
  else
  {
    Serial.println("Not Available");
  }

  Serial.print("Time: ");
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(":");
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(":");
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(".");
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.println(gps.time.centisecond());
  }
  else
  {
    Serial.println("Not Available");
  }

  Serial.println();
  Serial.println();
  delay(1000);
}
void processGps(){
   // This sketch displays information every time a new sentence is correctly encoded.
  if (gpsSerial.available() > 0)
    if (gps.encode(gpsSerial.read()))
      displayInfo();
}
void loop() {
  /*if(establishTcpConnect()){
    httpGetLedStatus();
    readHttpPacketAndProcessLEDStatus();
  }*/
  processGps();
  }

```

# Answer
> 1 votes
As mentioned by StarCat and romkey, SoftwareSerial only allows one connection at a time.

There are two potential solutions to this in my opinion, but each requires some new hardware.

### Solution 1 - Replace Arduino Uno with an STM32 Blue Pill

STM32 Blue Pill has more than one hardware serial interfaces, so that you don't even need the SoftwareSerial, in fact, the `LiteESP8266Client.h` will auto detect if a STM32 is used or an AVR-based Arduino is used to decide whether to use `HardwareSerial` or `SoftwareSerial`, see here.

Pros:

* Minimum code change. You be able to use what you have written so far and continue to use ESP-01 as a WiFi-shield;

Cons:

* A little bit extra works to setup STM32duino Core for Arduino and requires either a SWDI programmer or USB-serial programmer.

Read this for getting started with STM32 and the things need to be aware of.

### Solution 2 - Replace both Arduino Uno and ESP-01 with an ESP8266 Dev Board

Instead of using an ESP-01 as a WiFi shield, get an ESP12-based development board as an Arduino to replace both the Arduino Uno and ESP-01. In this case, you run Arduino sketch directly on the board and replace the AT firmware with Arduino bootloader.

Pros:

* Integrated Arduino Uno with ESP wireless functionality into one hardware.

Cons:

* Need complete re-write of your application.

ESP8266 Arduino github should have sufficient information for getting started.

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


title: Is Arduino Mega Hackable Over The Air

text:
# Question
Title: Is Arduino Mega Hackable Over The Air
After reviewing similar topics I've decided to ask this question below in the Security Stackexchange forum about 11 days ago. https://security.stackexchange.com/questions/235423/is-arduino-mega-hackable-over-the-air

*No one gave an answer yet, perhaps I was wrong about the medium that's why I am also posting the question here.*

I am collecting data (by reading input registers) from a machine by RS-485 protocol and Arduino Mega 2560 hardware.

I am also sending this data from Arduino Mega to a NodeMCU which is connected to the internet over WiFi.

I made 100% sure that no physical interference can be performed on the hardware I setup.

But since this machine, I collect data from is controllable (by writing holding registers) over RS-485 (I've tested it) I have to make sure that Arduino's software cannot be changed/re-programmed/flashed over the air by someone.

There is no other device than NodeMCU which is open to the Internet and can be the source of vulnerability. And the only physical connections between Arduino & NodeMCU ar TX3+RX3 pins and power+ground pins.

I do not really care if the data or WiFi password or cloud server credentials are stolen. The only thing I care about is that Arduino is not flashed over the air which can ultimately damage the machine I am taking data from. Do you think this setup is safe regarding the information I present to you?

# Answer
1. the bootloader doens't listen on RX/TX3.
2. to start the bootloader reset is required
3. to communicate with the bootloader a serial programmer must have STK500 protocol or a telnet bridge for avrdude, which your NodeMCU sketch doesn't have

If your NodeMCU sketch has OTA, then the sketch could be updated to an avrdude telnet bridge. then reset would be needed to activate the bootloader. If your NodeMCU doesn't have a wire to Mega reset pin or you don't have a command in your Mega sketch to activate the reset, some serial overload of your Mega sketch could be a way.

But all this doesn't have an effect because the bootloader only listens at RX0
> 1 votes

---
Tags: arduino-mega, wifi, nodemcu, safety
---