Часы на 30 светодиодах из CraftDuino!


Время на этих необычных часах высвечивается всего 30-ю светодиодами. Есть узнаваемый часовой круг и после предварительной тренировки можно понять сколько времени :))
Сейчас на часах 5 часов 46 минут.
Круг показывает часы, верхний экран — десятки минут, а нижний — минуты.

Часы используют внутренний таймер ардуино.
Тестирование показало точность не хуже ±1мин в трое суток.
Главная особенность этих часов в том, что как понятно — у ардуино просто не хватит портов для управления 30-ю светодиодами .
Поэтому, автор использовал оригинальную технику под названием Charlieplexing

В данном случае, для подключения 30 светодиодов потребуется (X=N*(N-1)) — всего 6 портов!
Есть и минус этой техники — отображние будет динамическим, т.е. диод будет светиться только маленький квант времени. Но из-за инертности восприятия глаза, наблюдателю будет казаться, что диод светиться постоянно.

Технология Charlieplexing
Если подать «1» Pin 1 и «0» на Pin 2, будет гореть светодиод Led 1. Светодиод Led 2 в этом случае светиться не будет. Если поменять полярность, то будет гореть Led 2.
Cхема ниже показывает, как экономятся порты — с помощью трех портов можно управлять шестью светодиодами:

Для отсоединения порта от схемы используется третье состояние порта — он включается «на вход».
Для arduino есть специальная библиотека для реализации принципа работы charlielexing.

Для изготовления автор использовал ProtoShield

Разводка платы:

Вид на светодиоды:

Монтаж

Прототип

Файлы проекта

скетч:

#include <Charlieplex.h>

unsigned long lastTick = 0, frameTick = 0,  setTick = 0, cur_millis;// 
int hour=0, minute=0, second=0; //start the time on 00:00:00
int munit, ihour, idecmin, iunitmin;
int frameNum = 0;
boolean ch =  true, sets = false; // 

#define NUMBER_OF_PINS 6
//define pins in the order you want to adress them
byte pins[] = {7,8,9,10,11,12};

#define PIN_SET_HOURS 5 // button for set hours
#define PIN_SET_MINS 6 // button for set minutes

//initialize object for the Charlieplexing
Charlieplex charlieplex = Charlieplex(pins,NUMBER_OF_PINS);

// pins in pairs for the hours 
charliePin leds_hours[12] = { 
  {4, 5}, {4, 3}, {5, 3}, {0, 4}, {1, 4}, {2, 4}, {3, 4}, {5, 4}, {0, 5}, {1, 5} , {2, 5}, {3, 5}
};

// pins in pairs for the decades of minutes
charliePin leds_decmin[5] = {
  {2, 3}, {1, 3}, {0, 3}, {5, 2}, {4, 2}
};

// pins in pairs for the minutes
charliePin leds_min[9] = {
  {3, 2}, {1, 2}, {0, 2}, {5, 1}, {4, 1}, {3, 1}, {2, 1}, {0, 1}, {5,0} 
};

// pins in pairs for the alarms
charliePin leds_alarm[4] = {
  {1, 0}, {2, 0}, {3, 0}, {4, 0} 
};


void setup(){  
  ch = true;
  lastTick = 0;
  setup_sets;
}

void loop(){
  
  cur_millis  = millis(); // current time count
  
  if (cur_millis - lastTick >= 1000) {
    lastTick = cur_millis;
    second++;
  }

  // move forward one minute every 60 seconds
  if (second >= 60) {
    minute++;
    second = 0; // reset seconds to zero
    ch = true;  // flag of change in status of leds
  }
  
  // move forward one hour every 60 minutes
  if (minute >=60) {
    hour++;
    minute = 0; // reset minutes to zero
  }
  
  if (hour >=12) {
    hour=0;
    minute = 0; // reset minutes to zero
  }
   
  if (ch) { // flag of change in status of leds
    ihour = hour;
    munit = minute%10;
    iunitmin = munit-1;
    idecmin = (minute - munit) / 10 - 1;
    ch = false;
  }

  if (cur_millis - frameTick >= 1) { // shift of frame
    frameTick = cur_millis;
    frameNum++;
    if (frameNum > 2) {
      frameNum = 0;
    }
    charlieplex.clear(); // clear all
    
    switch (frameNum) {
      case 0: // show 0 frame
        showpin(leds_hours[ihour]); 
        break;
      case 1: // show 1 frame
        if (idecmin >=0) {
          showpin(leds_decmin[idecmin]);
        }
        break;
      case 2: // show 2 frame
        if (iunitmin >=0 ) {
          showpin(leds_min[iunitmin]);
        }
        break;
    }
  }
   
  check_sets();
  
}

void showpin(charliePin pin) {
  charlieplex.charlieWrite(pin, HIGH); 
}

void setup_sets(void) {
  pinMode(PIN_SET_HOURS, INPUT);     
  pinMode(PIN_SET_MINS, INPUT);     
}

void check_sets(void) { // check status of the buttons
  if (sets) { // if in status of set then delay
    if (cur_millis - setTick >= 300) {
       sets = false;
       setTick = 0;
    } 
  } else {
    if (digitalRead(PIN_SET_HOURS) == HIGH) {
      hour++; sets = true; ch = true; setTick = cur_millis;
    }
    if (digitalRead(PIN_SET_MINS) == HIGH) {
      minute++; sets = true; ch = true; setTick = cur_millis;
    }
  }  
}

Автор: alexchin
оригинал


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение