# Question
Title: Reading from SPIFFS - What's the best way to deal with a string (or char) array with undefined length?
I've read that it's best to avoid using String in Arduino so I'm ready to use a char array if it's better. I'm reading the file names from an SD Card and my goal is to store them in an array and then be able to read that array. What I'm currently doing is:

```
String lib_arr[100];
int lib_arr_size;

```

and then

```
File dir = SD.open("/");
int c = 0;
while (true) {
  File entry = dir.openNextFile();
  if (!entry) {
    // If no more files
    lib_arr_size = c - 1;
    break;
  }
  if(strcmp(entry.name(), "SYSTEM~1") == 0) {
    continue;
  }
  lib_arr[c] = entry.name();
  entry.close();
  c++;
}

```

and then

```
for (int i = 0; i < lib_arr_size; i++) {
  if(i == pos) {
    tft.print("> ");
    tft.println(lib_arr[i]);
  } else {
    tft.println(lib_arr[i]);
  }
}

```

This is not a solution because, for my purposes, the String lib\_arr\[100\] can be 1000 or 10000 or 100000... and I found out that by increasing that value the global variables use skyrockets and Arduino says that it's out of memory. My goal is memory optimization. I don't know how to go about this problem.

# Answer
> 0 votes
Well, you cannot use more memory than you have. If the length of file names is (probably/possibly) too much, you just cannot store it in memory. Some alternatives:

* Use some compression... This will save you a bit, but at the end if you don't know how much the maximum bytes you need to store is, it will not help much
* Use external SRAM memory... You need to write your own memory functions. Also a slight performance hit.
* Use SD card memory... As SRAM, but much slower. Also not sure if you can use the same SD card to write on.
* The best solution, but could be a big performance hit, is not to store at all the file names, but go through the file names and process what you need along the way. This is not always possible or feasible though. In your solution you can print the file names directly without storing (but I guess you want to do some additional processing).

# Answer
> 0 votes
Please look into the SPIFFS/ LittleFS library. You will see that the length of a filename (in those file systems it includes the path and the root indicator "/" as well as the extension .XXXXX as in .shtml ). The maximum length defined in the libs is 32 as max length this means **31 chars to use** \+ 1 terminator. To all the wise guys claiming you can change that (Yes you can but you should not). Do not do it - there are reasons for that. Read more.
The maximum files is defined by blocksize and howlargeyou defined your SPIFFS partition.
There is no difference between writing to SPIFFs or a SD card both have around 100.000 r/w cycles per individual physical "cell" Sometimes it is cheaper to get a new ESP than a SDcard.
**The question of the OP:**
As long as you read its no problem to do it often if you do mass renames you might have a problem after some time. What you do is actually partly copying what the libs do - so utterly obsolete. Speed is the same because its the same flash memory anyway (+ your processing overhead).
You do not really have directories its a flat table system, so searching for path beginning with or containing (combined with a clever read strategy) can be done on the fly without problems.
If you need data elsewhere (browser) filter & stream it - do not make in between storage (=duplication) with the small memory
As a final thought from the tech specs:

> The main complication writing spiffs was that it cannot be assumed the target has a heap. Spiffs must go along only with the work ram buffer given to it. This forces extra implementation on many areas of spiffs. ....
>
> SPI flash devices are physically divided in blocks. On some SPI flash devices, blocks are further divided into sectors. Datasheets sometimes name blocks as sectors and vice versa.
>
> Common memory capacaties for SPI flashes are 512kB up to 8MB of data, where blocks may be 64kB. Sectors can be e.g. 4kB, if supported. Many SPI flashes have uniform block sizes, whereas others have non-uniform \- the latter meaning that e.g. the first 16 blocks are 4kB big, and the rest are 64kB.
>
> The entire memory is linear and can be read and written in random access. Erasing can only be done block- or sectorwise; or by mass erase.

---
Tags: arduino-ide, string, array, memory, spiffs
---


title: Return photo stacking rail to start

text:
# Question
Title: Return photo stacking rail to start
In isolation (73 years old) and trying to get my macro photo stacking rail to return to start without a limit switch. I know the number of steps taken, so it is just a matter of reversing the motor. My code (copied and pasted from other sites) works like a dream (10 steps, fire an IR camera trigger) and continues up to when I want to return (line 73) taking 100 shots or steps however many I want - no problem.

I started a void return loop (and terminated the loop) but the coding has me beat. I have attached my code (might look terrible, but it works). Can anyone help out this old guy and give me the code to counter clockwise 1000 steps?

Thanks fellas David

```
[code]
#include <AccelStepper.h>
#include <MultiStepper.h>

int smDirectionPin = 2; //Direction pin
int smStepPin = 3; //Stepper pin
int Distance = 0; // records the number of steps we have taken
byte numRepeats = 0;
byte maxRepeats = 100;
int smFirePin = 13;  //Trigger pin
#define fire 13

 void setup(){
  /*Sets all pin to output; the microcontroller will send them(the pins) bits, it will not expect to receive any bits from thiese pins.*/
  pinMode(2, OUTPUT);  //Direction Pin
  pinMode(3, OUTPUT);  //Step Pin
  pinMode(13, OUTPUT);  //LED pin
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
  digitalWrite(13,LOW);
  pinMode(smDirectionPin, OUTPUT);
  pinMode(smStepPin, OUTPUT);

  Serial.begin(9600); //Open Serial connection for debugging
}

void loop(){
   if (numRepeats < maxRepeats) {
   move1Step();
   Distance = Distance + 1; //record this step to see if we are et the end of our move

  if (Distance == 10)
  {
 if (digitalRead(2) == LOW)
 {
  digitalWrite(2 , LOW);
 }
 else
 {
  digitalWrite(2, LOW);
 }
 Distance = 0;
 numRepeats ++;
 delay(3000);
{
    trigger();
}
   }
 }
}
void move1Step() {
  digitalWrite(3, HIGH);
  delayMicroseconds(750);
  digitalWrite(3, LOW);
  delayMicroseconds(750);
}
// Power on the IR trigger circuit to fire the camera
void trigger()
{
    delay(1000); // wait for vibration to settle
    digitalWrite(fire, HIGH); // take the picture
    delay(2000); // wait for that to happen
    digitalWrite(fire, LOW); // disable the IR circuit again
}

// Advance the motor by one step
void step()
{
  digitalWrite(step, HIGH); //Trigger one step forward
  delay(1);
  digitalWrite(step, LOW); //Pull step pin low so it can be triggered again
  delay(1);
}

  void return();

{
  digitalWrite(smDirectionPin, HIGH);
  /*Slowly turns the motor 1600 steps*/
  for (int i = 0; i <200; i++){
    digitalWrite(smStepPin, HIGH);
    delayMicroseconds(700);
    digitalWrite(smStepPin, LOW);
    delayMicroseconds(700);
  }

  while(1) { }
}

[/code]

```

# Answer
> 0 votes
I cleaned up your code a bit. Removed duplicate and unused code. I used a `for`-loop to make it run for 100 repetitions.

Feel free to let me know if you have any more questions, or if there are things that aren't clear.

```
// You aren't using these libraries, so I commented them out
//#include <AccelStepper.h>
//#include <MultiStepper.h>

int smDirectionPin = 2; //Direction pin
int smStepPin = 3; //Stepper pin
int smFirePin = 13;  //Trigger pin

byte maxRepeats = 100;

void setup()
{
  /*Sets all pin to output; the microcontroller will send them(the pins) bits, it will not expect to receive any bits from thiese pins.*/
  pinMode(smDirectionPin, OUTPUT);  //Direction Pin
  pinMode(smStepPin, OUTPUT);  //Step Pin
  pinMode(smFirePin, OUTPUT);  //Fire pin
  digitalWrite(smDirectionPin, LOW);
  digitalWrite(smStepPin, LOW);
  digitalWrite(smFirePin,LOW);

  Serial.begin(9600); //Open Serial connection for debugging
}

void loop()
{
  digitalWrite(smDirectionPin, LOW); // set stepper motor to run forwards

  for( byte i=0; i<maxRepeats; i++ ) // run the following section 100 times
  {
    //move 10 steps forward
    for( byte j=0; j<10; j++ )
    {
      move1Step();
    }

    // wait and take a photo
    delay(3000);// there is already a delay in the `trigger` function, so this like could be removed
    trigger();
  }

  // return the stepper motor to the starting position
  digitalWrite(smDirectionPin, HIGH); // set stepper motor to run in reverse
  for( byte i=0; i<maxRepeats; i++ ) // run the following section 100 times
  {
    //move 10 steps backwards
    for( byte j=0; j<10; j++ )
    {
      move1Step();
    }
  }

  // Do nothing
  while(1){ }
}

void move1Step()
{
  digitalWrite(smStepPin, HIGH);
  delayMicroseconds(750);
  digitalWrite(smStepPin, LOW);
  delayMicroseconds(750);
}

// Power on the IR trigger circuit to fire the camera
void trigger()
{
    delay(1000); // wait for vibration to settle
    digitalWrite(smFirePin, HIGH); // take the picture
    delay(2000); // wait for that to happen
    digitalWrite(smFirePin, LOW); // disable the IR circuit again
}

```

---
Tags: arduino-uno, code-review
---


# Question
Title: Update class attribute with attachInterrupt
I want to refactor this code

```
/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
volatile int flow_frequency; // Measures flow sensor pulses
unsigned int l_hour; // Calculated litres/hour
unsigned char flowsensor = 2; // Sensor Input
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Interrupt function
{
   flow_frequency++;
}
void setup()
{
   pinMode(flowsensor, INPUT);
   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
   Serial.begin(9600);
   attachInterrupt(0, flow, RISING); // Setup Interrupt
   sei(); // Enable interrupts
   currentTime = millis();
   cloopTime = currentTime;
}
void loop ()
{
   currentTime = millis();
   // Every second, calculate and print litres/hour
   if(currentTime >= (cloopTime + 1000))
   {
      cloopTime = currentTime; // Updates cloopTime
      // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
      l_hour = (flow_frequency * 60 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
      flow_frequency = 0; // Reset Counter
      Serial.print(l_hour, DEC); // Print litres/hour
      Serial.println(" L/hour");
   }
}

```

*Originally found here: source*

to an Class based solution:

```
/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
class FlowSensor {
  volatile int flow_frequency;
  unsigned int l_hour;
  unsigned char pin;
  unsigned long currentTime;
  unsigned long cloopTime;
  public:
    void flow () {
      flow_frequency++;
    };
    void setup() {
      pinMode(pin, INPUT);
      digitalWrite(pin, HIGH); // Optional Internal Pull-Up
      Serial.begin(9600);
      attachInterrupt(digitalPinToInterrupt(pin), flow, RISING); // Setup Interrupt
      sei(); // Enable interrupts
      currentTime = millis();
      cloopTime = currentTime;
    }
    void loop() {
      currentTime = millis();
      // Every second, calculate and print litres/hour
      if(currentTime >= (cloopTime + 1000))
      {
        cloopTime = currentTime; // Updates cloopTime
        // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
        l_hour = (flow_frequency * 60 / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
        flow_frequency = 0; // Reset Counter
        Serial.print(l_hour, DEC); // Print litres/hour
        Serial.println(" L/hour");
      }
    }
    FlowSensor() {
      setup();
    };
};
FlowSensor flowsensor_intake;
void setup()
{
   flowsensor_intake = FlowSensor();
}
void loop ()
{
   flowsensor_intake.loop();
}

```

But i get the following error in the Arduino IDE:

> /tmp/087639235/water\_flow/water\_flow.ino: In static member function 'static void FlowSensor::flow()':
>
> /tmp/087639235/water\_flow/water\_flow.ino:17:19: error: cannot call member function 'void FlowSensor::update\_flow()' without object
>
> update\_flow()
>
> ^
>
> exit status 1

I understand that flow is not a static function and that i cannot make it static because it is midifying a non static member.

But i cannot think of an alternate solution to this Problem. My goal is to monitor multiple flow sensors by creating an object in the `setup()` function, and updating them with every `loop()` call.

