# Question
Title: My two ultrasonic sensors are reading inaccurately
I am having trouble getting two of my ultra sonic sensors to read accurate results in cm. I am using a HC-SR04 currently.

I get random numbers at different distances with an object in front (smooth cover book)

Test 1: Real distance: 10 cm Sensor 1: 0.00cm Sensor 2: 82.42

Test 2: Real distance: 10cm Sensor 1: 92.11cm Sensor 2: 95.03

Against the wall with no book:

Test 1: Real distance: 10 cm Sensor 1:0.00cm Sensor 2: 13.20

Test 2: Real distance: 10 cm Sensor 1:24.37cm Sensor 2:26.75

The numbers constantly fluctuate. I am trying to get accurate results.

I am not sure if the sensors are broken or if my code is incorrect.I appreciate any help.

Here is my set up: \[

```
#define trigPin1 13
#define echoPin1 12
#define trigPin2 11
#define echoPin2 10

float duration, distance, duration1, distance1, duration2, distance2;

void setup() {
  Serial.begin (9600);
  pinMode (trigPin1, OUTPUT);
  pinMode (echoPin1, INPUT);
  pinMode (trigPin2, OUTPUT);
  pinMode (echoPin2, INPUT);

}

void loop() {

  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");
  delay(100);

}

void FindRange(int trigPin, int echoPin) {

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) * 0.0345;
  delay(100);

}

```

# Answer
> 2 votes
I am not sure but may be it helps just by checking principle of working of this sensors as it is depicted for low range distance you must be carefull about reflection from other source of ultrasonic. I think it would be a good Idea to place a delay between these two module so to make sure it get less noise from each other

```
  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;
  delay(1000);//add delay
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  delay(1000);//add delay

```

the other reason for getting zero may be your controller could not measure reflection from wall due to lowspeed sampling (if you are polling) or reading time with low precision so I have a suggestion for you if you are familiar with STM32 there is a built-in hardware implementation for measure time of pulse using timers called one-pulse mode it may helps you get precision you need

# Answer
> 1 votes
In the loop you trigger trgPin1 then trigPin2 but in the first range find you read echoPin2 instead of echoPin1.

```
void loop() {

  FindRange(trigPin1, echoPin2);
  duration1 = duration;
  distance1 = distance;
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");
  delay(100);

}

```

must be

```
void loop()
{
  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;

  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;

  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");

  delay(100);
}

```

# Answer
> 1 votes
Where they are plugged in they won't work as the rows (like the other side) are connected. Example: http://wiring.org.co/learning/tutorials/breadboard/imgs/breadboard-02.jpg

They aren't connected to the other pins, and they are connected themselves.

# Answer
> 1 votes
change the MCU, that arduino is a chinese version. Use a original or other original board.

I had the same problem with two diferents projects, and it happend the same to me. One with ultrasonic and other with RF24 module. In both projects, some really extrange things happens. But when i change for one original arduino, everything works perfect.

# Answer
> 0 votes
The working principle of HC-SR04 is based the reflection of ultrasonic wave. Therefore, It measures distance inaccurately in the following case:

* The obstacle is something that can **adsorbs the ultrasonic wave**. For example, cotton wool.
* The obstacle is faced in non-90-degree. In this case, the obstacle may **reflect the ultrasonic wave to another direction**
* The obstacle's surface can **diffuse the ultrasonic wave**

You can see the working principle of HC-SR04 here.

One more thing: two ultrasonic sensor may interfere to each other if they work at the same time. Try to give delay(100); between two reads

```
void loop()
{
  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;

  delay(100);

  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;

  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");

  delay(100);
}

```

# Answer
> 0 votes
I tested your code as it currently is with my own HC-SR04s and a clone Arduino Nano (since that is, what I have here currently). It works like a charm. The values are rather good, maybe accurate about +-1cm. I checked in the change between 10 and 70cm with my desk plate and a wall as obstacle. (I just looked, if the values are plausible. I didn't investigate thoroughly, how accurate the values are).

So I guess, that your sensors are broken.

---
Tags: arduino-uno
---


title: Why won't my motor run?

text:
# Question
Title: Why won't my motor run?
I am trying to run a small 3v motor with a Keyestudio MEGA 2560(which is the same as the Arduino MEGA 2560). I am getting a consistent 5 volts everywhere I check with a multimeter. The voltage drops to 0.01-0.05 once I connect the motor. The motor runs once it is connected directly to the Arduino's 5v output pin. The motor draws about 600mA consistently when we connect it directly to 5v.

My code is rather basic, which just sends voltage out pin 5. I am not using any shield. controlling the speed is not my main concern here, though later on in my project I would like the motor to be able to reverse as well.

I found this circuit diagram in "Arduino for dummies," and found this same diagram on many other websites too.

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

void loop() {
  digitalWrite(5,HIGH);
}

```

simulate this circuit – Schematic created using CircuitLab

# Answer
> 1 votes
An NPN bipolar transistor requires a current to flow from base to the emitter which is then multiplied by the beta of the transistor controlling the maximum current which flows from the collector to the emitter. A 2n2222 beta is about 100. Let us calculate the amount of current which will be allowed to flow from the collector to the emitter of the 2n2222 transistor. First calculate the current from the base to the emitter:

```
I(be) = (5.0 volts- 0.7 volts) / 1,000 ohms
I(be) = .0043 Amps

```

Use this current to find the maximum current flowing from the emitter to the collector:

```
I(ce) = 100 x I(be) = 0.430 Amp or 430mA

```

We see that the transistor does not provide enough current to drive a 600mA motor.

We need to reduce the value of R1 such that I(ce) is at least 600mA which means that I(be) needs to be at least 6mA. Rearranging the earlier equation to find R1:

```
I(be) = (5.0 volts- 0.7 volts) / 1,000 ohms
I(be) = (5.0 volts- 0.7 volts) / R1
R1 = (5.0 volts- 0.7 volts) / I(be)
R1 = (5.0 volts- 0.7 volts) / 0.006 Amps
R1 = 716.67 ohms

```

However, because of the large amount of I(ce) current necessary to drive the load, we find the transistor reaching it's limits and the beta of the transistors drop apprecably:

This diagram is a little hard to understand. And there is no curve for 600mA. But we can get an idea of what to expect if we look at the 500mA curve. We see that in order to get less than a volt drop across the transistor (V(ce)) we need to pump in more than 10mA (I(be)). To get similar results for 600mA we would likely approach 20mA and now we are dangerously close to the processor pin current driving capabilities.

A common alternative is to use a Darlington Transistor configuration:

The resulting beta is essentially the product of the individual transistor's betas.

Let's do some rough calculations. If the 2n2222 that switches the load current has a lower beta of about 10, we would need about 60mA to switch a 600mA current. To generate 60mA through the transistor connected to the processor, we would need about 0.6mA from the processor. That's really small and we can afford to triple it to ensure reliable operation. So let's pick 3mA:

```
R1 = (5.0 volts- (2 * 0.7 volts)) / 0.003
R1 = 1200 ohm

```

So a 1K ohm resistor should likely work.

---
Tags: arduino-mega, motor, transistor
---


# Question
Title: Movement and storage of servo positions via bluetooth
I am trying to program a 4DOF robotic arm (using 4 servo motors). I would like to move the servos using an Android app, by means of bluetooth (HC-05).

I developed the app, in whose interface there are 7 buttons (Up, Down, Left, Rght, Forward, Backward, Save) and a field in which you can type using the keyboard (I attached an app interface screenshot).

So far, I tried to manage only Up button (which senses 'U' via bluetooth to Arduino) and Down (which sens 'D'), which would move the servo intended for vertical arm movements. That code works quite well, although the app crashes sometimes, but I still can't figure the reason out. Using the println() function I can see that Arduino reads in the bluetooth input the character '⸮ ' , what does it mean? I use a baud rate of 9600.

Then, what I would like to do is: once I have moved the servo and reached a particular position, I'd like to save the position of the motor into an array. In order to allow multiple positions saving, after Save button is pressed, I want Arduino to wait for another input from the bluetooth (so that, it would wait for another button to be clicked from the app or for something typed into the dedicated bar from keyboard) that defines the position within the array, in which I save the servo position (eg: I type '2' into the dedicated app bar and Arduino, which is waiting for an input, receiving it, saves the last servo position into the array servo01pos\[2\]). I wrote the "case ('S')" code that is quite long and inefficient but, at least, it works.

Thanks in advance to anyone who will help me.

Giammarco

```

#include <SoftwareSerial.h>
SoftwareSerial bluetooth(10, 11); //BlueTooth RX ,TX
#include <Servo.h> // servo library

unsigned long timestampSend = 0; // BT Write wait period
String readString;
Servo servo01; // servo name
byte pos01 = 90;
#define ANGLE_STEP 10 // 10 degree steps
int servo01pos\[50\];
char data;
char button;
int x = 1;

void setup() {
  Serial.begin(9600);
  bluetooth.begin(9600);
  delay(1000);
  Serial.println("Ready ...");
  Serial.println ("\n");
  servo01.attach(12);
  servo01.write(pos01);
}

void loop() {
  do {
    if (bluetooth.available() > 0) {
      Serial.println(data);
      do {
        delay(500);
        data = bluetooth.read();
        Serial.println(data);
      } while (bluetooth.available() > 0);
      if (data == 'U' || data == 'D' || data == 'L' || data == 'R' || data == 'F' || data == 'B' || data == 'S' || data == 'X') {
        Serial.print("Received value: ");
        Serial.println(data);
        switch (data) {
          case ('S'): //SAVE
            Serial.println("Enter the button you desire to set...");
            do {
              data = 254;
              bluetooth.listen();
              button = bluetooth.read();
              if (button == '0' || button == '1' || button == '2') {
                data = 'S';
              }
            } while (data != 'S');
            Serial.println("SAVING POSITIONS ...");
            if (button == '0') {
              servo01pos\[0\] = pos01;
            } else if (button == '1') {
              servo01pos\[1\] = pos01;
            } else if (button == '2') {
              servo01pos\[2\] = pos01;
            }
            servo01.write(pos01);
            Serial.println(button);
            Serial.println(pos01);
            Serial.println(servo01pos\[1\]);
            Serial.println(servo01pos\[2\]);
            Serial.println(servo01pos\[0\]);
            //}
            break;

          case ('U'):
            Serial.println("UP");
            if (pos01 <= 180 - ANGLE_STEP) {
              pos01 = pos01 + ANGLE_STEP;
              servo01.write(pos01);
              Serial.println(pos01);
              delay(20);
              Serial.println(data);
            }
            break;

          case ('X'):
            Serial.println("EXIT");
            x = 0;
            break;
        }
      }
    }
  } while (x != 0) ;
}

```

# Answer
> 1 votes
The character '⸮ ' was given everytime there was a power outage. So, it is enough to use an external power supply to power bluetooth and servos (Arduino cannot power all those modules simultaniously).

---
Tags: servo, hc-05, error
---


title: Arduino expected ')' before '{' token

text:
# Question
Title: Arduino expected ')' before '{' token
```
 for (byte i = 0; i < mfrc522.uid.size; i++)
  {
    Serial.print(mfrc522.uid.uidByte{i} < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte{i}, HEX);
    content.concat(String(mfrc522.uid.uidByte{i} < 0x10 ? " 0" : " "));
    content.concat(String(mfrc522.uid.uidByte{i}, HEX));
  }

```

I use this code to get UID of an RFID card, but the error `"expected ')' before '{' token"` comes out. Does anybody know how to solve this problem?

# Answer
> 1 votes
Welcome to this site, next time use ctrl-k to align your code.

The problem is in:

```
Serial.print(mfrc522.uid.uidByte{i} < 0x10 ? " 0" : " ");

```

To get the value of an array, use `[i]`, not `{i}`, thus

```
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");

```

(similar to other lines).

To give some additional hints:

* Try to prevent duplicated code by storing the byte into a variable. Now you can use `uidValue` in the subsequent lines.

uint8\_t uidValue = mfrc522.uid.uidByte\[i\];
* Store 0x10 inside a constant.

So you get:

```
const uint8_t MAX_HEX_SINGLE_DIGIT_VALUE 0x0F;

for (byte i = 0; i < mfrc522.uid.size; i++)
{
    uint8_t uid_byte = mfrc522.uid.uidByte[i];
    Serial.print(uid_byte < LOW_VALUE <= MAX_HEX_SINGLE_DIGIT_VALUE ? " 0" : " ");
    Serial.print(uid_byte, HEX);
    content.concat(String(uid_byte < MAX_HEX_SINGLE_DIGIT_VALUE ? " 0" : " "));
    content.concat(String((uid_byte, HEX));
  }

```

I assume the Serial lines are only for debugging, otherwise you can combine them too.

---
Tags: c++, compilation-errors
---


# Question
Title: Connecting multiple ultrasonic sensors(hc-sr04) to a single arduino board.(mega)
I am currently working on an alarm system using multiple sensors and one arduino board and I am getting readings from 2 of the sensors but one gives a constant zero and a constant buzzer sound even without sensing the distance...I have followed the schematics of the original project but nothing works. Here is the code

```

int ledred1 = 2;
int ledgreen1 = 3;
int ledorange1 = 4;
int ledred2 = 5;
int ledgreen2 = 6;
int ledorange2 = 7;
int ledred3 = 8;
int ledgreen3 = 9;
int ledorange3 = 10;

int sound = 250;

int trigPin1 = 11;
int echoPin1 = 12;

int trigPin2 = 13;
int echoPin2 = 30;

int trigPin3 = 31;
int echoPin3 = 32;

#define buzzer1 33
#define buzzer2 34
#define buzzer3 35

void setup() {
  Serial.begin (9600);
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);

  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);

  pinMode(trigPin3, OUTPUT);
  pinMode(echoPin3, INPUT);

  pinMode(ledred1, OUTPUT);
  pinMode(ledred2, OUTPUT);
  pinMode(ledorange1, OUTPUT);
  pinMode(ledgreen1, OUTPUT);
  pinMode(ledgreen2, OUTPUT);
  pinMode(ledred3, OUTPUT);
  pinMode(ledgreen3, OUTPUT);
  pinMode(ledorange2, OUTPUT);
  pinMode(ledorange3, OUTPUT);

}
void firstsensor(){ // This function is for first sensor.
  int duration1, distance1;
  digitalWrite (trigPin1, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigPin1, LOW);
  duration1 = pulseIn (echoPin1, HIGH);
  distance1 = (duration1/2) / 29.1;

      Serial.print("1st Sensor: ");
      Serial.print(distance1);
      Serial.print("cm    ");

  if (distance1 <=200 && distance1>=100) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,HIGH);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=250;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
     }

  if (distance1 <100&& distance1>=50) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,HIGH);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=275;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
      }
        if (distance1 <50&& distance1>=0) {  // Change the number for long or short distances.
    digitalWrite (ledred1, HIGH);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=300;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
      }
      if(distance1>200 || distance1<0){
    Serial.println("Out of Range");
    noTone(buzzer1);
  }
  else{
    Serial.print(distance1);
    Serial.println("cm");
    tone(buzzer1,sound);

  }
}
void secondsensor(){ // This function is for second sensor.
    int duration2, distance2;
    digitalWrite (trigPin2, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin2, LOW);
    duration2 = pulseIn (echoPin2, HIGH);
    distance2 = (duration2/2) / 29.1;

      Serial.print("2nd Sensor: ");
      Serial.print(distance2);
      Serial.print("cm    ");

     if (distance2 <=200&& distance2>=100) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, HIGH);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=250;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
     }

  if (distance2 <100&& distance2>=50) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,HIGH);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=275;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
      }
        if (distance2 <50&& distance2>=0) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, HIGH);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=300;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
      }
      if(distance2>200 || distance2<0){
    Serial.println("Out of Range");
    noTone(buzzer2);
  }
  else{
    Serial.print(distance2);
    Serial.println("cm");
    tone(buzzer2,sound);

  }
}
void thirdsensor(){ // This function is for third sensor.
    int duration3, distance3;
    digitalWrite (trigPin3, HIGH);
    delayMicroseconds (10);
    digitalWrite (trigPin3, LOW);
    duration3 = pulseIn (echoPin3, HIGH);
    distance3 = (duration3/2) / 29.1;

      Serial.print("3rd Sensor: ");
      Serial.print(distance3);
      Serial.print("cm");

     if (distance3 <=200&& distance3>=100) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, HIGH);

    sound=250;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
     }

  if (distance3 <100&& distance3>=50) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,HIGH);
    digitalWrite (ledgreen3, LOW);

    sound=275;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
      }
        if (distance3 <50&& distance3>=0) {  // Change the number for long or short distances.
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);

    sound=300;

  } else {
    digitalWrite (ledred1, LOW);
    digitalWrite (ledgreen1,LOW);
    digitalWrite (ledorange1,LOW);
    digitalWrite (ledred2, LOW);
    digitalWrite (ledorange2,LOW);
    digitalWrite (ledgreen2, LOW);
    digitalWrite (ledred3, LOW);
    digitalWrite (ledorange3,LOW);
    digitalWrite (ledgreen3, LOW);
      }
      if(distance3>200 || distance3<0){
    Serial.println("Out of Range");
    noTone(buzzer3);
  }
  else{
    Serial.print(distance3);
    Serial.println("cm");
    tone(buzzer3,sound);

  }
}

void loop() {
Serial.println("\n");
firstsensor();
delay(100);
secondsensor();
delay(100);
thirdsensor();
delay(100);
}

```

This is what I get in the serial monitor This is the snapshot of the pin configuration

# Answer
This is NOT an answer to the question, but I did some (major) refactoring which make it much more clear what is happening.

I think you made some mistake within the (refactored) method Sensor::UpdateState.

File \<.ino\>:

```
#include "Sensors.h"

Sensors _sensors;

void setup() {
  Serial.begin (9600);
  _sensors.Init();
}

void loop()
{
  _sensors.Process();
}

```

File Sensors.h:

```
#ifndef SENSORS_H
#define SENSORS_H

#include "Arduino.h"
#include "Sensor.h"

class Sensors
{
  public:
    Sensors();

    void Init();
    void Process();

  private:
    static const int NR_OF_SENSORS = 3;

    Sensor _sensors[NR_OF_SENSORS];
};

#endif // SENSORS_H

```

File Sensors.cpp:

```
#include "Sensors.h"

Sensors::Sensors()
:
  //              index trigPin echoPin redLed orangeLed greenLed buzzer)
  _sensors( { Sensor(1 ,  11   ,  12   ,  2       3     ,   4    ,  33),
              Sensor(2 ,  13   ,  30   ,  5       6     ,   7    ,  34),
              Sensor(3 ,  31   ,  32   ,  8       9     ,   10   ,  35) })
{
}

void Sensors::Init()
{
  for (uint8_t index = 0; index < NR_OF_SENSORS; index++)
  {
    _sensors[index].Init();
  }
}

void Sensors::Process()
{
  for (uint8_t index = 0; index < NR_OF_SENSORS; index++)
  {
    _sensors[index].Process();
  }
}

```

File Sensor.h:

```
#ifndef SENSOR_H
#define SENSOR_H

#include "Arduino.h"

class Sensor
{
  public:
    enum EState
    {
      LOW_OUT_OF_RANGE,
      WAY_TOO_CLOSE,
      TOO_CLOSE,
      OK,
      HIGH_OUT_OF_RANGE
    };

    Sensor(uint8_t index, uint8_t trigPin, uint8_t echoPin, uint8_t redLed, uint8_t orangeLed, uint8_t greenLed, uint8_t buzzer);

    uint8_t Index    (void) { return _index;     };
    uint8_t TrigPin  (void) { return _trigPin;   };
    uint8_t EchoPin  (void) { return _echoPin;   };
    uint8_t RedLed   (void) { return _redLed;    };
    uint8_t OrangeLed(void) { return _orangeLed; };
    uint8_t GreenLed (void) { return _greenLed;  };
    uint8_t Buzzer   (void) { return _buzzer;    };

    void Init();
    void Process();

  private:
    uint8_t _index;
    uint8_t _trigPin;
    uint8_t _echoPin;
    uint8_t _redLed;
    uint8_t _orangeLed;
    uint8_t _greenLed;
    uint8_t _buzzer;
    EState _state;
    uint8_t _distance;

    void Measure();
    void UpdateState();
    void ProcessState();
    void Show(uint16_t sound, uint8_t led);
    void PrintDistance(void);
};

#endif // SENSOR_H

```

File Sensor.cpp:

```
#include "Sensor.h"

Sensor::Sensor(uint8_t index, uint8_t trigPin, uint8_t echoPin, uint8_t redLed, uint8_t orangeLed, uint8_t greenLed, uint8_t buzzer)
:
  _index(index),
  _trigPin(trigPin),
  _echoPin(echoPin),
  _redLed(redLed),
  _orangeLed(orangeLed),
  _greenLed(greenLed),
  _buzzer(buzzer),
  _state(OK),
  _distance(0)
{
}

void Sensor::Init()
{
  pinMode(TrigPin()  , OUTPUT);
  pinMode(EchoPin()  , INPUT);
  pinMode(RedLed()   , OUTPUT);
  pinMode(OrangeLed(), OUTPUT);
  pinMode(GreenLed() , OUTPUT);
}

void Sensor::Process()
{
  Measure();
  UpdateState();
  ProcessState();
  PrintDistance();
  delay(100);
}

void Sensor::Measure()
{
  digitalWrite(TrigPin(), HIGH);
  delayMicroseconds (10);
  digitalWrite(TrigPin(), LOW);
  uint16_t duration = pulseIn (EchoPin(), HIGH);
  _distance = (duration / 2) / 29.1;
}

void Sensor::UpdateState()
{
  if (_distance < 0)
  {
    _state = LOW_OUT_OF_RANGE;
  }
  else if (_distance <= 50)
  {
    _state = WAY_TOO_CLOSE;
  }
  else if (_distance <= 100)
  {
    _state = TOO_CLOSE;
  }
  else if (_distance <= 200)
  {
    _state = OK;
  }
  else
  {
    _state = HIGH_OUT_OF_RANGE;
  }
}

void Sensor::ProcessState()
{
  digitalWrite(RedLed(), LOW);
  digitalWrite(OrangeLed(), LOW);
  digitalWrite(GreenLed(), LOW);

  switch (_state)
  {
  case LOW_OUT_OF_RANGE:
    noTone(Buzzer());
    break;

  case WAY_TOO_CLOSE:
    Show(300, RedLed());
    break;

  case TOO_CLOSE:
    Show(275, OrangeLed());
    break;

  case OK:
    Show(250, GreenLed());
    break;

  case HIGH_OUT_OF_RANGE:
    noTone(Buzzer());    break;
    break;

  default:
    // Error
    break;
  }
}

void Sensor::Show(uint16_t sound, uint8_t led)
{
  tone(Buzzer(), sound);
  digitalWrite(led, HIGH);
}

void Sensor::PrintDistance()
{
  Serial.print("Sensor ");
  Serial.print(Index());
  Serial.print(": ");
  Serial.print(_distance);
  Serial.print("cm    ");

  if ((_state == LOW_OUT_OF_RANGE) || (_state == HIGH_OUT_OF_RANGE))
  {
    Serial.print(" (Out of range)");
  }

  Serial.println("");
}

```
> 1 votes

---
Tags: arduino-uno, arduino-mega, hc-sr04
---


# Question
Title: Sketch will not start with external power source
NOOB Question: when my Uno is connected to an external power source it will not start running the uploaded sketch. The Arduino web site says it's because the RX pin is not connected and then gets random data.

The site suggests grounding the RX pin using a resistor (granted it suggests a 10K and I used a smaller one ) or connecting it to the TX pin.

From Why doesn't my sketch start when I power up or reset the Arduino board?

> Most likely because you are sending serial data to the board when it firsts turns on. During the first few seconds, the bootloader (a program pre-burned onto the chip on the board) listens for the computer to send it a new sketch to be uploaded to the board. After a few seconds without communication, the bootloader will time out and start the sketch that's already on the board. If you continue to send data to the bootloader, it will never time out and your sketch will never start. You'll either need to find a way to stop serial data from arriving for the first few seconds when the board powers (e.g. by enabling the chip that sends the data from within your setup() function) or burn your sketch onto the board with an external programmer, replacing the bootloader.

From Why doesn't my sketch start when I'm powering the board with an external power supply? (Arduino Diecimila or earlier)

> Because the RX pin is unconnected, the bootloader on the board may be seeing garbage data coming in, meaning that it never times out and starts your sketch. Try tying the RX pin to ground with a 10K resistor (or connecting RX directly to the TX pin).

Both failed for me.

What should I do?

# Answer
The problem was, as Gerben said, the battery was too weak to run the engine.
> 4 votes

# Answer
I also had a similar problem running with an external power supply. In my case the sketch ran but totally incorrectly . Conected RX to ground with a 10K Ohm resistor and solved the problem.

Thanks for the info!! Others have spent a lot more time solving this problem than I did.
> 2 votes

# Answer
I will add my little drop of experience here... So I am using a display tm1637, having CLK in 6 and DIO in 5. When connecting the Battery (12V 3s lipo 4000mA) to Vin, the arduino will freeze, even connected to the USB, will still freeze.

Short version, Moving DIO from 5 to 7 corrected the problem, now i have my device running from USB and or battery with no problem.

Long version: after 3 hours of trying different mods, including resistor to RX,TX, to GND, even removing the ch340 chip and connecting Rts and others to GND/VCC.. Nothing, so i decided to move the different devices from One nano to Other but testing after each connection. When the display was connected, the Nano will freeze while running on battery power. So... i moved DIO first to a different pin, and the device started working. I know is a very particular case, but one more thing to try if you are like me, stock without knowing what to do.... moving some pins (maybe skipping 5?)...
> 2 votes

---
Tags: arduino-uno
---


# Question
Title: Is it possible my ATMega is burnt due to bad wiring?
While working on a project I tried sending data from my Arduino NANO to ATMega64 placed on AREXX Robot arm PCB via TXD/RXD. After plugging in VCC, GND, TXD and RXD to UART socket it didn't work so I figured the socket itself must be backwords or mirror image from my perspective. Then I tried plugging everything in on the other side of the socket and as I plugged VCC to one of the pins a little smoke came out (I can't specify exact place where smoke came from) and from now on there is no connection to the robot. However LEDs seem to work just like before the 'incident'. It can be seen as COM but, desktop app constantly displays 'Connection failed' when trying to access the robot. It seems that I plugged VCC to the MRESET pin and GND to the RXD1 pin of the ATMega64. Can anyone help define if my processor is burnt? And if so, what can I do to fix the robot? Are there any other ways to send data to ATMega considering it is already programmed adn I want to keep it that way? Unfotunately, replacing ATMega isn't possible for me. Thanks in advance for any help.

UART :

ATMega :

Robot PCB :

# Answer
> 3 votes
Smoke is a definite sign something failed. The LED (power indicator)is independent of the microprocessor, it just indicates power is applied in the appropriate direction. Go to the basics, and load the simple blink sketch and see if it works, if so you are lucky. You then might want to write some code to check all the outputs and inputs. It is possible you destroyed both devices, you need to do some investigating to determine what is still properly operating.

---
Tags: serial, avr, electronics, uart, robotics
---


title: Read Comma Separated String

text:
# Question
Title: Read Comma Separated String
I have a string that looks like this "10.00,20.00,-50.00," in which these are angle values and they have 2 decimals and can be negative. I want to separate them into 3 separate floats. Here is my current code in which I use sscanf. All I get is 0.00 and have no idea why. Any help is truly appreciated.

```
String recvString = "10.00,20.00,-50.00,";
float r,p,y;

void setup() {
  Serial.begin(9600);
  Serial.println(r);
  int result = sscanf(recvString.c_str(), "%f,%f,%f,", &r, &p ,&y);
  Serial.println(r);
}

void loop() {}

```

# Answer
> 0 votes
Use the indexOf function to find index then use the subString to get values like this:

```
String recvString = "10.00,20.00,50.00";
float r, p, y;

void setup() {
  Serial.begin(9600);
  //Serial.println(r);
  //recvString.toCharArray(s, recvString.length() + 1);
  //int result = sscanf(recvString.c_str(), "%f,%f,%f,", &r, &p ,&y);
  int i1 = recvString.indexOf(',');
  int i2 = recvString.indexOf(',', i1+1);
  Serial.println(i1);
  Serial.println(i2);

  String firstValue = recvString.substring(0, i1);
  String secondValue = recvString.substring(i1 + 1, i2);
  String thirdValue = recvString.substring(i2 + 1);

  Serial.println(firstValue);
  Serial.println(secondValue);
  Serial.println(thirdValue);

}

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

}

```

# Answer
> 2 votes
The AVR implementation of `sscanf()` does not support parsing floating point numbers, thus you only get zeros out of it. You can't use the `%f` specifier with it. You need to convert these numbers by yourself with functions like `atof()` or similar.

Splitting a string into parts can be done many ways. You could use `sscanf()` to split up the string parts and then use something like `atof()` to actually convert to float. Or you use `strtok()` for splitting (see my answer to this question). Or you use one of the many other options, that you get, when googling for something like "Arduino split string" or "Arduino split c string".

Note: Using the `String` class in Arduino is easy for beginners, but not a good practice (dynamic allocation, heap fragmentation). Look at Majenkos blog for more information about that. Since you already used a function for C-strings, I would suggest moving completely to C-strings (which are basically only an array of `char`).

---
Tags: programming, c++, string, serial-data, c-string
---


# Question
Title: How many connections can Arduino I2C method create?
I was just learning about I2C between 2 Arduinos, one as sender and another as a receiver

So I have got curiosity to know how many Arduinos can be connected to I2C connection in serial?

I mean,

Arduino1 --\> Arduino2

Then can I connect Arduino3 to Arduino 2 then again Arduino 4 to Arduino 3? Till how many Arduinos can I continue this connection?

# Answer
> 4 votes
The limiting factor is the *bus capacitance*. This is the limit of the total capacitance of the bus from all devices connected to it plus the capacitance of the wires used.

It is also affected by the value of the pullup resistors.

The limit, according to the specifications, is 400pF. An Arduino has an input capacitance of 10pF. So ignoring the wires that's an absolute limit of 40 Arduinos all connected together.

Reduce that a bit for the wires, so say 30 is a reasonable estimate. Then reduce that again if you're using the internal pullups which are about 10x bigger than they should be. That gives you a guestimate of 5-10 devices.

Use proper pullups instead of the internal ones (why oh why oh why did Arduino ever encourage and even make default such a stupid option?!?!?!) of say 1kΩ and keep wires very short and you'll probably be OK up to 20-25 devices.

# Answer
> 1 votes
The number is as many as you want. There are switches that allow you to select different busses and each buss supports its full complement. From my point you are trying to use a solution before you have defined the problem fully. I have a feeling they will not be within a few inches of each other so consider an alternative designed for this type of use. CAN, RS485 and other interfaces would work much better with a lot less effort on your part.

---
Tags: arduino-uno, arduino-mega, arduino-nano, i2c
---


title: esp2866 powered externally not working

text:
# Question
Title: esp2866 powered externally not working
I got a beginner level problem.

I got two esp2866 nodeMCU, they both work with the usb cable and I can get the blink program to run though it. Running them with external power doesn't seem to work though. I expect the blink program to run when I plug them in but I get no led light signal at all. My power source looks identical to this. I got jumpers set on 5V. I don't have a voltage meter but I've tested against my Arduino Uno and it runs as expected when connected to the same wires.

1. Shouldn't I get the blink signal or any other led signal if the nodeMCU got power?
2. Any clue to how I could fail to provide power?

thank you!

edit: picture and jack barrel power input: 5V 3A

# Answer
> 3 votes
## Linear Regulator Dropouts

The linear voltage regulators found on that board are going to expect more than 5V at the barrel jack, because they require a minimum "drop out" voltage. The AMS1117 that is on that board, so far as I can tell, has a drop out voltage up to 1.3V. So you would want at least 6.3V (perhaps better 7V) at the barrel jack in order to get 5V out of it.

So the NodeMCU board may be seeing 5 - 1.3 or 3.7V at the input to its 3.3V regulator, which also requires its own drop out. The output of that 3.3V regulator may then be significantly below what the esp8266 specified operating voltage range.

## UPDATE

So I did the tests mentioned in the comments, just to illustrate the problem. And the results are about as expected.

I altered the stock blink sketch that comes with IDE version 1.8.13 to use LED\_BUILTIN (as opposed to 9) in the pinMode and digitalWrite calls.

I changed the LOW period, which is LED ON for my board, to 10000ms so that my voltmeter would have time to settle on a voltage test across the LED.

And I uploaded to the board, a NodeMCU 1.0 clone by Hitletgo.

When powered on its USB micro b jack, 3.3V labeled pin of the broad measuring 3.30 V. The LED color is blue, it is bright and it is dropping 2.66V.

Then I switched to powering the NodeMCU board by via of VIN pins from the YwRobot regulator board. I provided 5.05V to the barrel jack. To not great surprise, it does not blink.

The voltage out of regulator board was 3.26V. To be clear, I have this jumper for 5V. As a sanity check, I jumpered it for 3.3V and got about 2.5V out of it. Again, this is unsurprising because it also needs a dropout voltage.

I then measured the "3.3V" header line on the NodeMCU itself to be 2.14 V. Without sufficient voltage into the 3.3V regulator, it is not providing 3.3V out. And what it is producing is below that LED forward voltage when lit. So it is not surprising that it is not lit.

The ESP8266 technical specifications suggest that it can run down to 1.8V. So just for the hell of it I connected the board back to USB and updated the blink sketch to "blink" D8 (or GPIO15) 4 seconds on, 4 seconds off. I did not attach anything to this pin except the voltmeter.

I then reconnected the board to the test rig and found with a meter that it is "blinking" D8 just fine with a logic level consistent with the voltage the ESP8266 is actually receiving.

So in summary, the arrangement here is running the ESP8266 but there is not enough available voltage for it to light the LED. And it is very likely the exact same thing is happening for you.

# Answer
> 0 votes
Think of Vin like a car, not enough gas and you will not get there. Over fill it and you could burn it up.

---
Tags: nodemcu
---


# Question
Title: L293D driver DC motors need help to start rotating
I set up this circuit which uses L293D motor driver IC to control two DC motors.

+6V input is connected to unregulated power supply. It's current rating is 500 mA.

There is a connection between Arduino's ground line and power supplies ground line. There is a parallel 0.1 uF capacitor connected between motor terminal pins.

There is a wheel at the end of the motors but they don't have a gearbox. The wheels are suspended so that they can rotate freely.

The source code of the software is as follows.

```
#include <Arduino.h>

unsigned int firstMotorPositive = 8;
unsigned int firstMotorNegative = 7;
unsigned int enableFirstMotor = 9;
unsigned int secondMotorPositive = 5;
unsigned int secondMotorNegative = 4;
unsigned int enableSecondMotor = 3;

void setup()
{
    pinMode(firstMotorPositive, OUTPUT);
    /*  I've changed this part as shown by @timemage  */
    //pinMode(secondMotorPositive, OUTPUT); // <------
    pinMode(firstMotorNegative, OUTPUT);
    pinMode(enableFirstMotor, OUTPUT);
    pinMode(secondMotorPositive, OUTPUT);
    pinMode(secondMotorNegative, OUTPUT);
    pinMode(enableSecondMotor, OUTPUT);

    // All motors are off
    digitalWrite(firstMotorPositive, LOW);
    digitalWrite(firstMotorNegative, LOW);
    digitalWrite(secondMotorPositive, LOW);
    digitalWrite(secondMotorNegative, LOW);
}

void turnOnMotors()
{
    // Set motors to maximum speed
    // For PWM maximum possible values are 0 to 255
    analogWrite(enableFirstMotor, 255);
    analogWrite(enableSecondMotor, 255);

    // Turn on motor A & B
    digitalWrite(firstMotorPositive, HIGH);
    digitalWrite(firstMotorNegative, LOW);
    digitalWrite(secondMotorPositive, HIGH);
    digitalWrite(secondMotorNegative, LOW);
    delay(2000);

    // Turn off motors
    digitalWrite(firstMotorPositive, LOW);
    digitalWrite(firstMotorNegative, LOW);
    digitalWrite(secondMotorPositive, LOW);
    digitalWrite(secondMotorNegative, LOW);

    analogWrite(enableFirstMotor, 0);
    analogWrite(enableSecondMotor, 0);

}

void speedControl()
{
    digitalWrite(firstMotorPositive, HIGH);
    digitalWrite(firstMotorNegative, LOW);
    digitalWrite(secondMotorPositive, HIGH);
    digitalWrite(secondMotorNegative, LOW);

    analogWrite(enableFirstMotor, 63);
    analogWrite(enableSecondMotor, 63);

    delay(3000);

    analogWrite(enableFirstMotor, 127);
    analogWrite(enableSecondMotor, 127);
    delay(3000);

    analogWrite(enableFirstMotor, 191);
    analogWrite(enableSecondMotor, 191);
    delay(3000);
/*
    analogWrite(enableFirstMotor, 255);
    analogWrite(enableSecondMotor, 255);
    delay(3000);
*/

    // All motors are off
    digitalWrite(firstMotorPositive, LOW);
    digitalWrite(firstMotorNegative, LOW);
    digitalWrite(secondMotorPositive, LOW);
    digitalWrite(secondMotorNegative, LOW);
    analogWrite(enableFirstMotor, 0);
    analogWrite(enableSecondMotor, 0);
}

void loop()
{

    /*
      turnOnMotors();
      delay(1000);
    */

    speedControl();
    delay(1000);
}

```

The problem is they need help to start rotating. They will only start rotating if I physically twist the shaft with my fingers first.

As far as I know the motors used in this circuit are two 6 volt DC motors.

When I measure the maximum voltage between motor terminals I read about 0.5 volts. If I twist the shaft I read about 4.5 volts.

# Answer
> 1 votes
The L2978D is a terrible motor driver (I really wish people wouldn't use it!). It is "bipolar" which means that both the high and low side switches of the H-bridge are Bipolar Junction Transistors. This means that you get about 1.4V voltage drop in total between the inputs and outputs.

To counter that you must provide at least 1.4V more than your motors need for them to operate properly.

# Answer
> 0 votes
## no pinMode(firstMotorNegative, OUTPUT)

Well, here's a start at least:

```
pinMode(firstMotorPositive, OUTPUT);
pinMode(secondMotorPositive, OUTPUT); // <------
pinMode(enableFirstMotor, OUTPUT);
pinMode(secondMotorPositive, OUTPUT);
pinMode(secondMotorNegative, OUTPUT);
pinMode(enableSecondMotor, OUTPUT);

```

You are never setting `firstMotorNegative` to `OUTPUT` and probably intended to on the second line of this excerpt.

## firstMotorNegative floating or pulled high

The AVR GPIO pins are `INPUT` on power-up. Writing to the PORT register, which is what `digitalWrite` does, takes on a different meaning when the pin's mode is `INPUT`. That is, it enables or disables the pull-up internal resistors. In other words, your `digitalWrite(firstMotorNegative, HIGH);` and `digitalWrite(firstMotorNegative, LOW);` are effectively toggling between `pinMode(firstMotorNegative, INPUT_PULLUP)` and `pinMode(firstMotorNegative, INPUT)` respectively.

So your L293D is seeing either this signal being weakly pulled up or floating. During the floating condition in particular maybe a problem when you're doing:

```
// Turn on motor A & B
digitalWrite(firstMotorPositive, HIGH);
digitalWrite(firstMotorNegative, LOW);

```

... because you're disabling the pull-up here, the "negative" pin is `INPUT`/floating rather than reliably `LOW`. So, it may be being intermittently interpreted as `HIGH` at the L293D, in which case there is no movement while that's happening.

# Answer
> 0 votes
That is operating as expected. Take a look at the data sheet. You can lose 1.8 volt on each output pin. Since you are in bridge configuration you now lose 3.6 Volts. Now assume your power is 6VDC with 1 volt ripple. That adds to the voltage drop through the driver so rounding it out you lose 4 volts from your supply (not counting wiring loses) before you start, that is assuming the voltage does not droop. Two simple solutions, use a power supply with more voltage or go to a MOSFET bridge device.

---
Tags: arduino-uno, motor
---


title: I get an error?

text:
# Question
Title: I get an error?
```
void setup()
{
Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop() {
if(Serial.available()>0)
{s_num =Serial.read();}
if(s_num=='0'){
digitalWrite(13,HIGH);
delay(100); //the specified time for 0
digitalWrite(13,LOW);
delay(100);}
if(s_num=='1'){
digitalWrite(13,HIGH);
delay(200);
digitalWrite(13,LOW);
delay(200);}
if(s_num=='2'){
digitalWrite(13,HIGH);
delay(300);
digitalWrite(13,LOW);
delay(300);}
char s_num; if(s_num=='3'){
digitalWrite(13,HIGH);
delay(400);
digitalWrite(13,LOW);
delay(400);}
if(s_num=='4'){
digitalWrite(3,HIGH);
delay(500);
digitalWrite(13,LOW);
delay(500);}
if(s_num=='5'){
digitalWrite(13,HIGH);
delay(600);
digitalWrite(13,LOW);
delay(600);}
if(s_num=='6'){
digitalWrite(13,HIGH);
delay(700);
digitalWrite(13,LOW);
delay(700);}
if(s_num=='7'){
digitalWrite(13,HIGH);
delay(800);
digitalWrite(13,LOW);
delay(800);}
if(s_num=='8'){
digitalWrite(13,HIGH);
delay(900);
digitalWrite(13,LOW);
delay(900);}
if(s_num=='9'){
digitalWrite(13,HIGH);
delay(1000);
digitalWrite(13,LOW);
delay(1000);}
digitalWrite(13,LOW);
s_num=10;
}

```

# Answer
> 1 votes
One tip to prevent these kind of error: next time align the `{` and `}` and you see the error very fast:

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

void loop()
{
  char s_num;
  if(Serial.available()>0)
  {
    s_num =Serial.read();
  }

  if(s_num=='0')
  {
    digitalWrite(13,HIGH);
    delay(100); //the specified time for 0
    digitalWrite(13,LOW);
    delay(100);
  }

  if(s_num=='1')
  {
    digitalWrite(13,HIGH);
    delay(200);
    digitalWrite(13,LOW);
    delay(200);
  }

  if(s_num=='2')
  {
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
  }

  if(s_num=='3')
  {
    digitalWrite(13,HIGH);
    delay(400);
    digitalWrite(13,LOW);
    delay(400);
  }

  if(s_num=='4')
  {
    digitalWrite(3,HIGH);
    delay(500);
    digitalWrite(13,LOW);
    delay(500);
  }

  if(s_num=='5')
  {
    digitalWrite(13,HIGH);
    delay(600);
    digitalWrite(13,LOW);
    delay(600);
  }

  if(s_num=='6')
  {
    digitalWrite(13,HIGH);
    delay(700);
    digitalWrite(13,LOW);
    delay(700);
  }
  if(s_num=='7')
  {
    digitalWrite(13,HIGH);
    delay(800);
    digitalWrite(13,LOW);
    delay(800);
  }
  if(s_num=='8')
  {
    digitalWrite(13,HIGH);
    delay(900);
    digitalWrite(13,LOW);
    delay(900);
  }
  if(s_num=='9')
  {
    digitalWrite(13,HIGH);
    delay(1000);
    digitalWrite(13,LOW);
    delay(1000);
  }
  digitalWrite(13,LOW);
  s_num=10;
}

```

As you can see `char s_name` needs to be be declared in the front of the method as you need it in the second line, so you get the following code that compiles:

```
void loop()
{
  if(Serial.available()>0)
  {
    s_num =Serial.read();
  }

  if(s_num=='0')
  {
    digitalWrite(13,HIGH);
    delay(100); //the specified time for 0
    digitalWrite(13,LOW);
    delay(100);
  }

  if(s_num=='1')
  {
    digitalWrite(13,HIGH);
    delay(200);
    digitalWrite(13,LOW);
    delay(200);
  }

  if(s_num=='2')
  {
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
  }
  char s_num;

  if(s_num=='3')
  {
    digitalWrite(13,HIGH);
    delay(400);
    digitalWrite(13,LOW);
    delay(400);
  }

  ...
}

```

Now you also can see that you process the `s_num` variable even if there is not a new value from the serial class, so you should put it probably inside, getting:

```
void loop()
{
  if(Serial.available()>0)
  {
    char s_num =Serial.read();

    if(s_num=='0')
    {
      digitalWrite(13,HIGH);
      delay(100); //the specified time for 0
      digitalWrite(13,LOW);
      delay(100);
    }
  }
}

```

The last statement `s_num=10;` does not anything.

Now, to greatly reduce your code, all digits perform more or less the same code. You can combine this by calculating the delay time (0 -\> 100, 9 -\> 1000), and you get the following code:

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

void loop()
{
  if (Serial.available() > 0)
  {
    char s_num = Serial.read();
    if ((s_num >= '0') && (s_num <= '9'))
    {
      uint16_t delayTime = (s_num - '0' + 1) * 100;
      digitalWrite(13, HIGH);
      delay(delayTime);
      digitalWrite(13, LOW);
      delay(delayTime);
    }
    else
    {
      digitalWrite(13, LOW);
    }
  }
}

```

By subtracting '0' from a character digit ('0' to '9'), you get its value.

---
Tags: arduino-uno, arduino-nano, library, compilation-errors, error
---


# Question
Title: Why Are My High and Low Values Not Updating Correctly During Successive Loops
I am attempting to capture the high and low temperature and humidity values, then clearing the LCD and displaying them on 2 successive screen updates. All is working correctly except that the variables for high and low are updating on every loop to the current sensor pin read after the "if" statements are run. Why is this occurring? Also note that I declare the floats for the highs and lows to the unlikely value of 10000 in order to change them all to the initial pin read on the 1st loop as I didn't find a method to determine null on the initial loop. I would appreciate any suggestions for a better method! TIA

```
    #include <dht.h>
    #include <LiquidCrystal.h>

    //Low and High Temp and Humidity Variables
    float lTemp=10000;
    float hTemp=10000;
    float lHumid=10000;
    float hHumid=10000;

    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    dht DHT;

    #define DHT11_PIN 7

    void setup(){
      lcd.begin(16, 2);
      Serial.begin(9600);
    }

    void loop(){
       lcd.clear();

      int chk = DHT.read11(DHT11_PIN);

      float CurrTemp = DHT.temperature * 1.8 + 32;  //Converts celsius read from DHT read to farenheit

    //Sets High and Low Temperature Readings

       if (lTemp = 10000) {
         lTemp = CurrTemp;
       }
      if (CurrTemp < lTemp) {
         lTemp = CurrTemp;
      }

      if (hTemp = 10000) {
        hTemp= CurrTemp;
      }
       if (CurrTemp > hTemp) {
        hTemp = CurrTemp;
      }

    //Sets High and Low Humidity Readings

      if (lHumid = 10000) {
        lHumid = DHT.humidity;
       }
      if (DHT.humidity < lHumid) {
        lHumid = DHT.humidity;
      }

      if (hHumid = 10000) {
        hHumid = DHT.humidity;
      }
      if (DHT.humidity > hHumid) {
        hHumid = DHT.humidity;
      }

      //Prints Current Temp and Humidity to LCD and Serial Monitor
      lcd.setCursor(0,0);
      lcd.print("Temp: ");
      lcd.print(CurrTemp,1);
      lcd.print((char)223);
      lcd.print("F");

      Serial.print(CurrTemp,1);

      Serial.println(" F");

      lcd.setCursor(0,1);

      lcd.print("Humidity: ");
      lcd.print(DHT.humidity,0);
      lcd.print("%");

      Serial.print("Humidity: ");
      Serial.print(DHT.humidity,0);
      Serial.println("%");
      Serial.println("");

      delay(10000);

      //Prints Low and High Temp to LCD and Serial Monitor
      lcd.clear();

      lcd.setCursor(0,0);
      lcd.print("L Temp: ");
      lcd.print(lTemp,1);
      lcd.print((char)223);
      lcd.print("F");

      Serial.print("Low Temp: ");
      Serial.print(lTemp,1);
      //Serial.print((char,223);
      Serial.println(" F");

      lcd.setCursor(0,1);

      lcd.print("H Temp: ");
      lcd.print(hTemp,1);
      lcd.print((char)223);
      lcd.print("F");

      Serial.print("High Temp: ");
      Serial.print(hTemp,1);
      Serial.println(" F");
      Serial.println("");

      delay(3000);

     //Prints Low and High Humidity to LCD and Serial Monitor
      lcd.clear();

      lcd.setCursor(0,0);
      lcd.print("Low Humid: ");
      lcd.print(lHumid,0);
      lcd.print("%");

      Serial.print("Low Humid: ");
      Serial.print(lHumid,0);
      Serial.println("%");

      lcd.setCursor(0,1);

      lcd.print("High Humid: ");
      lcd.print(hHumid,0);
      lcd.print("%");

      Serial.print("High Humid: ");
      Serial.print(hHumid,0);
      Serial.println("%");
      Serial.println("");

      delay(3000);

    }

```

# Answer
> 2 votes
You have this or similar a number of times:

> ```
>   if (lTemp = 10000) {
>      lTemp = CurrTemp;
>    }
>
> ```

This is incorrect. The == operator is used for comparison.

Try:

> ```
>   if (lTemp == 10000) {
>      lTemp = CurrTemp;
>    }
>
> ```

The way you have it, the lTemp variable is assigned 10000 every time the statement is executed. It's not doing the comparison as you intend.

# Answer
> 2 votes
When programming in C, the "=" assigns a value and the "==" tests a value. So in this line of code:

```
if (lTemp = 10000)

```

... you are actually assigning variable lTemp the value of 10000. Consider changing the line of code to this:

```
if (lTemp == 10000)

```

... this will test if the variable lTemp is equal to 10000.

# Answer
> 2 votes
Although you already have two perfectly valid answers, I will share a trick that completely sidesteps the problem. Instead of choosing a particular number (here, 10,000) as a “magic” value that has a special meaning, you can instead initialize the highs and lows in a way that ensures they will be updated on the very first iteration:

* make `lTemp` higher than any temperature you may ever read
* make `hTemp` lower than any temperature you may ever read

For example:

```
float lTemp = +INFINITY;
float hTemp = -INFINITY;

```

and the same of course for the humidities. This way the first iteration does not need special handling anymore, as it becomes a regular iteration:

```
if (CurrTemp < lTemp) lTemp = CurrTemp;
if (CurrTemp > hTemp) hTemp = CurrTemp;

```

Note that the choice of ±∞ for the min and max of an empty set of readings is not just a dirty hack. It is actually consistent with the mathematical notion of infimum and supremum of the empty set.

---
Tags: arduino-nano, lcd, temperature-sensor
---


# Question
Title: Can I control solid state relay directly from arduino digital pin?
I want to switch on/off some AC device using solid state Omron G3MB relay I know that for magnetic relay there should be transistor and flyback diode, but what about SSR? Can I connect it directly to arduino digital pin without any transistors and anything else?

In a closer look on special arduino module, we can see some extras. Are they necessary? I want to put solid state relay (not separated module) into my custom PCB, and I'm confused about that extras.

# Answer
According to the datasheet there are multiple models.

Some already have an input resistor for the led (in the opto-isolator) inside the package, but some don't. For the ones that don't have a resistor inside, you'd **need to add** one yourself, to limit the current to around 10mA.

Some models also have a snubber circuit inside the package. The need for this depends on what kind of load is connected (inductive vs. resistive (AFAIK)).

I thinks the green thing, in the picture, is a fuse. On the other side of the SSR you can see and indicator led, transistor, and 3 resistor (one to limit current to the SSR, one to limit the current through the indicator led, and on for the base of the transistor.). They probably use a transistor, because the current for the SSR and the indicator led combined, is to high for certain micro controllers.
> 2 votes

# Answer
The answer is a qualified yes. In this case the relay is optically isolated from the load so there is no cross conduction. You need to connect the relay to the Arduino power +5 and Ground supply. I would not connect more then one to any arduino pin as the relay has a max requirement of 20mA. Not all SS relays are the same so you need to check there specs if you use another one.
> 0 votes

---
Tags: relay, digitalwrite
---


title: Run method every hour

text:
# Question
Title: Run method every hour
I have a method. I need to trigger it every hour (cron job).

I mean:

10.00 p.m -\> Trigger

11.00 p.m -\> Trigger

12.00 p.m -\>Trigger

...

...

Card: Arduino Uno + Wifi Shield.

**Draft Code**

```
  void setup() {

  }

  void onTimeChanged() {
      runTask();
  }

  void loop() {

  }

  /*run this method when:
  13.00 p.m
  14.00 p.m
  15.00 p.m
  ........
  ........    */
  void runTask() {

  }

```

# Answer
> 1 votes
An Arduino Uno doesn't have a *Real Time Clock*, but you could contact a **NTP time server** on the internet using the WiFi shield you mention, and get the time from there, and then keep track of time using `millis()`. Every so often, you should adjust the time with a new call to the NTP time server, because the Arduino's clock isn't all that accurate.

The easiest way would be to get a **RTC module** (I think the most accurate and still affordable at the moment are DS3231-based). They have a slot for a backup battery so they keep time even when there is no power supply.

Connect the module using I2C to your Arduino, install the appropriate library, and ask it every second (or however accurate you want to be) in your `loop()` for the exact time.

These modules usually also have an interrupt pin and can generate an interrupt when an alarm time is reached; you could use that also.

---
Tags: arduino-uno, c++, arduino-uno-wifi, task
---


# Question
Title: Arduino Library to make http post request with bearer authentication
I want to make an Http Post request with Bearer Authentication to my api using my Arduino Mkr Wifi 1010, but I couldn't find the appropriate library to do something like this (code generated with one made with Postman):

```
    POST /api/v1/rilevamento/transaction/commit HTTP/1.1
Host: www.....:8082
Authorization: Bearer eyJhb.......
Content-Type: application/json
Content-Length: 233

{
    "id": 0,
    "dispositivo": "sesto",
    "nomeutente": "MyName",
    "cognomeutente": "MySurname",
    "mailutente": "name@email.it",
    "data": "2020-11-23T09:23:03.142+00:00",
    "temperatura": 37.5
}

```

Can you tell me where to find this library? I tried WifiNiNa httpClient, ArduinoHttpClient, HTTPClient and other but I couldn't get any response or even enter in the method of my api on debug.

# Answer
> 6 votes
The "Authorization" is simply an HTTP header. So add it in your request like:

```
http.addHeader("Authorization", token);

```

The value of "token" is just the string "Bearer " followed by your authorization string. Don't neglect the SPACE after the word "Bearer". It will look like:

> "Bearer eyJhb......"

On the Arduino MKR WiFi 1010 you use the WiFiNINA library which is slightly different. Here is some example code:

```
  if (client.connect(server, 80)) {
    client.println("POST /test/post.php HTTP/1.1");
    client.println("Host: www.targetserver.com");
    client.println(authorizationHeader);
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(postData.length());
    client.println();
    client.print(postData);
  }

```

The variable `authorizationHeader` will have the "Authorization: Bearer xxxxx...." authorization string.

Or you can replace the `client.println(authorizationHeader);` by:

```
client.print("Authorization: Bearer ");
client.print(token);

```

to avoid dealing with concatenations, etc.

`client` can be an instance of `WiFiSSLClient` which works with both `WiFi101` and `WiFiNINA`.

---
Tags: wifi, http
---


# Question
Title: Sending letter by letter to LCD, however the LCD knows the full string?
I think this is my last post about this specific project, but I got a really weird curveball right now

I managed to do the webpage I wanted, and pass the string along. Now, when a LED lights up, it sends the corresponding letter to the LCD.

The problem now is that somehow, when I send a long string, the LCD somehow "knows" and display the overflow on the second row, which makes no sense to me. All I can think of is that the Ethernet Shield is using the same connections as my I2C that connects to the LCD.

That being said, here is my code:

```
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <Ethernet.h>
#define latchPin 5
#define clockPin 7
#define dataPin 6

LiquidCrystal_I2C lcd(0x27,16,2);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server(80);
String text;
char readHttp[100];
int i;
boolean temtexto;
char lcdtext[16];
void setup() {
  Serial.begin(9600);
  for (int i = 2; i < 7; i++) {
    if (i != 4) {
      pinMode(i, OUTPUT);
    }
   }
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  lcd.init();
  lcd.setBacklight(HIGH);
  lcd.setCursor(0,0);
  lcd.print("INICIANDO");
  Serial.println("Iniciando");
  if (Ethernet.begin(mac) == 0) {
    lcd.clear();
    lcd.setCursor(1,0);
    lcd.print("FALHA AO PEGAR");
    Serial.println("FALHA");
    lcd.setCursor(7,1);
    lcd.print("IP");
    delay(5000);
    return;
  }

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("PRONTO");
  lcd.setCursor(0,1);
  lcd.print(Ethernet.localIP());
  lcd.setCursor(0,0);
  Serial.println(Ethernet.localIP());
  server.begin();
  brilho(255);
  inicializationEffect();
}

void loop(){
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        lcd.setBacklight(LOW);
        lcd.clear();
        char c = client.read();
        if (c == ';') { temtexto = false; readHttp[i] = '\n';}
        if (temtexto) {
          if(i < 100) {
            readHttp[i] = toupper(c);
            i++;
          }
        }
        if (c == '?') { temtexto = true; }
        if (c == '\n') {
          client.println("HTTP/1.1 200 OK"); // Envia nova pagina
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println();
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Parede Stranger Things</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY>");
          client.println("<H1>Qual texto deseja enviar?</H1>");
          client.println("<input type=text id=texto style=width:295px  maxlength=50><br>");
          client.println("<input type=submit value='Enviar' style=width:150px;height:45px onClick=location.href='/?'+document.getElementById('texto').value+';'>");
          client.println("</BODY>");
          client.println("</HTML>");
          client.println("<string>");

          client.println("</string>");
          delay(1);
          client.stop();
          char *leader = readHttp;
          char *follower = leader;

          // While we're not at the end of the string (current character not NULL)
          while (*leader) {
              // Check to see if the current character is a %
              if (*leader == '%') {

                  // Grab the next two characters and move leader forwards
                  leader++;
                  char high = *leader;
                  leader++;
                  char low = *leader;

                  // Convert ASCII 0-9A-F to a value 0-15
                  if (high > 0x39) high -= 7;
                  high &= 0x0f;

                  // Same again for the low byte:
                  if (low > 0x39) low -= 7;
                  low &= 0x0f;

                  // Combine the two into a single byte and store in follower:
                  *follower = (high << 4) | low;
              } else {
                  // All other characters copy verbatim
                  *follower = *leader;
              }

              // Move both pointers to the next character:
              leader++;
              follower++;
          }
          // Terminate the new string with a NULL character to trim it off
          *follower = 0;
          lcd.clear();
          executeEffect(readHttp);
          memset(readHttp, 0, sizeof readHttp);
          i = 0;
        }
      }
    }
  }
}

void lineActivation(int line, int keepalive) {
  if (keepalive == 0) {
    for (int i = 2; i <= 4; i++) {
      if (i == 4) { i = 8; } //porta 4 usada pelo SD do Ethernet
      digitalWrite(i, LOW);
    }
  }
  if (line >= 1 && line <=3){
    if (line == 3) { line = 7; } //porta 4 usada pelo SD do Ethernet
    digitalWrite(line+1, HIGH); //coloca a linha 1 em estado lógico alto
  }
}

void activateLetter(char letter, int on, int off) {
  int lt;
  lt = (((int)letter - 64) % 9);
  if (((int)letter - 64) > 8) {
    lt = lt + 1;
  }
  if (on) {
    callCol(1<<lt-1);
    delay(on);
  }
  if (off) {
    callCol(0);
    delay(off);
  }
}

void callCol(int col){
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, highByte(col));
  shiftOut(dataPin, clockPin, MSBFIRST, lowByte(col));
  digitalWrite(latchPin, HIGH);
}

void executeEffect(char text[]) {
  if (strlen(text) > 0) {
    brilho(255);
    lcd.setBacklight(HIGH);
    memset(lcdtext, ' ', sizeof lcdtext);
  }
  for (int i = 0; i < strlen(text); i++) {
    if (text[i] == ' ') {
      lcdScreen(' ');
      delay(1000);
    } else if (((int)text[i] < -58 && (int)text[i] > -65) || ((int)text[i] < -28 && (int)text[i] > -33)) {
      text[i] = 'A';
    } else if (((int)text[i] < -47 && (int)text[i] > -41) || ((int)text[i] < -9 && (int)text[i] > -14)) {
      text[i] = 'O';
    } else if (((int)text[i] < -52 && (int)text[i] > -57) || ((int)text[i] < -20 && (int)text[i] > -25)) {
      text[i] = 'E';
    } else if (((int)text[i] < -49 && (int)text[i] > -53) || ((int)text[i] < -16 && (int)text[i] > -21)) {
      text[i] = 'I';
    } else if (((int)text[i] < -35 && (int)text[i] > -40) || ((int)text[i] < -3 && (int)text[i] > -8)) {
      text[i] = 'U';
    } else if (((int)text[i] == -25 || (int)text[i] == -57)) {
      text[i] = 'C';
    }
    if ((int)text[i] < 65 or (int)text[i] > 90) {
    } else {
      lineActivation(int(((int)text[i] - 64) / 9) + 1, 0);
      //Serial.println(text[i]);
      lcdScreen(text[i]);
      activateLetter(text[i], 1000, 200);
    }
  }
  for (int i = 0; i < 16; i++){
    lcdScreen(' ');
    delay(500);
  }
  lcd.setBacklight(LOW);
  lcd.clear();
}

void lcdScreen(char ltc) {
  Serial.println(ltc);
  memcpy(lcdtext, &lcdtext[1], sizeof(lcdtext) - sizeof(char));
  lcdtext[15] =  ltc;
  lcd.setCursor(0,0);
  lcd.print(lcdtext);
}

void inicializationEffect() {
  Serial.println("LineByLine");
  for (int i = 1; i < 27; i++) {
    lineActivation(int(i / 9) + 1, 0);//ativa a linha
    activateLetter(char(64 + i), 100, 10); //ativa a letra
  }
}

void waveEffect() {
  Serial.println("Wave");
  for (int i = 1; i < 4; i++) {
    lineActivation(i, 1);//ativa a linha
  }
  for (int i = 1; i < 10; i++) {
    activateLetter(char(72 + i), 100, 0);
  }

  for (int i = 1; i < 10; i++) {
    activateLetter(char(72 + i), 0, 100);
  }
  lineActivation(0, 0);
}

void blink() {
  Serial.println("Blink");
  callCol(511);
  lineActivation(1,1);
  lineActivation(2,1);
  lineActivation(3,1);
  for (int i = 0; i < 256; i++){
    brilho(i);
    delay(1);
  }
  delay(100);
  for (int i = 255; i >= 0; i--){
    brilho(i);
    delay(1);
  }
}

void brilho(byte brt) {
  analogWrite(9, 255-brt);
}

```

I am using a W5100 Ethernet Shield, a I2C to LCD adapter and a 16x2 LCD. The I2C is connected to the pins A4(SDA) and A5(SCL).

Here is a picture of how the LCD appears when I send "This is a really long string":

On the first line the text scrolls, one character at a time, as intended. However, on the second line there is an overflow of the text that, as far as I can tell, I never sent to the LCD in the first place. Even if I try to lcd.clear() after every character sent, it still persists with the end of the string on the second line.

# Answer
I think what you're seeing is the result of:

```
lcd.print(lcdtext);

```

and the fact that lcdtext is not null-terminated. `print()` is expecting a string, that is some sequence of zero or more non-'\0' characters followed by a `'\0'` character. Not having null-terminated it yourself, in practice it will continue reading memory after your the location of lcdtext in memory until it finds a `'\0'`. Somewhere in there it is probably finding the extra character(s) that you're seeing.

You could make a point of having `'\0'` at the end of it always, making lcdtext one character larger if necessary in order to do that. Or you could:

```
lcd.write(lcdtext, sizeof lcdtext);

```

In this form with the length/size as a second argument, `write` doesn't expect a string, just an arbitrary chunk of characters whether they contain `'\0'` or not and knows to stop at whatever count of characters was specified.

As an aside `memmove` should be used rather than `memcpy` when the input and output destinations overlap. What happens with `memcpy` when they do overlap is undefined:

```
memmove(lcdtext, &lcdtext[1], sizeof(lcdtext) - 1);

```

`memmove` is outwardly the same thing, only designed for this scenario. The difference between them is a matter of which optimizations are enabled by the knowledge that the source and destination may or may not overlap. It may not be a source of a problem on your current platform, depending on how memcpy was written, but it may later or when you switch platforms.
> 2 votes

# Answer
Huh, I kinda solved it, but I still dont get it how the `lcdtext` was getting the full string.

I replaced the lcdScreen function with this:

```
void lcdScreen(char ltc) {
  Serial.println(ltc);
  Serial.print(lcdtext);
  memmove(lcdtext, &lcdtext[1], sizeof(lcdtext) - 1);
  lcdtext[15] =  ltc;
  lcd.setCursor(0,0);
  for (int i = 0; i < 16; i++){
    lcd.print(lcdtext[i]);
  }
}

```

It works, but I still dont understand why I had the full text when I am just calling this function with a single char each time
> 0 votes

---
Tags: arduino-uno, i2c, lcd, ethernet-shield
---


# Question
Title: Sending a string from RPi to Arduino - Working Code
I've been researching for 2 days now trying to figure out how to receive a string via I2C on an Arduino. There are plenty of questions online but no real solutions or full tutorials... and sadly I threw my C++ book out years ago.

The code below compiles without error and receives the string correctly. (There are several commented out blocks that I've used to verify the data is being received.) The issue is printing the full received command string. I am unable to make it print in `receiveEvent()` or in the `loop()`. Ultimately I need it as a string such as "WIN-23-200" where I will explode the string by "-" to do something but I still can't get a hold of it.

If anyone can give me a nod in the right direction I'd appreciate it.

Thanks!

```
#include <Wire.h>

#define SLAVE_ADDRESS 0x04

volatile boolean receiveFlag = false;
char temp[32];
String command;

void setup() {
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
  Serial.println("Ready!");

}

void loop() {
  delay(1000);
  if (receiveFlag == true) {
    Serial.println("inFlag");
    Serial.println(command);
    receiveFlag = false;
  }
}

void receiveEvent(int howMany) {
  //works as expected
  /*while (0 < Wire.available()) { // loop through all
    char c = Wire.read();
    Serial.print(c);
    }*/

  int count = 0;
  while (0 < Wire.available()) { // loop through all
    temp[count] = Wire.read();
    count++;
  }
  //temp[32-1]='\0'; //make sure its 0 terminated, didn't matter
  command = temp; //put char array into a string variable named command

  Serial.print(temp); // prints nothing....

  //Verify Array is Loaded..works great.
  //for (int i = 0; i < count; i++)
  //{
  //  Serial.println(temp[i]);
  //}
  receiveFlag = true;
}

```

# Answer
Here's the working code. The hangup was my Raspberry Pi Master was adding a "cmd byte" to the string before transit. So when I would send "test" the Arduino received 5 bytes; "0test". Based on feedback here I added the null after ea char and then shifted the array to eliminate the first byte and the Serial.print started working.

Here's the working **RPi Master Python code**:

```
# -*- coding: utf-8 -*-
import smbus
import time
# for RPI version 1, use bus = smbus.SMBus(0)
bus = smbus.SMBus(1)

# This is the address we setup in the Arduino Program
address = 0x04

#http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2
def writeData(value):
    byteValue = StringToBytes(value)
    bus.write_i2c_block_data(address,0x00,byteValue) #first byte is 0=command byte.. just is.
    return -1

def StringToBytes(val):
        retVal = []
        for c in val:
                retVal.append(ord(c))
        return retVal

while True:
    print("sending")
    writeData("test")
    time.sleep(5)

    print('OPEN');
    writeData("OPEN-00-00")
    time.sleep(7)

    print('WIN');
    writeData("WIN-12-200")
    time.sleep(7)

```

And the **Arduino Slave Code**

```
#include <Wire.h>

#define SLAVE_ADDRESS 0x04

volatile boolean receiveFlag = false;
char temp[32];
String command;

void setup() {
  // initialize i2c as slave
  Wire.begin(SLAVE_ADDRESS);

  // define callbacks for i2c communication
  Wire.onReceive(receiveEvent);

  Serial.begin(9600);
  Serial.println("Ready!");

}

void loop() {

  if (receiveFlag == true) {
    Serial.println(temp);
    receiveFlag = false;
  }
}

void receiveEvent(int howMany) {

  for (int i = 0; i < howMany; i++) {
    temp[i] = Wire.read();
    temp[i + 1] = '\0'; //add null after ea. char
  }

  //RPi first byte is cmd byte so shift everything to the left 1 pos so temp contains our string
  for (int i = 0; i < howMany; ++i)
    temp[i] = temp[i + 1];

  receiveFlag = true;
}

```

Hopefully this helps someone else, I searched for along time to put this together!
> 2 votes

# Answer
onReceive is intended for use by slaves. master must request data from slave and wait for answer. look at MasterReader example from the Wire library
> 1 votes

# Answer
sorry for posting here after years but i need some help

This is my arduino code, the raspberry pi code is the same as above.

#include \<Wire.h\>

#define SLAVE\_ADDRESS 0x04

volatile boolean receiveFlag = false; char temp\[32\]; String command;

void setup() { // initialize i2c as slave Wire.begin(SLAVE\_ADDRESS);

// define callbacks for i2c communication Wire.onReceive(receiveEvent);

Serial.begin(1200); Serial.println("Ready!");

}

void loop() {

if (receiveFlag == true) { Serial.println(temp); if (temp == 'test'){ Serial.print("it works"); } receiveFlag = false; } }

void receiveEvent(int howMany) {

for (int i = 0; i \< howMany; i++) { temp\[i\] = Wire.read(); temp\[i + 1\] = '\0'; //add null after ea. char }

//RPi first byte is cmd byte so shift everything to the left 1 pos so temp contains our string for (int i = 0; i \< howMany; ++i) temp\[i\] = temp\[i + 1\];

receiveFlag = true; }

i want to make it do something like just turning on an led when the received data is test (for example).I do receive the text (test) in the serial monitor but it does nothing when i used this command

if (temp == 'test'){ Serial.print("it works"); }

any help will be appreciated
> 0 votes

---
Tags: arduino-uno, arduino-mega, c++, i2c
---


# Question
Title: Connecting Web Server in GoDaddy Hosting
I have a domain. It is hosted by GoDaddy. I need to connect that server and receive some data by executing PHP files.

I am not sure about the components.

Tutorials on internet describes how to control esp8266 from web server which is i do not want.

Also i found arduino uno wifi board/wifi shield but in arduino store, it says: this product is '**retired**'.

So do you recommend any component for this task or should i go with arduino uno wifi?

# Answer
> I have a domain.

Congratulations.

> It is hosted by GoDaddy.

You have my deepest sympathies.

> I need to connect that server and receive some data by executing PHP files.
>
> I am not sure about the components.
>
> Tutorials on internet describes how to control esp8266 from web server which is i do not want.

"Controlling" an ESP8266 from a web server is nothing more than making a request to a web server and responding to something the web server sends back.

If you don't want to respond to what is sent back you don't have to. You just have to make the request. That request can contain whatever you want in the way of data and sensor values.

> Also i found arduino uno wifi board/wifi shield but in arduino store, it says: this product is 'retired'.

Yes. It's been replaced with the Arduino WiFi Rev 2, which is a more modern AVR MCU coupled with an ESP32 based WiFi interface.

It's pretty wasteful really, since the WiFi interface is considerably more powerful than the AVR that it's connected to.

> So do you recommend any component for this task or should i go with arduino uno wifi?

I'd recommend an ESP32 based board. They're cheap, have direct connection to WiFi, very very powerful, plenty of inbuilt peripherals (unlike the ESP8266), and above all have great software support, examples and tutorials.
> 3 votes

---
Tags: esp8266, web-server, arduino-uno-wifi
---


# Question
Title: Connect 12 V DC sensor to Arduino Uno using TTL RS485
I'm trying to connect an Arduino Uno with a BGT PM2510 sensor (which uses 7-12 V DC) by using a UART TTL to RS485 Two-way Converter.

The only thing I wonder about is: can the sensor damage the MCU?

According to the information on the 12 V sensor, it says:

`Output signal: RS485 (Modbus protocol)`. I did measurements on the A & B ports of that sensor; the multimeter showed 3.3 V.

**My question is, can the sensor damage the MCU? I intend to connect the Arduino and sensor as in the diagram below**:

# Answer
You should be fine.

RS-485 does specify signal levels of ±1.5 V to ±5 V, but even so, and even when the sensor would misbehave or when the common mode voltage is low or high, there is still the TTL-to-RS485 converter in the middle that has 5 V TTL logic on the Arduino side.

As long as the TTL-to-RS485 converter is properly connected to the Arduino and working as it should, the Arduino is safe.
> 3 votes

---
Tags: arduino-uno, rs485, modbus
---


# Question
Title: Why does my 23,032 byte Arduino sketch take 36.32 sec to upload via ISP to an Atmega328p on a breadboard w/code verification disabled?
"Sketch uses 23032 bytes (71%) of program storage space. Maximum is 32256 bytes. Global variables use 1342 bytes (65%) of dynamic memory, leaving 706 bytes for local variables. Maximum is 2048 bytes."

I have "verify code after upload" disabled. With this enabled, it takes an additional 20 sec to upload for a total of 56 sec.

Using Sparkfun's avr programmer with USBtinyISP, win 10, arduino ide, minicore library. Code is utilizing several libraries from Mozzi. External 16mhz crystal. Have set fuse bits on the chip to use the external clock using the following command: "avrdude -c usbtiny-p m328p -U lfuse:w:0xFF:m"

Seems like it should be faster if truly uploading at 115200 bits / sec. But maybe I'm missing something in how this works.

Thanks !!

# Answer
ISP programmers typically default to low ISP clock rates. Often something like 10khz, sometimes slower, probably to just work by default with very slowly clocked AVR chips. The ISP clock rate must be about one eigth that of the AVR's clock. For example, by defaulting to a low rate like 10Khz, the programmer will successfully communicate with an AVR clocked at 125KHz with some margin. Around 4 KHz would work with a 32.768 KHz watch crystal.

Look in avrdude documentation for the -B option. Note uppercase 'B', this is the option for changing the ISP speed, not lowercase -b which is for the PC to programmer (or bootloader) baud rate. Not all programmers support -B, but many do.

## UPDATE

Well, I dug around the USBtinyISP code and in avrdude and it looks like the default value for -B is 10. So 10uS. The way this value is used in the USBtinyISP code is for high or low period, rather than total clock period. So it's about 20uS per bit, or 50kHz. If that's your rate, then the plain clocking of the SPI data only accounts for about 3.7 seconds. So that does cast doubt on this idea.

But, it still may be worth double checking that it is operating with the value 10 and not something larger. Just to put this in perspective: the maximum -B value is apparently 250, which would result in 2kHz ISP clock rate and about a minute and a half to clock out your roughly 23 KByte.

## More findings: Per byte SPI overhead

Each byte of the flash pages is being delivered into the ISP interface **by way of 4-byte long SPI commands**. The firmware for the programmer has the following code in it for writing a page in its spi/main.c file where you can see it calling `spi( cmd, res, 4 )` :

```
extern  void    usb_out ( byte_t* data, byte_t len )
{
    byte_t  i;
    uint_t  usec;
    byte_t  r;

    for ( i = 0; i < len; i++ )
    {
        cmd[3] = data[i];
        spi_rw();
        cmd[0] ^= 0x60; // turn write into read
        for ( usec = 0; usec < timeout; usec += 32 * sck_period )
        {   // when timeout > 0, poll until byte is written
          spi( cmd, res, 4 );
            r = res[3];
            if  ( r == cmd[3] && r != poll1 && r != poll2 )
            {
                break;
            }
        }
    }
}

```

This code is used to deliver data to the flash page buffer during ISP programming.

You can see a comment in avrdude's code explaining that each byte becomes a 4-byte SPI transaction as an aid to explaining their calculation for a communications timeout with the programmer. The following is in avrdude's usbtiny.c file for the `usbtiny_paged_write` function.

```
if (usb_out(pgm,
            function,       // Flash or EEPROM
            delay,          // How much to wait between each byte
            addr,           // Address in memory
            m->buf + addr,  // Pointer to data
            chunk,          // Number of bytes to write
            32 * PDATA(pgm)->sck_period + delay  // each byte gets turned into a
                                 // 4-byte SPI cmd  usb_out() multiplies
                                 // this per byte. Then add the cmd-delay
            ) < 0) {
  return -1;
}

```

To be clear, these two functions have the same name but are in fact two different functions; the former running in the programmer the later is running in avrdude.

So there is in fact substantial SPI transaction overhead in just delivering data into the page buffer. Beyond that there's a second USB and SPI transaction to commit the page buffer to flash.
> 2 votes

# Answer
I have a description of the uploading process which, if you extrapolate out from the 1082 bytes being uploaded in about 0.15 seconds (plus some overhead) should mean that you would get 23032 bytes uploaded in 23032 / 1082 * 0.15 seconds, namely about 3 seconds, including verification.

The fact that you are not achieving that would suggest (as Gil mentioned in their answer) that there is a problem with your PC actually sending data that fast down the USB port.

If you were to hook up a logic analyzer and watch what actually arrives, then you might find that there are bigger gaps between bytes (or batches of bytes) than you would expect.
> 1 votes

# Answer
It sounds like the bandwidth is limited. I have no idea how much delay the ISP is adding but it has to add some. The best would be via the USB at 115200 baud or faster if you can get it.
> 0 votes

---
Tags: atmega328, uploading, isp, speed, baud-rate
---


# Question
Title: How to use millis() in my code instead of delay()?
I'm having issues trying to convert my code to non-blocking. I was able to do so in some parts, but the rest aren't the same.

When I try to replace delay with an if statement like the spinning and sensors debounce it doesn't work at the right time, because the variable I subtract from cur\_ms is not updated.

What I'm trying to do is to always switch\_dir() and update\_code(), and when second\_btn.released() I want the other two functions to keep running but also to run a sequence of actions (those with the delay) without blocking.

I would love to get your help.

Thanks in advance :)

```
void loop()
{
    uint32_t cur_ms = millis();

    if (cur_ms - spin_ms >= SPINNING_MS) {
        switch_dir();
        spin_ms = cur_ms;
    }

    if (cur_ms - read_ms >= SENSORS_DEBOUNCE_MS) {
        update_code(get_sensors_state());
        read_ms = cur_ms;
    }

    if (second_btn.released()) {
        ball_servo.write(BALL_SERVO_MAX);   // drop the ball
        digitalWrite(BLOWER_PIN, LOW);  // blower on
        delay(BALL_DOOR_MS);
        ball_servo.write(BALL_SERVO_MIN);   // close ball door
        delay(BLOWER_MS);
        digitalWrite(BLOWER_PIN, HIGH); // blower off
    }
}

```

# Answer
You had the right idea with your first few if statements! Just keep checking if time has passed, don't `delay()`

```
uint32_t releasedTime = 0;
if (second_btn.released() && releasedTime == 0) {
    releasedTime = cur_ms; // remember that the button was pressed now
    ball_servo.write(BALL_SERVO_MAX);   // drop the ball
    digitalWrite(BLOWER_PIN, LOW);  // blower on
} else if ((cur_ms - releasedTime > BALL_DOOR_MS) && (cur_ms - releasedTime < BALL_DOOR_MS + BLOWER_MS)) {
    ball_servo.write(BALL_SERVO_MIN);   // close ball door
} else {
    // must be after BALL_DOOR_MS + BLOWER_MS, time to run
    digitalWrite(BLOWER_PIN, HIGH); // blower off
    releasedTime = 0; // so this doesn't keep running
}

```
> 1 votes

# Answer
When second\_btn.released is true, its two delay() statements will block the whole loop. You can avoid this by rewriting so that the delay() statements are handled like you already handle spin\_ms and cur\_ms, which will involve some state-machine-type logic so that (for example) you set a state when you enter the BALL\_DOOR\_MS delay, then return to the main loop which will have a branch that is taken only if the BALL\_DOOR\_MS state is active. When that state ends it sets a new state that enables a separate branch of the main loop to do the BALL\_SERVO\_MIN and start the BLOWER\_MS state, and so on. A switch/case chain may be the best way to handle this, replacing the present second\_btn.released.
> 0 votes

# Answer
\<To design in the millis() function, you have to think of it like using a stop watch. You record a time at which you started. Let's say you started at 10000mS. Then every so often, you check the current time. Let's say the current time is 10500mS. You then take the current time and subtract it by your start time to get the time elapsed since you started. This gives you 500mS. Let's say you're desired delay time is 1000mS. Since the elapsed time isn't 1000mS you keep doing other things until the Current time - Start time is greater than or equal to your delay time. Then you do what ever task you need to do, and then record a new start time and do the process all over again. It would look something like this.\>

```
#define DELAY_TIME     1000   // the amount of time you want to delay `

unsigned long startTime = 0;
unsigned long currentTime = 0;

void setup()
{
   startTime = millis();  // Record starting time
   currentTime = startTime; // Set current time to start time so elapsed time would = 0
}

void loop()

{

currentTime = millis(); // update the current time value

if((currentTime - startTime) >= DELAY_TIME)) // check amount of time elapsed
  {
    // The amount of delay time has elapsed
    // Do what ever you need to do here that requires the delay

       startTime = millis(); // Reset the start time so that it waits another 1000ms
       currentTime = startTime; // Set the current time = to start time to avoid negatives
    }
  // Then put the rest of the code that you want to run continuously here

}

```
> 0 votes

---
Tags: millis
---


# Question
Title: Connect 5V relay to ESP32 WROVER B board
I need to use a ESP32 WROVER B based MCU board with a standard (cheap) one-channel 5 V relay (e.g. to switch on a mains-power appliance).

Attempted removal of excess solder around the headers permanently disabled the 5 V power output line from the board (to power a relay or other modules), but other pins functional/board boots up correctly.

So at present, there is only a 3.3 V power source and 3.3 V GPIO pins (and others such as for external microphone and speaker).

I assume it is safe to connect a 3.3 V GPIO from the MCU to IN and external 5 V power source to VCC ad GND of the relay and connect the grounds of the MCU and relay together to complete the circuit.

The relay only needs to switch the appliance on when triggered (for example a lamp) and switch off when triggered again. I have a 3.3 ↔ 5 V bidirectional level shifter, but don't think it is suitable here (unless it can be incorporated directly). An alternative maybe is to use an Arduino Uno to connect with the relay, itself triggered by the ESP32 and more complex circuitry (bearing in mind the ESP32's GPIO is 3.3 V and the Arduino's is 5 V).

# Answer
> 1 votes
Assuming a relay *module*: check if it is OK to drive it with 3.3 V logic when it is on a 5 V power supply, or show the specs for us to look at.

Driving a relay module with 3.3 V logic is unlikely to harm the ESP32, but it may not drive the relay properly if the relay module expects 5 V logic.

Generally, I would even prefer using an external power supply rather than the 5 V pin on a microcontroller board to power a relay module.

As long as you connect everything as you describe, it should work just fine (if the relay module accepts 3.3 V logic).

# Answer
> 0 votes
These "digital relay" modules are available in 3.3V and 5V versions. Simply buy one of the 3V models. Here is one, for example: https://www.dfrobot.com/product-1572.html

---
Tags: arduino-uno, power, esp32, relay, voltage-level
---


# Question
Title: What’s the most common (and low cost) microprocessor with at least two threads?
I want to make a next version of my current project. I’m hoping to use an Arduino compatible processor that also supports at least 2 processes simultaneously without using pro threading or any other software workaround. The more commonly used the processor is, the better the user support will be if something goes wrong.

# Answer
> 5 votes
ESP32. Dual core 240MHz, plus an extra XLP state machine. Cheap and easily available on eBay/Amazon/Ali Express etc. And with full Arduino support.

# Answer
> 0 votes
You *may* also be interested in the Teensy 4.0. It *is* single-threaded (one CPU core), but it executes two instructions at a time if possible and runs at 600 MHz.

Beyond that, I only know of the ESP32 as well, for genuinely having two threads. Beware, if you want to design a product using that there might be extra hurdles with the FCC/whatever your country has since it is a radio emitter. Using an ESP32 module might simplify things, but I have very little idea how the legalities work.

It also seems a little wasteful to use a processor with Bluetooth and WiFi capabilities just because you need two threads, but it may be the only option.

---
Tags: threads
---


# Question
Title: Communicate from Arudino to computer over 3.5mm port
I'm wondering if it would be somehow possibly to have easy communication with a computer for Arduinos that don't have USB like the pro mini. That would make an easy way of having two-way communication with a computer. The computer could just play or record audio using software written specifically for this purpose. Would something like this require any special circuitry or would it just be a matter of connecting the right wires?

# Answer
> 0 votes
I didn't read the all page, but it seems it can be achieved, see David Awehr's blog (this one is conected to a android phone instead to a PC tho) and this Hackaday page where they seems to it, but the PC's audio input normally use 44,1kHz or 96kHz, so if you wanna go for the higher Serial speed (let's say just 115200bauds) you should think about it this.

---
Tags: softwareserial, communication, audio
---