I will use these last two blogs to only document the project I have done so far. Though I feel that there is still many things on which I could improve,

add more components and code but I am happy with what I was able to do in this challenge.

 

There are currently the following parts of the project.

 

  1. Raspberry Pi 4B
  2. Pimoroni Automation HaT
  3. Pimoroni Enviro HaT
  4. DPS310 Sensor
  5. ESP8266 + BME280 (MQTT Publishing)
  6. WemosD1R1 + BME280 (MQTT Publishing)
  7. Esp32 Pico V4 + RGB LED Strip (MQTT Subscribing)

 

 

Let me first explain what the project is doing. The RaspberryPi is controlling everything. There are sensors on Enviro-Hat and ESP's sending data over

MQTT and Automation Hat's LCD is used to display the data of the sensors.

 

I have kept publishing and subscribing ESPs separately. In the beginning, I wanted to use ESP8266 for subscribing + publishing the topics but I found some

issues are there with the libraries to do both subscription and publishing at the same time on ESPs. Hence, I decided to only do a subscription for controlling

LED Strips. The LED Strips are controlled in brightness. When an "ON" message is published on a topic by Raspberry Pi LED Strip will start with Lower brightness

and eventually, it will reach full brightness. It will take around 15 mins to blick the entire strip to full brightness.

 

The color of the strip is normally kept magenta pink as that is the wavelength required by the plants growing in space.

 

The following code is for controlling the LED strips over MQTT. There are two separate functions to Turn ON/OFF the strip. The topic is published by RaspberryPi.

The ESP32 will subscribe to that topic.

 

There is the possibility to Turn ON/OFF the LED strip at a specific time of the day.

 

now = datetime.now()
c_t = now.strftime("%H:%M:%S")
print("Current time = ", c_t)

if(c_t > '05:16:12'):
     #Publish ON

 

 

 

 

 

//ESP32 Pico code

#include <SPI.h>
#include <MQTT.h>
#include "WiFi.h"
#include <FastLED.h>


#define NUM_LEDS 120
#define DATA_PIN 15
String start = "";

CRGB leds[NUM_LEDS];

const char *ssid = "PiFi";
const char *Pass = "PSK";
const char *Lighttopic = "LEDStrip";
const char *mqtt_username = "ujjval";
const char *mqtt_pass = "PSK";
const char *client_ID = "IDOFCLIENT";
const char* mqtt_server = "192.168.43.71";

WiFiClient WiFiclient;
MQTTClient cl1;


void messageReceived(String &topic, String &payload){
  Serial.println("incoming: " + topic + " - " + payload);
  if(payload=="ON" & start!="started"){
    control_lights_on();
    }
  else if(payload=="OFF"){
    control_lights_off();
    }
  }


void setup() {
  // put your setup code here, to run once:
  delay(2000);
  FastLED.addLeds<WS2811, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(100);
  Serial.begin(9600);
  Serial.print("Connecting to the WiFi..");
  Serial.print(ssid);
  WiFi.begin(ssid, Pass);


  while(WiFi.status() != WL_CONNECTED){
    Serial.print("..");
    delay(500);
    }
  cl1.begin(mqtt_server, 1883, WiFiclient);
  cl1.onMessage(messageReceived);
  if(!cl1.connect(client_ID, mqtt_username, mqtt_pass, false)){
    Serial.print("..");
    delay(500);
    }
}

void loop() {
  // put your main code here, to run repeatedly:

  cl1.loop();
  delay(10);
  if(!cl1.connected()){
    cl1.connect(client_ID, mqtt_username, mqtt_pass);
    delay(20);
    }
  Serial.println("Connected to LEDStrip");
  cl1.subscribe("LEDStrip");
  cl1.loop();
  delay(10);
  delay(10);
  //LED Strip programming
   delay(10);
}

void control_lights_on(){
  start="started";
  for(int bright=10; bright<=150; bright++){
    for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1){
      // Turn our current led on to white, then show the leds
      leds[whiteLed] = CRGB::Purple;
      
      // Show the leds (only one of which is set to white, from above)
      FastLED.show();
      FastLED.setBrightness(bright);
    // Wait a little bit
      delay(10);
      //leds[whiteLed] = CRGB::Black;
      delay(10);
    }
    delay(5000);
  }
  }
  