# Answer
You've run into a classic trap. There are a couple of things to think about. First off, if this is a singleton class (as in there will only ever be one instance) then you can just have a non-member function that you use with attachInterrupt and have that function just call the member function you want. Normally what I would do would be to create the instance in the .cpp and put an extern declaration for it in the header so that it can just be used without creating it. Look at how Serial works for an example. Then put all the configuration type stuff into a begin or init method to call from setup. That way the non-member function for the interrupt can be part of the header and the user never has to see or mess with it and it feels like it's part of the class.

If this is not a singleton class and you might one day have several instances of this in one program then you have to start asking yourself how will the interrupt know which instance to act upon.
> 1 votes

---
Tags: arduino-mega, programming, c++, sketch, cpp
---


# Question
Title: PWM supplying led breaks down at near to zero threshold
I use timer1, mode 8, on both pin 9 and 10 at 1 kHz my PWM signal breaks down when I turn the potentiometer just above where I set the zero at, no matter where I set the zero at. I power the Arduino atmega328p with Vin and disconnect from the PC. I have potentiometer to A0 and pin out 9 or 10 connected to the oscilloscope. I have code and picture below.

The problem with my code is that I can't get TCNT1 or TCNT2 to start where I set it anywhere else but zero.

```
#include <avr/io.h>
#include <avr/interrupt.h>
//#include <SPI.h>
//ISR(TIM1_COMPA);
//ISR(TIM1_CAPT);

int analogInPin = PC0;
int analogOutPin9 = PB1;
int analogOutPin10 = PB2;
int analogOutPin3 = PD3;
int analogOutPin11 = PB3;
//int analogInPin = A0;
//int analogOutPin9 = 9;
//int analogOutPin10 = 10;

int sensorValueTimer1;
int sensorValueTimer2;

void sens(int &sensorValueTimer1, int &sensorValueTimer2){
   sensorValueTimer1 = (((long)analogRead(analogInPin)*1000)/1023);
   if (sensorValueTimer1 < 35){  //to stop flickering at low end
     sensorValueTimer1 = 0;
     }
        sensorValueTimer2 = (((long)analogRead(analogInPin)*255)/1023);
   if (sensorValueTimer2 < 0){  //to stop flickering at low end
     sensorValueTimer2 = 0;
     }
}

void updateOCRnx(){
  sens(sensorValueTimer1,sensorValueTimer2);
  int x = sensorValueTimer1;
  int y = sensorValueTimer2;
  OCR1A = x;
  OCR1B = x;
  OCR2A = y;
  OCR2B = y;
}

void setup() {
  Serial.begin(9600);
  //===============mode 5 pin 3,11==================//
  /*
  //TCCR2A = 0;
  //TCCR2B = 0;
  TCCR2A |= (1<<COM2A1);
  TCCR2A |= (1<<COM2A0);
  TCCR2A |= (1<<COM2B1);
  TCCR2A |= (1<<COM2B0);
  TCCR2A |= (1<<WGM21);
  TCCR2A |= (1<<WGM20);
  TCCR2B &= ~(1<<WGM22);
  TCCR2B &= ~(1<<CS22);
  TCCR2B |= (1<<CS21);
  TCCR2B |= (1<<CS20);

  //TIMSK2 |= (1<<OCIE2A);
  //TIMSK2 |= (1<<OCIE2B);
  //TIMSK2 |= (1<<TOIE2);
  //ASSR &= ~(1<<TCN2UB);
  //TIFR2 |= (1<<OCF2A);
  //TIFR2 |= (1<<TOV2);

  TCNT2 = 100;
 */
  //====================mode 5 pin 3,11=====================//
  //=====================mode 8 pin 9,10=====================//
  //TCCR1A = 0;

  TCCR1A |= (1<<COM1A1);
  TCCR1A &= ~(1<<COM1A0);
  TCCR1A |= (1<<COM1B1);
  TCCR1A &= ~(1<<COM1B0);
  TCCR1A &= ~(1<<WGM11);
  TCCR1A &= ~(1<<WGM10);
  TCCR1B |= (1<<WGM13);
  TCCR1B &= ~(1<<WGM12);
  TCCR1B |= (1<<CS11);
  TCCR1B &= ~(1<<CS12);
  TCCR1B &= ~(1<<CS10);

  //TCCR1B |= (1<<ICES1);

  //TCCR1C |= (FOC1A);
  //TCCR1C |= (FOC1B);

  ICR1=1000;  //1.333KH
  TCNT1=0;

  //TIMSK1 |= (1<<TOIE1);
  //TIMSK1 |= (1<<OCIE1A);
  //TIMSK1 |= (1<<OCIE1B);
  //TIMSK1 |= (1<<ICIE1);
  //TIFR1 |= (1<<TOV1);
  //TIFR1 |= (1<<OCF1A);
  //TIFR1 |= (1<<OCF1B);

  //EIMSK |= (1<<INT1);
  //EIFR |= (1<<INTF1);
  //EICRA &= ~(1<<ISC11);
  //EICRA &= ~(1<<ISC10);

  //PCMSK0 |= (1<<PCINT2);
  //PCICR |= (1<<PCIE0); //pin change interrupt 0 is enabled
  //PCIFR |= (1<<PCIF1); // triggers an interrupt request
  //=======================mode 8 pin 9,10=======================//

  sei();

  //pinMode(analogOutPin9,OUTPUT);
  //pinMode(10, INPUT);
  //pinMode(analogInPin, INPUT);

  //char data;

  DDRB |= (1<<analogInPin);
  DDRB |= (1<<analogOutPin9);
  DDRB |= (1<<analogOutPin10);
  DDRB |= (1<<analogOutPin11);
  DDRB |= (1<<analogOutPin3);
  //DDRB |= (1<<PB5);
  //DDRB &= ~(1<<PB4);

  //SPSR |= (1<<SPIF);

  //SPCR |= (1<<SPE);
  //SPCR |= (1<<MSTR);
  //SPSR &= ~(SPR1);
  //SPCR |= (1<<SPR0);
  //SPSR |= (1<<SPI2X);

  //SPDR = data;

}

void loop() {
  updateOCRnx();
  Serial.println(TCNT1);
  //delay(100);
  //int sensorValue = (((long)analogRead(analogInPin)*1000)/1023);
  //int sensorValue = analogRead(analogInPin);
  //analogWrite(analogOutPin9, sensorValue/4);
  //analogWrite(analogOutPin10, sensorValue/4);
  //Serial.println(analogOutPin9);
}

```

# Answer
> -1 votes
The analogread pin is unstable. This fixed it,ResponsiveAnalogRead, from github

---
Tags: led, interrupt, pwm
---


# Question
Title: Crazy Results with I2C and I2C_Anything()
I have the following code in a Arduino Mega function to retrieve two 4-byte integers from a Teensy 3.2.

```
Wire.requestFrom(SLAVE_ADDR, sizeof(float)+ 2*sizeof(long));
mySerial.printf("\n<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>\n\n");
mySerial.printf("Wire.Available() reports %d\n", Wire.available());
I2C_readAnything(Fin1);
mySerial.printf("Read Fin1 %d, Wire.Available() reports %d\n",Fin1, Wire.available());
Fin2 = Fin1;
mySerial.printf("Fin1 = %d, Fin2 = %d\n", Fin1, Fin2);
I2C_readAnything(Fin2);
mySerial.printf("Read Fin2 = %d, Wire.Available() reports %d\n", Fin2, Wire.available());
mySerial.printf("Fin1 = %d, Fin2 = %d and SteeringValue = %2.2f\n", Fin1, Fin1, SteeringValue);
mySerial.printf("Read %f, Wire.Available() reports %d\n", SteeringValue, Wire.available());
mySerial.printf("Fin1 = %d, Fin2 = %d and SteeringValue = %2.2f\n", Fin1, Fin1, SteeringValue);

```

And this produces the following output:

```
<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>

Wire.Available() reports 12
I2C_readAnything: Sizeof(value) = 4
Read Fin1 5375, Wire.Available() reports 0
Fin1 = 5375, Fin2 = 0
I2C_readAnything: Sizeof(value) = 4
Read Fin2 = 10750, Wire.Available() reports 0
Fin1 = 5375, Fin2 = 0 and SteeringValue = 0.00
Read 0, Wire.Available() reports 4
Fin1 = 5375, Fin2 = 0 and SteeringValue = 0.00

```

This is driving me nuts, because while the Fin1 & Fin2 values are apparently received correctly, the Fin2 value is always reported as 0, even after it was explicitly set to be equal to Fin1 as a test (line 6 in the code).

The values obtained from the Teensy (5375 and 10750 in the output snippet) are correct, but I can't get Fin2 to print out correctly (the 'SteeringValue' issue is probably the same as the 'Fin2' problem, but I haven't gotten there yet).

I cannot for the life of me figure out what I'm doing wrong here. Could someone walking by take a glance from 30 feet away and immediately see the problem?

TIA,

Frank

3/31/20 Update:

I finally got Wire.requestFrom() & I2C\_Anything() to behave the way I thought it should, but I'm still left with a mystery - why the PrintEx version of printf refuses to print the values properly: Here's the code snippet:

```
//get latest info from IR Demod Module
long Fin1 = 0; //03/30/20 needs to be 'long int' (4 bytes) here to match Teensy int (4 bytes)
long Fin2 = 23; //03/30/20 needs to be 'long int' (4 bytes) here to match Teensy int (4 bytes)
float SteeringValue;

mySerial.printf("\n<<<<<<<   In IsIRBeamAvail()  >>>>>>>>>>>>>>>>>>>>\n\n");

Wire.requestFrom(SLAVE_ADDR, sizeof(Fin1) + sizeof(Fin2)+ sizeof(SteeringValue));
mySerial.printf("Wire.Available() reports %d\n", Wire.available());

I2C_readAnything(Fin1);
mySerial.printf("Fin1 = %d\n", Fin1);

I2C_readAnything(Fin2);
mySerial.printf("Fin2 = %d\n", Fin2);

I2C_readAnything(SteeringValue);
mySerial.printf("SteeringValue = %2.3f\n", SteeringValue);

mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringVal = %6.3f\n", Fin1, Fin2, SteeringValue);

```

And here's the output produced. As you can see, the individual values print out correctly, but when combined into the last mySerial.printf() statement, things go awry. Anyone have a clue?

```
Wire.Available() reports 12
I2C_readAnything: Sizeof(value) = 4
Fin1 = 1986
I2C_readAnything: Sizeof(value) = 4
Fin2 = 3972
I2C_readAnything: Sizeof(value) = 4
SteeringValue = 6239.219
Fin1 = 1986, Fin2 = 0, SteeringVal =  0.000

```

Frank

And one last update: I compared the output obtained by using the StreamEx mySerial = Serial; object, and the one obtained by using the more traditional Serial.print() statement. The code

```
    Serial.print("Fin1 = "); Serial.print(Fin1); Serial.print(", ");
Serial.print("Fin2 = "); Serial.print(Fin2); Serial.print(", ");
Serial.print("SteeringValue = "); Serial.println(SteeringValue);
mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

```

And the output:

```
Fin1 = 9185, Fin2 = 18370, SteeringValue = 28851.73
Fin1 = 9185, Fin2 = 0, SteeringValue = 0.00

```

The top line is entirely correct, but for some reason, the mySerial.printf() version gets it wrong. Ideas?

Frank

# Answer
The devil is in the details. From the PrintEx repo doc, this is the formatting for printf:

> %\[flags\]\[width\]\[.precision\]\[length\]specifier

When you use ***long***, you will have to provide the \[length\], and the lib only accepts "**l**" (Letter L).

```
#include <PrintEx.h>

long int Fin1 = 5;
long int Fin2 = 2;
float SteeringValue = 3.5;

void setup()
{
  Serial.begin(9600);
  PrintEx mySerial = Serial;

  Serial.print("Fin1 = "); Serial.print(Fin1); Serial.print(", ");
  Serial.print("Fin2 = "); Serial.print(Fin2); Serial.print(", ");
  Serial.print("SteeringValue = "); Serial.println(SteeringValue);

  // This will fail
  mySerial.printf("Fin1 = %d, Fin2 = %d, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);

  // This will work as expected
  mySerial.printf("Fin1 = %ld, Fin2 = %ld, SteeringValue = %3.2f\n", Fin1, Fin2, SteeringValue);
}

void loop() {}

```

Line 16 is what you have. Line 19 is the format you should use.
> 1 votes

---
Tags: arduino-mega, teensy
---


title: Serial.println() not working in ISR

text:
# Question
Title: Serial.println() not working in ISR
Please refer my below code,

```
const int led_pin = PB5;
const uint16_t t1_load = 0;
const uint16_t t1_comp = 43750;
int blinkcount;

void setup() {
  // put your setup code here, to run once:
  DDRB |= (1<< led_pin);
  TCCR1A = 0;
  //TCCR1B = 0X03;
 TCCR1B |= (1 << CS12);
 TCCR1B &= ~(1 << CS11);
 TCCR1B &= ~(1 << CS10);

  TCNT1 = t1_load;
  OCR1A = t1_comp;

  TIMSK1 = (1 << OCIE1A);
  Serial.begin(9600);
  sei();

}

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

}

ISR(TIMER1_COMPA_vect) {
  TCNT1 = t1_load;
  PORTB ^= (1 << led_pin);
  blinkcount = blinkcount + 1;
  Serial.println(blinkcount);
}

```

the Serial.println(blinkcount); not working or the serial window does not show up.

Apologies if it sound stupid as I'm new to programming.

# Answer
> 0 votes
ISR are simply not intended for this abuse.

If you want to use Arduino level functions, you must have good reasons why you need to mix them with direct arv-gcc hardware-accessing code (or vice versa).

If you're new to programming and to Arduino, simply ignore that level (for now).

`DDRB |= BV(PB5);` is easier understandable if you write

`pinMode(13,OUTPUT);` ( or even use LED\_BUILTIN instead of 13 )

# Answer
> 0 votes

const uint16_t t1_load = 0;
const uint16_t t1_comp = 43750;
int blinkcount;
int flag, flag_1, a, i;

void setup() {
  // put your setup code here, to run once:
  DDRB |= (1<< led_pin);
  TCCR1A = 0;
  //TCCR1B = 0X03;
 TCCR1B |= (1 << CS12);  //for 256 prescalar
 TCCR1B &= ~(1 << CS11);
 TCCR1B &= ~(1 << CS10);

/* TCCR1B &= ~ (1 << CS12);
 TCCR1B |= (1 << CS11);
 TCCR1B &= ~(1 << CS10);*/

  TCNT1 = t1_load;
  OCR1A = t1_comp;

  TIMSK1 = (1 << OCIE1A);
  Serial.begin(9600);
  sei();

}

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

/*  blinkcount = blinkcount + 1;
  if(blinkcount++)
  {
    flag = 1;
  }
  if(flag == 1)
  {
    Serial.println("ok");
  }*/

}

void loop_1()
{
  i = blinkcount;
  //for(i=0; i<=blinkcount; i++);
  //{
  i = i + 1;
  //if(i++)
  // {
    flag = 1;
    flag_1 = flag;
   //}
  if(flag_1 == 1)
  {
    Serial.println(flag_1);
  }
//  }
}

ISR(TIMER1_COMPA_vect) {
  TCNT1 = t1_load;
  PORTB ^= (1 << led_pin);
  //blinkcount = blinkcount + 1;
  //Serial.println(blinkcount);
  loop_1();

}```

I've changed the code according to your suggestion, the tx led on arduino blinks but serial monitor does not pop up

---
Tags: serial, timers
---


# Question
Title: Reading bmp images from SD card, converting it and displaying it on serial monitor in Arduino
Can someone please help me write code that can read a 24-bit BMP file from an SD card, save converted to 8-bit BMP internally, and display the 8-bit BMP pixel values on Arduino terminal as a 2D matrix. The program should align the bytes as two HEX values on the Arduino terminal. I am new to this and not sure how to go about it. Your help will be much appreciated.

The image is present in the SD card and coded as:

```
include <SD.h>
include <SD_t3.h>

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

void loop() {
  if (!SD.begin (BUILTIN_SDCARD)) {
    Serial.println ("NO SDCARD");
    while (1);
  } else {
    Serial.println ("YES SDCARD");
  }
  delay (1000);
  if (SD.exists("filename.BMP")) {
    Serial.println ("filename.BMP exists");
  } else {
    Serial.println ("filename.BMP missing");
    while (1);
  }
  delay (1000);
  File hFi = SD.open ("filename.bmp", FILE_READ);
  if (hFi == false) {
    Serial.println ("File open failed");
    while (1);
  }

```

# Answer
> 0 votes
You have to writeyour own routines. To get you started Look at this source code
Add `view-source:https://javl.github.io/image2cpp/`. Although it is javascript, it can be transferred to C++ to a working conversion routine. The important part are the conversion routines.
A word of warning: As the memory os limited you will have to do a line by line read from SD card convert line and write line by line back or you use maximum 16x16 size.
Thats the reason why most converters run in browser or PC and the result is used in Arduino. An ESP8266 with 4MB memory would make life easier. For an implementation of graphic routines on Arduino Teensy look into this gaming library

---
Tags: arduino-ide, sd-card, teensy, convert
---


title: Passing struct from main.cpp to a class

text:
# Question
Title: Passing struct from main.cpp to a class
Sorry if this question been posted but I couldn't find the one that matches my issue. I couldn't pass my struct values from the main file to a class. Any ideas? I got this:

```
error: no matching function for call to 'ODriveArduino::SetParam(R_motor_params&)'

```

Main.cpp:

```
#include ODriveArduino.h
ODriveArduino odrive(Serial1);

struct L_motor_params{
 int axis=1;
 float vel_Gain= 2.5f/10000.0f ;
 float pos_Gain= 40.0f;
 float vel_Int_Gain= 0.0f/10000.0f;
};
struct R_motor_params{
 int axis=0;
 float vel_Gain= 2.75f/10000.0f ;
 float pos_Gain= 40.0f;
 float vel_Int_Gain= 0.0f/10000.0f;
};

void setup() {
  struct R_motor_params M;
  odrive.SetParam(M);
}

```

ODriveArduino.h:

```
class ODriveArduino {

private:

    struct motor_Params{
      int axis;
      float vel_Gain;
      float pos_Gain;
      float vel_Int_Gain;
    };

public:
    ODriveArduino(Stream& serial);

    // Commands
    void SetParam(struct motor_Params M);

 }

```

ODriveArduino.cpp:

```
#include "ODriveArduino.h"
template<class T> inline Print& operator <<(Print &obj,     T arg) { obj.print(arg);    return obj; }
template<>        inline Print& operator <<(Print &obj, float arg) { obj.print(arg, 4); return obj; }

ODriveArduino::ODriveArduino(Stream& serial)
    : serial_(serial) {}

void ODriveArduino::SetParam(struct motor_Params M){
  Serial1 << "w axis" << M.axis << ".motor.config.pos_gain " << M.pos_Gain << '\n';
  Serial1 << "w axis" << M.axis << ".motor.config.vel_gain " << M.vel_Gain << '\n';
  Serial1 << "w axis" << M.axis << ".motor.config.vel_integrator_gain " << M.vel_Int_Gain << '\n';
}

```

# Answer
It looks like you're trying to implement polymorphism without implementing polymorphism.

What you have done is create three completely independent structures and assumed that they will all work together just because they are the same size, with similar names, and fields named the same. That's not the case. They are all completely separate.

Instead you want just *one* structure but to use it multiple times to create different variables:

```
// from ODriveArduino.h, but move *outside* the class
struct motor_Params{
      int axis;
      float vel_Gain;
      float pos_Gain;
      float vel_Int_Gain;
};

// in your code
struct motor_Params left_params = {
    1, 2.5f/10000.0f, 40.0f, 0.0f/10000.0f
};

struct motor_Params right_params = {
    0, 2.75f/10000.0f, 40.0f, 0.0f/10000.0f
};

// later
  odrive.SetParam(left_params);

```
> 1 votes

---
Tags: c, atmega2560
---


title: smart coding possible?

text:
# Question
Title: smart coding possible?
Is there a way to clean up this code...or do some smart coding?

In this example I use 6 relays, in the final code it will be 10.

Also I now use 5 switches and that will be 8, each with an own led. Now I only stated 1 led.

The code reads a button, and a few relays will get a signal. Also the buttonled will go on. I will add more cases later. But I was wondering, is it possible/easier/just another way of writing the high/low to the relays and leds.

Can I somehow combine the LOWs or HIGHs within a case?

```
int relay1 = A5;
int relay2 = A4;
int relay3 = A3;
int relay4 = A2;
int relay5 = A1;
int relay6 = A0;

int led1 = 3;

int sw1 = 5;
int sw2 = 6;
int sw3 = 7;
int sw4 = 8;
int sw5 = 9;

int sw1Status, sw2Status, sw3Status, sw4Status, sw5Status;
int order = 1; // default is to set all relays off.

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

  pinMode(led1, OUTPUT);

  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  pinMode(relay5, OUTPUT);
  pinMode(relay6, OUTPUT);
  // input pull-up, so default state of buttons is HIGH.
  pinMode(sw1, INPUT_PULLUP);
  pinMode(sw2, INPUT_PULLUP);
  pinMode(sw3, INPUT_PULLUP);
  pinMode(sw4, INPUT_PULLUP);
  pinMode(sw5, INPUT_PULLUP);

}

void loop() {

  // read the buttons status
  sw1Status = digitalRead(sw1);
  sw2Status = digitalRead(sw2);
  sw3Status = digitalRead(sw3);
  sw4Status = digitalRead(sw4);
  sw5Status = digitalRead(sw5);

  if (sw1Status == LOW) { // if button 1 pressed
    order = 2; // go to case 2
  }
  if (sw2Status == LOW) {
    order = 3;
  }
  if (sw3Status == LOW) {
    order = 4;
  }
  if (sw4Status == LOW) {
    order = 5;
  }
  if (sw5Status == LOW) { // button 4 toggle
    if (order != 7) { // if order is not equal 5 turn on relay 1 & 4
      order = 6;
    }
    else { // else go to case 1, which will turns off all relays
      order = 1;
    }
  }

  switch (order) {
    case 1: // if order equals 1
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, LOW);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, LOW);
      break;

    case 2: // if order equals 2
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, LOW);
      digitalWrite(relay5, HIGH);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, HIGH);
      break;

    case 3: // if order equals 3
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, HIGH);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, HIGH);
      digitalWrite(led1, LOW);
      break;

    case 4: // if order equals 4
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, LOW);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, LOW);
      break;

    case 5: // if order equals 5
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, HIGH);
      digitalWrite(relay5, HIGH);
      digitalWrite(relay6, HIGH);
      digitalWrite(led1, LOW);
      break;

    case 6: // if order equals 5
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, HIGH);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, LOW);
      break;

    default: // if none of above cases is valid go to case 1
      order = 1;
      break;
  }
}

```

# Answer
If all are handled the same and they don't have individual names, arrays and for loops are what you are looking for.

```
const byte relayPins[] = { A5, A4, A3, A2, A1, A0};
const byte ledPin = 3;
const byte swPins[] = {5, 6, 7, 8, 9};

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  for (const byte relayPin: relayPins) pinMode(relayPin, OUTPUT);
  for (const byte swPin: swPins) pinMode(swPin, INPUT_PULLUP);
}

```

*Even arduino C++ nowadays understands the foreach syntax.*

BTW: for your final pin count you'll need other/additional hardware. Either a Mega or shift registers or port expanders.
> 1 votes

# Answer
Arduino Uno has 3 ports. You can read and write the ports as 1 byte.

With all the switches on one port, you can read them all at once. For example, using D7 to D3 to read the switches:

```
switches = (PIND & 0b11111000) >>3; // read D7 to D0, mask off D2-1-0, move data to lower 5 bits

```

Then you could have case (switches): for the 0 to 31 cases that are possible.

With all the relays on one port, you can change them all at once. For example, using D14 to D19 for the relays:

```
PORTC = 0b00110011; // Dxx, Dxx, D19,18,17,16,15,14 or A5,A4,A3,A2,A1,A0

```

to turn on relays 1,2,5,6, and 3,4 off.

The LED would still be on its own.
> 0 votes

---
Tags: arduino-uno
---


title: Nokia 5110 LCD number display problem

text:
# Question
Title: Nokia 5110 LCD number display problem
I have a problem regarding a Nokia 5110 LCD display. I am currently building a soldering station based on a PID controller. The original code was using a 7 segment display and I adapted the code to the Nokia display.

The problem is that when I rotate the potentiometer, the "read temp" and "set temp" is showing the exactly the same number, and after I finish rotating the potentiometer, the values return to their normal number.

How can I solve this problem ?

This is my code: https://pastebin.com/inPtkniX

This is the original project: https://www.allaboutcircuits.com/projects/do-it-yourself-soldering-station-with-an-atmega8/

```
//Soldering station Software using PID
//Thank you Alex from https://geektimes.ru/ for help with led array function
//AllAboutCircuits.com
//epilepsynerd.wordpress.com

#include <PID_v1.h>
#include <PCD8544.h>

PCD8544 lcd;
unsigned long updaterate = 500; //Change how fast the display updates. No lower than 500
unsigned long lastupdate;
int temperature = 0;
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Define the aggressive and conservative Tuning Parameters
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);

void setup() {
  lcd.begin(84, 48);
  //We do not want to drive the soldering iron at 100% because it may burn, so we set it to about 85% (220/255)
  myPID.SetOutputLimits(0, 220);
  myPID.SetMode(AUTOMATIC);
  lastupdate = millis();
  Setpoint = 0;
}

void loop() {
  lcd.clear();
  //Read temperature
  Input = analogRead(0);
  //Transform the 10bit reading into degrees celsius
  Input = map(Input, 0, 450, 25, 350);
  //Display temperature
  if (millis() - lastupdate > updaterate) {
    lastupdate = millis();
    temperature = Input;
  }
  //Read setpoint and transform it into degrees celsius(minimum 150, maximum 350)
  double newSetpoint = analogRead(1);
  newSetpoint = map(newSetpoint, 0, 1023, 150, 350);
  //Display setpoint
  if (abs(newSetpoint - Setpoint) > 3) {
    Setpoint = newSetpoint;
    //temperature = newSetpoint;
    lastupdate = millis();
  }
  double gap = abs(Setpoint - Input); //distance away from setpoint
  if (gap < 10) {
  //we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  } else {
    //we're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  //Drive the output
  analogWrite(11, Output);
  //Display the temperature
  show(temperature, newSetpoint);
}

void show(int value, int newspnt) {
  lcd.setCursor(0, 0);
  lcd.print("READ TEMP");
  lcd.setCursor(0, 1);
  lcd.print(value);
  lcd.setCursor(0, 2);
  lcd.print("SET TEMP");
  lcd.setCursor(0, 3);
  lcd.print(newspnt);
  delay(200);
}

```

# Answer
> 2 votes
Look at line 55, where you are doing this

```
temperature = newSetpoint;

```

There is no reason to give temperature the same value as the set point. It does not make sense. And the `temperature` variable is the same, that you are using to display.

So, while you are changing the setpoint, the `temperatur` variable gets overwritten with the setpoint. When you are not changing it anymore, the measured temperature is still in this variable, when you are displaying it.

Just remove the mentioned line.

---
Tags: display
---


# Question
Title: Getting coordinates from a touch panel with I2C
Hello world (this is my first message in this forum).

I am quite a just-married-to-Arduino guy, I am very passionate about this platform that I kew since long time but never had the time to dedicate.

Now I have done several home projects that made me both feel happy and feel sooooo rookie... But hey, here I am trying more and more complex things.

I am trying to do something I haven't found information about: I have a 10" touch panel (I am not talking about a screen, just the touch surface) which is a capacitive 10 pin panel that communicates with I2C protocol (there are SCL and SDK pins). I have managed to scan the address and turns out it is in the #40.

However, other than that I do not have the knowledge to get the coordinates out of that panel. My question is: is there any library that can help me with that or will I need to code everything?

I am attaching some pictures of the panel and the pinout to have a clearer picture of what I am talking about.

I thank you all for your time reading my post, I hope some day I will be able to provide some answers rather than questioning!

Joan.

# Answer
> 2 votes
There is a simple library that works for FT5xx6 display panel.

**Other information available:**

Application node - https://cdn-shop.adafruit.com/datasheets/FT6x06\_AN\_public\_ver0.1.3.pdf

Datasheet - https://www.newhavendisplay.com/appnotes/datasheets/touchpanel/FT5x26.pdf

In case those links might be no longer available in the future, a quick search on FocalTech FT5xx6 should give you the relevant information.

---
Tags: arduino-mega
---


# Question
Title: availableForWrite() function return error when compiling for Arduino nano 33 BLE
I used availableForWrite() function as below in my code. When I compile it for nano 33 IoT, everything is OK and compiles perfectly. However, when I change the board to nano 33 BLE, I end up with two scenarios: 1. using Arduino IDE as compiler \> gives no error but the board doesn't after programming. 2. using the web-based compiler in Arduino website \> give the following error:

```
error: 'class Arduino::USBSerial' has no member named 'availableForWrite'; did you mean 'available'?"

```

my code:

```
NoreplyTime=millis();
TimePassed= millis()-NoreplyTime;

         while(!Serial.availableForWrite()){
         TimePassed= millis()-NoreplyTime;
         if (TimePassed>1000){
         return false;
         }
        }

```

even simply having:

```
while (!Serial.availableForWrite());

```

generates error ONLY for nano 33 BLE board!

Thoughts?

# Answer
> 1 votes
The new Arduino cores use a common API maintained in a separate repository. This was copied from AVR core long time ago and doesn't contain some function added later to other cores. The function Stream.availableForWrite was added to Arduino API repository 5 months ago.

For the Arduino Mbed core they created a branch in the Arduino API repository to move the Arduino core in C++ namespace 'arduino'. But this was before availableForWrite was added. So the API version used in Mbed core doesn't have the function.

I reported it as issue. Even if they add the function to API I doubt they add an implementation of it to Serial.

---
Tags: serial, arduino-nano, arduino-nano-ble
---


# Question
Title: Sound quality is poor using a piezo in TinkerCad
I did a quick search and couldn't seem to find this question posted already, but I'm sure it must have so forgive me if it's a repeat.

I'm using a piezo and Arduino on TinkerCad to produce notes using the tone function, and the quality is not great (it's as if I can hear beats while the note is playing). I vaguely remember a colleague telling me this was an issue with the way my computer speakers handle square waves (I have a Macbook Air if that makes any difference), but I'm not positive. Has anyone had success in using TinkerCad to produce nicer sounding notes? If not, can anyone explain what the issue is to me?

