Hex Dimmer

Last Updated or created 2022-09-27

Control a dimmer using a hex wireless box.

Parts

  • Wemos Mini
  • MPU6050 – Gyroscope Module
  • 10k Resistor
  • TP4056 – Battery Charger Module
  • Mini Battery
  • Wireless Charger

Put the box flat on the table to switch off.
When you put it on one side, it will controll your lights brightness.
20,40,60,80 and 100%, just by rotating and putting it down on its sides.

3D printed case

Schematics (without the wireless charging part)

Wireless part

Node-Red Controll part (source below)

Nice to have’s :
Arduino-sleep mode, wakeup with a movement sensor.

Arduino Code

#include <Wire.h>
//#include <SPI.h>
#include <PubSubClient.h>
//#include <string.h>
//#include <stdio.h>
#include <ESP8266WiFi.h>

// Wifi settings
const char* ssid = "MTAP1";
const char* password = "xxxxxxxxxx";
const char* mqtt_server = "10.1.0.17";

// I2C address of the MPU-6050 - 0x68 or 0x69 if AD0 is pulled HIGH
const int MPU = 0x68;
int16_t AcX, AcY, AcZ, GyX, GyY, GyZ;
float gForceX, gForceY, gForceZ, rotX, rotY, rotZ;

// Wifi MAC address
byte mac[]= {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };

WiFiClient espClient;
IPAddress ip;
PubSubClient mqttClient(espClient);

// IP address of your MQTT server
const char* server = "10.1.0.17";
//const char* outTopic = "test/";
//const char* server = "iot.eclipse.org";

void dataReceiver(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
  AcX = Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)     
  AcY = Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  AcZ = Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  GyX = Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY = Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  GyZ = Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  processData();
}

void processData(){
  gForceX = AcX / 16384.0;
  gForceY = AcY / 16384.0; 
  gForceZ = AcZ / 16384.0;
  
  rotX = GyX / 131.0;
  rotY = GyY / 131.0; 
  rotZ = GyZ / 131.0;
}

void debugFunction(int16_t AcX, int16_t AcY, int16_t AcZ, int16_t GyX, int16_t GyY, int16_t GyZ){
  // Print the MPU values to the serial monitor
  Serial.print("Accelerometer: ");
  Serial.print("X="); Serial.print(gForceX);
  Serial.print("|Y="); Serial.print(gForceY);
  Serial.print("|Z="); Serial.println(gForceZ);  
  Serial.print("Gyroscope:");
  Serial.print("X="); Serial.print(rotX);
  Serial.print("|Y="); Serial.print(rotY);
  Serial.print("|Z="); Serial.println(rotZ);
}

void reconnect() {
  // Loop until we're reconnected
  while (!mqttClient.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (mqttClient.connect("arduinoClient")){
      Serial.println("connected");
    } 
    else {
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
//      Wait 5 seconds before retrying
      delay(1000);
    }
  }
}

void setup(){
  Serial.begin(9600);

    setup_wifi();
  
  Wire.begin(0,2);
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  mqttClient.setServer(server, 1883);
  
//  Ethernet.begin(mac);
//  ip = Ethernet.localIP();
  
  Serial.println(ip);  
  Serial.println(server);
  //delay(1500);
}

char* init(float val){
  
  char buff[100];

  for (int i = 0; i < 100; i++) {
      dtostrf(val, 4, 2, buff);  //4 is mininum width, 6 is precision
  }
   return buff;

}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void dataAcc(){

  char mpu6050X[100]= "";   
  strcat(mpu6050X,init(gForceX));

  char mpu6050Y[100]= "";   
  strcat(mpu6050Y,init(gForceY));

  char mpu6050Z[100]= "";   
  strcat(mpu6050Z,init(gForceZ));

  // accelerometer - "topic, mpu6050"
  mqttClient.publish("AcX/", mpu6050X);
  mqttClient.publish("AcY/", mpu6050Y);
  mqttClient.publish("AcZ/", mpu6050Z);
//  mqttClient.publish(outTopic, "text to send via mqtt");
}


void dataGy(){

  char mpu6050X[100]= "";
  strcat(mpu6050X,init(rotX));

  char mpu6050Y[100]= "";
  strcat(mpu6050Y,init(rotY));

  char mpu6050Z[100]= "";
  strcat(mpu6050Z,init(rotZ));
  
  // gyroscope - "topic, mpu6050"
  mqttClient.publish("GyX/", mpu6050X);
  mqttClient.publish("GyY/", mpu6050Y);
  mqttClient.publish("GyZ/", mpu6050Z);
//  mqttClient.publish(outTopic, "text to send via mqtt");
}

void loop(){
  dataReceiver();
  debugFunction(AcX,AcY,AcZ,GyX,GyY,GyZ);

  if (!mqttClient.connected()) {
    reconnect();
  }

  mqttClient.loop(); 

  dataAcc();
  dataGy();

  delay(2000);
}

Nodered Flow

