# Question
Title: need help in code to send sms to multiple contacts using arduino, gsm800, push button
When button 1 is pressed, the message should be sent to 4 members. But we are receiving the message for one member and after some delay for the other members. But receiving to all members of contacts given in the code (Here numbers are not mentioned)

```
#include <LiquidCrystal.h>

int ButtonValue1=0;
int ButtonValue2=0;
int ButtonValue3=0;
int ButtonValue4=0;

int Button1=8;
int Button2=9;
int Button3=10;
int Button4=11;
int buz=12;
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

void okcheck()
{
  unsigned char rcr;
  do{
    rcr = Serial.read();
  }while(rcr != 'K');
}

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

  pinMode(buz,OUTPUT);
  pinMode(Button1,INPUT);
  pinMode(Button2,INPUT);
  pinMode(Button3,INPUT);
  pinMode(Button4,INPUT);

  digitalWrite(12, HIGH);

  lcd.begin(16, 2);
  lcd.clear();
  lcd.print("INNOVATIVE CLG");
  lcd.setCursor(0, 1);
  lcd.print("BUS INFO SYSTEM");

  delay(1000);
}

void loop()
{
  ButtonValue1=digitalRead(Button1);
  ButtonValue2=digitalRead(Button2);
  ButtonValue3=digitalRead(Button3);
  ButtonValue4=digitalRead(Button4);

  if(ButtonValue1!=0)
  {
    lcd.clear();
    lcd.print("BUS STARTED...");
    Serial.write("AT\r\n");         okcheck();
    Serial.write("ATE0\r\n");         okcheck();
    Serial.write("AT+CMGF=1\r\n");         okcheck();
    Serial.write("AT+CNMI=1,2,0,0\r\n");         okcheck();
    Serial.write("AT+CSMP=17,167,0,0\r\n");         okcheck();
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(100);
    Serial.write("GUD MNG.. BUS STARTED FROM STARTING POINT\r");
    delay(100);
    Serial.write(0x1A);
    delay(1000);delay(1000);
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(100);
    Serial.write("GUD MNG.. BUS STARTED STARTING POINT\r");
    delay(100);
    Serial.write(0x1A);
    delay(1000);delay(1000);
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(100);
    Serial.write("GUD MNG.. BUS STARTED STARTING POINT\r");
    delay(100);
    Serial.write(0x1A);
    delay(1000);delay(1000);
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(100);
    Serial.write("GUD MNG.. BUS STARTED STARTING POINT\r");
    delay(100);
    Serial.write(0x1A);
    delay(1000);delay(1000);
  }
  if(ButtonValue2!=0)
  {
    lcd.clear();
    lcd.print("BUS IS @ 1st stage");
    Serial.write("AT\r\n");         okcheck();
    Serial.write("ATE0\r\n");         okcheck();
    Serial.write("AT+CMGF=1\r\n");         okcheck();
    Serial.write("AT+CNMI=1,2,0,0\r\n");         okcheck();
    Serial.write("AT+CSMP=17,167,0,0\r\n");         okcheck();
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(1000);
    Serial.write("BUS IS @ 1st stage\r");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);delay(1000);
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(1000);
    Serial.write("BUS IS @ 1st stage\r");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);delay(1000);
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(1000);
    Serial.write("BUS IS @ 1st stage\r");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);delay(1000);
  }
  if(ButtonValue3!=0)
  {
    lcd.clear();
    lcd.print("BUS IS @ 2nd stage");
    Serial.write("AT\r\n");         okcheck();
    Serial.write("ATE0\r\n");         okcheck();
    Serial.write("AT+CMGF=1\r\n");         okcheck();
    Serial.write("AT+CNMI=1,2,0,0\r\n");         okcheck();
    Serial.write("AT+CSMP=17,167,0,0\r\n");         okcheck();
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(1000);
    Serial.write("BUS IS @ 2nd stage\r");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);delay(1000);
    Serial.write("AT+CMGS=\"+91...........\"\r");
    delay(1000);
    Serial.write("BUS IS @ 2nd stage\r");
    delay(1000);
    Serial.write(0x1A);
    delay(1000);delay(1000);
  }
  if(ButtonValue4!=0)
  {
    lcd.clear();
    lcd.print("BUS IS @ COLLEGE");
    digitalWrite(buz,LOW);
    delay(1000);
    digitalWrite(buz,HIGH);
  }
}

```

# Answer
You need to refactor you code, It has become just too complicated for this kind of straight linear code! Your code must be organized better, Don't Repeat Yourself (DRY); just by doing this you may find your error(s).

First lets fix your variables:

```
#include <LiquidCrystal.h>
#define NUMBUTTS 4
int ButtonValues[NUMBUTTS]= {0,0,0,0};
int Buttons[NUMBUTTS]= {8,9,10,11};
int buz=12;
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

```

and add some new ones

```
String numbers[NUMBUTTS] =
{
    "+91234567890",
    "+91234567890",
    "+91234567890",
    "+91234567890",
}

String msgs[NUMBUTTS-1] =
{
   "GUD MNG.. BUS STARTED FROM STARTING POINT\r",
   "BUS IS @ 1st stage\r",
   "BUS IS @ 2nd stage\r",
}

```

next lets clean up your function:

```
void okcheck()
{
    unsigned char rcr = 0;
    while(rcr != 'K') // rcr can't be 'K' when it starts as 0
        rcr = Serial.read();
}

```

Setup needs to be changed now that we changed your vars:

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

    pinMode(buz,OUTPUT);
    digitalWrite(buz, HIGH);

    for(int i=0; i<NUMBUTTS; i++)
        pinMode(Buttons[i],INPUT);

    lcd.begin(16, 2);
    lcd.clear();
    lcd.print("INNOVATIVE CLG");
    lcd.setCursor(0, 1);
    lcd.print("BUS INFO SYSTEM");

    delay(1000);
}

```

now we need to extract duplicated code and put it in a function:

```
// common starting code.
void preamble()
{
    Serial.write("AT\r\n");
    okcheck();

    Serial.write("ATE0\r\n");
    okcheck();

    Serial.write("AT+CMGF=1\r\n");
    okcheck();

    Serial.write("AT+CNMI=1,2,0,0\r\n");
    okcheck();

    Serial.write("AT+CSMP=17,167,0,0\r\n");
    okcheck();
}

// common message code
void send_sms(String& msg)
{
    String prefix = "AT+CMGS=\"";
    preamble();

    for(int i=0;i<NUMBUTTS;i++)
    {
        Serial.write(prefix+numbers[i]+"\"\r");
        delay(100);

        Serial.write(msg);
        delay(100);

        Serial.write(0x1A);
        delay(2000)
    }
}

```

now we need to fix up loop():

```
void loop()
{
    for(int i=0; i<NUMBUTTS; i++)
    {
        ButtonValues[i]=digitalRead(Buttons[i]);
    }

    for(int i=0; i<NUMBUTTS-1; i++)
    {
        if(ButtonValues[i]!=0)
        {
            lcd.clear();
            lcd.print(msgs[i]);
            send_sms(msgs[i]);
        }
    }

    //special case for button4
    if(ButtonValue[3]!=0)
    {
         lcd.clear();
         lcd.print("BUS IS @ COLLEGE");
         digitalWrite(buz,LOW);
         delay(1000);
         digitalWrite(buz,HIGH);
    }
}

```

Now your program logic is separate from the code that sends the messages, and you can test each in isolation from each other. You can test that send\_sms() actually sends SMSs. Then you can see if your logic does what you think it does; by either replacing send\_sms() with a test stub, or just by inspection.

With clean code it should be easier to spot your problem. The code looks like it should work, so I would guess that the modem itself may be causing the delays, maybe it takes a while to send a message and you are queuing them up and it takes a few seconds to get through each one, its possible that not all get send because one or more gets dropped while it is busy sending another. Hard to know without looking at the documentation for your module.

Your diagram looks like it is hooked up wrong, you have TX-\> RX, but MOSI -\> TX; Serial.read() reads from RX not MOSI, so i don't know how checkok() doesn't just loop forever, since you left the arduino RX floating.
> 1 votes

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


title: storage problem

text:
# Question
Title: storage problem
I made a Arduino program to control my air conditioner(model:GREE Lomo) by PC. I download IRremote library from here for that.

```
#include "IRremote.h"

IRsend irsend;
int irPin = 3; // pin IR led

int khz = 38; // 38kHz carrier frequency for the NEC protocol

const unsigned int irSignalOn[] = {8972, 4492, 644, 1664, 640, 564, 644, 564, 640, 1668, 636, 568, 640, 1664, 644, 560, 644,
                               560, 644, 564, 640, 564, 644, 560, 644, 1664, 640, 564, 644, 564, 640, 564, 640, 1668, 640, 1664, 640, 564, 644,
                               1664, 640, 564, 644, 564, 640, 1668, 640, 1664, 640, 564, 644, 564, 640, 564, 640, 564, 644, 564, 640, 1664, 644,
                               560, 644, 1664, 640, 564, 644, 564, 640, 1668, 640, 560, 644, 19980, 640, 564, 644, 1664, 640, 1668, 640, 564, 640,
                               564, 644, 1660, 644, 560, 644, 564, 644, 560, 644, 564, 640, 564, 644, 560, 644, 564, 640, 1664, 640, 564, 644, 564,
                               640, 564, 640, 564, 644, 564, 640, 564, 644, 560, 644, 564, 640, 564, 644, 564, 640, 564, 640, 564, 644, 560, 644, 564,
                               640, 564, 640, 564, 644, 1664, 640, 564, 644, 39972, 8976, 4496, 640, 1664, 644, 560, 644, 564, 640, 1668, 640, 564, 640,
                               1668, 640, 564, 640, 564, 644, 560, 644, 564, 640, 564, 644, 1664, 640, 564, 644, 564, 640, 564, 644, 1664, 640, 1668, 640,
                               564, 640, 1668, 640, 564, 640, 564, 644, 1668, 636, 1668, 640, 564, 640, 564, 640, 564, 644, 560, 644, 564, 644, 560, 644,
                               1668, 640, 1664, 640, 564, 644, 564, 640, 1668, 640, 564, 640, 19980, 640, 564, 644, 564, 640, 564, 644, 560, 644, 564, 640,
                               564, 644, 560, 644, 564, 640, 564, 640, 564, 644, 564, 640, 1668, 636, 568, 640, 1664, 640, 564, 640, 1672, 636, 1664, 640,
                               564, 644, 564, 640, 564, 640, 1668, 640, 564, 640, 564, 640, 568, 640, 1664, 640, 564, 640, 564, 644, 564, 640, 1692, 616,
                               1664, 640, 564, 640, 1664, 640, 39980, 8972, 4492, 644, 1664, 640, 568, 636, 564, 644, 1664, 640, 564, 640, 1668, 640, 564,
                               640, 564, 644, 564, 640, 564, 640, 564, 640, 1668, 640, 564, 640, 568, 640, 560, 644, 1664, 640, 1664, 644, 564, 640, 1668,
                               640, 564, 640, 564, 644, 1660, 644, 1664, 640, 564, 644, 560, 644, 564, 640, 564, 640, 564, 644, 1664, 640, 1664, 644, 1664,
                               644, 560, 644, 564, 640, 1668, 640, 560, 644, 19984, 640, 564, 644, 560, 644, 564, 640, 564, 640, 564, 640, 564, 644, 564, 640,
                               564, 644, 564, 640, 564, 640, 564, 640, 568, 640, 564, 644, 560, 644, 564, 640, 564, 644, 560, 644, 564, 640, 564, 644, 564,
                               640, 1664, 640, 1668, 640, 564, 640, 564, 640, 564, 644, 564, 640, 568, 640, 560, 644, 1668, 640, 1664, 640, 564, 640, 564, 644
                              };

const unsigned int irSignalOff[] = {8996, 4496, 640, 1688, 616, 568, 636, 568, 640, 568, 636, 568, 640, 1688, 616, 568, 640, 564, 640, 564, 640, 564, 644, 564,
                                640, 1688, 616, 1692, 616, 568, 640, 568, 636, 1668, 640, 1688, 616, 1692, 616, 568, 636, 568, 640, 564, 640, 1692, 616,
                                568, 636, 568, 636, 568, 640, 564, 640, 568, 636, 568, 640, 1688, 616, 564, 640, 1692, 616, 568, 636, 564, 640, 1672, 636,
                                564, 644, 19980, 640, 568, 636, 1692, 616, 1688, 616, 568, 636, 568, 640, 1688, 616, 572, 636, 564, 640, 568, 640, 564, 640,
                                568, 636, 568, 636, 568, 640, 1688, 616, 568, 640, 564, 640, 568, 636, 564, 640, 568, 640, 564, 640, 564, 640, 568, 640, 568,
                                636, 568, 636, 568, 640, 564, 640, 564, 640, 568, 636, 568, 640, 1688, 616, 568, 636, 1692, 616, 39980, 8972, 4496, 640, 1688,
                                616, 568, 636, 568, 640, 568, 636, 568, 636, 1692, 616, 564, 640, 568, 640, 564, 640, 564, 640, 568, 640, 1688, 616, 1692, 612,
                                568, 640, 564, 640, 1692, 612, 1692, 616, 1692, 616, 564, 640, 568, 640, 564, 640, 1692, 612, 568, 640, 568, 636, 568, 636, 568,
                                640, 564, 640, 564, 640, 568, 640, 1692, 612, 1692, 616, 568, 640, 564, 640, 1688, 616, 568, 636, 19984, 640, 564, 640, 568, 640,
                                564, 640, 568, 636, 568, 636, 568, 640, 564, 640, 568, 636, 568, 640, 564, 640, 564, 644, 1688, 616, 568, 640, 564, 640, 568, 636,
                                568, 640, 564, 640, 568, 636, 1672, 636, 1692, 612, 568, 640, 564, 640, 568, 636, 568, 640, 1692, 612, 568, 640, 568, 636, 568, 640,
                                564, 640, 1692, 616, 1668, 632, 568, 640, 39980, 8972, 4500, 640, 1688, 616, 568, 636, 568, 640, 564, 640, 568, 636, 1668, 640, 568,
                                636, 568, 640, 568, 636, 564, 640, 568, 636, 1692, 616, 1688, 616, 568, 636, 568, 640, 1668, 636, 1688, 620, 1692, 612, 568, 640, 564,
                                640, 564, 640, 1692, 612, 568, 640, 564, 644, 564, 640, 564, 640, 552, 652, 568, 640, 1688, 616, 1688, 616, 1692, 616, 564, 640, 568,
                                640, 1664, 640, 564, 640, 19988, 636, 568, 640, 564, 640, 568, 636, 568, 640, 564, 640, 568, 636, 568, 640, 564, 640, 564, 640, 568,
                                636, 568, 640, 568, 636, 568, 640, 568, 640, 564, 636, 568, 640, 568, 636, 568, 636, 568, 636, 568, 640, 1668, 636, 1692, 616, 568,
                                640, 564, 640, 564, 640, 568, 636, 568, 640, 564, 640, 1692, 616, 564, 640, 568, 636, 1692, 616
                               };

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

void loop() {

  if (Serial.available() > 0) {
    char letter = Serial.read();
    if (letter == '1') {
      irsend.sendRaw(irSignalOn, sizeof(irSignalOn) / sizeof(irSignalOn[0]), khz); //Note the approach used to automatically calculate the size of the array.
      Serial.println("ON");
    } else if (letter == '0') {
      irsend.sendRaw(irSignalOff, sizeof(irSignalOff) / sizeof(irSignalOff[0]), khz); //Note the approach used to automatically calculate the size of the array.
      Serial.println("OFF");
    }
  }
}

```

i got an error for arduino uno : Global variables use 2080 bytes (101%) of dynamic memory, leaving -32 bytes for local variables. Maximum is 2048 bytes.

how can i fix it?

EDIT 07/26:

I know with board like ATmega2560 problem will fix but I want use Arduino uno.

I tried to save my data at program memory but I don't know how to read that.

# Answer
A solution is to move the tables into program memory (aka PROGMEM). Use the below:

```
const unsigned int irSignalOn[] PROGMEM = {
 ...
};

```

And modify the call to `sendRaw()` to `sendRaw_P()`.

```
irsend.sendRaw_P(irSignalOn, sizeof(irSignalOn) / sizeof(irSignalOn[0]), khz);

```

For more information see the library documentation.

Cheers!
> 3 votes

# Answer
**not an answer**

please try this

let me know if it turns on the A/C when you press `1`

```
#include "IRremote.h"

IRsend irsend;
int irPin = 3; // pin IR led

int khz = 38; // 38kHz carrier frequency for the NEC protocol

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

void loop() {

  if (Serial.available() > 0) {
    char letter = Serial.read();
    if (letter == '1') {
      irsend.sendNEC(0x4A08D3052, 35);
      irsend.sendNEC(0x64040002,  32);
      irsend.sendNEC(0x4A08D3032, 35);
      irsend.sendNEC(0x0015888D,  32);
      irsend.sendNEC(0x4A08D3072, 35);
      irsend.sendNEC(0x00000C0C,  32);

      Serial.println("ON");
    }
  }
}

```
> 1 votes

# Answer
One can also jump to a Atmega1284P based board, with it's 16K of SRAM, 8x that of a '328P's 2K and 2x that of the Mega's 8K. Dual hardware serial ports too if your project should need one.
> 0 votes

---
Tags: arduino-uno, memory-usage, memory
---


# Question
Title: ADXL345 Data Rate seems to depend more upon Baud rate than the actual Data Rate that I set
I have an Arduino UNO that is connected to an ADXL345. The problem is I need to collect data at 50Hz at least. The ADXL345 according to its Data sheet can go up to 3200Hz without any problem. I am using the Adafruit library using I2C interface but the accelerometer does not go above 10-12Hz as reported by the `getDataRate()` function of Adafruit library.

Im trying to set the data rate like this:

```
accel.setDataRate(ADXL345_DATARATE_100_HZ);

```

The strange thing is that the data rate is depended more upon increasing the baud rate at the beginning of my setup function. If I set this to 38400 I get around 90-92 readings every second. I have setup my code in a way that every measurement from the accelerometer is recorded with the timestamp down to seconds. This is a snapshot of the output from the serial monitor.

```
Data Rate:    9 Hz
------------------------------------
Sensor:       ADXL345
Driver Ver:   1
Unique ID:    12345
Max Value:    -156.91 m/s^2
Min Value:    156.91 m/s^2
Resolution:   0.04 m/s^2
------------------------------------

Range:         +/- 8  g

84.00,18:40:4,15/7/2018,0.59,9.14,2.82
85.00,18:40:4,15/7/2018,0.59,9.14,2.86
86.00,18:40:4,15/7/2018,0.63,9.10,2.86
87.00,18:40:4,15/7/2018,0.55,9.10,2.82
88.00,18:40:4,15/7/2018,0.55,9.10,2.82
89.00,18:40:4,15/7/2018,0.59,9.10,2.82
90.00,18:40:4,15/7/2018,0.59,9.10,2.82
91.00,18:40:4,15/7/2018,0.55,9.10,2.86
92.00,18:40:4,15/7/2018,0.55,9.10,2.86
93.00,18:40:4,15/7/2018,0.63,9.10,2.90
94.00,18:40:4,15/7/2018,0.63,9.10,2.90
95.00,18:40:4,15/7/2018,0.63,9.06,2.82
96.00,18:40:4,15/7/2018,0.63,9.06,2.82
97.00,18:40:4,15/7/2018,0.59,9.06,2.82
98.00,18:40:4,15/7/2018,0.59,9.06,2.82
99.00,18:40:4,15/7/2018,0.59,9.10,2.82

```

Is it a problem with the code, or the adxl345?

# Answer
> 2 votes
You do know that sending data through serial takes time, don't you?

You are sending 41 bytes per reading. The serial port has a 64 byte buffer. By the second reading the buffer is full and all printing blocks until there is room in the buffer.

At 38400 baud that's sending 3840 bytes per second. With 41 bytes per reading that's 93.66 readings per second (not including the time taken to do the actual reading) that you can squeeze down the serial port.

Either run at a faster speed, or reduce the quantity of data you're sending per reading - or do both.

---
Tags: arduino-uno, accelerometer
---


title: How to clear FIFO buffer on MPU6050?

text:
# Question
Title: How to clear FIFO buffer on MPU6050?
my MPU6050 works very unstable , the problem is unable clear excessed FIFO buffer on MPU6050, I am using Jeff Rowberg's MPU library and according to his DMP example but without using interruptions,here is my modified code but I've tried several method listed in the library to clear buffer but doesn't work..

Thanks very much!

```
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"

MPU6050 mpu(0x69); //AD0=High

//MPU control/status vars
bool dmpReady = false;
uint8_t mpuIntStatus;  //actual interrupt status byte
uint8_t deviceStatus; //device status , 0 = success ,
uint16_t packetSize; //expected DMP packet size (defult 42) -- ?
uint16_t fifoCount; //count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO buffer storage

// orientation/motion vars
Quaternion q;           // [w, x, y, z]         quaternion container
VectorInt16 aa;         // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;    // [x, y, z]            gravity vector
float euler[3];         // [psi, theta, phi]    Euler angle container
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

volatile bool mpuInterrupt = false;
//void dmpDataReady() {
//  mpuInterrupt = true;
//}

// put your setup code here, to run once:
void setup() {
  //join I2C bus
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        TWBR = 48; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
    #endif
  //initialize serial communication
  Serial.begin(115200);
  while(!Serial); //common for Leonardo issues

  //initialize the mpu
  Serial.println("Call MPU6050 Lib to initialize devices...");
  mpu.initialize(); //initialize I2C device by using MPU6050 library

  //verify connection
  Serial.println("Tesing device connections");
  Serial.println(mpu.testConnection() ? F("MPU6050 connection test successed ") : F("MPU6050 connection test failed"));

//  //wait for begin , uncomment if we need wait user interruption
//  Serial.println("Press any button to begin");
//  while (Serial.available() && Serial.read()); // empty buffer
//  while (!Serial.available());                 // wait for data
//  while (Serial.available() && Serial.read()); // empty buffer again

  //load and configure DMP
  Serial.println("initializing DMP");
  deviceStatus = mpu.dmpInitialize(); //use MPU6050 library to inilisalize the dmp

 //feed offsets
  mpu.setXGyroOffset(220);
  mpu.setYGyroOffset(76);
  mpu.setZGyroOffset(-85);
  mpu.setZAccelOffset(1788); // 1688 factory default for my test chip

  //make sure it works
  if (deviceStatus == 0) {
    Serial.println("DMP initialization success, now enable DMP for use");
    //turn on DMP
    mpu.setDMPEnabled(true); //use MPU6050 library to enable DMP)

    //wait for first interrup . currently just leave it false automatically
    mpuInterrupt == false;

    //let main llop know it's ok to use DMP, set dmpRead flag to ture
    dmpReady = true;
    Serial.println("DMP is ready to use.");

    //get expected DMP packet size for later comparison
    packetSize = mpu.dmpGetFIFOPacketSize();
  } else {
    //ERROR! , device status !=0 when initializing DMP
    Serial.print("DMP initialization failed when using MPU6050 library:");
    if (deviceStatus == 1) {
      Serial.println(" intial memory load failed");
    } else if (deviceStatus == 2) {
      Serial.println(" failed to update DMP configuration");
    } else {
      Serial.print(" unknow error with code: ");
      Serial.println(deviceStatus);
    }
}
}

int ticket = 1;
void printOnlyOnce (String message){
  if (ticket == 1){
   Serial.println(message);
   ticket = 0 ;
  } else {
    return;
  }
}

void loop() {
  //if DMP not ready don't do anything
  if (!dmpReady) {
    printOnlyOnce("MAIN LOOP: DMP disabled");
    return;
  } else {

    //testing overflow
    if (fifoCount == 1024) {
      mpu.resetFIFO();
      Serial.println("FIFO overflow");
    } else {

    //wait for enough avaliable data length
    while (fifoCount < packetSize) {
      //waiting until get enough
      fifoCount = mpu.getFIFOCount();
    }

    //read this packet from FIFO buffer
    mpu.getFIFOBytes(fifoBuffer,packetSize);

    //track FIFO count here is more then one packeage avalible

    //reset fifo count
    fifoCount -= packetSize ;
    Serial.println(fifoCount);

    if (fifoCount > 2) {
        ////// clear fifo buffer
    }
    //display stage
                // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180/M_PI);
  }
  }
}

```

# Answer
> 4 votes
Yank, I ended up clearing the buffer after every read. In your code it would be following the line

```
//read this packet from FIFO buffer
mpu.getFIFOBytes(fifoBuffer,packetSize);

```

I added

```
mpu.resetFIFO();

```

I came to this conclusion after watching when the over flows occurred. The fifo buffer is adding on to the end of the buffer, and when it gets full, rather than wrap, it over flows. Reading does not seem to remove data from buffer in any way. By clearing the buffer you might be discarding data, but the DMP is doing the integration for AHRS for you, so you really do not need to worry about dropping data since you are only interested in the current pitch,roll,yaw or Euler or whatever, at least that was my case. I am running it on an Arduino UNO shield prototype and it is rock solid stable (at the default 100 hz rate). See spiked3.com PiPlate / Pilot.

# Answer
> 1 votes
What if we can increase the size of the FIFo Buffer.

```
uint8_t fifoBuffer[64]; // FIFO storage buffer

```

What if I change it to lets say:

```
uint8_t fifoBuffer[1024]; // FIFO storage buffer

```

and then change :

```
if ((mpuIntStatus & 0x10) || fifoCount == 16384) { // I changed 1024 -> 16384
    // reset so we can continue cleanly
    mpu.resetFIFO(); // Resets the FIFO buffer when set to 1 while FIFO_EN equals 0.
    Serial.println(F("FIFO overflow!"));

// otherwise, check for DMP data ready interrupt (this should happen frequently)
}

```

Please check these changes.

# Answer
> 0 votes
To prevent overflow problems, please, go to MPU6050\_6Axis\_MotionApps20.h and modify that line:

```
0x02,   0x16,   0x02,   0x00, **0x01**                // D_0_22 inv_set_fifo_rate

```

The value in bold is the objective! Change it to `0x03` or `0x04` or `0x05` to reduce the Hz of rate. I am using `0x03` and not getting error values, junk data, or overflows anymore.

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


# Question
Title: Help in "An error occurred while uploading the sketch"
Trying to test THIS. Got following error:

```
esptool v0.4.13 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de>
    setting board to nodemcu
    setting baudrate from 115200 to 9600
    setting port from COM1 to COM3
    setting address from 0x00000000 to 0x00000000
    espcomm_upload_file
    espcomm_upload_mem
    setting serial port timeouts to 1000 ms
opening bootloader
resetting board
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    read 0, requested 1
trying to connect
    flush start
    setting serial port timeouts to 1 ms
    setting serial port timeouts to 1000 ms
    flush complete
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
    espcomm_send_command: receiving 2 bytes of data
Uploading 356000 bytes from C:\Users\PRAMIT~1\AppData\Local\Temp\arduino_build_521093/testPersWiFiManager.ino.bin to flash at 0x00000000
    erasing flash
    size: 056ea0 address: 000000
    first_sector_index: 0
    total_sector_count: 87
    head_sector_count: 16
    adjusted_sector_count: 71
    erase_size: 047000
    espcomm_send_command: sending command header
    espcomm_send_command: sending command payload
    setting serial port timeouts to 15000 ms
    setting serial port timeouts to 1000 ms
    espcomm_send_command: receiving 2 bytes of data
    writing flash
................................................................................ [ 22% ]
................................................................................ [ 45% ]
................................................................................ [ 68% ]
.......................An error occurred while uploading the sketch

```

All libraries are included, no compile error. Steps followed: 1st uploaded the data using `Tools>ESP8266 Sketch data upload`. Then `Sketch>upload`

After failing this, I tried a basic example similar to THIS. This uploaded successfully. The same configuration is used for both scenarios.

What am I missing? I am getting no clue.

Settings:

# Answer
> 0 votes
The upload to esp8266 with esptool used in IDE doesn't work good on slow baudrate. It fails for larger sketches. You can upload to NodeMcu at 921600 baud.

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


# Question
Title: Accidentally shorted 5V to GND on Arduino Nano, can I reuse the ATmega328p?
I've shorted 5V to GND and the Arduino Nano (CH340 clone) stopped working (power LED light is dimming). The board had a burning smell, and I also checked if other Arduini on the same USB port worked and they did, so I'm quite sure the Arduino is dead.

After the incident, I de-soldered the TQFP Atmega328p (plus the crystal) to reuse. I'm thinking that if it's only the external circuitry that's damaged, then the chip should be OK. Can I reuse the chip if I solder onto a new board? What components could have been damaged?

# Answer
> 1 votes
On a Arduino Nano, there is a diode that prevents an external 5V source from back feeding into the USB source. If your clone equivalent has that as well, I suspect that is the part that got fried.

---
Tags: power, arduino-nano, atmega328
---


# Question
Title: What happens when I exceed amp limit on Arduino 5v pin?
I'm using an Arduino Uno to power some rgb LEDs.

Each LED takes 20mA (on average). I have a strand of 400 LEDs. This should be drawing ~8,000mA.

Arduino Uno has a limit on its 5v pin of 500mA.

\**So how many amps is my Arduino outputting? My 8A worth of LEDs are illuminated, just dimly.

**Edit:** My Arduino still runs, and the 8,000mA LEDs illuminate, just dimly. I’ve left the setup on for 12 hours, and it all still works.

So it appears the behavior of the Arduino Uno is to limit the amp output of its 5v pin. It does not burn out.

Any explanations for this observed behavior?

**Edit 2:** I know how to wire up this setup correctly using power injection. I’m just curious why my Arduino is not burning out as we all expect it to.

# Answer
> 1 votes
If the 5V source is the barrel jack, (like from a 7.5V or 9V source), than you may be able to get up to 800mA to 1A from the 5V pin. There is a reverse polarity diode that is rated for 1A. The 5V regulator is only rated for 800mA. It does not have good heatsinking, and will overheat and shut before you see 800mA tho. USB, well, you may get 500mA from that, if the source doesn't shut down first. If it doesn't, then the 500mA inline fuse should open.

You really need a seperate source for 5V for power to the strands. Be sure to connect the Gnd from the source to the Arduino Gnd.

What kind of RGB LEDs are you using? WS2812B type LEDs?

# Answer
> 0 votes
If you exceed the amp limit, that can be drawn through (!) the Arduino, some components on the Arduino will be fried (As for most electronic devices. For the Arduino this is practically a short). There is no current limitation there. Which components are fried depends on how you provide the power. If you provide power through the power jack or VIN, the voltage regulator will burn out. If you provide power through USB a diode or the MOSFET will be fried (You can look this up in the Arduino UNOs schematic at this site).

The setup might output a current, that is a bit higher than 500mA, for a short time. But the mentioned components, that are in the currents path, will heat up very quickly and be destroyed. In this short time the LEDs will be very dim, since the Arduino cannot provide a current as big as 8A, not even for a short time.

All great loads have to be powered separately from the Arduino, so that their supply current will not flow through the Arduino. If you are using a powerful USB supply, you have to split the power lines, before giving the voltage to the Arduino. You can connect the USBs 5V pin to the 5V pin of the Arduino and to the LEDs. If you are using a power supply with a higher voltage than possible for your LEDs, you have to buy an extra regulator, that also capable of providing the needed current.

**Important note:** Since you didn't specify, how you are connecting the RGB LEDs, you also have to take care about the current limit of a single pin. It should not exceed 20mA, 40mA at the absolute maximum. So you cannot drive the LEDs directly. You will need a driver for then anyway. The simplest way is a MOSFET, that is capable of sourcing the corresponding current. It is then controlled by the Arduino, which needs very little current for it.

---
Tags: arduino-uno
---


# Question
Title: nrf24l01 fried when supplying 6.5V to VIN?
I have two Arduino Unos (One clone, one genuine) and I'm trying to make a remote and a base station. Got everything working flawlessly, (Using RF24 library) and the last piece of the wiring was to get the remote Arduino off the USB and powered by battery. I have a 4 AA battery holder which I put 4 brand new alkaline batteries in. Soldered up some connectors, plugged it in and...nothing?

Ran the demos everyone seems to use. Nothing again. Ran the "diagnostic script at the end of that thread...results seemed fine...

```
CheckConnection Starting

FIRST WITH THE DEFAULT ADDRESSES after power on
  Note that RF24 does NOT reset when Arduino resets - only when power is removed
  If the numbers are mostly 0x00 or 0xff it means that the Arduino is not
     communicating with the nRF24

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xe7e7e7e7e7
RX_PW_P0-6   = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x03
RF_CH        = 0x4c
RF_SETUP     = 0x07
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_MAX

AND NOW WITH ADDRESS AAAxR  0x41 41 41 78 52   ON P1
 and 250KBPS data rate

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xe7e7e7e7e7 0x4141417852
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xe7e7e7e7e7
RX_PW_P0-6   = 0x00 0x20 0x00 0x00 0x00 0x00
EN_AA        = 0x3f
EN_RXADDR    = 0x03
RF_CH        = 0x4c
RF_SETUP     = 0x27
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 250KBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_MAX

```

Ran test on the working arduino, and got a similar result. Checked continuity on all pins twice. Can't think of what could have suddenly gone wrong? Definitely didn't change my code, but just to be sure tried the examples from the above thread...

The only thing I did different was supplying power from VIN at 6.5 V (Measured with multimeter). Should be well within range for the linear voltage regulator? Definitely correct polarity. Hooked in a servo and wrote a quick sketch to drive it then powered the PWM from the battery powered arduino. Other function from my code (rotary encoder, OLED, etc) all seem to be functioning perfectly.

Fried module?

**EDIT**

I was powering the module through the 3.3V regulated output pin on the Arduino.

Noticed with the battery plugged in whenever I check the voltage with my meter 3.3 pin bounces to 3.7 then settles to 3.3. Not sure if that's the meter, or just the regulator catching up to the (what should be very low with a multimeter) load. Same behavior occurs with USB.

# Answer
> 1 votes
If I remember correctly (IIRC) The nrf24l01 module:

* runs on 3.3 Volts
* doesn't have a voltage regulator

It could be fried, try supplying a regulated 3v3 supply and see if it works then.

# Answer
> 1 votes
As per the datasheet nrf24L01 runs for voltages below 3.6V ~ 1.1V. Also soldering a capacitor between the Vcc and Gnd of an nrf24L01 module would help you to in connection issues. Please see this video for further assistance on working: A network of nrf24L01

# Answer
> 0 votes
The 3.3V regulator on the Arduino is only good for 150mA. On the clone, who knows. If you're seeing 3.3V, the regulator may be capable. The nrf24L01 draws more current when transmitting, so it's possible it looks good at time and fails at other times.

---
Tags: arduino-uno, voltage-level, nrf24l01+, battery, wireless
---


# Question
Title: Necessary torque of motor to move a door.
I am building an automatic door opener and for its mechanism I need a motor with a high torque and low speed. My question here is how to measure the torque needed to move the door as I cannot really weigh the door and find its mass. Can anyone help me out?

# Answer
You need a "hanging scale" preferably "analog one".

Mount it to any place of the door and slowly pool at 90 degrees. Check what value does the scale show when doors start moving. Static friction is always higher than dynamic friction.

Torque = Radius * Force

Raduis is the distance between mounting place and door hinges. Force is 9.81 times max value shown by the scale in kilograms.

Do this many times for many mounting points then take average. Use safety margin of 50% (motor should have at least 150% of required torque)
> 1 votes

---
Tags: motor
---


title: Sending >255 bytes array to arduino

text:
# Question
Title: Sending >255 bytes array to arduino
I am trying to send a 50x50 bitmap bytearray from my python client to arduino where it should be displayed on a screen.

I need to receive 350 bytes to have the data to show the bitmap but as soon as i initialise the array with \> 255 elements it does weird things (i guess because of the memory):

**When initialising the array with size 254 it does the expected:**

> Transmission of 350 completed in 2.805466s (arduino) Received: 253 elements

**with size 350 I only get**

> "Received: 93 elements"

How can i split the bytes i receive with the available memory and then build the bitmap accordingly or what is a better way to do it? I would like to have it transmitted via serial rather than building the qrcode in arduino (as i couldn't get the libraries required working in my setup).

*My python client does basically this:*

```
for element in qrCodeBytes:
    countElementsSent+=1
    ser.write(element)
    print("Sending " + str(element))
ser.write("$".encode()) #stop char

```

*My arduino code is based on the popular Serial input basics guide https://forum.arduino.cc/index.php?topic=288234.0*

```
 const byte numChars = 254;
 byte receivedChars[numChars]; // an array to store the received data

boolean newData = false;

void setup() {
 Serial.begin(114000);
 Serial.setTimeout(10000);
 Serial.println("<Arduino is ready>");
 display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
 display.clearDisplay();
 display.display();
}

void loop() {
 recvWithEndMarker();
 showNewData();
}

void recvWithEndMarker() {
 static byte ndx = 0;
 char endMarker = '$';
 char rc;

 // if (Serial.available() > 0) {
   while (Serial.available() > 0 && newData == false) {
     rc = Serial.read();
     if (rc != endMarker) {
       receivedChars[ndx] = rc;
       ndx++;
       if (ndx >= numChars) {
         ndx = numChars - 1;
       }
     }
     else {
     receivedChars[ndx] = '$'; // terminate the string
     Serial.println("Received: " + String(ndx) + " elements");
     ndx = 0;
     newData = true;
     }
   }
}

void showNewData() {
 if (newData == true) {
 Serial.println("This just in ... ");
 display.clearDisplay();
 drawBitMap(receivedChars,50,50,0);
 display.display();
 newData = false;
 }
}

void drawBitMap(unsigned char *img, int width, int height, int position){
  if (position ==0){
   display.drawBitmap(128/2-(width/2), 64/2-(height/2), img, width, height, 1);
  } else if (position == 1){
   display.drawBitmap(128-62,1, img, width, height, 1);
  } else if (position == 2){
   display.drawBitmap(0,5, img, width, height, 1);
  }
}

