20 Pin AVR Relay Development Board Firmware

From Catholicpenguin

Overview

Sparkfun makes a development board with 4 relays. The only practical chip is the ATTiny2313, which has so little ram that about all you can really do is turn the board into an a dumb I/O module over serial.

This firmware does this. This was last compiled with WinAVR-20081205 on Windows Vista.

Protocol:

  • 9600 baud serial.
  • 'in:[0-3]<SP>\n' - Reads the digital input 0-3, which correspond to the input pins 1-4. Note you need a space after the command, before the newline, because of a bug.
  • 'out:[0-3][0-1]<SP>\n' - Switches one of the relays on/off. Nothing is echoed back in confirmation of this command.

Source

#include <avr/io.h>
#include <stdio.h>
#include <string.h>

#define Rx PD0
#define Tx PD1

#define STATUS PB4

unsigned char inputs[] = {PD2,PD3,PD5,PD6};
unsigned char outputs[] = {PB3,PB2,PB1,PB0};

unsigned char IO_get(unsigned char input)
{
	return PIND & (1<<input);
}

void IO_set(unsigned char output, unsigned char val)
{
	if (val)
		PORTB |= (1<<output);
	else
		PORTB &= ~(1<<output);
}

void IO_Init(void)
{
	for (unsigned char i=0;i<4;i++) {
		DDRD  &= ~(1<<inputs[i]); // Input
		PORTD &= ~(1<<inputs[i]); // Tri-state
	}
	
	for (unsigned char i=0;i<4;i++) {
		DDRB  |= (1<<outputs[i]); // Outputs
		PORTB &= ~(1<<outputs[i]); // Off
	}
	DDRB  |= (1<<STATUS); // Outputs
	PORTB &= ~(1<<STATUS); // Off	
}


void USART_Init( unsigned int baud )
{
	/* Set baud rate */
	UBRRH = (unsigned char)(baud>>8);
	UBRRL = (unsigned char)baud;
	/* Enable receiver and transmitter */
	UCSRB = (1<<RXEN)|(1<<TXEN);
	/* Set frame format: 8data, 2stop bit */
	UCSRC = (1<<USBS)|(3<<UCSZ0);
}

static int USART_Transmit( unsigned char data , FILE *stream)
{
	/* Wait for empty transmit buffer */
	while ( !( UCSRA & (1<<UDRE)) )
		;
	/* Put data into buffer, sends the data */
	UDR = data;
	return 0;
}

static int USART_Receive( FILE *stream )
{
	/* Wait for data to be received */
	while ( !(UCSRA & (1<<RXC)) )
		;
	/* Get and return received data from buffer */
	if (UDR == '\r') return '\n';
	return UDR;
}

static FILE mystdout = FDEV_SETUP_STREAM(USART_Transmit, USART_Receive, _FDEV_SETUP_RW);
										 
void init(void)
{
	// Set USART Tx as output, Rx as input
	DDRD  &= ~(1<<Rx); // Input
	PORTD &= ~(1<<Rx); // Tri-state
	DDRB  |=  (1<<Tx); // Output
	USART_Init(64); // 9600, 10MHz clock == 64
	stdout = &mystdout;
	stdin  = &mystdout;
	
	IO_Init();
}

int main(void)
{
	char strbuf[16];
	
	init();

	printf("in:[0-3] \nor out:[0-3][0-1] \n");
	
	while (1)
	{
		fgets(strbuf,16,stdin);
		char * pos;
		if ((pos = strstr(strbuf,"in:")))
		{
			unsigned char input = *(pos+3)-'0';
			putchar(input+'0');		
			putchar(IO_get(input)+'0');
		}
		else if ((pos = strstr(strbuf,"out:")))
		{
			unsigned char output = *(pos+4)-'0';
			unsigned char val = *(pos+5)-'0';
			IO_set(output,val);
		}
		else
			putchar('?');
		
	}
	return 0;
}