title: Using Arduino as Keylogger

text:
# Question
Title: Using Arduino as Keylogger
Is it possible to use arduino uno r3 as USB keylogger by connecting the usb male pin to CPU and keybord cable to female USB pin of arduino. So that the keystrokes are stored in EEPROM. Without using an external storage modules or other components?

I am new to arduino, even suggestions are appreciated.

Thanks in advance.

# Answer
> 1 votes
USB-host is hard if not impossible to implement on an UNO.

Though I believe most USB keyboards support PS2 as well (normally done with a USB-to-PS2 plug). So you should be able to talk to the keyboard using the PS2 protocol, which is a lot easier. There are libraries to do this for you.

Next you could use V-USB to emulate a keyboard to the PC. For that USB connection you need to add some resistors and zener diodes, to stay withing the usb specification. This is all explained on the V-USB website.

Using a different Arduino that has real USB support might be a better option. Also the UNO is rather large, so not that easy to hide.

# Answer
> 0 votes
It is highly unlikely using an arduino uno r3.

USB Device: (To emulate a HID (Human Interface Device) Keyboard):

While there are Arduino libraries for emulating a keyboard, these will not work with the Uno R3. Instead, to make a Uno R3 act like a USB Keyboard Device, you need to reprogram the 2nd processor on the board and switch it from a USB Serial Device to a USB Keyboard Device. This is talked about in this stackexchange question.

USB Host (to talk to a USB Keyboard):

I do not believe there are any software solutions for emulating a USB Host on most Arduinos. Certainly not a Uno R3. A USB Host is a very complex software & hardware device. Instead, most Arduino projects use a USB Host Shield for this purpose.

# Answer
> -1 votes
No, it's not. Or not with any degree of ease. The best you could hope for would be to intercept the USB data and try and decode it, but that really is beyond the ability of a lowly Arduino.

I have thousands of dollars worth of equipment aimed at doing that kind of thing - it's not a simple task.

---
Tags: eeprom, datalogging
---


title: Why change the variable content?

text:
# Question
Title: Why change the variable content?
I don't understand why change `uidList[reader]` variable, when doesn't run more to the else. I use in this test only the "0" reader.

First loop go to the "else" and fill the `uid` to `uidList[reader]`. (good) Second loop go to the "if" because the two `uid` is equal.(good)

I remove NFC and place the other, but the `uidList[reader]` updated immediately to the new `UID`, not in the "else". Never go again to else. Why?

```
#define NR_OF_READERS   2
byte* uidList[NR_OF_READERS];
MFRC522 mfrc522[NR_OF_READERS];   // Create MFRC522 instance.
......
void loop() {
  ....
  delay(2500);
  for (uint8_t reader = 0; reader < NR_OF_READERS; reader++) {

     dump_byte_array(uidList[0], 8);
     dump_byte_array(uidList[1], 8);

   if (mfrc522[reader].PICC_IsNewCardPresent() &&     mfrc522[reader].PICC_ReadCardSerial()) {

     dump_byte_array(uidList[0], 8); //WHY UPDATED HERE???
     dump_byte_array(uidList[1], 8);

     if (uidList[reader] == mfrc522[reader].uid.uidByte) {

        Serial.println(F("Same NFC"));
        dump_byte_array(uidList[0], 8);
        dump_byte_array(uidList[1], 8);

     } else {

        Serial.println(F("Other NFC in this reader"));

        uidList[reader] = mfrc522[reader].uid.uidByte;

        dump_byte_array(uidList[0], 8);
        dump_byte_array(uidList[1], 8);

     }

   }
}

void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
  Serial.println();
}

```

When I placed the new NFC in the reader, this debug appear on serial monitor.

```
 DF 6D 05 D2 00 00 00 00 //old NFC uid it's good

 AB 00 6C 02 F0 21 00 00

 FF 2C 02 69 00 00 00 00 //WHY UPDATED HERE???

 AB 00 6C 02 F0 21 00 00

```

Same NFC

```
 FF 2C 02 69 00 00 00 00

 AB 00 6C 02 F0 21 00 00

```

Thanks any idea.

# Answer
> 2 votes
Well, it's easy, as you are using pointers. If the original place gets changed, you can see changed value because you don't have your own copy.

Your `if` statement is also wrong, as you are comparing two pointers here. They will be different at the first time comparation, but after the assigment they are unlikely to change.

The solution is using:

```
byte uidList[NR_OF_READERS][8]; // better to use some constant value instead of magic number

```

and `memcpy` for making a copy and `memcmp` for comparing its content. Both are from `<cstring>` include

---
Tags: arduino-mega, c++
---


# Question
Title: digispark - 2 pin push button to iterate through an hashmap
I'm trying to create a project with my digispark where i can iterate through an hashmap, when i press the push button the digispark writes via digikeyboard the values from an hashmap. Each time i press the button it's supposed to write the first value, then i press the push button again and in the same line it cleans what was written in the first value and writes the second value and so on. when the last value is reached it goes again to the first value if the button is pressed. Right now i'm trying to put the iterator to work preperlly, this is the code i have:

```
#include "DigiKeyboard.h"
#include "HashMap.h"

HashMap<String, String> hashMap;
int i = 0;

void setup() {
   //setup hashmap
  hashMap.put("key0","test0");
  hashMap.put("key1","test1");
  hashMap.put("key2","test2");
  hashMap.put("key3","test3");
  hashMap.put("key4","test4");

  DigiKeyboard.sendKeyStroke(0);
  pinMode(0, INPUT);
}
void loop() {
  int sensorValue = digitalRead(0);
      while(sensorValue ==1 and i < hashMap.count())
      {
        delay(100);
        DigiKeyboard.println( hashMap.valueAt(i));
        i++;
      }
}

```

when i plug the digispark it prints automatically the first and the second value ("test0" "test1") and every time i press the button i get nothing.

This is my configuration: http://cdn.instructables.com/FZA/0UN8/HI3TXV8D/FZA0UN8HI3TXV8D.LARGE.jpg

Can anyone help me please?

# Answer
> 0 votes
thank you all. i've manage to found a solution to my problem with this code, probably is not the most elegant way to do it but it works:

```
#include "DigiKeyboard.h"
#include "HashMap.h"

HashMap<char*, char*> hashMap;
int i = 0;
bool flag;

const byte switchPin = 0;
byte oldSwitchState = HIGH;  // assume switch open because of pull-up resistor
const unsigned long debounceTime = 100;  // milliseconds
unsigned long switchPressTime;  // when the switch last changed state

void setup ()
  {
  pinMode (switchPin, INPUT_PULLUP);

     //setup hashmap
  hashMap.put("key0","test0");
  hashMap.put("key1","test1");
  hashMap.put("key2","test2");
  hashMap.put("key3","test3");
  hashMap.put("key4","test4");

  DigiKeyboard.sendKeyStroke(0);

  }  // end of setup

void loop ()
  {
  // see if switch is open or closed
  byte switchState = digitalRead (switchPin);

  // has it changed since last time?
  if (switchState != oldSwitchState)
    {
    // debounce
    if (millis () - switchPressTime >= debounceTime)
       {
       switchPressTime = millis ();  // when we closed the switch
       oldSwitchState =  switchState;  // remember for next time
       if (switchState == HIGH)
          {
            delay(500);
            flag = true;
           while(i < hashMap.count() and flag == true)
            {
              DigiKeyboard.println( hashMap.valueAt(i));
              i++;
              flag = false;
              }
          }  // end if switchState is LOW
       }  // end if debounce time up

    }  // end of state change

  // other code here ...

  }  // end of loop

```

# Answer
> 0 votes
1. Even with a "clean" button, your while() loop will whip through all 5 hashmap values before you can release the button.
2. Switches and button aren't clean. They will (appear to) bounce, sending many pulses before they settle down to a fully on or fully off state. Read Nick Gammon's tutorial on de-bouncing switches.
3. I'm not familiar with your display but if it is a one-line display, and you .println() at it, will the newline character "scroll" the line of text off the display? This could explain why you didn't at least see the final line. You may need a plain .print() call in order not to do that.
4. Most LCD displays have a set of control codes to clear it, move the cursor, etc., which you would have to embed into the text string you send, or send using separate .print() calls. I don't see any provision in your code for including or sending those, so you'll need to fix that, too.
Right now, I expect your display receives something like
`test0\ntest1\ntest2\ntest3\ntest4\n`
It probably needs to see something more like
`\033Etest0`
, e.g., for the first one, etc. That cruft at the beginning of the string is the VT52-code,
`esc``E`, for "Clear the display". (I have no idea what command set your display uses, but the VT-52 commands have been in use for ... um, hmmph! well, a long time, anyway. :) You'll probably to replace it with whatever your particular device uses.

---
Tags: c, attiny, button, digispark
---


# Question
Title: Common/standard library and/or protocol for Arduino to be I2C slave for driving NeoPixel
I would like to control a string of WS2812/NeoPixels from a SBC like a BeagleBone or C.H.I.P. I realize someone has gone through the trouble to come up with a way to drive the WS2812 string from a BeagleBone directly with the PMU, but I would like to have an Arduino like a Pro Mini do the signal generation, while the SBC would direct the Arduino what to display.

I found the node-pixel setup with I2C backpack on the arduino, but it requires on the SBC side NodeJS, Johnny-Five and other libraries that I would have no other use for. It seems overkill.

Is there some commonly used protocol over I2C for controlling NeoPixels (with the arduino being the I2C slave), or will I be better off developing my own simple protocol?

On the SBC side, I would likely be coding either in C/C++ or Python.

# Answer
If it helps simplify your project, I wrote a small library that outputs to NeoPixels using the SPI hardware. The code to send one byte is simply this on the Atmega328P:

```
void sendByte (byte b)
  {
    // send one byte to the Neopixels - note that the "off" gap is partly handled by the loop overhead
    //   gaps measured empirically to be 1.7 µs to 2 µs, so we don't need to add any more of our own
    for (byte bit = 0; bit < 8; bit++)
      {
      if (b & 0x80) // is high-order bit set?
        SPI.transfer (0b11111100);  // 1 bit - 750 ns on + 250 ns off (acceptable "on" range 550 ns to 850 ns)
      else
        SPI.transfer (0b11100000);  // 0 bit - 375 ns on + 625 ns off (acceptable "on" range 200 ns to 500 ns)
      b <<= 1; // shift next bit into high-order position
    } // end of for each bit
} // end of sendByte

```

