Самая экономичная LED -индикация, проблема с "двоеточием".
- Войдите на сайт для отправки комментариев
Пт, 08/07/2016 - 21:48
Играюсь с динамической индикацией с очень низким потреблением тока, буквально, за один раз горит только один сегмент.
Почему-то не происходит инвертирование переменной S, отвечающей за мигание "двоеточия" (65,66 строка кода) (76 строка отвечает за отображение "двоеточия").
PS: Часы-минуты и, возможно, дата будет браться из DS3132, когда он приедет.
Вот код для индикатора с общим катодом:
byte A=2; //Символ A, сверху
byte B=3; //Символ B, сверху справо
byte C=4; //Символ C, снизу справо
byte D=5; //Символ D, нижний
byte E=6; //Символ E, снизу слева
byte F=7; //Символ F, сверху слева
byte G=8; //Символ G, центральный
byte Dp=9; //Символ "точка"
byte D1=10; //Первый сегмент
byte D2=11; //Второй сегмент
byte D3=12; //Третий сегмент
byte D4=14; //Четвертый сегмент
byte H=18; //Часы
byte M=00; //Минуты
boolean S=true; //Вкл/Откл светодиод секунд
unsigned long currentTime=0;
unsigned long loopTime=0;
byte H1=0; //Часы, первая цифра
byte H2=0; //Часы, вторая цифра
byte M1=0; //Минуты, первая цифра
byte M2=0; //Минуты, вторая цифра
void setup() {
pinMode(A, OUTPUT);
pinMode(B, OUTPUT);
pinMode(C, OUTPUT);
pinMode(D, OUTPUT);
pinMode(E, OUTPUT);
pinMode(F, OUTPUT);
pinMode(G, OUTPUT);
pinMode(Dp, OUTPUT);
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
pinMode(D4, OUTPUT);
digitalWrite(A, LOW);
digitalWrite(B, LOW);
digitalWrite(C, LOW);
digitalWrite(D, LOW);
digitalWrite(E, LOW);
digitalWrite(F, LOW);
digitalWrite(G, LOW);
digitalWrite(Dp, LOW);
digitalWrite(D1, HIGH);
digitalWrite(D2, HIGH);
digitalWrite(D3, HIGH);
digitalWrite(D4, HIGH);
currentTime = millis(); //считываем время, прошедшее с момента запуска программы
loopTime = currentTime;
}
void loop() {
H1=H/10;
H2=H-(H1*10);
M1=M/10;
M2=M-(M1*10);
currentTime = millis(); //считываем время, прошедшее с момента запуска программы
if(currentTime >= (loopTime + 1000)){
S = !S; //вкл/откл светодиод
}
loopTime = currentTime; //в loopTime записываем новое значение
digitalWrite(D1, LOW);
outd(H1);
digitalWrite(D1, HIGH);
digitalWrite(D2, LOW);
outd(H2);
if (S) { digitDp(); }
digitalWrite(D2, HIGH);
digitalWrite(D3, LOW);
outd(M1);
digitalWrite(D3, HIGH);
digitalWrite(D4, LOW);
outd(M2);
digitalWrite(D4, HIGH);
}
void outd(byte T){
switch (T) {
case 0:
digit0();
break;
case 1:
digit1();
break;
case 2:
digit2();
break;
case 3:
digit3();
break;
case 4:
digit4();
break;
case 5:
digit5();
break;
case 6:
digit6();
break;
case 7:
digit7();
break;
case 8:
digit8();
break;
case 9:
digit9();
break;
}
}
void digit1() {
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
}
void digit2() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(E, LOW);
digitalWrite(G, HIGH);
digitalWrite(G, LOW);
}
void digit3() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(G, HIGH);
digitalWrite(G, LOW);
}
void digit4() {
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(F, HIGH);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(G, LOW);
}
void digit5() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(F, HIGH);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(G, LOW);
}
void digit6() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(F, LOW);
}
void digit7() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
}
void digit8() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(G, LOW);
}
void digit9() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(F, HIGH);
digitalWrite(F, LOW);
digitalWrite(G, HIGH);
digitalWrite(G, LOW);
}
void digit0() {
digitalWrite(A, HIGH);
digitalWrite(A, LOW);
digitalWrite(B, HIGH);
digitalWrite(B, LOW);
digitalWrite(C, HIGH);
digitalWrite(C, LOW);
digitalWrite(D, HIGH);
digitalWrite(D, LOW);
digitalWrite(E, HIGH);
digitalWrite(E, LOW);
digitalWrite(F, HIGH);
digitalWrite(F, LOW);
}
void digitDp() {
digitalWrite(Dp, HIGH);
digitalWrite(Dp, LOW);
}
И не будет. Оператор "!" выполняет логическоую инверсию (true/false или 1/0), в то время, как вам нужна двоичная инверсия, за которую отвечает оператор "^".
А разве тип boolean не является по факту одним битом, со значением 1 и 0?
И про ^ в справочнике ничего не сказано.
Попробовал вставить ^ в код, не принимает.
Блиин!! Вот я слепой, loopTime = currentTime; , нужно в о внутрь условия запрятать, иначе loopTime будет всегда ненамного отставать и условие не выполнится.
currentTime = millis(); //считываем время, прошедшее с момента запуска программы if(currentTime >= (loopTime + 1000)){ S = !S; //вкл/откл светодиод loopTime = currentTime; //в loopTime записываем новое значение }У одного бита нет адреса. Минимально адресуемый объем информации - один байт. Соответственно, не может быть и переменной меньше байта.
Си - не Паскаль, здесь логические и целые типы не различаются. Поэтому компилятору нужно явно указывать, какой тип функции (арифметический или логический) нам нужен.
При двоичной инверсии 1 переходит в 254, а при логической - в 0. А 0 в 256 и 1 соответственно.
PS. Код не смотрел - только ответы на вопросы.
Си - не Паскаль, здесь логические и целые типы не различаются. Поэтому компилятору нужно явно указывать, какой тип функции (арифметический или логический) нам нужен.
Не знаю ни того ни этого языка, в училище делфи проходили.
А можно ссылку, где подробно это рассказано?
https://new.vk.com/doc14767444_322779111?hash=75b41fd49fea719852&dl=dd15...
Я тут, в ожидании часов точного времени, набросал код использующий в качестве таймера функцию millis(), с выводом в сериал, и увидел, что ход достаточно точен, всегда кратен 1000. Учитывая, что функция обнуляется раз в 50 дней, получается довольно точный ход, с отставанием на одну секунду в 50 дней. Которое легко компенсировать.
То есть, можно сделать достаточно точный ход без внешних часов, главное обеспечить бесперебойным питанием?
Вот такое чудо я наваял, прошу раскритиковать.
byte A=2; //Символ A, сверху byte B=3; //Символ B, сверху справо byte C=4; //Символ C, снизу справо byte D=5; //Символ D, нижний byte E=6; //Символ E, снизу слева byte F=7; //Символ F, сверху слева byte G=8; //Символ G, центральный byte Dp=9; //Символ "точка" byte D1=10; //Первый сегмент byte D2=11; //Второй сегмент byte D3=12; //Третий сегмент byte D4=14; //Четвертый сегмент byte H=0; //Часы byte M=0; //Минуты byte S=0; //Секунды byte Day=0; //Дни, для компенсации отставания bool Tik=true; //Вкл/Откл светодиод секунд bool Button1=0; //антидребезг кнопки 1 bool Button2=0; //антидребезг кнопки 2 int sensorValue=512; //сенсор двух кнопок unsigned long currentTime=0; unsigned long loopTime=0; byte H1=0; //Часы, первая цифра byte H2=0; //Часы, вторая цифра byte M1=0; //Минуты, первая цифра byte M2=0; //Минуты, вторая цифра void setup() { pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(C, OUTPUT); pinMode(D, OUTPUT); pinMode(E, OUTPUT); pinMode(F, OUTPUT); pinMode(G, OUTPUT); pinMode(Dp, OUTPUT); pinMode(D1, OUTPUT); pinMode(D2, OUTPUT); pinMode(D3, OUTPUT); pinMode(D4, OUTPUT); digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(C, HIGH); digitalWrite(D, HIGH); digitalWrite(E, HIGH); digitalWrite(F, HIGH); digitalWrite(G, HIGH); digitalWrite(Dp, HIGH); digitalWrite(D1, LOW); digitalWrite(D2, LOW); digitalWrite(D3, LOW); digitalWrite(D4, LOW); currentTime = millis(); //считываем время, прошедшее с момента запуска программы loopTime = currentTime; } void loop() { sensorValue = analogRead(A1); H1=H/10; H2=H-(H1*10); M1=M/10; M2=M-(M1*10); if(S==60){ M++; S=0; } if(M==60){ H++; M=0; } if(H==24){ Day++; H=0; } if(Day==50){ S++; Day=0; } if((sensorValue <= 300) && (Button1 == false)){ //Если нажата кнопка 1, замыкающая резистор 10К между выводом и землей, и флаг равен 0 Button1 = true; M++; //Добавляем минуту } if((sensorValue > 300) && (Button1 == true)){ Button1 = false; } if((sensorValue >= 700) && (Button2 == false)){ //Если нажата кнопка 2, замыкающая резистор 10К между выводом и плюсом, и флаг равен 0 Button2 = true; H++; //Добавляем час } if((sensorValue < 700) && (Button2 == true)){ Button2 = false; } currentTime = millis(); //считываем время, прошедшее с момента запуска программы if(currentTime >= (loopTime + 1000)){ loopTime = currentTime; //в loopTime записываем новое значение Tik = !Tik; //вкл/откл светодиод S++; } digitalWrite(D1, HIGH); outd(H1); digitalWrite(D1, LOW); digitalWrite(D2, HIGH); outd(H2); if (Tik) { digitDp(); } digitalWrite(D2, LOW); digitalWrite(D3, HIGH); outd(M1); digitalWrite(D3, LOW); digitalWrite(D4, HIGH); outd(M2); digitalWrite(D4, LOW); } void outd(byte T){ switch (T) { case 0: digit0(); break; case 1: digit1(); break; case 2: digit2(); break; case 3: digit3(); break; case 4: digit4(); break; case 5: digit5(); break; case 6: digit6(); break; case 7: digit7(); break; case 8: digit8(); break; case 9: digit9(); break; } } void digit1() { digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); } void digit2() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(E, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit3() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit4() { digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(F, LOW); digitalWrite(F, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit5() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(F, LOW); digitalWrite(F, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit6() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(F, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit7() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); } void digit8() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(F, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit9() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(F, LOW); digitalWrite(F, HIGH); digitalWrite(G, LOW); digitalWrite(G, HIGH); } void digit0() { digitalWrite(A, LOW); digitalWrite(A, HIGH); digitalWrite(B, LOW); digitalWrite(B, HIGH); digitalWrite(C, LOW); digitalWrite(C, HIGH); digitalWrite(D, LOW); digitalWrite(D, HIGH); digitalWrite(E, LOW); digitalWrite(E, HIGH); digitalWrite(F, LOW); digitalWrite(F, HIGH); } void digitDp() { digitalWrite(Dp, LOW); digitalWrite(Dp, HIGH); }1. Сэру известно о существовании такой конструкции как оператор цикла?
2. Крайне любопытно, проверялось ли это "в железе". Мне почему-то кажется, что это работать не будет (по крайней мере так, как хотелось бы автору).
1. Известно. Чем это поможет? Хотя, когда буду делать вольтметр, измеряющий напряжение резервной баттареи, думаю загнать в цикл посегметную индикацию, или вывести её так же в отдельную функцию. Пока не решил, как будет проще.
2. Работает, вот на столе лежит, хотя антидребезг, бывает, "прощелкивает", думаю как улучшить. Delay использовать не хочу, думаю на millis повлияет. Присматриваюсь к аппаратным решениям в виде связки кондера и резистора.
PS:
https://new.vk.com/doc14767444_322779111?hash=75b41fd49fea719852&dl=dd15d8151effaf8092
Это, пока, для меня слишком сложно, думаю в будущем дорасту.
PPS: Хотя аналога GOTO не хватает.