Доброго времени суток! Помогите разобраться. Делаю устройство для управления котлом отопления. Градусник передает значения температуры через Bluetooth. С передачей проблем не возникает в мониторе порта значения четкие, а вот на приеме постоянно вылезает 255 градусов 2 градуса 2555, -138 градусов причем передатчик отрицательные числа вообще не передает. Ошибка висит не долго 1 - 5 сек всегда по разному но котел успевает включится либо выключится. Код принимающего устройства: Код (C++): #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F,16,2); // Устанавливаем дисплей byte simvol[8] = {B11100,B10100,B11100,B00000,B00000,B00000,B00000,B00000,}; // Символ градуса int datB=7; // датчик бойер const int datT=9;// комнатный термостат int rele_1 =10; // питание клапана int rele_2 = 12; // питание насос int Temp; // освобождаем память для переменной "temp" int settemp; int flag; //состояние unsigned long currentTime; int t; void setup() { // put your setup code here, to run once: pinMode (datB, INPUT); pinMode (datT, OUTPUT); pinMode (rele_1, OUTPUT); pinMode (rele_2, OUTPUT); flag=1; settemp=22; lcd.init(); // lcd.print("iarduino.ru"); // lcd.setCursor(8, 1); // lcd.print("LCD 1602"); Serial.begin(9600); } void loop() { if(Serial.available() >0) {//если в порт пришли данные t = Serial.parseInt(); if(t>0||t<40){ //защита от ошибочных Temp= t; // данных НЕ РАБОТАЕТ } } Serial.print( t); // Serial.println("b"); // Serial.print (Temp); // Контроль Serial.println("Temp"); // // Serial.print(b); // delay(1000); lcd.clear(); lcd.backlight();// Включаем подсветку дисплея lcd.setCursor(0, 0); lcd.print("Temperatura"); lcd.createChar(1, simvol); // Создаем символ под номером 1 lcd.setCursor(0,1); // Устанавливаем курсор на 2 строку, ячейка 1 lcd.print(Temp); // Выводим показания температуры lcd.setCursor(14,1); lcd.setCursor(3,1); // Устанавливаем курсор на 2 строку, ячейка 6 lcd.print("\1"); // Выводим символ градуса lcd.setCursor(4,1); // Устанавливаем курсор на 2 строку, ячейка 7 lcd.print("C"); // Выводим текст lcd.setCursor(11,1); lcd.print(flag); delay(1000); // ставим небольшую задержку if ( digitalRead(datB)==LOW&&(Temp>=settemp+1)) {// если бойлер горячий в дома тепло flag=1; } if ( digitalRead(datB)==HIGH&&(Temp>=settemp+1)){//если бойлер холодный в доме тепло flag=2; } if ( Temp <=settemp){//если в доме холодно flag=3; } if ( Temp <settemp && digitalRead(datB)==HIGH){//если в доме холодно и бойлер холодный flag=4; } if (flag==1){ digitalWrite (datT, LOW);//разамкнуть датчик термостата delay(300); digitalWrite (rele_1, LOW);//открыть клапан отопления delay(300); digitalWrite (rele_2, LOW); // откл. насос бойера if(millis()-currentTime>31000){ currentTime=millis(); digitalWrite(datT, HIGH); delay(2000); digitalWrite (datT, LOW); } //digitalWrite (datU, LOW); } if (flag==2){ digitalWrite (rele_2, HIGH); // вкл. насос бойера delay(300); digitalWrite (rele_1, HIGH);//закрыли клапан отопления delay(300); digitalWrite (datT, HIGH);//зомкнуть датчик термостата //digitalWrite (datU, LOW); } if (flag==3){ digitalWrite (rele_1, LOW);//открыть клапан отопления digitalWrite (rele_2, LOW); // откл. насос бойера digitalWrite (datT, HIGH);//разомкнуть датчик термостата if (Temp>=23){ digitalWrite (datT, LOW);//разамкнули датчик термостата } } //digitalWrite (datU, LOW); if (flag==4){ digitalWrite (rele_2, HIGH); // вкл. насос бойера delay(300); digitalWrite (rele_1, HIGH);// закрыть клапан отопления delay(300); digitalWrite (datT, HIGH);//замкнуть датчик термостата //digitalWrite (datU, LOW); } } Код передающего устройства: Код (C++): #include <OneWire.h> #include <Wire.h> #include <DallasTemperature.h> #define DS18B20 2 // Указываем, к какому выводу подключена DQ OneWire oneWire(DS18B20); DallasTemperature sensors(&oneWire); int rst =6; //питание датчика int t; //byte a; void setup() { Serial.begin(9600); pinMode (rst,OUTPUT); digitalWrite(rst,HIGH); } void loop() { sensors.requestTemperatures(); // читаем температуру if (sensors.getTempCByIndex(0)>0){ // если значение боьше нуя t=sensors.getTempCByIndex(0);//*100; // сохраняем данные } Serial.println(t); // отправить в порт delay(1000); if (sensors.getTempCByIndex(0)<=-100) { digitalWrite(rst,LOW); delay(300); digitalWrite(rst,HIGH); } }
я бы тут поставил И. Всегда прут ложные данные или иногда? Если всегда, то надо проверять подключение. Если иногда, то, как гипотеза, что произойдёт если данные приходят, но еще не пришли все? Я бы делал через serialEvent (см. в примерах) и ограничивал пачку данных какими-нибудь символами. Чтобы когда данные придут не сразу ломиться их обрабатывать, а дождаться, что пришел символ начала пачки, а когда придет символ конца пачки. Между ними будут данные. Если случился сбой, то стереть буфер и ждать следующей пачки. Реализацию я где-то на форуме приводил.
С начало "И" ставил результат тот же. сбои периодические но постоянные) хорошая идея Код (C++): String inputString = ""; // строка, в которую будут записываться входящие данные //int inputTemp ; boolean stringComplete = false; // заполнилась ли строка или нет void setup() { Serial.begin(9600); inputTemp.reserve(200); } void serialEvent() { while (Serial.available()) { // получаем новый байт: char inChar = (char)Serial.read(); // добавляем его к inputString: inputString += inChar; // если получили символ новой строки, оповещаем программу об этом, // чтобы она могла принять дальнейшие действия. if (inChar == '\n') { stringComplete = true; } } } void loop() { // если прибыл символ новой строки, показываем строку: if (stringComplete) { Serial.println(inputString); // очищаем строку: inputString = " "; stringComplete = false; } } Но как теперь из Код (C++): String сделать Код (C++): int [/QUOTE]
тут просто условие, извиняюсь, глупое. Все числа от -бесконечности до + бесконечности пройдут его) Если сбои появляются временами, то я подозреваю на рассинхронизацию према. Если это так, то лучше идти путем введения избыточности и маркеров в протокол передачи данных, что я и советовал ранее. Как делать из стрингов инты написано не раз во всех обучающих материалах и описании библиотеки String, но я бы советовал поискать тут.
А зачем вообще числа передавать буквами? Все эти Ардуиновские parseInt() и прочая фигня хороши для мигания светодиодами и обучения - в готовых устройствах пользоваться тем что не понятно как работает изнутри извращение.
Что-то не вижу у вас в коде, зачем это делать А так коллеги правильно сказали - отправляйте значение температуры одним байтом командой Serila.write(). принимайте Serial.read() - и даже SerialEvent не нужен будет