title: Compiling error at ATmega2560

text:
# Question
Title: Compiling error at ATmega2560
I have a error.The error is showing as:

exit status 1 Error compiling for board Arduino Mega or Mega 2560.

The Code is:

```
#include <Wire.h>

#include <LCD.h>

#include <LiquidCrystal_I2C.h>

#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);

SoftwareSerial BT(10,11); //Tx and Rx pins for BT communication const int temp_sensor = 0; //pin A0 (temperature sensor) const int fan = 22; //pin D2 (fan) float temp; //temperature value

int threshold = 21; //temperature threshold

const int LDRsensor = 1; //pin A1 (lighting sensor)

const int LED1 = 6; //pin D6 (LED 1)

const int LED2 = 7; //pin D7 (LED 2)

const int LED3 = 8; //pin D8 (LED 3)

const int LED4 = 9; //pin D9 (LED 4)

int LDRvalue; //natural light value

const int WL_sensor = 15; //pin A15 (water level sensor)

const int Wpump = 13; //pin D13 (water pump)

float water_level; //water level value

const int mov_sensor = 3; //pin D3 (movement sensor)

const int LEDalrm = 4; //pin D4 (alarm LED)

const int buzzer = 5; //pin D5 (buzzer)

int mov_value; //movement value (true or false)

char state; //data sent from App

char mode; //mode selected according to "state" value char order; //order to actuators according to "state" value
void setup() //this function is only executed one time

{

lcd.begin (16,2);

lcd.setBacklightPin(3,POSITIVE);

lcd.setBacklight(HIGH);

lcd.setCursor(0,0);

lcd.print("TFG");

lcd.setCursor(0,1);

lcd.print("Anna Merino");

delay(4000);

lcd.clear();

pinMode(temp_sensor, INPUT); //temperature sensor Mode

pinMode(fan, OUTPUT) ; //fan Mode

pinMode(LDRsensor, INPUT); //lighting sensor Mode

pinMode(LED1, OUTPUT); //LED1 Mode

pinMode(LED2, OUTPUT); //LED2 Mode

pinMode(LED3, OUTPUT); //LED3 Mode

pinMode(LED4, OUTPUT); //LED4 Mode

pinMode(WL_sensor, INPUT) ; //water level sensor Mode

pinMode(Wpump, OUTPUT); //water pump Mode

pinMode(mov_sensor, INPUT); //movement sensor Mode

pinMode(LEDalrm, OUTPUT); //alarm LED Mode

pinMode(buzzer, OUTPUT); //buzzer Mode

BT.begin(9600); //set data rate in bits per second (baud) for data transmission }
void loop() //function loop – continuously executed

{

if(BT.available()>0)

{

state = BT.read(); //transfer data sent by App to a local variable

}

if (state == 'Y')

{

mode = 'A';

}

else

if (state == 'Z')

{

mode = 'R';

}

else

if (state == 'X')

{

mode = 'D';

}

if (mode == 'A')

{

automaticmode(); //execute automatic function

}

else

if (mode == 'R')

{

remotemode(); //execute remote function

}

else

if (mode == 'D')

{

alarmmode(); //execute alarm function

}

}
void alarmmode() // alarm function

{

water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

if (digitalRead(mov_sensor)) //evaluate movement captured {

digitalWrite(LEDalrm, HIGH);

digitalWrite(buzzer, HIGH);

}

else

{

digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

}

if (water_level > 100) //water level control

{

digitalWrite(Wpump, HIGH);

}

else

{

digitalWrite(Wpump, LOW);

}

}
void automaticmode() // automatic function

{

LDRvalue = analogRead(LDRsensor); //data of natural light transmission to a local variable water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

temp = analogRead(temp_sensor); //data of temperature sensor transmission to a local variable temp = temp*0.4883; //adjustment of temperature value digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

lcd.setCursor(0,0);

lcd.print("Temperature");

lcd.setCursor(0,1);

lcd.print(temp); //LCD display – shows temperature value

lcd.setCursor(7,1);

lcd.print("ºC");

if (water_level > 100) //water level control

{

digitalWrite(Wpump, HIGH);

}

else

{

digitalWrite(Wpump, LOW);

}

if ((LDRvalue < 1023) & (LDRvalue >= 822)) //light control {

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 821)& (LDRvalue >= 617))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 616)& (LDRvalue >= 412))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

else if ((LDRvalue < 411)& (LDRvalue >= 206))

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, LOW);

}

else if (LDRvalue < 205)

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, HIGH);

}

if (temp >= threshold) //temperature control

{

digitalWrite(fan, HIGH);

}

else if (temp < threshold)

{

digitalWrite(fan, LOW);

}

}

void remotemode() // remote function

{

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

digitalWrite(fan, LOW);

digitalWrite(Wpump, LOW);

digitalWrite(LEDalrm, LOW);

digitalWrite(buzzer, LOW);

if(BT.available()>0)

{

state = BT.read(); //transfer data sent by App to a local variable

}

if (state == 'D') //actuators operation according to orders received {

digitalWrite(LED1, LOW);

}

else

if (state == 'C')

{

digitalWrite(LED1, HIGH);

}

else

if (state == 'F')

{

digitalWrite(LED2, LOW);

}

else

if (state == 'E')

{

digitalWrite(LED2, HIGH);

}

else

if (state == 'H')
{

digitalWrite(LED3, LOW);

}

else

if (state == 'G')

{

digitalWrite(LED3, HIGH);

}

else

if (state == 'J')

{

digitalWrite(LED4, LOW);

}

else

if (state == 'I')

{

digitalWrite(LED4, HIGH);

}

else

if (state == 'L')

{

digitalWrite(fan, LOW);

}

else

if (state == 'K')

{

digitalWrite(fan, HIGH);

}

else

if (state == 'N')

{

digitalWrite(Wpump, LOW);

}

else

if (state == 'M')

{

digitalWrite(Wpump, HIGH);

}
if (state == 'O')

{

digitalWrite(LED1, HIGH);

digitalWrite(LED2, HIGH);

digitalWrite(LED3, HIGH);

digitalWrite(LED4, HIGH);

}

else

if (state == 'P')

{

digitalWrite(LED1, LOW);

digitalWrite(LED2, LOW);

digitalWrite(LED3, LOW);

digitalWrite(LED4, LOW);

}

}

```

# Answer
The main issue with your code is the formatting. It seems that you have managed to 'comment out' some of the necessary `{` or `}` for some of the functions and/or if/else blocks, hence the failure to compile.

e.g.

```
BT.begin(9600); //set data rate in bits per second (baud) for data transmission }

```

The `}` at the end of that particular line is the closing brace for the `void setup()` function... but because it's after the `//` for the comment, the compiler won't see it, so it is effectively missing.

This code *should* now compile on your system... once all the missing `{` and `}` were un-commented.

```
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7);
SoftwareSerial BT(10, 11); //Tx and Rx pins for BT communication const int temp_sensor = 0; //pin A0 (temperature sensor) const int fan = 22; //pin D2 (fan) float temp; //temperature value

int threshold = 21; //temperature threshold

const int LDRsensor = 1; //pin A1 (lighting sensor)
const int LED1 = 6; //pin D6 (LED 1)
const int LED2 = 7; //pin D7 (LED 2)
const int LED3 = 8; //pin D8 (LED 3)
const int LED4 = 9; //pin D9 (LED 4)
const int WL_sensor = 15; //pin A15 (water level sensor)
const int Wpump = 13; //pin D13 (water pump)
const int mov_sensor = 3; //pin D3 (movement sensor)
const int LEDalrm = 4; //pin D4 (alarm LED)
const int buzzer = 5; //pin D5 (buzzer)

int LDRvalue; //natural light value
float water_level; //water level value
int mov_value; //movement value (true or false)

char state; //data sent from App
char mode;   //mode selected according to "state" value char order; //order to actuators according to "state" value

void setup() //this function is only executed one time
{
    lcd.begin(16, 2);
    lcd.setBacklightPin(3, POSITIVE);
    lcd.setBacklight(HIGH);

    lcd.setCursor(0, 0);
    lcd.print("TFG");
    lcd.setCursor(0, 1);
    lcd.print("Anna Merino");

    delay(4000);

    lcd.clear();

    pinMode(temp_sensor, INPUT); //temperature sensor Mode
    pinMode(fan, OUTPUT); //fan Mode
    pinMode(LDRsensor, INPUT); //lighting sensor Mode
    pinMode(LED1, OUTPUT); //LED1 Mode
    pinMode(LED2, OUTPUT); //LED2 Mode
    pinMode(LED3, OUTPUT); //LED3 Mode
    pinMode(LED4, OUTPUT); //LED4 Mode
    pinMode(WL_sensor, INPUT); //water level sensor Mode
    pinMode(Wpump, OUTPUT); //water pump Mode
    pinMode(mov_sensor, INPUT); //movement sensor Mode
    pinMode(LEDalrm, OUTPUT); //alarm LED Mode
    pinMode(buzzer, OUTPUT); //buzzer Mode

    BT.begin(9600); //set data rate in bits per second (baud) for data transmission
}

void loop() //function loop – continuously executed
{
    if (BT.available() > 0)
    {
        state = BT.read(); //transfer data sent by App to a local variable
    }

    if (state == 'Y')
    {
        mode = 'A';
    }
    else if (state == 'Z')
    {
        mode = 'R';
    }
    else if (state == 'X')
    {
        mode = 'D';
    }

    if (mode == 'A')
    {
        automaticmode(); //execute automatic function
    }
    else if (mode == 'R')
    {
        remotemode(); //execute remote function
    }
    else if (mode == 'D')
    {
        alarmmode(); //execute alarm function
    }
}

void alarmmode() // alarm function
{
    water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable

    if (digitalRead(mov_sensor)) //evaluate movement captured
    {
        digitalWrite(LEDalrm, HIGH);
        digitalWrite(buzzer, HIGH);
    }
    else
    {
        digitalWrite(LEDalrm, LOW);
        digitalWrite(buzzer, LOW);
    }
    if (water_level > 100) //water level control
    {
        digitalWrite(Wpump, HIGH);
    }
    else
    {
        digitalWrite(Wpump, LOW);
    }
}

void automaticmode() // automatic function
{
    LDRvalue = analogRead(LDRsensor); //data of natural light transmission to a local variable water_level = analogRead(WL_sensor); //data of water level sensor transmission to a local variable
    temp = analogRead(temp_sensor); //data of temperature sensor transmission to a local variable temp = temp*0.4883; //adjustment of temperature value digitalWrite(LEDalrm, LOW);

    digitalWrite(buzzer, LOW);

    lcd.setCursor(0, 0);
    lcd.print("Temperature");

    lcd.setCursor(0, 1);
    lcd.print(temp); //LCD display – shows temperature value

    lcd.setCursor(7, 1);
    lcd.print("ºC");

    if (water_level > 100) //water level control
    {
        digitalWrite(Wpump, HIGH);
    }
    else
    {
        digitalWrite(Wpump, LOW);
    }

    if ((LDRvalue < 1023) & (LDRvalue >= 822)) //light control
    {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 821) & (LDRvalue >= 617))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 616) & (LDRvalue >= 412))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
    else if ((LDRvalue < 411) & (LDRvalue >= 206))
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, LOW);
    }
    else if (LDRvalue < 205)
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, HIGH);
    }

    if (temp >= threshold) //temperature control
    {
        digitalWrite(fan, HIGH);
    }
    else if (temp < threshold)
    {
        digitalWrite(fan, LOW);
    }
}

void remotemode() // remote function
{
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);

    digitalWrite(fan, LOW);
    digitalWrite(Wpump, LOW);
    digitalWrite(LEDalrm, LOW);
    digitalWrite(buzzer, LOW);

    if (BT.available() > 0)
    {
        state = BT.read(); //transfer data sent by App to a local variable
    }

    if (state == 'D') //actuators operation according to orders received
    {
        digitalWrite(LED1, LOW);
    }
    else if (state == 'C')
    {
        digitalWrite(LED1, HIGH);
    }
    else if (state == 'F')
    {
        digitalWrite(LED2, LOW);
    }
    else if (state == 'E')
    {
        digitalWrite(LED2, HIGH);
    }
    else if (state == 'H')
    {
        digitalWrite(LED3, LOW);
    }
    else if (state == 'G')
    {
        digitalWrite(LED3, HIGH);
    }
    else if (state == 'J')
    {
        digitalWrite(LED4, LOW);
    }
    else if (state == 'I')
    {
        digitalWrite(LED4, HIGH);
    }
    else if (state == 'L')
    {
        digitalWrite(fan, LOW);
    }
    else if (state == 'K')
    {
        digitalWrite(fan, HIGH);
    }
    else if (state == 'N')
    {
        digitalWrite(Wpump, LOW);
    }
    else if (state == 'M')
    {
        digitalWrite(Wpump, HIGH);
    }

    if (state == 'O')
    {
        digitalWrite(LED1, HIGH);
        digitalWrite(LED2, HIGH);
        digitalWrite(LED3, HIGH);
        digitalWrite(LED4, HIGH);
    }
    else if (state == 'P')
    {
        digitalWrite(LED1, LOW);
        digitalWrite(LED2, LOW);
        digitalWrite(LED3, LOW);
        digitalWrite(LED4, LOW);
    }
}

```

In future, when posting a question, please also list *WHICH* libraries you are using. e.g. there is more than one `LiquidCrystal_I2C` library... and probably only one right one. Also, that will only be part of the error message. Give the entire message - as the end bit isn't of much use!
> 1 votes

---
Tags: arduino-mega
---


title: Sending Strings from NRF24L01 to app

text:
# Question
Title: Sending Strings from NRF24L01 to app
I want to send pushbutton status from the nrf24l01 module to the app named nrfConnect. I could only find libraries that allow me to send float values. How could I send String values to the app? Thank You!

# Answer
> 1 votes
nRF Connect is for Bluetooth LE devices, the nRF24L01+ is really not a Bluetooth Low Energy transceiver.

The best the nRF24L01+ can do is make a few Bluetooth LE advertisements but that's very finicky. Here's a long description how: https://dmitry.gr/index.php?r=05.Projects&proj=15&proj=11.%20Bluetooth%20LE%20fakery

---
Tags: arduino-uno, bluetooth, nrf24l01+, wireless, ble
---


# Question
Title: How do I serial print a constant single string and a changing variable within it?
I want to print a single line including the variable "val" only once rather than looping or repeating of the same line and within it the val will change according to the reading. Is it possible? If so, how?

```
#define trigPin 5
#define echoPin 6

float distance(uint8_t T, uint8_t H);

void setup()
{
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    Serial.begin(9600);
    Serial.print("The object is: ");
}

void loop()
{
    float val = distance(32, 68);
    Serial.print(val);
    Serial.println(" cm away");
    delay(500);
}

```

# Answer
> within it \[the already printed line\] the val will change according to the reading

This “within it” makes little sense. “Printing” is just sending bytes through the serial port, and you don't choose where these bytes are going: you just send them one at a time. The program you use as a “serial port monitor” then displays those bytes in whatever manner it sees fit. You cannot control from the Arduino where things get displayed.

Or maybe you can...

If your monitor program can emulate an old school terminal, then it can understand special control sequences, including escape codes, that instruct it to perform specific actions, such as moving the cursor or erasing part of the screen. Suitable terminal emulators include screen on Linux and MacOS, and Putty on Windows. You may find something appropriate for your mobile platform. Notably, the Arduino serial monitor is *not* a terminal emulator, and doesn't interpret those control sequences.

Assuming you are using a suitable terminal emulator, the simplest solution to your problem is to just repeat the whole sentence “The object is: xx.xx cm away” for every measurement, but do so by overwriting the current line instead of moving to the next one. You thus replace `Serial.println()` by `Serial.print()`, and precede each sentence by a carriage return character (ASCII CR = `0x0d` = `'\r'`), which is interpreted as the command “move the cursor to the start of the line”:

```
void loop() {
    float val = distance(32, 68);
    Serial.print("\rThe object is: ");  // note the '\r'
    Serial.print(val);
    Serial.print(" cm away");  // no println()
    delay(500);
}

```

There is a caveat here. If you overwrite a sentence (say “The object is: 10.07 cm away”) by a shorter one (“The object is: 9.92 cm away”, one character less), the previous sentence will not be completely overwritten, so you may end up with “awayy” showing on the display. This can be overcome by ensuring a fixed-length formatting of the numbers displayed, by padding with spaces, or by sending an “erase current line” command to the terminal.

As a side note, what `Serial.println()` does is print what you requested, followed by a CR character, and then a line feed character (ASCII LF = `0x0a` = `'\n'`). The line feed is interpreted by the terminal as the command “move the cursor to the next line, without changing its horizontal position”.

If you find it annoying to repeatedly print “The object is:”, you can instead use more advanced control sequences. For instance:

* “\<ESC\>\[16G” means “move the cursor to column 16”
* “\<ESC\>\[K” means “clear from the cursor to the end of the line”

where \<ESC\> is the escape character:

```
void loop() {
    float val = distance(32, 68);
    Serial.print("\x1b[16G\x1b[K");  // "\x1b" is the escape character
    Serial.print(val);
    Serial.print(" cm away");
    delay(500);
}

```
> 1 votes

---
Tags: serial
---


title: Convert Binary to char

text:
# Question
Title: Convert Binary to char
I'm reading a text file saved on my ESP8266 device (using `LittleFS`).

```
while (myFile.available()) {
        Serial.write(myFile.read());
    }

```

My goal is to save file content ( each line ) to a `String` / `char` array. `myFile.read()` returns a binary - and I'm looking for a quick and elegant way to do so ( as in `Serial.write` which converts it to text ).

Guy

# Answer
> 2 votes
`myFile.read()` returns one character. That character can be represented as a number (such as 65 for 'A') or a character, or whatever you want. Everything is just a number.

Letters are just our personal representation of certain numbers as humans. You could think of it as the numbers represented in base 256, where each value between 0 and 255 is assigned a unique symbol.

`Serial.write()` just passes that number verbatim to the computer which then maps it in the serial monitor to the corresponding letter in the ASCII table.

Thanks to the object-oriented and polymorphic nature of the Arduino API (see C++ Polymorphism) there is no difference between reading from a file and reading from serial. They all inherit the same `Stream` class that gives you the same functions regardless of what you're reading.

So you could, like Serial, read each byte from the file one at a time until you reach the line ending character(s) (`\n` for a Unix file, or `\r\n` for a Windows file) and append each to the end of a string (either a `String` object, which is frowned upon, though less so on more capable MCUs like the ESP8266 and ESP32, or a `char` array).

Alternatively you could use one of the helper functions of the `Stream` class, such as `readStringUntil()`, which reads an entire string up to (and discarding) the specified terminating character and returns a `String`.

However both those have problems when it comes to building up an array of all the results, especially if you don't know beforehand how many lines there are in the file - since in C++ arrays have a fixed size.

A better solution, if you really *do* want it all in RAM (see below), might be instead to, at first, forget the idea of lines and just read the entire file into memory. Once it is in memory you can read through the entire block of data counting the number of `\n` bytes (and add one if it doesn't end with `\n`). That will give you the number of lines in the file.

You can then allocate an array of pointers with the same number of entries as there are lines.

From there you can use `strtok()` on the data to split it into chunks on the `\n` bytes and assign each chunk to one of the pointers in your array. That array then becomes a kind of index to the data.

But one has to ask... why do you want to store this data in RAM anyway? You have it in flash, and that is quite fast to access (not as fast as internal flash in a traditional MCU, but still many times faster than an SD card for example). If ease of navigating the data is your goal, maybe you should be thinking of better ways of storing your data. Depending on what that data is maybe a fixed size record based file structure using a `struct` to manipulate the data would be a better solution - then you can just seek to multiples of the record (or struct) size to almost instantly get to different entries in the file.

If it's textual data then maybe reading through the file and recording the file offsets of the start of each line in an array (note: two passes - one to count the lines for allocating the array and one for recording the offsets into the array) similar to the indexing of the data block described above would be a better solution. That way you're only storing 4 bytes per entry in your array rather than all the data. Seeking is instant (just seek to the offset stored in the array for the line you want) and you're not having to store all the data in RAM.

---
Tags: string, spiffs
---


# Question
Title: Timer question: Phase Correct PWM at specific frequency
I am trying to create a sinusoidal wave segmented in 64 **Frame**, each holding a **Duty cycle** precisely varying from 0x00 to 0xff. This is for an Arduino Nano.

I have trouble understanding the following:

* Which Wave Generator Mode and Matches will cause an interrupt at the constant **Frame** as well as help do a phase correct/fast PWM for the varying **Duty Cycle**?
* How to tell which pin to use? I guess OC0B means Pin5 according to Pin Mapping but I'm not sure I truly understand.

This is what I have for the moment.

```
const byte waveFrame = 126;
const byte wave[]    = {
    0x80,0x98,/*a total of 64 values*/,0x67
};
byte frame = 0;
void setup(){
    pinMode(3,OUTPUT);
    noInterrupts();
    TCCR0A = (1<< WGM00)  // Phase correct PWM with top as OCR0A
           | (1<<COM0A0)  // Toggle OC0A on match
           | (1<<COM0B1); // Clear/Set OC0B on Compare Match when up/down-counting.
    TCCR0B = (1<<  CS01); // Prescaler of 8 (16MHz/8= 2MHz)
    TCNT0  = 0;           // Counter restarted
    OCR0A  = waveFrame;   // Constant frequency/64 for each frame
    OCR0B  = 0;           // Duty Cycle
    interrupts();
}
ISR(TIMER2_COMPA_vect){
    OCR0B = wave[frame & 0x3f]; //Rolls around
    frame++;
}

```

Thank you! I've lost a little bit of hair on this.

# Answer
> 2 votes
> pinMode(3,OUTPUT);

Pin 3 on the Nano is `OC2B`. It's PWM is controlled by Timer 2. You want to use pin 5 (`OC0B`), since you are using Timer 0. Or switch to Timer 2.

> Phase correct PWM with top as OCR0A

Note that this is the description of mode 5. If you want this mode, you have to set both the bit `WGM00` in `TCCR0A` (which you did) and the bit `WGM02` in `TCCR0B` (which you didn't). Here you have set mode 1: phase correct PWM with top = 0xff.

---
Tags: interrupt, pwm, timers, wave
---


title: Missing ACKs on I²C

text:
# Question
Title: Missing ACKs on I²C
I am using a GY-521 accelerometer as well as BMP280 pressure sensors via I²C on an ESP8266.

When I analyze I²C data with the oscilloscope, I can see missing ACKs on both of them as shown in the pictures.

Is that something to worry about or is it just normal, considering I bought cheap Chinese sensors?

My BMP280 code is this:

```
// https://github.com/mahfuz195/BMP280-arduino-library
#include <BMP280.h>
BMP280 bmp280;

#include "Wire.h"
TwoWire i2c = TwoWire();

// Hardware setup
#define CLOCK_PIN D1
#define DATA_PIN D2
#define I2C_SPEED 400000

// I²C response codes
#define FOUND 0
#define NORESPONSE 2

bool sensorAvailableAt(byte address)
{
   i2c.beginTransmission(address);
   byte response = i2c.endTransmission();
   return response == FOUND;
}

void stop(char* message){
  Serial.println(message);
  while(true);
}

void setup() {
  Serial.begin(115200);
  while(!Serial){} // Waiting for serial connection

  i2c.begin(DATA_PIN, CLOCK_PIN, I2C_SPEED);
  if (!sensorAvailableAt(0x76))
  {
    stop("BMP280 sensor not found");
  }

  if (bmp280.begin())
  {
    Serial.println("BMP280 init success");
  }
  else
  {
    stop("BMP280 initialization failed.");
  }
}

void loop() {
  double temperature;
  double pressure;
  bmp280.getTemperatureAndPressure(temperature, pressure);
  double sealevel = bmp280.sealevel(pressure, 800);

  Serial.print("Temperature: ");
  Serial.print(temperature,1);
  Serial.println(" °C");

  Serial.print("Pressure: ");
  Serial.print(pressure, 1);
  Serial.println(" mbar (absolute)");

  Serial.print("Pressure: ");
  Serial.print(sealevel);
  Serial.println(" mbar (sealevel, compensated for 800 m height)");

  delay(50);
}

```

# Answer
> 4 votes
The NACK at the end of a master read/slave send transmission is normal expected behavior.

In I2C communication the acknowledgement is a possibility to react to send data. For example, when the slave sends a NACK while the master sends data to it, it might be, because it currently cannot process further data. Acknowledgement goes in both ways, depending on the direction of transmission. The reader always needs to acknowledge the data to mark a successful transmission. It is normal for the master to send a NACK on the end of it's reading cycle to mark, that it doesn't want to receive more data. While this isn't strictly logically needed (since the end of a transmission is marked by the master by a STOP or RESTART condition), it is done nonetheless.

I think I have also seen this behavior with the `Wire` library of Arduino. So it comes down to the implementation of the I2C protocol in your case. As your library simply uses the `Wire` library, the behavior is not part of it. The I2C protocol is implemented by `Wire`. You would see the same behavior in every sensor library, that uses the `Wire` library.

You can read more about the I2C protocol at this site.

---
Tags: esp8266, i2c
---


# Question
Title: Do I need a resistor to control a servo with a PWM signal?
I working with Arduino Nano Every that has several analog PWM pins. I want to use one to control a small servo.

Do I need to put a resistor between PWM pin and the servo signal?

# Answer
> 2 votes
No, you don't.

Resistors are used to limit and control current (amongst other things) and you don't need to do that when sending a signal from one digital device to another.

---
Tags: pwm, resistor, pcb-design
---


# Question
Title: How do I make my LCD screen scroll text while allowing for button input?
Here's what I want my code to do: This is part of a tea infusing project that would automate the steeping of tea, part of this is initially having a selection of either Black/Herbal tea or White/Green tea, this will then set off several other factors down the timeline. I want my LCD screen to display and scroll "Please select a tea" while still being able to take in pushbutton input.

I've been doing this all day, and I've tried several things. I firstly tried using a normal delay function so my text could scroll properly, but the problem with that is that it halts all the code and doesn't allow for any other input, so I quickly found millis() was likely what I needed to use. However, when I try to apply it to this specific example, it just scrolls all my text extremely quickly through the LCD. Perhaps I'm being stupid and ignoring something obvious, but please let me know.

```

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

const int black_herbal_osb = 2;

int black_select;

//Timing
unsigned long prev_millis;
unsigned long current_millis;
const unsigned long LCD_delay = 500;

void setup() {

  //Tea selection buttons
  pinMode(black_herbal_osb, INPUT);

  //LCD screen setup
  lcd.init();
  lcd.backlight();

}

void loop() {

  lcd.autoscroll();
  lcd.setCursor(16, 0);
  lcd.print("Please");

  current_millis = millis();

  black_select = digitalRead(black_herbal_osb);

  if (black_select != HIGH) {

    if (current_millis - prev_millis >= LCD_delay) {
      lcd.print(" select ");
      prev_millis = current_millis;
    }
    if (current_millis - prev_millis >= LCD_delay * 2) {
      lcd.print("a ");
      prev_millis = current_millis;
    }
    if (current_millis - prev_millis >= LCD_delay * 3) {
      lcd.print("tea ");
      prev_millis = current_millis;
    }
  }

  else if (black_select == HIGH) {
    lcd.clear();
    lcd.autoscroll();
    lcd.setCursor(16, 0);
    lcd.print("Black/Herbal ");
    delay(500);
    lcd.print("tea ");
    delay(500);
    lcd.print("selected");
    delay(2000);
    lcd.noAutoscroll();
    lcd.clear();
  }

}

```

# Answer
> 0 votes
I figured it out. I was thinking about it all wrong, I just needed to figure out how the scrolling worked for the LCD and the rest was much easier. Only current issue with my code is that on the initial scroll of "Please select a tea" right after the "Booting..." process, it doesn't seem to start at (16,0) but nearer to the front which makes it not super easy to read initially but it corrects itself after a single scroll.

Here's the code for those interested:

```
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);

const int black_herbal_pin = 2;
const int white_green_pin = 3;
const int LCD_scroll = 200;

int black_select;
int white_select;

unsigned long current_millis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previous_scroll_millis = 0;

void setup() {
  Serial.begin(9600);
  //Tea selection buttons
  pinMode(black_herbal_pin, INPUT);
  pinMode(white_green_pin, INPUT);

  //LCD screen setup
  lcd.init();
  lcd.backlight();

}

void loop() {

  if (current_millis == 0) {
    lcd.setCursor (0, 0);
    lcd.print("Booting");
    delay(500);
    lcd.print(".");
    delay(500);
    lcd.print(".");
    delay(500);
    lcd.print(".");
    delay(1000);
    lcd.clear();
  }

  lcd.setCursor(16, 0);
  lcd.print("Please select a tea ");

  current_millis = millis();
  for (int position_counter = 0; position_counter < 16; position_counter++) {

    if (current_millis - previous_scroll_millis >= LCD_scroll) {
      lcd.scrollDisplayLeft();

      previous_scroll_millis += LCD_scroll;
    }
  }

  if (digitalRead(black_herbal_pin) == HIGH) {
    lcd.clear();
    lcd.setCursor (16, 0);
    lcd.print("Black/Herbal tea selecte");
    for (int position_counter = 0; position_counter < 26; position_counter++) {
      lcd.setCursor (0, 0); //This part is likely not necessary for you as it seems to be a bug within my own LCD
      lcd.print("d"); // without this it prints "d" on the second row
      lcd.scrollDisplayLeft();
      delay (150);
    }

    delay(2000);
    lcd.clear();
  }

  if (digitalRead(white_green_pin) == HIGH) {
    lcd.clear();
    lcd.setCursor (16, 0);
    lcd.print("White/Green tea selected");
    for (int position_counter = 0; position_counter < 26; position_counter++) {
      lcd.scrollDisplayLeft();
      delay (150);
    }

    delay(2000);
    lcd.clear();
  }

}

```

# Answer
> 0 votes
See my answer to a similar question \- about motors but the idea is the same. You call a function for each piece of the job that needs to be done. The function itself decides whether it needs to be done yet, and if so, does it and returns, otherwise it just returns. The loop() function just calls all your other action functions and *does nothing else* -- all of the real work takes place in those functions.

Looking at your scrolling code, I think one function could print successive pieces of the message by remembering what did last. Another could read and debounce the button(s) and save its/their state.

And once you get to controlling the infusing process, one (or maybe more) functions could be used to control that.

---
Tags: arduino-uno, lcd, button, timing
---


# Question
Title: Check if any of loop's insides returns 1 and hold it until the whole loop is 0 again
I'm new to this, so, please, don't crucify me.

I have a function that checks if an entry in multilevel array is in a certain range. Using FOR loop I check the whole array with this function, which gives me true/false value for each record.

And now the problem: I need to check if ANY entry in that loop returns true and hold it until every result of that loop is false again.

Any tips?

Thanks a lot.

There is my for loop:

```
  for(int i = 0; i < arrayTop; i++){
for(int j = 0; j < arrayDay; j++){
  for(int k = 0; k < arrayTime; k++){
    timeCompare(timeArray[i][j][k][0], timeArray[i][j][k][1], timeArray[i][j][k][2], timeArray[i][j][k][3], timeArray[i][j][k][4], timeArray[i][j][k][5], timeArray[i][j][k][6]);

    //Serial.print(i);Serial.print(j);Serial.print(k);Serial.print(" ");
    Serial.println(compareVar);

    if(i == 0){

      //set water switch
      if(compareVar == 1){
        waterOn = 1;
        Serial.println("Water ON");

        goto bailout;
      }
      else {
        waterOn = 0;
        Serial.println("water OFF");
      }
    }
    else if(i == 1){

      //set light switch
      if(compareVar == 1){
        lightOn = 1;
        Serial.println("Light ON");
        goto bailout;
      }
      else {
        lightOn = 0;
        Serial.println("light OFF");
      }
    }
  }
}

```

} bailout:

and this is the called function:

```
//time compare with ON/OFF switch
int timeCompare(int hrOn, int minOn, int secOn, int hrOff, int minOff, int secOff, int timerSwitch){
  unsigned long int onTime = (hrOn*10000UL) + (minOn*100UL) + secOn;
  unsigned long int offTime = (hrOff*10000UL) + (minOff*100UL) + secOff;
  unsigned long int currentTime = (dt.hour*10000UL) + (dt.minute*100UL) + dt.second;

  if(timerSwitch == 1){
    if(onTime < currentTime && offTime > currentTime){
      compareVar = 1;
    }
    else {
      compareVar = 0;
    }
  }
 else if(timerSwitch == 0) {
    compareVar = 0;
  }

  //Serial.print("compare: "); Serial.println(compareVar);

}

```

# Answer
> 0 votes
First, you should really not use a global variable to get the result of your comparison function. That is only confusion and unnecessary complicated code. For that we have return values. So instead of setting the `compareVar` variable inside the `timeCompare()` function, you should just return the corresponding value. In the `timeCompare()` function replace

```
compareVar = 1;

```

with

```
return 1;

```

and

```
compareVar = 0;

```

with

```
return 0;

```

Then in your main code: As I understood, you only need `compareVar` in the for loops, so you could delete the globally defined `compareVar` and declare it directly before the for loops:

```
int compareVar = 0;

```

Now we can do the magic trick. We want to go through our for loops and get a result of `1`, if for any of the elements `timeCompare()` returns 1. For that we just doing an OR operation:

```
compareVar = compareVar || timeCompare(timeArray[i][j][k][0], timeArray[i][j][k][1], timeArray[i][j][k][2], timeArray[i][j][k][3], timeArray[i][j][k][4], timeArray[i][j][k][5], timeArray[i][j][k][6]);

```

This is a boolean OR `||`. In C++ zero is treated as `false`, while any other number is treated as `true`. We are starting with `compareVar` begin zero. When `timeCompare()` for the element returns also zero, it stays zero. If it returns 1, `compareVar` will become 1. If it returns 1 again, it will stay one. If it returns zero, it will stay zero.

So now you can check for `compareVar` after the for loops. It will be 1, if any of the elements gave you 1.

Similarly you could check for all elements returning 1, if you replace the OR `||` by an AND `&&` operation.

---

Lastly I want to strongly discourage you from using `goto`. It ignores some important principles and you can easily create really bad code with it. Refer to questions like this one to read more about it. I would say, that in every case you have better ways than `goto`. Here it seems, that you simply want to go out of both loops. I would pack these loops into a function, so that you could simply use a `return` statement to get out of them.

---
Tags: array, loop
---


title: Arduino I2C Multiplexing uisng TCA9548A

text:
# Question
Title: Arduino I2C Multiplexing uisng TCA9548A
I am using 5 sensors out of which two have the same I2C address and are connected via TCA9548 multiplexer. The remaining 3 sensors are connected to the main arduino I2C bus. In example sketches online I see the following function to choose the specific port/channel on the multiplexer:

```
#define MPLXADR 0x70 // Address of TCA9548A I2C Multiplexer
void multiplexer (uint8_t ch) {
  if (ch > 7) return;
  Wire.beginTransmission(MPLXADR);
  Wire.write(1 << ch);
  Wire.endTransmission();
}

```

I understand that this function should be called before executing instructions for the sensors with shared address but how would it still send the data to the right sensor when the last line "Wire.endTransmission();" just closes connection?

Since in my circuit there are sensors which are connected directly to the arduino I2C bus, I wonder if the code related to those sensors comes after the code for sensors with shared address, wouldn't those instructions also be sent to the ensors with shared I2C address? To me it makes more sense if the instructions for the shared address sensors are enclosed inside the above mentioned function as follows:

channel select -\> execute instruction -\> end transmission

But the usage I see in the tutorials baffles me. Could somebody please clarify these points? Thanks

Here is the complete sketch I am using:

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

Adafruit_BME280 bme1; // on Arduino I2C bus
Adafruit_BME280 bme2; // on multiplexer I2C bus
Adafruit_BME280 bme3; // on mulitplexer I2C bus
AHT10 AHT(AHT10_ADDRESS_0X38); // on Arduino I2C bus
HDC2080 HDC2080(0x41);// on Arduino I2C bus

#define MPLXADR 0x70 // Address of TCA9548A I2C Multiplexer
void multiplexer (uint8_t ch) {
  if (ch > 7) return;
  Wire.beginTransmission(MPLXADR);
  Wire.write(1 << ch);
  Wire.endTransmission();
}

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

  while (AHT.begin() != true)
  {
    Serial.println(F("AHT10 not connected or fail to load calibration coefficient"));
    delay(5000);
  }
  Serial.println(F("AHT10 OK"));

  HDC2080.begin();

  // Begin with a device reset
  HDC2080.reset();

  // Set up the comfort zone
  HDC2080.setHighTemp(28);         // High temperature of 28C
  HDC2080.setLowTemp(22);          // Low temperature of 22C
  HDC2080.setHighHumidity(55);     // High humidity of 55%
  HDC2080.setLowHumidity(40);      // Low humidity of 40%

  // Configure Measurements
  HDC2080.setMeasurementMode(TEMP_AND_HUMID);  // Set measurements to temperature and humidity
  HDC2080.setRate(ONE_HZ);                     // Set measurement frequency to 1 Hz
  HDC2080.setTempRes(FOURTEEN_BIT);
  HDC2080.setHumidRes(FOURTEEN_BIT);

  //begin measuring
  HDC2080.triggerMeasurement();
  Serial.println();

  Serial.println(F("BME280 test"));

  //BME280 sensor 1
  multiplexer(0);
  if (! bme1.begin(0x77, &Wire)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // weather monitoring
  Serial.println("-- Weather Station Scenario --");
  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  Serial.println("filter off");
  bme1.setSampling(Adafruit_BME280::MODE_FORCED,
                   Adafruit_BME280::SAMPLING_X1, // temperature
                   Adafruit_BME280::SAMPLING_X1, // pressure
                   Adafruit_BME280::SAMPLING_X1, // humidity
                   Adafruit_BME280::FILTER_OFF   );

  //BME280 sensor 2
  multiplexer(1);
  if (! bme2.begin(0x77, &Wire)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

  // weather monitoring
  Serial.println("-- Weather Station Scenario --");
  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  Serial.println("filter off");
  bme2.setSampling(Adafruit_BME280::MODE_FORCED,
                   Adafruit_BME280::SAMPLING_X1, // temperature
                   Adafruit_BME280::SAMPLING_X1, // pressure
                   Adafruit_BME280::SAMPLING_X1, // humidity
                   Adafruit_BME280::FILTER_OFF   );

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

  // weather monitoring
  Serial.println("-- Weather Station Scenario --");
  Serial.println("forced mode, 1x temperature / 1x humidity / 1x pressure oversampling,");
  Serial.println("filter off");
  bme3.setSampling(Adafruit_BME280::MODE_FORCED,
                   Adafruit_BME280::SAMPLING_X1, // temperature
                   Adafruit_BME280::SAMPLING_X1, // pressure
                   Adafruit_BME280::SAMPLING_X1, // humidity
                   Adafruit_BME280::FILTER_OFF   );

  // suggested rate is 1/60Hz (1m)
 }

void loop() {
  bme3.takeForcedMeasurement(); // has no effect in normal mode
  printValuesBME3();
  delay(5000);

  printValuesAHT();
  delay(5000);

  printValuesHDC2080();
  delay(5000);

  multiplexer(0);
  bme1.takeForcedMeasurement(); // has no effect in normal mode
  printValuesBME1();
  delay(5000);

  multiplexer(1);
  bme2.takeForcedMeasurement(); // has no effect in normal mode
  printValuesBME2();
  delay(10000);
}

void printValuesBME1() {

  Serial.println();
  Serial.print("BME1 Readings");

  Serial.print("Temperature = ");
  Serial.print(bme1.readTemperature());
  Serial.println(" *C");

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

  Serial.println();
}

void printValuesBME2() {

  Serial.println();
  Serial.print("BME2 Readings");

  Serial.print("Temperature = ");
  Serial.print(bme2.readTemperature());
  Serial.println(" *C");

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

  Serial.println();
}

void printValuesBME3() {

  Serial.println();
  Serial.print("BME3 Readings");

  Serial.print("Temperature = ");
  Serial.print(bme3.readTemperature());
  Serial.println(" *C");

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

  Serial.println();
}

void printValuesHDC2080() {
  Serial.println("HDC2080 Values");
  Serial.print("Temperature (C): "); Serial.print(HDC2080.readTemp());
  Serial.print("\t\tHumidity (%): "); Serial.println(HDC2080.readHumidity());
}

void printValuesAHT() {

  Serial.println(F("AHT10: read 12-bytes, show 255 if communication error is occurred"));
  Serial.print(F("Temperature: ")); Serial.print(AHT.readTemperature()); Serial.println(F(" +-0.3C")); //by default "AHT10_FORCE_READ_DATA"
  Serial.print(F("Humidity...: ")); Serial.print(AHT.readHumidity());    Serial.println(F(" +-2%"));   //by default "AHT10_FORCE_READ_DATA"
}

```

# Answer
The TCA9548 is a switch.

You begin a transaction to it, change the channel that it allows through, and then end *that specific transaction.*

From that point on one and only one of the other two sensors are attached to your bus - the other doesn't exist. When you communicate on the address of that sensor it passes through the TCA9548 as if it doesn't exist.

You can think of the TCA9548 as a controller that sits *next to* the switch:

simulate this circuit – Schematic created using CircuitLab

Send channel 0 and it flips the switch one way. Send channel 1 and it flips the switch the other way. Once the switch is flipped it stays flipped until you tell it otherwise.

From your sketches perspective the two HDC2080s on the MUX are only one HDC2080. You just flip the switch to the right position to access the specific physical device you want at the time.
> 2 votes

---
Tags: arduino-uno, i2c, multiplexer
---


title: Code for 2 ultrasonic sensors

text:
# Question
Title: Code for 2 ultrasonic sensors
This is my code:

```
int trigPin=13; //Sensor Trig pin connected to Arduino pin 13
int echoPin=11;  //Sensor Echo pin connected to Arduino pin 11
float pingTime;  //time for ping to travel from sensor to target and return
float targetDistance; //Distance to Target in inches
float speedOfSound=776.5; //Speed of sound in miles per hour when temp is 77 degrees.
int trigPin1=2;
int echoPin1=3;
float pingTime1;  //time for ping to travel from sensor to target and return 1
float targetDistance1; //Distance to Target in inches 1
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
}

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

  digitalWrite(trigPin, LOW); //Set trigger pin low
  delayMicroseconds(2000); //Let signal settle
  digitalWrite(trigPin, HIGH); //Set trigPin high
  delayMicroseconds(15); //Delay in high state
  digitalWrite(trigPin, LOW); //ping has now been sent
  delayMicroseconds(10); //Delay in low state
  digitalWrite(trigPin1, LOW); //Set trigger pin low
  delayMicroseconds(2000); //Let signal settle
  digitalWrite(trigPin1, HIGH); //Set trigPin high
  delayMicroseconds(15); //Delay in high state
  digitalWrite(trigPin1, LOW); //ping has now been sent
  delayMicroseconds(10); //Delay in low state

  pingTime1 = pulseIn(echoPin1, HIGH);  //pingTime is presented in microceconds
  pingTime1=pingTime1/1000000; //convert pingTime to seconds by dividing by 1000000 (microseconds in a second)
  pingTime1=pingTime1/3600; //convert pingtime to hourse by dividing by 3600 (seconds in an hour)
  targetDistance1= speedOfSound * pingTime;  //This will be in miles, since speed of sound was miles per hour
  targetDistance1=targetDistance1/2; //Remember ping travels to target and back from target, so you must divide by 2 for actual target distance.
  targetDistance1= targetDistance*63360;    //Convert miles to inches by multipling by 63360 (inches per mile)
  pingTime = pulseIn(echoPin, HIGH);  //pingTime is presented in microceconds
  pingTime=pingTime/1000000; //convert pingTime to seconds by dividing by 1000000 (microseconds in a second)
  pingTime=pingTime/3600; //convert pingtime to hourse by dividing by 3600 (seconds in an hour)
  targetDistance= speedOfSound * pingTime;  //This will be in miles, since speed of sound was miles per hour
  targetDistance=targetDistance/2; //Remember ping travels to target and back from target, so you must divide by 2 for actual target distance.
  targetDistance= targetDistance*63360;    //Convert miles to inches by multipling by 63360 (inches per mile)

  Serial.println(targetDistance);

  Serial.println(targetDistance1);

  delay(100); //delay tenth of a  second to slow things down a little.
}

```

Python code:

```
import serial #Import Serial Library

arduinoSerialData = serial.Serial('com3',9600) #Create Serial port object called arduinoSerialData

while (1==1):
    if (arduinoSerialData.inWaiting()>0):
        myData = arduinoSerialData.readline()
        myData=str(myData)
        myData= myData.replace("b'",'')
        myData=myData.replace("\\r\\n'",'')
        if myData<"3":

            print( myData)

```

When I compile the sketch, it shows no error.But when I run the file in python, output=0.However, when they are run individually, python gives me a valid input.so is this code correct?Also, is there a way to call for the exact c++file in python?Thanks for the help!

# Answer
> 1 votes
You are trying to measure with 2 ultrasonic sensors at once. You cannot do that so easily. You need to measure sequentially for 2 reasons:

1. The ultrasonic sensors might get confused by the others signal
2. You will miss the pulse of the one sensor, while you are reading the pulse of the other via `pulseIn()`.

So the order of actions is like this:

1. Trigger sensor 1
2. Read sensor 1 with `pulseIn()`
3. Trigger sensor 2
4. Read sensor 2 with `pulseIn()`

---
Tags: arduino-uno, c++, python, hc-sr04
---


# Question
Title: ESP8266-01 Wifi module + Wifi shield not present + ESP8266-01 libraries not working?
I have Arduino IDE v. 1.8.13. I bought an ESP8266-01 module which I want to use in my Arduino-UNO board to send fingerprint registration confirmation (ID) via HttpClient to a xampp server since I dont want to store the fingerprint image in the database. My ESP connection is as below:

In the serial monitor, my AT commands work well when I connect the module to my wifi using AT+CWJAP="ssid","password".

When I upload my code, which is supposed to connect to wifi, it says WiFi shield not present. Im new to this, is there anything I am missing? Thanks in advance.

Here is my code:

```
#include <ArduinoHttpClient.h>
#include <WiFi101.h>
#include "arduino_secrets.h"
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

char serverAddress[] = "localhost/bel/arduino/scannerstatus/php";  // server address
int port = 80;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
  }

```

Basically, my uploaded code does not go past the wifi connection stage. Even though the AT commands individually can connect to wifi. I have tried different ESP8266 libraries and HttpClient libraries but they all seem to not connect to wifi. Is there any other way to call a php script from arduino without using wifi?

# Answer
> -1 votes
Can you please include some explanation of how the Arduino Uno and ESP8266-01 are connected. You will need to program for the ESP8266 ESP-01 module like shown below,

You will need to write code for the ESP module to connect to the WIFI and listen to its Serial Com Port. The ESP will need to handle the message interpretation & WIFI updating.

The Arduino Uni will not be capable of directly using the ESP-01 module as a WIFI shield. It will need to communicate with the ESP via a serial coms link, you will need to send commands that include instructions & a Message to the ESP from the Arduino.

https://create.arduino.cc/projecthub/jeffpar0721/add-wifi-to-arduino-uno-663b9e \- Link to the above image document, this should help explain my concept in more detail

I apologies if my comments above miss the point but with the amount of information provided I don't think I can help further.

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


# Question
Title: Anyone have example code for ESP32 as media controller for Android/iPhone Media Apps
There's actually another post with this very same topic but no answers on that post. Back in January of 2020, the last commenter said he had sample code and then he went dark without posting the actually code. The thread is here:

Want to create bluetooth audio control (volume up/down, play, pause, etc.) for smartphone

My problem is the exactly the same as the original post. Amazon and Aliexpress have literally hundreds of these "media buttons" that you can buy and pair via bluetooth with your Android or iOS. You can then playback media on iOS/Android and the "media buttons" can control the playback. Pretty common controls are volume up/down, next, previous, play and pause.

I've written a lot of Arduino code for Nano, Uno and even MKR. I've written a bunch of ESP8266 and ESP32 code as well. Usually when I try and learn something, a few google searches will find an example that I can figure out. For this, I've been able to find nothing.

Every tutorial or sample code is about how to send commands to the ESP32 via Bluetooth or pair an ESP32 with a bluetooth joystick, etc. None of those examples help me understand what's needed for an ESP32 to pair with my Android and act as media buttons, sending volume up, down and play/pause commands via bluetooth.

Can anyone help with example code for doing this with an ESP32? (by the way, this forum would not let me comment on the original post or I would have. it said I didn't have enough karma points or something)

# Answer
> 8 votes
Well after I posted this question, I kept googling. Literally hours of googling at this point. Then I stumbled across this example:

https://github.com/T-vK/ESP32-BLE-Keyboard

I wrote that sketch to my ESP32, paired my iPhone and it immediately starting controlling music playback on my phone. After looking at the code, it's so simple that I'm embarrassed I couldn't figure this out on my own. In case the link goes dead, I'll paste the code here:

```
#include

BleKeyboard bleKeyboard;

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  bleKeyboard.begin();
}

void loop() {
  if(bleKeyboard.isConnected()) {
    Serial.println("Sending 'Hello world'...");
    bleKeyboard.print("Hello world");

    delay(1000);

    Serial.println("Sending Enter key...");
    bleKeyboard.write(KEY_RETURN);

    delay(1000);

    Serial.println("Sending Play/Pause media key...");
    bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);

    delay(1000);

    Serial.println("Sending Ctrl+Alt+Delete...");
    bleKeyboard.press(KEY_LEFT_CTRL);
    bleKeyboard.press(KEY_LEFT_ALT);
    bleKeyboard.press(KEY_DELETE);
    delay(100);
    bleKeyboard.releaseAll();

  }
  Serial.println("Waiting 5 seconds...");
  delay(5000);
}

```

---
Tags: bluetooth, esp32
---


# Question
Title: Calling a localhost php script from arduino
Is it possible to connect arduino uno to call a php script using ONLY an arduino uno board, and an esp8266-01 wifi module.? That is, I lack wifi shield such as node MCU. I just need the setup to call a php script on my localhost server. I'm using arduino IDE 1.8.13. Gracias

# Answer
You can program the ESP-01 module using the arduino IDE. There are instructions in the README here: https://github.com/esp8266/Arduino

You can program the ESP-01 to connect to WiFi and communicate with your arduino sketch using the serial port. Don't forget the ESP-01 runs at 3.3V while the arduino runs at 5V. You'll need to shift the voltages somehow, otherwise you'll burn the arduino uno.

Here's an example of code you can run on the ESP-01 to connect to WiFi and start a TCP connection: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino

All that's missing is making an HTTP request instead of a "raw" TCP connection. You can probably find that in the examples. Then, add code for serial communication back to your arduino uno.

Good luck!
> 1 votes

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


# Question
Title: Issues with Arduino UNO printing repeated "double" on serial monitor
A weird is happening which i can't figure out why. First I had issue communicating with SIM800L. So i tried checking the USART Hardware to see what UNO sends to SIM800 using small piece attached below. The sketch is to compares what i send from serial monitor with strings "Hello", "heLLo" and "Hello" expecting to get Found .... or No match found. each line string i send, the serial monitor prints twice WHY?, The first says not found and the second say Received == ........ WHY?

\**See the output of serial terminal when i typed "Hello" with quotes.

```
12:03:46.536 -> Buffer Received= "  No match found
12:03:46.569 ->
12:03:46.569 -> Buffer Received= Hello"
12:03:46.603 ->     Found Hello
when i typed "HELLO" with quotes.
12:03:55.855 -> Buffer Received= "  No match found
12:03:55.888 ->
12:03:55.888 -> Buffer Received= HELLO"
12:03:55.921 ->     Found HELLO**

