Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Smart Cube: Hub de Controle Residencial de Próxima Geração

Componentes e Materiais Necessários

Componente Quantidade Observações
Arduino 101 1
LED (genérico) 5 1 azul - 1 amarelo - 1 verde - 2 vermelhos
Resistor 221 ohm 5
Protoboard (genérica) 1 Não obrigatório
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
Jumpers (genéricos) 1
Bateria 9V (genérica) 1
Conector de Bateria 9V 1
Fibra de Média Densidade (MDF) 20x30 cm 1 3mm MDF ou outro material para corte a laser

Ferramentas e Máquinas Necessárias

Aplicativos e Serviços Online

Sobre o Projeto

O que é o SMART CUBE?

O Smart Cube é um controlador para seus dispositivos de casa inteligente.

Hoje em dia, gerenciar de forma mais inteligente todos os dispositivos em nossas casas está se tornando uma exigência. Precisamos de algo simples e intuitivo de usar. O Smart Cube pode ser uma solução: é um dispositivo portátil que contém uma placa Arduino 101 e alguns sensores que se comunicam com os eletrodomésticos e atuadores em sua casa inteligente.

A inovação deste controlador remoto está relacionada à inovação da placa Arduino 101. Ele usa Bluetooth (BLE) para controlar luzes, temperatura e sua TV, e você também pode sincronizá-lo com seu smartphone. Mas a grande inovação é a forma como você interage com o Smart Cube com seus gestos usando o giroscópio e o acelerômetro. O cubo tem 6 faces e cada uma controla uma função específica. A função que você deseja usar é detectada graças ao giroscópio que reconhece a face superior. Por exemplo, você pode acender as luzes do ambiente em que está apenas posicionando o cubo com a "face de luz" na posição superior. Se quiser apagar a luz, basta sacudir o cubo.

Se uma face estiver PARA CIMA e não se mover por mais de 2 segundos, a função relacionada é ativada. Este atraso é feito para que você possa ter tempo para girar e interagir com o cubo para encontrar a face que precisa sem ativar acidentalmente outras funções. Quando você sacode o cubo por mais de 2 segundos, a última função ativada é fechada.

Este projeto visa ajudá-lo a construir um controlador inteligente. Este dispositivo precisa de um receptor (central inteligente na imagem) que interprete os dados e gerencie as funções de sua casa inteligente. A principal saída do cubo é um sinal BLE que pode ser usado de várias maneiras: por exemplo, você pode conectar o cubo com um aplicativo para smartphone (ou criar o seu próprio), ou pode construir uma estação com outro Arduino que colete os dados BLE e controle diretamente os eletrodomésticos de sua casa. Devido à variedade de casos, esta parte depende de sua necessidade. Neste guia, veremos como construir um smart cube e você aprenderá como personalizá-lo.

Smart Cube: Hub de Controle Residencial de Próxima Geração

Funções

A estrutura do código é fácil de personalizar (analisamos o código depois) para que você possa decidir quais funções controlar. Estas são as funções que decidi controlar:

Smart Cube: Hub de Controle Residencial de Próxima Geração

LUZES: Esta face na posição PARA CIMA acende as luzes do ambiente em que você está. Se você sacudir o cubo, as luzes apagam e um LED amarelo nesta face é ativado para que você encontre o cubo no escuro. A comunicação com suas lâmpadas é feita pelo BLE da placa 101.

TEMPERATURA: Esta face PARA CIMA ativa (via BLE) o ar condicionado se estiver quente ou o aquecimento se estiver frio. Detecta a temperatura usando um sensor térmico e acende um LED azul se o condicionador estiver ligado (floco de neve) ou um vermelho se o aquecimento estiver ativado (sol).

TIMER: Esta face PARA CIMA inicia um temporizador que você pode ver no display LCD. Há um buzzer que funciona como alarme quando a contagem regressiva termina. Se você sacudir, para o temporizador e vê o tempo restante. Quando a contagem termina, a cor do LCD muda de azul para vermelho e o buzzer emite três sons.

TV: Esta face PARA CIMA liga a TV. O cubo se torna um controle remoto para sua TV. Há um painel de botões com números que é ativado apenas se esta face estiver PARA CIMA, para evitar toques acidentais. O número que você pressiona é enviado via BLE para o controlador central conectado à sua TV. Sacudindo o cubo, você desliga a TV.

SOM: Esta face PARA CIMA ativa um LED cujo brilho é baseado no nível de ruído do ambiente. O ruído é detectado graças a um sensor de som. Se você sacudir o cubo, fecha esta função. (Se quiser, pode ativar sua função pessoal batendo palmas).

FACE OFF: Se você não sacudir o cubo, esta face é como uma posição neutra na qual nada é alterado. Se quiser fechar tudo, posicione o cubo com a face OFF PARA CIMA e sacuda-o. Este gesto é como o botão home do seu smartphone que você pressiona se quiser sair rapidamente. Há um LED vermelho para que você encontre o cubo se estiver escuro.

Diferenças do Conceito Original

O plano original era usar também comunicação IR para conectar sua TV diretamente ao cubo. Como o Arduino 101 não suporta (por enquanto) a biblioteca que gerencia sinais IR, decidi enviar as informações via BLE para uma estação que possa gerenciar esta biblioteca (como Arduino UNO). Por causa desse problema, removi a função rádio (muito similar à face TV), substituindo-a por uma face com sensor de som. Esta face pode ser usada para reconhecer um ruído alto (como bater palmas) para ativar algo. A maior mudança está no material do cubo. Inicialmente pensei em construí-lo com uma impressora 3D, mas depois decidi usar um cortador a laser. Dessa forma, é mais fácil substituir uma face se você quiser mudar uma função. Por exemplo, você pode remover a face do timer e trocá-la por uma que encha automaticamente o pote do seu gato. Sendo modular, você não precisa reconstruir toda a estrutura!

Smart Cube: Hub de Controle Residencial de Próxima Geração

Vamos Construí-lo

Siga estas instruções para construir seu próprio smart cube. Começaremos pelo hardware, montando os componentes eletrônicos primeiro e depois o corpo do cubo cortado a laser feito de MDF. Após esta operação, explicarei como o código funciona e como você pode personalizá-lo. Depois de fazer o upload do código no seu Arduino 101, você pode baixar o aplicativo para ver a saída BLE do cubo ou conectá-lo diretamente com sua casa inteligente!

Smart Cube: Hub de Controle Residencial de Próxima Geração

Hardware - Eletrônica

Vamos começar pelo seu Arduino 101. Este é o esquema fritzing a seguir:

Smart Cube: Hub de Controle Residencial de Próxima Geração

Monte o Grove base shield na sua placa e comece com as conexões.

Smart Cube: Hub de Controle Residencial de Próxima Geração

Keypad: você deve conectar os fios em ordem aos pinos: 10, 8, 7, 6, 5, 4, 2.

Smart Cube: Hub de Controle Residencial de Próxima Geração

Conexões dos LEDs:

Primeiro, temos que preparar os LEDs:

Agora conecte os fios vermelhos ao seu Arduino: LED VERDE no pino 9, LED AMARELO no pino 11, LED VERMELHO no pino 12, LED AZUL no pino 13 e o último VERMELHO no pino A2.

Smart Cube: Hub de Controle Residencial de Próxima Geração

Sensores Grove:

Conecte os sensores Grove ao shield (veja o esquema nos anexos).

Buzzer no D3, LCD RGB no I2C, Sensor de temperatura no A0, Sensor de som no A1.

Smart Cube: Hub de Controle Residencial de Próxima Geração

Ok, agora conectamos todas as partes elétricas. Agora você precisa do gabinete.

Hardware - Caixa

