title: Need ESP32 to use 3 serial ports

text:
# Question
Title: Need ESP32 to use 3 serial ports
I have a project that needs 3 serial ports on my ESP32 Dev 38-pin MCU. Two of them are for Nextion touch displays and the other is for a GPS.

The problem from what I understand is that the ESP32 has 3 hardware serial ports, of which only 2 can be used. GPIO 1 and 3 can not be connected to the display during upload and the software serial that is in Arduino IDE 2.0.4 is not compatible with an ESP32.

Can anyone tell me how I can use 3 serial ports?

Thanks.

# Answer
> 2 votes
Yes it is possible to assign any GPIO pins to serial using HardwareSerial library for up to 3 UART Connections. See this link for reference: https://copperhilltech.com/blog/esp32-programming-three-serial-ports-uarts-using-the-arduino-ide/

I'm playing with 2 nextions and esp32 also. would be great to chat with you and brainstorm

# Answer
> 0 votes
```
    #define UART1_ODU_BAUD_RATE 2400
    #define U1RXD 32
    #define U1TXD 33

```

Use this for UART Init in the setup

```
    // UART1 Configuration
      uart_config_t Configurazione_UART1 = {
        .baud_rate = UART1_ODU_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_EVEN,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_APB,
      };
      uart_param_config(NUMERO_PORTA_SERIALE, &Configurazione_UART1);
      esp_log_level_set(TAG, ESP_LOG_INFO);
      uart_set_pin(NUMERO_PORTA_SERIALE, U1TXD, U1RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
      uart_driver_install(NUMERO_PORTA_SERIALE, BUF_SIZE, BUF_SIZE, 20, &uart1_queue, 0);
      xTaskCreate(UART_ISR_ROUTINE, "UART_ISR_ROUTINE", 2048, NULL, 12, NULL);
      //vTaskDelete(NULL);

```

Create a ISR function

```
    static void UART_ISR_ROUTINE(void *pvParameters)                //uart1
    {
      uart_event_t event;
      size_t buffered_size;
      bool exit_condition = false;
      String ODU_PAC_ONE_Temp = "";

      ODU_PAC_ONE = "";

      while (1) {
        if (xQueueReceive(uart1_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
          if (event.type == UART_DATA) {
            uint8_t UART1_data[128];
            int UART1_data_length = 0;
            ESP_ERROR_CHECK(uart_get_buffered_data_len(UART_NUM_1, (size_t*)&UART1_data_length));
            UART1_data_length = uart_read_bytes(UART_NUM_1, UART1_data, UART1_data_length, 100);

            for (byte i = 0; i < UART1_data_length; i++) {
                ODU_PAC_ONE_Temp += (int) UART1_data[i];
            }
          }
          else if (event.type == UART_FRAME_ERR) {

          }
        }
        if (exit_condition) {
          break;
        }
      }
      vTaskDelete(NULL);
    }

```

You will get your data in here `(int) UART1_data[i]`

---
Tags: serial, esp32, softwareserial
---


# Question
Title: Is it "safe" to use "new" keyword to instantize several sensor objects?
I've read that it is bad practice to use dynamic memory allocations on a microcontroller and I have a pretty good grasp of why.

I am developing a custom PCB around an ATMega2560 and in my situation, I need to create 24 objects for one kind of sensor and 8 more for another.

With a small number of sensors, you might create objects like this:

```
Ezo_board PH = Ezo_board(99, "PH");       //create a PH circuit object, who's address is 99 and name is "PH"
Ezo_board EC = Ezo_board(100, "EC");      //create an EC circuit object who's address is 100 and name is "EC"

```

But since I have so many and I want to loop through them I created a pointer array `Ezo_board *EC[maxEC];`

and in setup function I wrote:

```
for (uint8_t i = 0; i < maxEC; i++)
 {
  EC[i] = new Ezo_board(i+11) //passing the I2C address which start at 11 and increment

```

I never delete the Ezo\_board objects in the code. Is this a safe way to use dynamic memory allocation or is there a better way to do this while still maintaining ability to loop through the sensors in subsequent code?

# Answer
> 0 votes
The danger in using dynamic memory on embedded devices lies in *repeated* allocation & de-allocation of chunks of memory. The memory allocator splits off a piece of memory for each allocation. When one is returned the de-allocator joins it - or should join it - with an adjacent free chunk, *if there is one*, to create a larger free chunk instead of two adjacent smaller ones. But that is a big 'if': 1) does the particular memory-manager even try to do that? and 2) in too many instances, it won't even be possible.

The net result is that the memory pool becomes a bunch of small fragments that aren't join-able and aren't large enough to satisfy further requests.

In your scenario, dynamic allocation at the start of the run with no further returns and re-alloacation, there is very little difference between it and static allocation, other than the static allocation would have be done at load-time, just before the run begins.

Either way is fine in that case. If anyone else might ever look over your code, or if someday in the future you might come back to it and wonder whether this application might have created a fragmentation problem, then it's worth leaving a comment to make your intentions clear.

I should add here that when I need dynamic allocation in an embedded system, I write my own memory allocator that never splits free memory. Instead, it simply hands out one buffer from a statically allocated array of fixed size buffers for any request up to that size (and returns a failure code otherwise). Memory is never split or joined, so it never gets fragmented. As long as the demand for buffers is predictable and you allocate enough of them to meet the maximum demand, your system won't fail for running out of memory.

# Answer
> 0 votes
Yes, it is (in common sense) bad practise and you know why and you probabelly also know, why it is not problem in your case.

**It is perfectly safe way and I do not see, why you should not do it this way.**

I do similar things regularry and I have no problem with it.

I want my code working right and the readibility and maintainability are the more important steps in this way. So I structure my code in such way, that I can understand it easily even after couple of years.

There are many rules, how to make code better and there is some reason after each one. But some goes against others.

I have Arduino for fun and I use the rules as recomendations, but I am the Master of my code. So I sometime take other ways.

If it helps me to see the code better organized, I have not problem to do things my own way.

(In large corporation, where you must share code with many others, the formal rules are more important, as they helps all to be at the same platform. There you are payed to stick to rules.

In home developement I share code mainly with myself and I am not paid. So I have to care mainly only about future me)

---
Tags: memory-usage
---


# Question
Title: Is is possible to install a bootloader to an Arduino clone without a physical programmer?
I got an Arduino UNO clone, connected it to my PC via USB. I can't upload any sketches.

Correct board and port are selected in the IDE. Windows recognizes it as a device, even though it has a CH340 (known issue with Chinese clones), so drivers don't seem to be the issue. All physical connections and wiring on the board seem good.

So I am led to believe that the bootloader is the issue.

After a bit of digging around, I didn't find a way to install an Arduino bootloader that didn't require a programmer device or an extra original Arduino board in hand.

Here is the console output after trying to upload a sketch.

```
avrdude: Version 6.3-20190619
     Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
     Copyright (c) 2007-2014 Joerg Wunsch

     System wide configuration file is "C:\Users\lhyse\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

     Using Port                    : COM3
     Using Programmer              : arduino
     Overriding Baud Rate          : 115200
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0xaa
     avrdude: stk500_recv(): programmer is not responding
     avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0xaa

     avrdude done.  Thank you.

     Failed uploading: uploading error: exit status 1

```

# Answer
For devices with an Atmega MCU and no pre-installed bootloader, the answer is NO - it is not possible to install a bootloader without a physical programmer.

If **there is a working bootloader**, but not the one you need, it might be possible under some circumstances.

Lets assume an Atmega328p has a current bootloader that is only 512 bytes large (4 pages) and resides at 0x3F00-0x3FF and BOOTSZ=11.

One might use the *current bootloader* to program the *new bootloader* (also 512 bytes) into the application area just below the current bootloader to address 0x3E00-0x3EFF. Now, **if the current bootloader is capable of changing fuses** BOOTSZ=10, the next time a reset occurs, at least I think so, the *new bootloader* at 0x3E00 will be startet. The bootloaders should not overlap each other for this to work.
> 0 votes

---
Tags: bootloader
---


# Question
Title: OLED and Wifi not working together on ESP8266 Heltec NodeMCU
I have this ESP8266 Heltec NodeMCU board with OLED. The pins are described here.

I have the following problem. The both OLED (with u8g2) and Wifi work fine individually. There is a problem getting them working together.

In particular, the following code works (and shows Hello World, blanks the screen and then repeats):

```
#include <U8g2lib.h>
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
  u8g2.begin();
}

void loop() {
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.firstPage();
  do {
    u8g2.setCursor(0, 20);
    u8g2.print(F("Hello World!"));
  } while ( u8g2.nextPage() );
  delay(2000);
  u8g2.clear();
  delay(2000);
}

```

Adding the Wifi to the code (the only difference to the code above are the 2 lines in the setup).

```
#include <ESP8266WiFi.h>
#include <U8g2lib.h>
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

void setup() {
  u8g2.begin();

  WiFi.begin ( "xxx", "yyy" );
  while ( WiFi.status() != WL_CONNECTED  ) { delay(500); }
}

void loop() {
  u8g2.setFont(u8g2_font_ncenB14_tr);
  u8g2.firstPage();
  do {
    u8g2.setCursor(0, 20);
    u8g2.print(F("Hello World!"));
  } while ( u8g2.nextPage() );
  delay(2000);
  u8g2.clear();
  delay(2000);
}

```

In this case, "Hello World" appears 3 times and then the screen remains blank.

**Edit:**

I noticed something which, I believe, is an important piece of information when I turned the debugging of the WiFi on.

The display stops working after the output `pm open,type:2 0` of the debugger. I believe that pm refers to powermanagement. Could it be that the system goes sleeping? How to prevent this from happening?

# Answer
I managed to solve the issue and figure out what the problem is. I put here an answer for reference, if this question appears again. It turns out that the reset of the OLED is important. It is easy to see, if one uses the `Adafruit_SSD1306` library. The code

```
  #define SCREEN_WIDTH 128
  #define SCREEN_HEIGHT 32
  #define OLED_RESET 0
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

```

produces exactly the issues described in the text. Changing it into

```
  #define SCREEN_WIDTH 128
  #define SCREEN_HEIGHT 32
  #define OLED_RESET 16
  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

```

solves the issue. Similarly, replacing `U8X8_PIN_NONE` with `16` in the code above, runs as expected. It looks like the example provided with the board is incorrect.
> 4 votes

---
Tags: esp8266, nodemcu, oled
---


# Question
Title: Modifying the alert-like popup in ESPAsyncWebServer authenticate() function
So, ESPAsyncWebServer library is using the Digest MD5 Authentication by default, and I want to use this feature in my webserver, but there is a problem, I don't like the ugly prompt box, and I don't want to write a form for authentication, because is sends the password in clear text. I have searched all files in the Src folder of the ESPAsyncWebServer library, Yet I had no luck up to my beginner programming knowledge. So, how can I do this? it is something totally browser side and I cannot change it?

**Update:** I was able to get the following from the Wireshark.

```
Hypertext Transfer Protocol
    GET /openthefdoor HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): GET /openthefdoor HTTP/1.1\r\n]
            [GET /openthefdoor HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: GET
        Request URI: /openthefdoor
        Request Version: HTTP/1.1
    Host: 192.168.1.3\r\n
    Connection: keep-alive\r\n
    Cache-Control: max-age=0\r\n
     [truncated]Authorization: Digest username="admin", realm="asyncesp", nonce="d13ba3040a4ed5c661a47d28c08554f4", uri="/openthefdoor", response="ca8806aa058dda66838784e784e67f8b", opaque="90ba2cd8a2870065f4daa582fd57105a", qop=auth, nc=0000
         username="admin"
         realm="asyncesp"
         nonce="d13ba3040a4ed5c661a47d28c08554f4"
         uri="/openthefdoor"
         response="ca8806aa058dda66838784e784e67f8b"
         opaque="90ba2cd8a2870065f4daa582fd57105a"
         qop=auth
         nc=00000002

```

**2nd update:** based on this question I guess the popup is coming up from the browser and I was looking in a wrong place!

# Answer
> 1 votes
The authentication dialog, that you get, is provided by the browser. You cannot change this, since it is part of the browser software.

> I don't want to write a form for authentication, because is sends the password in clear text.

That is false. How exactly the data is send depends on how you implement your login/action site. You can also tap into the forms `submit` event and use javascript with something other than Basic Authentication, like the Digest Authentication, that you mentioned. So your webpage, that gets served from the ESP, would contain the nice looking HTML form and javascript code, that uses the `submit` event of the form and does a webrequest to the ESP for the `/openthefdoor` endpoint, providing the credentials as digest (hashes).

From the ESPs (aka webservers) perspective, it is functionally irrelevant, if the login webrequest is done by typing in the login address in the address bar, or by javascript code embedded inside the served website. Both are just simple webrequests. You don't need to submit data from a form directly (unencrypted)

I cannot give you a ready made example of such javascript code and this is off topic for this Arduino site. Though you should be able to find example code online. Maybe by searching for something like "javascript digest authentication" or similar.

Note: Digest authentication transmits hashes of the credentials. That is not the same as encryption, especially with an easy hash standard like MD5. Better than plain text, but with a hash table an attacker would still be able to read the credentials. For encryption you would need TLS (https).

---
Tags: web-server
---


# Question
Title: Photoresistor Matrix has the same values
I'm a second-year System Engineer student who needs to make a project for class. I have a 4x4 matrix of photoresistors that goes to an analog digital multiplexer connected to an Arduino Uno. This setup is put in a box with a lid. The lid has a hole in the middle of the matrix. I want to calculate the angle of a light source depending on the photoresistors' readings. Basically, I want to recreate a Sattelite Sun Sensor. I have the following problem: all the photoresistors from a row have the same reading, even if I try to isolate one of them and shine a light on it. In the column, everything works well.

This is my circuit on a 2 layers PCB: (C0-C15, SIG, S0-S3, EN are the pins of the CD74HC4067 Multiplexer)

Also, this is my code:

```
//Mux control pins
int s0 = 11;
int s1 = 10;
int s2 = 9;
int s3 = 8;

//Mux in "SIG" pin
int SIG_pin = 0;
float values[4][4] = {0.0};

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);

  Serial.begin(9600);
}

void loop(){

  //Loop through and read all 16 values
  for(int i = 0; i < 4; ++i)
      for(int j = 0; j < 4; ++j){
        values[i][j] = readMux(i);
        delay(500);
      }

  Serial.println("-----Matrix-----");
  for(int i = 0; i < 4; ++i){
      for(int j = 0; j < 4; ++j){
        Serial.print(values[i][j]);
        Serial.print(" ");
        delay(100);
    }
    Serial.println();
  }
  Serial.println();
  Serial.print(calculateAngle());
  Serial.println();
  delay(1000);
}

float calculateAngle(){
  const int dx[] = {-2, -1, 1, 2, -2, -1, 1, 2, -2, -1, 1, 2, -2, -1, 1, 2};
  const int dy[] = {-2, -2, -2, -2, -1, -1, -1, -1, 1, 1, 1, 1, 2, 2, 2, 2};
  float x = 0, y = 0;

  for(int i = 0; i < 16; ++i){
    x += dx[15 - i] * values[i / 4][i % 4];
    y += dy[15 - i] * values[i / 4][i % 4];
  }
  Serial.print(x);
  Serial.print(" ");
  Serial.print(y);
  Serial.print(" ");
  return atan2(y, x) * 180 / 3.14;
}

float readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };
  DDRB = 0;
  //loop through the 4 sig
  for(int i = 0; i < 4; i ++)
    DDRB |= (1 << i) & muxChannel[channel][i]; //faster than digitalWrite(controlPin[i], muxChannel[channel][i]);
  delay(100);
  //read the value at the SIG pin
  int val = analogRead(SIG_pin);
  //convert the value in voltage
  float voltage = (val * 5.0) / 1024.0;
  //return the voltage
  return voltage;
}

```

Example of a bogus reading:

```
-----Matrix-----
0.13 0.14 0.13 0.12
3.14 3.17 3.12 2.96
0.12 0.12 0.11 0.12
2.77 2.81 2.83 2.77

```

What am I doing wrong? Did I make a mistake in my code or connecting everything together? Thank you for any help!

# Answer
> 0 votes
This is probably, because you don't actually set the MUX pins. The `DDRx` registers set the **D**ata **D**irection of the port pins. A 1 in there means, that the pin corresponding to that bit is set as output. A zero means, it is set as input. The output state of a pin is controlled by the `PORTx` registers. If the `DDRx` bits are set to input and the `PORTx` bits are set to 1, then the internal pullup resistor is activated.

In setup you set all the MUX pins to OUTPUT and LOW, so `DDRB` with 1s and `PORTB` with zeros. Then in `readMux()` you are just setting bits in `DDRB` via the (overcomplicated) line:

```
DDRB |= (1 << i) & muxChannel[channel][i];

```

So you are switching the pins between OUTPUT+LOW and INPUT+NO\_PULLUP. Instead you should write to the `PORTB` register, which controls the output state of the port B pins.

Also writing the mux channel can be done way easier. When you look at your array in `readMux()` you might notice, that the channel patters are just a binary number. So you have the following channel number to pattern relationship:

```
channel  0 --> binary 0000 --> decimal 0
channel  1 --> binary 0001 --> decimal 1
channel  2 --> binary 0010 --> decimal 2
channel  3 --> binary 0011 --> decimal 3
...
channel 10 --> binary 1010 --> decimal 10
...

```

So instead of using the above overcomplicated line, you can just write the channel number to the 4 target bits of `PORTB`:

```
PORTB |= channel & 0b00001111;

```

You don't even need to for loop for that. The `& 0b00001111` part is only for cutting the channel number to only ever use the first 4 bits of the register (keeping it down between 0 and 15).

---
Tags: arduino-uno, multiplexer, pcb-design, photoresistor
---


title: Upgrade ESP-01 firmware on MacOS

text:
# Question
Title: Upgrade ESP-01 firmware on MacOS
I recently bought an ESP-01 as well as an FTDI programmer (3.3v-5v) and after typing `AT+GMR` I noticed it said:

* AT version:0.40.0.0(Aug 8 2015 14:45:58)
* SDK version:1.3.0
* Ai-Thinker Technology Co.,Ltd.
* Build:1.3.0.2 Sep 11 2015 11:48:04

I have looked and looked on a way to upgrade its firmware (on MacOS) to no avail. How can I upgrade it? I want to be able to change the baud rate to 9600. A lot of examples to do it are in windows requiring another application or something like that but how can I do it in a Macbook? Thanks.

# Answer
Here is the step-by-step on upgrade the ESP-01 AT Command firmware (for running on macOS).

## Wiring

For flashing the ESP-01 firmware, you need to have a USB-TTL adaptor as a programmer.

```
+---------------------+---------+
|                     | RxD Vcc |
|       Top View      | IO2 RST |
|                     | IO0 CPD |
|                     | GND TxD |
+---------------------+---------+

ESP-01          USB-TTL Adaptor
 VCC   ---------- 3V3
 GND   ---------- GND
 TxD   ---------- RxD
 RxD   ---------- TxD
 CH_PD ---------- see note* below
 GPIO0 ---------- Connect to a push switch (Flash button) to GND
 RST   ---------- a push switch (Reset button) to GND

```

> Note: depend on whether you have ESP-01 or ESP-01S, for ESP-01, you will need to connect CH\_PD either directly to 3v3 or via a 3k-10k resistor to 3v3. However, you don't need an extra pull-up resistor for ESP-01S as CH\_PD already has on-board pull-up resistor. This picture shows the different between ESP-01 and ESP-01S, visually ESP-01 has 2 LEDs on board near the antenna, while ESP-01S have two extra resistor between header pins and ESP8266EX chip, and with only one LED.

## Download and install esptool

Download and install esptool from https://github.com/espressif/esptool. `esptool` is a python application. You need to have python installed as well.

## Download firmware 2.1

Download ESP8266 nonOS SDK - Release 2.1.x, noticed that this is not the latest version as the latest version doesn't works for ESP-01 based on my experience.

## Upgrade the firmware

You will actually only need 4 files for the upgrade, I would suggest that you copy and paste those files into your esptool directory from the downloaded `bin/` directory. `cd` into your esptool directory and run the following commands to upgrade the firmware.

To put ESP-01 into programming mode:

1. Press and hold Flash(GPIO0) button;
2. Press Reset button once, this will put ESP-01 in programming mode;
3. Press Reset to start the newly uploaded program when upload is completed.

```
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x00000 boot_v1.7.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x01000 user1.1024.new.2.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x7c000 esp_init_data_default.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x3e000 blank.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x7e000 blank.bin

```

