body:
I am currently struggling with an intermittent problem with an Arduino project.

**Background**

I am using a LabVIEW program to control a few pieces of hardware. One of them is a NEMA 17 stepper motor that drives a rack and pinion actuator. I am using a genuine Arduino Nano with an (official) EasyDriver motor driver to drive the NEMA 17. The Arduino listens for the state of a DI pin, and if it is pulled high it moves out the rack until a U-shaped sensor sends a high input signal at the outermost position, it then listens for that DI pin to be pulled low and retracts the rack until a proximity sensor sends a high input signal.

**The Problem**

I noticed that my actuator was either becoming unresponsive to the input signals from the LabVIEW DAQ, or that it was getting stuck mid actuation (motor has plenty of torque for this application). After changing up the code to print updates to the serial port, I realized that after a few cycles the Arduino resets and re-enters the Setup() function.

I changed out the Nano and it made no difference. I am using a timeout feature for the first time and I was wondering if the memory usage of this feature could be causing problems - however I commented out this part of the code and the Arduino still reset. The code is below - would really love to hear any thoughts on whether this is likely to be a hardware or software issue. I am powering the Arduino with a 7V line from a Power Supply into the Vin port. The prox sensor operates at 24V but I divide the output signal's voltage so that the input voltage is ~4.8V (I have measured this). I am using the same U-shaped sensor with a few other Arduinos and I am not seeing this issue. I have powered Arduinos with the same 7V line in the past and have also never seen them reset like this.

