/*
* Part1.c
*
* Created: 18/08/2017 2:14:36 PM
* Author : s4394976
*/
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
#include "light_ws2812.h"
#include <inttypes.h>
#include <compat/twi.h>
#include "i2cmaster.h"
#include <string.h>
#define MAXPIX 30
#define COLORLENGTH (MAXPIX/2)
#define FADE (256/COLORLENGTH)
#define Dev24C02 0xDE // device address of EEPROM 24C02, see datasheet
void set_leds( int brightness);
void buzzer_go( void );
void splash_screen(void);
struct cRGB colors[8];
struct cRGB colours[8];
struct cRGB led[28];
int gettime = 0;
int setalarm = 0;
int input_count = 0;
int brightness;
char time_input[7] = "\0";
int alarm_hour = 0;
int alarm_minutes = 0;
int hour_time = 0;
int minute_time = 0;
int getweather = 0;
int LED_ON_OFF[29];
char weather_status;
int alarm_keeper[3];
int this_minute;
int last_minute;
int display_weather = 0;
void reset_seconds( void ) {
int ret;
ret = i2c_start(Dev24C02 + I2C_WRITE); // set device address and write mode
if (ret) {
} else {
i2c_write(0x00); // Seconds register
i2c_write(0b10000000); // turn on the oscillator and set the seconds to zero
i2c_stop();
}
}
int set_hours( char hours_dec, char hours, char time_of_day, char input_error_check) {
if (input_error_check != 'm') {
return 0;
}
int writing_hours = 0;
if (time_of_day == 'p') {
writing_hours = 0b01100000;
} else if (time_of_day == 'a') {
writing_hours = 0b01000000;
} else {
return 0;
}
if (hours_dec == '1') {
writing_hours = writing_hours | 0b00010000;
} else if (hours_dec == '0' ) {
writing_hours = writing_hours | 0b00000000;
} else {
return 0;
}
if ((hours <= 57) && (hours >= 48)) {
writing_hours = writing_hours | (hours - '0');
} else {
return 0;
}
int ret = i2c_start(Dev24C02 + I2C_WRITE); // set device address and write mode
if (ret) {
i2c_stop();
return 0;
} else {
i2c_write(0x02); // hours register
i2c_write(writing_hours); // Set
i2c_stop();
}
return 1;
}
int set_minutes(char minutes_decade, char minutes) {
int writing_minutes = 0;
if ((minutes_decade <= 53) && (minutes_decade >= 48)) {
writing_minutes = writing_minutes | (minutes_decade - '0');
} else {
return 0;
}
writing_minutes = writing_minutes << 4;
if ((minutes <= 57) && (minutes >= 48)) {
writing_minutes = writing_minutes | (minutes - '0');
} else {
return 0;
}
int ret = i2c_start(Dev24C02 + I2C_WRITE); // set device address and write mode
if (ret) {
i2c_stop();
return 0;
} else {
i2c_write(0x01); // hours register
i2c_write(writing_minutes); // Set
i2c_stop();
}
return 1;
}
void set_rtc_time( char input) {
if (input == 'T') {
} else {
time_input[input_count] = input;
input_count++;
if (input_count == 7) {
for(int i = 0; i<29; i++){
LED_ON_OFF[i] = 0;
}
input_count = 0;
reset_seconds();
int error = set_hours(time_input[0], time_input[1], time_input[5], time_input[6]);
int error2 = set_minutes(time_input[3], time_input[4]);
if ((!error) || (!error2)) {
UDR0 = 'F'; _delay_ms(10); UDR0 = 'A'; _delay_ms(10); UDR0 = 'I'; _delay_ms(10); UDR0 = 'L'; _delay_ms(10); UDR0 = '\n'; _delay_ms(10);
}
for (int i = 0; i < strlen(time_input); i++) {
UDR0 = time_input[i];
_delay_ms(10);
}
strcpy(time_input, "\0");
}
}
}
int set_alarm_hours( char hours_dec, char hours, char time_of_day, char input_error_check) {
int hours_keep = 0;
if (input_error_check != 'm') {
return 0;
}
int writing_hours = 0;
if (time_of_day == 'p') {
alarm_keeper[2] = 1;
writing_hours = 0b01100000;
} else if (time_of_day == 'a') {
alarm_keeper[2] = 0;
writing_hours = 0b01000000;
} else {
return 0;
}
if (hours_dec == '1') {
writing_hours = writing_hours | 0b00010000;
hours_keep = 10;
} else if (hours_dec == '0' ) {
hours_keep = 0;
writing_hours = writing_hours | 0b00000000;
} else {
return 0;
}
if ((hours <= 57) && (hours >= 48)) {
writing_hours = writing_hours | (hours - '0');
hours_keep += (hours - '0');
} else {
return 0;
}
int ret = i2c_start(Dev24C02 + I2C_WRITE); // set device address and write mode
alarm_keeper[0] = hours_keep;
if (ret) {
i2c_stop();
return 0;
} else {
i2c_write(0x13); // hours register
i2c_write(writing_hours); // Set
i2c_stop();
}
return 1;
}
int set_alarm_minutes(char minutes_decade, char minutes) {
int writing_minutes = 0;
int minutes_keep = 0;
if ((minutes_decade <= 53) && (minutes_decade >= 48)) {
writing_minutes = writing_minutes | (minutes_decade - '0');
minutes_keep = (minutes_decade - '0') * 10;
} else {
return 0;
}
writing_minutes = writing_minutes << 4;
if ((minutes <= 57) && (minutes >= 48)) {
writing_minutes = writing_minutes | (minutes - '0');
minutes_keep = minutes_keep + (minutes - '0');
} else {
return 0;
}
int ret = i2c_start(Dev24C02 + I2C_WRITE); // set device address and write mode
if (ret) {
i2c_stop();
return 0;
} else {
i2c_write(0x0B); // hours register
i2c_write(writing_minutes); // Set
i2c_stop();
}
alarm_keeper[1] = minutes_keep;
return 1;
}
void print_to_putty(char* weather_string) {
for (int i = 0; i<strlen(weather_string);i++) {
UDR0 = weather_string[i];
_delay_ms(10);
}
}
void set_rtc_alarm(char input) {
if (input == 'A') {
int ret = i2c_start(Dev24C02 + I2C_WRITE);
if (ret) {
i2c_stop();
} else {
i2c_write(0x07); // Control register
i2c_write(0b00110000); // Enable Alarm 0 and 1
i2c_stop();
}
} else {
time_input[input_count] = input;
input_count++;
if (input_count == 7) {
input_count = 0;
int error = set_alarm_hours(time_input[0], time_input[1], time_input[5], time_input[6]);
int error2 = set_alarm_minutes(time_input[3], time_input[4]);
if ((!error) || (!error2)) {
print_to_putty("FAIL");
}
for (int i = 0; i < strlen(time_input); i++) {
UDR0 = time_input[i];
_delay_ms(10);
}
strcpy(time_input, "\0");
}
}
}
void set_weather ( char input ) {
if (input == 'W') {
} else if (input == '.') {
getweather = 0;
} else if (display_weather == 1) {
switch(input) {
case '0':
print_to_putty("SUNNY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 0;
LED_ON_OFF[18] = 1;
LED_ON_OFF[19] = 1;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 1;
LED_ON_OFF[22] = 1;
LED_ON_OFF[23] = 1;
LED_ON_OFF[24] = 1;
LED_ON_OFF[25] = 1;
LED_ON_OFF[26] = 1;
LED_ON_OFF[27] = 1;
LED_ON_OFF[28] = 1;
break;
case '1':
print_to_putty("SUNNY AND WINDY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 0;
LED_ON_OFF[18] = 1;
LED_ON_OFF[19] = 1;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 2;
LED_ON_OFF[22] = 1;
LED_ON_OFF[23] = 2;
LED_ON_OFF[24] = 1;
LED_ON_OFF[25] = 1;
LED_ON_OFF[26] = 2;
LED_ON_OFF[27] = 1;
LED_ON_OFF[28] = 2;
break;
case '2':
print_to_putty("CLOUDY AND WINDY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 2;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 2;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 2;
LED_ON_OFF[22] = 0;
LED_ON_OFF[23] = 2;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 2;
LED_ON_OFF[26] = 2;
LED_ON_OFF[27] = 2;
LED_ON_OFF[28] = 2;
break;
case '3':
print_to_putty("CLOUDY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 2;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 2;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 0;
LED_ON_OFF[22] = 0;
LED_ON_OFF[23] = 0;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 2;
LED_ON_OFF[26] = 0;
LED_ON_OFF[27] = 2;
LED_ON_OFF[28] = 0;
break;
case '4':
print_to_putty("CLOUDY AND RAIN");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 2;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 2;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 0;
LED_ON_OFF[22] = 0;
LED_ON_OFF[23] = 0;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 2;
LED_ON_OFF[26] = 2;
LED_ON_OFF[27] = 2;
LED_ON_OFF[28] = 2;
break;
case '5':
print_to_putty("RAIN");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 2;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 2;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 0;
LED_ON_OFF[22] = 0;
LED_ON_OFF[23] = 0;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 0;
LED_ON_OFF[26] = 2;
LED_ON_OFF[27] = 0;
LED_ON_OFF[28] = 2;
break;
case '6':
print_to_putty("WINDY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 0;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 0;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 2;
LED_ON_OFF[22] = 0;
LED_ON_OFF[23] = 2;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 0;
LED_ON_OFF[26] = 2;
LED_ON_OFF[27] = 0;
LED_ON_OFF[28] = 2;
break;
case '7':
print_to_putty("RAIN AND WINDY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 2;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 2;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 2;
LED_ON_OFF[22] = 0;
LED_ON_OFF[23] = 2;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 0;
LED_ON_OFF[26] = 2;
LED_ON_OFF[27] = 0;
LED_ON_OFF[28] = 2;
break;
case '8':
print_to_putty("STORM");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 0;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 1;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 0;
LED_ON_OFF[22] = 1;
LED_ON_OFF[23] = 1;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 0;
LED_ON_OFF[26] = 1;
LED_ON_OFF[27] = 0;
LED_ON_OFF[28] = 0;
break;
case '9':
print_to_putty("STORM AND WINDY");
for(int i = 0; i<17; i++){
LED_ON_OFF[i] = 0;
}
LED_ON_OFF[17] = 0;
LED_ON_OFF[18] = 0;
LED_ON_OFF[19] = 1;
LED_ON_OFF[20] = 0;
LED_ON_OFF[21] = 2;
LED_ON_OFF[22] = 1;
LED_ON_OFF[23] = 1;
LED_ON_OFF[24] = 0;
LED_ON_OFF[25] = 0;
LED_ON_OFF[26] = 1;
LED_ON_OFF[27] = 0;
LED_ON_OFF[28] = 2;
break;
default:
print_to_putty("FAIL");
}
} else {
if ((input == '0') || (input == '1') || (input == '2') || (input == '3') || (input == '4') || (input == '5') || (input == '6') || (input == '7') || (input == '8') || (input == '9')) {
weather_status = input;
} else {
print_to_putty("FAIL");
}
}
}
ISR (USART_RX_vect) {
// A char has been recieved - we will read it. If it is lower case, we convet it and send back
int input = UDR0;
if ( input == '.') {
gettime = 0;
getweather = 0;
setalarm = 0;
}
else if ((input == 'T') || (gettime == 1)) {
gettime = 1;
set_rtc_time(input);
splash_screen();
}
else if ((input == 'A') || (setalarm == 1)) {
setalarm = 1;
set_rtc_alarm(input);
splash_screen();
}
else if ((input == 'W') || (getweather = 1)) {
getweather = 1;
set_weather(input);
splash_screen();
}
}
void init_buzzer ( void ) {
DDRD |= (1 << 6); // Setting PortD Pin 6 Output
TCCR0A |= (1<<COM0A0) | (1<<WGM01); // Clear Timer on compare match. Toggle OCOA on Compare Match
TCCR0B |= (1<<CS01); //
OCR0A = 0; // Set to value, output pin will toggle depending on set value
}
void init_light_sensor( void ) {
ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)); //Prescaler at 128 so we have an 125Khz clock source
ADMUX |= (1<<REFS0); // Set to AVcc
ADMUX |= (1<< MUX1) | (1 << MUX0);
ADMUX |= (1 << ADLAR); //Left adjust
ADCSRA |= (1<<ADEN); //Power up the ADC
ADCSRA |= (1 << ADSC);
}
int read_light_sensor( void ) {
ADCSRA |= (1 << ADSC);
if (ADCH < 30) {
brightness = 1;
} else if ((ADCH > 30) && (ADCH < 60)) {
brightness = 2;
} else if ((ADCH > 60) && (ADCH < 90)) {
brightness = 3;
} else if ((ADCH > 90) && (ADCH < 120)) {
brightness = 4;
} else if ((ADCH > 120) && (ADCH < 150)) {
brightness = 5;
} else if (ADCH > 150) {
brightness = 6;
}
return brightness;
}
void init_usart( void ) {
// Set baud rate under 1000
UBRR0 = 499;
// enable transmission and recieving via UART and also enable the recieve complete interrupt
UCSR0B = ( 1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0);
//No need to se UCSR0C - we wjust want the defualt value
// Enable Interrupts
sei();
}
void set_leds( int brightness) {
for(int i=0; i<29;i++){
if (LED_ON_OFF[i] == 0) {
led[i].r =0;led[i].g=0;led[i].b=0;
} else if (LED_ON_OFF[i] == 1) {
led[i].r =42*brightness;led[i].g=0;led[i].b=0;
} else if (LED_ON_OFF[i] == 2) {
led[i].r =0;led[i].g=0;led[i].b=42*brightness;
}
}
ws2812_sendarray((uint8_t *)led,MAXPIX*4);
_delay_ms(1);
}
void alarm_init( void ) {
i2c_start_wait(Dev24C02+I2C_WRITE);
i2c_write(0x0D); // ALARM 0
i2c_write(0b00010000); // Set to minutes
i2c_stop();
i2c_start_wait(Dev24C02+I2C_WRITE);
i2c_write(0x14); // Alarm 1
i2c_write(0b00100000); // Set to hours
i2c_stop();
i2c_start_wait(Dev24C02+I2C_WRITE);
i2c_write(0x0D); // A0 seconds
i2c_write(0b00000000); // Set to 0
i2c_stop();
i2c_start_wait(Dev24C02+I2C_WRITE);
i2c_write(0x14); // A1 seconds
i2c_write(0b00000000); // Set to 0
i2c_stop();
}
void get_time_rtc (void) {
for (int i = 0; i < 29; i++) {
LED_ON_OFF[i] = 0;
}
int check_alarm = 0;
int time_of_day = 1;
int yo, back;
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x02); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
yo = i2c_readNak();
back = yo >> 4;
time_of_day = yo >> 5;
if((yo & 0b0100000) == 0) {
UDR0 = 'A';
_delay_ms(10);
UDR0 = 'M';
time_of_day = 1;
if (alarm_keeper[2] == 0) {
check_alarm = 1;
} else {
check_alarm = 0;
}
}else{
time_of_day = 2;
UDR0 = 'P';
_delay_ms(10);
UDR0 = 'M';
if (alarm_keeper[2] == 1) {
check_alarm = 1;
} else {
check_alarm = 0;
}
}
_delay_ms(10);
yo = yo & 0b00001111;
back = back & 0b00000001;
if (back == 1) {
LED_ON_OFF[9 + yo] = time_of_day;
} else {
LED_ON_OFF[yo - 1] = time_of_day;
}
UDR0 = '0' + back;
_delay_ms(10);
UDR0 = '0' + yo;
_delay_ms(10);
if (alarm_keeper[0] == (back + yo)) {
check_alarm = 1;
} else {
check_alarm = 0;
}
back = 0;
yo = 0;
i2c_stop();
UDR0 = ':';
_delay_ms(10);
int minute_keep = 0;
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x01); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
yo = i2c_readNak(); // read one byte
back = yo >> 4;
UDR0 = '0' + (back & 0b00000111);
back = back & 0b00000111;
minute_keep += (back * 10);
if (back == 0) {
} else {
LED_ON_OFF[11 + back] = time_of_day;
}
_delay_ms(10);
UDR0 = '0' + (yo & 0b00001111);
_delay_ms(10);
yo = yo & 0b00001111;
minute_keep += yo;
for (int i = 17; i < yo + 17; i++) {
LED_ON_OFF[i] = time_of_day;
}
UDR0 = '\n';
_delay_ms(10);
if (alarm_keeper[1] == minute_keep) {
check_alarm = 1;
} else {
check_alarm = 0;
}
this_minute = minute_keep;
if (check_alarm == 1) {
buzzer_go();
}
}
void splash_screen ( void ) {
for(int i = 0; i<29; i++){
LED_ON_OFF[i] = 1;
set_leds(6);
}
}
void read_alarm( void ) {
int yo, back;
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x13); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
yo = i2c_readNak();
back = yo >> 4;
if((yo & 0b0100000) == 0) {
alarm_keeper[2] = 0; // Am
} else {
alarm_keeper[2] = 1; // Pm
}
yo = yo & 0b00001111;
back = back & 0b00000001;
yo = yo + (back * 10);
alarm_keeper[0] = yo;
back = 0;
yo = 0;
i2c_stop();
i2c_start_wait(Dev24C02+I2C_WRITE); // set device address and write mode
i2c_write(0x0B); // write address = 5
i2c_rep_start(Dev24C02+I2C_READ); // set device address and read mode
yo = i2c_readNak(); // read one byte
back = yo >> 4;
yo = yo & 0b00001111;
yo = yo + back;
alarm_keeper[1] = yo;
i2c_stop();
}
void buzzer_go ( void ) {
for (int i = 0; i < 2; i++) {
OCR0A = 60;
_delay_ms(500);
OCR0A = 200;
_delay_ms(500);
}
OCR0A = 0;
}
int main(void) {
for(int i = 0; i<29; i++){
LED_ON_OFF[i] = 0;
}
weather_status = '\0';
int count = 100;
while (count) {
splash_screen();
_delay_ms(5);
for(int i = 0; i<29; i++){
LED_ON_OFF[i] = 0;
set_leds(3);
}
count--;
}
splash_screen();
init_light_sensor();
init_buzzer();
init_usart();
i2c_init();
alarm_init(); // init I2C interface
read_alarm();
for(int i = 0; i<29; i++){
LED_ON_OFF[i] = 0;
}
get_time_rtc();
last_minute = this_minute;
while (1) {
brightness = read_light_sensor();
get_time_rtc();
set_leds(brightness);
if (last_minute != this_minute) {
display_weather = 1;
set_weather(weather_status);
set_leds(brightness);
_delay_ms(3000);
last_minute = this_minute;
display_weather = 0;
}
}
}