***Please noted that `/dev/cu.SLAB_USBtoUART` is the USB port for my USB-TTL interface, yours might be different, run `ls /dev/tty.*` to find out your USB port***
> 4 votes

# Answer
You use `esptool.py` available from github.

It's exactly the same usage regardless of which operating system you are using (apart from the serial port device name of course), so instructions for Linux (for example) are the same as instructions for Mac OS X.
> 0 votes

# Answer
The OP doesn't need to upgrade the ESP's firmware, despite that that's what the question said. They apparently want to change its baud rate. That is doable with an AT command in the existing firmware, as described @hcheung described in a comment.

See my answer to a similar question here, noting especially, the last few lines of that post which is essentially a script for manually making the change. Note also, that this is not at all host operating system specific; everything is done with a sketch like the one in that question, and the Arduino IDE Serial Monitor.
> -1 votes

---
Tags: esp8266, ftdi, mac-os, firmware, baud-rate
---


title: ESP32-CAM camera: SD help

text:
# Question
Title: ESP32-CAM camera: SD help
I'm struggling with making a simple sketch to take a photo with an ESP32-CAM and save to an SD card.

I have found a bunch of examples that that do what I want, but basically they just take a photo and go to sleep, so every time you reset the unit it runs some code to take a photo, then goes into deep sleep.

The thing is the photos suck, they are green and have no exposure control. I think that it is a known issue that the first photo is always green and the auto gain has not figured out the exposure yet. So because every photo is the first photo after waking up, they all suck.

I tried to move the setup stuff into the loop, and remove the sleep part, but it just straight up doesn't work, and I don't understand enough about coding to even get ChatGPT to help.

I will put the working code below, and then the part I changed. Any help would be great. I thought it would be so simple, I just want to take a photo when I push a button.

```
/*
ESP32 CAM Camera with MicroSD storage
  esp32cam-microsd.ino
  Take picture when button pressed
  Store image on MicroSD card

  DroneBot Workshop 2022
  https://dronebotworkshop.com
*/
// Include Required Libraries

// Camera libraries
#include "esp_camera.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"

// MicroSD Libraries
#include "FS.h"
#include "SD_MMC.h"

// EEPROM Library
#include "EEPROM.h"

// Use 1 byte of EEPROM space
#define EEPROM_SIZE 1

// Counter for picture number
unsigned int pictureCount = 0;

// Pin definitions for 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

void configESPCamera() {
  // Configure Camera parameters

  // Object to store the camera configuration parameters
  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; // Choices are YUV422, GRAYSCALE, RGB565, JPEG

  // Select lower framesize if the camera doesn't support PSRAM
  if (psramFound()) {
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10; //10-63 lower number means higher quality
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

  // Initialize the Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  // Camera quality adjustments
  sensor_t * s = esp_camera_sensor_get();

  // BRIGHTNESS (-2 to 2)
  s->set_brightness(s, 0);
  // CONTRAST (-2 to 2)
  s->set_contrast(s, 1);
  // SATURATION (-2 to 2)
  s->set_saturation(s, 0);
  // SPECIAL EFFECTS (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia)
  s->set_special_effect(s, 2);
  // WHITE BALANCE (0 = Disable , 1 = Enable)
  s->set_whitebal(s, 1);
  // AWB GAIN (0 = Disable , 1 = Enable)
  s->set_awb_gain(s, 1);
  // WB MODES (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
  s->set_wb_mode(s, 0);
  // EXPOSURE CONTROLS (0 = Disable , 1 = Enable)
  s->set_exposure_ctrl(s, 1);
  // AEC2 (0 = Disable , 1 = Enable)
  s->set_aec2(s, 0);
  // AE LEVELS (-2 to 2)
  s->set_ae_level(s, 0);
  // AEC VALUES (0 to 1200)
  s->set_aec_value(s, 300);
  // GAIN CONTROLS (0 = Disable , 1 = Enable)
  s->set_gain_ctrl(s, 1);
  // AGC GAIN (0 to 30)
  s->set_agc_gain(s, 0);
  // GAIN CEILING (0 to 6)
  s->set_gainceiling(s, (gainceiling_t)0);
  // BPC (0 = Disable , 1 = Enable)
  s->set_bpc(s, 0);
  // WPC (0 = Disable , 1 = Enable)
  s->set_wpc(s, 1);
  // RAW GMA (0 = Disable , 1 = Enable)
  s->set_raw_gma(s, 1);
  // LENC (0 = Disable , 1 = Enable)
  s->set_lenc(s, 1);
  // HORIZ MIRROR (0 = Disable , 1 = Enable)
  s->set_hmirror(s, 0);
  // VERT FLIP (0 = Disable , 1 = Enable)
  s->set_vflip(s, 0);
  // DCW (0 = Disable , 1 = Enable)
  s->set_dcw(s, 1);
  // COLOR BAR PATTERN (0 = Disable , 1 = Enable)
  s->set_colorbar(s, 0);
}

void initMicroSDCard() {
  // Start the MicroSD card
  Serial.println("Mounting MicroSD Card");
  if (!SD_MMC.begin()) {
    Serial.println("MicroSD Card Mount Failed");
    return;
  }
  uint8_t cardType = SD_MMC.cardType();
  if (cardType == CARD_NONE) {
    Serial.println("No MicroSD Card found");
    return;
  }
}

void takeNewPhoto(String path) {
  // Take Picture with Camera
  // Setup frame buffer
  camera_fb_t  * fb = esp_camera_fb_get();

  if (!fb) {
    Serial.println("Camera capture failed");
    return;
  }

  // Save picture to microSD card
  fs::FS &fs = SD_MMC;
  File file = fs.open(path.c_str(), FILE_WRITE);
  if (!file) {
    Serial.println("Failed to open file in write mode");
  }
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
  }
  // Close the file
  file.close();

  // Return the frame buffer back to the driver for reuse
  esp_camera_fb_return(fb);
}

void setup() {
  // Disable brownout detector
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  // Start Serial Monitor
  Serial.begin(115200);

  // Initialize the camera
  Serial.print("Initializing the camera module...");
  configESPCamera();
  Serial.println("Camera OK!");

  // Initialize the MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();

  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureCount = EEPROM.read(0) + 1;

  // Path where new picture will be saved in SD Card
  String path = "/image" + String(pictureCount) + ".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());

  // Take and Save Photo
  takeNewPhoto(path);

  // Update EEPROM picture number counter
  EEPROM.write(0, pictureCount);
  EEPROM.commit();

  // Bind Wakeup to GPIO13 going LOW
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);

  Serial.println("Entering sleep mode");
  delay(1000);

  // Enter deep sleep mode
  esp_deep_sleep_start();
}

void loop() {
}

```

I changed the set up and loop:

```
void setup() {
  // Disable brownout detector
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);

  // Start Serial Monitor
  Serial.begin(115200);

  // Initialize the camera
  Serial.print("Initializing the camera module...");
  configESPCamera();
  Serial.println("Camera OK!");

  // Initialize the MicroSD
  Serial.print("Initializing the MicroSD card module... ");
  initMicroSDCard();

  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureCount = EEPROM.read(0) + 1;
}

void loop() {
  // Path where the new picture will be saved on the SD Card
  String path = "/image" + String(pictureCount) + ".jpg";
  Serial.printf("Picture file name: %s\n", path.c_str());

  // Check if GPIO13 is low
  if (digitalRead(GPIO_NUM_13) == LOW) {
    // Take and Save Photo
    takeNewPhoto(path);

    // Update EEPROM picture number counter
    EEPROM.write(0, pictureCount);
    EEPROM.commit();

  }
}

```

# Answer
> 0 votes
Read this web page, in the section take photo to SD card

```
fb = esp_camera_fb_get();
dealy(1000)////

```

***This is key to avoid an issue with the image being very dark and green. If needed adjust total delay time.***

```
fb = esp_camera_fb_get();

```

Hope this helps,

I would suggest take some image buffers first wake the camera up then write the data later to SD card.

---
Tags: esp32-cam
---


title: Which sketch was this?

text:
# Question
Title: Which sketch was this?
With ESP32 being so plentiful here (3 more for Christmas) I am at a loss to determine which sketch I used for a particular unit. Has anyone devised a record keeping scheme or even a serial monitor feedback with the sketch details available when plugged back in to the PC?

# Answer
> 2 votes
Early in setup() I print one line to the terminal with the .ino file's name, revision, and date. I keep all projects under source-code control which maintains that line without any effort from me, as long as I've included the small snippet of data and and the Serial.println() call to print it.

Update:

> Can you show some code how you include the automatic revision identification into the Arduino Build Chain?

Here's an example. Note that the build-chain isn't modified; everything happens in the source code, RCS, in my case. You'll probably have to tweak the keyword that gets the revision data, ($Id$ in RCS) for whatever source control you use. If you aren't using source control, you could print the compile-time macros suggested by @DataFiddler.

```
/*
 * Macro to tell ::println() & family to expact a pointer to Flash memory
 * #define this in your library's local.h file, or where ever you'd
 * put your personal, site-unique, or non-public macros like your
 * WiFi password:
 *
 * #define FLSTR_HLP(str) (const __FlashStringHelper *)str
 * (Look up __FlashStringHelper for more information)
 *
 */
// ----------------------------------
// Your .ino file would start here:

#include <local.h>                        // gets the above #define

// Define one of these in each .ino file:
// const char IdString[] PROGMEM = $Id$
// RCS expands or updates it to something like this,
//  every time you check out any version:
//  (Other source control systems will have similar facilities)
const char IdString[] PROGMEM = "$Id: HowTo_IdString.ino,v 1.1 2023-12-26 18:16:06-05 jrobert Exp $";   // def an IdString in Flash

void setup() {
   Serial.begin(115200);
   Serial.print("");
   Serial.println(FLSTR_HLP(IdString));   // prints the IdString from Flash

   // .. more setup ..
}

void loop() {
   Serial.print(F("Run time: "));
   Serial.println(millis());
   delay(5000);
}

```

# Answer
> 0 votes
If you want just a simple way of identification, use some of the compiler's predefined macros* as automagic source of information:

```
void setup() {
  while (!Serial);
  Serial.begin(115200);
  Serial.print("(");
  Serial.print(__VERSION__);
  Serial.print(") ");
  Serial.print(__FILE__);
  Serial.print(": ");
  Serial.print(__DATE__);
  Serial.print(", ");
  Serial.println(__TIME__);
}

void loop() {
}

```

The output of the sketch is:

```
(7.3.0) /home/XXXXXXXX/name_of_sketch.ino: Dec 27 2023, 23:03:58

```

\*) In my case (Arduino IDE version 1.8.19) the version of G++ is 7.3.0.

---
Tags: serial, esp32, sketch
---


title: Adding a custom platform to PlatformIO

text:
# Question
Title: Adding a custom platform to PlatformIO
How can I add the STM32duino core as a custom platform to PlatformIO?

# Answer
## Creating custom board support for PlatformIO

PlatformIO provides a very comprehensive documentation on how to use PlatformIO for programming STM32 with various platforms. You can find "Custom Platform & Boards" on the side menu, which will lead you to this section of the document, which again is well documented.

It basically involves creating a JSON file that describes your custom platform or custom board. The easier way is to copy one of the family MCUs JSON configuration file that's already supported by the PlatformIO or STM32duino framework, and make modifications from there. For example, if your custom board is STM32G070xx, which is not supported by PlatformIO yet, you can find the board description JSON from platform-stm32 github repository for Nucleo\_G070RB board and use it as a template to create your own custom board JSON structure.

## Creating custom board support for Arduino IDE

The official STM32duino wiki provides a description on how to create a custom board variant on Arduino IDE for the framework. I also have an example of a custom variant for supporting my two custom boards in my github that you could take a look at in case you are interested to create custom board support under Arduino IDE.
> 1 votes

---
Tags: stm32, platformio
---


title: UCSR0B equivalent for ESP2866

text:
# Question
Title: UCSR0B equivalent for ESP2866
I'm trying to convert an Arduino Uno program for use with the ESP2866. I've converted most of the program successfully, but there are a few lines I can't seem to figure out. For example,

```
  UCSR0B = 0b10011101;
  UCSR0B = 0b10011100;

```

These lines result in the following error:

```
Compilation error: 'UCSR0B' was not declared in this scope

```

My understanding is that these lines modify parameters within one of the Uno's serial registers. Is it possible to do the equivalent action on the ESP? I have tried researching this but have found very little info online. I am using Arduino IDE v2.2.1. Thank you!

# Answer
> 1 votes
UCSR0B is the UART Control and Status Register on an ATMEGA328, the processor used on many Arduino models. This is extract from the ATMEGA328 datasheet shows what the bits do:

Setting it to 0b10011101 enables RXCIE, RXEN,TXEN, UCSZ2 and TXB, and setting to the 0b10011100 sets all of the bits except TXB. Setting UCSZ2 enables 9-bit mode, and setting or clearing TXB sets or clears the ninth bit for transmitted data.

Taking a quick look at the ESP8266 UART config, the UART supports a maximum of 8 bits, so if your app definitely requires 9 bits, you won't be able to do it on an ESP8266.

```
typedef enum {
    UART_DATA_5_BITS = 0x0,    /*!< word length: 5bits*/
    UART_DATA_6_BITS = 0x1,    /*!< word length: 6bits*/
    UART_DATA_7_BITS = 0x2,    /*!< word length: 7bits*/
    UART_DATA_8_BITS = 0x3,    /*!< word length: 8bits*/
} uart_word_length_t;

```

---
Tags: serial, communication, uart
---


# Question
Title: Where should unit tests go in the Arduino IDE
I have an Arduino project where the file structure looks like this

```
myProject/
    myProject.ino
    ImportantClass1.hpp
    ImportantClass1.cpp
    ImportantClass2.hpp
    ImportantClass2.cpp
    Etc….

```

It compiles and runs fine. No problem pulling the cpp and hpp files into the ino program. However to really make sure of reliability I want to make additional ino files for unit testing of importantClass1 & etc. I have made files `importantClass1UnitTest.ino` & `importantClass2UnitTest.ino` however these can’t be in the same dir as the respective source files as the arduino compiler requires the ino file and the dir to have the same name.

The tests run when I move the files around. But I am not happy with that, I want to be able to run the tests at any time with the standard arduino compiler without having to script filecopy commands.

If I put the unit test in its own dir separate to the class source and `#include` using the full path it also works. However this solutions is not portable, when I (or any collaborator) pull the project from git hub on any other computer the paths are wrong and it doesn’t work.

Where am I going wrong? How can I do this so as to avoid moving/copying files and also avoid using full paths?

# Answer
One way to do it is to use preprocessor conditionals. Name your project file and unit-test files with `.cpp` extensions and put them in a subfolder (called "sources" in my example). Then your `.ino` file would only be used to instruct the preprocessor which of the several "main" file to start compiling with:

myProject.ino:

```
/*
 * myProject.ino
 * define which "main" CPP file to compile:
 */

#define PRODUCTION
// #define UNITTEST1
// #define UNITTEST2
// #define UNITTEST3

// The compilation starts here with the requested "main" file:
#if defined PRODUCTION
#include "sources/myProject.cpp"

#elif defined UNITTEST1
#include "sources/unitTest1.cpp"

#elif defined UNITTEST2
#include "sources/unitTest2.cpp"

#elif defined UNITTEST3
#include "sources/unitTest3.cpp"

#else
// If nothing defined, compile for production
#include "sources/myProject.cpp"
#endif

/* END */

```

Only the .ino file would need to be edited to compile one of the unit tests, and only one project file would be needed.

Update: "did you try it? "

Yes, and it does work. The only caveat I'd add is: don't name your subfolder "src" - that seems to be a magic-name to the IDE, and you'll get complaints of compilation errors (multiple definitions) if you use it. And further, if you try it, you can't get back simply by changing the folder's name (on disk and in the code); you'll have to restart the IDE as well.
I tested it with v1.8.19 of the IDE.
> 1 votes

# Answer
OK. Update, better late than never. I used soft links to overcome this problem.

The final directory structure is like this:

```
myProject/
    .git/
    myProject.ino
    Class1.hpp
    Class1.cpp
    Class2.hpp
    Class2.cpp
    ...
    UnitTests/TestClass1/TestClass1.ino
    UnitTests/TestClass1/Class1.cpp -> ../../Class1.cpp
    UnitTests/TestClass1/Class1.h   -> ../../Class1.h
    ...

```

Both the main program and all the unit tests run fine when compiled in the Arduino compiler and there is only one copy of the class files that I want to test.
> 1 votes

---
Tags: arduino-ide, c++, testing
---


# Question
Title: Joystick library not reading potentiometer
I am using Joystick Library to make a HOTAS system for flight simulators. When I load the test program I can get all the simulated controller inputs to register in windows. I can also get the value from my slide potentiometer to read in the serial monitor. But it will not change the value of the input function i pass it to. my guess is its the wrong kind of integer but I don't know very much about int types. Joystick.setThrottle has an int32\_t as a parameter. Windows reads the value of throttle at 49% when its connected.

What I have tried:

changing the range (the default is 0 to 1023 I want it to be 0 to 255)

changing the type of throttle\_ to int, unsigned int, and int\_32\_t

changing initAutoSendState

using the pin number instead of the macro throttle passing throttle\_ directly into Joystick.setThrottle without the updateThrottle function

I have some programming experience from my high school class so I just tried different approaches but I am new to Arduino.

```
#include "Joystick.h"
//define input pins
#define throttle A0
//include hid, type, button count, hat count, x axis, y axis, z axis, Rx axis, Ry axis, Rz axis, rudder, Throttle, Accelerator,  Brake, Steering
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_JOYSTICK, 0, 0, false, false, false, false, false, false, false, true, false, false, false);
const bool initAutoSendState = true;

int32_t throttle_ = 0;
void updateThrottle (int32_t value)
{
Joystick.setThrottle(value);
}
void setup() {
  // put your setup code here, to run once:

Serial.begin(9600);
pinMode(throttle, INPUT_PULLUP);
Joystick.setThrottleRange(0, 255);

}
void loop() {
  // put your main code here, to run repeatedly:

  throttle_ = analogRead(throttle);
  throttle_ = map(throttle_, 0, 1023, 0,  255);
updateThrottle(throttle_);
Serial.print(throttle_);
Serial.print("\n");

}

```

# Answer
Looking through the examples turns out I needed to add `Joystick.begin();` to the setup
> 0 votes

---
Tags: arduino-leonardo, windows, joystick, hid
---


title: inputs randomly turn on and off

text:
# Question
Title: inputs randomly turn on and off
I'm building the dactyl manuform, and I'm writing all of the code myself, but I've ran into a problem here's my code:

```
// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);

  for (int i=0;i<20;i++){
    pinMode(i, INPUT);
  }
}

// the loop routine runs over and over again forever:
void loop() {
  for (int i=0;i<20;i++){
    Serial.print(digitalRead(i));
  }
  Serial.print("\n");

  //delay(100); //uncomment if you want to
}

```

The problem is even when the inputs are not connected to 5V, the serial monitor sometimes gives a 1, and sometimes a 0. At first I was only using analog inputs, so I was suspecting that, but the same happens with digital inputs. I'm 99% sure it's not the switches, because I tested them with a multimeter. I feel like this is something obvious, and I'm just stupid (well I am, but you get the point).

# Answer
There are several possible reasons random values are seen at micro controller inputs when connected to switches. Here are two:

1. Missing pull up or pull down resistor when using a SPST switch.

Micro controller inputs should not be allowed to float. This can lead to unexpected input states. Instead, inputs should be connected to ground or the micro controller's positive voltage supply usually either directly or though a resistor. It is common to use a pull up resistor when using a SPST switch connected to ground. Or a pull down resistor when using a SPST switch connected to the micro controller's positive voltage supply. Not all micro controllers have pull up or pull down resistors built internally. Some only have one or the other. In these cases an external resistor may be required. Some thought should be given to using micro controllers that do have built in pull up or pull down resistors. The actual resistance value of these built in resistors does vary (may not be carefully controlled). This is fine for the majority of cases. However, if a specific value is needed, it may be best if external resistors were used instead.

2. Long wires between the micro controller and the switch.

Longer wires are more likely to develop unexpected currents due external electrical noise. It is possible wires are long enough and the environment they are in electrically noisy enough to develop currents that will change the voltage across a pull up or pull down resistor. And, in turn, change the value of the micro controller's input. The higher the resistor value the more likely this will happen. However, the lower the resistor value chosen the more power needed when the SPST switch is closed. This is usually a concern when operating on batteries. There are many aspects to mitigating the effects of electrical noise. And will take us off subject. Instead, if long wires are necessary, consider using a "brake-before-make" SPDT switch which will connect the micro controller's input pin directly to ground or the micro controller's positive supply voltage. This will require running 3 rather than 2 wires to the switch.