Let me know what you think, thank you!

     const int uSensor = 12;
    const int proxSensor = 10;

    const int labViewHomePin = 9;
    const int labViewInputPin = 8;

    const int labViewOutFeedback = 7;
    const int labViewInFeedback = 6;

    const int StepperStepPin = 2;
    const int StepperDirectionPin = 3;
    const int ENPin = 13;

    enum {IdleState, ForwardState, BackwardState} State;            // this switch case is used to call the correct function that turns the motor in the desired direction

    boolean rampDone = false;
    boolean pusherIn = false;
    boolean pusherOut = false;
    boolean homingDone = false;

    boolean updateGiven = false;

    int motorSpeed = 300;
    int rampStartSpeed = 500;
    int rampStepCountNo = 800;

    boolean boolInitialMove = true;
    unsigned long timeInitialMove = 6000;
    unsigned long startTime;
    unsigned long endTime;

    void setup() {
      Serial.begin(9600);
      pinMode(uSensor, INPUT);
      pinMode(proxSensor, INPUT);
      pinMode(labViewHomePin, INPUT);                                  // initialising input pins
      pinMode(labViewInputPin, INPUT);                                  // initialising input pins

      pinMode(StepperDirectionPin, OUTPUT);                             //Direction
      pinMode(StepperStepPin, OUTPUT);                                  // Step
      pinMode(ENPin, OUTPUT);                                           // Enable

      Serial.println();
      Serial.println("Setup phase called");
      Serial.println();

      pinMode(labViewInFeedback, OUTPUT);
      pinMode(labViewOutFeedback, OUTPUT);

      State = IdleState;
      digitalWrite(ENPin,HIGH);                                         // Disable the drive by default

      homingDone = false;
    }

    void loop() {
      if ((digitalRead(labViewHomePin) == HIGH) && (homingDone == false)) {
        Serial.println("Homing Pin High Detected");
        homingRoutine();
        homingDone = true;
        Serial.print("Homing Done = ");
        Serial.println(homingDone);
        State = IdleState;

        if(digitalRead(proxSensor) == HIGH) {
          digitalWrite(labViewInFeedback,HIGH);
          digitalWrite(labViewOutFeedback,LOW);
        }
        else if(digitalRead(uSensor) == HIGH)  {
          digitalWrite(labViewInFeedback,LOW);
          digitalWrite(labViewOutFeedback,HIGH);
        }
        else {
          digitalWrite(labViewInFeedback,LOW);
          digitalWrite(labViewOutFeedback,LOW);
        }

      }

      switch (State) {
        case IdleState:
        boolInitialMove = true;
        digitalWrite(ENPin,HIGH);

          if(updateGiven == false) {
            Serial.println("I am in IdleState");
            Serial.print("Pusher Out Boolean = ");
            Serial.println(pusherOut);
            Serial.print("Pusher In Boolean = ");
            Serial.println(pusherIn);
            Serial.print("Prox Sensor status: ");
            Serial.println(digitalRead(proxSensor));
            Serial.print("U-Sensor status: ");
            Serial.println(digitalRead(uSensor));
            updateGiven = true;
          }

          if ((digitalRead(labViewInputPin) == HIGH) && (pusherOut == false) && (homingDone == true)) {
            digitalWrite(ENPin,LOW);                                    // Enable drive
            State = ForwardState;
            Serial.println("LabVIEW High detected. Case switched to ForwardState");
            Serial.println("");
            updateGiven = false;
          }
          else if ((digitalRead(labViewInputPin) == LOW) && (pusherIn == false) && (homingDone == true)) {
            digitalWrite(ENPin,LOW);                                    // Enable drive
            State = BackwardState;
            Serial.println("LabVIEW Low detected. Case switched to BackwardState");
            Serial.println("");
            updateGiven = false;
          }
          else {
            //do nothing
          }

          if(digitalRead(uSensor) == HIGH) {
            pusherOut = true;
            pusherIn = false;
          }
          else if(digitalRead(proxSensor) == HIGH) {
            pusherOut = false;
            pusherIn = true;
          }
          else {
            //do nothing
          }

          break;

        case ForwardState:

        if(updateGiven == false) {
            Serial.println("I am in ForwardState");
            Serial.print("LabVIEW Actuate Pin = ");
            Serial.println(digitalRead(labViewHomePin));
            updateGiven = true;
          }

        if(boolInitialMove == true) {
            digitalWrite(StepperDirectionPin, LOW);
            rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
            startTime = millis();
            endTime = startTime;
            boolInitialMove = false;
          }

          endTime = millis();
          rotateForward(motorSpeed);                                            // this calls the function ForwardState which starts pushing out the pusher

          if (digitalRead(uSensor) == HIGH) {
            digitalWrite(labViewInFeedback,LOW);
            digitalWrite(labViewOutFeedback,HIGH);
            Serial.println("U-Sensor High detected. Case switched to Idlestate");
            Serial.println("");
            updateGiven = false;

            pusherOut = true;
            pusherIn = false;
            State = IdleState;
          }
          else if((endTime-startTime) > timeInitialMove) {
            digitalWrite(ENPin,HIGH);
            digitalWrite(StepperStepPin, LOW);
            digitalWrite(StepperDirectionPin, LOW);
            digitalWrite(labViewOutFeedback,HIGH);
            digitalWrite(labViewInFeedback,HIGH);

            Serial.println("");
            Serial.println("**TIMEOUT DETECTED**");
            Serial.println("");

            State = IdleState;
          }
          break;

        case BackwardState:

        if(updateGiven == false) {
            Serial.println("I am in BackwardState");
            Serial.print("LabVIEW Actuate Pin = ");
            Serial.println(digitalRead(labViewHomePin));
            updateGiven = true;
          }

        if(boolInitialMove == true) {
            digitalWrite(StepperDirectionPin, HIGH);
            rampUpCosineWave(rampStartSpeed, rampStepCountNo, motorSpeed);
            startTime = millis();
            endTime = startTime;
            boolInitialMove = false;
          }

          endTime = millis();
          rotateBackward(motorSpeed);

          if (digitalRead(proxSensor) == HIGH) {
            digitalWrite(labViewInFeedback,HIGH);
            digitalWrite(labViewOutFeedback,LOW);                                // Disable drive
            Serial.println("Prox Sensor High detected. Case switched to Idlestate");
            Serial.println("");
            updateGiven = false;

            pusherOut = false;
            pusherIn = true;
            State = IdleState;
          }
          else if((endTime-startTime) > timeInitialMove) {
            digitalWrite(ENPin,HIGH);
            digitalWrite(StepperStepPin, LOW);
            digitalWrite(StepperDirectionPin, LOW);
            digitalWrite(labViewOutFeedback,HIGH);
            digitalWrite(labViewInFeedback,HIGH);

            Serial.println("");
            Serial.println("**TIMEOUT DETECTED**");
            Serial.println("");

            State = IdleState;
          }
          break;

      } // end switch
    }

    void rotateForward(int mtrSpeed) {
      digitalWrite(StepperDirectionPin, LOW);
      digitalWrite(StepperStepPin, HIGH);
      delayMicroseconds(mtrSpeed);
      digitalWrite(StepperStepPin, LOW);
    }

    void rotateBackward(int mtrSpeed) {
      digitalWrite(StepperDirectionPin, HIGH);
      digitalWrite(StepperStepPin, LOW);
      delayMicroseconds(mtrSpeed);
      digitalWrite(StepperStepPin, HIGH);
    }

    void homingRoutine() {
      digitalWrite(ENPin,LOW);
      Serial.println("Homing Routine called");
      bool firstCycle = false;
      bool secondCycle = false;
      bool thirdCycle = false;
      bool fourthCycle = false;

      while(digitalRead(uSensor) != HIGH) {
        rotateForward(rampStartSpeed);
      }
      delay(500);
      Serial.println("First home movement completed");
      while(digitalRead(proxSensor) != HIGH) {
        rotateBackward(rampStartSpeed);
      }
      delay(500);
      Serial.println("Second home movement completed");
      while(digitalRead(uSensor) != HIGH) {
        rotateForward(rampStartSpeed);
      }
      delay(500);
      Serial.println("Third home movement completed");
      while(digitalRead(proxSensor) != HIGH) {
        rotateBackward(rampStartSpeed);
      }

      delay(500);

      homingDone = true;
      pusherIn = true;
      pusherOut = false;

    }

      int rampUpCosineWave(int startSpeed, int rampUpSteps, int maximumSpeed) {
      int countedSteps = 0;
      float amp = ((startSpeed-maximumSpeed)/2);
      for(int currentSpeed = startSpeed; currentSpeed > maximumSpeed; currentSpeed = (int)((amp + maximumSpeed)+(amp*(cos((PI/rampUpSteps)*countedSteps))))) {
        digitalWrite(StepperStepPin, LOW);
        delayMicroseconds(currentSpeed);
        digitalWrite(StepperStepPin, HIGH);
        countedSteps++;
      }

      return countedSteps;
    }