Você pode baixar o esboço do cubo para cortar com laser. As linhas vermelhas no esboço são os símbolos das faces, apenas grave elas. As linhas pretas devem ser cortadas. A dimensão interna do cubo é 9 cm. O esboço está ok se você usar material de 3mm, se usar espessura diferente, deve modificá-lo (pode usar este site: https://www.makercase.com/).

O material que escolhi é MDF (Fibra de Média Densidade), mas você pode usar o que quiser.

Aqui estão algumas fotos do corte a laser:

Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração

Agora temos que montá-lo.

Eu colei alguns pedaços de papelão para dar espessura aos LEDs. Dessa forma, eles ficarão alinhados com a superfície.

Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração

Agora montamos o keypad. Insira-o no furo e remova a película adesiva, depois reconecte os pinos.

Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração

Agora o LCD RGB. Este encaixa perfeitamente no furo.

Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração

Vamos preparar o conector da bateria:

Cortei um plug de transformador velho e conectei a um clipe de bateria. Dessa forma, economizamos espaço dentro da caixa.

Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração
Smart Cube: Hub de Controle Residencial de Próxima Geração

Neste ponto, é isso que você deve ter:

Smart Cube: Hub de Controle Residencial de Próxima Geração

Agora você só precisa conectar a bateria, fazer o upload do código e fechar o cubo!

DICA: fixe a placa e a bateria no gabinete para que, quando você sacudir o cubo, eles fiquem estáveis.

Smart Cube: Hub de Controle Residencial de Próxima Geração

Código

Você pode encontrar o código nos anexos. Faça o upload na sua placa com o Arduino IDE (lembre-se de atualizar seu software para compatibilidade com Arduino 101).

Eu comentei quase todas as linhas do código para torná-lo o mais compreensível possível. Não se assuste com as 500+ linhas, a estrutura não é tão complicada.

No início estão as bibliotecas e todas as variáveis de declaração.

Nesta parte também há a definição de serviços e características BLE. Usei o serviço Automation IO. Usei a característica Digital para luzes e temperatura (usa 2 bits, então 4 casos possíveis para codificar) e a Analog para TV (para enviar todos os códigos do keypad).

Então o setup. Esta parte é executada apenas uma vez no início. Aqui inicializamos os componentes como entradas ou saídas e inicializamos o BLE e o giroscópio da placa 101.

A parte principal é o loop. Ele é dividido em quatro partes:

Você pode modificar as funções das faces com algumas modificações no código. A estrutura principal deve ser como descrita. Você pode mudar a parte dentro das condições if de cada face.

if (face2 == true) { // face TEMPERATURA
// INÍCIO DA PERSONALIZAÇÃO
digitalWrite (LEDOFF, LOW); // se esta face é true, o LED da face OFF fica LOW
if (central.connected() == true) { // se o cubo está conectado via BLE
  // lê valor de temperatura
  int val = analogRead(pinTemp); // obtém valor analógico
  resistance=(float)(1023-val)*10000/val; // obtém resistência
  temperature=1/(log(resistance/10000)/B+1/298.15)-273.15; // calcula temperatura
  // condições de ativação
  if (temperature > tooHot) { // ativar ar condicionado
    digitalWrite(LEDhot, LOW); // fechar LED de aquecimento
    digitalWrite(LEDcold, HIGH); // abrir LED de ar condicionado
    termoChar.setValue(1); // definir via BLE a condição 1 = frio ligado - quente desligado
  }
  if (temperature < tooCold) { // ativar aquecimento
    digitalWrite(LEDhot, HIGH);
    digitalWrite(LEDcold, LOW);
    termoChar.setValue(2); // 2 = frio desligado - quente ligado
  }
  if (temperature > tooCold && temperature < tooHot) { // temperatura ideal: nada ativado
    digitalWrite(LEDhot, LOW);
    digitalWrite(LEDcold, LOW);
    termoChar.setValue(0); // 0 = frio desligado - quente desligado
  }
}
// FIM DA PERSONALIZAÇÃO
}

Você deve codificar a parte "true" (como no código anterior) e também a parte "false" quando o cubo é sacudido:

// Desativação TEMPERATURA
if (lastFUNCTION == 2) { // face TEMPERATURA
// INÍCIO DA PERSONALIZAÇÃO
// se um central está conectado ao peripheral:
if (central.connected() == true) {
  digitalWrite(LEDhot, LOW); // fechar LED vermelho de temperatura
  digitalWrite(LEDcold, LOW); // fechar LED azul de temperatura
  termoChar.setValue(0); // sinal BLE temperatura: 0 = frio desligado - quente desligado
// FIM DA PERSONALIZAÇÃO
}
Serial.println("TEMPERATURA false - FECHAR");
face2 = false; // face TEMPERATURA torna-se false
}

Lembre-se de definir a face como false quando sacudir.

Aplicativo

Para ver as saídas BLE do cubo, você pode baixar este aplicativo: nRF Connect

https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&hl=it

Quando abri-lo, apenas busque por dispositivos e conecte com "smartcubesketch". Então você verá três abas "Automation IO", clique nelas e pressione o coletor de dados contínuo.

É importante conectar o cubo porque algumas funções (luzes, temperatura e TV) são executadas apenas se o cubo estiver conectado.

Como Funciona: VÍDEO

Faça o upload do código, insira a bateria, feche a caixa e...

...agora você tem um SMART CUBE!

Fiz um vídeo para mostrar todas as funções do cubo e como usá-lo.

Conclusões

Este projeto é apenas o primeiro passo para uma casa inteligente. Meu objetivo era usar o potencial da placa Arduino 101 para criar algo novo. Acho que o acelerômetro e o giroscópio dão à placa novas oportunidades em termos de mobilidade. Com o BLE, além de ser portátil, também é fácil de conectar.

Esta é a primeira vez que realizo concretamente um dos meus projetos (quero dizer, com um protótipo funcional). Foi difícil e houve algumas dificuldades no caminho, mas no final aprendi muito e estou feliz com o resultado. Espero que todos que lerem este guia também possam aprender algo com meu trabalho e modificar este projeto para suas necessidades. Peço desculpas pelo meu inglês ruim, mas espero que as imagens possam ajudar.

No futuro deste projeto, espero criar a central que é como a ponte entre o smart cube e os atuadores (luzes, temperatura, tv...). Esta central receberá o sinal BLE do cubo e usará esta informação para fazer coisas inteligentes em sua casa.

Estou muito feliz por ter a oportunidade de usar o Arduino 101 e o Grove kit (o kit é muito simples e rápido para prototipagem).

Espero que usar a placa desta forma possa ser uma inspiração para seu projeto. Você pode personalizá-lo como quiser: Tenho curiosidade para ver quais funções você criará e em que contextos diferentes você o usará!

Talvez não seja uma revolução, mas é uma nova forma de interagir com sua casa.

Espero que tenha gostado deste tutorial.

Agora é sua vez: coloque as mãos no cubo e faça seu hack!

Código Completo

SMART CUBE - Código completo com comentários (Arduino)

// Bibliotecas
#include "CurieIMU.h" // Acelerômetro & Giroscópio
#include <CurieBLE.h> // Bluetooth Low Energy
#include <Wire.h>
#include "rgb_lcd.h" // LCD
#include <Keypad.h> // Keypad

rgb_lcd lcd; // Inicialização do LCD

// Inicialização do Bluetooth:
BLEPeripheral blePeripheral; // Dispositivo Peripheral BLE (a placa que você está programando)

// Serviços BLE
BLEService lightsService("1815"); // BLE Automation IO (1815) - informações de luzes
BLEService termoService("1815"); // BLE Automation IO - informações de temperatura
BLEService TVService("1815"); // BLE Automation IO - informações de TV

// Características BLE
BLEUnsignedCharCharacteristic lightsChar("2A56", // Característica BLE Digital (2A56) - luzes
  BLERead | BLENotify);
BLEUnsignedCharCharacteristic termoChar("2A56", // Característica BLE Digital - temperatura
  BLERead | BLENotify);
BLEUnsignedCharCharacteristic TVChar("2A58", // Característica BLE Analog (2A58) - TV
  BLERead | BLENotify);

// Constantes e declaração de variáveis:
// Funções de orientação da face e shake:
int lastOrientation = -1; // orientação anterior (para comparação)
unsigned long previousMillis = 0; // última atualização de tempo
unsigned long interval = 2000; // tempo para esperar na posição superior antes da ativação da face
unsigned long SHAKEpreviousMillis = 0; // última atualização de tempo
unsigned long SHAKEinterval = 2000; // tempo para esperar durante o shake para desativação da face
boolean keep = false; // usado para contar apenas uma vez a mudança de orientação da face
int lastFUNCTION = -1; // usado para saber qual era a orientação anterior

// Inicialização das faces: no início, cada face é false
boolean face0 = false;
boolean face1 = false;
boolean face2 = false;
boolean face3 = false;
boolean face4 = false;
boolean face5 = false;

// Face LUZES
const int LEDlights = 11; // pino 11: LED amarelo

// Face TEMPERATURA
const int pinTemp = A0; // pino A0: sensor de temperatura
const int LEDhot = 12; // pino 12: LED vermelho
const int LEDcold = 13; // pino 13: LED azul
float temperature; // valor de temperatura memorizado
int B=3975; // valor B do termistor
float resistance; // valor de resistência memorizado
float tooHot = 26.0; // temperatura na qual o ar condicionado é ativado [CONFIGURÁVEL]
float tooCold = 23.0; // temperatura na qual o aquecedor é ativado [CONFIGURÁVEL]

// Face TIMER
int BUZZER = 3; // pino 3: buzzer
boolean KEEPtime = false; // usado para contar apenas uma vez a mudança de orientação (não reiniciar enquanto conta)
int TIMERmillis = 0; // para determinação da contagem regressiva
int prevSHOWsecond = 0;
int CountdownInMillis = 0;
int SHOWmillis = 0; // valor de millis calculado
int SHOWminute = 0; // valor de minutos para mostrar no monitor na contagem regressiva
int SHOWseconds = 0; // valor de segundos para mostrar no monitor na contagem regressiva
const int SETminute = 2; // definir timer de 2 minutos [CONFIGURÁVEL]
const int SETsecond = 30; // definir timer de 30 segundos [CONFIGURÁVEL]

// Face SOM
const int soundLED = 9; // pino 9: LED verde
const int soundSENSOR = A1; // pino A0: sensor de som
int brightness = 0; // inicialização do brilho do LED verde

// Face TV
const byte ROWS = 4; // quatro linhas do keypad
const byte COLS = 3; // três colunas do keypad
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
}; // valores dos botões do keypad
byte rowPins[ROWS] = {10,8,7,6}; // pinos 10,8,7,6: conectar aos pinos de linha do keypad
byte colPins[COLS] = {5,4,2}; // pinos 5,4,2: conectar aos pinos de coluna do keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // inicialização do keypad

