Показано с 1 по 7 из 7

Тема: "Ленинградский односвод". Макет станции метро (WIP)

  1. #1

    "Ленинградский односвод". Макет станции метро (WIP)

    Ленинградские односводы глубокого заложения всегда привлекали своей открытостью и большим пространством. Ещё с малых лет, бывая в Северной столице, наряду с горизонтальными лифтами, в памяти отложились эти огромные залы Удельной (тогда она была конечной), Пионерской. Спускаясь по маршу к платформе, глубоко под землёй открывалось пространство, где можно было видеть всё и сразу: вот пассажиры стоят и ждут своего поезда; вот порталы туннелей и станционные пути...Тишина... И никуда не спрячешься от ветра прибывающих поездов... А книга Соловьёва «Сто историй о подземном городе» с изумительными иллюстрациями,вообще непонятно каким образом оказавшаяся в тверской детской библиотеке на улице Богданова, дала первые представления об устройстве метрополитена. И это именно был, тогда ещё, Ленинградский метрополитен.

    Одна из новых-старых открытых станций Питерской подземки такого типа - станция "Садовая". Она расположена в центре города, является частью большого пересадочного узла, названа по расположенному над ней топониму - одноимённой улице. Что с ней только не делали за короткое время существования. Подключали к разным линиям, обустраивали спуски в центре зала (к заранее заложенным переходам), меняли информационную систему навигации. В общем, эту станцию было решено взять за референс-основу для постройки макета в масштабе 1:120. Сама по себе станция достаточно интересна. Верхнее освещение в фермах, расположенных под зонтом, вензеля вдоль путевых стен, деревья новой навигации, лестницы переходов и скамья в центре зала... Над этим постарались архитекторы А.И. Прибульский, Г.П.Кашихин, В.В. Попов и А.В. Гончаров. Также - это единственная односводчатая станция в Петербурге, где вход и выход обустроены с обеих торцевых сторон платформы. С учётом современной возможности применения светодиодов и электроники для визуализации, есть желание, чтобы всё это выглядело достаточно эффектно.

    [spoiler=Спойлер]Конечно, не хочу превратить строительство в долгострой, но и торопиться особо не собираюсь. Сами понимаете, проводить различные работы, связанные с шумом, пылью в зимний период проблематично (у каждого свои возможности). Поэтому начну с малых форм. По мере завершения этапов постройки буду делать небольшие WIP-отчёты в этой теме.[/spoiler]

    На данный момент сделано не так много, но буду рад если эта информация кому-то поможет в своих начинаниях и проектах.

    * * *

    Светофор типа «метро» c литерой «Д». Его можно видеть рядом с одним из порталов. На макете будет гореть всегда красным. Сделан из полистирола и фольгированного текстолита. Внутри установлен SMD-светодиод красного свечения.
    Нажмите на изображение для увеличения. 

Название:	bild_svet.jpg 
Просмотров:	56 
Размер:	62.2 Кб 
ID:	29332 Нажмите на изображение для увеличения. 

Название:	bild_svet_1.jpg 
Просмотров:	55 
Размер:	31.4 Кб 
ID:	29333

    Заготовки для светильников в виде шара. Сама имитация плафона изготовлена из головки от булавок диаметром 3.8 мм. Внутрь примерен SMD-светодиод белого свечения. Питание планирую подать через провод в лаковой изоляции внутри стойки из иглы от одноразового шприца.
    Нажмите на изображение для увеличения. 

Название:	bild_plafon.jpg 
Просмотров:	53 
Размер:	86.0 Кб 
ID:	29334 Нажмите на изображение для увеличения. 

Название:	bild_plafon_1.jpg 
Просмотров:	54 
Размер:	44.2 Кб 
ID:	29335

    Визуализация интервальных таймеров 1 и 2 пути и часов реального времени. Помимо верхнего освещения, подсвеченных транспарантов новой навигации для пассажиров, щелевых фонарей контроля посадки (расположены в концах посадочных платформ) на макете станции достаточно интересно могут смотреться действующие интервальные таймеры и часы над порталами станционных туннелей. С учётом предложений DIY-электроники реализовать это оказалось не так сложно. Для отображения информации идеально подходят миниатюрные двухцветные (синие с жёлтой полосой) OLED-дисплеи с диагональю 0.96 дюйма и разрешением 128х64 пикселей. Контроль прохода поезда в туннель осуществляется ИФК-датчиками, сделанными из оптопар от старой компьютерной мышки. Часы реального времени поставляются в виде отдельного модуля. Ну и управлять всем этим будет микроконтроллер Atmel Atmega328.
    Нажмите на изображение для увеличения. 

Название:	bild_2.jpg 
Просмотров:	68 
Размер:	161.1 Кб 
ID:	29336 Нажмите на изображение для увеличения. 

