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

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

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

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

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

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

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

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

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

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

/*
  Basic code for using Maxim MAX7219/MAX7221 with Arduino.
  Wire the Arduino and the MAX7219/MAX7221 together as follows:
  | Arduino   | MAX7219/MAX7221 |
  | --------- | --------------- |
  | MOSI (11) | DIN (1)         |
  | SCK (13)  | CLK (13)        |
  | I/O (9)*  | LOAD/CS (12)    |
    * - This should match the LOAD_PIN constant defined below.

  For the rest of the wiring follow the wiring diagram found in the datasheet.

  Datasheet: http://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf
  Author:  Nicholas Dobie <nick@nickdobie.com>
  Date:    30 December 2013
  License: WTFPL (http://www.wtfpl.net/)
 */



#include <SPI.h>

// What pin on the Arduino connects to the LOAD/CS pin on the MAX7219/MAX7221
#define LOAD_PIN 9
#define pkey 300

const 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};
const int scrt[9] = { 495, 205, 157, 133, 117, 106, 97, 90, 80};
byte hr = 12;
byte mn = 34;
byte sc = 56;
byte dh, dm, eh, em;
byte ii, zx, zy, zz, zt = 0;

byte pics[25];

byte hod = 0;
unsigned long tempus,tmkey;
unsigned long tmscr;

/**
 * Transfers data to a MAX7219/MAX7221 register.
 *
 * @param address The register to load data into
 * @param value   Value to store in the register
 */
void maxTransfer(uint8_t address, uint8_t value) {
  // Ensure LOAD/CS is LOW
  digitalWrite(LOAD_PIN, LOW);
  // Send the register address
  SPI.transfer(address);
  // Send the value
  SPI.transfer(value);
  // Tell chip to load in data
  digitalWrite(LOAD_PIN, HIGH);
}


void setup() {
  // Set load pin to output
  pinMode(LOAD_PIN, OUTPUT);
  // Reverse the SPI transfer to send the MSB first
  SPI.setBitOrder(MSBFIRST);
  // Start SPI
  SPI.begin();
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);

  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);

  maxTransfer(0x0F, 0x00);
  // Disable mode B
  maxTransfer(0x09, 0x00);
  // Use lowest intensity
  maxTransfer(0x0A, 0x00);
  // scan all
  maxTransfer(0x0B, 0x07);
  for (uint8_t i = 1; i < 9; ++i)
  {
    maxTransfer(i, 0);
  }
  // Turn on chip
  maxTransfer(0x0C, 0x01);

  format_pics();
  tempus = millis() + 1000;
  zt = 0;
  tmscr = millis() +  scrt[zt];
  zy = 0;
tmkey = millis() + pkey;

}


void gettime() {
  dh = hr / 10;
  eh = hr - 10 * dh;
  dm = mn / 10;
  em = mn - 10 * dm;
}

void getdg(byte am) {
  ii = am * 4; // adres digit
  for (uint8_t i3 = ii; i3 < ii + 4; ++i3)
  {
    if (zx < 6) pics[zx] = dg[i3];
    if (zx > 5)     pics[zx] = dg[i3] * 4;
    if (zx > 17)     pics[zx] = dg[i3];


    zx++;
  }
}

void format_pics() {
  gettime();

  zx = 0;
  pics[zx] = 0; // space
  zx++; //1
  getdg(dh);//5
  pics[zx] = 0; // space
  zx++;//6
  getdg(eh);//10
  pics[zx] = 0; // space
  zx++;//11
  pics[zx] = 18 * 4; // dots
  zx++;//12
  pics[zx] = 0; // space
  zx++;//13
  getdg(dm);//17
  pics[zx] = 0; // space
  zx++;//18
  getdg(em);//22
  pics[zx] = 0; // space

  //23 byte  0-22




}

void scr()
{
  for (byte k = 1; k < 9; ++k)  {
    zz = zy + k - 1;
    
    //11 выводим в 4 и 5 позицию
    if (zz==11) {if ((k==4)||(k==5))    maxTransfer(k, pics[zz]);} else maxTransfer(k, pics[zz]);
    
  }

}

void loop() {

  if (millis() > tmscr) {  // horizont
    if (hod == 0) zy++;
    if (hod == 1) zy--;
    if (zy == 0)   hod = 0;
    if (zy == 15)   hod = 1;
    zt = zy; // 0 1 2 17
    if (zt > 7) zt = 15 - zt;
    tmscr = millis() + scrt[zt];
    scr();
  }


  if (millis() > tempus) {  // ход часов
    tempus = millis() + 1000;
    seci();
  }

  //
  if (millis() > tmkey) {  // ход часов
    tmkey = millis() + pkey;
    key();
  }
}
void key()
{
  digitalWrite(2, LOW);
  if (!digitalRead(3)) {
    hr++;
    if (hr>23)hr=0;
    format_pics();
    scr();
  }

  if (!digitalRead(5))
  { mn++;
    if (mn>59)mn=0;
    format_pics();
    scr();
  }
  if (!digitalRead(4)) {
    hr--;
    if (hr==0)hr=23;
    format_pics();
    scr();
  }

  if (!digitalRead(6))
  { mn--;
    if (mn==0)mn=59;
    format_pics();
    scr();
  }
  digitalWrite(2, HIGH);
}


void seci()
{
  sc++;
  if (sc > 59)
  {
    sc = 0;
    mn++;
    if (mn > 59) {
      mn = 0;
      hr++;
    }
    if (hr > 23) {
      hr = 0;
    }
    format_pics();
  }
}

 

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

красиво!

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

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

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