20. Final Project Requirements¶
This week, I am going to do ‘Data visualization & to control color of a LED strip remotely over the Internet using MQTT protocol’.
Demonstrate workflows used in this project¶
Definition of User Interface¶
The user interface will provide two icons corresponding to the functions:
1 Colorwheel
This icon allows users to pick their favorite color.Once selection is confirmed,the color of a Lamp will be changed into that color.
2 Data visualization
This icon will display the current temperature/humidity value of the sensor.
Workflows¶
Color control part: In this case, the application operated by the user (I will use MQTT Dashboard) will act as a Publisher, sending the RGB value of the color to the MQTT broker; XIAO ESP32C3 is set as a Subscriber, listening to the topic (fabacademy/LampColor), receiving the RGB value, processing it in the program, and switching the Lamp color through the D1 pin after the converted RGB value;
Data visualization:
In this case, XIAO ESP32C3 will act as a Publisher, receiving the temperature and humidity values ββtransmitted by the temperature and humidity sensor through the D2 pin, and uploading it to the MQTT broker through its own wifi module; the MQTT Dashboard on the mobile phone is set as a subscriber, listening to the topic (fabacademy/LampTemprature or fabacademy/LampHumidity), and displays the received data on the user interface.
Select and apply suitable processes (and materials) for this project¶
Preparation - software & materials¶
For user interface: MQTT Dash, for Google Play; For Android;
For programming : Arduino IDE;
Materials :
LED strip;
Grove DHT11;
PCB I made;
Embedded Programming¶
Trouble-shoot:
I need to include the DHT.h
file.
In Arduino, the #include statement uses angle brackets (<>) or double quotes (“) to search for a file when creating a library: Angle brackets (<>): Searches the library’s paths for the file. Double quotes (“): Searches the folder of the file using the #include directive, then the library’s paths if the file isn’t found in the local path. This syntax is used for header files in the sketch’s folder.
Make sure you have these header files :
if not, just install it :
if fail to upload, then try upload again with holding on Boot
and press on Reset
button on the board.
Success!
Switch to Serial Monitor to see no returned values, then Press Reset
button on the board.
Resluts/ HeroShot¶
Source Code¶
/*
Originally from MQTT ESP8266 Example
Basic XIAO-ESP32 MQTTS example
Before starting , You should have
- MQTT Broker Name
- MQTT Broker Username
- MQTT Borker Password
Modified by Salman Faris - Added MQTTS Implimenation as per ESP32 and MQTTS.
Modified by Dion Tsang - Added Colorwheel, DHT Datavisualization.
*/
#include <WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define DHTPIN D2
#define DHTTYPE DHT11 // DHT 11
#define NUMPIXELS 80 // Popular NeoPixel ring size
#define PIN D1
#define BUF_SIZE (100)
#define BUF_SIZE2 (100)
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor.
Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 20 // Time (in milliseconds) to pause between pixels
// Update these with values suitable for your network.
const char* ssid = "AndroidAP26ab"; // WiFi Name
const char* password = "tawd7050"; // WiFi Password
const char* mqtt_server = "mqtt.fabcloud.org"; //MQTT Broker Name
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;
// int BUILTIN_LED = D10
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(DELAYVAL);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.print("This is length");
Serial.print(length);
Serial.println();
if (strcmp(topic, "fabacademy/myLampSwitch") == 0) {
if ((char)payload[0] == '1') {
pixels.clear(); // Set all pixel colors to 'On'
for (int i = 0; i < NUMPIXELS; i++) {
// pixels.setPixelColor(i, pixels.Color(0, 150, 0));
pixels.setPixelColor(i,0xDE3759);
}
pixels.show(); // Send the updated pixel colors to the hardware
} else if ((char)payload[0] == '0') {
pixels.clear(); // Set all pixel colors to 'Off'
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
pixels.show(); // Send the updated pixel colors to the hardware
}
}
if (strcmp(topic, "fabacademy/LampColor") == 0) {
// Parse the hex color code from the payload
char hexColor[7] = { 0 }; // 6 characters + null terminator
if (length == 7) {
// strncpy(hexColor, (char*)payload, 6);
for (int i=1; i <length;i++){
hexColor[i-1]=(char)payload[i];
Serial.println(hexColor[i-1]);
}
hexColor[6] = '\0'; // Ensure null-terminated string
// Serial.println(hexColor);
// Convert hex color code to a 32-bit integer
uint32_t color = (uint32_t)strtol(hexColor, NULL, 16);
// Extract RGB components from the 32-bit color value
byte red = (color >> 16) & 0xFF;
byte green = (color >> 8) & 0xFF;
byte blue = color & 0xFF;
// Set the NeoPixel color using the 32-bit integer
pixels.clear();
for (int i = 1; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(red, green, blue));
}
pixels.show(); // Send the updated pixel colors to the hardware
}
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "XIAO-ESP32-Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
// if (client.connect(clientId.c_str())) {
if (client.connect(clientId.c_str(), "fabacademy", "fabacademy")) {
Serial.println("connected");
// Once connected, publish an announcement...
//client.publish("fabacademy/dionTest/Temperature", "hello world");
// ... and resubscribe
client.subscribe("fabacademy/myLampSwitch");
client.subscribe("fabacademy/LampColor");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(DELAYVAL);
}
}
}
void setup() {
// pinMode(PIN, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
dht.begin();
// END of Trinket-specific code.
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
delay(DELAYVAL);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
char tempra[BUF_SIZE];
snprintf(tempra, BUF_SIZE, "%f", t);
client.publish("fabacademy/Temprature", tempra);
char humidity[BUF_SIZE2];
snprintf(humidity, BUF_SIZE2, "%f", h);
client.publish("fabacademy/Humidity", humidity);
}
For 2D & 3D¶
This file shows the 2D & 3D of the project,with parametic design.
Parametric design: