Last Updated or created 2024-07-06
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.
Schematics (without the wireless charging 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 = "xxxxxx";
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
}
]