title: Arduino Nano randomly resetting

Answers: 2

body: I expect you have a lot going on with your design.  Dividing down is never a good voltage (power) supply regardless of what you measure unless you are using a good scope to measure and it is well bypassed. Consider a Buck regulator from one of the China suppliers they are just a few bucks and will stabilize your circuit. If the prox sensor draws just a few mills consider powering it with the Arduino 5 volts. Motors like other inductive devices generate lots of transinents that are both conducted and radiated, something like that may be getting into your system possibly via the prox sensor. This should get you started.

body:
Thank you all for your contributions. I managed to find the issue and solve the intermittent reset. I was expecting to find a hardware problem as the root cause, but just in case it was software related I wanted to check as well. It turned out to be hardware

Gil is certainly questioning the correct piece of hardware. It was indeed the wiring of the Prox sensor. I had connected both the data and power common rails to facilitate the prox sensor but on inspection, I decided to keep these separate and voltage divide the prox sensor away from the rails and instead bring a direct 4.8V line into the Arduino. Whatever noise the stepper motor was creating was unable to impact the data lines of the Arduino, and I haven't seen the issue return since.

Really appreciate the help everyone. I didn't scope the power lines to the Arduino, as the issue continued regardless of me powering the arduino through only the COM port of a PC, a combo of both the COM port and 7V to the Vin line (presume the Arduino draws from the 7V line but I am unsure) and just the 7V line. Appears to have been noise disrupting the data common rail of the Arduino.