```

# Answer
> 5 votes
You use type `byte` for the variable `ndx`. Type byte is 8 bits, so the max value is 255. The variable `ndx` is incremented and after 255 it continues counting from 0.

---
Tags: arduino-uno, serial, array, memory-usage
---


# Question
Title: How do I use 4 inputs on the Arduino as a binary decoder?
How do I use 4 input lines as a binary decoder? I would like to read the 4 inputs (16 variations) and based on that choose one of 16 output behaviors?

I need to be able to set my “Ten Moon Phase Indicator” (MPI ECP) circuit project to the phase of the Moon as seen in the sky on this day, or to a specific time as indicated in one of the many apps available on the Internet. Currently the MPI ECP resets to the start of the Full Moon loop, as it is the only loop available. (this code works) NOTE: Due to the circuit & Arduino processor power consumption for this application, a eternal power will be necessary.

To resolve this problem my intent is to use four of the available 14 I\O on the Arduino Uno as INPUT's employing four debounced toggle switches (with pull up resistors): (0) Off, (1) as On. The other ten available I/O's to be used for the ten Moon display OUTPUT LED's or to control ten relays.

What I would like the sketch program to accomplish:

1. `digitalRead` pins `0`, `1`, `12`, `13`
2. Depending on 1 of 16 resulting four on/off combinations that are possible, run a specific loop.

This is what I came up with: (note, the code does not compile, I'm new)

```
 void setup()  {
 pinMode(2, OUTPUT);   // New     Waxing:
 pinMode(3, OUTPUT);   // Young  Waxing:
 pinMode(4,OUTPUT);   // Crescent Waxing:
 pinMode(5, OUTPUT);   // Quarter Waxing:
 pinMode(6, OUTPUT);   // Gibbous Waxing:
 pinMode(7,OUTPUT);   // Full Moon:
 pinMode(8, OUTPUT);   // Gibbous Wanning:
 pinMode(9, OUTPUT);   // Quarter Wanning:
 pinMode(10, OUTPUT);  // Crescent Wanning:
 pinMode(11, OUTPUT);  // Old Wanning:
 pinMode(13, INPUT);  // Switch 4
 pinMode(12,INPUT);     // Switch 3
 pinMode(1, INPUT);     // Switch 2
 pinMode(0,INPUT);      // Switch 1

 } void loop() {
 int Reading = digitalRead;
Reading = digitalRead (12); Reading = digitalRead (13);
Reading = digitalRead (1);   Reading = digitalRead (0);

 if  (digitalRead(0) == HIGH; digitalRead (1)==
   HIGH; digitalRead(12) == HIGH; (digitalRead(13) == HIGH);  { } else
    {   // loop Full Moon Start   digitalWrite(7, HIGH);  // FULL MOON ON
  delay(5000);
  digitalWrite(7, LOW);    // FULL MOON OFF
        delay(10);
   digitalWrite(8,HIGH);   // WAN GIBBOUS MOON ON
        delay(5000);
 digitalWrite(8, LOW);    // WAN GIBBOUS MOON OFF
          delay(10);
  digitalWrite(9, HIGH);   // 3RD QUARTER MOON ON
          delay(5000);
   digitalWrite(9, LOW);     // 3RD QUARTER MOON OFF
          delay(10);
  digitalWrite(10, HIGH);    // WAN CRESENT MOON ON
         delay(5000);
  digitalWrite(10, LOW);     // WAN CRESENT MOON OFF
          delay(10);
  digitalWrite(11, HIGH);     // OLD MOON ON
         delay(5000);
 digitalWrite(11, LOW);      // OLD MOON OFF
          delay(5000);
   digitalWrite(2, HIGH);  // NEW MOON ON
          delay(5000);
  digitalWrite(2, LOW);   // NEW MOON OFF
          delay(10);
 digitalWrite(3, HIGH);  // YOUNG MOON ON
          delay(5000);
   digitalWrite(3, LOW);  // YOUNG MOON OFF
          delay(100);
 digitalWrite(4, HIGH);   // WAX CRESCENT MOON ON
         delay(5000);
   digitalWrite(4, LOW);    // WAX CRESCENT MOON OFF
          delay(10);
  digitalWrite(5, HIGH);   // FIRST QUARTER ON
          delay(5000);
   digitalWrite(5, LOW);     // FIRST CRESCENT OFF
          delay(10);
 digitalWrite(6, HIGH);   // WAX GIBBOUS ON
         delay(5000);
  digitalWrite(6, LOW);    // WAX GIBBOUS OFF
          delay(10);

// loop for New moon Reset   if  (digitalRead(0) == LOW;digitalRead (1)==LOW; digitalRead(12) == LOW;(digitalRead(13) ==
    LOW);
  { } else   // loop New Moon Start
 digitalWrite(2, HIGH);  // NEW MOON ON
          delay(5000);
   digitalWrite(2, LOW);   // NEW MOON OFF
          delay(10);
   digitalWrite(3, HIGH);  // YOUNG MOON ON
          delay(5000);
   digitalWrite(3, LOW);    // YOUNG MOON OFF
          delay(100);
   digitalWrite(4, HIGH);   // WAX CRESCENT MOON ON
         delay(5000);
   digitalWrite(4, LOW);    // WAX CRESCENT MOON OFF
          delay(10);
   digitalWrite(5, HIGH);   // FIRST QUARTER ON
          delay(5000);
  digitalWrite(5, LOW);     // FIRST CRESCENT OFF
          delay(10);
  digitalWrite(6, HIGH);   // WAX GIBBOUS ON
         delay(5000);
   digitalWrite(6, LOW);    // WAX GIBBOUS OFF
          delay(10);
  digitalWrite(7, HIGH);  // FULL MOON ON
        delay(5000);
   digitalWrite(7, LOW);    // FULL MOON OFF
        delay(10);
   digitalWrite(8,HIGH);   // WAN GIBBOUS MOON ON
        delay(5000);
   digitalWrite(8, LOW);    // WAN GIBBOUS MOON OFF
          delay(10);
   digitalWrite(9, HIGH);   // 3RD QUARTER MOON ON
          delay(5000);
   digitalWrite(9, LOW);     // 3RD QUARTER MOON OFF
          delay(10);
  digitalWrite(10, HIGH);    // WAN CRESENT MOON ON
         delay(5000);
   digitalWrite(10, LOW);     // WAN CRESENT MOON OFF
          delay(10);
  digitalWrite(11, HIGH);     // OLD MOON ON
         delay(5000);
   digitalWrite(11, LOW);      // OLD MOON OFF
          delay(5000);
 { } else  { // Young moon Reset Start
 if  (digitalRead(0) == LOW; digitalRead (1)==LOW; digitalRead(12) ==
    LOW;(digitalRead(13) == HIGH;
 )
   { } else  // loop New Moon Start
         digitalWrite(3, HIGH);
  // YOUNG MOON ON
          delay(5000);
   digitalWrite(3, LOW);    // YOUNG MOON OFF
          delay(100);
  digitalWrite(4, HIGH);   // WAX CRESCENT MOON ON
         delay(5000);
  digitalWrite(4, LOW);    // WAX CRESCENT MOON OFF
          delay(10);
   digitalWrite(5, HIGH);   // FIRST QUARTER ON
          delay(5000);
  digitalWrite(5, LOW);     // FIRST CRESCENT OFF
          delay(10);
  digitalWrite(6, HIGH);   // WAX GIBBOUS ON
         delay(5000);
  digitalWrite(6, LOW);    // WAX GIBBOUS OFF
          delay(10);
 digitalWrite(7, HIGH);    // FULL MOON ON
        delay(5000);
   digitalWrite(7, LOW);    // FULL MOON OFF
        delay(10);
   digitalWrite(8,HIGH);   // WAN GIBBOUS MOON ON
        delay(5000);
  digitalWrite(8, LOW);    // WAN GIBBOUS MOON OFF
          delay(10);
  digitalWrite(9, HIGH);   // 3RD QUARTER MOON ON
          delay(5000);
 digitalWrite(9, LOW);     // 3RD QUARTER MOON OFF
          delay(10);
  digitalWrite(10, HIGH);    // WAN CRESENT MOON ON
         delay(5000);
   digitalWrite(10, LOW);     // WAN CRESENT MOON OFF
          delay(10);
  digitalWrite(11, HIGH);     // OLD MOON ON
         delay(5000);
  digitalWrite(11, LOW);      // OLD MOON OFF
          delay(5000);
         digitalWrite(2, HIGH);   // NEW MOON ON
          delay(5000);
   digitalWrite(2, LOW);       // NEW MOON OFF
          delay(10);
  }
 // Waxing Crescent Reset Start if  (digitalRead(0) == LOW; digitalRead (1)== LOW; digitalRead(12) ==
    HIGH; digitalRead(13) == HIGH;)    { } else  // Waxing Crescent Moon
    reset Start
  digitalWrite(4, HIGH);   // WAX CRESCENT MOON ON
         delay(5000);
   digitalWrite(4, LOW);    // WAX CRESCENT MOON OFF
          delay(10);
 digitalWrite(5, HIGH);   // FIRST QUARTER ON
          delay(5000);
   digitalWrite(5, LOW);     // FIRST CRESCENT OFF
          delay(10);
   digitalWrite(6, HIGH);   // WAX GIBBOUS ON
         delay(5000);
  digitalWrite(6, LOW);    // WAX GIBBOUS OFF
          delay(10);
  digitalWrite(7, HIGH);    // FULL MOON ON
        delay(5000);
   digitalWrite(7, LOW);    // FULL MOON OFF
        delay(10);
  digitalWrite(8,HIGH);   // WAN GIBBOUS MOON ON
        delay(5000);
   digitalWrite(8, LOW);    // WAN GIBBOUS MOON OFF
          delay(10);
  digitalWrite(9, HIGH);   // 3RD QUARTER MOON ON
          delay(5000);
   digitalWrite(9, LOW);     // 3RD QUARTER MOON OFF
          delay(10);
 digitalWrite(10, HIGH);    // WAN CRESENT MOON ON
         delay(5000);
   digitalWrite(10, LOW);     // WAN CRESENT MOON OFF
          delay(10);
  digitalWrite(11, HIGH);     // OLD MOON ON
         delay(5000);   digitalWrite(11, LOW);      // OLD MOON OFF
         delay(5000);
   digitalWrite(2, HIGH);   // NEW MOON ON
          delay(5000);
   digitalWrite(2, LOW);      // NEW MOON OFF
          delay(10);
   digitalWrite(3, HIGH);  // YOUNG MOON ON
          delay(5000);
   digitalWrite(3, LOW);       // YOUNG MOON OFF
          delay(100);
  }
  // First Quarter Moon Reset if  (digitalRead(0) == LOW; digitalRead(1) == HIGH; digitalRead(12) ==
    HIGH; digitalRead(13) == HIGH;)   { else  {
  //FIRST QUARTER  Moon
    reset Start
digitalWrite(5, HIGH);   // FIRST QUARTER ON
          delay(5000);
   digitalWrite(5, LOW);     // FIRST CRESCENT OFF
          delay(10);
   digitalWrite(6, HIGH);   // WAX GIBBOUS ON
         delay(5000);
  digitalWrite(6, LOW);    // WAX GIBBOUS OFF
          delay(10);
  digitalWrite(7, HIGH);  // FULL MOON ON
        delay(5000);
   digitalWrite(7, LOW);    // FULL MOON OFF
        delay(10);
   digitalWrite(8,HIGH);   // WAN GIBBOUS MOON ON
        delay(5000);
  digitalWrite(8, LOW);    // WAN GIBBOUS MOON OFF
          delay(10);
  digitalWrite(9, HIGH);   // 3RD QUARTER MOON ON
          delay(5000);
   digitalWrite(9, LOW);     // 3RD QUARTER MOON OFF
          delay(10);
  digitalWrite(10, HIGH);    // WAN CRESENT MOON ON
         delay(5000);
   digitalWrite(10, LOW);     // WAN CRESENT MOON OFF
          delay(10);
  digitalWrite(11, HIGH);     // OLD MOON ON
         delay(5000);
  digitalWrite(11, LOW);      // OLD MOON OFF
          delay(5000);
  digitalWrite(2, HIGH);   // NEW MOON ON
          delay(5000);
  digitalWrite(2, LOW);    // NEW MOON OFF
          delay(10);
   digitalWrite(3, HIGH);  // YOUNG MOON ON
          delay(5000);
   digitalWrite(3, LOW);    // YOUNG MOON OFF
          delay(100);
   digitalWrite(4, HIGH);   // WAX CRESCENT MOON ON
         delay(5000);
  digitalWrite(4, LOW);        // WAX CRESCENT MOON OFF
          delay(10);
 }
// code would continue with other loops. Thanks for looking at  my 16 RESET problem, email me. Any suggestions would be appreciated

```

# Answer
> 1 votes
a skeleton solution:

```
int in[] = {0,1,12,13};
int out[] = {2,3,4,5,6,7,8,9,10,11};
...
void setup()
{
    for(int i=0; i < 4; i++)
        pinMode(in[i], INPUT)

    for(int i=0; i < 10; i++)
        pinMode(out[i], OUTPUT)
}
...
void do0 {...};
void do1 {...};
void do2 {...};
void do3 {...};
void do4 {...};
void do5 {...};
void do6 {...};
void do7 {...};
void do8 {...};
void do9 {...};
void do10 {...};
void do11 {...};
void do12 {...};
void do13 {...};
void do14 {...};
void do15 {...};
...
void loop()
{
    int addr = 0;
    for(int i=0; i<4; i++)
       addr |= digitalRead(in[i]) << i;

    switch(addr)
    {
    case 0:
       do0();
       break;
    case 1:
       do1();
       break;
    case 2:
       do2();
       break;
    case 3:
       do3();
       break;
    case 4:
       do4();
       break;
    case 5:
       do5();
       break;
    case 6:
       do6();
       break;
    case 7:
       do7();
       break;
    case 8:
       do8();
       break;
    case 9:
       do9();
       break;
    case 10:
       do10();
       break;
    case 11:
       do11();
       break;
    case 12:
       do12();
       break;
    case 13:
       do13();
       break;
    case 14:
       do14();
       break;
    case 15:
       do15();
       break;
    }
}

```

# Answer
> 1 votes
This may be a little too advanced for the OP but... reading esoterik’s answer, I couldn't help the urge to transform that big switch/case into an array lookup. Admittedly, the syntax for declaring the array of function pointers is a little bit esoteric. ;-)

```
void loop()
{
    // List of implemented behaviors.
    static void (* const behaviors[])() = {
        do0, do1, do2,  do3,  do4,  do5,  do6,  do7,
        do8, do9, do10, do11, do12, do13, do14, do15
    };

    // Build the index of the requested behavior.
    int addr = 0;
    for (int i = 0; i < 4; i++)
       addr |= digitalRead(in[i]) << i;

    // Now do it.
    behaviors[addr]();
}

```

---

**Edit**: To address the OP's issue. I may have missed something, but it looks to me like all the cases do the exact same thing: loop through the outputs, turn each one on, wait 5 seconds, then turn it off. The only difference between the cases is the index of the output that is turned on first. In this case, all this repetitive code can be factored into a single loop as follows:

```
// Turn on then off all the outputs in turn,
// starting from the given index.
void loop_outputs(int start_index)
{
    int index = start_index;
    for (int count = 0; count < 10; count++) {

        // Light up that LED for 5 s.
        digitalWrite(out[index], HIGH);
        delay(5000);
        digitalWrite(out[index], LOW);
        delay(10);

        // Go to the next one, wrapping index 10 -> 0.
        if (++index == 10) index = 0;
    }
}

```

# Answer
> 0 votes
Note that A0 to A5 are available as for `digitalRead()` also. I normally initialize them as

```
byte pin14 = 14; // make the name mean something to you

pinMode (pin14, INPUT_PULLUP);

Then you can read it as

if (digitalRead(pin14) == LOW){

// pin is connected to Gnd

}

```

Or if you use D14-17 for your 4 inputs, you can read all 4 with a PORT read, and act on that (you still use `pinMode()` to initialize them):

```
byte addressByte = PORTC & 0x0F; // result is 0 to 15 based on state of the 4 pins

```

(I think PORTC is A0 to A5, might want to check that)

then read them and act accordingly. Way cleaner than a while bunch of `digitalRead()s` and `if()` statements.

```
switch(addressByte){

case 0:

// whatever happens

:

:

case 15:

// whatever happens
}

```

---
Tags: arduino-uno
---


# Question
Title: Arduino writes file to SD but not content to file
I'm using an Arduino UNO, the Extended Database Library (EDB), and an microSD Card to read/write 2 database tables. I've managed to create both ".db" files on the SD (they show up in Finder when I load the microSD directly onto my Mac).

I can also populate them with placeholder data, but this data does not seem to be actually written to the file (and thus doesn't survive reboot).

Also, trying `dbFile = SD.open(db_name1, FILE_WRITE);` returns false, even though the files do exist on the drive?

Here's my create code:

```
#include <SPI.h>
#include <SD.h>
#define SD_PIN 10  //SD read/write pin
#define TABLE_SIZE 8192  //256*32
#include "Arduino.h"
#include <EDB.h>

char* db_name1 = "/DB/SENSOR1.db";
char* db_name2 = "/DB/SENSOR2.db";
File dbFile;

struct sensorLog1 {
  unsigned int id;
  float input;
  unsigned int timestamp;
}
sensorLog1;
struct sensorLog2 {
  unsigned int id;
  float input;
  unsigned int timestamp;
}
sensorLog2;

// Setting up EDB object
inline void writer (unsigned long address, const byte* data, unsigned int recsize) {
  dbFile.seek(address);
  dbFile.write(data,recsize);
  dbFile.flush();
}
inline void reader (unsigned long address, byte* data, unsigned int recsize) {
    dbFile.seek(address);
    dbFile.read(data,recsize);
}
// Create an EDB object with the appropriate write and read handlers
EDB db(&writer, &reader);

void setup() {

  Serial.begin(9600);

  createDB(db_name1, "sensorLog1");
  createDB(db_name2, "sensorLog2");

  dbFile = SD.open(db_name1, FILE_WRITE);  // Doesn't work!
  if (!dbFile) { Serial.println("File does not exist"); }

}

void loop() {}

void createDB(char* db_name, char* table_name) {

  // create file
  dbFile = SD.open(db_name, FILE_WRITE);
  db.create(0, TABLE_SIZE, (unsigned int)sizeof(table_name));

  // populate with placeholder data
  for (unsigned int i = 1; i <= 20; i++) {
    table_name.id = i;
    table_name.input = 0;
    table_name.timestamp = 0;
    EDB_Status result = db.appendRec(EDB_REC table_name);
  }

  // check data
  Serial.println(db.count());  // returns '20'

  // close file to write
  dbFile.close();

}

```

# Answer
> 1 votes
> db.create(0, TABLE\_SIZE, **(unsigned int)sizeof(table\_name)**);

The third parameter is the record size! sizeof doesn't work on data, it works on types, so your getting the size of a **char\*** instead of the size of your sensorlogN struct.

Your code as written shouldn't compile! a char\* doesn't have a .id member.

```
table_name.id = i;
table_name.input = 0;
table_name.timestamp = 0;

```

---
Tags: arduino-uno, sd-card
---


# Question
Title: What happens if you supply too much voltage to an LED?
Say I have an LED that requires 3.5v. What happens if I power it with more voltage?

For example, my Arduino Uno has a 5v pin. If I power the 3.5v LED from the 5v pin, what will happen?

# Answer
> 5 votes
In the most simple terms: it will kill the LED. However things are really not that simple.

First off, an LED is a *current* driven device, not a *voltage* driven device. That is, it doesn't really care what the voltage is, but it does care what the current is. Of course, too much voltage will kill it - but too much current, regardless of the voltage, will kill it.

It's important to understand that an LED is what is known as a *non-linear component*. Things like resistors are called *linear* because they have a linear relationship between voltage and current. Increase the voltage, and the current increases by the same proportion. Increase the resistance and the current decreases by the same proportion.

However an LED is not like that. A typical Voltage-vs-Current graph for an LED looks like this:

Once the voltage reaches the "forward voltage" of the LED the current flowing through it rapidly increases. As you can see it very quickly gets towards infinity. Above a certain point and an increase in voltage has no real difference in the current. In that example the difference between 3V and 5V would be both infinite and zero. In other words, it's pretty meaningless.

But we're still over-simplifying, and that's because we've assumed an *ideal* power supply. That is, one that can supply a fixed voltage, but *infinite* current. In other words, a power supply with *zero impedance*.

No such thing exists, though.

Every fixed-voltage power supply can be seen as an ideal voltage source with an in-line (series) resistor. That resistor limits the amount of current that the supply can provide before the voltage drops too low. In schematic terms, it looks like this:

simulate this circuit – Schematic created using CircuitLab

If the voltage of the source is above the forward voltage of the LED it will try and draw an infinite amount of current from the source. That current will lead to a voltage drop across the resistance *RZ*, which results in the output voltage of the source being reduced.

It will reduce to be the same as the forward voltage of the LED.

We can, of course, calculate the current that would come out of the supply if we know the impedance of the source, but that's not something that is often known. So you assume it's low and take precautions.

For example, if we happen to know the impedance of the source is 1Ω (maybe it's stated in the datasheet for the power source...) and the voltage is 5V, and we have an LED that has a forward voltage of 2V (I like nice round numbers), we can work out that:

* The voltage drop caused by the impedance is 3V (5-2)
* The current that causes that drop is 3A (I=V/R, 3/1=3A)

3A is way off the scale for an LED, and it will basically melt internally.

So we add an extra resistance to drop *more* of the voltage at a lower current.

Now if we take the example of powering an LED directly from an Arduino's GPIO pin without a resistor, we can do the same kind of calculations.

We know that we mustn't draw more than 40mA from a pin (*absolute maximum*), so if we take that as the current that can come out of a pin before it drops below an acceptable level we can work out an estimate of the impedance. Since the datasheet tells us the output level it shouldn't drop below is 4.2V when powered by 5V, we know that the maximum voltage drop at the maximum current would be 0.8V (5-4.2). So:

* R=V/I = 0.8/0.04 = 20Ω.

There. That's an approximation of the output impedance of a GPIO pin on an Arduino. So we can plug that into our formulae and connect an LED, and we get:

* The voltage drop caused by the impedance is 3V (5-2)
* The current that causes that drop is 150mA (I=V/R, 3/20=0.15)

150mA is not massive. It's more than an LED typically wants (20-30mA tops), so the LED won't be happy, but it won't instantly blow at that level. It will be brighter than normal, get hotter than normal, and its lifetime will be much much shorter than normal.

That's not the worrying thing though. The worst thing is the *power dissipation* from the impedance:

* P=I²R = 0.15²×20 = 0.45W.

That's almost half a watt of heat being generated by the GPIO pin's drivers. If you consider that a half-watt resistor is pretty chunky, if you can picture that power being crammed into the tiny space of a single MOSFET within a silicon chip, you can see how that may become a problem.

It's really not capable of dealing with that level of heat, and the GPIO pin's driver MOSFET goes belly up. Bye bye MOSFET, bye bye GPIO pin.

As an aside, you would probably also see other strange things happening as the chip tries in vain to deliver large currents to a single GPIO pin. Other areas of the chip get starved of power, power rails drop in voltage, code crashes, etc. All from just one little LED being connected without a resistor.

---
Tags: arduino-uno
---


title: Arduino status of bit

text:
# Question
Title: Arduino status of bit
Is the a way to check the status of a bit in an arduino Uno?

Like how in Atmel AVR, there is bit\_is\_clear or bit\_is\_set

# Answer
> 5 votes
you can do it in a single line:

```
bool isSet = (var & (1 << bitNumber)) != 0;

```

`1 << bitNumber` is a bit shift in this case it means that the 1 will be multiplied with the power of 2

`&` is the bitwise AND operator. The each bit of the result is 1 if and only if both the corresponding bits in the inputs is 1.

# Answer
> 2 votes
Let's say there is a register called *r1*, and you want to do something if its *6th* bit is set to *1*.

Here are two equivalent if statements, both doing the same thing:

```
if(r1&64){Do something;}
if(r1&(1<<6)){Do something;}

```

---

Tiny extra code information:

Let's say you want to do something if r1 = 01XX10XX00 where X means you don't care.

Here are three if statements, all doing the same thing:

```
if((r1&0b11001100)==(0b01001000)){Do something;}
if((r1&0b11001100)==((1<<6) | (1<<3))){Do something;}
if((r1|0b00110011)==(0b01111011)){Do something;}

```

If you & (logic and) a 0 somewhere, then you are setting that bit to 0
If you | (logic or) a 1 somewhere, then you are setting that bit to 1

---

Best of luck on your future ventures.

# Answer
> 0 votes
Arduino defines the function `bit()`, which makes it easy to do an `if`:

```
if (val & bit(5)) { // Is bit 5 set?
    // Do something
} // if

```

Note that you need to use the bit-and (`&`) operator, not the Boolean-and (`&&`) operator.

If you want to check if the bit is clear, you can use the not (`!`) operator - but then you need parentheses:

```
if (!(val & bit(5))) { // Is bit 5 not-set (clear)?
    // Do something
} // if

```

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


# Question
Title: How would I include Arduino libraries using AVR-gcc without the IDE?
I am writing my own code for the Arduino Uno. I compile my code with AVR-gcc, and then upload it with AVRdude. I am not using the Arduino software, but I do have it installed and working on my PC. I want to include some of the Arduino libraries in my project, like Wire.h for example.

I realise that I could either copy the source file to my current working directory or include the entire path, like: `#include "/usr/share/arduino/libraries/Wire/Wire.h"` but the issue with that is `Wire.h` includes `Stream.h` which includes `Print.h` which includes...you get the idea. These different libraries are not kept in the same place either. I would have to hunt up and down chains of files, copy them and then use them locally. This does not seem like a good option to me.

Including them like I normally would using the IDE doesn't work at all, which is not surprising.

So, how can I use these libraries in my project without all the pain of finding them manually?

# Answer
Since you will end up using a significant portion of the Arduino core library, the easiest path is to accept the idea that you are now writing “Arduino sketches” rather than plain C++ code. Don't resist, be assimilated, fire the IDE and write `setup()` and `loop()`. ;-)

Once you have something working, the next step is to get rid of the IDE, which is admittedly not very nice. A couple of ways to do that:

* Use Arduino Builder, the command-line tool for building Arduino sketches. The internals of this are the same as for the Arduino IDE, but it works on the command line.
* Use a Makefile, like Sudar Muthu's Arduino-Makefile. This is a generic Makefile for building Arduino programs. It is not 100% compatible with the IDE or Aduino builder, as it does not add function declarations for you, but it may suit you better if you are used to a more standard toolchain (it's just make + avr-gcc + avrdude).
> 2 votes

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


# Question
Title: How to programmatically choose "board model" and "port number" in Arduino IDE?
I'm testing three different Arduino (nano, Uno and Mega) each of them having a nRF module. The codes (sketches) are different for each module.
I've connected the arduinos to my single laptop via 3 USB ports.

Problem is, whenever I want to re-upload a sketch and fix a bug, I have to choose board model and port number of that sketch by using the menus. It has become frustrating using mouse each time I need to change something.
How can I set these parameters in code so each sketch knows which port and model it is related to?

# Answer
You can't in the Arduino IDE, it's not designed that way (you can't even have different board/port settings in different windows - it's stored in the Java equivalent of a single global).

Instead you will have to switch to a different programming environment.

Personally (since I am the author) I would suggest switching to UECIDE. That has far more advanced facilities than the Arduino IDE, yet still retains most of the simplicity of use.

In UECIDE you can not only have different ports and boards selected in different windows, you can also configure individual sketches to automatically select their board and port.

* **Sketch -\> Sketch Properties... -\> Objects tab**
> 2 votes

# Answer
Take a look at the (similar) question and answer in https://arduino.stackexchange.com/a/9182/22924

It talks about multiple UNOs, but the solution should help here.
> 0 votes

---
Tags: arduino-ide, uploading, debugging, automatization
---


# Question
Title: Using the Arduino compiler, is it possible to use Atmega2560 interrupt pins that are unused by Mega?
Looking into the schematics for the Arduino Mega I noticed that pins PE6 and PE7 are interrupt-enabled (INT6 and INT7 respectively); however, they remain unconnected to any Arduino I/O pin.

I'm designing a custom board based on the Atmega2560 and want to use the Arduino IDE/Compiler to upload my code to it, so I'm pretty much replicating a big part of the Arduino Mega schematic into my board.

However, I would really like to enable these two extra interrupt pins (having 8 interrupt pins in total) in my board, but I'm now sure how to proceed from the software side. How could I enable this new pins in order to use them from the Arduino compiler?

Thanks!

# Answer
If you are not afraid of getting your hands dirty by touching hardware registers, you can access those pins bare-metal style, using port manipulation. You will have to read the datasheet, specifically the section “External Interrupts” if that's what you are after.

This works with the stock Arduino core (or even without core), which may be interesting from a maintenance point of view, but it's not as easy to use as the Arduino interrupt API.
> 1 votes

---
Tags: arduino-mega, arduino-ide, atmega2560, pcb-design
---


title: Arduino IDE won't upload sketches

text:
# Question
Title: Arduino IDE won't upload sketches
I recently updated my Arduino IDE to 1.8.5 from 1.6.9. I am getting issues with uploading sketches. The sketch compiles, but when I try to upload it I get this message:

```
Arduino: 1.8.5 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560,
ATmega2560 (Mega 2560)"

Sketch uses 642 bytes (0%) of program storage space. Maximum is 253952 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 8183 bytes for local variables. Maximum is 8192 bytes.
java.io.IOException: Cannot run program "___REMOVE___/bin/avrdude": error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at java.lang.Runtime.exec(Runtime.java:485)
    at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:11)
    at cc.arduino.packages.Uploader.executeUploadCommand(Uploader.java:129)
    at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:207)
    at cc.arduino.UploaderUtils.upload(UploaderUtils.java:78)
    at processing.app.SketchController.upload(SketchController.java:713)
    at processing.app.SketchController.exportApplet(SketchController.java:686)
    at processing.app.Editor$DefaultExportHandler.run(Editor.java:2168)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 10 more
An error occurred while uploading the sketch

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

```

I get this message whether or not an Arduino is connected. I also get the same message weather I connect my Arduino Mega or Uno. I tried my sketch, the blink sketch and a completely blank sketch, all with the same results.

Could I please get some help with this issue?

# Answer
> 1 votes
You may be able to fix this by taking some drastic action. Be aware this is somewhat advanced and will remove any boards you have installed via Boards Manager:

1. Click the link on the line following **File \> Preferences \> More preferences can be edited directly in the file**. This will open the `Arduino15` (or similar name depending on OS) folder.
2. Delete all files and folders under the `Arduino15` folder except for preferences.txt. Please be very careful when deleting things from your computer. When in doubt, back up!
3. Restart the Arduino IDE.
4. Verify you can now upload before re-installing any boards via Boards Manager.

---
Tags: arduino-ide
---


title: Memory chip for arduino

text:
# Question
Title: Memory chip for arduino
I know that you can't expand your ram because it is intern. But I want a extern memory chip (1024KBytes) that is very fast. I know that I need a library to access information on this chip. And functions to read and write data. A shield or breakout board it doesn't matter, and I want that it is compatible with Arduino mega. If the arduino lost power it doesn't matter if I lost the data. It must hold the data when the arduino is powerd.

# Answer
> 5 votes
You can quite easily connect multiple 128kB SPI ram chips to an Arduino. 4 of them together would give you 512kB of extra SPI-connected SRAM.

Access isn't super fast.

Another option is to use a parallel 8-bit SRAM chip. These take a lot more wiring since you need 8 wires for the data, log2(n) wires for the address, plus a couple of control wires (OE, WE, etc). But if you wire it making use of entire IO ports you can get much faster access times. Also, these come in larger capacities than the SPI SRAM chips.

There is also PSRAM available in even bigger capacities. The same interface as SRAM but it's actually DRAM. The "P" stands for "Pseudo". You can get these in megabyte capacities, although they are usually in a BGA footprint, so you'd need to find one on a breakout board.

---
Tags: arduino-mega, memory
---


title: Arduino Nano BME280 weird values

text:
# Question
Title: Arduino Nano BME280 weird values
My goal is to measure temperature, pressure and humidity using my Arduino Nano and the BME280 (GY-BME/P280).

To do this I use this library from SparkFun and that works almost. What I notice is probably invalid values for temperature and no humidity values at all.

The PINs:

* GND -\> GND
* VCC -\> 3.3V
* SDO -\> D12
* CSB -\> D10
* SDA -\> D11
* SCL -\> D13

I have noticed that I can unplug the VCC pin, it makes to difference to the measurements. I find that odd. And I have noticed that the results are the same for 5V to VCC.

This is the result, I have tested this with I2C and SPI, it's the same:

```
Program Started
Starting BME280.Program Started
Starting BME280... result of .begin(): 0x58
Displaying ID, reset and ctrl regs
ID(0xD0): 0x58
Reset register(0xE0): 0x0
ctrl_meas(0xF4): 0x27
ctrl_hum(0xF2): 0x0

Displaying all regs
0x80:9A 70 90 28 92 2D AF 00 76 6F 7D 67 32 00 93 8C
0x90:C1 D6 D0 0B CF 18 AD FF F9 FF 8C 3C F8 C6 70 17
0xA0:00 45 82 00 00 00 00 00 00 00 00 00 33 00 00 C0
0xB0:00 54 00 00 00 00 60 02 00 01 FF 82 13 4E 08 00
0xC0:00 87 27 FF 00 00 00 00 00 00 00 00 00 00 00 00
0xD0:58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xE0:00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xF0:00 00 00 0C 27 00 00 58 DD 00 82 72 00 00 00 00

Displaying concatenated calibration words
dig_T1, uint16: 28534
dig_T2, int16: 26493
dig_T3, int16: 50
dig_P1, uint16: 35987
dig_P2, int16: -10559
dig_P3, int16: 3024
dig_P4, int16: 6351
dig_P5, int16: -83
dig_P6, int16: -7
dig_P7, int16: 15500
dig_P8, int16: -14600
dig_P9, int16: 6000
dig_H1, uint8: 69
dig_H2, int16: 0
dig_H3, uint8: 0
dig_H4, int16: 0
dig_H5, int16: 0
dig_H6, uint8: 0

Temperature: 24.59 degrees C
Temperature: 76.26 degrees F
Pressure: 101121.63 Pa
Altitude: 18.25m
Altitude: 59.87ft
%RH: 0.00 %

```

My script is almost exactly like the example from the library.

```
/******************************************************************************
I2C_ReadAllData.ino
BME280 Arduino and Teensy example
Marshall Taylor @ SparkFun Electronics
May 20, 2015
https://github.com/sparkfun/SparkFun_BME280_Arduino_Library

This sketch configures the BME280 to read all measurements.  The sketch also
displays the BME280's physical memory and what the driver perceives the
calibration words to be.

Resources:
Uses Wire.h for I2C operation
Uses SPI.h for SPI operation

Development environment specifics:
Arduino IDE 1.6.4
Teensy loader 1.23

This code is released under the [MIT License](http://opensource.org/licenses/MIT).
Please review the LICENSE.md file included with this example. If you have any questions
or concerns with licensing, please contact techsupport@sparkfun.com.
Distributed as-is; no warranty is given.
******************************************************************************/

#include <stdint.h>
#include "SparkFunBME280.h"
//Library allows either I2C or SPI, so include both.
#include "Wire.h"
#include "SPI.h"

//Global sensor object
BME280 mySensor;

void setup()
{
  //***Driver settings********************************//
  //commInterface can be I2C_MODE or SPI_MODE
  //specify chipSelectPin using arduino pin names
  //specify I2C address.  Can be 0x77(default) or 0x76

  //For I2C, enable the following and disable the SPI section
  //mySensor.settings.commInterface = I2C_MODE;
  //mySensor.settings.I2CAddress = 0x76;

  //For SPI enable the following and dissable the I2C section
  mySensor.settings.commInterface = SPI_MODE;
  mySensor.settings.chipSelectPin = 10;

  //***Operation settings*****************************//

  //renMode can be:
  //  0, Sleep mode
  //  1 or 2, Forced mode
  //  3, Normal mode
  mySensor.settings.runMode = 3; //Normal mode

  //tStandby can be:
  //  0, 0.5ms
  //  1, 62.5ms
  //  2, 125ms
  //  3, 250ms
  //  4, 500ms
  //  5, 1000ms
  //  6, 10ms
  //  7, 20ms
  mySensor.settings.tStandby = 0;

  //filter can be off or number of FIR coefficients to use:
  //  0, filter off
  //  1, coefficients = 2
  //  2, coefficients = 4
  //  3, coefficients = 8
  //  4, coefficients = 16
  mySensor.settings.filter = 0;

  //tempOverSample can be:
  //  0, skipped
  //  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
  mySensor.settings.tempOverSample = 1;

  //pressOverSample can be:
  //  0, skipped
  //  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
    mySensor.settings.pressOverSample = 1;

  //humidOverSample can be:
  //  0, skipped
  //  1 through 5, oversampling *1, *2, *4, *8, *16 respectively
  mySensor.settings.humidOverSample = 1;

  Serial.begin(57600);
  Serial.print("Program Started\n");
  Serial.print("Starting BME280... result of .begin(): 0x");

  //Calling .begin() causes the settings to be loaded
  delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
  Serial.println(mySensor.begin(), HEX);

  Serial.print("Displaying ID, reset and ctrl regs\n");

  Serial.print("ID(0xD0): 0x");
  Serial.println(mySensor.readRegister(BME280_CHIP_ID_REG), HEX);
  Serial.print("Reset register(0xE0): 0x");
  Serial.println(mySensor.readRegister(BME280_RST_REG), HEX);
  Serial.print("ctrl_meas(0xF4): 0x");
  Serial.println(mySensor.readRegister(BME280_CTRL_MEAS_REG), HEX);
  Serial.print("ctrl_hum(0xF2): 0x");
  Serial.println(mySensor.readRegister(BME280_CTRL_HUMIDITY_REG), HEX);

  Serial.print("\n\n");

  Serial.print("Displaying all regs\n");
  uint8_t memCounter = 0x80;
  uint8_t tempReadData;
  for(int rowi = 8; rowi < 16; rowi++ )
  {
    Serial.print("0x");
    Serial.print(rowi, HEX);
    Serial.print("0:");
    for(int coli = 0; coli < 16; coli++ )
    {
      tempReadData = mySensor.readRegister(memCounter);
      Serial.print((tempReadData >> 4) & 0x0F, HEX);//Print first hex nibble
      Serial.print(tempReadData & 0x0F, HEX);//Print second hex nibble
      Serial.print(" ");
      memCounter++;
    }
    Serial.print("\n");
  }

  Serial.print("\n\n");

  Serial.print("Displaying concatenated calibration words\n");
  Serial.print("dig_T1, uint16: ");
  Serial.println(mySensor.calibration.dig_T1);
  Serial.print("dig_T2, int16: ");
  Serial.println(mySensor.calibration.dig_T2);
  Serial.print("dig_T3, int16: ");
  Serial.println(mySensor.calibration.dig_T3);

  Serial.print("dig_P1, uint16: ");
  Serial.println(mySensor.calibration.dig_P1);
  Serial.print("dig_P2, int16: ");
  Serial.println(mySensor.calibration.dig_P2);
  Serial.print("dig_P3, int16: ");
  Serial.println(mySensor.calibration.dig_P3);
  Serial.print("dig_P4, int16: ");
  Serial.println(mySensor.calibration.dig_P4);
  Serial.print("dig_P5, int16: ");
  Serial.println(mySensor.calibration.dig_P5);
  Serial.print("dig_P6, int16: ");
  Serial.println(mySensor.calibration.dig_P6);
  Serial.print("dig_P7, int16: ");
  Serial.println(mySensor.calibration.dig_P7);
  Serial.print("dig_P8, int16: ");
  Serial.println(mySensor.calibration.dig_P8);
  Serial.print("dig_P9, int16: ");
  Serial.println(mySensor.calibration.dig_P9);

  Serial.print("dig_H1, uint8: ");
  Serial.println(mySensor.calibration.dig_H1);
  Serial.print("dig_H2, int16: ");
  Serial.println(mySensor.calibration.dig_H2);
  Serial.print("dig_H3, uint8: ");
  Serial.println(mySensor.calibration.dig_H3);
  Serial.print("dig_H4, int16: ");
  Serial.println(mySensor.calibration.dig_H4);
  Serial.print("dig_H5, int16: ");
  Serial.println(mySensor.calibration.dig_H5);
  Serial.print("dig_H6, uint8: ");
  Serial.println(mySensor.calibration.dig_H6);

  Serial.println();
}

void loop()
{
  //Each loop, take a reading.
  //Start with temperature, as that data is needed for accurate compensation.
  //Reading the temperature updates the compensators of the other functions
  //in the background.

  Serial.print("Temperature: ");
  Serial.print(mySensor.readTempC(), 2);
  Serial.println(" degrees C");

  Serial.print("Temperature: ");
  Serial.print(mySensor.readTempF(), 2);
  Serial.println(" degrees F");

  Serial.print("Pressure: ");
  Serial.print(mySensor.readFloatPressure(), 2);
  Serial.println(" Pa");

  Serial.print("Altitude: ");
  Serial.print(mySensor.readFloatAltitudeMeters(), 2);
  Serial.println("m");

  Serial.print("Altitude: ");
  Serial.print(mySensor.readFloatAltitudeFeet(), 2);
  Serial.println("ft");

  Serial.print("%RH: ");
  Serial.print(mySensor.readFloatHumidity(), 2);
  Serial.println(" %");

  Serial.println();

  delay(10000);

}

```

# Answer
The photo of the board shows that it is for BM E/P 280. It can take either the BME280 chip which does temperature, pressure and humidity, or the BMP280 chip which only does temperature and pressure.

The Register 0xD0 contains an ID which has a value of 0x60 for the BME280 and 0x58 for the BMP280.

Your output shows the ID as 0x58 which means you have a BMP280 temperature pressure chip.

I have been sold one of these, claiming to be a BME280 chip. I shall be asking for a refund.
> 4 votes

# Answer
I'm after getting a batch of these myself...

I can't get it working with the Adafruit libraries, but it will work with the SparkFun Ones

To get data... the wiring is, well, nonstandard.

I can't get it to work in SPI mode, but it will work in I2C mode I'm using an Arduino mega so the pin layout is different from an uno.

Pin no|Label|Arduino pin

Pin 1 |VCC |3.3V

Pin 2 |GND |GND/Ground

Pin 3 |SCL | The SCL pin, on a mega its digital 21

Pin 4 |SCA | The SCA pin, on a mega its digital 20

Pin 5 |CSB |Do not connect

Pin 6 |SDO |3.3V

Weird as it sounds, it needs to be connected to power on 2 separate pins
> 0 votes

# Answer
The breakout board photo shows that it is not the original BOSCH BME280 sensor. The dimensions are off. The original is square. This is how it should look like.
> 0 votes

---
Tags: sensors, arduino-nano
---


title: Connect a TM1627 to ESP32

text:
# Question
Title: Connect a TM1627 to ESP32
I want to control a 7 segment display that has a TM1637 integrated with an ESP32.

Some time ago I created a layout that used an ESP12e but I need more GPIO pins so I'm switching over to an ESP32.

This was how I had it hooked up:

```
CLK -> GPOI14
DIO -> GPIO12

```

I think I did it this way because I had to use the special CLK pin tou can see in this pinout.

Only I don't know if I need to hook them up with special pins on the ESP32. I can't find a good tutorial and I don't have the parts yet to test with.

Do you guys know which pin(s) are suitable for the TM1637?

# Answer
The label CLK on esp8266 is in a context of SPI pins CLK, MISO, MOSI, SS. You had no reason to connect TM1637 CLK to this pin, since with TM1637 you can use any GPIO pins of the MCU for CLK and DIO.
> 1 votes

---
Tags: esp32, 7-segment
---


title: How fast can I read Arduino port D?

text:
# Question
Title: How fast can I read Arduino port D?
I'm trying to see how fast I can read an Arduino IO port. It's being toggled with an random speed /white square wave and I want to see which is faster, the Arduino or the signal. The pin on port D is driven by an open collector comparator (LM311).

So I have this code

```

buffer[0] = PORTD;
buffer[1] = PORTD;
buffer[2] = PORTD;
buffer[3] = PORTD;
buff...

...fer[28] = PORTD;
buffer[29] = PORTD;

```

that I can read the port in burst mode. This code is as fast as I can write I think. I've unrolled a possible loop here. buffer\[\] is a local variable as that seems faster. I'm not an assembly expert so I can't really browse the assembly instructions.

I've added a 500 Ohm pullup resistor to the input pin that I'm interested in. A lower value seems to give more randomly distributed values that a 10k resistor.

I tried timing buffer\[0\] ... buffer\[29\] readings and that returns 4 microseconds with interrupts off. I hope that micros() doesn't need interrupts to function! That would equate to 7.5 million readings /sec. That's about 2 clock cycles per instruction on my 16 MHz board. Can this be right?

How fast can this code run?

# Answer
> 4 votes
Your timing seems reasonable.

At a rough guess, without actually compiling it, your code will turn into something along the lines of:

```
IN R24,PORTD  ;First read   - temp = PORTD     - 1 cycle
ST X+, R24    ;First store  - buffer[0] = temp - 2 cycle
IN R24,PORTD  ;Second read  - temp = PORTD     - 1 cycle
ST X+, R24    ;Second store - buffer[1] = temp - 2 cycle
...

```

This is indeed the fastest way of reading the port if you want to keep the data. Basically it will do an IO read from PORTD using the `IN` instruction which takes 1 clock cycle. Then it will perform a store to SRAM using the `STS` instruction which takes another 2 clock cycles. The store instruction can also post increment the pointer it is using (stored in the R28/R29 X-register pair in my example) for free which saves you time.

So basically that should do 3 clock cycles for every read - one to do the read, and one to do the store, or \>5 million reads per second from a 16MHz clock.

---

There will additionally be a couple of cycles at the beginning to set X-register to point to the buffer. If the buffer is a constant pointer - i.e. the buffer has a fixed address, it will only take two instruction cycles at the beginning to load the address. If it is a non-constant address, it will take up to four as it has to load the address from the SRAM.

# Answer
> 1 votes
I just tried compiling your code with avr-gcc 4.9.2:

```
buffer[0]  = PORTD;
buffer[1]  = PORTD;
...
buffer[29] = PORTD;

```

Here is what I got:

```
in  r24,    0x0b  ; temp = PORTD     – 1 cycle
sts 0x0110, r24   ; buffer[0] = temp – 2 cycles
in  r24,    0x0b  ; temp = PORTD     – 1 cycle
sts 0x0111, r24   ; buffer[1] = temp – 2 cycles
...

```

That's 3 cycles per read, i.e. a 5.33 Mhz reading frequency. For some reason the compiler didn't want to use the `st X+, r24` instruction suggested in Tom Carpenter's answer. Let's try to hint the compiler a little bit, and rewrite the C code as follows:

```
uint8_t * p = buffer;
*p++ = PORTD;
*p++ = PORTD;
...

```

This generated the exact same assembly! The compiler somehow figured out the address of each memory write, and it replaced each occurrence of the pointer `p` by an explicit address. To prevent this kind of “optimization”, let's make the pointer a variable whose value is unknown at compile time:

```
void fill_buffer(uint8_t *p)
{
    *p++ = PORTD;
    *p++ = PORTD;
    ...
    *p++ = PORTD;
}

```

Here is the generated assembly:

```
movw r30,  r24   ; Z = p (Z is the register pair r31:r30)
in   r24,  0x0b  ; temp = PORTD   – 1 cycle
st   Z,    r24   ; *Z = temp      – 2 cycles
in   r24,  0x0b  ; temp = PORTD   – 1 cycle
std  Z+1,  r24   ; *(Z+1) = temp  – 2 cycles
...
in   r24,  0x0b  ; temp = PORTD   – 1 cycle
std  Z+29, r24   ; *(Z+29) = temp – 2 cycles
ret              ; return

```

Still 3 cycles per read. Here the compiler is using the `std` (store with displacement) instruction rather than `st X+` (store with post-increment).

In the end, what instruction the compiler chooses doesn't really matter. All memory access instructions takes two cycles. Then, no matter what you do, repeatedly transferring data from a port to RAM will take 3 cycles per transfer, irrespective of the instruction you choose for the memory write.

Now, this doesn't mean you can't read faster. The AVR CPU core has 32 general purpose registers. Since you are only performing 30 port reads per burst, this means you can use the register file as an ultra-fast temporary buffer. This seems easier to do in assembly, and it will cost you a significant overhead in saving registers to the stack and restoring them afterwards. But the read burst itself will be faster:

```
; declare as:
;   extern "C" void fill_buffer(uint8_t *p);
.global fill_buffer
fill_buffer:

    ; Prologue: save registers and move the pointer.
    push r2         ; save all the registers belonging to the caller:
    push r3         ;  - 18 register to save (r2 – r17, r28, r29)
    ...
    push r28        ;  - 2 cycles per register
    movw r30, r24   ; Z = p (Z = r31:r30 is a pointer register)

    ; Now we can read the port really fast.
    in   r0,  0x0b  ; temp_0  = PORTD – 1 cycle
    in   r1,  0x0b  ; temp_1  = PORTD – 1 cycle
    ...
    in   r29, 0x0b  ; temp_29 = PORTD – 1 cycle

    ; Now save to RAM.
    st   Z+,  r0    ; *Z++ = temp_0   – 2 cycles
    st   Z+,  r1    ; *Z++ = temp_1   – 2 cycles
    ...
    st   Z+,  r29   ; *Z++ = temp_29  – 2 cycles

    ; Epilogue: restore the registers.
    pop  r28        ; restore all the previously saved registers:
    ...
    pop  r3         ;  - 18 registes to restore
    pop  r2         ;  - 2 cycles per register
    clr  r1         ; leave r1 cleared, as required by the ABI
    ret             ; return

```

Now we are reading the port at 16 MHz: one read per cycle!

It turns out that that we can convince the compiler to do exactly this. I had to see to believe, but it works. Something essentially equivalent to the above assembly can be generated from C++ like this:

```
// Quickly read the port into temporaries.
uint8_t temp_0  = PORTD;
uint8_t temp_1  = PORTD;
...
uint8_t temp_29 = PORTD;

// Now save to RAM.
buffer[0]  = temp_0;
buffer[1]  = temp_1;
...
buffer[29] = temp_29;

```

---
Tags: port-mapping
---


title: Relay does not trigger

text:
# Question
Title: Relay does not trigger
Its my first attempt to work with relay I tried to test my relay with this simple code

```
int Relay = 2; void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(Relay,OUTPUT);
}

void loop() {

  digitalWrite(Relay,HIGH);
  delay(1000);
  digitalWrite(Relay,LOW);
  delay(1000);
}

```

Connected to IN -\> Digital 2 GND -\> GND VCC -\> 5V

The only thing is happened is the LED of the relay blinking in every sec. but can not hear the clicking sound from the relay box or testing with a multimeter's diode function the two(NC and COM) OUTs aren't close I tried to test other relays(from the same type) but does not do anything else.

thank you for your help What can be wrong?

# Answer
> 1 votes
NC is "Normally Connected" - this contact is connected to COM ("common") if coil of the relay is not powered - the relay is disconnected.

NO "Normally Open" is connected to COM when the coil of the relay is powered - the relay is connected.

Some relays have the coil powered when the signal from MCU is LOW.

If the coil of the relay doesn't click, but the signaling LED lights up, then VCC is not connected. Check if you plugged the wire really to 5 V on Arduino side.

# Answer
> 0 votes
You need to define `Relay`. If the LED on the relay module is blinking, then you must have defined as pin 2 output, but omitted it from the code you posted. Please post all of the code!

It is good practice for all user variables to start with lowercase, e.g. `relay` not `Relay`. Then the code becomes:

```
relay = 2;
void setup(){
pinMode(relay,OUTPUT);
digitalWrite(relay,"LOW");
}

void loop(){
digitalWrite(relay,"HIGH");
delay(1000);
digitalWrite(relay,"LOW");
delay(1000);
}

```

If the relay still does not click on/off, test the microcontoller voltage output on the `relay` pin using your voltmeter. Check the relay is not dead or mis-wired.

---
Tags: arduino-uno, relay
---


title: Timer interrupt triggers too often

text:
# Question
Title: Timer interrupt triggers too often
The following question is based on the Arduino Pro Mini (8MHz, 3.3V)

I'm in process of developing (yet another) LED strip driver shield. For that I wrote a simple control loop, that adjusts the channel brightness (PWM duty cycle) to a given target value with a smooth transition.

For testing purposes I configured Timer1 with a 0.5Hz interval to randomly assign new target values. This works almost as intended. When watching the values you can see the constant value periods and completely random, fast changing periods in between (picture generated with Arduino built-in plot). The curved, rather smooth lines are the PWM outputs following the target value (that part is confirmed to work):

The relevant code responsible for the changing of the target value is

```
ISR(TIMER1_COMPA_vect) //timer1 interrupt 0.5Hz
{
  for(auto it = 0; it < 4; ++it)
        channel_target[it] = random(0, 255);  // assign a random value between 0..255 (max for pwm)
}

```

My assumption is, that the ISR is called very fast in the fuzzy intervals but since I havn't done much with arduinos yet, I'm not familiar on what kind of background functions might interfere with that.

For completeness the full code:

```
double          channel[4];
uint8_t         channel_target[4];
const double    channel_k_p[4]      = { 0.001, 0.001, 0.001, 0.001 };
const double    channel_k_i[4]      = { 0.01, 0.01, 0.01, 0.01 };
double          err;
const uint8_t   led_pins[4]         = { 3, 5, 6, 9 };
char            serial_buffer[100];

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

    for(auto it = 0; it < 4; ++it)
        channel[it] = 0;

    for(auto it = 0; it < 4; ++it)
    {
        pinMode(led_pins[it], OUTPUT);   // sets the pin as output
        analogWrite(led_pins[it], 0);
    }

    cli();//stop interrupts

    TCCR1A = 0;// set entire TCCR1A register to 0
    TCCR1B = 0;// same for TCCR1B
    TCNT1  = 0;//initialize counter value to 0
    // set compare match register for 1hz increments
    OCR1A = 15624;// = (8*10^6) / (0.5*1024) - 1 (must be <65536)
    // turn on CTC mode
    TCCR1B |= (1 << WGM12);
    // Set CS10 and CS12 bits for 1024 prescaler
    TCCR1B |= (1 << CS12) | (1 << CS10);
    // enable timer compare interrupt
    TIMSK1 |= (1 << OCIE1A);

    //set timer2 interrupt at 500Hz
    TCCR2A = 0;// set entire TCCR2A register to 0
    TCCR2B = 0;// same for TCCR2B
    TCNT2  = 0;//initialize counter value to 0
    // set compare match register for 8khz increments
    OCR2A = 248;// = (8*10^6) / (500*64) - 1 (must be <256)
    // turn on CTC mode
    TCCR2A |= (1 << WGM21);
    // Set CS21 bit for 64 prescaler
    TCCR2B |= (1 << CS21) | (1 << CS20);
    // enable timer compare interrupt
    TIMSK2 |= (1 << OCIE2A);

    sei();  // reactivate interrupts

    randomSeed(analogRead(0));
}

void loop()
{
    for(auto it = 0; it < 4; ++it)
    {
        sprintf(serial_buffer, "%d ",  channel_target[it]);
        Serial.write(serial_buffer);
    }

    for(auto it = 0; it < 4; ++it)
    {
        sprintf(serial_buffer, "%d ", round(channel[it]));
        Serial.write(serial_buffer);
  }
    Serial.write("\n");

    delay(100);
}

ISR(TIMER2_COMPA_vect)  // timer2 interrupt at 1kHz
{
    // ******************************
    // Channel brightness control loop
    for(auto it = 0; it < 4; ++it)
    {
        err = channel_target[it] - channel[it];

        channel[it] += err * channel_k_p[it];           // proportional
        channel[it] -= err * 0.002 * channel_k_p[it];   // integral

        if(channel[it] > 255)
            channel[it] = 255;
        analogWrite(led_pins[it], floor(channel[it]));
    }
}

ISR(TIMER1_COMPA_vect) //timer1 interrupt 0.5Hz
{
  for(auto it = 0; it < 4; ++it)
        channel_target[it] = random(0, 255);  // assign a random value between 0..255 (max for pwm)
}

```

# Answer
The `analogWrite()` function generates a PWM output signal using a hardware timer. Output on pin 3 is driven by timer 2, whereas output on pin 9 is driven by timer 1. Here, you are trying to use these timers for PWM generation **and** for your own code timing at the same time. This cannot work. Either you let the Arduino core library use the timers for `analogWrite()`, or you take them for you, but not both.

The solution to your problem is very simple. Nothing in your code really requires a timer to start with. You can handle both the brightness control loop and the value changes using the technique of the Blink Without Delay Arduino tutorial:

```
const uint32_t TARGET_CHANGE_PERIOD = 500000;
const uint32_t BRIGHTNESS_UPDATE_PERIOD = 1000;

void loop()
{
    uint32_t now = micros();
    static uint32_t last_target_change;
    if (now - last_target_change >= TARGET_CHANGE_PERIOD) {
        last_target_change += TARGET_CHANGE_PERIOD;
        // Change the brightness targets.
    }
    static uint32_t last_brightness_update;
    if (now - last_brightness_update >= BRIGHTNESS_UPDATE_PERIOD) {
        last_brightness_update += BRIGHTNESS_UPDATE_PERIOD;
        // Update the channel brightnesses.
    }
}

```
> 1 votes

---
Tags: led, interrupt, pwm, timers, arduino-pro-mini
---


title: HC-05 Bluetooth module got virus

text:
# Question
Title: HC-05 Bluetooth module got virus
We have a problem. Our HC-05 Bluetooth module got virus. We checked it in serial monitor and found out that the output is wrong. It has a mirrored question marks(⸮)and variables(b⸮, bW⸮, k⸮, U) which is not included in our codes. How can we fix it?

# Answer
> 2 votes
It is unlikely this module got a virus. It sounds more like a data rate mismatch or a noisy connection.

If you get ONLY the strange characters and nothing that you would expect, even in part, then confirm that the serial port speeds are equal on both the Arduino and the HC-05 module.

If you get some expected data, with junk characters mixed in, then check that your wires are secure and that you have connected all grounds from the Arduino and HC-05 module together with the power supply ground.

# Answer
> 0 votes
Your module does NOT have a virus (Who would waste their time writing a virus for a bluetooth module...?!?!). You either have a bad baud rate setting, bad wiring, or you are trying to use a high baud rate coupled with SoftwareSerial.

---
Tags: hc-05
---