📄 gsm_remote.c
字号:
/*
* 080324 - GSM Fernsteuerung
* 2008
* Elektor International Media B.V.
* (C) Florian Sch鋐fer, http://www.blafusel.de
* Compiler: WinAVR 20060421 with avr-gcc (GCC) 3.4.6
*/
#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>
#define UART_BAUD_CALC(UART_BAUD_RATE,F_CPU) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
#define SMSMODE 0
void delay_ms(uint16_t);
void uart_init (uint16_t);
uint8_t getSW_TelTyp (void);
uint8_t getSW_ExitTyp (void);
void 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);
void RingDetected (void);
void getGSMcmd (void);
uint8_t getSIMnumber (uint8_t);
void BaudrateGSM (void);
int main(void);
extern uint8_t rbuffcnt;
unsigned char buffer[170],
nachricht2[160],
clipnr[20],
gpscoord[55],
tmp[20],
tmp2[20];
volatile uint8_t timer_gps=60,
timer_rings=0,
timer_waitGSM=0,
cnt_rings=0,
gps_detect=0,
exit1=0,
exit2=0,
exit3=0,
exit3_time=0,
SW_TelTyp,
SW_ExitTyp,
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++;
if (exit1 == 2)
{
PORTD |= (1<<PD5);
exit1=1;
}
else if (exit1 == 1)
{
PORTD &= ~(1<<PD5);
exit1=0;
}
if (exit2 == 2)
{
if (SW_ExitTyp)
{
PORTD ^= (1<<PD6);
exit2=0;
}
else
{
PORTD |= (1<<PD6);
exit2=1;
}
}
else if (exit2 == 1)
{
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) (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;
}
void uart_init (uint16_t baud_rate)
{
UBRRH=(uint16_t)(UART_BAUD_CALC(baud_rate,F_CPU)>>8);
UBRRL=(uint16_t)UART_BAUD_CALC(baud_rate,F_CPU);
uart_ini();
}
uint8_t getSW_TelTyp (void)
{
if (PINC & (1 << PINC4))
return 0;
else
return 1;
}
uint8_t getSW_ExitTyp (void)
{
if (PINC & (1 << PINC5))
return 0;
else
return 1;
}
void 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 : exit3_time = 1; break;
case 1 : exit3_time = 5; break;
case 2 : exit3_time = 10; break;
case 3 : exit3_time = 15; break;
case 4 : exit3_time = 20; break;
case 5 : exit3_time = 30; break;
case 6 : exit3_time = 45; break;
case 7 : exit3_time = 60; break;
case 8 : exit3_time = 90; break;
case 9 : exit3_time = 120; break;
}
}
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;
char zeichen1 = 0,
zeichen2 = 0;
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 == 8)
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);
while(ser_getc()!=' ');
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);
}
sprintf(tmp2, "%c",0x1A);
uart_puts(tmp2);
while (ser_getc() != 10);
do
{
zeichen2 = ser_getc();
if ((zeichen2 == 'R') && (zeichen1 == 'E'))
{
erg = 1; // Mistake
}
if ((zeichen2 == 'G') && (zeichen1 == 'M'))
{
erg = 0; // OK
while (ser_getc() != 10);
while (ser_getc() != 10);
}
zeichen1 = zeichen2;
}
while (zeichen1 != 10);
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;
timer_gps = 0;
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 == 10)
{
gps_dect=1;
}
}
}
timer_gps=0;
if (gps_dect)
return 0;
else
{
PORTB &= ~(1<<PB5);
gps_detect=0;
sprintf (gpscoord, "* NO GPS"); return 1;
}
}
void RingDetected (void)
{
uint8_t u=0;
if (SW_TelTyp)
{
getTeilstring (tmp, buffer, 2, '+', ',');
if (tmp[0] != '\0')
{
u=strlen(tmp);
if (tmp[u-1] == '"')
{
tmp[u-1] = '\0';
}
u=1;
while (!getSIMnumber(u))
{
u++;
if (strcmp (tmp, clipnr) == 0)
{
cnt_rings++;
break;
}
}
}
}
else
{
cnt_rings++;
}
}
void getGSMcmd (void)
{
uint8_t i=0;
timer_waitGSM=0;
while (1)
{
if (rbuffcnt)
{
buffer[i] = ser_getc();
if (buffer[i] == 10)
{
buffer[i] = '\0';
if ((SW_TelTyp && strncmp(buffer, "+CLIP", 5) == 0) || (!SW_TelTyp && strncmp(buffer, "RING", 4) == 0))
{
RingDetected();
}
break;
}
i++;
}
if (timer_waitGSM >= 5)
break;
}
}
uint8_t getSIMnumber (uint8_t index)
{
uint8_t i,u=0;
for (i=1; i<=2; i++)
{
uart_puts ("AT+CPBR=");
uart_putc (index + 0x30);
uart_puts ("\r");
getGSMcmd();getGSMcmd();
if (buffer[0] == '+')
{
getTeilstring (clipnr, buffer, 2, '+', ',');
u=strlen(clipnr);
if (clipnr[u-1] == '"')
{
u--;
clipnr[u]='\0';
}
getGSMcmd();
getGSMcmd();
if (u>0)
u=0;
else
u=1;
}
else
u=1;
}
return u;
}
void BaudrateGSM (void)
{
uint16_t baudrate=9600;
uint8_t i=0;
timer_waitGSM=0;
uart_init(baudrate);
uart_puts ("AT\r");
while (1)
{
if (rbuffcnt)
{
buffer[i] = ser_getc();
if (buffer[i] == 10)
{
buffer[i+1]='\0';
buffer[i+2]='\0';
}
if ((i >= 2) && (buffer[i-1] == 'O') && (buffer[i] == 'K'))
break;
i++;
}
if (timer_waitGSM >= 5)
{
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;
}
i=0;
timer_waitGSM=0;
uart_init(baudrate);
uart_puts ("AT\r\n");
}
}
getGSMcmd();
for (i=0; i<=70; i++)
{
PORTB ^= (1<<PB5);
delay_ms(35);
}
PORTB &= ~(1<<PB5);
}
int main(void)
{
uint8_t i;
uart_ini();
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); // PORTD Input RxD GPS
DDRD |= (1 << DDD5) | (1 << DDD6) | (1 << DDD7); // PORTD as Output (Relays)
DDRB |= (1 << DDB5); // PORTB as Output (GPS LED)
MCUCR |= (1 << ISC10);
GICR |= (1 << INT1);
TIMSK |= (1 << OCIE1A);
OCR1A = (uint16_t)(F_CPU/256);
sei();
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS12);
SW_TelTyp = getSW_TelTyp();
SW_ExitTyp = getSW_ExitTyp();
getSW_BCDTime();
BaudrateGSM();
uart_puts ("ATE0\r");
getGSMcmd();getGSMcmd();
uart_puts ("AT+CLIP=1\r");
getGSMcmd();getGSMcmd();
uart_puts ("AT+CPBS=\"SM\"\r");
getGSMcmd();getGSMcmd();
while(1)
{
if (rbuffcnt)
{
getGSMcmd();
}
else
{
if (timer_gps >= 60)
i = getGPS();
if (alarm)
{
i = getSIMnumber (1);
if (!i)
{
sprintf (buffer, "** ALARM ** GSM Remote Switcher %s", gpscoord);
do
{
i = SMS_send (clipnr, buffer, SMSMODE);
} while (i);
alarm=0;
}
}
}
if (timer_rings >= 90)
{
if (!SW_TelTyp)
cnt_rings--;
switch (cnt_rings)
{
case 1 : exit1=2;
break;
case 2 : exit2=2;
break;
case 3 : exit3=2;
break;
case 4 : i=0;
if (!SW_TelTyp)
{
i = getSIMnumber (1);
}
if (!i)
{
sprintf (buffer, "Status: TelTyp:%i Exit2Typ:%i Time:%imn Exit1:%i Exit2:%i Exit3:%i %s", SW_TelTyp, SW_ExitTyp, exit3_time, (PORTD >> PD5) & 1, (PORTD >> PD6) & 1, (PORTD >> PD7) & 1, gpscoord);
do
{
i = SMS_send (clipnr, buffer, SMSMODE);
} while (i);
}
break;
default: break;
}
cnt_rings=0;
timer_rings=0;
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -