Проект GreyBox[Серая коробка] - Начало

28.01.2017 10:01

jazon



        Здравствуйте, сегодня я хочу вам рассказать о моём проекте. Проект называется GreyBox, всё потому что основан проект на базе серой коробки, то есть вначале был корпус. Купил я эту коробочку на одном из наших местных форумов, там она позиционировалась как корпус для встраивания различной радиоэлектроники. На протяжении всего времени, в течение которого я занимаюсь изучением Arduino мне хотелось как то оформить эту плату в какой либо корпус, ну в общем мы знаем, что продаётся она так сказать в виде обычной платы. Вообще для Arduino UNO продаются различные акриловые варианты корпусов, но опять же - в любом из этих случаев не избежать кучи разнообразно раскиданных проводов, всяческих соединений и некоторого бардака на столе. Поэтому, купив вот такую коробку я сразу взялся за встраивание моей платы в эту самую коробку. Что у меня из этого вышло - об этом ниже и будет написано много слов, а также постараюсь показать некоторые фотографии о процессе сборки, о самом корпусе. Итак, обо всём по порядку, для начала фотография того что получилось у меня в самом конце, это можно сказать полноценная оболочка-контроллер:



        Всё началось как я уже говорил с желания оформить плату Arduino UNO в какой либо корпус. Изготовление корпуса для радиоаппаратуры - это очень важный шаг в работе любого радиолюбителя, впервые с эти явлением я столкнулся когда собрал свой первый аудиоусилитель, без корпуса это напоминало какую-то разноцветную кучу проводов, и поэтому был запилен корпус в виде колонки. В общем с того времени, прежде чем что то собирать я всегда думаю сначала о корпусе. Итак, как я уже сказал, была приобретена вот такая вот серая коробочка:


 

        Коробочка была разобрана, с целью изучения - что же там внутри? Внутри оказалось... Пусто!!! Но в целом, меня порадовали будущие  её возможности, литые стойки, для монтажной пластины, да, жаль что самой пластины там не было...


 

        Что же начну с описания того что я решил встроить в переднюю и заднюю панели, родные панели я снял, вместо них были вырезаны другие панели, под нужное мне оборудование. Кстати, резали эти панели на лазерном станке ЧПУ, по чертежам разработанным мною же. Вырезаны панели из акрила, пленку я снимать не стал, потому что делалось это всё из прозрачного акрила, а прозрачность мне как бы была не нужна, но нужна была именно толщина материала в 2 миллиметра, а такие показатели были именно у прозрачного. Ну что же, вот список того что мы можем видеть снаружи GreyBox'a:

  • LCD экран размерностью 20х4(20 столбцов и 4 строки)
  • Кнопочная клавиатура от фирмы RobotDyn размерностью 3х4(12 кнопок)
  • Разъёмы Banana в количестве 24 штуки
  • Потенциометр 10кОм
  • Кнопка, нормально разомкнутая 

Всё это то, что видно снаружи... А что же внутри? Вот список того что находится внутри серой коробки:

  • Плата Arduino UNO R3
  • Модуль часов реального времени на базе микросхемы DS1307
  • Модуль Buzzer, по другому называемый пъезопищалка
  • Релейные модули, механические, ток коммутации 10А
  • Преобразователь напряжения, ток отдаваемый в нагрузку 3А(для различной периферии)

Посмотрим на фотографии вскрытой коробочки:




        Как видите, всё из списка было собрано внутри этой серой коробочки и скоммутировано проводами. Часть пинов Arduino UNO были задействованы для вышеуказанного оборудования, замечу что при подключении к экрану я не использовал I2C преобразователь для LCD дисплеев, а подключил дисплей по шести проводам. Ну а другая часть пинов, которые собственно говоря не были задействованы нигде, были выведены на заднюю панель. Вот список задействованных оборудованием пинов Arduino UNO:

  • LCD дисплей - задействованные пины 13,12, 11, 10, 9, 8
  • Модуль Buzzer - задействованный пин 4
  • Кнопочная клавиатура - задействованный пин (аналоговый) A0
  • Модули реле - задействованные пины (аналоговые) А2, А3
  • Модуль RTC DS1307 - задействованные пины (аналоговые) А4, А5 (SCL, SDA)

