Showing posts with label power control. Show all posts
Showing posts with label power control. Show all posts

Tuesday, 31 October 2017

Power control 2-01 - Testing

Power control 2-01 - Testing

Sensors arrived

Finally! The sensors are here. I ordered ACS712T from Aliexpress almost a month ago and yesterday received 10 of them. I quickly soldered the sensors to the adapter board with separately soldered wires for stronger current (up to 5A).

Test Setup

According to ACS712T datasheet the device provides continuous output of instantaneous measurements of current. Also I found out since the resolution is roughly 30mA for a 10bit ADC I will not be able to measure small current. I am still waiting for a single supply opamps, this will help me to expand the current range.

Due to the instantaneous nature of current measurement it would be hard to sample high frequency AC. Since I don't need high precision I decide to use some analogue circuitry to maintain the voltage level. In the datasheet I found the following rectifier circuit.

Since I wanted the full range I omitted the resistors, leaving only the diode and capacitor.

First impressions

After running a small DC motor with the current sensor and rectifier circuit I was able to measure the current. Of course the data was not accurate - I will need to get a formula to adjust for capacitor and diode influence. But the general increase/decrease in current were consistent with the motor's behavior.

Next step will be running an AC load (up to 1A to start with) and plotting the data in real time. Also I will have a power calculation, but first I need to test it with a proper power meter.

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 ...