Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Перекидные часы Arduino с одной светодиодной матрицей

Компоненты и расходные материалы

Arduino Nano R3
× 1
Maxim Integrated DS3231M - ± 5ppm, часы реального времени I2C
× 1
Светодиодная матрица 8x8 с драйвером MAX7219
× 1
Общий катод, рассеянный RGB
× 1
Резистор 220 Ом
× 2
Поворотный энкодер с кнопкой
× 1

Необходимые инструменты и машины

Паяльник (общий)

Приложения и онлайн-сервисы

IDE Arduino

Об этом проекте

Я создаю этот светодиодный матричный модуль ЧАСЫ 8x8, разработанный Адрианом Джонсом. Время отображается путем прокрутки слева направо или, под управлением программного обеспечения, сверху вниз. Каждая цифра времени последовательно сдвигается с правой стороны и при центрировании на мгновение останавливается и немного светлеет. Затем он прокручивается влево, пока на дисплее появляется следующая цифра. Цикл повторяется с небольшой задержкой между последовательными отображениями. Для вертикального переворачивания "сверху вниз" необходимо изменить:

статическое логическое значение top2bottom =false;

кому:

статическое логическое значение top2bottom =true;

Как вы можете видеть в комментариях к коду, можно изменить многие параметры, например, скорость прокрутки, количество пустых строк между символами, отображение 12/24 часов, мс между символами, яркость и т. Д.

Время можно легко установить с помощью поворотного энкодера. Двухцветный диод отображает режим настройки (минуты, часы или нормальный). Я положил часы в коробку, состоящую из двух основных частей, так что доступ к внутренней части коробки очень удобно и практично.

Код

  • код
код Arduino
 // ******************************************* ******************************************* //// МАТРИЧНЫЕ ЧАСЫ // Адриан Джонс, март 2014 г. //// - позволяет прокрутку слева направо и сверху вниз //// ********************* ************************************************* ****************** // # include  // Библиотека I2C-WIRE # include  // RTC-Library // определение max7219 регистров и контрольные штифты # определить max7219_reg_noop 0x00 # определить max7219_reg_digit0 0x01 # определить max7219_reg_digit1 0x02 # определить max7219_reg_digit2 0x03 # определить max7219_reg_digit3 0x04 # определить max7219_reg_digit4 0x05 # определить max7219_reg_digit5 0x06 # определить max7219_reg_digit6 0x07 # определить max7219_reg_digit7 0x08 # определить max7219_reg_decodeMode 0x09 # определить max7219_reg_intensity 0x0a # определить max7219_reg_scanLimit 0x0b # define max7219_reg_shutdown 0x0c #define max7219_reg_displayTest 0x0f # define dataIn 12 // DIN # define load 10 // CS #define clock 11 // CLKchar alphanum [] [8] ={{0x00,0x00,0x00,0x00,0x00,0x00 , 0x00,0x00}, // пустой шестнадцатеричный 20 декабря 32 {0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10}, //! 33 {0x00,0x28,0x28,0x28,0x00,0x00,0x00,0x00}, // "34 {0x00,0x28,0x7C, 0x28,0x7C, 0x28,0x00,0x00}, // # 35 {0x10,0x38, 0x50,0x38,0x14,0x54,0x38,0x10}, // $ {0x41,0xA2,0x44,0x08,0x10,0x22,0x45,0x82}, //% {0x38,0x44,0x44,0x38,0x50,0x4A, 0x44,0x3A}, // &{0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00}, // '{0x30,0x40,0x80,0x80,0x80,0x80,0x40,0x30}, // ( 40 {0xC0,0x20,0x10,0x10,0x10,0x10,0x20,0xC0}, //) {0x28,0x10,0xAA, 0x54,0xAA, 0x10,0x28,0x00}, // * {0x00,0x10,0x10, 0x10,0xFE, 0x10,0x10,0x10}, // + {0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x10}, //, {0x00,0x00,0x00,0x00,0x7E, 0x00,0x00, 0x00}, // - {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18}, //. {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}, // / {0x7E , 0xC1,0xA1,0x91,0x89,0x85,0x83,0x7E}, // 0 {0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x7C}, // 1 {0x38,0x44,0x82,0x04,0x18 , 0x20,0x40,0xFE}, // 2 50 {0x7C, 0x82,0x02,0x3C, 0x02,0x02,0x82,0x7C}, // 3 {0x08,0x18,0x28,0x48,0xFE, 0x08,0x08,0x08} , // 4 {0xFE, 0x80,0xF8,0x04,0x02,0x82,0x44,0x38}, // 5 {0x38,0x44,0x80,0xB8,0xC4 , 0x82,0x44,0x38}, // 6 {0xFE, 0x02,0x04,0x08,0x10,0x20,0x20,0x20}, // 7 {0x7C, 0x82,0x82,0x7C, 0x82,0x82,0x82,0x7C}, // 8 {0x7C, 0x82,0x82,0x7E, 0x02,0x82,0x44,0x38}, // 9 {0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00}, //:{0x00,0x00, 0x18,0x18,0x00,0x18,0x18,0x30}, //; {0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10}, // <60 {0x00,0x00,0x00,0x7E, 0x00,0x7E, 0x00,0x00}, // ={0x00,0x80,0x40, 0x20,0x10,0x20,0x40,0x80}, //> {0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20}, //? {0x7E, 0x81,0x99,0xA1,0xA1,0x9E, 0x80,0x7E}, // @ {0x3C, 0x42,0x81,0x81,0xFF, 0x81,0x81,0x81}, // A {0xFC, 0x82,0x81,0xFE , 0x81,0x81,0x82,0xFC}, // B {0x3C, 0x42,0x81,0x80,0x80,0x81,0x42,0x3C}, // C {0xFC, 0x82,0x81,0x81,0x81,0x81,0x82,0xFC }, // D {0xFE, 0x80,0x80,0xFC, 0x80,0x80,0x80,0xFE}, // E {0xFE, 0x80,0x80,0xFC, 0x80,0x80,0x80,0x80}, // F 70 {0x3C , 0x42,0x81,0x80,0x87,0x81,0x42,0x3C}, // G {0x81,0x81,0x81,0xFF, 0x81,0x81,0x81,0x81}, // H {0xFE, 0x10,0x10,0x10,0x10 , 0x10,0x10,0xFE}, // I {0xFF, 0x08,0x08,0x08,0x08,0x88,0x88,0x70}, // J {0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x84}, // K {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFE}, // L {0x81,0xC3,0xA5,0x99,0x81,0x81,0x81,0x81}, // M {0x81,0xC1, 0xA1,0x91,0x89,0x85,0x83,0x81}, // N {0x3C, 0x42,0x81,0x81,0x81,0x81,0x42,0x3C}, // O {0xFC, 0x82,0x81,0x82,0xFC, 0x80, 0x80,0x80}, // P 80 {0x3C, 0x42,0x81,0x81,0x81,0x85,0x42,0x3D}, // Q {0xFC, 0x82,0x81,0x82,0xFC, 0x84,0x82,0x81}, // R {0x3C, 0x42,0x81,0x40,0x3E, 0x81,0x42,0x3C}, // S {0xFE, 0x10,0x10,0x10,0x10,0x10,0x1 0,0x10}, // T {0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38}, // U {0x82,0x82,0x82,0x82,0x82,0x44,0x28,0x10}, // V {0x81,0x81,0x81,0x81,0x99,0xA5,0xC3,0x81}, // W {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81}, // X {0x82,0x44,0x28,0x10 , 0x10,0x10,0x10,0x10}, // Y {0xFF, 0x02,0x04,0x08,0x10,0x20,0x40,0xFF}, // Z 90 {0xE0,0x80,0x80,0x80,0x80,0x80,0x80, 0xE0}, // [{0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}, // {0x07,0x01,0x01,0x01,0x01,0x01,0x01,0x07}, //] {0xE0, 0xA0,0xE0,0xA0,0xAA, 0x15,0x15,0x11}, // am (кодируется как '^' {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E}, // _ {0x10,0x08, 0x00,0x00,0x00,0x00,0x00,0x00}, // '{0x00,0x00,0x38,0x04,0x3C, 0x44,0x48,0x34}, // a {0x00,0x40,0x40,0x40,0x78,0x44, 0x44,0x38}, // b {0x00,0x00,0x18,0x24,0x40,0x40,0x24,0x18}, // c {0x00,0x04,0x04,0x04,0x3C, 0x44,0x44,0x38}, // d 100 {0x00,0x00,0x38,0x44,0x7C, 0x40,0x44,0x38}, // e {0x00,0x18,0x20,0x20,0x78,0x20,0x20,0x20}, // f {0x00,0x38,0x44, 0x44,0x38,0x04,0x44,0x38}, // g {0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44}, // h {0x0 0,0x00,0x40,0x00,0x40,0x40,0x40,0x40}, // i {0x00,0x08,0x00,0x08,0x08,0x08,0x48,0x30}, // j {0x00,0x40,0x40,0x48, 0x50,0x60,0x50,0x48}, // k {0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x20}, // l {0x00,0x00,0x00,0x28,0x54,0x44,0x44,0x44} , // m {0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44}, // n 110 {0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38}, // o {0x00, 0x00,0x70,0x48,0x48,0x70,0x40,0x40}, // p {0x00,0x00,0x30,0x48,0x48,0x38,0x08,0x08}, // q {0x00,0x00,0x00,0x30,0x48, 0x40,0x40,0x40}, // r {0x00,0x30,0x48,0x40,0x30,0x08,0x48,0x30}, // s {0x00,0x20,0x70,0x20,0x20,0x20,0x28,0x10}, / / t {0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x38}, // u {0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10}, // v {0x00,0x00,0x82 , 0x82,0x82,0x92,0x54,0x28}, // w {0x00,0x00,0x84,0x48,0x30,0x30,0x48,0x84}, // x 120 {0x00,0x48,0x48,0x48,0x38,0x08, 0x48,0x30}, // y {0x00,0x00,0x00,0x7C, 0x08,0x10,0x20,0x7C}, // z {0x00,0x30,0x40,0x40,0x80,0x40,0x40,0x30}, // { {0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20}, // | {0x00,0x60,0x10,0x10,0x08,0x10,0x10,0x60}, //} {0xE0,0xA0,0xE0,0x80,0x8A, 0x15,0x15,0x11} // pm коды как '~' Hex 7E, Dec 126}; // определяем операцию RTC RTC_DS1307 RTC; // Крошечный модуль RTC (DS1307) (SDA - A4, SCL - A5) // поворотный энкодер, переключатель и управление светодиодами # define enc_PinA 2 // энкодер A к контакту 2 (прерывание 0) #define enc_PinB 4 // энкодер B к pin 4 # define enc_Switch 3 // переключатель энкодера на контакт 3 (прерывание 1) #define mode_Pin 8 // вывод светодиода режима # define min_Pin 9 // минутный светодиод pinunsigned char enc_A, enc_B, enc_A_prev =0; static boolean rotating =false; статическое логическое значение по часовой стрелке =false; статическое логическое значение updateFlag =false; static int mode =0; // 0 - ничего, 1 - установка часа, 2 - минимальная установка // определение отображаемых строк # определение max_array_size 100char ac [max_array_size] ={}; byte rc [8] ={}; String display_message =""; int arrayylen; // рабочие параметры # define delay_line 75 // мс между сдвигами строк # define delay_char 400 // мс между символами # define delay_mess 500 // мс между сообщениями # define cblanks 1 // количество пустых строк между символами # define eblanks 0 // количество дополнительных пустых строк (больше 8) в конце сообщения // особенности отображения статическое логическое значение top2bottom =false; // направление отображения (сверху вниз или справа налево статическое логическое значение hour24 =false; // отображение за 24 часа? static boolean charHI =true; // выделение всего символа статическое логическое значение doSerial =true; // последовательный вывод? // *** ************************************************* ************************************//// Начальная настройка//****** ************************************************* ******************************** // void setup () {Wire.begin (); Serial.begin ( 57600); if (doSerial) Serial.print ("Часы MATRIX - Адриан Джонс, март 2014 г."); // Выводы управления светодиодной матрицей 8x8 pinMode (dataIn, OUTPUT); pinMode (clock, OUTPUT); pinMode (load, OUTPUT ); initMatrix (); // инициализируем светодиодную матрицу // выводы светодиода pinMode (mode_Pin, OUTPUT); // вывод режима digitalWrite (mode_Pin, 1); pinMode (min_Pin, OUTPUT); // вывод минут digitalWrite (min_Pin, 1); // управление энкодером pinMode (enc_PinA, INPUT_PULLUP); digitalWrite (enc_PinA, HIGH); // вывод A поворотного энкодера pinMode (enc_PinB, INPUT_PULLUP); digitalWrite (enc_PinB, HIGH); // поворотный вывод B кодировщика pinMode (enc_Switch, INPUT_PULLUP); digitalWrite (enc_Switch, HIGH); // переключатель энкодера attachInterrupt (0, rotEncoder, CHANGE); // установка времени attachInterrupt (1, swEncoder, CHANGE); // минуты / часы // RTC RTC.begin (); если (! RTC.isrunning ()) {RTC.adjust (DateTime (__ DATE__, __TIME__)); if (doSerial) Serial.println ("(сброс RTC)"); } else {if (doSerial) Serial.println ("(RTC работает)"); }} // ******************************************** ****************************************** //// Главный цикл / / ************************************************ *************************************** // void loop () {DateTime now =RTC.now (); // show_time_and_date (сейчас); // отображение времени display_message =createMessage (now); arrayylen =initDisplayString (display_message); если (updateFlag) {show_time_and_date (сейчас); updateFlag =false; } пока (вращение) {задержка (1); // debounce adjTime (теперь по часовой стрелке); show_time_and_date (RTC.now ()); display_message =createMessage (сейчас); arrayylen =initDisplayString (display_message); задержка (1); вращение =ложь; // Сбрасываем флаг прерывания обратно на false} delay (5); for (int i =0; i <(arraylen-7); i ++) {// перебирает массив сообщений, продвигаясь по одному байту за (int j =1; j <9; j ++) {maxSingle (j, ac [i + 8-j]); } // строка 1 получает ac [i + 8], строка 2 получает ac [i + 7] и т.д. ... строка 8 получает ac [i + 0] if (i% (8 + cblanks) ==0) {/ / когда на дисплее отображается полный символ ... if (charHI) maxSingle (max7219_reg_intensity, 0x01); // ... увеличить яркость и временно остановить newDelay (delay_char); } else {// нормальная яркость maxSingle (max7219_reg_intensity, 0x00); newDelay (delay_line); }} if (mode ==0) newDelay (delay_mess);} // ******************************** ************************************************ / /// ПРОГРАММЫ ПРЕРЫВАНИЯ // ****************************************** ************************************* //// Функция rotEncoder ():вызывается ISR когда энкодер вращаетсяvoid rotEncoder () {delay (1); enc_A =цифровое чтение (enc_PinA); enc_B =цифровое чтение (enc_PinB); if (! enc_A &&enc_A_prev) {// изменение состояния по часовой стрелке =(! enc_A &&enc_B)? истина:ложь; если (режим! =0) вращение =истина; } enc_A_prev =enc_A; // Сохранение значения A для следующего раза} // функция swEncoder ():ISR вызывается при нажатии кнопки кодировщикаvoid swEncoder () {delay (1); если (digitalRead (enc_Switch)! =LOW) return; // если переключатель нажат delay (1); // устранение неполадок if (digitalRead (enc_Switch)! =LOW) return; // если переключатель все еще нажат, режим ++; mode =mode% 3; // режим увеличения digitalWrite (mode_Pin,! (mode ==1)); // регулировка времени светодиода digitalWrite (min_Pin,! (mode ==2)); // регулировка минут LED updateFlag =true;} // ************************************* ****************************************** //// ПРОЦЕДУРЫ РАБОТЫ // *********************************************** ********************************* //// function newDelayvoid newDelay (int dly) {for (int z =1; z  =25) adj_hrs =1; } else {// уменьшаем if (adj_hrs ==0) adj_hrs =24; если (- adj_hrs <=0) adj_hrs =24; } RTC.adjust (DateTime (now.year (), now.month (), now.day (), adj_hrs, now.minute (), now.second ())); } if (mode ==2) {// настраиваем минуты int adj_mins =now.minute (); если (директория) {если (++ adj_mins> =60) adj_mins =0; } иначе {если (- adj_mins <0) adj_mins =59; } RTC.adjust (DateTime (now.year (), now.month (), now.day (), now.hour (), adj_mins, now.second ())); }} // функция rotChar (char):для символа char меняет биты на 90 градусов. (сверху - снизу ==> слева - справа) // и сохраняет результаты в rc [0] - rc [7] .byte rotChar (char inLetter) {int ind =int (inLetter) - 0x20; for (int col =0; col <8; col ++) {байтовая маска =0x01 <<(7-col); for (int row =0; row <8; row ++) {bitWrite (rc [col], 7-row, (alphanum [ind] [row] &mask)); }}} // функция show_time_and_date:распечатать строку времени и байтовvoid show_time_and_date (DateTime datetime) {if (doSerial) {int minutes =datetime.minute (); int часы =datetime.hour (); если (часы ==0) часы =24; интервал секунд =datetime.second (); char delim ='/'; char dend =''; Строка te ="Текущая дата / время:"; te =te + datetime.year () + delim + datetime.month () + delim + datetime.day () + dend; Serial.print (te); если (часы <10) Serial.print (0); Serial.print (часы, DEC); Serial.print (":"); если (минут <10) Serial.print (0); Serial.print (минуты, DEC); Serial.print (":"); если (секунд <10) Serial.print (0); Serial.print (секунды, DEC); Serial.println (""); }} String createMessage (DateTime datetime) {String new_mess =""; int hr =datetime.hour ()% 24; если (ч ==0) ч =24; интервал mn =datetime.minute (); if (mode ==0) {// Нормальный режим if (hour24) {new_mess + =hr; } еще {new_mess + =(hr> 12)? час - 12 часов; } new_mess + =':'; если (mn <10) new_mess + ='0'; new_mess + =мин; если (! hour24) new_mess + =(hr> 12)? «~»:«^»; } if (mode ==1) {// Настройка часов new_mess + =hr; } if (mode ==2) {// Регулировка минут if (mn <10) new_mess + ='0'; new_mess + =мин; } return new_mess;} // функция initDisplayString ():создает массив строки сообщения с пробелами между символами и в конце initDisplayString (String message) {int x =0; для (int y =0; y > 1); // помещаем данные digitalWrite (load, HIGH);} // функция putByte ():загружает данные в матрицу, MSB в LSB void putByte (byte data) {byte i =8; байтовая маска; while (i> 0) {// маска от MSB к LSB =0x01 <<(i - 1); // создать битовую маску digitalWrite (clock, LOW); // поставить галочку if (data &mask) {// выбрать бит digitalWrite (dataIn, HIGH); // отправить 1} else {digitalWrite (dataIn, LOW); // отправляем 0} digitalWrite (clock, HIGH); // tock --i; // переход к меньшему разряду}} 

Схема


Производственный процесс

  1. Часы видения Arduino pov
  2. Самодельные простейшие часы Numitron IV9 с Arduino
  3. Основные часы
  4. Игра Arduino Nano Tetris на самодельной матрице 16x8
  5. MotionSense
  6. Светодиодная матрица + датчик движения дверной дисплей [Arduino Holiday]
  7. Четвероногий Arduino
  8. Управление яркостью светодиода с помощью Bolt и Arduino
  9. Датчик Интернета вещей с Arduino, Yaler и IFTTT
  10. Отталкивающая электромагнитная левитация Arduino