Страница 1 из 2
Преобразование строки
Добавлено: Сб сен 29, 2018 5:20 pm
svetozar161
Здравствуйте уважаемые знатоки. Прошу помощи.
С помощью уважаемого serghei наконец-то запустил систему отопления и парсинг температуры с внешнего датчика, но температура конвертится с помощью Int в целое число и термостат неудобно работает по целому числу, хотелось бы десятые доли. Есть оператор "atof" но как его применить толком не пойму. Вот код:
Объявляется переменная
Парсится строка "espdata&idesp" и ищется символ с 50 по 55 затем преобразуется в переменную data1
Код: Выделить всё
if (parameter.startsWith("espdata&idesp")) { // Температура датчика в спальне ESP05
data1 = (parameter.substring(50,55)).toInt();
Здесь код для реле
Код: Выделить всё
void testRele(){
if(!releSt && data1 > 24){
digitalWrite(relePin, HIGH);
timeStamp();
Serial.println(" Rele \"OFF\"");
releSt = 1;
#ifdef MAJORDOMO_FEATURE
sendRequestM("Rele_kotla", 0);
#endif
}
if(releSt && data1 < 21){
{
digitalWrite(relePin, LOW);
timeStamp();
Serial.println(" Rele \"ON\"");
releSt = 0;
#ifdef MAJORDOMO_FEATURE
sendRequestM("Rele_kotla", 1);
#endif
}
}
Все работает. Но хотелось бы использовать float вместо int. Как сделать десятые доли?
Да и еще забыл такой момент. Если на пинах АМС не висит хотя бы один даллас, цикл реле не работает. Почему?
Re: Преобразование строки
Добавлено: Вс сен 30, 2018 7:18 am
ser009
Если вы используете библиотеку <DallasTemperature.h>, значение с датчика читается в формате float.
Код: Выделить всё
...
float current_temp[MAX_TEMP_SENSORS];...
...
current_temp[n] = sensors.getTempC(tempSensor[n]);
...
Если у вас проблемы с передачей значения с плавающей точкой, то в таких случаях из Float разбивают на 2 int (целое число и все что после запятой) передают 2 int и потом их снова собирают во float
Re: Преобразование строки
Добавлено: Вс сен 30, 2018 10:56 am
svetozar161
Это очень сложно, да и зачем float разбивать на int, потом опять собирать в float? Нужно просто правильно составить строку substring с atof
Re: Преобразование строки
Добавлено: Вс сен 30, 2018 11:54 am
svetozar161
Да и значение температуры у меня берется не со встроенных далласов а преобразуется из строки из сериала
Re: Преобразование строки
Добавлено: Вс сен 30, 2018 1:15 pm
alexsis_76
а что флоат разве уже не передают целиком, видимо надо коды переписывать
Re: Преобразование строки
Добавлено: Вс сен 30, 2018 3:07 pm
ser009
Дайте кусок кода, который разбирает принятый пакет данных и получаемые данные
Re: Преобразование строки
Добавлено: Вс сен 30, 2018 4:08 pm
serghei
Смысл происходящего простой - AMS получает по сети или сериалу данные с других ардуино. Для этого создаем буфер в 64 байта и записываем туда всё что прилетело. Дальше по шаблону ( первые несколько байт ) распарсиваем ответ. В этом ответе ( от сети WiFi-iot ) первые байты всегда одинаковые. А интересующая температура всегда с 50 по 55 байт в виде 12,34 . Вот её и надо присвоить некой переменной Data1, что бы потом дергать реле или вывести на страницу. Код работал у меня на ESP32 и получал данные от сети MySensors. Но меня интересовали целые значения температур или влажности.
Затем я применил этот же алгоритм и для Меги по сериалу 3 получаю время от AMS на 8266 и от UNO по сериалу 2. И дробное значение всегда правильное. Почему это не работает с HTTP я не знаю. Вернее целое число видно , а дробное нет. Что делаем:
1 Определяем переменные
Код: Выделить всё
String data1;
String data2;// 20;2;1;0;0;23.8 - Температура 20 ноды
2 В парсере
Код: Выделить всё
if (serialReq.startsWith("20;2;1;0;0;")) {
data2 = (serialReq.substring(11,16));
Serial.println(data2);
}
C ESP32 и UDP это работает. А с WiFi-iot не хочет.
Полный код для MySensors
Тут. Для сериала только тестирую.
Re: Преобразование строки
Добавлено: Пн окт 01, 2018 5:11 am
ser009
У вас data2 является строкой String, а вы хотите float.
Создайте переменную типа float и уже в ней пишите значения.
http://cppstudio.com/post/792/
Re: Преобразование строки
Добавлено: Вт окт 02, 2018 12:50 am
svetozar161
Подсказали сделать так:
Объявляем
парсим строку из сериала: espdata&idesp=ESP826600895b59&hostname=ESP05&shtt=21.3&shth=62.7&uptime=95130&errconn=334&wanip=192.168.1.2
Код: Выделить всё
if (parameter.startsWith("espdata&idesp")) { // Температура датчика в спальне ESP05
data1 = atof(parameter.substring(50,54).c_str());
Serial.println(data1);
}
в сериале появляется "21.3"
цикл реле:
Код: Выделить всё
#define relePin 49 // пин реле
void testInit()
{
pinMode(relePin, OUTPUT);
digitalWrite(relePin, HIGH);
}
//==============
void testRele()
{
if(!releSt && data1 > 23)
{
digitalWrite(relePin, HIGH);
timeStamp();
Serial.println(" Rele \"OFF\"");
releSt = 1;
#ifdef MAJORDOMO_FEATURE
sendRequestM("Rele_kotla", 0);
#endif
}
if(releSt && data1 < 21)
{
digitalWrite(relePin, LOW);
timeStamp();
Serial.println(" Rele \"ON\"");
releSt = 0;
#ifdef MAJORDOMO_FEATURE
sendRequestM("Rele_kotla", 1);
#endif
}
И нихрена! Как включалось реле по целому числу, так и включается. Непонятно...
Re: Преобразование строки
Добавлено: Вт окт 02, 2018 4:42 am
ser009
Попробуйте так.
Для начала создайте для реле отдельную функцию отвечающую за вкл и выкл
Код: Выделить всё
#define RELE_1_PIN 1
byte rele1State = 0;
void initReles() {
pinMode(RELE_1_PIN, OUTPUT);
moduleReles = ENABLE;
started(F("RELE"), true);
}
void rele1On(){
if(digitalRead(RELE_1_PIN)==LOW){
digitalWrite(RELE_1_PIN, HIGH);
rele1State = 1;
}else{}
}
void rele1Off(){
if(digitalRead(RELE_1_PIN)==HIGH){
digitalWrite(RELE_1_PIN, LOW);
rele1State = 0;
}else{}
}
А функция вкл/выкл котла будет выглядеть так
Код: Выделить всё
void testRele(){
if(rele1State==1 && data1 > 24){
rele1Off();
timeStamp();
Serial.println(" Rele \"OFF\"");
#ifdef MAJORDOMO_FEATURE
sendRequestM("Rele_kotla", 0);
#endif
}
if(rele1State==0 && data1 < 21){
{
rele1On();
Serial.println(" Rele \"ON\"");
#ifdef MAJORDOMO_FEATURE
sendRequestM("Rele_kotla", 1);
#endif
}