void control_lights_off(){
  for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
          leds[whiteLed] = CRGB::Black;
          FastLED.show();
          delay(10);
  }
  start = "";
  }

 

 

The ESP8266 and Wemos D1R1 with BME280 has almost a similar code running. They will gather the temperature/humidity data from the sensor and publish it on the respective topics.

 

//ESP8266 code
#include <Wire.h>
#include <PubSubClient.h>
#include <Adafruit_BME280.h>
#include "ESP8266WiFi.h"


const char *ssid = "PiFi";
const char *Pass = "";
const char *Humiditytopic = "ESP8266_humy";
const char *Temperature  "ESP8266_temp";
const char *mqtt_username = "ujjval";
const char *mqtt_pass = "";
const char *client_ID = "";
const char* mqtt_server = "192.168.43.71";


Adafruit_BME280 bme;


float t,h,p;


WiFiClient WiFiclient;
PubSubClient client(mqtt_server, 1883, WiFiclient);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("Connecting to the WiFi..");
  Serial.print(ssid);
  WiFi.begin(ssid, Pass);


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


  if(client.connect(client_ID, mqtt_username, mqtt_pass)){
    Serial.println("Connected to MQTT client..");
    }
    else{
      Serial.println("Connection to WifiClient failed.");
      }
  
  Serial.println("BME280 test");
  bme.begin(0x76);
}


void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("The weather data from the BME280 sensor..");
  Serial.print("Temp = ");
  t = bme.readTemperature();
  Serial.print(t);
  Serial.print(" *C");
  Serial.println();
  Serial.print("Humidity = ");
  h = bme.readHumidity();
  Serial.print(h);
  Serial.print(" %");
  Serial.println();
  Serial.print("Pressure = ");
  Serial.print(bme.readPressure());
  Serial.print(" hPa");
  Serial.println();
  Serial.println();
  delay(50);


  if(client.publish(Temperature, String(t).c_str())){
    Serial.println("Temprature is sent on MQTT");
    
    }
  else{
    Serial.print("Temprature failed to send, reconnecting and trying again");
    Serial.println();
    client.connect(client_ID, mqtt_username, mqtt_pass);
    delay(10);
    client.publish(Temperature, String(t).c_str());
    delay(10);
      }
   if(client.publish(Humiditytopic, String(h).c_str())){
    Serial.println("Humidity is sent on MQTT");
    }
   else{
    Serial.println();
    Serial.print("Humidity failed to send, reconnecting and trying again");
    client.connect(client_ID, mqtt_username, mqtt_pass);
    delay(10);
    client.publish(Humiditytopic, String(t).c_str());
    }
  delay(1000);
}

 

The Wemos D1 is running the following code

//Wemos D1 R1 code
#include <Wire.h>
#include <PubSubClient.h>
#include <Adafruit_BME280.h>
#include "ESP8266WiFi.h"


const char *ssid = "PiFi";
const char *Pass = "";
const char *Humiditytopic = "/home/top/humidity";
const char *Temperature = "/home/top/temperature";
const char *Lighttopic = "LEDStrip";
const char *mqtt_username = "ujjval";
const char *mqtt_pass = "";
const char *client_ID = "";
const char* mqtt_server = "192.168.43.71";  


byte* light;
Adafruit_BME280 bme;


float t,h,p;
WiFiClient WiFiclient;


PubSubClient client(mqtt_server, 1883, WiFiclient);
//client->setCallback(callback);




void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("Connecting to the WiFi..");
  Serial.print(ssid);
  WiFi.begin(ssid, Pass);


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


  if(client.connect(client_ID, mqtt_username, mqtt_pass)){
    Serial.println("Connected to MQTT client..");
    }
    else{
      Serial.println("Connection to WifiClient failed.");
      }
  Serial.println("BME280 test");
  bme.begin(0x76);
  
  
}


void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("The weather data from the BME280 sensor..");
  Serial.print("Temp = ");
  t = bme.readTemperature();
  Serial.print(t);
  Serial.print(" *C");
  Serial.println();
  Serial.print("Humidity = ");
  h = bme.readHumidity();
  Serial.print(h);
  Serial.print(" %");
  Serial.println();
  Serial.print("Pressure = ");
  Serial.print(bme.readPressure());
  Serial.print(" hPa");
  Serial.println();
  Serial.println();
  delay(50);
  
  if(!client.connected()){
    client.connect(client_ID, mqtt_username, mqtt_pass);
    }
  
  if(client.publish(Temperature, String(t).c_str())){
    Serial.println("Temprature is sent on MQTT");
    }
  else{
      Serial.print("Temprature failed to send, reconnecting and trying again");
      client.connect(client_ID, mqtt_username, mqtt_pass);
      delay(10);
      client.publish(Temperature, String(t).c_str());
      delay(10);
      }
  if(client.publish(Humiditytopic, String(h).c_str())){
    Serial.println("Humidity is sent on MQTT");
    }
  else{
      Serial.println();
      Serial.print("Humidity failed to send, reconnecting and trying again");
      client.connect(client_ID, mqtt_username, mqtt_pass);
      delay(10);
      client.publish(Humiditytopic, String(t).c_str());
      }
  client.disconnect();
  delay(100);
  
  Serial.println("Connected to LEDStrip");
}

 

The Raspberrypi has both the HaT's and programmed in Python to control everything automatically. The LCD on the Automation HaT will display data

from sensors connected over MQTT and data from Enviro as well.

 

#!/usr/bin/env python3
import os
import sys
import time
import bme280
import smbus2
from ltr559 import LTR559
sys.path.append(os.path.abspath("/home/pi/1m3pi/MqTT.py"))
sys.path.append(os.path.abspath("/home/pi/1m3pi/Disp.py"))
from Disp import *
import paho.mqtt.client as mqtt
import paho.mqtt.subscribe as subscribe
import paho.mqtt.publish as publish
import DPS
from struct import *
from datetime import *


dps310 = DPS.DPS()


ser_add = '192.168.43.71'
Wemos_temp = '/home/top/temperature'
Wemos_humy = '/home/top/humidity'
Esp_temp = 'ESP8266_temp'
Esp_humy = 'ESP8266_humy'
Lighttopic = 'LEDStrip'
mqtt_user =''
mqtt_pass =''


ltr559 = LTR559()


port = 1
address = 0x76
bus = smbus2.SMBus(port)
cal_par = bme280.load_calibration_params(bus, address)


def on_connect(wemos_client, userdata, flags, rc):
    #print('connected with code' + str(rc))
    wemos_client.subscribe((Wemos_temp,0))
    wemos_client.subscribe((Wemos_humy,0))
    wemos_client.publish("LEDStrip","ON")
    sleep(0.5)
    
def on_publish(wemos_client, userdata,mid):
    print ("This call is from the pblish callback\n"
    "Which means that your message was published")
    
def on_connect1(esp_client, userdata, flags, rc):
    #print('connected with code' + str(rc))
    esp_client.subscribe((Esp_temp,0))
    esp_client.subscribe((Esp_humy,0))


def on_message(wemos_client, userdata, msg):
    payload = msg.payload
    print(msg.topic)
    global wemos_t, wemos_h
    if(msg.topic=='/home/top/temperature'):
        wemos_t = float(msg.payload)
    else:
        wemos_h = float(msg.payload)
    print(float(payload))
    
def on_message1(esp_client, userdata, msg):
    payload = msg.payload
    print(msg.topic)
    global esp_t, esp_h
    if(msg.topic=='ESP8266_temp'):
        esp_t = float(msg.payload)
    else:
        esp_h = float(msg.payload)
    print(float(payload))


def on_disconnect(self, wemos_client, userdata, rc):
    self.disconnected.set_result(rc)


def on_disconnect1(self, esp_client, userdata, rc):
    self.disconnected.set_result(rc)
    
