Вопрос по модулю SIM900
- Войдите на сайт для отправки комментариев
Пнд, 30/12/2013 - 05:47
Имеется такой модуль SIM900
Подключил к Arduino UNO
При попытке отправки SMS или GPRS пакета идет перезагрузка контроллера. Питание подавал как по USB, так и по внешнему разъему Arduino 12V с блока ATX.

Как подать к данной плате внешнее питание?
На какие ноги Arduino заведены POWER и RESET ?
Что за странный разъем RI Jumper с ногами D14 RI D2 ?

вам на кофе погадать? или пасьянс разложим?
вам на кофе погадать? или пасьянс разложим?
Да хоть на столе спляшите. Мне все равно.
Может кто-то имел опыт работы с такими модулями?
Имел.. отличный модуль!!! но есть косяки... по крайней мере там где я покупал...
вот ветка, где мне помогли с написанием кода к этому модулю! http://arduino.ru/forum/programmirovanie/pomogite-novichku-dopisat-kod#comment-40099
откройте datasheet и внимательно изучите! там все есть! и попробуй только поспорить!
если все сложно - по логике, достаточно открыть datasheet на sim900, взять мультиметр и все выяснить! и не надо лениться! не стоит покупать такие модули и не ударить "палец об палец"!
вам на кофе погадать? или пасьянс разложим?
действительно!!! Хотя бы написали, каким образом вы пытались отправить "что-то там"...
откройте datasheet и внимательно изучите! там все есть! и попробуй только поспорить!
Даташит там очень короткий
С мультиметром разобрался по своим вопросом, но проблема осталась:
Использую GSM Shield Library for Arduino. Плата работает на програмном COM. Все AT команды работают без проблем. Плата принимает звонки и SMS, но вот при попытки отправки SMS хоть функцией SendSMS, хочь через AT Arduino уходит в перезагрузку. Похоже, что данная проблема аппаратная, поэтому код и не приводил
где то в тырнете читал по самой сборке Sim900, у людей таже проблема была с передачей. Советовали обратить внимание на питание модуля.
Ну вот по всем вопросам разобрался:
POWER сидит на 9-м пине
RESET на 10-м пине
D14 RI D2 сигнализируют о получении SMS, входящих звноках и прочих событий с модуля
Питания на модуль подать можно с ноги шилда 5В
Перезагрузки контроллера к питанию не имеют отношения, а имеет глючная библиотека, которой пользовался первоначально. Плюнул на все эти библиотеки и через SoftwareSerial напрямую с AT командами разобрался. Остался один вопрос. Хочу отослать по GPRS информацию на народный мониторинг. Получаю следующее:
Через Ethernet спокойно отсылаю эти данные, через GPRS ошибка получается. Перепрошивка SIM900 поможет?
Зачем вы "AT+CIPSHUT" в начале отсылаете?
AT+CMEE=1
AT+CGATT=1
AT+CSTT="internet" // Ваша точка APN и логин с паролем
AT+CIICR
AT+CIFSR // в ответ - ваш IP покажет. без этой команды - дальше не будет работать.
AT+CIPSTART="TCP","narodmon.ru","8283" // Адрес и порт сервера. Почему у вас 7777 не понятно..
AT+CIPSEND // В ответ будет знак ">" после чего надо отсылать данные. не успеете за 10сек. вас отбросит сервер.
#XXXXXXXXXXXXX
XXXXXXXXXXXXX01#100
##
AT+CIPSHUT // Закрываем TCP.
Зачем вы "AT+CIPSHUT" в начале отсылаете?
После этой команды статус AT+CIPSTATUS становится STATE: IP INITIAL
после CIPSHUT "падает" PDP! что вам и ответил модуль: STATE: PDP DEACT!
Попробуйте, то что я написал выше. Я сам недавно только закончил проэкт для NARODMON под 8 датчиков DHT22 на Icomsat 1.1 (Sim900) шилде.
Сокет не открывается с народным мониторингом
читайте внимательней!!!
"AT+CIFSR // в ответ - ваш IP покажет. без этой команды - дальше не будет работать."
UPD: "AT+CIFSR" Возвращает IP-адрес модуля. Если в ответ нет IP адреса - оператор вашей сети не на делил вас IP! дальнейшая работа - бесполезна!
И еще, я не знаю как у вас там мтс работает, у нас на Украине (для MTS) достаточно только строчки "
AT+CSTT="internet"", без логина и пароля. На даный момент, у них так заявлено на сайте mts.com.ua.И еще, я не знаю как у вас там мтс работает, у нас на Украине (для MTS) достаточно только строчки "
AT+CSTT="internet"", без логина и пароля. На даный момент, у них так заявлено на сайте mts.com.ua.MTS у нас очень плохо работает. Поменял симку на Ростелеком, и все заработало с вашим кодом.
Спасибо. Вы мне очень помогли!
Рад что помог! ;)
Советую еще этот ресурс: Module Tester | M2MSupport.net он мне очень помог разобраться с командами для модуля SIM900.
Всем кто работает с GSM/GPRS модулями совет - храните AT команды в PROGMEM. Иначе они очень быстро съедают оперативную память и скетч начинает глючить (перезагружается, виснет, сбивает перемнные). Никаких аппаратных проблем по питанию, например с USB в связке UNO - SIM900 не выявлено.
sav13
Выложите пожалуйста пример кода для отправки данных на narodmon.
Я уже совсем запутался... Через LAN один код, через WiFi другой, через SIM900 третий...
// Через SIM900 void SendTCPMessage(int x) { char b1[20]; gsm.SimpleWriteln("AT+CGATT=1"); delay(100); gsm.SimpleWriteln("AT+CDNSCFG=\"8.8.8.8\""); delay(100); gsm.SimpleWriteln("AT+CIPCSGP=1,\"mts.internet,ru\",\"\",\"\""); delay(5000); gsm.SimpleWriteln("AT+CIPSTART=\"TCP\",\"narodmon.ru\",\"8283\""); delay(100); gsm.SimpleWriteln("#00-11-22-33-44-5"); sprintf(b1,"#00112233445566#%d",x); gsm.SimpleWriteln(b1); gsm.SimpleWriteln("##"); delay(100); gsm.SimpleWriteln((char)26);//the ASCII code of the ctrl+z is 26 delay(100); gsm.SimpleWriteln(""); }// Через Ethernet boolean SendToNM() { if (client.connect(nm_server, 8283)) { Serial.println("connected for error"); client.print("#00-11-22-33-44-55"); // Отправляем GET запрос client.print("\n"); client.print("#00112233445566#"); client.print(t2); client.print("\n"); client.print("##"); client.stop(); }//end if }Код для narodmon.ru sim900 dht22 bmp180 по протоколу UDP
Правда для слегка другого шилда.
https://drive.google.com/file/d/0B8Yn3QheuZFGdHpfZFZjdUFWRFU/view?usp=sharing
Доброго дня! Собрался повторить термометр с отправкой данных на narodmon.ru из предидущего сообщения, но при проверке высыпалось множество ошибок с которыми не смог справится (в програмировании новичок). Вопрос к автору как повторить ваш проект?
Всем кто работает с GSM/GPRS модулями совет - храните AT команды в PROGMEM. Иначе они очень быстро съедают оперативную память и скетч начинает глючить (перезагружается, виснет, сбивает перемнные). Никаких аппаратных проблем по питанию, например с USB в связке UNO - SIM900 не выявлено.
Добрый день! не могли бы дать пример скетча с PROGMEM для SIM900
sav13, Вроде бы сделал с PROGMEN, но глюки не ушли. но наблюдаю у себя вроде бы то же что и было у вас
в основном в монитор приходят корректные данные от модуля, но иногда кракозябры. причем это может быть во время одного и того же "сеанса работы" устройства. иногда пол строки придет кракозябры, половина нормальных символов...
мой изначальный вариант скетча:
#include <SoftwareSerial.h> #include <OneWire.h> #include <EEPROM.h> #include <RCSwitch.h> SoftwareSerial gsm(7, 8); OneWire ds(10); RCSwitch RC = RCSwitch(); unsigned long TimePrint; // из конечного устройства можно убрать int che=1; // //Сигнализация unsigned long loopTime[4]; //указать количество беспроводных датчиков сигнализации unsigned long currentTime; unsigned long zaderjkaSignSMS = 10000;//интервал между сообщениями сигнализации 1000=1секунда //Беспроводные датчики byte numRC = 4; //количество беспроводных датчиков сигнализации int RCvalue[4] = {12410657,12410658,12410660,12410664}; //добавить коды всех датчиков через запятую String RCvalueName [4] = {"Kuhn9","Dver' vhod","Dver' garaj","Luk"}; //названия должны соответствовать кодам датчиков из предыдущей строки //датчики температуры DS18B20 //____НЕОБХОДИМО ПРОПИСАТЬ АДРЕСА СВОИХ ДАТЧИКОВ______ byte flagDallRead; byte addr[1][8]={{0x28,0xBC,0x74,0x03,0x00,0x00,0x80,0x12}}; //в первых скобках [] скобках необхлодимо указать сколько у вас DS18B20 и в фигурных скобках прописать их адреса {{},{}.....{},{}} byte numDS = 1; // количество DS18B20. float Temp[1]; //в скобках указать количество ваших DS18B20 bool TkritFlag = true; int TkritMax; int TkritMin; unsigned long loopTimeTemp; unsigned long zaderjkaTempSMS = 30000;//000; //интервал между сообщениями о критической температуре 1000=1секунда //ДЛЯ GSM и около него boolean isStringMessage = false; // Переменная принимает значение True, если текущая строка является сообщением int ch; String sms = ""; String val = ""; String val1 = ""; //переменная для хранения технической информации сообщения/звонка (номер, время) String val2 = ""; //переменная для хравнения содержания полученной СМСки String master1 = "7916ХХХххХХ"; /ваш номер byte PIN_PWRKEY = 9; //пин включения sim900 //ДЛЯ РЕЛЕ byte Pins[6] = {14, 15, 16, 17,18,19}; // Массив задействованных номеров Pins Arduino, для управления реле. byte PinStatus[6]; // Массив для фиксации изменений byte numPins = 6; // количество реле byte ON = HIGH; //для проверки работоспособности на светодиодах ON=HIGH, для реле ON=LOW byte OFF = LOW; //для проверки работоспособности на светодиодах OFF=LOW, для реле OFF=HIGH void setup() { {// GSM pinMode(9, OUTPUT); digitalWrite(9,LOW); delay(1000); digitalWrite(9,HIGH); delay(2000); digitalWrite(9,LOW); delay(15000); Serial.begin(9600); gsm.begin(19200); //gsm.write("A\r"); // отправляем А чтобы sim900 автоматически настроился на скорость // delay(1000); //gsm.println("AT+IPR=19200\r"); delay(100); gsm.print("AT+CMGF=1\r"); //устанавливает текстовый режим смс-сообщения delay(300); gsm.print("AT+IFC=1, 1\r"); //устанавливает программный контроль потоком передачи данных delay(300); gsm.print("AT+CPBS=\"SM\"\r"); //открывает доступ к данным телефонной книги SIM-карты delay(300); gsm.print("AT+GSMBUSY=1, 1\r"); //запрет всех входящих звонков delay(300); gsm.print("AT+CMGDA=«DEL ALL»\r"); //Очищаем накопившиеся СМС delay(300); gsm.print("AT+CNMI=1,2,2,1,0\r"); //включает оповещение о новых сообщениях delay(10000);} che=EEPROM.read(10); TkritMin=EEPROMReadInt(11); TkritMax=EEPROMReadInt(13); TkritFlag=EEPROM.read(15); RC.enableReceive(0); // Receiver on interrupt 0 => that is pin #2 for(int i = 0; i <= numPins -1; i++) { //восставновление состояния реле pinMode(Pins[i],OUTPUT); PinStatus[i]=EEPROM.read(i); //считываем состояние до перезагрузки ардуины digitalWrite(Pins[i],PinStatus[i]); //восстанавливаем состояние реле } for(int i = 0; i <= numRC -1; i++) { //для отправки смс loopTime[i] = 0; } TimePrint = 0; loopTimeTemp = 0; Serial.println("GOTOVO"); } void loop() { currentTime = millis(); // считываем время, прошедшее с момента запуска программы dallRead(flagDallRead * 1000); if (Serial.available()) { //обработка Serial данных while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val2 += char(ch); delay(10); } Serial.println(val2); val1=master1; razborkomand(); val2=""; val1=""; //очищаем } if (gsm.available()) {//если модуль что то шлет while(gsm.available()) { ch = gsm.read(); if(ch == '\r') continue; if(ch == '\n') { gsmRead(val); val = ""; } else val += char(ch); } } if (RC.available()) { //Обработка беспроводных датчиков if (che == 1) { //обработа сигналов с беспроводных датчиков ch = RC.getReceivedValue(); for(int i = 0; i <= numRC -1; i++) { if (ch == RCvalue[i]) { if (currentTime >= loopTime[i]) { loopTime[i] = currentTime + zaderjkaSignSMS; Alarm(RCvalueName[i]); for(int n = 0; n <= numRC -1; n++) { if (n!=i) { loopTime[n] = 0; } } } } } } RC.resetAvailable(); } if (TkritFlag) { //если TkritFlag=true, заходим в оповещения о крит температуре for(byte n = 0; n <= numDS-1; n++) //перебор всех темп. датчиков { if (Temp[n]!=-0.06 && Temp[n]!=0.00) { if ((Temp[n] <= TkritMin) || (Temp[n] >= TkritMax)) { if (currentTime >= loopTimeTemp) { TempStatus(master1); loopTimeTemp = currentTime + zaderjkaTempSMS; } } } } } { //Печать данных в монитор. нужно только для отладки. из конечного устройства вырезать if (currentTime >= TimePrint) { TimePrint = currentTime+15000; Serial.print("Temp1="); Serial.println(Temp[0]); Serial.println("- - - - - -"); } } } void Alarm(String zona) { sms = "Trevoga!"; sms += zona; smssend(master1); Serial.println("Trevoga! " + zona); } void razborkomand () { if (val1.indexOf(master1) > -1) //на команды в этом блоке придет ответ { if (val2.indexOf("Pozvoni") > -1) Proslushka(master1); //если в сообщении "позвони", ардуинка звонит нам на номер, с которого пришел запрос if (val2.indexOf("Temp?") > -1) TempStatus(master1); //если в сообщении "температура?", ардуинка высылает температуры на номер, с которого пришел запрос if (val2.indexOf("Tkriton") > -1) TkritONOFF(true, master1); // {TkritFlag = true; EEPROM.write(15,TkritFlag);Serial.println("Tkriton");} if (val2.indexOf("Tkritoff") > -1) TkritONOFF(false, master1); // {TkritFlag = false; EEPROM.write(15,TkritFlag);Serial.println("Tkritoff");} if (val2.indexOf("Off") > -1) AlarmSet(0, master1, String ("OFF")); //если в сообщении "OFF", ардуинка выключает режим сигнализации и отправляет смс с оповещением о сняьтт с сигнализации тому, кто прислал команду if (val2.indexOf("On") > -1) AlarmSet(1, master1, String ("ON")); //если в сообщении "ON", ардуинка включает режим сигнализации и отправляет смс с оповещением о постановке на сигнализацию тому, кто прислал команду if (val2.indexOf("Vkl") > -1) { //если в сообщении "вкл1234", включить реле №1 и №2 и №3 и №4 sms = "Vklucheno "; if (val2.indexOf("1")> -1) RelaySet(1, ON); if (val2.indexOf("2")> -1) RelaySet(2, ON); if (val2.indexOf("3")> -1) RelaySet(3, ON); if (val2.indexOf("4")> -1) RelaySet(4, ON); if (val2.indexOf("5")> -1) RelaySet(5, ON); if (val2.indexOf("6")> -1) RelaySet(6, ON); smssend(master1); } if (val2.indexOf("Vikl") > -1) { //если в сообщении "выкл1234", выключить реле №1 и №2 и №3 и №4 sms = "Viklucheno "; if (val2.indexOf("1")> -1) RelaySet(1, OFF); if (val2.indexOf("2")> -1) RelaySet(2, OFF); if (val2.indexOf("3")> -1) RelaySet(3, OFF); if (val2.indexOf("4")> -1) RelaySet(4, OFF); if (val2.indexOf("5")> -1) RelaySet(5, OFF); if (val2.indexOf("6")> -1) RelaySet(6, OFF); smssend(master1); } } if (val2.indexOf("Tkritmin") > -1) {val1= val2.substring(9, 14); Serial.println(val1); TkritMin = val1.toInt(); Serial.println(TkritMin); EEPROMWriteInt(11,TkritMin);} if (val2.indexOf("Tkritmax") > -1) {val1= val2.substring(9, 12); Serial.println(val1); TkritMax = val1.toInt(); Serial.println(TkritMax); EEPROMWriteInt(13,TkritMax);} } void TkritONOFF (boolean onoff, String phone) { TkritFlag = onoff; EEPROM.write(15,TkritFlag); Serial.println(TkritFlag); if (TkritFlag) { sms = "TKrit VKL"; sms += '\n'; sms += "Tmin "; sms += TkritMin; sms += '\n'; sms += "Tmax "; sms += TkritMax; } if (TkritFlag==false) { sms = "TKrit VIKL"; } smssend(phone); } void gsmRead(const String val) { //разбираем данные от gsm if (!val.startsWith("+CMT") && isStringMessage == false ) {Serial.println(val);} //если НЕ смс и это не вторая строка(которая является непосредственно сообщением), значит это иная информация от модуля. выводим в сериал if (isStringMessage == true) // если флаг "ПРАВДА", значит дошли до строки с сообщением { isStringMessage = false; // меняем флаг на "ЛОЖЬ", чтобы при обработке последующей информации, не относящейся к сообщению, в этот кусок не попасть снова if (val1.indexOf(master1) > -1) // Если в первой строке VAL1 есть мастер(или один из номеров) номер { Serial.println("master"); //в сериал шлется, что сообщение от мастера val2 = val; // сохраняем в переменную Serial.println("VAL2: " + val2); // выводим в сериал razborkomand(); // разбираем что за команда пришла } else Serial.println("NE master"); } else { if (val.startsWith("+CMT")) // если текущая строка начинается с "+CMT", то следующая строка является сообщением; { val1=val; isStringMessage = true; //флаг означающий, что следующая строка сообщение Serial.println("VAL1: " + val1); // выводим в сериал } } } void smssend(String phone) { //процедура отправки СМС // Serial.print(sms); Serial.println(phone); Serial.println("SMS send started"); gsm.print("AT+CMGF=1\r"); delay(100); gsm.println("AT + CMGS = \"+" + phone + "\""); delay(100); gsm.print(sms); // text = ""; delay(100); gsm.print((char)26); delay(100); Serial.println("SMS send complete"); sms=""; } void Proslushka(String phone){ //Цикл дозвона абоненту (для аудиоконтроля)___________________ gsm.println("AT+CMIC=0,10"); // Команда для установки чувствительности микрофона Поэкспериментировать с цифрой. // 0,- это канал микрофона (1,2,3),15 это уровень см.инструкцию к СИМ900 delay(2000); gsm.println("ATD+"+ phone + ";"); // Набираем номер //Serial2.println("ATH"); // Вешаем трубку } void RelaySet(byte rnum, byte state) { //управление реле PinStatus[(rnum-1)] = state; digitalWrite(Pins[(rnum-1)],PinStatus[(rnum-1)]); EEPROM.write((rnum-1),PinStatus[(rnum-1)]); //запись в энергонезависимую память состояния реле для вооставноления этого состояния после потери питания sms += rnum; } void AlarmSet(int vklvikl, String phone, String onoff) { che = vklvikl; EEPROM.write(10,che); sms=onoff; smssend(phone); } void TempStatus(String phone) { sms = ""; for(byte n = 0; n <= numDS-1; n++) { sms += "T"; sms += (n+1); sms += " "; sms += Temp[n]; sms += "C"; sms += '\n'; } smssend(phone); sms = ""; } void EEPROMWriteInt(int address, int value) { //Запись двухбайтового числа в память EEPROM.write(address, lowByte(value)); EEPROM.write(address + 1, highByte(value)); } unsigned int EEPROMReadInt(int address) { //Чтение числа из памяти byte lowByte = EEPROM.read(address); byte highByte = EEPROM.read(address + 1); return (highByte << 8) | lowByte; } void dallRead(unsigned long interval){ //температура static unsigned long prevTime = 0; if (millis() - prevTime > interval) { //Проверка заданного интервала static boolean flagDall = 0; //Признак операции prevTime = millis(); flagDall =! flagDall; //Инверсия признака if (flagDall) { ds.reset(); ds.write(0xCC); //Обращение ко всем датчикам ds.write(0x44); //Команда на конвертацию flagDallRead = 1; //Время возврата в секундах } else { byte i; int temp; for (i = 0; i < 3; i++){ //Перебор количества датчиков ds.reset(); ds.select(addr[i]); ds.write(0xBE); //Считывание значения с датчика temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры Temp[i] = (float)temp / 16.0; flagDallRead = 2; //Время возврата в секундах } } } }попытка два, с (F(.....));
#include <SoftwareSerial.h> #include <avr/wdt.h> #include <avr/pgmspace.h> #include <OneWire.h> #include <EEPROM.h> #include <RCSwitch.h> SoftwareSerial gsm(7, 8); OneWire ds(10); RCSwitch RC = RCSwitch(); unsigned long TimePrint; // из конечного устройства можно убрать int che=1; // //Сигнализация unsigned long loopTime[4]; //указать количество беспроводных датчиков сигнализации unsigned long currentTime; unsigned long zaderjkaSignSMS = 10000;//интервал между сообщениями сигнализации 1000=1секунда //Беспроводные датчики byte numRC = 4; //количество беспроводных датчиков сигнализации int RCvalue[4] = {12410657,12410658,12410660,12410664}; //добавить коды всех датчиков через запятую String RCvalueName [4] = {"Kuhn9","Dver' vhod","Dver' garaj","Luk"}; //названия должны соответствовать кодам датчиков из предыдущей строки //датчики температуры DS18B20 //____НЕОБХОДИМО ПРОПИСАТЬ АДРЕСА СВОИХ ДАТЧИКОВ______ byte flagDallRead; byte addr[1][8]={{0x28,0xBC,0x74,0x03,0x00,0x00,0x80,0x12}}; //в первых скобках [] скобках необхлодимо указать сколько у вас DS18B20 и в фигурных скобках прописать их адреса {{},{}.....{},{}} byte numDS = 1; // количество DS18B20. float Temp[1]; //в скобках указать количество ваших DS18B20 bool TkritFlag = true; int TkritMax; int TkritMin; unsigned long loopTimeTemp; unsigned long zaderjkaTempSMS = 30000;//000; //интервал между сообщениями о критической температуре 1000=1секунда //ДЛЯ GSM и около него boolean isStringMessage = false; // Переменная принимает значение True, если текущая строка является сообщением int ch; String sms = ""; String val = ""; String val1 = ""; //переменная для хранения технической информации сообщения/звонка (номер, время) String val2 = ""; //переменная для хравнения содержания полученной СМСки String master1 = "7916xxxxxxx"; //ваш номер byte PIN_PWRKEY = 9; //пин включения sim900 //ДЛЯ РЕЛЕ byte Pins[6] = {14, 15, 16, 17,18,19}; // Массив задействованных номеров Pins Arduino, для управления реле. byte PinStatus[6]; // Массив для фиксации изменений byte numPins = 6; // количество реле byte ON = HIGH; //для проверки работоспособности на светодиодах ON=HIGH, для реле ON=LOW byte OFF = LOW; //для проверки работоспособности на светодиодах OFF=LOW, для реле OFF=HIGH void reboot() { wdt_disable(); wdt_enable(WDTO_15MS); while (1) {} } void setup() { pinMode(12, INPUT); Serial.begin(9600); Serial.println(F("START")); pinMode(19, OUTPUT); digitalWrite(19,LOW); {// GSM if (digitalRead(12)==LOW) //пин12 мониторит включенность ГСМ(напругу на светодиоде status). если ГСМ выключен, то после включения ардуина перезагружается и загружается при ключенном ГСМ { Serial.println(F("Budet RESET")); pinMode(9, OUTPUT); digitalWrite(9,LOW); delay(1000); digitalWrite(9,HIGH); delay(2000); digitalWrite(9,LOW); delay(15000); reboot(); delay(500); } gsm.begin(19200); //gsm.write("A\r"); // отправляем А чтобы sim900 автоматически настроился на скорость // delay(1000); //gsm.println("AT+IPR=19200\r"); delay(100); gsm.print(F("AT+CMGDA=\"DEL ALL\"\r")); //Очищаем накопившиеся СМС delay(300); gsm.print(F("AT+CMGF=1\r")); //устанавливает текстовый режим смс-сообщения delay(300); gsm.print(F("AT+IFC=1, 1\r")); //устанавливает программный контроль потоком передачи данных delay(300); gsm.print(F("AT+CPBS=\"SM\"\r")); //открывает доступ к данным телефонной книги SIM-карты delay(300); //gsm.print(F("AT+GSMBUSY=1, 1\r")); //запрет всех входящих звонков // delay(300); gsm.print(F("AT+CNMI=1,2,2,1,0\r")); //включает оповещение о новых сообщениях delay(300);} che=EEPROM.read(10); TkritMin=EEPROMReadInt(11); TkritMax=EEPROMReadInt(13); TkritFlag=EEPROM.read(15); RC.enableReceive(0); // Receiver on interrupt 0 => that is pin #2 for(int i = 0; i <= numPins -1; i++) { //восставновление состояния реле pinMode(Pins[i],OUTPUT); PinStatus[i]=EEPROM.read(i); //считываем состояние до перезагрузки ардуины digitalWrite(Pins[i],PinStatus[i]); //восстанавливаем состояние реле } for(int i = 0; i <= numRC -1; i++) { //для отправки смс loopTime[i] = 0; } TimePrint = 0; loopTimeTemp = 0; Serial.println(F("GOTOVO")); } void loop() { currentTime = millis(); // считываем время, прошедшее с момента запуска программы dallRead(flagDallRead * 1000); if (Serial.available()) { //обработка Serial данных while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val2 += char(ch); delay(10); } Serial.println(val2); val1=master1; razborkomand(); val2=""; val1=""; //очищаем } if (gsm.available()) {//если модуль что то шлет while(gsm.available()) { ch = gsm.read(); if(ch == '\r') continue; if(ch == '\n') { gsmRead(val); val = ""; } else val += char(ch); } } if (RC.available()) { //Обработка беспроводных датчиков if (che == 1) { //обработа сигналов с беспроводных датчиков ch = RC.getReceivedValue(); for(int i = 0; i <= numRC -1; i++) { if (ch == RCvalue[i]) { if (currentTime >= loopTime[i]) { loopTime[i] = currentTime + zaderjkaSignSMS; Alarm(RCvalueName[i]); for(int n = 0; n <= numRC -1; n++) { if (n!=i) { loopTime[n] = 0; } } } } } } RC.resetAvailable(); } if (TkritFlag) { //если TkritFlag=true, заходим в оповещения о крит температуре for(byte n = 0; n <= numDS-1; n++) //перебор всех темп. датчиков { if (Temp[n]!=-0.06 && Temp[n]!=0.00) { if ((Temp[n] <= TkritMin) || (Temp[n] >= TkritMax)) { if (currentTime >= loopTimeTemp) { TempStatus(master1); loopTimeTemp = currentTime + zaderjkaTempSMS; } } } } } { //Печать данных в монитор. нужно только для отладки. из конечного устройства вырезать if (currentTime >= TimePrint) { TimePrint = currentTime+15000; Serial.print(F("Temp1=")); Serial.println(Temp[0]); Serial.println(F("- - - - - -")); } } } void Alarm(String zona) { sms = "Trevoga!"; sms += zona; smssend(master1); Serial.println(F("Trevoga! ")); Serial.println(zona); } void razborkomand () { if (val1.indexOf(master1) > -1) //на команды в этом блоке придет ответ { if (val2.indexOf("Pozvoni") > -1) Proslushka(master1); //если в сообщении "позвони", ардуинка звонит нам на номер, с которого пришел запрос if (val2.indexOf("Temp?") > -1) TempStatus(master1); //если в сообщении "температура?", ардуинка высылает температуры на номер, с которого пришел запрос if (val2.indexOf("Tkriton") > -1) TkritONOFF(true, master1); // {TkritFlag = true; EEPROM.write(15,TkritFlag);Serial.println("Tkriton");} if (val2.indexOf("Tkritoff") > -1) TkritONOFF(false, master1); // {TkritFlag = false; EEPROM.write(15,TkritFlag);Serial.println("Tkritoff");} if (val2.indexOf("Off") > -1) AlarmSet(0, master1, String ("OFF")); //если в сообщении "OFF", ардуинка выключает режим сигнализации и отправляет смс с оповещением о сняьтт с сигнализации тому, кто прислал команду if (val2.indexOf("On") > -1) AlarmSet(1, master1, String ("ON")); //если в сообщении "ON", ардуинка включает режим сигнализации и отправляет смс с оповещением о постановке на сигнализацию тому, кто прислал команду if (val2.indexOf("Vkl") > -1) { //если в сообщении "вкл1234", включить реле №1 и №2 и №3 и №4 sms = "Vklucheno "; if (val2.indexOf("1")> -1) RelaySet(1, ON); if (val2.indexOf("2")> -1) RelaySet(2, ON); if (val2.indexOf("3")> -1) RelaySet(3, ON); if (val2.indexOf("4")> -1) RelaySet(4, ON); if (val2.indexOf("5")> -1) RelaySet(5, ON); if (val2.indexOf("6")> -1) RelaySet(6, ON); smssend(master1); } if (val2.indexOf("Vikl") > -1) { //если в сообщении "выкл1234", выключить реле №1 и №2 и №3 и №4 sms = "Viklucheno "; if (val2.indexOf("1")> -1) RelaySet(1, OFF); if (val2.indexOf("2")> -1) RelaySet(2, OFF); if (val2.indexOf("3")> -1) RelaySet(3, OFF); if (val2.indexOf("4")> -1) RelaySet(4, OFF); if (val2.indexOf("5")> -1) RelaySet(5, OFF); if (val2.indexOf("6")> -1) RelaySet(6, OFF); smssend(master1); } } if (val2.indexOf("Tkritmin") > -1) {val1= val2.substring(9, 14); Serial.println(val1); TkritMin = val1.toInt(); Serial.println(TkritMin); EEPROMWriteInt(11,TkritMin);} if (val2.indexOf("Tkritmax") > -1) {val1= val2.substring(9, 12); Serial.println(val1); TkritMax = val1.toInt(); Serial.println(TkritMax); EEPROMWriteInt(13,TkritMax);} } void TkritONOFF (boolean onoff, String phone) { TkritFlag = onoff; EEPROM.write(15,TkritFlag); Serial.println(TkritFlag); if (TkritFlag) { sms = "TKrit VKL"; sms += '\n'; sms += "Tmin "; sms += TkritMin; sms += '\n'; sms += "Tmax "; sms += TkritMax; } if (TkritFlag==false) { sms = "TKrit VIKL"; } smssend(phone); } void gsmRead(const String val) { //разбираем данные от gsm if (!val.startsWith("+CMT") && isStringMessage == false ) {Serial.println(val);} //если НЕ смс и это не вторая строка(которая является непосредственно сообщением), значит это иная информация от модуля. выводим в сериал if (isStringMessage == true) // если флаг "ПРАВДА", значит дошли до строки с сообщением { isStringMessage = false; // меняем флаг на "ЛОЖЬ", чтобы при обработке последующей информации, не относящейся к сообщению, в этот кусок не попасть снова if (val1.indexOf(master1) > -1) // Если в первой строке VAL1 есть мастер(или один из номеров) номер { Serial.println(F("master")); //в сериал шлется, что сообщение от мастера val2 = val; // сохраняем в переменную Serial.print(F("VAL2: ")); // выводим в сериал Serial.println(val2); razborkomand(); // разбираем что за команда пришла } else Serial.println(F("NE master")); } else { if (val.startsWith("+CMT")) // если текущая строка начинается с "+CMT", то следующая строка является сообщением; { val1=val; isStringMessage = true; //флаг означающий, что следующая строка сообщение Serial.println(F("VAL1: ")); // выводим в сериал Serial.println(val1); } } } void smssend(String phone) { //процедура отправки СМС // Serial.print(sms); Serial.println(F(phone); Serial.println(F("SMS send started")); gsm.print(F("AT+CMGF=1\r")); delay(100); gsm.print(F("AT + CMGS = \"+")); gsm.print(phone); gsm.println(F("\"")); delay(100); gsm.print(sms); // text = ""; delay(100); gsm.print((char)26); delay(100); Serial.println(F("SMS send complete")); sms=""; } void Proslushka(String phone){ //Цикл дозвона абоненту (для аудиоконтроля)___________________ gsm.println(F("AT+CMIC=0,10")); // Команда для установки чувствительности микрофона Поэкспериментировать с цифрой. // 0,- это канал микрофона (1,2,3),15 это уровень см.инструкцию к СИМ900 delay(2000); gsm.print(F("ATD+")); // Набираем номер gsm.print(phone); gsm.println(F(";")); //Serial2.println("ATH"); // Вешаем трубку } void RelaySet(byte rnum, byte state) { //управление реле PinStatus[(rnum-1)] = state; digitalWrite(Pins[(rnum-1)],PinStatus[(rnum-1)]); EEPROM.write((rnum-1),PinStatus[(rnum-1)]); //запись в энергонезависимую память состояния реле для вооставноления этого состояния после потери питания sms += rnum; } void AlarmSet(int vklvikl, String phone, String onoff) { che = vklvikl; EEPROM.write(10,che); sms=onoff; smssend(phone); } void TempStatus(String phone) { sms = ""; for(byte n = 0; n <= numDS-1; n++) { sms += "T"; sms += (n+1); sms += " "; sms += Temp[n]; sms += "C"; sms += '\n'; } smssend(phone); sms = ""; } void EEPROMWriteInt(int address, int value) { //Запись двухбайтового числа в память EEPROM.write(address, lowByte(value)); EEPROM.write(address + 1, highByte(value)); } unsigned int EEPROMReadInt(int address) { //Чтение числа из памяти byte lowByte = EEPROM.read(address); byte highByte = EEPROM.read(address + 1); return (highByte << 8) | lowByte; } void dallRead(unsigned long interval){ //температура static unsigned long prevTime = 0; if (millis() - prevTime > interval) { //Проверка заданного интервала static boolean flagDall = 0; //Признак операции prevTime = millis(); flagDall =! flagDall; //Инверсия признака if (flagDall) { ds.reset(); ds.write(0xCC); //Обращение ко всем датчикам ds.write(0x44); //Команда на конвертацию flagDallRead = 1; //Время возврата в секундах } else { byte i; int temp; for (i = 0; i < 3; i++){ //Перебор количества датчиков ds.reset(); ds.select(addr[i]); ds.write(0xBE); //Считывание значения с датчика temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры Temp[i] = (float)temp / 16.0; flagDallRead = 2; //Время возврата в секундах } } } }попытка с прогмен:
#include <SoftwareSerial.h> #include <avr/wdt.h> #include <avr/pgmspace.h> #include <OneWire.h> #include <EEPROM.h> #include <RCSwitch.h> SoftwareSerial gsm(7, 8); OneWire ds(10); RCSwitch RC = RCSwitch(); unsigned long TimePrint; // из конечного устройства можно убрать int che=1; // //Сигнализация unsigned long loopTime[4]; //указать количество беспроводных датчиков сигнализации unsigned long currentTime; unsigned long zaderjkaSignSMS = 10000;//интервал между сообщениями сигнализации 1000=1секунда //Беспроводные датчики byte numRC = 4; //количество беспроводных датчиков сигнализации int RCvalue[4] = {12410657,12410658,12410660,12410664}; //добавить коды всех датчиков через запятую String RCvalueName [4] = {"Kuhn9","Dver' vhod","Dver' garaj","Luk"}; //названия должны соответствовать кодам датчиков из предыдущей строки //датчики температуры DS18B20 //____НЕОБХОДИМО ПРОПИСАТЬ АДРЕСА СВОИХ ДАТЧИКОВ______ byte flagDallRead; byte addr[1][8]={{0x28,0xBC,0x74,0x03,0x00,0x00,0x80,0x12}}; //в первых скобках [] скобках необхлодимо указать сколько у вас DS18B20 и в фигурных скобках прописать их адреса {{},{}.....{},{}} byte numDS = 1; // количество DS18B20. float Temp[1]; //в скобках указать количество ваших DS18B20 bool TkritFlag = true; int TkritMax; int TkritMin; unsigned long loopTimeTemp; unsigned long zaderjkaTempSMS = 30000;//000; //интервал между сообщениями о критической температуре 1000=1секунда //ДЛЯ GSM и около него boolean isStringMessage = false; // Переменная принимает значение True, если текущая строка является сообщением int ch; String sms = ""; String val = ""; String val1 = ""; //переменная для хранения технической информации сообщения/звонка (номер, время) String val2 = ""; //переменная для хравнения содержания полученной СМСки String master1 = "7916xxxxxxx"; //ваш номер byte PIN_PWRKEY = 9; //пин включения sim900 const char string_0[] PROGMEM = "AT+CMGF=1\r"; const char string_1[] PROGMEM = "AT+IFC=1, 1\r"; const char string_2[] PROGMEM = "AT+CPBS=\"SM\"\r"; const char string_3[] PROGMEM = "AT+CMGDA=\"DEL ALL\"\r"; const char string_4[] PROGMEM = "AT+CNMI=1,2,2,1,0\r"; const char string_5[] PROGMEM = "AT + CMGS = \"+"; const char string_6[] PROGMEM = "AT+CMIC=0,10"; const char string_7[] PROGMEM = "ATD+"; const char string_8[] PROGMEM = "AT+CMGD=1,4\r"; const char* const string_table[] PROGMEM = {string_0, string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8}; char buffer[30]; //ДЛЯ РЕЛЕ byte Pins[6] = {14, 15, 16, 17,18,19}; // Массив задействованных номеров Pins Arduino, для управления реле. byte PinStatus[6]; // Массив для фиксации изменений byte numPins = 6; // количество реле byte ON = HIGH; //для проверки работоспособности на светодиодах ON=HIGH, для реле ON=LOW byte OFF = LOW; //для проверки работоспособности на светодиодах OFF=LOW, для реле OFF=HIGH void reboot() { wdt_disable(); wdt_enable(WDTO_15MS); while (1) {} } void setup() { pinMode(12, INPUT); Serial.begin(9600); Serial.println(F("START")); pinMode(19, OUTPUT); digitalWrite(19,LOW); {// GSM if (digitalRead(12)==LOW) //пин12 мониторит включенность ГСМ(напругу на светодиоде status). если ГСМ выключен, то после включения ардуина перезагружается и загружается при ключенном ГСМ { Serial.println(F("Budet RESET")); pinMode(9, OUTPUT); digitalWrite(9,LOW); delay(1000); digitalWrite(9,HIGH); delay(2000); digitalWrite(9,LOW); delay(15000); reboot(); delay(500); } gsm.begin(19200); //gsm.println("AT+IPR=19200\r"); delay(100); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0]))); //gsm.print(F("AT+CMGF=1\r")); gsm.print(buffer); //устанавливает текстовый режим смс-сообщения delay(300); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[1]))); //gsm.print(F("AT+IFC=1,1\r")); gsm.print(buffer); //устанавливает программный контроль потоком передачи данных delay(300); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[2]))); //gsm.print(F("AT+CPBS=\"SM\"\r")); gsm.print(buffer); //открывает доступ к данным телефонной книги SIM-карты delay(300); //gsm.print(F("AT+GSMBUSY=1, 1\r")); //запрет всех входящих звонков // delay(300); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[3]))); //gsm.print(F("AT+CMGDA=\"DEL ALL\"\r")); gsm.print(buffer); //Очищаем накопившиеся СМС delay(300); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[8]))); //gsm.print(F("AT+CMGD=1,4\r")); gsm.print(buffer); //включает оповещение о новых сообщениях delay(300);} che=EEPROM.read(10); TkritMin=EEPROMReadInt(11); TkritMax=EEPROMReadInt(13); TkritFlag=EEPROM.read(15); RC.enableReceive(0); // Receiver on interrupt 0 => that is pin #2 for(int i = 0; i <= numPins -1; i++) { //восставновление состояния реле pinMode(Pins[i],OUTPUT); PinStatus[i]=EEPROM.read(i); //считываем состояние до перезагрузки ардуины digitalWrite(Pins[i],PinStatus[i]); //восстанавливаем состояние реле } for(int i = 0; i <= numRC -1; i++) { //для отправки смс loopTime[i] = 0; } TimePrint = 0; loopTimeTemp = 0; Serial.println(F("GOTOVO")); } void loop() { currentTime = millis(); // считываем время, прошедшее с момента запуска программы dallRead(flagDallRead * 1000); if (Serial.available()) { //обработка Serial данных while (Serial.available()) { //сохраняем строку в переменную val ch = Serial.read(); val2 += char(ch); delay(10); } Serial.println(val2); val1=master1; razborkomand(); val2=""; val1=""; //очищаем } if (gsm.available()) {//если модуль что то шлет while(gsm.available()) { ch = gsm.read(); if(ch == '\r') continue; if(ch == '\n') { gsmRead(val); val = ""; } else val += char(ch); } } if (RC.available()) { //Обработка беспроводных датчиков if (che == 1) { //обработа сигналов с беспроводных датчиков ch = RC.getReceivedValue(); for(int i = 0; i <= numRC -1; i++) { if (ch == RCvalue[i]) { if (currentTime >= loopTime[i]) { loopTime[i] = currentTime + zaderjkaSignSMS; Alarm(RCvalueName[i]); for(int n = 0; n <= numRC -1; n++) { if (n!=i) { loopTime[n] = 0; } } } } } } RC.resetAvailable(); } if (TkritFlag) { //если TkritFlag=true, заходим в оповещения о крит температуре for(byte n = 0; n <= numDS-1; n++) //перебор всех темп. датчиков { if (Temp[n]!=-0.06 && Temp[n]!=0.00) { if ((Temp[n] <= TkritMin) || (Temp[n] >= TkritMax)) { if (currentTime >= loopTimeTemp) { TempStatus(master1); loopTimeTemp = currentTime + zaderjkaTempSMS; } } } } } { //Печать данных в монитор. нужно только для отладки. из конечного устройства вырезать if (currentTime >= TimePrint) { TimePrint = currentTime+15000; Serial.print(F("Temp1=")); Serial.println(Temp[0]); Serial.println(F("- - - - - -")); } } } void Alarm(String zona) { sms = "Trevoga!"; sms += zona; smssend(master1); Serial.println(F("Trevoga! ")); Serial.println(zona); } void razborkomand () { if (val1.indexOf(master1) > -1) //на команды в этом блоке придет ответ { if (val2.indexOf("Pozvoni") > -1) Proslushka(master1); //если в сообщении "позвони", ардуинка звонит нам на номер, с которого пришел запрос if (val2.indexOf("Temp?") > -1) TempStatus(master1); //если в сообщении "температура?", ардуинка высылает температуры на номер, с которого пришел запрос if (val2.indexOf("Tkriton") > -1) TkritONOFF(true, master1); // {TkritFlag = true; EEPROM.write(15,TkritFlag);Serial.println("Tkriton");} if (val2.indexOf("Tkritoff") > -1) TkritONOFF(false, master1); // {TkritFlag = false; EEPROM.write(15,TkritFlag);Serial.println("Tkritoff");} if (val2.indexOf("Off") > -1) AlarmSet(0, master1, String ("OFF")); //если в сообщении "OFF", ардуинка выключает режим сигнализации и отправляет смс с оповещением о сняьтт с сигнализации тому, кто прислал команду if (val2.indexOf("On") > -1) AlarmSet(1, master1, String ("ON")); //если в сообщении "ON", ардуинка включает режим сигнализации и отправляет смс с оповещением о постановке на сигнализацию тому, кто прислал команду if (val2.indexOf("Vkl") > -1) { //если в сообщении "вкл1234", включить реле №1 и №2 и №3 и №4 sms = "Vklucheno "; if (val2.indexOf("1")> -1) RelaySet(1, ON); if (val2.indexOf("2")> -1) RelaySet(2, ON); if (val2.indexOf("3")> -1) RelaySet(3, ON); if (val2.indexOf("4")> -1) RelaySet(4, ON); if (val2.indexOf("5")> -1) RelaySet(5, ON); if (val2.indexOf("6")> -1) RelaySet(6, ON); smssend(master1); } if (val2.indexOf("Vikl") > -1) { //если в сообщении "выкл1234", выключить реле №1 и №2 и №3 и №4 sms = "Viklucheno "; if (val2.indexOf("1")> -1) RelaySet(1, OFF); if (val2.indexOf("2")> -1) RelaySet(2, OFF); if (val2.indexOf("3")> -1) RelaySet(3, OFF); if (val2.indexOf("4")> -1) RelaySet(4, OFF); if (val2.indexOf("5")> -1) RelaySet(5, OFF); if (val2.indexOf("6")> -1) RelaySet(6, OFF); smssend(master1); } } if (val2.indexOf("Tkritmin") > -1) {val1= val2.substring(9, 14); Serial.println(val1); TkritMin = val1.toInt(); Serial.println(TkritMin); EEPROMWriteInt(11,TkritMin);} if (val2.indexOf("Tkritmax") > -1) {val1= val2.substring(9, 12); Serial.println(val1); TkritMax = val1.toInt(); Serial.println(TkritMax); EEPROMWriteInt(13,TkritMax);} } void TkritONOFF (boolean onoff, String phone) { TkritFlag = onoff; EEPROM.write(15,TkritFlag); Serial.println(TkritFlag); if (TkritFlag) { sms = "TKrit VKL"; sms += '\n'; sms += "Tmin "; sms += TkritMin; sms += '\n'; sms += "Tmax "; sms += TkritMax; } if (TkritFlag==false) { sms = "TKrit VIKL"; } smssend(phone); } void gsmRead(const String val) { //разбираем данные от gsm if (!val.startsWith("+CMT") && isStringMessage == false ) {Serial.println(val);} //если НЕ смс и это не вторая строка(которая является непосредственно сообщением), значит это иная информация от модуля. выводим в сериал if (isStringMessage == true) // если флаг "ПРАВДА", значит дошли до строки с сообщением { isStringMessage = false; // меняем флаг на "ЛОЖЬ", чтобы при обработке последующей информации, не относящейся к сообщению, в этот кусок не попасть снова if (val1.indexOf(master1) > -1) // Если в первой строке VAL1 есть мастер(или один из номеров) номер { Serial.println(F("master")); //в сериал шлется, что сообщение от мастера val2 = val; // сохраняем в переменную Serial.print(F("VAL2: ")); // выводим в сериал Serial.println(val2); razborkomand(); // разбираем что за команда пришла } else Serial.println(F("NE master")); } else { if (val.startsWith("+CMT")) // если текущая строка начинается с "+CMT", то следующая строка является сообщением; { val1=val; isStringMessage = true; //флаг означающий, что следующая строка сообщение Serial.println(F("VAL1: ")); // выводим в сериал Serial.println(val1); } } } void smssend(String phone) { //процедура отправки СМС // Serial.print(sms); Serial.println(F(phone); Serial.println(F("SMS send started")); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[0]))); //"AT+CMGF=1\r" gsm.print(buffer); delay(100); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[5]))); //"AT + CMGS = \"+" gsm.print(buffer); gsm.print(phone); gsm.println(F("\"")); delay(100); gsm.print(sms); // text = ""; delay(100); gsm.print((char)26); delay(100); Serial.println(F("SMS send complete")); sms=""; } void Proslushka(String phone){ //Цикл дозвона абоненту (для аудиоконтроля)___________________ strcpy_P(buffer, (char*)pgm_read_word(&(string_table[6]))); //"AT+CMIC=0,10" gsm.println(buffer); // Команда для установки чувствительности микрофона Поэкспериментировать с цифрой. // 0,- это канал микрофона (1,2,3),15 это уровень см.инструкцию к СИМ900 delay(1000); strcpy_P(buffer, (char*)pgm_read_word(&(string_table[7]))); //"ATD+" gsm.print(buffer); // Набираем номер gsm.print(phone); gsm.println(F(";")); //Serial2.println("ATH"); // Вешаем трубку } void RelaySet(byte rnum, byte state) { //управление реле PinStatus[(rnum-1)] = state; digitalWrite(Pins[(rnum-1)],PinStatus[(rnum-1)]); EEPROM.write((rnum-1),PinStatus[(rnum-1)]); //запись в энергонезависимую память состояния реле для вооставноления этого состояния после потери питания sms += rnum; } void AlarmSet(int vklvikl, String phone, String onoff) { che = vklvikl; EEPROM.write(10,che); sms=onoff; smssend(phone); } void TempStatus(String phone) { sms = ""; for(byte n = 0; n <= numDS-1; n++) { sms += "T"; sms += (n+1); sms += " "; sms += Temp[n]; sms += "C"; sms += '\n'; } smssend(phone); sms = ""; } void EEPROMWriteInt(int address, int value) { //Запись двухбайтового числа в память EEPROM.write(address, lowByte(value)); EEPROM.write(address + 1, highByte(value)); } unsigned int EEPROMReadInt(int address) { //Чтение числа из памяти byte lowByte = EEPROM.read(address); byte highByte = EEPROM.read(address + 1); return (highByte << 8) | lowByte; } void dallRead(unsigned long interval){ //температура static unsigned long prevTime = 0; if (millis() - prevTime > interval) { //Проверка заданного интервала static boolean flagDall = 0; //Признак операции prevTime = millis(); flagDall =! flagDall; //Инверсия признака if (flagDall) { ds.reset(); ds.write(0xCC); //Обращение ко всем датчикам ds.write(0x44); //Команда на конвертацию flagDallRead = 1; //Время возврата в секундах } else { byte i; int temp; for (i = 0; i < 3; i++){ //Перебор количества датчиков ds.reset(); ds.select(addr[i]); ds.write(0xBE); //Считывание значения с датчика temp = (ds.read() | ds.read()<<8); //Принимаем два байта температуры Temp[i] = (float)temp / 16.0; flagDallRead = 2; //Время возврата в секундах } } } }а в монитор вот такое лезет:
Здравствуйте!
Прошу новичка сильно не пинать. Хочу организовать передачу данных по MODBUS TCP через SIM900 на сервер.
Сервер выступает как Slave.
В SIM900 стоит симка МТС, на тарифе Коннкект-4 с опцией "МТС планшет мини", где 17 Мб бесплатно.
IMEI SIM900 прошил от планшета, теперь связь до 17 Мб в сутки бесплатно.
Написал соединение с сервером по IP и порту 502, в результате в терминале вижу, что подключение происходит.
Есть также программа, которая передает-принимает данные на сервер по MODBUS TCP через Ethernet модуль.
Хочу соединение через Ethernet модуль заменить соединением через SIM900.
Заменил в программе всю передачу-прием данных с Ethernet модуля на SIM900, соединение поднимается, данные идут, но скорее некорректные, т.к. сервер никак не реагирует. Так как данные мы уже передаем по порту(который уже соединен по TCP), надо наверно вместо MODBUS TCP поднимать просто Modbus по порту? Или проще использовать для приема-передачи библиотеку? У кого был подобный опыт, прошу помощи.
Приветствую!
Пришел к такому вопросу, что SIM900 не отправляет данные на сервер.
Порядок действий:
mySerial.println("AT"); delay(1000); ShowSerialData(); mySerial.println("AT+CREG?"); // Проверка регистрации в сети delay(2000); ShowSerialData(); mySerial.println("AT+CGATT?"); // Проверка регистрации в GPRS сети delay(2000); ShowSerialData(); mySerial.println("AT+CIPSTATUS"); // Инициализируем IP стек. delay(2000); ShowSerialData(); mySerial.println("AT+CSTT=\"internet.mts.ru\",\"mts\",\"mts\""); // Устанавливаем установки соединения с нитернетом. delay(2000); ShowSerialData(); mySerial.println("AT+CIICR"); // Открываем GPRS соединение. delay(2000); ShowSerialData(); mySerial.println("AT+CIFSR"); // Получаем локальный IP адрес. delay(2000); ShowSerialData(); mySerial.println("AT+CIPSTART=\"TCP\",\"XX.XX.XX.XX\",\"502\""); // Подключаемся к серверу. delay(2000); ShowSerialData(); mySerial.println("AT+CIPSEND"); // Запрос на посылку сообщения серверу delay(1000); ShowSerialData(); byte data[] = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x01, 0x00, 0xE0 }; // Массив передачи в 16-ричном виде. mySerial.write(data, 12); // Передаем в модуль. delay(100); mySerial.write((char)26); // Команда на передачу данных на сервер. delay(1000); ShowSerialData(); .................................... void ShowSerialData() { while(mySerial.available()!=0) Serial.write(mySerial.read()); }Сервер видит подключение, пишет, что подключился такой-то клиент, но данные на сервер не идут... Пробовал в ручном режиме, после отправки самих данных в модуль и команды 26 - все наглухо виснет. Модуль не реагирует даже на команду AT, пока на него не позвонишь.
На входящий звонок он выдает сообщение "ERROR" и далее информацию о звонке. Сбросив звонок, модуль снова начинает реагировать на команды, пока опять не дашь команду AT+CIPSEND, появляется > и снова данные, далее команда 26, и тишина.
Что я делаю не так?
Питание модуля отличное, симка рабочая, а данные не идут. Через модуль Ethernet эти же данные на сервер идут на ура.
Разобрался. Оказывается GPRS пакеты на отправляются с СИМ-картой оператора МТС, несмотря на то, что соединение устанавливается. Сейчас все работает с Мегафоном. Для бесплатного пользования GPRS подключайте тариф "Интернет планшет ХС" (600 Мб интернета в месяц бесплатно), программируйте IMEI модуля командой AT+SIMEI="xxxxxxxxxxxxxxx", где xxx.... должен быть IMEI планшета, например 860944020813422. Перед прошивкой обязательно проверьте IMEI на сайте http://imeidata.net IMEI ищите на прострах интернета, есть базы с корректными номерами, а также возможность правильного составления IMEI.
Всем Удачи!
Обнаружился один недостаток SIM900.
Если отправлять данные в формате Modbus TCP, пример данных (0,1,0,0,0,6,1,6,0,0,0,0x1A), где 0x1A(0x1B) - данные, (в десятичном виде 26 или 27), то модуль обрежет пакет, приняв данные за команду отправки данных на сервер (26), или команду отмены отправки данных на сервер (27).
Получается, через SIM900 можно отправить любоые значения кроме 0x1A (26) и 0x1B (27).
Для того, чтобы обойти это ограничение, необходимо присвоить конкретную длину пакета данных. В данном случае AT+CIPSEND=12. И пакет отправится автоматически при достижении данной длины оправляемых данных. Команд конца строки 0x1A посылать не надо.
При работе в сети Биллайн GPRS по протоколу TCP/IP, соединяясь с сервером, пакеты также невозможно отправить, как и в сети МТС. При этом входящие пакеты будут приходить. К сожалению, Мегафон возможность подключения к тарифу Планшет без забот, закрыл, оставив возможность подключения к данному тарифу только при покупке планшета.
Люди помогите!!!!! Не видит СИМ карту, уже чего только не пробывал! И пропоял sim holder, и протел все спиртом, и пробывал перепрошивать, На AT выдает Ok, на все команды реагирует, за исключением рабочих с картой, но симку ни как. Что можно сделать подскажите пожааааааааалуйста!!!
Шилд китайский
Привет, rodger.
Работал с данным шилдом. Был первый по части экспериментов. Не так требователен к питанию, как например sim800l с одним конденсатором на борту, но в достаточной мере, поэтому проверь, у Тебя питание медными проводами идет пайкой на плату, или хрень-перемычкой? Я подавал со стабилизарованного испочника питания 1А 4,1В плюс аккумуляторная батарея на 4,1В плюс электролит на 1500 мкФ и в параллели 100мкФ керамики, все это 0,5 проводом длиной 5см сразу пайкой на плату.
Недостаточное питание - 100% невозможность регистрации в сети, отсюда признаки нерабочей симки, а также постоянная перезагрузка модуля.
Недостаточное питание у меня было с лабораторного стабиллизированного блока питания на 5А 4,1В, 0,75 проводом, но подцепил его через хрень-перемычку 10см длиной, что обычно используются в макетках.
Как только выкинул перемычку - все заработало.
Если это не поможет - тогда плата, но этой модификации неисправных плат не встречал, брака не было.
1 Припаял все на плату проводом 0,5 - не помогло! Но я, если честно, сомневаюсь что дело в питании, потому что: при включении модуля просадки по питанию нет, В COM порт выдает сразу что симка не установлена:
Только включил и сразу:
Да, похоже на то, что с платой дело... Симки ты конечно повтыкал разные, собрав их у домочадцев. И сим-карту ты конечно правильно ставишь, а то у меня был случай, когда я микросим в защелкивающийся слот не тем концом вставлял, т.к. контактов в слоте не видно.
Прозвонил контакты сим-карты на ножки самого напаянного модуля Sim900 ?
В режиме регистрации в сети потребление примерно 40-85 мА.
В режиме соединения с сервером и постоянной пересылки пакетов, модуль потребляет примерно 110-120мА на напряжении 4,1В.
1) Да!
2) Да!
3) При включении ток 65-85 мА.
4) До этого дело не доходит.
Данная модификация в России стоит около 1800-2000 руб.
Модификация голой sim800L с керамическим конденсатором на борту или версии 2.0 с согласованием уровней Tx Rx, стоит 200-450 руб на Aliexpress. Обе модификации рабочие, но предпочтительней версии 2.0. Заказывайте, и будет Вам счастье.
Спасибо, я эту штуку на алике за 800 р. взял. Буду теперь расматривать Ваш вариант. Спасибо огромное за поомощь, успехов во всем!!!