# Question
Title: How to include Vref in thermistor temperature calculation?
simulate this circuit – Schematic created using CircuitLab

This is the code that I'm using to get the temperature:

```
#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07

float VRT, Temp;
float Vref = 2.52;

void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
}

void loop() {
  long Resistance;
  VRT = analogRead(A3);
  Resistance = 10000 / ((1023.0 / VRT) - 1);
  Temp = log(Resistance);
  Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
  Temp += -273.15;
  Serial.println(Temp);
  delay(500);
}

```

I know that the calculation should be: `V = Vref × VRT ÷ 1023` but i don't know how to implant it in this code, any help appreciated.

---

# Update

After Edgar Bonet answer, the edited code is:

```
#define COEFF_A 0.8662984364E-03
#define COEFF_B 2.780704551E-04
#define COEFF_C -0.9395108479E-07

float VRT, Temp, VR;

void setup() {
  Serial.begin(9600);
  analogReference(EXTERNAL);
}

void loop() {
  long Resistance;
  VRT = analogRead(A3);
  VR = 2.52 * VRT / 1024;
  Resistance = 10000 * VR / (2.52 - VR);
  Temp = log(Resistance);
  Temp = 1 / (COEFF_A + (COEFF_B * Temp) + (COEFF_C * pow(Temp, 3)));
  Temp += -273.15;
  Serial.println(Temp);
  delay(500);
}

```

But the temperature reading is 2 centigrade less than what it should be, when i remove the `analogReference(EXTERNAL);` it shows the normal/correct temperature readings.

# Answer
The formula to get the analog voltage from the ADC reading is:

V = Vref × reading ÷ 1024

(yes, it's 1024, not 1023). The formula to get the thermistor resistance from the measured voltage is:

R = Rref × V ÷ (Vref − V)

where Rref is your 10 kΩ pull-up. You can combine these two formulas in order to get the resistance directly from the ADC reading:

R = Rref × reading ÷ (1024 − reading)

You may notice that, while doing this simplification, Vref cancels out. It's not an error. The readings you get with this setup are indeed independent of your reference voltage.

---

**Update 1**: After the OP's edit, we now have a *completely different* question. The question is now: how come the readings do depend on the reference voltage that is used, whereas in theory they should not.

The answer lies most likely in the ADC calibration. If high accuracy is a requirement, the correct formula for the measured voltage is

V = Vref × (reading + Eoff) ÷ (1024 + Egain)

where Eoff and Egain are the offset error and the gain error respectively. These errors are not knows *a priori*, and they are usually neglected when the accuracy requirement is low. The datasheet only gives constraints on how big these errors can be. The actual values depend on the specific microcontroller and can somewhat depend on the reference voltage. The only solution to get rid of these errors is to calibrate your own ADC. See Response of the Arduino ADC for an example on how this could be done.

---

**Update 2**: If I had to program this in an Arduino, I would rather simplify the calculations as much as possible before coding:

* do *not* compute the measured analog voltage, nor the resistance, as they are not needed
* compute instead the ratio R/Rref directly from the analog reading
* rewrite the calibration polynomial as a function of log(R/Rref) instead of log(R) (which actually means log(R/(1 Ω)))
* optimize the evaluation of the polynomial by using Horner's method.

With these optimizations, we get:

```
// Coefficients of polynomial fit of log(R/Rref) -> 1/T.
const float c0 = 3.3540165e-3;
const float c1 = 2.5416075e-4;
const float c2 = -2.5959644e-6;
const float c3 = -9.3951087e-8;

// Convert ADC reading to temperature in deg. C.
static float temperature(int reading)
{
    float R_ratio = reading / (1024.0 - reading);  // = R / Rref
    float x = log(R_ratio);
    float inverse_T = c0 + x*(c1 + x*(c2 + x*c3));
    return 1/inverse_T - 273.15;
}

void loop()
{
    int reading = analogRead(A3);
    Serial.println(temperature(reading));
    deay(500);
}

```
> 2 votes

# Answer
Note: I formulated this answer on your previous, deleted question.

Whether the voltage increases or decreases with rising temperature depends on your circuit: if you use the ntc with R1 as a pull-down, the voltage will increase on rising temperature. If R1 is a pullup the voltage will fall respectively.

Concerning your calculation: I highly recommend using a look-up table instead. Those are some hard calculations, and at the arduinos resolution you'll be fine with a LUT with about 64 entries. There're tools out there which generate LUTs for a given NTC setup (I personally like this tool).
> 0 votes

---
Tags: programming, c++, thermistor
---


title: How I can connect module GSM SIM800L?

text:
# Question
Title: How I can connect module GSM SIM800L?
I bought a GSM module, and I want to connect it with Arduino but I have a problem.

I linked GSM SIM800L with regular LM2596 12 V 2 VA I changed tension to 5 V, So far the GSM is working but if I connect TX\_ARDUINO with RX\_GSM the module enters in the loop of the restart.

The picture explains the montage.

# Answer
> 1 votes
Follow this tutorial on how to connect your Sim800l with Arduino.

---
Tags: arduino-mega, arduino-nano, gsm
---


# Question
Title: Using INT2/3 on Arduino Micro (Atmega32u4)
My project is using almost all the pins on this board and I require an interrupt pin to read radio state (rather than polling). I'm using I2C, so that leaves INT2 and INT3, which are the TX and RX pins for USB/Serial1. According to the documentation, disabling serial, using `Serial.end()`, should allow me to take control of those pins. However, using the pins as interrupt handlers doesn't work. Here is a sample sketch:

```
static int ledpin = 13;
volatile byte state = LOW;

void func()
{
  state = !state;
}

void setup() {
  Serial.end();

  pinMode(ledpin, OUTPUT);

  // INT2
  pinMode(0, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(0), func, CHANGE);

  // INT3
  pinMode(1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(1), func, CHANGE);
}

void loop() {
  digitalWrite(ledpin, state);
}

```

This example is mostly copy-pasted from the Arduino website. All the other interrupts work fine, only INT2 and INT3 don't.

Is there a way to use these interrupts?

# Answer
> 2 votes
You problem isn't with your pins or code, but with debouncing the signals. I've changed the "func()" method to read:

```
void func()
{
  static uint32_t lastChange = 0; // Note millis() don't change inside ISR, but can be read
  if (millis() - lastChange > 100)
  {
    state = !state;
  }
  lastChange = millis(); // Set new value
}

```

which will ignore spurious interrupts if they occur within 100ms of each other. This solves the issue that you are seeing, I've tested it on an Arduino Micro I have lying around.

# Answer
> 0 votes
```
/*
   2019-08-29 Nicola Bernardelli. Going through the ATmega32U4 Datasheet and applying the steps
   to set up the analog comparator on a Pro Micro board.

   While doing this, I understand that the Analog to Digital Converter must be switched off.
   So, if you are needing to stick with ATmega32U4 but also need the ADC (as I do in my current project), you might have to add a
   circuit with a comparator, e.g. LM393 or LM339, instead of using the built-in Analog Comparator.
   Disabling this interrupt and reactivating the ADC has not been added to this sketch.

   Also, a "real" handling of the interrupt-triggered event has not been added and the sketch leaves the possibility of a very fast
   succession of interrupt requests. You might want to check the (currently only one) answer given here:
   https://arduino.stackexchange.com/questions/49195/using-int2-3-on-arduino-micro-atmega32u4

   [I wanted to ask/contribute here https://arduino.stackexchange.com/questions/17480/using-analog-comparator-on-atmega32u4
   (I see that it is 3 years 9 months old but it's still "searchable" on the Internet, which is how I went there. I think that keeping the
   information under that pertinent title is a better option than opening a new thread.)
   So I created an account, but it turns out that I don't have enough "reputation" there to comment, so I wrote into the edit field
   available to give an answer, and that did not work out either:
   "Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed,
   posting an answer now requires 10 reputation on this site (the association bonus does not count)."
   So... pretty much chessmate. Well... their board, their rules.]
*/

#include "Arduino.h"

#ifndef ARDUINO_AVR_PROMICRO
#error This sketch is meant for the Arduino Pro Micro, it is based on the ATmega32U4 Datasheet and the Pro Micro pinout. \
       You might decide to try it on a different ATmega32U4-based board if the pins choice is OK (please check/change the LED pin number).
#endif

#define THIS_BOARD_LED_BUILTIN 17
#define LED_ON_DURATION 200

volatile bool analogCompInterruptToggled;
unsigned long millisLastTrigger;

void setup() {

  Serial.begin(9600);

  analogCompInterruptToggled = false;
  millisLastTrigger = 0;
  pinMode(THIS_BOARD_LED_BUILTIN, OUTPUT);
  digitalWrite(THIS_BOARD_LED_BUILTIN, HIGH);

  /* As per Atmega32U4 Datasheet starting pag 293 (and linked pages). */

  PRR0 &= ~bit(PRADC); // Disables power reduction for the ADC in order to use the ADC input MUX.

  /*
     ACME in ADCSRB: When this bit is written logic one and the ADC is switched off (ADEN in ADCSRA is zero),
     the ADC multiplexer is connected to the negative input to the Analog Comparator. When this bit is written
     logic zero, the Bandgap reference is connected to the negative input of the Analog Comparator
  */
  ADCSRA &= ~bit(ADEN); /* Switches off the ADC so we can use the Muxer with the Analog Comparator instead of the ADC. */
  ADCSRB |= bit(ACME);  /* With the line above => the ADC multiplexer is connected to the negative input of the Analog Comparator. */
                        /* See table at page 295: ACME 0 or (ACME 1 and ADEN 1) => bandgap ref as the Analog Comparator Negative Input. */

  /*                                        ******** A0 NEGATIVE INPUT ********
     Let's select pin ADC7 = A0 as the negative input to the Analog Comparator, as per pag 295 of the ATmega32U4 DataSheet:
     ACME to 1 done above, ADEN to 0 done above, MUX2..0 to 111.
  */
  ADMUX |= 0b00000111;

  /*                                        ******** D7 POSITIVE INPUT ********
     When this bit is set, a fixed bandgap reference voltage replaces the positive input to the Analog Comparator.
     When this bit is cleared, AIN0 is applied to the positive input of the Analog Comparator.
  */
  ACSR &= ~bit(ACBG); // AIN0 = D7 => positive input of the Analog Comparator

  /* Pages 294-295 of the ATmega32U4 Datasheet. */
  ACSR &= ~bit(ACIC); /* Analog Comparator Input Capture disabled. */

  /* Comparator Interrupt trigger mode. 0-0 => TOGGLE, meaning any change; 1-0 => FALLING; 1-1 => RISING). */
  // ACSR &= ~bit(ACIS1); ACSR &= ~bit(ACIS0); // TOGGLE
  // ACSR |= bit(ACIS1);  ACSR &= ~bit(ACIS0); // FALLING
     ACSR |= bit(ACIS1);  ACSR |= bit(ACIS0);  // RISING

  DIDR1 &= ~bit(AIN0D); /* It's actually the rightmost bit, we could write DIDR1 &= ~1 */
  /*
     When this bit is written logic one, the digital input buffer on the AIN0 pin is disabled. [...]
     When an analog signal is applied to the AIN0 pin and the digital input from this pin is not needed,
     this bit should be written logic one to reduce power consumption in the digital input buffer.
  */

  ACSR |= bit(ACIE);
  SREG |= bit(SREG_I);
  /* When the ACIE bit is written logic one and the I-bit in the Status Register is set,
     the Analog Comparator interrupt is activated. When written logic zero, the interrupt is disabled.
  */
}

ISR(ANALOG_COMP_vect) {
  analogCompInterruptToggled = true;
}

void loop() {
  // put your main code here, to run repeatedly:
  if (analogCompInterruptToggled) {
    analogCompInterruptToggled = false;
    digitalWrite(THIS_BOARD_LED_BUILTIN, LOW);
    millisLastTrigger = millis();
    Serial.print("toggled - millis() == ");
    Serial.println(millisLastTrigger);
  }
  else if (millis() > millisLastTrigger + LED_ON_DURATION) {
    digitalWrite(THIS_BOARD_LED_BUILTIN, HIGH);
  }
}

```

---
Tags: interrupt, arduino-micro, atmega32u4
---


title: Trouble in sensor data reading sequence

text:
# Question
Title: Trouble in sensor data reading sequence
I am reading from two MPU6050 sensors using Arduino Uno but it give trouble in squence. The code is perfect and also sensors reading is done. See image of serial monitor.

>

You can see the above image in which the output data of serial monitor is not lining up. It breaks the lines after some time interval. I want to expect the serial data in lining. Here is the code:

```
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"

#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file

// Arduino Wire library is req1uired if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif

// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
// AD0 high = 0x69
//MPU6050 mpu;
MPU6050 mpu1(0x68);
MPU6050 mpu2(0x69); // <-- use for AD0 high

// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
// pitch/roll angles (in degrees) calculated from the q1uaternions coming
// from the FIFO. Note this also req1uires gravity1 vector calculations.
// Also note that yaw/pitch/roll angles suffer from gimbal lock (for
// more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
#define OUTPUT_READABLE_YAWPITCHROLL

int pre_count = 0;

#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;

// MPU control/status vars
bool dmpReady1 = false;  // set true if DMP init was successful
uint8_t mpuIntStatus1;   // holds actual interrupt status byte from MPU
uint8_t devStatus1;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize1;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount1;     // count of all bytes currently in FIFO
uint8_t fifoBuffer1[64]; // FIFO storage buffer

// MPU control/status vars
bool dmpReady2 = false;  // set true if DMP init was successful
uint8_t mpuIntStatus2;   // holds actual interrupt status byte from MPU
uint8_t devStatus2;      // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize2;    // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount2;     // count of all bytes currently in FIFO
uint8_t fifoBuffer2[64]; // FIFO storage buffer

// orientation/motion vars
Quaternion q1;           // [w, x, y, z]         q1uaternion container
VectorInt16 aa1;         // [x, y, z]            accel sensor measurements
VectorInt16 aa1Real1;     // [x, y, z]            gravity1-free accel sensor measurements
VectorInt16 aa1World1;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity1;    // [x, y, z]            gravity1 vector
float euler1[3];         // [psi, theta, phi]    euler1 angle container
float ypr1[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket1[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

Quaternion q2;           // [w, x, y, z]         q1uaternion container
VectorInt16 aa2;         // [x, y, z]            accel sensor measurements
VectorInt16 aa1Real2;     // [x, y, z]            gravity1-free accel sensor measurements
VectorInt16 aa1World2;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity2;    // [x, y, z]            gravity1 vector
float euler2[3];         // [psi, theta, phi]    euler1 angle container
float ypr2[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

// packet structure for InvenSense teapot demo
uint8_t teapotPacket2[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt1 = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady1() {
  mpuInterrupt1 = true;
//  Serial.println("Mpu interrupt true");
}

volatile bool mpuInterrupt2 = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady2() {
  mpuInterrupt2 = true;
}

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
  // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
  Wire.begin();
  TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
  Fastwire::setup(400, true);
#endif

  // initialize serial communication
  // (115200 chosen because it is req1uired for Teapot Demo output, but it's
  // really up to you depending on your project)
  Serial.begin(115200);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately

  // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
  // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
  // the baud timing being too misaligned with processor ticks. You must use
  // 38400 or slower in these cases, or use some kind of external separate
  // crystal solution for the UART timer.

  // initialize device
  Serial.println(F("Initializing I2C devices 1..."));
  mpu1.initialize();

   // initialize device
  Serial.println(F("Initializing I2C devices 2..."));
  mpu2.initialize();

  // verify connection
  Serial.println(F("Testing device 1 connections..."));
  Serial.println(mpu1.testConnection() ? F("MPU6050 1 connection successful") : F("MPU6050 1 connection failed"));

  // verify connection
  Serial.println(F("Testing device 2 connections..."));
  Serial.println(mpu2.testConnection() ? F("MPU6050 2 connection successful") : F("MPU6050 2 connection failed"));

  // wait for ready
  Serial.println(F("\nSend any character to begin DMP programming and demo: "));
  while (Serial.available() && Serial.read()); // empty buffer
  while (!Serial.available());                 // wait for data
  while (Serial.available() && Serial.read()); // empty buffer again

  // load and configure the DMP
  Serial.println(F("Initializing DMP 1..."));
  devStatus1 = mpu1.dmpInitialize();

  // load and configure the DMP
  Serial.println(F("Initializing DMP 2..."));
  devStatus2 = mpu2.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu1.setXGyroOffset(220);
  mpu1.setYGyroOffset(76);
  mpu1.setZGyroOffset(-85);
  mpu1.setZAccelOffset(1788); // 1688 factory default for my test chip

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu2.setXGyroOffset(74);
  mpu2.setYGyroOffset(14);
  mpu2.setZGyroOffset(-19);
  mpu2.setZAccelOffset(253); // 1688 factory default for my test chip

  // make sure it worked (returns 0 if so)
  if (devStatus1 == 0) {
    // turn on the DMP, now that it's ready
    Serial.println(F("Enabling DMP 1..."));
    mpu1.setDMPEnabled(true);

    // enable Arduino interrupt detection
    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
    attachInterrupt(0, dmpDataReady1, RISING);
    mpuIntStatus1 = mpu1.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    Serial.println(F("DMP 1 ready! Waiting for first interrupt..."));
    dmpReady1 = true;

    // get expected DMP packet size for later comparison
    packetSize1 = mpu1.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    Serial.print(F("DMP 1 Initialization failed (code "));
    Serial.print(devStatus1);
    Serial.println(F(")"));
  }

  // make sure it worked (returns 0 if so)
  if (devStatus2 == 0) {
    // turn on the DMP, now that it's ready
    Serial.println(F("Enabling DMP 2..."));
    mpu2.setDMPEnabled(true);

    // enable Arduino interrupt detection
    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
    attachInterrupt(0, dmpDataReady2, RISING);
    mpuIntStatus2 = mpu2.getIntStatus();

    // set our DMP Ready flag so the main loop() function knows it's okay to use it
    Serial.println(F("DMP 2 ready! Waiting for first interrupt..."));
    dmpReady2 = true;

    // get expected DMP packet size for later comparison
    packetSize2 = mpu2.dmpGetFIFOPacketSize();
  } else {
    // ERROR!
    // 1 = initial memory load failed
    // 2 = DMP configuration updates failed
    // (if it's going to break, usually the code will be 1)
    Serial.print(F("DMP 2 Initialization failed (code "));
    Serial.print(devStatus2);
    Serial.println(F(")"));
  }

  // configure LED for output
  pinMode(LED_PIN, OUTPUT);
}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {

  // if programming failed, don't try to do anything
  if (!dmpReady1) return;

  // if programming failed, don't try to do anything
  if (!dmpReady2) return;

// Serial.println("code access here 1");
  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt1 && fifoCount1 < packetSize1) {
    // other program behavior stuff here
    // .
    // .
    // .
    // if you are really paranoid you can freq1uently test in between other
    // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
    // while() loop to immediately process the MPU data
    // .
    // .
    // .
     break;

//    Serial.println("code access here 2");
  }

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt2 && fifoCount2 < packetSize2) {
    // other program behavior stuff here
    // .
    // .
    // .
    // if you are really paranoid you can freq1uently test in between other
    // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
    // while() loop to immediately process the MPU data
    // .
    // .
    // .
    break;
  }

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt1 = false;
  mpuIntStatus1 = mpu1.getIntStatus();

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt2 = false;
  mpuIntStatus2 = mpu2.getIntStatus();

  // get current FIFO count
  fifoCount1 = mpu1.getFIFOCount();

  // get current FIFO count
  fifoCount2 = mpu2.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus1 & 0x10) || fifoCount1 == 1024) {
    // reset so we can continue cleanly
    mpu1.resetFIFO();
    Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
  } else if (mpuIntStatus1 & 0x02) {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount1 < packetSize1) fifoCount1 = mpu1.getFIFOCount();

    // read a packet from FIFO
    mpu1.getFIFOBytes(fifoBuffer1, packetSize1);

    // track FIFO count here in case there is > 1 packet available
    // (this lets us immediately read more without waiting for an interrupt)
    fifoCount1 -= packetSize1;

#ifdef OUTPUT_READABLE_YAWPITCHROLL
    // display euler1 angles in degrees
    mpu1.dmpGetQuaternion(&q1, fifoBuffer1);
    mpu1.dmpGetGravity(&gravity1, &q1);
    mpu1.dmpGetYawPitchRoll(ypr1, &q1, &gravity1);
    int count = 0;
    count++;
    pre_count += count;
    Serial.print(pre_count);
    Serial.print("\t");
    Serial.print(ypr1[0] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr1[1] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr1[2] * 180 / M_PI);
    Serial.print("\t");
#endif

//    // blink LED to indicate activity
//    blinkState = !blinkState;
//    digitalWrite(LED_PIN, blinkState);
  }

   // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus2 & 0x10) || fifoCount2 == 1024) {
    // reset so we can continue cleanly
    mpu2.resetFIFO();
    Serial.println(F("FIFO 2 overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
  } else if (mpuIntStatus2 & 0x02) {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount2 < packetSize2) fifoCount2 = mpu2.getFIFOCount();

    // read a packet from FIFO
    mpu2.getFIFOBytes(fifoBuffer2, packetSize2);

    // track FIFO count here in case there is > 1 packet available
    // (this lets us immediately read more without waiting for an interrupt)
    fifoCount2 -= packetSize2;

#ifdef OUTPUT_READABLE_YAWPITCHROLL
    // display euler1 angles in degrees
    mpu2.dmpGetQuaternion(&q2, fifoBuffer2);
    mpu2.dmpGetGravity(&gravity2, &q2);
    mpu2.dmpGetYawPitchRoll(ypr2, &q2, &gravity2);
    Serial.print("\t");
    Serial.print(ypr2[0] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr2[1] * 180 / M_PI);
    Serial.print("\t");
    Serial.println(ypr2[2] * 180 / M_PI);
#endif

//    // blink LED to indicate activity
//    blinkState = !blinkState;
//    digitalWrite(LED_PIN, blinkState);
  }

   // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
}

```

What is the problem? Thanks in advance!

# Answer
> 1 votes
Both printing codes are inside of different if statements, which involve testing `mpuIntStatus1` and `mpuIntStatus2`. This works good, as long as in one `void loop()` iteration both of these if statements are executed. But that's a timing issue and you cannot assume, that these things happen regularly and always this way. Without completely analyzing your code, the variables `mpuIntStatus1/2` seem to indicate, that new data arrived. There is no reason, why this should be synchronized with the `void loop()` iterations.

To solve this you should rewrite your code to include all these print statements into one single if statement at the end of `void loop()`. In the if statements from above you can set a flag to indicate, that data arrived. This flag will be tested by the if statement at the end of loop. It is up to you to decide, how this should behave, when only data from 1 sensor arrived. You can only print the values from this sensor, or you can print both and using dummy values, that can be distinguished by humans (for example all values zero). Or you can choose to only print out values, if both sensors have given you results.

---
Tags: arduino-uno, serial, imu
---


title: OLED not updating display

text:
# Question
Title: OLED not updating display
I'm trying to connect a GPS unit (GY-GPS6MV2) and an OLED screen as in the diagram below (green connector is GPS; VCC, RX, TX, GND left to right):

Here's the code I've come up with:

```
#include <Wire.h>
#include <Adafruit_SH1106.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);
static const int RXPin = 5, TXPin = 3;
static const uint32_t GPSBaud = 9600;
float vkph;
float vmps;

TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

void setup(){
  Serial.begin(9600);
  ss.begin(GPSBaud);
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);
  display.display();
  delay(2000);
  display.clearDisplay();
}

void loop(){
  while (ss.available() > 0){
    gps.encode(ss.read());
    vkph = gps.speed.kmph();
    vmps = gps.speed.mps();
    if (gps.location.isUpdated()){
      Serial.print("Position: ");
      Serial.print(gps.location.lat(), 6);
      Serial.print(" : ");
      Serial.println(gps.location.lng(), 6);
      Serial.print("Speed: ");
      Serial.print(vmps);
      Serial.print(" m/s");
      Serial.print(", ");
      Serial.print(vkph);
      Serial.println( " km/hr");

      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println("Hello"); // Changing this to display.println(vmps);
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.println("World"); // Changing this to display.println(vkph);
      display.display();
      delay(1000);

    }
  }
}

```

The GPS outputs to the serial monitor fine, and the screen displays "Hello `\n` World" as expected. But when I make the changes indicated in the comments to the display part of the code, the display just shows its splash screen, flashing when the GPS updates.

How can I get the display to show the speeds in m/s and km/hr?

# Answer
> -1 votes
> Maybe you need to add `delay()` in your code,I am not sure.

```
display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println("Hello"); // Changing this to display.println(vmps);
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.println("World"); // Changing this to display.println(vkph);
      display.display();
      delay(1000);

```

---
Tags: gps, display, tinygps
---


title: Parent class callback from child class

text:
# Question
Title: Parent class callback from child class
I want the Parent class to pass a pointer to a callback function to the child class when the child class is created. I got this working when the parent was the sketch thanks to this post:
In this example, the parent was the `.ino` file, i.e. not a class but a collection of functions. This code worked fine. However, I need to be able to make the call to the child constructor from a within a class as shown in the code below. I get I get an "invalid use of non-static member function on the line `child = new Child ( handlerDispatcher );`

Here is the complete code:

```
class Child {
public:
    typedef void ( *callback_t ) ( uint8_t, uint8_t );

    callback_t callback;

    //  Constructor
    Child ( callback_t _callback ): callback ( _callback ) {}

    void doCallback ( uint8_t id, uint8_t index ) {
        callback ( id, index );
    }

    void makeCallbacks () {
        doCallback ( 1, 0 );
        doCallback ( 2, 1 );
        doCallback ( 3, 2 );
    }
};

class Parent {
public:
    Child *child;

    Parent () {}

    void handlerDispatcher ( uint8_t id, uint8_t index ) {
        ( this->*callbackHandlers [ index ] ) ( id );
    }

    typedef void ( Parent:: *handlerPointer ) ( uint8_t );
    handlerPointer callbackHandlers [ 3 ] = {
        &Parent::handler1,
        &Parent::handler2,
        &Parent::handler3,
    };

    void handler1 ( uint8_t index ) { echo ( index ); }
    void handler2 ( uint8_t index ) { echo ( index ); }
    void handler3 ( uint8_t index ) { echo ( index ); }
    void echo ( uint8_t value ) {
        Serial.print ( "Got: " );
        Serial.println ( value );
    }

    void configure () {
        child = new Child ( handlerDispatcher );

    }
    void test () {
        child->makeCallbacks ();
    }
};

Parent parent;
void setup () {
    Serial.begin ( 115200 );
    parent.configure ();
    parent.test ();
}

void loop() {}

```

# Answer
> 1 votes
Use virtual functions. On object of type `Child`, `fnc2` defined in `Parent` will call `fnc1` of class `Child`:

```
class Parent {
public:

  virtual void fnc1() {
  }

  void fnc2 {
    ...
    fnc1();
    ...
  }
}

class Child : public Parent {
public:
  virtual void fnc1() {
    ...
  }
}

```

# Answer
> 0 votes
It is because

```
void Parent::handlerDispatcher ( uint8_t id, uint8_t index )

```

is not

```
void ( *callback_t ) ( uint8_t, uint8_t )

```

The closest equivalent would be:

```
void ( *callback_t ) (Parent *, uint8_t, uint8_t )

```

Though I am not sure off hand if that is even possible.

But it seems you are trying to do something insanely convoluted and complex which would be made far simpler if you just used object inheritance and forget about callbacks.

With object inheritance a child object can implement the functions that a parent object defines. That way you end up with a single object instance which is a combination of the parent functions and the child functions, one overlaid on the other.

To build on Juraj's excellent answer and add a bit of explanation, if you take the following parent object:

```
class Parent {
public:

  virtual void fnc1() = 0;

  void fnc2 {
    fnc1();
  }
};

```

What we have here are two functions in the parent. `fnc2()` simply calls `fnc1()` as an example. However `fnc1()` isn't a normal function - it's a *pure virtual* function. That is akin to an `interface` in Java. It's a placeholder in the parent that says "This function *will* exist, but the child will implement it, not me". If you try and instantiate a Parent object the compiler will complain that certain functions are pure virtual and the object can't be created.

So then you create a child class which takes the parent class and extends it with the body of any pure virtual functions that are needed, and can also add more. For example:

```
class Child : public Parent {
public:
  void fnc1() final {
    ...
  }
};

```

Here we only have one function - `fnc1()`, which is marked as `final`. The `final` keyword is kind of the opposite of the `virtual` keyword. `virtual` means "This function will be overridden by the child". `final` means "I have overridden this, and nothing else can now override it". It's not essential, but it does help with the compiler's optimiser somewhat, since it no longer needs to worry about further inheritance of that function.

So now you can create a `Child` instance, and you will have access to all the parent functions and data, as well as all the child functions and data. Simply calling `fnc2()` on this child instance will call that function on the parent, which then itself calls `fnc1()` which is implemented by the child.

And thanks to something called *polymorphism*, the child can be seen as a parent for all intents and purposes (though if you look at it as a parent you won't see any of the child's own functions).

To wrap it all up, here's a full example that uses two different child classes and stores pointers to them in an array of parents (so the children are seen as if they are objects of class `Parent`), iterates through them, and calls the parent's `fnc2()` function:

```
class Parent {
    public:
        virtual void fnc1() = 0;
        void fnc2() {
            fnc1();
        }
};

class Child1 : public Parent {
    public:
        void fnc1() final {
            Serial.println("I am child 1");
        }
};

class Child2 : public Parent {
    public:
        void fnc1() final {
            Serial.println("I am child 2");
        }
};

Child1 c1;
Child2 c2;

Parent *objects[2] = {
    &c1, &c2
};

void setup() {
    Serial.begin(115200);
    for (int i = 0; i < 2; i++) {
        objects[i]->fnc2();
    }
}

void loop() { }

```

The serial output from that program is:

```
I am child 1
I am child 2

```

Which I think is the end effect that you are looking for.

---
Tags: c++, callbacks
---


# Question
Title: How can I stop a loop when using a servo with a Key input?
How can I stop my following code using a key?

Basically the code should run the servo in a loop if "t" is pressed and stop the loop if "s" is pressed.

```
#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
int servodata;

void setup() {
  myservo.attach(8);  // attaches the servo on pin 9 to the servo object

  Serial.begin(9600);

}

void loop() {
  if (Serial.available()>0){
    servodata = Serial.read();
    while (servodata == 't'){
           for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(3);                       // waits 15ms for the servo to reach the position
  }
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
       myservo.write(pos);              // tell servo to go to position in variable 'pos'
       delay(3);                       // waits 15ms for the servo to reach the position
    }
    }
  }
  while (servodata == 's'){
    break;
  }
}

```

thank you for help.

# Answer
> 1 votes
Here is a quick and dirty solution, where each `loop()` iteration corresponds to one “start sweeping”/“stop sweeping” cycle:

* wait for the “start” command
* then sweep back and forth in an infinite loop
* stop at any point if you receive the “stop” command

```
void loop() {
    // Wait for the 'start' command.
    while (Serial.read() != 't')
        continue;

    // Repeatedly sweep back and forth.
    for (;;) {
        for (int pos = 0; pos <= 180; pos += 1) {
            myservo.write(pos);
            delay(3);
            if (Serial.read() == 's') // check for 'stop' command
                return;
        }
        for (pos = 180; pos >= 0; pos -= 1) {
            myservo.write(pos);
            delay(3);
            if (Serial.read() == 's') // check for 'stop' command
                return;
        }
    }
}

```

Note that this approach has a couple of drawbacks:

1. As this is blocking code, you cannot easily extend the program to do other things.
2. The sweeping runs always start at position 0, instead of resuming from the position that was current on the last “stop” command.

If you need anything more sophisticated, you should go to a non-blocking approach based on a Finite State Machine (c.f. jsotola's comment). Note that you can get away with `delay(3);`, as it is a quite short delay, but you would have to break the sweeps into one step per `loop()` iteration.

I suggest you give the FSM approach a try: read the tutorial I linked to, then try to implement it. If you cannot get it to work, you can always post another question here.

---
Tags: programming, arduino-nano, c, loop
---


# Question
Title: arduino mega multi integer values reading on other arduino mega
I need two Arduino communications. The master arduino from the slave arduino needs to read 16 signals. The sample serial port output from the slave is as follows.

```
@ 125 @ 13 @ 874 @ 1023 & 950 @ 547 @ 965 @ 852 @ 654 @ 478 @ 0 @ 456 @ 996 @ 789 @ 556 @ 847 @

```

I need to throw this output into an integer array.

# Answer
> 0 votes
You can use the following C functions:

* `strtok`: to split a string (see strtok).
* `atoi`: to convert a string to an integer (see atoi).

---
Tags: serial, arduino-mega, string
---


# Question
Title: How to set PC (Program Counter) register to another function (for scheduler)
I am trying to implement a scheduler for Arduino Mega 2560. I think I lack understanding of how to set the PC register to another instruction. Here is my simple approach so far:

```
void dummy(){
    digitalWrite(LED_BUILTIN, HIGH);
 }

```

in a naked ISR method:

```
SP = (uint16_t)(&dummy)
__asm volatile(
"reti     \n\t"
)

```

However it is not working. How should the PC register be set to a certain function or to where it was in a previous process for a scheduler approach?

# Answer
This:

```
SP = (uint16_t)(&dummy)

```

is changing the stack pointer. Not what you want. You want to instead `push` the destination address to the stack. However, rather than simulating a function return, it should be simpler to perform an indirect jump:

```
asm volatile("ijmp" :: "z"(dummy));

```

Don't forget that your naked ISR has to save *all* the call-used registers, as well as `SREG`, `r0` and `r1`, in its custom prologue. And restore them in its epilogue. Check the AVR calling conventions.
> 1 votes

---
Tags: arduino-mega, arduino-ide, avr, assembly
---


# Question
Title: How can I measure if a battery is there?
With my arduino I want to measure if one / two AAA batteries are in their single / double battery holder.

When the Arduino is running, connected to some other power supply and the batteries are in place everything is fine: I get my measurements of around 1.5V / 3V on the analog pin the battery is connected to (- of battery and Arduino GND are connected as well of course).

Problems arise when I either

a) pull the batteries out: The analog pin is left floating. Not good. Can I put the pin into INPUT\_PULLUP mode? Is the internal resistor big enough? Or will the then connected 5V damage my batteries when they are back in the battery holder?

b) dissconect the Arduino from its external power supply: Because the Arduino is then "powered" by the 3V through the analog pin my blinking LED keeps blinking (at less brightness, but still...). I neither want the batteries to get drained nor damage my Arduino with it. So I would like to avoid this.

Actually I don't care about the actual battery voltage - I just want to know if the batteries are in their holder or not. And I want to leave the batteries there even though the Arduino is not powered. I would even consider something like "a button is held down when a battery is in its holder" or any other (simple) creative ideas.

Is this possible? How?

# Answer
I see 1 main problem: Keeping the batteries isolated, so that no current flows between them and the Arduino (especially no parasitic current into the input pin of a turned off Arduino), while still reading a voltage level (HIGH or LOW).

I would suggest using a fitting N-Channel MOSFET. Connect the minus pin of the batteries to ground and the plus pin to the gate of the MOSFET. Then source and drain of MOSFET to ground and a digital arduino pin respectively. Enable the internal pullup resistor. Add a pulldown resistor between gate and ground.

Now, without the batteries, the gate is at ground level, so the MOSFET is not conducting. The level at the input pin will be high. If the batteries are in, their voltage will activate the MOSFET, which pulls the Arduinos input pin to ground, thus LOW level. Since the MOSFET is somewhat like a capacitor between gate and the rest, almost no current will flow here (only enough to load the small capacitance). Though I'm not sure, I think that no current will flow either in the case of the Arduino being unpowered.

The task now would be to find a fitting MOSFET, which goes in saturation for 1.5V.

Of course you can also use a microswitch, that gets pushed down by the batteries. That is electronically easier, but maybe mechanically challenging.
> 0 votes

# Answer
You could add a pull**down** to the analog pin. If the ADC reads a value below e.f. 10, you could consider this the state when there are no batteries.

From the signal perspective a pullup would be better, because without batteries you would read 5V which is unambigous as it can not be provided by the batteries themselves. But in general I don't think that applying higher voltage to the batteries is good practice, even though you could limit the current with a reasonably high resistor.
> 0 votes

---
Tags: battery
---


# Question
Title: Error while reburning bootloader to atmega328p by usbasp in Arduino IDE
I have got the Bootloaded ATMega328P-PU from China and I want to reburn new bootloader into it. For this I use UsbAsp programmer. I want to do it in Arduino IDE. But when I try to flash, for example, an empty flash it says that error:

```
 Using Port                    : usb
         Using Programmer              : usbasp
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

avrdude: auto set sck period (because given equals null)
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: error: program enable: target doesn't answer. 0
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.

```

But when I work in *Avrdudeprog*, it works without any problems.
How can I fix it?

# Answer
> 1 votes
use Zadig 2.4 to change the driver for USBasp. USBasp works with 3 drivers but it seems the type of installed driver causes some problems in various software. khazama, progisp on one hand and Arduino on the other hand. despite all of them using avrdude.

libusb-win32 : khazama works, Arduino does not WinUSB : khazama doesn't work, Arduino works libusbK : both work

---
Tags: arduino-ide, atmega328, bootloader, usbasp
---


title: Confusion with ATmega328P and 3.3V/8MHz

text:
# Question
Title: Confusion with ATmega328P and 3.3V/8MHz
Firstly, I have tried to set the bootloader to be 8MHz internal oscillator.

I have tried the board setup from here - https://github.com/oshlab/Breadboard-Arduino.

And also the `breadboard-1-6-x.zip` setup from here - http://www.arduino.cc/en/Tutorial/ArduinoToBreadboard.

Burning the bootloader in both cases seems to work, with fuse settings of `-Uefuse:w:0x05:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xE2:m` (using Arduino IDE 1.6.7):

```
avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0x05:
avrdude: load data efuse data from input file 0x05:
avrdude: 1 bytes of efuse verified
...
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDA:
avrdude: load data hfuse data from input file 0xDA:
avrdude: 1 bytes of hfuse verified
...
avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xE2:
avrdude: load data lfuse data from input file 0xE2:
avrdude: 1 bytes of lfuse verified

```

When I try and run the test sketch (below) at these voltages:

* 3.3V it fails (tried multiple 3.3V sources, all fail).
* 4.23V (3xAA rechargeable batteries) it works.
* 4.8V (3xAA alkaline batteries) it works.
* 5V it works.

To try and determine if it was my power sources or the bootloader that was the problem I uploaded this test sketch on my ATmega328P, an Arduino Nano (all Nanos are 16MHz?) and a 16MHz Arduino Pro to see if the red LED (with 100 Ohm resistor for ATmega328P) lights up in about the same time. This test sketch also does not work at 3.3V, and must be run at 5V to work.

(*edit*) When running this test sketch at 3.3V I see **no** 3.3V logic level on **any** output pin with my multimeter. When running at 4.23, 4.28, 5V I see this logic level on all output pins.

(**update**) When connecting the +ve of the LED directly to 3.3V, the LED lights up. So the 3.3V source has enough power to light the LED directly.

So I assumed that because my ATmega328P circuit has no crystal in it (and the Nano and Pro Mini are 16MHz), these loops would execute in different amounts of time? But no, the loops *do* execute at the same speed (3 and a bit seconds) - so is my Nano/Pro Mini underclocked, or my ATmega still running at 16MHz but without a crystal?? Rather confused.

Thanks.

(**update**) I tried a second ATmega328P, same problem.

(*code edited to use 14 output pins*)

```
void setup() {
  for (int p=0; p<14; p++) pinMode(p, OUTPUT);
}

void loop() {
  // waste some time.
  int y = 0;
  for (int i = 0; i < 11; i++) {
    for (int j = 0; j < 11; j++) {
      for (int k = 0; k < 101; k++) {
        y+=analogRead(A0);
      }
    }
  }
  for (int p=0; p<14; p++) digitalWrite(p, y % 2);
  for (int p=0; p<14; p++) digitalWrite(p, HIGH);
  delay(1000);
  for (int p=0; p<14; p++) digitalWrite(p, !(y % 2));
  for (int p=0; p<14; p++) digitalWrite(p, LOW);
  delay(1000);
}

```

# Answer
It was a brownout fuse problem.

Changing `boards.txt` from:

`atmega328bb.bootloader.extended_fuses=0x05`

to

`atmega328bb.bootloader.extended_fuses=0x02`

solved it for me (\*).

The chip and red LED now work at 3.01V (1xAA alkaline and 1xAA rechargeable) and 3.19V (2xAA alkaline).

(\*) not sure why I had to invert the bits (`0000 0010`=0x02 versus `0000 0101`=0x05) when compared to the tables below.

---
> 4 votes

# Answer
If you are using an LED to indicate that your sketch is running, then that may be the problem.

For example, if you have a fairly average red LED, it might have a forward voltage of 2.0v @ 20ma (refer to your spec sheet for your particular LED). Putting these values into the LED calculator, it would tell you that you need a 150 ohm resistor. You might have tested this, and seen the LED light up.

Then, if you drop the voltage to 3.3v, your LED might be either very dim, or (more likely!) not light up at all. Putting 3.3v into the same web page, it shows you need a smaller resistor, 68 ohm, for the same LED.

P.S. - I just noticed your paragraph about the green LED - a "true green" LED might have a voltage drop of 3.3v, which means for 5v you would need a 100 ohm resistor (as described in your paragraph); for a 3.3v supply you would need a 1 ohm resistor instead. This is pretty certainly your problem
> 4 votes

# Answer
If you are powering your circuit off a cell battery, you might find that your battery cannot supply enough current. To test this, use a multimeter to measure the voltage of the battery, while your circuit is connected (and possibly, or possibly not, running). If the voltage drops below 2.7v (as defined by your fuses - use the AtMel Fuse Calculator page to see what your fuses mean), your chip will shut down, causing the voltage to rise back, turning the chip back on, and round it goes.The battery may even take a while to recover (I think last time this happened to me, it took about 10 seconds -I thought I'd destroyed the battery).

This is fairly common issue with motors (which draw a lot of power), but depends on your exact battery, and the exact load.

If this happens, you might get away with using multiple batteries in parallel (connect all the + sides together, to the + side of your circuit; all the - sides together to the - side of your circuit). Most battery holders are in series, which means they boost the voltage instead; you will have to do your own wiring for this.
> 2 votes

# Answer
Hy all,

I´m facing the same issue. Had an ATMEGA328P-PU with 8Mhz Oscillator on a breadboard that did not work with 3.3V (stabilized) as a supply. At 5V things work as expected.

Finally I got things running with extended fuses set to xxxxx110, which sets BOD to 1.8V. I coud verify that my ATMEGA328P-PU does not run with fuses set to xxxxx101 = 2,7V (max. 2.9V). The supply is about 3.4V and has blocking condensators, so it cannot be a supply issue.

Best regards, Eckehard
> 0 votes

---
Tags: atmega328, voltage-level, bootloader, oscillator-clock
---


title: pulseIn only returning 0

text:
# Question
Title: pulseIn only returning 0
I'm new to arduino and I've searched through a lot of posts but can't find anything to fix the issue.

I'm trying to send a signal through some medium (water in this example) using a pizoelectric transducer and measure the time it takes for the signal to go from transducer to the other.

Attached is an image of the setup. Below is the code.

```
const int trigPin = 1;
const int echoPin = 0;
float duration;

void setup() {
  pinMode (trigPin, OUTPUT);
  pinMode (echoPin, INPUT);
  Serial.begin (9600);
}

void loop() {
  // set transmitting pin to low
  digitalWrite (trigPin, LOW);
  delayMicroseconds (2);

  // send the signal
  digitalWrite(trigPin, HIGH);
  digitalWrite (trigPin, LOW);

  // read in the signal on receiving pin, print duration to the Monitor
  duration = pulseIn (echoPin, HIGH);
  Serial.print("duration: ");
  Serial.print(duration);
  Serial.print("\n");
}

```

The issue is "duration" variable has been 0 in all of my tests. I've tried using various values for the timeout parameter in pulsIn to no avail. Any advice is appreciated.

# Answer
> 0 votes
There are a few issues here.

The most obvious is that you are using the wrong pins. On the Arduino Uno, digital 0 is the serial RX pin, and digital 1 is TX. Thus, if you use `Serial` in your sketch, you cannot use these pins for anything else.

At a more fundamental level, it looks from your picture that you have connected your Arduino to a couple of bare piezo transducers. Your code, on the other hand, assumes the Arduino is connected to a digital sonar module, like the very common HC-SR04. You have to keep in mind that a piezo transducer is an analog device. The sonar module, on the other hand contains quite a few electronic parts that take care of conditioning the analog signals and providing an easy to use digital interface, where you just have to call `pulseIn()` to get the measurement.

If you want to use the bare piezo transducers, the first thing you have to do is *read their datasheet*. This is really essential. Once you have read (and understood) that document, you can figure out whether or not you need some interface electronics between the piezos and your Arduino. Maybe you can get away with exciting the transmitter with PWM and reading the receiver with the on-board ADC. Or maybe not. First read the datasheet, then design your circuit, then test using a scope to look at your signals.

---
Tags: arduino-uno
---


title: Sim808 module HTTP Bad request

text:
# Question
Title: Sim808 module HTTP Bad request
I have an Arduino UNO and sim808 EVB-V3.02.4. I want to send a GET request to my url but I always receive 400 Http bad request error.

```
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>

#define PIN_TX    7
#define PIN_RX    8
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,

char http_cmd[] = "GET /index.php?lat=10&long=100 HTTP/1.0\r\n\r\n";
char buffer[512];

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

void loop() {
  //*********** Attempt DHCP *******************
  while(!sim808.join(F("cmnet"))) {
      Serial.println("Sim808 join network error");
      delay(2000);
  }

  //************ Successful DHCP ****************
  Serial.print("IP Address is ");
  Serial.println(sim808.getIPAddress());

  //*********** Establish a TCP connection ************
  while(!sim808.connect(TCP,"39c309ae.ngrok.io", 80)) {
      Serial.println("Connect error");
  }
  Serial.println("Connection success");

  //*********** Send a GET request *****************
  Serial.println("waiting to fetch...");
  sim808.send(http_cmd, sizeof(http_cmd)-1);
  while (true) {
      int ret = sim808.recv(buffer, sizeof(buffer)-1);
      if (ret <= 0){
          Serial.println("fetch over...");
          break;
      }
      buffer[ret] = '\0';
      Serial.print("Recv: ");
      Serial.print(ret);
      Serial.print(" bytes: ");
      Serial.println(buffer);
      break;
  }

  //************* Close TCP or UDP connections **********
  sim808.close();

  //*** Disconnect wireless connection, Close Moving Scene *******
  sim808.disconnect();
  delay(5000);
  }

```

My php code:

```
<?php
file_put_contents('test.txt', $_GET['lat'] . '---' . $_GET['lon']);
print '
<html>
<head>
<title>Good</title>
</head>
<body>
Was Good
</body>
</html>
';
?>

```

I want just open http://39c309ae.ngrok.io/index.php?lat=10&long=100 with arduino and sim808.

What is wrong in my codes?

# Answer
> 1 votes
You aren't sending the `Host:` header with your request. Without that the web server has no idea which website you want to get the /index.php page from.

```
char http_cmd[] = "GET /index.php?lat=10&long=100 HTTP/1.0\r\n"
                  "Host: 39c309ae.ngrok.io\r\n"
                  "\r\n";

```

---
Tags: arduino-uno, gsm, http
---


title: Wiring ESP8266 and PN532

text:
# Question
Title: Wiring ESP8266 and PN532
I'm trying the Android Hce example in this PN532 library. I can't find how to set SDA and SCL address in the code, so I tried connecting them in CLK and SD0 pins. The serial monitor gives me "Didn't find PN53x board". Can someone help me?

```
    #if 0
      #include <SPI.h>
      #include <PN532_SPI.h>
      #include "PN532.h"

      PN532_SPI pn532spi(SPI, 10);
      PN532 nfc(pn532spi);
    #elif 1
      #include <PN532_HSU.h>
      #include <PN532.h>

      PN532_HSU pn532hsu(Serial1);
      PN532 nfc(pn532hsu);
    #else
      #include <Wire.h>
      #include <PN532_I2C.h>
      #include <PN532.h>
    #endif

    void setup()
    {
        Serial.begin(115200);
        Serial.println("-------Peer to Peer HCE--------");

        nfc.begin();

        uint32_t versiondata = nfc.getFirmwareVersion();
        if (! versiondata) {
          Serial.print("Didn't find PN53x board");
          while (1); // halt
        }

        // Got ok data, print it out!
        Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
        Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
        Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

        // Set the max number of retry attempts to read from a card
        // This prevents us from waiting forever for a card, which is
        // the default behaviour of the PN532.
        //nfc.setPassiveActivationRetries(0xFF);

        // configure board to read RFID tags
        nfc.SAMConfig();
    }

    void loop()
    {
      bool success;

      uint8_t responseLength = 32;

      Serial.println("Waiting for an ISO14443A card");

      // set shield to inListPassiveTarget
      success = nfc.inListPassiveTarget();

      if(success) {

         Serial.println("Found something!");

        uint8_t selectApdu[] = { 0x00, /* CLA */
                                  0xA4, /* INS */
                                  0x04, /* P1  */
                                  0x00, /* P2  */
                                  0x07, /* Length of AID  */
                                  0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* AID defined on Android App */
                                  0x00  /* Le  */ };

        uint8_t response[32];

        success = nfc.inDataExchange(selectApdu, sizeof(selectApdu), response, &responseLength);

        if(success) {

          Serial.print("responseLength: "); Serial.println(responseLength);

          nfc.PrintHexChar(response, responseLength);

          do {
            uint8_t apdu[] = "Hello from Arduino";
            uint8_t back[32];
            uint8_t length = 32;

            success = nfc.inDataExchange(apdu, sizeof(apdu), back, &length);

            if(success) {

              Serial.print("responseLength: "); Serial.println(length);

              nfc.PrintHexChar(back, length);
            }
            else {

              Serial.println("Broken connection?");
            }
          }
          while(success);
        }
        else {

          Serial.println("Failed sending SELECT AID");
        }
      }
      else {

        Serial.println("Didn't find anything!");
      }

      delay(1000);
    }

    void printResponse(uint8_t *response, uint8_t responseLength) {

       String respBuffer;

        for (int i = 0; i < responseLength; i++) {

          if (response[i] < 0x10)
            respBuffer = respBuffer + "0"; //Adds leading zeros if hex value is smaller than 0x10

          respBuffer = respBuffer + String(response[i], HEX) + " ";
        }

        Serial.print("response: "); Serial.println(respBuffer);
    }

    void setupNFC() {

      nfc.begin();

      uint32_t versiondata = nfc.getFirmwareVersion();
      if (! versiondata) {
        Serial.print("Didn't find PN53x board");
        while (1); // halt
      }

      // Got ok data, print it out!
      Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
      Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
      Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

      // configure board to read RFID tags
      nfc.SAMConfig();
    }

```

# Answer
Solved. Set #if 1 and #elif 0. Connected: SCK to D5 MISO to D6 MOSI to D7 SS to D0 (and set it on pn532spi)
> 1 votes

---
Tags: esp8266, library, wires
---


# Question
Title: Maze solving robot turning failure due to sensor distance to the corner increasing during the turn
At my school we have a project where we have to make a robot that can solve a 3D-maze using an arduino controlled robot that uses ultrasonic sensors to determine how to turn. The robot may not be pre-programmed and must work on all simple mazes with 90d turns.

I have figured out most of the code I think, however my problem is that when the robot needs to turn. Since how much and which direction the robot should turn is determined by distance sensors, the distance to the corners increase, making it longer than what is required to turn. This makes the robot want to turn back into the corner and then it gets stuck in a loop of turning in and out of the corner (see image attached).

Note: we don't want to program a 90d turn as it could mess up later and we believe it better to try make how long the robot should turn be determined by the value of the different sensors.

The robot is made up of three ultrasonic sensors, front, right, and left. The robot has tracks which lets it turn on the spot. The arduino is an arduino mega, so it is fast at updating and measuring values (unless the time needed for measuring the distance is long).

Files:

Pictures describing the turning problem:

Images of the robot:

If any other information is needed that is left out, I will try to obtain it (such as images, dimensions, exact component names, etc.)

The entire code:

```
enum robState {
  robInit,
  robInitForward,
  robInitRotL,
  robInitRotR,
  robStop,
  //robWaitCrystals,
  robInitBack,
  robReset,
  robFindWay
};

struct LFR {
  int L;
  int F;
  int R;
};

struct robMotor {
  byte pwm;
  byte dir_1;
  byte dir_2;
};

robState robStatus;
//const int robTurnSpeed = 255;
robMotor motorL = {2, 4, 3};
robMotor motorR = {5, 6, 7};

int dirInt = 1;
LFR echoPin = {12, 11, 13};
LFR trigPin = {24, 26, 22};
LFR distance;
const int robStartStopPin;

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

  //init pinModes
  initPins();

  Serial.begin(9600);
  robStatus = robInit;
}

void loop() {
  int disWall = 12;
  // put your main code here, to run repeatedly:
  distance.L = distanceUpdater(trigPin.L, echoPin.L);
  distance.F = distanceUpdater(trigPin.F, echoPin.F);
  distance.R = distanceUpdater(trigPin.R, echoPin.R);
  Serial.print("/n distance.L= ");
  Serial.println(distance.L);
  Serial.print("/n distance.F= ");
  Serial.println(distance.F);
  Serial.print("/n distance.R= ");
  Serial.println(distance.R);
  //delayMicroseconds(50);

  switch (robStatus) {

    case robInit:
      //init motors and shit
      motor(0, 0);
      motor(1, 0);
      //wait for start/stop
      //while (digitalRead(robStartStopPin) == LOW);
      Serial.print("/n robInit");
      robStatus = robFindWay;
      break;

    case robInitForward:
      motor(0, 1);
      motor(1, 1);
      Serial.print("/n robInitForward");
      robStatus = robFindWay;
      break;

    case robFindWay:

      Serial.print("/n robFindWay");
      if (distance.R > disWall) {
        //if open to right, turn right.
        robStatus = robInitRotR;
      }
      else if ((distance.R < disWall) && (distance.F > disWall)) {
        //go forward if you can't go right
        robStatus = robInitForward;
      }

      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L > disWall)) {
        //if nothing else works, turn left.
        robStatus = robInitRotL;
      }
      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L < disWall)) {
        //found the end, must turn. turns left.
        robStatus = robInitRotL;
      }
      else {
        Serial.print("shit somethings wrong with path finding");
      }
      break;

    case robInitRotL:
      Serial.print("robInitRotL");
      //forward direction of motorR
      motor(1, 1);
      //reverse direction of motorL
      motor(0, -1);
      //send the correct motor speed*/
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robInitRotR:
      Serial.print("robInitRotR");
      //reverse direction of motorR
      motor(1, -1);
      //forward direction of motorL
      motor(0, 1);
      //send right motor speed
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robStop:
      motor(0, 0);
      motor(1, 0);
      //while (digitalRead(robStartStopPin) == LOW);
      robStatus = robInit;
      break;

    case robInitBack:
      //reverse both motors
      motor(0, -1);
      motor(1, -1);
      break;
  }

}

void initPins() {
  //init motors
  pinMode(motorL.pwm, OUTPUT);
  pinMode(motorL.dir_1, OUTPUT);
  pinMode(motorL.dir_2, OUTPUT);

  pinMode(motorR.pwm, OUTPUT);
  pinMode(motorR.dir_1, OUTPUT);
  pinMode(motorR.dir_2, OUTPUT);
  //init sensors
  pinMode(trigPin.L, OUTPUT);
  pinMode(trigPin.F, OUTPUT);
  pinMode(trigPin.R, OUTPUT);

  pinMode(echoPin.L, INPUT);
  pinMode(echoPin.F, INPUT);
  pinMode(echoPin.R, INPUT);
  //init button
  pinMode(robStartStopPin, INPUT);
  //init power sources
  /*pinMode(VCCPin1, OUTPUT);
  digitalWrite(VCCPin1, HIGH);
  pinMode(GNDPin1, OUTPUT);
  digitalWrite(GNDPin1, LOW);*/
}

void motor(int side, int action) {
  //side 0=L 1=R
  //action -1=reverse 0=still 1=forward
  int normalSpeed = 255;
  if ((side == 0) && (action == -1)) {
    //reverse left
    digitalWrite(motorL.dir_1, LOW);
    digitalWrite(motorL.dir_2, HIGH);
    analogWrite(motorL.pwm, normalSpeed);
  }
  else if ((side == 0) && (action == 0)) {
    //still left
    digitalWrite(motorL.dir_1, HIGH);
    digitalWrite(motorL.dir_2, LOW);
    analogWrite(motorL.pwm, 0);
  }
  else if ((side == 0) && (action == 1)) {
    //forward left
    digitalWrite(motorL.dir_1, HIGH);
    digitalWrite(motorL.dir_2, LOW);
    analogWrite(motorL.pwm, normalSpeed);
  }
  else if ((side == 1) && (action == -1)) {
    //reverse right
    digitalWrite(motorR.dir_1, LOW);
    digitalWrite(motorR.dir_2, HIGH);
    analogWrite(motorR.pwm, normalSpeed);
  }
  else if ((side == 1) && (action == 0)) {
    //still right
    digitalWrite(motorR.dir_1, HIGH);
    digitalWrite(motorR.dir_2, LOW);
    analogWrite(motorR.pwm, 0);
  }
  else if ((side == 1) && (action == 1)) {
    //forward right
    digitalWrite(motorR.dir_1, HIGH);
    digitalWrite(motorR.dir_2, LOW);
    analogWrite(motorR.pwm, normalSpeed);
  }
  else {
    Serial.print("monkaS wrong motor inputs");
  }
}

int distanceUpdater(int trigPin, int echoPin) {
  long duration;
  int distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration * 0.034 / 2);
  return distance;
}

```

The pathfinding and turning:

```
switch (robStatus) {

    case robInit:
      //init motors and shit
      motor(0, 0);
      motor(1, 0);
      //wait for start/stop
      //while (digitalRead(robStartStopPin) == LOW);
      Serial.print("/n robInit");
      robStatus = robFindWay;
      break;

    case robInitForward:
      motor(0, 1);
      motor(1, 1);
      Serial.print("/n robInitForward");
      robStatus = robFindWay;
      break;

    case robFindWay:

      Serial.print("/n robFindWay");
      if (distance.R > disWall) {
        //if open to right, turn right.
        robStatus = robInitRotR;
      }
      else if ((distance.R < disWall) && (distance.F > disWall)) {
        //go forward if you can't go right
        robStatus = robInitForward;
      }

      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L > disWall)) {
        //if nothing else works, turn left.
        robStatus = robInitRotL;
      }
      else if ((distance.R < disWall) && (distance.F < disWall) && (distance.L < disWall)) {
        //found the end, must turn. turns left.
        robStatus = robInitRotL;
      }
      else {
        Serial.print("shit somethings wrong with path finding");
      }
      break;

    case robInitRotL:
      Serial.print("robInitRotL");
      //forward direction of motorR
      motor(1, 1);
      //reverse direction of motorL
      motor(0, -1);
      //send the correct motor speed*/
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robInitRotR:
      Serial.print("robInitRotR");
      //reverse direction of motorR
      motor(1, -1);
      //forward direction of motorL
      motor(0, 1);
      //send right motor speed
      robStatus = robFindWay;
      /*analogWrite(motorR.pwm, robTurnSpeed);
        analogWrite(motorL.pwm, robTurnSpeed);*/
      break;

    case robStop:
      motor(0, 0);
      motor(1, 0);
      //while (digitalRead(robStartStopPin) == LOW);
      robStatus = robInit;
      break;

    case robInitBack:
      //reverse both motors
      motor(0, -1);
      motor(1, -1);
      break;
  }

```

# Answer
> 1 votes
Your main loop (`loop()`) is powering through the whole code continuously. It wouldn't be a bad idea to put some "breaks" between each sensor scan cycle. For example:

```
long timerCounter = 0;

void setup()
{
    // Do your setup here

    timerCounter = millis();
}

void loop()
{
    // Only do some code every 1 second (1000ms)
    if (millis() - timerCounter >= 1000)
    {
        ScanSensor1();
        ScanSensor2();
        ScanSensor3();

        robState state = DetermineStateFromSensorReadings();

        DoActionForState(state);
    }
}

```

What this does is break the cycle down to 1Hz (change as you wish). When you are using ultrasonics (as per your images), it's always a good idea to reduce the intervals between each reading, as it allows residual noise to quieten down. Imagine the beeping sound from the sonar on a submarine.

You've got the right idea by using a state machine in your code. Each cycle can determine which state it should be in after reading the sensor data. Good job on that!

Just some additional information about ultrasonics regarding your project:

* Sonar has an emission angle of 30 degrees (not a straight line!). Imagine a code pointing out with an angle of 30 degrees. This means anything inside this range could be picked up by the sensor. Looking at your *turning problem image 2*, I'd expect a lot of erroneous data from that sensor pointing towards the corner.
* Multiple sensors working at the same frequency (40kHz?) may interfere with each other.

The problem you are seeing is mainly caused by the fact that you are checking the walls around you as you are turning. I would suggest you use either the forward facing sensor or the opposite sensor to that in *turning problem image 2* to significantly reduce erroneous data.

If your budget (and time) allows, you may benefit from using a cheap Lidar (like this one for example) to more accurately determine your surrounding. Lidar doesn't have an emission angle, which means that it's measurement point is in a straight line from the source.

# Answer
> 1 votes
You need two states. Making a turn and not making a turn.

Once you start making a turn, ignore the side sensors, and continue turning until *the front sensor distance has reached its peak*.

---
Tags: algorithm, sensors
---


# Question
Title: 2 buttons pressed at the same time elevator logic
I have currently created a working elevator code where the elevator goes up when pressed a button, and stops at a floor when the sensor senses that it has reached the floor. This is how it works:

```
#define Buzzer 5

#define pwmMot 6

#define halPin 8

#define butto1 9  //level 1
#define butto2 10 //level 2
#define butto3 11 //level 3

#define SeEcho 12
#define SeTrig 13

int button1_status = 0;
int button2_status = 0;
int button3_status = 0;

int current_level = 1;
int required_level =-1;

void setup(){
  Serial.begin(9600);
  pinMode(Buzzer, OUTPUT);
  digitalWrite(Buzzer, HIGH);
  pinMode(halPin, INPUT);
  pinMode(butto1, INPUT);
  pinMode(butto2, INPUT);
  pinMode(butto3, INPUT);
  pinMode(SeTrig, OUTPUT);
  pinMode(SeEcho, INPUT);
  pinMode(pwmMot, OUTPUT);
  Serial.println("you are in level 1");
}

void emergencyStop(){
  analogWrite(pwmMot, 255);
}
int sensor() {
  unsigned long duration;
  int distance;
  digitalWrite(SeTrig, LOW);
  delayMicroseconds(2);
  digitalWrite(SeTrig, HIGH);
  delayMicroseconds(5);
  digitalWrite(SeTrig,LOW);
  duration = pulseIn(SeEcho,HIGH);
  distance = int(duration/2/29.412);
  return distance;
}

bool hallSen(){
  return digitalRead(halPin);
}

int going_up(){
  while (sensor() > 12){
    analogWrite(pwmMot, 1600);
  }
  return 1;
}

int going_down(){
  while (sensor() > 12){
    analogWrite(pwmMot, 570);
  }
  return 1;
}

void loop() {
  button1_status = digitalRead(butto1);
  button2_status = digitalRead(butto2);
  button3_status = digitalRead(butto3);
  required_level = button1_status == HIGH ? 1 : button2_status == HIGH ? 2 : button3_status == HIGH ? 3 : -1;
  if (required_level != -1 && required_level != current_level){
    while (current_level != required_level){
      if (current_level > required_level) Serial.println("Going Down"), current_level-=going_down();
      else if (current_level< required_level) Serial.println("Going Up"), current_level+=going_up();
      Serial.print("you are in level "); Serial.println(current_level);
      delay(1000);
    }
    analogWrite(pwmMot, 1550); //stop elevator
    digitalWrite(Buzzer, LOW);
    delay(100);
    digitalWrite(Buzzer, HIGH);
    required_level = -1;
  }
}

```

Now I am just curious as to how I will extend this so that for example if we are in level 1, both the levels 2 and 3 are pressed it should go to level 2 even if level 3 was pressed first. Or if we are in level 2 and both level 1 and 3 are pressed, it should go to the one that is pressed first as both levels are the same distance from level 2.

# Answer
> 3 votes
> if we are in level 1, both the levels 2 and 3 are pressed it should go to level 2 even if level 3 was pressed first.

For this to work, the program should remember which buttons (mind the plural!) have been pressed. Thus, instead of remembering only one request, as in

```
int required_level =-1;

```

it should have a boolean variable for each of the possible levels, telling us whether a stop was requested for that level.

For convenience, I would number the levels from zero, and hold these variables in an array:

```
const int LEVEL_COUNT = 3;
bool requested_stop[LEVEL_COUNT];

```

> if we are in level 2 and both level 1 and 3 are pressed, it should go to the one that is pressed first *as both levels are the same distance from level 2*.

The part I emphasized doesn't make sense to me. The elevator should go to the one that was pressed first, *irrespective of the distances*. Imagine you are in an elevator at level 5, and press the button for level 2. As the elevator just starts moving down, another rider presses the button for level 6. Should the elevator immediately revert to going up in order to reach level 6, which is closer? Of course not. If it is going down, it should continue in that direction. Now, if the other rider presses 3, it should stop by level 3 on its way down, even though you pressed 2 first.

As stated by chrisl in a comment, a finite state machine is definitely the solution for this kind of problems. I propose a state machine with three states, `STOPPED`, `GOING_UP`, and `GOING_DOWN`:

* when `STOPPED`, it should change to `GOING_UP` or `GOING_DOWN` as soon as a button for another level is pressed
* when `GOING_UP`, as soon as it reaches a level that has been requested, it should change to `STOPPED`
* same thing when `GOING_DOWN`.

And here is my proposed implementation:

```
void loop() {
    // Check the buttons.
    for (int i = 0; i < LEVEL_COUNT; i++)
        if (digitalRead(button[i]) == HIGH)
            requested_stop[i] = true;

    // Finite state machine.
    static enum { STOPPED, GOING_UP, GOING_DOWN } state = STOPPED;
    switch (state) {
    case STOPPED:
        requested_stop[current_level] = false;
        for (int i = 0; i < LEVEL_COUNT; i++) {
            if (requested_stop[i]) {
                if (i < current_level) {
                    analogWrite(pwmMot, PWM_DOWN);
                    state = GOING_DOWN;
                    break;
                } else if (i > current_level) {
                    analogWrite(pwmMot, PWM_UP);
                    state = GOING_UP;
                    break;
                }
            }
        }
        break;
    case GOING_UP:
        if (elevator_height() >= LEVEL_HEIGHT[current_level + 1]) {
            current_level++;
            if (requested_stop[current_level]) {
                analogWrite(pwmMot, PWM_STOP);
                state = STOPPED;
            }
        }
        break;
    case GOING_DOWN:
        if (elevator_height() <= LEVEL_HEIGHT[current_level - 1]) {
            current_level--;
            if (requested_stop[current_level]) {
                analogWrite(pwmMot, PWM_STOP);
                state = STOPPED;
            }
        }
        break;
    }
}

```

This code assumes you have written the function `elevator_height()` that measures the height of the elevator, and have defined an array of constants `LEVEL_HEIGHT[]`.

Notice that this is still far from perfect. You should probably ensure that each stop lasts at least some minimum duration. Otherwise, if the elevator stops at level 1 while level 0 has also been requested, the stop will only last an instant. This can be achieved by splitting the `STOPPED` state in two distinct states, and switching from “waiting for the riders to go in/out” to “waiting for a button to be pressed” on a timeout. You may also want to ensure that, after a stop, the elevator continues in the same direction if possible. Otherwise it will never reach level 2 if some joker is repeatedly pressing 0 and 1.

---
Tags: serial, motor, button
---


title: Communication with sensor KMX63 in I2C

text:
# Question
Title: Communication with sensor KMX63 in I2C
I trying to use a new sensor the KMX63 with a Arduino Uno board, my sensor is on a evaluation board made by kionix. For the connexion il linked as follows:

| Pin Uno | Pin evaluation board |
| A5 | 5 |
| A4 | 7 |
| 3.3 | 1 |
| GND | 8 |

Here the schematic of the evaluation board:

I found a technical note from the constructor that advice to do some steps after the power up of the sensor to insure it's well functioning I wrote a code following it:

```
#include <Wire.h>
#include "KMX62.h"

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

  Serial.println(F("Starting"));

  byte error=7;
  byte id=0;
  byte command=0;
  delay(60);
  Wire.beginTransmission(KMX62_I2C_ADD_2);
  Wire.write(0x7F);
  Serial.println(F("Write 0x7F"));
  Wire.write(0x00);
  Serial.println(F("Write 0x00"));
  delay(100);
  error=Wire.endTransmission();
  Serial.print(F("retour 1 : "));
  Serial.println(error);
  if( error==0 ){
    Wire.beginTransmission(KMX62_I2C_ADD_2);
    Wire.write(CNTL2);
    Wire.write(0x00);
    error=Wire.endTransmission();
    if( error==0 ){
      Wire.beginTransmission(KMX62_I2C_ADD_2);
      Wire.write(CNTL1);
      Wire.write(0x80);
      error=Wire.endTransmission();
      if(error==0){
        delay(5);
        Wire.beginTransmission(KMX62_I2C_ADD_2);
        Wire.write(WHO_AM_I);
        Wire.endTransmission(false);
        Wire.requestFrom(KMX62_I2C_ADD_2,1);
        id=Wire.read();
        error=Wire.endTransmission();
        if(id==0x18||id==0x2D){
          Wire.beginTransmission(KMX62_I2C_ADD_2);
          Wire.write(COTR);
          Wire.endTransmission(false);
          Wire.requestFrom(KMX62_I2C_ADD_2,1);
          command=Wire.read();
          error=Wire.endTransmission();
          if(command==0x55){
            Serial.println(F("device ok"));
          }else{
            Serial.println(F("Issue with the sensor step e : need to be rebooted"));
          }
        }else{
          Serial.println(F("Issue with the sensor step d id=wrong : need to be rebooted"));
        }
      }else{
        if(error==2||error==3){
        Serial.println(F("Issue with the sensor step c : need to be rebooted"));
        }
      }
    }else{
      if(error==2||error==3){
        Serial.println(F("Issue with the sensor step b : need to be rebooted"));
      }
    }
  }
}

void loop(){

}

```

but i have an issue the steps , the program seem to freeze when i try to write into the register 0x7F.
I don't get any trace that i should have after the wire.endtransmission().
Here the trace i obtain :

```
09:56:35.477 -> Starting
09:56:35.511 -> Write 0x7F
09:56:35.511 -> Write 0x00

```

i have use the I2C scanner to check if the sensor appear, i had to modify the scanner to add a delay before Wire.beginTransmission and the Wire.endTransmission to avoid the scanner to be freeze too at the first address tried. After the modification i did saw the sensor at the address it was mean to be. here the trace for the I2C scanner :

```
Scanning...
I2C device found at address 0x0F  !
done

```

Anyone have an idea of why i can't write anything to my sensor without making my program freeze indefinitely each time ?

PS : After the advice of chrisl i rerunned all my programs on a arduino mini pro on 3.3V / 8Mhz and got the same result.

# Answer
> 1 votes
I finally found where the problem was, i had made a error on the reading of the schematic of the evaluation board. I thought that the pin J1-9 was already wired in intern but it was wrong. I wired it to the VCC output of my board and it work perfectly now.

---
Tags: arduino-uno, sensors, i2c, arduino-mini
---


# Question
Title: Why do most arduino function return a -1 instead of a 0
Many arduino functions return -1 if something 'fails'. Serial.read for example returns -1 or the infamous ÿ when this function is called while the serial buffer is empty.

As embedded C progammer, I am personally a fan of letting functions return data in the form of modifying pointers which points to passed on addresses and return states with the actual return functionality of a function. I am used to return a 0 if a function is 'not done' or 'failed'.

I see no logic in why many arduino functions return an int type which contains -1 instead of just a 0.

Would it not be better to let functions return a boolean type or an unsigned char type in which false or '0' would indicate a 'failed' process and true or '1' would indicate a 'succesful' process?

Also: if I type: `if(Serial.read()) {/* body */ }` and `Serial.read()` returns -1 because the buffer is empty. Will the If's body be executed or not?

# Answer
> 3 votes
I cannot assert anything for sure, as I was not involved in the design of the Arduino APIs. However, just like Elliot Alderson, I suspect this was inspired by the traditional C APIs. The manual page for `getchar()`, which is a very old function from the standard C library, states:

> **fgetc**(), **getc**() and **getchar**() return the character read as an *unsigned char* cast to an *int* or **EOF** on end of file or error.

Given that `EOF` is usually defined as `-1`, this is consistent with the behavior of `Serial.read()`.

Being beginner-friendly is also a *major* goal of the API. Pointers are known to be a *huge* difficulty for beginners.

There may also be some efficiency considerations involved. Arduino started on the AVR platform. This is a RISC architecture, with a large number of generic CPU registers (namely 32). The compiler usually manages to allocate most local variables to registers. The calling convention ensures that in most cases function parameters and return values also go through CPU registers. This means we can avoid many RAM accesses, which are inherently much slower than register access. Using a return-by-pointer convention defeats these optimizations.

Lastly, it is a good thing that simple things are easy to write. For example, an interpreter for single-character commands can be very easily written as:

```
switch (Serial.read()) {
case 'a':
    do_command_a();
    break;
case 'b':
    do_command_b();
    break;
// etc...
}

```

with no need to explicitly test for the serial buffer not being empty. Obviously, a more complex command language will need a full-blown interpreter, but the focus of Arduino has always been on *simple* programs being easy to write.

# Answer
> 1 votes
Arduino API is port of Processing. Processing is Java API to communicate with a MCU running Firmata. Arduino enabled sketches with the same API to run directly on the MCU.

So for example stream functions from Java stream classes were ported to Arduino API. This includes the read() function, to read one byte. Of course Java and Java basic libraries have inspiration in C++.

For other read and write functions, if the return value is count of bytes written or read then 0 is a valid return value and -1 indicates error.

Processing, Wiring and Arduino were created by interactive arts teachers and students, not by embedded systems developers. So you can't wonder about not ideal data types used. Later some things were improved by software developers.

---

as embedded C developer you should know that:

* 0 is a valid value to read, so it can't be a value indicating error
* 'if' executes if the evaluated value is not 0

# Answer
> 0 votes
I suspect that this a legacy from Unix command programming, which was first done in C. For commands that only needed to return status and not data, a return value of zero meant success and any other return value indicated some kind of failure. Individual programmers could designate specific non-zero values for specific error types, if desired.

Remember that the return value comes back to the calling function in a register. And these days the term "Arduino" encompasses a broad range of architectures, including 32-bit ARM Cortex-M. Specifying that the return value is a char offers no advantage in this case.

The boolean datatype is a fairly recent addition to the C language, so it's not surprising that you don't see it used much in existing, portable libraries.

Returning an address from a simple function that just needs to indicate success or failure seems like overkill.

If you really want control over the datatypes, include `stdint.h` and use the types defined therein. If you want an unsigned 8-bit value use `uint8_t` and not `unsigned char`. If you want to allow the compiler to choose the best datatype that is at least 8 bits, use `uint_fast8_tf`.

# Answer
> 0 votes
-1 is returned when "0" would be a perfectly valid response.

To take your example of `Serial.read()`: 0 is a valid byte or ASCII character. -1 isn't. If you returned 0 for "failure" then there would be no way of differentiating between that and the valid byte value 0.

---
Tags: library, functions
---


# Question
Title: Is it support to use Infrared radiation module in ESP12E?
I have a IR module --\>image as shown

is it possible to use the IR module in esp8266?

how to do(sent and receive)?

what is the packet format of IR module?

please explain.

Thanks

# Answer
> is it possible to use the IR module in esp8266?

Yes.

> how to do(sent and recive)?

You send by pressing a button on your remote control. You receive by measuring the timing of the changes in the pin state.

> what is the packet format of IR module?

Whatever packet format your remote control sends.

It's no different using IR on an ESP8266 compared to an Arduino. There's a library that everyone uses (IRRemote.h), and there are plenty of examples and tutorials on the web (or on YouTube if you can't be bothered to read). I suggest you ask Google for some.
> 1 votes

---
Tags: esp8266, ir
---


# Question
Title: How can I program a ATmega328 au tqfp32 ( SMD ) chip?
I have some experience with the Arduino UNO , Nano , mega etc .. But today I want to upgrade my skills and knowledge to next level . So I am about to design my own PCB for ATmega328 au ( SMD ) but this time I want to use a tqfp32 programmer to get the job done .. I have searched the internet and I have found that people use Universal programmers ( ISP ) such as Top2013 universal programmer or TL86ii but I have no idea how to use them and I don't even know what software that the youtubers are using ... They are actually uploading some \*.hex files it seems I am not sure but they aren't using Arduino IDE . According to my knowledge they are using a tqfp32 to dip28 programming module ( I have attached a pic ) . And then the Module is mounted on top of the ISP . Then they have uploaded code using some unknown software. And few people are using USBasp , can any explain me the scenario and what they have done .. https://youtu.be/GFyr9tVEHzQ The link is a reference video .

# Answer
> 2 votes
To upload compiled code (.hex) to a bare atmega which doesn't have a bootloader installed you can use ISP. As this stands for **i**n-**s**ystem-**p**rogramming you don't have to flash the chip before assembly, but you can flash it in-system, so when already soldered onto your pcb. There actually is no need for those adapters like shown in your first picture, which often are a bit expensive. Also, both pictures stand in contrast to the idea of ISP, they seem to show firmware upload via serial connection, which as far as I know only works with a bootloader already installed... ISP is based on SPI (serial peripheral interface) and you need to break out the corresponding pins to fit this connector. This obviously has the advantage of being able to update a firmware afterwards without the need of a bootloader.

Atmel provides a tool for flashing firmware via ISP which is called `avrdude` (tutorial) or you can use the atmel studio. To compile your code, you can use avr-gcc.

# Answer
> 1 votes
I use Atmel AVR ISP MKii, which is a dedicated Programmer - it connects via USB to the PC, and to the Power/Gnd/Reset/SCK/MOSI/MISO pins of the SMD device (i.e. the pins that connect to an ICSP header if one were installed). Then in the IDE you can select Upload Using Programmer, and it will load the .hex file that is created as part of the IDE compilation process into the chip. This blows away any bootloader that might exist.

The Arduino as ISP does the same, running a sketch on an Uno for example that then interfaces with the PC and the target device to program it via the ICSP connection.

If the pins are not brought to a header, but are accessible via edge connecters, than a Programmer adapter can be used to connect the Programmer to the desired pins. Imagine this board had a SMD package vs a DIP - then the 6 wires are connected to the desired pins, in this case via flying wires, and programming can be done. A FTDI module is connected to other pins (5V, Gnd, DTR, Tx, Rx) just to provide power to the board. The AVR ISP MKii only monitors the power level in use (generally 3.3V or 5V) and adjusts its output levels accordingly.

The TQFP socket you show would generally be used to pre-program chips in a manufacturing type environment before they are installed on boards, or by a distributor like Digikey if you were ordering a large quantity of parts.

Making the ICSP pins accessible on board somehow is often not hard, and can be beneficial for making changes.

Here is an example of the same chip in a TQFP package, and you can see the dedicated ICSP and FTDI headers to allow onboard bootloading and then Serial downloads of code being developed.

I find the dedicated hardware very convenient as I bootload and/or program a lot of boards and SMD chips on boards.

I also have this adapter for Atmega328P chips that are installed on a board. There are 6 little spring-loaded pins that press down onto the chip's ICSP pins from above to allow programming when an ICSP header is not provided, or the signals are not brought out to accessible pins. Unfortunately, hobbyking.com does not stock them anymore, this has gotten me out of a jam on occasion.

---
Tags: arduino-nano, atmega328, isp, arduinoisp
---


# Question
Title: Reset arduino nano after disabling tx/rx
I know, i am a bit dummy sometimes and i don't know why i actually did this but here it is. I have an arduino nano and i want it to use an external power via the the Vin port using a 12V external power supply. I thought this would be as simple as replacing the usb power supply by my external 12V power supply on the Vin pin. But nothing works so i did some digging on the problem and after many tries like soldering the pins 25 and 26 of the FTDI or connect the TX/RX pins to the GND. Concerning that last point, because the TX/RX was still flashing after beeing connected to the GND i have put in my program this two lines to force TX/RX to be disabled and this is my mistake :

```
digitalWrite(0,LOW);
digitalWrite(1,LOW);

```

And now what a surprise i can't load a program in my arduino nano anymore even using another arduino to burn the bootloader. And i get this message :

```
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x2e
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x30
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x2c
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x33
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x38
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x2e
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x33
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x31

```

I would like to come back to my factory arduino nano and/or enable once again the TX/RX connections ...

# Answer
> 0 votes
After some more tries something actually worked reinitialising the TX/RX pins, but i don't know why really. I wired RX pin to the reset and i loaded an empty code into the arduino, after that i was able to load any program into my arduino again. Problem solved, but why it solved the problem is the question now.

# Answer
> 0 votes
You could also do this: in the IDE, select File:Preferences and turn on Verbose outputs.

Press & hold reset, that puts all the IO pins into Inputs, then start a download. When the compiler process shows "compilation complete, xxxxxx bytes of 32xxx used" or similar, release the Reset button.

That allows the bootloader code to run and talk to the PC over the serial pins - before your sketch has chance to run and write the 2 serial pins low.

It might take a couple of tries to release Reset at the correct time. Be patient try a few times with just a short sketch to clear out the offending code:

```
void setup();
void loop();

```

That would do it.

---
Tags: serial, arduino-nano, reset
---


title: Can a pin be Neutral, not high or low?

text:
# Question
Title: Can a pin be Neutral, not high or low?
I'm trying to figure out a way to controll a DFplayer mini mp3 player with ADkeys.
Because I only have two or three files to play at a fixed volume I find it easier to just use the ADkeys. https://wiki.dfrobot.com/DFPlayer\_Mini\_SKU\_DFR0299#target\_4

Lets say I want to use Segment 1 - Segment 3 (MP3 file 1 - MP3 file 3). I would then connect a resistor (or none in Segment 1) in between and to three pins on the Arduino.
But how can I make the pin neutral, so that it does not trigger everything at once?
As far as I can read the pins are grounded in Arduino if not "high".

# Answer
> 3 votes
What you are talking about in this instance is "Open Drain". Normally, as you rightly note, with outputs you have either HIGH or LOW, which effectively connects the output pin to +5V or GND respectively.

Instead you are asking for Open Drain. In this arrangement a pin is either "active", in which case it connects it to GND, or "inactive", in which case it is disconnected from (almost) anything.

Most 8-bit Arduino boards don't have Open Drain capability on their IO pins (some more advanced 32-bit boards do, though), but it is easy enough to emulate it in software.

You can emulate it using "Tri-State" logic. That is logic where, as well as HIGH and LOW you have "High Impedance", or "HI-Z". HI-Z is pretty much the same as "inactive" Open Drain. On the Arduino HI-Z is the same as INPUT.

So you can emulate it by:

* To activate a pin set it to OUTPUT and LOW
* To deactivate a pin set it to INPUT

For example, to "press" one of your buttons for 100ms you could:

```
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
delay(100);
pinMode(4, INPUT);

```

# Answer
> 1 votes
Your drawing appears to be attempting to provide analog levels to the DF miniplayer.

What you can do in that case is use two PWM outputs from the Arduino, with a RC lowpass filter to smooth the PWM into a DC level. (Arduino pin to 10K resistor, 4.7uF cap to gnd after that, the cap/resistor junction going to the DF Miniplayer).

Then

```
analogWrite(pin, 128); // with pin being 3,5,6,9,10,11 on a Uno for example

```

to output 2.5V to the DF Miniplayer. Similarly, 64 would be about 1.25V, while 192 would be about 3.75V. Other levels are easily obtained.

---
Tags: pins
---