Showing posts with label atmega8. Show all posts
Showing posts with label atmega8. Show all posts

Sunday, 17 September 2017

Power control - Hardware

Power control - Hardware

System overview

The power control unit consists of 6 relays connected to an ATMega8 MCU. The main (lower) board is self sufficient and contains all necessary parts for proper function.

The top board serves as an easy indicator of the relay state. It plugs to the header pins on the bottom PCB.

Power control in action

The system can be connected to any AC circuit (limited by relay characteristics - usually up to 10A/400V AC). In the picture below the system is connected to the modified power board, serving individual 4 outlets (out of possible 6). The power control gets signal from computer or similar control device via RJ45 cable.

With the top board connected to the main unit it is possible to see which relays are operational at any moment. Red LED means that relay is conducting and green LED means that relay is not conducting (Unsafe/Safe).

Power Control - Code

Power control - Code

Syntax highlight generated with tohtml.com

Relay1.c file

#include <avr/io.h>
#include <util/delay.h>
// Clock Speed
#define F_CPU 8000000
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
#define CMDERR 0x02
volatile unsigned char c;
volatile unsigned char i;

void blink(unsigned char led){
        if (led) PORTB |= 0x02;
        else PORTB &= ~0x02;  
}

void USART_Init( unsigned int ubrr)
{
        /*Set baud rate */
        UCSRA |= (1<<2); //set U2X bit
        UBRRH = ( unsigned char)(ubrr>>8);
        UBRRL = ( unsigned char)ubrr;
        /*Enable receiver and transmitter */
        UCSRB = (1<<RXEN)|(1<<TXEN);
        /* Set frame format: 8data, 2stop bit */
        UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}
void USART_Transmit(  unsigned char data )
{
        /* Wait for empty transmit buffer */
        while ( !( UCSRA & (1<<UDRE)));
        /* Put data into buffer, sends the data */
        UDR = data;
}

void send_string(unsigned char * s){
        unsigned int i=0;
        while(s[i]!='\0'){
                USART_Transmit(s[i]);
                i++;
        }
        USART_Transmit('\n');
        _delay_ms(100);
}
void send_number(unsigned char n, unsigned char radix){
        char s[8];
        itoa(n,s,radix);
        send_string(s);
}

unsigned char USART_Receive( void ){
        /* Wait for data to be received */
        while ( !(UCSRA & (1<<RXC)) )
                ;
        /* Get and return received data from buffer */
        return  UDR;
}


void main(void )
{
        DDRD |= ((1<<DDD2)|(1<<DDD3)|(1<<DDD4)|(1<<DDD5)|(1<<DDD6)|(1<<DDD7));
        USART_Init(MYUBRR);
        send_string("\n\nReady...");
        i=32;
        char dir=1;
        short n=0;
        short relay=0;
        unsigned char b1;
        unsigned char b2;
        short data;
        short data2;
        char buffer[20];
        char message[20];
        while(1){
                c=0;
                while(c != '\n' && c != '\r' && n<20){
                        c=USART_Receive();
                        buffer[n]=c;
                        n++;
                }

                buffer[n]='\0';
                send_string("received:");
                send_string(buffer);
                for(i=0;i<n;i++){
                        if(buffer[i] == 'R' || buffer[i] == 'r'){
                                relay = buffer[i+1] - '0';
                                relay += 1;     //adjust for unused tx/rx port d
                                if (buffer[i] == 'r'){
                                        PORTD |= 1<<relay;
                                        sprintf(message,"portd %d on",relay);
                                        send_string(message);
                                        send_string("relay off");
                                }else{
                                        PORTD &= ~(1<<relay);
                                        sprintf(message,"portd %d off",relay);
                                        send_string(message);
                                        send_string("relay on");
                                }
                        }
                }
                n=0;
        }

}

Makefile

# sample makefile for programming AVR microcontrollers
# be sure to fill up the blank entries before you run this!

# the C source file, without extension
SOURCE = relay1

# device name
MCU = atmega8

# CPU speed, needed by <util/delay.h>
F_CPU = 8000000

# tools
CC = avr-gcc
SIZE = avr-size
OBJ = avr-objcopy
OBJD = avr-objdump
AVRDUDE = avrdude
RM = rm -f

# avr-gcc options
CC_OPT = s
CC_WARN = all
CC_LST = -Wa,-adhlns

# avrdude options
AVRDUDE_WRITE_FLASH = -U flash:w:$(SOURCE).hex
AVRDUDE_PROGRAMER = usbasp
AVRDUDE_PORT = 

# some strings for the UI
STR_BEGIN = Starting Build...
STR_CLEAN = Starting Clean...
STR_PROGRAM = Downloading Code...
STR_END = Done.

# general targets
build:
        $(CC) -mmcu=$(MCU) -W$(CC_WARN) -DF_CPU=$(F_CPU) -O$(CC_OPT) $(CC_LST)=$(SOURCE).lst $(SOURCE).c -o $(SOURCE).elf
        $(OBJD) -S $(SOURCE).elf > $(SOURCE).lss
        $(OBJ) -O ihex $(SOURCE).elf $(SOURCE).hex
size:
        $(SIZE) --mcu=$(MCU) --format=avr $(SOURCE).elf
clean_files:
        $(RM) $(SOURCE).elf
        $(RM) $(SOURCE).lst
        $(RM) $(SOURCE).lss
        $(RM) $(SOURCE).hex
download:
#       $(AVRDUDE) -c $(AVRDUDE_PROGRAMER) -p $(MCU) -P $(AVRDUDE_PORT) $(AVRDUDE_WRITE_FLASH) 
        $(AVRDUDE) -c $(AVRDUDE_PROGRAMER) -p $(MCU) -B 20 $(AVRDUDE_WRITE_FLASH) 

begin_all:
        @echo $(STR_BEGIN)
begin_clean:
        @echo $(STR_CLEAN)
begin_program:
        @echo $(STR_PROGRAM)
end:
        @echo $(STR_END)

# WINAVR targets
all: begin_all build size begin_program download end
clean: begin_clean clean_files end
program: begin_program download end

Is low level programming still relevant these days?

The levels of abstraction have made the application programming much easier and faster. But everything comes at a price. This is a new ...