Два TM1637 в одном скетче.
- Войдите на сайт для отправки комментариев
Приветствую. Прошу помочь со скетчем. Саму разобраться не получается. Если новичок=первоклассник, то я ближе к детсаду в С++. С ардуиной общался только через программы визуального программирования. То, что понадобилось сейчас, это термометр с "-" , часы и вывод на два индикатора. В этих прогах полностью реализовать не удалось. По этому взял два кода сделанных в проге визуального программирования и соединил их в ардуино иде. Один код- термометр на DS18B20, TM1637 и Nano. Второй код- часы на DS3231, TM1637, две сенсорных кнопки и Nano. Некоторые строки добавил, другие поправил и вроде заработало. Часы работают хорошо, но обнаружился косяк, индикатор на который выводится температура меняет индикацию. Показывает температуру примерно 0,3-0,5 сек., потом меняет индикацию на нули во всех знакоместах на тоже время и так по кругу.
Знатоков С+ прошу, подскажите чего поправить в коде, что бы нули не выводились на индикатор с температурой.
Ты издеваешься ?
В смысле?
:-)
И после этого if (_D0_9C_D0_B5_D0_BD_D1_8E == 2) мне будут писать, что я радистка "КЭТ".
Код прогнали через исправитель от кодирования)))
За Кет ни чего сказать не могу.
А с этим if (_D0_9C_D0_B5_D0_BD_D1_8E == 2) чего делать?
Выбросить этот кошмар и написать нормально.
За Кет ни чего сказать не могу.
А с этим if (_D0_9C_D0_B5_D0_BD_D1_8E == 2) чего делать?
Пойти на форум "визуального пронраммирования" и спрашивать там, здесь в этом говне никто копаться не будет
За Кет ни чего сказать не могу.
http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/delay-millis-k...
сообщение №22
А вам наверное код надо вставить согласно правилам этого форума. Ну и стиль его писания совсем не ясен мне, может здешние спецы помогут.
#include <OneWire.h> // термометр #include <DallasTemperature.h> // термометр #include "TM1637.h" // термометр #include <RTClib.h> OneWire oneWireBus(11); // термометр DallasTemperature sensors(&oneWireBus); // термометр TM1637 tm16371(8,9); // добавил // термометр TM1637 tm1637(6,7); RTC_DS3231 rtc; DateTime t; String daysOfTheWeek[7]={"Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sabado"}; String monthsNames[12]={"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"}; long x11; // добавил // термометр? long x22; // добавил // термометр? long x33; // добавил // термометр? long x44; // добавил // термометр? long x1; long x2; long x3; long x4; int _D0_A7_D0_B0_D1_81; int _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B; long _D0_9C_D0_B5_D0_BD_D1_8E; void _D0_9E_D1_82_D0_BE_D0_B1_D1_80_D0_B0_D0_B6_D0_B5_D0_BD_D0_B8_D0_B5__D0_B2_D1_80_D0_B5_D0_BC_D0_B5_D0_BD_D0_B8() { x1 = int((_D0_A7_D0_B0_D1_81 / 10)); x2 = _D0_A7_D0_B0_D1_81 - x1 * 10; x3 = int((_D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B / 10)); x4 = _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B - x3 * 10; tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_ON); _D0_9C_D0_B5_D0_BD_D1_8E2(); delay(500); tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_OFF); _D0_9C_D0_B5_D0_BD_D1_8E2(); delay(500); tm16371.point(POINT_OFF); // добавил tm16371.display(0,x11); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(1,x22); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(2,x33); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(3,x44); // добавил _D0_9C_D0_B5_D0_BD_D1_8E2(); // добавил // delay(500); // добавил } void _D0_9C_D0_B5_D0_BD_D1_8E2() { if (digitalRead(3) == true) { _D0_9C_D0_B5_D0_BD_D1_8E = _D0_9C_D0_B5_D0_BD_D1_8E + 1; delay(300); } } void setup() { Serial.begin(9600); // термометр sensors.begin(); // термометр tm1637.init(); tm1637.set(BRIGHT_TYPICAL); tm16371.init(); // термометр tm16371.set(BRIGHT_TYPICAL); // термометр rtc.begin(); x1 = 0; x2 = 0; x3 = 0; x4 = 0; _D0_A7_D0_B0_D1_81 = 0; _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B = 0; _D0_9C_D0_B5_D0_BD_D1_8E = 0; pinMode(4,INPUT); pinMode(3,INPUT); } void loop() { sensors.requestTemperatures(); // термометр Serial.println(sensors.getTempCByIndex(0)); // термометр tm16371.display(sensors.getTempCByIndex(0)); // термометр, изменил tm1637 t=rtc.now(); _D0_A7_D0_B0_D1_81 = t.hour(); _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B = t.minute(); if (_D0_9C_D0_B5_D0_BD_D1_8E == 0) { _D0_9E_D1_82_D0_BE_D0_B1_D1_80_D0_B0_D0_B6_D0_B5_D0_BD_D0_B8_D0_B5__D0_B2_D1_80_D0_B5_D0_BC_D0_B5_D0_BD_D0_B8(); } if (_D0_9C_D0_B5_D0_BD_D1_8E == 1) { _D0_9C_D0_B5_D0_BD_D1_8E2(); tm1637.display(_D0_A7_D0_B0_D1_81); if (digitalRead(4) == true) { _D0_A7_D0_B0_D1_81 = _D0_A7_D0_B0_D1_81 + 1; if (_D0_A7_D0_B0_D1_81 >= 24) { _D0_A7_D0_B0_D1_81 = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,_D0_A7_D0_B0_D1_81,_D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B,0)); tm1637.display(_D0_A7_D0_B0_D1_81); delay(300); } } if (_D0_9C_D0_B5_D0_BD_D1_8E == 2) { _D0_9C_D0_B5_D0_BD_D1_8E2(); tm1637.display(_D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B); if (digitalRead(4) == true) { _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B = _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B + 1; if (_D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B >= 60) { _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,_D0_A7_D0_B0_D1_81,_D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B,0)); tm1637.display(_D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B); delay(300); } } if (_D0_9C_D0_B5_D0_BD_D1_8E == 3) { _D0_9C_D0_B5_D0_BD_D1_8E = 0; } }Как отредактировать первое сообщение не нашел.
int _D0_A7_D0_B0_D1_81; int _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B; long _D0_9C_D0_B5_D0_BD_D1_8E; void _D0_9E_D1_82_D0_BE_D0_B1_D1_80_D0_B0_D0_B6_D0_B5_D0_BD_D0_B8_D0_B5__D0_B2_D1_80_D0_B5_D0_BC_D0_B5_D0_BD_D0_B8() {Блин, ну сказали же - не издевайся! Или заменяй на человеческие имена или никто с этим ковыряться не будет
И после этого if (_D0_9C_D0_B5_D0_BD_D1_8E == 2) мне будут писать, что я радистка "КЭТ".
Так это ж не он писал - это генератор кода из его картинок/кубиков. Вот пример, чуть получше:
if(_tim2O) {_swi3=UB_45495025_Instance1.ubo_200391650;} else {_swi3=0;} UB_45495025_ubi_92073087 = (analogRead (1)); UB_45495025_Instance1 = _func_UB_45495025(UB_45495025_Instance1, UB_45495025_ubi_92073087, 890, 150, 650, 450, 300);Так это ж не он писал - это генератор кода из его картинок/кубиков. Вот пример, чуть получше:
Это понятно. Но если человек хочет помощи - пусть немного нарпряжется и приведет код в удобочитаемый вид. Каких-то особых познаний для этого не требуется. Просто потратить немного времени.
Выжпрограммисты. Что там сложного - дел на пять минут. Вот ТС всегда помогает тем, кто к нему с просьбой приходит. Правда, в 70 лет уже сложно учится.
Из разряда: Тыж ремонтник - почини адронный коллайдер))))
Если бы я в С++ разбирался и знал, что там закодировано, я б наверное за помощью не обращался.
По отдельности оба кода работают корректно. Я их соединил в С++ и один индикатор стал промаргивать нулями.
Если бы я в С++ разбирался и знал, что там закодировано, я б наверное за помощью не обращался.
По отдельности оба кода работают корректно. Я их соединил в С++ и один индикатор стал промаргивать нулями.
ну CTRL+F можно было сделать...
#include <OneWire.h> // термометр #include <DallasTemperature.h> // термометр #include <TM1637.h> // термометр #include <RTClib.h> OneWire oneWireBus(11); // термометр DallasTemperature sensors(&oneWireBus); // термометр TM1637 tm16371(8,9); // добавил // термометр TM1637 tm1637(6,7); RTC_DS3231 rtc; DateTime t; String daysOfTheWeek[7]={"Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sabado"}; String monthsNames[12]={"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"}; long x11; // добавил // термометр? long x22; // добавил // термометр? long x33; // добавил // термометр? long x44; // добавил // термометр? long x1; long x2; long x3; long x4; int s_01; int s_02; long l_01; void func_01() { x1 = int((s_01 / 10)); x2 = s_01 - x1 * 10; x3 = int((s_02 / 10)); x4 = s_02 - x3 * 10; tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_ON); func_02(); delay(500); tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_OFF); func_02(); delay(500); tm16371.point(POINT_OFF); // добавил tm16371.display(0,x11); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(1,x22); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(2,x33); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(3,x44); // добавил func_02(); // добавил // delay(500); // добавил } void func_02() { if (digitalRead(3) == true) { l_01 = l_01 + 1; delay(300); } } void setup() { Serial.begin(9600); // термометр sensors.begin(); // термометр tm1637.init(); tm1637.set(BRIGHT_TYPICAL); tm16371.init(); // термометр tm16371.set(BRIGHT_TYPICAL); // термометр rtc.begin(); x1 = 0; x2 = 0; x3 = 0; x4 = 0; s_01 = 0; s_02 = 0; l_01 = 0; pinMode(4,INPUT); pinMode(3,INPUT); } void loop() { sensors.requestTemperatures(); // термометр Serial.println(sensors.getTempCByIndex(0)); // термометр tm16371.display(sensors.getTempCByIndex(0)); // термометр, изменил tm1637 t=rtc.now(); s_01 = t.hour(); s_02 = t.minute(); if (l_01 == 0) { func_01(); } if (l_01 == 1) { func_02(); tm1637.display(s_01); if (digitalRead(4) == true) { s_01 = s_01 + 1; if (s_01 >= 24) { s_01 = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,s_01,s_02,0)); tm1637.display(s_01); delay(300); } } if (l_01 == 2) { func_02(); tm1637.display(s_02); if (digitalRead(4) == true) { s_02 = s_02 + 1; if (s_02 >= 60) { s_02 = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,s_01,s_02,0)); tm1637.display(s_02); delay(300); } } if (l_01 == 3) { l_01 = 0; } }Если бы я в С++ разбирался и знал, что там закодировано, я б наверное за помощью не обращался.
По отдельности оба кода работают корректно. Я их соединил в С++ и один индикатор стал промаргивать нулями.
Ты на форуме 7 лет. Хрен с ним, что не понимаешь как «запрограммировать», но что тролить тебя будет как ты мог не знать?!)))
Если бы я в С++ разбирался и знал, что там закодировано, я б наверное за помощью не обращался.
По отдельности оба кода работают корректно. Я их соединил в С++ и один индикатор стал промаргивать нулями.
Ты на форуме 7 лет. Хрен с ним, что не понимаешь как «запрограммировать», но что тролить тебя будет как ты мог не знать?!)))
Администраторы форума - добавьте кнопку «темы пользователя», так на много проще будет.
Если бы я в С++ разбирался и знал, что там закодировано, я б наверное за помощью не обращался.
По отдельности оба кода работают корректно. Я их соединил в С++ и один индикатор стал промаргивать нулями.
Ты на форуме 7 лет. Хрен с ним, что не понимаешь как «запрограммировать», но что тролить тебя будет как ты мог не знать?!)))
Администраторы форума - добавьте кнопку «темы пользователя», так на много проще будет.
Знал, они ныньче в каждой бочке затычки. Чхать на них.
Я тебе подскажу, что форумчане хотят - есть такая функция «автозамена». Так вот замени свои «36443 и тд» на понятное тебе слова (если это переменная), а если за столько лет не понял этого - только на форуме с подобными (уже привычными им) кракозябрами обращаться нужно.
ЗЫ: Ты же «хлеб» называешь не «533789643468954689», так?)
Если бы я в С++ разбирался и знал, что там закодировано, я б наверное за помощью не обращался.
По отдельности оба кода работают корректно. Я их соединил в С++ и один индикатор стал промаргивать нулями.
ну CTRL+F можно было сделать...
#include <OneWire.h> // термометр #include <DallasTemperature.h> // термометр #include <TM1637.h> // термометр #include <RTClib.h> OneWire oneWireBus(11); // термометр DallasTemperature sensors(&oneWireBus); // термометр TM1637 tm16371(8,9); // добавил // термометр TM1637 tm1637(6,7); RTC_DS3231 rtc; DateTime t; String daysOfTheWeek[7]={"Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sabado"}; String monthsNames[12]={"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"}; long x11; // добавил // термометр? long x22; // добавил // термометр? long x33; // добавил // термометр? long x44; // добавил // термометр? long x1; long x2; long x3; long x4; int s_01; int s_02; long l_01; void func_01() { x1 = int((s_01 / 10)); x2 = s_01 - x1 * 10; x3 = int((s_02 / 10)); x4 = s_02 - x3 * 10; tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_ON); func_02(); delay(500); tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_OFF); func_02(); delay(500); tm16371.point(POINT_OFF); // добавил tm16371.display(0,x11); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(1,x22); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(2,x33); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(3,x44); // добавил func_02(); // добавил // delay(500); // добавил } void func_02() { if (digitalRead(3) == true) { l_01 = l_01 + 1; delay(300); } } void setup() { Serial.begin(9600); // термометр sensors.begin(); // термометр tm1637.init(); tm1637.set(BRIGHT_TYPICAL); tm16371.init(); // термометр tm16371.set(BRIGHT_TYPICAL); // термометр rtc.begin(); x1 = 0; x2 = 0; x3 = 0; x4 = 0; s_01 = 0; s_02 = 0; l_01 = 0; pinMode(4,INPUT); pinMode(3,INPUT); } void loop() { sensors.requestTemperatures(); // термометр Serial.println(sensors.getTempCByIndex(0)); // термометр tm16371.display(sensors.getTempCByIndex(0)); // термометр, изменил tm1637 t=rtc.now(); s_01 = t.hour(); s_02 = t.minute(); if (l_01 == 0) { func_01(); } if (l_01 == 1) { func_02(); tm1637.display(s_01); if (digitalRead(4) == true) { s_01 = s_01 + 1; if (s_01 >= 24) { s_01 = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,s_01,s_02,0)); tm1637.display(s_01); delay(300); } } if (l_01 == 2) { func_02(); tm1637.display(s_02); if (digitalRead(4) == true) { s_02 = s_02 + 1; if (s_02 >= 60) { s_02 = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,s_01,s_02,0)); tm1637.display(s_02); delay(300); } } if (l_01 == 3) { l_01 = 0; } }Вопрос по коду. Это исправленный код? Если да, то с ним тоже самое происходит.
Я тебе подскажу, что форумчане хотят - есть такая функция «автозамена». Так вот замени свои «36443 и тд» на понятное тебе слова (если это переменная), а если за столько лет не понял этого - только на форуме с подобными (уже привычными им) кракозябрами обращаться нужно.
ЗЫ: Ты же «хлеб» называешь не «533789643468954689», так?)
Ти по того?
[code] #include <OneWire.h> // термометр #include <DallasTemperature.h> // термометр #include "TM1637.h" // термометр #include <RTClib.h> OneWire oneWireBus(11); // термометр DallasTemperature sensors(&oneWireBus); // термометр TM1637 tm16371(8,9); // добавил // термометр TM1637 tm1637(6,7); RTC_DS3231 rtc; DateTime t; String daysOfTheWeek[7]={"Domingo","Lunes","Martes","Miercoles","Jueves","Viernes","Sabado"}; String monthsNames[12]={"Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"}; long x11; // добавил // термометр? long x22; // добавил // термометр? long x33; // добавил // термометр? long x44; // добавил // термометр? long x1; long x2; long x3; long x4; int chas; // _D0_A7_D0_B0_D1_81 int minuti; // _D0_9C_D0_B8_D0_BD_D1_83_D1_82_D1_8B long xren; void two_xrenthree_xren() { x1 = int((chas / 10)); x2 = chas - x1 * 10; x3 = int((minuti / 10)); x4 = minuti - x3 * 10; tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_ON); xren2(); delay(500); tm1637.display(0,x1); tm1637.display(1,x2); tm1637.display(2,x3); tm1637.display(3,x4); tm1637.point(POINT_OFF); xren2(); // _D0_9C_D0_B5_D0_BD_D1_8E2 delay(500); tm16371.point(POINT_OFF); // добавил tm16371.display(0,x11); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(1,x22); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(2,x33); // добавил tm16371.point(POINT_OFF); // добавил tm16371.display(3,x44); // добавил xren2(); // добавил // delay(500); // добавил } void xren2() { if (digitalRead(3) == true) { xren = xren + 1; delay(300); } } void setup() { Serial.begin(9600); // термометр sensors.begin(); // термометр tm1637.init(); tm1637.set(BRIGHT_TYPICAL); tm16371.init(); // термометр tm16371.set(BRIGHT_TYPICAL); // термометр rtc.begin(); x1 = 0; x2 = 0; x3 = 0; x4 = 0; chas = 0; minuti = 0; xren = 0; pinMode(4,INPUT); pinMode(3,INPUT); } void loop() { sensors.requestTemperatures(); // термометр Serial.println(sensors.getTempCByIndex(0)); // термометр tm16371.display(sensors.getTempCByIndex(0)); // термометр, изменил tm1637 t=rtc.now(); chas = t.hour(); minuti = t.minute(); if (xren == 0) { two_xrenthree_xren(); // _D0_9E_D1_82_D0_BE_D0_B1_D1_80_D0_B0_D0_B6_D0_B5_D0_BD_D0_B8_D0_B5_three_xren } if (xren == 1) { xren2(); // _D0_9C_D0_B5_D0_BD_D1_8E2 tm1637.display(chas); if (digitalRead(4) == true) { chas = chas + 1; if (chas >= 24) { chas = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,chas,minuti,0)); tm1637.display(chas); delay(300); } } if (xren == 2) { xren2(); // _D0_9C_D0_B5_D0_BD_D1_8E2 tm1637.display(minuti); if (digitalRead(4) == true) { minuti = minuti + 1; if (minuti >= 60) { minuti = 0; } t=rtc.now(); rtc.adjust(DateTime(20,9,12,chas,minuti,0)); tm1637.display(minuti); delay(300); } } if (xren == 3) { xren = 0; } } [/code]ну CTRL+F можно было сделать...
а смысл?
Код после автогенерации нормальным от этого не станет
Доброго времени. Да простит меня ТС - не стал создавать новую тему, т.к. тоже имеется(небольшая) проблема с выводом на 2 дисплея ТМ1637. На втором дисплее, при температуре меньше -9,9 (т.е -10 и ниже) не выводится первая единица у показаний влажности. Такое ощущение, что не срабатывает условие в 40 строке. Но по радиоканалу передается все как нужно, hHum = 100. Так, что проблема именно здесь. Хоть и не великая, но все же хочу понять из-за чего.
На пальцах:
******
* -9,9*
******
*100%* (в данный момент влажность датчик показывает больше 100%, как не знаю)
******
******
*-10.0*
******
* 00%*
******
как то так отображает.
Всю голову уже сломал, не могу понять в чем дело.
//==== Выводим данные на дисплеи ==== // void WriteToDisplay(){ if (abs(hTmp) > 9){ if (negFlg){ dataT[0] = SEG_G; // 1 символ dataT[1] = dispTemp.encodeDigit(abs(hTmp) / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp) % 10) | SEG_H; // 3 символ }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = dispTemp.encodeDigit(hTmp / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp % 10) | SEG_H; // 3 символ }// end else }// end if else{ if (negFlg){ dataT[0] = 0; // 1 символ dataT[1] = SEG_G; // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp)) | SEG_H; // 3 символ }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = 0; // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp) | SEG_H; // 3 символ }// end else }// end else dataT[3] = dispTemp.encodeDigit(lTmp); // 4 символ dispTemp.setSegments(dataT); // выводим на 1 дисплей if (prtVolt){ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b - (batt) dataH[1] = dispHum.encodeDigit(int(realVolt)) | SEG_H; // 1 символ + точка dataH[2] = dispHum.encodeDigit(int(realVolt * 100) / 10 % 10); // 2 символ dataH[3] = dispHum.encodeDigit(int(realVolt * 100) % 10); // 3 символ }//end if else{ // если больше 99, выводим 100 if (hHum > 99){ dataH[0] = SEG_B |SEG_C; // 1 символ (единица) dataH[1] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 2 символ dataH[2] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 3 символ }//end if else { dataH[0] = 0; // 1 символ (пусто) dataH[1] = dispHum.encodeDigit(hHum / 10); // 2 символ dataH[2] = dispHum.encodeDigit(hHum % 10); // 3 символ }//end else dataH[3] = SEG_C | SEG_F; // 4 символ (типа проценты) }//end else dispHum.setSegments(dataH); // выводим на 2 дисплей }// end WriteToDisplay()mir0tv0rec, показывай весь код
библиотеку другую возьмите, и не надо будет по цифиркам вывод разбивать
библиотеку другую возьмите, и не надо будет по цифиркам вывод разбивать
Для удобства работы можно форкнуть и далее сделать новый branch )))
Для удобства работы можно форкнуть и далее сделать новый branch )))
похоже кто-то осваиваем гитхаб :)))
Вот весь код:
// Подключаем библиотеки: #include <iarduino_RF433_Transmitter.h> // Подключаем библиотеку для работы с передатчиком FS1000A #include <SPI.h> // подключаем библиотеку для работы с шиной SPI #include <Wire.h> // подключаем библиотеку для работы с шиной I2C #include <sav_button.h> // подключаем библиотеку для работы с кнопками #include <Adafruit_HTU21DF.h> // подключаем библиотеку для работы с HTU21DF #include "TM1637Display.h" // подключаем библиотеку для работы с TM1637 (для отладки) #define CLK_PIN_T 6 // пин TM1637 - температура #define DIO_PIN_T 7 // пин TM1637 - температура #define CLK_PIN_H 8 // пин TM1637 - влажность #define DIO_PIN_H 9 // пин TM1637 - - влажность #define BT_PIN 2 // Пин подключения кнопки #define RF_PIN 4 // Пин подключения передатчика #define CHRG_IN_PIN PD3 // Пин отслеживание подключения ЗУ #define CHRG_ON_PIN PD5 // Пин управления полевиком зарядки АКБ #define RD_WAIT 10000 // Пауза в миллисекундах между опросами датчика #define LOW_VOLT 175 // Значение низкого напряжения АКБ ~3V #define HIGH_VOLT 242 // Значение высокого напряжения АКБ ~4.15V Adafruit_HTU21DF HTU21 = Adafruit_HTU21DF(); // Создаём объект HTU21 для работы с библиотекой Adafruit_HTU21DF iarduino_RF433_Transmitter radio(RF_PIN); // Создаём объект radio для работы с библиотекой iarduino_RF433, указывая номер вывода к которому подключён передатчик TM1637Display dispTemp(CLK_PIN_T, DIO_PIN_T); // объявляем переменную для работы с TM1637 (температура) TM1637Display dispHum(CLK_PIN_H, DIO_PIN_H); // объявляем переменную для работы с TM1637 (влажность) unsigned long ms, ms1, ms2; // переменная таймера float realTemp, realHum; // переменные для хранения температуры и влажности float realVolt; // переменные для хранения значения напряжения uint8_t backTime = 0; // время отображения uint8_t brLvl = 1 ; // уровень яркости 0-7 uint8_t maxBr = 3 ; // максимальный уровень яркости 0-7 int16_t hTmp; // переменные для разбивки температуры по разрядам uint8_t lTmp; // переменные для разбивки температуры по разрядам uint8_t hHum; // влажность uint8_t analog_ref = DEFAULT; // переменная для хранения состояния регистра ADMUX bool autoBr = true; // флаг включения дисплея bool prtVolt = false; // флаг вывода напряжения bool brPin = false; // флаг выбора входа АЦП bool trueValue = false; // переменная для пропуска преобразования АЦП при переключении входов bool lowVoltage = false; // флаг низкого напряжения bool charging = false; // флаг включения зарядки АКБ bool longClick = false; // флаг удержание кнопки bool negFlg = false; // флаг отрицательной температуры uint8_t countBr = 0, countVolt = 0, // countV1 = 0, countV2 = 0, // счетчики countVDisp = 0, countAuto = 0; // uint8_t voltVal = 0; // значение с АЦП для ослеживания пропадания напряжения питания uint16_t voltValTmp = 0; // значение для временного хранения и усреднения занчений с АЦП uint8_t brightVal = 0; // значение с АЦП для автоматического изменения яркости uint16_t brightValTmp = 0; // значение с АЦП для автоматического изменения яркости const uint8_t SEG_Err[] = { SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E SEG_E | SEG_G, // r SEG_E | SEG_G // r }; uint8_t dataT[] = {0x00, 0x00, 0x00, 0x00}; // массив для вывода данных на дисплей температуры uint8_t dataH[] = {0x00, 0x00, 0x00, 0x00}; // массив для вывода данных на дисплей влажности char msg[20]; SButton BUT (BT_PIN, 50, 1500, 0, 0); //==== Выводим данные на дисплеи ==== void WriteToDisplay(){ if (abs(hTmp) > 9){ if (negFlg){ dataT[0] = SEG_G; // 1 символ dataT[1] = dispTemp.encodeDigit(abs(hTmp) / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp) % 10) | SEG_H; // 3 символ }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = dispTemp.encodeDigit(hTmp / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp % 10) | SEG_H; // 3 символ }// end else }// end if else{ if (negFlg){ dataT[0] = 0; // 1 символ dataT[1] = SEG_G; // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp)) | SEG_H; // 3 символ }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = 0; // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp) | SEG_H; // 3 символ }// end else }// end else dataT[3] = dispTemp.encodeDigit(lTmp); // 4 символ dispTemp.setSegments(dataT); // выводим на 1 дисплей if (prtVolt){ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b - (batt) dataH[1] = dispHum.encodeDigit(int(realVolt)) | SEG_H; // 1 символ + точка dataH[2] = dispHum.encodeDigit(int(realVolt * 100) / 10 % 10); // 2 символ dataH[3] = dispHum.encodeDigit(int(realVolt * 100) % 10); // 3 символ }//end if else{ // если влажность больше 99, выводим 100 (датчик почему-то кажет до 119%) if (hHum > 99){ dataH[0] = SEG_C |SEG_B; // 1 символ (единица) dataH[1] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 2 символ dataH[2] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 3 символ }//end if else { dataH[0] = 0; // 1 символ (пусто) if (hHum < 10){ dataH[1] = 0; // 2 символ dataH[2] = dispHum.encodeDigit(hHum); // 3 символ }//end if else{ dataH[1] = dispHum.encodeDigit(hHum / 10); // 2 символ dataH[2] = dispHum.encodeDigit(hHum % 10); // 3 символ }//end else }//end else dataH[3] = SEG_C | SEG_F; // 4 символ (типа проценты) }//end else dispHum.setSegments(dataH); // выводим на 2 дисплей }// end WriteToDisplay() //==== Выводим данные на дисплеи ==== // void WriteAuto(){ if (autoBr){ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b dataH[1] = SEG_E |SEG_G; // r dataH[2] = SEG_G; // - dataH[3] = SEG_A |SEG_B | SEG_C |SEG_E |SEG_F |SEG_G; // A }//end if else{ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b dataH[1] = SEG_E |SEG_G; // r dataH[2] = SEG_G; // - dataH[3] = SEG_C |SEG_E | SEG_G; // n }//end else dispHum.setSegments(dataH); // выводим на 2 дисплей }// end WriteToDisplay() //------------------------------------------------------ // инициализируем АЦП // void ADC_init(){ ACSR = 0x00; // сбрасываем регистр компаратора ACSR |= 1 << ACD; // выключаем питание компаратора ADCSRA = 0; // Сбрасываем регистр ADCSRA ADCSRB = 0; // Сбрасываем регистр ADCSRB ADMUX |= (1 << REFS1) | (1 << REFS0); // Задаем ИОН внутренний 1.1В (для АТМега328) ADMUX |= (1 << ADLAR); // Меняем порядок записи бит, чтобы можно было читать только 8 бит регистра ADCH analog_ref = ADMUX; // Запоминаем состояние регистра - из него мы будем формировать маску для смены входного пина вход A0 ADMUX |= (1 << MUX2) | (1 << MUX1); // Выбираем пин A6 для преобразования ADCSRA |= (1 << ADPS2) | (1 << ADPS1); // Устанавливаем предделитель - 64(125кГц) (биты 1 1 0) ADCSRA |= (1 << ADEN); // Включаем АЦП }// ADC_init() //---------------------------------------------------------- // Считываем значения с АЦП void ADC_Read(){ if (trueValue) { uint8_t result = ADCH; // ADLAR=1, Получаем 8-битный результат, 2 младшими битами пренебрегаем (ADCL) // Если актуальный входной пин A7, то присваиваем значение соответствующей переменной if (brPin) { if (countBr < 10){ brightValTmp += result; countBr++; }// end if else{ brightVal = brightValTmp / countBr; brightValTmp = 0; countBr = 0; brPin = false; // выбираем пин ADMUX = analog_ref; // сбрасываем вход (A0) ADMUX |= (1 << MUX2) | (1 << MUX1); // Выбираем пин A6 для преобразования }// end else }// end if else { if (countVolt < 10){ //10 отсчетов для более стабильного результата voltValTmp += result; countVolt++; }// end if else { voltVal = voltValTmp / countVolt; // находим среднее значание из количества отсчетов voltValTmp = 0; // обнуляем временную переменную countVolt = 0; // обнуляем счетчик if (voltVal <= LOW_VOLT) { // если напряжения меньше LOW_VOLT countV1++; // инкрементируем счетчик if (countV1 > 4){ // считываем несколько раз, исключая ошибку countV1 = 0; // обнуляем счетчик lowVoltage = true; // устанавливаем флаг низкого напряжения // Если не включена зарядка и подключено ЗУ if (!charging && (PIND & (1 << CHRG_IN_PIN))){ charging = true; // флаг включения зарядки АКБ PORTD |= (1 << CHRG_ON_PIN); // подключаем АКБ к зарядке (полевик) }//end if (!charging && (PIND & (1 << PD3))) // Если включена зарядка и отключили ЗУ if (charging && !(PIND & (1 << CHRG_IN_PIN))){ charging = false; // флаг включения зарядки АКБ }//end if (!charging && (PIND & (1 << PD3))) }// end if (countV1 > 4) }// end if (voltVal < LOW_VOLT) else{ if (lowVoltage) lowVoltage = false; // флаг низкого напряжения // если включена зарядка и отключили ЗУ if (!(PIND & (1 << CHRG_IN_PIN))){ charging = false; // флаг включения зарядки АКБ PORTD &= ~(1 << CHRG_ON_PIN); // отключаем АКБ от зарядки (полевик) }//end if }//end else if (voltVal >= HIGH_VOLT){ countV2++; // инкрементируем счетчик if (countV2 > 4){ // countV2 = 0; // обнуляем счетчик // если шла зарядка if (charging){ charging = false; // флаг зарядки PORTD &= ~(1 << CHRG_ON_PIN); // отключаем АКБ от зарядки (полевик) }//end if (charging) }// end if (countV2 > 4) }// end if brPin = true; // выбираем пин ADMUX = analog_ref; // сбрасываем вход ADMUX |= (1 << MUX2) | (1 << MUX1) | (1 << MUX0); // Выбираем пин A7 для преобразования }// end else }// end else trueValue = false; // Устанавливаем флаг смены входного пина - следующее прерывание пропускаем }// end if (trueValue) else { trueValue = true; // Первый раз пропускаем считывание и устанавливаем флаг на чтение в следующий раз }// end else }// ADC_Read() //---------------------------------------------- // авторегулировка яркости void AutoBright(){ uint8_t brLvlAuto = 0; if (brightVal <= 170){ brLvlAuto = 0; }// end if else if (brightVal > 180 && brightVal <= 200){ brLvlAuto = 1; }//end else if else if (brightVal > 210 && brightVal <= 230){ brLvlAuto = 2; }//end else if else if (brightVal > 240){ brLvlAuto = 3; }//end else if dispTemp.setBrightness(brLvlAuto); // устанавливаем яркость dispHum.setBrightness(brLvlAuto); // устанавливаем яркость }// end AutoBright() // вывод "Ошибка" на дисплеи // void HTUErr() { while (!HTU21.begin()) { dispTemp.setSegments(SEG_Err); // выводим "Err" delay(1000); dispTemp.clear(); dispHum.setSegments(SEG_Err); // выводим "Err" delay(1000); dispHum.clear(); }// end while }//end HTUErr() void setup() { //Serial.begin(9600); DDRD |= (1 << CHRG_ON_PIN); // пин включения зарядки на выход PORT PD5 //PORTD |= (1 << CHRG_ON_PIN); // высокий уровеннь на пине dispTemp.setBrightness(brLvl); // устанавливаем яркость dispHum.setBrightness(brLvl); // устанавливаем яркость radio.begin(); // Инициируем работу передатчика FS1000A radio.setDataRate(i433_1KBPS); // Cкорость передачи данных radio.openWritingPipe(5); // Открываем 5 трубу для передачи данных BUT.begin(); ADC_init(); }// end setup() void loop() { // если есть результаты преобразования АЦП if (!(ADCSRA & (1 << ADSC))) { ADC_Read(); // Считываем и обрабатываем данные с АЦП realVolt = 3.95 / 231 * voltVal; // получаем значение в вольтах ADCSRA |= (1 << ADSC); // Запускаем преобразование }//end if // Устанавливаем уровень яркость в автоматическом режиме // Выводим информацию на дисплеи if (millis() - ms2 > 250) { ms2 = millis(); if (prtVolt) { countVDisp++; // инкрементируем счетчик времени отображения на дисплее if (countVDisp > 12) { prtVolt = false; countVDisp = 0; }// end if }//end if if (autoBr) AutoBright(); if (longClick) { WriteAuto(); // выводим на дисплей br-A / br-n countAuto++; if (countAuto > 8) { countAuto = 0; longClick = false; }//end if }//end if else WriteToDisplay(); // выводим информацию на дисплеи }// end if // моргаем диодом зарядки при разряженной АКБ, если не подключено ЗУ if ((millis() - ms) > 1000) { ms = millis(); // если низкий заряд и не подключена зарядка if (lowVoltage && !(PIND & (1 << CHRG_IN_PIN))) { PORTD ^= (1 << CHRG_ON_PIN); // мигаем диодом зарядки }//end if }//end if // считываем показания датчика раз в RD_WAIT mc if ((millis() - ms1) > RD_WAIT) { ms1 = millis(); if (!HTU21.begin()) { HTUErr(); // переходим в функцию ошибки delay(500); // задержка после инициализации датчика }//end if realTemp = HTU21.readTemperature(); if (realTemp < 0) negFlg = true; else negFlg = false; //Serial.println(realTemp); // отладка if (negFlg) hTmp = (realTemp - 0.01) * 100; // приводим к целому else hTmp = realTemp * 100; // приводим к целому lTmp = abs(hTmp) % 100; // отделяем десятые hTmp = hTmp / 100; // отделяем целые //округляем до десятых if (lTmp % 10 < 5) lTmp = lTmp / 10; // если сотые меньше 5 else if (lTmp / 10 < 9) lTmp = lTmp / 10 + 1; // если сотые больше 4, число меньше 90 else{ // если > 94 lTmp = 0; // обнуляем if (negFlg) hTmp--; // увеличиваем десятки else hTmp++; }// end else if // вводим поправочный коэфф. при темп. от 0 до 80 // влажность с учетом поправочного коэфф. if (realTemp >= 0 && realTemp <= 80) realHum = (HTU21.readHumidity() + (25 - realTemp) * -0.15); else realHum = HTU21.readHumidity(); //Serial.println(realHum); // отладка hHum = round(realHum); // округляем влажность, дробные нам не нужны... if (hHum > 99) hHum = 100; // при высокой влажности датчик может показывать больше 100% String strMsg = "HTU21"; //сигнатура - данные strMsg += "="; //разделитель температуры и влажности strMsg += hTmp; //температуру в строку strMsg += "."; //десятичная точка strMsg += lTmp; //температуру в строку strMsg += "="; //разделитель температуры и влажности strMsg += hHum; //присоединяем влажность strMsg += "="; //разделитель температуры и влажности strMsg += realVolt; //напряжение АКБ strMsg.toCharArray(msg, strMsg.length() + 1); //переводим строку в массив символов radio.write(&msg, sizeof(msg)); // отправляем данные из массива data указывая сколько байт массива мы хотим отправить }//end if //обработка кнопки switch (BUT.Loop()) { case SB_NONE: break; case SB_CLICK: longClick = false; // флаг удержания кнопки if (!autoBr) { brLvl++; if (brLvl > 3) brLvl = 0; // яркость ограничиваем 3 dispTemp.setBrightness(brLvl); // устанавливаем яркость температура dispHum.setBrightness(brLvl); // устанавливаем яркость влажность WriteToDisplay(); // изменяем яркость (нужно вывести данные для изменения яркости) }//end if else { prtVolt = true; // поднимаем флаг отображения напряжения }//end else break; case SB_LONG_CLICK: autoBr = !autoBr; // инвертируем флаг longClick = true; // флаг удержания кнопки prtVolt = false; break; case SB_AUTO_CLICK: break; }//end switch(BUT.Loop()) }//end loopDetSimen, в принципе мне твоя библиотека, думаю, подходит. Просто изначально выводил градусы, проценты. По этому вывод так и сделан.
не знаю, явных ошибок не вижу.
Я бы начал с того, чтоб упростил код. Вместо написания кучи методов вывода на дисплей отдельно для температуры. отдельно для влажности более 99, менее 99, менее 10 и тд - все это можно записать единым образом в виде деления на разряды, как это сделано например для напряжения. Код сократится строк на сто и разбираться в нем станет легче.
Зачем, например, вы задаете вывод числа "100" явно через сегменты?
if (hHum > 99){ dataH[0] = SEG_C |SEG_B; // 1 символ (единица) dataH[1] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 2 символ dataH[2] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 3 символ }//end ifЭто же неправильно, поменяете сегменты - придется полкода переписывать. У вас же есть метод через цифры, пользуйтесь им, это же нагляднее:
if (hHum > 99){ dataH[0] = dispHum.encodeDigit(1); // 1 символ (единица) dataH[1] = dispHum.encodeDigit(0); // 2 символ dataH[2] = dispHum.encodeDigit(0); // 3 символ }//end ifУ меня так и было до этого, но когда увидел, что пропала единица, указал явно посегментно вывод, но это не помогло. Причем, чтобы я там не указывал, как только температура опускается ниже -10 градусов, такое чувство, что условие hHum > 100 перестает выполняться. Ладно попробую через серийник отладить, вручную проимулирую отрицательную температуру, т.к. датчик с улицы снять затруднительно.
Вывел значения в порт:
// считываем показания датчика раз в RD_WAIT mc if ((millis() - ms1) > RD_WAIT) { ms1 = millis(); /* if (!HTU21.begin()) { HTUErr(); // переходим в функцию ошибки delay(500); // задержка после инициализации датчика }//end if realTemp = HTU21.readTemperature(); */ if (realTemp < 0) negFlg = true; else negFlg = false; Serial.println(realTemp); // отладка if (negFlg) hTmp = (realTemp - 0.01) * 100; // приводим к целому else hTmp = realTemp * 100; // приводим к целому lTmp = abs(hTmp) % 100; // отделяем десятые hTmp = hTmp / 100; // отделяем целые //округляем до десятых if (lTmp % 10 < 5) lTmp = lTmp / 10; // если сотые меньше 5 else if (lTmp / 10 < 9) lTmp = lTmp / 10 + 1; // если сотые меньше 94 else{ // если > 94 lTmp = 0; // обнуляем if (negFlg) hTmp--; // увеличиваем десятки else hTmp++; }// end else if /* // вводим поправочный коэфф. при темп. от 0 до 80 // влажность с учетом поправочного коэфф. if (realTemp >= 0 && realTemp <= 80) realHum = (HTU21.readHumidity() + (25 - realTemp) * -0.15); else realHum = HTU21.readHumidity(); */ Serial.println(realHum); // отладка hHum = round(realHum); // округляем влажность, дробные нам не нужны... Serial.println(hHum); // отладка //if (hHum > 99) hHum = 100; // при высокой влажности датчик может показывать больше 100% String strMsg = "HTU21"; //сигнатура - данные strMsg += "="; //разделитель температуры и влажности strMsg += hTmp; //температуру в строку strMsg += "."; //десятичная точка strMsg += lTmp; //температуру в строку strMsg += "="; //разделитель температуры и влажности strMsg += hHum; //присоединяем влажность strMsg += "="; //разделитель температуры и влажности strMsg += realVolt; //напряжение АКБ strMsg.toCharArray(msg, strMsg.length() + 1); //переводим строку в массив символов radio.write(&msg, sizeof(msg)); // отправляем данные из массива data указывая сколько байт массива мы хотим отправить // для отладки realTemp += 0.01; realHum += 1; if(realHum > 120) realHum = 0; }//end if //==== Выводим данные на дисплеи ==== void WriteToDisplay(){ Serial.print("Влажность: "); // отладка Serial.println(hHum); // отладка if (abs(hTmp) > 9){ if (negFlg){ dataT[0] = SEG_G; // 1 символ dataT[1] = dispTemp.encodeDigit(abs(hTmp) / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp) % 10) | SEG_H; // 3 символ Serial.println("Вывели температуру ниже -9"); // отладка }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = dispTemp.encodeDigit(hTmp / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp % 10) | SEG_H; // 3 символ Serial.println("Вывели температуру выше 9"); // отладка }// end else }// end if else{ if (negFlg){ dataT[0] = 0; // 1 символ dataT[1] = SEG_G; // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp)) | SEG_H; // 3 символ Serial.println("Вывели температуру выше -10"); // отладка }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = 0; // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp) | SEG_H; // 3 символ Serial.println("Вывели температуру ниже 10"); // отладка }// end else }// end else dataT[3] = dispTemp.encodeDigit(lTmp); // 4 символ dispTemp.setSegments(dataT); // выводим на 1 дисплей if (prtVolt){ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b - (batt) dataH[1] = dispHum.encodeDigit(int(realVolt)) | SEG_H; // 1 символ + точка dataH[2] = dispHum.encodeDigit(int(realVolt * 100) / 10 % 10); // 2 символ dataH[3] = dispHum.encodeDigit(int(realVolt * 100) % 10); // 3 символ Serial.println("Вывели напряжение АКБ"); // отладка }//end if else{ // если влажность больше 99, выводим 100 (датчик почему-то кажет до 119%) if (hHum > 99){ dataH[0] = SEG_C |SEG_B; // 1 символ (единица) dataH[1] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 2 символ dataH[2] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 3 символ Serial.print("Вывели влажность больше 99%: "); // отладка Serial.println(hHum); // отладка }//end if else { dataH[0] = 0; // 1 символ (пусто) if (hHum < 10){ dataH[1] = 0; // 2 символ dataH[2] = dispHum.encodeDigit(hHum); // 3 символ Serial.println("Вывели влажность меньше 10%"); // отладка }//end if else{ dataH[1] = dispHum.encodeDigit(hHum / 10); // 2 символ dataH[2] = dispHum.encodeDigit(hHum % 10); // 3 символ Serial.println("Вывели влажность меньше 100%"); // отладка }//end else }//end else dataH[3] = SEG_C | SEG_F; // 4 символ (типа проценты) }//end else dispHum.setSegments(dataH); // выводим на 2 дисплей }// end WriteToDisplay()Почему-то при температуре меньше -9,9 в функции WriteToDisplay() влажность выше 99 обнуляется.
а вот тут уже все, как и должно быть:
похоже на порчу значения в памяти из-за выхода за границу массива.
mir0tv0rec - не имейте плохой привычки выкладывать куски кода.
Давайте вот этот код, с отладочными выводами в Сериал - но целиком.
Полный код выше, здесь выложил только изменения, для понимания, где беру данные для вывода в .serial.
// Подключаем библиотеки: #include <iarduino_RF433_Transmitter.h> // Подключаем библиотеку для работы с передатчиком FS1000A #include <SPI.h> // подключаем библиотеку для работы с шиной SPI #include <Wire.h> // подключаем библиотеку для работы с шиной I2C #include <sav_button.h> // подключаем библиотеку для работы с кнопками #include <Adafruit_HTU21DF.h> // подключаем библиотеку для работы с HTU21DF #include "TM1637Display.h" // подключаем библиотеку для работы с TM1637 (для отладки) #define CLK_PIN_T 6 // пин TM1637 - температура #define DIO_PIN_T 7 // пин TM1637 - температура #define CLK_PIN_H 8 // пин TM1637 - влажность #define DIO_PIN_H 9 // пин TM1637 - влажность #define BT_PIN 2 // Пин подключения кнопки #define RF_PIN 4 // Пин подключения передатчика #define CHRG_IN_PIN PD3 // Пин отслеживание подключения ЗУ #define CHRG_ON_PIN PD5 // Пин управления полевиком зарядки АКБ #define RD_WAIT 500 // Пауза в миллисекундах между опросами датчика #define LOW_VOLT 175 // Значение низкого напряжения АКБ ~3V #define HIGH_VOLT 242 // Значение высокого напряжения АКБ ~4.15V Adafruit_HTU21DF HTU21 = Adafruit_HTU21DF(); // Создаём объект HTU21 для работы с библиотекой Adafruit_HTU21DF iarduino_RF433_Transmitter radio(RF_PIN); // Создаём объект radio для работы с библиотекой iarduino_RF433, указывая номер вывода к которому подключён передатчик TM1637Display dispTemp(CLK_PIN_T, DIO_PIN_T); // объявляем переменную для работы с TM1637 (температура) TM1637Display dispHum(CLK_PIN_H, DIO_PIN_H); // объявляем переменную для работы с TM1637 (влажность) unsigned long ms, ms1, ms2; // переменная таймера float realTemp, realHum; // переменные для хранения температуры и влажности float realVolt; // переменные для хранения значения напряжения uint8_t backTime = 0; // время отображения uint8_t brLvl = 1 ; // уровень яркости 0-7 uint8_t maxBr = 3 ; // максимальный уровень яркости 0-7 int16_t hTmp; // переменные для разбивки температуры по разрядам uint8_t lTmp; // переменные для разбивки температуры по разрядам uint8_t hHum; // влажность uint8_t analog_ref = DEFAULT; // переменная для хранения состояния регистра ADMUX bool autoBr = true; // флаг включения дисплея bool prtVolt = false; // флаг вывода напряжения bool brPin = false; // флаг выбора входа АЦП bool trueValue = false; // переменная для пропуска преобразования АЦП при переключении входов bool lowVoltage = false; // флаг низкого напряжения bool charging = false; // флаг включения зарядки АКБ bool longClick = false; // флаг удержание кнопки bool negFlg = false; // флаг отрицательной температуры uint8_t countBr = 0, countVolt = 0, // countV1 = 0, countV2 = 0, // счетчики countVDisp = 0, countAuto = 0; // uint8_t voltVal = 0; // значение с АЦП для ослеживания пропадания напряжения питания uint16_t voltValTmp = 0; // значение для временного хранения и усреднения занчений с АЦП uint8_t brightVal = 0; // значение с АЦП для автоматического изменения яркости uint16_t brightValTmp = 0; // значение с АЦП для автоматического изменения яркости const uint8_t SEG_Err[] = { SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E SEG_E | SEG_G, // r SEG_E | SEG_G // r }; uint8_t dataT[] = {0x00, 0x00, 0x00, 0x00}; // массив для вывода данных на дисплей температуры uint8_t dataH[] = {0x00, 0x00, 0x00, 0x00}; // массив для вывода данных на дисплей влажности char msg[20]; SButton BUT (BT_PIN, 50, 1500, 0, 0); //#include "text_to_disp.h" // кусок кода из файла //==== Выводим данные на дисплеи ==== void WriteToDisplay(){ Serial.print("Влажность: "); // отладка Serial.println(hHum); // отладка if (abs(hTmp) > 9){ if (negFlg){ dataT[0] = SEG_G; // 1 символ dataT[1] = dispTemp.encodeDigit(abs(hTmp) / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp) % 10) | SEG_H; // 3 символ Serial.println("Вывели температуру ниже -9"); // отладка }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = dispTemp.encodeDigit(hTmp / 10); // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp % 10) | SEG_H; // 3 символ Serial.println("Вывели температуру выше 9"); // отладка }// end else }// end if else{ if (negFlg){ dataT[0] = 0; // 1 символ dataT[1] = SEG_G; // 2 символ dataT[2] = dispTemp.encodeDigit(abs(hTmp)) | SEG_H; // 3 символ Serial.println("Вывели температуру выше -10"); // отладка }// end if else{ dataT[0] = 0; // 1 символ dataT[1] = 0; // 2 символ dataT[2] = dispTemp.encodeDigit(hTmp) | SEG_H; // 3 символ Serial.println("Вывели температуру ниже 10"); // отладка }// end else }// end else dataT[3] = dispTemp.encodeDigit(lTmp); // 4 символ dispTemp.setSegments(dataT); // выводим на 1 дисплей if (prtVolt){ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b - (batt) dataH[1] = dispHum.encodeDigit(int(realVolt)) | SEG_H; // 1 символ + точка dataH[2] = dispHum.encodeDigit(int(realVolt * 100) / 10 % 10); // 2 символ dataH[3] = dispHum.encodeDigit(int(realVolt * 100) % 10); // 3 символ Serial.println("Вывели напряжение АКБ"); // отладка }//end if else{ // если влажность больше 99, выводим 100 (датчик почему-то кажет до 119%) if (hHum > 99){ dataH[0] = SEG_C |SEG_B; // 1 символ (единица) dataH[1] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 2 символ dataH[2] = SEG_A |SEG_B | SEG_C |SEG_D | SEG_E | SEG_F; // 3 символ Serial.print("Вывели влажность больше 99%: "); // отладка Serial.println(hHum); // отладка }//end if else { dataH[0] = 0; // 1 символ (пусто) if (hHum < 10){ dataH[1] = 0; // 2 символ dataH[2] = dispHum.encodeDigit(hHum); // 3 символ Serial.println("Вывели влажность меньше 10%"); // отладка }//end if else{ dataH[1] = dispHum.encodeDigit(hHum / 10); // 2 символ dataH[2] = dispHum.encodeDigit(hHum % 10); // 3 символ Serial.println("Вывели влажность меньше 100%"); // отладка }//end else }//end else dataH[3] = SEG_C | SEG_F; // 4 символ (типа проценты) }//end else dispHum.setSegments(dataH); // выводим на 2 дисплей }// end WriteToDisplay() //==== Выводим данные на дисплеи ==== void WriteAuto(){ if (autoBr){ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b dataH[1] = SEG_E |SEG_G; // r dataH[2] = SEG_G; // - dataH[3] = SEG_A |SEG_B | SEG_C |SEG_E |SEG_F |SEG_G; // A }//end if else{ dataH[0] = SEG_C |SEG_D | SEG_E |SEG_F |SEG_G; // b dataH[1] = SEG_E |SEG_G; // r dataH[2] = SEG_G; // - dataH[3] = SEG_C |SEG_E | SEG_G; // n }//end else dispHum.setSegments(dataH); // выводим на 2 дисплей }// end WriteToDisplay() //#include "ADC.h" // кусок кода из файла /------------------------------------------------------ // инициализируем АЦП // void ADC_init(){ ACSR = 0x00; // сбрасываем регистр компаратора ACSR |= 1 << ACD; // выключаем питание компаратора ADCSRA = 0; // Сбрасываем регистр ADCSRA ADCSRB = 0; // Сбрасываем регистр ADCSRB ADMUX |= (1 << REFS1) | (1 << REFS0); // Задаем ИОН внутренний 1.1В (для АТМега328) ADMUX |= (1 << ADLAR); // Меняем порядок записи бит, чтобы можно было читать только 8 бит регистра ADCH analog_ref = ADMUX; // Запоминаем состояние регистра - из него мы будем формировать маску для смены входного пина вход A0 ADMUX |= (1 << MUX2) | (1 << MUX1); // Выбираем пин A6 для преобразования ADCSRA |= (1 << ADPS2) | (1 << ADPS1); // Устанавливаем предделитель - 64(125кГц) (биты 1 1 0) ADCSRA |= (1 << ADEN); // Включаем АЦП }// ADC_init() //---------------------------------------------------------- // Считываем значения с АЦП void ADC_Read(){ if (trueValue) { uint8_t result = ADCH; // ADLAR=1, Получаем 8-битный результат, 2 младшими битами пренебрегаем (ADCL) // Если актуальный входной пин A7, то присваиваем значение соответствующей переменной if (brPin) { if (countBr < 10){ brightValTmp += result; countBr++; }// end if else{ brightVal = brightValTmp / countBr; brightValTmp = 0; countBr = 0; brPin = false; // выбираем пин ADMUX = analog_ref; // сбрасываем вход (A0) ADMUX |= (1 << MUX2) | (1 << MUX1); // Выбираем пин A6 для преобразования }// end else }// end if else { if (countVolt < 10){ //10 отсчетов для более стабильного результата voltValTmp += result; countVolt++; }// end if else { voltVal = voltValTmp / countVolt; // находим среднее значение из количества отсчетов voltValTmp = 0; // обнуляем временную переменную countVolt = 0; // обнуляем счетчик if (voltVal <= LOW_VOLT) { // если напряжения меньше LOW_VOLT countV1++; // инкрементируем счетчик if (countV1 > 4){ // считываем несколько раз, исключая ошибку countV1 = 0; // обнуляем счетчик lowVoltage = true; // устанавливаем флаг низкого напряжения // Если не включена зарядка и подключено ЗУ if (!charging && (PIND & (1 << CHRG_IN_PIN))){ charging = true; // флаг включения зарядки АКБ PORTD |= (1 << CHRG_ON_PIN); // подключаем АКБ к зарядке (полевик) }//end if (!charging && (PIND & (1 << PD3))) // Если включена зарядка и отключили ЗУ if (charging && !(PIND & (1 << CHRG_IN_PIN))){ charging = false; // флаг включения зарядки АКБ }//end if (!charging && (PIND & (1 << PD3))) }// end if (countV1 > 4) }// end if (voltVal < LOW_VOLT) else{ if (lowVoltage) lowVoltage = false; // флаг низкого напряжения // если включена зарядка и отключили ЗУ if (!(PIND & (1 << CHRG_IN_PIN))){ charging = false; // флаг включения зарядки АКБ PORTD &= ~(1 << CHRG_ON_PIN); // отключаем АКБ от зарядки (полевик) }//end if }//end else if (voltVal >= HIGH_VOLT){ countV2++; // инкрементируем счетчик if (countV2 > 4){ // countV2 = 0; // обнуляем счетчик // если шла зарядка if (charging){ charging = false; // флаг зарядки PORTD &= ~(1 << CHRG_ON_PIN); // отключаем АКБ от зарядки (полевик) }//end if (charging) }// end if (countV2 > 4) }// end if brPin = true; // выбираем пин ADMUX = analog_ref; // сбрасываем вход ADMUX |= (1 << MUX2) | (1 << MUX1) | (1 << MUX0); // Выбираем пин A7 для преобразования }// end else }// end else trueValue = false; // Устанавливаем флаг смены входного пина - следующее прерывание пропускаем }// end if (trueValue) else { trueValue = true; // Первый раз пропускаем считывание и устанавливаем флаг на чтение в следующий раз }// end else }// ADC_Read() //#include "autobright.h" // кусок кода из файла //---------------------------------------------- // авторегулировка яркости void AutoBright(){ uint8_t brLvlAuto = 0; if (brightVal <= 170){ brLvlAuto = 0; }// end if else if (brightVal > 180 && brightVal <= 200){ brLvlAuto = 1; }//end else if else if (brightVal > 210 && brightVal <= 230){ brLvlAuto = 2; }//end else if else if (brightVal > 240){ brLvlAuto = 3; }//end else if dispTemp.setBrightness(brLvlAuto); // устанавливаем яркость dispHum.setBrightness(brLvlAuto); // устанавливаем яркость }// end AutoBright() // вывод "Ошибка" на дисплеи // void HTUErr() { while (!HTU21.begin()) { dispTemp.setSegments(SEG_Err); // выводим "Err" delay(1000); dispTemp.clear(); dispHum.setSegments(SEG_Err); // выводим "Err" delay(1000); dispHum.clear(); }// end while }//end HTUErr() void setup() { Serial.begin(9600); DDRD |= (1 << CHRG_ON_PIN); // пин включения зарядки на выход PORT PD5 //PORTD |= (1 << CHRG_ON_PIN); // высокий уровеннь на пине dispTemp.setBrightness(brLvl); // устанавливаем яркость dispHum.setBrightness(brLvl); // устанавливаем яркость radio.begin(); // Инициируем работу передатчика FS1000A radio.setDataRate(i433_1KBPS); // Cкорость передачи данных radio.openWritingPipe(5); // Открываем 5 трубу для передачи данных BUT.begin(); ADC_init(); // для отладки realTemp = -11.01; realHum = 0; }// end setup() void loop() { // если есть результаты преобразования АЦП if (!(ADCSRA & (1 << ADSC))) { ADC_Read(); // Считываем и обрабатываем данные с АЦП realVolt = 3.95 / 231 * voltVal; // получаем значение в вольтах ADCSRA |= (1 << ADSC); // Запускаем преобразование }//end if // Устанавливаем уровень яркость в автоматическом режиме // Выводим информацию на дисплеи if (millis() - ms2 > 250) { ms2 = millis(); if (prtVolt) { countVDisp++; // инкрементируем счетчик времени отображения на дисплее if (countVDisp > 12) { prtVolt = false; countVDisp = 0; }// end if }//end if if (autoBr) AutoBright(); if (longClick) { WriteAuto(); // выводим на дисплей br-A / br-n countAuto++; if (countAuto > 8) { countAuto = 0; longClick = false; }//end if }//end if else WriteToDisplay(); // выводим информацию на дисплеи }// end if // моргаем диодом зарядки при разряженной АКБ, если не подключено ЗУ if ((millis() - ms) > 1000) { ms = millis(); // если низкий заряд и не подключена зарядка if (lowVoltage && !(PIND & (1 << CHRG_IN_PIN))) { PORTD ^= (1 << CHRG_ON_PIN); // мигаем диодом зарядки }//end if }//end if // считываем показания датчика раз в RD_WAIT mc if ((millis() - ms1) > RD_WAIT) { ms1 = millis(); /* if (!HTU21.begin()) { HTUErr(); // переходим в функцию ошибки delay(500); // задержка после инициализации датчика }//end if realTemp = HTU21.readTemperature(); */ if (realTemp < 0) negFlg = true; else negFlg = false; Serial.println(realTemp); // отладка if (negFlg) hTmp = (realTemp - 0.01) * 100; // приводим к целому else hTmp = realTemp * 100; // приводим к целому lTmp = abs(hTmp) % 100; // отделяем десятые hTmp = hTmp / 100; // отделяем целые //округляем до десятых if (lTmp % 10 < 5) lTmp = lTmp / 10; // если сотые меньше 5 else if (lTmp / 10 < 9) lTmp = lTmp / 10 + 1; // если сотые меньше 94 else{ // если > 94 lTmp = 0; // обнуляем if (negFlg) hTmp--; // увеличиваем десятки else hTmp++; }// end else if Serial.println((String) hTmp + '.' + lTmp); // отладка /* // вводим поправочный коэфф. при темп. от 0 до 80 // влажность с учетом поправочного коэфф. if (realTemp >= 0 && realTemp <= 80) realHum = (HTU21.readHumidity() + (25 - realTemp) * -0.15); else realHum = HTU21.readHumidity(); */ Serial.println(realHum); // отладка hHum = round(realHum); // округляем влажность, дробные нам не нужны... Serial.println(hHum); // отладка //if (hHum > 99) hHum = 100; // при высокой влажности датчик может показывать больше 100% String strMsg = "HTU21"; //сигнатура - данные strMsg += "="; //разделитель температуры и влажности strMsg += hTmp; //температуру в строку strMsg += "."; //десятичная точка strMsg += lTmp; //температуру в строку strMsg += "="; //разделитель температуры и влажности strMsg += hHum; //присоединяем влажность strMsg += "="; //разделитель температуры и влажности strMsg += realVolt; //напряжение АКБ strMsg.toCharArray(msg, strMsg.length() + 1); //переводим строку в массив символов radio.write(&msg, sizeof(msg)); // отправляем данные из массива data указывая сколько байт массива мы хотим отправить // для отладки realTemp += 0.01; realHum += 1; if(realHum > 120) realHum = 0; }//end if //обработка кнопки switch (BUT.Loop()) { case SB_NONE: break; case SB_CLICK: longClick = false; // флаг удержания кнопки if (!autoBr) { brLvl++; if (brLvl > 3) brLvl = 0; // яркость ограничиваем 3 dispTemp.setBrightness(brLvl); // устанавливаем яркость температура dispHum.setBrightness(brLvl); // устанавливаем яркость влажность WriteToDisplay(); // изменяем яркость (нужно вывести данные для изменения яркости) }//end if else { prtVolt = true; // поднимаем флаг отображения напряжения }//end else break; case SB_LONG_CLICK: autoBr = !autoBr; // инвертируем флаг longClick = true; // флаг удержания кнопки prtVolt = false; break; case SB_AUTO_CLICK: break; }//end switch(BUT.Loop()) }//end loopmir0tv0rec - поясните, откуда в этом отладочном скетче берется величина realHum. Насколько я вижу, датчик вы закомментировали и в setup() задаете realHum =0 .
А дальше откуда она вдруг станет более 100?
Строка 411.
Еще вопросы
mir0tv0rec - какая ардуина у вас?
И еще - попробуйте самой первой строчкой в процедуру WriteToDisplay() вставить вот это
Ок, Pro Mini 8МНz.
Если считываю влажность в функции, то все нормально.
при компиляции что пишет ардуино иде на тему размера кода и памяти?
запостите прямо сюда вывод компилятора в виде текста
Ок, Pro Mini 8МНz
контроллер какой? промини бывают с атмега328, а бывают атмега168.
Посмотрите, что написано на чипе или выложите сюда фото платы в хоршем качестве
После этих сточек она равна 0, если больше 99. Почему такое?
на фото видно плохо, но вроде 328-ая
Но все равно, после того как вы ответили, что при переносе обработки влажности внутрь процедуры дисплея ошибка уходит - у меня практически уверенность, что дело в памяти.
=== удалил неверное предположение ===
ну вот. я похоже угадал.
Почему - попытался обьяснить выше. Возможно более опытные поправят
Конкретно после этой строки:
Конкретно после этой строки:
величину strMsg.length() выведите в Сериал, что покажет?
В ней и была проблема, не хватило длины массива, т.к. я раньше выводил влажность до 99. Длина была 20, нужно было 21, т.к "/0" уже не помещался.
ага, см сообщение #33:
похоже на порчу значения в памяти из-за выхода за границу массива.
только не сумел отыскать, где именно.
Поздравляю с победой