Самая экономичная 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 будет всегда ненамного отставать и условие не выполнится.
У одного бита нет адреса. Минимально адресуемый объем информации - один байт. Соответственно, не может быть и переменной меньше байта.
Си - не Паскаль, здесь логические и целые типы не различаются. Поэтому компилятору нужно явно указывать, какой тип функции (арифметический или логический) нам нужен.
При двоичной инверсии 1 переходит в 254, а при логической - в 0. А 0 в 256 и 1 соответственно.
PS. Код не смотрел - только ответы на вопросы.
Си - не Паскаль, здесь логические и целые типы не различаются. Поэтому компилятору нужно явно указывать, какой тип функции (арифметический или логический) нам нужен.
Не знаю ни того ни этого языка, в училище делфи проходили.
А можно ссылку, где подробно это рассказано?
https://new.vk.com/doc14767444_322779111?hash=75b41fd49fea719852&dl=dd15...
Я тут, в ожидании часов точного времени, набросал код использующий в качестве таймера функцию millis(), с выводом в сериал, и увидел, что ход достаточно точен, всегда кратен 1000. Учитывая, что функция обнуляется раз в 50 дней, получается довольно точный ход, с отставанием на одну секунду в 50 дней. Которое легко компенсировать.
То есть, можно сделать достаточно точный ход без внешних часов, главное обеспечить бесперебойным питанием?
Вот такое чудо я наваял, прошу раскритиковать.
1. Сэру известно о существовании такой конструкции как оператор цикла?
2. Крайне любопытно, проверялось ли это "в железе". Мне почему-то кажется, что это работать не будет (по крайней мере так, как хотелось бы автору).
1. Известно. Чем это поможет? Хотя, когда буду делать вольтметр, измеряющий напряжение резервной баттареи, думаю загнать в цикл посегметную индикацию, или вывести её так же в отдельную функцию. Пока не решил, как будет проще.
2. Работает, вот на столе лежит, хотя антидребезг, бывает, "прощелкивает", думаю как улучшить. Delay использовать не хочу, думаю на millis повлияет. Присматриваюсь к аппаратным решениям в виде связки кондера и резистора.
PS:
https://new.vk.com/doc14767444_322779111?hash=75b41fd49fea719852&dl=dd15d8151effaf8092
Это, пока, для меня слишком сложно, думаю в будущем дорасту.
PPS: Хотя аналога GOTO не хватает.