# Question
Title: Programming barebones ATMega328 with external programmer and no bootloader
I have created a circuit with a barebones ATMega328. I also have an external programmer (Sparkfun's Pocket AVR Programmer)...

Now I want to program a particular sketch... When uploading a sketch, do i also have to flash the bootloader beforehand?

Or is it possible to upload the sketch directly to the microcontroller without a bootloader?

# Answer
> 2 votes
The Pocket AVR Programmer is just a standard ISP programmer, meaning it uses the ISP protocol built into the hardware of the microcontroller to write data to flash and EEPROM. That is also the way, that the bootloader got onto the microcontroller in the first place.

The bootloader of the Arduino on the other hand is a small program to communicate over Serial (or USB depending on the Arduino board) and then write the data to flash and EEPROM.

So: **No, you don't need the bootloader, if you want to use the ISP programmer.** Select your programmer in the corresponding menu of the Arduino IDE to use it.

Though keep in mind, that you won't be able to upload a new sketch via Serial/USB without the bootloader. You can always use the ISP programmer to again write the bootloader to the microcontroller.

---
Tags: programming, spi, bootloader, isp
---


# Question
Title: MD5 of File doesnot match data in flash Error with ESP32 S3
I am getting the `fatal error MD5 of file not match data in flash`. Below is the output of upload.

```
[1/5] cmd.exe /C "cd /D D:\Users\INOMETRICS\espressif\workspace\blink\build\esp-idf\esptool_py && python D:/Espressif/frameworks/esp-idf-v4.4/components/partition_table/check_sizes.py --offset 0x8000 partition --type app D:/Users/INOMETRICS/espressif/workspace/blink/build/partition_table/partition-table.bin D:/Users/INOMETRICS/espressif/workspace/blink/build/blink.bin"
blink.bin binary size 0x31340 bytes. Smallest app partition is 0x100000 bytes. 0xcecc0 bytes (81%) free.
[2/5] Performing build step for 'bootloader'
[1/1] cmd.exe /C "cd /D D:\Users\INOMETRICS\espressif\workspace\blink\build\bootloader\esp-idf\esptool_py && python D:/Espressif/frameworks/esp-idf-v4.4/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x0 D:/Users/INOMETRICS/espressif/workspace/blink/build/bootloader/bootloader.bin"
Bootloader binary size 0x5180 bytes. 0x2e80 bytes (36%) free.
[2/3] cmd.exe /C "cd /D D:\Espressif\frameworks\esp-idf-v4.4\components\esptool_py && D:\Espressif\tools\cmake\3.20.3\bin\cmake.exe -D IDF_PATH="D:/Espressif/frameworks/esp-idf-v4.4" -D SERIAL_TOOL="python D:/Espressif/frameworks/esp-idf-v4.4/components/esptool_py/esptool/esptool.py --chip esp32s3" -D SERIAL_TOOL_ARGS="--before=default_reset --after=hard_reset write_flash @flash_args" -D WORKING_DIRECTORY="D:/Users/INOMETRICS/espressif/workspace/blink/build" -P D:/Espressif/frameworks/esp-idf-v4.4/components/esptool_py/run_serial_tool.cmake"
esptool.py esp32s3 -p COM8 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 80m --flash_size 2MB 0x0 bootloader/bootloader.bin 0x10000 blink.bin 0x8000 partition_table/partition-table.bin
esptool.py v3.2-dev
Serial port COM8
Connecting...
Chip is ESP32-S3
Features: WiFi, BLE
Crystal is 40MHz
MAC: 70:04:1d:be:ab:74
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x00005fff...
Flash will be erased from 0x00010000 to 0x00041fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 20864 bytes to 13002...
Writing at 0x00000000... (100 %)
Wrote 20864 bytes (13002 compressed) at 0x00000000 in 0.1 seconds (effective 1284.4 kbit/s)...
File  md5: 1d4bc050825217f8434a2cfd167894cd
Flash md5: 1b32e380d00eb036ce18a632dedbe04d
MD5 of 0xFF is b145c0e952abec491d69c8c5f8ac47c4

A fatal error occurred: MD5 of file does not match data in flash!
CMake Error at run_serial_tool.cmake:56 (message):
  python
  D:/Espressif/frameworks/esp-idf-v4.4/components/esptool_py/esptool/esptool.py
  --chip esp32s3 failed

```

I am getting the same error while uploading with esp-idf and Arduino ide or platformio.

How could i solve the issue.

Regards

# Answer
> 2 votes
Yes, I have managed to get it working now, the issue encountered was with the strapping pins. Specifically, Pin 45 of ESP32S3 is responsible for configuring VDD\_SPI\_FLASH. To ensure it operates at 3.3V, the pin should be connected to the ground. Otherwise, it will function at 1.8V, which might cause problems with the Flash functionality.

Fortunately, this can also be resolved by burning some EFUSES using the espefuse.py tool, which comes along with esptool.py. All you need to do is run the command: `espefuse.py set_flash_voltage <voltage>` (where voltage can be either 3.3V or 1.8V or OFF). For more details, you can visit: link to the official documentation.

---
Tags: arduino-ide, esp32, espressif
---


title: Push button issues

text:
# Question
Title: Push button issues
I have been using https://wokwi.com/ to learn Arduino and I am having a problem that seems to be happening no matter what I do. I am trying to set up a push button and an LED. The end goal here is to set it up so that when I tap the push button down and release it that the LED blinks like a turn signal in a car. When I push it down and release it again, the LED should stop blinking. I have tried tons of different code, even using code copied and pasted directly from Arduino's website. What ends up happening is that the button is unreliable. Sometimes the button will click, other times it won't register. It is very bizarre behavior. I read about the bouncing effect but any code I put in to ignore bouncing doesn't seem to have any effect on the system. Why are push buttons so unreliable? I know in real life they aren't because I am able to type this using presumably push buttons on my keyboard. What am I doing wrong??

Here is an example. The push button is totally unpredictable. Why is it behaving like this?

```
int state = 0;

void setup()
{
  pinMode(9, OUTPUT);
  pinMode(6, INPUT);
}

void loop()
{
  if (digitalRead(6)) {
    state = !state;
  }
  digitalWrite(9, state);
}

```

# Answer
You've got the button wired wrong. Your resistor is inline with the signal going to the pin. It should be going from the pin to 5V. The button should be wired directly to the pin and ground. Or you can use INPUT\_PULLUP in pinMode instead of INPUT and eliminate the resistor entirely.

Your code should test for the button pin being LOW, not HIGH. When you press the button it will read LOW. When unpressed it will read HIGH. This is the normal way that buttons are wired up.

Also note that your loop() function will repeat thousands of times per second. As long as you still have your finger on the button it will keep cycling the state. That means that every time you press the button, the state gets cycled a few tens of thousands of times and there's no real way of knowing which state it will be on when you finally get your finger off the button.

You should look at the "State Change Example" in the Arduino IDE. It shows how to keep track of the previous state of the button so you can react once to each press.
> 5 votes

---
Tags: sensors, led, button, resistor
---


# Question
Title: NodeMcu V3 & BMe280 -> Temperature, Humidity, Pressure: value nan
I've just started playing around with a NodeMcu V3 and a BME280 sensor.

wiring

```
VCC -> 3.3V
GND -> GND
SCL -> D1 (GPIO5)
SDA -> D2 (GPIO4)

```

I've tried this sketch / I2C scanner: it finds the BME280 at 0x76

```
#include <Wire.h>

// Set I2C bus to use: Wire, Wire1, etc.
#define WIRE Wire

void setup() {
  WIRE.begin();

  Serial.begin(9600);
  while (!Serial)
     delay(10);
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    WIRE.beginTransmission(address);
    error = WIRE.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

```

Then I've tried library BMx280I2C into this sketch:

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

BMx280I2C bmx280(0x76);

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

  // Setup BMx280
  Wire.begin();
  bmx280.begin();
  bmx280.resetToDefaults();
  bmx280.writeOversamplingPressure(BMx280I2C::OSRS_P_x16);
  bmx280.writeOversamplingTemperature(BMx280I2C::OSRS_T_x16);
  bmx280.writeOversamplingHumidity(BMx280I2C::OSRS_H_x16);

}

void loop() {

  // T,P,H measurements
  bmx280.measure();

  do{
    delay(100);
    Serial.println("No value, yet!");
  } while (!bmx280.hasValue());

  Serial.print("Pressure ");
  Serial.println(bmx280.getPressure());

  Serial.print("Temperature ");
  Serial.println(bmx280.getTemperature());

  Serial.print("Humidity ");
  Serial.println(bmx280.getHumidity());

  delay(1000);

}

```

the output is always and only:

> ```
> -> No value, yet!
> -> Pressure nan
> -> Temperature nan
> -> Humidity nan
>
> ```

Why? How can I understand the origin of the problem?Thanks!

# Answer
> 0 votes
Solved with Adafruit library

```
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme;

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

  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void loop() {
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");

  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");

  Serial.print("Pressure = ");
  Serial.print(bme.readPressure() / 100.0F);
  Serial.println(" hPa");

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.println();

  delay(2000);
}

```

---
Tags: esp8266, sensors, nodemcu, temperature-sensor
---


# Question
Title: How does actually arduino measure voltage?
I am not interested into the AnalogRead() part, but rather on how he converts 5 or 2 V into a number between 0 and 1023. How does it practically do it to convert the voltage level into a number or into bits to then send to the processor? Thanks in advance

# Answer
The ATmega328P features a 10-bit successive approximation ADC. The ADC is connected to an 8-channel Analog Multiplexer.

First, an input is selected from the multiplexer on the left. This allows any of 8 input channels to be active at one time (but only one). These are: A0 to A5 on the Uno (some boards also have A6 and A7). There are also additional input channels (not shown) which also allows the selection of:

* The internal temperature sensor
* Ground
* Bandgap reference voltage

The input channel (multiplexer output) is connected to a "sample and hold" capacitor, as shown. Once an analog conversion starts the switch is opened after 1.5 ADC cycles (12 µs with the default prescaler of 128) so that the capacitor retains its current reading (ie. it holds it) so that the input voltage can now change without affecting the result. This would be useful for fast-changing signals, as the whole conversion can take 104 µs (depending on the prescaler).

To work out the voltage the logic applies the analog reference voltage (ARef) divided down by a DAC (digital-to-analog converter) under the control of the ADC logic. The output of the DAC is sent to the comparator which determines if the input voltage is higher or lower than the reference voltage, at its current divided state. For example, the high-order bit would be set or cleared by setting the DAC to divide the reference voltage by 2 (ie. 2.5V if ARef is 5V). If the input is higher than 2.5V then the high-order bit in the result is set. This takes one ADC cycle (8 µs at the default prescaler of 128 with a 16 MHz processor clock).

To get the next result bit the DAC would be set to the next step (ie. 0.25 of ARef or 0.75 of ARef depending on whether the first bit was set or not) and another comparison done. This process is repeated for all 10 bits.
> 2 votes

# Answer
The Arduino Uno is powered by an ATmega328P microcontroller. According to the datasheet:

> The ATmega48A/PA/88A/PA/168A/PA/328/P features a 10-bit successive approximation ADC.

On the next page, you can see the following schematic, where I have highlighted the most essential parts of the converter. You can see the DAC, the comparator, and the SAR data register.

If you want to get into the details of how this works, see the Wikipedia article on Successive-approximation ADC. You may notice the schematic at the top of that Wikipedia page is somewhat similar to the one above.
> 1 votes

---
Tags: arduino-uno, analogread, electronics, analog
---


# Question
Title: How EEMEM maps the variables? (avr/eeprom.h)
I can store and restore my data with avr/eeprom.h if I don't change the sketch.

1. I have a sketch that stores the data. After power cycle of the device the data are fine.
2. If I change the sketch with Serial.print statements (I want to re-read the data on-screen) the sketch seeks the data in wrong addresses of EEPROM, although I can verify with another sketch that the data are fine.

More detailed: I store around 50 bytes, but I verified the location for only the 4 bytes variable. I can see that this variable is at the start of the EEPROM (address: 0). But the second sketch seeks the data on address 30. Not even close.

To my understanding avr/eeprom.h is more easy to use since you don't need to police the location of data. But it seems that if change (what?) in your sketch it seeks the data on other locations although on eeprom are fine.

In other words, it's like if I change the firmware (not the EEMEM variables / definitions!), that firmware seeks the data on different places.

I understood something wrong?

In my situation is better to use the arduino EEPROM.h with static location of EEPROM addresses?

Fun fact. Google Bard seems it got it completely wrong:

> What are the differences of avr/eeprom.h and EEPROM.h from arduino?

(Google Bard Answer)

> The avr/eeprom.h and EEPROM.h libraries in Arduino are both used to access the EEPROM memory on AVR microcontrollers. However, there are some key differences between the two libraries. avr/eeprom.h is a lower-level library that provides direct access to the EEPROM registers. This means that it can be used to access any location in the EEPROM, but it also requires more code and can be more error-prone. EEPROM.h is a higher-level library that provides a more user-friendly interface to the EEPROM. It only allows you to access addresses that are within the range of the EEPROM, but it is easier to use and less error-prone. In general, avr/eeprom.h should only be used if you need to access specific locations in the EEPROM that are not within the range of EEPROM.h. Otherwise, EEPROM.h is the preferred library to use.

Edit: avr-objdump of eeprom section

| Prints on Sketch | Without prints | Prints both on Library and Sketch |
| --- | --- | --- |
| 00810000 \<eeprom\_lw\_dev\_nonce\>: | 00810000 \<eeprom\_lw\_f\_nwk\_s\_int\_key\>: | 00810000 \<eeprom\_lw\_dev\_addr\>: |
| 00810002 \<eeprom\_lw\_f\_nwk\_s\_int\_key\>: | 00810010 \<eeprom\_lw\_s\_nwk\_s\_int\_key\>: | 00810004 \<eeprom\_lw\_dev\_nonce\>: |
| 00810012 \<eeprom\_lw\_s\_nwk\_s\_int\_key\>: | 00810020 \<eeprom\_lw\_has\_joined\>: | 00810006 \<eeprom\_lw\_f\_nwk\_s\_int\_key\>: |
| 00810022 \<eeprom\_lw\_join\_nonce\>: | 00810021 \<eeprom\_lw\_dev\_nonce\>: | 00810016 \<eeprom\_lw\_s\_nwk\_s\_int\_key\>: |
| 00810026 \<eeprom\_lw\_has\_joined\>: | 00810023 \<eeprom\_lw\_join\_nonce\>: | 00810026 \<eeprom\_lw\_nwk\_s\_enc\_key\>: |
| 00810027 \<eeprom\_lw\_tx\_frame\_counter\>: | 00810027 \<eeprom\_lw\_tx\_frame\_counter\>: | 00810036 \<eeprom\_lw\_app\_s\_key\>: |
| 00810029 \<eeprom\_lw\_rx\_frame\_counter\>: | 00810029 \<eeprom\_lw\_nwk\_s\_enc\_key\>: | 00810046 \<eeprom\_lw\_has\_joined\>: |
| 0081002b \<eeprom\_lw\_nwk\_s\_enc\_key\>: | 00810039 \<eeprom\_lw\_rx\_frame\_counter\>: | 00810047 \<eeprom\_lw\_rx\_frame\_counter\>: |
| 0081003b \<eeprom\_lw\_app\_s\_key\>: | 0081003b \<eeprom\_lw\_app\_s\_key\>: | 00810049 \<eeprom\_lw\_tx\_frame\_counter\>: |
| 0081004b \<eeprom\_lw\_dev\_addr\>: | 0081004b \<eeprom\_lw\_dev\_addr\>: | 0081004b \<eeprom\_lw\_rx2\_data\_rate\>: |
| 0081004f \<eeprom\_lw\_rx2\_data\_rate\>: | 0081004f \<eeprom\_lw\_rx1\_delay\>: | 0081004c \<eeprom\_lw\_rx1\_data\_rate\_offset\>: |
| 00810050 \<eeprom\_lw\_rx1\_data\_rate\_offset\>: | 00810050 \<eeprom\_lw\_rx2\_data\_rate\>: | 0081004d \<eeprom\_lw\_join\_nonce\>: |
| 00810051 \<eeprom\_lw\_rx1\_delay\>: | 00810051 \<eeprom\_lw\_rx1\_data\_rate\_offset\>: | 00810051 \<eeprom\_lw\_rx1\_delay\>: |

Image kept for historical reasons.

1st window: Serial.print(s) only in sketch. 2nd window: without Serial.print(s) 3rd window: Serial.print(s) both on sketch and library.

# Answer
> 1 votes
I managed to reproduce your issue with the simple sketch below:

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

EEMEM uint8_t int8_ee;
EEMEM uint16_t int16_ee;
EEMEM uint32_t int32_ee;
EEMEM char str_ee[40];

void show(const char *name, void *address)
{
    Serial.print(name);
    Serial.print(": ");
    Serial.println((uint16_t) address);
}

void setup() {
    Serial.begin(9600);
    show("int8_ee", &int8_ee);
#ifdef SWAP_PRINTING_VARS
    show("int32_ee", &int32_ee);
    show("int16_ee", &int16_ee);
#else
    show("int16_ee", &int16_ee);
    show("int32_ee", &int32_ee);
#endif
    show("str_ee", str_ee);
}

void loop(){}

```

As is, it prints:

```
int8_ee: 46
int16_ee: 44
int32_ee: 40
str_ee: 0

```

If I `#define SWAP_PRINTING_VARS`, it prints instead:

```
int8_ee: 46
int32_ee: 42
int16_ee: 40
str_ee: 0

```

I have no proper answer to your question. Although one may try to unveil the linker's reasoning, I believe it is safer to just assume that the way these variables are allocated is unpredictable, and unstable between subsequent versions of the program.

For your specific issue, I suggest you allocate *only one* variable to EEMEM: put everything you need in a single `struct`, and allocate that as a whole. I am quite confident it will always end at address zero. This should be robust against changes in the program provided that, if you ever add extra fields to that `struct`, you add them at the end.

# Answer
> 0 votes
I wouldn't rely on the compiler necessarily allocating variables at any particular memory address, especially after what you posted. You can make a little include file that simplifies reading from/writing to EEPROM, as below:

```
#include <Arduino.h>  // for type definitions
#include <EEPROM.h>

template <typename T> unsigned int EEPROM_writeAnything (int ee, const T& value)
{
    const byte* p = (const byte*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
        EEPROM.write(ee++, *p++);
    return i;
}

template <typename T> unsigned int EEPROM_readAnything (int ee, T& value)
{
    byte* p = (byte*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}

```

Then you can do something like this:

```
int someData;  // declare a local variable

...

EEPROM_readAnything (0, someData);  // read into it, from address zero in EEPROM

...

someData++;
EEPROM_writeAnything (0, someData);  // write it back out, to address zero

```

The library above uses templates to manage any size data, so you can write or write ints, arrays, etc. One possibility would be to make a struct and read/write the whole thing every time. That way you don't need to keep track of offsets (the whole struct could be written to address 0).

---

Here's an example of doing that, using `offsetof` to manage the offsets of individual fields inside your overall struct, the thing that is stored in the EEPROM.

```
#include <EEPROMAnything.h>

const long MAGIC_ID = 'Nick';

// information in EEPROM
typedef struct {
    unsigned long magic;   // to see if we initialised EEPROM
    unsigned long counter;
    char myName [30];
}  myInformation;

void setup() {
  Serial.begin (115200);
  Serial.println ("Starting ...");

  // see if EEPROM initialised

  unsigned long magicTest;
  EEPROM_readAnything (offsetof (myInformation, magic), magicTest);

  if (magicTest != MAGIC_ID)
    {
    Serial.println ("Initialising EEPROM");
    myInformation initStuff;
    initStuff.magic = MAGIC_ID;
    initStuff.counter = 0;
    strcpy (initStuff.myName, "Nick Gammon");
    EEPROM_writeAnything (0, initStuff); // write whole struct
    } // end of if not initialised

  // find counter
  unsigned long myCounter;
  EEPROM_readAnything (offsetof (myInformation, counter), myCounter);
  Serial.print ("Counter is ");
  Serial.println (myCounter);

  // find name
  char hisName [sizeof (myInformation().myName)];
  EEPROM_readAnything (offsetof (myInformation, myName), hisName);
  Serial.print ("Name is ");
  Serial.println (hisName);

  // add to counter
  myCounter++;

  // write counter back
  EEPROM_writeAnything (offsetof (myInformation, counter), myCounter); // write whole struct

  Serial.println ("Done.");

} // end of setup

void loop()
{
  // whatever
}   // end of loop

```

---
Tags: eeprom
---


title: TFT display shows black stripes

text:
# Question
Title: TFT display shows black stripes
I'm new to the field: I'm trying to drive a TFT ST7735S display (this is the model I'm currently using: https://www.amazon.it/dp/B078JBBPXK/ref=pe\_24968671\_487022601\_TE\_SCE\_dp\_1) with an Arduino Mega following this video (https://www.youtube.com/watch?v=iPeukOK6stk&ab\_channel=Artigiano2.0-AlessioRomanelli). Once the hardware is set up and the code is written, when I run the example script "graphictest" of the Adafruit library for st7735 and st7789, the display shows stripes on the background as shown in the picture below:

(Note that the strange effect is not camera's fault)

Reading online I thought that the problem could be the fact that the display is powered with 5V instead of 3.3V, but I've also tried powering it with 3.3V (Arduino Mega 3.3V) with little to no changes. I've changed the `tft.initR(INITR_BLACKTAB);` to `tft.initR(INITR_GREENTAB);` too, as suggested by a user i this thread (https://forum.arduino.cc/t/bugged-1-8-inch-tft-diplay/1012166/5) and i've also tried powering the display with 5V but using 4.7k resistors in series to reduce the voltage as suggested in the same post, but it still doesn't work.

Moreover the strange effect that the image shows does only appear, if I use a 5V supply, just when the program executes the `void setup()` function, then becomes sharp (this does not happen if I power the display using the Arduino Mega 3.3V output supply: in fact in this case the stripes are still present even when entering the `void loop()` function)

As I said before, the program and the hardware setup arethe same as the video I was talking about. One thing I noticed is that, when I press the reset button on the Arduino Mega, an instant before the program is reloaded, the stripes disappear leaving the image as sharp as it should have been, without any strange background effect. Does anyone have any idea on how to solve this issue?

Thank you in advance for any eventual answer!

**EDIT**:

This is the picture of the modified verison of the connections, running the graphictest program with the suggested code:

```
#else
  // For the breakout board, you can use any 2 or 3 pins.
  // These pins will also work for the 1.8" TFT shield.
  #define TFT_CS        10
  //#define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_RST        8 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         9
#endif

```

// OPTION 2 lets you interface the display using ANY TWO or THREE PINS, // tradeoff being that performance is not as fast as hardware SPI above.

```
#define TFT_MOSI 11  // Data out
#define TFT_SCLK 13  // Clock out

// For ST7735-based displays, we will use this call
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

```

Hopefully every connection is visible

# Answer
> 0 votes
Adafruit made that graphictest program for screens that they sell. The screen that you have is not sold by Adafruit and there is no reason why they should support that screen.

Still, you can get it to work, if it is not bricked. After you see enough variants, you get an idea about what you need to get them to work. So, I suggest the following.....

Go here https://www.arthurwiz.com/software-development/177-inch-tft-lcd-display-with-st7735s-on-arduino-mega-2560 and hook up the screen to your mega just exactly as in their table. You will make 8 connections. Download and execute their 'Hello World' program from the tutorial. If that runs ok, then you know that the connections are correct. Note that the constructor is:

Adafruit\_ST7735 tft = Adafruit\_ST7735(TFT\_CS, TFT\_DC, TFT\_MOSI, TFT\_SCLK, TFT\_RST);

Also, don't worry if the screen is not rotated correctly - you can add one line in setup() to fix that:

```
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(1); // <---added
  tft.fillScreen(ST7735_BLACK);

```

Now on to graphictest. Find these lines and change them to how I have them. I left one line commented out to illustrate. You do this to identify which GPIO go with which function. Yes, I could have started here, but going through the first tutorial successfully means you have not bricked the screen and you have the connections correct.

```
#else
  // For the breakout board, you can use any 2 or 3 pins.
  // These pins will also work for the 1.8" TFT shield.
  #define TFT_CS        10
  //#define TFT_RST        9 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_RST        8 // Or set to -1 and connect to Arduino RESET pin
  #define TFT_DC         9
#endif

```

You will use Option 2 and the constructor as stated previously - so

```
// OPTION 2 lets you interface the display using ANY TWO or THREE PINS,
// tradeoff being that performance is not as fast as hardware SPI above.
#define TFT_MOSI 11  // Data out
#define TFT_SCLK 13  // Clock out

// For ST7735-based displays, we will use this call
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);

// Use this initializer if using a 1.8" TFT screen:
  tft.initR(INITR_BLACKTAB);      // Init ST7735S chip, black tab

```

Note that even though my screen still has a green tab, if I use the green tab initializer, I will have offset problems.

Make sure you haven't left any other configuration lines uncommented. I have the same screen and just hooked it up and tested all of this and everything works fine.

Let us know how it goes.

Edited to add:

You do not need to add ANY external resistors. Your Mega has connections for both 3V and 5V and you need to use both voltages.

Your initial pic (see below) shows that both pin 2 and pin 8 are connected to the same +V on the rail of the breadboard. This is incorrect. As shown in the table I linked, Pin 2 on the LCD goes to 5V on the Mega and pin 8 on the LCD goes to 3.3V on the Mega.

# Answer
> 0 votes
I had the exact same issue, and tested the things here but it did not help. Then I pressed the reset button on my UNO with the same result as Luke\__ had (the screen looked nice as long as I pressed the reset). After doing that a few times the display started to work as it should.

Strange, but resolved my issue.

---
Tags: spi, display, tft
---


# Question
Title: My ESP32-S3 DevkitC-1 has two USB micro ports labeled 'USB' and 'UART'. What are they for?
I'm new to micro-controllers. I've got an ESP32-S3-DevKitC-1 and I'm trying to do a simple hello world with the Serial. I'm using the Arduino IDE for flashing and serial monitoring. My code is:

```
/**
 * As simple as it gets, right? Setup the Serial, wait on it. The periodically print during the loop.
 */
void setup() {
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);
}

void loop() {
  Serial.println("Hello World");
  delay(1000);
}

```

I've tried various baud rates. I've also tried a few different configurations for flashing-- this includes flashing over the UART port with upload mode 'UART0/Hardware CDC' and 'USB-OTG CDC (TinyUSB)'. I'm basically at guess and check right now and am looking for some tips or resources to understand the ports. My serial always shows gibberish. I've even tried miniterm like this:

`pyserial-miniterm /dev/cu.usbserial-1410 9600`

# Answer
The USB port connects directly to the D+/D- pins of the ESP32, which allows it to act as a USB host. CircuitPython, for instance, uses this functionality to look like a USB flash drive. You could also write software that might have the ESP32 mimic a keyboard or mouse or other simple USB devices over this port. You generally will not use it to program the board, though CircuitPython does install its own firmware updates from files written to the USB flash drive its boot loader presents.

The UART port connects to a USB/serial chip which is connected to the RX and TX pins of the ESP32. If you want to flash firmware to the board in a traditional way (using esptool.py) you'd use this connector. You may need to press the BOOT button to get the device into firmware download mode.

The ESP32 defaults to 115200 baud, which is why you'd see gibberish at 9600 baud - that would be the boot loader messages.

You'll need to ensure that the firmware you're trying to flash to it is built for the correct model CPU and also for the amount of PSRAM on your board. I would stick with 115200 baud for the serial speed so that you'll be able to see the boot loader messages as well as any output of your program, if it's correctly built and flashed to the board. \[**edit**: as @hcheung pointed out there is no official stable support for the S3 in the Arduino Core at the time this question was asked\]

You can learn more about your device by reading the official Espressif documentation on it.
> 5 votes

# Answer
I had to spent some additional time debugging my smart hardware electronics for a home automation wall mount switch based on the ESP32 S3 ( see it on my GitHub here )

because I was able to upload the firmware code into it however when reading serial output it only displayed "gibberish" characters.

On the internet I could not find the answer, so I had to work harder to find the solution. Common problems found when dealing with serial output errors are:

* poor UART ground
* absence of a 500 Ohm resistor on the TX line
* UART cable to long
* track coupling and track length mismatch

are all hardware issues that cause serial communication errors and malfunctioning. However, for the ESP32 there's one missing on the list above. On this particular hardware, I had incorrectly soldered the RTC crystal of 32,768MHz into the MCU crystal place which is for one of 40MHz. The result was, it is possible to do firmware upload using a 32,768Mhz crystal for the MCU however, and due to the incorrect clock frequency, serial output is no longer 115200bps and displays "gibberish" characters.

**In summary make sure the crystal has the correct clock frequency value**.
> -1 votes

---
Tags: usb, esp32
---


# Question
Title: How to get the scan duration below 1 sec with Arduino BLE?
I want to scan continuously for other Bluetooth devices with my ESP32 using BLE. The `scan` method only accepts integers larger than 0, such as `scan->start(1, false)`. However I want the results to be more "responsive" and a 1-second scanning duration is too long. This is my sample code:

```
#include <Arduino.h>
#include <BLEAdvertisedDevice.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <string>
#include <iostream>

const int PIN = 2;
const int CUTOFF = -40;
BLEScan* scan;

#define SERVICE_UUID "f5aeb701-4395-4387-b8d4-e1f542b05151"
#define CHARACTERISTIC_UUID "b2bd617f-6f78-45e7-bfdd-3edf29a5661a"

void setup() {
  pinMode(PIN, OUTPUT);
  BLEDevice::init("ESP32 GrooveBrick");
  Serial.begin(9600);
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
    CHARACTERISTIC_UUID,
    BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
  pService->start();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  scan = BLEDevice::getScan();
  scan->setActiveScan(true);
  /*!< Scan interval. This is defined as the time interval from
    when the Controller started its last LE scan until it begins the subsequent LE scan.
    Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
    Time = N * 0.625 msec
    Time Range: 2.5 msec to 10.24 seconds*/
  scan->setInterval(100); //interval (how often there is a scan)
  /*!< Scan window. The duration of the LE scan. LE_Scan_Window
    shall be less than or equal to LE_Scan_Interval
    Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
    Time = N * 0.625 msec
    Time Range: 2.5 msec to 10240 msec */
  scan->setWindow(99);  // window (how long the scans are) must be <= interval
  BLEDevice::startAdvertising();
}

void loop() {
  BLEScanResults results = scan->start(1, true);
  int best = CUTOFF;

  std::cout << "Scanning!" << "\n";
  for (int i = 0; i < results.getCount(); i++) {
    BLEAdvertisedDevice device = results.getDevice(i);
    std::cout << "Found BT-device: " << device.getName() << " RSSI: " << std::to_string(device.getRSSI()) << "\n";
    int rssi = device.getRSSI();
    if (rssi > best) {
      best = rssi;
    }
  }
  digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
  scan->clearResults();   // delete results fromBLEScan buffer to release memory
}

```

# Answer
You can't using the callback from that function, but what you can do is add you own callback that will receive every new radio event.

Add this to your init code:

```
BLEDevice::setCustomGapHandler(custom_handler);

```

and this before it:

```
static void it_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event)
    {
        case ESP_GAP_BLE_SCAN_RESULT_EVT:
            if (param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT)
            {
                // This event is triggered every time a new device is found, and contains the advertised data.
                // We should avoid processing or printing anything here to avoid hardware congestion
                // log_i("ESP_GAP_BLE_SCAN_RESULT_EVT");

                if (param->scan_rst.ble_adv != NULL)
                {
                    //this makes sure that there is data to be processed
                }
            }
            break;
        default:
            // log_i("Event %d unhandled", event);
            break;
    }
}

```
> 2 votes

---
Tags: esp32, ble, cpp
---


title: ATtiny85 with sleep and serial

text:
# Question
Title: ATtiny85 with sleep and serial
I want to communicate over serial to another device (dfplayer) and also set the microcontroller into sleep mode.

The ATtiny85 does not have a hardware serial pin so I need to use a virtual serial (like `SoftwareSerial.h`)

I've googled a lot and tried a lot of things but it basically seems to come always to the same problem. `SoftwareSerial` (or `NeoSWSerial`) do not work with `avr/sleep`. Something to do with interrupts,

> NeoSWSerial.cpp.o (symbol from plugin): In function `NeoSWSerial::read()': (.text+0x0): multiple definition of` \__vector\_2' .pio\build\attiny85\src\main.cpp.o (symbol from plugin):(.text+0x0): first defined here

AltSoftSerial won't work because it requires a 16bit timer which the ATtiny does not have\__

Is there anything I can do about this?

---

What I actually want to do

Connect 6 buttons with 6 different resistors to a single ADC pin of the controller. When a button is pressed wake up the device /if necessary), read the ADC value, pick a track based on that value and then play the track on the dfplayer.

After a while, if no button is pressed, put the dfplayer and the mcu to sleep. And that's why I need the mcu at all. You can't set the dfplayer to sleep or wake it up without serial

---

Update:

I confused SPI and Serial indeed. I need to use serial communication

I want to send and receive packages. Send: `InitCommand`, Receive: `PlayerInitialized` / `InitializationFailed`. And so on.Well it's some hex codes of course but you get the point I think

My flow should basiclly look like this:

boot/wakeup // \<-- this is where I need the interrupt, don't I?
read adc value
pick track number based on adc value
send PlayTrack command to DFPlayer
delay x ms
send Sleep command to DFPlayer
go back to sleep

But the issue is in the combination of the Sleep and SoftwareSerial library. It's not the interrupt that is an issue. At least not yet

# Answer
Thanks to @Delta\_G I was able to figure out a solution.

I took the source files of the SoftwareSerial library from github and copied it to my project. I renamed it so it wont give any conflicts. I then continued to comment out the interrupts in the cpp file and took care of calling `handle_interrupt` from my program. I also had to remove the inline keyword from the `handle_interrupt` function

I've posted my modified files on github.
> 0 votes

# Answer
> boot/wakeup // \<-- this is where I need the interrupt, don't I?

Is the interrupt to detect that you have pressed one of the buttons? If you have that then you shouldn't need to use a timer to wake up.

If you connect your buttons with resistors in such a way that any button at all will send at least 0.6Vcc (ie. 3V upwards for a 5V system) then that could be configured to generate an interrupt (a rising interrupt). So you might set up the resistors so the buttons send 3.2V, 3.5V, 3.8V, 4.1V, 4.4V and 4.7V. That gives you six different voltages and they are all high enough to be considered "high" on a digital pin. Then make that pin generate the interrupt and also do the ADC reading on it once you wake up.

Then you can put the processor into a deep sleep until a button is pressed. While the track is playing you might also set up a watchdog timer interrupt so that you can wake up and check if it is time to put the player to sleep as well.
> 0 votes

---
Tags: interrupt, softwareserial, attiny, sleep, attiny85
---


# Question
Title: How .data + .text section can be = How much flash the final program will consume
I could not understand one point related with Arduino code.

Let's say i have following code

```
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
}

void loop()
{

}

```

When i compile above code for Arduino Uno. Arduino IDE gives.

> Sketch uses 1478 bytes (4%) of program storage space. Maximum is 32256 bytes. Global variables use 192 bytes (9%) of dynamic memory, leaving 1856 bytes for local variables. Maximum is 2048 bytes.

I examine the generated file with `avr-size`.

```
.data                         26   8388864
.text                       1452         0
.bss                         166   8388890
.comment                      17         0
.note.gnu.avr.deviceinfo      64         0
.debug_aranges               208         0
.debug_info                 6150         0
.debug_abbrev               2721         0
.debug_line                 2239         0
.debug_frame                 504         0
.debug_str                  1770         0
.debug_loc                  1908         0
.debug_ranges                 80         0

```

As you can see .data + .text = consuming program storage space. Then i checked this document. https://courses.cs.washington.edu/courses/csep567/04sp/pdfs/avr-libc-user-manual.pdf. It says about `avr-size`

```
Note:
The avr-size program (part of binutils), coming from a Unix background,
doesn’t account for the .data initialization space added to the .text section, so in
order to know how much flash the final program will consume, one needs to add
the values for both, .text and .data (but not .bss), while the amount of pre-allocated
SRAM is the sum of .data and .bss.

```

Then, i check contents of .data section with

```
avr-objdump.exe -s -j .data <my.elf>

```

Then I got

```
Contents of section .data:
 800100 00000000 ff005f00 8c004c01 bd009b00  ......_...L.....
 800110 af00666f 6f000d0a 0000               ..foo.....

```

I'm confused, what above quote really means ? "foo" stored in .data section, but why i need to add this section to .text section in order to calculate how much flash consumes ?

# Answer
> 4 votes
Just to expand on what JRobert said, variables which are initialized, and other literals (eg. the word "foo" in your example) have to come from somewhere, and thus are stored in program (flash) memory and copied into RAM as part of the C++ initialisation.

However, uninitialised variables do not take up flash memory. Compare:

```
char foo [1000];
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
  Serial.print (foo);
}

void loop()
{
}

```

This reports for the Uno:

```
Sketch uses 1498 bytes (4%) of program storage space. Maximum is 32256 bytes.
Global variables use 1192 bytes (58%) of dynamic memory, leaving 856 bytes for local variables. Maximum is 2048 bytes.

```

However if you initialise that global variable foo, like this:

```
char foo [1000] = { 1, 2, 3, 4, 5 };
void setup()
{
  Serial.begin(9600);
  Serial.println("foo");
  Serial.print (foo);
}

void loop()
{
}

```

Now the flash takes 1000 more bytes:

```
Sketch uses 2498 bytes (7%) of program storage space. Maximum is 32256 bytes.
Global variables use 1192 bytes (58%) of dynamic memory, leaving 856 bytes for local variables. Maximum is 2048 bytes.

```

This clearly shows that, since uninitialised variables at global scope are set to zero, the compiler has generated code to do just that. However initialised variables have to be copied from flash into RAM.

A very useful technique when using these chips with not much RAM is to use the "F" macro, which effectively tells the compiler to copy strings directly from flash, rather than into RAM, thus saving RAM space. For example:

```
Serial.println (F("Hello, world"));

```

In this case the string "Hello, world" still has to be in flash, but doesn't have to be copied into RAM, thus saving precious memory for other purposes.

---

# Putting initialised arrays into flash

I've got a lengthy discussion about using PROGMEM for storing data, other than just literal strings for printing on my forum.

This example code here shows how you can store messages in PROGMEM (flash memory) and retrieve them at runtime. It uses `pgm_read_word` to read the pointers, and then `strcpy_P` to copy the string from PROGMEM into RAM, so it can then be printed.

```
const int NUMBER_OF_ELEMENTS = 10;

const char Message0000 [] PROGMEM = "Twas bryllyg, and ye slythy toves";
const char Message0001 [] PROGMEM = "Did gyre and gymble";
const char Message0002 [] PROGMEM = "in ye wabe:";
const char Message0003 [] PROGMEM = "All mimsy were ye borogoves; And ye mome raths outgrabe.";
const char Message0004 [] PROGMEM = "\"Beware the Jabberwock, my son! \n The jaws that bite, the claws that catch!";
const char Message0005 [] PROGMEM = "Beware the Jubjub bird, and shun\n The frumious Bandersnatch!\"";
const char Message0006 [] PROGMEM = "He took his ";
const char Message0007 [] PROGMEM = "vorpal sword in hand:";
const char Message0008 [] PROGMEM = "Long time the manxome foe he sought - ";
const char Message0009 [] PROGMEM = "So rested he by the Tumtum tree, \n And stood awhile in thought.";

const char * const messages[NUMBER_OF_ELEMENTS] PROGMEM =
   {
   Message0000,
   Message0001,
   Message0002,
   Message0003,
   Message0004,
   Message0005,
   Message0006,
   Message0007,
   Message0008,
   Message0009,
   };

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

  unsigned int count = 0;

  for (int i = 0; i < NUMBER_OF_ELEMENTS; i++)
    {
    char * ptr = (char *) pgm_read_word (&messages [i]);
    char buffer [80]; // must be large enough!
    strcpy_P (buffer, ptr);
    Serial.println (buffer);
    count += strlen (buffer) + 1;
    }   // end of for loop

  Serial.print (F("String memory used = "));
  Serial.println (count);

  }  // end of setup

void loop () { }

```

This particular example doesn't use much RAM:

```
Sketch uses 2220 bytes (6%) of program storage space. Maximum is 32256 bytes.
Global variables use 188 bytes (9%) of dynamic memory, leaving 1860 bytes for local variables. Maximum is 2048 bytes.

```

# Answer
> 1 votes
The values of your initialized-data (.data) are stored in flash together with your code. The initialized-data gets copied to RAM after every upload, reset, or power-up, before your code starts executing.

---
Tags: avr, flash
---


# Question
Title: Does the UNO R4 still have the standard on-board led on pin 13?
I need to add support for the UNO R4 (both models) for a library I'm maintaining. The library uses the LED on pin 13 as status indicator. I can't find any information whether that LED is still there on the R4 Minima and Wifi boards. The R4 Wifi has this nice LED matrix, so the other LED might be gone for it.

# Answer
The schematics for the R4 Minima and Wifi boards can be found at: https://docs.arduino.cc/resources/schematics/ABX00080-schematics.pdf and https://docs.arduino.cc/resources/schematics/ABX00087-schematics.pdf . Pin 13 is also labeled SCK. A LED is attached to this pin.
> 4 votes

---
Tags: led
---


# Question
Title: Avoid using delay with the HR-S04 ultrasonic sensor
How can I measure the distance of an HR-S04 ultrasonic sensor with millis and micros?

# Answer
In response to @Majenko comment on the original question, here is some code that I use which uses the Timer1 input capture function to read an ultrasonic sensor. It also uses the Timer1 PWM generator to create the trigger pulses. The entire code is interrupt driven and nothing blocks the main program.

It's not built as an official style library with all the extra parts, but the .h and .cpp can be put into a folder in the libraries folder as in the manual installation process. It's really just a personal library that I use on some of my robots, but I'm happy to share.

The code as written supports the ATMEGA1284P and ATMEGA328P chips. There are a couple of lines to comment and un-comment to change between the two.

It exposes a singleton instance much like the Serial class, so there's nothing to instantiate. The pins are all set by hardware, you can't change them.

Depending on how much total range you want, you can set the prescaler to a much lower value. If you run with no prescaler then the resolution would be something on the order of nearly 100 times what you can get with micros (62.5ns vs 4us resolution). But that would be shorter distances like 1.2m and less.

https://github.com/delta-G/PingTimer

```
#include "PingTimer.h"

int distance;

void setup() {

  Serial.begin(9600);
  ping.begin();
  ping.sendPing();

}

void loop() {

  //  if the ping sensor has new data save it to distance and print it.
  if(ping.hasNewData()){
    distance = ping.getDistanceMM();
    Serial.print("Current Distance: ");
    Serial.println(distance);
    ping.sendPing();
  }

  //  Do other things not blocked by ping sensor

}

```

PingTimer.h

```
/*

PingTimer  --  uses Timer1 Input Capture to read a HC-SR04
     Copyright (C) 2019  David C.

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

     */

#ifndef PINGTIMER_H_
#define PINGTIMER_H_

#include "Arduino.h"

// Ping pin on OC1A -- PB1 on 328P.  (UNO pin 9)
                    //-- PD5 on 1284P  (pin 13)
#define PING_PIN_MASK (1 << 5)
#define PING_PIN_PORT PORTD

// Echo pin on ICP1 -- PB0 on 328P  (UNO pin 8)
                    //-- PD6 on 1284P  (pin 14)
#define ECHO_PIN_MASK (1 << 6)
#define ECHO_PIN_PORT PIND

class PingTimer {
private:
    volatile uint16_t timerVal;
    volatile boolean overflowed;
    volatile boolean newData;

    void initTimer();

    void startPulse();

public:
    PingTimer();
    void begin();

    void sendPing();
    void echoHandler();
    void overflowHandler();

    boolean hasNewData();
    boolean hasOverflowed();
    uint16_t getTimerVal();

    int16_t getDistanceMM();

};

extern PingTimer ping;

#endif /* PINGTIMER_H_ */

```

And the PingTimer.cpp

```
/*

PingTimer  --  uses Timer1 Input Capture to read a HC-SR04
     Copyright (C) 2019  David C.

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

     */

#include "PingTimer.h"

PingTimer ping;

PingTimer::PingTimer(){
    newData = false;
    overflowed = false;
    timerVal = 0;
}

void PingTimer::begin() {
    initTimer();
    // ATMEGA328P
//  pinMode(8, INPUT);
//  pinMode(9, OUTPUT);
    // ATMEGA1284P
    pinMode(14, INPUT);
    pinMode(13, OUTPUT);
}

void PingTimer::initTimer(){
    cli();
    TCCR1A = 0;  // no PWM
    // Noise Cancel On, RISING Edge , No prescaler, 4ms range.
    TCCR1B |= ((1 << ICNC1) | (1 << ICES1) | (1 << CS11) | (0 << CS10));
    // make sure analog comparator isn't selected as capture input
    ACSR &= ~(1 << ACIC);
    //  Turn off Timer interrupts
    TIMSK1 = 0;
    // setup COMPA for 10us to time the trigger pulse
    // and COMPB for 12ms for out of range signal (a little over 4 meters)
    OCR1AH = 0;
    OCR1AL = 20;  // With prescaler at 8 each tick is 0.5 us.
    OCR1BH = 0xB5;
    OCR1BL = 0xB0; // 0xB5B0 is 46512.  That's a little over 4 meters with prescaler at 8.
    sei();
}

//  This is a public facing function to call the startPulse so it can stay private
//  since it twiddles registers
void PingTimer::sendPing() {
    startPulse();
}

void PingTimer::startPulse(){
    // set pin high and setup PWM unit to
    // turn the pin off 10us later
    cli();
    TCNT1H = 0x00;
    TCNT1L = 0x00;
    //Set up to get one pulse of PWM
    // Clear OC1A on compare match.  10bit fast PWM
    TCCR1A = ((1 << COM1A1) | (1 << WGM11) | (1 << WGM10));
    // Setup input capture interrupt to catch the rising
    // of the echo pin and start the timer
    // Noise Cancel On, RISING Edge ,prescaler at 8 gives a 32ms timer = 5.5 meter range
    TCCR1B = ((1 << ICNC1) | (1 << ICES1) | (1 << CS11) | (0 << CS10) | (1 << WGM12));
    //  Turn on interrupt Input Capture
    TIFR1 = ((1 << ICF1) | (1 << TOV1));
    TIMSK1 = ((1 << ICIE1));
    overflowed = false;
    newData = false;
    sei();
}

// Called from ISR
void PingTimer::echoHandler() {
    if (ECHO_PIN_PORT & ECHO_PIN_MASK) {  //Rising Pin
        // Kill the OC1A PWM unit and return to normal mode
        TCCR1A = 0;
        // Noise Cancel On, FALLING Edge ,prescaler at 8 gives a 32ms timer = 5.5 meter range
        TCCR1B = (1 << ICNC1) | (0 << ICES1) | (1 << CS11) | (0 << CS10);
        // Reset Timer1
        TCNT1H = 0;
        TCNT1L = 0;
        //  Reset Input Capture and Timer Overflow Interrupts
        TIFR1 = (1 << ICF1) | (1 << TOV1);
        //  Turn on interrupts Input Capture and Timer Overflow
        TIMSK1 = (1 << ICIE1) | (1 << TOIE1);
    } else {  // Falling pin
        // Read the ICR1 Register
        uint8_t low = ICR1L;
        uint8_t high = ICR1H;
        timerVal = ((high << 8) | low) - 4; // Noise canceler adds 4 clock cycles

        //  turn off the timer interrupts
        TIMSK1 = 0;
        newData = true;
    }
}

// Called from ISR  Timer 1 OVF
void PingTimer::overflowHandler(){
    //turn off timer interrupts
    TIMSK1 = 0;
    newData = true;
    overflowed = true;
}

boolean PingTimer::hasNewData(){
    cli();
    boolean retval = newData;
    newData = false;
    sei();

    return retval;
}

boolean PingTimer::hasOverflowed(){
    cli();
    boolean retval = overflowed;
    overflowed = false;
    sei();

    return retval;
}

uint16_t PingTimer::getTimerVal() {
    uint16_t retval = 0;
    cli();
    if (overflowed) {
        retval = -1;
    } else {
        uint16_t copy = timerVal;
        retval = copy;
    }
    sei();
    return retval;
}

int16_t PingTimer::getDistanceMM() {

    int16_t retval = 0;
    uint16_t copy = getTimerVal();
    if (copy == (uint16_t) -1) {
        retval = -1;
    } else {
        // 16Mhz is 62.5 ns/clock
        // We've got the prescaler dividing by 8
        uint32_t nanoSecs = copy * 62.5 * 8;
        //speed of sound in mm/ns
        uint16_t mm = nanoSecs * 0.000344;
        retval = mm / 2;  // half a round trip
    }
    return retval;
}

ISR(TIMER1_CAPT_vect){
    ping.echoHandler();
}

ISR(TIMER1_OVF_vect){
    ping.overflowHandler();
}

ISR(TIMER1_COMPB_vect){
    ping.overflowHandler();
}

```
> 3 votes

# Answer
I have noticed that many people on the net have problems using millis with the sensor to take measurements etc. so I created this sketch to help anyone.

You are free to ask for any clarification about it!

```
/*
 *  HC-SR04 sensor measuring
 *
 *  Non-blocking HC-SR04 sensor measuring
 *
 *  The circuit:
 *  - Echo pin connected to pin 2
 *  - Trigger pin connected to pin 3
 *  - VCC pin connected to VCC (5v)
 *  - GND gger pin connected to GND
 *
 *  created 3 Jul 2021
 *  by alessandromrc
 */

#define trigPin 3
#define echoPin 2

unsigned long timerStart = 0;
unsigned long StartTime = micros();
bool timer = false;
const unsigned long HIGH_TRIGGER = 10;
const unsigned long LOW_TRIGGER = 2;

float timeDuration, distance;

enum SensorStatus {
  TRIG_LOW,
  TRIG_HIGH,
  ECHO_HIGH
};

SensorStatus sensorStatus = TRIG_LOW;

bool isTimerReady(const unsigned long Sec) {
  return (micros() - timerStart) < Sec;
}

void setup(void) {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop(void) {
  switch (sensorStatus) {
  case TRIG_LOW: {
    digitalWrite(trigPin, LOW);
    timerStart = micros();
    if (isTimerReady(LOW_TRIGGER)) {
      sensorStatus = TRIG_HIGH;
    }
  }
  break;

  case TRIG_HIGH: {
    digitalWrite(trigPin, HIGH);
    timerStart = micros();
    if (isTimerReady(HIGH_TRIGGER)) {
      sensorStatus = ECHO_HIGH;
    }
  }
  break;

  case ECHO_HIGH: {
    if (!timer) {
      Serial.print("Microseconds Passed in initialization: ");
      Serial.println(micros() - StartTime);
      timer = !timer;
      Serial.println("Starting to Measure");
    }
    digitalWrite(trigPin, LOW);
    timeDuration = pulseIn(echoPin, HIGH);
    Serial.print("Measured: ");
    Serial.print(timeDuration * 0.034 / 2);
    Serial.println(" cm");
    sensorStatus = TRIG_LOW;
  }
  break;
  }
}

```

Github Repository
> 1 votes

---
Tags: c++, ultrasonics
---


title: "Best" architecture for handle events

text:
# Question
Title: "Best" architecture for handle events
I come from web world, so i usually code in a more procedurally manner, so the loop is a bit difficult to handle.

i mean if i do something like `if(condition) doSomething()` it will exec `doSomething()` a lot, or a click of a button....

```
bool condition = false;
void loop(){
  if(condition){
    doSomething();
  }

}

void doSomething(){
  condition = false;
  // ........
}

```

iam doing things like this, but i feel its wrong somehow

so iam struggling why could be the "best" architecture to execute `doSomething()` only once, in a way it not become a hell of state management, some kind of event driven, event sourcing or something more battle tested for arduino

iam totally newbie in this hardware/arduino world

# Answer
> 9 votes
Coming from the Web world, you are most likely used to work in a single-threaded environment (save for Web workers). You have been trained to program in a non-blocking fashion, as blocking the browser's UI thread would freeze the user interface. This is actually **a valuable asset** when moving to Arduino programming. Most Arduino programs run on a single-threaded, bare-metal platform. Non-blocking code is a must for all but the most trivial programs, and is not easy to master for newcomers.

The most striking difference between an Arduino and your typical JavaScript environment (be it a browser or Node.js) is that in JavaScript the event loop is *implicit*. You do not see it, but it runs under the hood of your interpreter. It looks conceptually like this:

```
void JavaScript_event_loop() {
    if (there_is_a_pending_event()) {
        dispatch_the_event_to_the_registered_callback();
    }
}

```

On the Arduino, however, you have to write the event loop yourself. Most often you do not need full-blown event queue management, as you know beforehand the set of events your program will have to handle. Your typical Arduino loop should normally look like this:

```
void loop() {
    if (event_foo_happened())
        handle_event_foo();
    if (event_bar_happened())
        handle_event_bar();
    if (event_baz_happened())
        handle_event_baz();
    // etc...
}

```

There are a few recurring idioms for testing common events. Here are some examples:

```
// Handle a periodic event (like setInterval()).
uint32_t now  = millis();
static uint32_t last_event_time;
if (now - last_event_time >= event_period) {
    // Use `last_event_time = now;` instead of this if you want to
    // guarantee a minimal interval between events:
    last_event_time += event_period;  // this avoids systematic drift
    handle_periodic_event();
}

// Handle a rising edge on an input_pin.
uint8_t pin_state = digitalRead(pin);
static uint8_t previous_pin_state;
if (previous_pin_state == LOW && pin_state == HIGH)
    handle_input_rising_edge();
previous_pin_state = pin_state;

// Handle Serial data.
if (Serial.available())
    handle_input_byte(Serial.read());

// Handle a push button with a debouncing library.
button.update();
if (button.fell())
    handle_button_press();

```

A few recommended readings:

* The Blink Without Delay Arduino tutorial shows how to handle periodic events
* Reading Serial on the Arduino is a tutorial showing how to buffer serial input in order to handle one full message at a time
* Bounce2 is an example of a button-debouncing library
* The Finite State Machine is a nice tutorial on writing finite state machines, which sooner or later you will need for handling some situations in a non-blocking way

---

**Edit**: Regarding the example code you posted, I would like to rewrite your `loop()` like this:

```
void loop() {
    if (condition) {
        doSomething();
        condition = false;  // <- move this out of doSomething()
    }
}

```

It doesn't look like a big change, but there is an idea here that can help make your code more readable and maintainable. The idea is to think of your program in terms of “events” you have to respond to. This should feel natural to someone raised on JavaScript, and it is also a good approach for programming microcontrollers. You then want to handle the event detection/dispatching and the event response as separate problems. The function `doSomething()` should not have to care about the `condition` variable, as it is only used to handle the event detection and dispatching, which is the responsibility of the event loop.

> When i said to execute once I mean, when press a button, it should do something only once, this control of what should/was executed is a bit tricking, can go out of control and became a mess.

To detect a button press you *do* have to manage some state, there is no way around it. Your program should not respond to the *state* of the button (pressed or released) but instead to specific *transitions* of this state (press or release events).

In its most basic form, the problem is about detecting a falling edge (or rising edge, depending on how the button is wired) on the input signal. This is handled by remembering the state you had on the previous loop iteration, and comparing this previous state with the state you are reading right now, as show in the “Handle a rising edge on an input pin” example above.

Real buttons have an additional issue, namely mechanic bounce: when the button is actuated, the signal can go through many fast transitions before settling into a stable state. In order to deal with this, you have to look at the timing of the transitions and sort out the legit ones from the spurious ones. This is called debouncing. There are a few libraries out there than can handle this for you. Most will also do edge detection, which makes handling button presses as simple as testing for `button.fell()` (again, see example above). Some will even report distinct event types for short press, long press and double press.

# Answer
> 3 votes
The usual way to do things only once (at startup) is to put them in `setup()`.

You put only statements in `loop()` that need endless repetitions.

You can think of the underlying main function as:

```
int main() {
    setup();
    for (;;) {
        loop();
    }
}

```

Therefore, your example can be:

```
void setup() {
    doSomething();
}

void loop() {
}

void doSomething() {
    // ........
}

```

---

**Addition after clarification**

You commented:

> as far as i know i cant detect a button press outside of the loop right? when i said to execute once i mean, when press a button, it should do somenthing only once, this control of what should/was executed is a bit tricking, can go out of control and became a mess

With that requirement, you are right, you need to put the check and reaction inside `loop()`. However, you can "hide" the "mechanic" inside the called function:

```
void setup() {
}

void loop() {
    doSomething();
}

void doSomething() {
    static bool isDone = false;
    if (!isDone && condition) {
        isDone = true;
        // ........
    }
}

```

A dedicated variable is simple and clear. You might choose some other type and value, depending on the actual things to do.

# Answer
> 0 votes
You don't have to use their "setup" and "loop" paradigm, you know. This will work:

```
#include <Arduino.h>

int main ()
  {
  init ();  // initialize timers
  Serial.begin (115200);
  Serial.println ("Hello, world");
  Serial.flush (); // let serial printing finish
  }  // end of main

```

So, inside your code, if you want to do something once, do it once. If you want to make a loop, make one. Just like in C++. Which is what the Arduino code is.

---

> so iam struggling why could be the "best" architecture to execute doSomething() only once

Put it in `setup` if you want to run with their "setup" and "loop" paradigm. It was just designed for beginners, to clarify that some things you do once, and some things you do in a loop.

---
Tags: arduino-uno
---


title: RX and TX pins on esp32

text:
# Question
Title: RX and TX pins on esp32
hello guys i'm new to this field i really need your help i want to wire a GSM module (SIM808) to a ESP32 board using the TX and RX pins so the pins are labeled RX and TX no pin number like the others how can i declare them in the code. i already tested the code on an arduino uno on pins 0 and 1 (RX and TX) and it works fine here is the board i'm using : i already tried using pins 16 and 17 but didn't work i need to try using pins number 40 and 41 according to image below

# Answer
> -1 votes
First off, thank you for all the guidance and support you've provided. As a beginner in the world of Arduino and embedded systems, it's been tremendously helpful.

The main issue I was facing had to do with not knowing how to declare the TX and RX pins in my C++ code, especially when these pins weren't labelled with their GPIO numbers like the others on my ESP32 board. After a bit of research and reading through your comments, I learned that these pins can simply be declared using their GPIO numbers, which are indicated on the schematic of the board.

For instance, to utilize RX0 and TX0, they need to be declared as 3 and 1 respectively. Here's an example:

```
 #define RXD 3  //RXD
    #define TXD 1  //TXD

    HardwareSerial SIM808(2);

void setup()
{
  //
  //
   SIM808.begin(9600, SERIAL_8N1, RXD, TXD);
}

```

I was able to get the SIM808 module working with this method, but I'm noticing that the system isn't always consistent. Sometimes it takes a long time to execute commands, which is something I will have to look into.

I just wanted to express my gratitude for the warm welcome and helpful guidance I've received here. This being my first post, I was worried about asking a "dumb question," but the community has been nothing but supportive.

As I continue to learn and explore more about embedded systems, I'm sure I'll be back with more questions, and hopefully, in time, some answers of my own to contribute!

---
Tags: esp32, wifi, communication
---


# Question
Title: ESP32 Pins won't fit in solderless breadboard
I bought an Adafrut Huzzah32 ESP32 for an IoT project. When the ESP32 arrived, I attempted to fit it into my existing breadboard, but I immediately noticed that no matter how hard I pushed, the pins wouldn't fit into the solderless breadboard.

I tried to find others with the same problem with no luck, so I went on amazon and purchased another breadboard (an Elegoo 830 tie-points Breadboard). It arrived today and I'm having the exact same problem. I don't want to use a soderable breadboard at this stage of the project as I'm just starting, but I don't know what else to do at this point.

I've Googled images of other peoples' setups and there pins are snug down in the board. What am I doing wrong? I've included photos below:

As you can see, the power module on the end fits fine but the ESP32 won't go down into the board. At this point, I've tried two different boards (one of those small Arduino ones and this one) with no luck.

Any suggestions?

You can see that the pins aren't even close to being down in the board.

# Answer
I ended up taking Gerben's suggestion from the comments and ordering the stacking headers (adafruit.com/product/2830) and plugging the ESP32 into that. The reason it works is because the stacking headers (as Gerben mentioned) are thinner and fit down into the breadboard while the female ports on top are big enough for the male pins coming out of the ESP32.

Thanks everyone!
> 3 votes

# Answer
I understand. These breadboards are pretty difficult to work with. Not only fitting an ESP-32 or similar board is difficult, these breadboards are not broad enough to expose all the GPIOs on both the sides.

I had solved this problem in this video. Do have a look. It might be helpful

https://youtu.be/CQlbE1x2i2g
> 2 votes

# Answer
or you can simply fit two bread boards together and mount the esp on them

(i had to twist the pins a little bit )
> 2 votes

---
Tags: adafruit, esp32, breadboard
---


# Question
Title: esp32, platformio A fatal error occurred: Packet content transfer stopped (received 8 bytes) *** [upload] Error 2
When i try to upload code to the esp32 the following error shows up in the command line:

**A fatal error occurred: Packet content transfer stopped (received 8 bytes).**

I use platformio in VScode the platform.ini file looks like this:

```
    [env:esp-wrover-kit]
    platform = espressif32
    board = esp-wrover-kit
    framework = arduino
    upload_port = COM4
    monitor_speed = 115200

```

Here's the code i'm trying to upload:

```
#include <Arduino.h>

void setup() {
    Serial.begin(115200);
    Serial.println("init");
}

void loop() {
}

```

It's an esp32-wrover-dev from freenove. When i unplug it and plug it back in it starts to write random stuff to the serial monitor, when i attempt an upload it stops but it also gives me the error above.

# Answer
For anyone wondering, i found out it means that there's some kind of disconnect between the computer from which your uploading and the file system. Essentially, the esp32 is broken.
> 2 votes

# Answer
I was able to resolve this issue by detaching jumpers that i had connected to the GPIO 12/13 pins during upload.

After uploading they can be attached again. See this github issue: https://github.com/espressif/arduino-esp32/issues/2415
> 5 votes

# Answer
I had this error when trying to upload a sketch from Arduino IDE to a TTGO T-Display, found that I could resolve this by changing the upload speed from the default of 921600 to 115200.

After doing that it uploaded just fine with no issues.
> 4 votes

# Answer
Hi all I found I got this error because my FTDI adapter was in 3.3V mode, not 5V as soon as I set it to 5V the issue was resolved and it programmed fine. One more thing to check before you scrap your ESP32.

Mick
> 1 votes

---
Tags: esp32, uploading, error, platformio, vscode
---


title: DS18B20 oneWire analog vs digital

text:
# Question
Title: DS18B20 oneWire analog vs digital
I just discovered that the Dallas DS18B20 can be read from either digital or analog pins. I never thought analog was an option until I stumbled across an article searching for another issue. So now I'm wondering, if I have a dozen DS18B20's on about 20 feet of wire with a 4.7k resistor, what would be the better option for reading? Digital or Analog?

# Answer
To use multiple DS18B20 devices on the same bus

1/ First get the address of each DS18B20 device by attaching it alone to the Arduino, and calling the `discoverOneWireDevices();` function. Write down the address. This is a set of 8 hexadecimal digits, eg 0x28, 0x13, 0x97, 0x9A, 0x0A, 0x00, 0x00, 0x6A

2/ Hard-code the address of each device, e.g. `#define TEMP_SENSOR1 {0x28, 0x13, 0x97, 0x9A, 0x0A, 0x00, 0x00, 0x6A}` before the call to the setup, and define the corresponding device address: `DeviceAddress tempSensor1 = TEMP_SENSOR1;`

3/ each time you launch a command to a DS18B20, specify to which you are speaking, eg `temperature1 = sensors.getTempC(tempSensor1);`
> 2 votes

# Answer
Analog is not an option as the 1-wire is a digital communication bus, however using an analog pin is on many processors to do this is possible. This is achieved on many of the processors because the analog pin can be configured and used for digital I/O. Arduinos such as the UNO can accomplish this because of the processor they use. Note not all microprocessors are designed use an analog pin for digital I/O.

There is an application note by AMD called "1-Wire Search Algorithm", https://www.analog.com/en/app-notes/1wire-search-algorithm.html. By using this process you can read all of the sensors independently without knowledge of there addresses. Using this method will not guarantee which sensor you are reading but the sequence will repeat and you can simply replace a sensor but the order will probably change. This allows you to change sensors etc when there are not many sensors involved. Here are some links to better explain this.

https://docs.arduino.cc/learn/communication/one-wire

https://www.arduino.cc/reference/en/libraries/onewire/
> 1 votes

---
Tags: arduino-uno, temperature-sensor
---


# Question
Title: changing a single bit in an arduino EEPROM byte
In my code I have a number of boolean flags that tell me if data has been written to specific places in the EEPROM. I need to save these flags to the EEPROM and recover them on a restart.

Is the following syntax valid to update a single bit in an EEPROM cell?

```
EEPROM.update (0, EEPROM.read(0)| 0x20);

```

ie I'm reading cell '0' , putting a '1' into bit 5 and then updating cell; '0' of the EEPROM. There will be several other bits to be updated throughout the running of the programme.

# Answer
Yes, your syntax is indeed correct. The `|` operator is the bitwise OR operator in C and C++, and it's used to set a specific bit in a byte. Here's a breakdown of what your line of code does:

* `EEPROM.read(0)` reads the current value of the first byte in the EEPROM.
* `0x20` is the hexadecimal representation of 32, which is `00100000` in binary. This means that the fifth bit (counting from zero) is set to 1, and all other bits are set to 0.
* `EEPROM.read(0) | 0x20` performs a bitwise OR operation on the current value of the first byte in the EEPROM and `0x20`. This will set the fifth bit of the byte to 1, and leave the other bits unchanged.
* `EEPROM.update(0, EEPROM.read(0) | 0x20)` updates the first byte in the EEPROM with the new value.

So, your approach to set a specific bit in an EEPROM byte is correct.

Here's a more detailed example:

```
byte bitToSet = 5; // Bit number to set (0-7)
byte eepromAddress = 0; // EEPROM address (0-1023 for ATmega328)

// Read current value
byte currentValue = EEPROM.read(eepromAddress);

// Create mask for bit to set
byte mask = 1 << bitToSet;

// Update value
byte newValue = currentValue | mask;

// Write updated value back to EEPROM
EEPROM.update(eepromAddress, newValue);

```

It's worth noting that the `EEPROM.update()` function is smart enough to only perform a write if the new value is different from the old one. This is important because the EEPROM has a limited number of write cycles. So using `EEPROM.update()` instead of `EEPROM.write()` can help extend the life of the EEPROM.
> 2 votes

---
Tags: eeprom, bit
---


# Question
Title: How to use Arduino Uno as PS/2 to USB converter for typical keyboard usages?
I'm beginner in Arduino and recently programmed an Arduino uno board with various PS/2 to USB converters. They work when typing in Serial Monitor of Arduino IDE, but not in the other programs such as Notepad.

How can I connect the board as HID keyboard for usual works with my PS/2 keyboard?

**Update:**

As @KIIV mentioned in the comments, Uno hasn't native USB and his suggestion is to start with boards such as Leonardo.

I want to ask, what is the straightforward way of using Uno for this purpose?

# Answer
As the Uno has no generic USB module, it generally works only as a virtual serial device. Without additional hardware you cannot make a Uno work as a USB keyboard. In principle.

A possible solution is the usage of V-USB. This nice library uses bit-banging to realize low-speed USB communication. A USB keyboard commonly is such a low-speed USB device.

Another possible solution is an accompanying software "driver" on the PC. It will receive the key events via the USB serial port and translate them to key events for the operating system. But I'm sure you will not want this.
> 2 votes

---
Tags: arduino-uno, keyboard
---


# Question
Title: Overhead of using 'new' to create object in dynamic ram vs automatic to create on stack
Let's suppose I have a class named `Foo`, and `sizeof(Foo)` is 10 bytes.

As I understand it, creating a Foo with 'automatic' scope (on the stack) has zero overhead. If the Object occupies 10 bytes, it consumes 10 bytes on the stack. Period.

I'm kind of fuzzy about how creating objects with 'new' works on an 8-bit AVR. I know that 'new' ultimately calls malloc(), and that on Windows/Linux, malloc() ultimately asks the operating system for memory whose management is up to the OS itself. But... with 8-bit AVR, there *is no* operating system. So, presumably, something else has ultimate responsibility for managing its heap. And presumably, there's some kind of overhead involved so it can keep track of which bytes have been returned to it by a destructor, and which ones are still in use.

So... using the hypothetical 10-byte `Foo` as an example... if I make 7 sequential calls in a row to `new Foo()`, how many bytes will it *actually* burn through (including overhead)?

For objects that have to be instantiated via `new`, but will persist "forever" (until the next reset), is there any special syntax that tells the compiler/malloc()/whatever, "This object will **never** be destroyed, so there's no need to preserve any information that would otherwise be necessary to release its memory eventually"?

---

Giving this a bit of context, assume `View` is a class with multiple templated subclasses (let's say, `TemperatureView<int, int, int, int>` and `LabelView<int, int, int, const char*>`), and I'm doing something like this:

```
const PROGMEM char* pLABEL = "Foo:";
View* views[] = {
    (new TemperatureView<0,3,0,2>{}),
    (new LabelView<1,4,0,pLABEL>{})
};

```

I'm trying to figure out just how big of a penalty hit (in terms of wasted ram from overhead) I'm taking by rolling it all into one nice, neat combined declaration instead of doing something like:

```
const PROGMEM char* pLABEL = "Foo:";
TemperatureView<0,3,0,2> firstTemp {};
LabelView<1,4,0,pLABEL> firstLabel {};
View* views[] = {
    &firstTemp,
    &firstLabel
};

```

(I originally wanted to put the objects whose addresses were being added to views\[\] in automatic/stack, but apparently, that's taboo because the compiler thinks the array will outlive the objects whose addresses would otherwise be stored there)

# Answer
If you make an automatic variable, its lifetime is the lifetime of the function it is inside, so it won't persist forever, unless it is at global scope, or it is declared `static`.

The overhead of using `new` is the size of the object you allocate plus a couple of bytes to keep track of what that bit of memory is used for.

> if I make 7 sequential calls in a row to new Foo(), how many bytes will it actually burn through (including overhead, which appears to be two bytes, see test below)

Seven times the size of the object plus the overhead I mentioned.

Normally you would release that memory with `delete` unless you want it kept forever.

> For objects that have to be instantiated via new, but will persist "forever" (until the next reset), is there any special syntax that tells the compiler/malloc()/whatever, "This object will never be destroyed ...

No. It persists until you call `delete` which there is no compunction to do.

I wrote a test program for my Uno to see what the overhead was, to use `new`.

```
#include "memdebug.h"

void showFreeMemory ()
  {
  Serial.print (F("Free memory = "));
  Serial.println (getFreeMemory ());
  } // end of showFreeMemory

typedef struct {char s [20]; } foo;

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();
  showFreeMemory ();   // 1664
  foo * bar = new foo;
  showFreeMemory ();   // 1642
  strcpy (bar->s, "Hello, world");
  Serial.println (bar->s);
  delete bar;
  showFreeMemory ();   // 1664
  }  // end of setup

void loop () { }

```

> I'm trying to figure out just how big of a penalty hit (in terms of wasted ram from overhead)

Two bytes, by the looks, for each allocation.

> (I originally wanted to put the objects whose addresses were being added to views\[\] in automatic/stack, but apparently, that's taboo because the compiler thinks the array will outlive the objects whose addresses would otherwise be stored there)

I'm not sure what you mean by that, can you give a concrete example?

---

I think you will save more memory by using PROGMEM, which you seem to be doing, a bit.

See my post here for ideas about doing that.

---

## Reference

I got memdebug.h (and memdebug.c) from Andy's workshop - Debugging AVR dynamic memory allocation
> 1 votes

# Answer
Just as a small complement to the previous answer... The documentation of the avr-libc has a whole page discussing the workings of `malloc()`. The section titled Implementation details states:

> Dynamic memory allocation requests will be returned with a two-byte header prepended that records the size of the allocation. This is later used by `free()`. The returned address points just beyond that header.

This is consistent Nick Gammon's experimental finding.
> 1 votes

---
Tags: c++
---


title: Separate from Serial for digitalWrite()

text:
# Question
Title: Separate from Serial for digitalWrite()
This is my current code (Arduino Mega 2560):

```
#define p1 2
#define p2 3

void setup() {
 pinMode(p1, OUTPUT);
 pinMode(p2, OUTPUT);
 Serial.println("ARDUINO : CONNECTED");
}

void loop() {
 if (Serial.available()) {
  String state = Serial.readString();

  if (state.startsWith("LED1ON")) {
    digitalWrite(p1, HIGH);
  }
  if (state.startsWith("LED1OFF")) {
    digitalWrite(p1, LOW);
  }
  if (state.startsWith("LED2ON")) {
    digitalWrite(p2, HIGH);
  }
  if (state.startsWith("LED2OFF")) {
    digitalWrite(p2, HIGH);
  }
  // ... and next condition LED
 }
}

```

how can i do for multiple input serial use seperator(";") ? like : LED1ON;LED2OFF

expacted: one time command (LED1ON;LED2OFF) many condition (led turn on and led 2 turn off)

please, tks

# Answer
You might want to get used to visit the Arduino library reference to learn what is possible and how to use it.

For your case, you are interested in the method `readStringUntil()`.

The reading, understanding, experimenting, debugging, and finishing is left as an exercise to the user.
> 2 votes

# Answer
Consider refactoring your code such that you read in strings then search through the string character by character copying each character to a new string until you find a semicolon. When this happens do not copy the semicolon. Instead execute the existing "if" statements to turn on / off the LEDs based on the content of the new string. When done, erase the new string, loop back and continue to copy characters to the new string until the next semicolon. If there is no more data to be copied, read in more data until data is unavailable.
> 0 votes

# Answer
readString reads from Serial until it times out. This means it might undershoot or overshoot both the end of the line (if there is one) or the semicolon.

I suggest reading into a `char` buffer (say, of 30 bytes length) until either a newline or semicolon is reached. Then terminate the buffer with 0x00 (to make it a proper "C" string) and then do a simple string compare (`strcmp`).
> 0 votes

---
Tags: arduino-uno, arduino-mega
---


# Question
Title: TMC2208 Stepper Motor does not change its RPM linearly
This is my first project working with stepper motors, so I may have a bit of a shaky understanding of the electronic side of the project. I'm trying to create a simple device with 4 buttons connected to a stepper motor driver/NEMA 17 motor, with the ability to increase/decrease RPM, switch motor spin direction, and run the motor with the button being held down. (LCD screen included for output as well)

I'm noticing that when changing the RPM on my motor, i.e. from 3.2 to 3.1 to 3.0, the speed of the motor is really slow, then when set to 3.0, suddenly increases a lot, but goes down when setting the RPM back down to 2.8 or so. This occurs multiple times along different intervals of RPMs that I have tested as well.

I think that there may be an issue with the method with which I am calculating the pulse delay given the RPM in my function `setRPM()` at the end of my code or with the way that I am micro-stepping, which I am doing because I need extremely precise movement.

Included below is the code that I used to run with my TMC2208 driver. (Sorry if it is rather long, but I included comments to document my thought process when programming the Arduino.)

Included list of RPMs and pulse delays

| rpm | pulse\_delay (us) |
| --- | --- |
| 1 | 37500 (too fast) |
| 2 | 18750 (too fast) |
| 2.25 | 16666.6667 (works) |
| 2.5 | 15000 (works) |
| 3 | 12500 (works) |
| 5 | 7500 (works) |
| 10 | 3759 (works) |

```
// Stepper motor run code with TMC2208 driver and LCD code
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Stepper.h>
// Define Pins for Step Motor Driver
#define stepPin 7  // define pin for step
#define dirPin 8   // define pin for direction
#define enPin 9    // define pin for enable ^^ Do I need this?

// Define Buttons for Speed and Direction
#define buttGo 10      // define pin for button input
#define buttSwitch 11  // define pin for button input
#define incSpeed 12    // define button for increasing speed
#define decSpeed 13    // define button for decreeasing speed

// Define LCD pinout
const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;  // Adapter Pinout
const int i2c_addr = 0x27;                                                 // Adapter pinout
LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

/* Formulas for determining RPM
Assuming one step per pulse, delay is: wait = (μs/min)*(1/rpm)*(1/pulses per revolution) - overhead
Overhead = extra time it takes to run digitalWrite twice and loop
RPM = (steps per second)/(steps per revolution) * (60 seconds/minute)
step angle = 1.8 degrees ; 200 steps per revolution ; .005 revolutions per step
Solving for Steps Per Second: SPS = (RPM)/((REV_P_STEP)*(60 sec/min))

According to Notes:
  C0 = 15 * M_PI ; Motor X Circumference
  XSPR = 1 * (200 * 11) ; Motor X Steps per Rotation
  dVx = dS * (XSPR/C0) ; Desired X-Axis time from mm/s to x-axis steps/sec (dS represents desired x-axis speed)
  Assuming we use a button/knob, each increment/decrement would change the mm/s by 0.1
  So, to get the necessary pulse delay, increment/decrement by:
    dVx = 0.1 * (1 * (200 * 11))/(15*M_PI)

  Example: If we have an initial target rpm of 10, that gives us a dS of 10
  As such, dVx which is our speed in steps will be 10 * (1 * (200 * 11)) / (15 * M_PI)
  All of these variables are set globally
  wait = (microsecondsPminute)*(1/RPM)*(1/pulsesPrevolution) - overhead
  rpm / 60 = rps
  60 / rpm = spr
  (60 / rpm)/360 = spd
  ((60 / rpm)/360) * 1.8 = sps
***
Frequency = (RPM)/((Resolution/360)*60)
Resolution =  360/(Steps/Revolution)
For us, Resolution = 360/(200); so Resolution = 1.8**
Frequency = (RPM)/(0.005 * 60) = RPM/(0.3)
*
T_inc = incremental torque produced with each microstep
T_hfs = holding torque (full-step operation)
SDR = step division ratio (number of microsteps per full step)

T_inc = T_hfs * sin(90/SDR)
T_inc = 0.14 * sin(90/256)
T_inc = 0.00085902385
*/
float resolution = 1.8;
float rpm = 10;
float pulse_delay;  // Temporary starting value that will change after void setup
bool buttonState = false;
bool onState = false;

// Set up output types
void setup() {
  Serial.begin(9600);  // Change this baud rate to whatever rate the LCD screen runs on - should generally be 9600
  // Set up LCD screen
  pulse_delay = setRPM(rpm, resolution);
  lcd.begin(16, 2);  // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0);
  lcd.print("Current RPM: ");
  lcd.setCursor(12, 0);
  lcd.print(rpm);
  lcd.setCursor(0, 1);
  lcd.print("MOVE RIGHT");

  // Sets up buttons
  pinMode(buttSwitch, INPUT);
  pinMode(buttGo, INPUT);
  pinMode(incSpeed, INPUT);
  pinMode(decSpeed, INPUT);

  // Establish initials
  pinMode(enPin, OUTPUT);
  digitalWrite(enPin, HIGH);  // deactivate driver
  pinMode(dirPin, OUTPUT);
  digitalWrite(dirPin, HIGH);
  pinMode(stepPin, OUTPUT);
  digitalWrite(enPin, LOW);  // activates driver
}

// Revolutions per second should be able specified to the tenths
// Run code to continual
void loop() {
  // Read Buttons Being Pressed
  int pressSwitch = digitalRead(buttSwitch);
  int pressGo = digitalRead(buttGo);
  int pressInc = digitalRead(incSpeed);
  int pressDec = digitalRead(decSpeed);
  pulse_delay = setRPM(rpm, resolution);  //pulse_delay = (rpm * 200)/60;

  if (pressSwitch == HIGH)  // Moves motor Right (Counter-Clockwise)
  {
    if (buttonState == 0) {
      digitalWrite(dirPin, LOW);  // sets direction of the motor turning
      buttonState = 1;
      lcd.setCursor(0, 1);
      lcd.print("MOVE  LEFT");
      delay(500);
    }
    else {
      if (buttonState == 1) {
        digitalWrite(dirPin, HIGH);  // sets direction of the motor turning
        buttonState = 0;
        lcd.setCursor(0, 1);
        lcd.print("MOVE RIGHT");
        delay(500);
      }
    }
  }

  if (pressGo == HIGH)  // Moves motor
  {
    digitalWrite(stepPin, HIGH);  // This LOW to HIGH change is what creates the "Rising Edge" so the easydriver knows when to step.
    delayMicroseconds(pulse_delay);
    digitalWrite(stepPin, LOW);
  }

  if (pressInc == HIGH)  // Increases RPM
  {
    rpm = rpm + 0.1;
    delay(150);
    lcd.setCursor(12, 0);
    lcd.print(rpm);
  }

  if (pressDec == HIGH)  // Decreases RPM
  {
    rpm = rpm - 0.1;
    delay(150);
    lcd.setCursor(12, 0);
    lcd.print(rpm);
  }
}

// Function to get pulse delay time based off of inputted RPM value
float setRPM(float rpm, float resolution) {
  /*
  float temper = ((60 / rpm) / 360);
  float pulsetime = ((temper * resolution) * 1000000);
  1 rpm = 37500 us delay (too fast)
  2 rpm = 18750 us delay (too fast)
  2.25 rpm = 16666.6667 us delay
  2.5 rpm = 15000 us delay
  3 rpm = 12500 us delay
  5 rpm = 7500 us delay
  10 rpm = 3750 us delay
  */
  unsigned int pulsetime = (60000000 / (1600 * rpm));
  return pulsetime;  // Converts to microseconds
}

```

# Answer
The documentation says:

> Currently, the largest value that will produce an accurate delay is 16383; larger values can produce an extremely short delay.

The value given to `delayMicroseconds()` seems to be processed by a modulo 16384 operation. That means that the value is divided by 16384, and the remainder of this division is the effective delay in microseconds.

If we apply this to the delays in your table, we get:

| desired rpm | calculated delay (µs) | effective delay (µs) | effective rpm |
| --- | --- | --- | --- |
| 1 | 37500 | 4732 | 7.9 |
| 2 | 18750 | 2366 | 15.8 |
| 2.25 | 16666 | 16666 | 2.25 |
| 2.5 | 15000 | 15000 | 2.5 |
| 3 | 12500 | 12500 | 3 |
| 5 | 7500 | 7500 | 5 |
| 10 | 3750 | 3750 | 10 |

One possible solution is presented in the same documentation:

> For delays longer than a few thousand microseconds, you should use `delay()` instead.

You might want to consider to use both functions, depending on the necessary delay.

---

And then there is the other issue with the time when the output is low. Currently, it is determined by the time the code takes to quit `loop()`, do its internal looping, call `loop()` and your statements until the pin goes high again.

You might want to divide the pulse period in two halves and take control of this low phase, too.
> 2 votes

# Answer
For reference for any future readers who have had similar problems using a TMC2208 Stepper Motor - I have attached my annotated code to this answer for your use. In the annotation, I also include equations that can be used to determine spacings for a coiling setup.

```
// Stepper motor run code with A4988 driver and LCD code
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Stepper.h>
// Define Pins for Step Motor Driver
#define stepPin 7  // define pin for step
#define dirPin 8   // define pin for direction
#define enPin 9    // define pin for enable ^^ Do I need this?

// Define Buttons for Speed and Direction
#define buttGo 10      // define pin for button input
#define buttSwitch 11  // define pin for button input
#define incSpeed 12    // define button for increasing speed
#define decSpeed 13    // define button for decreeasing speed

// Define LCD pinout
const int en = 2, rw = 1, rs = 0, d4 = 4, d5 = 5, d6 = 6, d7 = 7, bl = 3;  // Adapter Pinout
const int i2c_addr = 0x27;                                                 // Adapter Pinout
LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, bl, POSITIVE);

/* Formulas for determining RPM
Assuming one step per pulse, delay is: wait = (μs/min)*(1/rpm)*(1/pulses per revolution) - overhead
Overhead = extra time it takes to run digitalWrite twice and loop
RPM = (steps per second)/(steps per revolution) * (60 seconds/minute)
step angle = 1.8 degrees ; 200 steps per revolution ; .005 revolutions per step
Solving for Steps Per Second: SPS = (RPM)/((REV_P_STEP)*(60 sec/min))

According to John Craig:
  C0 = 15 * M_PI ; Motor X Circumference
  XSPR = 1 * (200 * 11) ; Motor X Steps per Rotation
  dVx = dS * (XSPR/C0) ; Desired X-Axis time from mm/s to x-axis steps/sec (dS represents desired x-axis speed)
  Assuming we use a button/knob, each increment/decrement would change the mm/s by 0.1
  So, to get the necessary pulse delay, increment/decrement by:
    dVx = 0.1 * (1 * (200 * 11))/(15*M_PI)

  Example: If we have an initial target rpm of 10, that gives us a dS of 10
  As such, dVx which is our speed in steps will be 10 * (1 * (200 * 11)) / (15 * M_PI)
  All of these variables are set globally
  wait = (microsecondsPminute)*(1/RPM)*(1/pulsesPrevolution) - overhead
  rpm / 60 = rps
  60 / rpm = spr
  (60 / rpm)/360 = spd
  ((60 / rpm)/360) * 1.8 = sps
***
*Assume from measured diameter with calipers that it is 12 mm (Check 11.85 as well)
To get Spacings: V_extruder / RPM_rod
V_extruder = M_PI * Diam_extruder * RPM_extruder (in (mm*rev)/min)
RPM_rod = 13 rpm (set from original bought parts)
V_extruder = M_PI * 12 mm * X
Spacing = (M_PI * 12 * X) / 9.64507699 RPM
Spacing = 3.90863773 * X
For Spacings of 3 mm... 0.76753084 rev/min ~= 0.77 rev/min
For Spacings of 5 mm... 1.27921807 rev/min ~= 1.28 rev/min
For Spacings of 7 mm... 1.79090529 rev/min ~= 1.79 rev/min
*
y = 1.0715x + 2.6653
y = Voltage Setting
x = RPM
For Voltage Setting of 13, RPM = 9.64507699

T_inc = incremental torque produced with each microstep
T_hfs = holding torque (full-step operation)
SDR = step division ratio (number of microsteps per full step)

T_inc = T_hfs * sin(90/SDR)
T_inc = 0.14 * sin(90/256)
T_inc = 0.00085902385
*/
float resolution = 1.8;
float rpm = 3;
unsigned int pulse_delay;  // Temporary starting value that will change after void setup
bool buttonState = false;
bool onState = false;

// Set up output types
void setup() {
  Serial.begin(9600);  // Change this baud rate to whatever rate the LCD screen runs on - should generally be 9600
  // Set up LCD screen
  pulse_delay = setRPM(rpm);
  lcd.begin(16, 2);  // set up the LCD's number of columns and rows:
  lcd.setCursor(0, 0);
  lcd.print("Current RPM: ");
  lcd.setCursor(12, 0);
  lcd.print(rpm);
  lcd.setCursor(0, 1);
  lcd.print("MOVE RIGHT");

  // Sets up buttons
  pinMode(buttSwitch, INPUT);
  pinMode(buttGo, INPUT);
  pinMode(incSpeed, INPUT);
  pinMode(decSpeed, INPUT);

  // Establish initials
  pinMode(enPin, OUTPUT);
  digitalWrite(enPin, HIGH);  // deactivate driver
  pinMode(dirPin, OUTPUT);
  digitalWrite(dirPin, HIGH);
  pinMode(stepPin, OUTPUT);
  digitalWrite(enPin, LOW);  // activates driver
}

// Revolutions per second should be able specified to the tenths
// Run code to continual
void loop() {
  // Read Buttons Being Pressed
  int pressSwitch = digitalRead(buttSwitch);
  int pressGo = digitalRead(buttGo);
  int pressInc = digitalRead(incSpeed);
  int pressDec = digitalRead(decSpeed);
  pulse_delay = setRPM(rpm);  //pulse_delay = (rpm * 200)/60;

  if (pressSwitch == HIGH)  // Moves motor Right (Counter-Clockwise)
  {
    if (buttonState == 0) {
      digitalWrite(dirPin, LOW);  // sets direction of the motor turning
      buttonState = 1;
      lcd.setCursor(0, 1);
      lcd.print("MOVING  LEFT");
      delay(500);
    } else {
      if (buttonState == 1) {
        digitalWrite(dirPin, HIGH);  // sets direction of the motor turning
        buttonState = 0;
        lcd.setCursor(0, 1);
        lcd.print("MOVING RIGHT");
        delay(500);
      }
    }
  }
// Both of the next functions move the motor, but switches between Microseconds and Milliseconds in delay time to fit.
  if (pressGo == HIGH && pulse_delay >= 16383)  // Moves motor
  {
      digitalWrite(stepPin, HIGH);  // This LOW to HIGH change is what creates the "Rising Edge" so the easydriver knows when to step.
      delay(pulse_delay/1000);
      digitalWrite(stepPin, LOW);
  }

  if (pressGo == HIGH && pulse_delay < 16383)
  {
      digitalWrite(stepPin, HIGH);  // This LOW to HIGH change is what creates the "Rising Edge" so the easydriver knows when to step.
      delayMicroseconds(pulse_delay);
      digitalWrite(stepPin, LOW);
  }

  if (pressInc == HIGH)  // Increases RPM
  {
    rpm = rpm + 0.01;
    delay(150);
    lcd.setCursor(12, 0);
    lcd.print(rpm);
  }

  if (pressDec == HIGH)  // Decreases RPM
  {
    rpm = rpm - 0.01;
    delay(150);
    lcd.setCursor(12, 0);
    lcd.print(rpm);
  }
}

// Function to get pulse delay time based off of inputted RPM value
float setRPM(float rpm) {
  /*
  float temper = ((60 / rpm) / 360);
  float pulsetime = ((temper * resolution) * 1000000);
  1 rpm = 37500 us delay (too fast)
  2 rpm = 18750 us delay (too fast)
  2.25 rpm = 16666.6667 us delay
  2.5 rpm = 15000 us delay
  3 rpm = 12500 us delay
  5 rpm = 7500 us delay
  10 rpm = 3750 us delay
  */
  unsigned int pulsetime = (60000000 / (1600 * rpm));
  return pulsetime;  // Converts to microseconds
}

```
> 1 votes

---
Tags: arduino-uno, sensors, stepper, stepper-motor
---