/*---------------------------------------------------------------------------- Copyright: Radig Ulrich mailto: mail@ulrichradig.de Author: Radig Ulrich Remarks: known Problems: none Version: 24.10.2007 Description: Webserver uvm. Modifiziert für AVR-NET-IO: RoBue Version: 1.3 Versuchsstadium Datum: 24.11.2008 Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten eine Kopie der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. ----------------------------------------------------------------------------*/ #include #include "config.h" #include "usart.h" #include "networkcard/enc28j60.h" #include "networkcard/rtl8019.h" #include "stack.h" #include "timer.h" #include "wol.h" #include "httpd.h" #include "cmd.h" #include "telnetd.h" #include "ntp.h" #include "base64.h" #include "http_get.h" #include "lcd.h" #include "udp_lcd.h" #include "analog.h" #include "camera/cam.h" #include "camera/servo.h" #include "sendmail.h" volatile unsigned int variable[MAX_VAR]; // RoBue: // Die Uhrzeit wird zentral in main.c berechnet (s.u.) // Die anderen Programmteile lesen nur noch hh,mm,ss aus. // -> httpd.h/c, cmd.h/c unsigned char hh; unsigned char mm; unsigned char ss; // RoBue: // Das periodische Auslesen der 1-Wire-Sensoren erfolgt in main.c (s.u.) // Die anderen Programmteile lesen nur noch "ow_array" aus. // -> httpd.h/c, cmd.h/c #if USE_OW #include "1-wire/ds18x20.h" // Variable uint16_t ow_array[MAXSENSORS] = {200,200}; // Speicherplatz für 1-wire Sensorwerte // Position 0-4 eig. ID, Pos. 5+6 ist die Temperatur, Pos. 7 CRC-Byte PROGMEM uint8_t DS18B20IDs[MAXSENSORS+1][OW_ROMCODE_SIZE] = { OW_ID_T01, // 1. DS18B20 OW_ID_T02, OW_ID_Last }; // Endmarker uint8_t auslesen = 0; uint8_t messen = 1; #endif // RoBue // Schaltbedingungen (evtl. in config.h auslagern!) // Temperatur: Pin von PORTD, 'T (=Temperatur)', Sensornummer, 0 (=unbelegt), Gradzahl, 0 (=unbelegt) // Zeit: Pin von PORTD,'Z (=Zeit)',ein-Stunden,ein-Minuten,aus-Stunden,aus-Minuten //unsigned char Schalt_D[6][6] = { //{2,'T',0,0,20,0}, //{3,'T',1,0,19,0}, //{4,'Z',20,0,23,0}, //{5,0,0,0,0,0}, //{6,0,0,0,0,0}, //{7,0,0,0,0,0} }; uint8_t schalten = 1; // Schaltbedingungen: // ----------------- uint8_t temperatur1 = 20; // -> 20 Grad uint8_t temperatur2 = 18; // -> 18 Grad uint8_t temperatur3 = 5; // -> 5 Grad (Frostschutz) unsigned char hh1 = 21; // -> 21:45 Uhr unsigned char mm1 = 45; unsigned char hh2 = 22; // -> 22:00 Uhr unsigned char mm2 = 00; //---------------------------------------------------------------------------- // Hier startet das Hauptprogramm // ****************************** int main(void) { //Konfiguration der Ausgänge bzw. Eingänge //definition erfolgt in der config.h DDRA = OUTA; //DDRC = OUTC; // -> LCD DDRD = OUTD; // RoBue: // Pullups einschalten PORTA = (1 << PORTA0) | (1 << PORTA1) | (1 << PORTA2) | (1 << PORTA3) | (1 << PORTA4) | (1 << PORTA5) | (1 << PORTA6); unsigned long a; #if USE_SERVO servo_init (); #endif //USE_SERVO usart_init(BAUDRATE); // setup the UART #if USE_ADC ADC_Init(); #endif usart_write("\n\rSystem Ready\n\r"); usart_write("Compiliert am "__DATE__" um "__TIME__"\r\n"); usart_write("Compiliert mit GCC Version "__VERSION__"\r\n"); for(a=0;a<1000000;a++){asm("nop");}; //Applikationen starten stack_init(); httpd_init(); telnetd_init(); //Spielerrei mit einem LCD #if USE_SER_LCD udp_lcd_init(); lcd_init(); // RoBue: // LCD-Ausgaben: lcd_clear(); lcd_print(0,0,"** AVR-NET-IO **"); lcd_print(2,0,"Counter: "); lcd_print(3,0,"Zeit:"); #endif //Ethernetcard Interrupt enable ETH_INT_ENABLE; #if USE_SER_LCD // RoBue: // IP auf LCD lcd_print(1,0,"%1i.%1i.%1i.%1i",myip[0],myip[1],myip[2],myip[3]); #endif //Globale Interrupts einschalten sei(); #if USE_CAM #if USE_SER_LCD lcd_print(1,0,"CAMERA INIT"); #endif //USE_SER_LCD for(a=0;a<2000000;a++){asm("nop");}; cam_init(); max_bytes = cam_picture_store(CAM_RESELUTION); #if USE_SER_LCD back_light = 0; lcd_print(1,0,"CAMERA READY"); #endif //USE_SER_LCD #endif // -> USE_CAM #if USE_NTP ntp_init(); ntp_request(); #endif //USE_NTP #if USE_WOL wol_init(); #endif //USE_WOL #if USE_MAIL mail_client_init(); #endif //USE_MAIL //Hauptschlfeife // ************* while(1) { #if USE_ADC ANALOG_ON; #endif eth_get_data(); //Terminalcommandos auswerten if (usart_status.usart_ready){ usart_write("\r\n"); if(extract_cmd(&usart_rx_buffer[0])) { usart_write("Ready\r\n\r\n"); } else { usart_write("ERROR\r\n\r\n"); } usart_status.usart_ready =0; } // RoBue: // Counter ausgeben #if USE_SER_LCD lcd_print(2,9,"%4i",var_array[MAX_VAR_ARRAY-1]); #endif // RoBue: // Uhrzeit bestimmen und auf LCD ausgeben hh = (time/3600)%24; mm = (time/60)%60; ss = time %60; #if USE_SER_LCD lcd_print(3,7,"%2i:%2i:%2i",hh,mm,ss); #endif // RoBue: // DS18B20 auslesen // Anmerkung: // - Sekunde (25 und) 55 -> Sensor zum Messen und Berechnen auffordern // - Sekunde (28 und) 58 -> Sensor(en) auslesen // (- delay von 750 ms ist nicht nötig !!!) // Ausgabe ueber UART und in ow_array #if USE_OW uint8_t i = 0; //uint16_t TWert; uint8_t subzero, cel, cel_frac_bits; uint8_t tempID[OW_ROMCODE_SIZE]; if ( ss == 55 ) { // Messen? if ( messen == 1 ) { // RoBue Anmerkung: // Hiermit werden ALLE Sensoren zum Messen aufgefordert. // Aufforderung nur bestimmter Sensoren: // "NULL" durch "tempID" ersetzen // RoBue Testausgabe UART: // usart_write("Starte Messvorgang ...\r\n"); DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL ); // Kein Messen mehr bis ss= (25 oder) 55 messen = 0; // Jetzt kann ausgelesen werden auslesen = 1; } // -> if messen } // -> if ss if ( ss == 58 ) { // Auslesen? if ( auslesen == 1 ) { // (erste) ID ins RAM holen memcpy_P(tempID,DS18B20IDs[0],OW_ROMCODE_SIZE); while ( tempID[0] != 0 ) { //while ( tempID[0] == 0x10 ) { // RoBue Anmerkung: // Hiermit wird jeweils ein einzelner Sensor ausgelesen // und die Temperatur in ow_array abgelegt. // Achtung: // Pro Sekunde können max. ca. 10 Sensoren ausgelesen werden! if ( DS18X20_read_meas( tempID, &subzero,&cel, &cel_frac_bits) == DS18X20_OK ) { ow_array[i] = DS18X20_temp_to_decicel(subzero, cel, cel_frac_bits); //TWert = DS18X20_temp_to_decicel(subzero, cel, cel_frac_bits); //ow_array[i] = TWert; // RoBue: // Testausgabe UART: // usart_write("%2i:%2i:%2i: Temperatur: %3i Grad\r\n",hh,mm,ss,ow_array[i]/10); } // -> if else { usart_write("\r\nCRC Error (lost connection?) "); DS18X20_show_id_uart( tempID, OW_ROMCODE_SIZE ); } // -> else // nächste ID ins RAM holen memcpy_P(tempID,DS18B20IDs[++i],OW_ROMCODE_SIZE); } // -> while } // -> if auslesen auslesen = 0; // Auslesen vorläufig abschalten messen = 1; // Messen ab ss=25 und 55 wieder ermöglichen // Temperatur auf LCD ausgeben lcd_print(1,0," "); lcd_print(1,0,"%i C",ow_array[0]/10); lcd_print(1,8,"%i C",ow_array[1]/10); } // -> if ss #endif // RoBue: // Schalten der Ports durch bestimmte Bedingungen // - Temperatur // - Zeit // (- PORTA (digital, analog)) // Abfrage alle 30s if ( ss == 00 ) { if ( schalten == 1 ) { // RoBue Testausgabe UART: // usart_write("%2i:%2i: Schaltfunktionen testen ...\r\n",hh,mm); // Über Temperatur: temperatur1 - Sensor0 if ( ow_array[0]/10 < temperatur1 ) { PORTD |= (1 << PD2); // ein } else { PORTD &= ~(1 << PD2); // aus } // Über Temperatur: temperatur2 - Sensor1 if ( ow_array[1]/10 < temperatur2 ){ PORTD |= (1 << PD3); // ein } else { PORTD &= ~(1 << PD3); // aus } // Über Zeit: ein/aus if ( hh == hh1 ) { if ( mm == mm1 ) { PORTD |= (1 << PD4); // ein } } if ( hh == hh2 ) { if ( mm == mm2 ) { PORTD &= ~(1 << PD4); // aus } } schalten = 0; // Vorerst nicht mehr schalten } // -> schalten == 1 } // -> if ss == 00 u. 30 if ( ss == 01 ) { schalten = 1; // Schalten wieder ermöglichen } //Wetterdaten empfangen (Testphase) #if GET_WEATHER http_request (); #endif //Empfang von Zeitinformationen #if USE_NTP if(!ntp_timer){ ntp_timer = NTP_REFRESH; ntp_request(); } #endif //USE_NTP //Versand von E-Mails #if USE_MAIL if (mail_enable == 1) { mail_enable = 0; mail_send(); } #endif //USE_MAIL //Rechner im Netzwerk aufwecken #if USE_WOL if (wol_enable == 1) { wol_enable = 0; wol_request(); } #endif //USE_WOL //USART Daten für Telnetanwendung? telnetd_send_data(); } return(0); }