One pixel is 3 bytes (green / red / blue):

```
void sendPixel (const byte r, const byte g, const byte b)
  {
  sendByte (g);        // NeoPixel wants colors in green-then-red-then-blue order
  sendByte (r);
  sendByte (b);
  } // end of sendPixel

```

The timing issue arises because the pixels "latch" if around 9µs elapses with no data. Thus you either precompute the data to be sent, or decide what to send very quickly.

---

Under the circumstances, using I2C, you would need to precompute the data, these is no way you could receive I2C on the fly and send it out to the Neopixels with them latching.

---

> Is there some commonly used protocol over I2C for controlling NeoPixels ?

Not that I am aware of. I suggest you either send the pixel data (which would be a lot, and have to be broken into smallish packets), or send a "pattern number" and have the receiver generate the data.

Be aware that the standard I2C library has a 32-byte buffer so you can't send hundreds of bytes in a single I2C transaction.
> 0 votes

# Answer
You should break your project up into smaller parts.

1. Consider using other led strips, that can be driven directly. Consider using ready-made parts or opensource code (google).
2. Make an Arduino drive a NeoPixel Ledstrip. (Check adafruit libraries/NeoPixel guide)(Sanity/wiring check)
3. Communicate with Arduino and Beaglebone over I2C. Try sending "Hi" and respond "Ok".
4. Think of a protocol, how to indicate start/stop of a message.
5. Send the "color bytes" using said protocol.
6. Unpack the color bytes and put them in a pixel array (See NeoPixel library).
7. Run "ledstrip.show();”

Please atleast try to do these steps. If one fails, you can create a question with details on what you have tried or what isn't working.

Maybe "nodepixel" already has the Arduino code for you. You then only need to know what bytes to send over I2C, which you can do with any programming language that supports I2C access on your platform.
> 0 votes

---
Tags: i2c, neopixel
---


# Question
Title: How do interrupts work on the Arduino Uno and similar boards?
Please explain how interrupts work on the Arduino Uno and related boards using the ATmega328P processor. Boards such as the:

* Uno
* Mini
* Nano
* Pro Mini
* Lilypad

In particular please discuss:

* What to use interrupts for
* How to write an Interrupt Service Routine (ISR)
* Timing issues
* Critical sections
* Atomic access to data

---

*Note: this is a reference question*.

# Answer
> 37 votes
# TL;DR :

When writing an Interrupt Service Routine (ISR):

* Keep it *short*
* Don't use `delay ()`
* Don't do serial prints
* Make variables shared with the main code **volatile**
* Variables shared with main code may need to be protected by "critical sections" (see below)
* Don't try to turn interrupts off or on

---

# What are interrupts?

Most processors have interrupts. Interrupts let you respond to "external" events while doing something else. For example, if you are cooking dinner you may put the potatoes on to cook for 20 minutes. Rather than staring at the clock for 20 minutes you might set a timer, and then go watch TV. When the timer rings you "interrupt" your TV viewing to do something with the potatoes.

---

# Example of interrupts

```
const byte LED = 13;
const byte SWITCH = 2;

// Interrupt Service Routine (ISR)
void switchPressed ()
{
  if (digitalRead (SWITCH) == HIGH)
    digitalWrite (LED, HIGH);
  else
    digitalWrite (LED, LOW);
}  // end of switchPressed

void setup ()
{
  pinMode (LED, OUTPUT);  // so we can update the LED
  pinMode (SWITCH, INPUT_PULLUP);
  attachInterrupt (digitalPinToInterrupt (SWITCH), switchPressed, CHANGE);  // attach interrupt handler
}  // end of setup

void loop ()
{
  // loop doing nothing
}

```

This example shows how, even though the main loop is doing nothing, you can turn the LED on pin 13 on or off, if the switch on pin D2 is pressed.

To test this, just connect a wire (or switch) between D2 and Ground. The internal pullup (enabled in setup) forces the pin HIGH normally. When grounded, it becomes LOW. The change in the pin is detected by a CHANGE interrupt, which causes the Interrupt Service Routine (ISR) to be called.

In a more complicated example, the main loop might be doing something useful, like taking temperature readings, and allow the interrupt handler to detect a button being pushed.

---

# Converting pin numbers to interrupt numbers

To simplify converting interrupt vector numbers to pin numbers you can call the function `digitalPinToInterrupt()`, passing a pin number. It returns the appropriate interrupt number, or `NOT_AN_INTERRUPT` (-1).

For example, on the Uno, pin D2 on the board is interrupt 0 (INT0\_vect from the table below).

Thus these two lines have the same effect:

```
  attachInterrupt (0, switchPressed, CHANGE);    // that is, for pin D2
  attachInterrupt (digitalPinToInterrupt (2), switchPressed, CHANGE);

```

However the second one is easier to read and more portable to different Arduino types.

---

# Available interrupts

Below is a list of interrupts, in priority order, for the Atmega328:

```
 1  Reset
 2  External Interrupt Request 0  (pin D2)          (INT0_vect)
 3  External Interrupt Request 1  (pin D3)          (INT1_vect)
 4  Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
 5  Pin Change Interrupt Request 1 (pins A0 to A5)  (PCINT1_vect)
 6  Pin Change Interrupt Request 2 (pins D0 to D7)  (PCINT2_vect)
 7  Watchdog Time-out Interrupt                     (WDT_vect)
 8  Timer/Counter2 Compare Match A                  (TIMER2_COMPA_vect)
 9  Timer/Counter2 Compare Match B                  (TIMER2_COMPB_vect)
10  Timer/Counter2 Overflow                         (TIMER2_OVF_vect)
11  Timer/Counter1 Capture Event                    (TIMER1_CAPT_vect)
12  Timer/Counter1 Compare Match A                  (TIMER1_COMPA_vect)
13  Timer/Counter1 Compare Match B                  (TIMER1_COMPB_vect)
14  Timer/Counter1 Overflow                         (TIMER1_OVF_vect)
15  Timer/Counter0 Compare Match A                  (TIMER0_COMPA_vect)
16  Timer/Counter0 Compare Match B                  (TIMER0_COMPB_vect)
17  Timer/Counter0 Overflow                         (TIMER0_OVF_vect)
18  SPI Serial Transfer Complete                    (SPI_STC_vect)
19  USART Rx Complete                               (USART_RX_vect)
20  USART, Data Register Empty                      (USART_UDRE_vect)
21  USART, Tx Complete                              (USART_TX_vect)
22  ADC Conversion Complete                         (ADC_vect)
23  EEPROM Ready                                    (EE_READY_vect)
24  Analog Comparator                               (ANALOG_COMP_vect)
25  2-wire Serial Interface  (I2C)                  (TWI_vect)
26  Store Program Memory Ready                      (SPM_READY_vect)

```

Internal names (which you can use to set up ISR callbacks) are in brackets.

*Warning: If you misspell the interrupt vector name, even by just getting the capitalization wrong (an easy thing to do) the interrupt routine **will not be called**, and you will not get a compiler error.*

---

# Reasons to use interrupts

The main reasons you might use interrupts are:

* To detect pin changes (eg. rotary encoders, button presses)
* Watchdog timer (eg. if nothing happens after 8 seconds, interrupt me)
* Timer interrupts - used for comparing/overflowing timers
* SPI data transfers
* I2C data transfers
* USART data transfers
* ADC conversions (analog to digital)
* EEPROM ready for use
* Flash memory ready

The "data transfers" can be used to let a program do something else while data is being sent or received on the serial port, SPI port, or I2C port.

## Wake the processor

External interrupts, pin-change interrupts, and the watchdog timer interrupt, can also be used to wake the processor up. This can be very handy, as in sleep mode the processor can be configured to use a lot less power (eg. around 10 microamps). A rising, falling, or low-level interrupt can be used to wake up a gadget (eg. if you press a button on it), or a "watchdog timer" interrupt might wake it up periodically (eg. to check the time or temperature).

Pin-change interrupts could be used to wake the processor if a key is pressed on a keypad, or similar.

The processor can also be awoken by a timer interrupt (eg. a timer reaching a certain value, or overflowing) and certain other events, such as an incoming I2C message.

---

# Enabling / disabling interrupts

The "reset" interrupt cannot be disabled. However the other interrupts can be temporarily disabled by clearing the global interrupt flag.

## Enable interrupts

You can enable interrupts with the function call "interrupts" or "sei" like this:

```
interrupts ();  // or ...
sei ();         // set interrupts flag

```

## Disable interrupts

If you need to disable interrupts you can "clear" the global interrupt flag like this:

```
noInterrupts ();  // or ...
cli ();           // clear interrupts flag

```

Either method has the same effect, using `interrupts` / `noInterrupts` is a bit easier to remember which way around they are.

The default in the Arduino is for interrupts to be enabled. Don't disable them for long periods or things like timers won't work properly.

## Why disable interrupts?

There may be time-critical pieces of code that you don't want interrupted, for example by a timer interrupt.

Also if multi-byte fields are being updated by an ISR then you may need to disable interrupts so that you get the data "atomically". Otherwise one byte may be updated by the ISR while you are reading the other one.

For example:

```
noInterrupts ();
long myCounter = isrCounter;  // get value set by ISR
interrupts ();

```

Temporarily turning off interrupts ensures that isrCounter (a counter set inside an ISR) does not change while we are obtaining its value.

**Warning:** if you are not sure if interrupts are already on or not, then you need to save the current state and restore it afterwards. For example, the code from the millis() function does this:

```
unsigned long millis()
{
  unsigned long m;
  uint8_t oldSREG = SREG;    // <--------- save status register

  // disable interrupts while we read timer0_millis or we might get an
  // inconsistent value (e.g. in the middle of a write to timer0_millis)
  cli();
  m = timer0_millis;
  SREG = oldSREG;            // <---------- restore status register including interrupt flag

  return m;
}

```

Note the indicated lines save the current SREG (status register) which includes the interrupt flag. After we have obtained the timer value (which is 4 bytes long) we put the status register back how it was.

---

# Tips

## Function names

The functions `cli` / `sei` and the register SREG are specific to the AVR processors. If you are using other processors such as the ARM ones the functions may be slightly different.

## Disabling globally vs disabling one interrupt

If you use `cli()` you disable **all** interrupts (including timer interrupts, serial interrupts, etc.).

However if you just want to disable a **particular** interrupt then you should clear the interrupt-enable flag for that particular interrupt source. For example, for external interrupts, call `detachInterrupt()`.

---

# What is interrupt priority?

Since there are 25 interrupts (other than reset) it is possible that more than one interrupt event might occur at once, or at least, occur before the previous one is processed. Also an interrupt event might occur while interrupts are disabled.

The priority order is the sequence in which the processor checks for interrupt events. The higher up the list, the higher the priority. So, for example, an External Interrupt Request 0 (pin D2) would be serviced before External Interrupt Request 1 (pin D3).

---

# Can interrupts occur while interrupts are disabled?

Interrupts **events** (that is, noticing the event) can occur at any time, and most are remembered by setting an "interrupt event" flag inside the processor. If interrupts are disabled, then that interrupt will be handled when they are enabled again, in priority order.

---

# How do you use interrupts?

* You write an ISR (interrupt service routine). This is called when the interrupt occurs.
* You tell the processor when you want the interrupt to fire.

## Writing an ISR

Interrupt Service Routines are functions with no arguments. Some Arduino libraries are designed to call your own functions, so you just supply an ordinary function (as in the examples above), eg.

```
// Interrupt Service Routine (ISR)
void switchPressed ()
{
 flag = true;
}  // end of switchPressed

```

However if a library has not already provided a "hook" to an ISR you can make your own, like this:

```
volatile char buf [100];
volatile byte pos;

// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;  // grab byte from SPI Data Register

  // add to buffer if room
  if (pos < sizeof buf)
    {
    buf [pos++] = c;
    }  // end of room available
}  // end of interrupt routine SPI_STC_vect

```

In this case you use the "ISR" macro, and supply the name of the relevant interrupt vector (from the table earlier on). In this case the ISR is handling an SPI transfer completing. (Note, some old code uses SIGNAL instead of ISR, however SIGNAL is deprecated).

## Connecting an ISR to an interrupt

For interrupts already handled by libraries, you just use the documented interface. For example:

```
void receiveEvent (int howMany)
 {
  while (Wire.available () > 0)
    {
    char c = Wire.receive ();
    // do something with the incoming byte
    }
}  // end of receiveEvent

void setup ()
  {
  Wire.onReceive(receiveEvent);
  }

```

In this case the I2C library is designed to handle incoming I2C bytes internally, and then call your supplied function at the end of the incoming data stream. In this case receiveEvent is not strictly an ISR (it has an argument) but it is called by an inbuilt ISR.

Another example is the "external pin" interrupt.

```
// Interrupt Service Routine (ISR)
void switchPressed ()
{
  // handle pin change here
}  // end of switchPressed

void setup ()
{
  attachInterrupt (digitalPinToInterrupt (2), switchPressed, CHANGE);  // attach interrupt handler for D2
}  // end of setup

```

In this case the attachInterrupt function adds the function switchPressed to an internal table, and in addition configures the appropriate interrupt flags in the processor.

## Configuring the processor to handle an interrupt

The next step, once you have an ISR, is to tell the processor that you want this particular condition to raise an interrupt.

As an example, for External Interrupt 0 (the D2 interrupt) you could do something like this:

```
EICRA &= ~3;  // clear existing flags
EICRA |= 2;   // set wanted flags (falling level interrupt)
EIMSK |= 1;   // enable it

```

More readable would be to use the defined names, like this:

```
EICRA &= ~(bit(ISC00) | bit (ISC01));  // clear existing flags
EICRA |= bit (ISC01);    // set wanted flags (falling level interrupt)
EIMSK |= bit (INT0);     // enable it

```

EICRA (External Interrupt Control Register A) would be set according to this table from the Atmega328 datasheet. That defines the exact type of interrupt you want:

* 0: The low level of INT0 generates an interrupt request (LOW interrupt).
* 1: Any logical change on INT0 generates an interrupt request (CHANGE interrupt).
* 2: The falling edge of INT0 generates an interrupt request (FALLING interrupt).
* 3: The rising edge of INT0 generates an interrupt request (RISING interrupt).

EIMSK (External Interrupt Mask Register) actually enables the interrupt.

Fortunately you don't need to remember those numbers because attachInterrupt does that for you. However that is what is actually happening, and for other interrupts you may have to "manually" set interrupt flags.

---

# Low-level ISRs vs. library ISRs

To simplify your life some common interrupt handlers are actually inside library code (for example INT0\_vect and INT1\_vect) and then a more user-friendly interface is provided (eg. attachInterrupt). What attachInterrupt actually does is save the address of your wanted interrupt handler into a variable, and then call that from INT0\_vect / INT1\_vect when needed. It also sets the appropriate register flags to call the handler when required.

---

# Can ISRs be interrupted?

In short, no, not unless you want them to be.

When an ISR is entered, **interrupts are disabled**. Naturally they must have been enabled in the first place, otherwise the ISR would not be entered. However to avoid having an ISR itself be interrupted, the processor turns interrupts off.

When an ISR exits, then **interrupts are enabled again**. The compiler also generates code inside an ISR to save registers and status flags, so that whatever you were doing when the interrupt occurred will not be affected.

However you **can** turn interrupts on inside an ISR if you absolutely must, eg.

```
// Interrupt Service Routine (ISR)
void switchPressed ()
{
  // handle pin change here
  interrupts ();  // allow more interrupts

}  // end of switchPressed

```

Normally you would need a pretty good reason to do this, as another interrupt now could result in a recursive call to pinChange, with quite possibly undesirable results.

---

# How long does it take to execute an ISR?

According to the datasheet, the minimal amount of time to service an interrupt is 4 clock cycles (to push the current program counter onto the stack) followed by the code now executing at the interrupt vector location. This normally contains a jump to where the interrupt routine really is, which is another 3 cycles. Examination of the code produced by the compiler shows that an ISR made with the "ISR" declaration can take around 2.625 µs to execute, plus whatever the code itself does. The exact amount depends on how many registers need to be saved and restored. The minimum amount would be 1.1875 µs.

The external interrupts (where you use attachInterrupt) do a bit more and take around 5.125 µs in total (running with a 16 MHz clock).

---

# How long before the processor starts entering an ISR?

This varies somewhat. The figures quoted above are the ideal ones where the interrupt is immediately processed. A few factors may delay that:

* If the processor is asleep, there are designated "wake-up" times, which could be quite a few milliseconds, while the clock is spooled back up to speed. This time would depend on fuse settings, and how deep the sleep is.
* If an interrupt service routine is already executing, then further interrupts cannot be entered until it either finishes, or enables interrupts itself. This is why you should keep each interrupt service routine short, as every microsecond you spend in one, you are potentially delaying the execution of another one.
* Some code turns interrupts off. For example, calling millis() briefly turns interrupts off. Therefore the time for an interrupt to be serviced would be extended by the length of time interrupts were turned off.
* Interrupts can only be serviced at the end of an instruction, so if a particular instruction takes three clock cycles, and has just started, then the interrupt will be delayed at least a couple of clock cycles.
* An event that turns interrupts back on (eg. returning from an interrupt service routine) is guaranteed to execute at least one more instruction. So even if an ISR ends, and your interrupt is pending, it still has to wait for one more instruction before it is serviced.
* Since interrupts have a priority, a higher-priority interrupt might be serviced before the interrupt you are interested in.

---

# Performance considerations

Interrupts can increase performance in many situations because you can get on with the "main work" of your program without having to constantly be testing to see if switches have been pressed. Having said that, the overhead of servicing an interrupt, as discussed above, would actually be more than doing a "tight loop" polling a single input port. You can barely respond to an event within, say, a microsecond. In that case you might disable interrupts (eg. timers) and just loop looking for the pin to change.

---

# How are interrupts queued?

There are two sorts of interrupts:

* Some set a flag and they are handled in priority order, even if the event that caused them has stopped. For example, a rising, falling, or changing level interrupt on pin D2.
* Others are only tested if they are happening "right now". For example, a low-level interrupt on pin D2.

The ones that set a flag could be regarded as being queued, as the interrupt flag remains set until such time as the interrupt routine is entered, at which time the processor clears the flag. Of course, since there is only one flag, if the same interrupt condition occurs again before the first one is processed, it won't be serviced twice.

Something to be aware of is that these flags can be set before you attach the interrupt handler. For example, it is possible for a rising or falling level interrupt on pin D2 to be "flagged", and then as soon as you do an attachInterrupt the interrupt immediately fires, even if the event occurred an hour ago. To avoid this you can manually clear the flag. For example:

```
EIFR = bit (INTF0);  // clear flag for interrupt 0
EIFR = bit (INTF1);  // clear flag for interrupt 1

```

However the "low level" interrupts are continuously checked, so if you are not careful they will keep firing, even after the interrupt has been called. That is, the ISR will exit, and then the interrupt will immediately fire again. To avoid this, you should do a detachInterrupt immediately after you know that the interrupt fired.

---

# Hints for writing ISRs

In brief, keep them short! While an ISR is executing other interrupts cannot be processed. So you could easily miss button presses, or incoming serial communications, if you try to do too much. In particular, you should not try to do debugging "prints" inside an ISR. The time taken to do those is likely to cause more problems than they solve.

A reasonable thing to do is set a single-byte flag, and then test that flag in the main loop function. Or, store an incoming byte from a serial port into a buffer. The inbuilt timer interrupts keep track of elapsed time by firing every time the internal timer overflows, and thus you can work out elapsed time by knowing how many times the timer overflowed.

Remember, inside an ISR interrupts are disabled. Thus hoping that the time returned by millis() function calls will change, will lead to disappointment. It is valid to **obtain** the time that way, just be aware that the timer is not incrementing. And if you spend too long in the ISR then the timer may miss an overflow event, leading to the time returned by millis() becoming incorrect.

A test shows that, on a 16 MHz Atmega328 processor, a call to micros() takes 3.5625 µs. A call to millis() takes 1.9375 µs. Recording (saving) the current timer value is a reasonable thing to do in an ISR. Finding the elapsed milliseconds is faster than the elapsed microseconds (the millisecond count is just retrieved from a variable). However the microsecond count is obtained by adding the current value of the Timer 0 timer (which will keep incrementing) to a saved "Timer 0 overflow count".

