PROJEKT

Väderstation

Din egna maskin som kan mäta temperatur och fuktighet, med endast ett knapptryck kan du välja bland informationen visad på skärmen

Grupp 16

Stationen

Byggt från grund på en kopplingsplatta. Med hjälp av microprocessorn Atmega1284 kunde vi programera och kontrollera komponenterna.

Kretsritning

Källkod

  • #define F_CPU 1000000UL
  • #include
  • #include
  • #include
  • #define LCD_RS PD2
  • #define LCD_RW PD5
  • #define LCD_E PD6
  • #define LCD_DB0 PB0
  • #define LCD_DB1 PB1
  • #define LCD_DB2 PB2
  • #define LCD_DB3 PB3
  • #define LCD_DB4 PB4
  • #define LCD_DB5 PB5
  • #define LCD_DB6 PB6
  • #define LCD_DB7 PB7
  • #define DHT22_DDR DDRD
  • #define DHT22_PORT PORTD
  • #define DHT22_PIN PIND
  • #define DHT22_DATA_PIN PD4
  • #define BUTTON1_PIN PA2
  • #define BUTTON2_PIN PA3
  • enum DisplayMode {
  • LM35,
  • DHT22
  • };
  • void lcd_command(unsigned char cmd) {
  • _delay_ms(100);
  • PORTD &= ~(1 << LCD_RS);
  • PORTD &= ~(1 << LCD_RW);
  • PORTD |= (1 << LCD_E);
  • PORTB = cmd;
  • PORTD &= ~(1 << LCD_E);
  • PORTD |= (1 << LCD_E);
  • }
  • void lcd_data(unsigned char data) {
  • _delay_ms(100);
  • PORTD |= (1 << LCD_RS);
  • PORTD &= ~(1 << LCD_RW);
  • PORTD |= (1 << LCD_E);
  • PORTB = data;
  • PORTD &= ~(1 << LCD_E);
  • PORTD |= (1 << LCD_E);
  • }
  • void lcd_init() {
  • DDRB = 0xFF;
  • DDRD |= (1 << LCD_RS) | (1 << LCD_RW) | (1 << LCD_E);
  • lcd_command(0x30);
  • _delay_ms(5);
  • lcd_command(0x30);
  • _delay_us(100);
  • lcd_command(0x30);
  • _delay_us(100);
  • lcd_command(0x38);
  • lcd_command(0x06);
  • lcd_command(0x01);
  • lcd_command(0x0F);
  • }
  • void lcd_clear() {
  • lcd_command(0x01);
  • }
  • void lcd_goto_row2() {
  • lcd_command(0xC0);
  • }
  • void lcd_print(char *str) {
  • unsigned char i = 0;
  • while (str[i] != 0) {
  • lcd_data(str[i]);
  • i++;
  • }
  • }
  • void lm335_setup() {
  • ADMUX = (1 << REFS0);
  • ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
  • }
  • float lm335_read() {
  • uint16_t adc_value;
  • float temperature;
  • ADCSRA |= (1 << ADSC);
  • while (ADCSRA & (1 << ADSC));
  • while (ADCSRA & (1 << ADSC));
  • adc_value = ADC;
  • temperature = adc_value * 5.0 / 1024.0;
  • temperature = (temperature - 0.5) * 100.0;
  • return temperature;
  • }
  • void temp_indoor() {
  • float temp = lm335_read();
  • char temp_str[10];
  • int celsius_temp = (273.15 - temp) / 10;
  • sprintf(temp_str, "%d.%d C", celsius_temp, abs((int)temp % 10));
  • lcd_clear();
  • lcd_print("Temp: ");
  • lcd_print(temp_str);
  • _delay_ms(1000);
  • }
  • void start_signal(){
  • DHT22_DDR |= (1 << DHT22_DATA_PIN);
  • DHT22_PORT &= ~(1 << DHT22_DATA_PIN);
  • _delay_ms(18);
  • DHT22_PORT |= (1 << DHT22_DATA_PIN);
  • _delay_us(40);
  • DHT22_DDR &= ~(1 << DHT22_DATA_PIN);
  • }
  • void check_response() {
  • while (DHT22_PIN & (1 << DHT22_DATA_PIN));
  • while ((DHT22_PIN & (1 << DHT22_DATA_PIN)) == 0);
  • while (DHT22_PIN & (1 << DHT22_DATA_PIN));
  • }
  • uint8_t read_data() {
  • uint8_t i, j;
  • uint8_t data = 0;
  • for (j = 0; j < 8; j++) {
  • while ((DHT22_PIN & (1 << DHT22_DATA_PIN)) == 0);
  • _delay_us(30);
  • if (DHT22_PIN & (1 << DHT22_DATA_PIN)) {
  • data |= (1 << (7 - j));
  • }
  • while (DHT22_PIN & (1 << DHT22_DATA_PIN));}
  • return data;
  • }
  • void temp_outdoor() {
  • char temp_str[10];
  • char humidity_str[10];
  • uint8_t dht_data[5];
  • lcd_clear();
  • start_signal();
  • check_response();
  • for (int i = 0; i < 5; i++) {
  • dht_data[i] = read_data();
  • }
  • uint16_t humidity = (dht_data[0] << 8) | dht_data[1];
  • int16_t temp = (dht_data[2] << 8) | dht_data[3];
  • if (temp & 0x8000) {
  • temp = -(temp & 0x7FFF);
  • }
  • int celsius_temp = temp / 10;
  • sprintf(temp_str, "%d.%d C", celsius_temp, abs(temp % 10));
  • int humidity_int = humidity / 10;
  • sprintf(humidity_str, "%d.%d %%", humidity_int, abs(humidity % 10));
  • lcd_clear();
  • lcd_print("Temp: ");
  • lcd_print(temp_str);
  • lcd_goto_row2();
  • lcd_print("Humid: ");
  • lcd_print(humidity_str);
  • _delay_ms(1000);
  • }
  • int main() {
  • lcd_init();
  • lm335_setup();
  • dht22_init();
  • enum DisplayMode displayMode = LM35;
  • while (1) {
  • display_time();
  • if (PINA & (1 << BUTTON1_PIN)) {
  • displayMode = LM35;
  • } else if (PINA & (1 << BUTTON2_PIN)) {
  • displayMode = DHT22;
  • }
  • switch (displayMode) {
  • case LM35:
  • temp_indoor();
  • break;
  • case DHT22:
  • temp_outdoor();
  • break;
  • }
  • }
  • return 0;
  • }