Thank you!

# Answer
> 1 votes
To pack the comments into a proper answer to the question:

As Majenko stated in the comments, Tinkercad is a simulation. The codes doesn't get compiled and uploaded to hardware. Instead Tinkercad interprets the code on the fly. Simulations are not perfect clones of the real hardware, so you cannot expect the same performance from it as from the real Arduino. Also it is not build for producing high quality sound. The focus is entirely on simulating how the Arduino works.

If you are using this with a real Arduino you most likely will not have the glitches in sound.

What you are currently hearing is not a problem of Arduino, but of Tinkercad. You could file a problem with the developer, but probably they will not think this is an issue, or they will give it a very low priority.

---
Tags: sound, piezo, buzzer, speaker
---


title: Slow refresh rate of 1.8 TFT display

text:
# Question
Title: Slow refresh rate of 1.8 TFT display
I have 1.8 TFT display for Arduino Nano and it changes color very slow. When I try to change the color of the whole screen I see how it changes color line by line. I use "Adafruit GFX graphics core" and "Adafruit ST7735" libraries to change colors.

**Question:** Slow refresh rate of 1.8 TFT display is due to limited computation capability of Arduino or 1.8 TFT display itself or library used?

# Answer
The ST7735 TFT uses SPI to communicate. That can *never* be particularly fast.

At 160x128 pixels with 16-bit colour depth that gives you 327680 bits that you need to transfer just for the colour data. On top of that you have 88 bits to set up a drawing window (11 bytes of "set X coordinate and width" \[5 bytes\], "set Y coordinate and height" \[5 bytes\] and "start drawing" \[1 byte\]).

That's a total of 327768 bits that you need to transfer.

Now the transferring of that data is at the mercy of the SPI clock speed. How fast that can go depends on what the ST7735 can work at and the quality of your wiring (if it's a shield you can almost discount the wiring). Assuming you can operate at the maximum 8MHz that the Arduino can run SPI at (which is probable) then you get:

```
8,000,000
---------   =  24.4 frames per second
 327768

```

That is the absolute maximum theoretical speed, and doesn't take into account any work done by the Arduino to actually send the data. The SPI library is completely blocking in its operation and each pixel has to be sent separately as one blocking transaction. So you can expect about half that rate in reality, if not less, while it loops around and sends each pixel, then blocks waiting for the pixel to be sent.

And of course that's assuming running at the maximum speed. In reality that probably isn't happening. Libraries that use SPI often choose the "lowest common denominator" for their SPI speed (if they actively choose a speed at all) so that the library "just works" in the majority of cases. So the speed the library is running at will most likely be considerably lower than the actual maximum speed you *could* run at.

For example, if it runs at 1MHz instead of 8MHz then you will get about 3 frames per second (which is more like what you are describing).

So examine your chosen library and see what it does in the way of configuring the SPI speed. If it doesn't do anything then consider adding code to increase the speed. If it does then consider increasing the speed it operates at (see the SPI library reference for more details).

TBH, though, a small Arduino is seldom a good choice to control a TFT screen. At the bare minimum you really need a chip with far more memory so you can draw graphics "off-screen" in a framebuffer, and then use DMA to transfer that off-screen buffer to the TFT screen over a 16-bit parallel connection at high speed while leaving the CPU free to do other jobs. Or even better a microcontroller with a built-in TFT controller to directly generate the correct drive signals for a TFT panel and store the whole screen image in internal RAM.
> 3 votes

# Answer
Given you use the last library versions and have the cables right - it is hard to guess without your code.

So to check if it your code load one or two of the library examles and see if it works there.
Another option is to set SPI speed the set with begin(freq) is not working, because its wrong see more in this issue.
If the problem still exists come back with wiring and code used. The nano is not the best choice with TFTs but runs decently.
> 1 votes

---
Tags: arduino-nano, display, tft
---


# Question
Title: Marlin g-codes applicable for a Melzi Sanguino board
How/where do I find a complete listing of "acceptable" Marlin g-codes applicable to a Melzi Sanguino board on a 3D printer (Zonestar). It appears that not all printer boards accept all available Marlin codes.

---

Then I was thinking incorrectly. I had assumed that not all g-codes (from a Marlin build) were, in fact, “implemented” the same way on all boards, and some would not even be recognized or interpreted. But I still don’t understand why that is.

# Answer
As already written in the comments the software defines what G-Codes are taken by a (printer) board
**BUT** Even if the software has the same name (eg Marlin) it might behave different on different boards because of:

* different release versions for different hardware
* different release repositories being ahead or behind the master repo
* hardware specific features a G-code triggers (most unlikely)

The clever way is to go from features I need to software supporting thosefeatures to boards supported AND useable for my hardware to controll (3d-printer/CNC-router/laser-cutter aso) \-
> 1 votes

---
Tags: arduino-uno
---


title: Including Class with .h and .cpp files

text:
# Question
Title: Including Class with .h and .cpp files
I am trying to use a class in .ino file. The code is:
.ino file

```
#include <LED.h>

int Pin1 = 13;
int Pin2 = 12;
int Pin3 = 11;
LED led;
void setup() {
  pinMode(Pin1,OUTPUT);
  pinMode(Pin2,OUTPUT);
  pinMode(Pin3,OUTPUT);
  digitalWrite(Pin1,LOW);
  digitalWrite(Pin2,LOW);
  digitalWrite(Pin3,LOW);
}

void loop() {
  led.on(Pin1);
  delay(2);
  led.on(Pin2);
  delay(2);
  led.on(Pin3);
  delay(2);
}

```

.h file

```
#ifndef LED_h
#define LED_h

class LED{
public:
    void on(int);
    void off(int);
};

#endif

```

.cpp file

```
#include <stdio.h>
#include <Arduino.h>
#include "LED.h"

void LED::on(int PIN){
    digitalWrite(PIN,HIGH);
}

void LED::off(int PIN){
    digitalWrite(PIN,LOW);
}

```

Arduino compiler picks the object declaration error:

LEDC:6: error: 'LED' does not name a type
LEDC.ino: In function 'void loop()':
LEDC:17: error: 'led' was not declared in this scope

How should I declare objects in Arduino then?

The way that I am putting the files in folders is like the attached image:

# Answer
> 1 votes
That version of the IDE (it seems to change from version to version) differentiates between includes with `<...>` and includes with `"..."`.

If you use `<...>` it only looks in the system and library areas. If you use `"..."` it also looks inside your sketch.

So in your main INO file change the LED include from:

```
#include <LED.h>

```

To:

```
#include "LED.h"

```

and it should compile.

# Answer
> 0 votes
All you need to do is this in the (.ino)

```
#include <LED.h>

int Pin1 = 13;
int Pin2 = 12;
int Pin3 = 11;
LED led1;
LED led2;
LED led3;
void setup() {
  pinMode(Pin1,OUTPUT);
  pinMode(Pin2,OUTPUT);
  pinMode(Pin3,OUTPUT);
  digitalWrite(Pin1,LOW);
  digitalWrite(Pin2,LOW);
  digitalWrite(Pin3,LOW);
}

void loop() {
  led1.on(Pin1);
  delay(2);
  led2.on(Pin2);
  delay(2);
  led3.on(Pin3);
  delay(2);
}

```

---
Tags: c++
---


title: If condition not working as expected

text:
# Question
Title: If condition not working as expected
In the last condition in else if (see code marked with \***), I am not getting my screen with the laser/specklke fail, if both failflag 1 and failgflag 5 is there, however it shows me laser fail instead. Please help to solve my error.

```
#include <UTFT.h>
#include <avr/pgmspace.h>
#include <SPI.h>
#include <avr/wdt.h>
extern uint8_t Retro8x16[];
extern unsigned int virtek3[];  //display pic
UTFT myDisplay(ST7735, 11, 13, 3, 2, 4);

int buttonhold = 0;
int state = HIGH;
int tim = 0;
int tim1 = 0;
int tim2 = 0;
int button = 1;

float volt = 0;
float volt1 = 0;
float volt2 = 0;
float volt3 = 0;
float volt4 = 0;
float volt5 = 0;
float volt6 = 0;
float volt7 = 0;
float volt8 = 0;
float volt9 = 0;
float volt10 = 0;
float volt11 = 0;
float volt12 = 0;
float volt13 = 0;
float volt14 = 0;
float volt15 = 0;
float volt16 = 0;
float volt17 = 0;
float volt18 = 0;
float volt19 = 0;
float volt20 = 0;
float volt21 = 0;
float vcc = 0.0;
float temp = 0.0;
float r1 = 10000.0;
float r2 = 2200.0;
int failflag = 0;

//void(* resetFunc) (void) = 0;

void setup()
{
    pinMode(18, INPUT);   //For NEXT button
    pinMode(20, OUTPUT);  //For Relay power
    pinMode(21, OUTPUT);  //For Relay power
    pinMode(14, INPUT);
    Serial.begin(9600);
    myDisplay.InitLCD();
    myDisplay.clrScr();
    myDisplay.setFont(Retro8x16);

                                                                                digitalWrite(20, HIGH);
    digitalWrite(20, HIGH);
    digitalWrite(21, LOW);

    attachInterrupt(digitalPinToInterrupt(18), next, LOW);
    myDisplay.fillScr(255, 255, 255);
    myDisplay.drawBitmap(20, 1, 126, 126, virtek3, 1);

   while (1) {
    delay(100);
    if (state == LOW) {
    break;
    }
  }
}

void next() {
    state = LOW;
    Serial.println(buttonhold);
    buttonhold++;
    if (buttonhold > 500) {
    //digitalWrite(21, LOW);
    resetFunc();
    }
  }

void loop()
{
  digitalWrite(20, LOW);
 digitalWrite(21, LOW);   //Relay is ON.
  myDisplay.clrScr();
  state = HIGH;
  buttonhold = 0;
  while (1) {
    failflag = 0;
    float voltage_value = 0;

    myDisplay.setColor(0, 255, 255);
    myDisplay.print("1.Voltage Test", 35, 0);

    myDisplay.setColor(255, 255, 255);
    myDisplay.print("(V)", 0, 20);
    myDisplay.print("LASER",50,20);
    myDisplay.print("SPECKLE",100,20);

delay(1000);

      //FOR ANALOG A4 PIN
      //A4 pin connected to TP2 of speckle
      float volt_b = 0;
       float volt_c = 0;
       float volt_d = 0;
      for (int i = 0; i < 1000; i++) {
      volt_b =(volt_b + (4.99 / 1024 * analogRead(A4)));
      }
      volt_b = volt_b / 1000;
      volt1 = volt_b / (r2 / (r1 + r2));

      myDisplay.setColor(255, 255, 255);
      myDisplay.print("TP2 :", 0, 38);

      myDisplay.setColor(0, 255, 255);
      myDisplay.print("NA", 60, 37);

      Serial.println(volt1);                      //ANALOG A4
      if (volt1 >= 5 && volt1 <= 7.30) {
      myDisplay.setColor(0, 255, 0);
      myDisplay.printNumF(volt1, 2, 120, 38);
      //myDisplay.print("  ", 130, 20);
      } else {
      myDisplay.setColor(0, 0, 255);
      myDisplay.printNumF(volt1, 2, 120, 38);
      //myDisplay.print(" ", 150, 38);
      failflag = 1;
      }

      delay(2000);

      digitalWrite(20, HIGH);
      digitalWrite(21, LOW);
       delay(2000);

      //FOR ANALOG A4 PIN
      //A4 pin connected to TP2/L of SPECKLE

      for (int i = 0; i < 1000; i++) {
      volt_b =(volt_b + (4.99 / 1024 * analogRead(A4)));
      }
      volt_b = volt_b / 1000;
      volt2 = volt_b / (r2 / (r1 + r2));

      myDisplay.setColor(255, 255, 255);
      myDisplay.print("TP2/L :", 0, 56);

      myDisplay.setColor(0, 255, 255);
      myDisplay.print("NA", 60, 56);

      Serial.println(volt2);                       //ANALOG A4
      if (volt2 >= 5 && volt2 <= 0.05) {
      myDisplay.setColor(0, 255, 0);
      myDisplay.printNumF(volt2, 2, 120, 56);
      //myDisplay.print("  ", 130, 20);
      } else {
      myDisplay.setColor(0, 0, 255);
      myDisplay.printNumF(volt2, 2, 120, 56);
      //myDisplay.print(" ", 150, 56);
      failflag = 1;
      }

      //FOR ANALOG A1 PIN
      //A1 pin connected to J1_1 of SENSOR
      volt = analogRead(A1);
      volt3 =(volt * 4.8) /1024;

      myDisplay.setColor(255, 255, 255);
      myDisplay.print("J1_1 :", 0, 74);

      Serial.println(volt3);                 //ANALOG A1
      if (volt3 >= 0 && volt3 <= 5.25) {
      myDisplay.setColor(0, 255, 0);
      myDisplay.printNumF(volt3, 2, 60, 74);
      //myDisplay.print("  ", 130, 20);
      } else {
      myDisplay.setColor(0, 0, 255);
      myDisplay.printNumF(volt3, 2, 60, 74);
      //myDisplay.print(" ", 150, 74);
      failflag = 5;
      }

      myDisplay.setColor(0, 255, 255);
      myDisplay.print("NA", 125, 74);

      //FOR ANALOG A0 PIN
      //A0 pin connected to J2_2 of SENSOR

      for (int i = 0; i < 1000; i++) {
      volt_b =(volt_b + (4.99 / 1024 * analogRead(A0)));
      }
      volt_b = volt_b / 1000;
      volt4 = volt_b / (r2 / (r1 + r2));

    //volt4 = volt_c - 2.7;

      myDisplay.setColor(255, 255, 255);
      myDisplay.print("J2_2 :", 0, 92);

      Serial.println(volt4);                //ANALOG A0
      if (volt4 >= 5 && volt4 <= 8.82) {
      myDisplay.setColor(0, 255, 0);
      myDisplay.printNumF(volt4, 2, 60, 92);
      //myDisplay.print("  ", 130, 20);
      } else {
      myDisplay.setColor(0, 0, 255);
      myDisplay.printNumF(volt4, 2, 60, 92);
      //myDisplay.print(" ", 150, 92);
      failflag = 5;
      }

      myDisplay.setColor(0, 255, 255);
      myDisplay.print("NA", 125, 93);

      digitalWrite(20, LOW);
      digitalWrite(20, LOW);
      delay(2000);

      if (failflag == 5) {
      myDisplay.setColor(0, 0, 255);
      myDisplay.print("LASER FAIL", 35, 108);
      delay(4000);
      state = 0;

      }

      else if (failflag == 1) {
      myDisplay.setColor(0, 0, 255);
      myDisplay.print("SPECKLE FAIL", 35, 108);
      delay(40000);
      state = 0;

      }

 // *** Here the condition not working START
    else if ((failflag == 5) && (failflag == 1)) {
      myDisplay.setColor(0, 0, 255);
      myDisplay.print("LASER/SPECKLE FAIL", 15, 108);
      delay(40000);
      state = 0;
      }
  // *** Here the condition not working END

```

# Answer
```
(failflag == 5) && (failflag == 1))

```

`failflag` can't be both 5 and 1 at the same time.
> 5 votes

# Answer
As you ask for two different assignments for the same var its never gone to work this way. Two quick options:
Do binary addidition

```
 failflag = 0;
 if(errorA) failflag += 1;
 if(errorB) failflag += 2;
 if(errorC) failflag += 4;
 if(errorD) failflag += 8;

//then you can decode combined errors as follows
else if (failflag == 13) {
    Serial.println("Errors: A, C, D"); // 1 + 4 + 8 =13
}

```

The other quick one is defining failflag as bool array

```
bool failflag [5] = {00000}; // 5 elements

 if(errorA) failflag [0]= 1;
 if(errorB) failflag [1]= 1;
 if(errorC) failflag [2]= 1;
 if(errorD) failflag [3]= 1;

//then you can decode combined errors as follows
else if ( failflag [0] == 1 &&  failflag [2]== 1 && failflag [3]== 1) {
    Serial.println("Errors: A, C, D"); // 1 + 4 + 8 =13
}

```

as we have failflag\[i\] as a bool we can condense the code to

```
else if ( failflag [0] && failflag [2] && failflag [3]) {
    Serial.println("Errors: A, C, D"); // 1 + 4 + 8 =13
}

```

Whatever suits your needs. As I said just 2 quick ones
**Edit** Cleaning up you question other things to change:
Get rid of the delay() (except in setup to initialize your hardware and in loop during debuging.
The 21 float vars could be stores in a float array

```
 float myFloatVars [22]

```

and write the values to the position

```
 myFloatVars [11] = myMeasureFunction();

```

you can do this even in a timed for loop doing a recurring FIFO function (kind of circle buffer), the first saved value is dumped if the array is full to put the next one in. So you are able to produce a "gliding" average, which is what you want
> 1 votes

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


# Question
Title: What is the difference betwen “ESP8266Wifi.h” and “WiFiEsp.h” libraries?
I'll start a project using **NodeMCU V3 WiFi Module**, which uses **esp8266** chip. However, I am undecided as to which library to use. I don't want use a *serial bridge* with an arduino, I think it is better to use NodeMcu in *Standalone* *mode*.

So, here's my question: which library should I use? And, regarding the type of use, what is their difference? (**both libraries reference looks like the same for me**)

*p.s.: I also heard about the "WiFi.h" library. Does it work only on WiFi shields for arduino or does it also work on esp8266?*

# Answer
> 3 votes
It's quite simple:

* ESP8266WiFi.h - Runs on the ESP8266 to control the WiFi.
* WiFiEsp.h - Runs on an Arduino to communicate with an ESP8266 module with AT commands
* WiFi.h - Runs on an Arduino to work with the Arduino WiFi shield.

So the one you want, which is part of the ESP8266 core, is ESP8266WiFi.h.

---
Tags: esp8266, nodemcu
---


# Question
Title: NodeMCU Server side cannot send things to client side - multiple clients attached
I technically need your help, when I am working on my project, I found out that my server-side cannot send data to the client-side, my server-side is made with `WiFiServer(80)` so it is when my client-side do `client.print`, it can send to the server-side, and the server-side just easily send to the Python side with Serial, and Python can still send it to the server-side, but the server-side cannot send it to the client-side. The basic code is from this page

1. Server Code

Here's the code:

```
#include <SPI.h>
#include <ESP8266WiFi.h>
#define led LED_BUILTIN
char ssid[] = "AP";
char pass[] = "Science_Fair";
WiFiServer server(80);
WiFiClient client;
IPAddress ip(10, 241, 241, 27);
IPAddress gateway(10, 241, 241, 254);
IPAddress subnet(255, 255, 255, 0);
int i;

void setup()
{
  Serial.begin(9600);
  WiFi.mode(WIFI_STA);
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(100);
  }
  // Serial.println("Connected to WiFi");
  server.begin();
  pinMode(led, OUTPUT);
}

void loop()
{
  client = server.available();
  client.setTimeout(3000);
  Serial.setTimeout(2000);
  if (client)
  {

    // Serial.println("Available");
    if (client.connected())
    {
      Serial.println("Connected");
    }

    while (client.connected())
    {
      // Serial.println(".");

      String request = client.readStringUntil('e');
      if (request == "LR")
      {
        digitalWrite(led, LOW);
        Serial.println("LR");
        for (i = 0; i < 3; i++)
        {
          String reply = Serial.readStringUntil('e');
          if (reply == "WARN_B")
          {
            Serial.println("Confirm");
            client.print("WARN_Be");
            break;
          }
          yield();
        }
      }
      else if (request == "RR")
      {
        Serial.println("RR");
        for (i = 0; i < 3; i++)
        {
          String reply = Serial.readStringUntil('e');
          yield();
          if (reply == "WARN_A")
          {
            Serial.println("Confirm");
            client.print("WARN_Ae");
            break;
          }
          yield();
        }
        yield();
      }
      yield();
    }
  }
  // Serial.println("");
  client.stop();
}

```
2. Client A Code

```
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#define PIR_A D3
#define PIR_B D8
#define led LED_BUILTIN
const char ssid[] = "AP";
const char pass[] = "Science_Fair";
SoftwareSerial DFPlayer_Mini(D1, D2);
WiFiClient client;
IPAddress server(10, 241, 241, 27);
IPAddress ip(10, 241, 241, 28);
IPAddress gateway(10, 241, 241, 254);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
    pinMode(PIR_A, INPUT);
    pinMode(PIR_B, INPUT);
    pinMode(led, OUTPUT);
    DFPlayer_Mini.begin(9600);
    mp3_set_serial(DFPlayer_Mini);
    mp3_set_volume(30);
    WiFi.mode(WIFI_STA);
    WiFi.config(ip, gateway, subnet);
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(100);
    }
    Serial.begin(9600);
}

void loop()
{
    int i;
    float time = 0;
    int PIR_A_VAL = digitalRead(PIR_A);
    int PIR_B_VAL = digitalRead(PIR_B);
    client.connect(server, 80);
    client.setTimeout(1500);
    if (PIR_A_VAL == HIGH)
    {
        while (1)
        {
            time += 1;
            delay(1);
            if (time >= 1000)
            {
                Serial.println("OFD");
                for (i = 0; i < 40; i++)
                {
                    delay(100);
                    yield();
                }
                break;
            }
            else if (PIR_B_VAL == HIGH)
            {
                if (time == 1)
                {
                    client.print("RRe");
                    client.flush();
                    for (i = 0; i < 40; i++)
                    {
                        delay(100);
                        yield();
                    }
                    break;
                }
                break;
            }
            PIR_B_VAL = digitalRead(PIR_B);
            yield();
        }
    }
    else if (PIR_B_VAL == HIGH)
    {
        String fromServer = client.readStringUntil('e');
        yield();
        if (fromServer == "WARN_A")
        {
            mp3_play();
        }
        Serial.println("B Triggered");
        for (i = 0; i < 2; i++)
        {
            delay(1250);
            yield();
        }
    }
    Serial.println("OFL");
    client.stop();
}

```
3. Client B Code

```
#include <SPI.h>
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#define PIR_A D7
#define PIR_B D8
#define led LED_BUILTIN
const char ssid[] = "AP";
const char pass[] = "Science_Fair";
SoftwareSerial DFPlayer_Mini(D1, D2);
WiFiClient client;
IPAddress server(10, 241, 241, 27);
IPAddress ip(10, 241, 241, 29);
IPAddress gateway(10, 241, 241, 254);
IPAddress subnet(255, 255, 255, 0);

void setup()
{
    pinMode(PIR_A, INPUT);
    pinMode(PIR_B, INPUT);
    pinMode(led, OUTPUT);
    DFPlayer_Mini.begin(9600);
    mp3_set_serial(DFPlayer_Mini);
    mp3_set_volume(30);
    WiFi.mode(WIFI_STA);
    WiFi.config(ip, gateway, subnet);
    WiFi.begin(ssid, pass);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(100);
    }
    Serial.begin(9600);
}

void loop()
{
    int i;
    float time = 0;
    int PIR_A_VAL = digitalRead(PIR_A);
    int PIR_B_VAL = digitalRead(PIR_B);
    client.connect(server, 80);
    client.setTimeout(1500);
    if (PIR_A_VAL == HIGH)
    {
        while (1)
        {
            time += 1;
            delay(1);
            if (time >= 1000)
            {
                Serial.println("OFD");
                for (i = 0; i < 40; i++)
                {
                    delay(100);
                    yield();
                }
                break;
            }
            else if (PIR_B_VAL == HIGH)
            {
                if (time == 1)
                {
                    client.print("LRe");
                    client.flush();
                    for (i = 0; i < 40; i++)
                    {
                        delay(100);
                        yield();
                    }
                    break;
                }
                break;
            }
            PIR_B_VAL = digitalRead(PIR_B);
            yield();
        }
    }
    else if (PIR_B_VAL == HIGH)
    {
        String warnStatus = client.readStringUntil('e');
        yield();
        if (warnStatus == "WARN_B")
        {
            mp3_play();
        }
        Serial.println("B Triggered");
        for (i = 0; i < 2; i++)
        {
            delay(1250);
            yield();
        }
    }
    Serial.println("OFL");
    client.stop();
}

```

I've tried: \- Using `client.print` instead of `client.printf` \- Using data with underlines instead of spaces \- Added `client.flush` \- Added `client.stop` \- Changed NodeMCU \- Checked wires \- Checked power supply \- Checked the data to send \- Made the timeout longer \- Checked speaker But none of them is working

Please help me guys I'm in a rush, thank you!

# Answer
> 0 votes
I read through the instructable and found - hidden in the comments the following

> Author of the instructable:
> Would you like to send message to the four clients in the same time?
>
> If it is right I can not support you. I am not a expert in this topic. My server sends message to the current client only which is triggering the server. Using my sketch you can send same message to the clients, but in different time. (Remark codebreaker007: which would not work anyway!)

So this solution you have in your code is supposed to work with only one client. So you have to implement yourself a kind of com-sequence wether sever triggered or client side. Here a short how to add this functionality:

```
#define MAX_SRV_CLIENTS 4 // max clients connecting

WiFiClient serverClients[MAX_SRV_CLIENTS];

```

in the loop do the following:

```
  uint8_t i;
 for (i = 0; i < MAX_SRV_CLIENTS; i++) {
  //check if there are any new clients
  if (server.hasClient()) {
 //find free/disconnected client spot
  if (!serverClients[i] || !serverClients[i].connected()) {
    if (serverClients[i]) serverClients[i].stop();
    serverClients[i] = server.available();
    Serial.print("New client: "); Serial.print(i);
    break;
  }
 }

```

So you can differentiate between the clients and send with for loop to all or

```
 serverClients[2].print("WARN Client 2");

```

Hope this resolves the issue (And read also comments of instructables about problems - the author is actually a newbie)

---
Tags: esp8266, wifi, nodemcu, communication, wireless
---


# Question
Title: Serial read SSID and PASSWORD WiFI connection failed in ESP32
Trying to get Wifi SSID and password dynamically from serial monitor and connecting to WiFi, tried the below program, but wifi is always in Connecting state only, it is not getting connected after receiving input from serial monitor.

```
#include <WiFi.h>

#define BAUDRATE 115200

char ssid[50];
char pass[50];

void setup() {
  Serial.begin(BAUDRATE);
  Serial.println();
  Serial.print("Enter your WiFi credentials.\n");
  Serial.print("SSID: ");
  while (Serial.available() == 0) {
    // wait
  }
  Serial.readBytesUntil(10, ssid, 50);
  Serial.print(ssid);
Serial.print("donessid");

  Serial.print("PASS: ");
  while (Serial.available() == 0) {
    // wait
  }
  Serial.readBytesUntil(10, pass, 50);
  Serial.print(pass);
 Serial.print("donepass");

  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("Connecting....");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
void loop()
{}

```

# Answer
> 1 votes
Is your Serial Monitor setting set to "Both NL and CR"? Change it to "Newline" should works.

What happened is if your Serial Monitor has a setting of "Both NL and CR", when your press Enter, it generates a `\r\n`, the `Serial.readBytesUntil(10, ssid, 50)` picked up that `\r` at the end of the array, when you use it as SSID, it is not a valid SSID.

---
Tags: wifi, esp32
---


# Question
Title: How to connect RedBearLab BLE shield (Or how to find Nordic_nRF8001.h)?
I am trying to explore the possibilities of connecting an Arduino to Phonegap/Cordova. I have a RedBearLab BLE Shield, which I want to test the connection with. My MVP would be to get the value of a PIN to a Cordova app. Nevertheless, I couldn't make it even close.

The closest I got, it was using Don Coleman's Phonegap plugin. I am trying his Simple Chat example.

With this example the sketch is attempting to include `Nordic_nRF8001.h`. Nevertheless, I can't seem to find this library. I downloaded it from various sources, but no matter what I do, my sketch still can't find the file.

The only way I could make it work was via CodeBender, but then the readings were a bit of a mess.

I'm not expecting anyone to do all the work for me, so if you can help me in one of the two directions, it would be awesome:

1. Figure out why I can't find that Nordic\_nRF8001.h file.
2. Or help me find another method of BLE communication.

**Later edit** Using the examples that come with RBL library, I figured out the name of the files I need to use. Now I'm running into another problem for which I opened a new question.

Thank you!

# Answer
I used Arduino Create Web Editor to load the SimpleChat example. It loads with these libraries, and it works perfectly:

```
#include <SPI.h>
#include <EEPROM.h>
#include <boards.h>
#include <RBL_nRF8001.h>

```

Thanks, Andi
> 0 votes

---
Tags: bluetooth, ble
---


# Question
Title: SimpleChat BLE Example prints scrambled characters
I am trying to use the SimpleChat application to test my RedBearLab Shield. If I send "Hello" and to to Serial.print or Serial.write the return what I see in my Serial monitor is stuff like "Fh\`Fx\**-H3r:AJb6# E0CbJ"

Any idea what I'm doing wrong?

Thank you, Andi Stancu

# Answer
If you are transmitting `Hello` and receiving `Fh'Fx**-H3r:AJb6# E0CbJ`, then the problem is most likely a `baud rate mismatch`.

The receiver is sampling the data signal 3 or 4 times faster than it should.

Start by lowering the baud rate of the serial monitor to 1/4 of the current baud rate.

If that does not produce correct data reception, then start at the lowest baud rate and work your way up.
> 0 votes

---
Tags: arduino-uno, bluetooth
---


# Question
Title: Serial monitor reading input strings, but cannot stop a while statement
I have just learned something called 'communication protocols' in Arduino, while I was testing this code, it appears to me that every time I input a string "YELLOW\_ON" while statement works perfectly fine, however after that the serial monitor input cannot receive strings anymore. after inputting the string "YELLOW\_ON", I cannot input another string which is "YELLOW\_OFF" may I know why that is the case?

```
#include"Display.h"
const int YELLOW_LED = 7;

void setup()
{
  pinMode(YELLOW_LED, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available())
  {
    INPUT_SERIAL();
  }
}

void INPUT_SERIAL()
{
  String INPUT_INFO = Serial.readStringUntil('\n');
  Serial.println(INPUT_INFO);

  while (INPUT_INFO == "YELLOW_ON")
  {
    Display.show("ON");
    digitalWrite(YELLOW_LED, HIGH);
    delay(250);
    digitalWrite(YELLOW_LED, LOW);
    delay(250);
  }
  if (INPUT_INFO == "YELLOW_OFF")
  {
    Display.show("OFF");
    digitalWrite(YELLOW_LED, LOW);
  }
}

```

# Answer
From your comments:

> I want the while loop to be there and I somehow want to stop it, is that possible?

=\> yes - press the reset button.
When I started programming some decades ago one of the basics was NEVER use while loops.
Why? Because you might run into deadlocks like your code does. Options:

* Check inside the while for a state change/input to break the while loop (worst choice)
* Get rid of blocking code (while/delay() ) and work with if clauses (medium)
* Get rid of blocking code (while/delay() ) and implement a state machine with switch case (better)

How to get rid of delays - IDE-file-examples-2 Digital - blinkwithoutdelay
> 0 votes

---
Tags: arduino-uno, arduino-ide
---


# Question
Title: Connecting two sensors to one analog pin
I am completely new to programming with Arduino so please bear with me if this seems stupid.

I am using an Arduino Uno R3. I have two sensors, a Soil Moisture sensor and an LDR Light Sensor. Both of them have one pin marked as A0 on them. So now, do I connect them both to A0 using a breadboard (Like how I am connecting multiple sensors' VCC to the 5V pin currently) OR do I use a different analog pin say A0 for one and A1 for the other? Will it make a difference?

# Answer
AO is not "Ay Zero", it's "Ay Oh", and stands for "Analog Output". It means it just sends a varying voltage. It really doesn't care where it's sent to, it just sends it.

It's up to you where you connect that *output* to. But suffice it to say it wants to be connected to an *input* that can read an *analog signal*. And the Arduino has 6 of them.

Which one you connect it to is entirely up to you - you just have to *read* from that analog input by using the right pin number in `analogRead()`.
> 0 votes

# Answer
(https://i.stack.imgur.com/Rm3On.jpg) you can simply connect one in the A0 and the other in the A1 since all those pins can be used for the same function
> 0 votes

---
Tags: arduino-uno, sensors, analog
---


# Question
Title: What are the units of output of soil moisture sensor?
I want to use a soil moisture sensor using arduino uno R3. I am using the analog output. The values are in the range of 100 to 1300 as in the readings mention in this question.

May I know what exactly these numbers mean? I read in a website that:

> Most soil moisture sensors are designed to estimate soil volumetric water content based on the dielectric constant (soil bulk permittivity) of the soil.

So what are the units? Basically I want to base an estimate for the normal amount of soil moisture for typical loamy soil and I don't understand how to base this threshold based on the readings given by the sensor. It would be greater help if someone actually knows what an appropriate soil moisture threshold is for loamy soil.

I searched on the internet but the closest i could come to answers was this table and this particular entry:

> Table 1.1. Typical field capacity and wilting point values (m^3 m^(–3)) for different soil textures
>
> Soil texture| Field capacity| Wilting point| Available water
>
> Loam |0.27| 0.12| 0.15|

I am so sorry if I seem confused but I am very new to the whole of sensors and electronics This is the sensor that I am making use of

# Answer
> 1 votes
Those sensors have no units. If you can find a schematic you could possibly relate the value to the resistance of the soil, but you'd need to know the resistance that the soil is paired with to form the resistive divider.

All you can say from the numbers is "This is wet" or "This is dry". Normally you would use trial and error to determine what the values roughly relate to, and say that "Anything under X should trigger watering. Anything over Y should stop watering."

---
Tags: arduino-uno, sensors
---


title: Why doesn't this timer code work?

text:
# Question
Title: Why doesn't this timer code work?
Why doesn't the code below work? Timer will count 370ms then function called to ON LED. Again 370ms then function called to OFF LED. Basically a toggle function.

```
int IN0 = 12;
int IN1 = 11;
int OUT1 = 10;
int OUT2 = 9;
int OUT3 = 7;
int OUT4 = 6;
int LED = 13;
unsigned int count = 370;
unsigned int tcount = 0;
bool tflag = 0, mflag = 0, sflag = 0, lflag = 0, rflag = 0;
int a, b;

void setup() {
  pinMode(IN0, INPUT);
  pinMode(IN1, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(OUT1, OUTPUT);
  pinMode(OUT2, OUTPUT);
  pinMode(OUT3, OUTPUT);
  pinMode(OUT4, OUTPUT);
  Timer1.initialize(a); // 370 miliseconds on time
  //Timer1.attachInterrupt(flash);
}

void flash_on() {
  //digitalWrite(LED, !digitalRead(LED));
  digitalWrite(LED, HIGH);
}

void flash_off() {
  //digitalWrite(LED, !digitalRead(LED));
  digitalWrite(LED, LOW);
}

void loop() {
  Timer1.attachInterrupt(flash_on);
  a = count;
  Timer1.attachInterrupt(flash_off);
  a = count;
}

```

# Answer
> 1 votes
You should give `a` a value before calling `Timer1.initialize(a)`.

For example, like this:

```
void setup() {
  ....
  a = count;
  Timer1.initialize(a); // 370 miliseconds on time
  ....
}

```

Your `loop()` code will also not work like you expect it to. As it is, you will be switching between two different ISRs very fast, without having any control over which of the two will be called once the Timer1 interrupt occurs.

It will be better to stick to one ISR that toggles the LED. That’s kind of the point of a Timer interrupt.

---
Tags: timers
---


# Question
Title: How to round up millis() when divided into minutes?
```
unsigned long milliseconds=millis();
// if at time of reading the above milliseconds = 599999 ie 1 millisecond short of 600000 ie 10 minutes
unsigned long minutes = (milliseconds/1000)/60;
// this will return 9 instead of 10.

```

How do you round the result to 10 minutes? I don't mean adding 1 to final result. It has to be within the calculation.

# Answer
To round to the nearest X in fixed point arithmetic: add 1/2 X (in the base units, msec, in this case) and divide by X (again, in the base units) so: `milliseconds = (milliseconds + (30*1000L))/(60*1000L);`

The addition of 1/2 X causes a carry of one whole X if the fractional X in the original quantity was 1/2 X or greater. (Likewise, if the fractional X was less than 1/2 X, no carry will result).

Integer division naturally truncates any fractional amounts, so you'll be left with the rounded integer result.
> 2 votes

# Answer
Here is a simple trick how to switch from integer math to floating point math and use round function.

```
  unsigned long milliseconds = 599999;

  unsigned long minutes_long = (milliseconds/1000)/60;
  // minutes_long = 9

  double minutes_double = (milliseconds/1000.0)/60.0;
  // minutes_double = 9.99998...

  double minutes_rounded = round(minutes_double);
  // minutes_rounded = 10

```

There also exists a trick that allows calculation of `round` using integer math. It's perfect if you don't have enough memory for a cast.

```
  unsigned long milliseconds;

  milliseconds = 600000 - 30*1000 - 1;
  //milliseconds = 569999

  unsigned long minutes_9 = (milliseconds+30000)/60000;
  // minutes_9 = 9

  milliseconds = 600000 - 30*1000;
  //milliseconds = 570000

  unsigned long minutes_10 = (milliseconds+30000)/60000;
  // minutes_10 = 10

```
> -1 votes

---
Tags: arduino-uno
---


# Question
Title: how do i know what battery(how much ampere and voltage) my circuit needs to work perfectly?
i really love to make a lot of things but i always have this problem that i don't know how can i determine what battery(with how much voltage and amp)my circuit must have to work perfectly! please help me:( for example i have two circuits.circuit 1 includes:arduino uno ,2 servo motors and a DFplayer module and an led but i don't know is a 7.4 voltage Lipo battery with 1500mAh suitable for it or not??? and circuit 2 includes:arduino uno,L298 driver & 2 dc motors & 2 ultrasonics sensor but i don't know what battery does it need? i really love to learn it (determine the battery my self)

# Answer
TL;DR: You really need to know what components you have and you need to find datasheets. In the datasheet, you find what voltage the component requires.

Don't care too much about amperes in the beginning. If you get the voltage right, each component will just draw as much current as it needs.

An Arduino Uno operates from 7 to 12 Volts, so 7.4 V is ok.

"Servo motor" is simply not enough information. There are servo motors for 4.8 V, some for 6 V and others for 12 V. There are even AC servo motors for 240 V~.

DFPlayer is for 3.2 V to 5 V, so it shouldn't be powered directly off the 7.4 V battery. Maybe it can be powered from a 5 V pin of the Arduino. Since they power it from the 5 V pin, it seems to be possible.

Also "LED" is not a term that is good enough. Is it Infrared, Red, Yellow, Green, Violet, UV or white? Depending on the color, it needs something between 1.6 and 3.0 V. Therefore, you need a resistor. What's the use of the LED? Do you need to turn it on and off by Arduino, or can it just be always on from the Lipo battery?

The L298N has a supply voltage from 2.5 V to 46 V, so 7.4 V is fine.

Next, "DC motor" is not specific enough. I have seen 3 V, 5 V, 6 V, 12 V, 24 V.

Also, for ultrasonic, there are SR04 and SRF05. These two operate at 5 V. But if you have a different one, that may not be the case.
> 1 votes

---
Tags: arduino-uno, power, battery, voltage, electricity
---


# Question
Title: What is the name of a peripheral which reads servo output data physically?
I know the title is phrased terribly, but I'm not sure how to phrase it since I'm not sure of the name.

I have a servo, that I cannot connect to, except for the output spine/shaft (physically). I need to get the output of that servo into an arduino, or raspberry pi. So I need some kind of peripheral that can attach to the shaft of the servo, and tell me what position it's in. I can't figure out how to find what part I need, because I can't google for the name of it correctly. I've tried servo input shaft, and many other things that don't make sense.

**More Info.**

I have a servo on a machine, and I can not interface with this servo in any way but physically. I can't read the output from it electronically, and the signals are proprietary. I can't take anything apart, all I can do is put something physically on it.

So, the issue is, I need to (based on nothing but the position of the servo shaft) figure out what position that 3rd party servo is at.

With that information, I'm then going to man in the middle, and attach another servo to my device, and change the value to what I want.

So if the factory servo is at 50%, and I know that by using something like a rotary encoder, if that ends up being the answer, I then could add x% to my actual servo.

# Answer
> 1 votes
What you need is an `absolute rotary encoder`.

It will provide feedback about the absolute rotational position of the servo shaft.

An encoder that uses `gray code` is preferred because only one binary bit changes between adjacent positions.

---
Tags: servo, raspberrypi, input
---


# Question
Title: Can we use ESP32 to program ESP32-CAM through ESP-IDF
Can we just use an ESP32 NodeMCU for example to program an ESP32-CAM? I saw a lot of people programming ESP32-CAM using an arduino Uno, can we do the same for ESP32 NodeMCU? Of course, in the "Arduino as ISP" programming mode. If we can, is there anything more that I need? if not, why? and are there any other solutions to program it?

Moreover, I want to use ESP-IDF which is better than using the Arduino GUI app.

# Answer
I have discovered how to use the ESP32 NodeMCU as a serial interface. In other words, make the ESP32 traverse ALL of the serial communication to the TX & RX pins directly without any interference. When you press the "RST" (Reset) button, it turns off, but when you release your finger, it will turn on. However, when it is turned off, it traverses all the serial communication to the TX & RX pins, which can then be used to program and contact with the ESP32-CAM. Of course, you can't keep pressing the "RST" button all the time, instead connect the "En" (Enable) pin to GND which will then disable the 3.3 voltage regulator (Same as if you were pressing the "RST" button), in other words, turns the ESP32 off. And then, connect any two GND pins together from both of the ESP32's. At last, upload your program to the ESP32-CAM.
> 1 votes

# Answer
All you need to program any ESP32 (Cam or not) is a serial interface. How you make that serial interface is up to you.

Most ESP32 development boards have a USB to UART converter on them which you can use just like on an Arduino - keep the ESP32 you're using for the programming in RESET so it doesn't try and respond on the UART.

You could also program the "programmer" ESP32 as a UART passthrough to connect the USB UART through to the other UART so you don't need to mess with holding in RESET.
> 0 votes

---
Tags: arduino-ide, esp32, ftdi
---


# Question
Title: Is there a better way to combine if statement with an ISR?
In my sketch when an interrupt gets triggered, a state variable is toggled from high to low and vice versa. Depending upon the variable state I have an if statement in the main loop that will call alarm\_On function if state is high and the else part of the conditional statement will call alarm\_Off function if the interrupt is triggered a second time. Thus I want this if condition to run only when the interrupt is triggered. In all other circumstances I want to run other code but if it concerns the same components e.g. the leds, the other code doesn't execute. If it's not a common component then it works fine. How can I overcome this "common component" issue?

```
 // Analog Input devices
# define humiditySensor A5

// Alarm input
# define alarmButton 2 // Pushbutton

// Output Devices
# define redLed 10
# define yellowLed 11
# define greenLed 12
# define waterPump 9 // LED on relay
# define spk 5

// Variables
volatile byte alarm = LOW;

void setup() {
  pinMode (alarmButton, INPUT);
  pinMode (redLed, OUTPUT);
  pinMode (yellowLed, OUTPUT);
  pinMode (greenLed, OUTPUT);
  pinMode (waterPump, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(alarmButton), ISR_Alarm, RISING);
  Serial.begin(9600);
}

void loop() {
  if (alarm == 1) {
    alarm_On();
  } else if (alarm == 0) {
    alarm_Off();
  }
  int humVal = analogRead(humiditySensor);
  Serial.println(humVal);
  if (humVal >= 500) {
    digitalWrite(redLed, HIGH);
  } else {
    digitalWrite(redLed, LOW);
  }
} // void loop

void ISR_Alarm () {
  alarm = !alarm;  // toggle alarm function if pushed more than once
}

void alarm_On() {
  tone (spk, 100);
  digitalWrite(waterPump, HIGH);
  static byte ledState = LOW;
  static unsigned long oldTime = 0;
  if (millis() - oldTime >= 250) { // loop to blink leds in emergency
    oldTime = millis();
    if (ledState == LOW) {
      digitalWrite(redLed, HIGH);
      digitalWrite(yellowLed, HIGH);
      digitalWrite(greenLed, HIGH);
      ledState = HIGH;
    } else {
      digitalWrite(redLed, LOW);
      digitalWrite(yellowLed, LOW);
      digitalWrite(greenLed, LOW);
      ledState = LOW;
    }
  }
} // end of alarm on function

void alarm_Off () {
  noTone (spk);
  digitalWrite(redLed, LOW);
  digitalWrite(yellowLed, LOW);
  digitalWrite(greenLed, LOW);
  digitalWrite(waterPump, LOW);
} // end of alarm off function

void high_Humidity() {
  digitalWrite(waterPump, HIGH);
}

void low_Humidity() {
  digitalWrite(waterPump, LOW);
}

```

# Answer
> 0 votes
Your code is not blocked, but ON or OFF are called each loop so your change are to the "common" components are overwritten quite fast.

Do not track the state within the IRQ. You could do something like:

```
volatile byte alarm = 1;
byte alarm_state = 1;

void ISR_Alarm () {
    alarm = 1;
}

void loop() {
    if (alarm){
        alarm = 0;

        if (alarm_state) {
            alarm_state = 0;
            alarm_Off();
        } else {
            alarm_state = 1;
            alarm_On();
        }
    }

    // other code
}

```

---
Tags: arduino-uno, isr
---


# Question
Title: How to respond dynamically by using File Containing Templates?
We are developing a Web Console and REST API for the NodeMCU V3 ESP8266, using `ESPAsyncWebServer`. We are facing some difficulties to serve dynamic pages using File Containing Templates! We're unable to replace `REQ_HOST_ID` with `request->host()` using Template Processor! The following code is working fine when a static host name is supplied.

```
// server->on("/", HTTP_GET, HomePage::index);

void HomePage::index(AsyncWebServerRequest *request) {
    Serial.println(request->host());
    auto processor = [](const String &var) -> String {
        if (var == "REQ_HOST_ID"){
        //  return F(request->host()); //FIXME
            return F("10.10.10.1");
        }
        return String();
    };
    AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/www/index.html", String(), false, processor);
    response->addHeader("Server", "Academia Web Server");
    request->send(response);
}

```

**Edited:**

Commented code causes a compile-time error and needs to be fixed to set the value of `request->host()`. `request->host().c_str()` causes the same error!

```
/Users/Chorke/Documents/Arduino/libraries/AcademiaCoreWeb/src/pages/HomePage.cpp: In lambda function:
/Users/Chorke/Documents/Arduino/libraries/AcademiaCoreWeb/src/pages/HomePage.cpp:16:22: error: 'request' is not captured
             return F(request->host()); //FIXME
                      ^
/Users/Chorke/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/WString.h:38:76: note: in definition of macro 'FPSTR'
 #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
                                                                            ^
/Users/Chorke/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/WString.h:39:34: note: in expansion of macro 'PSTR'
 #define F(string_literal) (FPSTR(PSTR(string_literal)))
                                  ^
/Users/Chorke/Documents/Arduino/libraries/AcademiaCoreWeb/src/pages/HomePage.cpp:16:20: note: in expansion of macro 'F'
             return F(request->host()); //FIXME

```

Your help resolving this issue is highly appreciated.

# Answer
> 0 votes
Fixed:

```
auto processor = [request](const String &var) -> String {
    if (var == "REQ_HOST_ID"){
        return request->host().c_str();
    }
    return String();
};

```

Two mistake causes compile time error:

1. Needs to pass `request` to the `Lambda` expression
2. Need not to wrap the dynamic value with `F()` macro

---
Tags: arduino-uno, esp8266, nodemcu, cpp, spiffs
---


title: Ultrasonic Sensor as Unlock Sensor

text:
# Question
Title: Ultrasonic Sensor as Unlock Sensor
Is it possible to use ultrasonic sensors maybe HC SR04 type as unlock sensors? I'm figuring out if it can replace matrix keypad?

For example 6 HC SR04 are used to be an input sensor waiting for a pattern to unlock a certain thing? Usually, in matrix keypad we will push \[ 6,0,1,7\] as the password is it possible to replace that with ultrasonic sensors as the receiver of input, and if it i possible, what type of code to be used?

# Answer
> 0 votes
Short answer: yes.

General answer: you can use any input device for use as unlock mechanism. You can use a keypad, several single buttons, you can even use a single ultrasonic sensor (and depending on the distance differences from that sensor create a pattern), you can use a microphone, a temperature sensor (that will be tricky to unlock something though).

I would start with a typical example of an ultrasonic sensor sketch and program a pattern recognition algorithm in it. How that sketch would look like exactly, depends on your requirements (how you want to store the pattern, should it be hardcoded or changeable).

First try one sensor, than try multiple (I never tried, but I guess it's possible). If not by a default library, you have to write your own (that will be tricky possibly). Than think about the pattern recognition (values of the ultrasonic sensor in the correct order), than about changing/storing the 'code'.

---
Tags: sensors, c++, input, keypad
---


title: How to add a yield before else if?

text:
# Question
Title: How to add a yield before else if?
So I am running my project on a NodeMCU, but I don't know how to let it add a yield in front of an else if. It will give me an error like this:

> Arduino:1.8.12 (Windows 10), 開發板:"NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Sketch + WiFi Settings, 115200"
>
> G:\資優班\科展\程式碼\Front\_End\Main\_Code\_V5\Main\_Server\Main\_Server.ino: In function 'void loop()':
>
> Main\_Server:84:5: error: 'else' without a previous 'if'
>
> exit status 1 'else' without a previous 'if'
>
> This report would have more information with "Show verbose output during compilation" option enabled in File -\> Preferences.

Here's the code:

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

#define MAX_SRV_CLIENTS 2
#define led LED_BUILTIN

WiFiServer server(80);
WiFiClient serverClients[MAX_SRV_CLIENTS];
IPAddress ip(10, 241, 241, 27);
IPAddress mask(255, 255, 255, 0);
IPAddress gateway(10, 241, 241, 254);
char ssid[] = "AP";
char pass[] = "Science_Fair";

void setup() {
  Serial.begin(9600);
  WiFi.config(ip, gateway, mask);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED) {
    yield();
  }
  server.begin();
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
}

void loop() {
  uint8_t i;
  Serial.setTimeout(10);
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
    Serial.println("Pre 1");
    if (server.hasClient()) {
      Serial.println("Pre 2");
      if (!serverClients[i] || !serverClients[i].connected()) {
        Serial.println("Pre 3");
        if (serverClients[i]) {
          Serial.println("Pre 4");
          serverClients[i].stop();
          Serial.println("Pre 5");
        }
        Serial.println("Pre 6");
        serverClients[i] = server.available();
        Serial.println("Pre 7");
        serverClients[i].setTimeout(10);
        Serial.println("Pre 8");
        Serial.print("New client: ");
        Serial.println("Pre 9");
        Serial.println(i);
        Serial.println("Pre 10");
        break;
      }
    }
    yield();
  }
  for (i = 0; i < MAX_SRV_CLIENTS; i++) {
    String fromClient = serverClients[i].readStringUntil('e');
    Serial.println("P1");
    yield();
    if (fromClient == "LR") {
      Serial.println("LR");
      String reply = Serial.readStringUntil('e');
      Serial.println("P2");
      yield();
      if (reply == "Warn_B") {
        yield();
        Serial.println("Confirm");
        Serial.println("P3");
        for (i = 0; i < MAX_SRV_CLIENTS; i++) {
          serverClients[i].print("Warn_B");
          Serial.println("P4");
          yield();
        }
      }
    }
    yield(); // this is the yield I need to add
    else if (fromClient == "RR") {
      Serial.println("RR");
      Serial.println("P5");
      String reply = Serial.readStringUntil('e');
      Serial.println("P6");
      yield();
      if (reply == "Warn_A") {
        Serial.println("P7");
        Serial.println("Confirm");
      }
      for (i = 0; i < MAX_SRV_CLIENTS; i++) {
        serverClients[i].print("Warn_A");
        Serial.println("P8");
        yield();
      }
    }
    yield();
  }
}

```

I need the `yield()` there but I don't know how to let it still do the else if. Please help me guys, thanks!

# Answer
First of all do yourself a favour and listen to your IDE

```
This report would have more information with
 "Show verbose output during compilation"
option enabled in File -> Preferences.

```

and in an if else there is no in between so either let it run as a state machine especially inyour case A != B != C != other:

```
void subfunction(){
  if(A){
  // code to run
  return;
  }
 yield();
 if(B){
  // code to run
  return;
  }
 yield();
 if(C){
  // code to run
  return;
  }
 else{}  // to catch if not A or B or C
 yield();
}

```

or implement switch case (Pseudo code)

```
 switch(fromClient){
    case "LR":
      //code to run
      yield();
      break;
    case "RR":
      //code to run
      yield();
      break;
    default:
      //code to run
      yield();
      break;
  }

```

Id else chains are prone to errors as in your case its A != B != C != other
> 1 votes

---
Tags: programming, nodemcu, uploading
---