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);
Вот спасибо!
Теперь отсылает, пойду дальше по алгоритму.
Не за что.