```

\****when i typed "heLLo" with quotes.

```
12:04:04.016 -> Buffer Received= "  No match found
12:04:04.049 ->
12:04:04.049 -> Buffer Received= heLLo"
12:04:04.082 ->     Found heLLo
12:04:04.115 ->****

```

When i typed without quotes, all i get No match found

```
char buffer[100];
uint8_t index=0;

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

void loop()
{
  if(Serial.available()>0)
  {
    index=0;
    while(Serial.available())
    {
      buffer[index++]=Serial.read();
    }

    buffer[index]='\0';
    Serial.println(' ');
    Serial.print("Buffer Received");
    Serial.print(buffer);
    Serial.print('\t');
    if(strstr(buffer, "Hello")!=NULL) Serial.println("Found Hello");
    else if(strstr(buffer, "HELLO")!=NULL) Serial.println("Found HELLO");
    else if(strstr(buffer, "heLLo")!=NULL) Serial.println("Found heLLo");
    else Serial.println("No match found");
    Serial.flush();
  }
}

```

Note: Suspecting my PC hardware and serial driver, so I tried it in my Ubuntu 20.04 and window 10 installed with Arduino IDE 1.8.13 suspecting it may be crystal, i tried two different boards and used even Atmega328P core. I also suspected my keyboard "ENTER" key, so i tried the serial monitor "send" button.
with no difference.

I seems to run short is ideas so i am posting to the community. Let me have your advice and experience too.

Thanks.

# Answer
As Majenko and DataFiddler already stated in the comments, you are reading the Serial interface in the wrong way, because you seem to misunderstand a specific point involving the interface.

The Serial (UART) interface knows only of individual bytes, which are send asynchronously over the lines. It does not have any context of a full packet or message. When you type in some data into the Serial Monitor and then press "Send", the data will be send, but not as one big bunch of data. The individual bytes are delayed.

The first delay comes with the nature of the interface itself, as you send with a limited baudrate. With a baudrate of 9600 the Arduino is way faster, than the bytes can arrive. So when you first get a result higher than zero from `Serial.available()`, the rest of the message is not yet received. Thus with your current code you would only process only the first part of the message.

The second delay comes with the fact, that you and the Serial program on your PC cannot control, when exactly each byte is send. Thats done by the driver. So it might happen, that there is a small gap between 2 bytes somewhere in your message. You cannot mitigate this without writing your own driver and you cannot predict this.

**So, what to do now?** You should read data, when it is available, and put it into a buffer. And only, when a full message was received, you should process the data. Now you need to know, where the end of a message is. Mostly a delimiting character (like the newline character `\n`) at the end of the message is used. So you read, if available, and only process the message, when you have read the delimiting character. Something like this:

```
unsigned int buffer_pos = 0;
char buffer[50]="";

void loop(){
    if(Serial.available()){
        char c = Serial.read();
        if(c == '\n'){
            buffer[buffer_pos] = '\0'; // End the message as C string with a null character
            // process the message here
            buffer_pos = 0;
        } else {
            buffer[buffer_pos] = c;
            buffer_pos++;
        }
    }
}

```

`buffer` holds the message. `buffer_pos` is the current position in the buffer. We terminate the message with the null character, to get a valid C string in the buffer. After processing the message, we set the position back to zero, to receive the next message. When you send data from your PC, you need to make sure, that the message is ended with the newline character.

Now you are independent on when exactly the data is send.

---

DataFiddler stated in the comments, that without a delimiting character you can simply delay for enough time, so that the data has enough time to arrive. He also stated, that it is ugly. It is a bad coding style. A long delay will impact the responsiveness of your program, while a short delay may give you problems with longer messages. So I suggest, that you directly use the correct way to read the Serial interface. Then you don't have such pitfalls.
> 1 votes

---
Tags: arduino-uno
---


title: String array length in function

text:
# Question
Title: String array length in function
I know this question has been asked a thousand times, but I can't find a solution for my case.

I what to get the length of a string array in a given function. This is for an arduino board.

```
#define LEN(x) sizeof(x)/sizeof(x[0])
const char* mainMenu[] = {"FirstWord", "SecondWord", " "};

void myFunction(const char** m) {
  int a = LEN(m);

  /* Do something */
};

void setup(){
   myFunction(mainMenu);
};

```

The `LEN(m)` works fine in the `setup()` function. But in `myFunction()` it either gives me 1 (i guess the length of the pointer) or 9 (length of the 0th element of the array)

# Answer
> 1 votes
The problem is that LEN is evaluated locally for each usage replacing it with the content. In `myFunction` the parameter being passed to it is a pointer, not the array.

You need to evaluate the size once and once only in the context where the array hasn't collapsed into a pointer. That is usually done immediately where the array is defined:

```
const char* mainMenu[] = {"FirstWord", "SecondWord", " "};
#define MAINMENU_LEN (sizeof(mainMenu) / sizeof(mainMenu[0]))

```

Because `mainMenu` is a global it's always available, and when you require the length you get the length of the global array.

If you want to keep things local you will have to pass the number of elements in the array as a parameter to the function that uses that information.

```
myFunction(mainMenu, MAINMENU_LEN);

```

Another common alternative is to have some "end of array" marker and you loop through your array until you find that marker (that's how strings work - with `\0` for the end of array marker):

```
const char* mainMenu[] = {"FirstWord", "SecondWord", " ", 0};

```

Then:

```
for (int i = 0; m[i] != 0; i++) {
    ...
}

```

---
Tags: arduino-uno, array, cpp
---


# Question
Title: Jumping to bootloader from application code in atmega328p
I'm trying to program an Arduino Uno (atmega328p) using only the serial Tx/Rx lines (no DTR, so no automatic reset). This is so I can upload code via WiFi/TCP using an ESP-01.

To achieve this, I need to Arduino sketch/application to reset itself (and run the bootloader) whenever it sees avrdude trying to upload code (e.g. when `0 0`  appears in the serial port).

I've tried a few approaches to jumping to the bootloader from application code but had no success so far.

1. **Using the watchdog timer**

```
void reset_to_bootloader() {
    // see 11.2.2 MCUCR – MCU Control Register
    // Enable change of interrupt vectors
    MCUCR = (1<<IVCE);
    // Move interrupts to Boot Flash section
    MCUCR = (1<<IVSEL);

    // enable watchdog timer
    wdt_enable(WDTO_30MS);

    // block waiting for the watchdog to timeout and jump to the bootloader
    while(1);
}

```

Unfortunately, the datasheet\[1\] mentions the `IVSEL` bit is not available in atmega328p, so even though this compiles, it simple resets the MCU and the bootloader does not run.

2. **Jumping to the bootloader address directly**

There is a table in the datasheet (Table 26-7. Boot Size Configuration, ATmega328P) that specifies the bootloader start address for the 4 supported bootloader section sizes, which are configured by the BOOTSZ fuse.

I have read the fuses and confirmed the bootloader section is 512-bytes (256 words) long. Therefore, according to the datasheet, the Boot Loader Flash Section is `0x3F00 - 0x3FFF`. So, the start of the bootloader should be at word-address 0x3F00.

I have even dumped the whole 32768-byte flash off the MCU and confirmed the bootloader is at byte-address `0x7e00`, which matches the expected word-address `0x3F00` (`0x7e00 / 2 = 0x3F00`).

I have tried a couple methods of jumping to address 0x3F00. Here's a few. None of them seem to work. They just reset the MCU and the bootloader doesn't seem to run.

```
void jump_to_bootloader() {
    size_t bootloader_addr = 0x3F00;

    void (*bootloader_ptr)() = (void (*)())(bootloader_addr);

    SREG = 0;
    wdt_disable();
    bootloader_ptr();
}

void jump_to_bootloader2() {
    asm volatile ("ijmp" ::"z" (0x3F00));
}

```
3. **Jumping and updating the value of `MCUSR`**

I then realised the bootloader\[4\] checks the reset source and only runs on an external reset:

```
ch = MCUSR;
if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
    pp_start();  // skip bootloader

```

So I tried faking it before jumping, but it didn't work either:

```
    MCUSR = _BV(EXTRF);
    asm volatile ("ijmp" ::"z" (0x3F00));
}

```

Any help is appreciated. Thanks in advance!

---

edit:

4. **Jumping to after the bootloader checks the reset source**

Following @Edgar Bonet's suggestion, avoiding the `if (!(ch & _BV(EXTRF))) appStart();` check in the bootloader by jumping to the instruction that follows it:

```
void jump_to_bootloader2() {
    // the bootloader assumes these are true:
    cli();
    SP = RAMEND;
    SREG = 0;
    MCUSR = 0;
    asm volatile ("eor  __zero_reg__, __zero_reg__");
    asm volatile ("eor  r1, r1");
    // jump to after the bootloader checks the reset source
    asm volatile ("ijmp" ::"z" (0x7e0au / 2));
    while(1);
}

```

I could see it entered the bootloader (LEDs flashed a couple times), but avrdude was not able to upload code.

The bootloader sets up a watchdog timer (WDT), so I'm suspecting avrdude waits for to long after sending the initial `0 0 0`  and since the bootloader does not see anything on the serial port the WDT resets it.

---

References:

# Answer
The source of Optiboot on Uno is here.

I would prefer a simple watchdog reset with

```
  wdt_enable(WDTO_15MS);
  while (true);

```

But I am not sure now if it runs sketch upload detection in bootloader.

For direct jump to Optiboot on Uno (one flash page) this should work

```
typedef void (*bootloader_jump_t)();
const bootloader_jump_t bootloader_jump = (bootloader_jump_t)((FLASHEND-511)>>1);

```

and then you can call `bootloader_jump();`

EDIT: while the Optiboot 4 on Uno from factory doesn't check for new upload after watchdog reset or direct jump, Optiboot 8 has checks to handle this right
> 1 votes

# Answer
Maybe you could jump to right after the line

```
if (!(ch & _BV(EXTRF))) appStart();

```

Here is an excerpt of the disassembly:

```
  if (!(ch & _BV(EXTRF))) appStart();
    7e06:   81 ff           sbrs    r24, 1
    7e08:   f0 d0           rcall   .+480       ; 0x7fea <appStart>

#if LED_START_FLASHES > 0
  // Set up Timer 1 for timeout counter
  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
    7e0a:   85 e0           ldi r24, 0x05   ; 5
    7e0c:   80 93 81 00     sts 0x0081, r24

```

The conditional call to `appStart()` is made by the instructions `sbrs` and `rcall`. The instruction right after that is the `ldi` at byte address 0x7e0c (word address 0x3f05). I would try jumping right there. You won't miss much:

* `eor r1, r1` is not needed when jumping from C++, as the value of r1 is already enforced by the compiler as per the ABI.
* `in r24, 0x34` reads `MCUSR` into a register that is clobbered right away
* `out 0x34, r1` clears `MCUSR`; if this turns out to be useful, you could do it right before jumping to the bootloader.

You may want to check that the bootloader you have matches the disassembly I linked to.
> 0 votes

---
Tags: arduino-uno, atmega328, c, bootloader, reset
---


# Question
Title: Function declared in another file not recognized (undefined reference to)
I am making a multi-file arduino project, but the compiler can't recognize a function. I am using the arduino-cli version 0.10.0

This is the error I received

`undefined reference to pin_init() collect2.exe: error: ld returned 1 exit status Error during build: exit status 1`

This is the command:

```
arduino-cli compile -b arduino:avr:uno C:\Users\Cioccarelli\Desktop\transmitterCopy\main

```

main.ino:

```
#include "C:\Users\Cioccarelli\Desktop\transmitter\automation\automation.h"

void setup() {
    pin_init();
}

void loop() {}

```

automation.h:

```
#pragma once

// This is where the components input pins are stored, they are put here by the add_pin function
byte pinSetup[0];
byte pinSetupSize = 0;

// This function is called in the setup() and it initializes every pin listed in pinSetup[] as input
void pin_init();

```

automation.cpp:

```
#include "C:\Users\Cioccarelli\Desktop\transmitter\automation\automation.h"

extern pinSetup;
extern pinSetupSize;

void pin_init() {
    for (int i = 0; i < pinSetupSize; i++)
        pinMode(i, INPUT);
}

```

I think this issue might have to do with the fact that I don't completely understand file inclusion, but I haven't found anything useful in my research

**Update**: today I rebuilt the project with different names and I cut everything which wasn't related to the problem, in hope to identify it.

new main:

```
#include "C:\Arduino\transmitter\nightmare\nightmare.h"

void setup() {
    pin_init();
}

void loop() {}

```

new automation.h (nightmare.h):

```
#pragma once

// This function is called in the setup() and it initializes every pin listed
//in pinSetup[] as input
void pin_init();

```

new automation.cpp (nightmare.cpp):

```
#include "C:\Arduino\transmitter\nightmare\nightmare.h"

void pin_init() {}

```

new file structure:

I also made a copy and made some changes so it could become a C++ file (substituting the setup() with main() and replace every "byte" type with "int")

I then put it in Visual studio, it compiled perfectly. The arduino IDE gives the same error

# Answer
The compiler didn't have a problem; the linker did. That is, once your main function was compiled (correctly) to call pin\_init(), the loader tried to put together all of the compiled modules and link up calls that were not satisfied locally - within the same file - to functions defined in another module. That is when this message got generated. No such function *definition* was found, despite the *declaration* of it in main.ino.

If you can compile this with the Arduino IDE, watch what it does: It will compile *each* of your source-code modules, one at a time. Then link *all* of your modules' compiled versions together to produce the .hex file (that will eventually get uploaded to the Arduino). You need to mimic that when you're compiling & loading from the command line.

Update:

> today I rebuilt the project with different names

Is your .cpp file in the same folder as your .ino file? Or in another folder, such as the folder containing your .h file? I suspect it's the latter. When I built your project it in the Arduino IDE, it succeeded when the .ino and the .h were in the same folder, failed exactly as you described when I moved the .cpp file to where the .h file is.

The solution goes back to what I suggested earlier; that no *definition* of pin\_input() was found, as the .cpp file containing it wasn't seen by the IDE (or your command-line compiler) and therefore not compiled and linked. Each of your files needs to be compiled and all of them together need to be linked, for the external calls to be satisfied.

With the IDE, put your project's .ino and .cpp files in the same folder so the IDE will see and compile each of them and know what to files to link. The IDE won't give you much flexibility for locating your .cpp files.

With the command line compiler, you can put your files wherever you will, make a separate\[1\] compile only run for each of them, then make another run of the linker component\[2\] naming all of the compiled units (the IDE names them as .d) and provide the path to your library folder(s).

\[1\] I'm not familiar with the command-line compiler's command-line syntax; maybe you're able to specify a number of compiles with one command.
\[2\] Again, IDK whether you need invoke the linker with the same command but with a link-only option switch, or you'll need to invoke the linker yourself, on the command line.
> 1 votes

# Answer
The Arduino IDE (and I guess arduino-cli behaves the same) will try to link into your project every source file that lives *in the same forlder* as the main .ino file.

Try this: get rid of the “automation” and “main” subfolders, put everything at the root of the project, and try to build again. If you end up with too much stuff in the root, you may consider the possibility of creating your own libraries, but that's for another day...
> 0 votes

---
Tags: c++, error, arduino-cli
---


# Question
Title: else if is ignored if not Serial.println anything before
I encountered to me inexplicable behavior on an arduino uno. I'm serial reading a string from the serial monitor/python serial. This string is the conditional on several if/else if statements. The crazy thing is, some strings just get ignored, but if I print out the read string after reading it, the ignored statements then get executed and the script works the way it's supposed to. This is the code:

```
// power outlet 1
# define OUT_1_1 2 // relay #4
# define OUT_1_2 3 // relay #3

// power outlet 2
# define OUT_2_1 4 // relay #2
# define OUT_2_2 5 // relay #1

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  // power outlet 1
  pinMode(OUT_1_1, OUTPUT);
  pinMode(OUT_1_2, OUTPUT);

  // power outlet 2
  pinMode(OUT_2_1, OUTPUT);
  pinMode(OUT_2_2, OUTPUT);

  // init outputs to HIGH
  digitalWrite(OUT_1_1, HIGH);
  digitalWrite(OUT_1_2, HIGH);
  digitalWrite(OUT_2_1, HIGH);
  digitalWrite(OUT_2_2, HIGH);

  Serial.begin(9600);
}

void loop() {
  String str = "";

  // checking for bytes in the buffer
  if (Serial.available() > 0) {
    str = Serial.readStringUntil("\n");
  }
  // Serial.println(str); // if this line is uncommented serial input "2_ON\n" and "2_OFF\n" is recognized and outled 2 is successfully switched

  // identity
  if (str == "IDN\n") {
    Serial.println("Serial Power Outlet");
  }

  // controlling power outlet 1
  else if (str == "1_ON\n") {
    digitalWrite(OUT_1_1, LOW);
    digitalWrite(OUT_1_2, LOW);
  }
  else if (str == "1_OFF\n") {
    digitalWrite(OUT_1_1, HIGH);
    digitalWrite(OUT_1_2, HIGH);
  }

  // controlling power outlet 2
  else if (str == "2_ON\n") {
    digitalWrite(OUT_2_1, LOW);
    digitalWrite(OUT_2_2, LOW);
  }
  else if (str == "2_OFF\n") {
    digitalWrite(OUT_2_1, HIGH);
    digitalWrite(OUT_2_2, HIGH);
  }
  delay(1000);
}

```

If I serial input `2_ON\n` or `2_OFF\n` the according else if blocks are just ignored (all other inputs work correctly).

But after I've uncommented `// Serial.println(str);` these blocks are executed the way they are supposed to and all works just fine.

Where is my mistake, what am I getting wrong here? These blocks also get executed if I `Serial.println` any random output. Why do I have to Serial.println something first so my script works according to plan? What am I missing?

EDIT: added all of the code.

# Answer
> 1 votes
Even though you read until \n, that just controls the ending of your buffered string. It does not control it's start. There may be some garbage before the command that you have not cut out. In other words, I suggest you check if the string endsWith as opposed to == the command string.

As for what noise could be causing garbage or why activity on the tx side of the serial cleaned it up, i do not know. Heck something might just be weird enough in the wiring that '2' is just the set of bits needed to aggravate it.

---
Tags: arduino-uno, serial, digitalwrite
---


# Question
Title: Cant upload arduino code when ESP8266-01 module is connected
I'm using this tutorial to connect my ESP8266-01 WiFi Module to Arduino UNO with Arduino IDE v. 1.8.13.

It works and the module can connect to my WiFi. However, when I try to upload my code, it says:

`avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x30`

What could be the problem, since when I remove the reset pin it uploads the code, but now the WiFi goes down.

# Answer
Your problem is that there are two ways of wiring your ESP-01 module to the Arduino:

1. Wired so the PC has access to it and the Arduino is effectively disabled, and
2. Wired so the Arduino has access to it

You are wired in configuration 1 at the moment whereby the Arduino is effectively turned off and the USB connection goes direct to the ESP-01. When you try and upload code to the Arduino it's the ESP-01 that the computer is talking to, not the Arduino.

You need to wire it in configuration 2. In this configuration the TX/RX pins of the ESP-01 connect to any two pins of the Arduino except pins 0 and 1, and the RESET pin is not connected to anything. Then you can't talk to the ESP-01 through the serial monitor - instead you have to write code for the Arduino that uses SoftwareSerial to communicate for you.

There are many many tutorials online about communicating between the Arduino and the ESP-01.
> 2 votes

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


# Question
Title: Where is the Arduino IDE log file located? Not the Serial Monitor
"An error ocurred while uploading the sketch"

I'm having this specific error when uploading a sketch to my board and the IDE doesn't specify the problem correctly.

It's version is 1.8.13 for Windows 10.

I would like to get a file with detailed information about the IDE's error. Where should I look for it?

# Answer
> 3 votes
There is no log file. Instead you need to turn on both "compilation" and "upload" under the "Show verbose output during:" option in Preferences.

This will give you far more information about any errors in the output scroll pane at the bottom of the IDE.

On Linux if you run the IDE from the command line you get large amounts of logging on stdout. There may be a way of doing the same from Windows.

---
Tags: ide, datalogging
---


# Question
Title: It is possible an Arduino generate 3d graphics on tft or vga
It is possible to an Arduino render 3d graphics like very low polygonal 3d models or generating lighting efects non realtime shadows or realtime shadows and reflections. Rendering like first 3d video game consoles. Someone can ask why you don't use an Rasberry Pi. Beacuse Linux can be more complex. Also Rasberry Pi is a computer runs Linux .Linux is hard and some people can say you can install Windows but it doesn't give freedom as Arduino on Arduino you have more control on system.It doesn't run operating system but Rasberry pi runs and you needed write programs for it. You can't do much anything ( at least i know) than Linux or Windows will allow.

My goal was running very basic 3d graphics on a Vga. Theres no rule it can be like old dos games.Fake 3d effect like distorting sprites to look like 3d and rotate them move change coordinates change camera position like a 3d but it's actually generating fake depth. Must camera position controllable . Like a video game.

Sprites,effects are completely pre rendered. Only realtime rendered thing was distorting sprites by camera position. Changing room (Square area will reset view that will make after another room it would show another room).

Is there a library can done that?

Your solution can be for another Arduinos.

Your solution can be Arduino dependent. Like only works for due,mega etc.

Theres a vga library for Due supports 256 colors your solution can use this library problary called DueVGA

# Answer
> 1 votes
While there is no VGA library for Arduinos with AVR, there is one for ESP32: ESP32 VGA Library.
It makes heavy use of the Hardware capabilities like I2S that are not present in in Arduino.

# Answer
> 0 votes
On AVR based Arduinos: No, definitely not. It is possible to create a VGA signal, but only with very limited resolution and few colors (like 4 or so) and also a framerate, that will not be enough. Also they all have too few memory.

It might be possible on the Due (don't have much experience with it), but it is still a bad choice for a platform (also partly because the Due is in general such a bad designed board with no good documentation).

> Is there a library can done that?

I don't think, that you will find any library doing all what you want. You might find libraries, that help you draw on the display, but you will do all the hard stuff (creating and loading sprites, distorting them, animating them) yourself. This is, because Arduino is a bad choice for such a project.

Also: In the title you mentioned TFT. I guess you meant one of the TFT display modules, that you can connect to Arduinos. Forget about that. They are connected over rather slow serial data interfaces (not meaning the Arduino `Serial` here, but serial interfaces like I2C or SPI). You won't get a sufficient frame rate with them.

---

I would oppose your arguments against the Raspberry Pi. Sure, it has an OS, but that also means, that it can make use of a variety of languages and frameworks. You are not bound to plain C/C++. You can use the language or framework, that best suites your needs. That can be a bit complex at first to find the right one. But thats, because your project is complex. What you are describing is a very complex task, when you cannot rely on others, that have already implemented the hard stuff (which would be the case for the Arduino).

Also a Raspberry Pi has plenty of RAM and plenty of storage space. It runs at high speed and is actually capable of outputting video with a good framerate.

Without wanting to offend you: I think, as you are asking this question here, you are not qualified enough yet to do such a project on an Arduino. There are insanely capable people out there (wouldn't count myself to them), who do incredible things with Arduinos by milking the very last drop of resources out of them. But they are doing it for the grind, not for having a functioning product at the end. I guess you want this to work good at the end, without needing you to work on it for many years. Then you are result-focused and should choose the correct platform for this. A computer (like the Pi) will be easier.

---

> Rasberry Pi had lot of things but some of them are unnecessary.

Yes, but is that really a problem? Is the unused potential really a no-go for the project? You could say the same thing about an Arduino. It has a lot of peripherals build in (depending on type Timers, Comparators, ADCs, DACs, several communication interfaces, power management peripherals, ...). Almost no project uses all of them. But that's simply the difference between general purpose chips/boards (like all Arduinos or Raspberry Pis) and custom made chips for a single purpose. If (!) a fitting chip for your project exists, that really only has what you need, it will most likely be very expensive. Chips for a single very narrow purpose have a very narrow target group, thus are more expensive (simple economy here). Companies have formally nearly everytime designed their own chips for gaming consoles (which is way beyond your current scope), like PS1 or N64. Current gaming consoles rely often on modified standard hardware, also because it is cheaper. The really old gaming consoles used the generic electronical chips, which means, that you didn't have one single programmable chip. Instead lots of the logic was build into the electronic design.

So you will always have some excessive features, that are not used. Why would you want to remove them from the project, just for the fuzzy goal of not wasting features. It will make your project only more complex and expensive. You will gain nearly nothing from minimizing the resources. This is a hobby project, not for selling it.

> In rasberry pi you just writing a computer program.You don't have much control like arduino

That depends on what type of control you mean. On a computer you are writing code on a higher level of abstraction. That also makes it easier to do complex things, since you can rely on the low level programming of others. What control do you want to have over the system, that you don't have on a computer like the Pi? Do you think, you can program better display drivers or graphic renderers, than all the other people? Then you can still do that on the Pi. A Pi also gives you control over the GPIO pins, which let's you do many hardware things, that you can also do on an Arduino.

Also Linux is open source. If you think, you need more low level interaction with the hardware (cannot think of a reason for needing it), then you can build your own OS, which gives you the needed freedom. Sure, that is very complex. But when you are able to use the low level programming, then you are also able to change the OS.

---

You seem to already have chosen the Arduino for your project. I, like others, have advised you to use a Pi instead to make it a lot easier and better. It is up to you, if you want to believe us or not. All in all I'm still not convinced, that you are able to pull that off on the Arduino platform, while still getting good results. You are simply not at that point of knowledge yet. You write confidently about the problems with an OS, while you don't seem to have a concept about the exact structure of these problems and how they impact you. We will not prevent you from doing it the hard way. Please for free to choose your own way.

# Answer
> 0 votes
# VGA

I suggest you build the famous world's worst video card. It's a great project and you'll definitely learn something when building it.

That graphics card uses only 2 bit per base color, which is 6 bits in total, or 64 colors. The resolution of the graphics card is 100x75 pixels. An image can basically become as good as

That picture is still 100x75 = 7.5 kB in size. That means it does not fit into the 2 kB of RAM of an Arduino Uno.

To clock the graphics card, Ben Eater uses a 10 MHz crystal to get the timing right. That means, your Arduino needs to output one color at a speed of 10 MHz. That's clearly not feasible for an Arduino Uno running at 16 MHz.

However, an Arduino Uno is nothing without some hardware attached. You could try to calculate the 3D graphics on the Arduino and write the results into an EEPROM (just like Ben Eater's graphics card) and let the EEPROM handle the output of the colors. That way, you could certainly generate single images. The frame rate will definitely not be high.

But: your request is not far fetched. My first computer, an Apple IIe was running at 1 MHz speed - but at least it had 64 kB of RAM. It could do all sorts of stuff, although I can't remember a 3D game. Using an Arduino Due with 84 MHz and 96 kB of RAM should be a realistic approach - and probably the reason why DueVGA exists.

# TFT

A TFT display already has its own memory, so you needn't worry about that aspect. People already did 3D rendering, although they were going through a lot of problems that I mentioned for VGA before. It requires a lot of optimization. A library is the ATmega328 Tiny 3D Engine.

With shading it seems to render up to 3 frames per second on an Arduino, which is likely not enough to for smooth interaction.

# Raspberry Pi

> Linux is hard

Some Linuxes are. Especially Kali Linux. But Raspbian is really a good OS for the Raspberry Pi. We are teaching internships Linux + Shell + Python in 1 week (like this project). It's enough to focus on the programming. Not much configuration needed.

> You can't do much anything ( at least i know) than Linux or Windows will allow.

That might be true. However, I am developing software that runs on operating systems since 1996 and have never had the feeling that the operating system restricts me from doing something. In the opposite: the OS provides features that would be very hard to implement on my own.

# Answer
> 0 votes
I disagree with your premise. If you use a high-end Arduino, like one of the ones based on an ARM processor, and you optimize the snot out of it, you might be able to generate crude VGA level graphics, and gin up some 3D looking images. But expect to spend a lot of time on very fussy timing code that requires a LOT of expertise to get right.

(An Arduino does not have any display driver at all.)

You want a device that can output video through hardware. A Raspberry Pi is a much, much better choice. Sure, it runs UNIX. UNIX isn't going to bite you. Roll up your sleeves and

# Answer
> 0 votes
You can definitely render 3D graphics on an Arduino-based MCU & TFT and I have done exactly that with Teensy.

It requires quite a bit of work to implement software rasterizer though and I'm not aware of an off-the-shelf 3D library you could use. I would think that someone has written a 3D graphics iib though, so might be good to scour GitHub if you don't want to write a rasterizer yourself.

There are plenty of different TFT options with both SPI (serial) and 8/16bit parallel interfaces you can use and have decent frame rate. E.g. with Teensy you can update a 320x240x16bpp screen over SPI at ~30fps. You can also pass SPI data transfer to DMA to free spending MCU cycles for it if your MCU supports it. With parallel interface you can bit bang the data to TFT faster and have potentially higher frame rate, but then you have to waste MCU cycles for the data transmission.

Newer Teensy models has plenty of RAM (1MB) for 3D rendering but it can be quite challenging to render 3D graphics on some MCU's with only few kilobytes of RAM. I'm using tiled rendering, which renders a frame in small tiles (e.g. 64x64px) and thus doesn't need to maintain the whole frame & depth buffers in memory. Because of this I was able to get the 3D renderer running on Teensy LC, which has only 8kb of RAM, but it's much slower and simpler 3D model. I also store the 3D assets (geometry, textures) in the MCU flash in format that can be directly used for rendering to save RAM.

You can also implement texture sampling on MCU, which opens possibility to implement various different effects, like sprites you mentioned.

---
Tags: arduino-uno
---


# Question
Title: Relay + Arduino uses too much power for battery to handle. Which solution is best?
You can see in my crumby schematic that I am using a Non-latching relay to turn on a 3A circuit (one of them arc lighters), which is powered by a 25C (supposedly) lipo battery. That same battery also powers an Arduino through a TP4056. This works fine when I first turn it all on, but once the relay is activated by the Arduino, the lighter + Relay only turn on for a split second before stopping (when the Arduino is powered via USB, it works fine). I am thinking that the Arduino+Relay+Lighter is too much for the battery, even though it claims to be 25C. It is just strange because the Arduino+Activated Relay consume what, like 200 mA?

Notes: When I manually turn on the lighter, the light on the Arduino dims a fair bit, but stays on. The Arduino is running at logic level of 3.3V so that I didn't need a booster.  As for fixes, I was thinking about trying to use a transistor or SSR instead of the chunky relay I have now (which would be good, I need this to be compact). Or maybe the TP4056 is failing to provide enough output despite a decent input?

I am FAR from an electrical engineer so if anyone has any pro tips for improving this it would be much appreciated.

# Answer
> 1 votes
The TP4056 is a battery charger, not a voltage regulator. It cannot be used to supply power to a device like an Arduino. It is designed for charging the Lithium Ion battery from a 5V (e.g., USB) source.

By trying to use it as a power supply you're asking for trouble. It thinks it's trying to charge a battery (from a 3.7V nominal source) and will be doing things like:

* Running constant current making the voltage fluctuate wildly as current demands change
* Running constant voltage with limited current causing starving of power
* Shutting off when it thinks it sees the non-existent battery being fully charged.

The TP4056 should be connected to a 5V USB power source and to the battery for charging it. The battery should be then through a (very) low-dropout regulator (ideally a switching regulator with zero dropout bypass ability) to power the Arduino at 3.3V.

Alternatively, if you don't need a (reasonably) precise 3.3V then you can power the Arduino directly from the battery.

---
Tags: power, relay, transistor, lipo
---


# Question
Title: I want 2 output pins to working alternately
I have given pwm output on pin(9) and I Want pin(10) to be high when pin(9) is low and pin(10) to be low when pin(9) is high. So what should i add to my code?

# Answer
You can set pin 10 to run in “inverted PWM” mode, and leave pin 9 in the default non-inverted mode. Pin 9 is the “OC1A” pin of the AVR microcontroller (output compare of Timer 1, channel A), whereas pin 10 is OC1B (channel B of the same timer). Inverting the PWM mode of channel B is a matter of changing a single bit in one of the control registers of Timer 1:

```
TCCR1A |= _BV(COM1B0);

```

You can do this once in `setup()`, the setting should persist. Then just `analogWrite()` the same value to both pins. For some background on how all this works, see the datasheet of the ATmega328P microcontroller (the MCU at the hearth of your Uno), especially section 16 “16-bit Timer/Counter1 with PWM” and table 16-3 “Compare Output Mode, Phase Correct and Phase and Frequency Correct PWM”.
> 4 votes

# Answer
would something like the following work?

```
digitalWrite(9,  !digitalRead(10));

```

like this: https://forum.arduino.cc/index.php?topic=128698.0
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Breaking out of the arduino fingerprint enroll loop
I am using the Arduino's Adafruit Finger Sensor library, and it has an example to enroll a fingerprint. I want it to enroll one print and exit/break out of the loop because it currently enrolls a user, then goes back to asking for a fingerprint. Here is the code:

```
#include <Adafruit_Fingerprint.h>
SoftwareSerial mySerial(2, 3);
Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);
uint8_t id;
void setup()
{
  Serial.begin(9600);
  while (!Serial);  // For Yun/Leo/Micro/Zero/...
  delay(100);
  Serial.println("\n\nAdafruit Fingerprint sensor enrollment");

  // set the data rate for the sensor serial port
  finger.begin(57600);

  if (finger.verifyPassword()) {
    Serial.println("Found fingerprint sensor!");
  } else {
    Serial.println("Did not find fingerprint sensor :(");
    while (1) { delay(1); }
  }
}

uint8_t readnumber(void) {
  uint8_t num = 0;

  while (num == 0) {
    while (! Serial.available());
    num = Serial.parseInt();
  }
  return num;
}

void loop()                     // run over and over again
{
  Serial.println("Ready to enroll a fingerprint!");
  Serial.println("Please type in the ID # (from 1 to 127) you want to save this finger as...");
  id = readnumber();
  if (id == 0) {// ID #0 not allowed, try again!
     return;
  }
  Serial.print("Enrolling ID #");
  Serial.println(id);

  while (!  getFingerprintEnroll() );
}

uint8_t getFingerprintEnroll() {

  int p = -1;
  Serial.print("Waiting for valid finger to enroll as #"); Serial.println(id);
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.println(".");
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger.image2Tz(1);
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  Serial.println("Remove finger");
  delay(2000);
  p = 0;
  while (p != FINGERPRINT_NOFINGER) {
    p = finger.getImage();
  }
  Serial.print("ID "); Serial.println(id);
  p = -1;
  Serial.println("Place same finger again");
  while (p != FINGERPRINT_OK) {
    p = finger.getImage();
    switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image taken");
      break;
    case FINGERPRINT_NOFINGER:
      Serial.print(".");
      break;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      break;
    case FINGERPRINT_IMAGEFAIL:
      Serial.println("Imaging error");
      break;
    default:
      Serial.println("Unknown error");
      break;
    }
  }

  // OK success!

  p = finger.image2Tz(2);
  switch (p) {
    case FINGERPRINT_OK:
      Serial.println("Image converted");
      break;
    case FINGERPRINT_IMAGEMESS:
      Serial.println("Image too messy");
      return p;
    case FINGERPRINT_PACKETRECIEVEERR:
      Serial.println("Communication error");
      return p;
    case FINGERPRINT_FEATUREFAIL:
      Serial.println("Could not find fingerprint features");
      return p;
    case FINGERPRINT_INVALIDIMAGE:
      Serial.println("Could not find fingerprint features");
      return p;
    default:
      Serial.println("Unknown error");
      return p;
  }

  // OK converted!
  Serial.print("Creating model for #");  Serial.println(id);

  p = finger.createModel();
  if (p == FINGERPRINT_OK) {
    Serial.println("Prints matched!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_ENROLLMISMATCH) {
    Serial.println("Fingerprints did not match");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }

  Serial.print("ID "); Serial.println(id);
  p = finger.storeModel(id);
  if (p == FINGERPRINT_OK) {
    Serial.println("Stored!");
  } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
    Serial.println("Communication error");
    return p;
  } else if (p == FINGERPRINT_BADLOCATION) {
    Serial.println("Could not store in that location");
    return p;
  } else if (p == FINGERPRINT_FLASHERR) {
    Serial.println("Error writing to flash");
    return p;
  } else {
    Serial.println("Unknown error");
    return p;
  }
}

```

Output is that after storing the fingerprint, it requests for finger to enroll, but I want it to exit after storing. Is this possible?

# Answer
Your `getFingerprintEnroll()` function is missing a return statement. Inside the `if (p == FINGERPRINT_OK)` statement, you need to insert

```
return 0;

```

after the Serial print. Only when returning zero, you will exit the while loop inside the `loop()` function.
> 1 votes

---
Tags: arduino-uno, loop
---