Last words: Take care not to connect pull up resistors or switches to voltages higher than the micro controller's positive supply voltage! Some Arduino boards regulate higher voltages to lower voltage before supplying power to the micro controller. For instance, an Arduino board that runs from the 5 Volt USB power source may have a micro controller which actually runs at 3.3 Volt. In such a case, use the 3.3 Volts supplied to the micro controller when connecting a pull up resistor or switch.
> 0 votes

---
Tags: arduino-uno
---


title: Button state changing randomly

text:
# Question
Title: Button state changing randomly
I have a push button wired to my Arduino but it seems to be triggering randomly.

I have one pin of the button connected to pin 2 on the arduino and the other connected to ground.

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

    pinMode(2, INPUT);
}

void loop() {
    Serial.println(digitalRead(2));
}

```

I expect it to print 1 continuously and go to 0 when I press the button down but sometimes it shows 0 even when I don't touch it.

# Answer
> 19 votes
When a button is connected in that configuration, the input is what's called *floating*, meaning it's not a 0 or a 1. When the button is pressed, it is connected to ground, so that's definitely a 0, but when it's not pressed down, we don't know the value of the pin.

## Pull Up Resistor

We need to include what's called a "pull-up" resistor to pull the signal up to a logic 1 when the button is not pressed.

Image from Sparkfun

What this means is when the button is not pressed, the Arduino reads a logic 1. When the button is pressed, the current flows through the resistor to ground and the Arduino reads a logic 0.

## Internal Pull Up Resistor

The Arduino also has internal pull up resistors so you don't necessarily have to add an extra component to your circuit. There are a couple of ways to use this.

You used to have to do it like this:

```
pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors

```

Now we can do it simply in one line:

```
pinMode(pin, INPUT_PULLUP);

```

This enables the 20k pull up resistor on that pin. The input will no longer be floating when the button is not pressed.

**Note:** This only works when the other end is connected to ground.

# Answer
> 1 votes
There are several possible reasons random values are seen at micro controller inputs when connected to switches. Here are two:

1. Missing pull up or pull down resistor when using a SPST switch.

Micro controller inputs should not be allowed to float. This can lead to unexpected input states. Instead, inputs should be connected to ground or the micro controller's positive voltage supply usually either directly or though a resistor. It is common to use a pull up resistor when using a SPST switch connected to ground. Or a pull down resistor when using a SPST switch connected to the micro controller's positive voltage supply. Not all micro controllers have pull up or pull down resistors built internally. Some only have one or the other. In these cases an external resistor may be required. Some thought should be given to using micro controllers that do have built in pull up or pull down resistors. The actual resistance value of these built in resistors does vary (may not be carefully controlled). This is fine for the majority of cases. However, if a specific value is needed, it may be best if external resistors were used instead.

2. Long wires between the micro controller and the switch.

Longer wires are more likely to develop unexpected currents due external electrical noise. It is possible wires are long enough and the environment they are in electrically noisy enough to develop currents that will change the voltage across a pull up or pull down resistor. And, in turn, change the value of the micro controller's input. The higher the resistor value the more likely this will happen. However, the lower the resistor value chosen the more power needed when the SPST switch is closed. This is usually a concern when operating on batteries. There are many aspects to mitigating the effects of electrical noise. And will take us off subject. Instead, if long wires are necessary, consider using a "brake-before-make" SPDT switch which will connect the micro controller's input pin directly to ground or the micro controller's positive supply voltage. This will require running 3 rather than 2 wires to the switch.

Last words: Take care not to connect pull up resistors or switches to voltages higher than the micro controller's positive supply voltage! Some Arduino boards regulate higher voltages to lower voltage before supplying power to the micro controller. For instance, an Arduino board that runs from the 5 Volt USB power source may have a micro controller which actually runs at 3.3 Volt. In such a case, use the 3.3 Volts supplied to the micro controller when connecting a pull up resistor or switch.

---
Tags: button
---


# Question
Title: How to check if the MQTT connection is still active?
I am wondering if there is a way to check and see if the MQTT connection is still active.

The reason for this is that I am having trouble with the connection dropping after a short while and not seeming to reconnect.

```
/*
  ArduinoMqttClient - WiFi Simple Sender

  This example connects to a MQTT broker and publishes a message to
  a topic once a second.

  The circuit:
  - Arduino MKR 1000, MKR 1010 or Uno WiFi Rev2 board

  This example code is in the public domain.
*/

#include <ArduinoMqttClient.h>
#include <MKRGSM.h>

#include "arduino_secrets.h"
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = SECRET_PINNUMBER;
// APN data
const char GPRS_APN[]      = SECRET_GPRS_APN;
const char GPRS_LOGIN[]    = SECRET_GPRS_LOGIN;
const char GPRS_PASSWORD[] = SECRET_GPRS_PASSWORD;

GSMClient client;
GPRS gprs;
GSM gsmAccess;
MqttClient mqttClient(client);

const char broker[] = "*****";
int        port     = 1883;
const char topic[]  = "Tempdata";

const long interval = 500000;
unsigned long previousMillis = 0;

float SERIESRESISTOR = 9.87;
float TEMPERATURENOMINAL = 25.0;
float BCOEFFICIENT = 3540.0;
float thermistor = 0.0;
float THERMISTORNOMINAL = 10;

int count = 0;

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);

  Serial.println("Starting Arduino web client.");
  // connection state
  bool connected = false;

  // After starting the modem with GSM.begin()
  // attach the shield to the GPRS network with the APN, login and password
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
    } else {
      Serial.println("Not connected");
      delay(1000);
    }
  }

  Serial.println("You're connected to the network");
  Serial.println();

  // You can provide a unique client ID, if not set the library uses Arduino-millis()
  // Each client must have a unique client ID
  mqttClient.setId("pump-house-gsm");

  // You can provide a username and password for authentication
  //mqttClient.setUsernamePassword("****", "****");

  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  // set analog resulotion to 12
  analogReadResolution(12);
}

void loop() {
  // call poll() regularly to allow the library to send MQTT keep alives which
  // avoids being disconnected by the broker
  mqttClient.poll();

  // to avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay
  // see: File -> Examples -> 02.Digital -> BlinkWithoutDelay for more info
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    /*Read analog outputof NTC module,
     i.e the voltage across the thermistor */
    float average = ((float)analogRead(A0) / 4095.0) * 3.3;

    average = (average * SERIESRESISTOR) / (3.3 - average);

    float steinhart;
    steinhart = average / THERMISTORNOMINAL;     // (R/Ro)
    steinhart = log(steinhart);                  // ln(R/Ro)
    steinhart /= BCOEFFICIENT;                   // 1/B * ln(R/Ro)
    steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
    steinhart = 1.0 / steinhart;                 // Invert
    steinhart -= 273.15;                         // convert absolute temp to C

    // save the last time a message was sent
    previousMillis = currentMillis;

    // Keep track of times a message was sent
    // this is to reconnect every hour.
    count = count + 1;

    // send message, the Print interface can be used to set the message contents
    mqttClient.beginMessage(topic);
    mqttClient.print("The temperature is ");
    mqttClient.print(steinhart);
    mqttClient.endMessage();
  }
}

```

Maybe `endMessage`, `beginMessage`, or `poll` has a return that says it has failed to send a message?

I've looked at `endMessage` and `beginMessage` and it does not seem like it to me, but `poll` is much more complicated and I can't really tell.

# Answer
> 1 votes
I found the solution with the `connected` function included in the ArduinoMqttClient (found it browsing the library code).

Here is a code snippet showing what I added:

```
...
...
if (currentMillis - previousMillis >= interval) {
  if (!mqttClient.connected()) {
    if (mqttClient.connect(broker, port)) {
        Serial.println("reconnected");
    }
  }

  /*Read analog outputof NTC module,
  i.e the voltage across the thermistor */
  float average = ((float)analogRead(A0) / 4095.0) * 3.3;
...
...

```

It is working so far!

---
Tags: gsm, mqtt, mkr-gsm-1400
---


# Question
Title: How to create a 1-hour timer with an ATtiny13A microcontroller?
I want to control an AC load such that it powers on for 1 minute, then turns off for 1 hour, then on again for 1 min, and so on, in a loop.

I just modified the blink sketch to do:

1. Turn `A1` on
2. Then delay for 60,000 ms
3. Then turn `A1` off
4. Then delay for 3,600,000 ms (3,600 sec, or 1 hour)

...but it doesn't seem to work.

It looks like the LED connected to `A0` turns on but instead of turning off after 1 min, it turns off after 8 min 30 s.

Any suggestions?

---

I rectified the sketch. Now it takes 1 sec as actual 1 sec. I chose 1 MHz clock in IDE.

```
int ledPin =  A3; // the number of the LED pin
int ledState = HIGH; // ledState used to set the LED
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long OnTime = 60000; // milliseconds of on-time
unsigned long OffTime = 10000; // milliseconds of off-time

void setup()
{
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();

  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis; // Remember the time
    digitalWrite(ledPin, ledState); // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis; // Remember the time
    digitalWrite(ledPin, ledState); // Update the actual LED
  }
}

```

Then it turns on for 1 sec and then turns off for 1 sec, then randomly turns on at 30 sec or 1 min 30 sec. I want to turn it on for 1 min every hour.

**I tried the Blink sketch modified as follows:**

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

void loop() {
  digitalWrite(A3, HIGH);
  delay(60000);
  digitalWrite(A3, LOW);
  delay(900000);
}

```

But it still turns on for 1 min and turns off for 1 min.

I also tried this:

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

void loop() {
  digitalWrite(A3, HIGH);
  delay(60000);
  digitalWrite(A3, LOW);
  delay(3.6e+6);
}

```

No matter what I do on time and off time, it always remains the same.

I wanted to know one thing: can I set a 1-hour off and 1-min on timer using ATtiny13A or not?

I tried 1.2 MHz, 1 MHz, all clocks in the IDE, nothing seems to work.

# Answer
As the unchanged blink sketch blinks with 8.4 seconds, I think my assumption is right. The clock of the Attiny is running 8 times slower, than the code thinks.

When you have installed the Attiny core, there should be a menu entry for the clock frequency. Most likely the standard is 8MHz. But having 8MHz set does not mean, that the Attiny is using 8MHz. To choose between different clock sources and frequencies, you must change the fuses of the microcontroller (which are just some bits of special non-volatile memory in the chip, that set special hardware configuration; more information in this question). This is done, when you burn the bootloader to the chip. That's the easy version. Alternatively you can use the `avrdude` command directly to set the fuses. That's the advanced way.

Currently the fuses of your Attiny seem to be set to the 1MHz internal clock. But the compiler uses the frequency, that you have chosen in the menu, hence 8MHz internal clock. So the compiler thinks, that the chip runs at 8MHz and thus generates the timing code for this execution speed. But your chip is currently 8 times slower, than the compiler thinks.

**TL;DR:** Burn the bootloader onto the chip to let the Arduino IDE set the right fuses for your clock frequency.
> 2 votes

# Answer
The code you wrote should work as expected. If it doesn't, I suspect there is something broken in the Arduino core you are using. However, such a trivial task can very easily be programmed in plain C, at the avr-libc level:

```
#define F_CPU 1000000  // 1 MHz
#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB |= _BV(PB3);  // PB3 as output
    for (;;) {
        PORTB |= _BV(PB3);   // PB3 high
        _delay_ms(60e3);     // 1 min
        PORTB &= ~_BV(PB3);  // PB3 low
        _delay_ms(3.6e6);    // 1 h
    }
}

```

I would compile it with:

```
avr-gcc -mmcu=attiny13a -Os -Wall -Wextra 1h-timer.c -o 1h-timer.elf

```

See the Port Registers Arduino tutorial for the meaning of the macros used here. You can tweak `F_CPU` to fine-tune the delays, in case your ATtiny clock is not quite 1 MHz.
> 0 votes

# Answer
Attiny13 has very as in very small memory. So if you want it to crunch stuff which seems to be easy for other mcu, it might not have enough memory for it. It cannot for example consistently carry out millis() like in:

long timeStart = millis(); . . . if (timeIsUp=0 && millis()-timeStart=\>60000) . . .

The most that that code will loop is less than 50 seconds in my experience.

As a workaround I was able to make attiny13 keep track of time for more than 10 minutes by using only integers and using count. The count being incremented after 10seconds. So example:

for (int i=0; i\>10; i++){ delay(10000); count++;

Then you can use count to keep track of time that has elapsed.

Using millis() is very heavy for attiny13.
> 0 votes

---
Tags: arduino-ide, time, attiny13
---


title: How to debug MIDI input?

text:
# Question
Title: How to debug MIDI input?
I'm trying to receive MIDI messages on a Leonardo. To do that I used the circuit in the diagram below (only the top half for receiving). The only thing I did differently was using an 1N4148 diode instead of the 1N914. I connected GND to pin GND, 5V to pin 5V and RX to pin 0 (RX), and I used code below to see whether I do get any inputs or not. (I first started with some more complex code but it seems this is the minimal thing I can do.) As a MIDI source I used an Arturia Keystep which I tested on a midi instrument.

Unfortunately I don't get any input, and I don't know why. What I tried so far:

* Verified the polarity of all cables, and made sure all connections work.
* Swapped the Leonardo with a different one (both new).
* Swapped out the 6N137 optocoupler with another one (both new).
* Addded above the `if`-statement a `Serial.println("test");` which then resulted in an endless avalanche of "test" in the serial monitor - just to check if the USB connection works.
* Measured the voltage between pin 5 and 8 on the 6N137 and it is indeed 5V.

Is there anything obvious I'm doing wrong? What things do you suggest doing to try to find the bug? (I do have a multimeter but no oscilloscope.)

(from this answer).

```
byte b;
void setup() {
  Serial.begin(9600); //USB
  Serial1.begin(31250); //MIDI
}

void loop() {
  if (Serial1.available() > 0) {
    b = Serial1.read();
    Serial.println((int)b);
  }
}

```

# Answer
The solution:
On the image is stated plugs are solder-side. So swapping pin 2/3 does the trick
> 2 votes

# Answer
I think problem is in baudrate of your USB, message from usb is slow and this destroy MIDI message (timing of 31250 baudrate). Set little bit faster USB serial speed. And make buffer between.

Is only try, i dont know if its solve this problem.
> 0 votes

---
Tags: serial, arduino-leonardo, midi, opto-isolator
---


title: Arduino Uno error resp=0x27

text:
# Question
Title: Arduino Uno error resp=0x27
I use the Chinese copy of board. My code is right, but when i upload to board, it print me this:

```
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x27
Failed uploading: uploading error: exit status 1

```

Do you know, what is it?

# Answer
It could be a number of things that we haven't enough information to diagnose. But 'not responding' is quite likely the result of the wrong- or no port or board being selected, or failure of the connection to your computer, or failure of your operating system to recognize the board.
Editing more information into your question would help: What board & chip (is it an Uno clone?), your OS, whether your board was or wasn't recognized by the OS (Windows) or the IDE (macOS), whether you've installed a CH340 or other alternative USB driver if your board requires it (most Chinese Uno clones require some version of the CH340 driver; macOS usually has it built in; Windows usually doesn't). Do some more digging and flesh out your question a lot more - you'll be able to get much better help. And you may not even need it by then!
> -1 votes

---
Tags: arduino-uno, error
---


# Question
Title: Declaration of global variables in separate file: compiler conflict
So I have:

1/ My `myapp.ino` file, that includes `src.h` (implemented in `src.cpp`). Compiled for Arduino Uno.

2/ I also have a `unit-tests.cpp` file that is meant to test functions in `src.cpp`. Compiled for desktop/MacOS.

I don't understand where to declare global variables. They have to be accessed by those three files (I know it's not 100% good practice but it's a simple app).

Simplified example: `src.h`

```
#ifndef CHAOS_SRC_H
#define CHAOS_SRC_H

extern float min_delta;
extern float max_delta;
extern float min_val;
extern float max_val;
extern float rescale_power;

#endif

```

`src.cpp`

```
#include "src.h"

//float min_delta;
//float max_delta;
//float min_val;
//float max_val;
float rescale_power;

```

`myapp.ino`

```
#include "src.h"

float presets[4][5] =  {
  // MIN_DELTA, MAX_DELTA, MIN_VAL, MAX_VAL
  {0, 500, 0, 30, 1}, // Old tape
  {200, 2000, 0, 255, 1}, // Broken tape
  {0, 500, 90, 100, 3}, // New broken tape (delay time at ~ min)
  {0, 100, 90, 140, 3}, //
};

float min_delta = presets[PRESET][0];
float max_delta = presets[PRESET][1];
float min_val = presets[PRESET][2];
float max_val = presets[PRESET][3];
float rescale_power = presets[PRESET][4];

```

`unit-tests.cpp`

```
#include "src.h"

int main()
{
}

```

When I compile `myapp.ino` for Arduino, the compiler complains `rescale_power` has multiple definitions. So I remove it in `src.cpp` and it works.

But then, when I compile `unit-tests.cpp` for desktop, that one compiler complains about `Undefined symbols for architecture x86_64: "_rescale_power"`. Re-adding it solves it. And so on.

What is the way to go please? Any kind of logic?

# Answer
> 3 votes
When you have a header/implementation pair of files, the general rule is that the implementation *defines* everything that the header *declares*. Thus, you keep the definition of `rescale_power` in src.cpp. Since every variable should be defined only once, you have to remove the definition from myapp.ino.

If for some reason src.cpp cannot know the initial value you would want to give to `rescale_power`, then live it default-initialized, and assign the value you want in myapp.ino:

```
void setup() {
    rescale_power = presets[PRESET][4];
}

```

---

**Edit**: In a comment, you wrote:

> I don't get why I can't put `rescale_power = 4` in `myapp.ino` outside a function ?

Because it's an assignment. Assignments are statements: they are executed at run time, and can only be written within functions. For reference, here are the syntaxes for a declaration, a definition and an assignment:

```
// Declaration:
extern float rescale_power;

// Definitions:
float rescale_power;      // implicitly zero-initialized
float rescale_power = 2;  // with explicit initialization

// Assignment:
rescale_power = 4;

```

---
Tags: c, variables, cpp
---


# Question
Title: ESP8266 - Where to find pin assignment guide for uploading code?
I try to upload a script which starts a webserver on the ESP8266 with a simple web GUI where the user can enter his WLAN credentials.

```
/*  ============================================================================================================

    Sample code to create a setup web portal using a soft access point on an ESP8266.

    For more info, please watch my video at https://youtu.be/1VW-z4ibMXI

    MrDIY.ca

============================================================================================================== */

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
ESP8266WebServer    server(80);

struct settings {
  char ssid[30];
  char password[30];
} user_wifi = {};

void setup() {

  EEPROM.begin(sizeof(struct settings) );
  EEPROM.get( 0, user_wifi );

  WiFi.mode(WIFI_STA);
  WiFi.begin(user_wifi.ssid, user_wifi.password);

  byte tries = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    if (tries++ > 30) {
      WiFi.mode(WIFI_AP);
      WiFi.softAP("Setup Portal", "mrdiy.ca");
      break;
    }
  }
  server.on("/",  handlePortal);
  server.begin();
}

void loop() {

  server.handleClient();
}

void handlePortal() {

  if (server.method() == HTTP_POST) {

    strncpy(user_wifi.ssid,     server.arg("ssid").c_str(),     sizeof(user_wifi.ssid) );
    strncpy(user_wifi.password, server.arg("password").c_str(), sizeof(user_wifi.password) );
    user_wifi.ssid[server.arg("ssid").length()] = user_wifi.password[server.arg("password").length()] = '\0';
    EEPROM.put(0, user_wifi);
    EEPROM.commit();

    server.send(200,   "text/html",  "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title><style>*,::after,::before{box-sizing:border-box;}body{margin:0;font-family:'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans','Liberation Sans';font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#f5f5f5;}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);border:1px solid #ced4da;}button{border:1px solid transparent;color:#fff;background-color:#007bff;border-color:#007bff;padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem;width:100%}.form-signin{width:100%;max-width:400px;padding:15px;margin:auto;}h1,p{text-align: center}</style> </head> <body><main class='form-signin'> <h1>Wifi Setup</h1> <br/> <p>Your settings have been saved successfully!<br />Please restart the device.</p></main></body></html>" );
  } else {

    server.send(200,   "text/html", "<!doctype html><html lang='en'><head><meta charset='utf-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Wifi Setup</title> <style>*,::after,::before{box-sizing:border-box;}body{margin:0;font-family:'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans','Liberation Sans';font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#f5f5f5;}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);border:1px solid #ced4da;}button{cursor: pointer;border:1px solid transparent;color:#fff;background-color:#007bff;border-color:#007bff;padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem;width:100%}.form-signin{width:100%;max-width:400px;padding:15px;margin:auto;}h1{text-align: center}</style> </head> <body><main class='form-signin'> <form action='/' method='post'> <h1 class=''>Wifi Setup</h1><br/><div class='form-floating'><label>SSID</label><input type='text' class='form-control' name='ssid'> </div><div class='form-floating'><br/><label>Password</label><input type='password' class='form-control' name='password'></div><br/><br/><button type='submit'>Save</button><p style='text-align: right'><a href='https://www.mrdiy.ca' style='color: #32C5FF'>mrdiy.ca</a></p></form></main> </body></html>" );
  }
}

```

I try to figure out how I need to connect the ESP8266 WLAN module with my Arduino Uno in order to be able to upload that script. I've searched the documentation, but I can't find much helpful.

The module has these pins:

```
3V3 | RX
RST | IO0
EN  | IO2
TX  | GND

```

But in the documentation there are other pins which I don't have and the pin **EN** is not even mentioned in the documentation.

I connected it like this (i did not used pull up resistors yet):

```
[ESP8266 -> Arduino Uno]

3V3 -> 3V3 (bread board)
EN  -> 3V3 (bread board)
RX  -> RX
TX  -> TX
GND -> GND

```

The connection works and it responds to AT commands.

But if I try to upload a script, then it fails with:

```
. Variables and constants in RAM (global, static), used 28236 / 80192 bytes (35%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ DATA     1504     initialized variables
╠══ RODATA   1020     constants
╚══ BSS      25712    zeroed variables
. Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 59535 / 65536 bytes (90%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ ICACHE   32768    reserved space for flash instruction cache
╚══ IRAM     26767    code in IRAM
. Code in flash (default, ICACHE_FLASH_ATTR), used 239164 / 1048576 bytes (22%)
║   SEGMENT  BYTES    DESCRIPTION
╚══ IROM     239164   code in flash
esptool.py v3.0
Serial port COM4
Connecting........_____....._____....._____....._____....._____....._____....._____

A fatal esptool.py error occurred: Failed to connect to ESP8266: Invalid head of packet (0xF0)

```

How do I need to connect my module in order to upload code?

I am using this chip. I also tested another chip (i got 4) to check if mine is broken, but I get the same error.

# Answer
The module is built around esp8266ex microcontroller. In order to make it enter into the flash programming mode the following steps must be taken.

1. Put mcu into reset state by pulling reset line low.
2. Pull gpio15 low and gpio0 low while still holding reset low.
3. Release reset, so it will go high and mcu will restart.
4. While starting the mcu will check pin states (gpio15 low=use spi flash 25xx series pre-attached to gpio6-11, gpio0 low=self programming mode, gpio2 is NOT low) and will enter the waiting state in a few milliseconds.
5. Release gpio0 and start data transfer to h/w uart0 (attached to gpio1 and gpio3, aka tx and rx).

So you need to ensure that: gpio0 is pulled up; gpio1 and gpio3 are attached to another host's uart by crossover connection; gpio2 is not low; gpio15 is pulled low; both reset and enable are pulled high; and, of course, you have 3v3 power and ground. Also, you need two push buttons to connect reset and gpio0 to ground temporarily. Then press reset, press gpio0 button, release reset, and, finally, release gpio0. Mcu should now wait for the data to flash. Also, when using esptool you need to tell it to skip auto-reset sequence (`--before no_reset`), as you're doing it manually.

Considering aforementioned pullups, their presence depends on a module you're using. For esp-01s, they all should be already there (except for the two buttons). For esp-01 (without "s"), you'll need to add pull ups for gpio0 and "chip enable" pin yourself.

There's also auto-programming sequence (which is default for esptool) also sometimes referred as "nodemcu reset method" or such. The idea is that the programming software will switch dtr and rts UART extra signals on and off before data transfer. If you have a small circuit between uart chip and esp8266 mcu that is capable to translate dtr/rts signals to reset/gpio0 states to make mcu to enter self programming mode then you won't need any push buttons anymore.

Such circuit can be made of only two npn transistors and two resistors and is searched online easily. Some boards (including nodemcu, of course) may have such circuit along with usb-ttl converter, dc-dc buck converter and usb plug all on-board. But they are bigger in size and slightly more expensive than esp-01, of course.

Also, for esp-01/esp-01s specifically, you can purchase a prebuilt adapter that provides exactly those missing parts (usb plug, dc buck, two transistor auto-circuit, ttl converter chip, some pullups and female header to plug esp-01 module in). So you can flash your modules using this adapter while sparing some space in your circuit too.

(Hint: the presence of auto programming feature could be guessed from the product photo usually by spotting two sot-23 transistors close to each other).

Or you can buy all these parts and solder such adapter board yourself. This might look a bit too much for a beginner, but, on the other hand, it could make an interesting challenge too.
> 1 votes

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


# Question
Title: How to pass AT commands to Lora from ESP32 UART?
I have connected "Reyax RYLR998" Lora module to ESP32 UART2, but AT commands passed through Hardware serial not working.

```
#define RXD2 16
#define TXD2 17

void setup()
{
    Serial.begin(115200);
    Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);

    Serial.print("\nSetting Lora Module \n");

    Serial2.print("AT+BAND=865000000\r\n");
    if (Serial2.available())
        Serial.println(Serial2.read());
    delay(1000);

    Serial2.print("AT+ADDRESS=1\r\n");
    if (Serial2.available())
        Serial.println(Serial2.read());
    delay(1000);

    Serial2.print((String)"AT+NETWORKID=5\r\n");
    if (Serial2.available())
        Serial.println(Serial2.read());
    delay(1000);
}

void loop()
{
    while (Serial2.available())
    {
        Serial.print(char(Serial2.read()));
    }
}

```

I tried

```
Serial2.print((String)"AT+NETWORKID=5\n");
Serial2.println((String)"AT+NETWORKID=5\r");
Serial2.print((String)"AT+NETWORKID=5\r");

```

Nothing worked, no response from AT command, Please help me I have been working on same problem for 2days.

\[!\[Here all AT commands works well\]\[2\]\]\[2\]

# Answer
> 2 votes
I am new to Lora module and ESP32 and only playing around for a week.

I have successfully sent AT commands to RYLR998 module via ESP32 and received messages via other RYLR998 connected to another computer via USB UART serial. You need use `trim()` before you send your string to `Serial2`.(ryltr998)

```
trim()
[StringObject Function]
Description
Get a version of the String with any leading and trailing whitespace removed. The trim() function modifies the String in place rather than returning a new one.

Syntax
myString.trim()

```

---
Tags: esp8266, arduino-nano, esp32, iot, lora
---


# Question
Title: UART - Different results between logic analyzer and an Arduino
I would like to decode a serial communication.

I have already found out how the protocol works. I can also send serial data with my logic analyzer and control the device this way.

I would like to integrate this function into an Arduino, but my Arduino Mega 2560 throws out completely different serial data than my Logic Analyzer.

The baud rate fits. 230400.

The first byte is 0x42. This is recognized correctly by the Arduino. After that, unfortunately, only gibberish comes out.

Does anyone have any idea how I can approach the problem?

# Answer
> 2 votes
You get the first byte correctly but miss the next bytes because you are busy printing out the first byte instead of receiving the following bytes.

Your code cannot to all that at once, especially if you are using Arduino libraries like that.

This is the upsides and downsides of Arduino, it lets you do simple things easily, but either your requirements already grew out of being simple and suitable for Arduino, or you are using the Arduino libraries without considering what they are capable of and how.

So instead of waiting for first byte and immediately printing it out, it might make more sense to wait and read bytes until you have read some whole packet and have enough time to print the bytes before next byte arrives.

Another thing, how do you even know your Arduino can use 230400 bps rate? If it uses a 16 MHz clock source, you cannot get exacltly 230400 but the closes baud rate is 222222 bps, and that is already a 3.55% error to what you need. Usually the target is better than 1% error, but in a pinch many devices might work within 2% error because in theory it allows both devices to be within 2% of the nominal rate. Having an error of 3.5% is usually too large and very close to the point of not working at all.

Edit: OK, it cannot be a software issue because Arduino UART does use interrupts and uses a ring buffer for buffering data.

What is known is that a 16 MHz AVR cannot exactly hit 230400 bps and will have 3.5% error in the baud rate which exceeds recommendations for maximum baud rate error. What even makes the situation worse is that instead of a more precise crystal, the Arduino Mega2560 uses a ceramic resonator with additional 0.5% tolerance, 0.3% temperature stability, and 0.2% aging. A crystal would have in any case better than 0.01% tolerance for all scenarios. So the most likely cause is that the Arduino Mega2560 can be simply said not to support baud rate of 230400 reliably so that is why it does not work.

And also the Mega256 data sheet says that minimum input high voltage is 0.6\*Vcc, so using a 5V MCU that will be 3.0V minimum, so it will be within specification to receive a 3.3V signal. So the voltage issue is extremely unlikely.

# Answer
> 2 votes
You need to understand the MCU you are using to be able to test and diagnose that the functionality meets your needs.

1. The accuracy of the baud/bit rate has to be considered for EACH serial link. In this case you have the serial link to your external device and the serial link to the Arduino console (a serial to USB converter implemented in an ATMEGA8). Here is a good link to understand the problem of baud/bit rate generation: https://wormfood.net/avrbaudcalc.php

Notice here that you cannot actually set 230.4k because of the rough granularity as UBRR approaches 1. You actually get 250k baud, which is used often for serial addressed DMX peripherals and works well on most Arduino variants. In you case however, this is you first problem, a mismatch between your peripheral bit rate and the Arduino 2560.

2. There will be a difference between the baud/bit rate for your two serial connection since the console serial link is defined in a separate MCU (the ATMEGA8) and they have different crystals. You should examine the schematic for the Arduino Mega 2560 and try to understand the configuration.

Here there is an obvious answer to most of your problem, and that is to eliminate one of the two serial connections. You already discovered that the Arduino Zero works successfully, you just didn't go on to discover why (and it's not the clock rate for the MCU that is the issue).

In several Arduino variants they have a direct USB peripheral controller built in. Look at the Arduinos that use the ATMEGA32u4 or as you found the more modern variants such as the Arduino Zero. In these variants the console transfer actually happens at USB speeds for the serial transfer, this is a rate fixed at the USB connection state rate.

You should experiment with raising the baud/bit rate on the console higher than the peripheral bit rate you are using, that may solve your immediate problem with the MEGA 2560. I'd suggest you try setting the console to 500k or 1M, this may depend on what your IDE device is (PC or Linux) allows configuration for of course. My suggestion would be to move to an MCU with inbuilt USB.

# Answer
> 0 votes
At that baud rate you have 23Kcps, giving you ~40us for each loop invocation. IIRC the default serial buffer length is 16 characters, and you don't comment on the speed of the serial interface you are using for println() relative to the incoming data rate. It is therefore possible that you might be simply getting behind on the incoming stream.

Your question asks for an approach to diagnosing.

If possible I'd start by changing the input stream to have the same bitrate, but with the characters spaced well apart. See if that works.

If it does, the issue is likely either tied to loop timing and responsiveness, or could be related to the crystal/PLL accuracy at that rate. (If may simply be the clock rate isn't a good match for the baudrate generator, with drift building up after the first character.)

# Answer
> 0 votes
I don't know how else to confirm a solution here. @Abel gave the decisive hint. I measured the voltage of the signal incorrectly.

Edit: I can't accept my own answer as a solution for another 2 days.

---
Tags: uart, serial
---


# Question
Title: class enum was not declared in this scope
I am programming an Arduino. In the same .ino file as `setup()` and `loop()` I have defined the following:

```
void setup()
{
  // setup code
}

enum class CYCLE { TypeA, TypeB };

String cycleToString (CYCLE cycle) {
  if (cycle == CYCLE::TypeA) {
    return "TypeA";
  }
  else if (cycle == CYCLE::TypeB) {
    return "TypeB";
  }
  return "Undefined";
}

void loop()
{
  // loop code
}

```

But on compiling it gives the error:

```
sketch_v1:37:22: error: 'CYCLE' was not declared in this scope
 String cycleToString (CYCLE cycle) {
                      ^
/Users/.../sketch_v1.ino: In function 'String cycleToString(CYCLE)':
sketch_v1:37:31: error: 'String cycleToString(CYCLE)' redeclared as different kind of symbol
 String cycleToString (CYCLE cycle) {
                                  ^
/Users/.../sketch_v1.ino:37:8: note: previous declaration 'String cycleToString'
 String cycleToString (CYCLE cycle) {
        ^

```

Note that the `enum class` is fine and works as intended but if I try to add the function relying on the `CYCLE` type it then errors.

# Answer
This is a known bug of Arduino builder, if you have functions before structs, classes or enums in sketch.

The sketch:

```
void foo() {
}

enum class CYCLE { TypeA, TypeB };

String cycleToString (CYCLE cycle) {
  if (cycle == CYCLE::TypeA) {
    return "TypeA";
  }
  else if (cycle == CYCLE::TypeB) {
    return "TypeB";
  }
  return "Undefined";
}

void setup() {
}

void loop() {
}

```

is processed to this .cpp file

```
#include <Arduino.h>
#line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
#line 1 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"

#line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
void foo();
#line 7 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
String cycleToString(CYCLE cycle);
#line 17 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
void setup();
#line 22 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
void loop();
#line 2 "/tmp/arduino_modified_sketch_327776/sketch_jun23a.ino"
void foo() {
}

enum class CYCLE { TypeA, TypeB };

String cycleToString (CYCLE cycle) {
  if (cycle == CYCLE::TypeA) {
    return "TypeA";
  }
  else if (cycle == CYCLE::TypeB) {
    return "TypeB";
  }
  return "Undefined";
}

void setup() {
}

void loop() {
}

```

as you can see the forward declarations of functions are before the first function so before the enum.

The workaround for this bug is to follow good practice and declare all the structs, enums and classes before the first function definition.
> 13 votes

# Answer
Note this is not an answer, since your code compiles perfectly. (adding a default/empty setup/loop function).

However, I want to give some improvements that cannot fit in a comment:

1. (optional) Align { and } under each other. Some put the { behind the line, some on a new line; this is mostly preference. But aligning { and } is mostly more clear.
2. Put each type/enum value on a new line; this makes it easier to add comments above/after it.
3. Except for trivial cases, never return from a statement, except the last one. In your case the function is quite simple, but still it's better to keep the return only at the end of a function.
4. Use a `switch` statement instead of multiple `if` statements.

So you get:

```
enum class CYCLE
{
  TypeA,
  TypeB
};

String cycleToString (CYCLE cycle)
{
  String str;

  switch (cycle)
  {
  case CYCLE::TypeA:
    str = "TypeA";
    break;

  case CYCLE::TypeB:
    str = "TypeB";
    break;

  default:
    str = "Undefined";
    break;
  }

  return str;
}

```
> 1 votes

# Answer
It works if you move the `enum class` to the top, i.e.:

```
enum class CYCLE { TypeA, TypeB };

void setup()
{
  // setup code
}

String cycleToString (CYCLE cycle) {
  if (cycle == CYCLE::TypeA) {
    return "TypeA";
  }
  else if (cycle == CYCLE::TypeB) {
    return "TypeB";
  }
  return "Undefined";
}

void loop()
{
  // loop code
}

```
> -1 votes

# Answer
I found workaround on Arduino forums: **Put your enums in separate file** (I use `enums.hpp`), and include it from the main sketch file (`.ino`) like `#include "enums.hpp"`.
> -1 votes

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


# Question
Title: Why are the UART ports not working on my Portenta breakout board?
I am using a Portenta Arduino Breakout Board that is connected to the Portenta H7 for a project I am working on. The project requires me to use three Adafruit Ultimate GPS sensors and connect each to its own UART ports on the Portenta breakout board. I am only using UART0, UART1, and UART2 (which are respectively Serial, Serial1, and Serial2).

To be able to get data, I've been using this example code from the Arduino IDE:

```
// Test code for Ultimate GPS Using Hardware Serial
// (e.g. GPS for Leonardo, Flora or FeatherWing)
//
// This code shows how to test a passthru between USB and hardware serial
//
// Tested and works great with the Adafruit GPS FeatherWing
// ------> https://www.adafruit.com/products/3133
// or Flora GPS
// ------> https://www.adafruit.com/products/1059
// but also works with the shield, breakout
// ------> https://www.adafruit.com/products/1272
// ------> https://www.adafruit.com/products/746
//
// Pick one up today at the Adafruit electronics shop
// and help support open source hardware & software! -ada

// what's the name of the hardware serial port?
#define GPSSerial Serial1

void setup() {
  // make this baud rate fast enough to we aren't waiting on it
  Serial.begin(115200);

  // wait for hardware serial to appear
  while (!Serial) delay(10);

  // 9600 baud is the default rate for the Ultimate GPS
  GPSSerial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    char c = Serial.read();
    GPSSerial.write(c);
  }
  if (GPSSerial.available()) {
    char c = GPSSerial.read();
    Serial.write(c);
  }
}

```

This code works for Serial1, and I get data when I connect a GPS to the UART1 port of breakout board. When I call for Serial, or Serial2, changing `#define GPSSerial Serial1` to `#define GPSSerial Serial` or `#define GPSSerial Serial2` the code will upload with no errors, but I am not receiving any data from the GPS when it is connected to the respective UART port (UART0 and UART2).

I checked to see if the data is automatically only coming from UART1 port but it will not show anything when I am calling for Serial or Serial2, which should be expected.

Does anyone know how to deal with this issue? Could UART0 and UART2 ports not be transferring data to the Portenta H7 board which could be why I am not seeing any data?

Please let me know if I should clarify anything.

# Answer
> 2 votes
I just spent a day tracking down this same issue. The cause is that Arduino made an absolute mess of the naming conventions for these UART ports. Please see the table below. I created this table from the Portenta Schematic and the Breakout board Schematic.

| Breakout Schematic | P. Schematic @ J1,J2 | P. Schematic @ Micro | Micro Pin (tx,rx) | pins\_arduino.h |
| --- | --- | --- | --- | --- |
| UART0 | Serial2 | UART4 | (PA0,PI9) | not defined |
| UART1 | Serial1 | LPUart | (PA9,PA10) | Maybe Serial 1? |
| UART2 | Serial3 | UART6 | (PG14,PG9) | not defined |
| UART3 | Serial4 | UART8 | (PJ8,PJ9) | Serial 3 |

Unfortunately as you can see, the built in serial definitions in pins\_arduino.h are not going to work for the breakout board. (unless you use Serial 1 or Serial 3)

If you want to use these other serial ports, you need to define your own serial ports which actually isn't that hard. You just have to manually specify the pins and you're off.

```
#include "Serial.h"
UART UART0Breakout = UART(PA_0, PI_9);
UART UART2Breakout = UART(PG_14, PG_9);
void setup()
{
    UART0Breakout.begin(115200);
    UART2Breakout.begin(115200);
}

```

Hope this helps you! It certainly drove me mad for a while. Unfortunately the schematic I used for the breakout board was not nearly as nicely annotated as the one I linked here (I found it while writing this answer).

---
Tags: arduino-uno, serial, uart
---


title: Test for wrong Wifi password?

text:
# Question
Title: Test for wrong Wifi password?
Maybe this is a dumb question, but is there a way to test for wrong Wifi password?

I know you can do WL\_CONNECT to check if the password works, but is there a command for checking if the password is wrong? Not just by waiting.

# Answer
> 3 votes
The information is available on SDK level. If you include `#include "user_interface.h"`, you can use function `wifi_station_get_connect_status()`. It returns one of:

```
STATION_GOT_IP
STATION_NO_AP_FOUND
STATION_CONNECT_FAIL
STATION_WRONG_PASSWORD
STATION_IDLE

```

The `WiFi.status()` function uses function `wifi_station_get_connect_status()`, but returns WL\_CONNECT\_FAILED for STATION\_WRONG\_PASSWORD.

# Answer
> 0 votes
one can check for wrong password using the following code snippet

```
  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("Connected successfully");
  }
  else if (WiFi.status() == WL_NO_SSID_AVAIL)
  {
    Serial.println("Wifi network is not avaliable");
  }
  else
  {
    Serial.println("Password is not correct");
  }

```

more information can be found on GitHub here: https://github.com/aeonSolutions/aeonlabs-ESP32-C-Base-Firmware-Libraries

---
Tags: arduino-ide, wifi, esp32
---