# Question
Title: MPU9250+arduino pro micro strange behaviour after reset
I have an arduino pro micro + mpu9250. For test sketch I'm using https://github.com/sparkfun/SparkFun\_MPU-9250-DMP\_Arduino\_Library

It works as intended after the first sketch upload. After that if I unplug usb cable thus cutting the both devices power and plug back - the fun starts here) My sketch is working, but this time the response from mpu9250 is like 10 times slower. Here is the weird part - it still works, but just shows the data slower in Serial Monitor and the led blinks are slower. What am I doing wrong?

Here is the example I'm using(from the library mentioned above):

```
    /* MPU9250 Basic Example Code
 by: Kris Winer
 date: April 1, 2014
 license: Beerware - Use this code however you'd like. If you
 find it useful you can buy me a beer some time.
 Modified by Brent Wilkins July 19, 2016

 Demonstrate basic MPU-9250 functionality including parameterizing the register
 addresses, initializing the sensor, getting properly scaled accelerometer,
 gyroscope, and magnetometer data out. Added display functions to allow display
 to on breadboard monitor. Addition of 9 DoF sensor fusion using open source
 Madgwick and Mahony filter algorithms. Sketch runs on the 3.3 V 8 MHz Pro Mini
 and the Teensy 3.1.

 SDA and SCL should have external pull-up resistors (to 3.3V).
 10k resistors are on the EMSENSR-9250 breakout board.

 Hardware setup:
 MPU9250 Breakout --------- Arduino
 VDD ---------------------- 3.3V
 VDDI --------------------- 3.3V
 SDA ----------------------- A4
 SCL ----------------------- A5
 GND ---------------------- GND
 */

#include "quaternionFilters.h"
#include "MPU9250.h"

#ifdef LCD
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// Using NOKIA 5110 monochrome 84 x 48 pixel display
// pin 9 - Serial clock out (SCLK)
// pin 8 - Serial data out (DIN)
// pin 7 - Data/Command select (D/C)
// pin 5 - LCD chip select (CS)
// pin 6 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(9, 8, 7, 5, 6);
#endif // LCD

#define AHRS true         // Set to false for basic data read
#define SerialDebug true  // Set to true to get Serial output for debugging

// Pin definitions
int intPin = 12;  // These can be changed, 2 and 3 are the Arduinos ext int pins
int myLed  = 17;  // Set up pin 13 led for toggling

MPU9250 myIMU;

void setup()
{
  Wire.begin();
   TWBR = 12;  // 400 kbit/sec I2C speed
  Serial.begin(115200);

  // Set up the interrupt pin, its set as active high, push-pull
  pinMode(intPin, INPUT);
  digitalWrite(intPin, LOW);
  pinMode(myLed, OUTPUT);
  digitalWrite(myLed, HIGH);

#ifdef LCD
  display.begin(); // Ini8ialize the display
  display.setContrast(58); // Set the contrast

  // Start device display with ID of sensor
  display.clearDisplay();
  display.setTextSize(2);
  display.setCursor(0,0); display.print("MPU9250");
  display.setTextSize(1);
  display.setCursor(0, 20); display.print("9-DOF 16-bit");
  display.setCursor(0, 30); display.print("motion sensor");
  display.setCursor(20,40); display.print("60 ug LSB");
  display.display();
  delay(1000);

  // Set up for data display
  display.setTextSize(1); // Set text size to normal, 2 is twice normal etc.
  display.setTextColor(BLACK); // Set pixel color; 1 on the monochrome screen
  display.clearDisplay();   // clears the screen and buffer
#endif // LCD

  // Read the WHO_AM_I register, this is a good test of communication
  byte c = myIMU.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
  Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX);
  Serial.print(" I should be "); Serial.println(0x71, HEX);

#ifdef LCD
  display.setCursor(20,0); display.print("MPU9250");
  display.setCursor(0,10); display.print("I AM");
  display.setCursor(0,20); display.print(c, HEX);
  display.setCursor(0,30); display.print("I Should Be");
  display.setCursor(0,40); display.print(0x71, HEX);
  display.display();
  delay(1000);
#endif // LCD

  if (c == 0x71) // WHO_AM_I should always be 0x68
  {
    Serial.println("MPU9250 is online...");

    // Start by performing self test and reporting values
    myIMU.MPU9250SelfTest(myIMU.SelfTest);
    Serial.print("x-axis self test: acceleration trim within : ");
    Serial.print(myIMU.SelfTest[0],1); Serial.println("% of factory value");
    Serial.print("y-axis self test: acceleration trim within : ");
    Serial.print(myIMU.SelfTest[1],1); Serial.println("% of factory value");
    Serial.print("z-axis self test: acceleration trim within : ");
    Serial.print(myIMU.SelfTest[2],1); Serial.println("% of factory value");
    Serial.print("x-axis self test: gyration trim within : ");
    Serial.print(myIMU.SelfTest[3],1); Serial.println("% of factory value");
    Serial.print("y-axis self test: gyration trim within : ");
    Serial.print(myIMU.SelfTest[4],1); Serial.println("% of factory value");
    Serial.print("z-axis self test: gyration trim within : ");
    Serial.print(myIMU.SelfTest[5],1); Serial.println("% of factory value");

    // Calibrate gyro and accelerometers, load biases in bias registers
    myIMU.calibrateMPU9250(myIMU.gyroBias, myIMU.accelBias);

#ifdef LCD
    display.clearDisplay();

    display.setCursor(0, 0); display.print("MPU9250 bias");
    display.setCursor(0, 8); display.print(" x   y   z  ");

    display.setCursor(0,  16); display.print((int)(1000*accelBias[0]));
    display.setCursor(24, 16); display.print((int)(1000*accelBias[1]));
    display.setCursor(48, 16); display.print((int)(1000*accelBias[2]));
    display.setCursor(72, 16); display.print("mg");

    display.setCursor(0,  24); display.print(myIMU.gyroBias[0], 1);
    display.setCursor(24, 24); display.print(myIMU.gyroBias[1], 1);
    display.setCursor(48, 24); display.print(myIMU.gyroBias[2], 1);
    display.setCursor(66, 24); display.print("o/s");

    display.display();
    delay(1000);
#endif // LCD

    myIMU.initMPU9250();
    // Initialize device for active mode read of acclerometer, gyroscope, and
    // temperature
    Serial.println("MPU9250 initialized for active data mode....");

    // Read the WHO_AM_I register of the magnetometer, this is a good test of
    // communication
    byte d = myIMU.readByte(AK8963_ADDRESS, WHO_AM_I_AK8963);
    Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX);
    Serial.print(" I should be "); Serial.println(0x48, HEX);

#ifdef LCD
    display.clearDisplay();
    display.setCursor(20,0); display.print("AK8963");
    display.setCursor(0,10); display.print("I AM");
    display.setCursor(0,20); display.print(d, HEX);
    display.setCursor(0,30); display.print("I Should Be");
    display.setCursor(0,40); display.print(0x48, HEX);
    display.display();
    delay(1000);
#endif // LCD

    // Get magnetometer calibration from AK8963 ROM
    myIMU.initAK8963(myIMU.magCalibration);
    // Initialize device for active mode read of magnetometer
    Serial.println("AK8963 initialized for active data mode....");
    if (SerialDebug)
    {
      //  Serial.println("Calibration values: ");
      Serial.print("X-Axis sensitivity adjustment value ");
      Serial.println(myIMU.magCalibration[0], 2);
      Serial.print("Y-Axis sensitivity adjustment value ");
      Serial.println(myIMU.magCalibration[1], 2);
      Serial.print("Z-Axis sensitivity adjustment value ");
      Serial.println(myIMU.magCalibration[2], 2);
    }

#ifdef LCD
    display.clearDisplay();
    display.setCursor(20,0); display.print("AK8963");
    display.setCursor(0,10); display.print("ASAX "); display.setCursor(50,10);
    display.print(myIMU.magCalibration[0], 2);
    display.setCursor(0,20); display.print("ASAY "); display.setCursor(50,20);
    display.print(myIMU.magCalibration[1], 2);
    display.setCursor(0,30); display.print("ASAZ "); display.setCursor(50,30);
    display.print(myIMU.magCalibration[2], 2);
    display.display();
    delay(1000);
#endif // LCD
  } // if (c == 0x71)
  else
  {
    Serial.print("Could not connect to MPU9250: 0x");
    Serial.println(c, HEX);
    while(1) ; // Loop forever if communication doesn't happen
  }
}

void loop()
{
  // If intPin goes high, all data registers have new data
  // On interrupt, check if data ready interrupt
  if (myIMU.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01)
  {
    myIMU.readAccelData(myIMU.accelCount);  // Read the x/y/z adc values
    myIMU.getAres();

    // Now we'll calculate the accleration value into actual g's
    // This depends on scale being set
    myIMU.ax = (float)myIMU.accelCount[0]*myIMU.aRes; // - accelBias[0];
    myIMU.ay = (float)myIMU.accelCount[1]*myIMU.aRes; // - accelBias[1];
    myIMU.az = (float)myIMU.accelCount[2]*myIMU.aRes; // - accelBias[2];

    myIMU.readGyroData(myIMU.gyroCount);  // Read the x/y/z adc values
    myIMU.getGres();

    // Calculate the gyro value into actual degrees per second
    // This depends on scale being set
    myIMU.gx = (float)myIMU.gyroCount[0]*myIMU.gRes;
    myIMU.gy = (float)myIMU.gyroCount[1]*myIMU.gRes;
    myIMU.gz = (float)myIMU.gyroCount[2]*myIMU.gRes;

    myIMU.readMagData(myIMU.magCount);  // Read the x/y/z adc values
    myIMU.getMres();
    // User environmental x-axis correction in milliGauss, should be
    // automatically calculated
    myIMU.magbias[0] = +470.;
    // User environmental x-axis correction in milliGauss TODO axis??
    myIMU.magbias[1] = +120.;
    // User environmental x-axis correction in milliGauss
    myIMU.magbias[2] = +125.;

    // Calculate the magnetometer values in milliGauss
    // Include factory calibration per data sheet and user environmental
    // corrections
    // Get actual magnetometer value, this depends on scale being set
    myIMU.mx = (float)myIMU.magCount[0]*myIMU.mRes*myIMU.magCalibration[0] -
               myIMU.magbias[0];
    myIMU.my = (float)myIMU.magCount[1]*myIMU.mRes*myIMU.magCalibration[1] -
               myIMU.magbias[1];
    myIMU.mz = (float)myIMU.magCount[2]*myIMU.mRes*myIMU.magCalibration[2] -
               myIMU.magbias[2];
  } // if (readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01)

  // Must be called before updating quaternions!
  myIMU.updateTime();

  // Sensors x (y)-axis of the accelerometer is aligned with the y (x)-axis of
  // the magnetometer; the magnetometer z-axis (+ down) is opposite to z-axis
  // (+ up) of accelerometer and gyro! We have to make some allowance for this
  // orientationmismatch in feeding the output to the quaternion filter. For the
  // MPU-9250, we have chosen a magnetic rotation that keeps the sensor forward
  // along the x-axis just like in the LSM9DS0 sensor. This rotation can be
  // modified to allow any convenient orientation convention. This is ok by
  // aircraft orientation standards! Pass gyro rate as rad/s
//  MadgwickQuaternionUpdate(ax, ay, az, gx*PI/180.0f, gy*PI/180.0f, gz*PI/180.0f,  my,  mx, mz);
  MahonyQuaternionUpdate(myIMU.ax, myIMU.ay, myIMU.az, myIMU.gx*DEG_TO_RAD,
                         myIMU.gy*DEG_TO_RAD, myIMU.gz*DEG_TO_RAD, myIMU.my,
                         myIMU.mx, myIMU.mz, myIMU.deltat);

  if (!AHRS)
  {
    myIMU.delt_t = millis() - myIMU.count;
    if (myIMU.delt_t > 500)
    {
      if(SerialDebug)
      {
        // Print acceleration values in milligs!
        Serial.print("X-acceleration: "); Serial.print(1000*myIMU.ax);
        Serial.print(" mg ");
        Serial.print("Y-acceleration: "); Serial.print(1000*myIMU.ay);
        Serial.print(" mg ");
        Serial.print("Z-acceleration: "); Serial.print(1000*myIMU.az);
        Serial.println(" mg ");

        // Print gyro values in degree/sec
        Serial.print("X-gyro rate: "); Serial.print(myIMU.gx, 3);
        Serial.print(" degrees/sec ");
        Serial.print("Y-gyro rate: "); Serial.print(myIMU.gy, 3);
        Serial.print(" degrees/sec ");
        Serial.print("Z-gyro rate: "); Serial.print(myIMU.gz, 3);
        Serial.println(" degrees/sec");

        // Print mag values in degree/sec
        Serial.print("X-mag field: "); Serial.print(myIMU.mx);
        Serial.print(" mG ");
        Serial.print("Y-mag field: "); Serial.print(myIMU.my);
        Serial.print(" mG ");
        Serial.print("Z-mag field: "); Serial.print(myIMU.mz);
        Serial.println(" mG");

        myIMU.tempCount = myIMU.readTempData();  // Read the adc values
        // Temperature in degrees Centigrade
        myIMU.temperature = ((float) myIMU.tempCount) / 333.87 + 21.0;
        // Print temperature in degrees Centigrade
        Serial.print("Temperature is ");  Serial.print(myIMU.temperature, 1);
        Serial.println(" degrees C");
      }

#ifdef LCD
      display.clearDisplay();
      display.setCursor(0, 0); display.print("MPU9250/AK8963");
      display.setCursor(0, 8); display.print(" x   y   z  ");

      display.setCursor(0,  16); display.print((int)(1000*myIMU.ax));
      display.setCursor(24, 16); display.print((int)(1000*myIMU.ay));
      display.setCursor(48, 16); display.print((int)(1000*myIMU.az));
      display.setCursor(72, 16); display.print("mg");

      display.setCursor(0,  24); display.print((int)(myIMU.gx));
      display.setCursor(24, 24); display.print((int)(myIMU.gy));
      display.setCursor(48, 24); display.print((int)(myIMU.gz));
      display.setCursor(66, 24); display.print("o/s");

      display.setCursor(0,  32); display.print((int)(myIMU.mx));
      display.setCursor(24, 32); display.print((int)(myIMU.my));
      display.setCursor(48, 32); display.print((int)(myIMU.mz));
      display.setCursor(72, 32); display.print("mG");

      display.setCursor(0,  40); display.print("Gyro T ");
      display.setCursor(50,  40); display.print(myIMU.temperature, 1);
      display.print(" C");
      display.display();
#endif // LCD

      myIMU.count = millis();
      digitalWrite(myLed, !digitalRead(myLed));  // toggle led
    } // if (myIMU.delt_t > 500)
  } // if (!AHRS)
  else
  {
    // Serial print and/or display at 0.5 s rate independent of data rates
    myIMU.delt_t = millis() - myIMU.count;

    // update LCD once per half-second independent of read rate
    if (myIMU.delt_t > 500)
    {
      if(SerialDebug)
      {
        Serial.print("ax = "); Serial.print((int)1000*myIMU.ax);
        Serial.print(" ay = "); Serial.print((int)1000*myIMU.ay);
        Serial.print(" az = "); Serial.print((int)1000*myIMU.az);
        Serial.println(" mg");

        Serial.print("gx = "); Serial.print( myIMU.gx, 2);
        Serial.print(" gy = "); Serial.print( myIMU.gy, 2);
        Serial.print(" gz = "); Serial.print( myIMU.gz, 2);
        Serial.println(" deg/s");

        Serial.print("mx = "); Serial.print( (int)myIMU.mx );
        Serial.print(" my = "); Serial.print( (int)myIMU.my );
        Serial.print(" mz = "); Serial.print( (int)myIMU.mz );
        Serial.println(" mG");

        Serial.print("q0 = "); Serial.print(*getQ());
        Serial.print(" qx = "); Serial.print(*(getQ() + 1));
        Serial.print(" qy = "); Serial.print(*(getQ() + 2));
        Serial.print(" qz = "); Serial.println(*(getQ() + 3));
      }

// Define output variables from updated quaternion---these are Tait-Bryan
// angles, commonly used in aircraft orientation. In this coordinate system,
// the positive z-axis is down toward Earth. Yaw is the angle between Sensor
// x-axis and Earth magnetic North (or true North if corrected for local
// declination, looking down on the sensor positive yaw is counterclockwise.
// Pitch is angle between sensor x-axis and Earth ground plane, toward the
// Earth is positive, up toward the sky is negative. Roll is angle between
// sensor y-axis and Earth ground plane, y-axis up is positive roll. These
// arise from the definition of the homogeneous rotation matrix constructed
// from quaternions. Tait-Bryan angles as well as Euler angles are
// non-commutative; that is, the get the correct orientation the rotations
// must be applied in the correct order which for this configuration is yaw,
// pitch, and then roll.
// For more see
// http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
// which has additional links.
      myIMU.yaw   = atan2(2.0f * (*(getQ()+1) * *(getQ()+2) + *getQ() *
                    *(getQ()+3)), *getQ() * *getQ() + *(getQ()+1) * *(getQ()+1)
                    - *(getQ()+2) * *(getQ()+2) - *(getQ()+3) * *(getQ()+3));
      myIMU.pitch = -asin(2.0f * (*(getQ()+1) * *(getQ()+3) - *getQ() *
                    *(getQ()+2)));
      myIMU.roll  = atan2(2.0f * (*getQ() * *(getQ()+1) + *(getQ()+2) *
                    *(getQ()+3)), *getQ() * *getQ() - *(getQ()+1) * *(getQ()+1)
                    - *(getQ()+2) * *(getQ()+2) + *(getQ()+3) * *(getQ()+3));
      myIMU.pitch *= RAD_TO_DEG;
      myIMU.yaw   *= RAD_TO_DEG;
      // Declination of SparkFun Electronics (40°05'26.6"N 105°11'05.9"W) is
      //    8° 30' E  ± 0° 21' (or 8.5°) on 2016-07-19
      // - http://www.ngdc.noaa.gov/geomag-web/#declination
      myIMU.yaw   -= 8.5;
      myIMU.roll  *= RAD_TO_DEG;

      if(SerialDebug)
      {
        Serial.print("Yaw, Pitch, Roll: ");
        Serial.print(myIMU.yaw, 2);
        Serial.print(", ");
        Serial.print(myIMU.pitch, 2);
        Serial.print(", ");
        Serial.println(myIMU.roll, 2);

        Serial.print("rate = ");
        Serial.print((float)myIMU.sumCount/myIMU.sum, 2);
        Serial.println(" Hz");
      }

#ifdef LCD
      display.clearDisplay();

      display.setCursor(0, 0); display.print(" x   y   z  ");

      display.setCursor(0,  8); display.print((int)(1000*myIMU.ax));
      display.setCursor(24, 8); display.print((int)(1000*myIMU.ay));
      display.setCursor(48, 8); display.print((int)(1000*myIMU.az));
      display.setCursor(72, 8); display.print("mg");

      display.setCursor(0,  16); display.print((int)(myIMU.gx));
      display.setCursor(24, 16); display.print((int)(myIMU.gy));
      display.setCursor(48, 16); display.print((int)(myIMU.gz));
      display.setCursor(66, 16); display.print("o/s");

      display.setCursor(0,  24); display.print((int)(myIMU.mx));
      display.setCursor(24, 24); display.print((int)(myIMU.my));
      display.setCursor(48, 24); display.print((int)(myIMU.mz));
      display.setCursor(72, 24); display.print("mG");

      display.setCursor(0,  32); display.print((int)(myIMU.yaw));
      display.setCursor(24, 32); display.print((int)(myIMU.pitch));
      display.setCursor(48, 32); display.print((int)(myIMU.roll));
      display.setCursor(66, 32); display.print("ypr");

    // With these settings the filter is updating at a ~145 Hz rate using the
    // Madgwick scheme and >200 Hz using the Mahony scheme even though the
    // display refreshes at only 2 Hz. The filter update rate is determined
    // mostly by the mathematical steps in the respective algorithms, the
    // processor speed (8 MHz for the 3.3V Pro Mini), and the magnetometer ODR:
    // an ODR of 10 Hz for the magnetometer produce the above rates, maximum
    // magnetometer ODR of 100 Hz produces filter update rates of 36 - 145 and
    // ~38 Hz for the Madgwick and Mahony schemes, respectively. This is
    // presumably because the magnetometer read takes longer than the gyro or
    // accelerometer reads. This filter update rate should be fast enough to
    // maintain accurate platform orientation for stabilization control of a
    // fast-moving robot or quadcopter. Compare to the update rate of 200 Hz
    // produced by the on-board Digital Motion Processor of Invensense's MPU6050
    // 6 DoF and MPU9150 9DoF sensors. The 3.3 V 8 MHz Pro Mini is doing pretty
    // well!
      display.setCursor(0, 40); display.print("rt: ");
      display.print((float) myIMU.sumCount / myIMU.sum, 2);
      display.print(" Hz");
      display.display();
#endif // LCD

      myIMU.count = millis();
      myIMU.sumCount = 0;
      myIMU.sum = 0;
    } // if (myIMU.delt_t > 500)
  } // if (AHRS)
}

```

# Answer
The fix found - wrong bootloader was flashed in the Arduino Pro Micro chip. Had to reflash it using AVR ISP mk2 and Arduino IDE. So if you got something like and your board is not genuine SparkFun Pro Micro - then reflash the bootloader.
> 1 votes

---
Tags: arduino-pro-micro, imu
---


# Question
Title: How does DDRD |= _BV(PD2) differ from digitalWrite(2,HIGH)?
I'm attempting to copycat the work of Louis Frigon's Toyota Aux Enabler. I have (with a lot of help on this site) managed to begin capturing and understanding messages on the AVC-LAN bus, but I can't quite send messages. Frigon uses the following line to drive output signal to high:

```
DDRD |= _BV(PD2) | _BV(PD3);

```

I have more or less no idea what this means. He then 'releases the output' with the following:

```
DDRD &= ~( _BV(PD2) | _BV(PD3) );

```

If I copy these lines verbatim I don't get the same results. If I set the output high and then read the bus, I don't even see the signal I'm putting out. I wonder if this is related to the differences between his Atmega8 and my Arduino Nano?

I can't paste my or Frigon's work here due to character count limitations, so here is his github for the project: https://github.com/halleysfifthinc/Toyota-AVC-LAN

The most important files to my question are BigSchematic.jpg and AVCLanDriver.c.

Here is a dump of my current code: https://pastebin.com/NG9U5FuL

Here is my schematic: https://i.stack.imgur.com/csiVv.jpg

# Answer
> 1 votes
Each port on the ATmega328P (or the ATmega8 for that matter) is controlled by two registers¹:

* `DDRx`, where x is B, C or D, is the “data direction register”. It is used to set the pin to either input or output. Writing to this register is roughly equivalent to calling `pinMode()`.
* `PORTx` is the port's “data register”. It is mostly used in output mode to set the pin to `HIGH` or `LOW`. Writing to this register is equivalent to calling `digitalWrite()`.

All this is covered by the Arduino tutorial on direct port access. And, of course, by the datasheet; more specifically by section 18.2: “Ports as General Digital I/O”.

As you may now notice, the original code does not use anything like `digitalWrite()` to write to the bus, relying instead of the equivalent of `pinMode()`. This is related to the electrical characteristics of the bus:

* You write a “physical 1” by actively driving AVC+ high and AVC− low
* You write a “physical 0” by releasing the bus, in which case the potentials of those lines are set by the termination resistors.

That's why you see `InitMCU()` setting `PORTD` for driving AVC+ high and AVC− low, but leaving `DDRD` in its initial state (“leave pins tri-stated” says the comment). At this point the bus is in the “released” state. Then pulses are sent by setting the pins to output mode (“Drive output to signal high” in the comment) and, after an appropriate delay, setting them back to input mode (“Release output”).

---

¹ I am leaving away the details that are irrelevant to the code in question, like the internal pullup or pin toggling via `PINx`.

---
Tags: arduino-ide, avr, wires, can-bus
---


title: Fool Proofing My Arduino IC Checker

text:
# Question
Title: Fool Proofing My Arduino IC Checker
I am creating an IC checker for some high school juniors since a faulty IC can be a nuisance of a bug to find when bread-boarding. These ICs are all simple TTL gating from the 74LS series; the set I am using are all 14-pin and have VCC and GND at pin 14 and 7 respectively.

Thus far my prototype's hardware looks like this:

* 14 digital pins to connect to the IC inputs/outputs
* 1 analog pin reading a joystick to navigate through the IC options
* 1 analog pin set to digital read as a button, which starts the checking process
* 1 analog pin writing to an LED to indicate whether the IC is valid
* 2 analog pins (SDA and SCL) as a serial bus to control my display

I actually have the prototype working for a few ICs, but I am concerned that these high school students may test an IC under the wrong selection. Since the digital pins have to dynamically change input/output depending which IC its checking, this allows for inputs and outputs to be mismatched, which could prove fatal to both the IC and the Arduino board.

I want to know if there is a way to check that inputs and outputs are misaligned without having serious electrical failure. Possible some advanced pin control I am unaware of?

Also, if you could answer my question with an example with the 74LS00, whose pinout is diagrammed below and datasheet can be found here.

# Answer
The simplest way to "fool proof" your system (i.e., to prevent damage by a fool, not make it so it always works right even with a fool) is to add a resistor to each connection. The resistor should be sized so that if an IO pin is HIGH and it's connected to a LOW output on the chip the current flow is below the maximum allowed by both ends.

simulate this circuit – Schematic created using CircuitLab

If D5 is set HIGH and the output of the NAND is LOW the voltage difference (assuming a 5V Arduino) would be around 5V. I=V/R, so 5/1000 is 5mA - way below the maximum of 25mA (40mA burst) of the Arduino.

It won't tell you that you have connected the wrong chip, but it will protect both the chip and the Arduino in such an event.

Since it now doesn't matter if the wrong chip is selected you could in fact cycle automatically through each of the chips testing each on in sequence until you find one that gives the correct results. No need to select a specific one - if no chip matches then it's a faulty chip.
> 3 votes

# Answer
I would connect each of the IC's IO pins to *both* a digital output and a digital (or analog) input of the Arduino, like this:

simulate this circuit – Schematic created using CircuitLab

Drive each pin with the digital output, alternatively `LOW` and `HIGH`. While doing this, read the pin voltage through your input:

* If the IC pin is an input, you will have no significant voltage drop through the protection resistor. Your reading should be `LOW` when driving the pin `LOW` and `HIGH` when driving it `HIGH`.
* If the IC pin is an output, you will have 5 V through the resistor whenever the IC's output value doesn't match your Arduino output. The reading on your input will be independent of the level of your output.

Obviously, an Uno doesn't have enough I/O pins to implement this idea. You could use a Mega instead. Notice also that with this setup you don't need the joystick input: you could just test for every known IC type until you find one that matches the observed behavior, then display the part number on your LCD.
> 4 votes

# Answer
I am tempted to repeat the old engineering trope "You can't make it foolproof - fools are so ingenious".

If you want to proceed, and are prepared for the complexity 2 solutions suggest themselves.

1. Limit the current supplied by the Arduino output if connected to a pin on the IC configured as output.
2. Probably less complex is to test each pin by loading it to 0V and 5V to find which are TTL outputs. A TTL input will unable to source any significant current, while an output will be able to draw current to/from either 0V or 5V.

Either will require quite a bit of additional hardware.

This is not strictly an Arduino problem, but an Arduino would be an ideal solution.
> 1 votes

---
Tags: arduino-uno, pins, digital
---


# Question
Title: How to communicate with GPS SIM900a without Serial Monitor
I am fairly new to Arduino. I was working on a project where I use a GSM SIM900a modem interfaced with an Arduino. The AT commands are sent via the Arduino to the GSM Modem. The problem, however, is that the commands are only sent when I open the Serial Monitor. I have an IR proximity sensor and I would like the AT commands to be sent when the sensor detects an object. I am putting the code for the GSM modem below (I have not yet put in the code for the IR sensor).I want to know how to send the AT commands when the Arduino is hooked up to a battery and not to a PC

```
#include <SoftwareSerial.h>
SoftwareSerial myGsm(7,8);
float temp;
int tempPin = 0;
void setup()
{
 myGsm.begin(9600);
 Serial.begin(9600);
 delay(500);

myGsm.println("AT+CIPSHUT");
 delay(1000);
 printSerialData();

 myGsm.println("AT+CIPMUX=0");
 delay(2000);
 printSerialData();

 myGsm.println("AT+CGATT=1");
 delay(1000);
 printSerialData();

 myGsm.println("AT+CSTT=\"bsnlnet\",\"\",\"\"");//setting the APN,2nd parameter empty works for all networks
 delay(5000);
 printSerialData();

 myGsm.println();
 myGsm.println("AT+CIICR");
 delay(6000);
 printSerialData();

 myGsm.println("AT+CIFSR"); //init the HTTP request
 delay(2000);
 printSerialData();

 myGsm.println("AT+CIPSTART=\"TCP\",\"122.178.80.228\",\"350\"");
 delay(5000);
 printSerialData();
 delay(5000);

 myGsm.println("AT+CIPSEND");
 delay(2000);
 printSerialData();

sendtemp();
delay(3000);
myGsm.println("AT+CIPCLOSE");
printSerialData();

myGsm.println("AT+CIPSHUT");
delay(1000);
printSerialData();
}

void loop()
{
}

void printSerialData()
{
 while(myGsm.available()!=0)
 Serial.write(myGsm.read());
}

void sendtemp()
{
  temp = analogRead(tempPin);
  temp = temp * 0.48828125;
  Serial.print("TEMPERATURE = ");
  Serial.print(temp);
  Serial.print("*C");
  Serial.println();
  delay(5000);
 myGsm.println(temp);
 delay(3000);
 printSerialData();
 myGsm.write(0x1A);
 delay(3000);
   printSerialData();

}

```

# Answer
Well, I too had the same problem until now. The simple way to fix is just to delay the void setup() before Serial communication begins. Add delay(15000); //15 Seconds so that GSM module boots up and connects to the network. And there is no need of changing any part of code. Hope this helps someone out there like me. :)
> 2 votes

---
Tags: arduino-uno, serial, gsm, communication, softwareserial
---


# Question
Title: Play .Wav sound only once on switch change
I have a project where if you change the value of the spdt switch the colour of the LEDs change. As well as this a .wav file plays. The problem is I only want the .wav to play once. At the moment it constantly plays over and over as it's within the loop. I've tried using a mute or disabling the pin after the play through but I am unable to re-enable so I scrapped it. I deally I want to keep the SPDT switch due to asthetics instead of a push switch. This is my code:

```
#include <TMRpcm.h>
#include <SD.h>
#define SD_ChipSelectPin 10
#include <SPI.h>

TMRpcm tmrpcm;

void setup()
{
// put your setup code here, to run once:

tmrpcm.speakerPin=9;
Serial.begin(9600);
if(!SD.begin(SD_ChipSelectPin))
{
  Serial.println("SD fail");
  return;
}
     tmrpcm.setVolume(6);
     tmrpcm.play("1.wav");
     while (tmrpcm.isPlaying()) {
     delay(1);
}
     tmrpcm.setVolume(6);
     tmrpcm.play("3.wav");
//set the switch input, pin 8, as an
pinMode(8, INPUT);

//set both the LED pins, pin 5 and 6 as OUTPUTs
pinMode (5, OUTPUT);
pinMode (6, OUTPUT);
 delay(1000);
}

void loop()
{
 int switchValue = digitalRead(8);
 if (switchValue == 1)
{
   while (tmrpcm.isPlaying()) {
   delay(1);
}
  tmrpcm.setVolume(6);
  tmrpcm.play("4.wav");
  digitalWrite(5,HIGH);
  digitalWrite(6,LOW);

}
else
{
   while (tmrpcm.isPlaying()) {
   delay(1);
}
   digitalWrite(6,HIGH);
   digitalWrite(5,LOW);
   tmrpcm.setVolume(6);
   tmrpcm.play("5.wav");

}
}

```

how can I make the wav play once but when the switch changes?

# Answer
Make a variable to hold the "last state" of the switch. Compare that *last state* to the current state as obtained by `switchValue = digitalRead(8)`.

Only call the play function if the old value and the current value are different.
> 0 votes

---
Tags: switch, sound
---


# Question
Title: Communication over UDP between Dues with Arduino WiFi Shield
I'm using the Arduino WiFi Shield to make two Arduinos Due communicate using UDP. The first node to send a message (the Client) doesn't always receive a reply from the other node (the Server). The code for the Client:

```
#include <string.h>

#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>

#define BUFSZ 90

// variables for WiFi connection
char ssid[] = "ssid";
char pass[] = "pwd";
int status = WL_IDLE_STATUS;

char sendBuffer[BUFSZ];
char recvBuffer[BUFSZ];

WiFiUDP Udp;
unsigned int localPort = 51515;

IPAddress server(192,168,88,251);
unsigned int serverPort = 12345;

void printWifiData()
{
    // print your WiFi shield's IP address:
    IPAddress ip = WiFi.localIP();
    Serial.print("IP Address: ");
    Serial.println(ip);

    // print your MAC address:
    byte mac[6];
    WiFi.macAddress(mac);
    Serial.print("MAC address: ");
    Serial.print(mac[5],HEX);
    Serial.print(":");
    Serial.print(mac[4],HEX);
    Serial.print(":");
    Serial.print(mac[3],HEX);
    Serial.print(":");
    Serial.print(mac[2],HEX);
    Serial.print(":");
    Serial.print(mac[1],HEX);
    Serial.print(":");
    Serial.println(mac[0],HEX);
}

void setup()
{
    Serial.begin(115200);
    while (!Serial); // wait for serial port to connect

    // connect to WiFi network
    while (status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);
        status = WiFi.begin(ssid, pass);
        delay(10000);
    }

    // print connection details
    Serial.println("You're connected to the network");
    printWifiData();

    Udp.begin(localPort);
    strcpy(sendBuffer, "abcdefghijklmnopqrstuvwxyz123456789101112131415161718192021222324252627282930313233343536");
}

void loop()
{
    Udp.beginPacket(server, serverPort);
    int len = Udp.write(sendBuffer);
    Udp.endPacket();

    Serial.print("Sent ");
    Serial.print(len);
    Serial.println(" bytes.");

    delay(10);

    int packetSize = Udp.parsePacket();
    if (packetSize > 0) {
        Serial.print("\nReceived packet of size ");
        Serial.println(packetSize);

        Serial.print("From ");
        IPAddress remoteIp = Udp.remoteIP();
        Serial.print(remoteIp);
        Serial.print(", port ");
        Serial.println(Udp.remotePort());

        // read the packet into recvBuffer
        int len = Udp.read(recvBuffer, BUFSZ);
        if (len > 0) {
            Serial.println("Contents:");
            Serial.println(recvBuffer);
        }
        else {
            Serial.println("Read 0 bytes.");
        }
    }
    else {
        Serial.println("\nNo packets yet.");
    }
}

```

Server:

```
#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>

#define BUFSZ 90

// variables for WiFi connection
char ssid[] = "ssid";
char pass[] = "pwd";
int status = WL_IDLE_STATUS;

char sendBuffer[BUFSZ];
char recvBuffer[] = "acknowledged";

WiFiUDP Udp;
unsigned int localPort = 12345;

void printWifiData()
{
    // print your WiFi shield's IP address:
    IPAddress ip = WiFi.localIP();
    Serial.print("IP Address: ");
    Serial.println(ip);

    // print your MAC address:
    byte mac[6];
    WiFi.macAddress(mac);
    Serial.print("MAC address: ");
    Serial.print(mac[5],HEX);
    Serial.print(":");
    Serial.print(mac[4],HEX);
    Serial.print(":");
    Serial.print(mac[3],HEX);
    Serial.print(":");
    Serial.print(mac[2],HEX);
    Serial.print(":");
    Serial.print(mac[1],HEX);
    Serial.print(":");
    Serial.println(mac[0],HEX);
}

void setup()
{
    Serial.begin(115200);
    while (!Serial); // wait for serial port to connect

    // connect to WiFi network
    while (status != WL_CONNECTED) {
        Serial.print("Attempting to connect to WPA SSID: ");
        Serial.println(ssid);
        status = WiFi.begin(ssid, pass);
        delay(10000);
    }

    // print connection details
    Serial.println("You're connected to the network");
    printWifiData();

    Udp.begin(localPort);
    Serial.println("Waiting...");
}

void loop()
{
    int packetSize = Udp.parsePacket();

    if (packetSize) {
        Serial.print("Received packet of size ");
        Serial.println(packetSize);

        Serial.print("From ");
        IPAddress remoteIp = Udp.remoteIP();
        Serial.print(remoteIp);
        Serial.print(", port ");
        Serial.println(Udp.remotePort());

        // read the packet into recvBuffer
        int len = Udp.read(recvBuffer, BUFSZ);
        if (len > 0) {
            Serial.println("\nContents:");
            Serial.println(recvBuffer);

            Udp.beginPacket(Udp.remoteIP(), 51515);
            Udp.write(sendBuffer);
            Udp.endPacket();
        }
        else {
            Serial.println("Read 0 bytes.");
        }
    }
}

```

I don't know if it's a timing problem... So I've tried to use delays after the Client send its message but the issue persists. So the Client sends many messages to the Server but receives few replies. I didn't want to put the part of the code in the Client when it's waiting for a response inside a loop in case the first message is lost (so the Client will never receive a response anyway). Did anyone have a simular problem or a suggestion to fix this issue?

# Answer
I was able to solve the problem. First of all, I needed a bigger delay between the send and receive parts in the Client.

So I'm using `delay(35);`. This is important so the Client can have enough time to receive the reply before sending another message.

Also, inside the Server, the buffers to send and receive a packet were inverted.

So, the correct would be:

```
char sendBuffer[] = "acknowledged";
char recvBuffer[BUFSZ];

```

I understand the messages can stil be lost because UDP does not guarantee delivery, but with a larger delay in an isolated WiFi network all of the messages from the Client got a reply.
> 1 votes

---
Tags: wifi, arduino-due, shields
---


# Question
Title: Is it possible for ESP8266WiFi client to request the number of clients currently connected to Access Point?
My system consists of several ESP8266 based 'stations', which are synchronised in a way that all of them go into deep sleep and wake up on the same schedule. All stations are WiFi clients. All stations run on batteries and energy saving is critical.

One of the stations is a Master. It contains a modem/router that serves as AP to all stations. The AP is switched OFF during the sleep phase. When a Master wakes up it switches on the AP and thus starts a communication session available to all stations. When all stations have their data sessions completed and disconnect from AP, the Master switches off the modem/router and goes to sleep.

My question is about the Master being informed that there are no other clients actively connected to the AP. My current solution is WAN based - each station reports to the Web Service on the start and end of their connection. Is it possible to achieve the same result locally - by a request from the WiFi client to the Access Point?

# Answer
Use `WiFi.softAPgetStationNum()` to return the number of clients connected to an ESP8266 AP.
> 1 votes

---
Tags: esp8266, wifi
---


# Question
Title: How to calculate actual Baud Rate and its percent error?
I am using an Arduino Uno, and I need to create a program that calculates the actual baud rate and the percent error for all standard baud rate in Arduino monitor program.

# Answer
First, look at the code used by the Arduino core library to configure the USART baud rate register: it's in `HardwareSerial::begin()`. The general formula is

```
uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;

```

but beware of the hard-coded exception. You can replicate that part of the code in your own.

Then, look at the ATmega328P datasheet. More specifically, at section 24.4.1. Internal Clock Generation – The Baud Rate Generator. Here you find the formula

```
BAUD = F_CPU / (8*(UBRR0 + 1))

```

assuming the `U2X0` bit has been set (again, beware of the hard-coded exception). Combine both formulas and you get the actual baud rate.
> 1 votes

---
Tags: arduino-uno, programming, c, baud-rate, calculation
---


title: LED blinking count with LDR sensor

text:
# Question
Title: LED blinking count with LDR sensor
How to count +1 all the time if LED blinks with LDR sensor

Image:

If i turn on led it must count into serial monitor 1 and if i turn off led and turn on again then it counts 2.

To turn on led I must put my hand into LDR sensor.

It also looping text in serial monitor "First LDR sensor is Dark".

```
int ledPin1 = 7;
int ledPin2 = 8;
int ledPin3 = 9;
int ldrPin1 = A0;
int ldrPin2 = A1;
int ledTest = 200;
int ldrStatus1 = 0;
int ldrStatus2 = 0;
int ledCheck1 = 0;
int ledCheck2 = 0;
int Count = 0;

void setup() {

  Serial.begin(9600);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);

  pinMode(ldrPin1, INPUT);
  pinMode(ldrPin2, INPUT);
}

void loop() {

  ldrStatus1 = analogRead(ldrPin1);
  ldrStatus2 = analogRead(ldrPin2);

   if (ldrStatus1 <= ledTest) {
    digitalWrite(ledPin1, HIGH);
    Serial.println("First LDR is Dark");
    ledCheck1 = 1;
    Count++;
    Serial.println(Count);
   } else {
    digitalWrite(ledPin1, LOW);
    ledCheck1 = 0;
   }

   if (ldrStatus2 <= ledTest) {
    digitalWrite(ledPin3, HIGH);
    Serial.println("Second LDR is Dark");
    ledCheck2 = 1;
    Count++;
    Serial.println(Count);
   } else {
    digitalWrite(ledPin3, LOW);
    ledCheck2 = 0;
   }

   if ((ledCheck1 == 1) && (ledCheck2 == 1)) {
    digitalWrite(ledPin2, HIGH);
    Count++;
    Serial.println(Count);
   } else {
    digitalWrite(ledPin2, LOW);
   }

}

```

At the moment it counts when it is turned on, like seconds.. How to fix or make it work correctly?

# Answer
Use state change detection and hysteresis for counting pulses in an analog signal.

```
const int lowerThreshold = 150;
const int upperThreshold = 200;

const uint8_t analogPin = A0;
const uint8_t ledPin = LED_BUILTIN;

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  static bool state = LOW;
  static unsigned int counter = 0;

  int analogValue = analogRead(analogPin);
  if (state == HIGH) {
    if (analogValue < lowerThreshold) {
      state = LOW;
      counter++;
      Serial.println(counter);
      digitalWrite(ledPin, LOW);
    }
  } else { // state == LOW
    if (analogValue > upperThreshold) {
      state = HIGH;
      digitalWrite(ledPin, HIGH);
    }
  }
}

```

This sketch basically applies a software Schmitt trigger to the analog input signal, and increments the counter on each falling edge. (Rising edge of light intensity, because your LDR configuration inverts the signal.)

The red waveform is the analog input from the LDR. The gray rectangular wave is the `state` (and the state of the LED). The counter is incremented at each black, vertical dashed line.
> 1 votes

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


# Question
Title: Can I use atmega328P without capacitors?
I need to use atmega328P without arduino board, so far I know that I will need `16MHZ Quartz Resonator` and two `22nf capacitors`. However, I have seen that other people are using atmega328P without capacitors.

What is the role of those capacitors? Can I use atmega328P without capacitors?

# Answer
> 4 votes
Those specific capacitors form part of the resonant clock oscillator circuit. If you are using a quartz crystal then they are required. You can't do without them.

If you use a 16MHz *ceramic resonator*, however, they don't need the capacitors (they're built into the resonator).

Also, if you have your ATMega328P on a breadboard the capacitance of the board itself is sometimes enough to "get it working", though as soon as you transfer your circuit to a permanent PCB it will suddenly stop working for no apparent reason.

---
Tags: atmega328
---


# Question
Title: Blink without delay for 5 times every 20 seconds
I'm trying to write a blink without delay code that will wait 20 seconds, then blink 5 times, then wait another 20 seconds - rinse and repeat.

Here's the minimal code I wrote:

```
if (currentTime % 20000 == 0) {
  for (int x = 0; x <= 5; x++) {
    if (currentTime % 500 == 0) {
      if (solenoid == LOW) {
        solenoid = HIGH;
      }   else {
        solenoid = LOW;
      }
      digitalWrite(solenoidpin, solenoid);
    }
  }
}
}

```

All this seems to do is set solenoid to HIGH and keep it there. If I get rid of the for loop and the second if statement, I can get it to switch between low and high every 20 seconds, but adding the if and for loops seems to kill it. Any thoughts on how to make this work?

# Answer
Here is a solution:

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

#define INTERVAL 20000L
#define BLINK_TIMES 5
void loop()
{
    static unsigned long lastBlink = 0;
    static int count = 0;

    unsigned long now = millis();

    if(count > 0) {
        count -= blink();
        lastBlink = now;
    } else {
        if(now - lastBlink >= INTERVAL) {
            count = BLINK_TIMES;
        }
    }
}

/*
 * Do one blink.
 * Return 1 when blink is done.
 */
int blink()
{
  static unsigned long lastFlip = 0;
  static int count = 0;
  bool last = false;

  unsigned long now = millis();

  if(now - lastFlip >= 500) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    Serial.print(now / 1000); Serial.print(". "); Serial.println("blink");
    lastFlip = now;
    count++;
    if (count == 2) {
      count = 0;
      last = true;
      }
   }

   return (last) ? 1 : 0 ;
}

```

The `count` variable controls when to blink and how many times. While it's zero, no blinking.

When not blinking, it keeps comparing actual time with the last time it blinked. When the time exceed 20s, it puts `count` to five, and in the next loop, the blinking start.

Variables are declared `static` so they keep their values between `loop` executions.
> 3 votes

# Answer
```
// assuming blinking is 500ms ON, 500ms OFF, so 4500ms for 5 blinks.

int tick = (currentTime/500) % 49;
// if one tick is 500ms, that means,
//    1 tick ON, 1 tick OFF, 1 tick ON, ... , 1 tick ON, 40 ticks OFF (for a total of 49 ticks)
if( ( tick < 5*2 ) && ( tick%2==0 ) )// only turn ON the led on the first 10 ticks (5 ON; 5 OFF)
                                     //  and only if the number of ticks is ODD
    digitalWrite(solenoidpin, HIGH);
else
    digitalWrite(solenoidpin, LOW);

```

What I did was convert the milliseconds in to `ticks` of 500 ms. Then based on the `tick` value, update the led.

PS I tested it on a Arduino Pro Mini
> 3 votes

---
Tags: arduino-uno
---


# Question
Title: Controlling multiple solenoids with arduino
I was wondering how I could connect multiple 12v solenoids (more than the 53 allowed on mega because of the pins) on the Arduino Mega 2560 to get it to control the keys on a piano/keyboard/organ. Would 74HC595 shift register work for it with the 12v? (Many of them) Because there are so many high voltage solenoids is it possible to control a few of them at a time? I was wondering if someone has a link to somewhere that I could refer to. Thanks

# Answer
> 2 votes
Arduino I/O pins, and the output pins of 74HC595 shift registers are logic-level outputs, and are not intended to drive power-hungry items like solenoids. In either case (direct I/O or shift registers) you need to use the logic signal from the output pin to drive *something else* that switches the 12V source.

That *something else* can be a MOSFET or a relay, though often even relay coils are themselves driven by a MOSFET or other transistor that is switched by a microcontroller output pin.

One of the many search results that describe this is at http://hades.mech.northwestern.edu/index.php/Driving\_using\_a\_single\_MOSFET

# Answer
> 1 votes
the shift register has 2 features that will help you:

1. a latch pin. When a the storage register pin is kept low the outputs won't change this allows you to shift in a new value without perturbing the outputs.
2. a Qh' output this is the output from the last bit that bypasses the normal output. If you connect that to the next shift register you can daisy chain several registers.

The outputs of the chip are not meant to driver significant currents. Instead use them to drive a mosfet that in turn drives the relay. There are boards that contain all the support circuitry needed to drive relays using low power signals.

---
Tags: arduino-mega
---


# Question
Title: Connect Arduino to Socket IO Webserver via Esp8266
As part of a project I want to receive data on my arduino uno via a sensor, which is working fine. This data should be sent to a webserver where a node js with socket io is running. Therefore i bought a esp8266 and the corresponding adapter (https://www.amazon.de/gp/product/B01LZLVEJ4/ref=oh\_aui\_detailpage\_o00\_s00?ie=UTF8&psc=1).

In the IDE I have the following code:

```
    #include <SoftwareSerial.h>

    SoftwareSerial esp8266(2, 3);

    void setup() {
      // Open serial communications and wait for port to open:
      Serial.begin(115200);
      while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
      }

      Serial.println("Started");

      // set the data rate for the SoftwareSerial port
      esp8266.begin(115200);
    }

    void loop() {
      if (esp8266.available()) {
        Serial.write(esp8266.read());
      }
      if (Serial.available()) {
        esp8266.write(Serial.read());
      }

    }

```

I use the serial monitor to perform my AT Commands and it seems to work some times, however there seems to be a problem with the output, for example if I type the command AT+CWLAP to display the Access Points. If I do so, it outputs something like:

```
    +CWLAP:(3,"WLAN-32CC39",-73,"10:c6:0f:2c:32:cc",1,65,0)
    +CWLAP:(3,"F1e:,:oMc:0(x8:1LN⸮⸮⸮:b),k7:,(-,36Ao-2,
    (e0e,C".66,Cwe8:"+L,:"+27:6L W79",944,Ab,::0(ot230( -5,CTO940PBc,63+3y8:")3,dc3
    "P4-ze6P!"80,3716

```

I should also note, that even if I input the same, the response differs, and sometimes it is just single characters that are wrong, e.g. "wigi" instead of "wifi". I tried different baud's for the esp8266 but the current one produces the least problems. So my questions here are:

1: Is there anything I am currently doing wrong while connecting to my local wifi network?

2: If there is a connection made, is there any way to connect to a socket io server as a client? Most Tutorials I have found have the arduino as a server. However, I want to have it as a client which communicates to a server. Therefore it should both be able to send and receive messages to/from the server.

Thanks in advance!

# Answer
### Using the ESP8266 in general

The easiest, most flexible, and most efficient way is to program the ESP8266 directly.
If it is possible, have it replace the Arduino entirely. To do this, it is best to get an ESP8266 development board that breaks out all IO pins and has a USB interface for easy programming. Programming these development boards is just like programming an Arduino: plug in the USB connection and hit upload in the Arduino IDE. One of my favourites is the WeMos D1 mini (around $3.50 from China).
The ESP8266 is a very powerful microcontroller on its own: it has a 32-bit processor that runs 10 times faster than an Arduino Uno, it has up to 4MB of flash memory (vs 32KB on the Uno), 160KB of RAM (vs 2KB on the Uno). It has 11 digital IO pins, an analog input, support for I²C, SPI, PWM, etc., just like an Arduino. If you use AT commands, you don't use its full potential.

### Your specific situation

Given that you already bought an ESP-01 + adapter that only gives you access to the UART, connecting the sensor to the ESP directly is probably not possible.
In this case, you can do one of three things:

1) Program the ESP8266 directly: Write a program that just reads a number from the serial port, and sends it to the server over WiFi.
This is the easiest, because you can use all features of the ESP8266, and you don't have to change the program that you wrote for the Arduino (it should just measure the sensor value, and send it to the ESP8266 over the serial port, this is exactly the same as sending it to the serial monitor on your computer).

2) Don't program the ESP8266, but use an AT commands library on the Arduino. (For example WiFiEsp)
The downside is that you have to make significant changes to your Arduino sketch, and that you cannot use all of the functions and resources of the ESP.

3) Control the ESP8266 using AT commands yourself, without any libraries.
This is very cumbersome, and is a complete waste of time, IMHO.

### Practical

*Programming the ESP8266 directly*
To program the ESP8266 directly (both with an Arduino and stand-alone), you need a USB-to-Serial converter. You can either use something like an FT232 (3.3V) or an Arduino. How to program it is covered here. If you use an Arduino as USB-to-Serial adapter, the right connections are TX-TX, RX-RX.

*Using AT commands or an AT commands library*
If your Arduino has a hardware UART that is not used for programming the Arduino (e.g. Arduino Mega, Arduino Leonardo, Arduino Due, ...), you can use this UART for communicating with the ESP8266. The right connections are TX-RX, RX-TX. You can use any baud rate that's supported by both devices (9600 - 921600).
If your Arduino doesn't have an extra hardware UART, you'll have to use the UART on pins 0 and 1, that's used for programming, and you'll have to disconnect the ESP8266 every time you upload new firmware to the Arduino.
Alternatively, you can use SoftwareSerial. Keep in mind that this is far from an optimal solution, as it uses a lot of resources, it is very slow, and data might get corrupted if you spend a lot of time in interrupts on the Arduino.
To use the ESP8266 with SoftwareSerial, you need to lower the baud rate to 9600 baud. To do this, first upload an empty sketch (bare minimum) to the Arduino to make sure that the hardware UART is not used. Then connect the ESP8266 to pins 0 and 1: TX-TX, RX-RX.
Open the Serial Monitor from the Arduino IDE, and select the baud rate that the ESP8266 is currently operating at. (This is probably 115200, but it could be something else.) Select "Both NL + CR" as the line ending, and send "AT" (without the quotes) to verify that it is working. If everything works, it should answer with "OK". If it doesn't, check your hardware, or try a different baud rate. Finally, send "AT+UART\_DEF=9600,8,1,0,0" to set the baud rate to 9600 baud. Then change the baud rate of the serial monitor to 9600 as well. Send "AT" again to verify that it is working.
Now you can connect the ESP8266 to the SoftwareSerial pins, using a baud rate of 9600 baud.

*Edit*: The WebSocket protocol is not supported using AT commands, so you have no other choice but to program the ESP8266 directly.
> 1 votes

---
Tags: esp8266, wifi, softwareserial, web-server, baud-rate
---


title: Using different ADC channels

text:
# Question
Title: Using different ADC channels
How could the same code be used with different ADC channels?

```
const byte adcPin = 0;  // A0

const int MAX_RESULTS = 100;

volatile int resultsV [MAX_RESULTS];
volatile int resultsI [MAX_RESULTS];

volatile int resultNumber;

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

  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  TCCR1B = bit (CS11) | bit (WGM12);  // CTC, prescaler of 8
  TIMSK1 = bit (OCIE1B);
  OCR1A = 338;
  OCR1B = 338;   // 39 = 20 uS - sampling frequency 50 kHz

  ADCSRA =  bit (ADEN) | bit (ADIE) | bit (ADIF);   // turn ADC on, want interrupt on completion
  ADCSRA |= bit (ADPS2);  // Prescaler of 16
  //  ADCSRA |= (1 << ADPS1) | (1 << ADPS0);    // 8 prescaler for 153.8 KHz
  ADMUX = bit (REFS0) | (adcPin & 7);
  ADCSRB = bit (ADTS0) | bit (ADTS2);  // Timer/Counter1 Compare Match B
  ADCSRA |= bit (ADATE);   // turn on automatic triggering
}

// ADC complete ISR
ISR (ADC_vect)
{
  resultsV[resultNumber++] = ADC;

  //resultsI[resultNumber++] = ADC;

  if (resultNumber == MAX_RESULTS)
  {
    ADCSRA = 0;  // turn off ADC
  }
}

EMPTY_INTERRUPT (TIMER1_COMPB_vect);

void loop () {

  while (resultNumber < MAX_RESULTS)
  { }

  for (int i = 0; i < MAX_RESULTS; i++)
  {
    Serial.print( resultsV);
    Serial.print("   ");
    Serial.print( resultsI);
    Serial.println();
  }
  resultNumber = 0;
  ADCSRA =  bit (ADEN) | bit (ADIE) | bit (ADIF) | bit (ADPS2) | bit (ADATE);
  // turn ADC back on
}

```

# Answer
> 1 votes
From what I understand, you want to read *two* ADC channels simultaneously. First, you have to understand that you cannot read them exactly at the same time, as you have a single ADC. What you can do, however, is read them one after the other: you read the V channel, then the I channel, then the V channel again, etc. This means you will have to change the multiplexer setting (the `ADMUX` register) in between the readings. The most convenient place to do this is within the ADC ISR, the logic of which becomes:

1. Save the value that has just been read
2. switch the multiplexer to the other channel
3. turn off the ADC if you are done.

Example code (not tested):

```
const byte PIN_V = 0;  // A0
const byte PIN_I = 1;  // A1

// ADC complete ISR.
ISR(ADC_vect)
{
    if (ADMUX & 7 == PIN_V) {
        // We have just read the V channel.
        // Save the value and switch to the I channel.
        resultsV[resultNumber] = ADC;
        ADMUX = bit(REFS0) | PIN_I;
    } else {
        // Otherwise we completed a (V, I) pair, we can increment
        // resultNumber.
        resultsI[resultNumber++] = ADC;
        ADMUX = bit(REFS0) | PIN_V;
    }

    // Turn off the ADC when done.
    if (resultNumber == MAX_RESULTS)
        ADCSRA = 0;
}

```

Note that this example assumes you do the readings in the (V, I) order. Thus, within `setup()`, you have to initialize the multiplexer for the V channel, as in

```
ADMUX = bit(REFS0) | PIN_V;

```

---
Tags: arduino-uno
---


title: Alternative to UART/I2C LCD displays?

text:
# Question
Title: Alternative to UART/I2C LCD displays?
I'm building a MIDI synthesizer on Arduino Uno, and am considering user interface options.

I see on Adafruit and Sparkfun there are 16x2 LCD panels available that interface via I2C serial or by UART, but I think neither of those will work in my application:

* The UART is clocked at 31250 baud to receive MIDI, and that's not a supported baud rate for these LCD devices;
* I'm producing audio by driving an external DAC (MCP4725) over full-speed I2C; any transmission to another device would audibly jitter the DAC output;
* SoftwareSerial would get around the UART clocking problem, but I believe it would stall the main loop while driving the output.

One option might be to roll my own software serial routine, carefully clocking it on the main loop, which (I believe) reliably runs at either 14.8KHz or 22.2KHz depending on the DAC protocol in use. I could set a SparkFun SerLCD into a slow data rate (2400 baud) and count passes through the main loop to time the data output.

Another option would be to use a secondary MCU -- I have a surplus Trinket M0 on hand -- and define a custom synchronous serial protocol between the two MCUs, and have the secondary relay commands to the LCD but that's getting into Rube Goldberg territory.

Any obvious options I'm overlooking?

# Answer
One obvious option would be to get a display with SPI interface, since you have it available. Another option is to get a DAC running on SPI, and use the I2C for the display.

If you insist on using one of these 16x2 LCDs, there are SPI adapters for them as well. Example
> 1 votes

---
Tags: arduino-uno, i2c, lcd, uart
---


title: Avoid a Pro Micro waking up a PC?

text:
# Question
Title: Avoid a Pro Micro waking up a PC?
I have an Arduino Pro Micro mimicking as a HID, connected to a PC.

The PC BIOS is configured to wake from keyboard events - it is switched on by hitting a key on the regular keyboard. This is a wanted feature and should stay.

Unfortunately, it also wakes when the Arduino sends HID events, which is understandable and pretty obvious, but to be avoided.

Is there something in the USB protocoll, or even in the Arduino HID libraries, that lets me tell the chip to either not wake up the host (unlikely, I guess); or so that I can detect when the PC has shut down, so I can tell the Arduino to go sleeping as well until the PC wakes up again?

EDIT: I am using the "HID-project" USB library (HID 2.4.3) from https://github.com/NicoHood/HID.

# Answer
Assuming you are using windows, on the device manager you can access each device's properties (power management tab), where you can allow or not each device to wake your system up.
> 2 votes

# Answer
Check your BIOS for an option to wake up on a particular key combination, rather than "any key".

Another option is to configure a particular USB port to be powered down when the computer is asleep (or discover which ports are powered down if no such option is available). If that doesn't help, you can try to put a USB hub between the Arduino and the PC: many hubs don't cope with sleep modes very well, so there's a chance they won't re-transmit anything your Arduino is sending unless the PC wakes up. If your computer has USB3, you can try a USB3 hub, which has an even higher chance of exhibiting this behavior since BIOS often lacks USB3 hub support.
> 1 votes

---
Tags: usb, arduino-pro-micro
---


# Question
Title: Can I get the current connection speed with ESP8266?
Using an ESP8266 I can get the RSSI of the Wifi network using `Wifi.getNetworkInfo()` or `Wifi.RSSI()`. But is there a way to know the actual connection speed in Mbps, after joining successfully a WiFi network?

# Answer
> 2 votes
Wifi modules decide on link speed based on signal strength. So you can estimate the link speed with signal strength, which you can get with `WiFi.RSSI(network)`.

The datasheet of ESP8266 contains a table mapping RSSI to link speed under "Sensitivity":

* -98 dBm: 1 Mbps
* -93 dBm: 6 Mbps
* -91 dBm: 11 Mbps
* -75 dBm: 54Mbps
* -71 dBm: 65Mbps, 72.2Mbps

Whenever these values are "minimum", "maximum" or "typical" remains unclear. These dBm limits are also quite low, which means the link speed will probably be capped by the other communication peer (your router). Here's the same table for a random D-link router, DI-624.

---
Tags: esp8266, wifi, speed
---


# Question
Title: Confusion over Transistors for a switching circuit with an Arduino Mega 2560
Apologies if this is a stupid question asked by a noob, but I've looked around to try and find the answer and just can't work it out.

Basically, I'm making a project on thingiverse (Glitch's MK2 Stargate), and I've tried all sorts of different transistors with my circuit, I just can't get it to work properly. Could you please advise which Transistor would work for the following circuit:

It's a basic thing, but the plan I was originally working from on thingiverse called for BC548BU transistors, however, the LEDs they were using were surface mount, and I am trying the same thing with 3mm standard LEDs. The BC548BU didn't work right on the normal LEDs.

I'm a total noob with this, but I've been trying to match the **Base** pin on the Transistor voltage output of my Arduino, but not sure if I'm doing the right thing. Can anybody help?

Thanks -Dave

p.s. I have a load of transistors already (listed below), if any of these work, that would be great, if not, I will order the correct ones. The only one that seemed to match Data with the BC548 is the S9014, but it didn't seem to work at all, unless my understanding of the wiring of Transistors needs adjustment.

# Answer
> 2 votes
A transistor amplifies current, not voltage.

The first thing to check is the current of your LEDs. In your current configuration, it is between 25 and 30 mA. This is too high for most LEDs. Check the datasheet of your LEDs for the actual forward voltage, and current rating.
To calculate the value for the resistor in your circuit, use Kirchhoff's and Ohm's laws. According to Kirchhoff: VResistor \+ 3 VLED = 12 V. Let's assume that the LED's forward voltage drop VLED = 1.8 V. This means that VResistor = 12 V - 3 VLED = 6.6 V. Ohm's law will then tell you the relationship between the voltage across the resistor and the current through it: R = VResistor / I. The current through the resistor is the same as the current through the LEDs. Let's assume that this is 20 mA. Therefore: R = VResistor / I = 6.6 V / 0.020 A = 330 Ω.

The next thing to calculate is the resistor between the Arduino and the base of the transistor. As mentioned before: the voltage on the base does not matter, the current does. You want to use the transistor as a switch, so you have to drive it into saturation. As a general rule of thumb, you want the base current to be a tenth of the collector current in that case: IBase = ICollector / 10. The current through the collector is the same as the current through the LEDs, so IBase = 20 mA / 10 = 2 mA.

In a similar way as before, we can calculate the base resistor: VResistor \+ VBase-Emitter = VArduino. The voltage of the Arduino pin is most likely 5 V, and the Base-Emitter voltage of a silicon transistor is around 700 mV (look it up in the datasheet): VResistor = 5 V - 0.7 V = 4.3 V. Then use Ohm's law again to calculate the resistor value: RBase = VResistor / IBase = 4.3 V / 0.002 A = 2150 Ω ≈ 2.2 kΩ.

The current has to flow *through* the base to the emitter. For current to flow, you need at least two connections: current flows from the Arduino pin, through the transistor, to ground. You have to connect the emitter of the transistor to the Arduino's ground.

You can use pretty much any normal transistor that has a maximum collector current that is larger than the LED current, and a maximum collector-emitter voltage greater than your power supply.

---
Tags: led, transistor, atmega2560, project
---


title: Call by reference

text:
# Question
Title: Call by reference
I am trying to learn 'call by reference'. I want to call a function `fcn1` from the main loop and pass a reference of the local variable `var` to the function `fcn1`. Next step is to call a second function `fcn2` from the function `fcn1` and pass again the reference of the local loop variable `var`. I always get this error massage:

```
invalid conversion from 'int' to 'int*' [-fpermissive]

```

Here a small example code:

```
void fcn1(int *variable)
{
  fcn2(&variable);
}

void fcn2(int *variable)
{
  //do something with the variable
}

void setup()
{

}

void loop()
{
  int var = 1000;
  fcn1(&var);
}

```

I tried to solve that issue by using:

```
void fcn1(int *variable)
{
  fcn2(*variable);
}

```

But it's the same error.

By deleting the `*` respectively `&` it works fine, but is it still a reference?

# Answer
```
void fcn1(int *variable)
{
  fcn2(*variable);
}

```

This function takes a pointer to an integer as parameter, and then passes the value of the integer to the second function.

To do it by reference, use an ampersand (`&`, not to be confused with the address-of operator).

```
void fcn1(int &variable) {
  // Do something to variable
}

```

For example:

```
void increment(int &variable) { // Reference to an integer
  variable++;
}
void setup() {
  Serial.begin(115200);
  int a = 1;
  Serial.println(a); // 1
  increment(a);
  Serial.println(a); // 2
}
void loop() {}

```

---

You could achieve the same thing using pointers, but using references is much cleaner and easier to read.

```
void increment(int *variable) { // Pointer to an integer
  ++*variable; // dereference first, then increment value
}
void setup() {
  Serial.begin(115200);
  int a = 1;
  Serial.println(a); // 1
  increment(&a); // address of a
  Serial.println(a); // 2
}
void loop() {}

```

Please note: this question is not specific to Arduino, it is just C++. For questions like this, it is best to google for 'C++ pass by reference' instead of 'Arduino pass by reference'.
> 7 votes

---
Tags: programming, variables, pointer
---


# Question
Title: does EEPROM.write() only writes changed data?
Do I understand the code in `EEPROM.cpp / write()` correctly, that `val` is only written to the EEPROM, if `val` differs from the current EEPROM contents at the given `address`?

And if the answer is *yes*, what is `commit()` doing?

# Answer
> 3 votes
From library Library, see fragment:

> EEPROM.write does not write to flash immediately, instead you must call EEPROM.commit() whenever you wish to save changes to flash. EEPROM.end() will also commit, and will release the RAM copy of EEPROM contents.

Probably to prevent too many writes into the same page (mostly EEPROM is divided in pages), the write stores it into some temporary buffer and the commit actually writes it to EEPROM. This decreases the number of writes, and since the number of writes has a maximum, the lifetime of the EEPROM is increased.

Update: Majenko's comment mentions no EEPROM is used, but flash, see below.

# Answer
> 1 votes
I read that after the EEPROM.commit() you need to add a delay(500). I had several issues with the EEPROM data gone after several restarts of the esp8266.

---
Tags: esp8266, eeprom
---


# Question
Title: Is it common that Uno clones misbehave when connected to 12v on VIN?
**Edit**: this was completely my mistake. See end.

My official Uno worked fine when powered by 12v on VIN, but my Uno clone acted really funny--it read random noise from an input when a simple wire was attached, but not with no wire. It was solved with a pulldown resistor. The worse problem was that the PWM didn't turn off when I called `analogWrite(pin, 0)`. More worrying, it seemed to be outputting by power rather than duty cycle, since my small LED strip seemed to be doing higher duty than my big LED strip (both powered by transistors), though both were being set with `analogWrite(pin, 0)`. I measured the 5v pin at 5.9v. The input voltage may have actually been up to 12.5 v, but clean. I disconnected VIN and hooked back up to USB, and everything worked fine.

I assume the solution is to either use a linear regulator wired to VIN, or a battery?

---

I did get the linear regulator, which didn't help. I finally checked all my voltages, and found there was a 0.8 volt difference between different grounds! It turned out my breadboard was wired to the Arduino pin next to ground, instead of ground itself. I feel very lucky not to have ruined the board, and my only complaint is that the pins aren't labeled clearly as they are on my official Arduino. On the other hand, I wouldn't have been able to debug this as easily on the official Arduino, since the clone has lovely solder holes at each pin which are a great spot to stick a voltmeter probe.

# Answer
> Is it common that Uno clones misbehave when connected to 12v on VIN

Whether it is "common" is probably unanswerable unless you do some sort of survey.

However bear in mind that clones or "knock off" boards (some of which pretend to be official ones) are built to a price. The original Arduino was already designed to be cheap. To make them even cheaper the manufacturers may well make a number of compromises. For example, some use a cheaper USB interface chip. It wouldn't surprise me if the components like the voltage regulator, capacitors, etc. are under-specified.

I see from eBay that clones are already quite cheap, possibly around $US 4.50. To compete with that, some manufacturers may be cutting back even further on the quality of components.

---

> I assume the solution is to either use a linear regulator wired to VIN, or a battery?

You are probably better off bypassing the on-board regulator entirely. Get a wall-wart that outputs 5V **regulated**. The sort of thing that might power a USB-based device. Then plug that into the 5V pin of the Uno (not VIN). In fact, virtually any mobile phone charger wall-wart will output exactly what you want. Just run a USB cable from that to the USB port on the Arduino, and there you have it! Regulated 5V power.

---

The other thing that could work would be to give the voltage regulator a break. Don't put 12V into it, put in 9V. Then it doesn't have to work so hard (that is, dissipate the extra voltage as heat).
> 1 votes

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


# Question
Title: How to create custom bootloader with accompanying program loader for ATMega2560
Just for some context, I have created a custom board based on the ATMega2560. I currently have the original Arduino Bootloader for the ATMega2560 and have no problems uploading code via the USB Port on TX0 and RX0.

What I am hoping to achieve is creating a custom Bootloader that allows me to upload my .hex binaries to flash but in a proprietary way, so that any program cannot be uploaded to it with the standard **Wiring** Protocol used by Arduino IDE. In addition, I will need a custom PC based program that can upload the code via the USB port.

The reason why I need this is that I will have this device out in areas where I would not want someone taking the device and uploading their own program to it and screw it up. I know it sounds paranoid, however, it would be preferred to have this feature so I can update the firmware via the USB Port without using the **Wiring** protocol.

Has anyone accomplished this before?

# TL;DR

Want to upload custom Bootloader to Arduino Mega so that I can upload my firmware with a proprietary programmer via the USB Port on TX0 and RX0 because I am paranoid.

# Answer
> 1 votes
The source of the bootloaders is publicly available, so a simple thing would be to make a minor modification, for example XOR each incoming byte with 0xEE. That would mean the bootloader wouldn't work with normal uploading programs (the IDE) but with a modified uploader.

However even simpler would be to upload your code using ICSP and **not include a bootloader at all**. Or, leave the bootloader there but turn off the BOOTRST fuse so that the processor ignores it.

That way, it takes some effort for people to replace your code.

---
Tags: arduino-mega, usb, bootloader, custom
---


title: ino.hex vs ino.with_bootloader.hex

text:
# Question
Title: ino.hex vs ino.with_bootloader.hex
I'm working on a Android App able to update the content of my Arduinos. Start to work (reset the Arduino, communicate with STK500 protocol, get id of ATmega and so on). But I face a question about the two hex files produced by the compiler. Some FAQ, forum... give replies about the two, explaining: "*the ino.hex file has only the code and the other as the code + the code of the bootloader*". After having a look at the hex files, that's true: you can find in the "with\_bootloader" the code of the bootloader.

The "why" gives the following answer: "*that's because when the bootloader receive the code, it erases the flash so the installed bootloader destroy itself. So if you send without bootloader, you will not have a bootloader any more in the Arduino*".

Problems:

1) In that case, in order to change the bootloader why use an ISP? Just add the HEX code of your new bootloader in the main HEX file, send it with AVRDUDE and that's all...
2) When you use the Arduino IDE with AVRDUDE in Verbose mode you'll see AVRDUDE send the file.... **without** the bootloader!

So the question is: when you want to update the content of the flash, sending "manually" the data using STK500 protocol, do you need to send the "ino.hex" or the "ino.with\_bootloader.hex" file? **And why?**

# Answer
> 8 votes
If flashing with AVR In System Programing (ISP) the bootloader is not needed. Only the flashing over Serial needs a bootloader.

The ISP erases the flash including the bootloader. To be able to use the serial flashing after ISP, the hex with\_bootloader can be used.

I flash AVR over WiFi with esp8266's core AVRISP library and I use the hex with\_bootloader to have the option of flashing later over USB.

Your Android app will use the serial flashing utilizing the bootloader. The bootloader doesn't delete itself. So you should use the hex WITHOUT bootloader.

# Answer
> 3 votes
While flashing the Arduino over USB (UART) you use the bootloader in that case the bootloader doesn't delete itself that's why the Arduino IDE sends the file without the bootloader. You need to use the file with a bootloader only when you are programming using an ISCP programmer and want to keep the ability to flash through USB.

---
Tags: bootloader, sketch
---


# Question
Title: State machine sketch to drive a DC motor with limit switches
I have a DC motor that will need to use two limit switches to detect end of travel in two directions.

I've read that coding a state machine to do this task is the best method, however I have no idea where to even begin.

Below you'll find a fritzing sketch of my experimental configuration for the code once implemented, and a flow chart.

# Answer
> 3 votes
You have created a flow chart. When discussing state machines it is better to use a state diagram.

In this state diagram of a turnstile (from the state machine wikipedia page linked to above) it is observed that the nodes (bubbles) contain the state of the turnstile and on the edges (arrows) is written the condition required to travel in the direction of the arrow to a new state.

For the question asked here, at least 2 nodes are needed to state the direction of the motor. The edges likely will state which arrow is to be used to travel to a new state based on which switch is open or closed. Later, consider adding a new state to stop the motor once an end switch is closed. (Hint: Likely, you will need 2 stop nodes. One for each end-stop switch. The reason being you will need to know which direction the motor is to turn when restarted.)

For certain cases, adding a momentary contact switch is complex due to the need to mitigate the contact bounce. This is true when the meaning of activating the switch changes. The end-stop switch meaning does not change so there is no need to mitigate the contact bounce or "debounce" the end-stop switches. However, it is assumed the "Cycle Switch" can start the motor spinning in different directions depending on the history of the motor movement. Therefor the "Cycle Switch" can benefit from a 4 node state machine where there is clearly nodes which output switch-closed and switch-open. But to get to either of these 2 nodes there needs to be 2 other nodes where the switch "debouncing" is handled.

When handling multiple state machines in one program it is important not to block the flow. All state machines need to be continuously checked for state chances (testing the edge conditions for traveling from the current node to a new node).

When writing for an Arduino (in C / C++), the code pattern most often used is a "case" statement (switch / case) where a variable is assigned numbers associated with different nodes. In such a code pattern, each "case" is a node which contains the edge test(s) and can assign a new value to the variable to switch to a new node ("case") if any of the edge tests are true.

Simplifying the design: If you do not plan on stopping the motor then you do not need to "debounce" the "Cycle Switch".

Here is why: The meaning of the "Cycle Switch" changes from push-to-start to push-to-stop should you want to stop the motor between the 2 stop-switches. If all you need is to start the motor after either of the stop-switches are closed, then the number of times the "Cycle Switch" bounces is irrelevant as long as the bounces do not continue for longer then it takes for the motor to reach the opposite stop-switch.

# Answer
> 2 votes
Each state in the state machine should be a state in which the arduino will be for a time. Anywhere you would use a delay() or a blocking function or a busy loop will be a state.

You can also use multiple orthogonal statemachines and mix them. For example 1 to control whether the motor needs to be driven at all and one to control which direction it is driven in. That way the motor control part will look like:

```
if(motorDriven) {
    if(motorDirection = TOP) {
        driveMotorCW();
    } else {
        driveMotorCCW();
    }
} else {
    stopMotor();
}

```

Then the control of the state machine is straightforward. If limit switch is pressed change motorDirection to the opposite (and maybe stop the motor).

For timing you should keep a timestamp of the start of the interval and then test if `millis() - timestamp > interval`. For intervals less than a month this will work decently enough (barring drift). For intervals greater than that you should invest in a external clock.

---
Tags: arduino-uno, motor, switch, l293d
---


# Question
Title: Need to read/send both values of a button push
I'm trying to use a float switch to receive alerts via Blynk when a water level drops, and when it rises again. The code I have been using has been working for when the float drops (button pressed) and I could get it to work when the water comes back up, but it gets stuck in a loop. I'm new to Arduino programming and I'm sure it's some simple error in the way I'm writing/modifying this code...

```
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
BlynkTimer timer;

char auth[] = "710a4af9b1d82412fa477705bf642c634";
char ssid[] = "SSID";
char pass[] = "PWD";
int flag=0;
void notifyOnButtonPress()
{
  int isButtonPressed = digitalRead(D1); //assignment here for pin
  if (isButtonPressed==1 && flag==0) {

    Blynk.notify("Alert : Water Level has dropped");
    flag=1;
  }
  else if (isButtonPressed==0 && flag==0)
      Blynk.notify("Alert : Water level has risen");
  {
    flag=0;
  }

}
void setup()
{
  // Debug console
  Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
  // Setup notification button on pin D1
  pinMode(D1,INPUT_PULLUP);
 timer.setInterval(16000L,notifyOnButtonPress);

}
void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}

```

I believe the problem is in function notifyOnButtonPress.

# Answer
It seems to me that the saved float level state needs to be initialized to what it's actual current level is rather than just starting it off as 0. That way conditions such as a power outage during which the float level has changed could be detected.

I also changed the text of your notifications, which may or may not be allowed, to more accurately describe the state of the system.

I haven't actually tested this so I would like feedback as to whether it works or not.

```
int floatSavedState = -1;      // initial float low state indicates not yet known

void notifyOnButtonPress()
{
  // pin D1 will be 1 if float has dropped due to low water level
  // pin D1 will be 0 if water level is high enough
  int floatLevelLow = digitalRead(D1);  // read the float low indicator pin

  if (floatLevelLow && floatLevelLow != floatSavedState) {
       // send notification if this is first time or if the float level has
       // changed since the last notification.
       Blynk.notify("Alert : Water Level low.");
       floatSavedState = floatLevelLow;
  } else if (floatLevelLow != floatSavedState)
     // send notification if this is first time or if the float level has
     // changed since the last notification.
     Blynk.notify("Alert : Water level high");
     floatSavedState = floatLevelLow;
  }
}

```

Or I suppose even simpler would be:

```
int floatSavedState = -1;      // initial float low state indicates not yet known

void notifyOnButtonPress()
{
  // pin D1 will be 1 if float has dropped due to low water level
  // pin D1 will be 0 if water level is high enough
  int floatLevelLow = digitalRead(D1);  // read the float low indicator pin

  if (floatLevelLow != floatSavedState) {
       // send notification if this is first time or if the float level has
       // changed since the last notification.
       if (floatLevelLow) {
           Blynk.notify("Alert : Water Level low.");
       } else {
           Blynk.notify("Alert : Water level high");
       }
       floatSavedState = floatLevelLow;
  }
}

```
> 0 votes

# Answer
Change

```
else if (isButtonPressed==0 && flag==0)
    Blynk.notify("Alert : Water level has risen");

```

to

```
else if ((isButtonPressed==0) && (flag==1))
{
    Blynk.notify("Alert : Water level has risen");
}

```

Otherwise, when flag == 1, it will never revert back to 0. Also it's best to add brackets, and use parenthesis.

Also, change the variable name flag to something more meaningfull.
> 0 votes

---
Tags: arduino-uno, nodemcu
---


title: Setting ESP8266-01 up with AT commands

text:
# Question
Title: Setting ESP8266-01 up with AT commands
I am facing for the first time with the ESP8266-01 module, so sorry if will write any stupid things.

I bought this module and I wanted to check its parameters through AT commands. Following some guide and wiring schemas found on the web I finally hook the ESP8266 up with an Arduino Uno (as in the picture below. The resistors are 220ohm each and the capacitor is 100uF) in order to print out to the serial monitor the AT commands and responses.

I uploaded the following code to Arduino Uno:

```
#include <SoftwareSerial.h>
SoftwareSerial esp8266(6, 7);

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
  }

  Serial.println("Started");

  // set the data rate for the SoftwareSerial port
  esp8266.begin(57600);
  esp8266.write("AT\r\n");
}

void loop() {
  if (esp8266.available()) {
    Serial.write(esp8266.read());
  }

  if (Serial.available()) {
    esp8266.write(Serial.read());
  }
}

```

But when I open the serial monitor (with both NL and CR selected and baud rate set to 9600) **I got no response**!! If I try to send simple AT or AT+GMR commands, it returns to me nothing or random characters.

Does anyone please could tell me what I am doing wrong?

# Answer
> 1 votes
We faced similar problems when using ESP8266 for the first time, Following approach to the problem was fruitful

1. ESP8266 is 3.3v compatible so to avoid problems make a simple adaptor circuit to make it compatible with 5v Arduino (find details here)
2. First thing you need to do is check and confirm if you are able to communicate with your ESP module, you can use any USB to TTL interface and connect ESP Module directly with your computer/laptop. (explained in detail here)
3. Use ESP8266 configuration utility, it will speed up the ESP Module setup and help get the desired product develop faster. (explained in detail here)

Hope it helps.

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


# Question
Title: POST to server using ESP8266 module- Arduino Uno- AT+ commands
I'm trying to send a set of data in Json format to a server I have set up which has a specific URL and an access token. The server requires a POST command. So my final URL is: http://myurl.com/myaccesstoken

The idea is that the Arduino UNO acquires some data from a sensor it then uses the ESP8266 to connect to wifi and send the acquired data to my server.

I do not understand why my server does not receive data

Thank you a lot in advance for your help.

I have used the following code:

---

```
#include "Arduino.h"
#include "ESP8266.h"
#include "SoftwareSerial.h"
#include "ArduinoJson.h"

#define ssid "mySSID"
#define pw "myPW"
#define IP "xxx.xxx.xxx.xxx"
#define URL "http://myurl.com/myaccesstoken"

int incomingByte;

void setup() {//I connect to wifi
  Serial.begin(115200);
  Serial.println("AT");
  delay(5000);
  analogReference(INTERNAL);
  if(Serial.find("OK")){
    Serial.println("AT+CWMODE=3");
    delay(1000);
    String WF=String("AT+CWJAP=\"")+ssid+"\",\""+pw+"\"";
    Serial.println(WF);
    delay(5000);}
}

void loop() {
  //JSON data creation
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["flow"] = 2.54;
root["measured"] = "2017-08-14T06:16:03.418Z";
root.printTo(Serial);
delay(5000);
 // I start communication with server
 Serial.println(String("AT+CIPSTART=\"TCP\",\"") + IP + "\",80");
 delay(5000);
 Serial.println("AT+CPSTATUS");
 // I use HTTP protocol to POST the data
    Serial.println("AT+HTTPINIT");
    delay(2000);
    Serial.println("AT+HTTPPARA=\"CID\",\"1");
    delay(2000);
    Serial.println("AT+HTTPPARA=\"URL\",\"http://myurl.com/myaccesstoken\"");
    delay(2000);
    Serial.println(String("AT+HTTPPARA=\"CONTENT\",\"application/json"));
    delay(2000);
    Serial.println("AT+HTTPDATA=\" + 81 + \",1000"); //81 is the computed length of my JSON
    delay(2000);
    Serial.println("AT+HTTPACTION=1");
    delay(2000);
    Serial.println("AT+HTTPREAD");
    delay(2000);
    if(Serial.available() > 0)
        {
                // read the incoming byte:
                incomingByte = Serial.read();
                // say what you got:
                Serial.print("I received: ");
                Serial.println(incomingByte);
    }
    Serial.println();
    Serial.println("AT+HTTPTERM");

    delay(5000);
  }

```

# Answer
Your code doesn't work because you start by sending ESP-specific AT commands to open a socket, then you suddenly switch to SIM800-specific AT commands, and the ESP goes "WTF dude?!"

I suggest you read some tutorials on accessing web sites with the ESP8266 not with the SIM800.
> 1 votes

# Answer
I suggest you use computer based tools to start communication with ESP8266 module and test out sending and receiving data before you connect the module with Arduino. If you are looking for tutorials for the same then I suggest you visit this link maybe it will solve your problem or give you a direction to work on
> 0 votes

---
Tags: esp8266, communication, http, json
---


# Question
Title: Error on sending AT+CWJAP_DEF commands to ESP8266
I am trying to send `AT` commands to `ESP8266` to get connected with internet with the Wifi.

When I am sending `AT` and `AT+RST` command on serial monitor then I am getting OK and ready response which seems perfect.

Then I am sending `AT+CWLAP` to get list of available wifi networks which is also executing correctly.

```
AT+CWLAP

+CWLAP:(3,"Moto",-42,"a4:70:d6:7a:fa:6c",1,25,0)
+CWLAP:(4,"PRANJAL",-95,"1c:a5:32:3d:f5:c4",1,-16,0)
+CWLAP:(2,"VIHAN",-94,"c8:3a:35:2f:1d:81",1,-21,0)
+CWLAP:(3,"Tenda",-93,"c8:3a:35:20:a9:b1",9,-4,0)

OK

```

Then I sent `AT+CWMODE?` which is also perfect.

```
AT+CWMODE?

+CWMODE:1

OK

```

Now I am trying to connect `ESP8266` with above listed Wifi with this command, it is sending an ERROR on serial monitor.

> AT+CWJAP\_DEF="Moto","reset1234"

**Error**

```
⸮=IRe"Moto","reset1234"

ERROR

```

Can anyone suggest me what could be the reason of this issue ?at

# Answer
Alright! I just tried to connect with different wifi and it got connected with it. It was some kinda issue with mobile hotspot.
> 0 votes

# Answer
The source of such problems are mostly as under

* Bad / loose wiring (power and communication)
* software serial is not much reliable
* Arduino serial monitor is not a user friendly way of testing out ESP modue

To solve wiring related problems for good check out this design.

To solve communication monitoring problems check out this solution

Use USB to TTL interface to connect ESP module directly to your PC without using an Arduino (find details here)
> 1 votes

# Answer
Based on the gibberish echo, the possible causes are:

* Insufficient power. You need a source that can supply up to 300mA which is about the max consumption for the module. A good-sized capacitor across the ESP power rails (10uF maybe) wouldn't hurt.
* Baud rate is too high. If you're using an Arduino as 'middle-man' and talking to the ESP8266 through a SoftwareSerial port, you're likely to face this sort of issue if the baud rate is as high as 115200; SoftwareSerial is unreliable at such rates.
> 0 votes

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


# Question
Title: Implementing AT commands with Arduino and ESP8266
Being a newbie to Arduino, I'm trying to implement AT commands in the serial monitor, though in vain. After connecting the ESP8266 (01) module to an Arduino Uno, I tried to scan for the nearest network present \[code link: https://github.com/esp8266/Arduino/blob/master/doc/esp8266wifi/scan-examples.md#simple-scan\] and it worked perfectly.

But the moment I am trying to connect to send AT commands (even manually), it shows nothing. In addition, `if(Serial.available())` and `if(esp8266.available())<` both are giving **false** value.

What am I doing wrong?

# Answer
> 0 votes
You don't give a circuit diagram or very much detail about what you've done, but if I guess correctly...

You have flashed the code in your link to the ESP-01 (perhaps using the Arduino as a serial port adapter). That code is now running on the ESP itself - it's *not* running on the Arduino and controlling the ESP.

Flashing the ESP erases the stock firmware, so the ESP can no longer respond to AT commands.

I don't know of a way to reprogram the 'AT' firmware into the ESP but perhaps Google will help.

If I've guessed incorrectly, please explain exactly what you have done - with circuit diagram, setup steps and code.

# Answer
> 0 votes
Anyone who is new to using ESP8266 module should consider following before interfacing it with Arduino

1. Try connecting ESP Module directly with your computer and test out all the AT Commands you will be implementing with Arduino. This approach is better because (a) this will give you confidence that your communication works perfectly (b) you will figure out all the problems that people face when sending AT commands and receive reply (c) this is a more visual approach so you will know what is going on and where you are going wrong.
2. Use Computer based communication tools and make a simple power adaptor to solve communication and wiring problems once and for all.

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