body:
     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?

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

Answers: 1

body:
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.


body:
[Trying to rescue a Yun with the 1.5.3 image.][1]

It's not possible to upload the required "Yun Serial Terminal" sketch  because the device hangs at U-Boot (hence the rescue attempt).

Using putty serial with:
Pin 0 (Rx)
Pin 1 (Tx)
Baud: 250000
8N1

This capture shows the result (which is the best I can find so far).
How do I properly connect to the serial console using the GPIO pins?

[![Putty Serial 250000 8N1][2]][2]

  [1]: https://www.arduino.cc/en/Tutorial/YunUBootReflash
  [2]: https://i.stack.imgur.com/AA4Gd.png

title: Is it possible to configure uboot without the "Yun Serial Terminal" sketch by using the hardware serial on pins 0 and 1 instead?

Answers: 0


body:
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[![enter image description here][1]][1]
This is the snapshot of the pin configuration[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/5HuaI.png
  [2]: https://i.stack.imgur.com/FmVpz.png

title: Connecting multiple ultrasonic sensors(hc-sr04) to a single arduino board.(mega)

Answers: 1

body:
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("");
    }


body:
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?

title: How many connections can Arduino I2C method create?

Answers: 2

body:
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.

body: 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.


body:
I want to switch on/off some AC device using [solid state Omron G3MB relay][1]
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.

[![Arduino module][2]][2]

  [1]: http://www.omron-russia.com/doc/relay/ssr/g3mb.pdf
  [2]: https://i.stack.imgur.com/ZOxbT.png

title: Can I control solid state relay directly from arduino digital pin?

Answers: 2

body: 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.

body:
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.


body:
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 :

[![enter image description here][1]][1]

ATMega :

[![enter image description here][2]][2]

Robot PCB :

[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/y1oT2.png
  [2]: https://i.stack.imgur.com/Zd2nK.png
  [3]: https://i.stack.imgur.com/E4wot.jpg

title: Is it possible my ATMega is burnt due to bad wiring?

Answers: 1

body: 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.


body:
I set up this circuit which uses L293D motor driver IC to control two DC motors.

[![LM298D motor driver][1]][1]

+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.

  [1]: https://i.stack.imgur.com/nATI3.png

title: L293D driver DC motors need help to start rotating

Answers: 3

body:
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.

body:
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.

body: 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.


body:
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() {

      }

title: Run method every hour

Answers: 1

body:
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][1]-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.

  [1]: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf


body:
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.

```c++
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() {}
```

title: Read Comma Separated String

Answers: 2

body:
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:

}
```

body:
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][1]). 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][2] 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`).

  [1]: https://arduino.stackexchange.com/questions/77081/arduino-split-comma-separated-serial-stream/77082#77082
  [2]: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/


body:
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);

        }

title: Why Are My High and Low Values Not Updating Correctly During Successive Loops

Answers: 3

body:
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.

body:
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.

body:
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:

```c++
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:

```c++
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](https://math.stackexchange.com/questions/432295).


body:
I'm trying to power on my NodeMCU ESP8266 Ver 0.1 (thats what is written in board), via VIN and Ground with my phone charger.

I'm 100% sure that the USB charger is working, providing 5V, and that the ground and VIN are connected to the right positions.

If I use the same phone charger via the NodeMCU USB, the program blinks the builtin led alright.

If I power via VIN, it flashes when I connect the charger to DC, but the program does not work.
It seems as the NodeMCU is not powering on complety.

Bizarrely, if I short 3V and G pins, the board starts working normally as powered directly via USB port.

This is the code

    /*
     ESP8266 Blink by Simon Peter
     Blink the blue LED on the ESP-01 module
     This example code is in the public domain

     The blue LED on the ESP-01 module is connected to GPIO1
     (which is also the TXD pin; so we cannot use Serial.print() at the same time)

     Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
    */

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
    }

    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
                                        // but actually the LED is on; this is because
                                        // it is acive low on the ESP-01)
      delay(1000);                      // Wait for a second
      digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
      delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
    }

[![This is the wiring][1]][1]

  [1]: https://i.stack.imgur.com/xZy0X.jpg

title: NodeMCU ESP8266 Ver 0.1 not powering on with VIN

Answers: 2

body:
Interesting problem. The input range for Vin is 5.5 to 10 volts. This link will give you more information: https://www.make-it.ca/nodemcu-arduino/nodemcu-details-specifications/
I would not venture to guess that your board is OK, since you short pins all kinds of nasties can happen. Also you do not state your reference point for your voltage measurements so I assume it is ground but the readings do not appear correct. How are you 100% sure that the USB charger is working, providing 5V, and that the ground and VIN are connected to the right positions. Did you measure it with the load connected? Can the charger output the voltage at the current you require?

body: I faced the same issue. My problem was on this version of board both ground (G) pins on the side of Vin pin (I say left side of the board when usb is towards bottom direction) do not have connection with the ground of the 3.3v regulator or to the Gnd pin on right side of the board !! No continuity from ground pin to regulator is the problem I understood. The moment I connected 5v between Vin and Right side 'G' pin it started working. Check and try if not resolved yet.


body:
    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;
    }

title: I get an error?

Answers: 1

body:
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.


body:
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("");
              client.println("");
              client.println("<TITLE>Parede Stranger Things</TITLE>");
              client.println("");
              client.println("");
              client.println("
Qual texto deseja enviar?
");
              client.println("<input type=text id=texto style=width:295px  maxlength=50>
");
              client.println("<input type=submit value='Enviar' style=width:150px;height:45px onClick=location.href='/?'+document.getElementById('texto').value+';'>");
              client.println("");
              client.println("");
              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":

[![enter image description here][1]][1]

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.

  [1]: https://i.stack.imgur.com/omqht.jpg

title: Sending letter by letter to LCD, however the LCD knows the full string?

Answers: 2

body:
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.

body:
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


body:
I'm trying to trigger eight different 5 V relays using an Arduino Atmega 2560. The relays (70Ω coil) are powered by an external 5 V source, and I'm trying to trigger them through a driving stage which contains for each relay an NPN transistor (2N3904) and a 1 kΩ resistor directly connected to digital pin of the Arduino.

The relays in my application are supposed to be driven 2 by 2, not all of them at once.

My problem is that I don't succeed in triggering the relay with digital pins of my Arduino; once I connect it to the resistor, the voltage of the digital pins drops from 5 V to 0.4 V or less. The transistor needs only 7 mA to be triggered, the output current of the Atmega2560 pins is 20 mA max.

I tried with an external 5 V source, it triggers correctly showing 10 mA maximum of current through the driving stage.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/7QGsM.jpg

title: Digital pin output voltage drops when driving a relay

Answers: 3

body: If the coil is 70 ohms and it's driven by 5V, it should draw about 5/70 = 71 mA.  That's pushing the 2n3904 a bit hard, and doesn't even account for inductive effects. (It's a small-signal transistor.)  Do you have an NPN power transistor to try, just as a test?  If its current gain (beta) is too low, use a Darlington configuration by combining it with your 2n3904.  (2n3904 base from digital out resistor, emitter drives power NPN base directly, both collectors are connected together to the bottom of the coil, and the power NPN emitter is the effective emitter of the just-created "super transistor" with high beta and power handling.)  Be sure to use an anti-kickback rectifier (1n4001)across the relay coil.

body: Good Job, you are right on, the transistor is rated at 200 mA which is adequate for the job. The flyback diode will protect your system and the transistor. the drain source drop would be maybe 0.01V on a bad day depending on the RDSon. You will probably need a little lower value base resistor depending on the gain of your transistor.  I would use something between 220 and 510 ohm. It should work fine. Using a darlington would hurt you instead of the ~.7 volts drop across the collector it would become about 1.4 volts, leaving the relay with 3.6V assuming you are actually getting 5V. My preference would be a small logic level avalanche rated MOSFET. Use a 50 Ohm resistor in the gate circuit and it will be just fine.   Use something like a 10K pull down resistor between the gate and source, that will guarantee that it will be off during reset.

body:
Your circuit will no longer work. The original transistor you used was a NPN, you have changed it to a PNP connected somehow as a low side driver.  It is important to show the emitter, as it tells us what type of transistor it is, leaving it out as you have done causes many of us to assume you have done it correctly ie the emitter is connected to the ground.  Here is a Copy of a circuit from electronics-tutorials that uses a simple MOSFET: https://www.electronics-tutorials.ws/blog/relay-switch-circuit.html Note the 10K resistor from the port pin to ground, that guarantees it will be off during reset and setup.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/MjHRW.png


body:
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
    }
}
```

title: How to use millis() in my code instead of delay()?

Answers: 3

body:
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.

body:
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
}
```

