title: How to calibrate a PID?

text:
# Question
Title: How to calibrate a PID?
I'm working on a pid-controlled levitating magnet device. It uses a hall-sensor to turn on and off an electro magnet in ordet to achieve levitation.

When I hold a magnet close to the hallsensor, I can sense a pulsation from the electro-magnet, however, I if let go of the magnet, it always sticks to the electro-magnet every time, as though the pid is not properly calibrated, the code i'm using came with a pre built possibility to calibrate the PID, you can change set point, Proportion, integral and derivative I've tried messing with it, but it doesn't seem to make any difference.

```
/*
   Magentic Levitation

   1) connect the digital pin PIN_COIL to the MOSFET gate for electromagnet activation.
   2) connect the analog input pin PIN_HALL_SENSOR to the hall sensor signal pin (the other
      two pins shall be wired to gnd and +5V).
   3) (optional) connect the digital pin PIN_CTRL_INDICATOR to the LED that indicates when the
      controller loop is running.
   4) run Arduino, on the serial port the following commands are available:
      - press 's' or 'S' to decrease or increase the setpoint,
      - press 'p' or 'P' to decrease or increase the P gain,
      - press 'd' or 'D' to decrease or increase the D gain,
      - press 'i' or 'I' to decrease or increase the I gain,
      - press 'x' or 'X' to show the current settings
   5) the system enters in IDLE mode, with a minimum PWM command that allows the orientation of the
      permanent magnet, when in range the system goes in CONTROL mode. When the magnet is too close to
      the coil, the system switches in OFF mode by turning off the PWM command.

   version 1.0: 23/12/2011 -  E.Assenza
*/

const int PIN_COIL = 11; // Pins 3 and 11 are connected to Timer 2.
const int PIN_HALL_SENSOR = 0;
const int PIN_CTRL_INDICATOR = 13;
// Coil resistance 3 ohm, max 1 A = 3 Volt max.
const int COIL_MAX_PWM_VALUE = 160;
// Minimum magnetic field when in idle mode (needed to properly orientate the magnet).
const int COIL_IDLE_VALUE = 50;
// Proximity thresholds, when the magnetic field is in this range enters in control mode.
const int MAG_PROX_THRESHOLD_MIN = 585;
const int MAG_PROX_THRESHOLD_MAX = 615;
// Magnetic field limits, when outside this range enters in idle mode.
const int MAG_LIMIT_MIN = 560;
const int MAG_LIMIT_MAX = 700;
// Control loop frequency.
const int CTRL_LOOP_PERIOD_MS = 1;
// Control loop bias value (PWM midpoint)
const int CONTROL_BIAS = 65;
// Set point corresponding to the control bias
const int CONTROL_SETPOINT = 597;
const int MAX_ERR_INTEGRAL = 10000;
// PID controller parameters
const float PGain = 2.1;
const float DGain = 23.6;
const float IGain = 0.001;

const float P_INCR = 0.1;
const float D_INCR = 0.1;
const float I_INCR = 0.001;

// State machine constants.
const byte MODE_OFF = 0;
const byte MODE_IDLE = 1;
const byte MODE_CONTROL = 2;

const char     *gAppName = "Arduino Magnetic Levitation";
byte            gMode;
int             gSetPoint;
int             gSensorReadout;
int             gPrevSensorReadout;
int             gPwmCommand;
int             gIntegral;
float           gBias;
float           gP;
float           gD;
float           gI;
unsigned long   gMillisCounter;

void setupCoilPWM()
{
   // Setup the timer 2 as Phase Correct PWM, 3921 Hz.
   pinMode(3, OUTPUT);
   pinMode(11, OUTPUT);
   // Timer 2 register: WGM20 sets PWM phase correct mode, COM2x1 sets the PWM out to channels A and B.
   TCCR2A = 0;
   TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);
   // Set the prescaler to 8, the PWM freq is 16MHz/255/2/<prescaler>
   TCCR2B = 0;
   TCCR2B = _BV(CS21);
}

void writeCoilPWM(uint8_t pin, int val)
{
   if( pin == 3 )
   {
      OCR2B = val;
   }
   else if( pin == 11 )
   {
      OCR2A = val;
   }
   else
   {
      OCR2A = 0;
      OCR2B = 0;
   }
}

void processCommand( int cmd )
{
   char tmp[64];

   switch(cmd)
   {
      case 'p':
         gP -= P_INCR;
         if( gP < 0 ) gP = 0;
         break;
      case 'P':
         gP += P_INCR;
         break;
      case 'd':
         gD -= D_INCR;
         if( gD < 0 ) gD = 0;
         break;
      case 'D':
         gD += D_INCR;
         break;
      case 'i':
         gI -= I_INCR;
         if( gI < 0 ) gI = 0;
         break;
      case 'I':
         gI += I_INCR;
         break;
      case 's':
         gSetPoint --;
         break;
      case 'S':
         gSetPoint ++;
         break;
      case 'x':
      case 'X':
         sprintf(tmp, "s(%d) c(%d) h(%d) P(%u) D(%u) I(%u,%d)\n", gSetPoint, gPwmCommand, gSensorReadout, (uint16_t)(gP*1000.0), (uint16_t)(gD*1000.0), (uint16_t)(gI*1000.0), gIntegral );
         Serial.print(tmp);
         break;
      default:
         break;
   }
}

byte executeOffMode()
{
   digitalWrite(PIN_CTRL_INDICATOR, LOW);

   // turn off magnetic field
   gPwmCommand = 0;
   writeCoilPWM(PIN_COIL, gPwmCommand);

   gSensorReadout = analogRead(PIN_HALL_SENSOR);

   if( gSensorReadout <= MAG_LIMIT_MIN )
   {
      // Switch to idle mode.
      return MODE_IDLE;
   }
   else
   {
      return MODE_OFF;
   }
}

byte executeIdleMode()
{
   digitalWrite(PIN_CTRL_INDICATOR, LOW);

   // Apply minimum magnetic field.
   gPwmCommand = COIL_IDLE_VALUE;
   writeCoilPWM(PIN_COIL, gPwmCommand);

   gSensorReadout = analogRead(PIN_HALL_SENSOR);

   if( (gSensorReadout >= MAG_PROX_THRESHOLD_MIN) && (gSensorReadout <= MAG_PROX_THRESHOLD_MAX) )
   {
      // Switch to control mode.
      gIntegral = 0;
      return MODE_CONTROL;
   }
   else if( gSensorReadout > MAG_LIMIT_MAX )
   {
      return MODE_OFF;
   }
   else
   {
      return MODE_IDLE;
   }
}

byte checkOutOfLimits(int val)
{
   if( val <= MAG_LIMIT_MIN )
   {
      return MODE_IDLE;
   }
   else if( val >= MAG_LIMIT_MAX )
   {
      return MODE_OFF;
   }

   return MODE_CONTROL;
}

byte executeControlMode()
{
   int err;
   int der;

   byte mode = MODE_CONTROL;

   // Execute control loop at frequency = 1/CTRL_LOOP_PERIOD_MS.
   if( (signed long)( millis() - gMillisCounter ) >= 0)
   {
      gMillisCounter = millis() + CTRL_LOOP_PERIOD_MS;

      digitalWrite(PIN_CTRL_INDICATOR, HIGH);

      gPrevSensorReadout = gSensorReadout;

      // Read hall sensor.
      gSensorReadout = analogRead(PIN_HALL_SENSOR);

      // Check if out of limits (the magnet is out of coil range).
      if( (mode = checkOutOfLimits(gSensorReadout)) != MODE_CONTROL )
      {
         return mode;
      }

      err = (gSetPoint - gSensorReadout);
      der = (gPrevSensorReadout - gSensorReadout);
      gIntegral += err;
      gIntegral = constrain( gIntegral, -MAX_ERR_INTEGRAL, MAX_ERR_INTEGRAL);

      gPwmCommand = gBias + (int)(gP*err) + (int)(gD*der) + (int)(gI*gIntegral);

      gPwmCommand = constrain( gPwmCommand, 0, COIL_MAX_PWM_VALUE);

      // Apply output.
      writeCoilPWM(PIN_COIL, gPwmCommand);

      // Write data to serial port.
/*      Serial.write( (uint8_t)0xAF );
      Serial.write( (uint8_t)gSetPoint );
      Serial.write( (uint8_t)(gSetPoint >> 8) );
      Serial.write( (uint8_t)gSensorReadout );
      Serial.write( (uint8_t)(gSensorReadout >> 8) );
      Serial.write( gPwmCommand );
   }

   return mode;
}

void setup()
{
   setupCoilPWM();

   pinMode(PIN_CTRL_INDICATOR, OUTPUT);

   Serial.begin(115200);

   gMillisCounter = 0;
   gMode = MODE_IDLE;
   gSetPoint = CONTROL_SETPOINT;
   gBias = CONTROL_BIAS;
   gSensorReadout = 0;
   gIntegral = 0;
   gP = PGain;
   gD = DGain;
   gI = IGain;
}

void loop()
{
   // User commands.
   if( Serial.available() )
   {
      processCommand( Serial.read() );
   }

   // State machine.
   switch( gMode )
   {
      case MODE_OFF:
         gMode = executeOffMode();
         break;

      case MODE_IDLE:
         gMode = executeIdleMode();
         break;

      case MODE_CONTROL:
         gMode = executeControlMode();
         break;

      default:
         break;
   }
}

```

# Answer
Gidday! First response as a new member. PID control is not an easy subject to grasp for starters but here is a link to a site that does explain it: http://www.csimn.com/CSI\_pages/PIDforDummies.html

The first thing about your project is that your output is digital (HIGH/LOW) whereas traditionally PID control is analog. AnalogIN to PID to AnalogOUT. So ideally you would need to vary the current through an electromagnet and have the hall-effect make very quick updates (feedback) to the PID controller. Now most young engineers (armed with some maths) learn to control the level of a tank (water or chemical or whatever) and yes, they follow a calibration method. The P is done first and this is the GAIN of the system the Integral usually follows & this is like a 'speed of response' type of adjustment. (Derivative rarely used).

I'm guessing your levitation system would require and extremely fast response & I think it would suffer from:

1. The time of the Analog to digital conversion at the input to the PID
2. The speed of the Arduino to process the code it runs
3. The time it takes for the OUTPUT to be applied to the electromagnet (e.g. the PWM updates inside the Arduino if you decided to use this as a pseudo 'analog output').

I know this is not good news for you but don't give up as someone will have found a work-around to this problem I'm sure. It just seems like a bit more research is required. Maybe some other members can assist further.
> 3 votes

# Answer
Well, the response time should not be a major issue, since the ball movement is based solely on the acceleration due to gravity and the magnetic force due to the coil. If you let the ball free fall from being stopped, it would take 14.3 ms for it to move the first 1 mm, and that is a lot of time for computing and for electrical circuits to respond.

To calibrate the PID, a process usually called PID tuning, you would start with the proportional constant, Kp. Since your system is unstable, that is, without the PID either the ball will fall or stick to the electromagnet, it will be hard to tune the Kp, even with minor errors on your hall sensor readings. If the position error is large or the sensor takes too much time to update, that can also complicate the tuning.

You should check the furthest away the ball can be and still be drawn to the magnet, that point is the limit where your PID can save the ball from falling. As a rule of thumb, try tuning the Kp with the setpoint being in between the magnet and that point. At first you want just the Kp being non-zero, and it should have a value great enough so that, if the ball falls a little bit bellow the setpoint the magnet is fully powered and if it goes a bit over the setpoint the magnet turns off. This should lead to the ball oscillating around the setpoint. This method will work on your system because the output is limited between a PWM with duty 100% and 0% (you can change these limiting values if needed!), (I suppose) turning the coil to its maximum and minimum doesn't damage the system and the system is relatively slow (the gravity effect is always the same and the acceleration due to the magnet depends on the mass of the ball).

After you got it to work so-so, try lowering the Kp to the minimum value that keeps the ball oscillating around the setpoint and then read on Ziegler–Nichols tuning method.

> When I hold a magnet close to the hallsensor, I can sense a pulsation from the electro-magnet, however, I if let go of the magnet, it always sticks to the electro-magnet every time, as though the pid is not properly calibrated,

That behavior is odd, even a bad PID should eventually turn off the magnet after detecting the ball went above the setpoint. Maybe the sensor reading is causing the problem, e.g. the ball goes close to the magnet but the sensor/code interpret it as going away from the magnet.
> 0 votes

---
Tags: programming, pid
---


title: Changing I2C address of MPU-6050

text:
# Question
Title: Changing I2C address of MPU-6050
Is it possible to change I2C address of MPU-6050 ?

I am trying to connect a bunch of MPU-6050 to my Arduino.

Almost all of them are running on the same address. Few are running on different address.

Can anyone tell me how to change I2C address of MPU-6050 if it is possible ?

# Answer
> 4 votes
The MPU-6050 has an address pin, marked as A0, which can be used to set the LSB (least significant bit) of the address. So if you connect A0 to ground, the address will be `0b1101000`, if you connect it to Vcc it will be `0b1101001`. You can find this information in the table under capter 6.4 in the MPU-6050 datasheet (page 15). Normally this pin is getting hardwired, but you can also connect A0 to a digital output pin of your Arduino and dynamically change the address of the MPU.

So with this pin you can have 2 different MPU-6050's on the bus. If you need more, you can keep all MPU's on one address, while pulling the MPU, that you want communicate with, to the other address. I described this principle at the end of my answer to this question. It is about a different chip, but the principle is the same.

It is important, that you cannot have multiple devices with the same address on one I2C bus, unless you never communicate with that address. When you try to use an address, where multiple devices will answer, the I2C bus most likely will get stuck, or the data will get corrupted. As long as such an address is never called, everything is fine.

---
Tags: arduino-uno, i2c, mpu6050
---


title: Why Buzzer interfere with PWM?

text:
# Question
Title: Why Buzzer interfere with PWM?
This is the code:

```
#define TMST A2 // Thermistor
#define BZR 10  // Buzzer
#define FanP 11 // Fan

void setup() {
  DDRD = B11000000;
  DDRB = B00001111;
  DDRC = B00000000;
  TCCR2B = TCCR2B & B11111000 | B00000101; // pin 3 & 11 -> 245Hz
  T0 = 25 + 273.15;
}

void loop() {
  if (hallState > magnetDistance) {
    PORTB &= ~(1 << 0); // port manipulation -> LOW
    strcpy(WPStatus, "OFF");
    if (Alarm == 1) { // this will be set in setting menu
      if ((millis() - BZRT) > 500) {
        tone(BZR, 2300);
        BZRT = millis();
      }
      if ((millis() - BZRT) > 250) {
        noTone(BZR);
      }
    }
    else {
      noTone(BZR);
    }
  }
  else {
    PORTB |= (1 << 0); // port manipulation -> HIGH
    noTone(BZR);
    strcpy(WPStatus, " ON");
  }

  if ((millis() - fanTimer) > 2000) { // checks every 2 seconds if temperature changed
    Thermistor();
    if (TX <= 32) {
      analogWrite(FanP, 60); // Fan spinning speed
    }
    if (TX > 32 && TX <= 36) {
      analogWrite(FanP, 120);
    }
    if (TX > 36) {
      analogWrite(FanP, 255);
    }
    fanTimer = millis();
  }
}
float Thermistor() { // reading and calculating from thermistor
  VRT = analogRead(TMST);
  VRT = (5.00 / 1023.00) * VRT;
  VR = 5 - VRT;
  RT = VRT / (VR / 10000);
  ln = log(RT / 10000);
  TX = (1 / ((ln / 3977) + (1 / T0)));
  TX = TX - 273.15;
  return TX; // returning the temperature
}

```

The 5V buzzer connected to a PWM pin with a 100 ohm resistor, thermistor and fan are connected to Arduino like this:

simulate this circuit – Schematic created using CircuitLab

Why When buzzer is alarming fan stops spinning?

# Answer
> 2 votes
The `tone()` command uses Timer2 to generate the square wave (it triggers an interrupt which toggles an IO pin).

However Timer2 is also used to generate the PWM signal on pins 3 and 11.

Thus you cannot use `tone()` and PWM on pins 3 or 11 simultaneously.

The simple fix: use PWM from pins 5, 6, 9 or 10 to control your fan.

---
Tags: pwm, buzzer
---


title: GY91 IMU module, Interrupt?

text:
# Question
Title: GY91 IMU module, Interrupt?
Are there interrupt Pin in the GY91 Module?
If not, are there good alternative for periodic sensor reading?
(apart from mcu schedule/external timer)

# Answer
> 1 votes
No. The INT pin of the MPU-9250 is not presented on the IO header of the GY-91.

The *only* way of knowing what is going on inside the MPU-9250 at any time is to go and look. I.e., periodic polling of the sensor.

If you want to use the interrupt pin you will have to shop around for a different module that gives you access to that pin.

---
Tags: interrupt, imu
---


# Question
Title: A recommendation for a fast-response-time-resolution-mp3-module for arduino
I am working with Arduino which activates a box which is similar to a Skinner Box. Some of the output sound stimuli are sine waves with duration of less then 5 milliseconds. I output the sounds using the MP3 module DFR0299.

However there are too much problems using this module: it seems like the module has a wakening delay of around 100 ms, so it is not working well with this duration and below (the response time of the module is important).

So, I was thinking of buying a better module. However, I am far from being an expert in these things..

I can look for other modules in the internet, but, just from looking at the datasheets, I cant tell if the quality of the module is what I need.

I would be grateful if any of you could give me names of modules that might feet my requirements (or even advice me at what to look in the datasheets)

Thanks!

# Answer
I'm going to suggest that you stay away from these mp3 modules. It is perfectly reasonable to use a stand-alone arduino unit to directly generate sound using the digital output pins with a low-pass filter RC circuit. This is the most efficient way of doing this and will give you a very low activation latency.

https://playground.arduino.cc/Code/PwmFrequency/

The other option is to connect a DAC circuit and simply build a sample table for the wave outputs you need for each tone.
> 1 votes

# Answer
MP3 modules are way to complex for this project. Tracks of 5ms at max may even be stored directly on the Arduino in raw wave format (without any compression)(depending on the resolution and sample frequency), and then outputted by it.

Since the PWM with low-pass filter method is rather noisy and not very accurate (especially for higher frequencies), you may want to use an external DAC chip. These are available with parallel input port or with SPI. I would suggest using SPI, which is fast and does only need 3 pins (+1 for slave select, if needed). Put the raw wave values into an array and send them to the DAC to output. Depending on available memory and number and size of your tracks you may be able to save them directly on the Arduino. If not, you may want to use an SD card, to save a library of tracks, which then get loaded onto the Arduino and played. This way you would only need to hold 1 or 2 (if double buffered) tracks in the Arduino's RAM.
> 1 votes

---
Tags: sound
---


# Question
Title: Serial Port fails with speeds greater than 19200
In Arduino Mega 2560 R3, properly selecting the Serial Monitor bauds, this code works with `#define R 38400`, but for some reason, not with `#define R 19200` (?),

```
#define R 38400
int rate=R;
HardwareSerial* hwSerial[]={&Serial,&Serial1,&Serial2,&Serial3};
void setup() {
    for (int i=0;i<=3;i++){
        hwSerial[i]->begin(rate);
        while (!hwSerial[i]);
    }
    hwSerial[0]->print("Hello World");
}

void loop() {
}

```

Both speeds should be not problematic for Arduino, what is happening?

It seems the `int rate R;` is problematic when changing speeds (??).

# Answer
> 2 votes
Answer is simple. You assign 38400 to a variable of type int. The signed range of integer values that can be stored in 16 bits is −32,768 through 32,767;

---
Tags: serial, array, atmega2560, speed
---


title: Why does the transistor burn out

text:
# Question
Title: Why does the transistor burn out
I have an arduino uno which turns on a water pump (12V, 3.6W) once every 10 hours for a few minutes (I've followed this tutorial on how to connect the water pump). To turn on the water pump I used a **PN2222A transistor**, and connected the **base** in serial with a **220 ohm** resistor to the **digital pin 9**. A few minutes after turning on the power on my Arduino UNO the **PN2222A** transistor burned out (lots of smoke coming out of it).

I also used a **1N4007** diode, cathode connected to the positive pin, and anode to the negative pin of the water pump.

The power supply outputs around 12.6V

Maybe the resistor is too low/weak?

I've created a schematic here, attached it's a snapshot of it.

**EDIT1:** Here is a picture on how I connected my transistor. I've removed from the photo:

* the input wires (should be top-right of breadboard)
* wire to arduino digital pin (should be on h-19 on the breadboard)
* water pump from the breadboard (positive pin: c-2, negative pin: h-2)

**EDIT2 (a solution that worked for me):**

It looks like the input to the arduino (arduino and the pump share the same 12V input, but the arduino's goes through a step down converter to 10V) was a bit loose (to be more specific, the negative pin was loose) and randomly, the arduino would shut down and then the pump would start (maybe because the digital pin becomes HIGH, dont know why though) all while the arduino is shut off. That's when the transistor (PN2222A) burned out. I switched to TIP120 with a 1k resistor as @Jot suggested and looks like when the same problem with the power happens, nothing is burning out :)

# Answer
> 1 votes
It looks like the input to the arduino (arduino and the pump share the same 12V input, but the arduino's goes through a step down converter to 10V) was a bit loose (to be more specific, the negative pin was loose) and randomly, the arduino would shut down and then the pump would start (maybe because the digital pin becomes HIGH, dont know why though) all while the arduino is shut off.

That's when the transistor (PN2222A) burned out. I switched to TIP120 with a 1k resistor as @Jot suggested in one of the comments and looks like everything is ifne now (even when the same problem/bug with the power randomly happens)

# Answer
> 3 votes
TinkerCAD may have mislead you on the pinout for the transistor

**TinkerCAD**

**PN2222A**

# Answer
> 3 votes
By this, does it mean that you still have a problem turning the pump on? Because a PN2222A should handle up to 1A through its collector, as the datasheet states http://www.mouser.com/ds/2/149/PN2222A-371983.pdf

> That's when the transistor (PN2222A) burned out. I switched to TIP120 with a 1k resistor as @Jot suggested and looks like when the same problem with the power happens, nothing is burning out :)

If you are still having problem turning the pump on, try turning it on manually by moving the jumper that is on the Arduino pin 9 to either GND or 5V, that should indicate if the problem lies on the Arduino pin (GPIO) or on the transistor.

It is also important to check the current needed by the pump, because the datasheet indicates that, to have a current IC = 350 mA -\> IB = 35 mA which is close to the maximum of an Arduino pin (40 mA). If the Arduino pin cannot supply enough current to put the transistor in saturation mode, it will either kill the pin or put the transistor in its linear region, meaning it will dissipate a lot of power (Ic\*Vce).

> Base-Emitter Saturation Voltage
>
> IC = 150 mA, IB = 15 mA
>
> IC = 500 mA, IB = 50 mA

# Answer
> 2 votes
Seems to be a simple pinout issue, I checked the PN2222A and its pins are in EBC order. You probabily reversed it and burned the transistor. Reverse the transistor and the problem will be solved.

simulate this circuit – Schematic created using CircuitLab

# Answer
> 0 votes
Datasheet for the PN2222A indicates it is only good for 150mA Ic for a pulse test, pulse width \<= 300 microseconds, 2% duty cycle.

Your water pump, 12V, 3.6W. With P=IV, or P/V = I, then 3.6W/12V = 0.3A, indicates this transistor is not the correct choice for this application.

---
Tags: arduino-uno, transistor, resistor
---


# Question
Title: Maximum sampling rate of Arduino Mega2560
I'd like to know what is the maximum sampling rate achievable while using ADC on Arduino Mega2560.

Thanks

# Answer
The beginning of section 26 of the datasheet for the ATMega2560 gives the following data:

> • 13µs - 260µs Conversion Time • Up to 76.9kSPS (Up to 15kSPS at Maximum Resolution)
> 1 votes

---
Tags: atmega2560
---


title: Arduino Nano - Strange problems

text:
# Question
Title: Arduino Nano - Strange problems
# Update:

**The arduino works only when I connect 3.3v to reset pin. And I successfully uploaded a sketch but it stops when I disconnect 3.3v and reset.**

# Update 2:

**-- Removed --**

# Update 3:

**Its working perfectly and running smoothly for like 5+ min but the problem starts again**

---

I bought a new arduino nano V3 clone. Till now, I have been facing very strange problems with it:

* The pre-uploaded blinking sketch works for a few seconds (like 5 sec and only works when powered after a break) and then it starts to glitch
* The L led stays on or off after that
* Reset button does nothing (No led blinks or anything)
* Can't upload any sketch
* Programmer is not responding
* RX led blinks during uploading (3 times only)
* USB not recognized when connected

Here is what I tried to solve:

* Loopback test \> Successful
* Changed ports
* Changed proccessor
* Tried uploading with parallel programming
* Sketch worked with another arduino nano clone
* Manual reset
* Tried with Old bootloader
* Tried uploading sketch with older version of Arduino IDE.

Here is the exact image of one I have:

Here is the error message:

```
Arduino: 1.8.10 Hourly Build 2019/07/23 10:33 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\arduino-builder -dump-prefs -logger=machine -hardware C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware -tools C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\tools-builder -tools C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -built-in-libraries C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\libraries -libraries C:\Users\MN\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328old -vid-pid=1A86_7523 -ide-version=10810 -build-path C:\Users\MN\AppData\Local\Temp\arduino_build_778230 -warnings=none -build-cache C:\Users\MN\AppData\Local\Temp\arduino_cache_273206 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -verbose C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\examples\01.Basics\Blink\Blink.ino
C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\arduino-builder -compile -logger=machine -hardware C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware -tools C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\tools-builder -tools C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -built-in-libraries C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\libraries -libraries C:\Users\MN\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328old -vid-pid=1A86_7523 -ide-version=10810 -build-path C:\Users\MN\AppData\Local\Temp\arduino_build_778230 -warnings=none -build-cache C:\Users\MN\AppData\Local\Temp\arduino_cache_273206 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr -verbose C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\examples\01.Basics\Blink\Blink.ino
Using board 'nano' from platform in folder: C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\arduino\avr
Detecting libraries used...
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\sketch\\Blink.ino.cpp" -o nul
Generating function prototypes...
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\sketch\\Blink.ino.cpp" -o "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10810 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\sketch\\Blink.ino.cpp" -o "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\sketch\\Blink.ino.cpp.o"
Compiling libraries...
Compiling core...
Using precompiled core: C:\Users\MN\AppData\Local\Temp\arduino_cache_273206\core\core_arduino_avr_nano_cpu_atmega328old_96bc3f74325b2724b539066aa6a6e44d.a
Linking everything together...
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/Blink.ino.elf" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230\\sketch\\Blink.ino.cpp.o" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/..\\arduino_cache_273206\\core\\core_arduino_avr_nano_cpu_atmega328old_96bc3f74325b2724b539066aa6a6e44d.a" "-LC:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230" -lm
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/Blink.ino.elf" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/Blink.ino.eep"
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/Blink.ino.elf" "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/Blink.ino.hex"
"C:\\Users\\MN\\Downloads\\Compressed\\arduino-nightly-windows\\arduino-nightly\\hardware\\tools\\avr/bin/avr-size" -A "C:\\Users\\MN\\AppData\\Local\\Temp\\arduino_build_778230/Blink.ino.elf"
Sketch uses 924 bytes (3%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr/bin/avrdude -CC:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:C:\Users\MN\AppData\Local\Temp\arduino_build_778230/Blink.ino.hex:i
An error occurred while uploading the sketch

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\MN\Downloads\Compressed\arduino-nightly-windows\arduino-nightly\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM6
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x85
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x85

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

```

What is wrong with my arduino?

Note: I was uploading the blink (Example) code, tried with others too...

# Answer
> 1 votes
When soldering the pin headers, I used too much flux. So this caused contact between the GND and RST on the ICSP causing the arduino to stay in the reset position. I removed the ICSP pin headers and there was a lot of flux. I removed it and now my arduino is working perfectly. Thanks to @Juraj for figuring it out that there must be a contact between GND and RST

# Answer
> 1 votes
The compiler log said:

`-libraries C:\Users\MN\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328old -vid-pid=1A86_7523 -ide-version=10810`

It seems your AVR is not updated, try to update your `Arduino Avr Bords` on the boards manager. also make sure your `avrdude.conf` file might to be :

`...
Using Programmer : arduino
 Overriding Baud Rate : 115200
 AVR Part : ATmega328P
 Chip Erase delay : 9000 us
 PAGEL : PD7
 BS2 : PC2
 RESET disposition : dedicated
 RETRY pulse : SCK
 serial program mode : yes
 parallel program mode : yes
 Timeout : 200
 StabDelay : 100
 CmdexeDelay : 25
 SyncLoops : 32
 ByteDelay : 0
 PollIndex : 3
 PollValue : 0x53
...`

Dont forget to wire RX to GND or connected RX to TX directly.

Hope this helps.

# Answer
> 0 votes
Sounds like it is missing the 10K reset pullup resistor. Try adding one from the RST pin to VCC, which is pin 2 of the 6-pin header.

---
Tags: arduino-nano, sketch
---


# Question
Title: Can you help me figure out why my arduino code is not working
The code is made to sense were an object is and send out

```
int const trigPin = 10;
int const echoPin = 9;
int const buzzPin = 1;
int const LED1 = 2;
int const LED2 = 3;
int const LED3 = 4;
void setup()
{
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzPin, OUTPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
}
void loop()
{
int duration, distance;
digitalWrite(trigPin, HIGH);
delay(1);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//                                      Go
distance = (duration/2) / 29.1;
if (distance <= 1000 && distance >=0) {
digitalWrite(LED1, HIGH);
} else {
digitalWrite(buzzPin, LOW);
digitalWrite(LED1, LOW);
}
delay(60);
}
//                                      SLOW
if (distance <= 50 && distance >=0) {
digitalWrite(LED2, HIGH);
} else {
digitalWrite(buzzPin, LOW);
digitalWrite(LED2, LOW);
}
delay(60);
}
//                                      STOP
if (distance <= 50 && distance >=0) {
digitalWrite(buzzPin, HIGH);
digitalWrite(LED3, HIGH);
} else {
digitalWrite(buzzPin, LOW);
digitalWrite(LED3, LOW);
}
delay(60);
}

```

# Answer
Try adding in some serial output at important code-parts. If you see that these are getting printed you can be sure that the code gets executed until that point. If it doesn't get executed it could also be a problem with the wiring so be sure to check that everythign is set up properly.

At this part:

```
...
void loop()
{
int duration, distance;
digitalWrite(trigPin, HIGH);
delay(1);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//                                      Go
distance = (duration/2) / 29.1;
...

```

You are trying to divide an integer (wich can only hold whole numbers) with a real number. Please make sure to use a data type wich can hold more fine-grained results like double or float.

To set up a serial interface you have to add **Serial.begin(9600)** to you code in the setup() function. Then when you write **Serial.println("Your debugging message here")** it should be visible in the serial monitor after compiling. (Arduino IDE-\>Tools-\>Serial Monitor)
> 1 votes

---
Tags: arduino-uno
---


title: Decoding RC transmitter data

text:
# Question
Title: Decoding RC transmitter data
I would like to use my FSi6 transmitter but not the receiver that comes with it (I´m trying to save weight), for that I was planning to get one of this NRF24L01 breakout boards. The problem is, how do you interpret the incoming traffic? After some googling, I couldn´t find any information from flysky.

I would think that this is a common thing to do, as you could pair the transmitter with another receiver (perhaps other brand) so there must be a standard protocol.

Any ideas? Thanks!

# Answer
> 0 votes
Unless the FSi6 (whatever that is) uses an nRF27L01+ as its transmitter, then no - you can't.

The nRF24L01+ chip will *only* communicate with other nRF24L01+ chips. It contains its own custom protocol within the chip and it can only talk that protocol and no others.

---
Tags: remote-control
---


# Question
Title: NodeMCU: Wiegand not working for one device, while working for another
I'm using a NodeMCU, and a working code for reading Wiegand data, with this library.

I managed to successfully read the Wiegand signal from this device.

However, I also have this new AR-721H device, and I can't get the Wiegand to work. This is the manual for the device.

There is absolutely nothing coming to the mcu. Everything is wired identically as the working device.

According to the manual, everything should be working, but I am at a loss.

**Can someone please tell me what I might be doing wrong?**

The store clerk told me something about needing a controller that converts RS485 to RS232, but I have no idea what that means. I already made it work with another device...

# Answer
> 1 votes
It's quite cryptic from the little information in that (somewhat chaotic) "manual", but I interpret it that the Wiegand interface is an *input* port, not an *output* port. It is intended to connect that port to an external card reader or keypad as a remote interface (typically the other side of the door to this unit).

For communication with your Arduino you should use the RS-485 interface. For that you need an MAX485 breakout board.

---
Tags: nodemcu, rfid, rs485, rs232
---


# Question
Title: How to save arduino serial monitor data into excel file
I am looking for the software that can help me to save arduino serial monitor data into excel file. And how to use that with your own code.

# Answer
Your computer is able to access the serial data and export it to a text file, which can then be converted to an excel file within *Excel \> Data \> From Text*. However, the data should be formatted in a way that excel can read it by separating values with a delimiter such as `","`.

Once you have done this, simply run your serial data and open up your computer's console and write: `type COM(# here) >> serialdata.txt`

Finally, import this text file into excel.

You could also use Excel VBA with MSCOMM to take the serial data directly into excel.

This answer is a regurgitation of a duplicate question asked earlier.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Check if a set of events occur in a limited time period
I am making a project in which I am using 4 Infrared sensors to take an input. The way I want it to work is such that when one of the sensors is triggered, the code listens for input from the other sensors for a fixed amount of time (say 2 seconds). Based on this data, further functions are executed.

I am assigning a number to each of the sensors, and the sequence in which they are triggered is stored in an array like:

```
// All relevant pins of the IR sensors are set to input with names ir1,ir2,ir3,ir4
int sequence[] = {0,0,0,0}
int s1 = digitalRead(ir1); //and similarly for all other pins
int counter = 0;

if(s1==1){
  sequence[counter] = 1; //similarly 2 for s2 and so on
  counter ++;
}

```

What I am attempting to do is something like this:

```
if(s1 == 1 || s2==1 || s3 == 1 || s4 == 1){
   if(s1 == 1){
      sequence[counter] = 1;
      counter ++;

   //Start listening for other sensors
   } // similarly check which sensor is triggered first

   //Allow 2 seconds for input from all sensors (no input from either one of them is also allowed)
   // After 2 seconds execute some code based on the sequence array which got updated from inputs by different sensors
}

```

How do I accomplish this?

# Answer
> 0 votes
Here's some pseudocode that might help:

```
   if millis() - start time >= 2000
         time is up, do what you want with the sequence so far
         maybe a boolean flag here so you only do it once
   if any button is pressed
      if counter == 0
          set start time = millis() // start the timer
          set first in sequence
      else
          add the button to the sequence

```

---
Tags: arduino-uno, timers
---


# Question
Title: How do I set up an ATTiny861A-PU for flashing with Arduino Uno?
I have found instructions for 8 pin Tiny but none for my 20 pin. How do I set this chip up on the breadboard for bootloading with Arduino?

# Answer
> 0 votes
The principle is the same, it's all only ISP (In System Programming), and nothing different from any other microcontroller, that uses ISP. Look at the descriptions of the used pins for the 8-pin Attinys, then connect the pins with the same description on your 20-pin chip.

Namely you have to connect the pins MOSI, MISO, SCK, RESET, VCC and GND. MOSI and MISO are the data lines, SCK the clock signal. If you look into a pinout diagram or - even better - at the pin configuration diagram in the chips datasheet, you will see pins, that are marked this way. The rest of the pins is pretty much self explaining.

---

Since you are using an Uno as programmer and didn't have a capacitor between Reset and ground of the programmer, I will explain, why this capacitor is needed here.

The Atmega328p on the Uno doesn't have a native USB interface. So in order to connect it via USB to a PC, there is another microcontroller on the Uno (on original board the Atmega16U2), which has a native USB interface. This microcontroller then is the middleman between Atmega328P and PC. It connects to the Serial (UART) interface of the 328P and translates that to USB communication.

Everytime that the corresponding serial port is opened on the PC, the PC sends a DTR signal, which is connected to the 328P's reset pin. So, when the Arduino IDE tries to connect to the Serial port for flashing the Attiny, the Uno get's resetted and hence cannot flash the Attiny.

The capacitor between Reset and Ground will hold the Reset pin high for long enough, so that this reset does not happen and the Uno can do it's duty.

On Arduino boards with native USB interface this is not necessary, since they don't have this hardwired connection to a reset and they communicate directly over USB.

---
Tags: arduino-uno, bootloader, attiny, flash
---


title: flash read err, 1000

text:
# Question
Title: flash read err, 1000
I know this question has been asked multiple times but solutions giving there hasn't been working,

I've got an esp32 soldered to my own designed PCB board with a UART to USB converter all that is working fine, I can get connected to my esp from the Serial monitor.

But it prints every about 0.5s:

```
rst:0x10 (RTCWDT_RTC_RESET)
boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000 ets_main.c
371 ets Jun 8 2016 00:22:57

```

Solutions have been to make sure to have 3.3v on the esp. I find it unlikely to have anything to do with it, 'cause its voltage range goes from 2.6v to 3.6v, but anyway I have tested it with an advanced transformer and a multimeter to check that there was 3.3v on the Vcc pin (didn't change anything).

All help would be appreciated.

Here is a bit more info:

I've also connected a 10uF capacitor (someone told me to try that).

If I pull IO0 to ground, it prints waiting for download in the serial monitor and I can almost upload the program, this is what I get:

> THERE IS NO CONNECTION BETWEEN NEIGHBORING PINS

(I have checked with multimeter)

PCB board:

# Answer
ok, the solution was to add a 10k pull-up resistor to the EN pin, as shown HERE

No capacitor needed
> 0 votes

# Answer
Your PCB is lacking in the majority of things you need to get the module working. These modules are not "simple" in that you provide power and forget about it. You must add all the *required* support components. Those support components are **NOT optional**. For example: you aren't setting the boot mode properly with the right pullups. You lack a capacitor on the power pins (I told you to add one already. Where is it?). Also your power traces are too thin. The impedance is too high.
> 0 votes

---
Tags: serial, arduino-ide, electronics, esp32
---


# Question
Title: Attempting to monitor serial output for a string to trigger function, apparently matching string is output but the function doesn't trigger
I'm working on my second Arduino project, and am somewhat stuck.

I'm running a PIR module from my Arduino Uno with the following sketch:

```
/*
 *  PIR Sensor test
 */

 int pirPin = 6;

 int minSecsBetweenEmails = 60; // 60 seconds

 long lastSend = -minSecsBetweenEmails * 1000l;

 void setup()
 {
  pinMode(pirPin, INPUT);

  Serial.begin(9600);
 }

 void loop() {
  long now = millis();
  if (digitalRead(pirPin) == HIGH)
    {
       if (now > (lastSend + minSecsBetweenEmails * 1000l))
        {
            Serial.println("MOVEMENT");
            lastSend = now;
        }
      else
        {
          Serial.println("Too soon");
        }
    }
        delay(500);
 }

```

I'm monitoring the COM3 port using the following in JupyterLab with PySerial.

```
import time
import serial
import smtplib

to = 'myemail@myemail.com'
GMAIL_USER = 'myemail@myemail.com'
GMAIL_PASS = '**********'

SUBJECT = 'MOTION pir'
TEXT = 'PIR sensor detected motion'

ser = serial.Serial('COM3', 9600)

def send_email():
    print("Sending Email")
    smtpserver = smtplib.smtp("smtp.gmail.com",587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(GMAIL_USER, GMAIL_PASS)
    header = str('To:' + TO + '\n' + 'From: ' + GMAIL_USER)
    header = header + '\n' + 'Subject:' + SUBJECT + '\n'
    print (header)
    msg - header + '\n' + TEXT + ' \n\n'
    smtpserver.sendmail(GMAIL_USER, TO, msg)
    smtpserver.close()

while True:
        message = ser.readline()
        print(message.decode('utf-8'))
        if message[0] == 'MOVEMENT' :
            send_email()
            time.sleep(0.5)

```

I believe my problem is with the `ser.readline()` function. I've been reading the docs, they seem to say I need to provide some kind of endpoint or timeout for the function to provide for EOF, but my goal was to have the

```
if message [0] == 'MOVEMENT' :

```

continuously evaluate the output lines from COM3...

Any input at all would be very much appreciated.

EDIT: Thanks to all three of you for your help! By changing the Python as shown below I was able to fulfill the `if message[0] == 'MOVEMENT' :`statement

Python should have been:

```
import time
import serial
import smtplib

to = 'myemail@myemail.com'
GMAIL_USER = 'myemail@myemail.com'
GMAIL_PASS = '**********'

SUBJECT = 'MOTION pir'
TEXT = 'PIR sensor detected motion'

ser = serial.Serial('COM3', 9600)

def send_email():
    print("Sending Email")
    smtpserver = smtplib.smtp("smtp.gmail.com",587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(GMAIL_USER, GMAIL_PASS)
    header = str('To:' + TO + '\n' + 'From: ' + GMAIL_USER)
    header = header + '\n' + 'Subject:' + SUBJECT + '\n'
    print (header)
    msg - header + '\n' + TEXT + ' \n\n'
    smtpserver.sendmail(GMAIL_USER, TO, msg)
    smtpserver.close()

while True:
        message = ser.readline()
        print(message)
        if message == b'MOVEMENT\r\n' :
            send_email()
            time.sleep(0.5)

```

# Answer
You're confusing `readlines()` with `readline()`. The former returns an array of lines, the latter a single line. You need to drop the `[0]` since you're not working with an array of lines, and you need to include the line endings that the Arduino sends:

```
while True:
    message = ser.readline()
    print(message.decode('utf-8'))
    if message == 'MOVEMENT\r\n' :
        send_email()
        time.sleep(0.5)

```
> 1 votes

---
Tags: serial, programming
---


# Question
Title: Trying to light an LED with one Button and have no idea what is wrong
New to Arduino. I am trying to use a single button to light and turn off a single LED. I followed an online tutorial (youtube video) and changed the code just a bit. I know it is for two LEDs but I tried it for one. I have no idea why it is not working. I don't see why it doesn't make sense but it just does not work.

Here is the code:

```
float LengthPush = 0; // LengthPush is the amount of time the button has been pressed.

int ShortPush = 100; // 100 ms push. Supposed to turn on the LED.
int LPush = 1000; // 1000 ms push. Supposed to turn it off.

int ButtonPin = 2;
int RLED = 13;

void setup() {
  // put your setup code here, to run once:
  pinMode(ButtonPin, INPUT_PULLUP);
  pinMode(RLED, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  while (digitalRead(ButtonPin) == LOW) {
    delay(100);
    LengthPush = LengthPush + 100;

    Serial.print("ms = ");
    Serial.println(LengthPush);
  }

  if (LengthPush >= LPush) {
    digitalWrite(RLED, LOW);
  } else if (ShortPush <= LengthPush < LPush) {
    digitalWrite(RLED, HIGH);
  }
  LengthPush = 0;
}

```

# Answer
I think your problem lies in the else-if-statement, where you try to compare 3 different values. While this doesn't thrown a compiling error in my Arduino IDE, it will probably not do, what you are trying to achieve.

Instead you need to compare `LengthPush` with one value and then with the other. You can even do this inside the same if statement:

```
if(ShortPush <= LengthPush && LengthPush < LPush)

```

The `&&` is the boolean AND operator, which means, that the if statement will be executed, if both statements around it will evaluate as `true`.

---

I'm not sure, what actually happens with your original code, since it doesn't throw a compilation error. It might be (and that's my theory here), that the program will first evaluate `ShortPush <= LengthPush` and then compare the result to `LPush`. Since boolean values evaluate as `0` or `1` in integer calculations, that messes up the whole intent of this. Take the case, that `LengthPush` is really in the required interval. Then the first part will evaluate as `true`, which means `1` as integer. Then this `1` get's compared to `LPush`, which is always higher, so the overall result is true. But the same result comes, when `LengthPush` is smaller than `ShortPush`.
> 1 votes

---
Tags: arduino-mega, led, button
---


# Question
Title: Convert Arduino MEGA Code to Arduino DUE Code?
I've been working with MEGA before. This code works completely with MEGA. I'm still at beginner level in Arduino.

**Q:** How do I adapt this code to DUE?

**Note:** I'm asking this question because I think the only problem in adaptation seems to be `SoftwareSerial`.

```
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(52,53);    // TX,RX
int bar_analog=0;
int head_analog=0;
int bar_anim=0;
int strip_anim=0;
int motor_speed=1;
int direct=0;
int level=0;
boolean debug = true;
int IN1a=49;
int IN2a=48;
int PWM1=3;
int IN1b=22;
int IN2b=23;
int PWM2=4;
int hiz=100;
int PWM_kare=2;
int INA_kare = 51;
int INB_kare = 50; //LED '+'sı OUTPUT B'de olduğu için INB'yi  HIGH yapıyoruz.
void m1_cw() {
    digitalWrite(IN1a,HIGH);
    digitalWrite(IN2a,LOW);
    analogWrite(PWM1,hiz);
}
void m1_ccw() {
    digitalWrite(IN1a,LOW);
    digitalWrite(IN2a,HIGH);
    analogWrite(PWM1,hiz);
}
void m2_cw() {
    digitalWrite(IN1b,HIGH);
    digitalWrite(IN2b,LOW);
    analogWrite(PWM2,hiz);
}
void m2_ccw() {
    digitalWrite(IN1b,LOW);
    digitalWrite(IN2b,HIGH);
    analogWrite(PWM2,hiz);
}
void m1_stop() {
    digitalWrite(IN1a,LOW);
    digitalWrite(IN2a,LOW);
    analogWrite(PWM1,0);
}
void m2_stop() {
    digitalWrite(IN1b,LOW);
    digitalWrite(IN2b,LOW);
    analogWrite(PWM2,0);
}
void mast_up() {
    digitalWrite(24,HIGH);
    digitalWrite(25,LOW);
}
void mast_down() {
    digitalWrite(24,LOW);
    digitalWrite(25,HIGH);
}
void mast_stop() {
    digitalWrite(24,LOW);
    digitalWrite(25,LOW);
}
void kare() {
    analogWrite(PWM_kare,head_analog);
    digitalWrite(INB_kare, HIGH);
    digitalWrite(INA_kare, LOW);
}
void setup() {
    Serial.begin(9600);
    bluetooth.begin(9600);
    Serial.println("Program is starting...");
    Serial.println("by Berke Ogulcan Parlak");
    pinMode(IN1a,OUTPUT);
    pinMode(IN2a,OUTPUT);
    pinMode(IN1b,OUTPUT);
    pinMode(IN2b,OUTPUT);
    pinMode(PWM1,OUTPUT);
    pinMode(PWM2,OUTPUT);
    pinMode(24,OUTPUT);
    pinMode(25,OUTPUT);
    pinMode(INA_kare, OUTPUT);
    pinMode(INB_kare, OUTPUT);
    pinMode(PWM_kare, OUTPUT);
    digitalWrite(IN1a,LOW);
    digitalWrite(IN2a,LOW);
    digitalWrite(IN1b,LOW);
    digitalWrite(IN2b,LOW);
    digitalWrite(PWM1,LOW);
    digitalWrite(PWM2,LOW);
    digitalWrite(24,LOW);
    digitalWrite(25,LOW);
    digitalWrite(INA_kare, LOW);
    digitalWrite(INB_kare, LOW);
    digitalWrite(PWM_kare, LOW);
}

void loop() {
    if (bluetooth.available()) {
        while (bluetooth.available())
        {                                                //AppInventor'dan çektiğimiz verileri,değişkenlere atıyoruz.
            bar_analog = bluetooth.parseInt();
            head_analog = bluetooth.parseInt();
            bar_anim = bluetooth.parseInt();
            strip_anim = bluetooth.parseInt();
            motor_speed = bluetooth.parseInt();
            direct = bluetooth.parseInt();
            level = bluetooth.parseInt();
            if (debug) {                                   // Arduin seri ekranından değerleri okumak için gereklidir.
                Serial.print("Bar Brightness: ");
                Serial.println(bar_analog);
                Serial.print("Bar Animation Type: ");
                Serial.println(bar_anim);
                Serial.print("Headlight Brightness: ");
                Serial.println(head_analog);
                Serial.print("Strip Animation Type: ");
                Serial.println(strip_anim);
                Serial.print("Motor Speed Level: ");
                Serial.println(motor_speed);
                Serial.print("Direction: ");
                Serial.println(direct);
                Serial.print("Mast Goes: ");
                Serial.println(level);
                Serial.println("--------------------------------");
            }
            if (bluetooth.read() == '\n') {               //Yazdırma işlemleri bu satırda yapılacak..

            }
        }}
    if(direct==1) { //ileri
        m1_ccw();
        m2_ccw();
    }
    else if(direct==2) { //geri
        m1_cw();
        m2_cw();
    }
    else if(direct==3) { //sol
        m1_ccw();
        m2_cw();
    }
    else if(direct==4) { //sağ
        m1_cw();
        m2_ccw();
    }
    else if(direct==0) { //durur
        m1_stop();
        m2_stop();
    }
    if(level==1) { //mast yukarı
        mast_up();
    }
    else if(level==2) { //mast aşağı
        mast_down();
    }
    else if(level==0) { //mast durur
        mast_stop();
    }
    kare();            //kare LED aktif.
}

```

# Answer
> 1 votes
SoftwareSerial is a workaround for Arduino versions without enough Hardware Serial ports, which is not the case of Arduino Mega or Arduino Uno which have 4.

Delete `SoftwareSerial`, replace all occurrences of `bluetooth` by `Serial1`, and rewire the Serial communication from pins `52`|`53` into pins `18`|`19` instead of (TX|RX)

Besides, the Arduino Due tends to be more "strict" than Arduino Mega compiler.

Besides that, your code will compile with no issues.

Also, remember Arduino Due is 3.3V and not 5V.

---
Tags: arduino-mega, bluetooth, arduino-due, communication
---


title: Output 3.3V when setting pin to high

text:
# Question
Title: Output 3.3V when setting pin to high
I would like to pass 3.3V and Ground to an component. How can I achieve such a thing?

I for example would like to let a wire get 3.3V when I for example do digitalWrite(pin, HIGH). It is hard for me to explain this, so I created an illustration in the hope of better clarifying it.

Edit: I have an product that I have dismantled. On the PCB, there is a push button. I would like to solder some wires to the place where the button is so it can be controlled with an arduino (probably wemos d1). When plugging a cable in the 3.3v of the arduino and a cable from the ground, when connecting it to the push button it will cause a boot of the dismantled product. This explains why I would like to give power to a component ONLY when a pin is set high, so I can for example boot the product via a website / app eventually.

# Answer
The normal way is to use a P-channel MOSFET as a "high side" switch.

simulate this circuit – Schematic created using CircuitLab

R1 keeps it switched off under "normal" circumstances. Driving D4 LOW makes M1 turn on and allow power through to the "component".

Make sure that the MOSFET has a threshold voltage of no more than (less than?) -3V (that is, somewhere between 0V and -3V - note: P-channel MOSFETs have their thresholds quoted as a negative voltage).

You could connect R1 to 3.3V instead of 5V, but since the GPIO would have 5V on it when HIGH it would be wasting power while idling - so it's better to pull it to 5V instead.
> 3 votes

---
Tags: arduino-uno, arduino-mega, arduino-nano, pins, voltage-level
---


# Question
Title: Cannot convert 'int (*)[size]' to 'int**'
Analyzing this and this answers under Arduino, which should be the proper way to pass a 2D array into a function?

The function should be applicable to different sizes of 2D arrays.

```
// NOT COMPILING EXAMPLE
void f(int** x,const int m, const int n){
// access x as x[0][0], x[0][1], etc...
}

void main{}{
    int x1[16][128];
    f(x1,16,128);
    int x2[64][16];
    f(x2,64,16);
}

```

# Answer
> 2 votes
According the prototype of `f` and the usage pattern for its `x` argument, the function expects this argument to be a pointer to the first element of an array of pointers to the first elements of arrays of `int`. However, the matrix in `main()` is defined as an array of arrays of `int`. If you try to pass this to a function, the matrix will decay into a pointer to an array of `int`. That's not what you want.

If you want both dimensions of the matrix to be variable, the only simple solution I see is to build an extra array of pointers (pointing to the matrix rows) and pass *that array* to the function

```
int main() {
    int x[16][128];

    // Build an array of pointers to rows.
    int *px[16];
    for (int i = 0; i < 16; i++)
        px[i] = x[i];

    f(px, 16, 128);
}

```

For more information on this, see the section Arrays and Pointers in the C FAQ, and more specifically the questions 6.16 (*How can I dynamically allocate a multidimensional array?*) and 6.19 (*How do I write functions which accept two-dimensional arrays when the width is not known at compile time?*).

---
Tags: array, functions
---


title: Class member variable would not update

text:
# Question
Title: Class member variable would not update
Code would not update variable inside drive method. The variable is updated inside the drive method, but it doesn't change in the rest of the class. I wrote a simple similar method in normal C++ and the variable actually updated in the rest of the class.

engine.hpp

```
#pragma once
#include <Arduino.h>

namespace engine
{
class Engine
{
public:
    Engine(const unsigned char t_motor, const unsigned char t_forward, const unsigned char t_backward);
    void drive(unsigned int t_speed, bool t_isForward = true);
    bool isMovingForward() const;
    void stop();

private:
    const unsigned char m_motor;
    const unsigned char m_forward;
    const unsigned char m_backward;

    // Movements
    bool m_isActive;
    bool m_isForward;
    unsigned int m_speed;
};
} // namespace engine

```

engine.cpp init list

```
Engine::Engine(const unsigned char t_motor, const unsigned char t_forward, const unsigned char t_backward)
    : m_motor(t_motor),
      m_forward(t_forward),
      m_backward(t_backward),
      m_isActive(false),
      m_isForward(true),
      m_speed(0U)
{
}

```

drive method

```
void Engine::drive(unsigned int t_speed, bool t_isForward)
{

    if (!m_isActive || m_isForward != t_isForward)
    {
        stop();

        // Set direction
        if (t_isForward)
        {
            digitalWrite(m_forward, HIGH);
            digitalWrite(m_backward, LOW);
        }
        else
        {
            digitalWrite(m_forward, LOW);
            digitalWrite(m_backward, HIGH);
        }

        m_isActive = true;
        m_isForward = t_isForward;
    }

    if (m_speed != t_speed)
    {
        m_speed = t_speed; // Updated here
        analogWrite(m_motor, t_speed);
    }
}

```

# Answer
> 1 votes
I figured it out.

I was passing the engine objects as references instead of pointers.

main.cpp

```
// Engines
engine::Engine
    engine1(motors::Constants::MOTOR_1, motors::Constants::MOTOR_1_FORWARD, motors::Constants::MOTOR_1_BACKWARD),
    engine2(motors::Constants::MOTOR_2, motors::Constants::MOTOR_2_FORWARD, motors::Constants::MOTOR_2_BACKWARD),
    engine3(motors::Constants::MOTOR_3, motors::Constants::MOTOR_3_FORWARD, motors::Constants::MOTOR_3_BACKWARD),
    engine4(motors::Constants::MOTOR_4, motors::Constants::MOTOR_4_FORWARD, motors::Constants::MOTOR_4_BACKWARD);

```

engine\_controller.cpp init list

```
EngineController::EngineController(engine::Engine &t_e1, engine::Engine &t_e2, engine::Engine &t_e3, engine::Engine &t_e4)
    : m_engine1(t_e1),
      m_engine2(t_e2),
      m_engine3(t_e3),
      m_engine4(t_e4),
      m_currentSpeed(EngineControllerConsts::MAX_SPEED),

      // Directions
      m_rights(0),
      m_lefts(0),

      m_rightDistance(-1),
      m_leftDistance(-1),

      m_lastForward(true),
      m_counter(0),

      m_lastForward1(true),
      m_lastForward2(true),
      m_turnsCounter(0)

{
}

```

The solution would be to use dynamic memory allocation.

main.cpp

```
// Engines
engine::Engine
    *engine1 = new engine::Engine(motors::Constants::MOTOR_1, motors::Constants::MOTOR_1_FORWARD, motors::Constants::MOTOR_1_BACKWARD),
    *engine2 = new engine::Engine(motors::Constants::MOTOR_2, motors::Constants::MOTOR_2_FORWARD, motors::Constants::MOTOR_2_BACKWARD),
    *engine3 = new engine::Engine(motors::Constants::MOTOR_3, motors::Constants::MOTOR_3_FORWARD, motors::Constants::MOTOR_3_BACKWARD),
    *engine4 = new engine::Engine(motors::Constants::MOTOR_4, motors::Constants::MOTOR_4_FORWARD, motors::Constants::MOTOR_4_BACKWARD);

```

engine\_controller.cpp init list

```
EngineController::EngineController(
    engine::Engine *t_e1, engine::Engine *t_e2,
    engine::Engine *t_e3, engine::Engine *t_e4)
    : m_engine1(t_e1),
      m_engine2(t_e2),
      m_engine3(t_e3),
      m_engine4(t_e4),
      m_currentSpeed(EngineControllerConsts::MAX_SPEED),

      // Directions
      m_rights(0),
      m_lefts(0),

      m_rightDistance(-1),
      m_leftDistance(-1),

      m_lastForward(true),
      m_counter(0),

      m_lastForward1(true),
      m_lastForward2(true),
      m_turnsCounter(0)

{
}

```

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


title: My device doesn't recognize my Arduino

text:
# Question
Title: My device doesn't recognize my Arduino
I'm planing to use the ESP8266 to create a web server as a start. My set up is: Arduino nano- Esp8266- Logic level converter as shown in the diagram.  After I connected everything my device doesn’t recognize the Arudion’s USB serial port, but when I disconnect everything from the breadboard and connect the Arduino alone it show up as COM3 and when I put the circuit back again and hock up the USB to my device it no longer show up. I’m having the issue on both win 10 and mac. Whenever I connected the usb cable to my computer the ESP8266 flashes a light for ones.

# Answer
> 2 votes
The Nano cannot power the ESP8266. It has an absolute maximum limit of about 50mA from the 3.3V pin, since it is provided by the USB interface chip. By drawing too much current (the ESP8266 needs hundreds of mA) the USB chip stops functioning.

You need an external 3.3V regulator to power the ESP8266.

---
Tags: esp8266, arduino-ide, arduino-nano
---


# Question
Title: How to send UDP data packet between two access point?
I am new to arduino programming and nodeMcu boards.I have two ESP8266 bards as access points and one board get some data form WiFi stations and resend that data to other access point. but the problem is second access point didn't receive any data packet from first access point.

This is the code of Access point which collect data and resend it to upper level Access point. This Access point successfully received the data from the WiFi stations.

```
const char *ssid1 ="SecondAP";
const char *pwd1 = "12345678910";

const char *ssid2 ="FirstAP";
const char *pwd2 = "123456789101";

ESP8266WiFiMulti WiFiMulti;

IPAddress local_IP(192,168,4,10);
IPAddress gateway(192,168,4,9);
IPAddress subnet(255,255,255,0);
IPAddress NextAP(192,168,4,9);
StaticJsonDocument<200> doc;
unsigned int locPort1 = 1000;
unsigned int locPort2 = 2000;
WiFiUDP udp1;
WiFiUDP udp2;
char packetBuffer[100];
IPAddress addrs;

void setup() {

  Serial.begin(9600);
  delay(10);
  Serial.println('\n');

  ConnectToAP();
  delay(1000);
  EnableAP();
  delay(1000);

  udp1.begin(locPort1);
  udp2.begin(locPort2);
}

void loop() {

int Icb = 0;

  Icb = udp1.parsePacket();

  if(Icb > 0){
      GetSensorDataPacket();
      Icb = 0;
    }
}

void EnableAP(){

  WiFi.softAPConfig(local_IP, gateway, subnet);
  WiFi.softAP(ssid2 , pwd2);
  delay(1000);

  Serial.print("Access Point \"");
  Serial.print(ssid2);
  Serial.println("\" started");
  Serial.print("IP address:\t");
  Serial.println(WiFi.softAPIP());
}

void ConnectToAP(){

  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(ssid1, pwd1);

  Serial.print("Connecting to ...........");
  Serial.print(ssid1); Serial.println("...");

  int i = 0;
  while (WiFiMulti.run() != WL_CONNECTED) {

   delay(1000);
   Serial.print(++i); Serial.print(' ');
  }

  Serial.println('\n');
  Serial.println("Connection established!");
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());
}

void GetSensorDataPacket(){

  Serial.println("GetSensorDataPacket Function");
  udp1.read(packetBuffer,100);
  DeserializationError error = deserializeJson(doc, packetBuffer);

  IPAddress ClientAddrs = udp1.remoteIP();

  double SensorData = doc["SensorData"];
  int ClientID = doc["ID"];

  delay(1000);
  Serial.println();
  Serial.print("Sensor reading = ");
  Serial.println(SensorData);
  Serial.print("Client ID = ");
  Serial.println(ClientID);

  SendDataToNextAP(SensorData,ClientID);
}

void SendDataToNextAP(double Sensor_Data,int Client_ID){

  StaticJsonDocument<500> jsonBuffr;
  Serial.println("I'm in SendDataToNextAP Function");

  udp2.beginPacket(NextAP, locPort1); //gateway
  JsonObject Sob1 = jsonBuffr.to<JsonObject>();
  Sob1["SensorData"] = Sensor_Data;
  Sob1["ID"] = Client_ID;
  serializeJson(jsonBuffr, udp2);

  udp2.println();
  udp2.endPacket();

  delay(1000);
}

```

This is the code of upper Access point which should receive data packet from first access point but didn't receive any data from the first access point.

```
const char *ssid = "SecondAP";
const char *pwd = "12345678910";
ESP8266WiFiMulti WiFiMulti;

IPAddress local_IP(192,168,4,9); // Ip address of this node
IPAddress gateway(192,168,3,1);
IPAddress subnet(255,255,255,0);

StaticJsonDocument<200> doc;
unsigned int locPort1 = 1000;
WiFiUDP udp1;
char packetBuffer[100];

void setup() {

  Serial.begin(9600);
  delay(10);
  Serial.println('\n');

  EnableAP();
  udp1.begin(locPort1);
  delay(1000);
}

void loop() {

int Icb = 0;

  Icb = udp1.parsePacket();
  if(Icb > 0){
      Serial.println("Got a Udp packet");
      GetSensorDataPacket();
    }
}

void EnableAP(){

  WiFi.softAPConfig(local_IP, gateway, subnet);
  WiFi.softAP(ssid,pwd);
  delay(1000);

  Serial.print("Access Point \"");
  Serial.print(ssid);
  Serial.println("\" started");
  Serial.print("IP address:\t");
  Serial.println(WiFi.softAPIP());
}

void GetSensorDataPacket(){

  Serial.println("GetSensorDataPacket Function");
  udp1.read(packetBuffer,100);
  DeserializationError error = deserializeJson(doc, packetBuffer);

  IPAddress ClientAddrs = udp1.remoteIP();

  double SensorData = doc["SensorData"];
  int ClientID = doc["ID"];

  delay(1000);
  Serial.println();
  Serial.print("Sensor reading = ");
  Serial.println(SensorData);
  Serial.print("Client ID = ");
  Serial.println(ClientID);
}

```

I couldn't find the reason for that. If anyone knows the solution for that please help me?

Thanks!

# Answer
The two network interfaces (station and SoftAP) of the middle esp8266 must have different IP address range. If the top AP has 192.168.4.x, set for the AP of the middle IP for example 192.168.5.1. Because with same IP address ranges the esp8266 doesn't know to which network do you want to send the UDP message.
> 0 votes

---
Tags: esp8266, programming, arduino-ide, nodemcu
---


# Question
Title: How to read shiftOut function using arduino
(I'm sorry for my bad English, but I will do my best)

I have a Chinese MUC which already programmed. It communicates with a LED driver chip using three wires (STB,CLK,DIN).
(LED driver controls 16 digit 7 Segment display)

After some research, I found that it can be talk to LED driver using shiftout function.

Now the main coal is to connect these 3 pins(STB,clk,din) to Arduino and read the incoming data and convert the data to numbers.

To test if this idea is working or not, I came with two arduino (uno to send shiftout function and mega to read it) after connect pin 2 of uno to pin 2 of mega and same 3 to 3, 4 to 4 and also Gnd of uno to Gnd of mega.
I wrote these codes:

arduino UNO side (to send shiftOut function)

```

    #define STB  4
#define clockPin  5
#define dataPin  6

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

  pinMode(STB, OUTPUT);
  pinMode(clockPin,  OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
 digitalWrite(STB, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, 0b10101010 ); // 1st digit
   digitalWrite(STB, HIGH);
}

```

arduino mega side (to read shiftOut function)

```

    #define STB 4
#define clockPin  5
#define dataPin  6

 int R_STB[8];
 int R_clockPin ;
 int R_dataPin ;
void setup() {
   Serial.begin(115200);

  pinMode(STB, INPUT);
  pinMode(clockPin,  INPUT);
  pinMode(dataPin, INPUT);
}

void loop() {

 R_STB = digitalRead(STB);
 R_clockPin = digitalRead(clockPin);
 R_dataPin = digitalRead(dataPin);

   for(int i=0 ; i<8;i++){
  Serial.print(R_STB[i]-2);

  Serial.print(" ");
  Serial.print (R_clockPin[i]);

 Serial.print(" ");
  Serial.print(R_dataPin[i]+2);
Serial.println(" ");
   }
 }

```

But the digital read at arduino mega side can't read all data due to it fast switching between High LOW statement maybe? and I am stuck here.

Please any one has any ideas?

# Answer
> 1 votes
You are right that you can't read the data fast enough with your method there. What you really need is the opposite of "shiftOut" - which happens to be called "shiftIn". You use it just like shiftOut, but instead of you sending it a value to send it instead returns a value that it reads.

You trigger it using the "STB" pin:

```
if (digitalRead(STB) == LOW) {
    uint8_t val = shiftIn(dataPin, clockPin, LSBFIRST);
    Serial.println(val, HEX);
}

```

But the protocol you describe is simply SPI. There is hardware within the Arduino to handle it for you. A little harder to work with, but it's capable of working at much higher speeds and is more likely to be able to read your incoming data fast enough.

Resources:

The latter includes how to configure an SPI "Slave" which is used for receiving data that is sent out from elsewhere.

---
Tags: arduino-uno, communication, stream
---


# Question
Title: Arduino Due Digital Inputs without Response
On two of my Arduino Due, when connecting the pin `3.3V` to any digital inputs (`37`,`36`,`35`,`34`), no serial message nor `LED_BUILTIN` is thrown as output, only the `Test` message.

Digital Pins are set as `INPUT` by default. `Blink` works.

I have never connected any other thing on those pins, even 5V.

What I am missing?

```
void setup() {
    Serial.begin(115200);
    while(!Serial);
    pinMode(LED_BUILTIN,OUTPUT);
    Serial.print("Test");
}

void loop() {
    if (digitalRead(37))
        Serial.print("37");
    if (digitalRead(36))
        Serial.print("36");
    if (digitalRead(35))
        Serial.print("35");
    if (digitalRead(34))
        Serial.print("34");
    digitalWrite(LED_BUILTIN,digitalRead(37));
}

```

# Answer
> 2 votes
A good practice is to set the pin mode for all the pins used by the sketch.

```
void setup() {
    Serial.begin(115200);
    while(!Serial);
    pinMode(34, INPUT);
    pinMode(35, INPUT);
    pinMode(36, INPUT);
    pinMode(37, INPUT);
    pinMode(LED_BUILTIN, OUTPUT);
    Serial.print("Test");
}

```

The Arduino AVR core does set the pin mode to INPUT by default but the Arduino SAM core does not. The SAM MCU is much more advanced and allows turning on and off the ports, and a lot of other functionality.

Cheers!

---
Tags: pins, arduino-due, input
---


# Question
Title: How to connect SPI device on Etherntet shield on Arduino Uno
In my project I need to connect RFID reader (RC522) on top of the Ethernet shield because of it's capability of reading and editing SD card. When I connect only RFID sensor on Arduino, it works. Same goes to Ethernet shield. But when I use both together, It simply doesn't work. I can compile it and upload it, but I don't get anything in the serial monitor. I think it's because both Ethernet shield and RFID reader use the same pins for SPI like MOSI, MISO and SCK. My question is, if that is the problem, how to connect multiple SPI devices on Arduino, or at least on Ethernet shield.

Here is my code, although I think there's nothing wrong with it. I just merged code for RFID and Ethernet shield with copy-pasting. Sorry for bad formatting, I need it just for test, I'll later make the real code.

```
#include <SPI.h>
#include <MFRC522.h>
#include <SD.h>

#define RST_PIN         6          // Configurable, see typical pin layout above
#define SS_PIN          7

MFRC522 mfrc522(SS_PIN, RST_PIN);

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
// MKRZero SD: SDCARD_SS_PIN
const int chipSelect = 4;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  SPI.begin();      // Init SPI bus
  mfrc522.PCD_Init();   // Init MFRC522
  mfrc522.PCD_DumpVersionToSerial();  // Show details of PCD - MFRC522 Card Reader details
  Serial.println(("Scan PICC to see UID, SAK, type, and data blocks..."));

  Serial.print("\nInitializing SD card...");

  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card inserted?");
    Serial.println("* is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    while (1);
  } else {
    Serial.println("Wiring is correct and a card is present.");
  }

  // print the type of card
  Serial.println();
  Serial.print("Card type:         ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    while (1);
  }

  Serial.print("Clusters:          ");
  Serial.println(volume.clusterCount());
  Serial.print("Blocks x Cluster:  ");
  Serial.println(volume.blocksPerCluster());

  Serial.print("Total Blocks:      ");
  Serial.println(volume.blocksPerCluster() * volume.clusterCount());
  Serial.println();

  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("Volume type is:    FAT");
  Serial.println(volume.fatType(), DEC);

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize /= 2;                           // SD card blocks are always 512 bytes (2 blocks are 1KB)
  Serial.print("Volume size (Kb):  ");
  Serial.println(volumesize);
  Serial.print("Volume size (Mb):  ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Gb):  ");
  Serial.println((float)volumesize / 1024.0);

  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
  }
}

void loop() {
    if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // Dump debug info about the card; PICC_HaltA() is automatically called
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}

```

# Answer
> 1 votes
The two devices should share SCK, MISO, and MOSI, but SS (or CS as it's sometimes called) will have to be different and both shields are probably trying to use pin 10 for SS. Let the ethernet shield have pin 10 for SS. On the other shield, take that pin and bend it out so it doens't go down into the header when you stack them and then solder a wire to it and take it to another pin. Go into the code and modify the code for that shield to use the new pin as SS instead of pin 10.

---
Tags: arduino-uno, spi, rfid, ethernet-shield
---


title: Is this Arduino UNO running at 12 MHz?

text:
# Question
Title: Is this Arduino UNO running at 12 MHz?
I am wondering if this Arduino UNO R3 clone is clocked at 12 MHz instead of the standard 16 MHz? On the board, you can see there is 12.000 written on the crystal oscillator.

But maybe it's not the MCU clock speed? I found this other clone, which has 2 crystal oscillators?! One is 12 MHz and the other one is 16 MHz.

I can't figure out what's happening with these boards... Are these sporting faster or slower speeds? The original Arduino UNO R3 has only one 16 MHz crystal oscillator.

# Answer
The 12MHz crystal is for the USB interface.

The main MCU uses a very small 16MHz resonator, which you can see between C5 and C6.
> 1 votes

# Answer
The 16 MHz resonator, a 3-pin part, can be seen between C5 and C6 in the first picture.

The 12 MHz is for the CH340 as noted.

So it's not an Uno, but a clone ripoff, as an Uno would have a Atmega16U2 for the USB.
> 0 votes

---
Tags: arduino-uno, clones
---


# Question
Title: How To Get Data From Arduino Uno Onto My Laptop Through The USB
I want to write a c++ program that does something with the data from one of the input analog pins as the program runs, but I want to know how to get the value from the arduino uno though the USB port (that I am also using to power the uno) and into my laptop for using. IS there any documentation I should read?

My laptop runs Ubuntu 18.04 if that matters.

EDIT: I am not talking about the Serial monitor by the way

# Answer
The "Serial Monitor" is merely a window to the Arduino's serial port. You don't have to use it to use Serial. It's just a (very simple) built in way of seeing the data.

You can use the Serial interface with your own software, or with third party software. It's not tied to the Serial Monitor in any way at all.

So:

* Use `Serial.print()` etc to send data to the PC
* Write your own PC software in your language of choice to process that data, or
* Use some third party application to read and process the serial data
> 1 votes

---
Tags: arduino-uno, c++, usb, ubuntu
---


# Question
Title: Why is my Arduino code for running a Bluetooth controlled robot with obstacle sensor not working as it should be?
I have created a Bluetooth based smartphone controlled robot (a 4 wheel car) earlier using Arduino and an obstacle avoidance robot. Now, I wanted to combine both of them. So, I combined their functions and codes in such a manner that felt right to me. But, it kinda seems wrong to my robot. My Bluetooth Controlled robot was running smoothly. My obstacle avoiding robot was running flawless. But, when I tried to join them, both of them started crying.

I tried to change orders of the functions, adding some functions twice or thrice removing them from some places that didn't feel right then. Nothing was worthy.

I need to upload whole code because I'm not sure where am I doing it wrong

```
#include <SoftwareSerial.h>

#include <RemoteXY.h>

// RemoteXY connection settings
#define REMOTEXY_SERIAL_RX A2
#define REMOTEXY_SERIAL_TX A3
#define REMOTEXY_SERIAL_SPEED 9600

// RemoteXY configurate
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
  { 255,8,0,54,0,176,0,8,228,4,
  5,48,44,26,30,30,0,31,8,1,
  6,0,-84,-142,20,20,0,2,26,129,
  0,6,37,23,8,0,64,78,97,118,
  101,100,0,131,3,51,1,20,5,1,
  2,31,82,111,98,111,116,32,67,97,
  114,0,131,0,62,5,19,5,2,2,
  31,67,111,110,116,114,111,108,108,101,
  114,0,129,0,10,45,13,7,0,16,
  84,72,69,0,129,0,5,52,25,8,
  0,136,83,104,101,105,107,104,0,1,
  0,-34,-111,12,12,1,2,31,88,0,
  1,4,79,44,12,12,0,37,151,240,
  159,147,162,0,65,4,87,9,7,7,
  0,65,1,87,17,7,7,0,65,2,
  87,25,7,7,0,67,5,3,3,25,
  14,0,94,24,51,2,0,86,1,11,
  5,0,135,26,31,31,79,78,0,79,
  70,70,0 };

// this structure defines all the variables of your control interface
struct {

    // input variable
  int8_t joystick_1_x; // =-100..100 x-coordinate joystick position
  int8_t joystick_1_y; // =-100..100 y-coordinate joystick position
  uint8_t rgb_1_r; // =0..255 Red color value
  uint8_t rgb_1_g; // =0..255 Green color value
  uint8_t rgb_1_b; // =0..255 Blue color value
  uint8_t button_1; // =1 if button pressed, else =0
  uint8_t button_2; // =1 if button pressed, else =0
  uint8_t switch_1; // =1 if switch ON and =0 if OFF

    // output variable
  uint8_t red_led_r; // =0..255 LED Red brightness
  uint8_t blue_led_b; // =0..255 LED Blue brightness
  uint8_t green_led_g; // =0..255 LED Green brightness
  char text_indicator[51];  // string UTF8 end zero

    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////

#define PIN_BUTTON_2 A4
#define PIN_SWITCH_1 A5

#include<AFMotor.h>
#include <NewPing.h>
#include <Servo.h>

#define TRIG_PIN A0
#define ECHO_PIN A1
#define MAX_DISTANCE 250
//#define MAX_SPEED 150 // sets speed of DC  motors
//#define MAX_SPEED_OFFSET 20

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);

AF_DCMotor left_motor_A(1, MOTOR12_64KHZ);
AF_DCMotor left_motor_B(2, MOTOR12_64KHZ);
AF_DCMotor right_motor_A(3, MOTOR34_64KHZ);
AF_DCMotor right_motor_B(4, MOTOR34_64KHZ);
Servo myservo;

int distance = 100;

int right_motor_speed = 0;
int left_motor_speed = 0;
//define two arrays with a list of pins for each motor
AF_DCMotor RightMotor[2] = {right_motor_A, right_motor_B};
AF_DCMotor LeftMotor[2] = {left_motor_A, left_motor_B};

//speed control of motors
void Wheel (AF_DCMotor * motor, int v) // v = motor speed, motor = pointer to an array of pins
{
  if (v > 100) v=100;
  if (v < -100) v=-100;
  if (v > 0){

    motor[0].run(FORWARD);
    motor[1].run(FORWARD);
    motor[0].setSpeed(v * 1.75);
    motor[1].setSpeed(v * 1.75);
  }
  else if ( v<0 ){

    motor[0].run(BACKWARD);
    motor[1].run(BACKWARD);
    motor[0].setSpeed(v * 1.75);
    motor[1].setSpeed(v * 1.75);
/*    //digitalWrite (motor [1], FORWARD);
    analogWrite (motor [2], (v) * 0.75);
    //analogWrite (motor [2], (-v) * 0.75); */
  }
  else{
    motor[0].run(RELEASE);
    motor[1].run(RELEASE);
    motor[0].setSpeed(0);
    motor[1].setSpeed(0);
  }
}

 int lookRight()
 {
    RemoteXY.blue_led_b = 255;
    RemoteXY.red_led_r = 0;
    RemoteXY.green_led_g = 0;
    sprintf(RemoteXY.text_indicator, "CHECKING THE RIGHT SIDE.");
    myservo.write(50);
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115);
    return distance;
 }

 int lookLeft()
 {
    RemoteXY.blue_led_b = 255;
    RemoteXY.red_led_r = 0;
    RemoteXY.green_led_g = 0;
    sprintf(RemoteXY.text_indicator, "CHECKING THE LEFT SIDE.");
    myservo.write(170);
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(115);
    return distance;
    delay(100);
 }

 int readPing()
 {
  delay(100);
  int cm = sonar.ping_cm();
   if(cm==0)
  {
    cm = MAX_DISTANCE ;
  }
  return cm;
 }

 void moveStop()
 {
  left_motor_A.run(RELEASE);
  left_motor_B.run(RELEASE);
  right_motor_A.run(RELEASE);
  right_motor_B.run(RELEASE);

 }

void setup()
{
  RemoteXY_Init ();

  pinMode (PIN_BUTTON_2, OUTPUT);
  pinMode (PIN_SWITCH_1, OUTPUT);

  myservo.attach(10);
  myservo.write(115);
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);

}

void loop()
{
  RemoteXY_Handler ();

  digitalWrite(PIN_BUTTON_2, (RemoteXY.button_2==0)?LOW:HIGH);
  digitalWrite(PIN_SWITCH_1, (RemoteXY.switch_1==0)?LOW:HIGH);

    int distanceR = 0;
    int distanceL =  0;
    delay(40);

    if(distance<=27)
    {
      moveStop();
      RemoteXY.blue_led_b = 0;
      RemoteXY.red_led_r = 255;
      RemoteXY.green_led_g = 0;
      sprintf(RemoteXY.text_indicator, "AN OBSTACLE HAS COME IN FRONT OF YOUR ROBOT!!!");
      digitalWrite(PIN_BUTTON_2, HIGH);
      delay(1500);
      distanceR = lookRight();
      delay(250);
      distanceL = lookLeft();
      delay(250);

      if(distanceR>=distanceL)
      {
        RemoteXY.blue_led_b = 255;
        RemoteXY.red_led_r = 0;
        RemoteXY.green_led_g = 0;

        sprintf(RemoteXY.text_indicator, "IT IS GOOD TO GO ON THE RIGHT SIDE.");
      }

      else
      {
        sprintf(RemoteXY.text_indicator, "IT IS GOOD TO GO ON THE LEFT SIDE.");
      }
    }
    else
    {
      RemoteXY.blue_led_b = 0;
      RemoteXY.red_led_r = 0;
      RemoteXY.green_led_g = 255;
      //manage the right motor
      Wheel (LeftMotor, RemoteXY.joystick_1_y - RemoteXY.joystick_1_x);
      Wheel (RightMotor, RemoteXY.joystick_1_y + RemoteXY.joystick_1_x);

    }
    distance = readPing();

    //manage the right motor
    //Wheel (LeftMotor, RemoteXY.joystick_1_y - RemoteXY.joystick_1_x);
    //Wheel (RightMotor, RemoteXY.joystick_1_y + RemoteXY.joystick_1_x);

  }

```

I want my Robot to work on my directions and when he senses something on its front end then he should stop there and tell me through a RemoteXY.text\_string and then check for obstacles at the left and right side and tell me on which side it is available to go. After that, it should again take my orders via my mobile phone.

Firstly, it became impossible to connect the robot to the Smartphone using Bluetooth because the robot was very busy in doing some other stuffs (only he knows what was he doing). Then, I applied a "RemoteXY Button" on my code (that is not in the code that I'm posting here) with an "if" block; such that if this switch is pressed via the Smartphone, only then the robot will start moving. So, doing this thing helped me to connect my robot to my smartphone via Bluetooth but, when I was connection then the Servo Motor was regularly spinning (again, I don't know why) after secure connection, when I turned that switch on, then my robot took only my first order (which is usually moving forward) and it performed on my first order for almost first 3 to 5 seconds and then the Robot got his system hanged and my smartphone was automatically disconnected from the robot.

I am unable to figure out where is the filth in my code or my code is itself fully filthy. This is the matter, where I need you guys' help

Other information that you might need for better Support/help, I am using: 1). RemoteXY app for Android to Robot Communication 2). Arduino UNO as Microcontroller 3). Arduino IDE for Programming Arduino 4). One SG 90 Servo Motor. 5). Four Geared DC- Motors. 6). L293D Motor Driver Shield for driving Dc motors and the Servo 7). HC SR-04 ultrasonic sensor for obstacle sensing 8). A 12V battery 9). HC-05 Module for Bluetooth Communication 10). A buzzer for external indicator/horn. At pin A4 11). A filthy code for Arduino Programming .

Any help with the code will be appreciated.

Thank You So Much in advance. ❤

# Answer
My guess is, that the function `RemoteXY_Handler()` has to be called very regularly (without long pauses in between) to communicate with the app on your smartphone, or the app will think, that the communication is lost, and disconnect from the robot. This means, that you cannot use long `delay()` calls in your code, since that is just busy waiting. In your code in case of an obstacle in front of the robot, you wait 3.6s in total. That is too much. The robot is doing nothing in this time. Instead you should use a non-blocking coding style. That means, that the code will not block, waiting (and doing nothing) until an event happends (for example a specific amount of time passed), but instead will execute other functions, until the event occurs. That is a generally better way to program a microcontroller, since it enables you to add more functionalities easily without disturbing the program flow.

Here you try to do timed things with `delay()`. Instead you should use a coding style, like the one found in the `BlinkWithoutDelay` example, that comes with the Arduino IDE. It is explained various times throughout the internet and this site. Basically it is like regularily looking at your watch (the `millis()` function here) and only doing things, when the time has come. You should look at the example and maybe go through some of the tutorials about this, so that you really understand, what happens there. Then you can start to rewrite your code and eliminate all `delay()` calls. That will need some restructuring of the code.

---

The `BlinkWithoutDelay` example is an easy structure, since it contains only few logic. Your goal is a bit more complex. So I suggest, that you use a Finite State Machine (FSM). It is rather easy to implement and a powerful tool to structure your code. It's definitely worth learning for every programmer.

A FSM consists of multiple states, that are connected by transitions. In each state there can be code executed. Also there might be code, that is only executed on transitions. First you have to model your project into states. One state here could be `REMOTE_CONTROLLED`, which would just execute the commands coming from the app. Based on input from sensors and the app you can then transition between the states. If you see, that you might need a `delay()` inside a state, that might be a hint, that you can further divide the state into substates. For example I would make an extra state, which gives the servo the time to move. I would suggest, that you really draw a graph for your project with all your states (state name in a bubble). Then draw arrows as state transitions between them. This will give you a good overview of the structure to implement.

In code this is often implemented with a `switch()` `case` structure and a state variable:

```
int state=0;
int distance = 100;

void loop(){
    RemoteXY_Handler ();
    distance = readPing();

    switch(state){
        case 0:
            // Do whatever the remote demands here
            if(distance <= 27){
                // Execute code, that should happen once at transition here
                state = 1; // This makes the transition to the next state
            }
        case 1:
            // Code of the next state
    }
}

```

With this structure at every time only the code of the current state will be executed. The transitions are made simply by setting the state variable to the next desired state. To make the states more speaking in the code, you can use an `enum`, so that every state can be referenced with an `enum` name. The remote handler and the reading of the distance is done outside the FSM here, since you always need the input from those. Based on them, you can do state transitions.

To do timed things in an FSM, you can put the `millis()` code (like in the `BlinkWithoutDelay` example) into the corresponding state.

---

Note, that this is only one way to implement a FSM. The video, that you linked, does this a bit different by using functions pointers (the `state()` function pointer is the state variable here). The principle is the same, only the programming structure is different. You can decide yourself, what works better for you, and what you understand better (pointers can be a bit difficult to understand for beginners).
> 0 votes

---
Tags: arduino-uno, arduino-ide, hc-sr04, l293d
---