Sorry dass ich mich erst jetzt melde.
1) RFM12 Gateway mit Datenbank Anbindung (Aufzeichnung von Luftfeuchte und Temperatur in Mysql)
2) Zeit über Funk und ntp (ohne offline Zeit) WD bei Funkausfall.
3) Wecken mit Vogelgewzitscher (WAV Player) und Alarm Eskalation.
4) Dimmer usw..
Code: Alles auswählen
/*----------------------------------------------------------------------------
Copyright: Radig Ulrich mailto: mail@ulrichradig.de
Author: Radig Ulrich
Remarks:
known Problems: none
Version: 24.10.2007
Description: Webserver uvm.
Modified: G. Menke, 05.08.2010
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 <avr/io.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "global.h"
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "base64_dec.h" // Base 64 Verschlüsselnung
#include "base64_dec.c"
#include "base64_enc.h"
#include "base64_enc.c"
#define MAX_BUF 64 // Paket Größe in Bytes
#define TX_TIMEOUT 100 // Maximale Wartezeit auf Daten in ms (max 255)
volatile unsigned char delaycnt;
char rxbuf[MAX_BUF];
char txbuf[MAX_BUF];
char ztemp[MAX_BUF];
char zfeucht[MAX_BUF];
char xbuf_base64[MAX_BUF];
uint8_t rf_rx_counter;
char rf_rx_buffer1[20];
#include "rf12.h"
#include "rf12.c"
#include "mylcd.c"
#include "small_font.h"
#include "mega.h"
#include "image_load.h"
#include "image_load.c"
#include "usart.h"
#include "usart.c"
#include "uart_addon.h"
#include "uart_addon.c"
#include "onewire.h"
#include "onewire.c"
#include "ds18x20.h"
#include "ds18x20.c"
#include "crc8.h"
#include "crc8.c"
#define MAXSENSORS 2
#define NEWLINESTR "\r\n"
uint8_t gSensorIDs[MAXSENSORS][OW_ROMCODE_SIZE];
uint8_t nSensors, i;
int16_t decicelsius;
uint8_t error;
char Wire1SensorT1[10];
char Wire1SensorT2[10];
#define Hindergrundbeleuchtung PA3
uint8_t toogledisplayled;
#include "1wire_exd.c"
#include "enc28j60.h"
#include "enc28j60.c"
#include "stack.h"
#include "stack.c"
#include "timer.h"
#include "timer.c"
#include "wol.h"
#include "wol.c"
#include "httpd.h"
#include "httpd.c"
#include "cmd.h"
#include "cmd.c"
#include "telnetd.h"
#include "telnetd.c"
#include "ntp.h"
#include "ntp.c"
#include "base64.h"
#include "base64.c"
#include "http_get.h"
#include "http_get.c"
#include "analog.h"
#include "analog.c"
#include "sendmail.h"
#include "sendmail.c"
#include <avr/eeprom.h>
#include "dhcpc.h"
#include "dhcpc.c"
#include "dnsc.h"
#include "dnsc.c"
#include "ad_messung.c" //Erweiterung Manfred
#include "temperaturAD0.h" //Erweiterung Manfred
#include "temperaturAD0.c" //Erweiterung Manfred
//----------------------------------------------------------------------------
//Hier startet das Hauptprogramm
int main(void)
{
uint8_t error;
uint8_t counterzf;
ADC_Init(); //Analog Digital Wandler initalisieren
DDRA |= 1<<Hindergrundbeleuchtung; //INIT Hintergrund Beleuchtung
PORTA |= 1<<Hindergrundbeleuchtung; /* Hindergrundbeleuchtung High */
_delay_ms(500);
PORTA &= ~(1<<Hindergrundbeleuchtung); /* Hindergrundbeleuchtung ist Low*/
_delay_ms(500);
PORTA |= 1<<Hindergrundbeleuchtung; /* Hindergrundbeleuchtung High */
unsigned char Buffer[30];
char Buffer1[30];
//init lcd
lcd_init();
lcd_init();
lcd_init();
lcd_clear();
/****************************************************
* Display Ausgabe
***************************************************/
lcd_clear(); // clear screen
lcd_set_cursor(0,LINE0); // new start position
lcd_puts(small_font,"Gateway V 1.0"); // draw string using internal ram (better use lcd_puts_p)
lcd_set_cursor(0,LINE1); // new start position
lcd_puts(small_font,"Initalisieren....."); // draw string using internal ram (better use lcd_puts_p)
lcd_draw_line(0,LINE2,127,LINE2,BLACK); // draw a line under the text
_delay_ms(500);
unsigned long a;
usart_init(BAUDRATE); // setup the UART
for(a=0;a<1000000;a++){asm("nop");};
//Applikationen starten
stack_init();
httpd_init();
telnetd_init();
lcd_set_cursor(0,LINE3); // new start position
lcd_puts(small_font,"Application: Stack,http,telnet"); // draw string using internal ram (better use lcd_puts_p)
//Ethernetcard Interrupt enable
ETH_INT_ENABLE;
//Globale Interrupts einschalten
sei();
#if USE_DHCP
dhcp_init();
if ( dhcp() == 0)
{
save_ip_addresses();
}
else
{
usart_write("DHCP fail\r\n");
read_ip_addresses(); //get from EEPROM
}
#endif //USE_DHCP
usart_write("\r\nIP %1i.%1i.%1i.%1i\r\n", myip[0] , myip[1] , myip[2] , myip[3]);
usart_write("MASK %1i.%1i.%1i.%1i\r\n", netmask[0] , netmask[1] , netmask[2] , netmask[3]);
usart_write("GW %1i.%1i.%1i.%1i\r\n", router_ip[0], router_ip[1], router_ip[2], router_ip[3]);
#if USE_DNS
usart_write("DNS %1i.%1i.%1i.%1i\r\n", dns_server_ip[0], dns_server_ip[1], dns_server_ip[2], dns_server_ip[3]);
#endif //USE_DNS
itoa(myip[2],Buffer1, 10);
lcd_set_cursor(0,LINE4); // new start position
lcd_puts(small_font,Buffer1); // draw string using internal ram (better use lcd_puts_p)
#if USE_NTP
#if USE_DNS
dns_init();
if ( dns_resolve("1.de.pool.ntp.org") == 0) //resolve NTP server
{
for (unsigned char count = 0; count<4; count++)
{
eeprom_busy_wait ();
eeprom_write_byte((unsigned char *)(NTP_IP_EEPROM_STORE + count),dns_resolved_ip[count]);
}
}
else
{
usart_write("DNS Err.\r\n");
}
#endif //USE_DNS
ntp_init();
lcd_set_cursor(0,LINE5); // new start position
lcd_puts(small_font,"NTP Initialisiern..."); // draw string using internal ram (better use lcd_puts_p)
for(a=0;a<1000000;a++){asm("nop");};
ntp_request();
if ( ntp() != 0 )
{
usart_write("NTP Err.\r\n");
}
else
{
command_time();
}
#endif //USE_NTP
#if USE_WOL
wol_init();
#endif //USE_WOL
#if USE_MAIL
mail_client_init();
#endif //USE_MAIL
/****************************************************
* StartUp RFM12
***************************************************/
lcd_set_cursor(0,LINE6); // new start position
lcd_puts(small_font,"RFM12 u. 1Wire Initalisieren"); // draw string using internal ram (better use lcd_puts_p)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf12_setfreq(RF12FREQ(433.92)); // Sende/Empfangsfrequenz auf 433,92MHz einstellen
rf12_setbandwidth(4, 0, 4); // 200kHz Bandbreite, -6dB Verstärkung, DRSSI threshold: -79dBm
rf12_setbaud(4800); // 4800 baud
rf12_setpower(0, 6); // 1mW Ausgangangsleistung, 120kHz Frequenzshift
unsigned char tx_cnt=0,rx_cnt;
unsigned char bufferch;
uint8_t rfError;
usart_write_str("\nGateway RFM12 laeuft !\n");
lcd_set_cursor(0,LINE7); // new start position
lcd_puts(small_font,"RFM12 Rx MOde"); // draw string using internal ram (better use lcd_puts_p)
rf12_rxmode(); // wieder auf RX umschalten
_delay_ms(10); // Startup Loop
unsigned char number;
number=32;
uint8_t temp_interrupt; // Zum Sicherern der Interrupts
/****************************************************
* Wire1 Sensor Init
***************************************************/
init_wire1_sensor();
/****************************************************
* Display Ausgabe
***************************************************/
lcd_clear(); // clear screen
lcd_set_cursor(0,LINE0); // new start position
lcd_puts(small_font,"Gateway laueft: "); // draw string using internal ram (better use lcd_puts_p)
lcd_draw_line(0,LINE2,127,LINE2,BLACK); // draw a line under the text
uint8_t x,z;
rfError=0;
x=0; //start init
z=0; //Zeile
toogledisplayled=0;
volatile unsigned long time_ori;
uint8_t sectaktcounter, sectaktcounter1;
time_ori=0;
sectaktcounter=0;
sectaktcounter1=0;
PORTA |= 1<<Hindergrundbeleuchtung; /* Hindergrundbeleuchtung High */
double TempPC;
while(1)
{
#if USE_ADC
//ANALOG_ON;
#endif
eth_get_data();
//Wetterdaten empfangen (Testphase)
#if GET_WEATHER
http_request ();
#endif
//**************************************************************************************************
//* 1 Wire Messung nur alle X Sekunden + NTP Refresh
//**************************************************************************************************
if(time != time_ori)
{
time_ori = time;
sectaktcounter++; //Takt1
sectaktcounter1++; //Takt2
}
if(sectaktcounter == 2){
sectaktcounter=0;
read_wire1_sensor(); //1 Wire Sensoren Lesen
ntp_timer = NTP_REFRESH; //NTP Refresh Timer
ntp_request(); //NTP Daten lesen
dtostrf(gettemperatur(0,
20,
0
) ,
2,
1,
Buffer1
); // Umwandeln mit der Funktion => Ergebnis in Buffer
lcd_set_cursor(0,LINE6); // new start position
lcd_puts(small_font, Buffer1);
lcd_set_cursor(20,LINE6); // new start position
lcd_puts(small_font, "C");
}
//**************************************************************************************************
//* NTP Zeit Auswertung und Ausgabe
//**************************************************************************************************
if (ntp_state == NTP_STATE_REQ_ERR)
{
strcpy("dstr","NTP: keine Verbindung!....");
}
else
{
ntp_struct dt;
decode_time(time, &dt);
sprintf_P(dstr, PSTR("%s, %s"), dt.datestr, dt.timestr);
if(sectaktcounter1 == 10){
lcd_init();
lcd_clear();
read_wire1_sensor(); //1 Wire Sensoren Lesen
dtostrf(gettemperatur(0,
20,
0
) ,
2,
1,
Buffer1
); // Umwandeln mit der Funktion => Ergebnis in Buffer
lcd_set_cursor(0,LINE6); // new start position
lcd_puts(small_font, Buffer1);
lcd_set_cursor(20,LINE6); // new start position
lcd_puts(small_font, "C");
// Variable befüllen.........
// Test LCD Ausgabe
strcpy(txbuf, "#00|");
error = rf12_poll_data(32);
//counterzf = 0;
//while(error == 1 && counterzf < 3){
// error = rf12_poll_data(32);
// counterzf ++;
//}
if(error == 0){
strcpy( zfeucht, rxbuf);
}
sectaktcounter1=0;
}
else if(sectaktcounter1 == 5){
// Variable befüllen.........
// Test LCD Ausgabe
strcpy(txbuf, "#01|");
error = rf12_poll_data(32);
//counterzf = 0;
//while(error == 1 && counterzf < 3){
// error = rf12_poll_data(32);
// counterzf ++;
//}
if(error == 0){
strcpy(ztemp, rxbuf); // Luftfeuchte aufs Display ausgeben.
}
}
lcd_set_cursor(0,LINE0);
lcd_puts(small_font,"Feucht: "); // Ergebnis auf LCD Display
lcd_puts(small_font,zfeucht); // Ergebnis auf LCD Display
lcd_set_cursor(0,LINE1);
lcd_puts(small_font,"Temp: "); // Ergebnis auf LCD Display
lcd_puts(small_font,ztemp); // Ergebnis auf LCD Display
_delay_ms(2);
}
//**************************************************************************************************
//* LCD Time Ausgabe auf Display
//**************************************************************************************************
lcd_set_cursor(0,LINE4); // new start position
lcd_puts(small_font, dstr); // draw string using internal ram (better use lcd_puts_p)
ntp_struct dt;
decode_time(time, &dt);
//**************************************************************************************************
//* NTP Time
//**************************************************************************************************
sprintf_P(dstr, PSTR("%s"), dt.timestr);
strcpy(txbuf, "#03");
strcat(txbuf, dstr);
strcat(txbuf, " |");
rf12_txdata(txbuf, 32); // Senden Der Zeit
//**************************************************************************************************
//* NTP Datum
//**************************************************************************************************
sprintf_P(dstr, PSTR("%s"), dt.datestr);
strcpy(txbuf, "#04");
strcat(txbuf, dstr);
strcat(txbuf, " |");
rf12_txdata(txbuf, 32); // Senden Der Zeit
//**************************************************************************************************
//* Alarm
//**************************************************************************************************
sprintf_P(dstr, PSTR("%s"), dt.datestr);
strcpy(txbuf, "#05");
strcat(txbuf, "22:55|");
rf12_txdata(txbuf, 32); // Senden Der Zeit
//**************************************************************************************************
//* NTP ausgabe Zeit
//**************************************************************************************************
lcd_set_cursor(0,LINE5); // new start position
itoa( time , Buffer1, 10 );
lcd_puts(small_font, Buffer1); // draw string using internal ram (better use lcd_puts_p)
// rf12_poll_data(32); // Response auf rxbuf
//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
#if USE_DHCP
if ( dhcp() != 0) //check for lease timeout
{
usart_write("dhcp lease renewal failed\r\n");
RESET();
}
#endif //USE_DHCP
//USART Daten für Telnetanwendung?
telnetd_send_data();
if(ping.result)
{
usart_write("Get PONG: %i.%i.%i.%i\r\n",ping.ip1[0],ping.ip1[1],ping.ip1[2],ping.ip1[3]);
ping.result = 0;
}
//_delay_ms(300);
}//while (1)
return(0);
}
zum rf12.c => ist nicht von mir wurde nur angepasst.
Es gibt aber inzwischen noch bessere libs die den internen SPI verwenden.
weiters hab ich eine Variante mit codebase64 verschlüsselung und crc.
Code: Alles auswählen
#include <avr/io.h>
#include <avr/interrupt.h>
#include "global.h"
#include "rf12.h"
#include <util/delay.h>
#define RF_PORT PORTA
#define RF_DDR DDRA
#define RF_PIN PINA
#define SDI PA5
#define SCK PA7
#define CS PA4
#define SDO PA6
unsigned short rf12_trans(unsigned short wert)
{ unsigned char i;
cbi(RF_PORT, CS);
for (i=0; i<16; i++)
{ if (wert&32768)
sbi(RF_PORT, SDI);
else
cbi(RF_PORT, SDI);
wert<<=1;
if (RF_PIN&(1<<SDO))
wert|=1;
sbi(RF_PORT, SCK);
asm("nop");
asm("nop");
cbi(RF_PORT, SCK);
}
sbi(RF_PORT, CS);
return wert;
}
void rf12_init(void)
{
RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
RF_PORT=(1<<CS);
for (unsigned char i=0; i<200; i++)
_delay_ms(10); // wait until POR done
rf12_trans(0xC0E0); // AVR CLK: 10MHz
rf12_trans(0x80D7); // Enable FIFO
rf12_trans(0xC2AB); // Data Filter: internal
rf12_trans(0xCA81); // Set FIFO mode
rf12_trans(0xE000); // disable wakeuptimer
rf12_trans(0xC800); // disable low duty cycle
rf12_trans(0xC4F7); // AFC settings: autotuning: -10kHz...+7,5kHz
}
void rf12_rxmode(void)
{
rf12_trans(0x82C8); // RX on
_delay_ms(1);
rf12_trans(0xCA81); // set FIFO mode
rf12_trans(0xCA83); // enable FIFO: sync word search
}
void rf12_stoprx(void)
{
rf12_trans(0x8208); // RX off
}
void rf12_setbandwidth(unsigned char bandwidth, unsigned char gain, unsigned char drssi)
{
rf12_trans(0x9400|((bandwidth&7)<<5)|((gain&3)<<3)|(drssi&7));
}
void rf12_setfreq(unsigned short freq)
{ if (freq<96) // 430,2400MHz
freq=96;
else if (freq>3903) // 439,7575MHz
freq=3903;
rf12_trans(0xA000|freq);
}
void rf12_setbaud(unsigned short baud)
{
if (baud<664)
baud=664;
if (baud<5400) // Baudrate= 344827,58621/(R+1)/(1+CS*7)
rf12_trans(0xC680|((43104/baud)-1)); // R=(344828/8)/Baud-1
else
rf12_trans(0xC600|((344828UL/baud)-1)); // R=344828/Baud-1
}
void rf12_setpower(unsigned char power, unsigned char mod)
{
rf12_trans(0x9800|(power&7)|((mod&15)<<4));
}
void rf12_ready(void)
{ cbi(RF_PORT, SDI);
cbi(RF_PORT, CS);
asm("nop");
while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
}
void rf12_txdata(char *data, char number)
{ unsigned char i;
rf12_trans(0x8238); // TX on
rf12_ready();
rf12_trans(0xB8AA);
rf12_ready();
rf12_trans(0xB8AA);
rf12_ready();
rf12_trans(0xB8AA);
rf12_ready();
rf12_trans(0xB82D);
rf12_ready();
rf12_trans(0xB8D4);
for (i=0; i<number; i++)
{ rf12_ready();
rf12_trans(0xB800|(*data++));
}
rf12_ready();
_delay_us(10);
rf12_trans(0x8208); // TX off
}
/*****************************************************************************
* rf12_ready mit Watchdog
* wartet wdcounter*xx us
* Damit muss kein Interrupt verschwendet werden
* (benötige keinen großen Datendurchsatz...)
* 18.01.11 Manfred K
*****************************************************************************/
uint8_t rf12_ready_wd(void)
{
uint16_t wdcounter;
wdcounter = 64000; // Watchdog, wenn FIFO nicht Ready, dann abbruch RX
cbi(RF_PORT, SDI);
cbi(RF_PORT, CS);
asm("nop");
while (!(RF_PIN&(1<<SDO))){
if(wdcounter > 0){
wdcounter--;
_delay_us(10);
}
else{
return 1; // Error Watchdog => kein RX innerhalb der Zeit
}
}; // wait until FIFO ready
return 0;
}
/*****************************************************************************
* RX RF12 geändert, Auswertung rf12_ready
* 18.01.11 Manfred K
*****************************************************************************/
uint8_t rf12_rxdata(char *data, char number)
{ unsigned char i;
uint8_t Err;
rf12_trans(0x82C8); // RX on
rf12_trans(0xCA81); // set FIFO mode
rf12_trans(0xCA83); // enable FIFO
for (i=0; i<number; i++)
{
Err= rf12_ready_wd();
if(Err== 0){ // Nur wenn Null Fehler also innerhalb der Zeit
*data++=rf12_trans(0xB000);
}
else{
return 1; // Sonst Rückgabe Error und Abbruch
}
}
rf12_trans(0x8208); // RX off
return 0; // Rückgabe kein Fehler!
}
/*****************************************************************************
* Poll Clients und warte auf Response
* (nur so lange wie im ready_wd definiert
* 18.01.11 Manfred Kogler
*****************************************************************************/
uint8_t rf12_poll_data(char number){
uint8_t error;
rf12_stoprx();
_delay_ms(10); // umschalten auf TX mit delay
xbuf_base64[0] = '\0'; //Array löschen
rxbuf[0] = '\0'; //Array löschen
rf12_txdata(txbuf, number); // Senden der Daten über RFM12
rf12_rxmode(); // umschalten auf RX Response
xbuf_base64[0] = '\0'; //Array löschen
error = rf12_rxdata(rxbuf ,number); // Empfangen der Daten base64 verschlüsselt
return error; // kein Fehler Error Code 0
}