body:
<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

    }


body:
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.

title: Arduino Library to make http post request with bearer authentication

Answers: 1

body:
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`.


body:
I have been messing around with this module, unfortunately i bought a fake one, but got the original firmware running inside it (V550).

So far i can set the **HM-10** up as **client/master** and by using an peripheral emulator on Android, i set up a **peripheral** as my **server/slave**

The peripheral is able to write to its own characteristic and it sends a notification to the client HM10 that fetches this value and displays it correctly on my serial reader (cutecom and arduino serial monitor)

After this, i'd like to write to the peripheral's characteristic, but **i can't find any information about this**, but it should be in the realm of possibility, i think.

I am using the Arduino IDE to interface with the HM-10 module.

Any information pointing in the right direction is very, very welcomed. Its driving me crazy now...

title: How to use HM-10 as client, and send messages to specific services/characteristics?

Answers: 1

body:
You can upgrade the firmware to V709 available on the [manufacture's website][1] and find instructions on how to update it. You'll need a USB to TTL converter or something that can act as one.

With firmware V709 you can use AT+FINDSERVICES? and AT+FINDALLCHARS? command to get the list of services and characteristics on the server and then read, write, notify, etc, on the characteristic you are interested in. It is outlined in the [datasheet][2]. They call it self learn function and there's a document outlining how to use it.

  [1]: http://jnhuamao.cn/download_rom_en.asp?id=1
  [2]: http://jnhuamao.cn/bluetooth40_en.zip


body:
"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 !!

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?

Answers: 3

body: 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.

body:
I have [a description of the uploading process](https://arduino.stackexchange.com/questions/15936/what-happens-when-code-is-uploaded-using-the-bootloader) 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.

body:
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 )` :

```cpp
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.

```cpp
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.


body:
I found this project and it seemed simple but now I don’t know. Please help. I tried changing the code and the wires but nothing happened.

```c++
int photoSensorPin = A0;
int redLedPin = 3;
int greenLedPin = 5;
int blueLedPin = 6;
int redLedVal = 0;
int greenLedVal = 0;
int blueLedVal = 0;
boolean isLedOn = false;

int brightness = 1023;
int darkThreshold = 50;
int changeColorTime = 900000;

long lastUpdate=0;

void setup()
{
    randomSeed(analogRead(1));
}

void loop()
{
    getBrightness();
    if (brightness < darkThreshold) {
        if (!isLedOn) {
            LedOn();
            isLedOn = true;
            lastUpdate = millis();
        } else if (millis() > lastUpdate + changeColorTime) {
            LedOn();
            isLedOn = true;
            lastUpdate = millis();
        }
    } else {
        LedOff();
        isLedOn = false;
    }
    delay(1000);
}

int getBrightness()
{
    brightness = analogRead(photoSensorPin);
    return brightness;
}

void LedOn()
{
    redLedVal = random(1,128);
    greenLedVal = random(1,128);
    blueLedVal = random(1,128);

    analogWrite(redLedPin,redLedVal);
    analogWrite(greenLedPin,greenLedVal);
    analogWrite(blueLedPin,blueLedVal);
}

void LedOff(){
    analogWrite(redLedPin,0);
    analogWrite(greenLedPin,0);
    analogWrite(blueLedPin,0);
}
```

  [1](https://i.stack.imgur.com/JYiLk.png)
  [2](https://i.stack.imgur.com/O2Rqe.jpg)
  [3](https://i.stack.imgur.com/wLxSo.jpg)
  [4](https://i.stack.imgur.com/ajrxT.jpg)

title: How do I use a photoresistor?

Answers: 2

body:
How fast does this project need to be for it to be useful?  A [photo resistor][1] can take as much as a second to react to bright to dark conditions.

> Photoresistors also exhibit a certain degree of latency between
> exposure to light and the subsequent decrease in resistance, usually
> around 10 milliseconds. The lag time when going from lit to dark
> environments is even greater, often as long as one second. This
> property makes them unsuitable for sensing rapidly flashing lights

Consider testing the code by connecting A0 to 5 volts to simulate a bright condition.  Then connect A0 to ground to simulate a dark condition.

  [1]: https://en.wikipedia.org/wiki/Photoresistor

body:
You forgot to set set the pins to output mode. In `setup()`, add:

```c++
pinMode(redLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(blueLedPin, OUTPUT);
```

If that doesn't work, then you will need some debugging. Add also this
to `setup()`:

```c++
Serial.begin(9600);
```

and this to `loop()`:

```c++
Serial.println(brightness);
```

Look at the values printed. Do they vary significantly when the lighting
conditions change? If not, check the wiring of the LDR (it is fine in
your schematic). Do they go below and above `darkThreshold`? If not,
then change your threshold.


body:
I have asked this question on [the arduino forum][1] as well.

I have used SMTP before using client.print (and client.println) but I am now trying to move as much text as I can from RAM to SD (and so I need the <SD.h> library). It does not work and I am thinking it may be because the SMTP server "dies of boredom" as it waits for my Arduino to read from the SD card and write it to the client (server?).
In the code below, I have included what I am trying (it will be uncommented if you copy+paste the code) and what already works (which will be commented when you copy+paste the code, but you can uncomment and comment the other section relatively easily). The text file I have on the SD in the code (commented).
If anyone can think of a workaround, that would be great.

<!-- language: lang-cpp -->

    #include <SPI.h>
    #include <SD.h>
    #include <Ethernet.h>

    //-v--- Ethernet -----------
    byte MyMac[] = {0xFE, 0xED, 0xBE, 0xEF, 0xFE, 0xED}; // <- The physical address of the machine's network card. Should be unique (no two network cards have the same MAC address)
    byte MyIp[] = {1, 1, 1, 1}; // <- This is the not the real IP address, but for the real address I have verified that the static IP works for sending mail
    byte Dns[] = {1, 1, 1, 1}; // <- Not the real DNS but I got it once through Serial.println(Ethernet.dnsServerIP()); and I know that it works
    byte Gateway[] = {1, 1, 1, 1}; //<- Not real
    byte Subnet[] = {1, 1, 1, 1}; //<- Not Real

    EthernetClient client ;
    //-^--- Ethernet -----------

    //-v-- Smtp --------
    char ServerChar[] = "blahblah";
    //-^-- Smtp --------

    //-v--- SD ------
    File theFile; String line;
    //-^--- SD ------

    void setup() {
      Ethernet.begin(MyMac, MyIp, Dns, Gateway, Subnet);
      SD.begin(4);
      bool test = TrySend();
    }

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

    }

    bool TrySend(){

      //*-v---- What I am trying ---
      bool SuccessOrNot;

      if(client.connect(ServerChar, 25)){
        SuccessOrNot = true;
        theFile = SD.open("Smtp.txt");   //Smtp.txt is listed toward the bottom of the code

        if(theFile){
          while(theFile.available()){
            client.write( theFile.read() );
          }
          theFile.close();
        }
      }

      else{ SuccessOrNot = false; }
      return SuccessOrNot;
      //-^---- What I am trying --- */

      /*-v-- The following works if used in place of [What I am trying] ---
      bool SuccessOrNot;

      if(client.connect(ServerChar, 25)){
        SuccessOrNot = true;
        client.println("EHLO ktlan");
        client.println("AUTH LOGIN");
        //-v- Most SMTP servers require verification in the form of base64-encoded username and base64-encoded password. However, since your IP must be whitelisted by the SMTP server, you don't need authentication
        //client.println("ThisIsInBase64"); // Encoded version of 'sender@blah.blah'
        //client.println("ThisIsInBase64"); // Encoded version of the password
        //-^-
        client.println("MAIL FROM:<sender@blah.blah>");
        client.println("RCPT TO:<receiver@blah.blah>");
        client.println("DATA");
        client.println("to:receiver@blah.blah");
        client.println("from:sender@blah.blah");
        client.print("SUBJECT: TRIGGER");
        client.println();
        client.println("The temperature Monitor Triggered.");
        client.println(".");
        client.println("QUIT");
      }
      else{ SuccessOrNot = false; }

      //-^-- The following works if used in place of [What I am trying] ---*/
    }

    /*-v--- Smtp.txt -------
    EHLO ktlan
    AUTH LOGIN
    MAIL FROM:<sender@blah.blah>
    RCPT TO:<receiver@blah.blah>
    DATA
    to:receiver@blah.blah
    from:sender@blah.blah
    SUBJECT: TRIGGER

    The temperature Monitor Triggered.
    .
    QUIT

    //-^--- Smtp.txt -------*/

    // NO NEED for authentication. For many Smtp servers you need:
    //client.println("ThisIsInBase64"); // Encoded version of 'sender@blah.blah'
    //client.println("ThisIsInBase64"); // Encoded version of the password
    // My IP must be whitelisted by the SMTP server, and since it is, I don't need authentication

  [1]: https://forum.arduino.cc/?topic=715110#msg4804055

title: SD seems too slow for SMTP

Answers: 1

body:
Try a simpler approach (with some code refactoring)

```
bool TrySend(){

  if(client.connect(ServerChar, 25)){
    theFile = SD.open("Smtp.txt");

    if(theFile){
      while(theFile.available()){
        client.print(theFile.readStringUntil('\n'));
        client.print('\n');
      }
      theFile.close();
      return true;
    }
  }
  return false;
}
```

> As a side note, you might want to consider some better code structure (e.g. local variables). But I assume this is just a sample/test. Also, the code above assumes the file uses `\r\n` at the end of each line. If it only has `\n`, then you can simply use: `client.println(theFile.readStringUntil('\n'));` (notice the `print*ln*`).
`println` sends both `\r\n`.


body:
I'm trying to connect an Arduino Uno with a [BGT PM2510 sensor](https://www.alibaba.com/product-detail/BGT-PM2510-Industrial-Dust-Particle-PM2_62480865889.html) (which uses 7-12 V DC) by using a [UART TTL to RS485 Two-way Converter](https://www.elecrow.com/uart-ttl-to-rs485-twoway-converter-p-1545.html).

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**:

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/Zw06h.png

title: Connect 12 V DC sensor to Arduino Uno using TTL RS485

Answers: 1

body:
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.