Tag Archives: uart

Arduino / ATMega and interrupts

As you certainly already know, Arduino boards (Uno, Mega, Due, etc.) allow us to handle interrupts.

Arduino Uno (based on Atmel’s ATMega328 microcontroller) can handle to external interrupts on it’s pins INT 0 and INT1, mapped to Arduino’s D2 and D3 (respectively pins 4 and 5 of ATMega328 in PDIP package).

External interrupts pins on an Arduino Uno

Interesting fact, ATMega328 (and therefore Arduino Uno) can handle state change interrupts on 20 of it’s pins ; however, handling these interrupts is not as simple as it is with external ones : you need to determine which pin has generated the interrupt, for which reason, etc. Good thing, an Arduino library exists to help us handling these interrupts :  arduino-pinchangeint.

Interrupts can me triggered uppon 4 modes :

  • LOW : pin is in a low state
  • RISING : pin state goes from low to high
  • FALLING : pin state goes from high to low
  • CHANGE : pin state changes

One line of code is enough to “listen” for an interrupt on Arduino ;  for example, on the pin INT0 (which is D2), we attach an interrupt, that will call the method “myInterrupt” when the pin’s state  goes from LOW to HIGH :

attachInterrupt(0, myInterrupt(), RISING);

Please notice that although the Arduino pin is “D2”, we define here pin “0” which is the interrupt pin number (0 for INT0 / D2, 1 for INT1 / D3).

We now define the method that will be called by the interrupt (this method does not take any argument and does not return anything) :

void myInterrupt() {
  // do something ...
}

A few limitations

As interrupts are based on your microcontroler’s timers, method delay() wont work and method millis() wont increment, within  the method attached to an interrupt.

Usually, it is not recommended to run time based operations in your interrupts, which will hang your µC ; for example, serial data transmission (UART), I2C, etc.

Best practices

Using interrupts is very useful to detect user actions, as a button pressed, a keypad, or even to detect a fast state change (infrared signal cut), without having to constantly poll a pin state.

Basically, a method attached to an interrupt should be the shortest and fastest possible : a good practice consists in using interrupts to set a flag in a variable (defined as “volatile”). The execution of the matching action will be done within the main loop.

For example :

volatile int change = 0;

void main() {
  attachInterrupt(0, myInterrupt(), RISING);
}

void loop() {
  if(change == 1) {
    // do something ...
    change = 0;
  }
}

void myInterrupt() {
  change = 1;
}

Useful links

Raspberry PI + Xbee: UART / Serial howto

Happy owner of a Raspberry PI for almost a year now, I couldn’t resist to take advantage of if advanced features, and especially it’s GPIO, to communicate with my other electronics parts including my Xbee-enabled wireless sensors.

Although RPI’s onboard UART usage seemed quite simple at first, it finally took me some time to figure out exactly how to read my first bytes received trough UART via Xbee on my RPI, that’s why I’m writing this short snippet.

On the original Debian available for the Raspberry PI, the UART allow you to have a serial console so you can connect to it, without needing network nor SSH.

It takes a few steps to change this default behavior so we can connect our Xbee (Series 1) to our RPI.

First of all, you will need to edit the /boot/cmdline.txt file :

sudo cp /boot/cmdline.txt /boot/cmdline.txt.bak # Backup file
sudo vi /boot/cmdline.txt

Remove all references to ttyAMA0 (console and kgdboc) so your file looks something like that :

dwc_otg.lpm_enable=0 rpitestmode=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait

Now edit /etc/inittab :

sudo cp /etc/inittab /etc/inittab.bak # Backup file
sudo vi /etc/inittab

Comment out the following line :

2:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Now reboot your Raspberry PI.

Let’s now connect our Xbee to the RPI’s GPIO. Here is a quick schema explaining how :

Raspberry PI Xbee

Raspberry PI and Xbee Series 1

Note that on this schema, I only connected a wire from Xbee’s DOUT to RPI’s RXD as will only use it to receive data. However, you might also connect your Xbee’s DIN to RPI’s TX according to this RPI GPIO pinout.

Your Raspberry PI should now receive it’s first bytes via the Xbee ; you can test this using Minicom (sudo aptitude install minicom, if not already installed) :

sudo minicom -b 9600 -o -D /dev/ttyAMA0

(You could also use minicom without sudoing by adding your current user [I guess pi] to dialout group)

Special thanks to Clayton Smith’s blog post which greatly helped me figure out what was wrong with my RPI’s UART.