GSM(SIM900) + SD
- Войдите на сайт для отправки комментариев
Два дня бьюсь с какой-то странной ситуацией.
Есть плата GBoard: http://iteadstudio.com/store/images/produce/Platform/ArduinoCom/GBoard/GBoard_DS.pdf
На борту GSM-модуль (SIM900), SD карта и интерфейс для nRF24L01+ (аппаратный SPI, CS=10 и CS=9 соответственно).
Для работы с GSM-Модулем используется библиотека: http://code.google.com/p/gsm-shield-arduino/downloads/list (версия 3.09)
Для работы с SD используется библиотека SDFat (где взял, уже не помню) или библиотека SD (аналогично не помню, отуда взял).
Примеры работают без проблем - все четко (в Serial превосходно отдают отладочные сообщения и т.п.). Но только, если работают по отдельности...
Как только начинаю объединять два примера в один скетч - все, "приехали". В ком-порт практически ничего не появляется (изредка приходят отладочные сообщения от GSM-модуля, но крайне редко).
Простенький скетч для примера:
// GSM
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "sms.h"
// SD
#include <SPI.h>
#include <SD.h>
const uint8_t SDchipSelect = 10;
SMSGSM sms;
Sd2Card card;
boolean gsmstarted=false; // флаг того, что GSM стартовал
void setup()
{
Serial.begin(9600);
Serial.println("GSM-SD testing.");
// включим GSM
pinMode(6, OUTPUT);
digitalWrite(6, HIGH);
if (gsm.begin(9600)){
Serial.println("\nstatus=READY");
gsmstarted=true;
}
else Serial.println("\nstatus=IDLE");
if(gsmstarted){
Serial.println("GSM OK");
}
if (!SD.begin(SDchipSelect)) {
Serial.println("Card failed, or not present");
}
else
Serial.println("Card initialized.");
}
void loop() {}
в ком-порт не приходит даже строка "GSM-SD testing."
В чем "грабли"? Куда копать?
А перемычки UART Setting как установлены? Как я помню если использовать библу <SoftwareSerial.h> то нужно указать ноги RX и TX...
Перемычки стоят как во второй картинке в даташите:
ST – D2(Software Rx/Tx of Arduino)
SR – D3(Software Rx/Tx of Arduino)
И стоят они, похоже, правильно (ведь по отдельности примеры из библиотек работают без проблем). Удивительно то, что когда примеры объединяются - в последовательный порт толком ничего не отдается.
Есть какие-нибудь мысли, которые бы прояснили ситуацию с выводом данных в последовательный порт? Почему по отдельности скетчи работают (и выдают отладочную информацию), а вот вместе "партизанят" и ничего не отдают?
Хотя бы в какую сторону копать?
Если из скетча, что привел выше выбросить или SD или GSM часть - все работает нормально...
P.S. библиотеку SDFat брал отсюда: http://code.google.com/p/sdfatlib/
Интересная тема, подключусь. Жду такую же плату и мне наверно будет сложнее, хочу и XBee использовать и GSM и nRF24L01
На какие пины джамперами подключен UART GSM модуля? На 0-1 или на 2-3? Мне видится, что есть конфликт двух UART
Перемычки стоят как во второй картинке в даташите:
ST – D2(Software Rx/Tx of Arduino)
SR – D3(Software Rx/Tx of Arduino)
Вопрос, почему они не конфликтуют по отдельности, но абсолютно не работоспособны вместе?
P.S. библиотеку для nRF24L01+ не подключаю, пока не разберусь с работой GSM и SD... как разберусь, и беспроводной модуль будет задействован.
Перемычки стоят как во второй картинке в даташите:
ST – D2(Software Rx/Tx of Arduino)
SR – D3(Software Rx/Tx of Arduino)
Вопрос, почему они не конфликтуют по отдельности, но абсолютно не работоспособны вместе?
P.S. библиотеку для nRF24L01+ не подключаю, пока не разберусь с работой GSM и SD... как разберусь, и беспроводной модуль будет задействован.
Если GSM подключен к софтверному UART то зачем использовать SoftwareSerial?
Замени SoftwareSerial на Serial и проверь. По идее в библиотеке GSM должна быть возможность выбора пинов через которые работать. Если не заработает - переключи GSM на D0/D1 и верни обратно SoftwareSerial только его нужно явно инициализировать на пины 2 и 3
Вы как то проигнарировали эту фразу
Как я помню если использовать библу <SoftwareSerial.h> то нужно указать ноги RX и TX...
// GSM #include "SIM900.h" #include <SoftwareSerial.h> #include "sms.h" // SD #include <SPI.h> #include <SD.h> const uint8_t SDchipSelect = 10; SoftwareSerial Serial1(2, 3); SMSGSM sms; Sd2Card card; boolean gsmstarted=false; // флаг того, что GSM стартовал void setup() { Serial.begin(9600); Serial.println("GSM-SD testing."); // включим GSM pinMode(6, OUTPUT); digitalWrite(6, HIGH); if (gsm.begin(9600)){ Serial.println("\nstatus=READY"); gsmstarted=true; } else Serial.println("\nstatus=IDLE"); if(gsmstarted){ Serial.println("GSM OK"); } if (!SD.begin(SDchipSelect)) { Serial.println("Card failed, or not present"); } else Serial.println("Card initialized."); } void loop() {}Вы как то проигнарировали эту фразу
Как я помню если использовать библу <SoftwareSerial.h> то нужно указать ноги RX и TX...
пина 2 и 3 сейчас у ТС заведены на GSM
Перемычки стоят как во второй картинке в даташите:
ST – D2(Software Rx/Tx of Arduino)
SR – D3(Software Rx/Tx of Arduino)
оппа... завелось!
Проблема оказалась "железячной".
Если смотреть даташит на плату - то на картинке, где выбираются пины, используются два блока джамперов (два джампера на левом блоке и два - на правом). Производитель почему-то укомплектовал плату всего двумя джамперами (для левого блока), а правый блок был без джамперов...
Как только добавил еще два джампера и полностью воспроизвел картинку - все заработало сразу! Обе библиотеки работают совместно.
P.S. в файле GSM.cpp прописаны пины для GSM-модуля:
Вы как то проигнарировали эту фразу
Как я помню если использовать библу <SoftwareSerial.h> то нужно указать ноги RX и TX...
пина 2 и 3 сейчас у ТС заведены на GSM
Библиотеке SoftwareSerial в любом случае надо знать на каких выводах поднимать UART. Но действительно надо перемычки тогда по другому ставить, что бы GSM оказался на 0 и 1 выводах.
Нда... рано обрадовался.
Похоже, ошибка еще интереснее. Тестовый пример из первого поста - завелся. Но вот если добавить всего одну строчку (просто отправить СМС) - все, "приехали".
sms.SendSMS("+79641234567", "Start Ok");Опять никакой отладочной информации. Если строчку с отправкой СМС закомментировать - опять работает.
Теперь-то на что грешить?
Посмотрел размеры скетчей - разница в (14504 байта и 15602 байта соответственно). Вроде как на недостаток памяти еще рано жаловаться (напомню, используется 328 камушек).
P.S. пины для SoftwareSerial указывал - разницы в поведении скетчей нет.
А питаетесь от USB? Уже несколько раз сталкивался что шилды всяких приемников/передатчиков начинают глючить пока не возьмешь внешний блок питания. Причем именно "плавают" проблемами. Вроде работают, а вроде и нет.
И еще, у SoftwareSerial http://arduino.cc/hu/Reference/SoftwareSerial есть ограничение на каких пинах можно RX использовать. Правда там упоминается что "не на всех" можно на меге и на Leonardo... так что скорее, скорее всего, "дело не в этом", но... может еще и это стоит проверить.
Без нормального внешнего внешнего питания GSM-модуль вообще включаться отказывался. Так что причина не в этом...
не могу никак понять, почему все примеры по отдельности работают, а если их начинаю комбинировать - сразу грабли?
Максимум, чего пока удалось:
- примеры с GSM (звонки, смс);
- примеры с SD (чтение, запись и т.п.)
- подцепить RTC и отправлять смс (где есть дата-время);
- заставить работать беспроводной модуль и отправлять ему команды через СМС
Но вот как только пытаюсь объединить все функции - все, "приехали". Все компилируется, скетчи по объемам вроде как совершенно нормальные...
Я бы на вашем месте для начала подключил GSM модуль к аппаратному UART (к D0 и D1), а програмный использовал бы для вывода в сериал монитор.
Интересно, может, все-таки проблема в размере скетча?
Может ли быть так, что у 328 камня почему-то только "половина памяти"???
Какой памяти?
Я бы на вашем месте для начала подключил GSM модуль к аппаратному UART (к D0 и D1), а програмный использовал бы для вывода в сериал монитор.
Попробвал. Переставил джампера, в файле GSM.cpp поправил номера пинов.
Не работают даже примеры:
Если не работает с аппаратным UART, значит что то не так делаете.
Какой памяти?
флеш-памяти.. той, которой должно быть 32к
А что у вас скейтчи получаются по 16 кБ ???
дык, догадываюсь.. но не понимаю, как сделать правильно и как проверить?
Можете подсказать какой-нибудь простой примерчик, который помог-бы проверить?
Вы вот этот пример проверяли?
// GSM #include "SIM900.h" #include <SoftwareSerial.h> #include "sms.h" // SD #include <SPI.h> #include <SD.h> const uint8_t SDchipSelect = 10; SoftwareSerial Serial1(2, 3); SMSGSM sms; Sd2Card card; boolean gsmstarted=false; // флаг того, что GSM стартовал void setup() { Serial.begin(9600); Serial.println("GSM-SD testing."); // включим GSM pinMode(6, OUTPUT); digitalWrite(6, HIGH); if (gsm.begin(9600)){ Serial.println("\nstatus=READY"); gsmstarted=true; } else Serial.println("\nstatus=IDLE"); if(gsmstarted){ Serial.println("GSM OK"); } if (!SD.begin(SDchipSelect)) { Serial.println("Card failed, or not present"); } else Serial.println("Card initialized."); } void loop() {}Как перемычки ставили?
Какой памяти?
флеш-памяти.. той, которой должно быть 32к
Так "флеш" это аналог "винчестера" у компа,а есть еще оперативка. И у 328-го камня, ее, если не изменяет память, всего 2k
И "сколько ее осталось" не всегда можно сказать точно.
Вот пара ссылок на эту тему
А что у вас скейтчи получаются по 16 кБ ???
угу... :( .. если размер скетча 14к - еще работает, а вот если больше 15к - уже "грабли"
Для начала настройте програмный UART и попробуйте вот этот пример
#include <SoftwareSerial.h> SoftwareSerial Serial1(2, 3); void setup() { Serial1.begin(9600); } void loop() { int sensorValue = analogRead(A0); Serial1.println(sensorValue, DEC); }Что в сериал мониторе?
Вы вот этот пример проверяли?
Да, проверял. Работает, если перемычки стоят как во втором изображении в даташите (Software UART to SIM900, Hardware UART to Specific)
Для начала настройте програмный UART и попробуйте вот этот пример
#include <SoftwareSerial.h> SoftwareSerial Serial1(2, 3); void setup() { Serial1.begin(9600); } void loop() { int sensorValue = analogRead(A0); Serial1.println(sensorValue, DEC); }Что в сериал мониторе?
полная тишина при любом положении перемычек
А что значит при любом положении?
Ну тогда вот так попробуйте
#include <SoftwareSerial.h> SoftwareSerial Serial1(3, 2); void setup() { Serial1.begin(9600); } void loop() { int sensorValue = analogRead(A0); Serial1.println(sensorValue, DEC); }Как в варианте "Hardware UART to SIM900, Software UART to Specific", так и в варианте "Software UART to SIM900, Hardware UART to Specific"
Напомню, речь идет о плате GBoard: http://iteadstudio.com/store/images/produce/Platform/ArduinoCom/GBoard/G...
К компу плата подключается через программатор http://iteadstudio.com/store/images/produce/Shield/Focav2.1/foca.pdf
Ну тогда вот так попробуйте
#include <SoftwareSerial.h> SoftwareSerial Serial1(3, 2); void setup() { Serial1.begin(9600); } void loop() { int sensorValue = analogRead(A0); Serial1.println(sensorValue, DEC); }опять тишина
Какой памяти?
флеш-памяти.. той, которой должно быть 32к
Так "флеш" это аналог "винчестера" у компа,а есть еще оперативка. И у 328-го камня, ее, если не изменяет память, всего 2k
И "сколько ее осталось" не всегда можно сказать точно.
Вот пара ссылок на эту тему
и про это тоже думал уже, попробую посмотреть, какие "объемы" свободны...
У вас что то с библиотекой SoftwareSerial, попробуйте другую скачать, помоему есть какая то новая библа, что то типа NewSoftwareSerial.
У вас что то с библиотекой SoftwareSerial, попробуйте другую скачать, помоему есть какая то новая библа, что то типа NewSoftwareSerial.
Вопреки названию NewSoftwareSerial это как раз "старая библиотека". Она переименовалась в SoftwareSerial и вошла в стандартную поставку ArduinoIDE начиная с версии 1.0
и про это тоже думал уже, попробую посмотреть, какие "объемы" свободны...
миленько...
воспользовался функцией:
int availableMemory() { int size = 2048; // Use 2048 with ATmega328 byte *buf; while ((buf = (byte *) malloc(--size)) == NULL) ; free(buf); return size; }Вывел результаты этой функции последней строчкой в фукнции setup() из первого поста.
Результат впечатляет - 143 (сто сорок три).
провел эксперимент.
Простой скетч:
void setup() { Serial.begin(9600); Serial.println(availableMemory()); } void loop(){}размер скетча - 2954 байта, в результатах вывода - 1795
Теперь чуть усложним:
#include "SIM900.h" #include <SoftwareSerial.h> void setup() { Serial.begin(9600); Serial.println(availableMemory()); } void loop(){}Размер скетча - 9196 байт и в результатах вывода уже скромные 856
Похоже, надо или искать другие библиотеки или писать самому...
А как прошивку делаете плате? У меня такая же, взял преходник для ардуины, которым я arduino mini pro шью, подключил пины 3.3в, GND, RX, TX, DTR. В Arduino IDE выбрал arduino Uno - пишут ошибку при прошивке. Пробовал прямо подключать (rx->rx, tx->tx) и перекресно (rx->tx, tx->rx). ошибка одинаковая
Опишите как вы прошиваете и какой у вас переходник usb<->uart, какую плату выбираете в Arduino IDE?
Надо выбирать arduino duemilanove - у UNO загрузчик другой.
Я шью обычным кабелем USB-COM на чипе Prolific. Пдключаю RX, TX, Землю, ресет жму ручками - всё работает.
Вопрос ко всем - у кого есть какие наработки по этой плате? Залил демо-скетч из стандартной библиотеки - звонок принимает, через 5 секунд даёт отбой, всё ок. Добавляю строчку gsm.SendDTMFSignal(5); после поднятия трубки, звоню, слушаю - в трубке тишина...
Завел на этой плате RF-модуль и с помощью СМС-команд опрашиваю другие модули (эта плата коммуницирует с ними, получет ответ - значение параметров и пуляет ответную СМС с полученным значением). Аналогично работает и управление ведомыми модулями (отправка конкретному модулю конкретную команду - в ответ "ок" или "wrong", если что-то не получилось).
Со звонками пока не заморачивался, еще надо то, что описал выше до нормального вида довести.
Завел на этой плате RF-модуль и с помощью СМС-команд опрашиваю другие модули (эта плата коммуницирует с ними, получет ответ - значение параметров и пуляет ответную СМС с полученным значением). Аналогично работает и управление ведомыми модулями (отправка конкретному модулю конкретную команду - в ответ "ок" или "wrong", если что-то не получилось).
Со звонками пока не заморачивался, еще надо то, что описал выше до нормального вида довести.
поделитесь кодом
Сталкивался с такой проблемой с Icomsat 1.1 от Iteadstudio
псоле подключения питания модуль не хотел запускаться
Serial.println("ERROR: SIM900 doesn't answer. Check power and serial pins in GSM.cpp");
сделал как советуют програмный резет
again: #ifdef BUTTONS #endif Serial.println("system startup"); if (gsm.begin(9600)) Serial.println("\nstatus=READY"); else {Serial.println("\nstatus=IDLE"); pinMode(9, OUTPUT); pinMode(10, OUTPUT); digitalWrite(9, HIGH); // sets the LED on delay(600); // waits for a second digitalWrite(9, LOW); goto again;надежно зависал
поставил дебаг принтов как в библиотеке, так и в HardwareSerial помойму, у меня Мега
выяснилось что на скорости 115000 контроллер вис на Serial.flush , в причинах не разобрался, просто выкинул последний цикл из GSM::begin() инициализации на разной скорости.
GSM модуль стал надежно подыматься
Что касается библиотеки, то она очень избыточна, стараюсь обходится функциями GSM::SendATCmdWaitResp
либо просто анализирую сериал на входе GSM
Не очень ясно зачем RTC цеплять, в GSM модуле часы есть с поддержкой от оператора сети.
Не могу понять в чём дело - плата вдруг перестала видеть GSM модуль (у меня gboard). Включил Debug - смотрю инициализация проходит без замечаний, а когда доходит до рабочего цикла то постоянно пишет "no response".
Хотел подключится к GSM модулю напрямую, но как бы я не переставлял перемычки у меня всё время на выходе последовательный порт "ардуины". Даже вобще без перемычек я вижу сообщения от микроконтроллера. То ли я неправильно понял назначение этих перемычек то ли у меня плата кривая попалась? В общем помогите отловить багу, а то я уже не знаю что с ней делать :(
поделитесь кодом
Код кривой, но работает.
Основные куски работающего кода взяты из темы: http://arduino.ru/forum/proekty/peredacha-temperatury-s-datchikov-dht11-ds18b20-cherez-nrf24l01
Выкладваю "как есть" без каких либо гарантий :)
Для того, чтобы получить значение конкретного датчика определенного модуля - отправляем СМС вида:
0 TEST 0
0 - получить значение
TEST - название модуля
0 - номер датчика.
Код блока GSM (плата GBoard):
#include "SIM900.h" #include <SoftwareSerial.h> //If not used, is better to exclude the HTTP library, //for RAM saving. //If your sketch reboots itself proprably you have finished, //your memory available. //#include "inetGSM.h" #include <SPI.h> #include <Mirf.h> #include <ASLibrary1.h> #include <MirfHardwareSpiDriver.h> /* GetAnswer(addr, 1, 0); - сколько датчиков GetAnswer(addr, 2, 0); - произвести измерение GetAnswer(addr, 4, 1); - вернуть значение датчика 1 (счет начинается с 0) GetAnswer(addr, 5, 2); - выполнить команду 2 (счет начинается с 0) */ //If you want to use the Arduino functions to manage SMS, uncomment the lines below. #include "sms.h" SMSGSM sms; //To change pins for Software Serial, use the two lines in GSM.cpp. //GSM Shield for Arduino //www.open-electronics.org //this code is based on the example of Arduino Labs. //Simple sketch to send and receive SMS. int numdata; boolean started=false; char smsbuffer[160]; char n[20]; char position; char unitID[5]; //идентификатор блока int command; //команда (0 - Get, 1 - Set) unsigned int attr; //аттрибут (команда или номер датчика) char buf[9]; unsigned int params; void setup() { pinMode(6, OUTPUT); digitalWrite(6, HIGH); //delay(10000); //Serial connection. //Serial.begin(9600); //Serial.println("GSM Shield testing."); //Start configuration of shield with baudrate. //For http uses is raccomanded to use 4800 or slower. if (gsm.begin(2400)){ //Serial.println("\nstatus=READY"); started=true; } else { //Serial.println("\nstatus=IDLE"); } if(started){ //Enable this two lines if you want to send an SMS. sms.SendSMS("+79641234567", "Starting OK!"); } // Зачистим сим-карту от старых СМС for(position=0;position<=21;position++) sms.DeleteSMS(position); }; void loop() { position = sms.IsSMSPresent(SMS_UNREAD); if(position){ if(sms.GetSMS(position, n, smsbuffer, 160)) { //Serial.println(n); //Serial.println(smsbuffer); // разбираем строку на команды params = sscanf(smsbuffer, "%d%s%d", &command, &unitID, &attr); if (params >= 2) { // если получили больше 2 параметров - обрабатываем //Serial.print("Command="); //Serial.println(command); //Serial.print("unitID="); //Serial.println(unitID); //Serial.print("data="); //Serial.println(attr); SetModule(unitID); if (command==0 && params==3){ AS_Answer MyAnswer=GetAnswer(unitID, 2, 0); if (MyAnswer.Status == 1) { MyAnswer=GetAnswer(unitID, 4, attr); if(MyAnswer.Status == 1) { dtostrf(MyAnswer.Value,8,1,buf); sms.SendSMS(n, buf); } } else { sms.SendSMS(n, "Wrong measure!"); } } if (command==1 && params==3){ AS_Answer MyAnswer=GetAnswer(unitID, 5, attr); if(MyAnswer.Status == 1){ sms.SendSMS(n, "Ok!"); } else { sms.SendSMS(n, "Wrong!"); } } } else { // иначе просто перешлем сообщение sms.SendSMS("+79641234567", n); sms.SendSMS("+79641234567", smsbuffer); } sms.DeleteSMS(position); // после завершения обработки - удаляем сообщение } } }; // устанавливаем адрес модуля, с которым работаем void SetModule(char *addr){ Mirf.spi = &MirfHardwareSpi; Mirf.csnPin = 9; Mirf.cePin = 8; Mirf.init(); Mirf.setRADDR((byte *)"GSM1");// Устанавливаем адрес, под которым будем принимать данные Mirf.setTADDR((byte *)addr); //Устанавливаем адрес, окуда считываем данные Mirf.payload = AS_NRF24L01_payload; Mirf.channel = AS_NRF24L01_channel; //Задаем канал Mirf.config(); //myDelay(1000); } //Посылает команду на устройство и вовращает ответ AS_Answer GetAnswer(char *addr, byte Command, byte Parametr){ AS_Command MyCommand; // Команда AS_Answer MyAnswer; // Ответ unsigned long time; // Время для отслеживания таймаута при запросе данных //Mirf.setTADDR((byte *)addr); //Устанавливаем адрес, окуда считываем данные //Mirf.config(); //myDelay(100); MyCommand.Command = Command; MyCommand.Parametr = Parametr; Mirf.send((byte *)&MyCommand); while(Mirf.isSending()){ } if (Command==2) myDelay(1000); // зачем? time = millis(); while(!Mirf.dataReady()){ if ( ( millis() - time ) > 1000 ) { //Serial.println(" no answer!"); tone(7,2500,250); MyAnswer.Status = 0; //skipD=1; return MyAnswer; } } Mirf.getData((byte *) &MyAnswer); return MyAnswer; }Код модуля TEST (к модулю подключен датчик DHT11 - температура и влажность):
#include <SPI.h> #include <DHT.h> #include <Mirf.h> #include <ASLibrary1.h> #include <MirfHardwareSpiDriver.h> #include <avr/sleep.h> #define NumSensors 2 AS_SensorStatus MySensors[NumSensors] = { 0,0,"tmp(C)", 0,0,"hdm(%)"}; DHT dht(6, DHT11); //Создаем датчик DHT11 на 6 пине float t, h; void wakeupFunction(){ } void toSleep(){ attachInterrupt(0,wakeupFunction,LOW); sleep_mode(); detachInterrupt(0); } void setup() { //Serial.begin(9600); dht.begin(); //Инициализируем датчик DHT for(int i=0; i<NumSensors; i++){ MySensors[i].Status = 0; } Mirf.spi = &MirfHardwareSpi; Mirf.csnPin = 9; Mirf.cePin = 8; Mirf.init(); Mirf.setRADDR((byte *)"TEST"); //Задаем адрес под которым будем принимать данные Mirf.setTADDR((byte *)"TEST"); Mirf.payload = AS_NRF24L01_payload; //Задаем размер буфера данных Mirf.channel = AS_NRF24L01_channel; //Задаем канал Mirf.config(); //Инициализируем модуль NRF24L01 //Serial.println("init"); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable();//Переходим в спящий режим } //Вычисляет все данные и заполняет массив значений датчиков byte CalculateAllData() { t = dht.readTemperature(); h = dht.readHumidity(); //Serial.println(t); if (isnan(t) || isnan(h)) { MySensors[0].Status = 0; MySensors[0].Value = 0; MySensors[1].Status = 0; MySensors[1].Value = 0; } else { MySensors[0].Status = 1; MySensors[0].Value = t; MySensors[1].Status = 1; MySensors[1].Value = h; } return 1; } AS_Answer ExecuteCommand(AS_Command MyCommand){ AS_Answer MyAnswer; // Ответ MyAnswer.Status = 0; MyAnswer.Value = 0; switch (MyCommand.Command) { case 0: //Reset resetFunc(); break; case 1: //Получиь количество датчиков //Serial.println("1"); MyAnswer.Status = 1; MyAnswer.Value = NumSensors; break; case 2: //Рассчитать все значения датчиков //Serial.println("2"); MyAnswer.Status = CalculateAllData(); break; case 4: //Получиь значение датчика по номеру //Serial.println("4"); if ((MyCommand.Parametr+1) > NumSensors){ MyAnswer.Status = 0; MyAnswer.Value = 0; memcpy(&MyAnswer.Comment,&"Too big num par.", CommentLen); } else{ MyAnswer.Status = MySensors[MyCommand.Parametr].Status; MyAnswer.Value = MySensors[MyCommand.Parametr].Value; memcpy(&MyAnswer.Comment,&MySensors[MyCommand.Parametr].Comment, CommentLen); } break; } return MyAnswer; } void loop() { AS_Command MyCommand; // Команда AS_Answer MyAnswer; // Ответ if(!Mirf.isSending() && Mirf.dataReady()){ Mirf.getData((byte *) &MyCommand); //Serial.println("command"); MyAnswer = ExecuteCommand(MyCommand); Mirf.send((byte *) &MyAnswer); while(Mirf.isSending()){} } else{ /* No data - night night. */ toSleep(); } }И для работы нужен еще вот этот файлик (ASLibrary1.h):
#ifndef __ASLibrary__ #define __ASLibrary__ #define CommentLen 20 //Длина комментария в сообщении #define AS_NRF24L01_payload 25 //Максимальный размер буфера в байтах для трансивера NRF24L01 //должен буть не меньше максимальной длины передаваемых данных //и не больше 32 (стркутуры _AS_COMMAND и _AS_ANSWER) #define AS_NRF24L01_channel 77 //канал, на котором работает трансивер NRF24L01 //RF Channel 0 - 127 or 0 - 84 in the US, default 0. // Команды состоят из 1 команды и 1 параметра // 0 x - Перезагрузка // 1 x - Получить количество датчиков // 2 x - Выполнить измерение по всем датчикам (записать в глобальные переменные, пока не принимать) // 3 N - Выполнить измерение по датчику N (записать в глобальные переменные, пока не принимать) // 4 N - Получить данные с датчика N (считать из глобальных переменных) typedef struct _AS_COMMAND { byte Command; //Команда byte Parametr; //Параметр }AS_Command; // Ответы состоят из 1 статуса и 1 значения // 0 x - Ошибка // 1 N - Данные переданы корректны, N значение typedef struct _AS_ANSWER { byte Status; //Статус float Value; //Значение byte Comment[CommentLen]; //Описание }AS_Answer; // Состояние датчиков // 0 x - Ошибка // 1 N - Данные актуальны, значение N typedef struct _AS_SENSORSTATUS { byte Status; //Статус float Value; //Значение byte Comment[CommentLen]; //Описание }AS_SensorStatus; void myDelay(unsigned long time){ unsigned long current = millis(); while((millis()-current)<time){} } void(* resetFunc) (void) = 0; // Reset MC function #endif // __ASLibrary__Все необходимые библиотеки легко гуглятся по названиям подключаемых файлов.
Что плохо и надо доделывать:
1. Нет проверки на "валидный номер" (чтобы только на "свои" смс-ки реагировал модуль)
2. Надо избавиться от беспроводной команды со смыслом "произвести измерение на модуле ...."
3. Сейчас значение датчика строго типа float (даже если "датчик" возвращает 0 или 1)
4. Дописать код так, чтобы при запросе к модулю можно было не указывать номер конкретного датчика и система вываливала бы данные всех датчиков с модуля
5. и т.п.
P.S. сейчас посмотрел код свежим взглядом и обнаружил, что пересылка "неправильных" sms-сообщений никогда не сработает - надо править код ;)
P.P.S. возможно наличие и других ошибок