**Warning:** Since interrupts are disabled inside an ISR, and since the latest version of the Arduino IDE uses interrupts for Serial reading and writing, and also for incrementing the counter used by "millis" and "delay" you should not attempt to use those functions inside an ISR. To put it another way:

* Don't attempt to delay, eg: `delay (100);`
* You can get the time from a call to millis, however it won't increment, so don't attempt to delay by waiting for it to increase.
* Don't do serial prints (eg. `Serial.println ("ISR entered");` )
* Don't try to do serial reading.

---

# Pin change interrupts

There are two ways you can detect external events on pins. The first is the special "external interrupt" pins, D2 and D3. These general discrete interrupt events, one per pin. You can get to those by using attachInterrupt for each pin. You can specify a rising, falling, changing or low-level condition for the interrupt.

However there are also "pin change" interrupts for all pins (on the Atmega328, not necessarily all pins on other processors). These act on groups of pins (D0 to D7, D8 to D13, and A0 to A5). They are also lower priority than the external event interrupts. However they are a bit more fiddly to use than the external interrupts because they are grouped into batches. So if the interrupt fires you have to work out in your own code exactly which pin caused the interrupt.

Example code:

```
ISR (PCINT0_vect)
 {
 // handle pin change interrupt for D8 to D13 here
 }  // end of PCINT0_vect

ISR (PCINT1_vect)
 {
 // handle pin change interrupt for A0 to A5 here
 }  // end of PCINT1_vect

ISR (PCINT2_vect)
 {
 // handle pin change interrupt for D0 to D7 here
 }  // end of PCINT2_vect

void setup ()
  {
  // pin change interrupt (example for D9)
  PCMSK0 |= bit (PCINT1);  // want pin 9
  PCIFR  |= bit (PCIF0);   // clear any outstanding interrupts
  PCICR  |= bit (PCIE0);   // enable pin change interrupts for D8 to D13
  }

```

To handle a pin change interrupt you need to:

* Specify which pin in the group. This is the PCMSKn variable (where n is 0, 1 or 2 from the table below). You can have interrupts on more than one pin.
* Enable the appropriate group of interrupts (0, 1 or 2)
* Supply an interrupt handler as shown above

## Table of pins -\> pin change names / masks

```
D0    PCINT16 (PCMSK2 / PCIF2 / PCIE2)
D1    PCINT17 (PCMSK2 / PCIF2 / PCIE2)
D2    PCINT18 (PCMSK2 / PCIF2 / PCIE2)
D3    PCINT19 (PCMSK2 / PCIF2 / PCIE2)
D4    PCINT20 (PCMSK2 / PCIF2 / PCIE2)
D5    PCINT21 (PCMSK2 / PCIF2 / PCIE2)
D6    PCINT22 (PCMSK2 / PCIF2 / PCIE2)
D7    PCINT23 (PCMSK2 / PCIF2 / PCIE2)
D8    PCINT0  (PCMSK0 / PCIF0 / PCIE0)
D9    PCINT1  (PCMSK0 / PCIF0 / PCIE0)
D10   PCINT2  (PCMSK0 / PCIF0 / PCIE0)
D11   PCINT3  (PCMSK0 / PCIF0 / PCIE0)
D12   PCINT4  (PCMSK0 / PCIF0 / PCIE0)
D13   PCINT5  (PCMSK0 / PCIF0 / PCIE0)
A0    PCINT8  (PCMSK1 / PCIF1 / PCIE1)
A1    PCINT9  (PCMSK1 / PCIF1 / PCIE1)
A2    PCINT10 (PCMSK1 / PCIF1 / PCIE1)
A3    PCINT11 (PCMSK1 / PCIF1 / PCIE1)
A4    PCINT12 (PCMSK1 / PCIF1 / PCIE1)
A5    PCINT13 (PCMSK1 / PCIF1 / PCIE1)

```

## Interrupt handler processing

The interrupt handler would need to work out which pin caused the interrupt if the mask specifies more than one (eg. if you wanted interrupts on D8/D9/D10). To do this you would need to store the previous state of that pin, and work out (by doing a digitalRead or similar) if this particular pin had changed.

---

# You are probably using interrupts anyway ...

A "normal" Arduino environment already is using interrupts, even if you don't personally attempt to. The millis() and micros() function calls make use of the "timer overflow" feature. One of the internal timers (timer 0) is set up to interrupt roughly 1000 times a second, and increment an internal counter which effectively becomes the millis() counter. There is a bit more to it than that, as adjustment is made for the exact clock speed.

Also the hardware serial library uses interrupts to handle incoming and outgoing serial data. This is very useful as your program can be doing other things while the interrupts are firing, and filling up an internal buffer. Then when you check Serial.available() you can find out what, if anything, has been placed in that buffer.

---

# Executing the next instruction after enabling interrupts

After a bit of discussion and research on the Arduino forum, we have clarified exactly what happens after you enable interrupts. There are three main ways I can think of that you can enable interrupts, which were previously not enabled:

```
  sei ();  // set interrupt enable flag
  SREG |= 0x80;  // set the high-order bit in the status register
  reti  ;   // assembler instruction "return from interrupt"

```

In all cases, the processor guarantees that the **next** instruction after interrupts are enabled (if they were previously disabled) will always be executed, even if an interrupt event is pending. (By "next" I mean the next one in program sequence, not necessarily the one physically following. For example, a RETI instruction jumps back to where the interrupt occurred, and then executes one more instruction).

This lets you write code like this:

```
sei ();
sleep_cpu ();

```

If not for this guarantee, the interrupt might occur **before** the processor slept, and then it might never be awoken.

---

# Empty interrupts

If you merely want an interrupt to wake the processor, but not do anything in particular, you can use the EMPTY\_INTERRUPT define, eg.

```
EMPTY_INTERRUPT (PCINT1_vect);

```

This simply generates a "reti" (return from interrupt) instruction. Since it doesn't try to save or restore registers this would be the fastest way to get an interrupt to wake it up.

---

# Critical sections (atomic variable access)

There are some subtle issues regarding variables which are shared between interrupt service routines (ISRs) and the main code (that is, the code not in an ISR).

Since an ISR can fire at any time when interrupts are enabled, you need to be cautious about accessing such shared variables, as they may be being updated at the very moment you access them.

## First ... when do you use "volatile" variables?

A variable should only be marked volatile if it is used both inside an ISR, and outside one.

* Variables **only** used outside an ISR should **not** be volatile.
* Variables **only** used inside an ISR should **not** be volatile.
* Variables used both inside and outside an ISR **should** be volatile.

eg.

```
volatile int counter;

```

Marking a variable as volatile tells the compiler to not "cache" the variables contents into a processor register, but always read it from memory, when needed. This may slow down processing, which is why you don't just make every variable volatile, when not needed.

## Turn interrupts off while accessing a volatile variable

For example, to compare `count` to some number, turn interrupts off during the compare in case one byte of `count` has been updated by the ISR and not the other byte.

```
volatile unsigned int count;

ISR (TIMER1_OVF_vect)
  {
  count++;
  } // end of TIMER1_OVF_vect

void setup ()
  {
  pinMode (13, OUTPUT);
  }  // end of setup

void loop ()
  {
  noInterrupts ();    // <------ critical section
  if (count > 20)
     digitalWrite (13, HIGH);
  interrupts ();      // <------ end critical section
  } // end of loop

```

---

# Read the data sheet!

More information about interrupts, timers, etc. can be obtained from the data sheet for the processor.

http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P\_datasheet\_Complete.pdf

---

# Further examples

Space considerations (post size limit) prevent my listing more example code. For more example code see my page about interrupts.

---
Tags: arduino-uno, c++, interrupt, atmega328, arduino-mini
---


# Question
Title: Arduino Uno's RX and TX lights not blinking. Unable to upload sketches!
When arduino starts up, RX TX lights doesn't blink. Only the PIN 13 and Green light turns on. Pin 13 light blinks thrice before getting stable. RX TX lights are not blinking at all. I am not able to upload any sketches. The error I get is "Not in sync resp=0x00" or "Programmer not responding" or "Not in sync resp=0x95" or "Not in sync resp=0x69" and so on. A new error everytime. Most probably the error is with serial communication.

A brief history of what I have done

I have a Relay which is operated at 12V. But Arduino works at 5V logic. So I used a comparator (IC741) to improve the logic (By setting Vcc and -Vcc at 12 and 0 and the input pins connected to arduino). I also connected HC-05 bluetooth module to use the relay using my cellphone. You know what I was trying was home automation. Also Arduino was connected to 12V DC supply (I think this was my mistake). Everything was going right.

Suddenly IC741 started burning,maybe I shorted some pins when I was trying to measure the voltages using multimeter. I quickly removed it. Suddenly HC 05 started burning. I immediately removed all the connections. After some time I turned on Arduino again (This time using USB connected to laptop). I connected HC05. The bluetooth module heats up again. I thought the module is now gone. I turned to check Arduino and as I stated I am unable to upload any more sketches. Most probably the bluetooth module cause an error in serial communication. May be not.

So my question is 1. What's the real problem. Is my bluetooth module gone? Or is Arduino gone? If arduino is still fine, how can I get the serial to work back and enable me to upload sketches? 2. If Arduino is gone, most probably the microcontroller Atmega328 is still fine. How can I use it now without Arduino (I don't have any extra Arduino)?

Things I have already tried :

1. Loopback test : No echo back. Serial data can neither be sent nor received.
2. When I open the Serial window, Arduino doesn't resets as it it earlier.
3. RX TX Vin and 5V pin reads 4.99V. I hope they are fine.

# Answer
> Pin 13 light blinks thrice before getting stable.

It is supposed to do exactly that. See What happens when code is uploaded using the bootloader?

> RX TX lights are not blinking at all.

That's not so good. See Have I bricked my Arduino Uno? Problems with uploading to board
> 1 votes

# Answer
Can you test the bluetooth module separately? i.e. just connect the power pins directly to the correct voltage source, and check if it overheats. In this way you may be able to find the source of the short circuit.

If you shorted one or more of your arduino's I/O pins, you may have damaged your Atmega328 chip, since there's no protection between the chip and IO headers. The other circuitry on the Arduino board is mostly power conditioning/regulation. So I'm assuming that's not the problem. Check if your 328 is getting the correct voltage at the VCC pin, to eliminate the power circuitry as the problem.
> 0 votes

# Answer
If you are getting three blinks, most likely bootloader is fine but don't take it for granted. Also, post a schematic and picture of your original setup to get better answers in future.

Here is how you should start the debugging process:

1) Disconnect everything from Arduino especially from Tx Rx pins, and try to dump the blinky sketch. If it works, then arduino is good. If it doesn't work, follow this article to burn a fresh bootloader in your atmega. Check again. If not able to burn bootloader or code afterwards, get a new atmega IC for cheap and replace the damaged one.

2) Check the voltage requirements for HC-05 whether it's 3.3V or 5V. Make sure you are not giving it a higher voltage. If it starts to smoke as soon as you connect the GND VCC, then probably it has been damaged. Measure the resistance between GND and VCC of HC-05 before attaching. If it's less than 10-20 ohms, you already know that it's damaged.
> 0 votes

---
Tags: relay, bluetooth
---


# Question
Title: how to measure level shock using vibration sensor and arduino
My project title is about crash detection, by using this kind of vibration sensor. When the sensor reads the shock (which is when I knock the sensor) more than 50, it assumes it's a crash and will send via SMS the location of the crash to me. The problem is, that I tried to connect the sensor with Arduino, but when I knocked the sensor, the value of the shock did not change. How can I fix this?

VCC I connected to 5V,
GND to Arduino GND,
A0 to analog input Arduino,
D0 is not used

This is my code

---

```
#include <SoftwareSerial.h>

#include <TinyGPS.h>

TinyGPS gps;
SoftwareSerial ss(2, 3);
SoftwareSerial GSMx(5, 11);

static void smartdelay(unsigned long ms);
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

//-------------------VARIABLE-------------------------------
float LastLon;
String dataString = "";
String DateString = "";
String TimeString = "";
int Sens1Pin = 0;
float Sens1;
int update=0;
float LastLat;
int dummy=0;
int RQScount;
int countERROR;
int countPHONE;
int countOK;
int commaPosition;
int index = 0;
int SMSx=0;
int ALARM=0;
int LOCK=0;
float latx;
float lonx;
int OUTRANGE=0;
String result[10];
String USER1 = "\"019*******\"";
String Data1 = "";
String Data2 = "";
String Data3 = "";
String Data4 = "";
String head = "";
String phone = "";
String pword = "";
String MESSAGE1="";
String MESSAGE2="";
String inputString = "";         // a string to hold incoming data
boolean stringComplete = true;  // whether the string is complete
boolean command = true;
boolean Enabled = false;
boolean Enabled1 = false;
boolean Enabled2 = false;
boolean Enabled3 = false;
boolean GPS_NoData = false;
float SHOCK;
int count;
float flat, flon;
  unsigned long age, date, time, chars = 0;
  float ExistingSpeed;
float SpeedGPS;

//----------------------------------------------------------

void setup()
{

  Serial.begin(9600);
  GSMx.begin(9600);
  inputString.reserve(150);
 delay(8000);

  //Serial.println("AT");
  GSMx.println("AT");
  delay(2000);
 // Serial.println("AT+CMGF=1");
  GSMx.println("AT+CMGF=1");
  delay(2000);
 // Serial.println("AT+CMGD=1");
  GSMx.println("AT+CMGD=1");
  delay(2000);
  //Serial.println("AT&W");
  GSMx.println("AT&W");
  delay(2000);

  //Serial.print("AT+CMGS=");
  delay(300);
  //Serial.println(USER1);
  GSMx.print("AT+CMGS=");
  delay(300);
  GSMx.println(USER1);
  delay(1000);
  //Serial.print("GPS-GSM TRACKER---ACTIVATED ");
  GSMx.print("Controller is now ready...");
  delay(200);
  //Serial.println(char(26));
  GSMx.println(char(26));
  delay(4000);

  //Serial.println("Sats HDOP Latitude  Longitude  Fix  Date       Time     Date Alt    Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  //Serial.println("          (deg)     (deg)      Age                      Age  (m)    --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  //Serial.println("-------------------------------------------------------------------------------------------------------------------------------------");

  ss.begin(9600);
  //--------------------------------------

  stringComplete = true;
}

void loop()
{

  Sens1 = analogRead(Sens1Pin);           //read the value from the sensor
  Sens1 = (5.0 * Sens1 * 100.0)/1024.0;  //convert the analog data to digital

  SHOCK = ((390 - Sens1)/390)*100;

  unsigned short sentences = 0, failed = 0;
  static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

 if (SHOCK > 40){
    ALARM=1;
  }

  if (ALARM==1){
    delay(100);

    if (SMSx==0){
     //  Serial.print("AT+CMGS=");
                GSMx.print("AT+CMGS=");
               // Serial.println(USER1);
                GSMx.println(USER1);
                delay(1000);
               // Serial.print("ALARM ALERT!! at location, lat:");
                GSMx.print("EMERGENCY ALERT!!");
               // Serial.print(flat,5);
                GSMx.print(TimeString);
                GSMx.print(" ");
                GSMx.print(DateString);
                GSMx.print(" (LAT/LON/SPEED) ");
                GSMx.print(dataString);

                GSMx.print("www.google.co.in/maps/place/");
                GSMx.print(flat,5);
                GSMx.print(",");
                GSMx.println(flon,5);

                delay(200);
               // Serial.println(char(26));
                GSMx.println(char(26));
                delay(4000);

      SMSx=1;
      ALARM=0;
    }
  }

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 10, 6);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 11, 6);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  print_date(gps);
  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 7, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0xFFFFFFFF : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? TinyGPS::GPS_INVALID_F_ANGLE : TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  //Serial.println();

   if (flat < 0.1){
    GPS_NoData = true;
  }
  if (flat > 0.1){
    GPS_NoData = false;
  }

  if (flat != LastLat){
               if (GPS_NoData == false){
                 LastLat = flat;
               }
             }
             if (flon != LastLon){
               if (GPS_NoData == false){
                 LastLon = flon;
               }
             }

  //---------------------------------GSM FUNCTION-----------------------------------------

              Serial.print(TimeString);
              Serial.print(" ");
              Serial.print(DateString);
              Serial.print(" ");
              Serial.print(flon,5);
              Serial.print(", ALARM:");
              Serial.print(ALARM);
              Serial.print(", DATA:");
              Serial.print(dataString);
              Serial.print(", SHOCK LEVEL: ");
              Serial.println(SHOCK);

if (stringComplete == true){

  //Serial.println("AT+CMGR=1");
   GSMx.println("AT+CMGR=1");

  count = 0;
  countERROR = 0;
  countPHONE = 0;
  countOK = 0;
  stringComplete = false;
  Enabled = false;
  Enabled1 = false;
  Enabled2 = false;
  Enabled3 = false;
}

  while (stringComplete == false){
 // count = count + 1;
       while (Serial.available() > 0){

        char inChar = Serial.read();
        inputString += inChar;

        if (Enabled2){
          Data2 += inChar;
          countPHONE = countPHONE + 1;
            if (countPHONE == 10){
            Enabled2 = false;
            }
        }

        if (inChar == 'E'){
          Enabled1 = true;
         }
         if (Enabled1){
          Data1 += inChar;
          countERROR = countERROR + 1;
                if (countERROR == 5){
                 Enabled1 = false;
                      if (Data1 == "ERROR"){
                        stringComplete = true;
                      }
                      if (Data1 != "ERROR"){
                        countERROR = 0;
                        Data1 += "";
                        Enabled1 = false;
                      }
                }

        }

        if (inChar == 'O'){
          Enabled3 = true;
         }
         if (Enabled3){
          Data4 += inChar;
          countOK = countOK + 1;
               if (countOK == 2){
                if (Data4 == "OK"){
                  stringComplete = true;
                }
                if (Data4 != "OK"){
                  countOK = 0;
                  Data4 = "";
                  Enabled3 = false;
                }
               }
         }
        if (inChar == '+'){
          if (count > 5){
            Enabled2 = true;
          }
        }
        if (count > 80){
            stringComplete = true;

         }

       }
}

       if (stringComplete){
         /*

                */
            // Serial.println(inputString);
            index = 0;
    do
  {
      commaPosition = inputString.indexOf('*');
      if(commaPosition != -1)
      {
          result[index++] = (inputString.substring(0,commaPosition));
          inputString = inputString.substring(commaPosition+1, inputString.length());
      }
    //  else
    //  {  // here after the last comma is found
    //     if(inputString.length() > 0)
    //       Serial.println(inputString);  // SMS message after final splitting
                             // print it
     // }
   }
   while(commaPosition >=0);
     MESSAGE1 = result[2];
     MESSAGE2 = result[3];

         if (result[1] == "LOCATION") {
    //            Serial.print("AT+CMGS=");
                GSMx.print("AT+CMGS=");
    //            Serial.println(USER1);
                GSMx.println(USER1);
                delay(1000);
    //            Serial.print("DEVICE TRACKING, lat:");
                GSMx.print("DEVICE TRACKING, lat:");
    //            Serial.print(flat,5);
                GSMx.print(flat,5);
    //            Serial.print(", lon:");
                GSMx.print(", lon:");
    //            Serial.println(flon,5);
                GSMx.println(flon,5);
    //            Serial.print("www.google.co.in/maps/place/");
    //            Serial.print(flat,5);
    //            Serial.print(",");
    //            Serial.println(flon,5);
                GSMx.println(" SPEED:");
                GSMx.println(SpeedGPS);
                GSMx.print("www.google.co.in/maps/place/");
                GSMx.print(flat,5);
                GSMx.print(",");
                GSMx.println(flon,5);

                delay(200);
    //            Serial.println(char(26));
                GSMx.println(char(26));
                delay(4000);
    //            Serial.println("AT+CMGD=1");
                GSMx.println("AT+CMGD=1");

                delay(4000);

            }

                              if (result[1] == "RST") {
    //            Serial.print("AT+CMGS=");
                GSMx.print("AT+CMGS=");
    //            Serial.println(USER1);
                GSMx.println(USER1);
                delay(1000);
    //            Serial.print("Alarm reset...");
                GSMx.print("Alarm reset..");
                delay(200);
    //            Serial.println(char(26));
                GSMx.println(char(26));
                delay(4000);
    //            Serial.println("AT+CMGD=1");
                GSMx.println("AT+CMGD=1");
                ALARM=0;  SMSx=0;

                delay(4000);

            }

       inputString = "";
       result[1] = "";
       result[2] = "";
       result[3] = "";
       result[4] = "";
       result[5] = "";
       result[6] = "";
       Data1 = "";
       Data2 = "";
       Data3 = "";
       Data4 = "";
      // Serial.flush();

      // stringComplete = true;
  delay(100);
  Sens1 = analogRead(Sens1Pin);           //read the value from the sensor
  Sens1 = (5.0 * Sens1 * 100.0)/1024.0;  //convert the analog data to digital
  SHOCK = ((390 - Sens1)/390)*100;
  if (SHOCK > 50){
    ALARM=1;
  }
  Serial.print("SHOCK LEVEL: ");
  Serial.println(SHOCK);
  delay(100);
  Sens1 = analogRead(Sens1Pin);           //read the value from the sensor
  Sens1 = (5.0 * Sens1 * 100.0)/1024.0;  //convert the analog data to digital
  SHOCK = ((390 - Sens1)/390)*100;
  if (SHOCK > 40){
    ALARM=1;
  }
  Serial.print("SHOCK LEVEL: ");
  Serial.println(SHOCK);
  delay(100);
  Sens1 = analogRead(Sens1Pin);           //read the value from the sensor
  Sens1 = (5.0 * Sens1 * 100.0)/1024.0;  //convert the analog data to digital
  SHOCK = ((390 - Sens1)/390)*100;
  if (SHOCK > 40){
    ALARM=1;
  }
  Serial.print("SHOCK LEVEL: ");
  Serial.println(SHOCK);
  delay(100);
  Sens1 = analogRead(Sens1Pin);           //read the value from the sensor
  Sens1 = (5.0 * Sens1 * 100.0)/1024.0;  //convert the analog data to digital
  SHOCK = ((390 - Sens1)/390)*100;
  if (SHOCK > 40){
    ALARM=1;
  }
  Serial.print("SHOCK LEVEL: ");
  Serial.println(SHOCK);
       }

  delay(100);
 // smartdelay(300);
}
//--------------------------------------START OF SUBROUTINES-------------------------------------
static void smartdelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (ss.available())
      gps.encode(ss.read());
  } while (millis() - start < ms);
}

static void print_float(float val, float invalid, int len, int prec)
{
  if (val == invalid)
  {
    while (len-- > 1)
    //  Serial.print('*');
    //Serial.print(' ');
    dummy=0;
  }
  else
  {
   // Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1); // . and -
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
     // Serial.print(' ');
     dummy=0;
  }
  smartdelay(0);
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0)
    sz[len-1] = ' ';
 // Serial.print(sz);
  smartdelay(0);
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  float Speed;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
   // Serial.print("********** ******** ");
   dummy = 1;

  else
  {

    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
        month, day, year, hour, minute, second);
   // Serial.print(sz);

  //  hour = hour+8;
  //  sprintf(lcd_buffer,"%02d/%02d/%02d %02d:%02d",day,month,year,hour,minute );

    hour = hour + 8;
    if (hour > 23){
      hour = hour - 24;
    }
    dataString="";
    TimeString="";
    DateString="";
    ExistingSpeed = gps.f_speed_kmph();
    Speed = gps.f_speed_kmph();
    SpeedGPS = Speed;

   TimeString = String(hour) + ":" + String(minute) + ":" + String(second);
   DateString = String(day) + "/" + String(month) + "/" + String(year);
   dataString = String(flat,5) + "  " + String(flon,5) + "  " + String(Speed,2);

  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  smartdelay(0);

    }

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
  //  Serial.print(i<slen ? str[i] : ' ');
  smartdelay(0);
}

```

# Answer
> 1 votes
From the huge amount of code it's hard to tell what exactly is wrong, but I noticed that you used `0` for the analog pin which is not the same as `A0`.

Your pin number should be defined as:

```
int Sens1Pin = A0;

```

---
Tags: arduino-uno, sensors, shields, gsm, gps
---


title: I2C collision detection

text:
# Question
Title: I2C collision detection
I have put together a system that uses multiple Arduinos and a couple of 20x4 LCD displays to monitor my PV sun tracker and a weather station. I am using I2C to link them all together. One of the LCDs has been modified to have a different address (0x3b) so as to not conflict with the first one (0x3f). So far, so good. The sun tracker shows its display on the yellow one and the weather station shows its data on the blue one.

In order to connect this together I am using the Mayhew I2C&Power devices, so one power source energizes the entire system. I send 12 Volts on the wire, then at each node I use a 12v to 5v converter to provide power for the I2C&Power board and the Nanos. (The anemometer on the WX needs 12V to operate so that's a plus)

Each Arduino has a unique I2C address - there is no master in the system.

I have learned to set the screen updates to be quick (take readings and do any calculations before writing to the LCD in one swell foop), and to stagger the display update timings (the WX info updates every 65050 ms (full display update) and the PV info updates every 67050 ms (4 characters) and 605550 ms (full display refresh). I chose these (arbitrarily random) values to make it less likely that they would try to update at the same time, because when both systems try to update their respective displays at the same time it causes some very interesting results - basically wiping out one or both displays. It works most of the time but eventually one or the other screen will get wiped out.

Question: Is there any way to implement collision detection on the I2C bus to prevent transmitting while other devices are communicating? Something like CSMA/CD (Carrier Sense Multiple Access with Collision Detection) on Ethernet..

# Answer
Collision detection on I2C is fully supported (See I2C Multi-Master). It works basically by attempting to transmit something and reading what is being transmitted at the same time. If what is read matches what is transmitted then the transmission worked. If it didn't match then there was a collision.

It is usually performed on a per-bit basis:

1. If a 0 then pull the data line LOW. If a 1 then let the resistor pull the data line HIGH.
2. Read the data line. If you want a 1 and get a 0 then some other device is pulling the data line low for a 0.
3. If the value was wrong then stop your transmission and back off by a random amount. Retry again. (note: both ends may retry, so you need good random numbers).

There is no support in the Wire library for collision detection, though, so you will have to implement it yourself. Section 22.4 of the datasheet gives you more information about how to implement it.
> 1 votes

---
Tags: arduino-nano, i2c
---


# Question
Title: Arduino Leonardo - Using ICSP pins for serial
I'd like to know if it's possible to use the ICSP header pins on the Leonardo as GPIO pins, for example for software serial, and how to address them. I've a project which needs all available I/O pins, and I could use having serial comms on those "extra" pins.

# Answer
> 3 votes
From `packages/arduino/hardware/avr/1.6.*/variants/leonardo/pins_arduino.h`:

> ```
> // Map SPI port to 'new' pins D14..D17
> #define PIN_SPI_SS    (17)
> #define PIN_SPI_MOSI  (16)
> #define PIN_SPI_MISO  (14)
> #define PIN_SPI_SCK   (15)
>
> static const uint8_t SS   = PIN_SPI_SS;
> static const uint8_t MOSI = PIN_SPI_MOSI;
> static const uint8_t MISO = PIN_SPI_MISO;
> static const uint8_t SCK  = PIN_SPI_SCK;
>
> ```

Those are the pin names and numbers you can use. Note that `SS`/17 is connected to the RX LED.

---
Tags: softwareserial, arduino-leonardo, icsp
---


# Question
Title: how to communicate MPU-6050 ( on arduino micro) wirelessly using nrf24l01 to arduino uno?
I have an Arduino Micro and MPU-6050. I'm trying to transfer the data obtained from the MPU-6050 wirelessly to my computer using an Arduino Uno at the other end. I'm not sure how to make this happen.

```
// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
// 6/21/2012 by Jeff Rowberg <jeff@rowberg.net>
// Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
//
// Changelog:
//      2013-05-08 - added seamless Fastwire support
//                 - added note about gyro calibration
//      2012-06-21 - added note about Arduino 1.0.1 + Leonardo compatibility error
//      2012-06-20 - improved FIFO overflow handling and simplified read process
//      2012-06-19 - completely rearranged DMP initialization code and simplification
//      2012-06-13 - pull gyro and accel data from FIFO packet instead of reading directly
//      2012-06-09 - fix broken FIFO read sequence and change interrupt detection to RISING
//      2012-06-05 - add gravity-compensated initial reference frame acceleration output
//                 - add 3D math helper file to DMP6 example sketch
//                 - add Euler output and Yaw/Pitch/Roll output formats
//      2012-06-04 - remove accel offset clearing for better results (thanks Sungon Lee)
//      2012-06-01 - fixed gyro sensitivity to be 2000 deg/sec instead of 250
//      2012-05-30 - basic DMP initialization working

/* ============================================
I2Cdev device library code is placed under the MIT license
Copyright (c) 2012 Jeff Rowberg

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================
*/

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

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

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

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

/* =========================================================================
   NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
   depends on the MPU-6050's INT pin being connected to the Arduino's
   external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is
   digital I/O pin 2.
 * ========================================================================= */

/* =========================================================================
   NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error
   when using Serial.write(buf, len). The Teapot output uses this method.
   The solution requires a modification to the Arduino USBAPI.h file, which
   is fortunately simple, but annoying. This will be fixed in the next IDE
   release. For more info, see these links:

   http://arduino.cc/forum/index.php/topic,109987.0.html
   http://code.google.com/p/arduino/issues/detail?id=958
 * ========================================================================= */

// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
// quaternion components in a [w, x, y, z] format (not best for parsing
// on a remote host such as Processing or something though)
//#define OUTPUT_READABLE_QUATERNION

// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
// (in degrees) calculated from the quaternions coming from the FIFO.
// Note that Euler angles suffer from gimbal lock (for more info, see
// http://en.wikipedia.org/wiki/Gimbal_lock)
//#define OUTPUT_READABLE_EULER

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

// uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
// components with gravity removed. This acceleration reference frame is
// not compensated for orientation, so +X is always +X according to the
// sensor, just without the effects of gravity. If you want acceleration
// compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
//#define OUTPUT_READABLE_REALACCEL

// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
// components with gravity removed and adjusted for the world frame of
// reference (yaw is relative to initial orientation, since no magnetometer
// is present in this case). Could be quite handy in some cases.
//#define OUTPUT_READABLE_WORLDACCEL

// uncomment "OUTPUT_TEAPOT" if you want output that matches the
// format used for the InvenSense teapot demo
//#define OUTPUT_TEAPOT

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

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

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

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

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

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

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

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

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

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

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

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

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

    // load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

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

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

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

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

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

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

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

void loop() {
    // if programming failed, don't try to do anything
    if (!dmpReady) return;

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

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

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

    // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

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

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

        #ifdef OUTPUT_READABLE_QUATERNION
            // display quaternion values in easy matrix form: w x y z
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            Serial.print("quat\t");
            Serial.print(q.w);
            Serial.print("\t");
            Serial.print(q.x);
            Serial.print("\t");
            Serial.print(q.y);
            Serial.print("\t");
            Serial.println(q.z);
        #endif

        #ifdef OUTPUT_READABLE_EULER
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetEuler(euler, &q);
            Serial.print("euler\t");
            Serial.print(euler[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(euler[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(euler[2] * 180/M_PI);
        #endif

        #ifdef OUTPUT_READABLE_YAWPITCHROLL
            // display Euler angles in degrees
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
            Serial.print("ypr\t");
            Serial.print(ypr[0] * 180/M_PI);
            Serial.print("\t");
            Serial.print(ypr[1] * 180/M_PI);
            Serial.print("\t");
            Serial.println(ypr[2] * 180/M_PI);
        #endif

        #ifdef OUTPUT_READABLE_REALACCEL
            // display real acceleration, adjusted to remove gravity
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetAccel(&aa, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
            Serial.print("areal\t");
            Serial.print(aaReal.x);
            Serial.print("\t");
            Serial.print(aaReal.y);
            Serial.print("\t");
            Serial.println(aaReal.z);
        #endif

        #ifdef OUTPUT_READABLE_WORLDACCEL
            // display initial world-frame acceleration, adjusted to remove gravity
            // and rotated based on known orientation from quaternion
            mpu.dmpGetQuaternion(&q, fifoBuffer);
            mpu.dmpGetAccel(&aa, fifoBuffer);
            mpu.dmpGetGravity(&gravity, &q);
            mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
            mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
            Serial.print("aworld\t");
            Serial.print(aaWorld.x);
            Serial.print("\t");
            Serial.print(aaWorld.y);
            Serial.print("\t");
            Serial.println(aaWorld.z);
        #endif

        #ifdef OUTPUT_TEAPOT
            // display quaternion values in InvenSense Teapot demo format:
            teapotPacket[2] = fifoBuffer[0];
            teapotPacket[3] = fifoBuffer[1];
            teapotPacket[4] = fifoBuffer[4];
            teapotPacket[5] = fifoBuffer[5];
            teapotPacket[6] = fifoBuffer[8];
            teapotPacket[7] = fifoBuffer[9];
            teapotPacket[8] = fifoBuffer[12];
            teapotPacket[9] = fifoBuffer[13];
            Serial.write(teapotPacket, 14);
            teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
        #endif

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

```

# Answer
> 2 votes
You have a few options here for the wireless communication (~ denotes wireless):

* MPU -\> Arduino -\> Bluetooth ~ ~ ~\> PC
* MPU -\> Arduino -\> NRF ~ ~ ~\> NRF -\> Arduino -\> PC
* MPU -\> Arduino -\> WiFi (ESP?) ~ ~ ~\> PC

I don't think it'd be easy to directly communicate I2C over the NRF, so I'd just *read* the data over I2C (presumably you're using Jeff Roweburg's library?), then once you have it in an integer or byte, you can use any wireless module to send it over whatever method you prefer. I haven't touched the ESP8266 for WiFi, but I know the HC-05/06 and the NRF24L01 both have fairly simple libraries that can do a simple write command that will buffer a number of bytes and send it all out in the correct order.

**edit:**

This is code I used a long time ago, and it is almost definitely somebody else's. I'm dreadfully sorry I can't find the original author at the moment, else I'd happily link to their page on the NRF. You can split this up into a receive and transmit pair though, and get rid of all the serial printing stuff as that just used the NRFs to 'text' each other.

Two Way Communication:

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);
const int radioNum = 0;
const byte rxAddr[6] = "00001";
const byte txAddr[6] = "00002";

String readSerial() {
    String input;
    while(Serial.available() > 0){
        input.concat((char)Serial.read());
        delay(1);     //allows the buffer to fill with each character
    }
    return input;
}

void setup()
{
  radio.begin();
  Serial.begin(9600);
  radio.setRetries(15, 15);
  if(radioNum){
    radio.openWritingPipe(rxAddr);
    radio.openReadingPipe(1, txAddr);
  }
  else{
    radio.openWritingPipe(txAddr);
    radio.openReadingPipe(1, rxAddr);
  }
  Serial.println("Enter a string of characters:");

}

void loop()
{
  radio.startListening();
  while(Serial.available()==0){
    char output[32];
    radio.read(&output, 32);
    if(output[0]){
      if(radioNum)
         Serial.print("Pong: ");
      else
         Serial.print("Ping: ");
      Serial.println(output);
    }
  }
  radio.stopListening();

  String input = readSerial();
  char text[32];
  input.toCharArray(text,32);
  radio.write(&text, 32);

  if(radioNum)
    Serial.print("Ping: ");
  else
    Serial.print("Pong: ");

  Serial.println(text);
}
}

```

# Answer
> 1 votes
I'm not sure about the "wirelessly" context, but you can try this steps
1. Make sure you can read the mpu-6050 data
2. You can use bluetooth (HC-05 is the most common) to transfer data to your PC bluetooth directly, or to another arduino, then send it via serial usb cable to PC

# Answer
> 0 votes
This is just a conception plan:

Make sure you can get all the data (YPR) you need from the MPU.

Then, using whatever protocol you want, send the data under the form of something like a byte. Here is a question I aksed about a similar topic.

For more info, please comment, I'll be happy to help.

---
Tags: arduino-uno, nrf24l01+, arduino-micro, mpu6050
---


# Question
Title: Thermosensor Error - 'Wire' does not name type?
Here is the code I am using:

```
#define D6T_ID 0x0A
#define D6T_CMD 0x4C

int ReadBuffer[35];
float ptat;
float tdata[16];

#include <Wire.h>
void setup() {
  Wire.begin();
  Serial.begin(9600);
  delay(500);

}

void loop() {

}
  int i;
  Wire.beginTransmission(D6T_ID);
  Wire.write(D6T_CMD);
  Wire.endTransmission();

  Wire.requestFrom(D6T_ID,35);

  for (i=0; i<35; ++i) {
    ReadBuffer[i] = Wire.read();
  }

  ptat = (ReadBuffer[0]+(ReadBuffer[1]*256))*0.1; //Reference Temp

  for (i=0; i<16; ++i) {
    tdata[i] = (ReadBuffer[(i*2+2)]+(ReadBuffer[(i*2+3)]*256))*0.1;
  }

  float tempF;

  if ( ((tdata[0]*9.0/5.0)+32.0)>0 )
  {
    for (i=0; i<16; ++i)
    {
      tempF = (tdata[i]*9.0/5.0)+32.0;
      Serial.print(tempF);
      Serial.print(',');
    }
    Serial.print((ptat*9.0/5.0)+32.0;
    Serial.print(',');
    Serial.println();
  }

    }
  }

```

This is the error I am getting:

exit status 1 'Wire' does not name a type

And it highlights this area of code:

```
Wire.requestFrom(D6T_ID,35);

```

I am completely new to using the arduino and coding so I am not sure if I already have the wire library that this code requires but when I look at the libraries in the Tools menu it is there. Do I need to download another library? If so can someone send me the link? Can someone explain what the error means? This is all foreign to me.

Thank you

# Answer
> 1 votes
You've goofed up your braces and none of that code is in `loop()`. Look at the braces in the code and make the appropriate corrections.

# Answer
> 0 votes
The reason for the error message is that your braces do not properly match, and the code that was meant to be inside `loop()` is not, but instead looks to the compiler like some new global declarations. Fix the syntax errors and your code will compile:

* Remove the brace in line 18 that closes the loop() function prematurely,
* Fix the missing ')' in line 46,
* Remove line 52, an extraneous '}',

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


title: Atmega boot loading UART or SPI

text:
# Question
Title: Atmega boot loading UART or SPI
I have an Atmega 328 chip and want to load the Arduino boot loader to the chip. I have planned to use a SPI protocol to do this, but I have read other posts saying that they have done similar using an UART with using an FTDI chip. I have planned to use the FTDI to support USB.

I did rad some information that said that loading the boot loader through UART is very slow.

Which is best? I would like to save space, if I do not need a SPI header then I would like to remove this. Is what I have read correct?

Thanks

# Answer
> I have read other posts saying that they have done similar using an UART with using an FTDI chip.

You have probably misread something. A brand-new, blank ATmega328 can only be programmed over SPI, or via parallel programming (more pins). There is no "native" UART bootloader.

It's possible to use certain FTDI chips to bit-bang the SPI programming interface. This is probably what the posts you're reading are referring to. As the post suggests, though, this is slower than using a programmer which directly supports the SPI interface, and is only really suitable if you don't have a better programmer available.

If space is a concern, one option to consider may be to provide the ISP port as a set of test points and use pogo pins to access it during manufacturing. You can lay out the test points however you want, possibly at a finer pitch than the 100 mil header you're probably used to.

Depending on your manufacturing process, another approach may be to program the chip before mounting it to the board.
> 1 votes

# Answer
Loading via UART is not so bad if you configure the bootloader to use a reasonable baud rate (say, 115200 instead of the default 9600). However, you do have to get the bootloader onto the chip in the first place, and that has to be done with SPI.
> 0 votes

---
Tags: spi, uart
---


title: Aptotec PN532 shield power consumption

text:
# Question
Title: Aptotec PN532 shield power consumption
I am currently planning a battery-powered project, where one of the tasks involves reading Desfire EV1 tags. Since the cheap RC522 based NFC shields are reported not to work with the Desfire EV1 tags, I wanted to make an attempt with a PN532 based shield. Due to offering the fastest shipping option, I ordered an Aptotec PN532 shield, although there are many other, and likely cheaper options out there as well. The Aptotec shield seems identical to the Seeed NFC Shield V2.0.

Communicating with the Desfire EV1 tags works as expected, but I am not understanding the shield's power consumption. If I understand the PN532 datasheet correctly, the chip itself should only draw 45µA when in standby mode, some 30mA when active, but not transmitting and additionally up to 150mA more during actual transmission.

After sending an 'InRelease all targets' command to the PN532, the shield however still draws about 50mA, although the PN532 should be in stand by mode. Using the RFConfiguration command to turn the RF field off completely still does not decrease the shield's power consumption. Activating the RF field e.g. by issuing an InListPassiveTarget command, the current draw increases to about 80mA, which matches with my assumption that the PN532 now draws 30mA more than when idle. There seems however to be something else on the shield causing a 'base line' 50mA current draw, which is not caused by powering the PN532 chip.

Does someone know where this power is lost, if it is possible to software-based turn off whatever is causing the power draw or if other PN532 shields show the same behaviour? Since my project must run on a battery, the 50mA unexplained current draw is not acceptable.

# Answer
After some trial and error, I think I can answer this one myself.

The circuit schematic from the Seeed module is actually broken and the Apotec model is built almost identically. The PN532 chip has an SVDD *output* pin to power an optional security access module for cryptography support. In the Seeed design, this pin is connected to the 3.3V input voltage from the voltage regulator, which is simply wrong and the pin sinks an essential amount of current.
> 1 votes

---
Tags: power, rfid
---


title: Multiple If Conditions Arduino

text:
# Question
Title: Multiple If Conditions Arduino
I have a project which requires me to read if the input is "HIGH". I have 15 inputs (switches), and each input has its own output (LED). I am using a Shift Register to control its inputs and outputs.

My current code looks like this (4 inputs and 4 outputs, it works though...):

```
#include "SPI.h"
#include "MFRC522.h"
#include "rgb_lcd.h"
#include <Wire.h>

