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

Smart Cube: контроллер нового поколения для умного дома

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

Компонент Количество
Arduino 101 1
Светодиоды (общие): 1 синий, 1 жёлтый, 1 зелёный, 2 красных 5
Резисторы 220 Ом 5
Макетная плата (не обязательна) 1
Seeed Base Shield V2 1
Seeed Grove LCD RGB Backlight 1
Seeed Grove Sound Sensor 1
Seeed Grove Buzzer 1
Seeed Grove Temperature Sensor 1
Матричная клавиатура (Keypad) 1
Перемычки 1
Крона 9V 1
Клипса для кроны 9V 1
МДФ 20x30 см, 3 мм (для лазерной резки) 1

Инструменты

Программное обеспечение и сервисы

О проекте

Что такое SMART CUBE?

Smart Cube — это контроллер для устройств умного дома. В наше время умное управление всеми приборами дома становится необходимостью. Нам нужно что-то простое и интуитивное. Smart Cube может стать решением: это портативное устройство с платой Arduino 101 и набором датчиков, которые общаются с приборами и исполнительными механизмами вашего умного дома.

Инновация пульта связана с инновациями Arduino 101. Он использует Bluetooth (BLE) для управления светом, температурой и ТВ, а также синхронизируется со смартфоном. Но главная инновация — способ взаимодействия с кубиком жестами с помощью гироскопа и акселерометра. У куба 6 граней, каждая управляет определённой функцией. Функция определяется гироскопом, который распознаёт верхнюю грань. Например, чтобы включить свет в комнате, просто положите куб гранью «свет» вверх. Чтобы выключить — встряхните куб.

Если грань ВВЕРХУ и не двигается более 2 секунд — активируется соответствующая функция. Эта задержка даёт время повернуть куб и найти нужную грань без случайных срабатываний. Встряхивание более 2 секунд закрывает последнюю активированную функцию.

Проект помогает построить умный контроллер. Устройству нужен приёмник (умная центральная единица на картинке), который интерпретирует данные и управляет функциями дома. Основной выход куба — BLE-сигнал, который можно использовать по-разному: подключить к приложению на смартфоне (или написать своё), или построить базовую станцию на другом Arduino, которая принимает BLE и напрямую управляет приборами. Так как вариантов много, эта часть зависит от ваших задач. В этом руководстве мы разберём, как собрать Smart Cube и как его персонализировать.

Smart Cube: контроллер нового поколения для умного дома

Функции граней

Структура кода легко персонализируется (разберём позже), поэтому вы решаете, какие функции управлять. Вот мой выбор:

Smart Cube: контроллер нового поколения для умного дома

СВЕТ (LIGHTS): Грань вверх — включает свет в комнате. Встряхивание — выключает свет и зажигает жёлтый LED на этой грани, чтобы найти куб в темноте. Связь по BLE.

ТЕМПЕРАТУРА (TEMPERATURE): Грань вверх — включает кондиционер, если жарко, или отопление, если холодно. Определяет температуру термодатчиком, зажигает синий LED (снежинка) при кондиционере или красный (солнце) при отоплении.

ТАЙМЕР (TIMER): Грань вверх — запускает обратный отсчёт на LCD. Зуммер пищит как будильник по окончании. Встряхивание — стоп, показывает остаточное время. Когда время вышло — LCD краснеет, зуммер пищит 3 раза.

ТВ (TV): Грань вверх — включает ТВ. Куб становится пультом. Кнопочная панель с цифрами активна только когда эта грань вверх (защита от случайных нажатий). Нажатая цифра уходит по BLE в центральный контроллер, подключённый к ТВ. Встряхивание — выключает ТВ.

ЗВУК (SOUND): Грань вверх — яркость зелёного LED зависит от уровня шума в комнате (датчик звука). Встряхивание — отключает функцию. (Можно использовать хлопки для активации своих сценариев).

OFF грань: Если не встряхивать — нейтральная позиция, ничего не меняется. Чтобы выключить всё — положите OFF грань вверх и встряхните. Жест как «Home» на смартфоне. Красный LED помогает найти куб в темноте.

Отличия от концепции

Изначально планировалось также использовать IR-коммуникацию для прямого управления ТВ. Но Arduino 101 пока не поддерживает библиотеку IR, поэтому решил передавать команды по BLE на станцию, где эта библиотека есть (например, Arduino UNO). Из-за этого убрал функцию радио (похожую на TV), заменив на грань со звуковым датчиком. Эта грань может распознавать громкие звуки (хлопки) для активации сценариев. Крупнейшее изменение — материал корпуса. Сначала думал печатать на 3D-принтере, но выбрал лазерную резку. Так легче заменять грани, если хотите сменить функцию. Например, убрать таймер и поставить грань для автозаполнения миски кота. Будучи модульным, не нужно пересобирать весь куб!

Smart Cube: контроллер нового поколения для умного дома

Сборка: пошагово

Следуйте инструкциям. Начнём с электроники, соберём компоненты, потом — корпус из МДФ. После загрузки кода на Arduino 101 можно скачать приложение для просмотра BLE-выходов или подключить напрямую к умному дому!

Smart Cube: контроллер нового поколения для умного дома

Электроника: подключение

Начнём с Arduino 101. Ниже схема Fritzing:

Smart Cube: контроллер нового поколения для умного дома

Установите Grove Base Shield на плату и начните подключения.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

Keypad (клавиатура): провода подключаются к пинам в порядке: 10, 8, 7, 6, 5, 4, 2.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

Светодиоды:

Подключение красных проводов к Arduino: зелёный LED → пин 9, жёлтый → 11, красный → 12, синий → 13, второй красный → A2.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

Grove-датчики: подключите к шилду по схеме (см. вложения). Зуммер → D3, LCD RGB → I2C, температуру → A0, звук → A1.

Smart Cube: контроллер нового поколения для умного дома

Корпус: лазерная резка и сборка

Скачайте чертеж куба (.dxf) для лазерного резака. Красные линии — гравировка (символы граней), чёрные — рез. Внутренний размер куба — 9 см. Чертеж рассчитан на материал 3 мм, при другой толщине нужно скорректировать (можно использовать MakerCase).

Материал — МДФ (средней плотности), но можно использовать другой.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

Сборка:

Установка клавиатуры: вставьте в отверстие, снимите защитную плёнку, подключите пины.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

RGB LCD вставляется идеально в отверстие.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

Подготовка батареи: отрезал старый штекер блока питания, припаял к клипсе для короны. Экономит место внутри.

Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома
Smart Cube: контроллер нового поколения для умного дома

Итоговый вид перед закрытием:

Smart Cube: контроллер нового поколения для умного дома

Осталось подключить батарею, загрузить код и закрыть куб!

Совет: зафиксируйте плату и батарею внутри корпуса, чтобы они не шатались при встряхивании.

Smart Cube: контроллер нового поколения для умного дома

Код

Код в вложениях. Загрузите через Arduino IDE (обновите IDE для поддержки Arduino 101). Почти каждая строка прокомментирована. Не пугайтесь 500+ строк — структура понятна.

Структура кода:

Функции граней можно модифицировать, меняя код внутри if (faceX == true) и соответствующие блоки деактивации при встряхивании. Не забывайте устанавливать faceX = false при встряхивании.

Приложение для проверки BLE

Скачайте nRF Connect: Google Play.

Откройте, найдите устройство «smartcubesketch», подключитесь. Откроются три вкладки «Automation IO» — нажмите на каждой непрерывный сбор данных.

Важно: некоторые функции (свет, температура, ТВ) работают только при подключении к центральному устройству.

Видео-демонстрация

Загрузите код, вставьте батарею, закройте коробку — и у вас есть SMART CUBE!

Снял видео со всеми функциями и управлением.

Заключение

Этот проект — только первый шаг к умному дому. Цель — использовать потенциал Arduino 101 для создания чего-то нового. Акселерометр и гироскоп открывают новые возможности мобильности, а BLE делает подключение простым.

Это мой первый завершённый рабочий прототип. Было сложно, были трудности, но в итоге многому научился и доволен результатом. Надеюсь, читатели тоже почерпнут что-то полезное и адаптируют проект под себя. Извините за английский — надеюсь, изображения помогут.

В будущем планирую создать центральную единицу — мост между Smart Cube и исполнительными механизмами (свет, температура, ТВ...). Она будет принимать BLE от куба и выполнять умные действия в доме.

Рад возможности использовать Arduino 101 и Grove kit (очень удобен для прототипирования). Надеюсь, это вдохновит вас на свои проекты. Персонализируйте как угодно — любопытно увидеть, какие функции придумаете и в каких контекстах примените!

Может, это не революция, но это новый способ взаимодействия с домом.

Теперь ваша очередь: возьмите куб в руки и хакните его!

Код (полный, с комментариями)

// Libraries
#include "CurieIMU.h"      // Акселерометр и гироскоп
#include        // Bluetooth Low Energy
#include 
#include "rgb_lcd.h"        // LCD
#include          // Keypad

rgb_lcd lcd;

// Bluetooth:
BLEPeripheral blePeripheral;

// BLE Services
BLEService lightsService("1815");  // Automation IO - свет
BLEService termoService("1815");   // Automation IO - температура
BLEService TVService("1815");      // Automation IO - TV

// BLE Characteristics
BLEUnsignedCharCharacteristic lightsChar("2A56", BLERead | BLENotify);  // Digital - свет
BLEUnsignedCharCharacteristic termoChar("2A56", BLERead | BLENotify);   // Digital - температура
BLEUnsignedCharCharacteristic TVChar("2A58", BLERead | BLENotify);      // Analog - TV

// Константы и переменные:
// Ориентация и встряхивание
int lastOrientation = -1;
unsigned long previousMillis = 0;
unsigned long interval = 2000;
unsigned long SHAKEpreviousMillis = 0;
unsigned long SHAKEinterval = 2000;
boolean keep = false;
int lastFUNCTION = -1;

// Грани (изначально все false)
boolean face0 = false; // TIMER
boolean face1 = false; // TV
boolean face2 = false; // TEMPERATURE
boolean face3 = false; // OFF
boolean face4 = false; // LIGHTS
boolean face5 = false; // SOUND

// LIGHTS
const int LEDlights = 11;

// TEMPERATURE
const int pinTemp = A0;
const int LEDhot = 12;
const int LEDcold = 13;
float temperature;
int B = 3975;
float resistance;
float tooHot = 26.0;
float tooCold = 23.0;

// TIMER
int BUZZER = 3;
boolean KEEPtime = false;
int TIMERmillis = 0;
int prevSHOWsecond = 0;
int CountdownInMillis = 0;
int SHOWmillis = 0;
int SHOWminute = 0;
int SHOWseconds = 0;
const int SETminute = 2;
const int SETsecond = 30;

// SOUND
const int soundLED = 9;
const int soundSENSOR = A1;
int brightness = 0;

// TV - Keypad
const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {10, 8, 7, 6};
byte colPins[COLS] = {5, 4, 2};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// OFF
const int LEDOFF = A2;

void setup() {
  pinMode(LEDlights, OUTPUT);
  pinMode(LEDhot, OUTPUT);
  pinMode(LEDcold, OUTPUT);
  pinMode(soundLED, OUTPUT);
  pinMode(LEDOFF, OUTPUT);
  Serial.begin(9600);
  
  CountdownInMillis = (SETminute * 60 + SETsecond) * 1000;
  
  lcd.begin(16, 2);
  lcd.setRGB(0, 0, 0);
  
  Serial.println("Initializing IMU device...");
  CurieIMU.begin();
  CurieIMU.setAccelerometerRange(2);
  CurieIMU.setDetectionThreshold(CURIE_IMU_SHOCK, 7000); // 7.0g = 7000 mg
  CurieIMU.setDetectionDuration(CURIE_IMU_SHOCK, 2000);   // 2000ms
  CurieIMU.interrupts(CURIE_IMU_SHOCK);
  
  // BLE setup
  blePeripheral.setLocalName("SmartCubeSketch");
  blePeripheral.setAdvertisedServiceUuid(lightsService.uuid());
  blePeripheral.addAttribute(lightsService);
  blePeripheral.addAttribute(lightsChar);
  lightsChar.setValue(3); // 0=off, 1=on, 3=initial
  
  blePeripheral.setAdvertisedServiceUuid(termoService.uuid());
  blePeripheral.addAttribute(termoService);
  blePeripheral.addAttribute(termoChar);
  termoChar.setValue(0); // 0=cold off/hot off
  
  blePeripheral.setAdvertisedServiceUuid(TVService.uuid());
  blePeripheral.addAttribute(TVService);
  blePeripheral.addAttribute(TVChar);
  TVChar.setValue('x'); // x=nothing
  
  blePeripheral.begin();
  Serial.println("Bluetooth device active, waiting for connections...");
}

void loop() {
  BLECentral central = blePeripheral.central();
  unsigned long currentMillis = millis();
  
  // Определение ориентации (из туториала Arduino)
  int orientation = -1;
  String orientationString;
  int x = CurieIMU.readAccelerometer(X_AXIS);
  int y = CurieIMU.readAccelerometer(Y_AXIS);
  int z = CurieIMU.readAccelerometer(Z_AXIS);
  int absX = abs(x);
  int absY = abs(y);
  int absZ = abs(z);
  
  if ((absZ > absX) && (absZ > absY)) {
    if (z > 0) { orientationString = "up"; orientation = 0; }
    else { orientationString = "down"; orientation = 1; }
  } else if ((absY > absX) && (absY > absZ)) {
    if (y > 0) { orientationString = "digital pins up"; orientation = 2; }
    else { orientationString = "analog pins up"; orientation = 3; }
  } else {
    if (x < 0) { orientationString = "connector up"; orientation = 4; }
    else { orientationString = "connector down"; orientation = 5; }
  }
  /* Ориентации:
     0: плоско, процессор вверх (TIMER)
     1: плоско, процессор вниз (TV)
     2: ландшафт, аналоговые пины вниз (TEMPERATURE)
     3: ландшафт, аналоговые пины вверх (OFF)
     4: портрет, USB вверх (LIGHTS)
     5: портрет, USB вниз (SOUND)
  */
  
  // Активация грани при удержании вверх > interval
  if (orientation != lastOrientation) {
    lastOrientation = orientation;
    previousMillis = currentMillis;
    keep = false;
  } else if (currentMillis - previousMillis > interval && keep == false && lastFUNCTION != orientation) {
    Serial.println(orientationString);
    
    if (orientation == 1) { face1 = true; lastFUNCTION = orientation; Serial.println("TV true"); TVChar.setValue('O'); }
    if (orientation == 4) { face4 = true; lastFUNCTION = orientation; Serial.println("LIGHTS true"); }
    if (orientation == 3) { face3 = true; lastFUNCTION = orientation; Serial.println("OFF true"); }
    if (orientation == 5) { face5 = true; lastFUNCTION = orientation; Serial.println("SOUND true"); }
    if (orientation == 2) { face2 = true; lastFUNCTION = orientation; Serial.println("TEMPERATURE true"); }
    if (orientation == 0) { face0 = true; lastFUNCTION = orientation; Serial.println("TIMER true"); if (!KEEPtime) TIMERmillis = currentMillis; }
    
    keep = true;
  }
  
  // Встряхивание — деактивация
  if (CurieIMU.getInterruptStatus(CURIE_IMU_SHOCK) && currentMillis - SHAKEpreviousMillis > SHAKEinterval) {
    Serial.println("SHAKE");
    
    // TV
    if (lastFUNCTION == 1) { TVChar.setValue('C'); Serial.println("TV false - CLOSE"); face1 = false; }
    // LIGHTS
    if (lastFUNCTION == 4) { if (central.connected()) { lightsChar.setValue(0); digitalWrite(LEDlights, HIGH); } Serial.println("LIGHTS false - CLOSE"); face4 = false; }
    // OFF — закрыть всё
    if (lastFUNCTION == 3) {
      digitalWrite(LEDOFF, HIGH);
      TVChar.setValue('C'); Serial.println("TV false - CLOSE"); face1 = false;
      Serial.println("LIGHTS false - CLOSE"); if (central.connected()) { lightsChar.setValue(0); digitalWrite(LEDlights, LOW); } face4 = false;
      analogWrite(soundLED, LOW); Serial.println("SOUND false - CLOSE"); face5 = false;
      if (central.connected()) { digitalWrite(LEDhot, LOW); digitalWrite(LEDcold, LOW); termoChar.setValue(0); } Serial.println("TEMPERATURE false - CLOSE"); face2 = false;
      Serial.println("TIMER false - CLOSE"); lcd.setRGB(0,0,0); lcd.clear(); KEEPtime = false; face0 = false;
      Serial.println("OFF false - CLOSE"); face3 = false;
    }
    // SOUND
    if (lastFUNCTION == 5) { analogWrite(soundLED, LOW); Serial.println("SOUND false - CLOSE"); face5 = false; }
    // TEMPERATURE
    if (lastFUNCTION == 2) { if (central.connected()) { digitalWrite(LEDhot, LOW); digitalWrite(LEDcold, LOW); termoChar.setValue(0); } Serial.println("TEMPERATURE false - CLOSE"); face2 = false; }
    // TIMER
    if (lastFUNCTION == 0) {
      Serial.println("TIMER false - CLOSE"); face0 = false;
      lcd.setRGB(180, 40, 0); lcd.clear(); lcd.setCursor(0,0); lcd.print("STOP AT "); lcd.setCursor(8,0); lcd.print(SHOWminute); lcd.setCursor(9,0); lcd.print(":"); lcd.setCursor(10,0); lcd.print(SHOWseconds);
      tone(BUZZER,1000,1000); delay(2000); lcd.clear(); lcd.setRGB(0,0,0); KEEPtime = false;
    }
    SHAKEpreviousMillis = currentMillis;
  }
  
  // Исполнение активных граней
  if (face1 == true) { // TV
    digitalWrite(LEDOFF, LOW);
    if (central.connected()) {
      char key = keypad.getKey();
      if (key && orientation == 1) {
        TVChar.setValue(key); Serial.println(key);
      }
    }
  }
  
  if (face4 == true) { // LIGHTS
    digitalWrite(LEDOFF, LOW);
    if (central.connected()) { lightsChar.setValue(1); digitalWrite(LEDlights, LOW); }
  }
  
  if (face3 == true) { // OFF - ничего не делает, LED OFF только при встряхивании
    digitalWrite(LEDOFF, LOW);
  }
  
  if (face5 == true) { // SOUND
    digitalWrite(LEDOFF, LOW);
    long sum = 0;
    for (int i = 0; i < 32; i++) sum += analogRead(soundSENSOR);
    sum >>= 5;
    brightness = (sum * 255) / 1024;
    analogWrite(soundLED, brightness);
    delay(50);
  }
  
  if (face2 == true) { // TEMPERATURE
    digitalWrite(LEDOFF, LOW);
    if (central.connected()) {
      int val = analogRead(pinTemp);
      resistance = (float)(1023 - val) * 10000 / val;
      temperature = 1 / (log(resistance / 10000) / B + 1 / 298.15) - 273.15;
      if (temperature > tooHot) { digitalWrite(LEDhot, LOW); digitalWrite(LEDcold, HIGH); termoChar.setValue(1); }
      else if (temperature < tooCold) { digitalWrite(LEDhot, HIGH); digitalWrite(LEDcold, LOW); termoChar.setValue(2); }
      else { digitalWrite(LEDhot, LOW); digitalWrite(LEDcold, LOW); termoChar.setValue(0); }
    }
  }
  
  if (face0 == true) { // TIMER
    digitalWrite(LEDOFF, LOW);
    SHOWmillis = (CountdownInMillis - (currentMillis - TIMERmillis)) / 1000;
    SHOWminute = SHOWmillis / 60;
    SHOWseconds = SHOWmillis % 60;
    lcd.setRGB(50, 100, 70);
    if (prevSHOWsecond != SHOWseconds) {
      lcd.clear(); lcd.setCursor(0,0); lcd.print("TIMER "); lcd.setCursor(7,0); lcd.print(SETminute); lcd.setCursor(8,0); lcd.print(":"); lcd.setCursor(9,0); lcd.print(SETsecond);
      lcd.setCursor(0,1); lcd.print(SHOWminute); lcd.setCursor(1,1); lcd.print(":"); lcd.setCursor(2,1); lcd.print(SHOWseconds);
      KEEPtime = true; prevSHOWsecond = SHOWseconds;
    }
    if (SHOWminute == 0 && SHOWseconds == 0) {
      lcd.clear(); lcd.setCursor(4,0); lcd.setRGB(180,40,0); lcd.print("TIME OUT");
      tone(BUZZER,1000,500); delay(900); tone(BUZZER,1000,500); delay(900); tone(BUZZER,1000,1000); delay(1500);
      lcd.clear(); lcd.setRGB(0,0,0); face0 = false; KEEPtime = false;
    }
  }
}

3D-модели / Детали корпуса

Файл .dxf для лазерного резака. Использовал МДФ 3 мм. Чёрные линии — рез, красные — гравировка. Важно: при другой толщине материала чертеж нужно скорректировать.

Тот же файл в формате .pdf.

Схемы

Smart Cube: контроллер нового поколения для умного дома

Схема подключений на Grove Shield

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

  1. Солнечные панели: выгодная инвестиция для вашего дома
  2. Почему слегка больший дизайн может ускорить инновации и снизить риски
  3. Как технологии умного дома трансформируют повседневную жизнь
  4. Построение доступной беспроводной сети датчиков для дома
  5. Мониторинг домашней температуры с панелью управления на Raspberry Pi
  6. Преодоление разрыва навыков умного дома: почему Британия отстает от Европы
  7. Эволюция умного дома: что будущее готовит для коннектед жилья
  8. Умная безопасность: экспертные стратегии защиты домашних IoT-устройств от хакеров
  9. Как усилить безопасность умного дома: экспертные советы
  10. Умная теплица IoT на Arduino и Azure: датчики, автополив и удалённый контроль