[
    {
        "id": "7550958a.b29dec",
        "type": "mqtt in",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "topic": "hex/x",
        "qos": "2",
        "broker": "8c74c5f6.9a7a48",
        "x": 270,
        "y": 100,
        "wires": [
            [
                "d251dd79.5700d"
            ]
        ]
    },
    {
        "id": "e84b0a1.18096f8",
        "type": "mqtt in",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "topic": "hex/y",
        "qos": "2",
        "broker": "8c74c5f6.9a7a48",
        "x": 270,
        "y": 180,
        "wires": [
            [
                "9c27bc8f.b62dd"
            ]
        ]
    },
    {
        "id": "6a1a0d8d.b3e754",
        "type": "mqtt in",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "topic": "hex/z",
        "qos": "2",
        "broker": "8c74c5f6.9a7a48",
        "x": 270,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "2d2a911a.6af3fe",
        "type": "ui_gauge",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "group": "d43a9f25.6c874",
        "order": 23,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "gauge",
        "label": "units",
        "format": "{{value}}",
        "min": "0",
        "max": "100",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 1010,
        "y": 120,
        "wires": []
    },
    {
        "id": "d251dd79.5700d",
        "type": "function",
        "z": "a0126a6a.9c70b8",
        "name": "Get level from box",
        "func": "var my=msg.payload;\nmsg.payload = {};\nif (my == 0.85){\n    msg.payload=20;\n    return msg;\n}\nelse if (my == 0.86){\n    msg.payload=20;\n    return msg;\n}\nelse if (my == 0.87){\n    msg.payload=20;\n    return msg;\n}\n\nelse if (my == 0.03){\n    msg.payload=40;\n    return msg;\n}\nelse if (my == 0.02){\n    msg.payload=40;\n    return msg;\n}\n\nelse if (my == 3.17){\n    msg.payload=60;\n    return msg;\n}\nelse if (my == 3.18){\n    msg.payload=60;\n    return msg;\n}\n\nelse if (my == 0.04){\n    msg.payload=80;\n    return msg;\n}\nelse if (my == 0.05){\n    msg.payload=80;\n    return msg;\n}\n\nelse if (my == 3.95){\n    msg.payload=100;\n    return msg;\n}\nelse if (my == 3.96){\n    msg.payload=100;\n    return msg;\n}\nelse {\n    return msg;\n    \n}\n",
        "outputs": 1,
        "noerr": 0,
        "x": 510,
        "y": 120,
        "wires": [
            [
                "ecd746cc.fce348",
                "8721e902.45d8b8",
                "39c8f1ac.86affe"
            ]
        ]
    },
    {
        "id": "39c8f1ac.86affe",
        "type": "function",
        "z": "a0126a6a.9c70b8",
        "name": "Set Living spots level (idx 5)",
        "func": "var level = Number(msg.payload);\nmsg.payload = {};\nmsg.payload.idx = 5;\nmsg.payload.switchcmd = (\"Set Level\");\nmsg.payload.command = \"switchlight\";\nmsg.payload.level = level;\nreturn msg;  ",
        "outputs": 1,
        "noerr": 0,
        "x": 820,
        "y": 260,
        "wires": [
            [
                "bc0d6507.1d7748"
            ]
        ]
    },
    {
        "id": "bc0d6507.1d7748",
        "type": "mqtt out",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "topic": "domoticz/in",
        "qos": "",
        "retain": "",
        "broker": "8c74c5f6.9a7a48",
        "x": 1080,
        "y": 260,
        "wires": []
    },
    {
        "id": "9c27bc8f.b62dd",
        "type": "function",
        "z": "a0126a6a.9c70b8",
        "name": "Flat or standing up",
        "func": "var mya=msg.payload;\nmsg.payload = {};\nif (mya < -3.80){\n    flow.set(\"levely\",1);\n    msg.payload  = \"plat\";\n        }\nelse {\n    flow.set(\"levely\",2);\n    msg.payload  = \"rechtop\";\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 450,
        "y": 200,
        "wires": [
            [
                "ecd746cc.fce348"
            ]
        ]
    },
    {
        "id": "ecd746cc.fce348",
        "type": "debug",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 640,
        "y": 340,
        "wires": []
    },
    {
        "id": "8721e902.45d8b8",
        "type": "function",
        "z": "a0126a6a.9c70b8",
        "name": "Gate for level ",
        "func": "\nvar x = msg.payload;\ny = flow.get(msg.payload);\nvar y = flow.get('levely') || 0;\n\nif (y == 1){\n    msg.payload = {};\n        msg.payload = 0;\n} else {\n    msg.payload = x;\n}\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 810,
        "y": 120,
        "wires": [
            [
                "2d2a911a.6af3fe",
                "da72437e.88376"
            ]
        ]
    },
    {
        "id": "da72437e.88376",
        "type": "debug",
        "z": "a0126a6a.9c70b8",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 890,
        "y": 200,
        "wires": []
    },
    {
        "id": "8c74c5f6.9a7a48",
        "type": "mqtt-broker",
        "z": "",
        "name": "10.1.0.17",
        "broker": "10.1.0.17",
        "port": "1883",
        "clientid": "",
        "usetls": false,
        "compatmode": true,
        "keepalive": "15",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": ""
    },
    {
        "id": "d43a9f25.6c874",
        "type": "ui_group",
        "z": "",
        "name": "Control",
        "tab": "739541e2.18396",
        "order": 1,
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "739541e2.18396",
        "type": "ui_tab",
        "z": "",
        "name": "7inch",
        "icon": "dashboard",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]