Проекционные часы. ( с пультом ду)

Тема в разделе "Глядите, что я сделал", создана пользователем olegoriy, 30 апр 2015.

  1. olegoriy

    olegoriy Гик

    Всем привет. Хочу представить вам мой проект Проекционные часы.
    Идея пришла достаточно давно до знакомства с Arduino. Когда то в детстве я увидел огромные часы из обычных 100 ваттных лампочек, которые были собраны в четыре восьмерки и о чудо показывали время! То что обычные лампочки такое могут, меня в то время очень поразило и хотелось повторить такое чудо.
    Служа в армии я пытался сделать что то подобное на реле, но успехов особых не достиг.
    И вот спустя какое-то количество лет, увидев эксперимент с семисегментным индикатором, мне захотелось воплотить в жизнь детскую мечту.
    Конечно не о каких 100 ваттных лампочках не могло идти и речи. Но и не хотелось громоздить огромную панель из светодиодов. По этому было решено сделать не большие матрицы из ярких светодиодов и применить линзы для проекции.
    Ну хватит пред историй. Сразу видео как все работает, а потом если кому интересно, фото как я это все делал.


    Вот еще несколько фото примеров работы днем при солнечном свете и в темноте.
    [​IMG]
    [​IMG]

    на последней фото чуть смазано. Фотик отказывался фокусироваться на цифры вблизи.

    Приступая к созданию часов я наивно предполагал что это проект на три - четыре дня. На самом деле все затянулось почти на месяц из-за того что столкнулся с различными сложностями некоторые из которых только раззадоривали, а некоторые бесили на столько что хотелось все бросить.
    Были приобретены макетные платы, четыре сдвиговых регистра, 120 сопротивлений 220 Ом. Светодиодов, как я уже писал у меня великое множество(остались после какой-то шабашки).
    [​IMG]
    С распайкой регистров проблем не возникло. Может получилось чуть не аккуратно но я утешал себя тем что все будет в коробке и не кто этого не увидит :)
    [​IMG]
    С матрицами получилось все сложнее. Сначала был спаян первый вариант:
    [​IMG]
    Но плата стала занимать много места и все было переделано.
    [​IMG]
    Далее все было собрано и прикручено на орг стекло. Тут было много интересного. С начала было поломано несколько стекол при сверлении отверстий, затем было решено перенести плату с регистрами на другую сторону для уменьшения длины, потом оказалось что платы с светодиодами должны быть под углом и в конце оказалось что длины проводов не хватает и их нужно дорастить.
    Ну в целом все получилось.
    [​IMG]
    После долгих и безрезультатных хождений по супермаркетам и хозтоварам в поисках подходящего корпуса (в порыве безумия я даже поглядывал на xbox 360 думая о том что если вытащить все запчасти то коробочка мне отлично подойдет) было решено сделать корпус самому из оргстекла.
    За оргстекло отдельное спасибо коллеги Роману.(оказалось что оргстекло большая редкость и купить его бесполезно).
    [​IMG]

    Нужно было решить чем питать всю эту конструкцию. Если arduino и регистры не очень прихотливы по питанию то светодиодам и аккумулятору для работы в буферном режиме требовалось уделить внимание.
    На блок питания тратиться не хотелось. Благо на работе целые стеллажи нужного и не очень барахла. Сделал блок питания сам, на основе какого-то интегрального стабилизатора(к сожалению названия не помню) который грелся как собака и пришлось ставить радиатор и охлаждение.[​IMG]
    ну и собственно все было собрано в корпус и закреплено

    [​IMG]
    Очень переживал за пожаробезопасность , все-таки устройство будет всегда включено в сеть даже когда не кого не будет дома. По этому поставил предохранители где только можно, перекрестил,
    и повесил на стену.
    [​IMG]
    ну вот и все.

    А да конечно код.
    В программировании я делаю еще только первые шаги так что прошу сильно не ругать а посмотреть как мой кот играет в танки.
    Код (Text):
    #define LED_PIN A1                                              // Светодиод секунд.
    #define latch_Pin  9
    #define CLOCK_PIN  13
    #define data_Pin  11
    #include <IRremote.h>
    int RECV_PIN = 2;
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    void dump(decode_results *results) {
    int count = results->rawlen;
    }
    int x = 0;                                                      // Вторая цифра минут.
    int z = 0;                                                      // Первая цифра часов.
    int a = 0;                                                      // Вторая цифра часов.
    int p = 1;                                                      // Переменная режима работы.
    int i = 1;                                                      // Переменная точек секунд.
    byte segments[11] = {
      0b01110111, 0b00100100, 0b01011110, 0b01101110, 0b00101101,  // Масив цифр.
      0b01101011, 0b01111011, 0b00100110, 0b01111111, 0b01101111,
      0b00000000
    };
    void setup() {
      pinMode(latch_Pin, OUTPUT);
      pinMode(CLOCK_PIN, OUTPUT);
      pinMode(data_Pin, OUTPUT);
      pinMode(LED_PIN, OUTPUT);
      irrecv.enableIRIn();
    }
    void loop() {
        for (int y = 0; y < 10; y++) {                            // Цикл первой цифры минут.
        for (int b = 0; b < 60; b++) {                            // Цикл секунд.
        if (p == 1){                                              // Режим работы.
        digitalWrite(latch_Pin, LOW);                              // Открываем регистр.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[y]);      // Загружаем байты первой цифры минут.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[x]);      // Загружаем байты второй цифры минут.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[a]);      // Загружаем байты второй цифры часов.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[z]);      // Загружаем байты первой цифры часов.
        digitalWrite(latch_Pin, HIGH); }                          // Закрываем регистр.
        if (p == 0){                                              // Режим выключения светодиодов.
        digitalWrite(latch_Pin, LOW);                              // Открываем регистр.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[10]);    // Загружаем нули светодиоды выключены.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[10]);    // Загружаем нули светодиоды выключены.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[10]);    // Загружаем нули светодиоды выключены.
        shiftOut(data_Pin, CLOCK_PIN, LSBFIRST, segments[10]);    // Загружаем нули светодиоды выключены.
        digitalWrite(latch_Pin, HIGH); }                          // Закрываем регистр.
        if (irrecv.decode(&results)) {
        irrecv.resume(); }
        if (results.value == 33441975){                            // Кнопка включения табло.
        p = 1;
        results.value = 0;}
        if (results.value == 33446055){                            // Кнопка выключения табло.
        p = 0;
        results.value = 0;}
        if (results.value == 33456255){                            // Кнопка включения светодиода секунд.
        i = 1;
        results.value = 0;}
        if (results.value == 33439935){                            // Кнопка выключения светодиода секунд.
        i = 0;
        results.value = 0;}
        if (results.value == 33431775){                            // Здесь и далее кнопки установки времяни.                    
        a = a + 1;
        results.value = 0;}
        if (results.value == 33464415){                      
        a = a - 1;
        results.value = 0;}
        if (results.value == 33480735){                      
        z = z + 1;
        results.value = 0;}
        if (results.value == 33427695){                      
        z = z - 1;
        results.value = 0;}
        if (results.value == 33444015){                      
        x = x + 1;
        results.value = 0;}
        if (results.value == 33478695){                      
        x = x - 1;
        results.value = 0;}
        if (results.value == 33435855){                      
        y = y + 1;
        results.value = 0;}
        if (results.value == 33468495){                      
        y = y - 1;
        results.value = 0;}
        if (i == 1){digitalWrite(LED_PIN, HIGH);}                  // Включаем светодиод секунд.
        delay(500);                                                // Ждем пол секунды.
        if (i == 1){digitalWrite(LED_PIN, LOW);}                  // Выключаем светодиод секунд.
        delay(500);                                                // Ждем пол секунды.
        }                                                          // Закрываем цикл секунд.
        if(y == 9) x = x + 1;                                      // При достижении первой цифры минут 9 прибавляем к второй цифре минут 1.
        if(x > 5){x = 0; z = z + 1;}                              // При достижении второй цифры минут 5 прибавляем к первой цифре часов 1 а второй присваиваем 0.
        if(z > 9){z = 0; a = a + 1;}                              // При достижении первой цифры часов 9 прибавляем к второй цифре часов 1 а первой присваиваем 0.
        if(a > 1 && z == 4) {a = 0; z = 0;}                        // Если вторая цифра часа больше 1 а первая равна 4 (т.е 24 часа) сбрасываем все в 0.
        }
        }
     
    [​IMG]
    Всем спасибо за внимание!
     
    Последнее редактирование: 30 апр 2015
  2. mike_KH

    mike_KH Гик

    А почему вы все переменные именно через дефайн создавали??
     
  3. olegoriy

    olegoriy Гик

    Действительно изначально код выглядел по другому.
    int LED_PIN = A1;
    int latchPin = 9;
    int clockPin = 13;
    int dataPin = 11;
    int x = 0;
    int z = 0;
    int a = 0;
    Но с применением библиотеки для ИК приемника компилятор стал ругаться в этом месте. Возможно я что то напутал с точками с запятой , но когда переделал на #define все стало работать.
     
    Последнее редактирование: 3 май 2015
  4. olegoriy

    olegoriy Гик

    Здравствуйте.
    Да у меня в блоке 4 шестикратные линзы. Типа таких:
    [​IMG]
    Чем больше кратность линзы тем ближе ее нужно располагать к источнику света для правильного фокуса. Особо выбирать конечно было не из чего. Просто купил первые попавшиеся где было четыре одинаковых.
    На счет светосилы при использовании 7-сегментного индикатора, определенно сказать не могу. Но думаю что для не большого расстояния вполне хватит. В общем нужно пробовать.
    Если вам интересно могу попробовать и сфоткать результат, но могу это сделать не раньше чем послезавтра.
     
    Федоров Александр нравится это.
  5. Да. Очень интересно. Спасибо. А если у Вас будут вопросы (может быть) по сетям XBee, для Вас отвечу на любые вопросы в переписке http://fedoroffalexander.wix.com/smart#!Автоматический-полив-растений/c149j/1