Бинарные часы
- Войдите на сайт для отправки комментариев
Пнд, 10/10/2011 - 20:11
Захотелось сделать бинарные часы. Нарыл схему. Собрал на макете но есть проблема. Необходимые лампочки загораются НО некоторые которые не должны гореть горят очень тускло. Никак не могу от этого избавиться. В чём может быть эта проблема?
001 | int LED1[] = { |
002 | 0,0,1,0,0,1,1,1,1,1 |
003 | }; |
004 | int LED2[] = { |
005 | 0,0,0,1,0,1,1,1,1,1 |
006 | }; |
007 | int LED3[] = { |
008 | 1,0,0,0,1,0,1,1,1,1 |
009 | }; |
010 | int LED4[] = { |
011 | 0,1,0,0,1,0,1,1,1,1 |
012 | }; |
013 | int LED5[] = { |
014 | 0,0,1,0,1,0,1,1,1,1 |
015 | }; |
016 | int LED6[] = { |
017 | 0,0,0,1,1,0,1,1,1,1 |
018 | }; |
019 | int LED7[] = { |
020 | 0,1,0,0,1,1,0,1,1,1 |
021 | }; |
022 | int LED8[] = { |
023 | 0,0,1,0,1,1,0,1,1,1 |
024 | }; |
025 | int LED9[] = { |
026 | 0,0,0,1,1,1,0,1,1,1 |
027 | }; |
028 | int LED10[] = { |
029 | 1,0,0,0,1,1,1,0,1,1 |
030 | }; |
031 | int LED11[] = { |
032 | 0,1,0,0,1,1,1,0,1,1 |
033 | }; |
034 | int LED12[] = { |
035 | 0,0,1,0,1,1,1,0,1,1 |
036 | }; |
037 | int LED13[] = { |
038 | 0,0,0,1,1,1,1,0,1,1 |
039 | }; |
040 | int LED14[] = { |
041 | 0,1,0,0,1,1,1,1,0,1 |
042 | }; |
043 | int LED15[] = { |
044 | 0,0,1,0,1,1,1,1,0,1 |
045 | }; |
046 | int LED16[] = { |
047 | 0,0,0,1,1,1,1,1,0,1 |
048 | }; |
049 | int LED17[] = { |
050 | 1,0,0,0,1,1,1,1,1,0 |
051 | }; |
052 | int LED18[] = { |
053 | 0,1,0,0,1,1,1,1,1,0 |
054 | }; |
055 | int LED19[] = { |
056 | 0,0,1,0,1,1,1,1,1,0 |
057 | }; |
058 | int LED20[] = { |
059 | 0,0,0,1,1,1,1,1,1,0 |
060 | }; |
061 | int LEDPins[] = { |
062 | 12,11,10,9,8,7,6,5,4,3}; |
063 |
064 |
065 | void vivod( int LED[]) |
066 | { |
067 | for ( int i=0;i<=9; i++) |
068 | digitalWrite(LEDPins[i], LED[i]); |
069 | delay(1); |
070 | } |
071 |
072 | int second=5, minute=5, hour=2; //start the time on 00:00:00 |
073 | int munit = 4; |
074 | int hunit = 9; |
075 | int suc = 5; |
076 | void setup() { |
077 | |
078 | for ( int i=0;i<=9; i++) |
079 | pinMode(LEDPins[i], OUTPUT); |
080 |
081 | } |
082 |
083 | void loop() { |
084 |
085 |
086 | if (suc == 1 || suc == 3 || suc == 5 || suc == 7 || munit == 9) vivod(LED20); |
087 | if (suc == 2 || suc == 3 || suc == 6 || suc == 7) vivod(LED19); |
088 | if (suc == 4 || suc == 5 || suc == 6 || suc == 7) vivod(LED18); |
089 | if (suc == 8 || suc == 9) vivod(LED17); |
090 |
091 | //minutes |
092 | if (second == 1 || second == 3 || second == 5 || second == 7 || second == 9) vivod(LED16); |
093 | if (second == 2 || second == 3 ) vivod(LED15); |
094 | if (second == 4 || second == 5 ) vivod(LED14); |
095 | |
096 | //minutes units |
097 | if (munit == 1 || munit == 3 || munit == 5 || munit == 7 || munit == 9) vivod(LED13); |
098 | if (munit == 2 || munit == 3 || munit == 6 || munit == 7) vivod(LED12); |
099 | if (munit == 4 || munit == 5 || munit == 6 || munit == 7) vivod(LED11); |
100 | if (munit == 8 || munit == 9) vivod(LED10); |
101 |
102 | //minutes |
103 | if (minute == 1 || minute == 3 || minute == 5 || minute == 7 || minute == 9) vivod(LED9); |
104 | if (minute == 2 || minute == 3 ) vivod(LED8); |
105 | if (minute == 4 || minute == 5 ) vivod(LED7); |
106 | |
107 |
108 | //hour units |
109 | if (hunit == 1 || hunit == 3 || hunit == 5 || hunit == 7 || hunit == 9) vivod(LED6); |
110 | if (hunit == 2 || hunit == 3 || hunit == 6 || hunit == 7) vivod(LED5); |
111 | if (hunit == 4 || hunit == 5 || hunit == 6 || hunit == 7) vivod(LED4); |
112 | if (hunit == 8 || hunit == 9) vivod(LED3); |
113 |
114 | //hour |
115 | if (hour == 1) vivod(LED2); |
116 | if (hour == 2) vivod(LED1); |
117 |
118 | } |
А менять местами яркие и неяркие светодиоды пробовали? Может просто светодиод бракованный или подпаленный? Можно еще попробовать махнуть местами резистры, мало ли?
Приведите схему подключения светодиодов.
А то светодиодов много, а резисторов мало...
Схема!
Попробуйте в конце функции loop, добавить delay(500); и сообщите перестали-ли гореть "в пол-накала" часть диодов.
Если я не ошибаюсь в своих подозрениях, то должны перестать. Правда часы будут показывать "только час" (минут и секуд не будет), но зато мы будем знать что "на правильном пути".
нет не перестали. диоды которые не должны гореть всё равно загораются. Я заметил что проблема только с нижнем рядом диодов.
> диоды которые не должны гореть всё равно загораются
А характер загорания изменился? Я не совсем правильно выразился что должно "произойти", перестать должны были именно "тускло". Правильно или неправильно, пока вторично. Главное что должны начать горет "четко". Либо горит, либо нет. Наблюдается такое?
А менять местами яркие и неяркие светодиоды пробовали? Может просто светодиод бракованный или подпаленный? Можно еще попробовать махнуть местами резистры, мало ли?
Я прошу прощения, я плохо прочитал сообщение и ответил невпопад.
На всякий случай спрошу. На схеме светодиоды подключаются к выходам 4-13, а в коде у Вас 3-12. Подключили Вы как в коде или как на схеме?
у меня подключено 3-12 как в коде. диоды: если вставить delay(500) в конце как вы говорили то загорается и стабильно горит только один диод. Остальные те которые должны гореть без этой строчки кода загораются и гаснут + загораются и те которые не должны гореть. Все они вспыхивают ярко.
Вопрос: Я работал с Цифровым сегментным индикатором и там не было таких проблем. Может внутри есть схема которая убирает эту проблему? Или там тупо светодиоды.
Светодиоды могут еле еле светиться если где-то есть "недоконтакт" к плюсу или минусу(в моём случае это был не смытый флюс) в вашем может быть некрасивая схема матрицы, перепроверьте всё
OK. Значит "догадка" подтвердилась. Ошибка - в коде. Это не исключает ошибку в схеме подключения, но вначале нужно разобратся с кодом. Задержку delay(500) можно убрать. Она нужна была только "для проверки догадки".
Проблема в том что во время одного прохода loop вызываете несколько раз vivod(...). Не решив до конца "какае диодны должны гореть", вы используя промежуточные результаты вычислений, уже пытаетесь "показать их на диодах". Например для показа часа hunit = 9, у вас выполнится vivod(LED6) и vivod(LED3) . Посмотрим, например, на PIN9. vivod(LED6) его включит, а vivod(LED3) его тут же выключит. Так как looup() крутится быстро, то если нет задержки delay(500), мы получаем на этом пине "мерцание" и диод горит "тускло".
Ну и так же возникает эффект, что более поздние "промежутночные" решения что должно гореть "перекрывают" более ранние.
Если посмотреть изначальную статью в которой описаны эти часы, то там написано примерно так:""I used following calculation....When done, the colum values are passed on to port C ". Что можно перевести как "я выполняют следующие вычисления.... когда они закончены, я отправлю результат в portC (поджигаю светодиоды)".
То есть вам нужно завести некий промежуточный буффер, и все вычисления "что включать, а что нет", должны писать в него и только уже в конце, когда все решения приняты, на основании инормации из буфера, нужно включать/выключать светодиоды. Функция vidod должна вызываться только один раз. И параметром иметь этот буфер. Попробуйте это реализовать, если не получится... попозже может набросаю как это в коде должно выглядет.
Так же, при подключении не забудте следующие: на этой схеме номера выводов это номера ног "микроконтроллера". Которые могут и не совпадать с нумерацией пинов ардуины (которые вы используете в коде). Соответсвие между ними вы можете найти вот тут www.arduino.cc/en/Hacking/PinMapping
Например то что в вашей схеме нарисована как "вывод 5", в коде должно соотвествовать digitalWrite(3,....)
Вообщем посмотрите эту шпаргалку и сверте нумерацию в своем LEDPins. Если там будут значения взятые просто "из схемы", то естествено диоды будут поджигатся неправильно.
>на этой схеме номера выводов это номера ног "микроконтроллера"
Все еще несколько "путаней". На схеме это даже не номера ног котроллера. А номера ног разъема который придумал автор этой статьи. Рядом он там дал еще одну схемку в которой видно соотвествие ног контроллера, пинам этого разъема.
То есть вам нужно "смотреть номер пина на разъеме", выяснить "какой ноге контроллера он соотвествует", потом смотреть в PinMapping и узнавать какой digital-пин ардуины соответсвует этой ноге контроллера.
То есть вам нужно завести некий промежуточный буффер, и все вычисления "что включать, а что нет", должны писать в него и только уже в конце, когда все решения приняты, на основании инормации из буфера, нужно включать/выключать светодиоды. Функция vidod должна вызываться только один раз. И параметром иметь этот буфер. Попробуйте это реализовать, если не получится... попозже может набросаю как это в коде должно выглядет.
Попробую
Что то я не соображу( ведь 2 верхних ряда работают нормально
Это ни о чем не говорит. Значит им повезло. И все множественные вызовы vivod(...) в данном конкретном случае их либо включают, либо все вызовы выключают. А, как только у вас попадается ситуация что одны вызовы включают, а другие выключают - вы получаете мерцание.
Попробуйте как то так:
01
int
LEDPinsBuff[10];
02
03
void
clearBuff()
04
{
05
for
(
int
i=0;i<=9; i++)LEDPinsBuff[i]=0;
06
}
07
08
void
vivod2buff(
int
LED[])
09
{
10
for
(
int
i=0;i<=9; i++)
11
if
(LED[i]==1)LEDPinsBuff[i]=1;
// если LEDPinsBuff[i] уже установлен в единицу, то он не будет сбрасываться даже если LED[i]==0. Этим мы "накапливаем" принятые решения
12
13
}
Далее,
"Мерцания" должны исчезнуть даже без delay(500).
Что-бы дальше было удобней отлаживать логику можно в setup добавить инициализацию порта
Serial.begin(9600); // если необходимо - подправте скорость.
Добавте функцию
1
void
vivod2serial(
int
LED[])
2
{
3
for
(
int
i=0;i<=9; i++){
4
Serial.print( LED[i],DEC);
5
Serial.print(
','
);
6
}
7
Serial.println();
8
delay(5000);
// задержка что-бы можно было в терминале неспеша прочитать какие пины зажгли
9
}
И вызов vivod2serial(LEDPinsBuff) в конец loop.
Тогда в окне терминала вы сможете увидеть "какие же пины собиралась включать" ваша логика. Если "не то что вы думали" - ищите ошибку в логике, если "тут все правильно, но горят не правильные диоды" - проверяйте схему подключения держа в уме необходимость маппинга пинов (пин разъема->нога контроллера->пин ардуины).
Блин не знаю даже чо за фигня. Ваш код вообще не работает. Но я решил сделать по другому. И всё равно не нужные диоды тускло горят. Проверил через порт. Всё четко))))
001
int
LED1[] = {
002
1,0,0,1,1,1,1,1,0,1
003
};
004
int
LED2[] = {
005
1,0,0,1,1,1,1,1,1,0
006
};
007
int
LED3[] = {
008
1,0,0,0,1,1,1,1,1,1
009
};
010
int
LED4[] = {
011
1,0,0,1,1,0,1,1,1,1
012
};
013
int
LED5[] = {
014
1,0,0,1,1,1,0,1,1,1
015
};
016
int
LED6[] = {
017
1,0,0,1,1,1,1,0,1,1
018
};
019
int
LED7[] = {
020
0,1,0,1,0,1,1,1,1,1
021
};
022
int
LED8[] = {
023
0,1,0,1,1,1,1,1,0,1
024
};
025
int
LED9[] = {
026
0,1,0,1,1,1,1,1,1,0
027
};
028
int
LED10[] = {
029
0,1,0,0,1,1,1,1,1,1
030
};
031
int
LED11[] = {
032
0,1,0,1,1,0,1,1,1,1
033
};
034
int
LED12[] = {
035
0,1,0,1,1,1,0,1,1,1
036
};
037
int
LED13[] = {
038
0,1,0,1,1,1,1,0,1,1
039
};
040
int
LED14[] = {
041
0,0,1,1,0,1,1,1,1,1
042
};
043
int
LED15[] = {
044
0,0,1,1,1,1,1,1,0,1
045
};
046
int
LED16[] = {
047
0,0,1,1,1,1,1,1,1,0
048
};
049
int
LED17[] = {
050
0,0,1,0,1,1,1,1,1,1
051
};
052
int
LED18[] = {
053
0,0,1,1,1,0,1,1,1,1
054
};
055
int
LED19[] = {
056
0,0,1,1,1,1,0,1,1,1
057
};
058
int
LED20[] = {
059
0,0,1,1,1,1,1,0,1,1
060
};
061
int
LEDPins[] = {
062
12,11,10,9,8,7,6,5,4,3};
063
064
void
vivod2(
int
var ,
int
nom)
065
{
066
switch
(var) {
067
case
1:
068
if
(nom==1){
069
vivod(LED2);
070
}
071
072
if
(nom==2){
073
vivod(LED6);
074
}
075
076
if
(nom==3){
077
vivod(LED9);
078
}
079
080
if
(nom==4){
081
vivod(LED13);
082
}
083
084
if
(nom==5){
085
vivod(LED16);
086
}
087
088
if
(nom==6){
089
vivod(LED20);
090
}
091
092
break
;
093
094
case
2:
095
if
(nom==1){
096
vivod(LED1);
097
}
098
099
if
(nom==2){
100
vivod(LED5);
101
}
102
103
if
(nom==3){
104
vivod(LED8);
105
}
106
107
if
(nom==4){
108
vivod(LED12);
109
}
110
111
if
(nom==5){
112
vivod(LED15);
113
}
114
115
if
(nom==6)
116
{
117
vivod(LED19);
118
}
119
break
;
120
121
case
3:
122
/*if (nom==1){
123
}*/
124
125
if
(nom==2){
126
vivod(LED6);
127
vivod(LED5);
128
}
129
130
if
(nom==3){
131
vivod(LED9);
132
vivod(LED8);
133
}
134
135
if
(nom==4){
136
vivod(LED13);
137
vivod(LED12);
138
}
139
140
if
(nom==5){
141
vivod(LED16);
142
vivod(LED15);
143
}
144
145
if
(nom==6)
146
{
147
vivod(LED20);
148
vivod(LED19);
149
}
150
break
;
151
152
case
4:
153
/*if (nom==1){
154
}*/
155
156
if
(nom==2){
157
vivod(LED4);
158
}
159
160
if
(nom==3){
161
vivod(LED7);
162
}
163
164
if
(nom==4){
165
vivod(LED11);
166
}
167
168
if
(nom==5){
169
vivod(LED14);
170
}
171
172
if
(nom==6){
173
vivod(LED18);
174
}
175
break
;
176
177
case
5:
178
/*if (nom==1){
179
}*/
180
181
if
(nom==2){
182
vivod(LED6);
183
vivod(LED4);
184
}
185
186
if
(nom==3){
187
vivod(LED9);
188
vivod(LED7);
189
}
190
191
if
(nom==4){
192
vivod(LED13);
193
vivod(LED11);
194
}
195
196
if
(nom==5){
197
vivod(LED16);
198
vivod(LED14);
199
}
200
201
if
(nom==6){
202
vivod(LED20);
203
vivod(LED18);
204
}
205
break
;
206
207
case
6:
208
/* if (nom==1){
209
}*/
210
211
if
(nom==2){
212
vivod(LED5);
213
vivod(LED4);
214
}
215
216
/* if (nom==3){
217
}*/
218
219
if
(nom==4){
220
vivod(LED12);
221
vivod(LED11);
222
}
223
224
/* if (nom==5){
225
}*/
226
227
if
(nom==6){
228
vivod(LED19);
229
vivod(LED18);
230
}
231
break
;
232
233
case
7:
234
/*if (nom==1){
235
}*/
236
237
if
(nom==2){
238
vivod(LED6);
239
vivod(LED5);
240
vivod(LED4);
241
}
242
243
/*if (nom==3){
244
vivod(LED9);
245
}*/
246
247
if
(nom==4){
248
vivod(LED13);
249
vivod(LED12);
250
vivod(LED11);
251
}
252
253
/*if (nom==5){
254
vivod(LED16);
255
}*/
256
257
if
(nom==6){
258
vivod(LED20);
259
vivod(LED19);
260
vivod(LED18);
261
}
262
break
;
263
264
case
8:
265
/*if (nom==1){
266
}*/
267
268
if
(nom==2){
269
vivod(LED3);
270
}
271
272
/*if (nom==3){
273
}*/
274
275
if
(nom==4){
276
vivod(LED10);
277
}
278
279
/*if (nom==5){
280
}*/
281
282
if
(nom==6){
283
vivod(LED17);
284
}
285
break
;
286
287
case
9:
288
/*if (nom==1){
289
}*/
290
291
if
(nom==2){
292
vivod(LED6);
293
vivod(LED3);
294
}
295
296
/*if (nom==3){
297
vivod(LED9);
298
}*/
299
300
if
(nom==4){
301
vivod(LED13);
302
vivod(LED10);
303
}
304
305
/* if (nom==5){
306
vivod(LED16);
307
}*/
308
309
if
(nom==6){
310
vivod(LED20);
311
vivod(LED17);
312
}
313
break
;
314
315
}
316
}
317
318
void
vivod(
int
LED[])
319
{
320
for
(
int
i=0;i<=9; i++)
321
{
322
digitalWrite(LEDPins[i], LED[i]);
323
Serial.print( LED[i],DEC);
324
Serial.print(
','
);
325
}
326
Serial.println();
327
delay(1);
328
329
}
330
331
int
second=0, minute=0, hour=2;
//start the time on 00:00:00
332
int
munit = 0;
333
int
hunit = 2;
334
int
suc = 2;
335
void
setup() {
336
337
for
(
int
i=0;i<=9; i++)
338
pinMode(LEDPins[i], OUTPUT);
339
Serial.begin(9600);
340
}
341
342
void
loop() {
343
344
vivod2(suc,6);
345
vivod2(second,5);
346
vivod2(munit,4);
347
vivod2(minute,3);
348
vivod2(hunit,2);
349
vivod2(hour,1);
350
Serial.println(
'iiiiiiiiiiiiiiiiiiiiiii'
);
351
//delay(5000);
352
}
353
/*if(suc == 1 || suc == 3 || suc == 5 || suc == 7 || suc == 9) vivod(LED20);
354
if(suc == 2 || suc == 3 || suc == 6 || suc == 7) vivod(LED19);
355
if(suc == 4 || suc == 5 || suc == 6 || suc == 7) vivod(LED18);
356
if(suc == 8 || suc == 9) vivod(LED17);
357
358
359
if(second == 1 || second == 3 || second == 5 || second == 7 || second == 9) vivod(LED16);
360
if(second == 2 || second == 3 ) vivod(LED15);
361
if(second == 4 || second == 5 ) vivod(LED14);
362
363
//minutes units
364
if(munit == 1 || munit == 3 || munit == 5 || munit == 7 || munit == 9) vivod(LED13);
365
if(munit == 2 || munit == 3 || munit == 6 || munit == 7) vivod(LED12);
366
if(munit == 4 || munit == 5 || munit == 6 || munit == 7) vivod(LED11);
367
if(munit == 8 || munit == 9) vivod(LED10);
368
369
//minutes
370
if(minute == 1 || minute == 3 || minute == 5 || minute == 7 || minute == 9) vivod(LED9);
371
if(minute == 2 || minute == 3 ) vivod(LED8);
372
if(minute == 4 || minute == 5 ) vivod(LED7);
373
374
375
//hour units
376
if(hunit == 1 || hunit == 3 || hunit == 5 || hunit == 7 || hunit == 9) vivod(LED6);
377
if(hunit == 2 || hunit == 3 || hunit == 6 || hunit == 7) vivod(LED5);
378
if(hunit == 4 || hunit == 5 || hunit == 6 || hunit == 7) vivod(LED4);
379
if(hunit == 8 || hunit == 9) vivod(LED3);
380
381
//hour
382
if(hour == 1) vivod(LED2);
383
if(hour == 2) vivod(LED1);
384
delay(1);*/
>Ваш код вообще не работает
В чем проявляется "вообще не работает"? Горят "не те" или "не те горят тускло"?
>Проверил через порт.
Всмысле вывели к ком-порт лог "какие пины включаются"? Включаются правильные, но "горят лишние"?
Тогда только проверять схему подключения.
Уже самого "заело". Попробую, чуть позже, в симуляторе воспроизвести вашу схему (нет под руками нужных деталей) и посмотреть "как оно работает". Если у вас получится решить проблему раньше - отпишитесь. Что-бы я не тратил время.
вообще не горят
>Всмысле вывели к ком-порт лог "какие пины включаются"? Включаются правильные, но "горят лишние"?
горят лишнии но в логе только те которые должны гореть написаны.
Я немного видоизменил схему подключения сделал как Цифрового сегментного индикатора. Глюков стало меньше но они есть
Посмотрел сейчас видео в статье. Похоже что "мерцание" это "так задуманно". На видео его тоже видно. Одновременно несколько диодов не зажигаются. Эффект одновременности достигается delay(1); в функции vivod(...) (можно кстати будет поигратся с этим параметром).
Так что буферезирование, наверное таки лишние. Нужно разбиратся только с "зажигаются неправильные".
Что-бы мы копали "в одном направлении". Какие, по вашему, диоды должны зажигатся при при
1
int
second=0, minute=0, hour=2;
//start the time on 00:00:00
2
int
munit = 0;
3
int
hunit = 2;
4
int
suc = 2;
И какие зажигают в реальности? По нумерации схемы (которые там нарисованы LED1, LED2,LED...)
>Эффект одновременности достигается delay(1); в функции vivod(...) (можно кстати будет поигратся с этим параметром).
я пробовал менять этот параметр. при 0 ненужные светодиоды горят ярко как и все при 1-10 горят тускло при10+++ начинается мерцание.
при данных параметрах горят LED2,4,18
тусклоLED15
Кстати, пока я пробую воспроизвести схему. Можете сделать еще одну проверочку:
Выкинуть все из loop. И написать в него
01
vivod(LED1);
02
delay(300);
03
04
vivod(LED2);
05
delay(300);
06
07
vivod(LED3);
08
delay(300);
09
10
vivod(LED4);
11
delay(300);
12
........
В результате это должно начать зажигать диоды "по очереди" (как они называются на схеме). Если "зажигает" в правильном порядке - значит схема собрана правильно, если нет, то...
))))) я так уже делал и не раз. последовательно зажигал каждый светодиод. и всё ок. Даже всё схему разобрал и собрал заново таже проблема! И светодиоды менял без результатно(
>последовательно зажигал каждый светодиод. и всё ок
Да быть такого не может. Вот если в loop у вас будет vivod(LED20) неужели зажигается именно LED20? (самый верхний правый на схеме).
Что-бы он зажегся только он должен быть LOW на четвертом PIN-е разъема и HIGH на 13-том.
По коду, по это должны быть (судя из ваших объяснений как вы подключили) 3 PIN арудины и 12-тый.
Смотрим в (первый ваш пример кода)
Как видим "крайние пины" у нас оба LOW. Следовательно LED20 гореть никак не может. На нем с обоих сторон 0. Зато, зачем-то "включили" кучу других пинов 9,8,7,6,5,4.
Вывод: либо пины у вас подключены как-то "совсем не так", либо никакого "LED-ы загораются последовательно нормально" нет и в помине.
Откуда вы брали последовательности LED1,LED2,LED3...?
На эмуляторе собрал упрощеную схему. Игрался именно с LED20. Правда "подключал" я по тому как нарисовано на схеме (то есть LEDPins у меня были свои), но пока не поправил int LED20[] на что-то подобное "int LED20[] = { 1,0,0,0,0,0,0,0,0,0};
vivod(LED20) у меня ничего не включал. Так что перепроверяйте свои включающие последовательности.
Кстати, только что рассмотрел на вашей фотке шпаргалку в клеточку. Если я правильно понял, то это ваша нумерация LED-дов. Сравните ее с нумерацией LED-ов в статье. Они, мягко говоря, отличаются. Возможно отсюда и пошла путаница в LEDxx[] последовательностях?
Что-то мне это уже начало дико напоминать детский водобпроводный ребус "какой шланг к какому крану идет". Вообщем "распутывайте" :)
Получилось у меня в симуляторе воспроизвести "помаргивание лишними диодами".
Подобно уже завтра "распишу".
В двух словах: "собака в том", что пины мы устанавливаем не одновременно, а "по очереди". Между вызовами digitalWrite есть небольшая задержка. Диоды мы зажигаем по такому принципу: подаем HIGH на аноды сразу нескольких диодов (аноды у них соеденены), LOW на катод того который должен гореть, и HIGH на катоды тех которые оказались "лишними" (так сказать лишили их "земли").
Так вот вначале у нас устанавливаются пины 12,11,10,9 - которые отвечают за аноды, и потом уже 8,7,6,5,4,3 которые отвечают за катоды. И вот в этом промежутке когда мы уже установили 12,11,10,9, но еще не успели установить в правильное состояние 8,7,6,5,4,3 (запретить лишние) у нас происходит кратковременное моргание "тех которых не ожидали".
Выход либо отказатся от digitalWrite и устанавливать состояние ног "одновременно". Это можно сделать через прямую запись в порт (как и делается в оригинальность статье). Либо попытатся вначале устанавливать "катоды", а потом "аноды". Как-то так (мне на симуляторе помогло):
1
void
vivod(
int
LED[])
2
{
3
for
(
int
i=0;i<=4;i++) digitalWrite(LEDPins[i],LOW);
// снимаем напряжение с анодов, если оно там есть от предыдущего вызова
4
for
(
int
i=9;i>=0; i--)
// проходим по пинам в обратном порядке, что-бы вначале установились катоды
5
digitalWrite(LEDPins[i], LED[i]);
6
delay(1);
7
}
Когда вы зажигали LED-ы "по очереди" с большими паузами, этих кратковременных лишних "подмаргиваний" видно небыло (трудно увидеть один милисекундный миг), а когда вы пускаете это в "цикл". И это лишние подмаргивание возникает несколько тысяч раз в секунду - его становится видно как "горит в пол накала".
P.S. А управляющие последовательности проверте.
Я вчера как раз думал об том чтобы все пины сбрасывать в 0. попробовал ваш код. РАБОТАЕТ)))) но они светят тускло. И я изменил и всё стало нормально гореть)))))) Спасибо большое)))
01
void
vivod(
int
LED[])
02
{
03
for
(
int
i=9;i>=0; i--)
04
{
05
digitalWrite(LEDPins[i], LED[i]);
06
}
07
delay(1);
08
for
(
int
i=0;i<=3; i++)
09
digitalWrite(LEDPins[i], 0);
10
}
Ну мне мой вариант все-таки кажется более предпочтительным. А с тусклостью в нем я бы преложил бороться небольшим увеличением delay(1)->delay(10).
Какие минусы я вижу в вашем коде: пока идет "вычисление логики" в вашем варинаты леды выключены, в моем - включены. Поэтому, теоретически, мой вариант должен быть ярче (хотя вы говорите что наоборот - непонятно). Так же вы сделали i<=3 вместо i<=4, теоретически, на некоторых комбинациях это опять может привести к "паразитам" (в нижнем ряду, удивляюсь почему не привело, видимо все-таки разные у нас схемы подключения).
Но конечно любой "профи" от нашего решения упал-бы в обморок. "Правильно" это нужно решать прямой записью в порт. И хранить необходимые состояния не в виде массивов, а в виде битовых масок. Тогда сама собой уйдет и проблема "одновременности" и код станет компактней, и прошивка меньше.
Делается "прямая запись", например вот так:
1
PORTD = B10101000;
// синхронно-одновременно устанавливаем 7,5,3 пины в HIGH, остальные в LOW
подробнее можно почитать тут:www.arduino.cc/en/Reference/PortManipulation
Кстати прямая запись в порт еще и работает в несколько раз быстрее чем через digitalWrite
>Но конечно любой "профи" от нашего решения упал-бы в обморок. ДААА это точно)))))
Про прямую запись в порт ничего не знал. Так что ща полезу посмотрю. Большое спасибо. что помогли разобраться.)))
>вы сделали i<=3 вместо i<=4
Похоже все-таки в этом вы больше правы. Вчера в три ночи дописывал этот код и прощитался с индексаторами. Ваш вариант более аккуратен.
А прямую запись в порт все-таки попробуйте. Это будет намного более правильное решение.
И пытаясь предугадать дальнейшие действия: вы же будуте кнопки обрабатывать? Возможно ловить их "нажатия" будет лучше через arduino.ru/Reference/AttachInterrupt
>Про прямую запись в порт ничего не знал
Если бы знали, то у нас бы небыло такого увлекательно квеста :) . Суть-то всех подобных хобби в "узнавании чего-то нового". Если бы сразу сделали "на портах", то про такой нюанс как "в каком порядке" включать ноги возможно и не подумали бы никогда.
А я бы так и не попробовал симуляцию-отладку ардуины в протеусе. Знал что "это возможно", но все "руки не доходили". Так что "время потрачено не зря".
Полностью согласен)))
Кстати сказать что вы "все делали неверно" тоже нельзя. С точки зрения ардуино-идеологии digitalWrite более правильно (понятней что происходит, легче переносить на другие контроллеры). Она и создавалась что-бы "скрыть технически детали от чайников".
Но как видите это не всегда благо (поэтому "профи" и называют ардуину "от лукавого"). Работа с портами это больше С/ASM идеология. Когда нужно хоть немного представлять внутренюю архитектуру контроллера на котором "все крутится". И при переходе на другой контроллер код может потребовать "небольшого допиливания".
Про прямую запись в порт ничего не знал. Так что ща полезу посмотрю.
Добавили перевод по использованию регистров микроконтроллера для прямой записи в порты. Читать тут - http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
ОООООООООооооо. Спасибо!!!!!
Ура!!! Ура!!! Ура!!! Наконец то, сегодня, Я завершил постройку бинарных часов!
И с радостью показываю их вам.
Сразу хочу выразить благодарность «leshak» за помощь в программировании.
Часы умеют показывать дату и время. На передней стороне имеются (кроме числовых светодиодов) одна кнопка, которая отвечает за переключением между режимами Дата/Время, и два маленьких светодиода (с права) показывающих, что в данный момент показывают числовые светодиоды.
На задней стороне имеются три кнопки настройки. Верхние две отвечают за + и – к времени а нижняя вводит часы в режим настройки. Также в нижнем левом углу есть рычажок выкл/вкл часов.
Ну я думаю что лучше перейти к фото части))))
001
int
LED1[] = {
002
1,0,0,1,1,1,1,1,0,1
003
};
004
int
LED2[] = {
005
1,0,0,1,1,1,1,1,1,0
006
};
007
int
LED3[] = {
008
1,0,0,0,1,1,1,1,1,1
009
};
010
int
LED4[] = {
011
1,0,0,1,1,0,1,1,1,1
012
};
013
int
LED5[] = {
014
1,0,0,1,1,1,0,1,1,1
015
};
016
int
LED6[] = {
017
1,0,0,1,1,1,1,0,1,1
018
};
019
int
LED7[] = {
020
0,1,0,1,0,1,1,1,1,1
021
};
022
int
LED8[] = {
023
0,1,0,1,1,1,1,1,0,1
024
};
025
int
LED9[] = {
026
0,1,0,1,1,1,1,1,1,0
027
};
028
int
LED10[] = {
029
0,1,0,0,1,1,1,1,1,1
030
};
031
int
LED11[] = {
032
0,1,0,1,1,0,1,1,1,1
033
};
034
int
LED12[] = {
035
0,1,0,1,1,1,0,1,1,1
036
};
037
int
LED13[] = {
038
0,1,0,1,1,1,1,0,1,1
039
};
040
int
LED14[] = {
041
0,0,1,1,0,1,1,1,1,1
042
};
043
int
LED15[] = {
044
0,0,1,1,1,1,1,1,0,1
045
};
046
int
LED16[] = {
047
0,0,1,1,1,1,1,1,1,0
048
};
049
int
LED17[] = {
050
0,0,1,0,1,1,1,1,1,1
051
};
052
int
LED18[] = {
053
0,0,1,1,1,0,1,1,1,1
054
};
055
int
LED19[] = {
056
0,0,1,1,1,1,0,1,1,1
057
};
058
int
LED20[] = {
059
0,0,1,1,1,1,1,0,1,1
060
};
061
int
LEDPins[] = {
062
2,3,4,12,13,11,10,9,7,8};
063
064
int
PinKnop1=14;
065
int
PinKnop2=16;
066
int
PinKnop3=15;
067
int
PinKnop4=17;
068
int
PinKontrotLED1=6;
069
int
PinKontrotLED2=5;
070
071
072
#include "Wire.h"
073
#define DS1307_I2C_ADDRESS 0x68
074
075
byte
decToBcd(
byte
val)
076
{
077
return
( (val/10*16) + (val%10) );
078
}
079
080
byte
bcdToDec(
byte
val)
081
{
082
return
( (val/16*10) + (val%16) );
083
}
084
085
void
setDateDs1307(
byte
second,
// 0-59
086
byte
minute,
// 0-59
087
byte
hour,
// 1-23
088
byte
dayOfWeek,
// 1-7
089
byte
dayOfMonth,
// 1-28/29/30/31
090
byte
month,
// 1-12
091
byte
year)
// 0-99
092
{
093
Wire.beginTransmission(DS1307_I2C_ADDRESS);
094
Wire.send(0);
095
Wire.send(decToBcd(second));
096
Wire.send(decToBcd(minute));
097
Wire.send(decToBcd(hour));
098
Wire.send(decToBcd(dayOfWeek));
099
Wire.send(decToBcd(dayOfMonth));
100
Wire.send(decToBcd(month));
101
Wire.send(decToBcd(year));
102
Wire.endTransmission();
103
}
104
105
void
getDateDs1307(
byte
*second,
106
byte
*minute,
107
byte
*hour,
108
byte
*dayOfWeek,
109
byte
*dayOfMonth,
110
byte
*month,
111
byte
*year)
112
{
113
Wire.beginTransmission(DS1307_I2C_ADDRESS);
114
Wire.send(0);
115
Wire.endTransmission();
116
117
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
118
119
*second = bcdToDec(Wire.receive() & 0x7f);
120
*minute = bcdToDec(Wire.receive());
121
*hour = bcdToDec(Wire.receive() & 0x3f);
122
*dayOfWeek = bcdToDec(Wire.receive());
123
*dayOfMonth = bcdToDec(Wire.receive());
124
*month = bcdToDec(Wire.receive());
125
*year = bcdToDec(Wire.receive());
126
}
127
128
void
vivod(
int
LED[])
129
{
130
131
for
(
int
i=9;i>=0; i--)
132
{
133
digitalWrite(LEDPins[i], LED[i]);
134
}
135
delay(1);
136
for
(
int
i=0;i<=3; i++)
137
digitalWrite(LEDPins[i], 0);
138
}
139
140
int
second1=0, minute1=0, hour1=0;
141
int
munit = 0;
142
int
hunit = 0;
143
int
suc = 0;
144
145
void
setup() {
146
147
for
(
int
i=0;i<=9; i++)
148
pinMode(LEDPins[i], OUTPUT);
149
pinMode (PinKontrotLED1,OUTPUT);
150
pinMode (PinKontrotLED2,OUTPUT);
151
pinMode(PinKnop1, INPUT);
152
pinMode(PinKnop2, INPUT);
153
pinMode(PinKnop3, INPUT);
154
pinMode(PinKnop4, INPUT);
155
156
byte
second, minute, hour, dayOfWeek, dayOfMonth, month, year;
157
Wire.begin();
158
Serial.begin(9600);
159
160
// second = 11;
161
// minute = 53;
162
// hour = 18;
163
// dayOfWeek = 5;
164
// dayOfMonth = 15;
165
// month = 10;
166
// year = 11;
167
// setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
168
}
169
int
knopka1=0;
170
int
knopka2=0;
171
int
knopka3=0;
172
int
knopka4=0;
173
int
k=0;
174
int
h=0;
175
int
f=0;
176
void
loop() {
177
178
byte
second, minute, hour, dayOfWeek, dayOfMonth, month, year;
179
getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
180
181
182
if
(digitalRead(PinKnop1)==HIGH&&knopka1==0)
183
{
184
k=!k;
185
knopka1++;
186
}
187
if
(digitalRead(PinKnop1)==LOW&&knopka1==1)
188
knopka1=0;
189
190
191
if
(digitalRead(PinKnop2)==HIGH&&knopka2==0)
192
{
193
h++;
194
if
(h==4)h=0;
195
knopka2++;
196
}
197
if
(digitalRead(PinKnop2)==LOW&&knopka2==1)
198
knopka2=0;
199
200
201
if
(digitalRead(PinKnop3)==HIGH&&knopka3==0)
202
{
203
if
(k==0)
204
{
205
if
(h==3)second++;
206
if
(h==2)minute++;
207
if
(h==1)hour++;
208
209
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
210
}
211
if
(k==1)
212
{
213
if
(h==3)year++;
214
if
(h==2)month++;
215
if
(h==1)dayOfMonth++;
216
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
217
}
218
219
220
knopka3++;
221
}
222
if
(digitalRead(PinKnop3)==LOW&&knopka3==1)
223
knopka3=0;
224
225
226
227
if
(digitalRead(PinKnop4)==HIGH&&knopka4==0)
228
{
229
if
(k==0)
230
{
231
if
(h==3)second--;
232
if
(h==2)minute--;
233
if
(h==1)hour--;
234
235
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
236
}
237
if
(k==1)
238
{
239
if
(h==3)year--;
240
if
(h==2)month--;
241
if
(h==1)dayOfMonth--;
242
setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
243
}
244
knopka4++;
245
}
246
if
(digitalRead(PinKnop4)==LOW&&knopka4==1)
247
knopka4=0;
248
249
250
251
if
(k==0)
252
{
253
digitalWrite(PinKontrotLED1, 1);
254
digitalWrite(PinKontrotLED2, 0);
255
if
(h==0||h==3)
256
{
257
258
second1 = second/10;
259
suc = second - pow((second/10), 1)*10;
260
}
261
if
(h==0||h==2)
262
{
263
minute1 = minute/10;
264
munit = minute - pow((minute/10), 1)*10;
265
}
266
if
(h==0||h==1)
267
{
268
269
hour1 = hour/10;
270
hunit = hour - pow((hour/10), 1)*10;
271
}
272
273
274
}
275
if
(k==1)
276
{
277
digitalWrite(PinKontrotLED1, 0);
278
digitalWrite(PinKontrotLED2, 1);
279
if
(h==0||h==3)
280
{
281
second1 = year/10;
282
suc = year - pow((year/10), 1)*10;
283
}
284
if
(h==0||h==2)
285
{
286
minute1 = month/10;
287
munit = month - pow((month/10), 1)*10;
288
}
289
if
(h==0||h==1)
290
{
291
292
hour1 = dayOfMonth/10;
293
hunit = dayOfMonth - pow((dayOfMonth/10), 1)*10;
294
}
295
}
296
297
298
299
if
(suc == 1 || suc == 3 || suc == 5 || suc == 7 || suc == 9) vivod(LED20);
300
if
(suc == 2 || suc == 3 || suc == 6 || suc == 7) vivod(LED19);
301
if
(suc == 4 || suc == 5 || suc == 6 || suc == 7) vivod(LED18);
302
if
(suc == 8 || suc == 9) vivod(LED17);
303
304
305
if
(second1 == 1 || second1 == 3 || second1 == 5) vivod(LED16);
306
if
(second1 == 2 || second1 == 3 ) vivod(LED15);
307
if
(second1 == 4 || second1 == 5 ) vivod(LED14);
308
309
//minutes units
310
if
(munit == 1 || munit == 3 || munit == 5 || munit == 7 || munit == 9) vivod(LED13);
311
if
(munit == 2 || munit == 3 || munit == 6 || munit == 7) vivod(LED12);
312
if
(munit == 4 || munit == 5 || munit == 6 || munit == 7) vivod(LED11);
313
if
(munit == 8 || munit == 9) vivod(LED10);
314
315
//minutes
316
if
(minute1 == 1 || minute1 == 3 || minute1 == 5) vivod(LED9);
317
if
(minute1 == 2 || minute1 == 3 ) vivod(LED8);
318
if
(minute1 == 4 || minute1 == 5 ) vivod(LED7);
319
320
321
//hour units
322
if
(hunit == 1 || hunit == 3 || hunit == 5 || hunit == 7 || hunit == 9) vivod(LED6);
323
if
(hunit == 2 || hunit == 3 || hunit == 6 || hunit == 7) vivod(LED5);
324
if
(hunit == 4 || hunit == 5 || hunit == 6 || hunit == 7) vivod(LED4);
325
if
(hunit == 8 || hunit == 9) vivod(LED3);
326
327
//hour
328
if
(hour1 == 1|| hour1 == 3) vivod(LED2);
329
if
(hour1 == 2|| hour1 == 3) vivod(LED1);
330
331
332
second1=0, minute1=0, hour1=0;
//start the time on 00:00:00
333
munit = 0;
334
hunit = 0;
335
suc = 0;
336
337
}
+ архив с печатной платой
Есть вопрос. Можно ли заменить atmega328 на atmega8? Вроде даже схему переделывать не надо.
P/S/ Думаю можно тему переместить в проекты.
>Можно ли заменить atmega328 на atmega8
Думаю можно. Хотя ответить на это вопрос можете только вы. Переключите в IDE целевую плату на "Ardino NG Older with Atmega8", скомпиляйте скетч, посмотрите какой размер получился, посмотрите влезет ли он в atmega8
Только подумайте еще: "оно вам надо?". Я вначале тоже "тискался" в младшие модели, а потом прикинул и увидел что "смысла нет". У нас на рынке, более страшие модели камня стоят дороже меньше чем на $1. А, иногда, и дешевле (гримасы логистики). Плюс проезд до рынка/обратно разницу точно "скушает". Ну и к тому же, прикинул, что при моех "хобби объемах", в несколько девайсов в год, гнатся за экономией в центы - смысла нет. Проще прикупить пару "жирных камней" и не гадать "влезет/не влезет".
>Думаю можно тему переместить в проекты.
Схема, скетч - было-бы не плохо. Вдруг кто-нибудь захочет повторить вашь подвиг. Все-таки "ардуина" задумывалсь как Open Source ;)
Да схему бы не помешало выложить.))) + плату. Я думаю что скоро добавлю (как только нарисую).
Аккуратно и красиво - молодцом) А корпус можно сделать просто как тонированный наглухо черный кусок стекла с приеклееными сзади часами, приклеете и крепление на стену - будет стильно и красиво.
Идея модернизации на будущие: датчик освещенности (или просто смотреть на текущие время) и ночью уменьшать "яркость", что-бы в темноте "по глазам" не било.
А корпус, можно сделать даже "только сзади" (что-бы прикрыть батарейку, камень), а впереди оставить "как есть". Так оно "гиковей" смотрится. Хотя и предложеный выше вариант - не плох. Дело вкуса.
кстати можно заняться поиском прозрачных/полупрозрачных корпусов и будет всё сразу) Удобно и гиково. Еще есть вариант это лазерная порезка акрила - круто но дорого в наших краях(особенно ломят цену за акрил)
я всё уже прикупил для своего проекта с часами, но нет времени(((( Я буду делать на модулях от dfrobot. и матрица 3216х2 тоесть будет явно 32 на 32, но пока всё лежит в коробочках
Нащет корпуса даже не знаю. Я обычно люблю внутренности видеть )))