Название:	bild_3-schema.jpg 
Просмотров:	53 
Размер:	96.4 Кб 
ID:	29337

    OLED-дисплеи SSD1306 с интерфейсом I²C. Доработка дисплея для смены адреса I²C без перемычек. Дисплеи подключаются к микроконтроллеру по шине I²C параллельно. Для работы двух дисплеев одновременно у каждого из них должен быть уникальный адрес. Обычно модули позволяют выбрать один из двух прошитых в них адресов (0x78 (0x3C) или 0x7A(0x3D)), путём перепайки резистора (перемычки) на самой плате. Но бывают модули и без такой возможности. Мне как раз такие и попались. И пришлось производить доработку одного из них, чтобы сменить адрес. Адрес выбирается путём замыкания 15-й ноги на землю (0x78), либо подачи на неё VCC (0x7А). По умолчанию 15-е выводы моих дисплеев были намертво соединены с землёй. На дисплее, у которого необходимо было сменить I²C-адрес, мне пришлось освободить 15-й вывод от земли, перерезав дорожку на плате под гибким шлейфом, осторожно его приподняв. И подать туда 3.3 вольта, соединив 15-й вывод тонким проводом в лаковой изоляции с выходом рядом расположенного стабилизатора 662K на 3.3В. Всё. Дисплеи имеют разные адреса, и их можно независимо использовать на шине I²C.
    Нажмите на изображение для увеличения. 

Название:	bild_4 change OLED adress from 0x3C to 0x3D .jpg 
Просмотров:	53 
Размер:	166.2 Кб 
ID:	29338

    Часы реального времени RTC на микросхеме DS1307. Доработка модуля Tiny RTC I²C modules. Чтобы на дисплеях можно было отображать текущее время, необходимы часы реального времени (RTC - real time clock). Такой модуль так же, как и OLED-дисплеи подключается параллельно на шину I²C и имеет адрес 0x68. Для автономной работы часов необходим дополнительный источник питания в виде батарейки или аккумулятора. Модуль Tiny RTC I²C modules DS1307 изначально рассчитан на использование аккумулятора LIR2032 и содержит у себя цепи его подзарядки. Так как такого аккумулятора у меня не было, решил установить туда обычную батарейку CR2032. При таком варианте цепи зарядки необходимо убрать. Для этого с платы удалён диод D1, резисторы R4 и R6. Вместо R6 установлена перемычка. ОК. Часы готовы.
    Нажмите на изображение для увеличения. 

Название:	bild_5 CR2032-bat-RTC-adaptation.jpg 
Просмотров:	44 
Размер:	140.1 Кб 
ID:	29340

    ИФК-датчики. Чтобы инициализировать отсчёт интервальных таймеров 1 и 2 пути необходим контроль прохода поездов в туннели. Для этого нужны соответствующие датчики. Магазины предлагают множество вариантов. Как правило все такие датчики построены на компараторе LM393 и изготавливаются по типовой схеме. При этом LM393 на самом деле содержит в себе два компаратора, а в предлагаемых модулях используется только один (то есть половина микросхемы). Для полноценного использования LM393 была изготовлена двухканальная схема датчиков. В качестве оптопар использованы ИФК-светодиоды и фототранзисторы от старой компьютерной мышки с шаром.
    Нажмите на изображение для увеличения. 

Название:	bild_6-LM393-PCB.jpg 
Просмотров:	35 
Размер:	78.9 Кб 
ID:	29341 Нажмите на изображение для увеличения. 

Название:	bild_7-LM393-PCB.jpg 
Просмотров:	35 
Размер:	95.7 Кб 
ID:	29342
    Нажмите на изображение для увеличения. 

Название:	bild_8-IR-pair.jpg 
Просмотров:	38 
Размер:	64.7 Кб 
ID:	29343 Нажмите на изображение для увеличения. 

Название:	bild_9-IR-pair-rail.jpg 
Просмотров:	42 
Размер:	88.1 Кб 
ID:	29344

    Микроконтроллер управления Atmega328. Управлением всеми процессами занимается микроконтроллер Atmega328. Самый удобный и простой вариант - использование готовой платформы Arduino nano. Чтобы подключить всю периферию, изготовлена кросс-плата. В неё подключаются сама плата arduino и модуль часов реального времени. Сделаны выводы для подключения двух OLED-дисплеев, предусмотрена возможность подключения четырёх датчиков.
    Нажмите на изображение для увеличения. 

Название:	bild_10-mainboard-PCB.jpg 
Просмотров:	45 
Размер:	50.2 Кб 
ID:	29345 Нажмите на изображение для увеличения. 

Название:	bild_11-mainboard-PCB.jpg 
Просмотров:	46 
Размер:	71.1 Кб 
ID:	29346

    Вариантов реализации скетчей достаточно много. Привожу (позже) два варианта с комментариями. Делают они одно и то же, но разными способами. В программах использованы типовые библиотеки для работы с применённой периферией. Для более точного соответствия прототипу был изменён шрифт в части отображения цифр. Так как жёлтая полоса у дисплеев расположена сверху, для вписывания в размер торцевых стен над порталами туннелей изображение программно повёрнуто на 180°.
    Нажмите на изображение для увеличения. 

Название:	bild_12-digit.jpg 
Просмотров:	71 
Размер:	89.2 Кб 
ID:	29347 Нажмите на изображение для увеличения. 

Название:	bild_13-probe.jpg 
Просмотров:	51 
Размер:	87.4 Кб 
ID:	29348

    Продолжение следует...





  2. #2
    оффтопик

  3. #3
    оффтопик

  4. #4
    Скетч для ардуино. Позже будут внесены правки для более точного позиционирования индикации в торцевых стенках (после того, как они будут изготовлены), с учётом того, что на одной из них индикаторы расположены не в ряд, а один над другим. Оба приведенных варианта скетчей рабочие. Профессиональные программисты - сильно не пинайте...

    Вариант 1. Здесь часы постоянно при выполнении основного цикла забирают время с RTC и также за каждый шаг происходит обновление дисплеев. Интервальные таймеры до первого срабатывания и при превышении значения 9:59 показывают только точку. Повторное срабатывание датчика возможно только через 10 секунд. В этом варианте могут наблюдаться расхождения значений часов RTC и таймеров из-за разных методов их вычисления.

    Код:
    //-------Макет станции Петербургского метрополитена "Садовая"--------------------------//-------Масштаб 1:120 (TT)------------------------------------------------------------
    //-------Скетч визуализации индикаторов времени и интервальных таймеров 1 и 2 пути-----
    
    
    #include <Wire.h>                 //Подключаем библиотеку для работы с интерфейсом I²C
    #include <Adafruit_SSD1306.h>     //Подключаем библиотеку для работы с OLED-дисплеями
    #include "RTClib.h"               //Подключаем библиотеку для работы с часами реального времени
    
    
    #define OLED_RESET LED_BUILTIN //Видимо для инициализации нужен ресет-пин, хотя в I²C-версии такого сигнала нет (только в SPI).
                                   //В референс-примере библиотеки Adafruit_SSD1306 тут был пин 4, но он нам самим пригодится. Поэтому поставим
                                   //тут онбоард-светодиод (13 пин)...
                                   
    Adafruit_SSD1306 Display1(OLED_RESET); //Дисплей -1
    Adafruit_SSD1306 Display2(OLED_RESET); //Дисплей -2
    
    
    RTC_DS1307 rtc; // часы реального времени
    
    
    //-------определяем необходимые переменные:--------------------------------------------
    
    
    bool timer1enable;       //Вкл-Выкл для таймера 1
    int minit1;              //минуты для таймера 1
    int sec1;                //секунды для таймера 1
    unsigned long timer_one; //вычисление миллис для таймера 1
    
    
    bool timer2enable;       //Вкл-Выкл для таймера 2
    int minit2;              //минуты для таймера 2
    int sec2;                //секунды для таймера 2
    unsigned long timer_two; //вычисление миллис для таймера 2
    
    
    String rtchour;    //строка для считывания часов из RTC
    String rtcmin;     //строка для считывания минут из RTC
    String rtcsec;     //строка для считывания секунд из RTC
    
    
    int clkhour;    //Время в INT для расчётов незначащего нуля Часов
    int clkmin;     //Время в INT для расчётов незначащего нуля Минут
    int clksec;     //Время в INT для расчётов незначащего нуля Секунд
    
    
    bool datchik1;  //флаг срабатывания датчика 1
    bool datchik2;  //флаг срабатывания датчика 2
    
    
    //-------Функция установки:---------------------------------------------------------------
    void setup() {
    
    
    pinMode(4, INPUT);    //Устанавливаем пин 4 на вход (не обязательно, по умолчанию он и так настроен на считывание)
    pinMode(5, INPUT);    //Устанавливаем пин 5 на вход (не обязательно, по умолчанию он и так настроен на считывание)
                          //На эти пины (4 и 5) будем принимать сигналы с ИФК-датчиков контроля ухода поезда в туннель              
    
    
    Display1.begin(SSD1306_SWITCHCAPVCC, 0x3C); //I²C адрес первого дисплея
    Display2.begin(SSD1306_SWITCHCAPVCC, 0x3D); //I²C адрес второго дисплея
    
    
    Display1.setRotation(2); //поворачиваем первый дисплей на 180°
    Display2.setRotation(2); //поворачиваем второй дисплей на 180°
    
    
    Display1.clearDisplay(); //очищаем первый дисплей
    Display2.clearDisplay(); //очищаем второй дисплей
    
    
    Display1.setTextColor(1); //установка "цвета" текста первого дисплея (светится на чёрном)
    Display2.setTextColor(1); //установка "цвета" текста второго дисплея
     
    Display1.setTextSize(1);  //установка размера шрифта первого дисплея
    Display2.setTextSize(1);  //установка размера шрифта второго дисплея
    
    
    Display1.setTextWrap(0);  //запрещаем пере-
    Display2.setTextWrap(0);  //нос слов
    
    
    Display1.ssd1306_command(SSD1306_SETCONTRAST);  // устанавливаем интенсивность свечения первого дисплея, используя установку контрастности
    Display1.ssd1306_command(5);                    //  0-255
    
    
    Display2.ssd1306_command(SSD1306_SETCONTRAST);  // устанавливаем интенсивность свечения второго дисплея, используя установку контрастности
    Display2.ssd1306_command(5);                    //  0-255
    
    
    //-------Инициализируем необходимые переменные:--------------------------------------------
    
    
    minit1=0;     //Сбрасываем значения
    sec1=0;       //времени таймера 1 в ноль
    
    
    timer_one=0;        //Начальный millis таймера 1 для сравнения (не обязательно, по умолчанию равно нулю)
    timer1enable=false; //До ухода первого поезда в туннель интервальный таймер 1 отключен
    
    
    minit2=0;     //Сбрасываем значения
    sec2=0;       //времени таймера 2 в ноль
    
    
    timer_two=0;        //Начальный millis таймера 2 для сравнения (не обязательно, по умолчанию равно нулю)
    timer2enable=false; //До ухода первого поезда в туннель интервальный таймер 2 отключен
    
    
    datchik1=false;     //Флаг состояния датчика 1 сброшен
    datchik2=false;     //Флаг состояния датчика 2 сброшен
    
    
    }
    //-------Конец функции установки-------------------------------------------------------------
    
    
    
    
    //-------Начало фунуции главного цикла-------------------------------------------------------
    void loop() {
      
    DateTime now = rtc.now(); //берём время с RTC
    rtchour=now.hour();
    rtcmin=now.minute();
    rtcsec=now.second();
    
    
    clkhour=rtchour.toInt();  //конвертируем время в int для расчёта незначащего нуля
    clkmin=rtcmin.toInt();
    clksec=rtcsec.toInt();
    
    
    Display1.clearDisplay();             //очищаем первый дисплей
    
    
    if (timer1enable==true)              //если таймер 1 включен, то показываем его цифры...(если нет - то ничего не показываем)
        {
        Display1.setCursor(0,57);            //устанавливаем курсор в позицию отображения минут таймера 1
        Display1.print(minit1);              //отображаем минуты таймера 1
        Display1.setCursor(8,57);            //устанавливаем курсор в позицию отображения секунд таймера 1
        if (sec1 < 10) Display1.print("0");  //если нужно, то отображаем незначащий ноль секунд таймера 1
        Display1.print(sec1);                //отображаем секунды таймера 1
        };
    Display1.drawPixel(6,63,1);          //децимальная точка таймера 1 горит всегда
    
    
    Display1.setCursor(38,57);                //Теперь часы. Устанавливаем курсор в позицию отображения часов часов реального времени
    if (clkhour < 10) Display1.print("0");    //Если нужно, то отображаем незначащий ноль в часах
    Display1.print(clkhour);                  //Отображаем значение часов часов реального времени
    Display1.drawPixel(50,63,1);              //Рисуем точку
    Display1.setCursor(52,57);                //Устанавливаем курсор в позицию отображения минут часов реального времени
    if (clkmin < 10) Display1.print("0");     //Если нужно, то отображаем незначащий ноль в минутах
    Display1.print(clkmin);                   //Отображаем значение минут часов реального времени
    Display1.drawPixel(64,63,1);              //Рисуем точку
    Display1.setCursor(66,57);                //Устанавливаем курсор в позицию отображения секунд часов реального времени
    if (clksec < 10) Display1.print("0");     //Если нужно, то отображаем незначащий ноль в секундах
    Display1.print(clksec);                   //Отображаем значение секунд часов реального времени
    Display1.display();                       //Ву-а-ля.....
    
    
    Display2.clearDisplay();             // очищаем второй дисплей... И то же самое, что для первого повторяем для дисплея 2
    
    
    if (timer2enable==true)              //если таймер 2 включен, то...
        {
        Display2.setCursor(0,57);            
        Display2.print(minit2);              
        Display2.setCursor(8,57);            
        if (sec2 < 10) Display2.print("0");
        Display2.print(sec2);
        };
    
    
    Display2.drawPixel(6,63,1);          
    
    
    Display2.setCursor(38,57);
    if (clkhour < 10) Display2.print("0");
    Display2.print(clkhour);
    Display2.drawPixel(50,63,1);
    Display2.setCursor(52,57);
    if (clkmin < 10) Display2.print("0");
    Display2.print(clkmin);
    Display2.drawPixel(64,63,1);
    Display2.setCursor(66,57);
    if (clksec < 10) Display2.print("0");
    Display2.print(clksec);
    
    
    Display2.display();
    
    
    //-------Таймер1----(можно определить в отдельную функцию, но не будем)-------------
    if (millis()-timer_one>1000 && timer1enable==true)
    {
      timer_one=millis();
      sec1=sec1+1;
                if (sec1>59)
                              {
                                sec1=0;
                                minit1=minit1+1;
    
    
                                  if (minit1>9)
                                    {
                                      timer1enable=false; //При превышении 9:59 таймер 1 отключается
                                      minit1=0;           
                                    }
                                
                              }
     } 
    //-------Таймер2---------------------------------------------------------------------
    if (millis()-timer_two>1000 && timer2enable==true)
    {
      timer_two=millis();
      sec2=sec2+1;
                 if (sec2>59)
                              {
                                sec2=0;
                                minit2=minit2+1;
    
    
                                  if (minit2>9)
                                    {
                                      timer2enable=false; //При превышении 9:59 таймер 2 отключается
                                      minit2=0;           
                                    }
                                
                              }
    } 
    
    
    //-------Управление датчиками (можно определить в отдельную функцию, но не будем)----
    
    
    if (digitalRead(4)==HIGH && datchik1==false)      //Если от ИФК-датчика 1 пришёл сигнал и его флаг сброшен, то...
                                {
                                  datchik1=true;      //Устанавливаем флаг того, что датчик 1 сработал
                                  timer1enable=true;  //Включаем таймер 1
                                  minit1=0;           //Начинаем отсчёт с ноля минут
                                  sec1=0;             //и ноля секунд
                                }
    
    
    if (digitalRead(5)==HIGH && datchik2==false)      //Если от ИФК-датчика 2 пришёл сигнал и его флаг сброшен, то...
                                {
                                  datchik2=true;      //Устанавливаем флаг того, что датчик 2 сработал
                                  timer2enable=true;  //Включаем таймер 2 
                                  minit2=0;           //Начинаем отсчёт с ноля минут
                                  sec2=0;             //и ноля секунд                
                                }
    
    
    //запрещаем считывать данные с ИФК-датчиков в течение 10 секунд после срабатывания (убираем повторные срабатывания):
    
    
    if (sec1>10)          
        {
        datchik1=false;   //Сбрасывем флаг срабатывания датчика 1 (разрешаем считывание с него данных, если прошло 10 сек с момента срабатывания)
        }
    if (sec2>10)          
        {
        datchik2=false;   //Сбрасывем флаг срабатывания датчика 2 (разрешаем считывание с него данных, если прошло 10 сек с момента срабатывания)
        }
                                
    
    
    
    
    
    
    }
    Вариант 2. Здесь часы однократно при включении синхронизируются с RTC и дальше все вычисления времени производятся за счёт внутреннего таймера микроконтроллера. Обновление дисплеев происходит только при изменении значений секунд таймеров или часов. Интервальные таймеры до первого срабатывания и при превышении значения 9:59 показывают только точку. Повторное срабатывание датчика возможно только через 10 секунд.

    Код:
    //-------Макет станции Петербургского метрополитена "Садовая"--------------------------//-------Масштаб 1:120 (TT)------------------------------------------------------------
    //-------Скетч визуализации индикаторов времени и интервальных таймеров 1 и 2 пути-----
    
    
    #include <Wire.h>                 //Подключаем библиотеку для работы с интерфейсом I²C
    #include <Adafruit_SSD1306.h>     //Подключаем библиотеку для работы с OLED-дисплеями
    #include "RTClib.h"               //Подключаем библиотеку для работы с часами реального времени
    
    
    #define OLED_RESET LED_BUILTIN //Видимо для инициализации нужен ресет-пин, хотя в I²C-версии такого сигнала нет (только в SPI).
                                   //В референс-примере библиотеки Adafruit_SSD1306 тут был пин 4, но он нам самим пригодится. Поэтому поставим
                                   //тут онбоард-светодиод (13 пин)...
                                   
    Adafruit_SSD1306 Display1(OLED_RESET); //Дисплей -1
    Adafruit_SSD1306 Display2(OLED_RESET); //Дисплей -2
    
    
    RTC_DS1307 rtc; // часы реального времени
    
    
    //-------определяем необходимые переменные:--------------------------------------------
    
    
    bool timer1enable;       //Вкл-Выкл для таймера 1
    int minit1;              //минуты для таймера 1
    int sec1;                //секунды для таймера 1
    unsigned long timer_one; //вычисление миллис для таймера 1
    
    
    bool timer2enable;       //Вкл-Выкл для таймера 2
    int minit2;              //минуты для таймера 2
    int sec2;                //секунды для таймера 2
    unsigned long timer_two; //вычисление миллис для таймера 2
    
    
    String rtchour;    //строка для считывания часов из RTC
    String rtcmin;     //строка для считывания минут из RTC
    String rtcsec;     //строка для считывания секунд из RTC
    
    
    int clkhour;    //Время в INT для расчётов незначащего нуля Часов
    int clkmin;     //Время в INT для расчётов незначащего нуля Минут
    int clksec;     //Время в INT для расчётов незначащего нуля Секунд
    
    
    bool datchik1;  //флаг срабатывания датчика 1
    bool datchik2;  //флаг срабатывания датчика 2
    
    
    unsigned long clock_millis; //вычисление миллис для часов
    
    
    int oldclocksec;      //переменные необходимы для вычисления ежесекундной отрисовки значений в теле основного цикла
    int oldtimer1sec;
    int oldtimer2sec;
    
    
    //-------Функция установки:---------------------------------------------------------------
    void setup() {
    
    
    pinMode(4, INPUT);    //Устанавливаем пин 4 на вход (не обязательно, по умолчанию он и так настроен на считывание)
    pinMode(5, INPUT);    //Устанавливаем пин 5 на вход (не обязательно, по умолчанию он и так настроен на считывание)
                          //На эти пины (4 и 5) будем принимать сигналы с ИФК-датчиков контроля ухода поезда в туннель              
    
    
    Display1.begin(SSD1306_SWITCHCAPVCC, 0x3C); //I²C адрес первого дисплея
    Display2.begin(SSD1306_SWITCHCAPVCC, 0x3D); //I²C адрес второго дисплея
    
    
    Display1.setRotation(2); //поворачиваем первый дисплей на 180°
    Display2.setRotation(2); //поворачиваем второй дисплей на 180°
    
    
    Display1.clearDisplay(); //очищаем первый дисплей
    Display2.clearDisplay(); //очищаем второй дисплей
    
    
    Display1.setTextColor(1); //установка "цвета" текста первого дисплея (светится на чёрном)
    Display2.setTextColor(1); //установка "цвета" текста второго дисплея
     
    Display1.setTextSize(1);  //установка размера шрифта первого дисплея
    Display2.setTextSize(1);  //установка размера шрифта второго дисплея
    
    
    Display1.setTextWrap(0);  //запрещаем пере-
    Display2.setTextWrap(0);  //нос слов
    
    
    Display1.ssd1306_command(SSD1306_SETCONTRAST);  // устанавливаем интенсивность свечения первого дисплея, используя установку контрастности
    Display1.ssd1306_command(5);                    //  0-255
    
    
    Display2.ssd1306_command(SSD1306_SETCONTRAST);  // устанавливаем интенсивность свечения второго дисплея, используя установку контрастности
    Display2.ssd1306_command(5);                    //  0-255
    
    
    //-------Инициализируем необходимые переменные:--------------------------------------------
    
    
    minit1=0;     //Сбрасываем значения
    sec1=0;       //времени таймера 1 в ноль
    
    
    timer_one=0;        //Начальный millis таймера 1 для сравнения (не обязательно, по умолчанию равно нулю)
    timer1enable=false; //До ухода первого поезда в туннель интервальный таймер 1 отключен
    
    
    minit2=0;     //Сбрасываем значения
    sec2=0;       //времени таймера 2 в ноль
    
    
    timer_two=0;        //Начальный millis таймера 2 для сравнения (не обязательно, по умолчанию равно нулю)
    timer2enable=false; //До ухода первого поезда в туннель интервальный таймер 2 отключен
    
    
    datchik1=false;     //Флаг состояния датчика 1 сброшен
    datchik2=false;     //Флаг состояния датчика 2 сброшен
    
    
    //-------Синхронизируем время c RTC--------------------------------------------------------
    
    
    DateTime now = rtc.now(); //берём время с RTC
    rtchour=now.hour();
    rtcmin=now.minute();
    rtcsec=now.second();
    
    
    clkhour=rtchour.toInt();  //конвертируем время в int для расчёта незначащего нуля
    clkmin=rtcmin.toInt();
    clksec=rtcsec.toInt();
    
    
    
    
    
    
    }
    //-------Конец функции установки-------------------------------------------------------------
    
    
    //-------Определяем функцию прорисовки первого дисплея---------------------------------------
    void DrawDisplay1()
    {
    Display1.clearDisplay();             //очищаем первый дисплей
    
    
    if (timer1enable==true)              //если таймер 1 включен, то показываем его цифры...(если нет - то ничего не показываем)
        {
        Display1.setCursor(0,57);            //устанавливаем курсор в позицию отображения минут таймера 1
        Display1.print(minit1);              //отображаем минуты таймера 1
        Display1.setCursor(8,57);            //устанавливаем курсор в позицию отображения секунд таймера 1
        if (sec1 < 10) Display1.print("0");  //если нужно, то отображаем незначащий ноль секунд таймера 1
        Display1.print(sec1);                //отображаем секунды таймера 1
        };
    Display1.drawPixel(6,63,1);          //децимальная точка таймера 1 горит всегда
    
    
    Display1.setCursor(38,57);                //Теперь часы. Устанавливаем курсор в позицию отображения часов часов реального времени
    if (clkhour < 10) Display1.print("0");    //Если нужно, то отображаем незначащий ноль в часах
    Display1.print(clkhour);                  //Отображаем значение часов часов реального времени
    Display1.drawPixel(50,63,1);              //Рисуем точку
    Display1.setCursor(52,57);                //Устанавливаем курсор в позицию отображения минут часов реального времени
    if (clkmin < 10) Display1.print("0");     //Если нужно, то отображаем незначащий ноль в минутах
    Display1.print(clkmin);                   //Отображаем значение минут часов реального времени
    Display1.drawPixel(64,63,1);              //Рисуем точку
    Display1.setCursor(66,57);                //Устанавливаем курсор в позицию отображения секунд часов реального времени
    if (clksec < 10) Display1.print("0");     //Если нужно, то отображаем незначащий ноль в секундах
    Display1.print(clksec);                   //Отображаем значение секунд часов реального времени
    Display1.display();                       //Ву-а-ля.....  
    }
    
    
    //-------Определяем функцию прорисовки второго дисплея---------------------------------------
    void DrawDisplay2()
    {
    Display2.clearDisplay();             // очищаем второй дисплей... И то же самое, что для первого повторяем для дисплея 2
    
    
    if (timer2enable==true)              //если таймер 2 включен, то...
        {
        Display2.setCursor(0,57);            
        Display2.print(minit2);              
        Display2.setCursor(8,57);            
        if (sec2 < 10) Display2.print("0");
        Display2.print(sec2);
        };
    
    
    Display2.drawPixel(6,63,1);          
    
    
    Display2.setCursor(38,57);
    if (clkhour < 10) Display2.print("0");
    Display2.print(clkhour);
    Display2.drawPixel(50,63,1);
    Display2.setCursor(52,57);
    if (clkmin < 10) Display2.print("0");
    Display2.print(clkmin);
    Display2.drawPixel(64,63,1);
    Display2.setCursor(66,57);
    if (clksec < 10) Display2.print("0");
    Display2.print(clksec);
    
    
    Display2.display();
    }
    
    
    //-------Начало фунуции главного цикла-------------------------------------------------------
    void loop() {
    
    
                  //-------Часы-------
    if (millis()-clock_millis>1000)
    {
      clock_millis=millis();
      clksec=clksec+1;
              if (clksec>59)
                            {
                              clksec=0;
                              clkmin=clkmin+1;
                                  if (clkmin>59)
                                                  {
                                                  clkmin=0;
                                                  clkhour=clkhour+1;
                                                             if (clkhour>23)
                                                                            {
                                                                              clkhour=0;
                                                                            }
                                                    
                                                  }
                            }
    }
                  //-------Таймер1----
    if (millis()-timer_one>1000 && timer1enable==true)
    {
      timer_one=millis();
      sec1=sec1+1;
                if (sec1>59)
                              {
                                sec1=0;
                                minit1=minit1+1;
    
    
                                  if (minit1>9)
                                    {
                                      timer1enable=false; //При превышении 9:59 таймер 1 отключается
                                      minit1=0;           
                                    }
                                
                              }
     } 
                  //-------Таймер2-----
    if (millis()-timer_two>1000 && timer2enable==true)
    {
      timer_two=millis();
      sec2=sec2+1;
                 if (sec2>59)
                              {
                                sec2=0;
                                minit2=minit2+1;
    
    
                                  if (minit2>9)
                                    {
                                      timer2enable=false; //При превышении 9:59 таймер 2 отключается
                                      minit2=0;           
                                    }
                                
                              }
    }
    
    
    //-------Управление датчиками (можно определить в отдельную функцию, но не будем)----
    if (digitalRead(4)==HIGH && datchik1==false)      //Если от ИФК-датчика 1 пришёл сигнал и его флаг сброшен, то...
                                {
                                  datchik1=true;      //Устанавливаем флаг того, что датчик 1 сработал
                                  timer1enable=true;  //Включаем таймер 1
                                  minit1=0;           //Начинаем отсчёт с ноля минут
                                  sec1=0;             //и ноля секунд
                                }
    
    
    if (digitalRead(5)==HIGH && datchik2==false)      //Если от ИФК-датчика 2 пришёл сигнал и его флаг сброшен, то...
                                {
                                  datchik2=true;      //Устанавливаем флаг того, что датчик 2 сработал
                                  timer2enable=true;  //Включаем таймер 2 
                                  minit2=0;           //Начинаем отсчёт с ноля минут
                                  sec2=0;             //и ноля секунд                
                                }
    
    
    //запрещаем считывать данные с ИФК-датчиков в течение 10 секунд после срабатывания (убираем повторные срабатывания):
    if (sec1>10)          
        {
        datchik1=false;   //Сбрасывем флаг срабатывания датчика 1 (разрешаем считывание с него данных, если прошло 10 сек с момента срабатывания)
        }
    if (sec2>10)          
        {
        datchik2=false;   //Сбрасывем флаг срабатывания датчика 2 (разрешаем считывание с него данных, если прошло 10 сек с момента срабатывания)
        }
    
    
    //-------отображаем всё на дисплеях в момент изменения секунд RTC, секунд таймера1 или секунд таймера2 (чтобы не дёргать дисплеи каждый проход цикла) ---------
    
    
    if (oldclocksec!=clksec || oldtimer1sec!=sec1 || oldtimer2sec!=sec2)
                {
                oldclocksec=clksec;
                oldtimer1sec=sec1;
                oldtimer2sec=sec2;
                DrawDisplay1();
                DrawDisplay2();
                }
                                
    
    
    
    
    
    
    }
    //-------конец основного цикла--------

  5. #5
    Мелкими шажками двигаюсь дальше.

    Светильники с плафоном в виде шара. Как писал выше, "плафон" изготовлен из головки от швейной булавки, а в качестве стойки применена игла от одноразового шприца. Внутри иглы проводники для питания установленного в "плафон" smd-светодиода. Пластиковый шарик предварительно высверливался сверлом подходящего диаметра. Основание "плафона" - кольцо из ПВХ-изоляции. Столб окрашен акрилом от "Звезды", "плафон" изначально уже был покрыт перламутром. Конечно, немного грубовато получились, но работа доставила удовольствие.
    Нажмите на изображение для увеличения. 

Название:	bild_2-1_bolllamp.jpg 
Просмотров:	74 
Размер:	71.9 Кб 
ID:	29825 Нажмите на изображение для увеличения. 

Название:	bild_2-2_bolllamplight.jpg 
Просмотров:	86 
Размер:	80.6 Кб 
ID:	29826

    Из листового полистирола нарезан комплект заготовок для сборки пассажирской платформы.
    Нажмите на изображение для увеличения. 

Название:	bild_2-3_platform.jpg 
Просмотров:	75 
Размер:	95.8 Кб 
ID:	29827

    Продолжение следует...

  6. #6
    Наконец-то выдалась минутка для "деревянных" работ. Да и погода располагала к работам на свежем воздухе.

    Подмакетник. Основание макета - деревянная рама из брусков 45х20. Собрана на ПВА и штифтована саморезами. Электролобзик оказал неоценимую помощь в работе. Чтобы избежать неприятностей, отверстия под саморезы предварительно высверливались сверлом 3мм и зенковались зенкером под головку.
    Нажмите на изображение для увеличения. 

Название:	bild_3-1_woodwork.jpg 
Просмотров:	33 
Размер:	236.4 Кб 
ID:	31220 Нажмите на изображение для увеличения. 

Название:	bild_3-2_woodwork.jpg 
Просмотров:	33 
Размер:	246.9 Кб 
ID:	31221

    К деревянной раме на клею с саморезами пришит лист фанеры, на котором разместятся все элементы макета. После сборки - прорезаны технологические отверстия для силового ввода (сбоку) и имитации переходов в центре зала (сверху на листе).
    Нажмите на изображение для увеличения. 

Название:	bild_3-3_woodwork.jpg 
Просмотров:	40 
Размер:	210.0 Кб 
ID:	31222 Нажмите на изображение для увеличения. 

Название:	bild_3-4_woodwork.jpg 
Просмотров:	49 
Размер:	255.5 Кб 
ID:	31223

  7. #7
    Давно не отмечался в теме постройки "Садовой" . На самом деле работа всё же движется. Сделан пробный лайтбокс и торцевые стенки станции.

    Питание модуля. В качестве источника питания для нужд модуля используется зарекомендовавший себя китайский импульсник на 5В и 2А. Установлен он будет в пластиковом защитном корпусе и прикручен к основанию таким образом, чтобы закрыть собой высоковольтную часть. С внешней стороны на алюминиевой пластине установлены разъём подключения шнура питания, выключатель и светодиодный индикатор.
    Нажмите на изображение для увеличения. 

Название:	bild_4-powerinput.jpg 
Просмотров:	27 
Размер:	465.2 Кб 
ID:	33253 Нажмите на изображение для увеличения. 

Название:	bild_4-powerACDC.jpg 
Просмотров:	25 
Размер:	541.6 Кб 
ID:	33254

    Лайтбоксы НИП. Пробный вариант. Концепция нового информационного пространства метрополитена Санкт-Петербурга датируется 2009 годом. О том, как это вписалось в архитектуру станций и общий облик транспортной системы было очень много споров. Лайтбокс изготовлен из фольгированного текстолита, обрамлённого полоской полистирола. В центре просверлены отверстия для SMD-светодиодов, которые установлены в них с обратной стороны. Таким образом излучающая часть находится внутри отверстий. Цветная распечатка с информацией "заламинированна" тонким скотчем, вырезана и приклеена к получившейся конструкции.
    Нажмите на изображение для увеличения. 

Название:	bild_4-nip1.jpg 
Просмотров:	37 
Размер:	426.2 Кб 
ID:	33255 Нажмите на изображение для увеличения. 

Название:	bild_4-nip2.jpg 
Просмотров:	42 
Размер:	439.9 Кб 
ID:	33256

    Торцевые стены станции. Торцевые стенки изготовлены из полистирола разной толщины послойно. В них предусмотрено место для установки OLED-дисплеев часов и интервальных таймеров.
    Нажмите на изображение для увеличения. 

Название:	bild_4-torec1.jpg 
Просмотров:	40 
Размер:	554.2 Кб 
ID:	33257 Нажмите на изображение для увеличения. 

Название:	bild_4-torec2.jpg 
Просмотров:	39 
Размер:	388.6 Кб 
ID:	33258
    Нажмите на изображение для увеличения. 

Название:	bild_4-torec3.jpg 
Просмотров:	43 
Размер:	484.9 Кб 
ID:	33259 Нажмите на изображение для увеличения. 

Название:	bild_4-paperdraw.jpg 
Просмотров:	35 
Размер:	612.5 Кб 
ID:	33260

    Продолжение следует...

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •