# Question
Title: millis() function works with inline code and gives output but when creating own library it doesn't works
I am creating library for GPS to use in my project. I am using Adafruit GPS and its library to create my own library in which I am using `millis()` function to display the GPS Location after 1 minute (60s). So when I created my inline code the function works very well and also displays location after 60s. But I created `header` and `cpp` file for my own library, in which it doesn't gives any error but the results(location) is not displayed. Doesn't shows any output. So I printed the time which is 0 (attached the output screenshot)

My code updates the GPS every 30s and prints the location every 1 minute.It also checks the if old location is equal to new location in every 1minute.

I think there is problem with my libaray or with the millis() function. I am new to Arduino programming , please help me with this.

My inline code is:

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

SoftwareSerial mySerial(11, 10);
Adafruit_GPS GPS(&mySerial);

#define GPSECHO  true
uint32_t timer = millis();
float old_lat,old_lon,new_lat,new_lon;

void setup()
{

  Serial.begin(9600);
  delay(1000);
  Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
}

void loop()                     // run over and over again
{
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

if (GPS.fix) {

      old_lat = GPS.latitudeDegrees;
      old_lon = GPS.longitudeDegrees;
      if (timer > millis())  timer = millis();
      if (millis() - timer > 60000) {
        timer = millis();
          Serial.println("Location 1 minute:");
          displaytime();
          new_lat = GPS.latitudeDegrees;
          new_lon = GPS.longitudeDegrees;

          if (new_lat == old_lat){
            new_lat = old_lat;
          }
          else{
            new_lat = GPS.latitudeDegrees;
          }
          Serial.print("Final Latitude: ");
          Serial.println(new_lat,6);

          if (new_lon == old_lon){
            new_lon = old_lon;
          }
          else{
            new_lon = GPS.longitudeDegrees;
          }
          Serial.print("Final Longitude: ");
          Serial.println(new_lon,6);

}
}
}

void displaytime(){
    Serial.print("\nTime: ");
    if (GPS.hour < 10) { Serial.print('0'); }
    Serial.print(GPS.hour, DEC); Serial.print(':');
    if (GPS.minute < 10) { Serial.print('0'); }
    Serial.print(GPS.minute, DEC); Serial.print(':');
    if (GPS.seconds < 10) { Serial.print('0'); }
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    if (GPS.milliseconds < 10) {
      Serial.print("00");
    } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
      Serial.print("0");
    }
    Serial.println(GPS.milliseconds);
}

```

My header file is :

```
/*
 * GPS.h - library used to show Latitude and Longitude
 */

 #ifndef GPS_Loc_h
 #define GPS_Loc_h

 #include "Arduino.h"

class SoftwareSerial;
class Adafruit_GPS;

 class GPS_Loc
 {
  public:
    GPS_Loc();
    void displaytime();
    void displayloc();
    uint32_t timer;
    float old_lat,old_lon,new_lat,new_lon;
 };

 #endif

```

My cpp file is:

```
/*
 * GPS_Loc.cpp - library used to show Latitude and Longitude
 */

 #include "Arduino.h"
 #include "GPS_Loc.h"

 #include "Adafruit_GPS.h"
 #include "SoftwareSerial.h"

 #define GPSECHO  true

SoftwareSerial mySerial(11,10);
Adafruit_GPS GPS(&mySerial);

GPS_Loc::GPS_Loc()
{
  timer = millis();
  old_lat = old_lat;
  old_lon = old_lon;
  new_lat = new_lat;
  new_lon = new_lon;
}

void GPS_Loc::displayloc(){
  //Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    }

if (GPS.fix) {

      old_lat = GPS.latitudeDegrees;
      old_lon = GPS.longitudeDegrees;
      if (timer > millis())  timer = millis();
      if (millis() - timer > 60000) {
        timer = millis();
          Serial.println("Location 1 minute:");
          displaytime();
          new_lat = GPS.latitudeDegrees;
          new_lon = GPS.longitudeDegrees;

          if (new_lat == old_lat){
            new_lat = old_lat;
          }
          else{
            new_lat = GPS.latitudeDegrees;
          }
      Serial.print("Location lat: ");
          Serial.println(new_lat,6);

          if (new_lon == old_lon){
            new_lon = old_lon;
          }
          else{
            new_lon = GPS.longitudeDegrees;
          }

          Serial.print("Location long: ");
          Serial.println(new_lon,6);

}
}
}

void GPS_Loc::displaytime(){
    Serial.print("\nTime: ");
    if (GPS.hour < 10) { Serial.print('0'); }
    Serial.print(GPS.hour, DEC); Serial.print(':');
    if (GPS.minute < 10) { Serial.print('0'); }
    Serial.print(GPS.minute, DEC); Serial.print(':');
    if (GPS.seconds < 10) { Serial.print('0'); }
    Serial.print(GPS.seconds, DEC); Serial.print('.');
    if (GPS.milliseconds < 10) {
      Serial.print("00");
    } else if (GPS.milliseconds > 9 && GPS.milliseconds < 100) {
      Serial.print("0");
    }
    Serial.println(GPS.milliseconds);
}

```

My demo code using my own library is:

```
#include <GPS_Loc.h>

GPS_Loc bgps;

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

}

void loop() {
  // put your main code here, to run repeatedly:
  bgps.displaytime();
  bgps.displayloc();
}

```

Output of inline code

# Answer
> 1 votes
I think Gerben is on to something. If you re-initialize the gps at every loop and then never give it time to acquire the gps signal then your if (GPS.fix) condition is never true and you never print out any other data. All your timing code is inside the GPS.fix condition which doesn't happen until you have a fix. Try putting the init code inside your contructor for your class. Somethink like :

```
GPS_Loc::GPS_Loc()
{
  timer = millis();
  old_lat = old_lat;
  old_lon = old_lon;
  new_lat = new_lat;
  new_lon = new_lon;

  //Serial.println("Adafruit GPS library basic test!");
  GPS.begin(9600);
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand("$PMTK220,30000*1F");
  mySerial.println(PMTK_Q_RELEASE);
}

void GPS_Loc::displayloc(){
  delay(100); // short delay to stop a no-fix runaway
  char c = GPS.read();
  if (GPS.newNMEAreceived()) {
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
    }

if (GPS.fix) {

```

It might also be useful to put a small delay somewhere in the code so that it won't loop like crazy before getting a fix.

---
Tags: arduino-ide, library, millis
---


# Question
Title: How fast should I be able to write to AT45DB321D flash memory?
I checked the AT45DB321D datasheet and it says it operates at either 66 MHz oder 33 MHz. Both of these speeds are higher than what an Arduino Nano supports (my google fu fails me here, but according to the Arduino SPI doc it's probably on the order of 4 MHz).

According to the datasheet

> Data can be clocked in from the input pin (SI) into either buffer 1 or buffer 2. To load data into the standard DataFlash buffer (528 bytes), a 1-byte opcode, 84H for buffer 1 or 87H for buffer 2, must be clocked into the device, followed by three address bytes comprised of 14 don’t care bits and 10 buffer address bits (BFA9-BFA0). The 10 buffer address bits specify the first byte in the buffer to be written. \[...\] Data will continue to be loaded into the buffer until a low-to-high transition is detected on the CS pin.

Which means to write a single byte I would need

* 1 opcode byte
* 3 address bytes
* 1 data byte

totaling 5 bytes or 40 bits which at 4 MHz yields 10 µs.

My code, as below, yields roughly 48 µs per byte (outputs a duration of ~12380 µs for transfering 256 bytes). I'm using the DataFlash library.

```
#include <SPI.h>
#include "DataFlash.h"

static const int csPin    = 10;
static const int resetPin = 8;
static const int wpPin    = 7;

DataFlash dataflash;

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

  SPI.begin();

  dataflash.setup(csPin, resetPin, wpPin);
  dataflash.begin();

  long start = micros();
  dataflash.bufferWrite(0, 0);
  for(int i = 0; i <= 255; i++) {
    SPI.transfer(i);
  }
  long afterBuffer = micros();

  Serial.print("Writing 256 values to buffer: ");
  Serial.println(afterBuffer - start);
}

void loop()
{
  // nothing
}

```

It's very likely I'm missing something, but especially if I want to transfer larger chunks of data at once I'd like to speed up that process a bit. Creating a 256 byte buffer and writing it all at once

```
// outside time measurement
uint8_t buffer256[256];
for(int i = 0; i <= 255; i++) {
  buffer256[i] = i;
}
// inside time measurement
SPI.transfer(buffer256, 256);

```

takes roughly the same time.

**tl;dr:** Is everything working correctly/what am I doing wrong? How can I speed up writing to a flash chip using an Arduino Nano?

# Answer
> 2 votes
> "Data will continue to be loaded into the buffer until a low-to-high transition is detected on the CS pin."

The `dataflash.bufferWrite` command writes the opcode and address bytes and then in the `for` loop you write 256 data bytes. The data bytes are written at once, without preceding each single one with the opcode and the address. (So it does already what you want to do.)

It doesn't matter whether you write the byte at once or each with a single SPI write. SPI can only send them sequentially. And the initial opcode and address is only send once with the `dataflash.bufferWrite` command.

BTW: There are two buffers to write to 1 and 2. So I'm curious why the command `dataflash.bufferWrite(0, 0);` works. IMHO that should be `dataflash.bufferWrite(1, 0);` or `dataflash.bufferWrite(2, 0);`.

You also not start the internal writing to the pages. There is no command e.g. `dataflash.bufferToPage(1, 7);`. The data are only transfered into the flash's buffer.

Because data is not written into a memory page, you'll lose it, if you switch off the power.

**UPDATE**

I fear I understood your question not completely. As I now see, you wondered why you need 48 µs in average for 256 Bytes when the SPI Bus is driven with 4MHz.

I looked a little in the codes and docs. And that's what I found:

The DataFlash lib selects a different Clock divider:

```
/* Setup SPI */
SPI.setDataMode(SPI_MODE3);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV2);

```

`SPI_CLOCK_DIV2` results after some computation to a frequency of Fosc/2. The computation are very difficult to follow, because they use an 8 bit number which is divided into 2 nibbles each of them defines a part of a register content. But I'm quite sure the result is Fosc/2. But that would result in a clock frequency of 8 MHz. That can not explain your observed timings.

BTW: There is also in interesting deprecation note about setting the clock speed this way. ;-)

```
  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setClockDivider(uint8_t clockDiv) {
    SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
    SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
  }

```

But then I saw another thing that could be a problem. There are to single value transfer functions. One for bytes (uint8\_t) and one for integers (uint16\_t). Your count variable is an integer so the two byte transfer method is used, resulting in two byte per transfer and therefor 512 bytes. But that also no explanation for the observations. And writing buffers works only with uint8\_t\[\] so ??.

What else could have happened?

The MCU could be clocked by a lower frequency then 16MHZ. I think there are fuses that can be configured to reduce the master clock speed for using the MCU with lower voltage (like 3.6 Volt).

The missing beginTransaction / endTransaction (DataFlash doesn't use this) of the SPI bus could have impact on the interrupts which could distort the timing. (But that's a very wild guess ;-))

The observation that, transferring twice the amount of data with the single int transfer method does take roughly the same time than the buffered method gives us a hint, that possibly the SPI speed is not the problem.

In the function `dataflash.bufferWrite(0, 0);` there is e.g. a wait function `waitUntilReady();` that could cause a long delay of ~12 milli seconds. You can easily try that, by taking the `dataflash.bufferWrite(0, 0);` out of the timing.

```
void DataFlash::waitUntilReady()
{
    while(!isReady()) {};
}

uint8_t DataFlash::isReady()
{
    return status() & AT45_READY;
}

uint8_t DataFlash::status()
{
    uint8_t status;
    reEnable();     // Reset command decoder.
    SPI.transfer(DATAFLASH_STATUS_REGISTER_READ);
    status = SPI.transfer(0);
    disable();
    return status;
}

```

---
Tags: arduino-nano, spi
---


# Question
Title: Issue connecting heartbeat & temperature sensor on arduino uno but working individually
So the code is working individually for temperature sensor and for heartbeat sensor but when i combine it together it shows wrong values for the temperature sensor

I'm using lm35 temperature sensor and powering by USB

```
#include <LiquidCrystal.h>

const int rs = 13, en = 12, d4 = 11, d5 = 10, d6 = 9, d7 = 8;
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

int pulsePin = A0;

int blinkPin = 5;                // pin to blink led at each beat

// Volatile Variables, used in the interrupt service routine!
volatile int BPM ;                   // int that holds raw Analog in 0. updated every 2mS
volatile int Signal;                // holds the incoming raw data
volatile int IBI = 600;             // int that holds the time interval between beats! Must be seeded!
volatile boolean Pulse = false;     // "True" when User's live heartbeat is detected. "False" when not a "live beat".
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

static boolean serialVisual = true;   // Set to 'false' by Default.  Re-set to 'true' to see Arduino Serial Monitor ASCII Visual Pulse

volatile int rate[10];                      // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P = 512;                      // used to find peak in pulse wave, seeded
volatile int T = 512;                     // used to find trough in pulse wave, seeded
volatile int thresh = 525;                // used to find instant moment of heart beat, seeded
volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM

const int sensor = A5;
int tempc ;
float vout;

void setup()
{
  vout =analogRead(sensor);
  pinMode(sensor,INPUT);
  pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!
  Serial.begin(9600);             // we agree to talk fast!
  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS
                                  // IF YOU ARE POWERING The Pulse Sensor AT VOLTAGE LESS THAN THE BOARD VOLTAGE,
                                    // UN-COMMENT THE NEXT LINE AND APPLY THAT VOLTAGE TO THE A-REF PIN
                                    //   analogReference(EXTERNAL);
 lcd.begin(16, 4);
 lcd.clear();
}

//  Where the Magic Happens
void loop()
{

lcd.setCursor(0,0);
lcd.print(" T in c = ");
lcd.print(tempc);
lcd.setCursor(0,1);

delay(100);
   serialOutput();

  if (QS == true) // A Heartbeat Was Found
    {
      // BPM and IBI have been Determined
      // Quantified Self "QS" true when arduino finds a heartbeat
      serialOutputWhenBeatHappens(); // A Beat Happened, Output that to serial.
      QS = false; // reset the Quantified Self flag for next time
      tempc=(vout*500)/1023;

    }

  delay(20); //  take a break
}

void interruptSetup()
{
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}

void serialOutput()
{   // Decide How To Output Serial.
 if (serialVisual == true)
  {
     arduinoSerialMonitorVisual('-', Signal);   // goes to function that makes Serial Monitor Visualizer
  }
 else
  {
      sendDataToSerial('S', Signal);     // goes to sendDataToSerial function
   }
}

void serialOutputWhenBeatHappens()
{
 if (serialVisual == true) //  Code to Make the Serial Monitor Visualizer Work
   {

     int din ;
      din = analogRead(4);

     Serial.print(BPM);
     Serial.print(", ");
     Serial.print(tempc);
     Serial.print(", ");
     Serial.print(din);
     Serial.print(", ");

     Serial.println();
     lcd.setCursor(0,2);
     lcd.print("Heart-Beat Found ");
     lcd.setCursor(6,3);
     lcd.print(BPM);
     delay(100);
     lcd.clear();
   }
 else
   {
     sendDataToSerial('B',BPM);   // send heart rate with a 'B' prefix
     sendDataToSerial('Q',IBI);   // send time between beats with a 'Q' prefix
   }
}

void arduinoSerialMonitorVisual(char symbol, int data )
{
  const int sensorMin = 0;      // sensor minimum, discovered through experiment
  const int sensorMax = 1024;    // sensor maximum, discovered through experiment
  int sensorReading = data; // map the sensor range to a range of 12 options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 11);
  // do something different depending on the
  // range value:
}

void sendDataToSerial(char symbol, int data )
{
   Serial.print(symbol);
   Serial.println(data);
}

ISR(TIMER2_COMPA_vect) //triggered when Timer2 counts to 124
{
  cli();                                      // disable interrupts while we do this
  Signal = analogRead(pulsePin);              // read the Pulse Sensor
  sampleCounter += 2;                         // keep track of the time in mS with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise
                                              //  find the peak and trough of the pulse wave
  if(Signal < thresh && N > (IBI/5)*3) // avoid dichrotic noise by waiting 3/5 of last IBI
    {
      if (Signal < T) // T is the trough
      {
        T = Signal; // keep track of lowest point in pulse wave
      }
    }

  if(Signal > thresh && Signal > P)
    {          // thresh condition helps avoid noise
      P = Signal;                             // P is the peak
    }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N > 250)
  {                                   // avoid high frequency noise
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) )
      {
        Pulse = true;                               // set the Pulse flag when we think there is a pulse
        digitalWrite(blinkPin,HIGH);                // turn on pin 13 LED
        IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
        lastBeatTime = sampleCounter;               // keep track of time for next pulse

        if(secondBeat)
        {                        // if this is the second beat, if secondBeat == TRUE
          secondBeat = false;                  // clear secondBeat flag
          for(int i=0; i<=9; i++) // seed the running total to get a realisitic BPM at startup
          {
            rate[i] = IBI;
          }
        }

        if(firstBeat) // if it's the first time we found a beat, if firstBeat == TRUE
        {
          firstBeat = false;                   // clear firstBeat flag
          secondBeat = true;                   // set the second beat flag
          sei();                               // enable interrupts again
          return;                              // IBI value is unreliable so discard it
        }
      // keep a running total of the last 10 IBI values
      word runningTotal = 0;                  // clear the runningTotal variable

      for(int i=0; i<=8; i++)
        {                // shift data in the rate array
          rate[i] = rate[i+1];                  // and drop the oldest IBI value
          runningTotal += rate[i];              // add up the 9 oldest IBI values
        }

      rate[9] = IBI;                          // add the latest IBI to the rate array
      runningTotal += rate[9];                // add the latest IBI to runningTotal
      runningTotal /= 10;                     // average the last 10 IBI values
      BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
      QS = true;                              // set Quantified Self flag
      // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }
  }

  if (Signal < thresh && Pulse == true)
    {   // when the values are going down, the beat is over
      digitalWrite(blinkPin,LOW);            // turn off pin 13 LED
      Pulse = false;                         // reset the Pulse flag so we can do it again
      amp = P - T;                           // get amplitude of the pulse wave
      thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
      P = thresh;                            // reset these for next time
      T = thresh;
    }

  if (N > 2500)
    {                           // if 2.5 seconds go by without a beat
      thresh = 512;                          // set thresh default
      P = 512;                               // set P default
      T = 512;                               // set T default
      lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
      firstBeat = true;                      // set these to avoid noise
      secondBeat = false;                    // when we get the heartbeat back
    }
  sei();
                                 // enable interrupts when youre done!
}// end isr

```

# Answer
Code seems to lack a repeating update of tempc via

```
vout =analogRead(sensor);

```

An alternative might be changing the line for setting tempc to be

```
tempc=(int) (analogRead(sensor) * 500.0f/1023.0f);

```
> 2 votes

# Answer
Why do you compute tempc only after you print out the value in serialOutputWhenBeatHappens\`? You also forgot to read the temperature continuously.

Here is how I would do it:

```
void loop()
{
  // read the sensor before it is printed on the LCD
  vout  = analogRead( sensor );

  // here I'm not sure what you are computing
  // you map the sensor voltage to a range from 0°C to 500°C
  // do you measure the heartbeat and temperature of a dragon? ;-)
  // this formula is the same as yours
  tempc = ( vout / 1023.0 ) * 500.0;

  // I would also clear the LCD before I write to it
  lcd.clear();

  lcd.setCursor( 0, 0 );
  lcd.print( "T in c = " );
  lcd.print( tempc );
  lcd.setCursor( 0,1 );

  // There is no need to slow down the loop here.
  // let it run ...
  // delay(100);

  serialOutput();

  // A Heartbeat Was Found
  if (QS == true)
  {
     // BPM and IBI have been Determined
     // Quantified Self "QS" true when arduino finds a heartbeat
     // A Beat Happened, Output that to serial.
     serialOutputWhenBeatHappens();

     // reset the Quantified Self flag for next time
     QS = false;
  }

  // take a break (Why?)
  // delay(20);
}

```
> 1 votes

# Answer
If the provided source is cut down to the lines that have to do with the temperature, it is just this. If you try this sketch it should behave equally "wrong":

```
const int sensor = A5;
int tempc;
float vout;

void setup()
{
    vout = analogRead(sensor);
    pinMode(sensor, INPUT);
}

void loop()
{
    lcd.print(tempc);
    tempc = (vout * 500) / 1023;
}

```

In `loop()` the value of `tempc` is printed *before* it is re-calculated from `vout`.

But `vout` is written to just one time in `setup()`.

So the "wrong" values you are talking about are **always the same value** which was measured at start-up time. (You did *not* mention *what* is wrong.)

---

*Note: Like documented in the Arduino's library reference, there is no need to set a pin to `INPUT` mode because it's the default.*

---

I read your comment on @Abel's answer and even watched your video. Since it's not clear what you did I can't say anything why you have jumping values now. (Please write some prose and show the new code in your question the next time.)

If we apply his advice the source will look like this. I removed the setting of the pin mode (see above) and made the sequence of instructions in `loop()` more logical.

```
const int sensor = A5;
int tempc;
float vout;

void setup()
{
}

void loop()
{
    vout = analogRead(sensor);
    tempc = (vout * 500) / 1023;
    lcd.print(tempc);
}

```

This sketch will show the current temperature tracking the actual value. If *not* you have another problem independent of the interrupt and the heartbeat sensor.

---

*Additional notes:*

1. `analogRead()` returns an `int`. You assign it to a `float` so here is an implicit conversion.
2. This `float` is fine because you do the mapping "by hand." If you'd use `map()` it could be an `int`.
3. The result of the mapping expression is of type `float` and you assign it to an `int`. Here is another implicit conversion which removes the fractional part. This is OK because of the accuracy of the measurement.

---

Now to your assumption that the interrupts disturb the measurement of the temperature.

From the source I don't see any reason. So you might like to proceed like this:

1. Comment everything that has to do with the heartbeat acquisition, including the timer interrupt. You can do this with `/* … */` or `#if 0`-`#endif`-pairs. The former can't be "stacked" and the latter need their own lines.
2. Check whether the temperature is tracked OK.
    * If yes, proceed.
    * If no, your temperature circuitry is faulty in some way. A schematic and a photo (edit your question for this) could be helpful for us. Don't proceed until this is solved.
3. The timer and its interrupt service routine is actived again but will execute nothing.
4. Check whether the temperature is OK.
    * If yes, proceed.
    * If no, I'm out of ideas for the moment.
5. Re-enable the heartbeat acquisition.
6. Check whether the temperature is OK.
    * If yes, proceed.
    * If no, I'm out of ideas for the moment.
7. Problem solved.
> 1 votes

---
Tags: arduino-uno, serial, sensors, pins, temperature-sensor
---


# Question
Title: Somewhat Obfuscated Serial With SIM800L and Uno R3
I am successfully communicating with my SIM800L from my UNOR3 aside form some errors. But the biggest problem is with the serial monitor.

Responses from the SIM800L are somewhat obfuscated in that some characters are randomly wrong. See a snippet below:

```
Initializing...

OK

+C⸮T'⸮⸮b⸮j

OK

88l4110068165694746f

O⸮

+CQEG:Y⸮⸮H⸮⸮*⸮⸮C⸮
ERROR
⸮> H⸮⸮*⸮⸮
F⸮ROR
H⸮⸮
ERRO
H⸮⸮*⸮⸮

```

My code is also below.

```
#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(11,10); //SIM800L Tx & Rx is connected to Arduino #3 & #2

void setup()
{

  pinMode(2, INPUT);
  pinMode(3, OUTPUT);
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(115200);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  updateSerial();
  mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  mySerial.println("AT+CREG?"); //Check whether it has registered in the network
  updateSerial();
  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CNMI=1,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();
  mySerial.println("AT+CMGS=\"+447518103652\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("System on!"); //text content
  updateSerial();
  mySerial.write(26);

  delay(1000);
}

int milli = millis();
void loop()
{
  if (digitalRead(2) == HIGH) {
    digitalWrite(3, HIGH);
  mySerial.println("AT+CMGS=\"+447518103652\"");//change ZZ with country code and xxxxxxxxxxx with phone number to sms
  updateSerial();
  mySerial.print("Button Pressed!"); //text content
  updateSerial();
  mySerial.write(26);
  } else {
    digitalWrite(3, LOW);
  }

  if (milli <= millis() - 500) {
    updateSerial();
    milli = millis();
  }
}

void updateSerial()
{
  //delay(300);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

```

The SIM800L runs off a separate power supply with a decoupling cap of 100n and the grounds are commoned.

# Answer
> 1 votes
Here is a good documentation: https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/ --

Did you add a voltage divider to the RX pin? If Arduino drive 5 Volt to the module's pin, the module might be destroyed.

The module has an automatic baud rate detection, so 115200 baud should be OK. Do you configured your terminal with 115200 baud for the serial communication?

While sending, the Software Serial switches off all interrupts to make the micro clock more accurate. That might distort a timer interrupt for the hardware serial (but I don't really know, whether it needs one).

You changed the pins 2 and 3 for software serial (as from the example) to `SoftwareSerial mySerial(11,10);` Did you add the connections to the right pins. (RX?? \<--\> TX??)?

And last but not least. The axample uses 9600 baud for both serial interfaces. Perhaps your decision 115200 is too high.

---
Tags: serial, gsm
---


title: while(1) inside if conditional

text:
# Question
Title: while(1) inside if conditional
```
if (!MDNS.begin("esp8266")) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }

```

I know this will result in an infinite loop if the `if` conditional is never satisfied, however I was wondering if this code would still result in an infinite loop if say, after 3 iterations the `if` conditional is satisfied?

Or if something like:

```
while(!MDNS.begin("esp8266")) {
   delay(1000);
}

```

is different?

Code from: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266mDNS/examples/mDNS\_Web\_Server/mDNS\_Web\_Server.ino (line 58)

# Answer
> 0 votes
This is likely a case where the original code needs to be inspected to understand the purpose of the infinite loop. In the original code we see this:

```
  if (!MDNS.begin("esp8266")) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");

```

Here, it can be inferred the infinite loop is used to preserve the error message on the serial monitor. By doing so prevents subsequent messages from announcing the Domain Name Server has started. Which may confuse the user.

As mentioned in other answers, infinite loops are often used to purposely reset a processor. However, this approach depend on an actively running watch dog feature. A feature that is not normally active or even supported in the Arduino development environment. Perhaps because the watch dog feature is considered an intermediate to advanced topic.

# Answer
> 1 votes
In the first case, the first time, that the outer if statement becomes true, the code will go into the `while(1)` loop and will be stuck there forever.

The second code is different, since the `while` loop will check at each start of it's iteration, if the condition is still met. If not, it will exit, so not necessarily an infinite loop.

---

Going into an infinite loop, if something fails to initialize is often done in the microcontroller world, especially when initializing external hardware. A reset loop (restarting until it works) is mostly not fitting there, because often it is not just waiting for a resource to become free. Often this is used for serious problems, for example external hardware not being there or functioning. Imagine trying to use an external GPS chip, but the chip is not there. It should be there, since the device is build this way. Why should a reset loop be better here? The problem won't get away with time. Or imagine, that the initialization fails, because the GPS chip is broken. Trying to interface such a broken chip repeatedly might break even more things. Either way, someone has to look at this, to fix the problem. It will not go away by itself.

I would say, that the failed initialization in the library above is such a situation.

---
Tags: programming, code-review, loop
---


title: arduino circuit review/ safety review

text:
# Question
Title: arduino circuit review/ safety review
I have the following circuit

It has a simple dc motor that is OFF, and switches ON once a day for 2 seconds.

I use MOSFET IRF540N as a switch

I use L7805CV as a voltage regulator

I would like to have a review and to ask whether it is safe to connect this circuit to a 9v 1A (center+) DC wall plug.

I have measured the dc motor and it takes 60 mA when it is on with 5V.

# Answer
The "Arduino" part of your schematic looks OK. 9 VDC to VIN on the Uno is OK. Connecting the MOSFET directly to the Arduino is OK.

Personally, I would connect a 1000 ohm resistor in series between the Arduino pin and the gate of the MOSFET. If you like to live dangerously like I do, and change wiring connections with power supplied to your Arduino, then a 1k resistor will limit the maximum current flow to around 5 mA. This is not going to "fry" anything if you inadvertently connect an output to power or ground.

The question about the L7805CV is off-topic, but a quick look at the datasheet suggests an input and output capacitor should be used.

I’m sorry to be the bearer of bad news, but the IRF540N is a poor choice as a MOSFET to use with a micro-controller. While it’s true that you are only drawing 60 mA, the VGS specified for this MOSFET is at 10 VDC, not the 5 VDC supplied by the Uno. A "logic level" MOSFET would be better suited for your application.

For more information regarding MOSFETs, please read: How to control a 12V solenoid valve with a mosfet?
> 1 votes

# Answer
In general your circuit is fine, but the parts are pretty overpowered. If there is a reasonable voltage drop at the IRF540N you better choose a mosfet with a lower gate-source threshold voltage, if it works I'd say it's fine.
> 0 votes

# Answer
You should not use a "naked" L7805CV. That voltage regulator requires a couple of capacitors in order to build a functioning voltage regulator out of it. You should be able to find instructions online for how to build one. Search on "L7805CV circuit" and you should find quite a few sample circuits.

That said, 9V is a good unregulated voltage to provide to the Vin line on the Arduino. Its built-in voltage regulator should be able to regulate that to 5V quite well, even with "bobble" caused by motor. (The built-in voltage regulator is able to handle input voltages from 7.5V to 12V, although if you feed it 12V and draw a lot of current out of the 5V line you may have overheating problems.)

You should also use a "logic level" MOSFET that can be driven with a 5V gate voltage.
> 0 votes

---
Tags: arduino-uno, code-review, safety, electricity
---


title: 8 digit 7 segment display issues

text:
# Question
Title: 8 digit 7 segment display issues
I've been trying to follow a few tutorials on how to get the 7 segment to display simple output but none seem to work 100%.

It starts out fine. It increments the number across the screen and then writes 8s to all of them and then reverses. After a few loops however it starts to act weird. Here's a video link where it acts a bit weird (a few digits don't write correctly and fix themselves) and then at the end, it only displays half of the 8 digit display before it goes to 8s and crashes. https://youtu.be/LD\_C7I\_bGyc

Here's the code:

```
//We always have to include the library
#include "LedControl.h"

// pin 4 is connected to the DIN pin
// pin 2 is connected to the CLK pin
// pin 3 is connected to the CS pin
// 1 as we are only using 1 MAX7219
LedControl lc = LedControl(4, 2, 3, 1);

void setup(){
    // the zero refers to the MAX7219 number, it is zero for 1 chip
    lc.shutdown(0, false);// turn off power saving, enables display
    lc.setIntensity(0, 0);// sets brightness (0~15 possible values)
    lc.clearDisplay(0);// clear screen
}

void loop(){
    // numbers 7 to 0
    for (int a = 0; a < 8; a++){
        lc.setDigit(0, a, a, false);
        delay(100);
    }
    delay(1000);
    // display number 8 on all segments
    for (int a = 0; a < 8; a++){
        lc.setDigit(0, a, 8, false);
        delay(100);
    }
    delay(1000);

    for (int a = 8; a >= 0; a--){
        lc.setDigit(0, a, a, false);
        delay(100);
    }
}

```

Hardware: Arduino Uno: https://www.jaycar.com.au/duinotech-uno-r3-development-board/p/XC4410 8 digit display: https://www.jaycar.com.au/8-digit-7-segment-display-module/p/XC3714

At this stage it's hard to tell if it's a hardware issue or if it's setup related. If someone could please give me some insight or maybe run it if they have the same hardware that would be fantastic.

Thanks!

# Answer
> 2 votes
This was an unexpected result. @Dougie was pretty on to it. I didn't know how to adjust the timings as I was pretty sure the library took care of it, so the only thing I could think of was to redo all the wiring again. That's when I noticed that the ground wire pin into the board was half sticking out.

In the video you can see the ground pin at the top right. So it was making a connection (otherwise the whole thing wouldn't work), but after replacing the wire it runs fine. So that would have messed up the timings if the connection was unstable.

# Answer
> 2 votes
The last loop exceeds the limits of 8 Digits. You iterate 9 times (0-8).

```
   for (int a = 7; a >= 0; a--){
        lc.setDigit(0, a, a, false);
        delay(100);
    }

```

---
Tags: arduino-uno, display
---


title: Stepper Motor won't reverse/turn CCW

text:
# Question
Title: Stepper Motor won't reverse/turn CCW
Before bothering anybody, I've been Googling this issue for the last three weeks and have not been able to solve the issue, so must reach out for help.

My son has done multiple Arduino projects after having a Creation Crate subscription, and now we're working on a project together. We bought a 28BYJ-48 stepper with driver, and figured it'd be just a question of copy-and-paste coding and we'd be in business.

I've tried the Arduino library, the AccelStepper library, countless other sketches from various websites and for some reason the stepper only vibrates when it's supposed to turn CCW. There was one sketch we were using that used Serial Monitor to enter in the number of steps, and when i'd do a minus number of steps, it'd go CCW, but the next day no longer would! I thought this was a motor or driver issue, but we've bought three more motor/drivers and still have the same problem. In researching an answer, I've seen some people say to switch IN 3 & 4 but I still get same results.

We've been connecting 8 to IN1, 9 to IN2, 10 to IN3 and 11 to IN4. Using a separate 5V power supply to the driver which is also grounded to the Arduino (have tried both ground pins just in case that makes a difference, but no). We've also tried changing for another Arduino and this hasn't made a difference either.

we've tried multiple sketches from multiple sources, here's one as an example:

```
#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  delay(500);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
  delay(500);
}

```

The Serial Monitor will state that it's turning CCW, but it isn't. Any help would be much appreciated! What we thought would be a simple step in our project has become a major roadblock!

# Answer
> 3 votes
I had this issue myself, when I tried to use these stepper motors (which are to be honest really crappy ones, but very cheap). Vibrating mostly means, that the phases of the motor are not activated in the correct order. These motors seem to work with an activation pattern for half steps (I don't know, if the motor is really doing half steps with this, because I didn't counted them for a whole revolution. But at least they worked). The Stepper library (I assume from your code, that you are using this one) isn't meant for this driver, so it will turn on the phases in a wrong order and always two phases at the same time (as for full steps).

I had success, when driving the 4 phases of the driver with the following pattern (for half steps):

```
1000
1100
0100
0110
0010
0011
0001
1001

```

I also found hints on the web (on a german site, just for reference, if you can read german), that - despite being meant for half steps - you can drive the motor with full steps with the Stepper library as well. You would have to change the order of pins in the definition of the stepper:

```
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);

```

This assumes the wiring as: D8-\>IN1, D9-\>IN2, D10-\>IN3, D11-\>IN4. Note, that using full steps means 2048 steps per revolution.

---

I also found a library specific for this stepper motor, but I haven't tested it: Stepper\_28BYJ\_48

---

Now you can decide yourself, which way you want to go. I personally would go for the full steps with the official Arduino Stepper library.

---

About the number of steps per revolution: I don't know, why the stepper doesn't work with a vale of 2048. But since the library only uses this to wrap up the correct phases for the revolutions, you can use a lower value, that is dividable by 4. For example 32, which is the number of full steps per revolution of the actual motor (it is attached to gears with a factor of 64). That should work.

# Answer
> 1 votes
https://forum.arduino.cc/index.php?topic=549927.0

This guy just flipped IN2 and IN3 and it solved the problem of going forwards and backwards. It worked for me and here is the code.

```
#include <Stepper.h> // Include the header file

// change this to the number of steps on your motor
#define STEPS 64

// create an instance of the stepper class using the steps and pins
Stepper stepper(STEPS, 8, 10, 9, 11);

int Pval = 0;
int potVal = 0;

void setup() {
  Serial.begin(9600);
  stepper.setSpeed(200);
}

void loop() {

potVal = map(analogRead(A0),0,1024,0,100);
if (potVal>Pval)
  stepper.step(10);
if (potVal<Pval)
  stepper.step(-10);

Pval = potVal;

Serial.println(Pval); //for debugging
}

```

---
Tags: stepper
---


title: Get data from Bluetooth scale

text:
# Question
Title: Get data from Bluetooth scale
I am trying to get data from this type of scale https://acaia.co/products/pearl. It does not show up under discover-able Bluetooth devices on a computer or phone, but it does have an app which it connects to automatically when turned on; the app can then display the weight in real time. This is my first time working with Bluetooth devices and am unsure as to how it is connecting to the app without showing up on other devices. Any information as to what is going on and possibly steps in the right direction would be greatly appreciated.

# Answer
> 1 votes
What you need to do is do some bluetooth sniffing to find out how the device is communicating with the phone. Here is a good article on doing that : http://nilhcem.com/iot/reverse-engineering-simple-bluetooth-devices

---
Tags: bluetooth
---


# Question
Title: How to split a binary data to form two split binary data?
I want to split a received binary data into two binary data.

Take the following received binary data for instance:

```
uint32_t data = 0xFFFF0001;

```

In binary format it is: 11111111111111110000000000000001

If we need to split this above binary into two new binary data how could it be done?

As an example from the 0xFFFF0001, how can we obtain the first 17-bit as as data1 = 11111111111111110 and then the remaining 15-bit as data2 = 000000000000001 ?

# Answer
> 2 votes
You can use the `bit shift` and `and` operator, like:

```
uint32_t data = 0xFFFF0001;

```

The following line will shift all bits 15 places to the right, meaning the least significant 15 bits will be removed, and the other bits shifted to the right.

```
uint32_t dataLeft = data >> 15;

11111111111111110000000000000001
>>>>>>>>>>>>>>>11111111111111110000000000000001
| Bit shift   || orig. bits    ||Removed bits |

```

For the other 15 bits, you can use the `and` operator, which just makes all 1's 0's for those bits not in the bit mask (0x7FFF).

```
uint16_t dataRight = data & 0x7FFF;

value:              11111111111111110000000000000001
bit mask (0x7FFF):  00000000000000000111111111111111
                    -------------------------------- & / AND
                    00000000000000000000000000000001

```

---
Tags: arduino-uno, programming, bit
---


# Question
Title: How to Compile Different Sketches in Different Visual Studio Code Workspaces
I'm using **Visual Studio Code** with the Arduino extension. I have two workspaces each with a different sketch file loaded - Sketch\_1 and Sketch\_2. Sketch\_1 will verify and upload properly. When I click on the Verify to compile or Upload buttons for Sketch\_2 in its workspace, VS Code verifies and uploads Sketch\_1, not Sketch\_2. Am I doing something wrong, or is it not possible to separately Verify and Upload different sketches in different workspaces?

# Answer
The first time you verify your sketch you are confronted with a list of available sketches (INO's). As soon as you select one of these it gets stored under `"sketch"` in `.vscode/arduino.json`. If you zero this, `""`, you'll once again be asked which sketch to set as "main sketch".

This "device context" is stored per workspace so you might consider narrowing your scope when opening a folder. I know this is no fun when exploring, and the will to switch and try different examples is big, but currently there are nothing that facilitates a smoother alternative.
> 1 votes

---
Tags: compile, visualstudio
---


title: Arduino L led glows continuously

text:
# Question
Title: Arduino L led glows continuously
can someone tell me why my L led on arduino uno glowing continuously I tried restarting my pc, changing USB port I also tried uploading an empty file and resetting the Arduino board but nothing seems to work. Does it mean I have to buy a new one?

# Answer
Don't let that pin float undefined: If undefined (INPUT), pull it to GND to have the led OFF.

If ever possible, try to use the LED\_BUILTIN pin as an OUTPUT pin.

And signal some information there. On an UNO (or other 328-based Arduino), this hint might collide with the SPI\_SCK pin, which is D13 (PB5 on an atmega328). But as an SPI Master, this pin is at least OUTPUT (and thus will signal SPI activity).
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: What kind of data type can be use store a binary bit-stream which is more than 64-bits?
I'm wondering if one needs to assign a bit-stream of 78 bits to a variable(later on to be processed), what datatype can be used? What is the max bit can be stored into a variable in C?

# Answer
There is no builtin data type that can store 78 bits. However, it depends a bit what you want to store. Like the following cases:

* If the 78 bits are one 'entity' (e.g. one really big value), you can store it as an array of bytes (10 bytes of 8 bits = 80 bits, leaving 2 bits unused)
* If the 78 bits can be split up in smaller parts, you can:
    + Create a structure or class to contain the sub elements into fields (instance variables), using for each sub type a normal type (e.g. signed/unsigned 8, 16 or 32 bits).
    + Create bit fields to save some memory if there are small items and memory space is an issue.
    + Or a combination of the above

If you have many of these items and you want to save space (thus the 2 unused bits of each 80 bits), you can create a big array that contains many items, and use bit operations to get each item. E.g. the first element will be in the first 10 bytes, where the last 2 bits are not part of the element. The second item will use the remaining 2 bits and the following 78 - 2 = 76 bits, etc. This saves only 2/80 * 100% = 2.5% so only use this when really needed.
> 1 votes

---
Tags: programming, data-type
---


# Question
Title: How can i connect 4 stepper motors and 3 sensors to an Anduino?
I have an Arduino AT MEGA 2560 circuit. I want to buy 1 Nema-17 bipolar stepper motors, 3 M49SP-2K stepper motors, 3 KY-032 sensors to do my project but i dont know how to connect them to my Arduino. Is there any Arduino shield for my purpose? Can I use Ramps 1.4 Arduino shield?

# Answer
Take a look at the Ramps V1.6, it is what I use. It plugs onto the AT Mega board.

https://reprap.org/wiki/RAMPS\_1.6

The 1.6 has a few improvements. I like the solder in power connectors rather than the plug in ones. More reliable.

Because I already had the AT Mega board I decided to try the ramps. There are better boards now, with 32 bit processors. But as a starting point the Ramps combo is the simplest to get going and it does the job.

Other boards may work out a little better, but the firmware is a bigger issue. Still in development.
> 1 votes

---
Tags: arduino-mega
---


# Question
Title: How to run led and buzzer at the same time?
I am making a police light and siren but the delay on light (); affects the buzzers delay tone

This is the code:

```
//PIN 9 - Buzzers
int f,d;
int t =0;

void setup()
{
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
}

void loop()
{
    buzzer ();

}

void buzzer () {

  for(f=635;f<=912;f++)
    {
        tone(9, f);
        delay(d);
        d=10;

        light ();
    }

    for(f=911;f>=634;f--)
    {

        light ();
        tone(9, f);
        delay(d);
            d=9;

    }

}

void light() {
 digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  delay(t);

  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);

  delay(t);

  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);

  delay(t);

  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);

  delay(t);

  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);

  delay(t);

  digitalWrite(5,HIGH);
  digitalWrite(6,HIGH);
  digitalWrite(7,HIGH);

  delay(t);

  digitalWrite(5,LOW);
  digitalWrite(6,LOW);
  digitalWrite(7,LOW);

  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

  digitalWrite(5,HIGH);
  delay(t);
  digitalWrite(5,LOW);
  digitalWrite(7,HIGH);
  delay(t);
  digitalWrite(7,LOW);
  delay(t);

}

```

# Answer
The following Code is not tested. You can take it as an example. If you find errors, it would be nice to report them, so I can correct my prog.

```
// here I just guess (10msec), I think you don't want a delay
// of 0 as in your code.
int   blinkDelay        = 10;
long  lastBlinkTime     =  0;
int   patternSequence[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 1, 2, 1, 2, 1, 2 };

int   patternSize     = 17;
int   actPattern      =  0;
int   delActive       = -1;

int  frequency     = 635;
int deltaFreq      =   1;
int  toneDelay     =  10;
long lastBuzzTime  =   0;

void setup()
{
  pinMode( 5, OUTPUT ) ;
  pinMode( 6, OUTPUT ) ;
  pinMode( 7, OUTPUT ) ;

  ledsOff();
  buzzer( frequency );
}

void loop()
{
  int actTime = millis();

  if ( ( actTime - lastBlinkTime ) > blinkDelay )
  {
    if ( delActive > 0 )
    {
      ledsOff();
    }
    else
    {
      actPattern++;
      if( actPattern > ( patternSize - 1) ) actPattern = 0;
      pattern( patternSequence[ actPattern ] );
    }
    delActive *= -1;

    lastBlinkTime = actTime;
  }

  if ( ( actTime - lastBuzzTime ) > toneDelay )
  {
    frequency += deltaFreq;

    if ( frequency > 911 ) deltaFreq = -1;
    if ( frequency < 636 ) deltaFreq = 1;

    buzzer( frequency );
    lastBuzzTime = actTime;
  }

}

void buzzer( int freq )
{
  //PIN 9 - Buzzer
  tone(9, freq);
}

void ledsOff()
{
  digitalWrite( 5, LOW );
  digitalWrite( 6, LOW );
  digitalWrite( 7, LOW );
}

void pattern( int num )
{
   switch ( num )
   {
      case 0:
        ledsOff();
        break;

      case 1:
        digitalWrite( 5, HIGH );
        break;

      case 2:
        digitalWrite( 7, HIGH );
        break;

      case 3:
        digitalWrite( 5, HIGH );
        digitalWrite( 6, HIGH );
        digitalWrite( 7, HIGH );
        break;
   }
}

```

**Update**

I've tested the code at home on my esplora. It worked, but not for a long time. I had to change the timing logic, by using the method `millis()`directly. Now it works. Below is the new code; tested this time. I also introduced some constants on top, because the their names act as documentation ;-). And I experimented with the values. The actual values are my preferences, But I'm by far no Bethoven and can not say if this relly sounds like a police siren. At least, it sounds not like a german police siren which I know better. (No I'm meither a policement nor his/her customer ;-))

Because I tested the code on my Esplora, I had to change the Pin assignments (now out commented). In this copy I changed back to the original ones.

```
int   blinkDelay        = 100;
long  lastBlinkTime     =  0;
int   patternSequence[] = { 1, 1, 1, 2, 2, 2, 3, 3, 3, 1, 2, 1, 2, 1, 2, 1, 2 };

int   patternSize     = 17;
int   actPattern      =  0;
int   clearActive       = -1;

int  lowerFreq       = 680;
int  higherFreq      = 840;
int  deltaFreq       =   2;
int  toneDelay       =  20;
int  toneDelayOffset =  -1;
long lastBuzzTime    =   0;

int  actFreqStep   = deltaFreq;
int  actFreq       = lowerFreq;

// orig pins
int col1Pin   =  5;
int col2Pin   =  6;
int col3Pin   =  7;
int buzzerPin =  9;

// esplora pins
// int col1Pin   =  5;
// int col2Pin   = 10;
// int col3Pin   =  9;
// int buzzerPin =  6;

void setup()
{
  pinMode( col1Pin, OUTPUT ) ;
  pinMode( col2Pin, OUTPUT ) ;
  pinMode( col3Pin, OUTPUT ) ;

  // initialize LEDs off
  ledsOff( );

  // and buzzer to the act frequency
  buzzer( actFreq );
}

void loop()
{
  if ( ( millis() - lastBlinkTime ) > blinkDelay )
  {
    if ( clearActive > 0 )
    {
      ledsOff();
    }
    else
    {
      actPattern++;
      if( actPattern > ( patternSize - 1) ) actPattern = 0;
      pattern( patternSequence[ actPattern ] );
    }

    clearActive     *= -1;
    lastBlinkTime  = millis();
  }

  if ( ( millis() - lastBuzzTime ) > ( toneDelay + toneDelayOffset ) )
  {
    actFreq += actFreqStep;

    if ( actFreq >= higherFreq )
    {
      actFreqStep   = -1 * deltaFreq;

      // down sweep is slower
      toneDelayOffset = -1;
    }

    if ( actFreq <= lowerFreq )
    {
      actFreqStep   =  deltaFreq;
      toneDelayOffset =  0;
    }

    buzzer( actFreq );
    lastBuzzTime = millis();
  }

}

void buzzer( int freq )
{
  tone( buzzerPin, freq );
}

void ledsOff()
{
  digitalWrite( col1Pin, LOW );
  digitalWrite( col2Pin, LOW );
  digitalWrite( col3Pin, LOW );
}

void pattern( int num )
{
   switch ( num )
   {
      case 0:
        ledsOff();
        break;

      case 1:
        // red
        digitalWrite( col1Pin, HIGH );
        break;

      case 2:
        // blue
        digitalWrite( col3Pin, HIGH );
        break;

      case 3:
        // white
        digitalWrite( col1Pin, HIGH );
        digitalWrite( col2Pin, HIGH );
        digitalWrite( col3Pin, HIGH );
        break;
   }
}

```
> 6 votes

# Answer
Don't use `delay()`. You'll need to rewrite your sketch to use the `millis()` function to decide when the desired amount of time has passed. Search on "Arduino Blink Without Delay" for information.
> 3 votes

---
Tags: arduino-uno
---


# Question
Title: How to control the power of attiny13a via pin change interrupt?
I'm trying controll the power of attity13a and turn off/turn on the led.
I'm going to goals:

* After to click on the button0 led will blicking 5 second nad then the attiny13a going to sleep.
* After to click on the button1 then wake attiny13a up and then led will shane.

The button0 to sleep and blink the led. the button1 to wake up and turn on the led.
Could you explain what is wrong in this sketch, please? thank you for your answers.

**code:**

```
    #define F_CPU   1200000UL
    #define LED     PB2 // PB2
    #define BUTTON1 PB1 // PCINT1
    #define BUTTON0 PB0 // PCINT0

    #define HIGH         1
    #define LOW          0
    #define INPUT        0
    #define OUTPUT       1
    #define INPUT_PULLUP 2
    #define FALSE        0
    #define TRUE         1
    #define _BV(bit)    (1 << (bit))

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <util/delay.h>

    void pinMode(uint8_t pin, uint8_t mode)
    {
        if(mode == OUTPUT) // Pin as output
            DDRB |= _BV(pin);
        else // Pin as input or input pullup
        {
            DDRB &= ~_BV(pin); // Set pin as input
            if(mode == INPUT_PULLUP)
                PORTB |= _BV(pin); // Enable pullup resistors
        }
    }

    void digitalWrite(uint8_t pin, uint8_t val)
    {
      if(val)
        PORTB |= _BV(pin);  // Set pin high
      else
        PORTB &= ~_BV(pin); // Set pin low
    }

    uint8_t digitalRead(uint8_t pin)
    {
      return !!(PINB & _BV(pin));
    }

    // go to sleep
    ISR(PCINT0_vect)
    {
       if(digitalRead(BUTTON0)){
            int i=0;
            while(i<10){
                blink();i=i+1;
            }
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);
            sleep_enable();
            sleep_cpu();
        }
    }

    //wake up
    ISR(PCINT1_vect){
       if(digitalRead(BUTTON1)){
        digitalWrite(LED, HIGH);
       }
    }

    void blink(){
        digitalWrite(LED, LOW);
        _delay_ms(500);
        digitalWrite(LED, HIGH);
        _delay_ms(500);
    }

    int main(void)
    {
        pinMode(BUTTON0, INPUT_PULLUP);
        pinMode(BUTTON1, INPUT_PULLUP);

        pinMode(LED, OUTPUT);
        digitalWrite(LED, LOW);

        // Sets the Pin change interrupt mask PB0, PB1
        PCMSK |= _BV(PCINT0)|_BV(PCINT1);

        //Enables Interrupts globally after setup
        //sei();
        SREG |= _BV(SREG_I);

        while(TRUE){}
    }

```

# Answer
> 1 votes
```
#define F_CPU   1200000UL

#define LED     PB2 // PB2
#define BUTTON1 PB1 // INT0
#define BUTTON0 PB0 // PCINT0

#define HIGH         1
#define LOW          0
#define INPUT        0
#define OUTPUT       1
#define INPUT_PULLUP 2
#define FALSE        0
#define TRUE         1
#define _BV(bit)    (1 << (bit))

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

void pinMode(uint8_t pin, uint8_t mode){
    if(mode == OUTPUT) // Pin as output
        DDRB |= _BV(pin);
    else // Pin as input or input pullup
    {
        DDRB &= ~_BV(pin); // Set pin as input
        if(mode == INPUT_PULLUP)
            PORTB |= _BV(pin); // Enable pullup resistors
    }
}

void digitalWrite(uint8_t pin, uint8_t val){
  if(val)
    PORTB |= _BV(pin);  // Set pin high
  else
    PORTB &= ~_BV(pin); // Set pin low
}

uint8_t digitalRead(uint8_t pin){
  return !!(PINB & _BV(pin));
}

//wake up
ISR(INT0_vect){
   sleep_disable();
   //cli(); // Turn off global interrupts
   digitalWrite(LED, HIGH);
}

void blink(){
    digitalWrite(LED, LOW);
    _delay_ms(1000);
    digitalWrite(LED, HIGH);
    _delay_ms(1000);
}

// go to sleep
ISR(PCINT0_vect)
{
   //cli(); // Turn off global interrupts
   if(!digitalRead(BUTTON0)){
        cli(); // Turn off global interrupts

        blink();

        digitalWrite(LED, LOW);

        sei(); // Turn on global interrupts
        set_sleep_mode(SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        sleep_cpu();
    }
}

int main(void)
{
    //enabled external interrupt
    MCUCR=0;
    //MCUCR=0b00000000;
    GIMSK|=_BV(INT0); // enabled external interrupt INT0 - PB1

    // Sets the Pin change interrupt mask
    GIMSK|=_BV(PCIE);
    PCMSK|=_BV(PCINT0);//PB0

    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);

    pinMode(BUTTON1, INPUT_PULLUP);//INT0 - PB1
    pinMode(BUTTON0, INPUT_PULLUP);//PCINT0 - PB0

    //Enables Interrupts globally after setup
    //SREG |= _BV(SREG_I);
    sei(); // Turn on global interrupts
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
    sleep_cpu();

    while(TRUE){}

    return 0;
}

```

---
Tags: attiny, avrdude, attiny13
---


# Question
Title: Does int array[100] = {0} construct work on Arduino?
I'm compiling my code in Arduino IDE. I have an array that I want to 0-initialize. I know `memset` works on Arduino, but I'm used to this way from my desktop C++ programming practice:

```
int array[100] = {0};

```

I couldn't find any info on whether or not this construct works on Arduino. I think it should since it uses GCC compiler. Even though it may be modified, I still expect it to remain C and C++-compliant. Still, can you confirm for me that this standard-compliant C/C++ construct works on Arduino?

# Answer
> I'm used to this way from my desktop C++ programming practice:
>
> ```
> int array[100] = {0};
>
> ```
>
> I couldn't find any info on whether or not this construct works on Arduino.

The `= {0}` has no actual effect. It is the same as:

```
int array[100];

```

Uninitialized static / global variables, and variables explicitly initialized to 0, are placed in the .bss section of memory.

This section is initialized to 0 by the CRT (C Runtime) code (the startup code for the system).

The compiler is responsible for placing these variables in the .bss, but it is the job of the startup (CRT) code to initialize it to zero.

This is standard C operation and is not likely to ever change since it would break all sorts of things.

Note: this does NOT apply to local variables allocated on the stack. These *must* be initialized to 0 if you want them to start as 0.
> 4 votes

# Answer
This construct does work in Arduino IDE. In fact, `= { 0 }` is one of the iconic idioms of C language. It can be used to zero-initialize an object of *any* type in C. In C++ things are a bit more complicated. It will work for an `int [100]` array, but in general case you might be better off with `= {}` initializer to achieve the same effect where applicable.

It is not clear why the accepted answer claims that this construct "has no actual effect" though. This is, of course, incorrect. More precisely, this initializer is *redundant* ("has no effect") on variables with static storage duration, since such variables are default-initialized anyway (zero-initialized for `int [100]`), even if you don't request it explicitly. But for a *local* variable declaration the effect of `= { 0 }` is undeniable and obvious: it will zero-initialize the array (which wouldn't've been initialized without it).

Note that even though the `0` in the `= { 0 }` initializes the first element of the array, this initializer ultimately triggers zero-initialization if the *entire* array.
> 5 votes

# Answer
The GNU cross compilers for Arduino use C/C++ front-ends and meet some version the language specs. (Although that is a moving target, you can expect a recent IDE version will be compliant with a reasonably recent language spec.)

"Arduino language" is a misnomer. The Arduino IDE will try to assist new programmers by, for example, automagically discovering library references and inserting the required #includes for you, but the resulting code is C++ and will be presented to a C++ compiler. The IDE provides a `main()` function that calls `setup()` and `loop()` (and `serialEventRun()` if you provide one) thereby reminding the programmer to initialize whatever needs to be initialized before expecting things to work right. However you can write proper C++ and get what you've come to expect. You'd have to go 'behind the IDE's back' as it were, to suppress the automatically-supplied `main()` function, but the toolchain doesn't care, as long as there is one and only one, `main()`.

I tested this this trivial program:

```
    int array[100];

    void setup() {
      // put your setup code here, to run once:
       for(uint8_t i = 0; i < sizeof(array); ++i)
          array[i] = i;
    }

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

    }

```

with both the Arduino IDE and Sloeber - Eclipse with the EclipseArduino plugin, which routinely provides a basic memory map after compilation - and with and without the initialization expression `= {0}`. I found no difference in the size of the output in either environment, with or without the initialization. In all four cases, the .bss was 209 bytes, 200 bytes larger than without the global array.
> 4 votes

---
Tags: arduino-ide, c++, array, gcc
---


title: How do I change the scope of an object?

text:
# Question
Title: How do I change the scope of an object?
I am using the File/Examples/Adafruit MQTT Library/mqtt\_ESP8266 example as a model for my code. In the example, the mqtt object is created as a global variable, and everything works fine. However, I need to create the mqtt object in setup(), because the constructor parameters are not known until then. If I move the constructor call

```
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

```

from the global namespace to inside setup(), I can no longer see it from inside loop().

I have tried declaring a pointer to mqtt in the global namespace, but don't know how to change it to point to the mqtt object that is created in setup(). How can I do this?

David

# Answer
> 1 votes
In general there is several ways to do it, none of them is the perfect one...

1. pointer to mqtt at global scope `Adafruit_MQTT_Client * mqtt_ptr;` and initialize it by `mqtt_ptr = new Adafruit_MQTT_Client(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);` in setup. Then you have to use arrow operator instead dot to access its methods. Or you can make an alias in loop (or whenever you need it) by `Adafruit_MQTT_Client& mqtt = *mqtt_ptr;` and access it in the same way as before.
2. returning reference to static variable created inside of function (singleton), but you have to provide parameters every time, even they're needed only for the first time. The static variable gets constructed only for the first call of function.
3. For esp8266 there might be available `std::optional` template. It's similar to pointer, but you don't have to use arrow `->` operator. But there might be extraneous copy when you assign (create) it's value.
4. You can also extend 1. or 2. by own class to hold parameters and then return instance of `Adafruit_MQTT_Client`

---
Tags: esp8266, mqtt
---


# Question
Title: what will be the sampling frequecy of my arduino Mega 2560 code. How would I calculate it?
```
void setup() {
    // initialize the serial communication:
    Serial.begin(9600);
    pinMode(10, INPUT); // Setup for leads off detection LO +
    pinMode(11, INPUT); // Setup for leads off detection LO -
}

void loop() {
    if ((digitalRead(10) == 1) || (digitalRead(11) == 1)) {
        Serial.println('!');
    }
    else {
        // send the value of analog input 0:
        Serial.println(analogRead(A0));
    }
    //Wait for a bit to keep serial data from saturating
    delay(1);
}

```

**EDIT**

This sketch is for plotting raw ECG signal having a baud rate of 9600. but when I use these data for calculating heart rate then I want sampling rate for calculation but I don't get the value by this sketch. How will I calculate the frequency from the coming raw data? As it does not show a clear picture.

# Answer
> 2 votes
On the Arduino Mega, the ADC is clocked at `F_CPU`/128 = 125 kHz (period = 8 µs). Except for the very first one, each ADC conversion takes 13 ADC clock cycles, i.e. 104 µs. If you run `analogRead()` in a tight loop, like

```
for (;;)
    analogRead(A0);

```

the CPU has to do some work in between the conversions, and since the ADC always starts by waiting for a rising edge of the ADC clock, you loose at least one full ADC cycle in between the conversions. You then get one conversion every 14 ADC cycles, which results in a sampling period of 112 µs, and the corresponding sampling frequency of about 8.93 kHz.

The code you showed does a little bit more than an `analogRead()` per iteration: two `digitalRead()`, a test, and a `Serial.println()` that involves a binary to decimal conversion. I am not sure the CPU will be able to handle all that in a mere 8 µs. You might end up using 15 ADC clock cycles per iteration (13 for the conversion, 2 for the computation), which would result in 120 µs (8.33 kHz) sampling period. Maybe even more. You will have to test if you want to know for sure. The sampling period is not even guaranteed to be constant: the code will take longer to run whenever it's interrupted by the timer interrupt, which the Arduino core uses for timekeeping purposes...

All this applies as long as the serial output buffer is not full. Once you have 64 bytes waiting to be sent, the buffer will be full, and `Serial.println()` will start delaying the output, effectively throttling down your loop to the speed of the serial connection. C.f. the busybee's answer for the details. Note that the sampling period is still not constant, as sending a 1-to-4-digit number through the serial port can take anywhere between 3.125 and 6.25 ms.

If you want a constant sampling period, you have to take control over the timing yourself. A straightforward example would be:

```
const uint32_t SAMPLING_PERIOD = 6500;  // 6.5 ms

void loop() {
    static uint32_t last_sample;
    if (micros() - last_sample >= SAMPLING_PERIOD) {
        last_sample += SAMPLING_PERIOD;
        Serial.println(analogRead(A0));
    }
}

```

You could go faster with a higher baud rate, but you have to always keep `SAMPLING_PERIOD` consistent with your chosen baud rate. The code above will still produce some jitter in the sampling, mostly due to the timer interrupt. If this is not acceptable for your application, you will have to read the datasheet of the microcontroller and learn how to set the ADC to be “auto-triggered” from a timer.

# Answer
> 0 votes
The sampling frequency is calculated by the number of samples per time. I think you need to know how fast you're able to do this in your `loop()`.

For this you could fetch the start time, do a number of sampling, fetch the end time, and calculate the frequency.

This is the straight forward and simple way.

Please be aware the the turn-arund time for your sketch will include the transmission time for the result. This will be much longer than the time for the "pure" analog conversion.

---

Alternatively you can lookup the source code of Arduino's library function for `analogRead()`, get the data sheet, learn how the conversion works, and calculate the time.

But this is not at all easy.

---

BTW, `delay(1)` is by far not enough to "saturate" the serial transmission you do. You are using 9600 baud which gives about 960 characters per second. The biggest number you send is "1023" and the sequence "\r\n" is appended due to `println()`. So you are transmitting 6 characters which need 6 characters / 960 characters/s = 0.00625 s. These are a bit more than 6 ms, so you would `delay(7)` at least.

If you don't, the call to `println()` will do the delay if the transmitter's buffer gets full. Therefore your sketch will wait anyway. So you might consider to remove the delay.

---

And please, use the correct formatting the next time. ;-)

---
Tags: atmega2560
---


# Question
Title: How to assign an interrupt to a button press with an ATtiny? (interrupt not fired with my code)
*(Here is finally a solution)*.

I'm using the following code on a ATtiny45 to **assign an interrupt to a button press** (pin #7, PB2, INT0). However the LED doesn't blink when the button is pressed, as if the interrupt is not working. **Why?**

Note: I'd like to use the least power when no interrupt happens, to have a current in the order of magnitude of ~ 1 µA, to run from batteries for years.

```
#include <avr/sleep.h>

void setup()
{
  pinMode(4, OUTPUT);  // LED
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);      // pin #7 = PB2
  digitalWrite(4, HIGH); delay(100); digitalWrite(4, LOW);  // LED blink, working here
}

void wake()
{
  sleep_disable();
  detachInterrupt(0);
  digitalWrite(4, HIGH);  // LED not working here when pressing the button
}

void loop()
{
  sleep_enable();
  ADCSRA = 0;
  attachInterrupt(0, wake, CHANGE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}

```

Note:

* I'm using Arduino IDE with damellis' attiny, I also tried with Spence Konde's ATtinyCore but it's the same
* In my real code, I have 3 buttons, on pin #5, #6, #7, so eventually I'd like to have interrupts for all these three pins.
* I've read https://gammon.com.au/forum/?id=11497 but using `noInterrupts()` / `interrupts()` did not change anything in my case.
* I've tried "Sketch J" from https://gammon.com.au/forum/?id=11497 but `EIFR = bit (INTF0);` gives an `error: 'EIFR' was not declared in this scope` (I'm compiling from Arduino IDE); probably this works on an ATmega but not ATtiny.

---

**Edit: Here is a working code of deep sleep, with an interrupt when the pin #5 (PB0) changes...**

```
#include <avr/interrupt.h>
#include <avr/sleep.h>

ISR(PCINT0_vect) {
  if (digitalRead(0) == LOW)
    digitalWrite(4, HIGH);
  else
    digitalWrite(4, LOW);
}

void setup() {
  pinMode(4,OUTPUT); // LED
  pinMode(0,INPUT_PULLUP);
  pinMode(1,INPUT_PULLUP);
  pinMode(2,INPUT_PULLUP);
  ADCSRA = 0; // ADC disabled
  GIMSK = 0b00100000;  // General Interrupt Mask Register, / Bit 5 – PCIE: Pin Change Interrupt Enable / When the PCIE bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt is enabled. Any change on any enabled PCINT[5:0] pin will cause an interrupt. The corresponding interrupt of Pin Change Interrupt Request is executed from the PCI Interrupt Vector. PCINT[5:0] pins are enabled individually by the PCMSK0 Register. / see https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
  PCMSK = 0b00000111;  // Pin-change interrupt for PB0, PB1, PB2
}

void loop() {
  sleep_enable();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_cpu();
}

```

**...but for an unknown reason, if I add this code:**

```
ISR(PCINT1_vect) {
  if (digitalRead(1) == LOW)
    digitalWrite(4, HIGH);
  else
    digitalWrite(4, LOW);
}

```

the pin-change interrupt for PB0 still works (PCINT0), but not the interrupt for PB1 (PCINT1). Why?

# Answer
Look at the datasheet of the ATtiny45. In the section “Sleep Modes”, there is a table that lists the wake-up sources available for each sleep mode. For the mode “power-down”, INT0 is listed as a possible wake-up source, but there is a small footnote:

> For INT0, only level interrupt.

This means that the `CHANGE` mode you are trying to use will not wake-up the MCU out of power-down. You have to instead

```
attachInterrupt(0, wake, LOW);

```

> In my real code, I have 3 buttons, on pin #5, #6, #7, so eventually I'd like to have interrupts for all these three pins.

You may then have to look into the “pin-change” interrupt. This is something different from the INT0 you are using here, and is not generally supported by the Arduino core. You will have to either get some pin-change-interrupt library, or work with no library using the information from the datasheet (not that hard). Pin-change interrupt is also a wake-up source for power-down.

---

**Edit**: Answering extra questions from comments.

> How did you know that "only level interrupt" means only "LOW"?

The Arduino documentation states that the `mode` parameter of `attachInterrupt()` can be either `LOW`, `CHANGE`, `RISING` or `FALLING`. A few boards also support `HIGH`, but the ATtinies are not among them. A “level” can be either `LOW` or `HIGH`, whereas `CHANGE`, `RISING` and `FALLING` are “edges”.

This is corroborated by the ATtiny45 datasheet: “The INT0 interrupts can be triggered by a falling or rising edge or a low level.”

> Is pin-change interrupt `PCINT`?

Yes.

> why do you think it isn't supported by the Arduino core?

The `attachInterrupt()` API only really makes sense for INT0, INT1, etc... not for PCINT. You can also look at the source code.

> Isn't it standard to interrupt when a pin changes states?

If you wish, you can configure INT0 to interrupt on a rising edge, a falling edge, or any logical change. But this uses an edge-detection logic which relies on the main clock, and thus does not work in power-down mode.

For more details on INT0 vs. PCINT, their differences, and how to use them, please refer to the datasheet, specifically to the “External Interrupts” section I linked to above.

---

**Addendum**: Extra question:

> why it doesn't work \[with `ISR(PCINT1_vect) {...}`\]?

Gcc tells me “**warning: ‘PCINT1\_vect’** appears to be a misspelled signal handler”. And indeed, there is no such interrupt vector on the ATtiny45: there is only PCINT0\_vect, and this interrupt is shared by all the pins that can generate a pin change interrupt. If you want to know which pin triggered the interrupt, you will have to figure that out within the interrupt handler itself.

This is the single point that makes the PCINTs trickier to work with than INT0 and co.: each PCINT interrupt is shared by a group of pins. On the ATtiny45, there is only one such group, and `PCINT0_vect` is the only interrupt handler. Larger AVRs have more groups (3 on the Uno/ATmega328P), and `PCINT1_vect` makes sense on them.

Also beware of the somewhat confusing naming scheme. Avr-libc defines some macros `PCINTn`, where `n` is a number. These macros expand to bit numbers, and are meant to be used in code like this:

```
PCMSK = _BV(PCINT0)   // sense changes in pin PCINT0 = PB0...
      | _BV(PCINT1)   // and PCINT1 = PB1...
      | _BV(PCINT2);  // and PCINT2 = PB2

```

In these macros, the number `n` identifies an *individual pin*. Avr-libc also defines the macros `PCINTm_vect` for defining interrupt handlers. In these macros, the number `m` identifies a *pin group*.
> 3 votes

---
Tags: power, interrupt, attiny
---


title: Atmega 328P in Arduino

text:
# Question
Title: Atmega 328P in Arduino
Does anyone know what it means by the Atmega 328p has 131 instructions? And could you give an example of how any one of these 131 instructions look like? Thanks in advance!!

# Answer
A CPU or MCU uses very basic instructions which are executed.

If you write code in a program language (like in Arduino IDE), the sketch is converted into many instructions (by the compiler and linker).

The instruction set can be found here.

An example is:

`ADC Rd, Rr`: Adds two registers and the contents of the C flag and places the result in the destination register Rd.

A CPU/MCU uses registers, which can be seen as very fast 'variables', mostly there are quite few of them, and all operators (like +, -, \*, /) are carried out using these registers.

If you are just starting Arduino, it's not so useful to dive into this, the compiler/linker will take care of these 'details'; just be glad you don't have to write in assembly (anymore).
> 2 votes

---
Tags: atmega328
---


# Question
Title: HC-05 can not use lower pins only 8 and higher
```
#include <Arduino.h>
#include <SoftwareSerial.h>

char Incoming_value = 0;

// SoftwareSerial BTSerial( 10, 11 ); // RX | TX +
// SoftwareSerial BTSerial( 9, 10 ); // RX | TX +
// SoftwareSerial BTSerial( 8, 9 ); // RX | TX +
// SoftwareSerial BTSerial( 7, 8 ); // RX | TX - ???
// SoftwareSerial BTSerial( 6, 7 ); // RX | TX - ???
// SoftwareSerial BTSerial( 5, 6 ); // RX | TX - ???
// SoftwareSerial BTSerial( 4, 5 ); // RX | TX - ???
// SoftwareSerial BTSerial( 3, 4 ); // RX | TX - ???

SoftwareSerial BTSerial( 8, 9 ); // RX | TX +

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

void loop() {
        delay( 1000 );
        BTSerial.println( "hello" );
        if( BTSerial.available() > 0 ) {
                BTSerial.println( "BINGO!" );
                Incoming_value = BTSerial.read();
                BTSerial.println( Incoming_value );
                if ( Incoming_value == '1' ) digitalWrite( 13, HIGH );
                else if ( Incoming_value == '0' ) digitalWrite( 13, LOW );
        }
}

```

My HC-05 Bluetooth module wont't work on lowers digital pins.

> BOARD\_TAG = leonardo

* It works fine on highers digital pins: 8-9, 9-10 or 10-11 - everything fine.
* but 2-3, 3-4, 4-5, 5-6, 6-7 or 7-8 - no....

Why? Should I inject jumper somewhere or what?

And yes: @Majenko, "0,1 - is required to debug from host". I want to have Serial from PC and BTSerial from bluetooth - to have both accesses to device simultaneously.

@Peter\_Paul\_Kiefer, so, you think, this is impossible with lowest pins, lower than 8?

# Answer
> 2 votes
From the official SoftwareSerial Site: https://www.arduino.cc/en/Reference/softwareSerial (Section Limitations)

> Not all pins on the Leonardo and Micro support change interrupts, so only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

---
Tags: bluetooth, arduino-leonardo
---


# Question
Title: What is the best data type to be used through i2C
i'm trying to send multiple commands to multiple slaves controlling motors. Slave Controller(Arduino Nano) will receive the command, and returns the current position of the motors to the Master(Arduino Mega).

What data type would be best to use in this scenario. I am considering, string or byte data type.

# Answer
I2C works with fixed size byte arrays.

Single bytes for commands should be sufficient. For positions you might need int16\_t or even bigger numbers. Unsigned positions relative to (above) zero might make things easier, eventually (?)

As you have the same architecture on both sides, mapping of byte arrays to bigger numbers via `union` will work well.
> 2 votes

# Answer
Strings (aka byte arrays of arbitrary length) are perfect for asynchronous and full duplex protocols like UART, essentially because those are no master-slave protocols. Here, both master and slave can transmit a byte stream independent of each other at any time and with any length.

But using strings on I2C is quite uncommon. As I2C is a master-slave bus where **any** communication (read and write) is initiated by the master generating the bus clock, using strings has the big disadvantage, that the master has to know the number of bytes the slave has to transmit. Of course you could implement it, but as long as you don't need the data to be human-readable, I suggest the more efficient way of transmitting bytes. Usually, an i2c read transmission is done by

1. addressing the slave in write mode
2. Writing the target value's register address
3. Addressing the slave in read mode
4. Reading an arbitrary number of bytes (e.g. four bytes for float values)

A write transmission is a bit simpler:

1. addressing the slave in write mode
2. Writing the target value's register address
3. Writing an arbitrary number of bytes (e.g. four bytes for float values)

This is the standard protocol that e.g. I2C sensors use and it's convenient to implement the same behaviour in the ISR when using a microcontroller (you could think of "register addresses" as "variable IDs").

To prepare values of any datatype for transmission (e.g. float to byte\[4\]) you can use a `union`.
> 1 votes

---
Tags: arduino-mega, i2c, data-type
---


# Question
Title: Detecting how many button presses(single tap, double tap etc) with two simultaneous buttons
noob here

So what I am trying to do is output a different number depending on the number of button presses e.g. for 1 button press it should output 1 and so forth. After that I only really want the outputs for 1 to 4 presses. I am using these inputs for a game. Right now, it does work and counts up until 4 and then resets back to 0. The problem that I am having is it continues after 1 click to 2 clicks; what I want it to do is count 1 click when its clicked once, twice when its clicked twice etc. I am trying to use a debouncing code to distinguish between single tap, double tap, triple tap etc @VE7JRO kindly provided a great solution to this problem, albeit it was for one button. I am trying to adjust the code to accommodate 2 separate buttons (on separate pins), but it is giving me an error.

This is the code:

```
#include <Bounce2.h>

// Connect both buttons in series with one connection
// to GND and the other to a digital pin.
const int buttonPin1 = 2;
const int buttonPin2 = 3;

class Button
{
  private:

    int m_buttonPin1;
    int m_buttonPin2;
    int m_counter;
    unsigned long m_buttonPressTimeout;
    unsigned long m_previousMillis;

  public:

    Button(int button):
      m_buttonPin1(buttonPin1),
      m_buttonPin2(buttonPin2),
      m_counter(0),
      m_buttonPressTimeout(1500), // Button press timeout 500 ms.
      m_previousMillis(0){}

    void Update()
    {
      int valA = digitalRead(button1); // read button stateint
      int  valB = digitalRead(button2); // read button state
       if (valA == LOW &&valB == LOW)
       {
      if(m_counter > 0 && millis() - m_previousMillis >= m_buttonPressTimeout)
      {
        Serial.print("Count from Update() just before it's re-set to 0 = ");
        Serial.println(GetCounter());
        m_counter = 0;
      }
    }

    void IncrementCounter(){
      m_counter++;
      if(m_counter > 4){m_counter = 4;}
      if(m_counter == 1){
        m_previousMillis = millis();
      }
    }

    byte GetCounter(){
      return m_counter;
    }

};

Bounce button1Debouncer = Bounce();
Bounce button2Debouncer = Bounce();
Button MyButton(buttonPin1);
Button MyButton(buttonPin2);

void setup(){

  Serial.begin(9600);

  pinMode(buttonPin1, INPUT_PULLUP);
  button1Debouncer.attach(buttonPin);
  button1Debouncer.interval(5);
  pinMode(buttonPin2, INPUT_PULLUP);
  button2Debouncer.attach(buttonPin);
  button2Debouncer.interval(5);

}

void loop(){

  // Call the Update function as fast as possible.
  MyButton.Update();

  // Button pressed.
  if(button1Debouncer.update() && button2Debouncer.update())
  {
    if(button1Debouncer.fell() && button2Debouncer.fell()){
      MyButton.IncrementCounter();
      Serial.print("Count from Button Debouncer = ");
      Serial.println(MyButton.GetCounter());
    }
  }

}
}

```

The error is: "'buttonPin1' is not a type", I do not understand this error as it didn't give that error for when a single button was used.

# Answer
> 0 votes
If it’s possible to connect the 2 buttons in series, then this sketch may give you the desired results.

```
#include <Bounce2.h>

// Connect both buttons in series with one connection
// to GND and the other to a digital pin.
const byte buttonPin = 2;

class Button{

  private:

    byte m_buttonPin;
    byte m_counter;
    unsigned long m_buttonPressTimeout;
    unsigned long m_previousMillis;

  public:

    Button(byte buttonPin):
      m_buttonPin(buttonPin),
      m_counter(0),
      m_buttonPressTimeout(500), // Button press timeout 500 ms.
      m_previousMillis(0){}

    void Update(){
      if(m_counter > 0 && millis() - m_previousMillis >= m_buttonPressTimeout){
        Serial.print("Count from Update() just before it's re-set to 0 = ");
        Serial.println(GetCounter());
        m_counter = 0;
      }
    }

    void IncrementCounter(){
      m_counter++;
      if(m_counter > 4){m_counter = 4;}
      if(m_counter == 1){
        m_previousMillis = millis();
      }
    }

    byte GetCounter(){
      return m_counter;
    }

};

Bounce buttonDebouncer = Bounce();
Button MyButton(buttonPin);

void setup(){

  Serial.begin(9600);

  pinMode(buttonPin, INPUT_PULLUP);
  buttonDebouncer.attach(buttonPin);
  buttonDebouncer.interval(5);

}

void loop(){

  // Call the Update function as fast as possible.
  MyButton.Update();

  // Button pressed.
  if(buttonDebouncer.update()){
    if(buttonDebouncer.fell()){
      MyButton.IncrementCounter();
      Serial.print("Count from Button Debouncer = ");
      Serial.println(MyButton.GetCounter());
    }
  }

}

```

**EDIT**

Based on your last update to the question:

> I am trying to adjust the code to accommodate 2 separate buttons (on separate pins), but it is giving me an error.

I have updated the sketch to use 2 buttons on separate digital pins.

```
#include <Bounce2.h>

// Connect each button with one connection
// to GND and the other to a digital pin.
const byte buttonPin = 2;
const byte buttonPin2 = 3;

class Button{

  private:

    byte m_buttonPin;
    byte m_counter = 0;
    unsigned long m_buttonPressTimeout;
    unsigned long m_previousMillis;

  public:

    Button(byte buttonPin):
      m_buttonPin(buttonPin),
      m_counter(0),
      m_buttonPressTimeout(750), // Button press timeout in ms.
      m_previousMillis(0){}

    void Update(){
      if(m_counter > 0 && millis() - m_previousMillis >= m_buttonPressTimeout){
        Serial.print("Count from Update() just before it's reset to 0 = ");
        Serial.println(GetCounter());
        m_counter = 0;
      }
    }

    void IncrementCounter(){
      m_counter++;
      if(m_counter > 4){m_counter = 4;}
      if(m_counter == 1){
        m_previousMillis = millis();
      }
    }

    friend void IncrementCounter(Button&);

    void IncrementCounter(Button&){
      IncrementCounter();
    }

    byte GetCounter(){
      return m_counter;
    }

};

Bounce buttonOneDebouncer = Bounce();
Bounce buttonTwoDebouncer = Bounce();
Button ButtonOne(buttonPin);
Button ButtonTwo(buttonPin2);

void setup(){
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  buttonOneDebouncer.attach(buttonPin);
  buttonTwoDebouncer.attach(buttonPin2);
  buttonOneDebouncer.interval(25);
  buttonTwoDebouncer.interval(25);
}

void loop(){

  // Call the Update function as fast as possible.
  ButtonOne.Update();
  ButtonTwo.Update();

  // Button one pressed.
  if(buttonOneDebouncer.update()){
    if(buttonOneDebouncer.fell()){
      if(digitalRead(buttonPin2) == 0){
        ButtonOne.IncrementCounter();
      }
    }
  }

  // Button two pressed.
  if(buttonTwoDebouncer.update()){
    if(buttonTwoDebouncer.fell()){
      if(digitalRead(buttonPin) == 0){
        ButtonOne.IncrementCounter(ButtonTwo);
      }
    }
  }

}

```

# Answer
> 2 votes
You SHOULD pay attention to the following issues:

**1. Floating input problem:**

***Symptom:*** the reading value from the input pin is not matched with the button's pressing state.

***Cause:*** input pin is NOT used pull-up or pull-down resistor.

***Solution:*** Use pull-up or pull-down resistor. See Arduino Button (with pull-up/pull-down)

**2. Chattering phenomenon**

It should be considered in only some application that needs to detect exactly number of the pressing.

***Symptom:*** Button is pressed one, but Arduino code detects several times.

***Cause:*** Due to mechanical and physical issues, the state of the button (or switch) is quickly toggled between LOW and HIGH several times

***Solution:*** Debounce. See Arduino Button Debounce

# Answer
> 2 votes
Your updated code has lots of problems. To do button debouncing, try something like this:

```
//Adjust debounceTime as desired. Shorter times will make fore faster button
//response, but make the debouncing less effective. 50 is 1/20th of a second.
#define debounceTime 50

unsigned long nextButtonCheckTime = 0;
bool buttonAState = false;
bool buttonBState = false;

void loop() {
  //Only check the buttons if the debounce time has passed
  if (millis() > nextButtonCheckTime)
    bool newButtonAState = digitalRead(buttonAPin) == LOW;
    bool newButtonBState = digitalRead(buttonBPin) == LOW;
    //If one or both buttons have changed state
    if  (buttonAState != newButtonAState || buttonBState != newButtonBState)) {
      nextButtonCheckTime = millis() + debounceTime;
      buttonAState = newButtonAState;
      buttonBState = newButtonBState;
      //Handle change of button state
    }
  }
}

```

That is pseudocode. It almost certainly contains syntax errors. You should use it as a guide, and rewrite it to suit your needs. Do **not** say "I copied your code into my sketch and it won't compile."

# Answer
> 1 votes
It is likely you are experiencing problems associated with button contact bounce. This is where the processor is so fast that it "sees" the button make several contacts when the user only intends for 1 contact to be seen by the program. Consider using this button de-bounce library instead of reading the state of the buttons directly in the sketch.

The code for the above debounce Arduino library is hosted here at github.com. In general, people using github.com will have an "example" folder along with the source code and documentation folders. The debounce Arduino library example folder is here. There are about half a dozen Arduino sketch examples including this 2 button example which might be used as the starting point for the project in the question.

There may be a logic problem in the code when interpreting the number of button presses into "a", "b", "c" & "d". The modulo operator "%" is used. And in the first test, the number of button presses % 1 is tested. If the result is zero the test is true. As any number % 1 has no remainder this test will always be zero and therefor always true. As all other tests are nested inside "else" statements none of the other tests will be executed. Instead consider using a switch / case statement where the code switches on the number of button presses and the case statements are "case 1:", case 2:", "case 3:" & "default:". It is good coding practice to always have a "default:" case in a switch statement. Here we use "default:" instead of "case 4:". After using the value representing the number of button presses, always remember to clear this value before the next iteration. Remember, any "global" values (values defined outside a function) will retain their values between calls to that function. Any "local" value (values defined inside a function) will not retain their values and need to be initialize each time they are used.

---
Tags: arduino-uno, button
---


# Question
Title: HC06 correct baud rate but missing characters/ no AT commands
I have an issue with the communication between my Serial Monitor and my BT HC06 Module. Iam able to send ascii characters from my phone with BT connection to my local serial monitor. When i send characters from my local serial monitor to my BT module i receive something like this: AT -\> U or 3 -\> 3

I have this issue since i changed the baud from 9600,0,0 to 9600,0,1

Code:

```
#include <SoftwareSerial.h>

SoftwareSerial BTSerial(10, 11); // RX | TX

void setup()
{
  pinMode(9, OUTPUT);  // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
  digitalWrite(9, HIGH);
  Serial.begin(9600);
  Serial.println("Enter AT commands:");
  BTSerial.begin(9600);  // HC-05 default speed in AT command more
}

void loop()
{

  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTSerial.available())
    Serial.write(BTSerial.read());

  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
    BTSerial.write(Serial.read());
}

```

# Answer
Sorry, my question was not easy to understand. Your solution had not worked for me. I found another libary where its possible to add the parity bit: https://github.com/ledongthuc/CustomSoftwareSerial

This works fine for me.

Thanks for your help :)
> 2 votes

# Answer
If I understand you right: You changed the UART settings on the HC05 module and now you are unable to connect to the HC-06.

You use SoftwareSerial for the connection as on an UNO you have only one HardwareSerial port. SoftwareSerial only allows to configure the baud rate. There are work arounds https://forum.arduino.cc/index.php?topic=251764 , but you can also write a little sketch that reconfigure your HC06 UART to 9600,0,0 using the HardwareSerial which can be setup to the new parity settings to connect to the HC-06.

Something like this

```
void setup()
{
  //Serial.begin( 9600, SERIAL_8O1 );
  Serial.begin( 9600, SERIAL_8E1 );

  // I do not setup to 9600,0,0 but to 9600,1,0
  // Because the Arduino use the stop bit set by default.
  Serial.println( "AT+UART=9600,1,0" );
}

void loop() {}

```

I can not try this program, so it's only an example on hoew to reset your HC-05.

Of cause; before you upload the sketch, you have to connect to HC-05 to the Hardware serial pins (0,1).
> 1 votes

---
Tags: arduino-uno, serial, bluetooth, baud-rate
---