Помогите с семи-сегментным четырёх-разрядным индикатором
- Войдите на сайт для отправки комментариев
Чт, 25/01/2018 - 16:40
Вообщем идея такая: Ардуино считывает с датчика температуру и разбивает на десятки и единицы. Потом выводит на дисплей.
А проблема такая: Выводить выводит, НО число градусов мигают, а значок градуса не мигает. Надо чтобы вообще ничего не мигало!!!
Помогите пожалуйста!!!
Ниже код скетча.
#include "DHT.h"
#define DHTPIN 2 // вывод, к которому подключается датчик
#define DHTTYPE DHT22 // DHT 22 (AM2302)
byte oc;
byte tc;
int t = 0;
int an1 = 51;
int an2 = 50;
int an3 = 52;
int an4 = 53;
int is1 = 34;
int is2 = 32;
int is4 = 30;
int is5 = 28;
int is7 = 26;
int is10 = 24;
int is11 = 22;
DHT dht(DHTPIN, DHTTYPE);
void setup() {
pinMode(an1, OUTPUT);
pinMode(an2, OUTPUT);
pinMode(an3, OUTPUT);
pinMode(an4, OUTPUT);
pinMode(is1, OUTPUT);
pinMode(is2, OUTPUT);
pinMode(is4, OUTPUT);
pinMode(is5, OUTPUT);
pinMode(is7, OUTPUT);
pinMode(is10, OUTPUT);
pinMode(is11, OUTPUT);
dht.begin();
}
void loop() {
int t = dht.readTemperature();
byte oc = t / 10;
byte tc = t % 10;
if(oc == 0){
digitalWrite(an1, LOW);
digitalWrite(an2, HIGH);
digitalWrite(an3, LOW);
digitalWrite(an4, LOW);
digitalWrite(is1, LOW);
digitalWrite(is2, LOW);
digitalWrite(is4, LOW);
digitalWrite(is5, HIGH);
digitalWrite(is7, LOW);
digitalWrite(is10, LOW);
digitalWrite(is11, LOW);
delay(15);
}
if(oc == 1){
digitalWrite(an1, LOW);
digitalWrite(an2, HIGH);
digitalWrite(an3, LOW);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, HIGH);
digitalWrite(is4, LOW);
digitalWrite(is5, HIGH);
digitalWrite(is7, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is11, HIGH);
delay(15);
}
if(oc == 2){
digitalWrite(an1, LOW);
digitalWrite(an2, HIGH);
digitalWrite(an3, LOW);
digitalWrite(an4, LOW);
digitalWrite(is11, LOW);
digitalWrite(is7, LOW);
digitalWrite(is5, LOW);
digitalWrite(is1, LOW);
digitalWrite(is2, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is4, HIGH);
delay(15);
}
if(oc == 3){
digitalWrite(an1, LOW);
digitalWrite(an2, HIGH);
digitalWrite(an3, LOW);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, LOW);
digitalWrite(is4, LOW);
digitalWrite(is5, LOW);
digitalWrite(is7, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is11, LOW);
delay(15);
}
if(oc == 4){
digitalWrite(an1, LOW);
digitalWrite(an2, HIGH);
digitalWrite(an3, LOW);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, HIGH);
digitalWrite(is4, LOW);
digitalWrite(is5, LOW);
digitalWrite(is7, LOW);
digitalWrite(is10, LOW);
digitalWrite(is11, HIGH);
delay(15);
}
if(tc == 0){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, LOW);
digitalWrite(is2, LOW);
digitalWrite(is4, LOW);
digitalWrite(is5, HIGH);
digitalWrite(is7, LOW);
digitalWrite(is10, LOW);
digitalWrite(is11, LOW);
delay(15);
}
if(tc == 1){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, HIGH);
digitalWrite(is4, LOW);
digitalWrite(is5, HIGH);
digitalWrite(is7, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is11, HIGH);
delay(15);
}
if(tc == 2){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is11, LOW);
digitalWrite(is7, LOW);
digitalWrite(is5, LOW);
digitalWrite(is1, LOW);
digitalWrite(is2, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is4, HIGH);
delay(15);
}
if(tc == 3){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, LOW);
digitalWrite(is4, LOW);
digitalWrite(is5, LOW);
digitalWrite(is7, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is11, LOW);
delay(15);
}
if(tc == 4){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, HIGH);
digitalWrite(is4, LOW);
digitalWrite(is5, LOW);
digitalWrite(is7, LOW);
digitalWrite(is10, LOW);
digitalWrite(is11, HIGH);
delay(15);
}
if(tc == 5){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, LOW);
digitalWrite(is4, LOW);
digitalWrite(is5, LOW);
digitalWrite(is7, HIGH);
digitalWrite(is10, LOW);
digitalWrite(is11, LOW);
delay(15);
}
if(tc == 6){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, LOW);
digitalWrite(is2, LOW);
digitalWrite(is4, LOW);
digitalWrite(is5, LOW);
digitalWrite(is7, HIGH);
digitalWrite(is10, LOW);
digitalWrite(is11, LOW);
delay(15);
}
if(tc == 7){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, HIGH);
digitalWrite(is4, LOW);
digitalWrite(is5, HIGH);
digitalWrite(is7, LOW);
digitalWrite(is10, HIGH);
digitalWrite(is11, LOW);
delay(15);
}
if(tc == 8){
digitalWrite(an1, LOW);
digitalWrite(an2, HIGH);
digitalWrite(an3, LOW);
digitalWrite(an4, LOW);
digitalWrite(is11, LOW);
digitalWrite(is7, LOW);
digitalWrite(is5, LOW);
digitalWrite(is1, LOW);
digitalWrite(is2, LOW);
digitalWrite(is10, LOW);
digitalWrite(is4, LOW);
delay(15);
}
if(tc == 9){
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, HIGH);
digitalWrite(an4, LOW);
digitalWrite(is11, LOW);
digitalWrite(is7, LOW);
digitalWrite(is5, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, LOW);
digitalWrite(is10, LOW);
digitalWrite(is4, LOW);
delay(15);
}
digitalWrite(an1, LOW);
digitalWrite(an2, LOW);
digitalWrite(an3, LOW);
digitalWrite(an4, HIGH);
digitalWrite(is11, LOW);
digitalWrite(is7, LOW);
digitalWrite(is5, LOW);
digitalWrite(is1, HIGH);
digitalWrite(is2, HIGH);
digitalWrite(is10, LOW);
digitalWrite(is4, HIGH);
delay(15);
}
категорически не использовать Delay,
не считывать так часто температуру - зачем? обновлять информацию по таймеру millis - сохранять значения в некий буфер, и из него уже выводить в каждом цикле loop,
если этого не хватит - все равно будет моргать - избавляться от digitalWrite - переходить на прямой вывод в порты МК
откуда вы взяли этот код, можно узнать? Мне интересно, откуда данные, что выводить цифры нужно именно так? Сами вряд ли догадались бы.... О процедурах и циклах ничего не слышали?
Что за индикатор, как он устроен? На сдвиговых регистрах?
откуда вы взяли этот код, можно узнать? Мне интересно, откуда данные, что выводить цифры нужно именно так? Сами вряд ли догадались бы.... О процедурах и циклах ничего не слышали?
Что за индикатор, как он устроен? На сдвиговых регистрах?
явно не сдвиговый - слишком много ног используется
Можете объясниь по подробнее. Я новичок в ардуине))
Писал сам. До-лго и тер-пе-ли-во! :)
явно не сдвиговый - слишком много ног используется
Да, уже по коду разобрался - динамика. Ноги an1-an4 управляют включением каждого знакоместа, ноги is - отдельные сегменты.
Автор. знак градуса у вас тоже мигает. Просто на фоне цифр это незаметно, потому что вы выодите знак градуса вдвое чаще, чем цифры.
Чтобы ничего не мигало - поменяйте все delay(15) на delay(5), к примеру. Только не читайте так часто температуру , читайте дачтчик раз в минуту.
Это 5462bs.
Пинов 12
-Это моя чуда-юда! )))
Если поменять на 5 миллисекунд, то цифры вообще не загораются. Еле заметно!
Сейчас только заметил, что если включать значок сначала, то еденицы показывает норально, НО значок градуса стаёт мигать!
явно не сдвиговый - слишком много ног используется
Да, уже по коду разобрался - динамика. Ноги an1-an4 управляют включением каждого знакоместа, ноги is - отдельные сегменты.
Автор. знак градуса у вас тоже мигает. Просто на фоне цифр это незаметно, потому что вы выодите знак градуса вдвое чаще, чем цифры.
Чтобы ничего не мигало - поменяйте все delay(15) на delay(5), к примеру. Только не читайте так часто температуру , читайте дачтчик раз в минуту.
Я и так знаю что мигает, НО это не заметно!
Можете объясниь по подробнее. Я новичок в ардуине))
много объяснять :(
не с того начали, учитесь постепенно, например так:
1. сделайте пока получение температуры например каждые 5 минут через таймер millis и вывод ее в терминал
2. меняете вывод в терминал на разбиение на отдельные цифры и сохранение в некий буфер
3. пишите отдельную функцию например на входе номер разряда индикатора и цифру/знак
4. внутри цикла loop делаете цикл по разрядам с 1 по 4ый, внутри цикла соответственно из буфера отображаем на нужном разряде нужный знак
5. в принципе все - проект готов
вот вам пример, но вряд ли он поможет, у меня сдвиговый регистр - немного логика отличается,
да и иногда проще с нуля написать чем выковыривать из чужого проекта
#include <RCSwitch.h> #include <Wire.h> #include <RTClib.h> #include <OneWire.h> #include <DallasTemperature.h> #include <SPI.h> #include <Adafruit_Sensor.h> #include <Adafruit_BMP280.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif #define PB2_HIGH sbi(PORTB,PB2); #define PB2_LOW cbi(PORTB,PB2); #define PB3_HIGH sbi(PORTB,PB3); #define PB3_LOW cbi(PORTB,PB3); #define PB4_HIGH sbi(PORTB,PB4); #define PB4_LOW cbi(PORTB,PB4); #define RX_PIN 2 // green // GND blue +5V yellow #define DS_TPN 8 // DS18B20 grey // GND black +5V white OneWire oneWire(DS_TPN); DallasTemperature sensors(&oneWire); #define FOTORES A1 // grey // GND yellow +5V maroon #define RTC_SDA A4 // - red #define RTC_SCL A5 // - black // GND white +5V grey RTC_DS1307 RTC; #define LED_SCLK 10 // - blue PB2 #define LED_RCLK 11 // - green PB3 #define LED_DIO 12 // - maroon PB4 // GND yellow +5V orange #define CYCLE_GET_TIME 60 #define CYCLE_SHOW 4 #define CYCLE_GET_TEMP 243 #define BMP_SCK 4 // - green #define BMP_MISO 5 // - yellow #define BMP_MOSI 6 // - orange #define BMP_CS 7 // - red // GND blue +5V maroon //Adafruit_BMP280 bmp; // I2C //Adafruit_BMP280 bmp(BMP_CS); // hardware SPI Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK); byte LED_0F[33] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E, 0xC2, 0x89, 0xF9, 0xF1, 0xC3, 0xA9, 0xC0, 0x8C, 0x98, 0x92, 0xC1, 0x91, 0xFE, 0xBF, 0xFF, 0x9C, 0xAB}; // 0123456789AbCdEFGHIJLnOPqSUY_- (null) (degree) (mm) byte LED_NU[8] = {16, 32, 64, 128, 1, 2, 4, 8}; byte LED_BUF[8] = {30, 30, 30, 30, 30, 30, 30, 30}; byte LED_PWM = 3; // level light 7 = MAX 0 = MIN byte dd = 99; // day byte mm = 99; // month byte yh = 99; // high year byte yl = 99; // low year byte ho = 99; // hour byte mi = 99; // minute float tt = 99; // temp float pr = 99; // pressure unsigned long lu = 0; // last time get street temp byte streettemp = 99; // street temp 0..60 word mas_str_temp[10]; byte med_str_pos = 0; byte med_str_cnt = 0; boolean minus_str_temp = false; unsigned long timerSec = 0; byte timerGetTime = 37; byte timerShow = 0; byte timerGetTemp = 242; byte flShow = 0; // 0 time and temp 1 date 2 street temp 3 press RCSwitch mySwitch = RCSwitch(); void setup() { // put your setup code here, to run once: // OFF unused pins pinMode(0, OUTPUT); digitalWrite(0, LOW); pinMode(1, OUTPUT); digitalWrite(1, LOW); pinMode(3, OUTPUT); digitalWrite(3, LOW); pinMode(10, OUTPUT); digitalWrite(10, LOW); pinMode(13, OUTPUT); digitalWrite(13, LOW); pinMode(A0, OUTPUT); digitalWrite(A0, LOW); pinMode(A2, OUTPUT); digitalWrite(A2, LOW); pinMode(A3, OUTPUT); digitalWrite(A3, LOW); pinMode(A6, OUTPUT); digitalWrite(A6, LOW); pinMode(A7, OUTPUT); digitalWrite(A7, LOW); //-- pinMode(LED_SCLK, OUTPUT); pinMode(LED_RCLK, OUTPUT); pinMode(LED_DIO, OUTPUT); sensors.begin(); Wire.begin(); if (! RTC.begin()) { while (1); } if (! RTC.isrunning()) { // following line sets the RTC to the date & time this sketch was compiled // RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); // This line sets the RTC with an explicit date & time, for example to set // January 21, 2014 at 3am you would call: // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0)); } //delay(2000); //RTC.adjust(DateTime(F(__DATE__), F(__TIME__))); bmp.begin(); mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin 2 // иницилизация.Используется вывод м/к с прерыванием под номером 0. } byte addPoint(byte inByte) { byte outByte = (inByte << 1); outByte = (outByte >> 1); return outByte; } void showLedBuf() { for (byte lp = 0; lp <= LED_PWM; ++lp) { for (byte i = 0; i <= 7; i++) { PB3_LOW; for (byte j = 0; j <= 7; j++) { if (bitRead(LED_BUF[i], (7 - j))) { PB4_HIGH; } else { PB4_LOW; } PB2_HIGH; PB2_LOW; } for (byte j = 0; j <= 7; j++) { if (bitRead(LED_NU[i], (7 - j))) { PB4_HIGH; } else { PB4_LOW; } PB2_HIGH; PB2_LOW; } PB3_HIGH; } } for (byte lp = 0; lp < (7 - LED_PWM); ++lp) { PB3_LOW; PB4_HIGH; for (byte j = 0; j <= 15; j++) { PB2_HIGH; PB2_LOW; } PB3_HIGH; delayMicroseconds(350); } } void loop() { // put your main code here, to run repeatedly: // receive street temp if (mySwitch.available()) { unsigned long receivedCode = mySwitch.getReceivedValue(); mySwitch.resetAvailable(); if ((receivedCode >= 11500UL) && (receivedCode <= 14750UL)) { receivedCode -= 11500; if (((receivedCode >= 2000UL) && (receivedCode <= 2600UL)) || ((receivedCode >= 0UL) && (receivedCode <= 400UL))) { if ((receivedCode <= 400UL)) { receivedCode = 2000UL - receivedCode; } lu = millis(); // correct temp if (receivedCode <= 1900UL) { receivedCode -= 12UL; // 1.2 degree } else { if (receivedCode <= 1950UL) { receivedCode -= 8UL; // 0.8 degree } else { if (receivedCode <= 1999UL) { receivedCode -= 5UL; // 0.5 degree } } } // -- mas_str_temp[med_str_pos] = (word)(receivedCode); if ((++med_str_pos) >= 10) { med_str_pos = 0; } if ((++med_str_cnt) >= 10) { med_str_cnt = 10; } word sum_temp = 0; for (int i = 0; i < med_str_cnt; ++i) { sum_temp += mas_str_temp[i]; } sum_temp /= med_str_cnt; if (sum_temp < 2000) { minus_str_temp = true; sum_temp = 2000 - sum_temp; } else { minus_str_temp = false; sum_temp -= 2000; } sum_temp /= 10; streettemp = (byte)(sum_temp); } } } if ((millis() - timerSec) >= 1000UL) { timerSec = millis(); //++timerGetTime; ++timerShow; ++timerGetTemp; if ((++timerGetTime) >= CYCLE_GET_TIME) { timerGetTime = 0; // get time and date DateTime now = RTC.now(); dd = now.day(); mm = now.month(); yh = (now.year()) / 100; yl = (now.year()) % 100; ho = now.hour(); mi = now.minute(); } if ((++timerShow) >= CYCLE_SHOW) { timerShow = 0; switch (flShow) { case 1 : { // show date if ((dd >= 1) && (dd <= 31)) { if (dd < 10) { LED_BUF[0] = LED_0F[30]; LED_BUF[1] = LED_0F[(dd % 10)]; } else { LED_BUF[0] = LED_0F[(dd / 10)]; LED_BUF[1] = LED_0F[(dd % 10)]; } } else { LED_BUF[0] = LED_0F[30]; LED_BUF[1] = LED_0F[30]; } LED_BUF[1] = addPoint(LED_BUF[1]); if ((mm >= 1) && (mm <= 12)) { if (mm < 10) { LED_BUF[2] = LED_0F[0]; LED_BUF[3] = LED_0F[(mm % 10)]; } else { LED_BUF[2] = LED_0F[(mm / 10)]; LED_BUF[3] = LED_0F[(mm % 10)]; } } else { LED_BUF[2] = LED_0F[30]; LED_BUF[3] = LED_0F[30]; } LED_BUF[3] = addPoint(LED_BUF[3]); if ((yh >= 20) && (yh <= 29) && (yl >= 00) && (yl <= 99)) { LED_BUF[4] = LED_0F[(yh / 10)]; LED_BUF[5] = LED_0F[(yh % 10)]; if (yl < 10) { LED_BUF[6] = LED_0F[0]; LED_BUF[7] = LED_0F[(yl % 10)]; } else { LED_BUF[6] = LED_0F[(yl / 10)]; LED_BUF[7] = LED_0F[(yl % 10)]; } } else { LED_BUF[4] = LED_0F[30]; LED_BUF[5] = LED_0F[30]; LED_BUF[6] = LED_0F[30]; LED_BUF[7] = LED_0F[30]; } ++flShow; break; } case 2 : { unsigned long cplu = timerSec - lu; if (((cplu) <= 10800000UL) && (streettemp < 99)) { // MAX 3 hour LED_BUF[3] = LED_0F[31]; LED_BUF[4] = LED_0F[30]; LED_BUF[5] = LED_0F[30]; LED_BUF[6] = LED_0F[30]; LED_BUF[7] = LED_0F[30]; if (minus_str_temp) { LED_BUF[0] = LED_0F[29]; } else { LED_BUF[0] = LED_0F[30]; } if (streettemp < 10) { LED_BUF[1] = LED_0F[30]; LED_BUF[2] = LED_0F[(streettemp % 10)]; } else { LED_BUF[1] = LED_0F[(streettemp / 10)]; LED_BUF[2] = LED_0F[(streettemp % 10)]; } ++flShow; // culculate and show delay last data from device unsigned long j = cplu / 600000UL; // 1 point = 10 sec (10000UL). if need 10 minute = 600000UL j = constrain(j, 0UL, 8UL); for (unsigned long i = 1UL; i <= j; ++i) { LED_BUF[8 - i] = addPoint(LED_BUF[8 - i]); } // - break; } else { ++flShow; } // show street temp } case 3 : { // show press if ((pr >= 600) && (pr <= 900)) { LED_BUF[0] = LED_0F[30]; LED_BUF[1] = LED_0F[30]; LED_BUF[5] = LED_0F[30]; LED_BUF[6] = LED_0F[32]; LED_BUF[7] = LED_0F[32]; int hp = int(pr); LED_BUF[2] = LED_0F[(hp / 100)]; byte pd = hp % 100; LED_BUF[3] = LED_0F[(pd / 10)]; LED_BUF[4] = LED_0F[(pd % 10)]; flShow = 0; break; } else { LED_BUF[0] = LED_0F[30]; LED_BUF[1] = LED_0F[30]; LED_BUF[2] = LED_0F[30]; LED_BUF[3] = LED_0F[30]; LED_BUF[4] = LED_0F[30]; LED_BUF[5] = LED_0F[30]; LED_BUF[6] = LED_0F[30]; LED_BUF[7] = LED_0F[30]; flShow = 0; } } default : { // show time and temp if ((ho >= 0) && (ho <= 23)) { if (ho < 10) { LED_BUF[0] = LED_0F[30]; LED_BUF[1] = LED_0F[(ho % 10)]; } else { LED_BUF[0] = LED_0F[(ho / 10)]; LED_BUF[1] = LED_0F[(ho % 10)]; } } else { LED_BUF[0] = LED_0F[30]; LED_BUF[1] = LED_0F[30]; } LED_BUF[1] = addPoint(LED_BUF[1]); if ((mi >= 0) && (mi <= 59)) { if (mi < 10) { LED_BUF[2] = LED_0F[0]; LED_BUF[3] = LED_0F[(mi % 10)]; } else { LED_BUF[2] = LED_0F[(mi / 10)]; LED_BUF[3] = LED_0F[(mi % 10)]; } } else { LED_BUF[2] = LED_0F[30]; LED_BUF[3] = LED_0F[30]; } // show temp if ((tt >= (-30)) && (tt <= 40)) { byte ta; if (tt < 0) { LED_BUF[4] = LED_0F[29]; ta = abs(tt); } else { LED_BUF[4] = LED_0F[30]; ta = tt; } if (ta < 10) { LED_BUF[5] = LED_0F[30]; LED_BUF[6] = LED_0F[(ta % 10)]; } else { LED_BUF[5] = LED_0F[(ta / 10)]; LED_BUF[6] = LED_0F[(ta % 10)]; } LED_BUF[7] = LED_0F[31]; } else { LED_BUF[4] = LED_0F[30]; LED_BUF[5] = LED_0F[30]; LED_BUF[6] = LED_0F[30]; LED_BUF[7] = LED_0F[30]; } ++flShow; } } } if ((++timerGetTemp) >= CYCLE_GET_TEMP) { timerGetTemp = 0; // get temp and bar sensors.requestTemperatures(); tt = sensors.getTempCByIndex(0); if (tt == 0.00) { tt = 99; } // get bmp280 pr = (bmp.readPressure() / 133.322); } } // set display light word ll = analogRead(FOTORES); LED_PWM = map(ll, 0, 1023, 0, 7); // show info showLedBuf(); //--- end loop }Если поменять на 5 миллисекунд, то цифры вообще не загораются. Еле заметно!
Я понял в чем дело.
Вы зажигаете первый раз ряд на 15мс, потом зажигаете второй тоже на 15мс (первый при этом гаснет), потом зажигаете знак градуса (цифры погасли) . На этом цикл заканчивается и вы идете считывать температуру. Дело это не быстрое, скажем миллисекунд 500. Все это время цифры у вас выключены, а знак градуса - горит. Потом все сначала.
В итоге каждая цифра у вас загорается на 15мс раз в полсекунды. а все остальное время горит знак градуса.
Вам надо переделать чтнеие температуры с датчика на неблокирующий вызов - чтобы программа не ждала полсекунды. Возможно, придется писать чтение температуры вручную, без библиотек.
Если поменять на 5 миллисекунд, то цифры вообще не загораются. Еле заметно!
Я понял в чем дело.
Вы зажигаете первый раз ряд на 15мс, потом зажигаете второй тоже на 15мс (первый при этом гаснет), потом зажигаете знак градуса (цифры погасли) . На этом цикл заканчивается и вы идете считывать температуру. Дело это не быстрое, скажем миллисекунд 500. Все это время цифры у вас выключены, а знак градуса - горит. Потом все сначала.
В итоге каждая цифра у вас загорается на 15мс раз в полсекунды. а все остальное время горит знак градуса.
Вам надо переделать чтнеие температуры с датчика на неблокирующий вызов - чтобы программа не ждала полсекунды. Возможно, придется писать чтение температуры вручную, без библиотек.
А если прерывания использовать!
что вы собрались прерывать?
ТС - вот почитайте
http://codius.ru/articles/Arduino_UNO_4%D1%80%D0%B0%D0%B7%D1%80%D1%8F%D0%B4%D0%BD%D1%8B%D0%B9_7%D1%81%D0%B5%D0%B3%D0%BC%D0%B5%D0%BD%D1%82%D0%BD%D1%8B%D0%B9_%D0%B8%D0%B4%D0%B8%D0%BA%D0%B0%D1%82%D0%BE%D1%80_12_pin_3641BS_red
я неделю назад, пока еще был один 4х разрядный индикатор начинал изучать именно с этого примера и спокойно вывел все данные на индикатор без миганий и прочего...
и код в разы короче
при этом он в примере далек от идеала и на деле очень просто еще сокращается и оптимизируется
ELITE. ну вы хоть со своими "познаниями" не лезьте! Не путайте человека, ему эта статья не нужна, у него нет проблем с выводом цифр на индикатор. Его проблема - создание скетча, который разом делает более одной задачи. Если б вы по этой статье писали его скетч - у вас бы тоже все мигало.
b707 я по ней и писал - ничего не мигало даже при 100 одновлениях экрана в секунду (собственно оно и задано было delay(1); ... которую я просто убюрал и всё отлично работало не мигая
при этом я тогда еще кромеdelay(1); и не знал ничего - поэтому первую кнопку на нем делал - и тоже ничего не мигало....
хоть я и новичек - но даже так явно видно - что проблема с выводе на экран изза кучи делаев, а не изза нехватки скорости выполнять более 1 действия
b707 я по ней и писал - ничего не мигало даже при 100 одновлениях экрана в секунду (собственно оно и задано было delay(1); ... которую я просто убюрал и всё отлично работало не мигая
добавьте в тот ваш код чтение температуры с датчика - замигает
хоть я и новичек - но даже так явно видно - что проблема с выводе на экран изза кучи делаев, а не изза нехватки скорости выполнять более 1 действия
а вот и нет. В данном случае делаи не являются причиной проблем, хотя. конечно, при переписывании кода их нужно убрать.
читаю пример, и нифига не могу понять зачем в процедуре
void displayMessage(int dig[4][8]) {
после зажигания сегмента, тут же через миллисекунду его гасить?
он же (сегмент) все равно погаснет если цифра/символ на индикаторе другая будет,
а если та - же - он (сегмент) будет просто гореть.
читаю пример, и нифига не могу понять зачем в процедуре
void displayMessage(int dig[4][8]) {
после зажигания сегмента, тут же через миллисекунду его гасить?
он же (сегмент) все равно погаснет если цифра/символ на индикаторе другая будет,
а если та - же - он (сегмент) будет просто гореть.
Не смотрел пример, но могу предположить, что зажигаются и гасятся сегменты/цифры так для того, чтобы визуально все это хозяйство имело одинаковую яркость - на свечение каждого отводится одинаковое время, значит и общая яркость у них не будет вразнобой.
читаю пример, и нифига не могу понять зачем в процедуре
void displayMessage(int dig[4][8]) {
после зажигания сегмента, тут же через миллисекунду его гасить?
он же (сегмент) все равно погаснет если цифра/символ на индикаторе другая будет,
а если та - же - он (сегмент) будет просто гореть.
Не смотрел пример, но могу предположить, что зажигаются и гасятся сегменты/цифры так для того, чтобы визуально все это хозяйство имело одинаковую яркость - на свечение каждого отводится одинаковое время, значит и общая яркость у них не будет вразнобой.
мысль хорошая, но сделана тогда криво, т.к. равномерно надо гасить/выравнивать целиком индикаторы а не сегменты, и я делал аналогично - но там задежки микросекундами меряется а не миллисекундами.
да вообще на прямую цеплять к ардуине индикатор - это дикое раточительство выходов ....
давно копеешные индикаторы с драйвером продают - 3-4 провода управления на всё
да вообще на прямую цеплять к ардуине индикатор - это дикое раточительство выходов ....
давно копеешные индикаторы с драйвером продают - 3-4 провода управления на всё
почему нет - если Мега да еще с одним действием - для тренировки самое то
Есть ряд проектов на индикаторах.
У тебя большие задержки 15 мс. Расчет простой, берем 25 кадров в секунду, разбиваем на 3 индикатора в динамической индикации, получаем 1000мс/75= 13 мс, у тебя 15 мс delay(15)
Реально на практике 25 кадров в секунду все равно видна пульсация, надо брать 50 - 100 кадров в секунду. Если нужно поищу свой код, с регулировкой яркости.
По поводу уменьшения яркости при уменьшении задержки. Во первых опрос датчика в начале каждого лупа занимает время, т.е перед каждой отрисовкой в динамике задержка до 10 мс на считывание. Я бы ввел некоторый счетчик до 20 и проверку ==0 запрос температуры ==5 считывание температуры. Во вторых если запитались через резисторы, потеря яркости. В динамической индикации цепляют напрямую к выводам индикатора, кратковременная яркость не убьет светодиоды, но в динамике будет хорошо смотреться, и желательно предусмотреть защиту по току на случай зависания, убьется сегмент.
По поводу вашего кода, еще непонятно опрос датчика. Обычно он состоит из 2х фаз, запрос на преобразование температуры, ожидание 15-100 мс, считывание температуры, у тебя в коде только считывание, т.е. считывается одна и та же цифра.
Реально на практике 25 кадров в секунду все равно видна пульсация, надо брать 50 - 100 кадров в секунду. Если нужно поищу свой код, с регулировкой яркости.
реально выше 20 выдит менее 1% людей, а выше 24 и вовсе единицы во всем вире
а то, что у вас "пульсирует" - знаит код не верный
вы гасите индикаторы и заново зажигаете с новыми цифрами - вот ваши и пульсации!, тк между гашением и включением проходит весьма долгое время
а вы попробуйне НЕ гасить индикатор а гасить и зажигать нужные сигменты, при этом если это будет единовременно - то будет лучше
и никаких пульсаций не будет вообще
я тоже столкнулся с "мерцанием", когда использовал штатную библиотеку, но стоило из неё выкинуть лишний код и убрать очистку (гашение) экрана перед каждым обновлением данных - как пульсации пропали
ну и схемотехника - конденсаторы где они должны быть - там они должны быть!
А проблема такая: Выводить выводит, НО число градусов мигают, а значок градуса не мигает. Надо чтобы вообще ничего не мигало!!!
Помогите пожалуйста!!!
Я выше написал пару соображений.
Реально на практике 25 кадров в секунду все равно видна пульсация, надо брать 50 - 100 кадров в секунду. Если нужно поищу свой код, с регулировкой яркости.
реально выше 20 выдит менее 1% людей, а выше 24 и вовсе единицы во всем вире
Я где то читал что кошки еще выше частоту воспринимают.
а то, что у вас "пульсирует" - знаит код не верный
вы гасите индикаторы и заново зажигаете с новыми цифрами - вот ваши и пульсации!, тк между гашением и включением проходит весьма долгое время
а вы попробуйне НЕ гасить индикатор а гасить и зажигать нужные сигменты, при этом если это будет единовременно - то будет лучше
и никаких пульсаций не будет вообще
я тоже столкнулся с "мерцанием", когда использовал штатную библиотеку, но стоило из неё выкинуть лишний код и убрать очистку (гашение) экрана перед каждым обновлением данных - как пульсации пропали
ну и схемотехника - конденсаторы где они должны быть - там они должны быть!
Я штатные библиотеки даже не видел, поэтому у меня этих проблем нету. При сдвиге в порт закидывается новый байт.
Но у меня есть регулировка яркости, т.к. устройство стоит в темноте и нужно чтобы оно не подсвечивало внешнюю обстановку, и при этом было видно циферки. На свету пульсации несильно, но были заметны для 25 Гц, а вот в темноте, при уменьшении яркости, видимо действительно проявился эффект который вы описываете т.к. есть период погашенного. Я вроде 100 Гц из за этого сделал динамическую индикацию.
taraserker, у ТС в скетче ошибка, не имеющая абсолютно никакого отношения к частоте зажигания индикаторов, так что не тратьте зря силы на объяснения
реально выше 20 выдит менее 1% людей, а выше 24 и вовсе единицы во всем вире
а то, что у вас "пульсирует" - знаит код не верный
Это неверное утверждение.
Опирается оно на кинематограф, где время экспрозиции кадра примерно вдвое превышает время между кадрами. Последнее, как не трудно подсчитать, примерно равно 1000/24/3=14 мс.
Дле дисплея на трубке время засвечиваниялюминофора практически мгновенно, поэтому промежуток между кадрами занимает практически весь период кадра. Т.е. при частоте кадров 72 получаем ту же самую величину.
Эта величина характерна для колбочек, т.е. для центральной области глаза - желтого пятна. Для периферийного (а также сумеречного - палочки чувствительнее колбочек) зрения эту величина несколько меньше - не более 11-12 мс. Поэтому при кратковременном включении источника света чатота должна быть не менее 85 Гц.
Впрочем, те советы, которые Вы даете далее в своем сообщении, вполне справедливы.
Теория, цифры....это всё хорошо, а вот скажите мне знатоки: выше я выкладывал код часов с термометром, все работает, яркость семисегментных индикаторов прекрасно регулируется в зависимости от внешнего освещения, но вот при полном отсутствии внешнего освещения последний из 8 индикаторов самый бледный и мерцает, это происходит потому что длительность loop цикла больше чем задержка паузы гашения индикаторов. Меня это не сильно напрягает, но любопытно как это вылечить.
Теория, цифры....это всё хорошо, а вот скажите мне знатоки: выше я выкладывал код часов с термометром, все работает, яркость семисегментных индикаторов прекрасно регулируется в зависимости от внешнего освещения, но вот при полном отсутствии внешнего освещения последний из 8 индикаторов самый бледный и мерцает, это происходит потому что длительность loop цикла больше чем задержка паузы гашения индикаторов. Меня это не сильно напрягает, но любопытно как это вылечить.
ответ очевиден - зажигайте последний индикатор на то же время, что и все остальные - а потом принудительно гасите, а не оставляйте включенным до конца loop
Сталкивался с такой же вещью, они будут мигать в любом случае, если постоянно в цикле, сколько бы задержку не ставить. Надо менять выводимые значения, с условием, если температура изменилась. Типо, If(старая тепмература не рава новоя){приравниваем переменную к новому значению и обновляем индикатор}.
Логично, спасибо
реально выше 20 выдит менее 1% людей, а выше 24 и вовсе единицы во всем вире
а то, что у вас "пульсирует" - знаит код не верный
Это неверное утверждение.
Опирается оно на кинематограф, где время экспрозиции кадра примерно вдвое превышает время между кадрами. Последнее, как не трудно подсчитать, примерно равно 1000/24/3=14 мс.
Дле дисплея на трубке время засвечиваниялюминофора практически мгновенно, поэтому промежуток между кадрами занимает практически весь период кадра. Т.е. при частоте кадров 72 получаем ту же самую величину.
Эта величина характерна для колбочек, т.е. для центральной области глаза - желтого пятна. Для периферийного (а также сумеречного - палочки чувствительнее колбочек) зрения эту величина несколько меньше - не более 11-12 мс. Поэтому при кратковременном включении источника света чатота должна быть не менее 85 Гц.
позвольте не согласится, для ЭЛТ засвечивание совершенно не мгновенное, и более того, оно весьма медленное - тут эффект иной - время постсвечения люминифора очень большет - и за счет этого картинка не мерцает (глаз этого почти невидит) - но при этом это мерцание очень легко увидить при помещении между экраном и наблюдателем движущейся цели - тогда стану видны моменты гажения точек...
да, глаз способен зафиксировать вспышки длительностью менее 1/100 с даже, но это именно мгновенная чувствительность.
А мы , когда речь идет о экранах или индикаторах, должны оперировать иным понятием - а именно инерционность зрения, а вот она уже на много ниже, и составляет 1/20 1/25с всего
а если мы будем говорить о скорости восприятия передаваемой информации - в данном случает отображаемое число - то человек более 3-5 изменений значения в секунду уже не может восприниматься в достаточной мере
Исключением является только вывод динамической графической информации (видео, осциолограммы и тд) - где требуется высокая детализация и точность отображения - в этих случаях частота обновления графического экрана и 25 и 50 и даже 100к/с являются обоснованно необходимыми.
Делая из вышеизложенно вывод ИМХО:
1) при изменении / вовода на экран/индикатор информации, он не должен полностью гаснуть и заново отрисовывать данные. Необходимо использовать алгоритмы, при которых идет обновление отображаемой информации (гажение только ненужных точек/сигмертов) и включение нужных, не затрагивая неизменяемые элементы
2) частота обновления экрана/андикатора выше 25к/с является избыточной - а в условиях ардуины еще и дает лишнюю нагрузку
3) частота обновления информации, выводимой на экран, выше 5к/с также избыточна
Исходя из п.2 и п.3 я лично рекомендую обновлять экран и данные на нем единовременно и не выше 5 раз в секунду.
Теория, цифры....это всё хорошо, а вот скажите мне знатоки: выше я выкладывал код часов с термометром, все работает, яркость семисегментных индикаторов прекрасно регулируется в зависимости от внешнего освещения, но вот при полном отсутствии внешнего освещения последний из 8 индикаторов самый бледный и мерцает, это происходит потому что длительность loop цикла больше чем задержка паузы гашения индикаторов. Меня это не сильно напрягает, но любопытно как это вылечить.
ответ очевиден - зажигайте последний индикатор на то же время, что и все остальные - а потом принудительно гасите, а не оставляйте включенным до конца loop
а зачем гасить то - вот он и мерцает
пусть он показывает данные до следующего обновления не меняя их - горит и чего ему мерцать то....
да и вообще в часах точность 1 секунда, менять показания Т чаще 1с тоже толку нет
так пусть он раз в 1 секунду и обновляет все данные разом
при этом выполнять весь цекл, а в конце него уже рассчитанные и подготовленные данные разом обновлять на индикаторе - это минимизирует все задержки при выводе
im14ilya выложите текущую версию вашего кода скетча, дабы поглядеть что не так и как улучшить+
Теория, цифры....это всё хорошо, а вот скажите мне знатоки: выше я выкладывал код часов с термометром, все работает, яркость семисегментных индикаторов прекрасно регулируется в зависимости от внешнего освещения, но вот при полном отсутствии внешнего освещения последний из 8 индикаторов самый бледный и мерцает, это происходит потому что длительность loop цикла больше чем задержка паузы гашения индикаторов. Меня это не сильно напрягает, но любопытно как это вылечить.
ответ очевиден - зажигайте последний индикатор на то же время, что и все остальные - а потом принудительно гасите, а не оставляйте включенным до конца loop
а зачем гасить то - вот он и мерцает
пусть он показывает данные до следующего обновления не меняя их - горит и чего ему мерцать то....
да и вообще в часах точность 1 секунда, менять показания Т чаще 1с тоже толку нет
так пусть он раз в 1 секунду и обновляет все данные разом
при этом выполнять весь цекл, а в конце него уже рассчитанные и подготовленные данные разом обновлять на индикаторе - это минимизирует все задержки при выводе
гасить в любом случае необходимо для равномерной регулировки яркости в зависимости от внешнего освещения, b707 прав - надо добавить условие именно для последнего индикатор, как нибудь сделаю....
вот текущий код если любопытно.
void showLedBuf() { for (byte lp = 0; lp <= LED_PWM; ++lp) { for (byte i = 0; i <= 7; i++) { PB3_LOW; for (byte j = 0; j <= 7; j++) { if (bitRead(LED_BUF[i], (7 - j))) { PB4_HIGH; } else { PB4_LOW; } PB2_HIGH; PB2_LOW; } for (byte j = 0; j <= 7; j++) { if (bitRead(LED_NU[i], (7 - j))) { PB4_HIGH; } else { PB4_LOW; } PB2_HIGH; PB2_LOW; } PB3_HIGH; } } for (byte lp = 0; lp < (7 - LED_PWM); ++lp) { PB3_LOW; PB4_HIGH; for (byte j = 0; j <= 15; j++) { PB2_HIGH; PB2_LOW; } PB3_HIGH; delayMicroseconds(350); } }зачем же гасить - если я верно прочел код - вы яркость регулируете частотой включений и выключений
так может быть схитрить?
у вам индикатор имеет общий анод (или катод) - так вот их подключить к ШИМ выходам
а в ЛУПЕ при каждом проходе по датчику освещенности переопределять скважность ШИМ выходов
//при этом по таймера раз 10 в секунду достаточно будет
Не верно прочитали - не частотой а именно длительностью, если например яркость равна 5 (из 8) то 5 циклов сегменты зажигают я, а 3 цикла подряд гасятся
ну да, а попробуйте как я предложил
у вес одна часть кода будет выводить сигменты
а другая ШИМить яркость разрядам
это не только упростит код, но и даст вам очень плавную регулировку яркости и можно будет не линейно менять - ведь яркость убдет задана числом от 0 до 127
итого останется 1 цикл на установку какие сегменты вкл/выкл
и 1 цикл задает уровень шим для разрядов
Мысль правильная анодом шим яркость регулировать, но я модуль купил целиковый и ковырять искать и отрывать общий анод лень
зачем ковырять? можно ссылку что за модуль у вас
а то по фото - просто индикатор на 4 резряда
итого имеет 12 ног, где 4 ноги - это 4 анода
фактически вы ШИМомо заменяете ваши пропуски циклов
Не то фото смотрите, у меня 8 сегментный на сдвиговом регистре 74hc595
ага, значит по этой схеме наверное
http://arduinolab.pw/wp-content/uploads/2015/12/141-c-8-digit-7-segment-...
В гугле наберите 7 сегментные индикаторы на 74hc595)
ЗЫ устройство собрано и реально его лень разбирать и что то там припаивать)
ну да, я просто сам паял себе на мах7221 -они специально заточены под индикаторы и имеют 16 ступеней регулировки яркости встроеннйо уже
у вас же да, остается только кодом рулить....
тогда выходит мледующее - индикатор принимает 2 байта данных
первый указывает какие разряды, а 2й какие сигменты ...
тогда может вам изменить алгоритм так:
сделать таймер (например 1000мс) //просто актуальность меня чаще 1 раза в секунду показания экрана нету - а зачем вычислениями грузить МК каждый луп тогда....
по нему вы в переменную (массив [16] байт) вормируете то, что надо вывести на экран
а вне таймера вы выводите на экран, готовый массив (фактически цикл по отправке готовых данных остается), уже используя ваш алгоритм пропусков вывода относительно освещенности
и да, делать это не по делею, а по таймеру, зачем же нам тормозить МК постоянно )
Не усложняйте)
Просто для последнего символа (разряда) добавляется условие зависимости длительности свечения в зависимости от нужной яркости, максимум четыре строки кода.