Arduino UNO, GPRS Shield, DS18B20
- Войдите на сайт для отправки комментариев
Ср, 28/12/2016 - 12:15
Здравствуйте, это мой первый проект на ардуинке, строго не судите.
Ситуация следующая:
Есть Ардуино уно, gprs shield и датчик температуры DS18B20.
Контроль 2 дискретных сигналов от реле (работа, авария) и вывод температуры по запросу смс запрос - смс ответ.
Смс запрос приходит, но ответное смс пустое, в чем может быть проблема
Скетч ниже:
#include <OneWire.h> #include <DallasTemperature.h> #include <SoftwareSerial.h> #include <GPRS_Shield_Arduino.h> #include <sim900.h> #define MESSAGE_LENGTH 160 // сообщение #define ONE_WIRE_BUS 8 // подключение термодатчика к 8 пину OneWire oneWire (ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); // переменная 1wire DeviceAddress insideThermometer; // адресс датчика SoftwareSerial mySerial(10,11); // софт. эмуляция сериала на 10 11 пине GPRS gprs(mySerial); // объект класса gprs int messageIndex = 0; // номер сообщения в сим char message[MESSAGE_LENGTH]; // текст сообщения char phone[16]; // номер с которого пришло смс char datetime[24]; // дата отправки смс boolean prevAlarm = LOW; // приравниваем к 0 предыдущею аварию int ledPin = 13; // светодиод на 13 пине int inPinW = 5; // вход работа int inPinA = 4; // вход авария int valW = 0; // переменная работа int valA = 0; // переменная авария void setup() { gprs.powerOn(); // включаем gprs shield Serial.begin(9600); // запуск сериал порта mySerial.begin(9600); // софт. соединение для gprs while (!Serial) { // ждем открытия монитора порта } while (!gprs.init()) { // проверяем есть ли связь delay(1000); // ждем секунду Serial.println("Init Error\r\n"); // если нет связи выводим ошибку и проверяем снова } Serial.println("GPRS init succes"); // если есть выводим ок состояние Serial.println("Send sms to me!"); pinMode (ledPin, OUTPUT); // режим выхода для светодиода pinMode (inPinW, INPUT); // режим входа для сигнала работа (замыкание) pinMode (inPinA, INPUT); // режим входа для сигнала авария (размыкание) digitalWrite (inPinW, HIGH); // вход +5в работа, замыкание с gnd digitalWrite (inPinA, HIGH); // вход +5в авария, замыкание с gnd Serial.println ("Find devices..."); // вывод в терминал sensors.begin(); Serial.println("Found"); Serial.print(sensors.getDeviceCount(), DEC); // датчик найден, кол-во Serial.println("Pcs"); Serial.print ("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println ("OFF"); // проверка режима питания датчиков if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Don't find sensor 0 address "); // если не найден адрес 1 датчика sensors.setResolution(insideThermometer, 9); // выставляем разрешение датчика Serial.print("Sensor 0 resolution is : "); Serial.print(sensors.getResolution(insideThermometer), DEC); Serial.println(); // вывод разрешение датчика } void printTemperature(DeviceAddress deviceAddress) { int tempC = sensors.getTempC(deviceAddress); Serial.print("Temp C: "); Serial.println(tempC); } void loop() { int tempC = sensors.getTempC(insideThermometer); Serial.print("Temp C: "); Serial.println(tempC); // вывод температуры int countT = 0; // счетчик температуры (для однократного посыла sms) boolean currAlarm = digitalRead(inPinA); // переменная current alarm valW = digitalRead (inPinW); // переменная работа valA = digitalRead (inPinA); // переменная авария if (valW == HIGH) // если вход работа разомкнут { digitalWrite(ledPin, LOW); // светодиод не горит Serial.println ("Not work"); } if (valA == HIGH) // если вход авария разомкнут { digitalWrite(ledPin, HIGH); delay(100); digitalWrite (ledPin, LOW); delay(500); Serial.println ("Alarm"); // моргание светодиодом и вывод в сериал } if (prevAlarm != currAlarm && currAlarm == HIGH) // один раз посылаем смс "Alarm" { gprs.sendSMS ("+7915XXXXXXX","Alarm"); } { prevAlarm = currAlarm; // сброс } { Serial.print ("Previous alarm is: "); Serial.println (prevAlarm); Serial.print ("Current alarm is: "); Serial.println (currAlarm); // выводим значение в сериал } if (valW == LOW) // если вход работа замкнут { digitalWrite(ledPin, HIGH); // светодиод горит Serial.println ("Work"); } delay (500); { Serial.println ("Read Temperature"); sensors.requestTemperatures(); Serial.println ("Done"); printTemperature(insideThermometer); delay(1000); // считываем температуру и выводим } if (gprs.ifSMSNow()) // если пришло смс { gprs.readSMS(message, phone, datetime); // читаем смс Serial.print ("From number: "); Serial.println (phone); // выводим номер Serial.print ("Datetime: "); Serial.println (datetime); // выводим дату Serial.print ("Received message: "); Serial.println (message); // выводим сообщение countT ++; } if ((strcmp(message, "Rtemp") == 0) && countT == 1) // условие для ответа темп { Serial.print ("from sms: "); Serial.println ( tempC ); gprs.sendSMS (phone, tempC); // шлем ответную смс с температурой } }
А оно у Вас компилируется? И чего говорит при этом? Предупреждения-то включены? Много их?
А что печатется в строке 144?
А по очевидным ошибкам:
1. Строка 77.
getTempC возвращает float, а Вы присваиваете его int. Дробная часть температуры для Вас потеряна, даже если она равна 0,9999999
2. строка 145
не знаю, что у Вас за библиотека, но если вот такая, то метод sendSMS ожидает втрорым параметром указатель на char (т.е. тестовую строку), а Вы ему int пихаете. Преобразуйте своё число в массив символов и передавайте sendSMS указатель на его нулевой элемент.
Да Компилируется замечательно, загружается и даже работает, кроме пустого смс.
Как я предполагаю, температура которая отсылается в смс (и в мониторе порта выдаёт действительное значение температуры)
по строке 77. значение float, которое было изначально нельзя отправить в смс
компилятор выдаёт следующее:
(no matching function for call to 'GPRS::sendSMS(char [16], float&)')
поэтому начались эксперименты с типами данных.
Разброс в +- 1 градус некритичен, по крайней мере для начала
145 строка
да, библиотека для шилда от амперки, по поводу массива, буду пробовать, спасибо за наводку.
Да Компилируется замечательно, загружается и даже работает, кроме пустого смс.
Ни фига не замечатльно. У Вас выключены предупреждения компилятора, иначе Вы бы увидели ошибку сразу. Идиоты - разработчики IDE выключили предупреждения по умолчанию (чтобы новичков не смущать), вот новички и работают зарыв голову в песок. Компилятор и готов предупредить об ошибке, да кто б его ещё слушал.
компилятор выдаёт следующее:
(no matching function for call to 'GPRS::sendSMS(char [16], float&)')
поэтому начались эксперименты с типами данных.
Правильно делает, что выдаёт. Если бы Вы не экспериментировали с типами методом тыка, а просто пробразовали число в текстовый массив, проблемы бы не было.
Ведь что Вы сейчас делаете, смотрите внимательно. Допустим Ваша температура равна 32. Теперь смотрим:
1. метод ожидает указателя на символьный массив (т.е. адреса в памяти, где лежит строка)
2. Вы пихаете ему число 32.
2. Он просто берёт то, что лежит в памяти начиная с адреса 32 и, считая это строкой, шлёт эту строку в SMS.
Вот и всё, чего Вы добились своими "экспериментами".
Надо не экспериментировать, а разбираться в чём дело и исправлять так, как Вам надо, а не просто, чтобы компилятор съел.
Включил предупреждения компилятора, да действительно показывает. Намного понятней стало.
по поводу массива:
объявил массив char temp[] = {tempC};
и в ответном смс изменил на отправку значения из массива gprs.sendSMS (phone, temp[0]);
присылает вопросительный знак
присылает вопросительный знак
Правильно делает
и в ответном смс изменил на отправку значения из массива gprs.sendSMS (phone, temp[0]);
объявил массив char temp[] = {tempC};
Что Вы этим хотели сказать? Я не понимаю, что тут написано.
Массив нужно объявлять, указывая максимально возможную длину содержимого + 1 в качестве размера массива. Если Ваша tempC по-прежнему int, то то она не может быть более пяти цифр + знак, т.е. 6-ти символов. Значит массив объявлете на 7
char temp[7];
а непосредственно перед отправкой, преобразуете своё число в строку, в этот массив. Ну, не знаю, есть миллион способов это сделать, хоть
itoa(tempC, temp, 10);
Вот спасибо!
Теперь отсылает, пойду дальше по алгоритму.
Не за что.