title: Bike Gear Indicator Coding Problem

text:
# Question
Title: Bike Gear Indicator Coding Problem
Lack of practice I forgot many function of C & C++... Can anyone help me with this coding Please...

I think this is The Main coding: Topic: Gear indicator

I first found this, Gear\_Indicator\_Raw

**But, There was many problem in those sketch,**

1. Those sketches work just like simple counter,
2. Can't Show "2" from "0"
3. No Neutral Detection,

As Bike Gear, (1 N 2 3 4 5) One Down Four up, I made some Changes, But can't add the Neutral part smoothly...

And here, My code:

```
#define BUTTON_DOWN 13
#define BUTTON_UP 4
#define BUTTON_N 11

int ledPinA = 7;
int ledPinB = 12;
int ledPinC = 10;
int ledPinD = 9;
int ledPinE = 8;
int ledPinF = 6;
int ledPinG = 5;

int val_up = 0;
int val_down = 0;
int val_n = 0;
int old_val_n = 0;
int old_val_down = 0;
int old_val_up = 0;
int gear = 0;
// The setup() method runs once, when the sketch starts

void setup()
{
  pinMode(BUTTON_N, INPUT);
  pinMode(BUTTON_UP, INPUT);
  pinMode(BUTTON_DOWN, INPUT);

  pinMode(ledPinA, OUTPUT);
  pinMode(ledPinB, OUTPUT);
  pinMode(ledPinC, OUTPUT);
  pinMode(ledPinD, OUTPUT);
  pinMode(ledPinE, OUTPUT);
  pinMode(ledPinF, OUTPUT);
  pinMode(ledPinG, OUTPUT);
}

void led0()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, LOW);
  digitalWrite(ledPinF, LOW);
  digitalWrite(ledPinG, HIGH);
}
void led1()
{
  digitalWrite(ledPinA, HIGH);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, HIGH);
  digitalWrite(ledPinE, HIGH);
  digitalWrite(ledPinF, HIGH);
  digitalWrite(ledPinG, HIGH);
}
void led2()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, HIGH);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, LOW);
  digitalWrite(ledPinF, HIGH);
  digitalWrite(ledPinG, LOW);
}
void led3()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, HIGH);
  digitalWrite(ledPinF, HIGH);
  digitalWrite(ledPinG, LOW);
}
void led4()
{
  digitalWrite(ledPinA, HIGH);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, HIGH);
  digitalWrite(ledPinE, HIGH);
  digitalWrite(ledPinF, LOW);
  digitalWrite(ledPinG, LOW);
}
void led5()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, HIGH);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, HIGH);
  digitalWrite(ledPinF, LOW);
  digitalWrite(ledPinG, LOW);
}
void led6()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, HIGH);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, LOW);
  digitalWrite(ledPinF, LOW);
  digitalWrite(ledPinG, LOW);
}
void led7()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, HIGH);
  digitalWrite(ledPinE, HIGH);
  digitalWrite(ledPinF, HIGH);
  digitalWrite(ledPinG, HIGH);
}
void led8()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, LOW);
  digitalWrite(ledPinF, LOW);
  digitalWrite(ledPinG, LOW);
}
void led9()
{
  digitalWrite(ledPinA, LOW);
  digitalWrite(ledPinB, LOW);
  digitalWrite(ledPinC, LOW);
  digitalWrite(ledPinD, LOW);
  digitalWrite(ledPinE, HIGH);
  digitalWrite(ledPinF, LOW);
  digitalWrite(ledPinG, LOW);
}

void setLed(int number)
{
  switch (number)
  {
    case 0:
      led0();
      break;
    case 1:
      led1();
      break;
    case 2:
      led2();
      break;
    case 3:
      led3();
      break;
    case 4:
      led4();
      break;
    case 5:
      led5();
      break;
    case 6:
      led6();
      break;
    case 7:
      led7();
      break;
    case 8:
      led8();
      break;
    case 9:
      led9();
      break;
  }
}

// the loop() method runs over and over again,
// as long as the Arduino has power

void oldloop()
{
  led0();
  led1();
  led2();
  led3();
  led4();
  led5();
  led6();
  led7();
  led8();
  led9();
}

void loop()
{
//neutral

    val_n =  digitalRead(BUTTON_N);
    if ((val_n == HIGH) &&gear<=2)
    {
      gear = 0;                         //Posted wrong "gear = HIGH"
      delay(100);
    }

// Gear Up

    val_up = digitalRead(BUTTON_UP);
    if ((val_up == HIGH) && (old_val_up == LOW) &&(gear<6) && (gear>0))
    {
      gear += 1;
      delay(100);
    }

    else if ((val_up == HIGH) && (old_val_up == LOW) &&(gear==0))
    {
      gear += 2;
      delay(100);
    }
    old_val_up = val_up;

// Gear Down

    val_down = digitalRead(BUTTON_DOWN);
    if ((val_down == HIGH) && (old_val_down == LOW)&& (gear>1))
    {
      gear -= 1;
      delay(100);
    }

    else   if ((val_down == HIGH) && (old_val_down == LOW) && (gear==0))
    {
      gear += 1;
      delay(100);
    }
    old_val_down = val_down;

// Max Limit

    if (gear >= 5)
    {
      gear = 5;
    }

    setLed(gear);
}

```

**The Problem:**

1. Without the "// neutral" part it's work OK, but can't show "0" without reset.
2. With the "// neutral" part, While **gear up**, instead of increasing, display shows "0" after "1".
3. If I press pin "4" very quickly, then it's increasing to Max gear.

I think there is some problem in this part:

```
//neutral

    val_n =  digitalRead(BUTTON_N);
    if ((val_n == HIGH) &&gear<=2)
    {
     gear = HIGH;
      delay(100);
    }

```

And, Please, If anyone can tell me about "Void oldloop()", what this is for?

# Answer
> 1 votes
**Likely problem**

I'm not sure how to solve the problem, however, I see at least one item that looks strange in the //neutral part:

```
gear = HIGH;

```

This seems `gear` is a pin status (LOW/HIGH), but two lines above:

```
if ((val_n == HIGH) &&gear<=2)

```

Here `gear` is an integer value. This seems quite inconsequent to me.

**Pin 4**

The reason is you do not have a debouncing algorithm, check for a Debounce Arduino example. When a button is pressed or depressed, it switches sometimes very fast a few times; this might result in multiple increases/decreases of the gear.

**oldLoop**

The function `oldLoop` is not used, but if you swap the names of `loop` and `oldLoop` you can use the 'test' scenario which is contained in `oldLoop`.

**Some other tips**

* Use spacing consequently
* You can refactor the LED code a lot.
* You can use `gear++;` to increase or `gear--;` to decrease.

**Update**

(Changed debouncing problem for pin 4).

You changed in your neutral code:

```
gear = 0;

```

Shouldn't that be `gear = 1;`? As gear 1 means Neutral (gear 0 is 1).

# Answer
> 1 votes
Your problem is that you are confused about the meaning of `gear`.

One possible meaning could be 0 = neutral, 1 .. 5 = gear. But then, when changing gears you can't simply do + or -, as the sequence is 1 - 0 - 2 - 3 - ...

The other interpretation is: gear-- from 2 means neutral and you display something that indicates neutral ( e.g. a '0' or a '-' ) whenever gear==1, and you display a '1' when you do another gear--, and have a numeric value of 0 in `gear`.

Your decision.

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


# Question
Title: Bluetooth: sync time from an NTP server via Internet connection shared with Android phone
I saw that it is possible to sync time from an NTP server over WiFi. I have the HC-06 Bluetooth module and an Android phone that can share its Internet connection with Arduino via Bluetooth. Would it be possible to sync time/date using this infrastructure? And if yes - how (which libraries, etc..)? Has anybody done it already and there is a tutorial on that?

# Answer
> 3 votes
No, not really. It is possible, but not easily like you want it to be. The HC-06 is a Bluetooth-Serial bridge. In the Bluetooth protocol there are many types of interfaces, that a client device might expose to the master. A Bluetooth mouse exposes a HID interface, a headset exposes a corresponding audio interface and the HC-06 exposes a pure Serial interface. Thus the HC-06 does not support what ever interface is used for tethering.

Ways, that may make it possible:

* Change the firmware of the HC-06 for exposing the correct interface and interact with it. For this you need to know how to reprogram the HC-06 and how exactly bluetooth works. I guess this is over your current level.
* Write an app for your Andriod smartphone, which plays the Serial-Internet bridge on the phone. The app would translate between Serial and Internet, involving your own protocol on the Serial interface. Easiest, when you just make a specialized app for syncing time, so that it does not have to do any other communication.

And at that point it is just too much work to go either way. It is unlikely, that you find libraries or any code for this, since it just doesn't make much sense. Instead you could move from an Arduino to an ESP, which can directly connect to the WiFi network in question and thus get directly the time from the internet, without tethering. That is way easier and you can use the many libraries, that already exist for that problem.

---
Tags: arduino-uno, bluetooth, time, hc-06
---


# Question
Title: I am trying to read input from 5th PIN of PORT B?
In a nutshell i want to read a PORTB 5th pin without using digitalRead API ( i am trying to learn baremetal using arduino-uno-r3)

Just to Learn How internal register works i did not used digitalRead API, instead i have used DDRB register to set the 5 bit of DDRB as Low indicating PORTB 5th pin is in input mode then i am using an if statment to check if 5th bit of PINB is high or low my expection was that when i connect arduino pin 13 to 5v if statment will become TRUE.

```
void setup() {
  // put your setup code here, to run once:
  DDRB = DDRB & ~(1<<5);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(PINB & (1<<5)){
     Serial.println("Got data");
    }
}

```

When i executed above code i am constantly getting if as TRUE

# Answer
> 2 votes
There seem to be several, separate issues in your question.

One is a simple matter of language. In English, “1st” is an abbreviation for “first”, which is an ordinal adjective applied to an item in a list meaning that there is no other item before it in that list. In the same vein, “5th” means “fifth”, which applies to the item that has exactly four items before it. For instance, the list of pins of port B is {PB0, PB1, PB2, PB3, PB4, PB5}. PB0 is the first in the list, and PB4 is the fifth. The fact the first item bears the number 0 makes this confusing. Thus, I recommend avoiding ordinal adjectives altogether and instead calling the pins by their names, like “digital 13” (Arduino naming) or “PB5” (AVR naming).

The second issue, and probably your main concern, is about the floating input pin. You cannot expect a reliable reading from a floating input. I will not try to explain why, as the issue has been discussed ad nauseam here and elsewhere. Just do a Web search. The simplest solution is to use the built-in pull-up resistor and externally connect a push button between the pin and ground. You will read `LOW` whenever the button is pressed:

```
void setup() {
    pinMode(13, INPUT_PULLUP);
    Serial.begin(9600);
}

void loop() {
    if (digitalRead(13) == HIGH)
        Serial.println("HIGH");
    else
        Serial.println("LOW");
}

```

The last point is about going bare metal and learning how to use the I/O registers directly. A small warning first: you have to keep in mind that this is board-specific. You tagged your question with both “arduino-uno” and “arduino-mega”, but these boards have different pin mappings (digital 13 is PB7 on the Mega). The general way of using the DDRx, PORTx and PINx registers is the same across all AVR chips, but is not portable to Arduinos based on a different architecture.

