Arduino UNO, GPRS Shield, DS18B20

rqt742
Offline
Зарегистрирован: 28.12.2016

Здравствуйте, это мой первый проект на ардуинке, строго не судите.

Ситуация следующая:

Есть Ардуино уно, 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); // шлем ответную смс с температурой 
 
}
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А оно у Вас компилируется? И чего говорит при этом? Предупреждения-то включены? Много их?

А что печатется в строке 144?

А по очевидным ошибкам:

1. Строка 77.

getTempC возвращает float, а Вы присваиваете его int. Дробная часть температуры для Вас потеряна, даже если она равна 0,9999999

2. строка 145

не знаю, что у Вас за библиотека, но если вот такая, то метод sendSMS ожидает втрорым параметром указатель на char (т.е. тестовую строку), а Вы ему int пихаете. Преобразуйте своё число в массив символов и передавайте sendSMS указатель на его нулевой элемент.

rqt742
Offline
Зарегистрирован: 28.12.2016

Да Компилируется замечательно, загружается и даже работает, кроме пустого смс.

Как я предполагаю, температура которая отсылается в смс (и в мониторе порта выдаёт действительное значение температуры)

по строке 77. значение float, которое было изначально нельзя отправить в смс

компилятор выдаёт следующее:

(no matching function for call to 'GPRS::sendSMS(char [16], float&)')

поэтому начались эксперименты с типами данных. 

Разброс в +- 1 градус некритичен, по крайней мере для начала

145 строка 

да, библиотека для шилда от амперки, по поводу массива, буду пробовать, спасибо за наводку.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

rqt742 пишет:

Да Компилируется замечательно, загружается и даже работает, кроме пустого смс.

Ни фига не замечатльно. У Вас выключены предупреждения компилятора, иначе Вы бы увидели ошибку сразу. Идиоты - разработчики IDE выключили предупреждения по умолчанию (чтобы новичков не смущать), вот новички и работают зарыв голову в песок. Компилятор и готов предупредить об ошибке, да кто б его ещё слушал.

rqt742 пишет:

компилятор выдаёт следующее:

(no matching function for call to 'GPRS::sendSMS(char [16], float&)')

поэтому начались эксперименты с типами данных. 

Правильно делает, что выдаёт. Если бы Вы не экспериментировали с типами методом тыка, а просто пробразовали число в текстовый массив, проблемы бы не было.

Ведь что Вы сейчас делаете, смотрите внимательно. Допустим Ваша температура равна 32. Теперь смотрим:

1. метод ожидает указателя на символьный массив (т.е. адреса в памяти, где лежит строка)
2. Вы пихаете ему число 32.
2. Он просто берёт то, что лежит в памяти начиная с адреса 32 и, считая это строкой, шлёт эту строку в SMS.

Вот и всё, чего Вы добились своими "экспериментами".

Надо не экспериментировать, а разбираться в чём дело и исправлять так, как Вам надо, а не просто, чтобы компилятор съел.

 

rqt742
Offline
Зарегистрирован: 28.12.2016

Включил предупреждения компилятора, да действительно показывает. Намного понятней стало.

по поводу массива: 

объявил массив                                                                       char temp[] = {tempC};

и в ответном смс изменил на отправку значения из массива  gprs.sendSMS (phone, temp[0]);

присылает вопросительный знак

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

rqt742 пишет:

присылает вопросительный знак

Правильно делает

rqt742 пишет:

и в ответном смс изменил на отправку значения из массива  gprs.sendSMS (phone, temp[0]);

Вам же надо передавать адрес нулевого элемента, а Вы сам нулевой элемент передёте. Пишите нормально:
 
gprs.sendSMS (phone, temp);

rqt742 пишет:

объявил массив                                                                       char temp[] = {tempC};

Что Вы этим хотели сказать? Я не понимаю, что тут написано.

Массив нужно объявлять, указывая максимально возможную длину содержимого + 1 в качестве размера массива. Если Ваша tempC по-прежнему int, то то она не может быть более пяти цифр + знак, т.е. 6-ти символов. Значит массив объявлете на 7

char temp[7];

а непосредственно перед отправкой, преобразуете своё число в строку, в этот массив. Ну, не знаю, есть миллион способов это сделать, хоть

itoa(tempC, temp, 10);

 

rqt742
Offline
Зарегистрирован: 28.12.2016

Вот спасибо!

Теперь отсылает, пойду дальше по алгоритму.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не за что.