# Question
Title: Using millis() to toggle an LED every 500 milliseconds
I thought the code below would toggle an LED every 500 milliseconds. But it does not work. I'm not able to catch the mistake, which must be very silly.

```
void setup() {
  pinMode(3, OUTPUT);
}

void loop() {
  unsigned long cnt=millis();
  if(!(cnt % 500)) {
    PORTD^= (1<<PD3);
  }
}

```

Anyhow the code below works. But why not the previous code?

```
void loop() {
  static unsigned long prev=0;
  // Note: First time case is not handled. As soon as we want to toggle,
  // we must store millis() in prev. In this case this happens after reset and may not be an issue.
  unsigned long current = millis();
  if((unsigned long)(current - prev) >= 500) {
    PORTD^= (1<<PD3);
    prev = current;
  }
}

```

# Answer
> 16 votes
> `if (!(millis() % 500)) ...`

There are two issues with this. The first, and most obvious, is that the condition will be true for a full millisecond. During that millisecond you will be toggling the LED on and off very fast. Whether you end up doing an odd or even number of toggles is anyone's guess.

The second and less obvious problem is that `millis()` skips some values. Roughly one integer every 42 is skipped over. This is because the `millis()` counter is incremented once every 1024 µs, getting 24 µs late on each increment. Once all those delays add up to a full millisecond, `millis()` catches up by incrementing the counter by two milliseconds instead of one. This is why you should never condition something on `millis()` having one specific value.

The almost correct solution to this problem is shown in Juraj's answer:

> `if (millis() > next) ...`

This is not quite correct because it fails each time `millis()` rolls over back to zero. The correct solution is

```
static unsigned long last;
if (millis() - last >= 500) {
    last += 500;
    ...
}

```

Because the subtraction follows the rules of modular arithmetic, this is guaranteed to work across the rollover events.

# Answer
> 4 votes
Your timing doesn't work, because it has a low probability to read a millisecond that is an exact multiple of 500.

Do it this way:

```
  static unsigned long next = millis();
  if (millis() - next > 500) {
    next += 500;

```

# Answer
> 1 votes
```
void loop() {
  unsigned long cnt=millis();
  if(!(cnt % 500)) {
    PORTD^= (1<<PD3);
  }
}

```

At every iteration, `cnt` is set with the number of milliseconds elapsed **since you turned on the Arduino...** So this is not gonna work. At all. What you need is two variables. One that holds the last `millis()` count when you blinked the LED, and for the current `millis()` count:

```
unsigned long lastCount;
void setup() {
  pinMode(3, OUTPUT);
  lastCount=millis();
}

void loop() {
  unsigned long cnt=millis();
  if((cnt-lastCount)>499) {
    PORTD^= (1<<PD3);
    lastCount=cnt;
  }
}

```

# Answer
> 0 votes
I always use this

```
if((millis()/500)%2==0))
{
    PORTD |= (1<<PD3);
}
else
{
    PORTD &= ~(1<<PD3);
}

```

It first divides millis by 500ms. So you get the number of 500ms chucks (since the Arduino started). Then you check to see if this number is even. If so, turn the led pin on. Else turn the led pin off.

---
Tags: arduino-nano
---


# Question
Title: Using a MIDI connector both as MIDI In and Out (not simultaneously)
I asked this question also in Electrical Engineering (stack exchange), however on question is more appropriate on this board (question 5). For completeness, I kept all questions intact, but made question 5 bold.

Electrical Engineering StackExchange Question Link: *Using a MIDI connector both as MIDI In and Out (not simultaneously)*,

In my current (Arduino) project I have (currently) 3 MIDI INs and 2 MIDI OUTs. However, it would be nice if I can configure each of the MIDI connectors as IN or OUT by software (Arduino).

The circuits I am using are:

And

What I would like is to use the connector shown in the above picture as MIDI In OR MIDI out. I have not tried it yet, since I have too many doubts and I do not want to break a component. However, I thought about it (with my limited electronic knowledge), and I think:

1. Pin 2 afaik for MIDI In, normally has +5V. In the MIDI Input circuit it is not connected, but in the MIDI Output circuit, it is connected to GND. I don't think this is good when being used as MIDI out, resulting in a short circuit (?). So I guess I have to make it +5V when used as MIDI Input and GND when used as MIDI Output (so putting HIGH or LOW 'digital' for Arduino).
2. Pins 1 and 3 remain in both circuits untouched (so I assume I can do the same).
3. Pin 4 and 5 is a bit tricky, since they are connected. I think I have to use one or two transistors to create two alternative paths for pins 4 and 5 for MIDI Input and Output. Or can I just set a specific voltage on pins 4 and 5 when used as MIDI In or Out? (and what would those values be?).
4. For the MIDI input, an optocoupler is used, while for MIDI output, directly the Arduino is used. I wonder if I have to use for both an optocoupler (since people might connect it accidentally to a MIDI output from a MIDI device.

**5. I'm not sure how to handle the RX and TX pins ... for 5 MIDI devices, I would need to use 5 RX and TX pins, but the Arduino (Mega) only has 4 of each. But this is probably a question for the Arduino board.**

# Answer
> 1 votes
I suggest you have a look at the 4051 or 4052 chip (datasheet). The 4051 is a 1:8 analog multiplexer while the 4052 contains two 4:1 multiplexers. So basically it allows you to switch one pin on your Arduino to any out of 4 or 8 MIDI circuits.

In the case of TX, it's really simple. You just need a pullup resistor on each output so that the pins don't float when not switched to.

In the case of RX, you have to make sure that you don't miss any transmissions. If your MIDI sources are not sending simultanously, that's easy as well... but probably they are. In that case you cannot use an existing RX UART. Since MIDI is very slow, you could still switch back and forth between the inputs and catch all the bits (you would be writing a software UART then). But if you're not short of pins, it would be much easier to just use SoftwareSerial for one input.

---
Tags: arduino-mega, midi
---


# Question
Title: Arduino keypad and RF 433MHz transmitter problem
So, the basic idea is that user presses a key on keypad, and key that is pressed is sent with RF transmitter. I got individual parts to work(keypad and transmitter), but can't send the actual key. When I try to send it, I get a strange string on the other end. I am convinced its simple issue with my syntax, so if anyone could help me, that would be great. Code is below:

```
#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile
RH_ASK driver; //use this driver for transmitter

#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {10, 9, 8, 7}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 5, 4, 3}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
    Serial.begin(9600);   // Debugging only
    if (!driver.init())
         Serial.println("init failed");
}

void loop()
{

    char key = keypad.getKey();

    if (key){
      Serial.println(key);//outputs correct key
      //transmitter part
//      const char *msg = "Hello World!";
      const char *msg = key;//here is the problem, when i send the string above, it works okay, when I send this, i get strange string on other end
      driver.send((uint8_t *)msg, strlen(msg));
      driver.waitPacketSent();
      Serial.println(key);//outputs correct key
      Serial.println("packet_sent");
    }
}

```

# Answer
The problem is you send a character of type char, thus exactly one byte. However, when you send it you have to give the length and you use strlen. However, msg is an array (at least that is what you want), but that array contains only the character to sent. What you want is to send only 1 character, so use 1 instead of strlen.

Also, you can get rid of the special msg pointer and instead of

```
  const char *msg = key;//here is the problem, when i send the string above, it works okay, when I send this, i get strange string on other end
  driver.send((uint8_t *)msg, strlen(msg

```

use

```
  driver.send(&key, 1);

```

Where &key defines the address (pointer to) key, and since there is always exactly 1 byte in key (the key itself), 1 can be used. To be more safe, you can use sizeof(key) thus

```
  driver.send(&key, sizeof(key));

```

What you also can do is create a string that ends with \0, so the first is the character to send, and strlen can be used, but the easiest way is to set the length to exactly 1.

Actually, using strlen on a string that does not end with \0 can result in strange behavior, because maybe there is no \0 in memory.
> 3 votes

---
Tags: arduino-uno, arduino-micro, remote-control, virtualwire, strlen
---


# Question
Title: How to make a button work a second time in my code?
I am making a security system, and the alarm starts when the button gets pressed. If i turn the alarm off by the serial communication, and want to turn it on again using the button, it will only let the alarm go on for about 0.5 seconds. Does someone see the mistake i'm making, and can help me? Thanks in advance!

```
const int ledrood = 11;
const int ledgroen = 12;
const int buttonPin = 2;
int buttonState = LOW;

int statePin = LOW;
const int trigPin = 9;
const int echoPin = 10;
long duration;
int distance;
bool alarm = false;
int speakerPin = 8;
String Message = "";
String NMessage = "";
String Command = "";
int index = 0;
bool Bericht = true;

void PlaySong()
{
  tone(speakerPin, 4699, 500);
  delay(1000);
  tone(speakerPin, 4699, 500);
  delay(1000);
  tone(speakerPin, 4699, 500);
  delay(1000);
  tone(speakerPin, 4699, 500);
  delay(1000);
  tone(speakerPin, 4699, 500);
  delay(1000);
  tone(speakerPin, 4699, 500);
  delay(1000);
  tone(speakerPin, 4699, 500);
  delay(1000);
}
void alarmaan()
{
 alarm = true;

  digitalWrite(ledrood, HIGH);
  digitalWrite(ledgroen, LOW);
  digitalWrite(trigPin, LOW);

 }

void AlarmUit() {
  Serial.println("alarm uit");
  alarm = false;
  digitalWrite(ledgroen, HIGH);
  digitalWrite(ledrood, LOW);
  digitalWrite(trigPin, LOW);

 }
void setup() {
  pinMode(ledrood, OUTPUT);
  pinMode(ledgroen, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600);
 }
String Doorsturen() //Methode om te communiceren via de serial monitor
{
 if (Serial.available() > 0)
  {
   char readChar = (char) Serial.read();
   NMessage = NMessage + readChar;
  }
  if (NMessage.startsWith("#") && NMessage.endsWith("%"))
  {
   index = NMessage.indexOf("%");
   NMessage = NMessage.substring(1, index);
   Serial.println(NMessage);
   Command = NMessage;
   NMessage = "";
   Bericht = true;
  }
  else if (NMessage.endsWith("%"))
 {
   NMessage = "";
 }
 return Command;
}
void loop() {
 Message = Doorsturen();
 int buttonState = digitalRead(buttonPin);
 digitalWrite(trigPin, HIGH);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = duration * 0.034 / 2;
 Serial.print("Distance: ");
 Serial.println(distance);

 if (alarm == false) {
   digitalWrite(ledgroen, HIGH);
 }

 if (Message == "alarm_off")
 {
   AlarmUit();
   Message = "";
 }
  if (Message == "1234")
  {
   AlarmUit();
   Message = "";
  }
  if (Message == "aan") {
   alarmaan();
   Message = "";
   }

  if (alarm == false) {
   if (buttonState == HIGH) {
    delay(50);
    while (digitalRead(buttonPin) == HIGH) {}
    alarmaan();
    Serial.println("fout");
   }
  }

  if (distance < 10 && alarm == true) {
   PlaySong();
  }

 if (alarm == true) {
   if (buttonState == HIGH) {
    delay(50);
    while (digitalRead(buttonPin) == HIGH) {}
    alarmaan();
    Serial.println("Test");
   }

 }
}

```

# Answer
The problem is that `Message = "";` doesn't actually do anything, because the next time `doorsturen` is called, it will just load the previous command from the `command` variable. I'd suggest having the `doorsturen` function only return the command once, and not on consecutive calls.

```
String Doorsturen() //Methode om te communiceren via de serial monitor
{
  Command = "";
  if (Serial.available() > 0)
  {
    char readChar = (char) Serial.read();
    NMessage = NMessage + readChar;

    if (NMessage.startsWith("#") && NMessage.endsWith("%"))
    {
      index = NMessage.indexOf("%");
      NMessage = NMessage.substring(1, index);
      Serial.println(NMessage);
      Command = NMessage;
      NMessage = "";
      Bericht = true;
    }
    else if (NMessage.endsWith("%"))
    {
      NMessage = "";
    }
  }
  return Command;
}

```

see comment in the code

```
if (alarm == false) {
  if (buttonState == HIGH) {
    //here you set alarm to true
  }
}

...

if (alarm == true) { //now this if statement is true
  if (buttonState == HIGH) {//also buttonState is still high, because it's never updated after you set alarm to true

  }

```

to fix do this

```
if (alarm == false) {
   if (buttonState == HIGH) {
    delay(50);
    while (digitalRead(buttonPin) == HIGH) {}
    delay(50);// this is to negate switch bounce, on release, from interfering
    buttonState = false;// add this line
    alarmaan();
    Serial.println("fout");
   }
  }

```
> 1 votes

---
Tags: arduino-uno
---


# Question
Title: How to make a 5-volt relay work with NodeMCU?
I have hooked up 2 channel 5-volt relays with NodeMCU v1.0 as shown in the fritzing below.

Relay are powered with a different power source than NodeMCU.

As of now, I am powering the NodeMCU from my laptop and the relay board from a 5-volt battery.

Below is the code I have written:

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "said.";
const char* password = "secret";
ESP8266WebServer server ( 80 );
const int led = 13;
const int outputLed = 12;

void turnOnRelayOne(){
  digitalWrite (outputLed, 1);
  digitalWrite (5, HIGH); //GPIO 5 // Relay 1
  server.send (200, "text/html", "Relay 1 turned on.");
  digitalWrite (outputLed, 0);
}

void turnOnRelayTwo(){
  digitalWrite (outputLed, 1);
  digitalWrite (4, HIGH); //GPIO 4 // Relay 2
  server.send (200, "text/html", "Relay 2 turned on.");
  digitalWrite (outputLed, 0);
}

void handleRoot() {
  digitalWrite ( led, 1 );

  char temp[400];
  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  snprintf ( temp, 400,

             "<html>\
  <head>\
    <meta http-equiv='refresh' content='5'/>\
    <title>NodeMCU hooked to Relay Board</title>\
    <style>\
      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
    </style>\
  </head>\
  <body>\
  <h1>Hello from NodeMCU!</h1>\
    <p>Uptime: %02d:%02d:%02d</p>\
  </body>\
</html>",

          hr, min % 60, sec % 60
           );
  server.send ( 200, "text/html", temp );
  digitalWrite ( led, 0 );
}

void handleNotFound() {
  digitalWrite ( led, 1 );
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  for ( uint8_t i = 0; i < server.args(); i++ ) {
    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  }

  server.send ( 404, "text/plain", message );
  digitalWrite ( led, 0 );
}

void setup ( void ) {
  pinMode ( led, OUTPUT );
  pinMode(10, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(outputLed, OUTPUT);
  digitalWrite ( led, 0 );
  Serial.begin ( 9600 );
  WiFi.begin ( ssid, password );
  Serial.println ( "" );

  // Wait for connection
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  Serial.println ( "" );
  Serial.print ( "Connected to " );
  Serial.println ( ssid );
  Serial.print ( "IP address: " );
  Serial.println ( WiFi.localIP() );

  if ( MDNS.begin ( "esp8266" ) ) {
    Serial.println ( "MDNS responder started" );
  }

  server.on ( "/", handleRoot );

  server.on ( "/inline", []() {
    server.send ( 200, "text/plain", "this works as well" );
  } );

  server.on("/relay1", turnOnRelayOne);
  server.on("/relay2", turnOnRelayTwo);
  server.onNotFound ( handleNotFound );
  server.begin();
  Serial.println ( "HTTP server started" );
}

void loop (void) {
  server.handleClient();
}

```

When I execute the URL: `192.168.1.8/relay1` the outputLed blinks as per the logic in `turnOnRelayOne`.

But neither of the relays turns on. Please help.

# Answer
I have several of these modules. They have an optional opto-isolator built-in, but you have to remove the jumper to use it.

* Connect your GPIO trigger as you have it
* Run the relay's `Vcc` and `Gnd` pins to the MCU, not the power plug.
* connect the power plug's +5v to the left-most pin, where the jumper once stood: `JDVcc`
* connect the power plug ground to the MCU or the open common `Gnd` on the left-group of pins.

Now your relay coil(s) will be powered by the 5v plug, but the relay's logic and control are handled by the MCU.
> 8 votes

# Answer
The relay has no reference for what the voltage from the NodeMCU is. Since the power supplies of the two devices are isolated (from each other; the laptop may not be isolated itself, but the battery certainly should be) you can (and in fact *must*) connect the grounds of the relay board and the NodeMCU together. If neither power supply is isolated or if you are unsure if they are isolated then you should use an optoisolator in order to prevent potential power issues.
> 3 votes

# Answer
I believe the problem could be that the relay is 5v but the signal coming from the NodeMCU is 3.3v. You may need do something like boost the signal to 5v or implement a logic level shifter, for example.

Here's a related post: https://electronics.stackexchange.com/questions/213051/how-do-i-use-a-5v-relay-with-a-3-3v-arduino-pro-mini
> 2 votes

# Answer
How are you powering your ESP-12E? This is not included in your diagram. I have had success using the VU pin (5V output) when powering from the Micro-USB. You would then connect VCC to VU, GND to GND, and Signal to your GPIO4. If you are powering your ESP-12E from a 5v power supply directly into the VIN pin, then I would power the Relay from the same 5V power supply. you would connect the + from the power supply to VIN (ESP) and VCC (relay) all the grounds tied together then the GPIO4 to Signal.
> 0 votes

# Answer
This relay module works differently. It is on when the signal is LOW and it turns off when the signal is HIGH (3v3V on the NodeMCU) So you only need to modify the code in the two functions to be LOW instead of HIGH Also make sure the NodeMCU and the relay module have a common ground.

```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char* ssid = "said.";
const char* password = "secret";
ESP8266WebServer server ( 80 );
const int led = 13;
const int outputLed = 12;

void turnOnRelayOne(){
  digitalWrite (outputLed, 1);
  digitalWrite (5, LOW); //GPIO 5 // Relay 1
  server.send (200, "text/html", "Relay 1 turned on.");
  digitalWrite (outputLed, 0);
}

void turnOnRelayTwo(){
  digitalWrite (outputLed, 1);
  digitalWrite (4, LOW); //GPIO 4 // Relay 2
  server.send (200, "text/html", "Relay 2 turned on.");
  digitalWrite (outputLed, 0);
}

void handleRoot() {
  digitalWrite ( led, 1 );

  char temp[400];
  int sec = millis() / 1000;
  int min = sec / 60;
  int hr = min / 60;
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  snprintf ( temp, 400,

             "<html>\
  <head>\
    <meta http-equiv='refresh' content='5'/>\
    <title>NodeMCU hooked to Relay Board</title>\
    <style>\
      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
    </style>\
  </head>\
  <body>\
  <h1>Hello from NodeMCU!</h1>\
    <p>Uptime: %02d:%02d:%02d</p>\
  </body>\
</html>",

          hr, min % 60, sec % 60
           );
  server.send ( 200, "text/html", temp );
  digitalWrite ( led, 0 );
}

void handleNotFound() {
  digitalWrite ( led, 1 );
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  for ( uint8_t i = 0; i < server.args(); i++ ) {
    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  }

  server.send ( 404, "text/plain", message );
  digitalWrite ( led, 0 );
}

void setup ( void ) {
  pinMode ( led, OUTPUT );
  pinMode(10, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(outputLed, OUTPUT);
  digitalWrite ( led, 0 );
  Serial.begin ( 9600 );
  WiFi.begin ( ssid, password );
  Serial.println ( "" );

  // Wait for connection
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  Serial.println ( "" );
  Serial.print ( "Connected to " );
  Serial.println ( ssid );
  Serial.print ( "IP address: " );
  Serial.println ( WiFi.localIP() );

  if ( MDNS.begin ( "esp8266" ) ) {
    Serial.println ( "MDNS responder started" );
  }

  server.on ( "/", handleRoot );

  server.on ( "/inline", []() {
    server.send ( 200, "text/plain", "this works as well" );
  } );

  server.on("/relay1", turnOnRelayOne);
  server.on("/relay2", turnOnRelayTwo);
  server.onNotFound ( handleNotFound );
  server.begin();
  Serial.println ( "HTTP server started" );
}

void loop (void) {
  server.handleClient();
}

```
> -1 votes

---
Tags: esp8266, relay, nodemcu
---


title: ATMega328p (Arduino) Timer1 set-up

text:
# Question
Title: ATMega328p (Arduino) Timer1 set-up
I am trying to measure AC power using an Arduino with an Atmega328p. In summary, I want to use timer1 to make an interrupt every 400us where I measure two ADC channels (A0 and A1) and put them into an array. The problem is that instead of measuring five mains periods (mains frequency = 50Hz so 20ms * 5), I get instead 13 of these periods (260ms). What am I doing wrong?

```
volatile int sample_incremental = 0;

void setup() {
      Serial.begin(115200);
      pinMode(voltagePin, INPUT);
      pinMode(currentPin, INPUT);
      set_sample_interrupt();
      sei();
    }

void set_sample_interrupt() {
  //Count to 400us
  OCR1A = 99;
  //Mode 4, CTC
  TCCR1B |= (1 << WGM12);
  //Enable interrupt
  TIMSK1 |= (1 << OCIE1A);
  //Prescaler 64
  TCCR1B |= (1 << CS11) | (1 << CS10);
}

ISR (TIMER1_COMPA_vect) {
  // action to be done every 400 usec
  current_sample[sample_incremental] = analogRead(currentPin) - 504;
  voltage_sample[sample_incremental] = analogRead(voltagePin) - 512;
  if (sample_incremental < (SAMPLES * PERIODREADS))
    sample_incremental++;
  else {
    //Disable interrupt
    TIMSK1 &= ~(1 << OCIE1A);
    sample_incremental = 0;
    finishedReading = true;
  }
}

```

Where after I do one reading, I stop the interrupt, and SAMPLES * PERIODREADS = 250.

# Answer
The Arduino core library configures the Timer 1 for phase-correct PWM at about 490 Hz. Then you are setting some configuration bits in the timer's control registers without clearing the bits that had previously been set by the Arduino core. If you want to use the timer for your own purposes, and configure it by yourself, you should completely overwrite the core's configuration with your own. For that, use the `=` operator rather than `|=`, as in:

```
OCR1A  = 99;                         //Count to 400us
TIMSK1 = (1 << OCIE1A);              //Enable interrupt
TCCR1A = 0;
TCCR1B = (1 << WGM12)                //Mode 4, CTC
       | (1 << CS11) | (1 << CS10);  //Prescaler 64

```
> 1 votes

---
Tags: power, atmega328, timers
---


title: Conditional randomization gets stuck

text:
# Question
Title: Conditional randomization gets stuck
First-time poster here...

I have the following code to randomize note values and store them in an array `loop1[i]`, where `i` is a specific step in the loop:

```
nextNote = random(-2, 3);
note = note + nextNote;

loop1[i] = note;

while (loop1[i] == loop1[i - 1] ||
       loop1[i] == loop1[i - 2] ||
       note > 6 ||
       note < 0) {
  nextNote = random(-2, 3);
  note = note + nextNote;
  loop1[i] = note;
}

```

(I hope this is clear enough).

Now, it usually works to a certain point until the sketch loops forever in order to randomize an allowed number. Therefore, my questions are:

Running an ATmega 2560, is this actually a task too demanding for the processor or should I suspect that it's not working properly?

How can I optimize the code, but retain the conditions above in order to avoid the loop getting stuck?

# Answer
I think you have a problem with your math here, not with your code. What you are simulating is very similar to a 1-dimensional random walk. According to the linked MathWorld page, for such a process “the most probable number of sign changes in a walk is 0”.

If, at some point in your program, the loop starts with `note == 6`, and then it starts randomly going up, there is a sizable probability for it to never go back to values below 7.

---

**Edit**: One possible solution could be to avoid the random-walk notion and instead repeat the random choice always from the same starting point.

```
int oldNote = note;  // starting point
do
    note = oldNote + random(-2, 3);
while (
    note == loop1[i - 1] ||
    note == loop1[i - 2] ||
    note > 6 ||
    note < 0);
loop1[i] = note;

```
> 1 votes

# Answer
Some reasons why it will not work:

* My feeling is that `i` gets too big, i.e. it is higher than the length of the array you are using. That can cause crashes, or at least unpredicted results. You can easily check this by printing the value of `i` (and check against the maximum value).
* I don't see problems with the while loop (although I would use brackets around `note > 6` and around `note < 0`, but I don't think this is really needed.
* If the value gets below 0 or higher than 6, still random values are added, assume the value is +10... then it might take a lot of time (if ever) for that value to reach max 6 again. The same is true for values \< 0. Maybe you should never allow values of less than 0 and higher than 6 anyway, or making the random values in such a way they tend to go towards the average (3).

Tip to debug:

However, the easiest way to debug this is to print all relevant variables (e.g. `nextNote`, `note`, `i`, the last two notes `loop[i-2]`, `loop[i-1]` and the current note `loop[i]`... Also print a line inside the while loop so you know when you skip it or not. This probably will give you enough information to see what is wrong.
> 1 votes

# Answer
The line `loop1[i] = note` doesn't belong in the loop (or above it); you're not changing `i` in the loop, so you're just rewriting the same location over and over again.

As for the loop itself, what sort of use case do you have for this, and what sort of distribution do you want? Waiting until it's between 0 and 6 is horribly inefficient. You need to decide what sort of distribution you want and implement it more directly. For instance, you could have a piecewise quadratic distribution by getting a random number between zero and sqrt(3), then squaring the result, and then randomly choosing whether to subtract the result from 6.
> 0 votes

---
Tags: code-optimization, atmega2560
---


title: How can I tell what programmer to use?

text:
# Question
Title: How can I tell what programmer to use?
I have a bunch of different dev boards for different projects. What I have been getting very confused about is what board needs what programmer from the Tools \> Programmer menu.

I wish the selection had the option to be partially automated for the board selection. But it's evidently not. Part of my problem is that if you choose the wrong programmer, some boards seem to work. Others read but won't write, or will write to some spaces, but not others. Or, you might get other cryptic errors that sound a lot like failed hardware. Have a look at this message for an example:

OK, so let's say I have some random dev board. How can I know what programmer I should use? Assume the manufacturer's documentation mentions nothing about it...

# Answer
Generally the **Tools \> Programmer** selection is only used for **Tools \> Burn Bootloader** and **Sketch \> Upload Using Programmer** and is not used for standard uploads. So for standard uploads you can set it to anything you like because it will have no effect.

The most notable exception is the Adafruit Trinket, which does require you to select **Tools \> Programmer \> USBTinyISP** even though you are uploading through the USB socket on the Trinket board without a separate ISP programmer.

You will also find some 3rd party hardware packages that are not written for boards with an Arduino style serial bootloader and so treat a standard upload as an "Upload Using Programmer" for the sake of convenience. Examples are MicroCore and the "Barebones ATmega Chips (no bootloader)" hardware package. In this case the correct Programmer menu selection is dependent on which model of ISP programmer you are using.

So regarding the question "How can I tell what programmer to use?": If you're doing a standard upload, start by assuming it doesn't matter. If that doesn't work, read the documentation!

If you're doing a **Tools \> Burn Bootloader** or **Sketch \> Upload Using Programmer** (or holding shift while pressing the "Upload" button) then you should select the model of the ISP programmer you're using.
> 4 votes

# Answer
The clock and the timing signals and the voltage levels do not always match. And perhaps something is connected to the pins already which makes it harder for the programmer.

I use mostly the cheap USBasp version 2 (the text "version 2" is often written on the PCB). They are based on the USBasp from Thomas Fischl.

Sometimes there is a timing conflict. Sometimes that can be corrected with options for avrdude or with the avrdude.conf file, sometimes I have to grab an older or newer USBasp programmer.

What do you mean by choosing the wrong programmer? If there is a programmer connected to the computer, then select that type of programmer. Do you have a programmer?
> 0 votes

---
Tags: arduino-ide
---


# Question
Title: Why does void loop() stop after some samples?
I am not getting any compile time error. After some samples of data `void loop()` stops executing. Please let know what the problem is. Below is my code.

Thanks and regards Thippeswamy

```
#include<SPI.h>
float amplitude=1.5;
int freq1=20; int freq2=12;
int k=20;float A= amplitude*k;
int Fs=10550; float sine[5000]; float Fs1=3000;
int i=0;int reg1=1; int reg2=0;
int sample1=Fs/freq1; float sample2=Fs1/freq2;

void setup() {
  int SS=10;
  pinMode(SS, OUTPUT);
  SPI.begin();
}

void data(int reg, int data) {
  digitalWrite(SS,LOW);
  SPI.transfer(reg);
  SPI.transfer(data);
  digitalWrite(SS,HIGH);
}

void loop() {
  for(int j=0;j<sample1||i<sample2||i>=sample2);j++) {
    float s=A*sin((2*3.14*freq1*j)/Fs);
    sine[j]=s+190;
    data(reg1,sine[j]);
    if(i<=sample2) {
      float s=A*sin((2*3.14*freq2*i)/Fs1);
      sine[i]=s+190;
      data(reg2,sine[i]);
      i++;
    } else if(i>sample2) {
      float s=A*sin((2*3.14*freq2*i)/Fs1);
      sine[i]=s+190;
      data(reg2,sine[i]);
      i++;
    }
  }
}

```

# Answer
> ```
> float sine[5000]
> ...
> sine[j]=s+190;
>
> ```

A float takes 4 bytes. You are allocating 5000 of them which is 20000 bytes. The Uno has 2048 bytes of RAM. Thus you are running out of RAM and overwriting something you shouldn't be.

---

As pointed out on the Arduino forum, your `for` loop which tests for:

```
i < sample2 || i >= sample2

```

will always be true. Of course `i` will be *either* **less than** or **greater than or equal to** `sample2`.
> 4 votes

---
Tags: arduino-uno, programming, c, spi, signal-processing
---


# Question
Title: Basic Arduino Question. Trying to turn off leds turned on through the serial monitor by using a push button
I'm new to using the serial monitor. I have a code set up so that LEDs turn on when I type an input on the keyboard. I know how to turn them off using a keyboard but I and can't figure out why the leds won't turn off when I press a push button.

```
    #define led1 10 //10th,
    #define led2 11 //11th
    #define led3 12 //12th
    #define led4 13 //13th
    #define ButtonA 9

    int ButtonState;
    int ButtonState2;
    int state;
    int StateNow;
    int PreviousState = HIGH;

    void setup(){
      pinMode(led1,OUTPUT);
      pinMode(led2,OUTPUT);
      pinMode(led3,OUTPUT);
      pinMode(led4,OUTPUT);
      pinMode(ButtonA,INPUT_PULLUP);
      Serial.begin(9600);
      Serial.println("Enter ch a, b, c, or d:");
    }

    void loop() {
    if (Serial.available())
    {
      ButtonState = digitalRead(ButtonA);
      delay(10);
      ButtonState2 = digitalRead(ButtonA);  //debounce
      if (ButtonState != ButtonState2)
      {
        StateNow = ButtonState2;
      }
      else
      {
        StateNow = ButtonState;
      }
      if(StateNow == LOW && PreviousState == HIGH)
  {
    digitalWrite(led1,LOW);
    digitalWrite(led2,LOW);
    digitalWrite(led3,LOW);
    digitalWrite(led4,LOW);
    Serial.println("Turned off all LEDs");
    PreviousState = LOW;
  }
  else if(StateNow == HIGH && PreviousState == LOW)
  {
    PreviousState = HIGH;
  }
  state = Serial.read();
  if (state == 'a' || state == 'A')
  {
    digitalWrite(led1,HIGH);
    Serial.println("Turned on led 1");
  }
  else if (state == 'b' || state == 'B')
  {
    digitalWrite(led2,HIGH);
    Serial.println("Turned on led 2");
  }
  else if (state == 'c' || state == 'C')
  {
    digitalWrite(led3,HIGH);
    Serial.println("Turned on led 3");
  }
  else if (state == 'd' || state == 'D')
  {
    digitalWrite(led4,HIGH);
    Serial.println("Turned on led 4");
  }
}

}

```

The LEDs turn on properly and I know the circuit is wired correctly so it's definitely something I'm missing in the software

# Answer
To turn off all leds when button is pressed, you must detect a rising or falling in the button signal.

In your code you detect the change only if serial is available, but you should do it in the loop.

The simple way to detect the change is doing this in every loop:

```
if (StateNow != PreviousState) {
  if (StateNow == LOW && PreviousState == HIGH) //button pushed
  {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
    digitalWrite(led3, LOW);
    digitalWrite(led4, LOW);
    Serial.println("Turned off all LEDs");
  }
  PreviousState = StateNow;
}

```

I simplify your code and add some comments:

```
#define led1 10 //10th,
#define led2 11 //11th
#define led3 12 //12th
#define led4 13 //13th
#define ButtonA 9

int state;
int StateNow;
int PreviousState;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(ButtonA, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Enter ch a, b, c, or d:");
  PreviousState = digitalRead(ButtonA);
}

void loop() {
  //detect changes in button signal to turn off leds
  StateNow = digitalRead(ButtonA);
  if (StateNow != PreviousState) {
    if (StateNow == LOW && PreviousState == HIGH) //button pushed
    {
      digitalWrite(led1, LOW);
      digitalWrite(led2, LOW);
      digitalWrite(led3, LOW);
      digitalWrite(led4, LOW);
      Serial.println("Turned off all LEDs");
    }
    PreviousState = StateNow;
  }

  //check serial biffer to turn on leds
  if (Serial.available())
  {
    state = Serial.read();
    if (state == 'a' || state == 'A')
    {
      digitalWrite(led1, HIGH);
      Serial.println("Turned on led 1");
    }
    else if (state == 'b' || state == 'B')
    {
      digitalWrite(led2, HIGH);
      Serial.println("Turned on led 2");
    }
    else if (state == 'c' || state == 'C')
    {
      digitalWrite(led3, HIGH);
      Serial.println("Turned on led 3");
    }
    else if (state == 'd' || state == 'D')
    {
      digitalWrite(led4, HIGH);
      Serial.println("Turned on led 4");
    }
  }
}

```
> 1 votes

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


# Question
Title: What's the difference between DDRB and pinMode?
It's my understanding that the following lines are equivalent. They seem to be interchangeable in my sketch:

```
DDRB = 1<<DDB0;

```

and

```
pinMode(0, OUTPUT);

```

Is the first form (`DDRB...`) setting a micro-controller address directly? Is that assembler?

And is the second form (`pinMode`) using an included library? Maybe the `avr/io.h` library?

*On a Digispark ATTiny85*.

# Answer
Yes, on a simple microcontroller like the ATTiny the two lines of code are equivalent. The function `pinMode(...)` just looks up what pins relate to what ports in a table and set the right registers.

Using `DDRB` instead of `pinMode(...)` is fine as long as you are never going to run your code on anything else (or give it to anyone else to run), since you have now hard coded into your sketch what pins are to be used. It is more efficient to use `DDRB` though. You sacrifice portability for efficiency.

However, for more complex microcontrollers that have many many functions on a single pin, just manipulating `DDRB` (or the equivalent on the target microcontroller) may not be enough. You may need to switch the pin into GPIO mode, disable analog inputs on the pin, or other operations as well. All that will be wrapped up in the `pinMode(...)` function for you by the Arduino API so you don't need to worry about it.

So, in short, if you don't care about portability, and you do care about efficiency and code size (which may well be the case on an ATTiny) then yes use `DDRB` and its friends.
> 1 votes

# Answer
> DDRB

is a register. Exactly: Port B Data Direction Register. See datasheet for ATtiny, chapter 10.4. Register Description and 10.2.1 Configuring the Pin. This part will explain why

> DDB0

value was used. Using this way of setting direction of a pin is much faster than `pinMode(0, OUTPUT);`
The possible problem is when you want to use same code to program different Arduino. In this case you have to remember to check all direct registers operations.
> 1 votes

---
Tags: pins, sketch, avr
---


# Question
Title: How to connect dual brushless motors to arduino
I'm planning on making a Force Feed Back racing wheel with arduino.Saw a lot of tutorials but it uses brushed DC motors ,couldn't find how to connect dual brushless motor for force feed back.

This the motor I want to use : http://www.dx.com/p/chrgm25bl2418-dc-brushless-motor-with-built-in-drive-24v-12v-470930#.WkurLcvhVAg

. .

# Answer
It looks like you provide the correct voltage to the VCC and GND pins to power it, and connect the CW/CCW and PWM (and GND of course) to your Arduino - the first to control the direction, and the second to a PWM pin to control the speed.

You can use the FG pin to monitor the speed from the internal hall effect sensor if you want.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Do I need to solder wires to my tilt sensor?
I am using the Arduino Starter Kit and I am on project 8. The picture of the sketch in the book is not clear because it shows the tilt sensor seemingly resting sideways, which is not the way that it connects. If you insert the pins into the board the sensor will always be standing and there will be no way to turn it. I was thinking you might have to solder wires to the pins. Does anyone know? -Thanks Edit: Perhaps this picture will help:

# Answer
> 1 votes
I don't have the starter kit but I have a tilt ball sensor:

My guess is that there is a ball inside it, and it connects the wires, like this:

This is confirmed by measurement.

---

I suggest you either solder wires to it, or push the wires into your breadboard. As you can imagine from the diagram, the contacts will be closed if the ball (or mercury or whatever it is) is downwards. In other words, if the leads are facing down. As you tilt it, the ball will move away from the two wires, breaking the connection. You may have to tilt it quite a lot for this to happen.

---

*(Edited to add)*

I see from the Arduino Starter Kit page that the tilt sensor works like this:

This shows that my guess was pretty accurate. :)

There are four pins, so I imagine that the ball would connect four of them if held upright, and various combinations if tilted forwards or sideways.

---

> If you insert the pins into the board the sensor will always be standing and there will be no way to turn it.

Well, you could tilt the breadboard, yes?

However I agree that if you want to tilt just the sensor, then soldering wires to it would seem quite sensible.

I think the starter kit is there to show you the concepts. There is nothing stopping you tilting the entire breadboard to see how it works. In practice you would mount the sensor in such a way that it activated when moved from position A to position B, whatever that is.

# Answer
> 0 votes
I have the starter kit with the exact same tilt sensor. In my experience it does sorta work. In that you can plug it in the breadboard and it will sit snugly and have a stable connection, but two and two of the connectors will be shorted so you can't use all four independently. And it will respond to tilting the board, at least in one specific direction. So it does work without soldering, at least for learning/demonstration purposes.

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


# Question
Title: Controlling amplifier using remote control jack
Many older amplifiers support wired remote control through connector jacks or ports. My 10-year old Marantz also supports this function, using a simple RCA connector.

Originally these were used with external IR receivers when the unit was not kept in plain sight.

I wonder if there is a way to control the amplifier using an Arduino, which probably means by generating the required signal over the connector instead of receiving it from an IR receiver. Any pointer to a similar project is appreciated as well.

# Answer
According to this thread on remotecentral the signal on the RCA connector is just the inverted signal that the IR-LED receives. So if you load an RC5 library and invert the output (0=1 and 1=0), you should be able to send codes to that connector with an arduino. Or even better, use an ESP8266 and control it over wifi ;)
The RC5 codes and their functions are in this nice excel sheet or use this information if you want to send raw hex
> 3 votes

---
Tags: remote-control, home-automation
---


title: Converting (char*)variable to int

text:
# Question
Title: Converting (char*)variable to int
I have the following code:

```
      uint8_t buf[1];
      uint8_t buflen = 1;
      if (driver.recv(buf, &buflen)) // Non-blocking
         {
            int i;
            // Message with a good checksum received, dump it.
            Serial.print("Message: ");
            Serial.println((char*)buf);//this prints out okay
            highPins[(char*)buf] = 1;
         }

```

The problem is in highPins\[(char\*)buf\]. highPins is array, and in (char\*)buf I get index number. When I display it with Serial.println, it shows the number, but here it does not. I am guessing its because (char\*)buf is not a number. I have tried to convert it to int with few functions I have found online, but it was unsuccessful. Any help is appreciated :)

# Answer
I would suggest improving your code slightly as follows:

```
  uint8_t buf;
  uint8_t buflen = 1;
  if (driver.recv(&buf, &buflen)) // Non-blocking
     {
        int i;
        // Message with a good checksum received, dump it.
        Serial.print("Message: ");
        Serial.println(buf);//this prints out okay
        highPins[buf] = 1;
     }

```

The important point is that you do not need to declare `buf` as an array of just one element, but just declare the element itself (as `uint8_t`) and pass its address (`&buf`) to `driver.recv(...)`.

As @Majenko suggested, you should alos check `buf` before using it as an index to `highPins` array, in order to avoid using an index bigger than teh array size.
> 1 votes

# Answer
The function you want is `atoi`.

```
int pinno = atoi((char *)buf);

```

I would suggest checking that the result is in the right range before using it.
> 0 votes

---
Tags: arduino-uno, serial, data-type
---


title: Arduino ADS1115 PGA settings

text:
# Question
Title: Arduino ADS1115 PGA settings
I am trying to use an external ADC with my UNO for very precise measurement of my signal. The ADC which I am using is ADS1115.

http://henrysbench.capnfatz.com/henrys-bench/arduino-voltage-measurements/arduino-ads1115-module-getting-started-tutorial/

This is the site which I am referring to.It says the default reference voltage of the PGA gives a resolution of 188microvolt per bit.It also indicates towards changing the reference voltage to 2.048, to still increase the resolution per bit.

Can you please guide me in how to achieve this 2.048V.

Update: https://www.google.co.in/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwiFpq3P89vNAhXJro8KHa6IC04QFggpMAI&url=https%3A%2F%2Fcdn-learn.adafruit.com%2Fdownloads%2Fpdf%2Fadafruit-4-channel-adc-breakouts.pdf&usg=AFQjCNGhdMw47MRlXolMiMoHdsTwKMwMow

It seems that by adjusting the gain (page number 16-17 of 18) we can achive it.

WHat I need to know now, is where should I put that piece of code

> > > ads1115.setgain(...)

in void loop() or in void setup()

Thanks

Anupam

# Answer
Reference voltage inputs are usually high impedance requiring little current. So you can get by with simple circuits like a resistor and zener diode. Here is just one I happened across:

Do some research to find out more about this.

For your specific case, you should read the ADS1115 specification sheet. As this ADC chip has it's own built in voltage reference.

In the Arduino paradigm, tasks that are to be executed once at the beginning of a program are placed in the setup() method. Tasks which are to be executed repeatedly are placed in the loop() method. As setting the gain of the ADC appears to only be done once (consult the ADS1115 PDF linked to above), it appears to fall into the former category.

Added later...

I changed the circuit diagram after I realized it was a bad example for creating an Analog to Digital Converter voltage reference.
> 2 votes

# Answer
`setup()` runs once at the beginning after the program is run. However, `loop()` runs continuously after that.

The `setgain()` instruction is needed once at the beginning, so it should be in `setup()` function.

good luck!
> 0 votes

---
Tags: arduino-uno, adc
---


title: Parsing serial port data

text:
# Question
Title: Parsing serial port data
Hello I found an Arduino project that works with serial port parsing and it had very interesting parsing code. I am trying to use it in my project but I still don't understand some lines and what is going there. (I marked them with ???).

```
char inData[82]; //create 82 char array
byte index = 0; //index byte (0 - 255)
String string_convert; //String
int PCdata[20]; //int array

void setup() {
  Serial.begin(9600); //init port
}

void loop() {
  parsing(); //loop the function
}

void parsing() {
  while (Serial.available() > 0) {
    //while there is data in serial buffer (128 bytes)
    char aChar = Serial.read(); //aChar - current symbol in buffer
    if (aChar != 'E') {
      //if aChar isnt the 'E' (End) symbol do:
      inData[index] = aChar;
      //(inData - array, index - loop № counter) write all Buffer to the array
      index++; //index + 1 - loop count
      inData[index] = '\0';
      //set the next position to '\0' or null symbol
    } else {
      //if aChar or current buffer symbol is 'E' (End) do:
      char *p = inData; //create inData address pointer
      char *str; //create pointer
      index = 0; //set counter to 0
      String value = ""; //create string
      while ((str = strtok_r(p, ";", &p)) != NULL) { //???
        string_convert = str; //???
        PCdata[index] = string_convert.toInt(); //???
        index++; //counter + 1 - loop count
      }
      index = 0; //counter to 0
    }
  }
}

```

Thank you for help!

# Answer
It's parsing a bunch of semi-colon separated data, like "12;34;45;". In each iteration, it converts one value from character representation to its integer value.

`strtok_r` is the reentrant version of `strtok`. On Arduino you simply use `strtok`. Every time you have to parse a string having a list of values separated by some char, you use `strtok`.

# Name

strtok, strtok\_r - extract tokens from strings

# Synopsis

```
#include <string.h>

char *strtok(char *str, const char *delim);

char *strtok_r(char *str, const char *delim, char **saveptr);

```

The strtok() function parses a string into a sequence of tokens (sub-strings). On the first call to strtok() the string to be parsed should be specified in `str`. In each subsequent call that should parse the same string, `str` should be NULL.

Each call to strtok() returns a pointer to a null-terminated string containing the next token. This token does not include the delimiting byte. If no more tokens are found, strtok() returns NULL.
> 2 votes

---
Tags: serial, c++, communication
---


# Question
Title: Why doesn't millis() use 1 µsec or 1 msec interrupt?
Arduino `millis()` does not make use of one millisecond interrupt. Instead they make use of 1,024 µsec interrupts and manipulate. Any specific reason why this was implemented this way?

In one case, we can go for timer0 without prescaler and use 1 µsec interrupts. In such case, we have to use CTC mode with `OCR0A=15`. Inside ISR, we could update the microsecond counter and if it reaches 1,000, we could update the msec timer count. Otherwise we could go for directly 1 msec interrupt (maybe using timer0).

I wrote this code to get `micros()` and `millis()`. But there is some issue and I'm not able to get it working correctly.

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

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

volatile uint32_t oneMilliCounter;
volatile uint32_t oneMicroCounter;
extern void initializeTimer0CTC_Mode (void);

extern uint32_t millis(void);
extern uint32_t micros(void);

volatile uint32_t oneMilliCounter = 0;
volatile uint32_t oneMicroCounter = 0;

uint32_t millis(void) {
  uint32_t value;
  uint8_t sregCopy = SREG;
  cli();
  value = oneMilliCounter;
  SREG = sregCopy;
  sei();
  return (value);
}

uint32_t micros (void) {
  uint32_t value;
  uint8_t sregCopy = SREG;
  cli();
  value = oneMicroCounter;
  SREG = sregCopy;
  sei();
  return (value);
}

void initializeTimer0CTC_Mode (void) {
  OCR0A = 15; // Set for 1 usec.
  TCCR0A |= 1 << WGM01;  // CTC Mode
  TIMSK0 |= 1 << OCIE0A;
  TCCR0B |= (1 << CS00); // prescaler=1
}

ISR(TIMER0_COMPA_vect) {
  static uint32_t prevMicro;
  oneMicroCounter++;
  if (oneMicroCounter - prevMicro >= 1000)   {
    prevMicro = oneMicroCounter;
    oneMilliCounter++;
  }
}

int main(void) {
  DDRD |= 1 << PD3;
  initializeTimer0CTC_Mode();
  sei();
  uint32_t prevTime = micros();
  while (1) {
    uint32_t currentTime = micros();
    if (currentTime - prevTime >= 1000) {
      PORTD ^= (1 << PD3);
      prevTime = currentTime;
    }
  }
  return (0);
}

```

# Answer
> 7 votes
One microsecond is only 16 CPU cycles.

The CPU needs 4 cycles to prepare itself for servicing the interrupt (save the program counter, load the interrupt vector and clear the I bit in SREG). The interrupt vector itself is a `jmp` instruction that takes 2 cycles. When the ISR is done, it executes the `reti` instruction (return from interrupt) that takes 4 cycles. This means you have only 6 CPU cycles left for:

* saving the context, i.e. pushing to the stack any register your ISR may modify (2 cycles per `push`)
* doing the actual ISR work
* restoring the context (2 cycles per `pop`)
* doing also some useful work in the main program.

There is no way you can do half of this in only 6 cycles.

---

**Edit**: I did a couple of experiments to gain more insight on the cost of running an interrupt too often.

In the first experiment, I used your `initializeTimer0CTC_Mode()` function to interrupt every microsecond the following program:

```
// This ISR consists of a sigle `reti' instruction.
EMPTY_INTERRUPT(TIMER0_COMPA_vect);

#include <util/delay.h>

int main(void)
{
    initializeTimer0CTC_Mode();
    DDRD |= _BV(PD2);       // PD2 = digital 2 as output
    sei();
    for (;;) {
        PIND |= _BV(PD2);   // toggle PD2
        _delay_us(499.75);  // 0.5 ms - 4 cycles
    }
}

```

The program is meant to generate a 1 kHz signal on pin 2, and that's exactly what it does if the `sei();` statement is commented out. With the `sei();` statement, the frequency drops to 375 Hz. This shows that processing an empty interrupt (an ISR consisting solely of the `reti` instruction) costs 62.5% of the CPU power, leaving 37.5% to the main program. 62.5% is exactly 10 out of every 16 CPU cycles, which confirms the cycle count of the first part of this answer.

The second experiment was to compile and disassemble your ISR. Here is what I got:

```
__vector_14:
    push r1
    push r0
    in   r0, 0x3f  ; 1 cycle
    push r0
    eor  r1, r1    ; 1 cycle
    push r18
    push r20
    push r21
    push r22
    push r23
    push r24
    push r25
    push r26
    push r27
; static uint32_t prevMicro;
; oneMicroCounter++;
    lds  r24, 0x0104
    lds  r25, 0x0105
    lds  r26, 0x0106
    lds  r27, 0x0107
    adiw r24, 0x01
    adc  r26, r1    ; 1 cycle
    adc  r27, r1    ; 1 cycle
    sts  0x0104, r24
    sts  0x0105, r25
    sts  0x0106, r26
    sts  0x0107, r27
; if (oneMicroCounter - prevMicro >= 1000)   {
    lds  r24, 0x0104
    lds  r25, 0x0105
    lds  r26, 0x0106
    lds  r27, 0x0107
    lds  r20, 0x0100
    lds  r21, 0x0101
    lds  r22, 0x0102
    lds  r23, 0x0103
    sub  r24, r20   ; 1 cycle
    sbc  r25, r21   ; 1 cycle
    sbc  r26, r22   ; 1 cycle
    sbc  r27, r23   ; 1 cycle
    cpi  r24, 0xE8  ; 1 cycle
    sbci r25, 0x03  ; 1 cycle
    cpc  r26, r1    ; 1 cycle
    cpc  r27, r1    ; 1 cycle
    brcs 0f  ; 1 cycle if the if() condition is true, 2 otherwise
;   prevMicro = oneMicroCounter;
    lds  r24, 0x0104
    lds  r25, 0x0105
    lds  r26, 0x0106
    lds  r27, 0x0107
    sts  0x0100, r24
    sts  0x0101, r25
    sts  0x0102, r26
    sts  0x0103, r27
;   oneMilliCounter++;
    lds  r24, 0x0108
    lds  r25, 0x0109
    lds  r26, 0x010A
    lds  r27, 0x010B
    adiw r24, 0x01
    adc  r26, r1    ; 1 cycle
    adc  r27, r1    ; 1 cycle
    sts  0x0108, r24
    sts  0x0109, r25
    sts  0x010A, r26
    sts  0x010B, r27
; } }
0:
    pop  r27
    pop  r26
    pop  r25
    pop  r24
    pop  r23
    pop  r22
    pop  r21
    pop  r20
    pop  r18
    pop  r0
    out  0x3f, r0  ; 1 cycle
    pop  r0
    pop  r1
    reti           ; 4 cycles

```

Unless otherwise noted in comments, every instruction of this listing takes 2 cycles to execute. Note the large number of CPU registers saved (`push`) and restored (`pop`), and the large number of SRAM accesses (`lds` and `sts`): three 4-byte variables read and written back. Counting the total number of cycles taken by this ISR is left as an “exercise to the reader”.

# Answer
> 2 votes
Using CTC mode would mean you can't use pin 9 as a PWM pin anymore.

Also, setting `OCR0A` to 15, would mean PWM on pin 10 could only have 15 different PWM values.

So, in essence, pins 9 and 10 can't be used for PWM.

# Answer
> 2 votes
Even if you could do what you are proposing, which you can't (see Edgar Bonet's excellent answer), imagine the performance hit running an interrupt *every single microsecond* would have on your code.

Every interrupt takes time away from your code.

Let's crunch some more numbers. If you wanted the millis/micros interrupt to take no more than 1% of the processing time, so it has no noticeable impact on your running code it would have to execute for only 10ns. That's 1% of 1000ns, or 0.000001 x 0.01.

Now assume it takes 50 clock cycles for a highly optimised version of your function to operate. That's a conservative estimate. That includes the time taken to prepare for, call and return from the interrupt.

For both those to hold true you would have to be able to execute 100 x 50 instructions in a microsecond. (To fill your 1uS you should be able to run your 1% interrupt 100 times, yes?) That's 5,000 x (1/0.000001) instructions per second, or 5,000,000,000 instructions per second.

Assuming a single clock cycle for each instruction, that means your chip would have to be running at 5GHz...!

Can you see the problem?

So we scale it back to something more realistic. Maybe a 10% performance hit instead of 1%. How would that be? Well, it's simple enough to say that it would require a chip running at 10% of the speed. 500 x (1/0.000001). So 500MHz.

Still a long long way away from the 16MHz that the Arduino's ATMega runs at.

So you can see the issue.

So we choose close to 1mS instead. That gives a much lower overhead and it's something that the 16MHz Arduino can cope with.

Why 1024 and not 1000? That's simple: 1000 is base 10. We, as humans, with two hands (usually) of (normally) 5 digits on each, love base 10. We thrive in base 10. However, computers with their 1s and 0s hate base 10. They much prefer working in base 2. It makes arithmetic really easy for them. And in interrupts we want the arithmetic to be easy.

Let's take a quick look at the maths involved and expand out the macros in the code.

Every tick the millis value is increased by `MILLIS_INC`, and any extra is added to a "fractional" count. What's `MILLIS_INC`? It's:

```
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)

```

So let's expand that out - what's `MICROSECONDS_PER_TIMER0_OVERFLOW`?

```
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

```

And what's `clockCyclesToMicroseconds`?

```
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )

```

What's `clockCyclesPerMicrosecond()`?

```
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )

```

And, of course, `F_CPU` is (typically) 16,000,000.

So now we can put it all together.

```
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
becomes:

#define MILLIS_INC ((clockCyclesToMicroseconds(64 * 256)) / 1000)
which becomes:

#define MILLIS_INC (((64 * 256)/clocksPerMicrosecond()) / 1000)

Which in turn becomes:
#define MILLIS_INC (((64 * 256)/(F_CPU/1000000L)) / 1000)

Which finally turns into:
#define MILLIS_INC (((64 * 256)/(16000000/1000000L)) / 1000)

So reduce those down a little:
#define MILLIS_INC ((16384 / 16) / 1000)

And finally:
#define MILLIS_INC (1.024)

```

And since we're talking integers here that is automatically truncated (by the compiler, not at runtime, so it's essentially "free") to 1.

But what about the 0.024ms...? That's simple. The "Fractional" amount is added to another counter - but not as 0.024 - instead as a `FRACT_INC` amount, which is calculated as `((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)`. That's 1024 % 100, or just 24, but then that's right shifted 3 times. That becomes 3. And when that count hits another limit it loops round and adds one to the millis count. That limit is `FRACT_MAX`, which is `1000 >> 3` or 125.

All nice and simple and straight forward. Variables, like the fractional count, are kept to just 8 bits (which is what you want on an 8 bit CPU...) and the majority of calculations are done by the compiler, not at runtime by the CPU. Everything else is simple addition / subtraction and comparisons. Very light. And it runs often enough to be good enough for the majority of uses. And given that, because it's just a timer interrupt and is subject to collision with other interrupts, and can't run when interrupts are disabled, it's only a rough figure anyway. Even the act of reading `millis()` can slow down the counting of milliseconds, since it disables interrupts while the value of the count is retreived (a so called "critical section").

And yes, it could be tweaked to run at precisely 1000uS intervals and do away with the fractional component - but why bother when it's never going to be that accurate anyway? Also the added complexity of calculating what 1000uS is for a timer configuration when you consider the vast array of speeds that Arduinos could potentially run at (16MHz for an Uno, 8MHz for the 3.3V boards, 1MHz for the default internal oscillator...) it's far simpler to say "This is what it ticks at, and this is the number of milliseconds per tick, with this bit left over" which is calculated at compile time, instead of having to work out prescalers and overflow counts, etc.

---
Tags: arduino-nano, atmega328, timers, millis
---


title: Use AS3935 with I2C?

text:
# Question
Title: Use AS3935 with I2C?
Has someone experience with interfacing the AS3935 lightning sensor using I2C? I found a library but it only works with SPI as far as I can tell. I really don't want to give up 4 pins for SPI as I need those for other things. I2C would be great as I use a couple more sensors with I2C so no extra pins only for AS3935.

# Answer
Just use these functions to read/write AS3935 registers, replacing the SPI ones (\_devAddr is the device address, usually 0x03) :

```
// read/write functions for I2C mode
uint8_t AS3935::_i2cRead(uint8_t addr)
{
    // send register number
    Wire.beginTransmission(_devAddr);
    Wire.write(addr);
    Wire.endTransmission(false); // <<<--- THE 'false' here is mandatory!

    // request register data
    Wire.requestFrom(_devAddr, (uint8_t)1);

    // read data
    return Wire.read();
}

void AS3935::_i2cWrite(uint8_t addr, uint8_t data)
{
    Wire.beginTransmission(_devAddr);
    Wire.write(addr);
    Wire.write(data);
    Wire.endTransmission();
}

```

The "trick" is to use Wire.endTransmission(false) inside the read routine; this avoid to send the stop bit, which is mandatory for AS3935 read operation.
> 1 votes

---
Tags: pins, i2c, spi
---


title: Function, struct or class?

text:
# Question
Title: Function, struct or class?
I am trying to learn more about arduino programming, and recently i've written functions for randomizing and then modifying a single array. Now i'd like to do the same for four individual arrays. This is where i'm getting stuck. My questions:

Am i right to assume that it's not possible calling a function for multiple individual arrays?

Perhaps a separate question, but if a class or struct would be more suitable for multiple instances, what are the major differences worth considering to choose the right approach?

# Answer
> 2 votes
Are you trying to use the same function for different arrays at different times, or are you trying to use a function that handles four different arrays at the same time?

If the former, you'd write something like

```
void myfunc( T *arr, size_t size ) // where T is the type of the array
{
  for ( size_t i = 0; i < size; i++ )
    arr[i] = some_new_value();
}

```

then call it for each array:

```
T arr1[N];  // where T is int, float, double, whatever
T arr2[M];
T arr3[O];
T arr4[P];

myFunc( arr1, N );
myFunc( arr2, M );
myFunc( arr3, O );
myFunc( arr4, P );

```

This assumes all the arrays have the same base type (e.g., they're all arrays of `int`).

If you want a function to work on four arrays simultaneously, you'd write it as

```
void myFunc( T *a1, size_t a1_size,
             T *a2, size_t a2_size,
             T *a3, size_t a3_size,
             T *a4, size_t a4_size )
{
  // code for handling each array
}

```

While I wrote it such that all the arrays have the same type, it doesn't have to be this way. Each array can be a different type (`a1` can be `int`, `a2` can be `double`, etc.).

# Answer
> 0 votes
> Am i right to assume that it's not possible calling a function for multiple individual arrays?

What would give you that impression? An array is just a pointer to a block of memory - as such it's just a variable. You can pass as many as you like to a function.

Just remember that a function can't know how big the array is that you pass it, since it only gets the pointer to the start of the array, so you need to pass the size of the array with it. You can't rely on the `sizeof` operator, since that is a compile-time directive that gives the size of a variable, which inside the function will be the size of a pointer (2 bytes on an 8 bit system). It can only give the size of an array (and then only the memory size in bytes, not the count of elements) if its run in the same (or a subordinate) scope as the declaration of the array.

> Perhaps a separate question, but if a class or struct would be more suitable for multiple instances, what are the major differences worth considering to choose the right approach?

A struct is just a way of grouping variables into compound types. Think of them as database records. Great for if you want to keep related, but different, information together in one block. Classes are the same thing but add functions as well.*

---

* That's a very simplistic description. In actuality you can have functions in structs and not have functions in classes. The real difference between them is how access controls (private/protected/public) are implemented (there is none in structs, and they are all there in classes) and how inheritance / polymorphism works.

---
Tags: class, struct
---


# Question
Title: MPU6050 accelerometer giving output as -1 -1. Can anyone tell the issue in the code?
```
// MPU-6050 Short Example Sketch
// By Arduino User JohnChi
// August 17, 2014
// Public Domain
#include<Wire.h>
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

void setup() {
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  Serial.begin(9600);
}

void loop() {
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  Tmp=Wire.read()<<8|Wire.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  Serial.print("AcX = "); Serial.print(AcX);
  Serial.print(" | AcY = "); Serial.print(AcY);
  Serial.print(" | AcZ = "); Serial.print(AcZ);
  Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
  Serial.print(" | GyX = "); Serial.print(GyX);
  Serial.print(" | GyY = "); Serial.print(GyY);
  Serial.print(" | GyZ = "); Serial.println(GyZ);
  delay(333);
}

```

Serial Monitor output:

```
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
AcX = -1 | AcY = -1 | AcZ = -1 | Tmp = 36.53 | GyX = -1 | GyY = -1 | GyZ = -1
[…]

```

# Answer
> 0 votes
I found that there was a communication problem between MPU and Arduino which I found using code given in this link http://playground.arduino.cc/Main/I2cScanner . Then I found thought problem Must be in MPU or arduino and problem was in Arduino MCU. So after changing the Arduino MCU it worked

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


# Question
Title: detachInterrupt(0) in arduino not working ? after giving continuous ground to INT0 wakeupnow function should execute once not again and again
```
#include <avr/sleep.h>

int wakePin = 2;                 // pin used for waking up
int led=13;
int flag=0;

void wakeUpNow()
{
  // execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
  // we don't really need to execute any special functions here, since we
  // just want the thing to wake up
  int count=10;
  while(count!=0)
  {
    delay(1000);
    count--;
    Serial.println(count);
    delay(1000);
  }
}

void setup()
{
  Serial.begin(9600);
  pinMode(wakePin, INPUT_PULLUP);  // wakePin is pin no. 2
  pinMode(led, OUTPUT);          //   led is pin no. 13
  attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW
}

void sleepNow()
{
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
    sleep_enable();                        // enables the sleep bit in the mcucr register
                      delay(500);
                      Serial.println("Rajat");
                      delay(500);
    attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
                      delay(500);
                      Serial.println("Rajat");
                      delay(500);
    sleep_mode();     // here the device is actually put to sleep...!!
      // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
                      delay(500);
                      Serial.println("Rajat2");
                      delay(500);
    detachInterrupt(0);      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
    sleep_disable();         // first thing after waking from sleep: disable sleep...
                      delay(500);
                      Serial.println("Rajat3");
                      delay(500);
       detachInterrupt(0);      // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.

}

void loop()
{
      digitalWrite(led, HIGH);
      delay(1000);
      digitalWrite(led, LOW);
      delay(1000);
    /* delay(500);
      Serial.println("jam");
      delay(500);  */
      if (flag==0)
      {
      sleepNow();     // sleep function called here
      flag=1;
      }
}

```

After Last Rajat I give ground to INT0.

Output in serial monitor :

```
Rajat
Rajat
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
9
8
7
6
5
4
3
2
& so on..!

```

# Answer
You're detaching in completely the wrong place. After sleep\_mode() returns from sleep and before the interrupt is detached you have an entire second of time where your interrupt can still fire. And it *will* fire, since a `LOW` interrupt will keep firing *while* the input is `LOW`.

```
sleep_mode();     // here the device is actually put to sleep...!!
  // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
                  delay(500);
                  Serial.println("Rajat2");
                  delay(500);
detachInterrupt(0);

```

Instead you should detach the interrupt within the interrupt routine itself:

```
void wakeUpNow()
{
  // execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
  // we don't really need to execute any special functions here, since we
  // just want the thing to wake up

    detachInterrupt(0);

  int count=10;
  while(count!=0)
  {
    delay(1000);
    count--;
    Serial.println(count);
    delay(1000);
  }
}

```

Also, all those delays and Serial prints in an interrupt are seriously problematic. An interrupt should *never* `delay()` and should *never* `Serial.println()`.
> 2 votes

---
Tags: arduino-uno, interrupt, sleep
---


# Question
Title: Is there a way to put multiple integers in a method?
I'm working on a project that has 3 RGB LEDs. I want to make a simple method that I can call to control the LEDs for example:

```
showColor(left, 255, 0, 50);

```

Which would light up the left LED at 100% red, 0% green, and 20% blue. The code I have running for the method is:

```
 void showColor(int ledPosition, int redIntensity, int blueIntensity, int greenIntensity)
    {
      if (ledPosition == left)
      {
        analogWrite (redPin1, redIntesity);
        analogWrite (greenPin1, greenIntesity);
        analogWrite (bluePin1, blueIntesity);
      }
      else if (ledPosition == middle)
      {
        analogWrite (redPin2, redIntesity);
        analogWrite (greenPin2, greenIntesity);
        analogWrite (bluePin2, blueIntesity);
      }
      else if (ledPosition == right)
      {
        analogWrite (redPin3, redIntesity);
        analogWrite (greenPin3, greenIntesity);
        analogWrite (bluePin3, blueIntesity);
      }
      else if (ledPosition == all)
      {
        for (int index=0, index < 3 ; index++)
        {
          analogWrite (redPins[index], redIntensity);
          analogWrite (greenPins[index], greenIntensity);
          analogWrite (bluePins[index], blueIntensity);
        }
      }
    }

```

I'm getting tons of errors, like that all of the Intensity variables are not declared and that left, right, all, and middle are not declared. I don't know if this is possible, or what I'm doing wrong. I think I've seen something like this before somewhere else, and I don't want to just use 1 variable to control everything. An answer would be greatly appreciated!

# Answer
Check your spelling `Intensity` instead of `Intesity`.

Consider using `switch` instead of `if-then-else`.

Define `left`, `right` and `middle` as \[integer\] constants somewhere (and probably something more descriptive like `rightLED`, `leftLED` and `middleLED`) because your code is looking for an `int`, instead you give it something undefined like left, right and middle (and all). I would consider using bitwise operators for identifying the LEDS, instead of a simple integer flag as this gives future flexibility in lighting up combinations without changing your code (the current function would be rewritten to accommodate this).
> 3 votes

# Answer
There are two errors in your code:

1. The word “Intensity” should always be spelled like this, rather than “Intesity” (missing “n”)
2. In `for (int index=0; index < 3; index++)`, the separators should be semicolons, not commas.

Other than that, and provided proper declarations, your function compiles just fine.
> 0 votes

# Answer
This answer is slightly off track, but after reading the title my first though was this.

You can have a function that takes multiple integer parameters and there is nothing wrong with that, but there comes a point in your code where you should be looking at better data management. In this case you have three intensity values that are always going to be related so you could look at a class or struct to hold the data as a single object.

```
struct Colour
{
    int Red;
    int Green;
    int Blue;
    Colour (const int& r = 0, const int& g = 0, const int& b = 0)
        : Red(r)
        , Green(g)
        , Blue(b)
    {}
}

```

This would allow you to define an object (called LEDLeft) that held the value for that LED, i.e.

```
Colour LEDLeft(0xFF, 0xFF, 0x00);    // Define a yellow left LED.

```

Extending this further you could define a second structure that defined the pins to control the LED, and a third that paired the current colour with the LED.

```
struct LED
{
    LEDPinout Pins;
    Colour    Colour;
   // Constructor ...
}

```

Its about this point that using a class rather than a struct would be a better (more conventional\*) idea. i.e.

```
// THIS IS NOT COMPLETE CODE - IT HAS NOT BEEN TESTED.
class LED
{
    LED (const int& pinRed, const int& pinGreen, const int& pinBlue);
    LED (const LED& other);  // Copy constructor

    void SetColour(const Colour& colour);
    Colour GetColour(void)const;
}

static const Colour RED(0xFF, 0x00, 0x00);
static const Colour BLUE(0x00, 0x00, 0xFF);
enum Positions {Left = 0, Middle, Right, All};
LED TheLeds[] = {LED(2, 3, 4), LED(5, 6, 7), LED(8, 9, 10)};
TheLeds[Left].SetColour (RED);
TheLeds[Right].SetColour (RED);
TheLeds[Middle].SetColour (RED);
delay(1000);
for (int loop = 0; loop < All; ++loop)
    TheLeds[loop].SetColour(BLUE);
delay(1000);

```
> 0 votes

---
Tags: arduino-mega, arduino-ide, rgb-led, variables
---


# Question
Title: How to generate hardware interrupt in mpu6050 to wakeup arduino from SLEEP_MODE_PWR_DOWN mode?
I am using Arduino UNO and has kept in SLEEP\_MODE\_PWR\_DOWN mode & want it to wakeup using MPU6050 hardware INT pin (which should send a signal when MPU is in motion). I have used the article https://lukelectro.wordpress.com/2016/08/11/how-to-enable-motion-detection-interrupt-on-mpu6050/

```
    #include <Wire.h>
    //Analog port 4 (A4) = SDA (serial data)
    //Analog port 5 (A5) = SCL (serial clock)
    #define SIGNAL_PATH_RESET  0x68
    #define I2C_SLV0_ADDR      0x37
    #define ACCEL_CONFIG       0x1C
    #define MOT_THR            0x1F  // Motion detection threshold bits [7:0]
    #define MOT_DUR            0x20  // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
    #define MOT_DETECT_CTRL    0x69
    #define INT_ENABLE         0x38
    #define WHO_AM_I_MPU6050   0x75 // Should return 0x68
    #define INT_STATUS 0x3A
    //when nothing connected to AD0 than address is 0x68
    #define ADO 0
    #if ADO
    #define MPU6050_ADDRESS 0x69  // Device address when ADO = 1
    #else
    #define MPU6050_ADDRESS 0x68  // Device address when ADO = 0
    #endif

    /*    Example for using write byte
          Configure the accelerometer for self-test
          writeByte(MPU6050_ADDRESS, ACCEL_CONFIG, 0xF0); // Enable self test on all three axes and set accelerometer range to +/- 8 g */
    void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
    {
      Wire.begin();
      Wire.beginTransmission(address);  // Initialize the Tx buffer
      Wire.write(subAddress);           // Put slave register address in Tx buffer
      Wire.write(data);                 // Put data in Tx buffer
      Wire.endTransmission();           // Send the Tx buffer
    //  Serial.println("mnnj");

    }

    //example showing using readbytev   ----    readByte(MPU6050_ADDRESS, GYRO_CONFIG);
    uint8

_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data;                            // `data` will store the register data
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}

void setup()
{
   /*
    * #define SIGNAL_PATH_RESET  0x68
      #define I2C_SLV0_ADDR      0x37
      #define ACCEL_CONFIG       0x1C
      #define MOT_THR            0x1F  // Motion detection threshold bits [7:0]
      #define MOT_DUR            0x20  // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
      #define MOT_DETECT_CTRL    0x69
      #define INT_ENABLE         0x38
      #define WHO_AM_I_MPU6050 0x75 // Should return 0x68
      #define INT_STATUS 0x3A*/
    Serial.begin(9600);
    writeByte( MPU6050_ADDRESS, SIGNAL_PATH_RESET, 0x07);//Reset all internal signal paths in the MPU-6050 by writing 0x07 to register 0x68;
    writeByte( MPU6050_ADDRESS, I2C_SLV0_ADDR, 0x20);//write register 0x37 to select how to use the interrupt pin. For an active high, push-pull signal that stays until register (decimal) 58 is read, write 0x20.
    writeByte( MPU6050_ADDRESS, ACCEL_CONFIG, 0x01);//Write register 28 (==0x1C) to set the Digital High Pass Filter, bits 3:0. For example set it to 0x01 for 5Hz. (These 3 bits are grey in the data sheet, but they are used! Leaving them 0 means the filter always outputs 0.)
    writeByte( MPU6050_ADDRESS, MOT_THR, 0x14);  //Write the desired Motion threshold to register 0x1F (For example, write decimal 20).
    writeByte( MPU6050_ADDRESS, MOT_DUR, 0x01 );  //Set motion detect duration to 1  ms; LSB is 1 ms @ 1 kHz rate
    writeByte( MPU6050_ADDRESS, MOT_DETECT_CTRL, 0x15); //to register 0x69, write the motion detection decrement and a few other settings (for example write 0x15 to set both free-fall and motion decrements to 1 and accelerometer start-up delay to 5ms total by adding 1ms. )
    writeByte( MPU6050_ADDRESS, INT_ENABLE, 0x40 ); //write register 0x38, bit 6 (0x40), to enable motion detection interrupt.     */

    pinMode(13, OUTPUT);      // sets the digital LED pin 13 as output
    pinMode(7, INPUT);        // sets the digital pin 7 as input

}
    uint16_t readdata;
void loop()
{
      Serial.println("scdf");

      if(digitalRead(7)==1)
      {
        while(1)
        {
          digitalWrite(13, 1);
          delay(100);
        }
      }

  //    readdata = readByte(MPU6050_ADDRESS,WHO_AM_I_MPU6050);
  //    Serial.println(readdata);
}

```

# Answer
> 8 votes
Well, this code worked. In this code, MPU's INT PIN is Active Low so generates Ground on motion which is than connected to INT0 or arduino UNO pin 2 which generates interrupt and wakes UP the MCU

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

#include <Wire.h>
 //Analog port 4 (A4) = SDA (serial data)
//Analog port 5 (A5) = SCL (serial clock)
#define SIGNAL_PATH_RESET 0x68
#define I2C_SLV0_ADDR 0x37
#define ACCEL_CONFIG 0x1C
#define MOT_THR 0x1F // Motion detection threshold bits [7:0]
#define MOT_DUR 0x20 // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
#define MOT_DETECT_CTRL 0x69
#define INT_ENABLE 0x38
#define WHO_AM_I_MPU6050 0x75 // Should return 0x68
#define INT_STATUS 0x3A
//when nothing connected to AD0 than address is 0x68
#define ADO 0
#if ADO
#define MPU6050_ADDRESS 0x69 // Device address when ADO = 1
#else
#define MPU6050_ADDRESS 0x68 // Device address when ADO = 0
#endif

int wakePin = 2; // pin used for waking up
int led = 13;
int flag = 0;

void wakeUpNow() { // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP    (i.e. after getting interrupt)
  // execute code here after wake-up before returning to the loop() function
  // timers and code using timers (serial.print and more...) will not work here.
  // we don't really need to execute any special functions here, since we
  // just want the thing to wake up

  delay(500);
  Serial.println("WOKEN UP !!!!!!!!!!");
  delay(500);
  int count = 10;
  while (count != 0) {
    delay(1000);
    count--;
    Serial.println(count);
    delay(1000);
  }
  // precautionary while we do other stuff
  detachInterrupt(0);

}

/*    Example for using write byte
      Configure the accelerometer for self-test
      writeByte(MPU6050_ADDRESS, ACCEL_CONFIG, 0xF0); // Enable self test on all three axes and set accelerometer range to +/- 8 g */
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) {
  Wire.begin();
  Wire.beginTransmission(address); // Initialize the Tx buffer
  Wire.write(subAddress); // Put slave register address in Tx buffer
  Wire.write(data); // Put data in Tx buffer
  Wire.endTransmission(); // Send the Tx buffer
  //  Serial.println("mnnj");

}

//example showing using readbytev   ----    readByte(MPU6050_ADDRESS, GYRO_CONFIG);
uint8_t readByte(uint8_t address, uint8_t subAddress) {
  uint8_t data; // `data` will store the register data
  Wire.beginTransmission(address); // Initialize the Tx buffer
  Wire.write(subAddress); // Put slave register address in Tx buffer
  Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (uint8_t) 1); // Read one byte from slave register address
  data = Wire.read(); // Fill Rx buffer with result
  return data; // Return data read from slave register
}

void setup() {

  /*
   * #define SIGNAL_PATH_RESET  0x68
     #define I2C_SLV0_ADDR      0x37
     #define ACCEL_CONFIG       0x1C
     #define MOT_THR            0x1F  // Motion detection threshold bits [7:0]
     #define MOT_DUR            0x20  // Duration counter threshold for motion interrupt generation, 1 kHz rate, LSB = 1 ms
     #define MOT_DETECT_CTRL    0x69
     #define INT_ENABLE         0x38
     #define WHO_AM_I_MPU6050 0x75 // Should return 0x68
     #define INT_STATUS 0x3A*/
  Serial.begin(9600);
  writeByte(MPU6050_ADDRESS, 0x6B, 0x00);
  writeByte(MPU6050_ADDRESS, SIGNAL_PATH_RESET, 0x07); //Reset all internal signal paths in the MPU-6050 by writing 0x07 to register 0x68;
  writeByte(MPU6050_ADDRESS, I2C_SLV0_ADDR, 0x20); //write register 0x37 to select how to use the interrupt pin. For an active high, push-pull signal that stays until register (decimal) 58 is read, write 0x20.
  writeByte(MPU6050_ADDRESS, ACCEL_CONFIG, 0x01); //Write register 28 (==0x1C) to set the Digital High Pass Filter, bits 3:0. For example set it to 0x01 for 5Hz. (These 3 bits are grey in the data sheet, but they are used! Leaving them 0 means the filter always outputs 0.)
  writeByte(MPU6050_ADDRESS, MOT_THR, 10); //Write the desired Motion threshold to register 0x1F (For example, write decimal 20).
  writeByte(MPU6050_ADDRESS, MOT_DUR, 40); //Set motion detect duration to 1  ms; LSB is 1 ms @ 1 kHz rate
  writeByte(MPU6050_ADDRESS, MOT_DETECT_CTRL, 0x15); //to register 0x69, write the motion detection decrement and a few other settings (for example write 0x15 to set both free-fall and motion decrements to 1 and accelerometer start-up delay to 5ms total by adding 1ms. )
  writeByte(MPU6050_ADDRESS, INT_ENABLE, 0x40); //write register 0x38, bit 6 (0x40), to enable motion detection interrupt.
  writeByte(MPU6050_ADDRESS, 0x37, 160); // now INT pin is active low

  pinMode(2, INPUT); // sets the digital pin 7 as input

  pinMode(wakePin, INPUT_PULLUP); // wakePin is pin no. 2
  pinMode(led, OUTPUT); //   led is pin no. 13
  // attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW

}

void sleepNow() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable(); // enables the sleep bit in the mcucr register
  delay(500);
  Serial.println("About to sleep");
  delay(500);
  attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
  delay(500);
  Serial.println("Interupt attached");
  delay(500);
  sleep_mode(); // here the device is actually put to sleep...!!

  // THE PROGRAM CONTINUES FROM HERE AFTER INTERRUPT IS CLOSED
  delay(500);
  Serial.println("Continuing main program after interupt");
  delay(500);

  sleep_disable(); // first thing after waking from sleep: disable sl¯eep...
  delay(500);
  Serial.println("Sleep disabled");
  delay(500);
}
uint16_t readdata;
void loop() {
  if (digitalRead(2) == 0) {
    {

      digitalWrite(13, 1);
      delay(100);
      digitalWrite(13, 0);
      delay(100);
    }
  }
  sleepNow(); // sleep function called here
  readdata = readByte(MPU6050_ADDRESS, 0x3A);
  Serial.print(readdata);
  Serial.print(",");
  readdata = readByte(MPU6050_ADDRESS, 0x37);
  Serial.println(readdata);

}

```

---
Tags: arduino-uno, interrupt, mpu6050, sleep
---


# Question
Title: Arduino Uno "if" statement is ignored in code and halts execution when using Serial.ReadString()
I'm having a weird issue with my Uno trying to power on a PWM fan using a MOSFET.

I'm setting a simple power on/off code using commands sent over the Serial Monitor, and although this code worked before, after I tried to add some code to control the speed of the PWM fan, my if statements do not work anymore, even with the simple power on/off code:

```
    String command;           //Define the string variable "command"

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

  pinMode(5, OUTPUT);     //Set pin 5 as MOSFET Gate signal pin
  pinMode(13, OUTPUT);    //Set pin 13 to use onboard LED as a waiting for command status LED
  digitalWrite(5, LOW);   //Start with MOSFET off
  digitalWrite(13, LOW);  //Star with status LED off
  Serial.begin(9600);     //Start Serial comm for sending commands

}

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

  Serial.println("What's your command?"); //Ask for a command in the Serial Monitor

  while (Serial.available()==0) {        //Wait for user input stopping the code
    digitalWrite(13, HIGH);               //Blink the onboard LED indicating that the code is waiting for user input
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }

  command=Serial.readString();          //Save the Serial Monitor String command to the "command" variable as a String
  Serial.println("data read");          //Confirm Serial Monitor input
  Serial.println(command);              //Print the command sent over the Serial Monitor to confirm the data received

  if (command=="On") {                  //Turn the MOSFET on
    digitalWrite(5, HIGH);
  } else if (command=="Off") {                  //Turn the MOSFET off
    digitalWrite(5, LOW);
  }
  else {                                 //Provide feedback for a wrong command
    Serial.println("Wrong command!");
  }
}

```

This is my Serial Monitor output after sending "On":

```
What's your command?
data read
On

Wrong command!
What's your command?

```

To check if the pin works, I tested a simple code that worked fine:

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

  pinMode(5, OUTPUT);     //Set pin 5 as MOSFET Gate signal pin
  digitalWrite(5, LOW);   //Start with MOSFET off
  Serial.begin(9600);     //Start Serial comm for sending commands

}

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

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

}

```

Does anyone have any idea why the if statements are not working anymore?

Thank you in advance!

AC

EDIT: After trying to use the "else" statement as recommended by per1234, the issue continues to happen, but changing the variable type to an integer works, although the Serial output is rather messy:

```
int command;           //Define the int variable "command"

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

  pinMode(5, OUTPUT);     //Set pin 5 as MOSFET Gate signal pin
  pinMode(13, OUTPUT);    //Set pin 13 to use onboard LED as a waiting for command status LED
  digitalWrite(5, LOW);   //Start with MOSFET off
  digitalWrite(13, LOW);  //Star with status LED off
  Serial.begin(9600);     //Start Serial comm for sending commands

}

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

  Serial.println("What's your command?"); //Ask for a command in the Serial Monitor

  while (Serial.available()==0) {        //Wait for user input stopping the code
    digitalWrite(13, HIGH);               //Blink the onboard LED indicating that the code is waiting for user input
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }

  command=Serial.parseInt();          //Save the Serial Monitor imput command to the "command" variable as an int

  Serial.println("data read");          //Confirm Serial Monitor input
  Serial.println(command);              //Print the command sent over the Serial Monitor to confirm the data received

  if (command==1) {                  //Turn the MOSFET on
    digitalWrite(5, HIGH);
  }
  if (command==2) {                  //Turn the MOSFET off
    digitalWrite(5, LOW);
  }
  else {                                 //Provide feedback for a wrong command
    Serial.println("Wrong command!");
  }
}