def get_remote_temp():
    
    wemos_client = mqtt.Client()
    wemos_client.username_pw_set(mqtt_user, mqtt_pass)
    wemos_client.on_connect = on_connect
    wemos_client.on_message = on_message
    wemos_client.on_publish = on_publish
    wemos_client.on_disconnect = on_disconnect
    wemos_client.loop_start()
    wemos_client.connect(ser_add, 1883)
    sleep(2)
    wemos_client.loop_stop()
    esp_client = mqtt.Client()
    esp_client.username_pw_set(mqtt_user, mqtt_pass)
    esp_client.on_connect = on_connect1
    esp_client.on_message = on_message1
    esp_client.on_disconnect =on_disconnect1
    esp_client.loop_start()
    esp_client.connect(ser_add, 1883)
    sleep(2)
    esp_client.loop_stop()
    
def main():
    while True:
        global wemos_t, wemos_h,esp_t, esp_h
        wemos_t = 0.00
        wemos_h = 0.00
        esp_t = 0.00
        esp_h = 0.00
        data = bme280.sample(bus, address, cal_par)
        print("Temprature",data.temperature)
        print("Humidity", data.humidity)
        print("Now printing the LTR sensor data....")
        ltr559.update_sensor()
        lux = ltr559.get_lux()
        prox = ltr559.get_proximity()
        print("Lux ", lux, "Proximity ", prox)
        scaled_p = dps310.calcScaledPressure()
        scaled_t = dps310.calcScaledTemperature()
        p = dps310.calcCompPressure(scaled_p, scaled_t)
        t = dps310.calcCompTemperature(scaled_t)
        print("Temprature", t)
        print("Dsp_press", p)
        get_remote_temp()       
        colour = (255, 181, 86)
        font = ImageFont.truetype(UserFont, 12)
        bar_height = disp1.height
        bar_width = disp1.width
        img=Image.new('RGB',(bar_width, bar_height), color=(0,0,0))
        draw = ImageDraw.Draw(img)
        rect_color =(0,180,180)
        draw.rectangle((0,0,160,80), rect_color)
        font_size = 25
        #font = ImageFont.truetype("fonts/Asap/Asap-Bold.ttf", font_size)
        colour=(255,255,255)
        temp="T1: {:.2f} *C".format(data.temperature)
        dsp_temp = "T2: {:.2f} *C".format(t)
        esp_temp ="T3: {:.2f} *C".format(esp_t)
        wemos_temp ="T3: {:.2f} *C".format(wemos_t)
        
        humy="H1: {:.2f} %".format(data.humidity)
        humy1="H2: {:2f} %".format(esp_h)
        humy3="H3: {:2f} %".format(wemos_h)
        
        lux = "Lux: {:.2f} ".format(lux)
        
        draw.text((0,0), temp, font=font, fill=colour)
        draw.text((0,10),dsp_temp, font=font, fill=colour)
        draw.text((0,20),esp_temp, font=font, fill=colour)
        draw.text((0,30),wemos_temp, font=font, fill=colour)
        
        draw.text((0,40),humy, font=font, fill=colour)
        draw.text((0,50),humy1, font=font, fill=colour)
        draw.text((0,60),humy3, font=font, fill=colour)
        
        draw.text((90,0),lux, font=font, fill=colour)
        
        disp.display(img)
        disp1.display(img)
        sleep(1)
        
if __name__ == "__main__":
    main()

 

from time import sleep
try:
    from PIL import Image, ImageFont, ImageDraw
except ImportError:
    print("""This example requires PIL.
Install with: sudo apt install python{v}-pil
""".format(v="" if sys.version_info.major == 2 else sys.version_info.major))
    sys.exit(1)


import ST7735 as ST7735
try:
    from fonts.ttf import RobotoBlackItalic as UserFont
except ImportError:
    print("""This example requires the Roboto font.
Install with: sudo pip3 install fonts font-roboto
""")
    sys.exit(1)
    
disp = ST7735.ST7735(
    port=0,
    cs=1,
    dc=9,
    backlight=25,
    rotation=270,
    spi_speed_hz=4000000
)


disp1 = ST7735.ST7735(
    port=0,
    cs=0,
    dc=9,
    backlight=12,
    rotation=270,
    spi_speed_hz=4000000
)


# Initialise display.
disp.begin()
sleep(1)
disp1.begin()

Let's first have a look at the photos