И список незадействованных пинов, выведенных на заднюю панель:

  • Пин 2(Возможность задействовать прерывание с номером 0)
  • Пин 3(Возможность задействовать прерывание с номером 1, ШИМ)
  • Пин 5(ШИМ)
  • Пин 6(ШИМ)
  • Пин 7
  • Пин А1(аналоговый)

        Далее можно видеть схему расположения пинов которые были выведены на заднюю панель, да, кстати, как видно по фотографиям готового устройства, пока еще не расписаны названия гнёзд и это будет обязательно исправлено, всё таки это только начало. А сейчас просто схематически покажу что и где.



        Начну пожалуй слева направо, гнезда условно сгруппированы по три в одном вертикальном столбце, первая группа это РЕЛЕ 1 центральное гнездо это общий контакт, верхнее - это нормально открыты, нижнее нормально закрытый. Аналогично сконфигурирована и вторая группа гнезд - это РЕЛЕ 2. Третья и последующие группы гнезд имеют существенное отличие - центральное гнездо это пин, верхнее это 5 вольт, нижнее это земля, питание подаётся с преобразователя напряжения. Сделано это чтобы можно было подключать что либо мощное непосредственно от отдельного источника питания.

        С платы Arduino UNO взято питание 3,3 вольта и выведено на соответствующее гнездо. Также выведены контакты для подключения по шине I2C - SCL и SDA. Сразу скажу, что потенциометр регулировки контраста дисплея был добавлен для того чтобы при подключении от различных источников питания можно было удобно подрегулировать контраст. Замечено, что при подаче разных по уровню напряжений питания на плату Arduino UNO дисплей контрастирует по разному а запитан дисплей именно от самой Arduino UNO, и решение с использованием внешнего потенциометра очень удобно. Вроде как всё, напоследок хочу сказать в плату Arduino UNO залит небольшой сырой скетч, демонстрирующий базовую работу всех компонентов установленных внутри. Работу скетча можно увидеть в конце моего обзорного видео по проекту GreyBox:



Сам скетч - это просто сырой код для первичной проверки проекта GreyBox. Вот листинг этого скетча, может кому то будет интересно:


#include "Wire.h"
#include "RTClib.h"
#include "LiquidCrystal.h"

RTC_DS1307 rtc;

LiquidCrystal LCD(13, 12, 11, 10, 9, 8);

//Функция определения нажатой кнопки
int getPressedButton();

//Функция загрузки и отрисовки сообщений при загрузке
void HardWareInitDisplay();

//Функция отрисовки главного экрана
void MainDisplay();

//Функция печатания символов при отрисовке сообщения
void Show_Messages(char msg[],
                      int msgLength,
                        int delayRendering, int strPosition);  

int button;
const int BUTTON_0 = 0;
const int BUTTON_1 = 1;
const int BUTTON_2 = 2;
const int BUTTON_3 = 3;
const int BUTTON_4 = 4;
const int BUTTON_5 = 5;
const int BUTTON_6 = 6;
const int BUTTON_7 = 7;
const int BUTTON_8 = 8;
const int BUTTON_9 = 9;
const int BUTTON_ENT = 10;
const int BUTTON_ESC = 11;
const int BUTTON_NONE = 12;

//Value delay rendering - Значение задержки отрисовки символов
const int VDR = 50;                      

//Сообщения инициализации размерность ограничена количеством                                            
//столбцов дисплея, то есть не более 20-ти символов
                                           
char RTCDevice[]  = "Real-Time Clock";      
char RTCDS1307[]  = "DS1307";                
char isFound[]    = "Device is found.";      
char notFound[]   = "Device is not found.";  
char isRunning[]  = "Device is running.";    
char notRunning[] = "Device not running.";  
char isLaunch[]   = "Launch device...";      
char done[]       = "Done...";              

char BuzzSignal[]     = "Buzzzer beep signal";    
char Rel1StatusHigh[] = "Relay1 preset is off";    
char Rel1StatusLow[]  = "Relay1 preset is on";    
char Rel2StatusHigh[] = "Relay2 preset is off";    
char Rel2StatusLow[]  = "Relay2 preset is on";    