// Face OFF
const int LEDOFF = A2; // pino A2: LED vermelho

void setup() {
  pinMode(LEDlights, OUTPUT); // cada LED é definido como saída
  pinMode(LEDhot, OUTPUT);
  pinMode(LEDcold, OUTPUT);
  pinMode(soundLED, OUTPUT);
  pinMode(LEDOFF, OUTPUT);
  Serial.begin(9600); // inicializa comunicação Serial
  CountdownInMillis = (SETminute*60 + SETsecond)*1000; // calcula o valor correspondente em millis a partir de minutos e segundos
  lcd.begin(16, 2); // Inicialização do LCD
  lcd.setRGB(0, 0, 0); // LCD RGB está DESLIGADO no início
  
  // Inicialização do dispositivo
  Serial.println("Inicializando dispositivo IMU...");
  CurieIMU.begin(); // Inicializa IMU
  // Define o alcance do acelerômetro para 2G
  CurieIMU.setAccelerometerRange(2);
  // Habilita Detecção de Choque
  CurieIMU.setDetectionThreshold(CURIE_IMU_SHOCK, 7000); // 7.0g = 7000 mg (este valor define a intensidade do choque)
  CurieIMU.setDetectionDuration(CURIE_IMU_SHOCK, 2000); // 2000ms (este valor define a duração do choque)
  CurieIMU.interrupts(CURIE_IMU_SHOCK);
  
  // Inicialização do BLE
  blePeripheral.setLocalName("SmartCubeSketch"); // nome do projeto
  blePeripheral.setAdvertisedServiceUuid(lightsService.uuid()); // adiciona UUID do serviço de luzes
  blePeripheral.addAttribute(lightsService); // adiciona serviço BLE de luzes
  blePeripheral.addAttribute(lightsChar); // adiciona característica BLE de luzes
  lightsChar.setValue(3); // valor inicial para esta característica = 3
  // Significado do valor BLE lights: 0 = luzes desligadas, 1 = luzes ligadas, 3 = estado inicial, 4 = não usado
  
  blePeripheral.setAdvertisedServiceUuid(termoService.uuid()); // adiciona UUID do serviço de temperatura
  blePeripheral.addAttribute(termoService); // adiciona serviço BLE de temperatura
  blePeripheral.addAttribute(termoChar); // adiciona característica BLE de temperatura
  termoChar.setValue(0); // valor inicial é 0: frio desligado - quente desligado
  // Significado do valor BLE termo: 0 = frio desligado - quente desligado, 1 = frio ligado - quente desligado, 2 = frio desligado - quente ligado, 3 = não usado
  
  blePeripheral.setAdvertisedServiceUuid(TVService.uuid()); // adiciona UUID do serviço de TV
  blePeripheral.addAttribute(TVService); // adiciona serviço BLE de TV
  blePeripheral.addAttribute(TVChar); // adiciona característica de TV
  TVChar.setValue('x'); // valor inicial para esta característica (x significa nada)
  // Significado do valor BLE TV: #número corresponde ao botão pressionado, C: fechar TV, O: abrir TV, x: estado inicial
  
  blePeripheral.begin();
  Serial.println("Dispositivo Bluetooth ativo, aguardando conexões...");
}

// Fim do setup

void loop() {
  BLECentral central = blePeripheral.central(); // Conexão BLE
  unsigned long currentMillis = millis(); // valor atual do tempo em millissegundos
  
  // O código a seguir vem de www.arduino.cc/en/Tutorial/Genuino101CurieIMUccelerometerOrientation
  // é usado para detectar a orientação da placa
  int orientation = -1; // orientação da placa
  String orientationString; // string para imprimir descrição da orientação
  
  // Lê acelerômetro:
  int x = CurieIMU.readAccelerometer(X_AXIS);
  int y = CurieIMU.readAccelerometer(Y_AXIS);
  int z = CurieIMU.readAccelerometer(Z_AXIS);
  
  // Calcula valores absolutos para determinar o maior
  int absX = abs(x);
  int absY = abs(y);
  int absZ = abs(z);
  
  if ((absZ > absX) && (absZ > absY)) {
    // orientação baseada no Z
    if (z > 0) {
      orientationString = "up";
      orientation = 0;
    } else {
      orientationString = "down";
      orientation = 1;
    }
  } else if ((absY > absX) && (absY > absZ)) {
    // orientação baseada no Y
    if (y > 0) {
      orientationString = "pinos digitais up";
      orientation = 2;
    } else {
      orientationString = "pinos analógicos up";
      orientation = 3;
    }
  } else {
    // orientação baseada no X
    if (x < 0) {
      orientationString = "conector up";
      orientation = 4;
    } else {
      orientationString = "conector down";
      orientation = 5;
    }
  }
  
  // Fim do código do tutorial.
  // Neste ponto, você tem o valor de orientação da placa constantemente atualizado:
  /* As orientações da placa:
  0: plana, processador virado para cima (TIMER)
  1: plana, processador virado para baixo (TV)
  2: paisagem, pinos analógicos para baixo (TEMPERATURA)
  3: paisagem, pinos analógicos para cima (OFF)
  4: retrato, conector USB para cima (LUZES)
  5: retrato, conector USB para baixo (SOM) */
  
  // Para este projeto, você precisa saber se a face mudou da face anterior [lastFUNCTION != orientation]
  // Mas esta informação é impressa apenas se a face estiver na posição UP por mais de [interval] tempo
  // E apenas por uma vez [keep] (você não precisa ativar a face constantemente, precisa apenas uma vez)
  // Como o valor de orientação é constantemente atualizado, você precisa começar a contar o tempo quando a orientação muda [orientation != lastOrientation]
  
  if (orientation != lastOrientation) {
    // Se a orientação mudou, começa a contar o tempo
    lastOrientation = orientation; // memoriza a orientação atual da face
    previousMillis = currentMillis; // memoriza o tempo quando a face mudou
    keep = false;
  } else if (currentMillis - previousMillis > interval && keep == false && lastFUNCTION != orientation) {
    // Esta condição imprime a orientação apenas se a face estiver para cima por um intervalo
    // E apenas por uma vez (keep)
    // E apenas se a face for diferente do loop anterior
    Serial.println(orientationString); // imprime a orientação
    
    // A face atual [orientation] é definida como true (isso significa que a função da face é definida como ativada)
    if (orientation == 1) { // face TV
      face1 = true; // face TV torna-se true
      lastFUNCTION = orientation; // memoriza esta ativação em [lastFUNCTION]
      Serial.println("TV true"); // imprime a face ativada
      TVChar.setValue('O'); // O: sinal de abrir TV (BLE): TV aberta apenas uma vez
    }
    if (orientation == 4) { // face LUZES
      face4 = true;
      lastFUNCTION = orientation;
      Serial.println("LUZES true");
    }
    if (orientation == 3) { // face OFF
      face3 = true;
      lastFUNCTION = orientation;
      Serial.println("OFF true");
    }
    if (orientation == 5) { // face SOM
      face5 = true;
      lastFUNCTION = orientation;
      Serial.println("SOM true");
    }
    if (orientation == 2) { // face TEMPERATURA
      face2 = true;
      lastFUNCTION = orientation;
      Serial.println("TEMPERATURA true");
    }
    if (orientation == 0) { // face TIMER
      face0 = true;
      lastFUNCTION = orientation;
      Serial.println("TIMER true");
      if (KEEPtime == false) { // timer ativado apenas se for o 1º ciclo ou foi parado
        TIMERmillis = currentMillis; // começa a contar o tempo
      }
    }
    keep = true; // [keep] muda valor para que, no próximo loop, não possa entrar nesta condição se a face não mudar (evita ativar novamente a mesma face)
  }
  
  // Esta condição é para a função shake: se você sacudir por mais de [SHAKEinterval] tempo, a face é desativada
  if (CurieIMU.getInterruptStatus(CURIE_IMU_SHOCK) && currentMillis - SHAKEpreviousMillis > SHAKEinterval) {
    Serial.println("SHAKE"); // imprime "SHAKE" se shake for detectado
    
    // A última face ativada [lastFUNCTION] é definida como false (significa que a função da face é desativada)
    // Desativação TV
    if (lastFUNCTION == 1) { // face TV
      TVChar.setValue('C'); // C: fechar sinal BLE da TV
      Serial.println("TV false - FECHAR"); // imprime a face fechada
      face1 = false; // face TV torna-se false
    }
    // Desativação LUZES
    if (lastFUNCTION == 4) { // face LUZES
      if (central.connected() == true) { // se um central está conectado ao peripheral:
        lightsChar.setValue(0); // sinal BLE luzes DESLIGADAS
        digitalWrite(LEDlights, HIGH); // abre o LED amarelo para ver o cubo no escuro
      }
      Serial.println("LUZES false - FECHAR");
      face4 = false; // face LUZES torna-se false
    }
    // OFF
    if (lastFUNCTION == 3) { // face OFF
      // Face OFF sacudida: tudo é fechado e LED vermelho OFF é aberto
      digitalWrite(LEDOFF, HIGH); // LED vermelho OFF liga quando cubo é fechado
      // Agora fecha todas as funções ativadas:
      // FECHAR TV
      TVChar.setValue('C'); // C: fechar sinal BLE da TV
      Serial.println("TV false - FECHAR");
      face1 = false;
      // FECHAR LUZES
      Serial.println("LUZES false - FECHAR");
      if (central.connected() == true) {
        lightsChar.setValue(0);
        digitalWrite(LEDlights, LOW); // LED de luzes é fechado se face OFF é sacudida
      }
      face4 = false;
      // FECHAR SOM
      analogWrite(soundLED, LOW); // fecha o LED de som
      Serial.println("SOM false - FECHAR");
      face5 = false;
      // FECHAR TEMPERATURA
      if (central.connected() == true) {
        digitalWrite(LEDhot, LOW);
        digitalWrite(LEDcold, LOW);
        termoChar.setValue(0); // sinal BLE temperatura: 0 = frio desligado - quente desligado
      }
      Serial.println("TEMPERATURA false - FECHAR");
      face2 = false;
      // FECHAR TIMER
      Serial.println("TIMER false - FECHAR");
      lcd.setRGB(0, 0, 0); // o RGB do LCD é fechado
      lcd.clear();
      KEEPtime = false;
      face0 = false;
      // O cubo está inativo, apenas LED OFF está ativo
      Serial.println("OFF false - FECHAR");
      face3 = false; // face OFF torna-se false
    }
    // Desativação SOM
    if (lastFUNCTION == 5) { // face SOM
      analogWrite(soundLED, LOW); // fecha o LED de som
      Serial.println("SOM false - FECHAR");
      face5 = false; // face SOM torna-se false
    }
    // Desativação TEMPERATURA
    if (lastFUNCTION == 2) { // face TEMPERATURA
      // Se um central está conectado ao peripheral:
      if (central.connected() == true) {
        digitalWrite(LEDhot, LOW); // fechar LED vermelho de temperatura
        digitalWrite(LEDcold, LOW); // fechar LED azul de temperatura
        termoChar.setValue(0); // sinal BLE temperatura: 0 = frio desligado - quente desligado
      }
      Serial.println("TEMPERATURA false - FECHAR");
      face2 = false; // face TEMPERATURA torna-se false
    }
    // Desativação TIMER
    if (lastFUNCTION == 0) { // face TIMER
      Serial.println("TIMER false - FECHAR");
      face0 = false; // face TIMER torna-se false
      // Se você sacudir o cubo quando o tempo está rodando, o LCD fica vermelho e mostra o tempo restante da contagem regressiva
      lcd.setRGB(180, 40, 0); // o backlight RGB torna-se vermelho
      lcd.clear(); // LCD é limpo
      lcd.setCursor(0, 0);
      lcd.print("PARAR EM ");
      lcd.setCursor(8, 0);
      lcd.print(SHOWminute); // indica os minutos quando você sacode o cubo
      lcd.setCursor(9, 0);
      lcd.print(":");
      lcd.setCursor(10, 0);
      lcd.print(SHOWseconds); // indica os segundos quando você sacode o cubo
      tone(BUZZER,1000,1000); // emite um som curto
      delay(2000);
      lcd.clear(); // limpa o LCD
      lcd.setRGB(0, 0, 0); // backlight RGB do LCD é fechado
      KEEPtime = false; // face TIMER torna-se false
    }
    SHAKEpreviousMillis = currentMillis; // memoriza o valor para o cálculo [SHAKEinterval]
  }
  
  // As instruções a seguir são executadas no loop apenas se a face estiver ativada
  if (face1 == true) { // face TV
    digitalWrite(LEDOFF, LOW); // se esta face é true, o LED da face OFF é LOW
    if (central.connected() == true) { // se o cubo está conectado via BLE
      char key = keypad.getKey(); // lê o valor do keypad
      if (key && orientation == 1){ // se algo é pressionado e apenas quando a face TV está para cima (evita pressão involuntária do keypad)
        if (key == '0') { // se a tecla pressionada é 0
          TVChar.setValue(key); // envia o valor [key] via BLE
          Serial.println(key); // imprime o botão pressionado (comente se não quiser mostrar esta informação)
        }
        if (key == '1'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '2'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '3'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '4'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '5'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '6'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '7'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '8'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '9'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '*'){ TVChar.setValue(key); Serial.println(key); }
        if (key == '#'){ TVChar.setValue(key); Serial.println(key); }
      }
    }
  }
  
  if (face4 == true) { // face LUZES
    digitalWrite(LEDOFF, LOW); // se esta face é true, o LED da face OFF é LOW
    if (central.connected() == true) { // se um central está conectado ao peripheral:
      lightsChar.setValue(1); // sinal BLE LUZES ativado
      digitalWrite(LEDlights, LOW); // LED amarelo é fechado porque as luzes da casa estão ligadas
    }
  }
  
  if (face3 == true) { // face OFF
    // Quando face OFF está para cima, nada é feito
    digitalWrite(LEDOFF, LOW); // LED OFF é ativado apenas quando o cubo é sacudido, então agora é LOW
  }
  
  if (face5 == true) { // face SOM
    digitalWrite(LEDOFF, LOW); // se esta face é true, o LED da face OFF é LOW
    // Sensor de som ativado, brilho do LED regulado pelo som
    // Este código vem do exemplo de regulação de brilho
    long sum = 0;
    for (int i=0; i<32; i++) {
      sum += analogRead(soundSENSOR);
    }
    sum >>= 5;
    brightness = (sum*255)/1024; // calcula o valor de brilho
    analogWrite(soundLED, brightness); // intensidade do brilho do LED verde é regulada pelo ruído
    delay(50);
    // Fim do exemplo de brilho
  }
  
  if (face2 == true) { // face TEMPERATURA
    digitalWrite(LEDOFF, LOW); // se esta face é true, o LED da face OFF é LOW
    if (central.connected() == true) { // se o cubo está conectado via BLE
      // lê valor de temperatura
      int val = analogRead(pinTemp); // obtém valor analógico
      resistance=(float)(1023-val)*10000/val; // obtém resistência
      temperature=1/(log(resistance/10000)/B+1/298.15)-273.15; // calcula temperatura
      // Condições de ativação
      if (temperature > tooHot) { // ativar ar condicionado
        digitalWrite(LEDhot, LOW); // fechar LED de aquecimento
        digitalWrite(LEDcold, HIGH); // abrir LED de ar condicionado
        termoChar.setValue(1); // definir via BLE a condição 1 = frio ligado - quente desligado
      }
      if (temperature < tooCold){ // ativar aquecimento
        digitalWrite(LEDhot, HIGH);
        digitalWrite(LEDcold, LOW);
        termoChar.setValue(2); // 2 = frio desligado - quente ligado
      }
      if (temperature > tooCold && temperature < tooHot){ // temperatura ideal: nada ativado
        digitalWrite(LEDhot, LOW);
        digitalWrite(LEDcold, LOW);
        termoChar.setValue(0); // 0 = frio desligado - quente desligado
      }
    }
  }
  
  if (face0 == true) { // Face TIMER ativada
    digitalWrite(LEDOFF, LOW); // se esta face é true, o LED da face OFF é LOW
    // Isto calcula o tempo para mostrar no display
    SHOWmillis = (CountdownInMillis - (currentMillis - TIMERmillis))/1000;
    SHOWminute = SHOWmillis/60; // valor de minutos para mostrar no LCD
    SHOWseconds = SHOWmillis%60; // valor de segundos para mostrar no LCD
    lcd.setRGB(50, 100, 70); // abre LCD com cor RGB azul
    if (prevSHOWsecond != SHOWseconds){ // atualiza a tela a cada segundo (porque atualizar a cada loop é muito rápido)
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("TIMER ");
      lcd.setCursor(7, 0);
      lcd.print(SETminute); // escreve os minutos que você definiu
      lcd.setCursor(8, 0);
      lcd.print(":");
      lcd.setCursor(9, 0);
      lcd.print(SETsecond); // escreve os segundos que você definiu
      lcd.setCursor(0, 1);
      lcd.print(SHOWminute); // escreve os minutos restantes atuais
      lcd.setCursor(1, 1);
      lcd.print(":");
      lcd.setCursor(2, 1);
      lcd.print(SHOWseconds); // escreve os segundos restantes atuais
      KEEPtime = true;
      prevSHOWsecond = SHOWseconds; // para atualizar a cada segundo
    }
    if (SHOWminute == 0 && SHOWseconds == 0) { // quando a contagem regressiva termina
      lcd.clear(); // limpa o LCD
      lcd.setCursor(4, 0);
      lcd.setRGB(180, 40, 0); // RGB do LCD torna-se vermelho
      lcd.print("TEMPO ESGOTADO");
      tone(BUZZER,1000,500); // três sons
      delay(900);
      tone(BUZZER,1000,500);
      delay(900);
      tone(BUZZER,1000,1000);
      delay(1500);
      lcd.clear(); // limpa e fecha o LCD
      lcd.setRGB(0, 0, 0);
      face0 = false; // Face TIMER agora está fechada (false)
      KEEPtime = false;
    }
  }
} // Fim do loop

Peças Personalizadas e Gabinetes

Este é o arquivo (.dxf) que você pode enviar para seu cortador a laser. Usei uma placa de fibra de média densidade (MDF) de 3mm. Corte as linhas pretas e grave as linhas vermelhas. Importante: se a espessura do seu material for diferente, você deve modificar este esboço.

smart_cube_8sVCflFmhM.dxf

O mesmo arquivo da caixa mas em formato diferente: .pdf

Esquemáticos

Este é um .jpeg do esquema Fritzing (fios amarelos estão conectados aos componentes Grove)

Smart Cube: Hub de Controle Residencial de Próxima Geração

Este é um esquema das conexões no Grove Shield

_cI0IwUsPVZ.Base%20shield%20connections

Processo de manufatura

  1. Painéis Solares: Um Investimento Sábio para Sua Casa
  2. Por que um Design Ligeiramente Maior Pode Acelerar Inovação e Reduzir Risco
  3. Como Tecnologia de Casa Inteligente Transforma Vida Cotidiana
  4. Construa uma Rede de Sensores Sem Fio Acessível para Sua Casa
  5. Monitore a Temperatura da Sua Casa com Dashboard no Raspberry Pi
  6. Preenchendo a Lacuna de Habilidades em Casas Inteligentes: Por Que a Grã-Bretanha Fica Atrás da Europa
  7. Evolução Casa Inteligente: O Que o Futuro Reserva para Vida Conectada
  8. Segurança Inteligente: Estratégias de Especialistas para Proteger Dispositivos IoT Domésticos de Hackers
  9. Como Fortalecer a Segurança da Sua Casa Inteligente: Dicas de Especialistas
  10. Planta Inteligente IoT: Estufa Conectada com Arduino e Azure