```

And the Serial Monitor output:

```
What's your command?
data read
1
What's your command?
data read
0
Wrong command!
What's your command?
data read
2
What's your command?
data read
0
Wrong command!
What's your command?

```

Does anyone experience this issue? I even tried rolling back my IDE to 1.8.3, which I used to write the code the first time, then after a library update, and also getting version 1.8.5, it stopped working.

Also, anyone knows how to avoid the multiple Serial Monitor outputs?

I tested this with "String" variables to be able to get this fixed.

Also, a side question regarding the post size, should I remove the original code when editing, or should I move it to another answer?

Thank you.

# Answer
The problem with the *original* code is evidenced in the following:

```
What's your command?
data read
On

Wrong command!

```

See that blank line? Nowhere in your sketch do you specifically print a blank line, rather it is being printed because the `command` string contains a carriage return and/or newline character captured with the input, which is causing a comparison of exact equality to fail.

To fix this, you could either trim these non-printing characters off the end, or use a different comparison, for example `command.startsWith("On")`. But if you do use a start-of-string comparison, beware if you have any command verbs that extend other shorter ones.

You also have a bug in your block if-else statements, in that instead of

```
if ...
if ...
else ...

```

you should have

```
if ...
else if ...
else ....

```

So that the "none of the above" clause only runs when none of the conditions are satisfied, rather than running whenever the penultimate condition is not satisfied.

In terms of the numeric version producing an un-entered value of 0, this is the documented return value of the `parseInt()` methods if they time out without finding a valid integer.

It would be more traditional to use an end-of-line condition rather than a timeout to detect the end of user input. Many traditional "until end of line" read mechanisms trim the line ending characters off the resulting string for you, eliminate the comparison problem, too.
> 1 votes

# Answer
Let's look at what this code does when you send "On":

```
  if (command=="On") {                  //Turn the MOSFET on
    digitalWrite(5, HIGH);
  }

```

This will evaluate true so pin 5 is set to HIGH.

```
  if (command=="Off") {                  //Turn the MOSFET off
    digitalWrite(5, LOW);
  }

```

This will evaluate false so the else clause is executed:

```
  else {                                 //Provide feedback for a wrong command
    Serial.println("Wrong command!");
  }

```

So the output you are seeing is correct for your code. The problem is that your code doesn't match your intent. For that you need to change this line:

```
  if (command=="Off") {                  //Turn the MOSFET off

```

to:

```
  else if (command=="Off") {                  //Turn the MOSFET off

```

Then the else clause will only run if the command doesn't match "On" or "Off".

For more information see: https://www.arduino.cc/reference/en/language/structure/control-structure/else/
> 3 votes

# Answer
Thank you for your help.

I have been able to find the root cause of my original problem.

After reading this post on https://forum.arduino.cc/index.php?topic=73372.0, more specifically an answer regarding filtering for \n and \r characters and the Arduino IDE Serial Monitor line ending option.

My problem was caused by having the "Newline" option selected in the Serial Monitor. After selecting "No line ending", my original code runs as expected, and I know now how to use String variable and Serial.readString() in a more efficient way, and the if-else statements.

Also, the blank line mentioned by Chris Stratton is gone, and my search to fix that led me to the solution of the main problem, and the code also works 100% with the formatting help provided by per1234.

Thank you both again for the help.
> 1 votes

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