Anonymous Anonymous - 5 days ago
110 0

aa

C

aaaaa

/*
 * 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;
		}
	}
}