UNO+EFcom V1.2
- Войдите на сайт для отправки комментариев
Пт, 16/08/2013 - 23:13
нужен скетч наподобие как на народном мониторе для передачи данных о температуре на сайт народного монитора.
Готов заплатить некую сумму.
нужен скетч наподобие как на народном мониторе для передачи данных о температуре на сайт народного монитора.
Готов заплатить некую сумму.
а что такое народный монитор?
Посмотрите http://jt5.ru/examples/gprs-narodmon/
там скетч под другой шилд мой не запускается
Видимо нет спецов которые смогли бы адаптировать имеющийся скетч. грустно.
Спецов - навалом, из Вас просто рыбак не очень ;)
Видимо нет спецов которые смогли бы адаптировать имеющийся скетч. грустно.
скока денег дадите?
дадите?
Дают в суде, за работу платят :)
MDV другие примеры работают с этим шилдом?
шилд рабочий.
температуру показывает.
при помощи АТ команд звонит, при звонке на него так же реагирует.
возможно необходимо поменять пину порта но ненашел где. у моего шилда порт на 2 и 3 пине:
puhlyaviy на какую сумму расчитываете, если конечно это вам по зубам.
puhlyaviy на какую сумму расчитываете, если конечно это вам по зубам.
сделать косметические изменения в готовом скече? гыыы на 1 бакс :)
можете постучать мне в скайп alexeyca4, я щас на пляж, часика через 2 вернусь и усе сделаем как в лучших домах лондона и парижу :)
Когда заоаботает 10 баксов ваши.
Готов скинуть два скетча с этого проекта но для других GSM шилдов и библиотеку от своего.
Шура, стучите в скайп. все решим.
В какое время лучше чтучаться?
Puhlyavyi есть еще вот такой скетч
#include <avr/pgmspace.h>
#include <GPRS.h>
#include <GSM.h>
#include <stuff.h>
#include <Narodmon.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10 // Номер линии, к которой подключены датчики температуры
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor_1, sensor_2, sensor_3, sensor_4; // Используем 4 температурных датчика
//ПИН-код! Поменяйте на свой!!! Иначе СИМ карта заблокируется!
const char PIN[] PROGMEM = "0000";
//Настройки для доступа к GPRS
const char ISP_IP[] PROGMEM = "home.beeline.ru";
const char LOGIN[] PROGMEM = "beeline";
//Буфер для считывания IMEI
char IMEI[16];
unsigned int minutes = 0;
//Интервал отправки данных в минутах
unsigned char SendIntervalInMinutes = 5;
//Флаг для активации отправки
unsigned char GSM_TASK_flag;
volatile unsigned char WDT_wake;
volatile unsigned char SleepTimeInSec = 60;
//volatile unsigned char WDT_counter; // увеличим счетчик прерываний
unsigned char RHMacn[8] = {0x00, 'S', 'H', 'T', '1', '1', '_', '0'};
/*
Обработчик прерываний по срабатыванию охранного таймера
*/
ISR(WDT_vect) {
static unsigned char WDT_counter; // увеличим счетчик прерываний
if (WDT_counter++ == SleepTimeInSec)
{ //отсчет минут
WDT_counter = 0;
if (minutes++ == SendIntervalInMinutes)
{
minutes = 0;
GSM_TASK_flag = 1; // Надо выполнить задачу по отправке данных на сервер
}
}
//Serial.print(WDT_counter, HEX);
asm ("WDR");
}
void setup_WDT(void)
{
asm ("CLI");
asm ("WDR");
// WDT_counter = 0;
MCUSR &= ~(1<<WDRF); //Сброс флага срабатывания
WDTCSR = (1 << WDCE)|(1<<WDE);
WDTCSR = (1 << WDP2)|(1 << WDP1)|(1 << WDIE)|(1 << WDIF); // Настройка сторожевого таймера на период 1 сек. Перевод в режим работы генерирования прерываний
asm ("SEI");
}
void off_WDT(void)
{
asm ("CLI");
asm ("WDR");
// WDT_counter = 0;
MCUSR &= ~(1<<WDRF); //Сброс флага срабатывания
WDTCSR = (1 << WDCE)|(1<<WDE)|(1 << WDIF);
/* Turn off WDT */
WDTCSR = 0x00;
asm ("SEI");
}
void sys_sleep(void)
{
asm ("CLI");
// asm ("WDR");
ADCSRA &= ~(1 << ADEN); // Выключим АЦП
SMCR = (1<<SE)|(1<<SM1); // Конфигурируем режим power-down
//MCUCR |= (1<<BODSE) | (1<<BODS); // Отключаем BOD на время сна
asm ("SEI");
asm ("SLEEP");
}
void sys_wake(void)
{
SMCR = 0x00; // Конфигурируем режим power-down
// тут можно включить АЦП
}
void setup()
{
delay(1000);
sensors.begin();
// Поиск 1-wire датчиков
sensors.getAddress(sensor_1, 0);
sensors.getAddress(sensor_2, 1);
sensors.getAddress(sensor_3, 2);
sensors.getAddress(sensor_4, 3);
// установка разрядности датчиков
sensors.setResolution(sensor_1, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_2, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_3, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_4, TEMPERATURE_PRECISION);
// опрос всех датчиков на шине
sensors.requestTemperatures();
GSM_TASK_flag = 1;
}
void loop()
{
if (GSM_TASK_flag) // В обработчике Watchdog таймер установился флаг GSM-задания
{
GSM_TASK_flag = 0;
// Отключаем сторожевой таймер
off_WDT();
// инициализация GSM модема
while (GSM.Init(PIN)<0);
// Пoлучаем IMEI
while (GSM.GetIMEI (IMEI) < 0);
// Конверитруем в MAC
Narodmon.SetDeviceMACbyIMEI(IMEI);
// считываем температуры, заносим в массив
unsigned char SensorsNum = 0; // Для подсчета работающих датчиков
signed int SensorData;
if (ReadSensor (sensor_1, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_1);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
if (ReadSensor (sensor_2, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_2);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
if (ReadSensor (sensor_3, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_3);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
/*
if (ReadSensor (sensor_4, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_4);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
*/
if (ReadSensorRH (&SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, RHMacn);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
u8 TxCounter = 0;
// попытка отправить данные
if (SensorsNum)
{
Narodmon.SetNumSensors(SensorsNum);
// Инициализация GPRS
u8 Success = 0;
do
{
if (GSM.InitGPRS(ISP_IP, LOGIN, LOGIN) > 0)
{
// Успешно инициализировали GPRS
// Открываем сокет 1
if (GSM.SocketOpen(1 , TCP, PSTR("map.net13.info"), 8283, 0) > 0)
{
// Сокет 1 открылся
//Пишем в сокет данные
Narodmon.TelnetSend(GSM.Write);
// Закрываем сокет 1
if (GSM.SocketClose(1) > 0) Success = 1;
else Success = 0;
} else Success = 0;
} else Success = 0;
if (!Success) delay (5000);
if (TxCounter++ == 4)
{
TxCounter =0;
// переинициализируем модуль
GSM_TASK_flag = 1;
return;
}
} while (!Success);
}
//Усыпляем GSM-модуль
while (GSM.PowerOFF() < 0);
// Включаем сторожевой таймер
setup_WDT();
}
// Усыпляем Атмегу
sys_sleep();
}
signed char ReadSensor (DeviceAddress sensor_addr, signed int* pData)
{
sensors.requestTemperaturesByAddress(sensor_addr);
float tempS = sensors.getTempC(sensor_addr);
if (tempS != DEVICE_DISCONNECTED)
{
signed int tempS10 = (signed int) (tempS * 10.0);
*pData = tempS10;
return 1;
}
return 0;
}
signed char ReadSensorRH (signed int* pData)
{
// Тут считываем с датчика влажности
float RH = 64.5;
if (RH >= 0) // Если датчик на линии
{
signed int RH10 = (signed int) (RH * 10.0);
*pData = RH10;
return 1;
}
return 0;
}
под него другие библиотеки #include <avr/pgmspace.h>
#include <util/delay.h>
#include "GSM.h"
#include "GPRS.h"
#include "stuff.h"
//activation of context
s8 GSMClass::InitGPRS(const char* ISP_IP, const char* LOGIN, const char* PWD)
{
GSM.WriteStr_P(PSTR("\r\nAT+CGDCONT=1,\"IP\",\""));
GSM.WriteStr_P(ISP_IP);
if (SendCmdWaitResp(PSTR("\""), OK, pause256 * 10) > 0 )
{
GSM.WriteStr_P(PSTR("\r\nAT#SGACT=1,1,'"));
GSM.WriteStr_P(LOGIN);
GSM.WriteStr_P(PSTR("','"));
GSM.WriteStr_P(PWD);
if (SendCmdWaitResp(PSTR("'\r\n"), OK, pause256 * 4) < 0) return -1;
}
else return -2;
return 1;
}
//open socket
s8 GSMClass::SocketOpen(u8 connId, u8 txProt, const char* SERVER_IP, u16 SERVER_PORT, u16 lPort)
{
char* pi2a;
GSM.WriteStr_P(PSTR("\r\nAT#SD="));
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(","));
// печатаем тип сокета 1 - UDP/ 0 - TCP
i2a(txProt, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(","));
// печатаем порт
i2a(SERVER_PORT, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(",\""));
// IP или Domain Name
GSM.WriteStr_P(SERVER_IP);
GSM.WriteStr_P(PSTR("\",255,")); // Сокет закроется автоматически после +++
// печатаем порт входящих соединений UDP
i2a(lPort, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(",0"));
if (SendCmdWaitResp(PSTR(""), PSTR("CONNECT"), pause256 * 4) < 0) return -1; // Сокет не открылся!
return 1; // Сокет открыт
}
//WriteSocket
s8 GSMClass::ActiveSocketWriteCb (void (*CALLBACK_FUNC)(unsigned char(*SocketWr)(unsigned char)))
{
(CALLBACK_FUNC)(&GSM.Write);
};
s8 GSMClass::ActiveSocketWriteStr (char* Str)
{
GSM.WriteStr(Str);
};
s8 GSMClass::ActiveSocketWriteStr_P (const char* Str)
{
GSM.WriteStr_P(Str);
};
s8 GSMClass::ActiveSocketSuspend ()
{
_delay_ms(1000);
GSM.WriteStr_P(PSTR("+++"));//Разрываем соединение
if (WaitResp(OK, pause256) < 0) return -1;
//_delay_ms(1000);
return 1;
};
s8 GSMClass::SocketClose (u8 connId)
{
ActiveSocketSuspend ();
GSM.WriteStr_P(PSTR("AT#SH="));//Разрываем соединение
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
char* pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
if (SendCmdWaitResp(PSTR(""), OK, pause256 * 2) < 0) return -1; // Сокет не закрылся!
return 1;
};
s8 GSMClass::SocketResume (u8 connId)
{
GSM.WriteStr_P(PSTR("AT#SO="));//Возобновляем соединение
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
char* pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
if (SendCmdWaitResp(PSTR(""), PSTR("CONNECT"), pause256 * 4) < 0) return -1; // Сокет не открылся!
};
s8 ActiveSocketReadStr (char* Str)
{
//*Str++ = getchar ();
};
/*
* Библиотека низкоуровневых функций для работы с платой CosmoGSM
* CosmoGSM.cpp
*
* Created: 28.02.2013 11:16:15
* Author: a-erezeev
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "GSM.h"
#include <string.h>
#define PD7 (7)
#define PD6 (6)
#define PD5 (5)
#define PB0 (0)
#define PB1 (1)
#ifdef _AVR_IOM328P_H_ || _AVR_IOM328_H_
#define RXCIEn RXCIE0
#define RXCn RXC0
#define RXENn RXEN0
#define TXENn TXEN0
#define UBRRnH UBRR0H
#define UBRRnL UBRR0L
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#define USARTn_RX_vect USART_RX_vect
#elif _AVR_IOM2560_H_
#ifdef GSM_USART0
#define USARTn_RX_vect USART0_RX_vect
#define RXCIEn RXCIE0
#define RXCn RXC0
#define RXENn RXEN0
#define TXENn TXEN0
#define UBRRnH UBRR0H
#define UBRRnL UBRR0L
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#elif GSM_USART1
#define USARTn_RX_vect USART1_RX_vect
#define RXCIEn RXCIE1
#define RXCn RXC1
#define RXENn RXEN1
#define TXENn TXEN1
#define UBRRnH UBRR1H
#define UBRRnL UBRR1L
#define UCSRnA UCSR1A
#define UCSRnB UCSR1B
#define UCSRnC UCSR1C
#define UDRn UDR1
#elif GSM_USART2
#define USARTn_RX_vect USART2_RX_vect
#define RXCIEn RXCIE2
#define RXCn RXC2
#define RXENn RXEN2
#define TXENn TXEN2
#define UBRRnH UBRR2H
#define UBRRnL UBRR2L
#define UCSRnA UCSR2A
#define UCSRnB UCSR2B
#define UCSRnC UCSR2C
#define UDRn UDR2
#elif GSM_USART3
#define USARTn_RX_vect USART3_RX_vect
#define RXCIEn RXCIE3
#define RXCn RXC3
#define RXENn RXEN3
#define TXENn TXEN3
#define UBRRnH UBRR3H
#define UBRRnL UBRR3L
#define UCSRnA UCSR3A
#define UCSRnB UCSR3B
#define UCSRnC UCSR3C
#define UDRn UDR3
#else #error Invalid USART port number!
#endif
//USART1_RX_vect
//USART2_RX_vect
//USART3_RX_vect
#else #error Unsupported target MCU!!!
#endif
//! Индекс поиска
static u8 rx_i;
//! Индекс записи в буфер приёма
static u8 rx_wr_i;
//! Флаги переполнения и подтверждения
volatile u8 rx_overflow, rx_ack;
const char * searchFor; // Указатель на шаблон поиска
static u8 rx_i_CMTI;
volatile u8 NewSMS_index, NewSMS_index_;
static unsigned char searchStr;
const char * searchCMTI;
static u8 putchar(unsigned char send_char)
{
while (!(UCSRnA & 0x20));
UDRn = (unsigned char) send_char;
_delay_us(500); //Пауза для нормальной работы модема
return(send_char);
}
static u8 getchar( void )
{
/* Wait for data to be received */
while ( !(UCSRnA & (1<<RXCn)) )
;
/* Get and return received data from buffer */
return UDRn;
}
u8 GSMClass::Write(unsigned char Byte)
{
return putchar(Byte);
}
void UART0_rx_reset( void )
{
UCSRnB &= ~(1<<RXCIEn);
rx_i = rx_wr_i = 0;
rx_ack = 0;
rx_buffer[ rx_wr_i ] = '\0';
}
void UART0_rx_on( void )
{
UCSRnB |= ( 1 << RXCIEn );
}
void UART0_rx_off( void )
{
UCSRnB &= ~( 1 << RXCIEn );
}
//Установка шаблона для поиска
//pSTR - адрес шаблона в ПЗУ
void UART0_setSearchString( const char * pPattern_P )
{
UCSRnB &= ~( 1 << RXCIEn );
searchFor = pPattern_P; //Что требуется найти в буфере ответа
rx_i = 0;
}
/************************************************************************/
/* Обработчик прерываний по приему нового символа по UART
/* Выполняет сравнение с шаблоном из FLASH "на лету" */
/************************************************************************/
ISR(USARTn_RX_vect)
{
char data;
data = UDRn;
if (!data) return;
rx_buffer[ rx_wr_i++ ] = data; //Положили новый символ в буфер
if( rx_wr_i > RX_BUFFER_MASK ) //Если буфер переполнен, продолжим сначала с перезатиранием
{
rx_wr_i = 0;
}
if( data == pgm_read_byte(&searchFor[rx_i]) ) //Если пришедший символ совпал с символом шаблона
{
rx_i++; //Следующий символ шаблона
if( !pgm_read_byte(&searchFor[rx_i]) ) // Если дошли до конца шаблона - выключим приём
{
rx_i = 0;
{
rx_buffer[ rx_wr_i] = 0x00;
rx_ack = 1; // поднимем флаг - пришел ответ
UCSRnB &= ~( 1 << RXCIEn );
}
}
}
else
{
rx_i = 0;
}
}
void GSMClass::begin()
{
sei();
}
void GSMClass::WriteStr(char* s)
{
while (*s) putchar(*s++);
}
void GSMClass::WriteStr_P(const char* s)
{
while (pgm_read_byte(s))
putchar(pgm_read_byte(s++));
}
void UART0_init(void)
{
UCSRnB = 0x00;
UCSRnA = 0x00;
UCSRnC = 0x06;
UBRRnL = 25; //38400 low speed ( @ 16 MHz)
UBRRnH = 0x00;
UCSRnB = ( 1 << TXENn )|( 1 << RXENn );
UART0_rx_reset();
}
// Проверка ответа от модема
s8 UART0_check_acknowledge( u16 pause )
{
//! Local variables
static u16 i, ii;
for( i = 0; ( rx_ack == 0 ) && ( i < 65535 ); i++ ) //Цикл ожидания
{
for( ii = 0; ii < pause; ii++ )
{
asm("nop"); // Тратим энергию в пустую
}
}
if( rx_ack > 0 )
{
rx_ack = 0;
return 1;
}
else
{
UART0_rx_off( );
UART0_rx_reset( );
return -1;
}
}
void GSMClass::end()
{
}
s8 GSMClass::SendCmdWaitResp(const char* pCommand_P, const char* pSearchPattern_P, u16 pause)
{
UART0_rx_reset( );
UART0_setSearchString(pSearchPattern_P);
//_delay_ms(500);
GSM.WriteStr_P(pCommand_P);
GSM.WriteStr_P(PSTR("\r\n"));
UART0_rx_on( );
if( UART0_check_acknowledge( pause ) > 0 )
{
return 1;
}
else return -1;
}
s8 GSMClass::WaitResp(const char* pSearchPattern_P, u16 pause)
{
UART0_rx_reset( );
UART0_setSearchString(pSearchPattern_P);
UART0_rx_on( );
if( UART0_check_acknowledge( pause ) > 0 )
{
return 1;
}
else return -1;
}
s8 GSMClass::Init(const char* PIN)
{
DDRD |= (1<<PD5);
PORTD |= (1<<PD5);
_delay_ms(300);
PORTD &= ~(1<<PD5);
_delay_ms(5000);
UART0_init();
GSM.WriteStr_P(PSTR("AT\r\n"));
// _delay_ms(100);
GSM.WriteStr_P(PSTR("ATE0\r\n"));
_delay_ms(500);
GSM.WriteStr_P(PSTR("AT+IFC= 0,0\r\n"));
// _delay_ms(500);
// searchFor = (const char*)pgm_read_word(&searchStrings[1]);
// GSM.WriteStr_P(searchFor);
sei();
while (SendCmdWaitResp(PSTR("AT"),OK, pause64) < 0);
if (SendCmdWaitResp(PSTR("AT+CPIN?"),PSTR("+CPIN: "), pause256))
{
//Пришел ответ "+CPIN:"
if (WaitResp(OK, pause64))
{
// Пришел OK
if (strstr_P((char*)rx_buffer, PSTR("SIM PIN")))
{
// Вводим PIN код
GSM.WriteStr_P(PSTR("AT+CPIN=\""));
GSM.WriteStr_P(PIN);
if ( SendCmdWaitResp(PSTR("\""),OK, pause256) < 0) return -3; // PIN код не верен
}
else if (!strstr_P((char*)rx_buffer, PSTR("READY")))
{
return -3;
}
}
else return -3;
}else return -2;
//
/*
Ждем регистрации в сети
*/
u8 Attempts=0;
while (CheckStatus() < 0)
{
if (Attempts++ > 16)
{
return -1;
}
}
/*
Инициализируем текстовый режим СМС
*/
if (SendCmdWaitResp(PSTR("AT+CMGF=1"), OK, pause256) < 0) return -2;
return 1;
}
s8 GSMClass::CheckStatus(void)
{
// GSM.WriteStr_P(PSTR("AT\r\n"));
_delay_ms(500);
if (SendCmdWaitResp(PSTR("AT+CGATT?"), PSTR("+CGATT: 1"), pause64) > 0 )
{
//Пришел ответ "+CGATT: 1", ждем теперь "OK"
if (WaitResp(OK, pause256) < 0) return -1;
}
else return -1;
return 1;
}
s8 GSMClass::GetIMEI (char* IMEIbuf)
{
if (SendCmdWaitResp(PSTR("AT+CGSN"), OK, pause64) > 0 )
{
char* pSrc = (char*)rx_buffer;
u8 n = 0; u8 k = 0;
while ((n < 15) && (k < 64))
{
if ((*pSrc >= '0') && (*pSrc <= '9')) {*IMEIbuf++ = *pSrc; n++;}
else if (*pSrc == 'O') break;
*pSrc++; k++;
}
if (n == 15) {*pSrc =0x00; return 1;}
else return -2;
} else return -1;
}
s8 GSMClass::PowerOFF()
{
if (SendCmdWaitResp(PSTR("AT#SHDN"), OK, pause256) > 0 )
{
return 1;
}
else return -1;
}
Puhlyavyi есть еще вот такой скетч
#include <avr/pgmspace.h>
#include <GPRS.h>
#include <GSM.h>
#include <stuff.h>
#include <Narodmon.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10 // Номер линии, к которой подключены датчики температуры
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor_1, sensor_2, sensor_3, sensor_4; // Используем 4 температурных датчика
//ПИН-код! Поменяйте на свой!!! Иначе СИМ карта заблокируется!
const char PIN[] PROGMEM = "0000";
//Настройки для доступа к GPRS
const char ISP_IP[] PROGMEM = "home.beeline.ru";
const char LOGIN[] PROGMEM = "beeline";
//Буфер для считывания IMEI
char IMEI[16];
unsigned int minutes = 0;
//Интервал отправки данных в минутах
unsigned char SendIntervalInMinutes = 5;
//Флаг для активации отправки
unsigned char GSM_TASK_flag;
volatile unsigned char WDT_wake;
volatile unsigned char SleepTimeInSec = 60;
//volatile unsigned char WDT_counter; // увеличим счетчик прерываний
unsigned char RHMacn[8] = {0x00, 'S', 'H', 'T', '1', '1', '_', '0'};
/*
Обработчик прерываний по срабатыванию охранного таймера
*/
ISR(WDT_vect) {
static unsigned char WDT_counter; // увеличим счетчик прерываний
if (WDT_counter++ == SleepTimeInSec)
{ //отсчет минут
WDT_counter = 0;
if (minutes++ == SendIntervalInMinutes)
{
minutes = 0;
GSM_TASK_flag = 1; // Надо выполнить задачу по отправке данных на сервер
}
}
//Serial.print(WDT_counter, HEX);
asm ("WDR");
}
void setup_WDT(void)
{
asm ("CLI");
asm ("WDR");
// WDT_counter = 0;
MCUSR &= ~(1<<WDRF); //Сброс флага срабатывания
WDTCSR = (1 << WDCE)|(1<<WDE);
WDTCSR = (1 << WDP2)|(1 << WDP1)|(1 << WDIE)|(1 << WDIF); // Настройка сторожевого таймера на период 1 сек. Перевод в режим работы генерирования прерываний
asm ("SEI");
}
void off_WDT(void)
{
asm ("CLI");
asm ("WDR");
// WDT_counter = 0;
MCUSR &= ~(1<<WDRF); //Сброс флага срабатывания
WDTCSR = (1 << WDCE)|(1<<WDE)|(1 << WDIF);
/* Turn off WDT */
WDTCSR = 0x00;
asm ("SEI");
}
void sys_sleep(void)
{
asm ("CLI");
// asm ("WDR");
ADCSRA &= ~(1 << ADEN); // Выключим АЦП
SMCR = (1<<SE)|(1<<SM1); // Конфигурируем режим power-down
//MCUCR |= (1<<BODSE) | (1<<BODS); // Отключаем BOD на время сна
asm ("SEI");
asm ("SLEEP");
}
void sys_wake(void)
{
SMCR = 0x00; // Конфигурируем режим power-down
// тут можно включить АЦП
}
void setup()
{
delay(1000);
sensors.begin();
// Поиск 1-wire датчиков
sensors.getAddress(sensor_1, 0);
sensors.getAddress(sensor_2, 1);
sensors.getAddress(sensor_3, 2);
sensors.getAddress(sensor_4, 3);
// установка разрядности датчиков
sensors.setResolution(sensor_1, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_2, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_3, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_4, TEMPERATURE_PRECISION);
// опрос всех датчиков на шине
sensors.requestTemperatures();
GSM_TASK_flag = 1;
}
void loop()
{
if (GSM_TASK_flag) // В обработчике Watchdog таймер установился флаг GSM-задания
{
GSM_TASK_flag = 0;
// Отключаем сторожевой таймер
off_WDT();
// инициализация GSM модема
while (GSM.Init(PIN)<0);
// Пoлучаем IMEI
while (GSM.GetIMEI (IMEI) < 0);
// Конверитруем в MAC
Narodmon.SetDeviceMACbyIMEI(IMEI);
// считываем температуры, заносим в массив
unsigned char SensorsNum = 0; // Для подсчета работающих датчиков
signed int SensorData;
if (ReadSensor (sensor_1, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_1);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
if (ReadSensor (sensor_2, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_2);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
if (ReadSensor (sensor_3, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_3);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
/*
if (ReadSensor (sensor_4, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_4);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
*/
if (ReadSensorRH (&SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, RHMacn);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
u8 TxCounter = 0;
// попытка отправить данные
if (SensorsNum)
{
Narodmon.SetNumSensors(SensorsNum);
// Инициализация GPRS
u8 Success = 0;
do
{
if (GSM.InitGPRS(ISP_IP, LOGIN, LOGIN) > 0)
{
// Успешно инициализировали GPRS
// Открываем сокет 1
if (GSM.SocketOpen(1 , TCP, PSTR("map.net13.info"), 8283, 0) > 0)
{
// Сокет 1 открылся
//Пишем в сокет данные
Narodmon.TelnetSend(GSM.Write);
// Закрываем сокет 1
if (GSM.SocketClose(1) > 0) Success = 1;
else Success = 0;
} else Success = 0;
} else Success = 0;
if (!Success) delay (5000);
if (TxCounter++ == 4)
{
TxCounter =0;
// переинициализируем модуль
GSM_TASK_flag = 1;
return;
}
} while (!Success);
}
//Усыпляем GSM-модуль
while (GSM.PowerOFF() < 0);
// Включаем сторожевой таймер
setup_WDT();
}
// Усыпляем Атмегу
sys_sleep();
}
signed char ReadSensor (DeviceAddress sensor_addr, signed int* pData)
{
sensors.requestTemperaturesByAddress(sensor_addr);
float tempS = sensors.getTempC(sensor_addr);
if (tempS != DEVICE_DISCONNECTED)
{
signed int tempS10 = (signed int) (tempS * 10.0);
*pData = tempS10;
return 1;
}
return 0;
}
signed char ReadSensorRH (signed int* pData)
{
// Тут считываем с датчика влажности
float RH = 64.5;
if (RH >= 0) // Если датчик на линии
{
signed int RH10 = (signed int) (RH * 10.0);
*pData = RH10;
return 1;
}
return 0;
}
под него другие библиотеки #include <avr/pgmspace.h>
#include <util/delay.h>
#include "GSM.h"
#include "GPRS.h"
#include "stuff.h"
//activation of context
s8 GSMClass::InitGPRS(const char* ISP_IP, const char* LOGIN, const char* PWD)
{
GSM.WriteStr_P(PSTR("\r\nAT+CGDCONT=1,\"IP\",\""));
GSM.WriteStr_P(ISP_IP);
if (SendCmdWaitResp(PSTR("\""), OK, pause256 * 10) > 0 )
{
GSM.WriteStr_P(PSTR("\r\nAT#SGACT=1,1,'"));
GSM.WriteStr_P(LOGIN);
GSM.WriteStr_P(PSTR("','"));
GSM.WriteStr_P(PWD);
if (SendCmdWaitResp(PSTR("'\r\n"), OK, pause256 * 4) < 0) return -1;
}
else return -2;
return 1;
}
//open socket
s8 GSMClass::SocketOpen(u8 connId, u8 txProt, const char* SERVER_IP, u16 SERVER_PORT, u16 lPort)
{
char* pi2a;
GSM.WriteStr_P(PSTR("\r\nAT#SD="));
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(","));
// печатаем тип сокета 1 - UDP/ 0 - TCP
i2a(txProt, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(","));
// печатаем порт
i2a(SERVER_PORT, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(",\""));
// IP или Domain Name
GSM.WriteStr_P(SERVER_IP);
GSM.WriteStr_P(PSTR("\",255,")); // Сокет закроется автоматически после +++
// печатаем порт входящих соединений UDP
i2a(lPort, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(",0"));
if (SendCmdWaitResp(PSTR(""), PSTR("CONNECT"), pause256 * 4) < 0) return -1; // Сокет не открылся!
return 1; // Сокет открыт
}
//WriteSocket
s8 GSMClass::ActiveSocketWriteCb (void (*CALLBACK_FUNC)(unsigned char(*SocketWr)(unsigned char)))
{
(CALLBACK_FUNC)(&GSM.Write);
};
s8 GSMClass::ActiveSocketWriteStr (char* Str)
{
GSM.WriteStr(Str);
};
s8 GSMClass::ActiveSocketWriteStr_P (const char* Str)
{
GSM.WriteStr_P(Str);
};
s8 GSMClass::ActiveSocketSuspend ()
{
_delay_ms(1000);
GSM.WriteStr_P(PSTR("+++"));//Разрываем соединение
if (WaitResp(OK, pause256) < 0) return -1;
//_delay_ms(1000);
return 1;
};
s8 GSMClass::SocketClose (u8 connId)
{
ActiveSocketSuspend ();
GSM.WriteStr_P(PSTR("AT#SH="));//Разрываем соединение
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
char* pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
if (SendCmdWaitResp(PSTR(""), OK, pause256 * 2) < 0) return -1; // Сокет не закрылся!
return 1;
};
s8 GSMClass::SocketResume (u8 connId)
{
GSM.WriteStr_P(PSTR("AT#SO="));//Возобновляем соединение
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
char* pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
if (SendCmdWaitResp(PSTR(""), PSTR("CONNECT"), pause256 * 4) < 0) return -1; // Сокет не открылся!
};
s8 ActiveSocketReadStr (char* Str)
{
//*Str++ = getchar ();
};
/*
* Библиотека низкоуровневых функций для работы с платой CosmoGSM
* CosmoGSM.cpp
*
* Created: 28.02.2013 11:16:15
* Author: a-erezeev
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "GSM.h"
#include <string.h>
#define PD7 (7)
#define PD6 (6)
#define PD5 (5)
#define PB0 (0)
#define PB1 (1)
#ifdef _AVR_IOM328P_H_ || _AVR_IOM328_H_
#define RXCIEn RXCIE0
#define RXCn RXC0
#define RXENn RXEN0
#define TXENn TXEN0
#define UBRRnH UBRR0H
#define UBRRnL UBRR0L
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#define USARTn_RX_vect USART_RX_vect
#elif _AVR_IOM2560_H_
#ifdef GSM_USART0
#define USARTn_RX_vect USART0_RX_vect
#define RXCIEn RXCIE0
#define RXCn RXC0
#define RXENn RXEN0
#define TXENn TXEN0
#define UBRRnH UBRR0H
#define UBRRnL UBRR0L
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#elif GSM_USART1
#define USARTn_RX_vect USART1_RX_vect
#define RXCIEn RXCIE1
#define RXCn RXC1
#define RXENn RXEN1
#define TXENn TXEN1
#define UBRRnH UBRR1H
#define UBRRnL UBRR1L
#define UCSRnA UCSR1A
#define UCSRnB UCSR1B
#define UCSRnC UCSR1C
#define UDRn UDR1
#elif GSM_USART2
#define USARTn_RX_vect USART2_RX_vect
#define RXCIEn RXCIE2
#define RXCn RXC2
#define RXENn RXEN2
#define TXENn TXEN2
#define UBRRnH UBRR2H
#define UBRRnL UBRR2L
#define UCSRnA UCSR2A
#define UCSRnB UCSR2B
#define UCSRnC UCSR2C
#define UDRn UDR2
#elif GSM_USART3
#define USARTn_RX_vect USART3_RX_vect
#define RXCIEn RXCIE3
#define RXCn RXC3
#define RXENn RXEN3
#define TXENn TXEN3
#define UBRRnH UBRR3H
#define UBRRnL UBRR3L
#define UCSRnA UCSR3A
#define UCSRnB UCSR3B
#define UCSRnC UCSR3C
#define UDRn UDR3
#else #error Invalid USART port number!
#endif
//USART1_RX_vect
//USART2_RX_vect
//USART3_RX_vect
#else #error Unsupported target MCU!!!
#endif
//! Индекс поиска
static u8 rx_i;
//! Индекс записи в буфер приёма
static u8 rx_wr_i;
//! Флаги переполнения и подтверждения
volatile u8 rx_overflow, rx_ack;
const char * searchFor; // Указатель на шаблон поиска
static u8 rx_i_CMTI;
volatile u8 NewSMS_index, NewSMS_index_;
static unsigned char searchStr;
const char * searchCMTI;
static u8 putchar(unsigned char send_char)
{
while (!(UCSRnA & 0x20));
UDRn = (unsigned char) send_char;
_delay_us(500); //Пауза для нормальной работы модема
return(send_char);
}
static u8 getchar( void )
{
/* Wait for data to be received */
while ( !(UCSRnA & (1<<RXCn)) )
;
/* Get and return received data from buffer */
return UDRn;
}
u8 GSMClass::Write(unsigned char Byte)
{
return putchar(Byte);
}
void UART0_rx_reset( void )
{
UCSRnB &= ~(1<<RXCIEn);
rx_i = rx_wr_i = 0;
rx_ack = 0;
rx_buffer[ rx_wr_i ] = '\0';
}
void UART0_rx_on( void )
{
UCSRnB |= ( 1 << RXCIEn );
}
void UART0_rx_off( void )
{
UCSRnB &= ~( 1 << RXCIEn );
}
//Установка шаблона для поиска
//pSTR - адрес шаблона в ПЗУ
void UART0_setSearchString( const char * pPattern_P )
{
UCSRnB &= ~( 1 << RXCIEn );
searchFor = pPattern_P; //Что требуется найти в буфере ответа
rx_i = 0;
}
/************************************************************************/
/* Обработчик прерываний по приему нового символа по UART
/* Выполняет сравнение с шаблоном из FLASH "на лету" */
/************************************************************************/
ISR(USARTn_RX_vect)
{
char data;
data = UDRn;
if (!data) return;
rx_buffer[ rx_wr_i++ ] = data; //Положили новый символ в буфер
if( rx_wr_i > RX_BUFFER_MASK ) //Если буфер переполнен, продолжим сначала с перезатиранием
{
rx_wr_i = 0;
}
if( data == pgm_read_byte(&searchFor[rx_i]) ) //Если пришедший символ совпал с символом шаблона
{
rx_i++; //Следующий символ шаблона
if( !pgm_read_byte(&searchFor[rx_i]) ) // Если дошли до конца шаблона - выключим приём
{
rx_i = 0;
{
rx_buffer[ rx_wr_i] = 0x00;
rx_ack = 1; // поднимем флаг - пришел ответ
UCSRnB &= ~( 1 << RXCIEn );
}
}
}
else
{
rx_i = 0;
}
}
void GSMClass::begin()
{
sei();
}
void GSMClass::WriteStr(char* s)
{
while (*s) putchar(*s++);
}
void GSMClass::WriteStr_P(const char* s)
{
while (pgm_read_byte(s))
putchar(pgm_read_byte(s++));
}
void UART0_init(void)
{
UCSRnB = 0x00;
UCSRnA = 0x00;
UCSRnC = 0x06;
UBRRnL = 25; //38400 low speed ( @ 16 MHz)
UBRRnH = 0x00;
UCSRnB = ( 1 << TXENn )|( 1 << RXENn );
UART0_rx_reset();
}
// Проверка ответа от модема
s8 UART0_check_acknowledge( u16 pause )
{
//! Local variables
static u16 i, ii;
for( i = 0; ( rx_ack == 0 ) && ( i < 65535 ); i++ ) //Цикл ожидания
{
for( ii = 0; ii < pause; ii++ )
{
asm("nop"); // Тратим энергию в пустую
}
}
if( rx_ack > 0 )
{
rx_ack = 0;
return 1;
}
else
{
UART0_rx_off( );
UART0_rx_reset( );
return -1;
}
}
void GSMClass::end()
{
}
s8 GSMClass::SendCmdWaitResp(const char* pCommand_P, const char* pSearchPattern_P, u16 pause)
{
UART0_rx_reset( );
UART0_setSearchString(pSearchPattern_P);
//_delay_ms(500);
GSM.WriteStr_P(pCommand_P);
GSM.WriteStr_P(PSTR("\r\n"));
UART0_rx_on( );
if( UART0_check_acknowledge( pause ) > 0 )
{
return 1;
}
else return -1;
}
s8 GSMClass::WaitResp(const char* pSearchPattern_P, u16 pause)
{
UART0_rx_reset( );
UART0_setSearchString(pSearchPattern_P);
UART0_rx_on( );
if( UART0_check_acknowledge( pause ) > 0 )
{
return 1;
}
else return -1;
}
s8 GSMClass::Init(const char* PIN)
{
DDRD |= (1<<PD5);
PORTD |= (1<<PD5);
_delay_ms(300);
PORTD &= ~(1<<PD5);
_delay_ms(5000);
UART0_init();
GSM.WriteStr_P(PSTR("AT\r\n"));
// _delay_ms(100);
GSM.WriteStr_P(PSTR("ATE0\r\n"));
_delay_ms(500);
GSM.WriteStr_P(PSTR("AT+IFC= 0,0\r\n"));
// _delay_ms(500);
// searchFor = (const char*)pgm_read_word(&searchStrings[1]);
// GSM.WriteStr_P(searchFor);
sei();
while (SendCmdWaitResp(PSTR("AT"),OK, pause64) < 0);
if (SendCmdWaitResp(PSTR("AT+CPIN?"),PSTR("+CPIN: "), pause256))
{
//Пришел ответ "+CPIN:"
if (WaitResp(OK, pause64))
{
// Пришел OK
if (strstr_P((char*)rx_buffer, PSTR("SIM PIN")))
{
// Вводим PIN код
GSM.WriteStr_P(PSTR("AT+CPIN=\""));
GSM.WriteStr_P(PIN);
if ( SendCmdWaitResp(PSTR("\""),OK, pause256) < 0) return -3; // PIN код не верен
}
else if (!strstr_P((char*)rx_buffer, PSTR("READY")))
{
return -3;
}
}
else return -3;
}else return -2;
//
/*
Ждем регистрации в сети
*/
u8 Attempts=0;
while (CheckStatus() < 0)
{
if (Attempts++ > 16)
{
return -1;
}
}
/*
Инициализируем текстовый режим СМС
*/
if (SendCmdWaitResp(PSTR("AT+CMGF=1"), OK, pause256) < 0) return -2;
return 1;
}
s8 GSMClass::CheckStatus(void)
{
// GSM.WriteStr_P(PSTR("AT\r\n"));
_delay_ms(500);
if (SendCmdWaitResp(PSTR("AT+CGATT?"), PSTR("+CGATT: 1"), pause64) > 0 )
{
//Пришел ответ "+CGATT: 1", ждем теперь "OK"
if (WaitResp(OK, pause256) < 0) return -1;
}
else return -1;
return 1;
}
s8 GSMClass::GetIMEI (char* IMEIbuf)
{
if (SendCmdWaitResp(PSTR("AT+CGSN"), OK, pause64) > 0 )
{
char* pSrc = (char*)rx_buffer;
u8 n = 0; u8 k = 0;
while ((n < 15) && (k < 64))
{
if ((*pSrc >= '0') && (*pSrc <= '9')) {*IMEIbuf++ = *pSrc; n++;}
else if (*pSrc == 'O') break;
*pSrc++; k++;
}
if (n == 15) {*pSrc =0x00; return 1;}
else return -2;
} else return -1;
}
s8 GSMClass::PowerOFF()
{
if (SendCmdWaitResp(PSTR("AT#SHDN"), OK, pause256) > 0 )
{
return 1;
}
else return -1;
}
Puhlyavyi есть еще вот такой скетч
#include <avr/pgmspace.h>
#include <GPRS.h>
#include <GSM.h>
#include <stuff.h>
#include <Narodmon.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10 // Номер линии, к которой подключены датчики температуры
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor_1, sensor_2, sensor_3, sensor_4; // Используем 4 температурных датчика
//ПИН-код! Поменяйте на свой!!! Иначе СИМ карта заблокируется!
const char PIN[] PROGMEM = "0000";
//Настройки для доступа к GPRS
const char ISP_IP[] PROGMEM = "home.beeline.ru";
const char LOGIN[] PROGMEM = "beeline";
//Буфер для считывания IMEI
char IMEI[16];
unsigned int minutes = 0;
//Интервал отправки данных в минутах
unsigned char SendIntervalInMinutes = 5;
//Флаг для активации отправки
unsigned char GSM_TASK_flag;
volatile unsigned char WDT_wake;
volatile unsigned char SleepTimeInSec = 60;
//volatile unsigned char WDT_counter; // увеличим счетчик прерываний
unsigned char RHMacn[8] = {0x00, 'S', 'H', 'T', '1', '1', '_', '0'};
/*
Обработчик прерываний по срабатыванию охранного таймера
*/
ISR(WDT_vect) {
static unsigned char WDT_counter; // увеличим счетчик прерываний
if (WDT_counter++ == SleepTimeInSec)
{ //отсчет минут
WDT_counter = 0;
if (minutes++ == SendIntervalInMinutes)
{
minutes = 0;
GSM_TASK_flag = 1; // Надо выполнить задачу по отправке данных на сервер
}
}
//Serial.print(WDT_counter, HEX);
asm ("WDR");
}
void setup_WDT(void)
{
asm ("CLI");
asm ("WDR");
// WDT_counter = 0;
MCUSR &= ~(1<<WDRF); //Сброс флага срабатывания
WDTCSR = (1 << WDCE)|(1<<WDE);
WDTCSR = (1 << WDP2)|(1 << WDP1)|(1 << WDIE)|(1 << WDIF); // Настройка сторожевого таймера на период 1 сек. Перевод в режим работы генерирования прерываний
asm ("SEI");
}
void off_WDT(void)
{
asm ("CLI");
asm ("WDR");
// WDT_counter = 0;
MCUSR &= ~(1<<WDRF); //Сброс флага срабатывания
WDTCSR = (1 << WDCE)|(1<<WDE)|(1 << WDIF);
/* Turn off WDT */
WDTCSR = 0x00;
asm ("SEI");
}
void sys_sleep(void)
{
asm ("CLI");
// asm ("WDR");
ADCSRA &= ~(1 << ADEN); // Выключим АЦП
SMCR = (1<<SE)|(1<<SM1); // Конфигурируем режим power-down
//MCUCR |= (1<<BODSE) | (1<<BODS); // Отключаем BOD на время сна
asm ("SEI");
asm ("SLEEP");
}
void sys_wake(void)
{
SMCR = 0x00; // Конфигурируем режим power-down
// тут можно включить АЦП
}
void setup()
{
delay(1000);
sensors.begin();
// Поиск 1-wire датчиков
sensors.getAddress(sensor_1, 0);
sensors.getAddress(sensor_2, 1);
sensors.getAddress(sensor_3, 2);
sensors.getAddress(sensor_4, 3);
// установка разрядности датчиков
sensors.setResolution(sensor_1, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_2, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_3, TEMPERATURE_PRECISION);
sensors.setResolution(sensor_4, TEMPERATURE_PRECISION);
// опрос всех датчиков на шине
sensors.requestTemperatures();
GSM_TASK_flag = 1;
}
void loop()
{
if (GSM_TASK_flag) // В обработчике Watchdog таймер установился флаг GSM-задания
{
GSM_TASK_flag = 0;
// Отключаем сторожевой таймер
off_WDT();
// инициализация GSM модема
while (GSM.Init(PIN)<0);
// Пoлучаем IMEI
while (GSM.GetIMEI (IMEI) < 0);
// Конверитруем в MAC
Narodmon.SetDeviceMACbyIMEI(IMEI);
// считываем температуры, заносим в массив
unsigned char SensorsNum = 0; // Для подсчета работающих датчиков
signed int SensorData;
if (ReadSensor (sensor_1, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_1);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
if (ReadSensor (sensor_2, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_2);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
if (ReadSensor (sensor_3, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_3);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
/*
if (ReadSensor (sensor_4, &SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, sensor_4);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
*/
if (ReadSensorRH (&SensorData))
{
Narodmon.SetMACnByIndex(SensorsNum, RHMacn);
Narodmon.SetDATAByIndex(SensorsNum, SensorData);
SensorsNum++;
}
u8 TxCounter = 0;
// попытка отправить данные
if (SensorsNum)
{
Narodmon.SetNumSensors(SensorsNum);
// Инициализация GPRS
u8 Success = 0;
do
{
if (GSM.InitGPRS(ISP_IP, LOGIN, LOGIN) > 0)
{
// Успешно инициализировали GPRS
// Открываем сокет 1
if (GSM.SocketOpen(1 , TCP, PSTR("map.net13.info"), 8283, 0) > 0)
{
// Сокет 1 открылся
//Пишем в сокет данные
Narodmon.TelnetSend(GSM.Write);
// Закрываем сокет 1
if (GSM.SocketClose(1) > 0) Success = 1;
else Success = 0;
} else Success = 0;
} else Success = 0;
if (!Success) delay (5000);
if (TxCounter++ == 4)
{
TxCounter =0;
// переинициализируем модуль
GSM_TASK_flag = 1;
return;
}
} while (!Success);
}
//Усыпляем GSM-модуль
while (GSM.PowerOFF() < 0);
// Включаем сторожевой таймер
setup_WDT();
}
// Усыпляем Атмегу
sys_sleep();
}
signed char ReadSensor (DeviceAddress sensor_addr, signed int* pData)
{
sensors.requestTemperaturesByAddress(sensor_addr);
float tempS = sensors.getTempC(sensor_addr);
if (tempS != DEVICE_DISCONNECTED)
{
signed int tempS10 = (signed int) (tempS * 10.0);
*pData = tempS10;
return 1;
}
return 0;
}
signed char ReadSensorRH (signed int* pData)
{
// Тут считываем с датчика влажности
float RH = 64.5;
if (RH >= 0) // Если датчик на линии
{
signed int RH10 = (signed int) (RH * 10.0);
*pData = RH10;
return 1;
}
return 0;
}
под него другие библиотеки #include <avr/pgmspace.h>
#include <util/delay.h>
#include "GSM.h"
#include "GPRS.h"
#include "stuff.h"
//activation of context
s8 GSMClass::InitGPRS(const char* ISP_IP, const char* LOGIN, const char* PWD)
{
GSM.WriteStr_P(PSTR("\r\nAT+CGDCONT=1,\"IP\",\""));
GSM.WriteStr_P(ISP_IP);
if (SendCmdWaitResp(PSTR("\""), OK, pause256 * 10) > 0 )
{
GSM.WriteStr_P(PSTR("\r\nAT#SGACT=1,1,'"));
GSM.WriteStr_P(LOGIN);
GSM.WriteStr_P(PSTR("','"));
GSM.WriteStr_P(PWD);
if (SendCmdWaitResp(PSTR("'\r\n"), OK, pause256 * 4) < 0) return -1;
}
else return -2;
return 1;
}
//open socket
s8 GSMClass::SocketOpen(u8 connId, u8 txProt, const char* SERVER_IP, u16 SERVER_PORT, u16 lPort)
{
char* pi2a;
GSM.WriteStr_P(PSTR("\r\nAT#SD="));
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(","));
// печатаем тип сокета 1 - UDP/ 0 - TCP
i2a(txProt, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(","));
// печатаем порт
i2a(SERVER_PORT, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(",\""));
// IP или Domain Name
GSM.WriteStr_P(SERVER_IP);
GSM.WriteStr_P(PSTR("\",255,")); // Сокет закроется автоматически после +++
// печатаем порт входящих соединений UDP
i2a(lPort, i2a_buf);
pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
GSM.WriteStr_P(PSTR(",0"));
if (SendCmdWaitResp(PSTR(""), PSTR("CONNECT"), pause256 * 4) < 0) return -1; // Сокет не открылся!
return 1; // Сокет открыт
}
//WriteSocket
s8 GSMClass::ActiveSocketWriteCb (void (*CALLBACK_FUNC)(unsigned char(*SocketWr)(unsigned char)))
{
(CALLBACK_FUNC)(&GSM.Write);
};
s8 GSMClass::ActiveSocketWriteStr (char* Str)
{
GSM.WriteStr(Str);
};
s8 GSMClass::ActiveSocketWriteStr_P (const char* Str)
{
GSM.WriteStr_P(Str);
};
s8 GSMClass::ActiveSocketSuspend ()
{
_delay_ms(1000);
GSM.WriteStr_P(PSTR("+++"));//Разрываем соединение
if (WaitResp(OK, pause256) < 0) return -1;
//_delay_ms(1000);
return 1;
};
s8 GSMClass::SocketClose (u8 connId)
{
ActiveSocketSuspend ();
GSM.WriteStr_P(PSTR("AT#SH="));//Разрываем соединение
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
char* pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
if (SendCmdWaitResp(PSTR(""), OK, pause256 * 2) < 0) return -1; // Сокет не закрылся!
return 1;
};
s8 GSMClass::SocketResume (u8 connId)
{
GSM.WriteStr_P(PSTR("AT#SO="));//Возобновляем соединение
// печатаем номер соединения 1...6
i2a(connId, i2a_buf);
char* pi2a = i2a_buf;
while (*pi2a) GSM.Write(*pi2a++);
if (SendCmdWaitResp(PSTR(""), PSTR("CONNECT"), pause256 * 4) < 0) return -1; // Сокет не открылся!
};
s8 ActiveSocketReadStr (char* Str)
{
//*Str++ = getchar ();
};
/*
* Библиотека низкоуровневых функций для работы с платой CosmoGSM
* CosmoGSM.cpp
*
* Created: 28.02.2013 11:16:15
* Author: a-erezeev
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "GSM.h"
#include <string.h>
#define PD7 (7)
#define PD6 (6)
#define PD5 (5)
#define PB0 (0)
#define PB1 (1)
#ifdef _AVR_IOM328P_H_ || _AVR_IOM328_H_
#define RXCIEn RXCIE0
#define RXCn RXC0
#define RXENn RXEN0
#define TXENn TXEN0
#define UBRRnH UBRR0H
#define UBRRnL UBRR0L
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#define USARTn_RX_vect USART_RX_vect
#elif _AVR_IOM2560_H_
#ifdef GSM_USART0
#define USARTn_RX_vect USART0_RX_vect
#define RXCIEn RXCIE0
#define RXCn RXC0
#define RXENn RXEN0
#define TXENn TXEN0
#define UBRRnH UBRR0H
#define UBRRnL UBRR0L
#define UCSRnA UCSR0A
#define UCSRnB UCSR0B
#define UCSRnC UCSR0C
#define UDRn UDR0
#elif GSM_USART1
#define USARTn_RX_vect USART1_RX_vect
#define RXCIEn RXCIE1
#define RXCn RXC1
#define RXENn RXEN1
#define TXENn TXEN1
#define UBRRnH UBRR1H
#define UBRRnL UBRR1L
#define UCSRnA UCSR1A
#define UCSRnB UCSR1B
#define UCSRnC UCSR1C
#define UDRn UDR1
#elif GSM_USART2
#define USARTn_RX_vect USART2_RX_vect
#define RXCIEn RXCIE2
#define RXCn RXC2
#define RXENn RXEN2
#define TXENn TXEN2
#define UBRRnH UBRR2H
#define UBRRnL UBRR2L
#define UCSRnA UCSR2A
#define UCSRnB UCSR2B
#define UCSRnC UCSR2C
#define UDRn UDR2
#elif GSM_USART3
#define USARTn_RX_vect USART3_RX_vect
#define RXCIEn RXCIE3
#define RXCn RXC3
#define RXENn RXEN3
#define TXENn TXEN3
#define UBRRnH UBRR3H
#define UBRRnL UBRR3L
#define UCSRnA UCSR3A
#define UCSRnB UCSR3B
#define UCSRnC UCSR3C
#define UDRn UDR3
#else #error Invalid USART port number!
#endif
//USART1_RX_vect
//USART2_RX_vect
//USART3_RX_vect
#else #error Unsupported target MCU!!!
#endif
//! Индекс поиска
static u8 rx_i;
//! Индекс записи в буфер приёма
static u8 rx_wr_i;
//! Флаги переполнения и подтверждения
volatile u8 rx_overflow, rx_ack;
const char * searchFor; // Указатель на шаблон поиска
static u8 rx_i_CMTI;
volatile u8 NewSMS_index, NewSMS_index_;
static unsigned char searchStr;
const char * searchCMTI;
static u8 putchar(unsigned char send_char)
{
while (!(UCSRnA & 0x20));
UDRn = (unsigned char) send_char;
_delay_us(500); //Пауза для нормальной работы модема
return(send_char);
}
static u8 getchar( void )
{
/* Wait for data to be received */
while ( !(UCSRnA & (1<<RXCn)) )
;
/* Get and return received data from buffer */
return UDRn;
}
u8 GSMClass::Write(unsigned char Byte)
{
return putchar(Byte);
}
void UART0_rx_reset( void )
{
UCSRnB &= ~(1<<RXCIEn);
rx_i = rx_wr_i = 0;
rx_ack = 0;
rx_buffer[ rx_wr_i ] = '\0';
}
void UART0_rx_on( void )
{
UCSRnB |= ( 1 << RXCIEn );
}
void UART0_rx_off( void )
{
UCSRnB &= ~( 1 << RXCIEn );
}
//Установка шаблона для поиска
//pSTR - адрес шаблона в ПЗУ
void UART0_setSearchString( const char * pPattern_P )
{
UCSRnB &= ~( 1 << RXCIEn );
searchFor = pPattern_P; //Что требуется найти в буфере ответа
rx_i = 0;
}
/************************************************************************/
/* Обработчик прерываний по приему нового символа по UART
/* Выполняет сравнение с шаблоном из FLASH "на лету" */
/************************************************************************/
ISR(USARTn_RX_vect)
{
char data;
data = UDRn;
if (!data) return;
rx_buffer[ rx_wr_i++ ] = data; //Положили новый символ в буфер
if( rx_wr_i > RX_BUFFER_MASK ) //Если буфер переполнен, продолжим сначала с перезатиранием
{
rx_wr_i = 0;
}
if( data == pgm_read_byte(&searchFor[rx_i]) ) //Если пришедший символ совпал с символом шаблона
{
rx_i++; //Следующий символ шаблона
if( !pgm_read_byte(&searchFor[rx_i]) ) // Если дошли до конца шаблона - выключим приём
{
rx_i = 0;
{
rx_buffer[ rx_wr_i] = 0x00;
rx_ack = 1; // поднимем флаг - пришел ответ
UCSRnB &= ~( 1 << RXCIEn );
}
}
}
else
{
rx_i = 0;
}
}
void GSMClass::begin()
{
sei();
}
void GSMClass::WriteStr(char* s)
{
while (*s) putchar(*s++);
}
void GSMClass::WriteStr_P(const char* s)
{
while (pgm_read_byte(s))
putchar(pgm_read_byte(s++));
}
void UART0_init(void)
{
UCSRnB = 0x00;
UCSRnA = 0x00;
UCSRnC = 0x06;
UBRRnL = 25; //38400 low speed ( @ 16 MHz)
UBRRnH = 0x00;
UCSRnB = ( 1 << TXENn )|( 1 << RXENn );
UART0_rx_reset();
}
// Проверка ответа от модема
s8 UART0_check_acknowledge( u16 pause )
{
//! Local variables
static u16 i, ii;
for( i = 0; ( rx_ack == 0 ) && ( i < 65535 ); i++ ) //Цикл ожидания
{
for( ii = 0; ii < pause; ii++ )
{
asm("nop"); // Тратим энергию в пустую
}
}
if( rx_ack > 0 )
{
rx_ack = 0;
return 1;
}
else
{
UART0_rx_off( );
UART0_rx_reset( );
return -1;
}
}
void GSMClass::end()
{
}
s8 GSMClass::SendCmdWaitResp(const char* pCommand_P, const char* pSearchPattern_P, u16 pause)
{
UART0_rx_reset( );
UART0_setSearchString(pSearchPattern_P);
//_delay_ms(500);
GSM.WriteStr_P(pCommand_P);
GSM.WriteStr_P(PSTR("\r\n"));
UART0_rx_on( );
if( UART0_check_acknowledge( pause ) > 0 )
{
return 1;
}
else return -1;
}
s8 GSMClass::WaitResp(const char* pSearchPattern_P, u16 pause)
{
UART0_rx_reset( );
UART0_setSearchString(pSearchPattern_P);
UART0_rx_on( );
if( UART0_check_acknowledge( pause ) > 0 )
{
return 1;
}
else return -1;
}
s8 GSMClass::Init(const char* PIN)
{
DDRD |= (1<<PD5);
PORTD |= (1<<PD5);
_delay_ms(300);
PORTD &= ~(1<<PD5);
_delay_ms(5000);
UART0_init();
GSM.WriteStr_P(PSTR("AT\r\n"));
// _delay_ms(100);
GSM.WriteStr_P(PSTR("ATE0\r\n"));
_delay_ms(500);
GSM.WriteStr_P(PSTR("AT+IFC= 0,0\r\n"));
// _delay_ms(500);
// searchFor = (const char*)pgm_read_word(&searchStrings[1]);
// GSM.WriteStr_P(searchFor);
sei();
while (SendCmdWaitResp(PSTR("AT"),OK, pause64) < 0);
if (SendCmdWaitResp(PSTR("AT+CPIN?"),PSTR("+CPIN: "), pause256))
{
//Пришел ответ "+CPIN:"
if (WaitResp(OK, pause64))
{
// Пришел OK
if (strstr_P((char*)rx_buffer, PSTR("SIM PIN")))
{
// Вводим PIN код
GSM.WriteStr_P(PSTR("AT+CPIN=\""));
GSM.WriteStr_P(PIN);
if ( SendCmdWaitResp(PSTR("\""),OK, pause256) < 0) return -3; // PIN код не верен
}
else if (!strstr_P((char*)rx_buffer, PSTR("READY")))
{
return -3;
}
}
else return -3;
}else return -2;
//
/*
Ждем регистрации в сети
*/
u8 Attempts=0;
while (CheckStatus() < 0)
{
if (Attempts++ > 16)
{
return -1;
}
}
/*
Инициализируем текстовый режим СМС
*/
if (SendCmdWaitResp(PSTR("AT+CMGF=1"), OK, pause256) < 0) return -2;
return 1;
}
s8 GSMClass::CheckStatus(void)
{
// GSM.WriteStr_P(PSTR("AT\r\n"));
_delay_ms(500);
if (SendCmdWaitResp(PSTR("AT+CGATT?"), PSTR("+CGATT: 1"), pause64) > 0 )
{
//Пришел ответ "+CGATT: 1", ждем теперь "OK"
if (WaitResp(OK, pause256) < 0) return -1;
}
else return -1;
return 1;
}
s8 GSMClass::GetIMEI (char* IMEIbuf)
{
if (SendCmdWaitResp(PSTR("AT+CGSN"), OK, pause64) > 0 )
{
char* pSrc = (char*)rx_buffer;
u8 n = 0; u8 k = 0;
while ((n < 15) && (k < 64))
{
if ((*pSrc >= '0') && (*pSrc <= '9')) {*IMEIbuf++ = *pSrc; n++;}
else if (*pSrc == 'O') break;
*pSrc++; k++;
}
if (n == 15) {*pSrc =0x00; return 1;}
else return -2;
} else return -1;
}
s8 GSMClass::PowerOFF()
{
if (SendCmdWaitResp(PSTR("AT#SHDN"), OK, pause256) > 0 )
{
return 1;
}
else return -1;
}