Здрасти! Есть 3-знаковая 7-сегментная LED панелька. Для вывода какого-то числа используется HC595, в нужный момент зажигаю нужный знак (один из трех). Все хорошо работает, до тех пор пока не начну получать данные с DHT22. На время опроса датчика, у меня выводится только 1 число. Как с этим бороться? Код (C++): #include <DHT.h> #include <DHT_U.h> //Пин подключен к ST_CP входу 74HC595 int HC595_LATCH_PIN = 12; //Пин подключен к SH_CP входу 74HC595 int HC595_CLOCK_PIN = 11; //Пин подключен к DS входу 74HC595 int HC595_DATA_PIN = 10; int DHT22_PIN = 2; int RELAY_PIN = 3; DHT dht(DHT22_PIN, DHT22); const int digitPins[3] = {7,8,9}; //Массив пинов. int8_t Disp[3]={0};// задается тип int8_t чтобы к нам ничего, кроме набора бит не попало. int Value = 0; //значение для отображения на индикаторе byte i=0; byte segments[10] = { //Массив из 10 значений B11111100, //0 B01100000, //1 B11011010, //2 B11110010, //3 B01100110, //4 B10110110, //5 B10111110, //6 B11100000, //7 B11111110, //8 B11110110 //9 }; void setup() { for(byte j=0;j<3;j++)pinMode(digitPins[j],OUTPUT); //цикл - назначаем всем режим выход из нашего массива пинов pinMode(HC595_DATA_PIN, OUTPUT); pinMode(HC595_CLOCK_PIN, OUTPUT); pinMode(HC595_LATCH_PIN, OUTPUT); pinMode(DHT22_PIN, INPUT); pinMode(RELAY_PIN, OUTPUT); Serial.begin(9600); dht.begin(); } // Моя функция для работы с индикатором и сдвиговым регистром 74НС595 void printInd() { //цифровые выходы из массива в 0 (LOW) - отключаем используем цикл for(byte d=0; d<3; d++) digitalWrite(digitPins[d], HIGH); //Для начала записи в 74HC595 нужно подать 0 на STCP (открыть) digitalWrite(HC595_LATCH_PIN, LOW); // с данными выпускаем поток битов на DS синхроннированные с SHCP shiftOut(HC595_DATA_PIN, HC595_CLOCK_PIN, LSBFIRST, segments[Disp[i]]); // А теперь когда последний бит числа передали закрываем digitalWrite(HC595_LATCH_PIN, HIGH); digitalWrite(digitPins[i], LOW); delayMicroseconds(300); //Частота мирцания и собственно она же яркость индикатора:) //delay(1000);// проследить появление i++; if(i > 2) i=0; } void loop() { Serial.println("Loop"); //Выводим значение отсрочки срабатывания таймера на дисплей Disp[0] = (Value/100)%10; //сотни Disp[1] = (Value/10)%10; //десятки Disp[2] = Value%10; //единицы //Функция для отображения на индикаторе float h = dht.readHumidity(); Value = int(h); printInd(); if (isnan(h)) { Serial.println("Cannot read data from DHT22"); return; } else { if (h > 90) { digitalWrite(RELAY_PIN,LOW ); } if (h < 80) { digitalWrite(RELAY_PIN, HIGH); } Serial.print(Value); } }
Не помогло. Код (C++): float h = dht.readHumidity(); delay(10); Value =int(h); printInd(); Проблема в задержке между считывания с датчика...
Так и должно быть. Индикация то динамическая. Пока идет считывание температуры все замирает. Можно считывать температуру не каждый цикл, а раз в 10-20 сек. Перед считыванием индикаторы гасить. Либо поменять схему индикации.
Если лень переделывать схему... то "вырвать" код из библиотеки... и встроить в него кроме чтения ещё и код индикации. Примерно так: Код (C++): int8_t iarduino_DHT::readSDA(){ // обнуляем массив reply[0]=reply[1]=reply[2]=reply[3]=reply[4]=0; // прижимаем шину к земле на 25мс pinMode(PinDHT,OUTPUT); digitalWrite(PinDHT,LOW); delay(25); // отпускаем шину pinMode(PinDHT,INPUT); // проверяем реакцию датчика на сигнал "старт" if(pulseIn(PinDHT,HIGH,600)==0){return -3;} // читаем ответ датчика (40бит данных) for(int i=0,j=0; i<40; i++) { j=pulseIn(PinDHT,HIGH,600); /* ******************************* где-то тут (в этом коментарии) ваше обращение к индикатору вы должны ориентироваться на временные интервалы работы этого цикла "for" всё должно быть компактно и оптимально ******************************* */ if(j) { reply[i/8]<<=1; reply[i/8]+=j>45?1:0; } else{ return -2;} } // проверяем не отправляет ли датчик в шину больше 40 бит данных if(pulseIn(PinDHT,HIGH,600)>0){return -2;} // проверяем контрольную сумму if(((reply[0]+reply[1]+reply[2]+reply[3])&0xff)!=reply[4]){return -1;} // определяем модель сенсора if(reply[1]||reply[3]||reply[2]&0x80){model=22;}else if(reply[0]>3||reply[2]>4){model=11;} return 0; } Другого выхода не видно. Только данные в работе индикации - глобальные. Простите если что не так - брал исходники отсюда http://iarduino.ru/file/225.html Ещё раз простите!
другой выход виден - использовать прерывания для индикации. Главное - не переборщить с частотой обновлений. А лучше вообще заботы об индикации отдать специальным чипам, хотя бы копеечному TM1637 (жаль, что в Амперке его нет), и забыть об этих проблемах.
Если есть свободный таймер, то можно попробовать индикацию повесить на обработчики прерываний таймера. Только желательно всякие 'digitalWrite' заменить на прямую запись в регистры порта.