Skip to content

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.

alt text

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;

alt text

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. alt text

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:
alt text

I need to include the DHT.hfile.

alt text

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 : alt text

if not, just install it : alt text

if fail to upload, then try upload again with holding on Boot and press on Reset button on the board.

alt text

Success! alt text

Switch to Serial Monitor to see no returned values, then Press Reset button on the board. alt text

alt text

Resluts/ HeroShot

alt text alt text alt text

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.

alt text

Parametric design:
alt text