const short int ROWS = 4;
const short int COLS = 20;

const int BUZZZER = 4;

unsigned char RELOUT1 = A2;
unsigned char RELOUT2 = A3;


void setup()
{
  pinMode(BUZZZER, OUTPUT);
   
  LCD.begin(COLS, ROWS);
  LCD.clear();

  HardWareInitDisplay();
}

void loop()
{
  button = getPressedButton();
  switch (button)
  {
  case BUTTON_NONE: // при нажатии кнопки выводим следующий текст
    //LCD.clear();
    analogWrite(RELOUT1, 255);
    analogWrite(RELOUT2, 255);
    noTone(BUZZZER);
    LCD.setCursor(0, 0);
    LCD.print("Press any key...    ");
    LCD.setCursor(0, 1);
    LCD.print("                    ");
    break;
  case BUTTON_0:
    LCD.setCursor(0, 0);
    LCD.print("Button 0 pressed... ");
    //delay(300);
    break;
  case BUTTON_1:
    analogWrite(RELOUT1, LOW);
    LCD.setCursor(0, 0);
    LCD.print("Button 1 pressed... ");
    LCD.setCursor(0, 1);
    LCD.print("Relay 1 is on... ");
    break;
  case BUTTON_2:
    analogWrite(RELOUT2, LOW);
    LCD.setCursor(0, 0);
    LCD.print("Button 2 pressed... ");
    LCD.setCursor(0, 1);
    LCD.print("Relay 2 is on... ");
    break;
  case BUTTON_3:
    LCD.setCursor(0, 0);
    LCD.print("Button 3 pressed... ");
    break;
  case BUTTON_4:
    LCD.setCursor(0, 0);
    LCD.print("Button 4 pressed... ");
    break;
  case BUTTON_5:
    LCD.setCursor(0, 0);
    LCD.print("Button 5 pressed... ");
    break;
  case BUTTON_6:
    LCD.setCursor(0, 0);
    LCD.print("Button 6 pressed... ");
    break;
  case BUTTON_7:
    LCD.setCursor(0, 0);
    LCD.print("Button 7 pressed... ");
    break;
  case BUTTON_8:
    LCD.setCursor(0, 0);
    LCD.print("Button 8 pressed... ");
    break;
  case BUTTON_9:
    LCD.setCursor(0, 0);
    LCD.print("Button 9 pressed... ");
    break;
  case BUTTON_ENT:
    LCD.setCursor(0, 0);
    LCD.print("Button ENT pressed..");
    break;
  case BUTTON_ESC:
    LCD.setCursor(0, 0);
    LCD.print("Button ESC pressed..");
    break;
  }
 
  MainDisplay();
}

void HardWareInitDisplay()
{
  Show_Messages(RTCDevice, strlen(RTCDevice), VDR, 0);
  Show_Messages(RTCDS1307, strlen(RTCDS1307), VDR, 1);
 
  if(!rtc.begin())
  {
    Show_Messages(notFound, strlen(notFound), VDR, 2);
    while(1);
  }
  else
  {
    Show_Messages(isFound, strlen(isFound), VDR, 2);
  }

  if(!rtc.isrunning())
  {
    Show_Messages(notRunning, strlen(notRunning), VDR, 3);
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    delay(3000);
  }
  else
  {
    Show_Messages(isRunning, strlen(isRunning), VDR, 3);
    delay(3000);
    LCD.clear();
  }

 
 
  Show_Messages(BuzzSignal, strlen(BuzzSignal), VDR, 0);
  tone(BUZZZER, 2340);
  delay(300);
  noTone(BUZZZER);

  if(digitalRead(RELOUT1))
    Show_Messages(Rel1StatusHigh, strlen(Rel1StatusHigh), VDR, 1);
  else
    Show_Messages(Rel1StatusLow, strlen(Rel1StatusLow), VDR, 1);

  if(digitalRead(RELOUT2))
    Show_Messages(Rel2StatusHigh, strlen(Rel2StatusHigh), VDR, 2);
  else
    Show_Messages(Rel2StatusLow, strlen(Rel2StatusLow), VDR, 2);

  Show_Messages(done, strlen(done), VDR, 3);
  delay(3000);
  LCD.clear();
}
void MainDisplay()
{
  DateTime now = rtc.now();
 
  LCD.setCursor(0, 4);
  LCD.print(now.year(), DEC);
  LCD.setCursor(4, 4);
  LCD.print('/');
  LCD.setCursor(5, 4);
  LCD.print(now.month() / 10, DEC);
  LCD.setCursor(6, 4);
  LCD.print(now.month() % 10, DEC);
  LCD.setCursor(7, 4);
  LCD.print('/');
  LCD.setCursor(8, 4);
  LCD.print(now.day() / 10, DEC);
  LCD.setCursor(9, 4);
  LCD.print(now.day() % 10, DEC);

  LCD.setCursor(10, 4);
  LCD.print("  ");

  LCD.setCursor(12, 4);
  LCD.print(now.hour() / 10, DEC);
  LCD.setCursor(13, 4);
  LCD.print(now.hour() % 10, DEC);
  LCD.setCursor(14, 4);
  LCD.print(':');
  LCD.setCursor(15, 4);
  LCD.print(now.minute() / 10, DEC);
  LCD.setCursor(16, 4);
  LCD.print(now.minute() % 10, DEC);
  LCD.setCursor(17, 4);
  LCD.print(':');
  LCD.setCursor(18, 4);
  LCD.print(now.second() / 10, DEC);
  LCD.setCursor(19, 4);
  LCD.print(now.second() % 10, DEC);
}

void Show_Messages(char msg[], int msgLength, int delayRendering, int strPosition)
{
  LCD.leftToRight();
 
  for(int j = 0; j < msgLength; j ++)
  {
    LCD.setCursor(j, strPosition);
    LCD.write(msg[j]);
    delay(delayRendering);
  }
}

int getPressedButton()
{
  // считываем значения с аналогового входа(A0)
  int buttonValue = analogRead(0);  

  if(buttonValue < 480)
    return BUTTON_NONE;
   
  else if(buttonValue < 500){
    tone(BUZZZER, 2340);
    return BUTTON_ESC;}
     
  else if(buttonValue < 525){
    tone(BUZZZER, 2340);
    return BUTTON_0;}
   
  else if(buttonValue < 551){
    tone(BUZZZER, 2340);
    return BUTTON_ENT;}
 
  else if(buttonValue < 582){
    tone(BUZZZER, 2340);
    return BUTTON_3;}

  else if(buttonValue < 615){
    tone(BUZZZER, 2340);
    return BUTTON_6;}

  else if(buttonValue < 652){
    tone(BUZZZER, 2340);
    return BUTTON_9;}

  else if(buttonValue < 695){
    tone(BUZZZER, 2340);
    return BUTTON_2;}

  else if(buttonValue < 744){
    tone(BUZZZER, 2340);
    return BUTTON_5;}

  else if(buttonValue < 800){
    tone(BUZZZER, 2340);
    return BUTTON_8;}

  else if(buttonValue < 865){
    tone(BUZZZER, 2340);
    return BUTTON_1;}

  else if(buttonValue < 940){
    tone(BUZZZER, 2340);
    return BUTTON_4;}

  else if(buttonValue < 1024){
    tone(BUZZZER, 2340);
    return BUTTON_7;}
}


        Ну и раз уж вы дочитали эту статью - выложу также и пошаговый фотоотчет сборки этого девайса, скачав архив его нужно распаковать, весит он примерно 500 Мб. Скажу напоследок - проект GreyBox, неплохая физическая оболочка для реализации других проектов, в будущем планируется совершенствовать его посредством дополнения элементарного меню, также расширять физическую базу - подключать различные датчики или какое либо исполнительное оборудование. Надеюсь вам было интересно, оставайтесь с нами, нас ждут интереснейшие открытия в мире АРДУИНО!!!!



Расскажи о нас

Сообщение

Если у Вас есть опыт в работе с Arduino и собственно есть время для творчества, мы приглашаем всех желающих стать авторами статей публикуемых на нашем портале. Это могут быть как уроки, так и рассказы о ваших экспериментах с Arduino. Описание различных датчиков и модулей. Советы и наставления начинающим. Пишите и размещайте свои статьи в соответсвующей ветке форума.