So let's assume this is intended to work only on an Uno, Nano, or other board based on an ATmega328P. Judging from the example code you show, you seem to already understand pretty well how these registers work. There is no problem in your code, beside the fact that it requires an external pull-up. If you want to enable the internal pull-up, you have to set the appropriate bit in PORTB. This can seem confusing, as the same register is used for pull-up control (when the pin is in input mode) and for output control (when the pin is an output). Essentially, each GPIO pin has four distinct electrical states which are controlled by to I/O bits:

```
│ DDRxn │ PORTxn │ state        │
├───────┼────────┼──────────────┤
│   0   │    0   │ INPUT        │
│   0   │    1   │ INPUT_PULLUP │
│   1   │    0   │ OUTPUT LOW   │
│   1   │    1   │ OUTPUT HIGH  │
└───────┴────────┴──────────────┘

```

The example program above can be translated to low-level AVR style as follows:

```
void setup() {
    DDRB &= ~_BV(PB5);  // input mode
    PORTB |= _BV(PB5);  // enable pullup
    Serial.begin(9600);
}

void loop() {
    if (PINB & _BV(PB5))
        Serial.println("HIGH");
    else
        Serial.println("LOW");
}

```

---
Tags: arduino-uno, arduino-ide
---


# Question
Title: How can arduino read a frequency higher than 16Mhz?
I will like to understand how does Arduino measure a frequency. Also how does my voltmeter can measure a frequency as well. Since I am a beginner on using microcontroler I would read a frequency like this:

```
void loop()
{
    while(digitalRead(myPin)==HIGH)
    {
       // pin is high
    }
    // measure time using millis (this is the time the pin was high)

    while(digitalRead(myPin)==LOW)
    {
       // pin is low
    }
    // measure time using millis (this is the time the pin was low)

}

```

**With this code it makes sense to me how to measure a frequency and a duty cycle. The problem with this code is that it will probably be very slow and I it will probably read frequencies up to 100Hz and less.**

So my questions are:

1. How can arduino read frequencies higher than 100Hz? How does it achieve that?
2. I Googled arduino's frequency and it shows to be 16MHz. That means arudino can read frequencies up to 16Mhz? Ethernet cables specifically CAT5 has a frequency of 100MHz. That means that it sends signals 100,000,000 in one second! How could Arduino send that many signals in one second if I where to buy a Ethernet shield such as this one?

# Answer
> 3 votes
> How can arduino read frequencies higher than 100Hz? How does it achieve that?

Interrupts (if you want to do it in software) or a magical piece of hardware called the Input Compare peripheral that is built into most MCUs.

> I Googled arduino's frequency and it shows to be 16MHz. That means arudino can read frequencies up to 16Mhz?

No, that is the speed the CPU operates at. The maximum frequency signal it can read is usually below that (for SPI it's half that, 8MHz, for example).

> Ethernet cables specifically CAT5 has a frequency of 100MHz. That means that it sends signals 100,000,000 in one second! How could Arduino send that many signals in one second if I where to buy a Ethernet shield such as this one?

It doesn't. The shield does. The Arduino just tells the shield what to do, and the chip on the shield does it.

# Answer
> 1 votes
I would not use `millis()` to measure the period of a signal unless my program had to deal with extremely low frequencies. And by extremely low I mean below 1 mHz (one millihertz). For frequencies above 1 mHz, the pseudo-code you show would work just as well or better using `micros()`.

As the frequency goes up, you will start to look at more fancy options for measuring it. You could for example count the rising edges from an interrupt and measure the duration of many (not just one) periods with `micros()`. This should work up to a few hundred kHz. For faster frequencies you can use a hardware timer configured as a counter, and measure the time it takes to overflow. This should be good for frequencies up to almost half the CPU frequency (8 MHz).

And for the Ethernet signals, see Majenko's answer.

---
Tags: frequency, ethernet-shield
---


# Question
Title: How to pass a changing value to a graphic display using Arduino?
I am using an EA DOGM132-5 graphic display, they also have provided a library for Arduino, so everything is nice and easy. The library has a function for easily passing a string to the LCD.

```
void dog_7565R::string(byte column, byte page, const byte *font_adress, const char *str)
{
unsigned int pos_array;                                         //Postion of character data in memory array
byte x, y, column_cnt, width_max;                               //temporary column and page adress, couloumn_cnt tand width_max are used to stay inside display area
byte start_code, last_code, width, page_height, bytes_p_char;   //font information, needed for calculation
const char *string;

start_code   = pgm_read_byte(&font_adress[2]);  //get first defined character
last_code    = pgm_read_byte(&font_adress[3]);  //get last defined character
width        = pgm_read_byte(&font_adress[4]);  //width in pixel of one char
page_height  = pgm_read_byte(&font_adress[6]);  //page count per char
bytes_p_char = pgm_read_byte(&font_adress[7]);  //bytes per char

if(type != DOGM132 && page_height + page > 8) //stay inside display area
        page_height = 8 - page;
  else  if(type == DOGM132 && page_height + page > 4)
    page_height = 4 - page;

//The string is displayed character after character. If the font has more then one page,
//the top page is printed first, then the next page and so on
for(y = 0; y < page_height; y++)
{
    position(column, page+y); //set startpositon and page
    column_cnt = column; //store column for display last column check
    string = str;             //temporary pointer to the beginning of the string to print
    digitalWrite(p_a0, HIGH);
    digitalWrite(p_cs, LOW);
    while(*string != 0)
    {
        if((byte)*string < start_code || (byte)*string > last_code) //make sure data is valid
            string++;
        else
        {
            //calculate positon of ascii character in font array
            //bytes for header + (ascii - startcode) * bytes per char)
            pos_array = 8 + (unsigned int)(*string++ - start_code) * bytes_p_char;
            pos_array += y*width; //get the dot pattern for the part of the char to print

    if(type != DOGM132 && column_cnt + width > 128) //stay inside display area
                width_max = 128-column_cnt;
    else if(type == DOGM132 && column_cnt + width > 132)
       width_max = 132-column_cnt;
            else
                width_max = width;

            for(x=0; x < width_max; x++) //print the whole string
            {
                spi_out(pgm_read_byte(&font_adress[pos_array+x]));
                //spi_out(pgm_read_byte(&font_adress[pos_array+x])); //double width font (bold)
            }
        }
    }
    digitalWrite(p_cs, HIGH);
}
}

```

So I just use the function in the sketch with the variables I want and I can easily show a string, but I want to show a changing value for example a temperature reading Tc.

```
int ThermistorPin = 0;
int Vo;
float R1 = 10000;
float logR2, R2, T, Tc, Tf;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;

Vo = analogRead(ThermistorPin);
R2 = R1 * (1023.0 / (float)Vo - 1.0);
logR2 = log(R2);
T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
Tc = T - 273.15;

```

But the string function doesn't support variables. Can someone help me to adjust the string function to take variables or perhaps suggest a better way altogether?

# Answer
You didn't mentioned how you convert the floating point value `Tc` to a string before passing it to `dog_7565R::string`, but if you are using `sprintf()`, by default Arduino has the `sprintf()` support for floating point turn off, there is a way to turn it on if you are using Platform.io IDE, but it will not work for Arduino IDE.

One workaround is to use the `dtostrf()` function available in the avr-libc that is accessible in Arduino:

```
dtostrf(floatvar, StringLengthIncDecimalPoint, numVarsAfterDecimal, charbuf);

```

The `dtostrf()` converts a float to a c string.

```
float Tc = T - 273.15;
char floatString[6];
dtostrf(Tc, 4, 2, floatString);

```

This will turn a value like `32.15` into a string `"32.15"`.
> 0 votes

# Answer
You have to first convert the floating point value to a string, then pass the resulting string to the `dog_7565R::string()` function.

It looks like the standard `sprintf()` provided by Arduino does not support the `%f` format for floats, so you may have to find another way to convert it or write your own conversion function.
> 0 votes

---
Tags: spi, lcd
---


# Question
Title: Writing to flash memory fails with Optiboot
I am having some issue writing to flash memory on Arduino Uno.

I burned the optiboot bootloader that ships with the IDE 1.8.3 to the chip, then uploaded the test\_dospm sketch to write content to flash memory but appears to reset the device instead.

Any idea why this might be happening?

# Answer
The bootloader which ships with Arduino IDE is version 4 which was already in the Uno from factory. To use the do\_spm function you need Optiboot 8 ~~build with this support enabled. It is not enabled in the default builds, because it doesn't fit in the usual Optiboot size for Uno~~.

The hex file of the bootloader is here. Simply replace the hex file in AVR boards package with this one.
> 0 votes

---
Tags: arduino-uno, arduino-ide, flash
---


title: How to calibrate Mpu6050 using library?

text:
# Question
Title: How to calibrate Mpu6050 using library?
I am using i2cdev library

Code:(i did not know this code is correct or not)

```
#include <Arduino.h>
#include <MPU6050.h>
#include <kalman.h>
#include <stdint.h>

#define ACCELLSB  2048
#define GYROLSB   16.4

#define CONSOLE
#define CALIBRATE

#ifdef  CALIBRATE
int16_t Accel_X_offset;
int16_t Accel_Y_offset;
int16_t Accel_Z_offset;

int16_t Gyro_X_offset;
int16_t Gyro_Y_offset;
int16_t Gyro_Z_offset;
#endif

MPU6050 mpu6050;

Kalman  AngleX;
Kalman  AngleY;

void setup()
{
   mpu6050.initialize();
   mpu6050.setFullScaleAccelRange(MPU6050_ACCEL_FS_16);
   mpu6050.setFullScaleGyroRange(MPU6050_GYRO_FS_2000);

   #ifdef CALIBRATE
   mpu6050.CalibrateAccel();
   mpu6050.CalibrateGyro();

   Accel_X_offset = mpu6050.getXAccelOffset();
   Accel_Y_offset = mpu6050.getYAccelOffset();
   Accel_Z_offset = mpu6050.getZAccelOffset();

   Gyro_X_offset  = mpu6050.getXGyroOffset();
   Gyro_Y_offset  = mpu6050.getYGyroOffset();
   Gyro_Z_offset  = mpu6050.getZGyroOffset();
   #endif

   int16_t AccelX, AccelY, AccelZ;
   int16_t GyroX, GyroY, GyroZ;

   mpu6050.getMotion6(&AccelX,&AccelY,&AccelZ,&GyroX,&GyroY,&GyroZ);

   // I am going to use this values in kalman filter
   #ifdef CALIBRATE
   AccelX -= Accel_X_offset;
   AccelY -= Accel_Y_offset;
   AccelZ -= Accel_Z_offset;

   GyroX  -= Gyro_X_offset;
   GyroY  -= Gyro_Y_offset;
   GyroZ  -= Gyro_Z_offset;
   #endif
}

void loop()
{

}

```

What is the correct way to calibrate mpu6050(Correct me what i am wrong or this is correct)?

Thanks.

# Answer
I personally suggest you `MPU6050_tockn` library.https://github.com/tockn/MPU6050\_tockn

If you use `calcGyroOffsets()` in `setup()`, it will calculate calibration of the gyroscope, and the value of the gyroscope will calibrated.

```
#include <MPU6050_tockn>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup(){
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets();
}

```

If you use `calcGyroOffsets(true)` in `setup()`, you can see state of calculating calibration in serial monitor.

```
#include <MPU6050_tockn>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup(){
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
}

```

Serial monitor:

```
Calculate gyro offsets
DO NOT MOVE MPU6050.....
Done!
X : 1.45
Y : 1.23
Z : -1.32
Program will start after 3 seconds

```

If you know offsets of gyroscope, you can set them by `setGyroOffsets()`, and you don't have to execute `calcGyroOffsets()`, so you can launch program quickly.

```
#include <MPU6050_tockn>
#include <Wire.h>

MPU6050 mpu6050(Wire);

void setup(){
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  mpu6050.setGyroOffsets(1.45, 1.23, -1.32);
}

```

But if want to do it with Kalman filter goto https://github.com/jarzebski/Arduino-KalmanFilter/blob/master/KalmanFilter\_MPU6050/KalmanFilter\_MPU6050.ino It will guide you.
> 0 votes

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


# Question
Title: How can I identify GPS sattelites in TinyGPS++?
I can see about 15 satellites (about 10 GPS + 5 Glonass) in u-center, but I see only about 10 satellites using TinyGPS++. I suspect that TinyGPS++ can see GPS only. I see lines containing $GNRMC $GNVTG $GNGGA $GPGSV $GNGLL $GNVTG $GLGSV in the input, so there are information from both constellation. But how can I check which constellations TinyGPS++ takes into account for the output:

> Sats=10 Nums=1 3 8 10 11 14 20 22 24 27 28 31 32 36 40 Elevation=46 17 45 31 69 59 1 43 5 24 9 1 60 36 32 Azimuth=304 255 215 66 267 137 77 263 28 184 316 140 89 181 150 SNR=12 0 0 17 8 20 0 11 0 11 0 0 21 0 0

# Answer
There is a bug in TinyGPS++ as it only counts GPS satellites. See https://github.com/mikalhart/TinyGPSPlus/issues/52

PRN numbers are used to identify satellites:

> GPS = 1 to 32
>
> SBAS = 33 to 64 (add 87 for PRN number)
>
> GLO = 65 to 96
> 1 votes

---
Tags: gps, tinygps
---


title: Vary the Speed of Motor

text:
# Question
Title: Vary the Speed of Motor
I am trying to control the speed of motor through VFD using 4-20mA signal.

I generate the 4-20mA signal using Arduino.I use low pas filter to obtain the voltages from Arduino PWM pins as shown in the circuit.

Their is continuous deviation at the output.But the deviation is very small.

Example: when Input is 1V(from 20% PWM in Arduino Code)--\> Then output continuous to vary between 3mA to 4mA.

when Input is 5V(from 100% PWM in Arduino Code)--\> Then output continuous to vary between 19mA to 20mA

Can I implement this circuit practically with VFD?

Will this deviation create problem for VFD to control the speed?

Will this very fast continuous deviation is dangerous for

# Answer
The sawtooth pattern you're showing looks like what I would expect from incomplete filtering of the PWM signal from the Arduino.

I don't know if the variation is going to affect your motor controller or not.

I suggest using a different low pass filter with a much lower pass frequency. That will slow down the response to changes in speed slightly, but produce smoother output. I'd suggest lowering the pass frequency of your filter by 10X or more.

(The good news is that you want to filter the hell out of your PWM signal. You want it to only pass like 10Hz or so. Using a very low cut-off frequency for your filter will get rid of that sawtooth. The result of that would be an output voltage that would be slower to respond, but that should be fine. If your motor takes 1/10th of a second to adjust speeds, is that a problem in your application?)
> 1 votes

---
Tags: motor, arduino-motor-shield, digital-analog-conversion
---


# Question
Title: Issues with reading numbers from serial port
I've built 2 motor drivers for a robotics project and need to set positions that I want the motors to move to, and read that using the arduino. The arduino then uses a rotary encoder to implement a closed loop PID controller and move the motor the set point. My code wasn't working so I started troubleshooting and found out that my setpoint was getting reset to 0 automatically!

The only thin that changes the setpoint was the serial read so I made a smaller sketch for troubleshooting which is this:

```
volatile long setpoint;

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

void loop() {
  if (Serial.available()){
    setpoint = Serial.parseInt();
    Serial.print("Set to: ");
    Serial.println(setpoint);
  }
}

```

The result was quite odd, it sets the value correctly but resets back to 0 without me sending any new commands!

I tried updating the IDE to 1.8.12, tried old and new arduinos (with old and new bootloader) but all had the same result. Here is a demo video showing the weird reset to 0 problem:

https://streamable.com/kfgv61

I tried changing the buadrate higher or lower but that also didn't fix anything. Any ideas on what I'm doing wrong?

# Answer
> 1 votes
The problem here is that `Serial.parseInt()` stops when it sees the newline, but *it does not consume that newline*, which is left in the input buffer. Thus, at the next loop iteration, `Serial.available()` returns true because of this newline and, unless you send another value fast enough, `Serial.parseInt()` times out and returns zero.

The easy fix is to consume that newline yourself:

```
void loop() {
  if (Serial.available()){
    setpoint = Serial.parseInt();
    if (Serial.peek() == '\n') Serial.read();  // consume LF
    Serial.print("Set to: ");
    Serial.println(setpoint);
  }
}

```

I personally would not use `Serial.parseInt()` at all, and would buffer the data myself until I see the `'\n'`. This way there are no surprises with timeouts being read as zero.

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


# Question
Title: Running a motor for a 3 seconds continuously with and without interrupt
I have interfaced a dc motor and IR sensor to my nano. The DC motor is supposed to run only if the IR sensor detects an obstacle. Now, I'm trying to get the motor to turn off if continuously obstructed for 3 seconds, and exit the interrupt (in case of the first code with interrupt), and again wait for the sensor to go low again (falling edge). I have implemented this using millis(), but the code doesnt seem to be working consistently, as the timing seems to have gone for a toss (random behavior; sometimes it keeps running continuously and sometimes it stops) . Can anyone on this forum please review it and suggest me a correction. Also, would it be possible to use a LOW trigger instead of falling edge to achieve this ?

```
#include <LowPower.h>

const int out1 = 5; //motor
const int IRSensor = 3; // connect ir sensor to arduino pin 6
const int LED = 6; // conect Led to arduino pin 9
const int Switch = 2;
const int Mspeed = 175;//0-255
const int Mtime =1500;//500-1000
int statusSensor=1;
int switchSensor=1;
unsigned long prevTime;
volatile int count =0;
volatile int count1=0;
volatile int count2 =0;
volatile int count3=0;
volatile int buttonstate=0;
volatile int lastbuttonstate=0;
volatile bool flag=false;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(out1,OUTPUT);
  //pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(IRSensor),IRinterrupt,FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  LowPower.powerDown(SLEEP_FOREVER , ADC_OFF, BOD_OFF);
  delay (100);
  if (flag==true){
  //Serial.println("true");
  switchSensor = digitalRead (Switch);
  //Serial.println ("zloop");

  statusSensor = digitalRead (IRSensor);
  //Serial.println (statusSensor);
  if (count1==1)
  { prevTime = millis();
    Serial.println(prevTime);
  }
  if (millis() - prevTime >= 1000)
  { doSomethingElse();
    Serial.println("going to else");
  }
  }
  //prevState = digitalRead(IRSensor);
  doSomething();

}

void IRinterrupt(){

   flag=true;
  }

void doSomething(){
  buttonstatus();
  if (statusSensor == 0 and switchSensor == 0 and count3==0){

     analogWrite(out1,Mspeed);
     //digitalWrite(out1,HIGH);
     count1=count++;
     Serial.println(count);
     digitalWrite(LED, LOW);
  }
   else if (statusSensor == 0 and switchSensor == 1) {

      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      }
   else if (statusSensor == 1 and switchSensor == 0) {

      //digitalWrite(out1,LOW);
      digitalWrite(LED, LOW);
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      }
    else {
      //Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      buttonstatus();
      }
}
void doSomethingElse(){

      //Serial.println ("ir high else");
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      count2++;
      count3=count2;

      //analogWrite(out1,0);
  }

void buttonstatus(){
  buttonstate=digitalRead (IRSensor);
   if (buttonstate != lastbuttonstate) {
    // if the state has changed,
    if (buttonstate == LOW) {
      count3=0;
    }
    delay(50);
   }
   lastbuttonstate = buttonstate;
}

```

I have written another piece of code without interrupts. How do I achieve the same timing part for this too ?

```
int out1 = 5; //motor
int IRSensor = 3; // connect ir sensor to arduino pin 6
int LED = 6; // conect Led to arduino pin 9
int Switch = 2;
int statusSensor=1;
int switchSensor=1;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(out1,OUTPUT);
  //pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  switchSensor = digitalRead (Switch);
  //Serial.println (switchSensor);

  statusSensor = digitalRead (IRSensor);
  //Serial.println (statusSensor);
  delayStart = millis();
  //Serial.println ("ir interupt");

   if (statusSensor == 0 and switchSensor == 0){
     Serial.println ("ir low");
     analogWrite(out1,120);
     digitalWrite(LED, LOW);
   }
      else {
      Serial.println ("ir high");
      analogWrite(out1,0);

      }

}

```

EDIT: I have now successfully implemented the code (without interupts) with timing part in the code below.Also, I have updated the first code in the post with interrupts, but I am not able to get the timing part working. Can, someone please help me how timing can now be done with interrupts, so that the arduino nano is in sleep, until it receives a falling edge on the interrupt pin from the IR sensor, so that it can process the next part. Doing so I believe I would save power consumed since its on all the time.

```
const int out1 = 5; //motor
const int IRSensor = 3; // connect ir sensor to arduino pin 6
const int LED = 6; // conect Led to arduino pin 9
const int Switch = 2;
const int Mspeed = 175;//0-255
const int Mtime =1500;//500-1000
int statusSensor=1;
int switchSensor=1;
unsigned long prevTime;
volatile int count =0;
volatile int count1=0;
volatile int count2 =0;
volatile int count3=0;
volatile int buttonstate=0;
volatile int lastbuttonstate=0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(100);
  switchSensor = digitalRead (Switch);
  statusSensor = digitalRead (IRSensor);
  if (count1==1)
  { prevTime = millis();
    Serial.println(prevTime);
  }
  if (millis() - prevTime >= Mtime)
  { doSomethingElse();
    //Serial.println("going to else");
  }
  doSomething();

}

void doSomething(){
  buttonstatus();
  if (statusSensor == 0 and switchSensor == 0 and count3==0){

     analogWrite(out1,Mspeed);
     //digitalWrite(out1,HIGH);
     count1=count++;
     Serial.println(count);
     digitalWrite(LED, LOW);
  }
   else if (statusSensor == 0 and switchSensor == 1) {

      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      }
   else if (statusSensor == 1 and switchSensor == 0) {

      //digitalWrite(out1,LOW);
      digitalWrite(LED, LOW);
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      }
    else {
      //Serial.println ("ir high");
      //digitalWrite(out1,LOW);
      digitalWrite(LED, HIGH);
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      buttonstatus();
      }
}
void doSomethingElse(){

      //Serial.println ("ir high else");
      analogWrite(out1,0);
      count=0;
      count1=0;
      prevTime = millis();
      count2++;
      count3=count2;

      //analogWrite(out1,0);
  }

void buttonstatus(){
  buttonstate=digitalRead (IRSensor);
   if (buttonstate != lastbuttonstate) {
    // if the state has changed,
    if (buttonstate == LOW) {
      count3=0;
    }
    delay(50);
   }
   lastbuttonstate = buttonstate;
}

```

# Answer
I often use a timer loop to read sensors. I've attached some code, which compiles, however I don't have the sensor.

BTW. I am assuming it is a single shot IR sensor that returns 0 if something is detected.

```
int out1 = 5; //motor
int IRSensor = 3; // connect ir sensor to arduino pin 6
int LED = 6; // conect Led to arduino pin 9
int Switch = 2;
int statusSensor=1;
int switchSensor=1;

unsigned long IRMillis;
int IRInterval = 100;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(out1,OUTPUT);
  //pinMode(out1,OUTPUT);
  pinMode (IRSensor, INPUT); // sensor pin INPUT
  pinMode (LED, OUTPUT); // Led pin OUTPUT
  pinMode(Switch, INPUT_PULLUP);
  IRMillis = millis();
}

void loop() {

   updateIR();

   switchSensor = digitalRead (Switch);

   if ((statusSensor == 0) && (switchSensor == 0)) {
     IRInterval = 3000; // 3 seconds
     statusSensor = 1;
     Serial.println ("ir low");
     analogWrite(out1,120);
     digitalWrite(LED, LOW);
   } else {
     Serial.println ("ir high");
     analogWrite(out1,0);
   }
}

void updateIR() {
  if (millis() - IRMillis > IRInterval) {
    //continue
  } else {
    return;
  }
  IRMillis = millis();
  IRInterval = 100;
  statusSensor = digitalRead (IRSensor);
}

```
> 0 votes

# Answer
Your interrupt code looks reasonable, except that once you set flag to true you never set it back to false again. You need a way to identify the the IR sensor is no longer active.

Perhaps change your interrupt to fire on a change of state and set the flag to true when it switches to LOW (like it does no) and false when it switches back to high? I'd need to know more about your IR sensor to tell you exactly what to do, but I can tell you that the way your coe is currently written, once you detect the first falling edge on the IRSensor pin, your flag will switch to true and never change back to false.

I also don't understand what all the if/else if/else if logic is supposed to do, so can't really tell if you have any coding errors there.
> 0 votes

---
Tags: arduino-nano, motor, interrupt, timers, ir
---


title: How do I use a SMD crystal with 4 pins?

text:
# Question
Title: How do I use a SMD crystal with 4 pins?
I am running my arduino project with the atmega328 chip like this:

I have purchased by mistake this crystal:

The reason why I purchased by mistake that crystal was because it has this description:

> 16MHz ±10ppm 22pF 60Ω SMD-3225 SMD Crystal Resonators RoHS

I thought that it contained the 22pF ceramic capacitors inside. But latter I learned that I still the 22pf ceramic capacitors. (Please correct me if I am wrong)

**Anyways how can I use that crystal?** I only know how to connect the 2 pin crystal. Since this crystal has 4 pins now I am confused.

To me it makes sense to connect it like this:

1. Connect pins 9 and 10 from atmega --TO--\> pins 1 and 3 from the crystal.
2. Connect pins 2 and 4 from crystal --TO--\> Ground
3. Connect the 22pf ceramic capacitors to pins 1 and 3 from crystal and ground like in the first diagram.

# Answer
this is a nice question. Once for a project I stumbled upon this problem too.

The way you described the connection should work perfectly fine.

> To me it makes sense to connect it like this: Connect pins 9 and 10 from atmega --TO--\> pins 1 and 3 from the crystal. Connect pins 2 and 4 from crystal --TO--\> Ground Connect the 22pf ceramic capacitors to pins 1 and 3 from crystal and ground like in the first diagram.

Keep it going and greetings from Switzerland.
> 1 votes

---
Tags: atmega328
---


# Question
Title: Placing decoupling capacitors when building an Arduino PCB with Atmega328-PU
I have previously asked this question:

Custom build of arduino on a pcb

And thanks to the answer by Majenco I have learned that my circuit works a lot better when adding a capacitor. For example I am using the NRF24L01 and it is much more stable when using a capacitor. I am placing the capacitor for now next to the power supply like this:

Right now I am running this on a breadboard. The Atmega328 chip is very cheap compared to the arduino uno board; therefore, I will like to continue building my projects based on the atmega328P-PU chip.

Anyways before printing the PCB based on the Atmega328P-PU chip, where should I place the capacitors in order to reduce the most noise? **The capacitors are very cheap and making one good design will enable me for all my future designs to be based from this one.**

From researching on the internet I see a lot of different examples. Everyone uses different capacitance sizes. For example I have found this:

I got that from this link: https://www.autodesk.com/products/eagle/blog/what-are-decoupling-capacitors/

On other places they say to place the capacitance closest to the pins such as from this video. **If that is true should I just place one capacitor on pins 7 and 8. Lastly the other capacitor on pins 20 and 22?**

I do not mind soldering extra pins knowing my circuit will have the best performance.

# Answer
The Autodesk link explains it very well.

You should place small/fast decoupling capacitors (0.1uF) close to the power pins of your on-board ICs to deal with local spikes in power consumption of those devices.

Place a larger/slower decoupling capacitor (1uF or larger, depending on many factors such as distance of the power supply from the board and expected power consumption) somewhere on the board to deal with varying loads and ripples in your power supply.

This has been common practice at least since I’ve started with electronics about 40 years ago (and probably much longer).
> 2 votes

---
Tags: atmega328, capacitors
---


# Question
Title: Trying to draw a bitmap to an LED matrix only draws the left half
I'm EXTREMELY new to Arduino and fairly new to programming as a whole, but I thought it would be fun to try and write a program that draws arbitrary 1-bit bitmaps to an LED matrix using the Adafruit RGBMatrixPanel library. I'm trying to draw this image to the screen:

But it conks out after 16 pixels each row...

Below is my code in full. It seems like the bit mask only works for the first 16 columns, but I can't seem to figure out why it stops at that point. I'm using an Arduino Nano, if that helps.

```
#define CLK  8
#define OE   9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2

RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
unsigned long int pixelGrid[] = {
  0x00000000,
  0x31CEFDCE,
  0x78CCFCCC,
  0x78CC84CC,
  0x78CC04CC,
  0x78CC04CC,
  0x78CC24CC,
  0x78783CFC,
  0x783024FC,
  0x303004CC,
  0x303004CC,
  0x303004CC,
  0x003084CC,
  0x3030FCCC,
  0x3078FDCE,
  0x00000000
};
unsigned long int bitMask = 0x00000001;
void setup() {
  matrix.begin();
  uint8_t r=0, g=0, b=0;

  for(uint8_t y=0; y<16; y++) {
    unsigned long data = pixelGrid[y]; // select row of bits from image
      for (byte x = 0; x <32; x++) { //iterate through columns
        if (data & (bitMask << x)) {// works!
          r = 1; // set LED to ON
        }
        else {
          r = 0; // LED is OFF
        }
      matrix.drawPixel(x, y, matrix.Color333(r, g, b));
    }
  }
}

void loop() {
}

```

Here's the part of the code that's probably messing up, isolated:

```
for (byte x = 0; x <32; x++) {
        if (data & (1 << x)) {
          r = 1;
        }
        else {
          r = 0;
        }

```

Thanks for your help!

Edit: Changing the `data` variable from `int` to `long` to avoid it being truncated lead adds another column of pixels, but it kind of looks like they're all squished into column 16 for some reason:

Note: I tried drawing a rectangle from (0,0) to (31, 15) to make sure that all the LEDs worked, and I was able to do that.

Edit 2: Instead of the bitmask being `1`, I made it so that:

```
unsigned long int bitMask = 0x00000001;
// ...
 if (data & (bitMask << x)) { // works!
          r = 1; // set LED to ON
        }
        else {
          r = 0; // LED is OFF
        }

```

I'm guessing regular numbers default to 16-bit unsigned ints. The issue is fixed, woo! I edited the big code block to match.

# Answer
> 0 votes
'pixelGrid\[\]' are longs but your temp inside the for() loop, 'data', is an int. Thus, it gets only half the data. Easy mistake to make (and they can be so hard to spot when you know perfectly well what you meant... :)

Update:

> By switching the int to long, I've successfully unlocked a seventeenth column! Unfortunately, it looks like all the pixels are bunched up in that seventeenth column.

Another error of the same kind (I missed it the first time around): Change `(1 << x)` to `(1L << x)`. The original expression is calculated as int and the result is widened in the assignment to 'data' (and I think there was compiler bug int the code that did that, besides). The corrected expression is calculated as a long in the first place, which is what I think you intended.

Update 2:

From your question Edit 2:

> I'm guessing regular numbers default to 16-bit unsigned ints.

You are correct - ints of unspecified size default to 16-bits in the Arduino gcc compiler used by the Arduino IDE (and just about everywhere else in the Arduino domain that I know of). The language standard leaves the compiler writer free to choose the size of an int that best fits the target-machine's architecture. 16-bits is the most common, but by no means the only - size implemented in most compilers. For this reason, most compilers' pre-processors implement specific-sized data types, and application writers - you & I - are advised to use these wherever data-size matters. For the Arduino's gcc compiler, there are predefined types such as `int8_t` (signed 8-bit int), `uint32_t` (unsigned long int), etc. `int` is an ok "I don't care, just as long as it works" option. When you do care - specify.

(If my answer helped you, please upvote it or select as best answer. The latter has the important function on this site of marking the question as "completed" so it doesn't keep re-appearing as an unanswered question.)

---
Tags: arduino-nano, adafruit, rgb-led
---


title: USB disconnects when using a capacitor

text:
# Question
Title: USB disconnects when using a capacitor
I'm currently working with some WS2812B LEDs and tried out adding a capacitor to be safe from voltage spikes (was recommended by Adafruit). I noticed that a soon as I connect a capacitor between 5V and ground that the USB is disconnect from the PC (Windows Usb disconnect sound plays). I wondered why and tried another setup. This time just the capacitor between 5V and ground. Nothing else. According to my knownledge this isn't a short (capacitor is intact) and therefor this setup should be valid. Again the same thing happens: USB disconnects...

I really don't know why this happens but want to understand it. The capacitor I use is rated 16V 1000 mF (electrolytic in case this is relevant). The capacitor is also connected the right polarity. What forces the USB to disconnect (and let Windows play the USB disconnect sound). Am I may damaging the USB Port somehow and therefor a disconnect is forced as a security measurement?

Oh yeah... Using an Arduino Uno R3 made by Elegoo.

Hope you can help me out, Tmirror

# Answer
The USB specifications allow a maximum of 10uF total capacitance on the USB power lines. By putting 1000uF you have given it 100x more than is allowed.

This causes a massive inrush current and the USB host (your computer) sees it as a short circuit, so it shuts off the power in a panic to protect itself.

A capacitor does have a role to play in helping to remove power supply noise caused by power-hungry and noisy devices like WS2812B LEDs, but just slapping it across the power supply pins isn't going to really help.

Instead you should increase the impedance of the power supply to the noisy device(s) and use a capacitor to reduce the impedance again. This will help to preferentially draw current from the capacitor to supply the LEDs while smoothing out the draw from the main supply over time.

A simple circuit is to use a resistor with a capacitor:

simulate this circuit – Schematic created using CircuitLab

The values I show there for the resistor and capacitor are pretty random. The smaller the resistor the more demand will be put on the power supply. The bigger the resistor the more demand will be put on the capacitor. If the resistor is too big the capacitor won't be able to store enough power to run the LEDs, and too much voltage will be dropped across it. If the capacitor is too small it won't be able to store enough power to run the LEDs. Tuning those values depends very much on the amount of noise there is and the current draw of the LEDs.

You must also make sure the resistor can handle the amount of power dissipated by the current flowing through it.
> 1 votes

---
Tags: arduino-uno, usb, capacitors
---


# Question
Title: How to run atmega328p at 8, 4 and 1 mhz?
Instead of using the regular Arduino board I have purchased the atmega328p-pu along with this components:

1. 22pf ceramic capacitor
2. 10K resistor
3. 16mhz crystal
4. 47uF capacitor
5. 3.3 Volts Power supply

The diagram looks like this:

Because the atmega328p chip that I purchased already comes loaded with arduino bootloader I can program this chip right away! This video explains in more detail how to upload the code to the chip. It is very simple.

**The reason why I run my atmega328p chip with a 3.3V power supply is because of these reasons:**

1. I have multiple sensors like the NRF24L01 that cannot take 5 volts.
2. I run this project of a 3.3 battery as well in order to save power.
3. I do not want to use voltage regulators as they are inefficient and they will waste my battery.
4. Everything works great.

Even though everything works great if I am running atmega328P at 16mhz @ 3.3V I am not following the specifications. **In order to do things correct I will like to run my code at 8mhz so that I am in within the specs**

## Question

What is the correct way of running this project at 8mhz? If I change the 16mhz crystal for a 8mhz it runs at 8mhz but everything is half the speed. I have to divide all time related functions by 2. Moreover, I cannot upload new code if it has a 8mhz crystal. In order to upload new code I have to place the 16mhz crystal upload the code and then change the crystal again.

Can I still use my 16mhz crystal and run at 8mhz so that I do not have to keep replacing the crystal? I want my `millis` function and other time dependent functions to have the correct time. I do not want to have to divide everything by 2.

Do I have to burn a different bootloader for this to work? Where can I find a tutorial that can explain me all this?

**There are tutorials on how to use the internal 8mhz crystal from the atmega328 chip but still want to use an external crystal as it is much more accurate**

## Edit

I just found this link that explains how to do it. Edgar Bonet answer seems a lot simpler so I will stick to that.

# Answer
> 2 votes
If you run your MCU at 8 MHz, everything will run at this frequency: not only the CPU core but also the timers, including Timer 0 which is used for `millis()`, `delay()`, etc. So you will have to use a modified version of the Arduino timing functions in order to cope with this clock frequency.

Fortunately, such version already exists. Actually, it is even supported by the standard Arduino core, since it supports the 3.3 V version of the Arduino Pro Mini, which uses an ATmega328P clocked at 8 MHz.

I thus suggest you install an 8 MHz crystal, burn in the bootloader for the 3.3 V Pro Mini, and tell your IDE that you are using that board. In the Tools menu:

* set board to "Arduino Pro or Pro Mini"
* set processor to ""ATmega328P (3.3V, 8 MHz)"

---
Tags: atmega328, frequency
---


# Question
Title: Arduino Uno CTC mode interrupt is not tiggering
I am trying to generate LED blink after 4 second using Interrupt but Interrupt is not triggering not even once . Request: if you have arduino uno r3 please check at your end and let me know result. I have read Timer counter section multiple times and applied everything i can for example :-

* Enabled Global Interrupt
* Select CTC Mode
* Enable Interrupt for OCIE0A
* Prescaling to clk/1024
* Initializing OCR0A
* When OCR0A equal TCNT0 ,interrupt will generate

```
int var;
void setup() {
  // put your setup code here, to run once:
    SREG = SREG | (1<<7);          // Gloval interrupt enable
    TCCR0A = TCCR0A | (1<<WGM01); // Clear counter on compare match mode
    OCR0A = 255; // when TCNT equal OCR0 interrupt will generate
    TIMSK0 = TIMSK0 | (1<<OCIE0A); //  Output Compare Match A Interrupt Enable
    TCCR0B = TCCR0B | (1<<CS01) | (1<<CS02);  // Prescaling by 1024
    DDRB = DDRB | (1<<5);
    Serial.begin(9600);      // Testing
    Serial.println("Start");   // Testing
}

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

}

ISR(TIMER0_COMPA_vect){
    var++;
    Serial.print(var); // Testing
    volatile long unsigned i;
    if(var == 246){
        PORTB = PORTB | (1<<5);
        for(i=0; i<30000; i++);
        PORTB = PORTB & ~(1<<5);
        for(i=0; i<30000; i++);
        var=0;
    }
}

```
* clock is 16 00 00 00 Hz
* Prescaling by 1024 = 15625
* 1 Tick = 1/15625 = 0.00 00 64 sec
* OCR0 is initialized by 255
* TCNT0 Ticks to 255
* Total time taken to generate one interrupt = 255 * 0.00 00 64 = 0.01632 sec that means after every 0.01632 sec Interrupt supposed to generate
* How many interrupt is required to generate LED after 4 sec =\> 4/0.01632 = 246

Update working code

```
int var;
void setup() {
  // put your setup code here, to run once:
  SREG = SREG | (1<<7);          // Gloval interrupt enable
  TCCR0A =(1<<WGM01); // Clear counter on compare match mode
  OCR0A = 255; // when TCNT equal OCR0 interrupt will generate
  TIMSK0 = (1<<OCIE0A); //  Output Compare Match A Interrupt Enable
  TCCR0B = (1<<CS00) | (1<<CS02);  // Prescaling by 1024

  DDRB = DDRB | (1<<5);

    Serial.begin(9600);      // Initialize the USART
    Serial.println("Start");   // Write the welcome message

}

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

}

ISR(TIMER0_COMPA_vect){
  var++;
 // Serial.print(var);
  volatile long unsigned i;
  if(var == 246){
        PORTB = PORTB | (1<<5);
        for(i=0; i<300000; i++);
        PORTB = PORTB & ~(1<<5);
        var=0;
  }
}

```

# Answer
There are a few issues with your code:

First, you should completely overwrite the timer control registers rather than changing single bits. For example, when you write

```
TCCR0A = TCCR0A | (1<<WGM01); // Clear counter on compare match mode

```

You end up with a timer mode that results from the combination of the bits that were already set there and the ones you are setting. Judging from the comment, you assume that this will be CTC mode, but this is not granted, because the Arduino initialization routine has already set some bits in this register. Since you are taking the timer for your own usage, just overwrite all the control registers:

```
TCCR0A = (1<<WGM01); // Clear counter on compare match mode

```

and same for `TCCR0B` and `TIMSK0`.

The second problem is that you misread the “Clock Select Bit Description” table from the datasheet. Your timer is being clocked from an external clock source on T0 pin. Presumably you have nothing connected there, so the timer does not increment. You probably meant

```
TCCR0B = (1<<CS00) | (1<<CS02);  // Prescaling by 1024

```

A smaller issue is your delay loop. The program would be easier to understand if you instead use a proper delay function. The Arduino `delay()` will not work, as you have reconfigured Timer 0, but you can use `_delay_ms()` from the avr-libc if you `#include <util/delay.h>`.
> 0 votes

---
Tags: arduino-uno, arduino-mega, arduino-ide
---


title: Arduino UARTS Auto addressing slaves

text:
# Question
Title: Arduino UARTS Auto addressing slaves
i'm using this serial topology to connect my Act ATmega328p (Arduino) slaves together to a master ESP32.

They are in total 10 ATmega328p slaves and one master:

With this type of wiring i'm sure that only one slave per time will talk back to master (when requested), now here comes the problem, basically i need dynamic addressing of slaves: they can be many (up to 30) and i need to access in order the slave devices.

In order to solve the "dynamic addressing" problem i'm thinking about that:

The first slaves will be plugged in and will send to the master his default address (i.e.: 0xFF) The master will check if the address is used and then reply back to the device with the first available address (i.e.: 0x01) The slave will get back the response from the master and set an internal variable with the new address (maybe it's a good idea to store the variable in a EEPROM like M24C02: enter link description here) Starting from the next cpu cycle, the master will ask sequentially to all enumerated slaves to (for example) do an analog read using this workflow:

The master will send a message to the serial bus with address 0x01 asking to do an analog read The respective slave will handle the request, read the analog input and then reply back to the master I think that this can work, but i've not found any kind of this implementation...maybe i'm totally out of mind?

**New idea and concept**

Guys, what do you think about sequentially power up the circuits and using the same mechanism to assign dynamically the address?

This assumption will avoid me to save the assigned id to the eeprom and some other id software function defined functionalities like address reset, etc...

It can be a good (and dynamic) method to solve the problem, about that, how I can implement this sequential power up?

# Answer
> 5 votes
> The first slaves will be plugged in and will send to the master his default address

If this happens while the master is talking to one of the other slaves, you risk a collision.

I suggest a very small variation on your scheme. Each slave has a default address (0xff). When you turn it on, it doesn't say anything. The slaves only talk when they are addressed.

Every now and then, the master sends a “ping” message to 0xff. The newly installed slave responds, then the master gives it a real address, and goes back to its business of collecting sensor data. If no response is received for the ping within some specified timeout, the master assumes there is no unconfigured slave.

Since no slave ever sends unsolicited messages, this should avoid any kind of collision. You just have to make sure that new slaves are added at a slow rate: after connecting a slave, you wait for slightly more than the ping period before connecting another one.

---
Tags: arduino-uno, serial, atmega328, uart
---


title: the use of the Arduino's EEPROM

text:
# Question
Title: the use of the Arduino's EEPROM
I want to know the purpose of using the EEPROM because I can't get it, I mean I know that it can store values for a long time, but I just can't get the goal here

```
#include<EEPROM.h>
void setup()
{
  Serial.begin(9600);
  EEPROM.write(0,4);
  int s=EEPROM.read(0);
  int f=10;
  Serial.print(s);
  Serial.print(" ");
  Serial.print(10);
}

void loop()  {}

```

For example, I'm using EEPROM to see the difference if I print a value inside variable `s` to the serial moniter using EEPROM and a normal value inside the variable `f`. But I couldn't find the difference between both because when unplugging the power and turn it on again, both of them are printed. Hope you got the idea and I hope to see some feedback. Thank you..

**the LED program**

then I made this program that will compare the EEPROM value to num.4 and compares the F variable to num.4 known that both F and the EEPROM values are 4. and then I changed both of the values to 3. shouldn't the GREEN LED of the EEPROM still on because it has already stored num.4??

```
#include<EEPROM.h>
void setup()
{
  pinMode(12,OUTPUT);
  pinMode(11,OUTPUT);
}

void loop()
{

  EEPROM.write(0,4);                 //GREEN LED
  int f=4;                           //RED LED

  if(EEPROM.read(0)==4) digitalWrite(12,HIGH);
  if(f==4) digitalWrite(11,HIGH);
}

```

# Answer
In short: Once you shutdown an Arduino, every variables on it, which have been calculated by the sketch, are lost. That is because they are stored in RAM, which is not able to store things without power. That is not the problem of EEPROM: values stored there will be available on reboot, and won't need to be calculated again.

This can prove useful is your device is allowing a user to store *presets*: so a configuration of the program. If this configuration, which can be for instance variables affecting the program behavior, is stored in RAM, it will be lost on next reboot. On the other hand, a value stored in EEPROM during the first execution (entered by user for instance) will still be available on next reboot, if you took the time to write it (on the first run) and to read it (on the second run). Just like *saving* and then *recalling* a preset.

Beware that EEPROM does not like to be written too many times and wear out, so you should keep that to a minimum (values that really need to be restored on reboot, and cannot be calculated at this time).
> 1 votes

# Answer
"It can store values for a long time" - that's not exactly what an eeprom does, the major property is that the information in the eeprom **persists during power cycles and chip resets**. In contrast, a RAM looses all information when you unpower the chip.

To get a feeling for eeproms, I suggest you follow the below routine:

**1.** Upload this sketch:

```
#include "EEPROM.h"

void setup() {
  EEPROM.write(0,4);
}

void loop(){}

```

**2.** Once this sketch has been executed, upload and run the below sketch (you could even unplug the arduino before this step):

```
#include "EEPROM.h"

void setup() {
  pinMode(12,OUTPUT);
  if(EEPROM.read(0)==4) digitalWrite(12,HIGH);
  EEPROM.write(0,3);
}

void loop(){}

```

**3.** Now, the green led will light up.

**4.** Reset the atmega and now the green led will remain off.

By just using a variable `int f` which is in RAM, you can not "transfer" a value between those sketches/runtimes.
> 0 votes

---
Tags: arduino-uno, serial, eeprom
---


title: EEPROM not consistent over reboot

text:
# Question
Title: EEPROM not consistent over reboot
I'am using a Wemos D1 mini V3.0.0 (esp 8266 core).

I tried to save a structure in EEPROM memory but all data are lost when i reboot the board.

I am using these basics functions :

```
int cle_verif = 519; //verification key

struct sauvegarde_data {
  int cle; //verification key
  int mode_ecl; //var
  int r; //var
  int v; //var
  int b; //var
};
sauvegarde_data customVar;

void sauvegardeEEPROM() {
  EEPROM.put(0, customVar);
  EEPROM.commit();
}

void chargeEEPROM() {
  // Lit la mémoire EEPROM
  EEPROM.get(0, customVar);
  Serial.println("");
  Serial.println("cle : "+String(customVar.cle));
  Serial.println("mode eclairage : "+String(customVar.mode_ecl));
  Serial.println("r : "+String(customVar.r));
  Serial.println("v : "+String(customVar.v));
  Serial.println("b : "+String(customVar.b));
  if(customVar.cle != cle_verif){ // check if the key is correct
    initialiserEEPROM();
  }
}

void initialiserEEPROM(){
  // Valeurs par défaut
  customVar.cle=cle_verif;
  customVar.mode_ecl=0;
  customVar.r=15;
  customVar.v=15;
  customVar.b=15;
  sauvegardeEEPROM();
}

```

and then, i ran the following code to initialize the EEPROM memory with default values :

```
EEPROM.begin(128);
initialiserEEPROM(); // initialisation
customVar.b=2; // change cached var value
chargeEEPROM(); // read EEPROM memory

```

the output is customVar.b=15 which is correct and it means it has been saved in EEPROM.

Any idea ?

Have a great day.

PS: i use four libraries which are FastLed, EEPROM, ESP8266WiFi, ESP8266WebServer. My goal is to save the LEDs color for a more pertinent reboot.

# Answer
It turns out i'm just really stupid. I spent something like 7 hours to make things work but i just selected the wrong card during the whole time.

Sorry for bothering you guys :-/
> 0 votes

---
Tags: esp8266, eeprom, memory
---


# Question
Title: Use ISRs inside a library more elegantly
At the moment I try to make a library which uses `attachInterrupt(?,?,RISING)` to read a sensor. The article of Nick Gammon on Calling an ISR from a class helped me a lot, but his "Glue routines" get pretty ugly with more than 30 potential Interrupt Pins on the ESP32, which all need their own `static void`. Has anyone got a more elegant idea how to do this "Gluing"?

# Answer
> 4 votes
As a matter of efficiency, I would favor chrisl’s advise to use the platform's low-level interrupts if at all possible. This, however, comes at the cost of portability: you would need an implementation specialized for each platform you want to support. If you don't want to or cannot maintain all this platform-specific code, `attachInterrupt()` may be a reasonable option.

Then, you will absolutely need all those glue routines: since the interrupt system calls your handlers with no parameters, you will not be able to share handlers between interrupts, and you end up with as many handlers as interrupts you are going to use.

There is, however, an elegant way of creating all these specialized functions without writing them explicitly: you can ask the compiler to write them for you on the basis of a *template* you provide.

Below is a version of Nick Gammon's example code modified to use a *template class*. Note that you do not necessarily need a class to use templates: you could use *template functions* as interrupt handlers if that is appropriate for your use case.

```
template <uint8_t pin>
class myClass
{
    static volatile bool switchChanged;

public:
    static void begin()
    {
        pinMode(pin, INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(pin),
                        switchPressed, FALLING);
    }

    static void switchPressed()
    {
        switchChanged = true;
    }
};

template <uint8_t pin>
volatile bool myClass<pin>::switchChanged;

myClass<2> foo;
myClass<3> bar;

void setup()
{
    foo.begin();
    bar.begin();
}

void loop(){}

```

Note also that `myClass<2>` and `myClass<3>` are two different classes: you actually have a different class for each pin. This means that `foo::switchChanged` and `bar::switchChanged` are two different class members even though both are `static`. Since you should (in principle) have at most one instance of each pin-specific class, you can make everything within the class `static`.

The main caveat of this method is that the pin numbers have now to be compile-time constants. The great advantage is that you will have a class created for each interrupt that is actually *used*: no need for an array of 32 instances on an ESP32 if only a handful of interrupt pins are going to be actually used.

---
Tags: c++, interrupt, library, class
---


# Question
Title: Interleave disassembly + source with avr-objdump
I have a C program for the attiny85, that I want to disassemble and display with interleaved source code.

Here's my program: test.c

```
#include <avr/io.h>
int main() {
    for(int i=0; i<100; i++) {
        PORTB=i;
    }
}

```

Here's how I compile it: `avr-gcc -g -O0 -mmcu=attiny85 -o test.elf test.c`

Finally, I generate the disassembly with interleaved source-code with the command: `avr-objdump -S -D test.elf`

The disassembly of the text section shows the following disassembly **without interleaved source code**:

```
00000030 <main>:
  30:   cf 93           push    r28
  32:   df 93           push    r29
  34:   00 d0           rcall   .+0             ; 0x36 <main+0x6>
  36:   cd b7           in      r28, 0x3d       ; 61
  38:   de b7           in      r29, 0x3e       ; 62
  3a:   1a 82           std     Y+2, r1 ; 0x02
  3c:   19 82           std     Y+1, r1 ; 0x01
  3e:   0a c0           rjmp    .+20            ; 0x54 <__SREG__+0x15>
  40:   88 e3           ldi     r24, 0x38       ; 56
  42:   90 e0           ldi     r25, 0x00       ; 0
  44:   29 81           ldd     r18, Y+1        ; 0x01
  46:   fc 01           movw    r30, r24
  48:   20 83           st      Z, r18
  4a:   89 81           ldd     r24, Y+1        ; 0x01
  4c:   9a 81           ldd     r25, Y+2        ; 0x02
  4e:   01 96           adiw    r24, 0x01       ; 1
  50:   9a 83           std     Y+2, r25        ; 0x02
  52:   89 83           std     Y+1, r24        ; 0x01
  54:   89 81           ldd     r24, Y+1        ; 0x01
  56:   9a 81           ldd     r25, Y+2        ; 0x02
  58:   84 36           cpi     r24, 0x64       ; 100
  5a:   91 05           cpc     r25, r1
  5c:   8c f3           brlt    .-30            ; 0x40 <__SREG__+0x1>
  5e:   80 e0           ldi     r24, 0x00       ; 0
  60:   90 e0           ldi     r25, 0x00       ; 0
  62:   0f 90           pop     r0
  64:   0f 90           pop     r0
  66:   df 91           pop     r29
  68:   cf 91           pop     r28
  6a:   08 95           ret

```

The disassembly makes somewhat sense, only that I miss the interleaved source code.

Interestingly enough, the output also includes a stab section, where I also find the main segment disassembled:

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

int main() {
  30:   20 00           .word   0x0020  ; ????
  32:   00 00           nop
  34:   80 00           .word   0x0080  ; ????
  36:   00 00           nop
  38:   00 00           nop
    for(int i=0; i<100; i++) {
  3a:   00 00           nop
  3c:   40 00           .word   0x0040  ; ????
  3e:   00 00           nop
        PORTB=i;
  40:   80 00           .word   0x0080  ; ????
  42:   00 00           nop
  44:   00 00           nop
  46:   00 00           nop
  48:   5a 00           .word   0x005a  ; ????
    for(int i=0; i<100; i++) {
  4a:   00 00           nop
  4c:   80 00           .word   0x0080  ; ????
  4e:   00 00           nop
  50:   00 00           nop
  52:   00 00           nop
  54:   91 00           .word   0x0091  ; ????
  56:   00 00           nop
  58:   80 00           .word   0x0080  ; ????
  5a:   00 00           nop
  5c:   00 00           nop
  5e:   00 00           nop
  60:   b7 00           .word   0x00b7  ; ????
    }

}

```

Now the output **includes source code, but the disassembly is wrong**.

How do I get an output were both is correct: the disassembled instructions and the interleaved source-code?

(avr-gcc (GCC) 9.3.0. Interleave Assembly and Source for avr-objdump does not seem to have the problem, although he's using the same compiler flags...)

# Answer
> 3 votes
The .stabs section contains debugging info, not actual code. There is no point in trying to “disassemble” it. The `-D` option of avr-objdump means “disassemble everything, whether or not you believe it's machine code”. Not what you want. For your purpose, `-S` should be enough.

I do not know why your `main()` is displayed without source code. I tried your exact same program with the exact same commands and I do see the source interleaved with the assembly. I am using avr-gcc 5.4.0 and avr-objdump 2.26.20160125 as shipped on Ubuntu Eoan.

---
Tags: avr-gcc, avr-toolchain
---


title: Program Arduino Uno as a digital clock

text:
# Question
Title: Program Arduino Uno as a digital clock
I have an arduino Uno board with a screen attached on top (http://www.freetronics.com.au/pages/16x2-lcd-shield-quickstart-guide#.VUf0tMWN0iT This is the screen).

I'm trying to get it so that the screen displays the time in hours, minutes and seconds and counts on a 24 hours loop. Like a digital clock. I have it so that it can count but it just counts up to 99 then repeats.

I have this code which counts milliseconds but I need minutes and hours

```
    #include <Wire.h>
    #include <LiquidCrystal.h>

    LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

    void setup()
{
    lcd.begin( 16, 2 );
}

    void loop()
{
    lcd.setCursor ( 0, 1);
    lcd.print(millis());
}

```

# Answer
Why not trying the timer interrupt from atmega328 uC. You'll also learn something usefully and I think is more interesting than using a library and some methods ( functions) without knowing how they are implemented.

It's really simple to make a digital clock just by interrupting every second. In ISR you'll just have to update the the values for seconds/minutes/hours. For displaying on the LCD, if you don't want to mess with LCD commands and bytes, you can use LiquidCrystal.

Example of code:(here I also used an analog pin for modifying time)

```
#define F_CPU   16000000UL
#include <avr/delay.h>
#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const short buttonPin = 5;
volatile unsigned char seconds;
volatile unsigned char minutes;
volatile unsigned char hours;
void update_clock()
{
    seconds++;
    if (seconds == 60)
    {
        seconds = 0;
        minutes++;
    }
    if(minutes==60)
    {
      minutes=0;
      hours++;
    }
    if(hours>23)
    {
      hours=0;
    }

}

ISR(TIMER1_COMPA_vect)
{

  update_clock();

}

void setup()
{

  // initialize Timer1
  pinMode(A5, INPUT_PULLUP);
  cli();          // disable global interrupts
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;     // same for TCCR1B

  // set compare match register to desired timer count:
  OCR1A = 15624;
  // turn on CTC mode:
  TCCR1B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR1B |= (1 << CS10);
  TCCR1B |= (1 << CS12);
  // enable timer compare interrupt:
  TIMSK1 |= (1 << OCIE1A);
  sei();          // enable global interrupts
  lcd.begin(16, 2);
  lcd.print("HH:MM:SS");
  Serial.begin(9600);

}

void display_on_lcd()
{

  lcd.setCursor(0, 1);
  lcd.print(hours);
  lcd.setCursor(2,1);
  lcd.print(":");
  lcd.setCursor(3,1);
  lcd.print(minutes);
  lcd.setCursor(5,1);
  lcd.print(":");
  lcd.setCursor(6,1);
  lcd.print(seconds);

}

void loop()
{

  display_on_lcd();

  Serial.println(analogRead(5));
  if(analogRead(buttonPin)<1000)
  {
    if(minutes==59)
    {
      minutes=0;
      if(hours==23)
        hours=0;
      else
        hours++;
    }
    else
    {
      minutes++;
    }
  }

}

```

Just search and you'll find a lot of examples.
> 1 votes

# Answer
Im with @arvid-jense on this one, if you are working on a serious Digital Clock, then you should get the Real Time Clock.

Now if you are learning Arduino and want to play with your LCD Minidisplay and build a clock, you must know some important limitations of the millis() function on this project:

* The mills function will overflow, after approximately 50 days.
* Your clock will be **inexact** because the cycles of the Arduino loop, you will be checking how much mills has passed on each loop. *(it will be lagging ~ 10 seconds each day, so on day 7 you will be one minute late)*
* the parameter for millis is an unsigned long, errors may be generated if a programmer tries to do math with other datatypes such as ints.

That being said

```
#include <Wire.h>
#include <LiquidCrystal.h>

/**
 * Clock Variables
 */
unsigned long currentMillis, previousMillis, elapsedMillis;
int seconds, minutes, hours;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{
    lcd.begin( 16, 2 );
}

void loop()
{
    setClock();
    /**
     * After set clock now you have 3 int variables with the current time
     */
     //seconds
     //minutes
     //hours
     lcd.setCursor ( 0, 1);
     lcd.print(millis());
}

void setClock()
{
    currentMillis = millis();
    elapsedMillis += currentMillis - previousMillis;

    /**
     * If we use equals 1000 its possible that because of the mentioned loop limitation
     * you check the difference when its value is (999) and on the next loop its value is (1001)
     */
    if (elapsedMillis > 999){
        seconds++;
        elapsedMillis = elapsedMillis - 1000;
    }

    if (seconds == 60){
        minutes++;
        seconds = 0;
    }
    if (minutes == 60){
        hours++;
        minutes = 0;
    }
    if (hours == 24){
        hours = 0;
    }

    previousMillis = currentMillis;
}

```

Nice tutorial on building an Alarm Clock
> 4 votes

# Answer
Others mention a Real-Time Clock (RTC), and it may look like the obvious choice, but maybe it isn't. All a RTC does is keep counters for hours, minutes, seconds, date and month, but your microcontroller can do that as well.
Unfortunately the Uno doesn't have a crystal, but a ceramic resonator, which isn't nearly as accurate. Not that it matters much, even a crystal-based RTC may deviate several seconds a day. You can measure the error over a long time, and correct at regular times in software, but this is tedious.

If you want long-time accuracy there are two cheap ways:

1. use an atomic clock receiver. In Europe there's DCF77, in North-America it's WWVB which broadcasts very accurate date and time information. A receiver module for these costs around 10 dollar
2. use the mains frequency to clock your clock. On the long term this is extremely accurate (just think about your alarm clock: how often do you have to adjust that?) In Europe you would count 100 half periods per second (120 in the US). When your counter reaches that count, reset it and increment the seconds. If seconds reaches 60, reset it and increment minutes. And so on. If you're not exactly electronics-savvy you can ask on electronics.stackexchange.com to help you out. It's not difficult.
> 2 votes

# Answer
Not sure what you're asking, but getting a Real Time Clock module will make your life a lot easier when dealing with time. Maybe post some sample code to show what your issue is.
> 1 votes

# Answer
Well you need to break this problem down.

If you are currently able to count in milliseconds, then you know 1000 milliseconds equal 1 second, so every time the milliseconds equals 1000, you reset it to 0 and increment the seconds by 1.

You keep going from here, if seconds equals 60, then you increase minutes by 1, and reset seconds to zero.. You get the picture.
> 1 votes

# Answer
Thanks everyone for your help! I've ended up with the code below which works quite well, there's the odd glitch with the seconds which is for some reason fixed if milliseconds is added on the end, but other than that it works very well.

```
#include <Wire.h>
#include <LiquidCrystal.h>

#define MILLIS_OVERFLOW 34359738

/**
* Clock Variables
*/
unsigned long currentMillis, previousMillis, elapsedMillis;
int seconds, minutes, hours;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{
  Serial.begin(9600);
  lcd.begin( 16, 2 );

}

void loop()
{
    setClock();
    /**
   * After set clock now you have 3 int variables with the current time
   */
   //seconds
   //minutes
   //hours
     lcd.setCursor ( 0, 1);
     lcd.print(hours);
     lcd.print(":");
     lcd.print(minutes);
     lcd.print(":");
     lcd.print(seconds);
     lcd.print(":");
     lcd.print(elapsedMillis);

}

void setClock()
{
    currentMillis = millis();
    /**
     * The only moment when currentMillis will be smaller than            previousMillis
     * will be when millis() oveflows
    */
    if (currentMillis < previousMillis){
    elapsedMillis += MILLIS_OVERFLOW - previousMillis + currentMillis;
} else {
    elapsedMillis += currentMillis - previousMillis;
}

/**
 * If we use equals 1000 its possible that because of the mentioned loop limitation
 * you check the difference when its value is (999) and on the next loop its value is (1001)
 */
if (elapsedMillis > 999){
    seconds++;
    elapsedMillis = elapsedMillis - 1000;
}

if (seconds == 60){
    minutes++;
    seconds = 0;
}
if (minutes == 60){
    hours++;
    minutes = 0;
}
if (hours == 24){
    hours = 0;
}

previousMillis = currentMillis;
}

```
> 1 votes

# Answer
The takeaway from the previous answers is that your best option is to use an RTC (real-time clock). Failing that, you can emulate the RTC using `millis()`, at the cost of a significant drift, especially if your Arduino is clocked off a ceramic resonator.

I would just like to add that you do not have to write the logic of that `millis()`-based “soft RTC” yourself, as this has already implemented in the `RTC_Millis` class from Adafruit's RTClib:

```
#include <RTClib.h>
#include <LiquidCrystal.h>

RTC_Millis rtc;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup() {
    rtc.begin(DateTime(F(__DATE__), F(__TIME__)));
    lcd.begin(16, 2);
}

void loop() {
    static DateTime last_time_printed;
    DateTime now = rtc.now();
    if (now != last_time_printed) {
        lcd.setCursor(0, 1);
        lcd.print(now.timestamp(DateTime::TIMESTAMP_TIME));
        last_time_printed = now;
    }
}

```

One nice thing about this option is that, if you later opt for a real RTC, you will only need to do minimal changes to your code. Another nice thing is that, if you measure the drift of your clock, you can easily correct it: just replace `RTC_Millis` with `RTC_Micros` and call `rtc.adjustDrift()` in `setup()`. You will be able to adjust the drift with a 1 ppm resolution. Note that both `RTC_Millis` and `RTC_Micros` are immune to rollover problems.
> 1 votes

---
Tags: arduino-uno, lcd
---


# Question
Title: Master Reader/Slave Sender with Distance Sensor
I am currently working on a project and want to transmit the information from a distance sensor from one arduino the another, but what i receive in the master board are not the correct measurements.

***Slave Code***

```
#include <Wire.h>

const int trig = 12;
const int echo = 13;

int state = 0;
int count = 0;
int contor = 0;
int set_distance = 5;
long duration, Distanceincm;

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);           // start serial for output
}

void loop()
{
 digitalWrite(trig, HIGH);
  delay(15);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  Distanceincm = (duration / 58);
  if (state == 0 && (Distanceincm < set_distance) ) {
    state = 1;
    count++;
    contor++;
    Serial.print("Distance=");
    Serial.println(Distanceincm);
    Serial.print("Count=");
    Serial.println(count);
    Serial.print("ConuntDay=");
    Serial.println(contor);
  }
  if (Distanceincm > set_distance) {
    state = 0;
  }
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);
  Wire.write(count);
  Wire.write(contor);
}

```

***Master Code***

```
#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start Serial for output
}

void loop()
{
  Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2
  while(Wire.available())    // slave may send less than requested
  {
    long a = Wire.read();
    Serial.print ("Distance = ");
    Serial.println(a);

    int b = Wire.read();
    Serial.print ("Count = ");
    Serial.println(b);

    int c = Wire.read();
    Serial.print ("CountDay = ");
    Serial.println(c);
  }

  delay(500);
}

```

What i get on the serial monitor is this :

# Answer
> 1 votes
Your code has some flaws, that I will address here:

* The main problem, that you see here, is that you only let the slave write data into the buffer, when it is receiving data. But you never send data to it. So there is never anything in the buffer.

In the slave code you have

```
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);
  Wire.write(count);
  Wire.write(contor);
}

```

Besides the unbalanced parentheses (which let's me think, that this might not be the actual code, that you are running currently), you are writing to the buffer only inside the `receiveEvent()`. That only get's called, when the master does a Master-Write transmission (via `Wire.beginTransmission()` and `Wire.endTransmission()`). In the master code you are only using `Wire.requestFrom()`. If you want to send back data on a request, you need to use the `onRequest` callback of the `Wire` library. You need to set the appropriate callback function:

```
Wire.onRequest(onRequestEvent);

```

And then write data inside that callback function:

```
void onRequestEvent(){
    Wire.write(...)
}

```

I will explain how to write the values correctly in a different point below.
* In the `receiveEvent()` function you want to loop through all received bytes but the last. But you are not doing anything with the data. You aren't even reading it. As your code currently stands, this line does not make any sense.
* In your master code you are requesting data from the slave with the address `2`. Your slave code initiates the `Wire` library with the address `4`. From that point there should never be a successful I2C transmission, unless you have another slave on the bus with the address `2` (another point, where I suspect, that these codes are not exactly the ones used for the test).
* In the master code you are using

```
while(Wire.available())

```

because the slave might have send less data, than requested. You are testing, that the number of available bytes is not zero. But then you are reading 3 bytes without checking again, which means, when you received 2 byte, you still would try to read 3 bytes, which cannot give good results.

The condition should be `Wire.available() >= 3`, to check, if at least 3 bytes are in the buffer, because you are reading 3 bytes from it. But also the loop does not make much sense to me. As you have a binary protocol here, how would you treat additional data (meaning excess data, send after the first valid data frame)? You want to receive 3 values per transmission and you are reading 3 values in one iteration of the loop. If there where more data in the buffer, you would be reading the next 3 bytes, throwing away the first 3 bytes. I don't think, that is what you want.

Instead use the return value of `Wire.requestFrom()`, which is the number of received bytes. Use it to distinguish valid transmissions, from those, which are too short:

```
uint8_t n = Wire.requestFrom(4, 3);
if(n >= 3){ // at least 3 bytes where received
    uint8_t value1 = Wire.read();
    uint8_t value2 = Wire.read();
    uint8_t value3 = Wire.read();
}

```

Any transmission, that is too small, will get ignored. Excess data in too long messages will also be ignored. Note, that I used `uint8_t`, which is an unsigned integer with 8 bits (1 byte) here for simplicity of that points logic. More about your data types and their implications on your code below.
* For the to send datatypes on the slave you have `int` and `long`. `int` is a signed integer with 16 bits, `long` is a signed long integer with 32 bits. (I suspect you don't need a `long` for the distance, as ultrasonic sensors mostly reach only 3m, but that is up to you). In contrast the argument of `Wire.write()` is an `uint8_t`, which has only 8 bits. That call is used to put exactly 1 byte into the buffer, not more. When you are using

```
Wire.write(Distanceincm);

```

you are putting the least significant byte of `Distanceincm` into the buffer. The rest will just be thrown away (this happens at the cast from `long` to `uint8_t`). This works as long, as the value is between 0 and 127 (which is the upper part of the `int8_t` value range). With higher (or lower) values your received data will be garbage. Instead you need to write every byte of your data into the buffer:

```
Wire.write(Distanceincm  & 0x000000FF);
Wire.write((Distanceincm & 0x0000FF00) >> 8);
Wire.write((Distanceincm & 0x00FF0000) >> 16);
Wire.write((Distanceincm & 0xFF000000) >> 24);

```

With bitwise ANDing (`&`) of the hexadecimal value `0x000000FF`, we are deleting all bits, beside the least significant byte (analog with `0x0000FF00` for the second least significant byte, and so on). Then we are shifting the corresponding byte to the position of the least significant byte (8 bits for the seconds least significant byte, 16 bits for the third least significant byte, and so on), which then gets used by `Wire.write()`. To better understand this, read about bitwise operators on the web.

You have to send both integer values in a similar fashion (though they both have only 2 bytes instead of 4).
* Now that we are sending more bytes, we also need to receive and read all these bytes correctly. First we need to request the correct number of bytes. 4 bytes for the `long` value and 2 bytes for both `int` values --\> 8 bytes. So you need to request 8 bytes:

```
Wire.requestFrom(4, 8);

```

Then you need to read these bytes into the corresponding variables:

```
long distance = Wire.read()
                | (Wire.read() << 8)
                | (Wire.read() << 16)
                | (Wire.read() << 24);

```

We are using the bitwise OR (`|`) to put the bytes together, shifting every byte to its correct position in the `long` value. In a similar way you are putting together the 2 `int` values.

---
Tags: i2c, communication, sketch
---


title: Is my sketch 'thread safe'?

text:
# Question
Title: Is my sketch 'thread safe'?
I come from a .Net background, typically I would 'lock' operations on an integer when I have thread-safe requirements. I'm not sure that applies to my sketch here? Could I potentially bypass an increment from one of my interrupt pins?

In summary, I have 2 interrupt pins - I want to increment a count which (every 5 seconds) writes via serial and resets.

I'm doing this to, kind of, avoid writing serial from within an interrupt - since I've read it's strongly discouraged.

```
#include <Controllino.h>

const byte interruptPin0 = CONTROLLINO_IN0;
const byte interruptPin1 = CONTROLLINO_IN1;
int counter1 = 0;
int counter2 = 0;
unsigned long previousMillis = 0;
unsigned long interval = 5000;
int a = 60;
char buffer[256];

void setup()
{
  pinMode(interruptPin0, INPUT_PULLUP);
  pinMode(interruptPin1, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin0), pin1Fired, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPin1), pin2Fired, RISING);
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    sprintf(buffer,"A%d",counter1);
    Serial.println(buffer);
    sprintf(buffer,"D%d",counter2);
    Serial.println(buffer);
    counter1 = counter2 = 0;
  }
}

void pin1Fired()
{
  counter1++;
}

void pin2Fired()
{
  counter2++;
}

```

# Answer
> 4 votes
There is indeed a race condition in your code: if an interrupt fires while you are reading one of the counters, you might read garbage. If it fires between reading and resetting the counter, you loose one count.

The way to prevent the race is to block interrupts while the main thread (everything that does not run in interrupt context) accesses the counters. BTW, do not forget to make the counters `volatile`.

The portions of the code that run with interrupts disabled are called “critical sections”, and you should keep them as short as possible in order to limit the interrupt latency they introduce. Typically, within those critical sections you do nothing more than access the shared variables. Example:

```
void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    noInterrupts();  // start of critical section
    int counter1Copy = counter1;
    counter1 = 0;
    interrupts();  // end of critical section
    Serial.print("A");
    Serial.println(counter1Copy);
    noInterrupts();  // start of critical section
    int counter2Copy = counter2;
    counter2 = 0;
    interrupts();  // end of critical section
    Serial.print("D");
    Serial.println(counter2Copy);
  }
}

```

---
Tags: serial, interrupt, threads
---


# Question
Title: How to automatically reset the nrf24l01+ with code?
I have two separate nrf24l01+ connected to two different Arduino UNOs, one as TX and the other as RX. The problem is the connection stops after a while between them.

On the Arduino COM screen I have noticed these things:

**TX Side:** Completely Frozen (Transmission Stops).
**RX Side:** Continuously receives the last data repeatedly.

The problem is solved temporarily when the TX MCU (hence the nrf) is restarted .Sometimes even after restarting the TX MCU the RX stops responding and I have to restart the RX as well. Therefore I am trying to find a way to reset my nrfs automatically using software when this situation occurs.

# Answer
> 2 votes
I found the problem occurs because the transmitter is expecting acknowledgment from the receiver which is getting lost somehow, while transmission and the transmitter still waits for ack for the last transmitted data (which it never gets) so it keeps on transmitting the last packet again and again. I saw on forums that its because of the TX buffer getting full after 3 retries or something. I don't exactly know why it happens.

I first tried resetting just the transmitter through code but it was not enough (as already mentioned in the question). So I now reset both the TX and RX using the below code. I have a separate 1 byte reset-counter in the first byte of the array (you may use a single byte variable) which acts as an id for the packet (you may use the internal PID as well).

The below code resets the **TX** if **transmission fails** by checking the **return value** of `write` function and resets the **RX** when it **receives the same ack** or packet (with the same reset-counter value) **more than 2 times** (I use a condition to check if the last counter value is different from the current one or not). To reset it using code I use the below algorithm :

1. **Power Down** the NRF using `powerDown()` function.
2. **Re-initialize** the nrf for the MCU.
3. **Power Up** the NRF using `powerUp()` function.

**Note:** I am using TMRH20 RF24 Library.

**TX Code**

```
void radio1_init()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  myRadio1.begin();
  delay(100);
  myRadio1.setChannel(96);
  myRadio1.setPALevel(POWERLEVEL);
  myRadio1.setDataRate(DATARATE);
  myRadio1.setAutoAck(1);
  myRadio1.enableAckPayload();
  myRadio1.enableDynamicPayloads();
  myRadio1.setRetries(2, 10);
  myRadio1.setCRCLength(RF24_CRC_8);
  myRadio1.openWritingPipe( addresses1[0]);
}

void loop()
{
  dataTransmitted[0]++;
  if ( myRadio1.write( &dataTransmitted, sizeof(dataTransmitted)))
  {

    if (myRadio1.isAckPayloadAvailable())
    {
      myRadio1.read(&ack, sizeof(ack));
    }
  }
  else
  {
    myRadio1.powerDown();
    \\Serial.println(" 1 Tx1 problem end");
    radio1_init();
    myRadio1.powerUp();
  }
}

```

**RX Code**

```
void radio2_init()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  myRadio2.begin();
  delay(100);
  myRadio2.setChannel(96);
  myRadio2.setPALevel(POWERLEVEL);
  myRadio2.setDataRate(DATARATE);
  myRadio2.setAutoAck(1);
  myRadio2.enableAckPayload();
  myRadio2.enableDynamicPayloads();
  myRadio2.setRetries(10, 10);
  myRadio2.setCRCLength(RF24_CRC_8);
  myRadio2.openReadingPipe(1, addresses2[0]);
  myRadio2.startListening();
}

void loop()
{
      if (myRadio2.available())
      {
        myRadio2.read( &dataReceived, sizeof(dataReceived));
        myRadio2.writeAckPayload(1, &ack2, sizeof(ack2));
        if (prevack2 == dataReceived[0])
        {
          \\Serial.println("RX 2 problem");
          c2++;
        }
        prevack2 = dataReceived[0];
        if (c2 > 2)
        {
          myRadio2.powerDown();
          radio2_init();
          myRadio2.powerUp();
          c2 = 0;
        }
      }
}

```

# Answer
> 1 votes
If you use standard arduino pin cables, then they do not provide stable connectivity for NRF24L01+. Try to solder pins instead (not kidding).

Another reason could be that one of your modules has bad power supply. Power it with perfect 3.3 volts (from another power source, not from Arduino), or use "base module" for the NRF24L01+ (connect this "base module" to 5V pin on Arduino) http://www.yourduino.com/sunshop/index.php?l=product\_detail&p=467

# Answer
> 1 votes
If the NRF24L01 truly locks up, as can happen with an inadequate power supply, then the powerDown(), init(), powerUp() method wont work as the NRF wont receive SPI commands. In this situation, which seems to be the most common form of lockup, a physical power cycle is the only option.

---
Tags: arduino-uno, programming, communication, nrf24l01+
---