/*
*
#include <stdint.h>
#include <stdio.h>
#include <avr/io.h>
#include "uart.h"
#include <util/delay.h>
#include <stdlib.h>
#include <string.h>
#include <avr/interrupt.h>
// Entweder: SMS senden
#define SMSMODE 0
// Oder: SMS als Vorlage im Handy speichern (zu Testzwecken)
// #define SMSMODE 1
#define _LF 0x0A
#define TIMEOUT 5
#define CLIPNR_MINLEN 10
#define INCALL_TOUT 20
#define OUTCALL_TOUT 20
#define KEEPALIVE_TOUT 30
void delay_ms(uint16_t);
void uart_init (uint16_t);
uint8_t get_SW_OutputTyp (void);
uint8_t get_SW_AlarmTyp (void);
uint8_t getSW_BCDTime (void);
uint8_t SMS_send (unsigned char *, unsigned char *, uint8_t);
void getTeilstring (unsigned char *, unsigned char *, uint8_t, char, char);
uint8_t getGPS (void);
uint8_t RingDetected (void);
void getGSMcmd ( unsigned short wWaitms, unsigned char wTimeout);
uint8_t getSIMnumber (uint8_t);
void BaudrateGSM (void);
int main(void);
extern uint8_t buffcnt;
unsigned char buffer[128],
nachricht2[160],
clipnr[20],
gpscoord[55],
tmp[20],
tmp2[20];
volatile uint8_t timer_gps=60,
timer_rings=0,
timer_waitGSM=0,
timer_KeepAlive,
cnt_rings=0,
gps_detect=0,
exit1=0,
exit2=0,
exit3=0,
SW_exit3_time,
SW_OutputTyp,
SW_AlarmTyp,
SW_BCDTime,
alarm = 0;
volatile uint16_t timer_exit3=0;
void delay_ms(uint16_t ms)
{
for(uint16_t t=0; t<=ms; t++)
_delay_ms(1);
}
ISR (TIMER1_COMPA_vect)
{
timer_gps++;
timer_waitGSM++;
if (cnt_rings)
timer_rings++;
else
timer_KeepAlive++;
// Exit 1 im Sekundenbetrieb
if (exit1 == 2)
{
PORTD |= (1<<PD5);
exit1=1;
}
else if (exit1 == 1)
{
PORTD &= ~(1<<PD5);
exit1=0;
}
// Exit 2 im Toggle Betrieb
if (exit2 == 2)
{
PORTD ^= (1<<PD6);
exit2=0;
}
if (exit3 == 2)
{
PORTD |= (1<<PD7);
exit3=1;
timer_exit3=0;
}
else if (exit3 == 1)
{
timer_exit3++;
if (timer_exit3 >= (uint16_t) (SW_exit3_time * 60))
{
PORTD &= ~(1<<PD7);
exit3=0;
}
}
if (gps_detect == 1)
PORTB ^= (1<<PB5);
if (gps_detect == 2)
PORTB |= (1<<PB5);
}
ISR (INT1_vect)
{
alarm=1;
}
uint8_t get_SW_OutputTyp (void)
{
if (PINC & (1 << PINC4))
return 0;
else
return 1;
}
uint8_t get_SW_AlarmTyp (void)
{
if (PINC & (1 << PINC5))
return 0;
else
return 1;
}
uint8_t getSW_BCDTime (void)
{
uint8_t sw = 0;
if (!(PINC & (1 << PINC0)))
sw += 1;
if (!(PINC & (1 << PINC1)))
sw += 2;
if (!(PINC & (1 << PINC2)))
sw += 4;
if (!(PINC & (1 << PINC3)))
sw += 8;
switch (sw)
{
case 0 : return 1;
case 1 : return 5;
case 2 : return 10;
case 3 : return 15;
case 4 : return 20;
case 5 : return 30;
case 6 : return 45;
case 7 : return 60;
case 8 : return 90;
case 9 : return 120;
}
return 1;
}
uint8_t SMS_send (unsigned char *zielnr, unsigned char *nachricht, uint8_t typ)
{
uint8_t anz_septents = 0,
anz_bytes = 1,
i = 0,
shift = 0,
erg=1;
// SMS Anzeigen START
PORTB ^= (1<<PB5);
while (nachricht[anz_septents] != 0)
{
nachricht2[anz_bytes] = (nachricht[anz_septents]&0x7F) >> shift;
if (shift != 0)
nachricht2[anz_bytes-1] |= (nachricht[anz_septents]&((1<<shift)-1)) << (8-shift);
shift++;
anz_septents++;
if (shift ==
shift=0;
else
anz_bytes++;
}
nachricht2[0] = anz_septents;
while (zielnr[i] !=0)
{
if (zielnr[i+1] == 0)
tmp[i] = 'F';
else
tmp[i] = zielnr[i+1];
tmp[i+1] = zielnr[i];
i += 2;
}
tmp[i] = 0;
if (typ == 0)
sprintf(tmp2, "at+cmgs=");
else if (typ == 1)
sprintf(tmp2, "at+cmgw=");
uart_puts(tmp2);
sprintf(tmp2, "%i\r\n", (anz_bytes+(i/2)+7));
uart_puts(tmp2);
// Daten empfangen, Handy Bereit
getGSMcmd( 3000, TIMEOUT );
sprintf(tmp2, "00");
uart_puts(tmp2);
sprintf(tmp2, "11");
uart_puts(tmp2);
sprintf(tmp2, "00");
uart_puts(tmp2);
if(tmp[i-2] == 'F')
i--;
sprintf(tmp2, "%02X91", i);
uart_puts(tmp2);
sprintf(tmp2, tmp);
uart_puts(tmp2);
sprintf(tmp2, "00");
uart_puts(tmp2);
sprintf(tmp2, "00");
uart_puts(tmp2);
sprintf(tmp2, "AA");
uart_puts(tmp2);
for (anz_septents = 0;anz_septents<anz_bytes;anz_septents++)
{
sprintf(tmp2, "%02X", nachricht2[anz_septents]);
uart_puts(tmp2);
}
// Sendevorgang abschließen
delay_ms(1000);
uart_putc(0x1A);
// Daten empfangen
getGSMcmd( 6000, TIMEOUT );
if ( strstr(buffer, "CMGW") != 0 )
erg = 0; // OK
else if ( strstr(buffer, "CMGS") != 0 )
erg = 0; // OK
else if ( strstr(buffer, "ERROR") != 0 )
erg = 1; // Mistake
else
erg = 3; // Unknown
// Daten empfangen
getGSMcmd( 3000, 1 );
// SMS Anzeigen ENDE
PORTB &= ~(1<<PB5);
return erg;
}
void getTeilstring (unsigned char *dest, unsigned char *from, uint8_t pos, char compare1, char compare2)
{
uint8_t detect=0,
cnt=0;
while (*from != '\0')
{
if (*from == compare1)
cnt++;
if (cnt == pos)
{
compare1=compare2;
if (detect == 0)
detect = 1;
else
{
*dest = *from;
dest++;
}
}
from++;
}
*dest = '\0';
}
uint8_t getGPS (void)
{
uint8_t i,
u=0,
gps_dect=0,
byte;
while (timer_gps < 20)
{
if (!(PIND & (1 << PIND2)))
{
_delay_us (52);
_delay_us (52);
_delay_us (52);
_delay_us (52);
_delay_us (52);
_delay_us (52);
byte=0;
for (i=0; i <= 7; i++)
{
if (PIND & (1 << PIND2))
byte |= (1 << i);
_delay_us (52);
_delay_us (52);
_delay_us (52);
_delay_us (52);
}
if (gps_dect)
{
buffer[u]=byte;
u++;
if (byte == '\n')
{
buffer[u-2]='\0';
u=0;
byte=0;
if (strncmp (buffer, "$GPRMC", 6) == 0)
{
getTeilstring (tmp, buffer, 2, ',', ',');
if (tmp[0] == 'V')
{
gps_detect=1;
sprintf (gpscoord, "*GPS INVALID*");
}
else
{
gps_detect=2;
sprintf (gpscoord, "*GPS OK*");
}
getTeilstring (tmp, buffer, 1, ',', ','); // = UTC Time
sprintf (gpscoord, "%s %c%c:%c%c:%c%c", gpscoord, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]); // "hh:mm:ss "
getTeilstring (tmp, buffer, 4, ',', ','); // = Hemisphere
sprintf (gpscoord, "%s %s", gpscoord, tmp);
getTeilstring (tmp, buffer, 3, ',', ','); // = Latitude (e.g. 5256.0361)
sprintf (gpscoord, "%s%c%c\x24%c%c%c%c%c%c%c ", gpscoord, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8]);
getTeilstring (tmp, buffer, 6, ',', ','); // = Hemisphere
sprintf (gpscoord, "%s %s", gpscoord, tmp);
getTeilstring (tmp, buffer, 5, ',', ','); // = Longitude (e.g. 01248.0766)
sprintf (gpscoord, "%s%c%c%c\x24%c%c%c%c%c%c%c", gpscoord, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9]);
}
}
}
if (byte == _LF)
{
gps_dect=1;
}
}
}
timer_gps=0;
if (gps_dect)
return 0;
else
{
PORTB &= ~(1<<PB5);
gps_detect=0;
sprintf (gpscoord, "* NO GPS"); return 1;
}
}
uint8_t RingDetected (void)
{
uint8_t u=0;
if ( strlen(clipnr) >= CLIPNR_MINLEN )
{
getTeilstring (tmp, buffer, 2, '+', ',');
if (tmp[0] != '\0')
{
u=strlen(tmp);
if (tmp[u-1] == '"')
tmp[u-1] = '\0';
if (strcmp (tmp, clipnr) == 0)
{
return 0;
}
}
}
else
{
return 0;
}
return 1;
}
// Telefonquittung auswerten
// mit Sonderbehandlung Anruferkennung
void getGSMcmd ( unsigned short wWaitms, unsigned char wTimeout)
{
uint8_t i=0;
// Warten vor Auswertung
delay_ms(wWaitms);
timer_waitGSM=0;
while (1)
{
if (buffcnt)
{
buffer[i++] = ser_getc();
if ( buffcnt == 0 )
break;
}
// Timeout
if (timer_waitGSM >= wTimeout)
break;
}
// Endezeichen
buffer[i] = '\0';
}
uint8_t getSIMnumber (uint8_t index)
{
uint8_t u=0;
uart_puts ("AT+CPBR=");
uart_putc (index + 0x30);
uart_puts ("\r\n");
getGSMcmd( 1000, TIMEOUT );
// String vorhanden
if ( strlen(buffer) >= CLIPNR_MINLEN )
{
getTeilstring (clipnr, buffer, 2, '+', ',');
u=strlen(clipnr);
if (clipnr[u-1] == '"')
{
u--;
clipnr[u]='\0';
}
if (u>0)
u=0;
else
u=1;
}
else
{
u=1;
}
return u;
}
void BaudrateGSM (void)
{
uint16_t baudrate=4800;
timer_waitGSM=TIMEOUT;
// Diese Schleife wird erst verlassen
// wenn ein Handy angesteckt wird
while (1)
{
if (timer_waitGSM >= TIMEOUT)
{
switch (baudrate)
{
case 4800 : baudrate = 9600; break;
case 9600 : baudrate = 19200; break;
case 19200 : baudrate = 38400; break;
case 38400 : baudrate = 57600; break;
case 57600 : baudrate = 4800; break;
}
timer_waitGSM=0;
uart_init(baudrate);
// Telefonerkennung
uart_puts ("AT\r\n");
}
// Daten empfangen
getGSMcmd( 1000,TIMEOUT);
if ( strstr(buffer, "OK") != 0 )
break;
}
}
void InitHandy (void)
{
uint8_t i=0;
// Handyinitialisierung START
PORTB ^= (1<<PB5);
// Baudrate ermitteln
BaudrateGSM();
uart_puts ("ATE0\r\n");
getGSMcmd( 1000, TIMEOUT);
uart_puts ("AT+CLIP=1\r\n");
getGSMcmd( 1000, TIMEOUT);
uart_puts ("AT+CPBS=\"SM\"\r\n");
getGSMcmd( 1000, TIMEOUT);
// Simnummer auslesen
clipnr[0] = 0x00;
// 3 Verusche zum auslesen der Nummer
if ( getSIMnumber(1) )
if ( getSIMnumber(1) )
if ( getSIMnumber(1) )
// Handyinitialisierung ENDE
PORTB &= ~(1<<PB5);
// Nummererkenung Anzeigen
if ( strlen(clipnr) >= CLIPNR_MINLEN )
{
for ( i=0; i<30; i++ )
{
delay_ms(35);
PORTB ^= (1<<PB5);
delay_ms(35);
PORTB &= ~(1<<PB5);
}
}
}
int main(void)
{
uint8_t Tout = INCALL_TOUT;
// Einschaltmeldung, LED AN-AUS
DDRB |= (1 << DDB5);DDRD |= (1 << DDD3);
PORTB ^= (1<<PB5);PORTD ^= (1<<PD3);
delay_ms(1000);
PORTB &= ~(1<<PB5);PORTD &= ~(1<<PD3);
delay_ms(1000);
// Einschaltmeldung ENDE
DDRC &= ~(1 << DDC0) & ~(1 << DDC1) & ~(1 << DDC2) & ~(1 << DDC3) & ~(1 << DDC4) & ~(1 << DDC5); // PORTC Input (Switch)
PORTC |= (1 << DDC0) | (1 << DDC1) | (1 << DDC2) | (1 << DDC3) | (1 << DDC4) | (1 << DDC5); // PORTC Input with internal pull-up resistors activated
DDRD &= ~(1 << DDD2) & ~(1 << DDD3); // PORTD Input RxD GPS
DDRD |= (1 << DDD5) | (1 << DDD6) | (1 << DDD7); // PORTD as Output (Relays)
DDRB |= (1 << DDB5); // PORTB as Output (GPS LED)
#if defined ( __AVR_ATmega8__ )
// Externer Interrupt 1, Change Interrupt
MCUCR |= (1 << ISC10);
GICR |= (1 << INT1);
// Timer Compare A auf 1 Sekunde
TIMSK |= (1 << OCIE1A);
OCR1A = (uint16_t)(F_CPU/256);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS12);
#endif
#if defined ( __AVR_ATmega88__ )
// Externer Interrupt 1, Change Interrupt
EIMSK |= (1 << INT1);
EICRA |= ( 1<< ISC10 );
// Timer Compare A auf 1 Sekunde
TIMSK1 |= (1 << OCIE1A);
OCR1A = (uint16_t)(F_CPU/256);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS12);
#endif
sei();
InitHandy();
while(1)
{
// Einstellungen immer wieder einlesen
SW_OutputTyp = get_SW_OutputTyp();
SW_AlarmTyp = get_SW_AlarmTyp();
SW_exit3_time = getSW_BCDTime();
// Laueft nur wenn keine Anrufe kommen
if ( timer_KeepAlive > KEEPALIVE_TOUT )
{
// Telefonerkennung
uart_puts ("AT\r\n");
getGSMcmd( 1000,1);
// Telefon noch aktiv ???
if ( strstr(buffer, "OK") == 0 )
InitHandy();
timer_KeepAlive = 0;
}
// Moeglicherweise Anruf eingehend ???
if (buffcnt)
{
getGSMcmd( 1000, 1 );
if ( ( strstr(buffer, "+CLIP") != 0) || ( strstr(buffer, "RING") ) )
{
if ( !RingDetected() )
{
// Anruferkennung START
PORTB ^= (1<<PB5);
// Zaehlen und Auflegen
cnt_rings++;
delay_ms(3000);
uart_puts ("ATH\r\n");
getGSMcmd( 1000, TIMEOUT);
// Timer zuruecksetzten (Watchdogprinzip)
timer_rings = 0;
Tout = INCALL_TOUT;
// Anruferkennung ENDE
PORTB &= ~(1<<PB5);
}
}
}
// Kein Anruf
else
{
// GPS Daten abholen
if (timer_gps >= 60)
{
timer_gps = 0;
// i = getGPS(); Nicht unterstuetzt
}
// Alarm Behandlung
if (alarm)
{
// Nur ausfuehren wenn Nummer da und Alarm-Anruf nicht aktiv
if ( ( strlen(clipnr) >= CLIPNR_MINLEN ) && ( cnt_rings < 100 ) )
{
// Alarmierung durch Anruf
if ( SW_AlarmTyp == 1 )
{
uart_puts ("ATD +");
uart_puts ( clipnr );
uart_puts (";\r\n");
getGSMcmd( 10000, TIMEOUT);
cnt_rings += 100; // Merker zum Auflegen
timer_rings = 0; // Nachtriggern
Tout = OUTCALL_TOUT;
}
// Alarmierung durch SMS
else
{
sprintf (buffer, "** ALARM ** GSM Remote Switcher %s", gpscoord);
SMS_send (clipnr, buffer, SMSMODE);
}
}
alarm=0; // Alarm zuruecksetzen
} // Endif Alarm Behandlung
} // Endif kein Anruf
if (timer_rings >= Tout)
{
switch (cnt_rings)
{
case 1 :
if ( SW_OutputTyp == 1 )
{
exit1=2;
exit2=2;
exit3=2;
}
else
{
exit1=2;
}
break;
case 2 :
if ( SW_OutputTyp == 1 )
{
exit1=2;
exit2=2;
exit3=2;
}
else
{
exit2=2;
}
break;
case 3 :
if ( SW_OutputTyp == 1 )
{
exit1=2;
exit2=2;
exit3=2;
}
else
{
exit3=2;
}
break;
case 4 :
if ( strlen(clipnr) >= CLIPNR_MINLEN )
{
sprintf (buffer, "Status: OutTyp:%i AlarmTyp:%i Time:%imn Exit1:%i Exit2:%i Exit3:%i %s", SW_OutputTyp, SW_AlarmTyp, SW_exit3_time, (PORTD >> PD5) & 1, (PORTD >> PD6) & 1, (PORTD >> PD7) & 1, gpscoord);
SMS_send (clipnr, buffer, SMSMODE);
}
break;
default:
// Auflegen des Alarmanrufes
uart_puts ("ATH\r\n");
getGSMcmd( 1000, TIMEOUT);
break;
}
cnt_rings=0;
timer_rings=0;
} // End Switch
} // End While 1
// wird niemal erreicht
return 0;
}
|