#define SS_PIN 17
#define RST_PIN 7

int counter = 0;
int lock = 100;

MFRC522 rfid(SS_PIN, RST_PIN);
rgb_lcd lcd;
MFRC522::MIFARE_Key key;

// Define Pins
int SHIFTIN_LATCH = 22;
int SHIFTIN_DATA = 23;
int SHIFTIN_CLOCK = 21;
int numberToDisplay = 0;

#define SHIFTOUT_DATA  18
#define SHIFTOUT_LATCH  19
#define SHIFTOUT_CLOCK  20

//Define variables to hold the data
//for each shift register.
//starting with non-zero numbers can help
//troubleshoot
byte keySlotID[15] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte keyInsert[15] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
byte keyReg[10] = {
  0,0,0,0,0,0,0,0,0,0}; // amt of reg.

void setup() {
  //start serial
  Serial.begin(9600);

  //define pin modes
  pinMode(SHIFTIN_LATCH, OUTPUT);
  pinMode(SHIFTIN_CLOCK, OUTPUT);
  pinMode(SHIFTIN_DATA, INPUT);

  pinMode(SHIFTOUT_DATA, OUTPUT);
  pinMode(SHIFTOUT_LATCH, OUTPUT);
  pinMode(SHIFTOUT_CLOCK, OUTPUT);
  Serial.begin(9600);
  SPI.begin();
  rfid.PCD_Init();
  lcd.begin(16, 2);
}

void KeyID(){
  // Key slot indicator.
  keySlotID[0] = (keyReg[0] & 0x1E) >> 1;
  keySlotID[1] = (((keyReg[1] & 0x03) << 3) | ((keyReg[0] & 0xE0) >> 5)) >> 1;
  keySlotID[2] = (keyReg[1] & 0x78) >> 3;
  keySlotID[3] = (keyReg[2] & 0x0F);
  // Key inserted indicator.
  keyInsert[0] = (keyReg[0] & 0x01);
  keyInsert[1] = (keyReg[0] & 0x20) >> 5;
  keyInsert[2] = (keyReg[1] & 0x04) >> 2; // X
  keyInsert[3] = (keyReg[1] & 0x80) >> 7; // X
}

void registerWrite(byte data1, byte data2) {
  digitalWrite(SHIFTOUT_LATCH, LOW);
  delay(10);
  shiftOut(SHIFTOUT_DATA, SHIFTOUT_CLOCK, MSBFIRST, data2);
  shiftOut(SHIFTOUT_DATA, SHIFTOUT_CLOCK, MSBFIRST, data1);
  digitalWrite(SHIFTOUT_LATCH, HIGH);
  delay(10);
}

void LedIFs() {

  if (keyInsert[0] == 0 && keyInsert[1] == 0 && keyInsert[2] == 0 && keyInsert[3] == 0) {
    registerWrite(0xFF,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 0 && keyInsert[2] == 0 && keyInsert[3] == 1) {
    registerWrite(0x40,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 0 && keyInsert[2] == 1 && keyInsert[3] == 0) {
    registerWrite(0x10,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 0 && keyInsert[2] == 1 && keyInsert[3] == 1) {
    registerWrite(0x50,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 1 && keyInsert[2] == 0 && keyInsert[3] == 0) {
    registerWrite(0x04,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 1 && keyInsert[2] == 0 && keyInsert[3] == 1) {
    registerWrite(0x44,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 1 && keyInsert[2] == 1 && keyInsert[3] == 0) {
    registerWrite(0x14,0);
  }
  else if (keyInsert[0] == 0 && keyInsert[1] == 1 && keyInsert[2] == 1 && keyInsert[3] == 1) {
    registerWrite(0x54,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 0 && keyInsert[2] == 0 && keyInsert[3] == 0) {
    registerWrite(0x01,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 0 && keyInsert[2] == 0 && keyInsert[3] == 1) {
    registerWrite(0x41,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 0 && keyInsert[2] == 1 && keyInsert[3] == 0) {
    registerWrite(0x11,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 0 && keyInsert[2] == 1 && keyInsert[3] == 1) {
    registerWrite(0x51,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 1 && keyInsert[2] == 0 && keyInsert[3] == 0) {
    registerWrite(0x05,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 1 && keyInsert[2] == 0 && keyInsert[3] == 1) {
    registerWrite(0x45,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 1 && keyInsert[2] == 1 && keyInsert[3] == 0) {
    registerWrite(0x15,0);
  }
  else if (keyInsert[0] == 1 && keyInsert[1] == 1 && keyInsert[2] == 1 && keyInsert[3] == 1) {
    registerWrite(0x55,0);
  }
}

void loop() {

  //Pulse the latch pin:
  //set it to 1 to collect parallel data
  digitalWrite(SHIFTIN_LATCH,1);
  //set it to 1 to collect parallel data, wait
  delay(1);
  //set it to 0 to transmit data serially
  digitalWrite(SHIFTIN_LATCH,0);

  //while the shift register is in serial mode
  //collect each shift register into a byte
  //the register attached to the chip comes in first
  keyReg[0] = ~shiftIn(SHIFTIN_DATA, SHIFTIN_CLOCK);
  keyReg[1] = ~shiftIn(SHIFTIN_DATA, SHIFTIN_CLOCK);
  keyReg[2] = ~shiftIn(SHIFTIN_DATA, SHIFTIN_CLOCK);

  LedIFs();
  KeyID();
}

```

The problem I'm facing is that it would be too long for me to write down 15 `KeyInsert`s. That would mean I have to write about or close to 200,000 lines of code...

# Answer
> 1 votes
Let's assume value that will be stored into "keyInsert" are either "1" or "0". Therefore, its a waste to declare them as an array byte

```
byte keyInsert[15] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

```

It means that you will have 15 * 8 bytes variable, and its overkill. it will be much simpler if you declare it as

```
uint16_t keyInsert;

```

Which have 16 bits data (2 bytes).
in your code, you can implement it by doing

```
void LedIFs() {
if (keyInsert == 0x0001) registerWrite(0xFF,0); else
if (keyInsert == 0x0002) registerWrite(......)......
......
}

```

# Answer
> 0 votes
I will be using `digitalRead`s and `digitalWrite`s but just follow this logic:

```
int state[num_of_switch_that_you_have];

for(int i=0; i<num_of_switch_that_you_have; i++)
{
  //buttonPins is the pin to which all your buttons are connected to in an array
  state[i] = digitalRead(buttonPins[i]);

  //leds is the pin to which all your leds are connected to in an array
  digitalWrite(leds[i], state[i]);
}

```

Try to follow this logic while using your shift registers. Sorry if I don't have a full code with shift registers for you, I'm not really good with them!

If you need any more details, please comment, I'll be happy to help!

# Answer
> 0 votes
I can't quite get the logic of your `keyInsert[]` array. Why don't you use a binary number (e.g. `uint16_t`, which is 16 bits) instead of an array of zeros and ones? Also, half of the lines of the output shift register seem essentially unused.

If I understand correctly, you want to simplify `LedIFs()` in order to handle many bits with few lines of code. Examining your current implementation, it appears that you are writing to the output register the very same bits you have in `keyInsert[]`, only in different positions. Instead of testing every possible combination, it would be much simpler to just move the bits into their appropriate positions:

* `keyInsert[0]` becomes bit 0 (i.e. least significant) of the first argument of `registerWrite()`
* `keyInsert[1]` becomes bit 2 (it's weight is 22 = 0x04)
* `keyInsert[2]` is bit 4 (weight: 24 = 0x10)
* `keyInsert[3]` is bit 6 (weight: 26 = 0x40)

This is done using bit shifts, and joining the bits with the `|` bitwise-or operator:

```
void LedIFs() {
    byte val = keyInsert[0] << 0
             | keyInsert[1] << 2
             | keyInsert[2] << 4
             | keyInsert[3] << 6;
    if (val == 0) val = 0xff;
    registerWrite(val, 0);
}

```

Notice that `<< 0` has no effect: it is here only because it looks nicer (more symmetric, easier to read) this way. The compiler will optimize out this operation anyway. Also, the case when all the bits are zero is special, since you are writing 0xff instead of zero.

If I were you, what I would do is store the information in `keyInsert[]` as a single number with the bits already at their correct position. Then I would write

```
uint16_t keyInsert;

//...

static inline void LedIFs() {
    registerWrite(keyInsert ? keyInsert : 0xff, 0);
}

```

---
Tags: arduino-uno, programming, shift-register
---