Connecting BugOne and Raspberry Pi

I challenged a friend to connect a micro-controller to a Raspberry Pi. I chose to use an ATMega168 programmed in C while he preferred to use a Microchip PIC programmed in ASM. Not that I don’t like ASM, but it took me only 45 minutes to get all the material together and blink some LEDs from a shell.┬áTo get thinks up very fast, I used a BugOne board. This is clearly an advantage for me since it is already assembled with an ISP connector and ready to use.

Connecting the AVR

I connected the BugOne to Raspberry Pi’s 3.3V, serial port and ground available from its GPIO (see the picture, only 4 wires).

DSC01561

Preparing the Raspberrry Pi

 

Then I removed any use of the /dev/ttyAMA0 port as mentioned in this article from [Oscar Liang]. Its pretty easy since you only need to edit two files: /boot/cmdline.txt and /etc/inittab.

The code

I used previous code from “Blinking a BugOne” and mixed various sources form Internet which I don’t remember and ATMega168 documentation to manage to do interruption driven communication. The source code below is self explanatory, but fill free to ask more details in comments if necessary :

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

#include <util/delay.h>
#include "avr_compat.h"

/* Serial */
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE ((( F_CPU / ( USART_BAUDRATE * 16UL ))) - 1)

/* Pinout of leds */
#define LED1 C,1
#define LED2 C,0

int main() {
	// --- Init UART -----------------------------------
	// Turn on the transmission and reception circuitry
	UCSR0B = (1 << RXEN0) | (1 << TXEN0);
	// Use 8-bit character sizes
	UCSR0C = (1 << UCSZ00) | (1 << UCSZ01); 
	// Load upper 8-bits of the baud rate value into the high byte 
	// of the UBRR register
	UBRR0H = (BAUD_PRESCALE >> 8);
	// Load lower 8-bits of the baud rate value into the low byte
	// of the UBRR register
	UBRR0L = BAUD_PRESCALE ; 
	// Enable the USART Recieve Complete interrupt (USART_RXC)
	UCSR0B |= (1 << RXCIE0); 

	// --- Init GPIO ----------------------------------------
	drive(LED1);
	drive(LED2);

	set_output(LED1);
	set_output(LED2);
	_delay_ms(500);
	clr_output(LED1);
	clr_output(LED2);

	// --- Interrupts ----------------------------------------
	sei();

	while (1) {
		toggle_output(LED1);
		_delay_ms(500);
	}
}

ISR(USART_RX_vect)
{
	uint8_t received;
	// Fetch the received byte value into the variable "ByteReceived"
	received = UDR0;
	if (received & 0x01) {
		set_output(LED2);
	} else {
		clr_output(LED2);
	}
	// Wait for USART to be ready to send
	// while (!(UCSR0A & (1 << UDRE0)));
	// Echo back the received byte back to the computer
	UDR0 = received;
}

Putting it all together

After compiling and flashing the BugOne, I connected to the BugOne through SSH and I used screen to connect to the BugOne.

screen /dev/ttyAMA0 9600

Then you can press any key. It will be echoed to the terminal and depending on the last bit of the char it will toggle LED2.

Leave a Reply

Your email address will not be published. Required fields are marked *