ходики Ждуна MAX7219 8х8

skoctehs
Offline
Зарегистрирован: 27.02.2016

Скорее милый сувенир, чем полезные часы.

Но они как-то  успокаивают что ли.

Динамика смены цифр аналогична ходу маятника, задается в массиве  const int scrt[9]

Были придуманы и запрограммированы за вечер, ничего лишнего™.

Установка даты D2 общий, а D3-D6 соответственно часы +- минуты+- .

Точность хода часов обеспечивает  функция millis().

Обмен данными с MAX7219 обеспечивает SPI.

конец июня 2019г. ШК

001/*
002  Basic code for using Maxim MAX7219/MAX7221 with Arduino.
003  Wire the Arduino and the MAX7219/MAX7221 together as follows:
004  | Arduino   | MAX7219/MAX7221 |
005  | --------- | --------------- |
006  | MOSI (11) | DIN (1)         |
007  | SCK (13)  | CLK (13)        |
008  | I/O (9)*  | LOAD/CS (12)    |
009    * - This should match the LOAD_PIN constant defined below.
010 
011  For the rest of the wiring follow the wiring diagram found in the datasheet.
012 
014  Author:  Nicholas Dobie <nick@nickdobie.com>
015  Date:    30 December 2013
016  License: WTFPL (<a href="http://www.wtfpl.net/" title="http://www.wtfpl.net/" rel="nofollow">http://www.wtfpl.net/</a>)
017 */
018 
019 
020 
021#include <SPI.h>
022 
023// What pin on the Arduino connects to the LOAD/CS pin on the MAX7219/MAX7221
024#define LOAD_PIN 9
025#define pkey 300
026 
027const byte dg[40] = {30, 33, 33, 30, 0, 34, 63, 32, 34, 49, 41, 38, 18, 33, 37, 26, 24, 20, 63, 16, 23, 37, 37, 25, 30, 37, 37, 25, 00, 01, 57, 07, 26, 37, 37, 26, 6, 41, 41, 30};
028const int scrt[9] = { 495, 205, 157, 133, 117, 106, 97, 90, 80};
029byte hr = 12;
030byte mn = 34;
031byte sc = 56;
032byte dh, dm, eh, em;
033byte ii, zx, zy, zz, zt = 0;
034 
035byte pics[25];
036 
037byte hod = 0;
038unsigned long tempus,tmkey;
039unsigned long tmscr;
040 
041/**
042 * Transfers data to a MAX7219/MAX7221 register.
043 *
044 * @param address The register to load data into
045 * @param value   Value to store in the register
046 */
047void maxTransfer(uint8_t address, uint8_t value) {
048  // Ensure LOAD/CS is LOW
049  digitalWrite(LOAD_PIN, LOW);
050  // Send the register address
051  SPI.transfer(address);
052  // Send the value
053  SPI.transfer(value);
054  // Tell chip to load in data
055  digitalWrite(LOAD_PIN, HIGH);
056}
057 
058 
059void setup() {
060  // Set load pin to output
061  pinMode(LOAD_PIN, OUTPUT);
062  // Reverse the SPI transfer to send the MSB first
063  SPI.setBitOrder(MSBFIRST);
064  // Start SPI
065  SPI.begin();
066  pinMode(2, OUTPUT);
067  digitalWrite(2, HIGH);
068 
069  pinMode(3, INPUT_PULLUP);
070  pinMode(4, INPUT_PULLUP);
071  pinMode(5, INPUT_PULLUP);
072  pinMode(6, INPUT_PULLUP);
073 
074  maxTransfer(0x0F, 0x00);
075  // Disable mode B
076  maxTransfer(0x09, 0x00);
077  // Use lowest intensity
078  maxTransfer(0x0A, 0x00);
079  // scan all
080  maxTransfer(0x0B, 0x07);
081  for (uint8_t i = 1; i < 9; ++i)
082  {
083    maxTransfer(i, 0);
084  }
085  // Turn on chip
086  maxTransfer(0x0C, 0x01);
087 
088  format_pics();
089  tempus = millis() + 1000;
090  zt = 0;
091  tmscr = millis() +  scrt[zt];
092  zy = 0;
093tmkey = millis() + pkey;
094 
095}
096 
097 
098void gettime() {
099  dh = hr / 10;
100  eh = hr - 10 * dh;
101  dm = mn / 10;
102  em = mn - 10 * dm;
103}
104 
105void getdg(byte am) {
106  ii = am * 4; // adres digit
107  for (uint8_t i3 = ii; i3 < ii + 4; ++i3)
108  {
109    if (zx < 6) pics[zx] = dg[i3];
110    if (zx > 5)     pics[zx] = dg[i3] * 4;
111    if (zx > 17)     pics[zx] = dg[i3];
112 
113 
114    zx++;
115  }
116}
117 
118void format_pics() {
119  gettime();
120 
121  zx = 0;
122  pics[zx] = 0; // space
123  zx++; //1
124  getdg(dh);//5
125  pics[zx] = 0; // space
126  zx++;//6
127  getdg(eh);//10
128  pics[zx] = 0; // space
129  zx++;//11
130  pics[zx] = 18 * 4; // dots
131  zx++;//12
132  pics[zx] = 0; // space
133  zx++;//13
134  getdg(dm);//17
135  pics[zx] = 0; // space
136  zx++;//18
137  getdg(em);//22
138  pics[zx] = 0; // space
139 
140  //23 byte  0-22
141 
142 
143 
144 
145}
146 
147void scr()
148{
149  for (byte k = 1; k < 9; ++k)  {
150    zz = zy + k - 1;
151     
152    //11 выводим в 4 и 5 позицию
153    if (zz==11) {if ((k==4)||(k==5))    maxTransfer(k, pics[zz]);} else maxTransfer(k, pics[zz]);
154     
155  }
156 
157}
158 
159void loop() {
160 
161  if (millis() > tmscr) {  // horizont
162    if (hod == 0) zy++;
163    if (hod == 1) zy--;
164    if (zy == 0)   hod = 0;
165    if (zy == 15)   hod = 1;
166    zt = zy; // 0 1 2 17
167    if (zt > 7) zt = 15 - zt;
168    tmscr = millis() + scrt[zt];
169    scr();
170  }
171 
172 
173  if (millis() > tempus) {  // ход часов
174    tempus = millis() + 1000;
175    seci();
176  }
177 
178  //
179  if (millis() > tmkey) {  // ход часов
180    tmkey = millis() + pkey;
181    key();
182  }
183}
184void key()
185{
186  digitalWrite(2, LOW);
187  if (!digitalRead(3)) {
188    hr++;
189    if (hr>23)hr=0;
190    format_pics();
191    scr();
192  }
193 
194  if (!digitalRead(5))
195  { mn++;
196    if (mn>59)mn=0;
197    format_pics();
198    scr();
199  }
200  if (!digitalRead(4)) {
201    hr--;
202    if (hr==0)hr=23;
203    format_pics();
204    scr();
205  }
206 
207  if (!digitalRead(6))
208  { mn--;
209    if (mn==0)mn=59;
210    format_pics();
211    scr();
212  }
213  digitalWrite(2, HIGH);
214}
215 
216 
217void seci()
218{
219  sc++;
220  if (sc > 59)
221  {
222    sc = 0;
223    mn++;
224    if (mn > 59) {
225      mn = 0;
226      hr++;
227    }
228    if (hr > 23) {
229      hr = 0;
230    }
231    format_pics();
232  }
233}

 

skoctehs
Offline
Зарегистрирован: 27.02.2016
b707
Offline
Зарегистрирован: 26.05.2017

красиво!

Поставил плюсик

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Действительно красиво - я не удержался, залил и посмотрел живьем.

skoctehs
Offline
Зарегистрирован: 27.02.2016
001const char now[] = __TIME__;
002 
003// 12в ленты часы ЗВЕЗДА и минуты стрелки динамическая индикация
004// uln2003a+bc237 2s8550 3pcs
005// stm8s103
006// таблица выводы - стрелки
007/*       13   14   15
008   12 = h0    h4    h8
009   11   m0    m20   m40
010   10   h1    h5    h9
011   9    m5    m25    m45
012   8    h2    h6     h10
013   7    m10   m30    m50
014   6    h3    h7     h11
015   5    m15    m35   m55
016*/
017boolean svd;
018long mms, msl;
019byte tt1, tt2, ma, mb, ha, hb, minut, mnn, hours, hnn, sec, led_c , lz = 0;
020int z;
021const int scrt[12] = { 495, 205, 157, 133, 117, 106, 106, 117, 133, 157, 205, 495};
022const int t10000=10000;
023void corr_h() {
024  // выбор стрелки часовой
025 
026  hnn = hours;
027  if (hnn == 0) {
028    ha = 13;
029    hb = 12;
030  }
031  if (hnn == 1) {
032    ha = 13;
033    hb = 10;
034  }
035  if (hnn == 2) {
036    ha = 13;
037    hb = 8;
038  }
039  if (hnn == 3) {
040    ha = 13;
041    hb = 6;
042  }
043  if (hnn == 4) {
044    ha = 14;
045    hb = 12;
046  }
047  if (hnn == 5) {
048    ha = 14;
049    hb = 10;
050  }
051  if (hnn == 6) {
052    ha = 14;
053    hb = 8;
054  }
055  if (hnn == 7) {
056    ha = 14;
057    hb = 6;
058  }
059  if (hnn == 8) {
060    ha = 15;
061    hb = 12;
062  }
063  if (hnn == 9) {
064    ha = 15;
065    hb = 10;
066  }
067  if (hnn == 10) {
068    ha = 15;
069    hb = 8;
070  }
071  if (hnn == 11) {
072    ha = 15;
073    hb = 6;
074  }
075 
076}
077 
078 
079 
080void corr_m() {
081  // выбор стрелки минутной
082  if (mnn == 0) {
083    ma = 13;
084    mb = 11;
085  }
086  if (mnn == 5) {
087    ma = 13;
088    mb = 9;
089  }
090  if (mnn == 10) {
091    ma = 13;
092    mb = 7;
093  }
094  if (mnn == 15) {
095    ma = 13;
096    mb = 5;
097  }
098  if (mnn == 20) {
099    ma = 14;
100    mb = 11;
101  }
102  if (mnn == 25) {
103    ma = 14;
104    mb = 9;
105  }
106  if (mnn == 30) {
107    ma = 14;
108    mb = 7;
109  }
110  if (mnn == 35) {
111    ma = 14;
112    mb = 5;
113  }
114  if (mnn == 40) {
115    ma = 15;
116    mb = 11;
117  }
118  if (mnn == 45) {
119    ma = 15;
120    mb = 9;
121  }
122  if (mnn == 50) {
123    ma = 15;
124    mb = 7;
125  }
126  if (mnn == 55) {
127    ma = 15;
128    mb = 5;
129  }
130 
131}
132 
133 
134 
135void key_k() {
136  // обработка кнопок
137bool k0=digitalRead(0);
138bool k1=digitalRead(1);
139  if (k0 == 0) tt1++ ; else tt1 = 0;
140  if (k1 == 0) tt2++ ; else tt2 = 0;
141if ((tt1*tt2)>75) {
142  minut=0;
143  sec=0;
144  mms = millis() + t10000;
145}
146  // 1 цикл опроса  8 ms * 50 = 400мс
147  if (tt1 > 50) {
148    hours++;
149    tt1 = 0;
150    if (hours > 11)hours = 0;
151    corr_h();
152  }
153  if (tt2 > 50) {
154    minut = minut + 5;
155    tt2 = 0;
156    if (minut > 59) minut = 0;
157 
158    mnn = minut;
159    mnn = 5 * byte(mnn / 5); // округляем до 5 минутки
160    corr_m();
161    mnn = minut;
162  }
163 
164}
165 
166 
167 
168void disp() {
169  // часовая стрелка
170  digitalWrite(ha, HIGH);   // turn the LED on (HIGH is the voltage level)
171  digitalWrite(hb, HIGH);   // turn the LED on (HIGH is the voltage level)
172  delay(2);                       // wait for a second
173  digitalWrite(ha, LOW);    // turn the LED off by making the voltage LOW
174  digitalWrite(hb, LOW);    // turn the LED off by making the voltage LOW
175 
176  // минутная стрелка
177  digitalWrite(ma, HIGH);   // turn the LED on (HIGH is the voltage level)
178  digitalWrite(mb, HIGH);   // turn the LED on (HIGH is the voltage level)
179  delay(2);                       // wait for a second
180  digitalWrite(ma, LOW);    // turn the LED off by making the voltage LOW
181  digitalWrite(mb, LOW);    // turn the LED off by making the voltage LOW
182}
183 
184void  circl_m() {
185  // оборот  минутной стрелки
186  for (z = 0; z < 12; z++) {
187    // минутная стрелка
188    mnn = minut + z * 5 ; //(0-55 = 0-11)
189    if (mnn > 59) mnn = mnn - 60; // проходим ноль
190    mnn = 5 * byte(mnn / 5); // округляем до 5 минутки
191 
192    corr_m();
193    digitalWrite(ma, HIGH);   // turn the LED on (HIGH is the voltage level)
194    digitalWrite(mb, HIGH);   // turn the LED on (HIGH is the voltage level)
195 
196    delay(scrt[z]);                       // wait for a second
197    digitalWrite(ma, LOW);    // turn the LED off by making the voltage LOW
198    digitalWrite(mb, LOW);    // turn the LED off by making the voltage LOW
199 
200  }
201  //  коррекция индикации
202  mnn = minut;
203  mnn = 5 * byte(mnn / 5); // округляем до 5 минутки
204  corr_m();
205  mnn = minut;
206  if (hnn != hours) corr_h(); // коррекция часовой стрелки
207}
208 
209void clc() {
210  //  тик так 10 секунд
211 
212  mms = millis() + t10000;
213  sec++;
214  if (sec > 5) {
215    minut++;
216    sec = 0;
217    if (minut > 59) {
218      hours++;
219      minut = 0;
220      if (hours > 11) hours = 0;
221    }
222    // смена минуты - эффект круга
223    circl_m();
224  }
225}
226 
227 
228void led() {
229 
230  // раз в полсекунды
231  // раз в 5 секунд моргаем сколько минут от стрелки прошло 19:53 - 3 минуты
232  //  svd = !svd; // инверсия светодиода
233  // моргаем сколько неполных минут до 5
234  mnn = minut;
235  mnn = 5 * byte(mnn / 5);
236  lz = (minut - mnn + 1) * 2 + 1; // 2 4 6 8 10
237  if (lz > led_c) svd = HIGH; else svd = LOW;
238 
239  if (bitRead(led_c, 0)) svd = LOW;
240 
241  digitalWrite(2, svd);    // светодиодик
242  msl = millis() + 500;
243  led_c++;
244  if (led_c > 15) led_c = 1;
245}
246 
247 
248void setup() {
249  pinMode(0, INPUT); // кнопка перевода часов
250  pinMode(1, INPUT);// кнопка перевода минут
251  pinMode(2, OUTPUT); // индикатор секунд
252  pinMode(5, OUTPUT);
253  pinMode(6, OUTPUT);
254  pinMode(7, OUTPUT);
255  pinMode(8, OUTPUT);
256  pinMode(9, OUTPUT);
257  pinMode(10, OUTPUT);
258  pinMode(11, OUTPUT);
259  pinMode(12, OUTPUT);
260  pinMode(13, OUTPUT);
261  pinMode(14, OUTPUT);
262  pinMode(15, OUTPUT);
263  hours =  4;
264  minut = 40;
265  hours =  atoi(&now[0]);
266  minut = atoi(&now[3]);
267  msl = millis() + 500;
268  mms = millis() + t10000;
269  circl_m();
270}
271 
272void loop() {
273 
274  key_k(); // контроль кнопок
275  if (mms < millis()) clc(); // ход часов и мигание светодиода
276  if (msl < millis() )led(); // мигание светодиода
277  disp(); // индикация стрелок
278}

 

skoctehs
Offline
Зарегистрирован: 27.02.2016

Собрано на STM8S103,ULN2003,S8550,BC237

использовал кусочки ленты 12в (по 3 светодиода) 

b707
Offline
Зарегистрирован: 26.05.2017

 Пишете для стм8 в ардуино иде? А что за аддон? Как поддержка, глюки есть? Много ли библиотек поддерживается?

skoctehs
Offline
Зарегистрирован: 27.02.2016

b707 пишет:

 Пишете для стм8 в ардуино иде?

первый раз = это ответ и на другие вопросы :)

А что за аддон?

устанавливается как новая плата (по инструкции  с инета, делал в прошлом году - а допаял  часы вчера)

не помогу = лучше вам поискать лично

Как поддержка, глюки есть?

тут вроде ок всё

Много ли библиотек поддерживается?

столкнулся mstimer2 не поддерживает - да и не искал вот

вроде есть I2C

использовал ST-LINK

по мне выходит самый  бюджетный вариант для разных глупостей

сорри, если не помог

Deniskyn
Offline
Зарегистрирован: 13.04.2019

Видео не доступно......

skoctehs
Offline
Зарегистрирован: 27.02.2016

https://disk.yandex.ru/i/ooZdR9avVFIEKA
Первую конструкцию разобрал