Page 1 of 1

ESP32 and MQTT

Posted: Sat Feb 15, 2020 10:57 pm
by Ivanhosa13
I am using a raspberry pi 3 and a ESP32. I am trying to make the ESP 32 (the client) communicate wirelessly with the pi being used as a broker. i need some help with a code that will make ESP32 connect automatically with the MQTT.
this is the code i am currently using.

Code: Select all

from time import sleep
from umqtt.simple import MQTTClient
from machine import Pin
from dht import DHT22

SERVER = '192.168.1.22'  # MQTT Server Address (Change to the IP address of your Pi)
CLIENT_ID = 'ESP32_DHT22_Sensor'
TOPIC = b'temp_humidity'

client = MQTTClient(CLIENT_ID, SERVER)
client.connect()   # Connect to MQTT broker

sensor = DHT22(Pin(15, Pin.IN, Pin.PULL_UP))   # DHT-22 on GPIO 15 (input with internal pull-up resistor)

while True:
    try:
        sensor.measure()   # Poll sensor
        t = sensor.temperature()
        h = sensor.humidity()
        if isinstance(t, float) and isinstance(h, float):  # Confirm sensor results are numeric
            msg = (b'{0:3.1f},{1:3.1f}'.format(t, h))
            client.publish(TOPIC, msg)  # Publish sensor data to MQTT topic
            print(msg)
        else:
            print('Invalid sensor readings.')
    except OSError:
        print('Failed to read sensor.')
    sleep(4)
Credits to : https://www.rototron.info/raspberry-pi- ... -tutorial/
I'm not getting errors, but when ever I restart the ESP32. It doesn’t connect back the Mqtt , I have to go back to REPL and import the code that we submit to work so all I want it to do is to connect to the Mqtt by it self.

Re: ESP32 and MQTT

Posted: Sun Feb 16, 2020 8:25 am
by kevinkk525
Your code doesn't even connect to wlan?

Re: ESP32 and MQTT

Posted: Sun Feb 16, 2020 10:46 pm
by Ivanhosa13
I am sorry, I do have a another script that makes the esp32 connect to WiFi automatically which called main.py. This is the code:

Code: Select all

 
import network
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("<your ssid>", "<password>")
Also I have a Payton script that ran on the the raspberry pi 3.which will display the temperature on an OLED.This the code

Code: Select all

 import paho.mqtt.client as mqtt
import Adafruit_SSD1306
from PIL import Image, ImageDraw, ImageFont

disp = Adafruit_SSD1306.SSD1306_128_32(rst=0)
disp.begin()
FONT_PATH = '/usr/share/fonts/truetype/piboto/PibotoCondensed-Regular.ttf'
FONT = ImageFont.truetype(FONT_PATH, 22)

def display_data(t, h):
    image = Image.new('1', (disp.width, disp.height))
    draw = ImageDraw.Draw(image)
    # Draw temperature / Humidity values.
    draw.text((0, 8), '{0}°C'.format(t),  font=FONT, fill=255)
    draw.text((71, 8), '{0}%'.format(h), font=FONT, fill=255)
    # Draw bar charts.
    draw.rectangle((0, 0, 50, 8), outline=255, fill=0)
    draw.rectangle((71, 0, 121, 8), outline=255, fill=0)
    draw.rectangle((0, 0, t / 100.0 * 50, 8), outline=255, fill=255)
    draw.rectangle((71, 0, 71 + (h / 100.0 * 50), 8), outline=255, fill=255)
    # Send to OLED display.
    disp.clear()
    disp.image(image)
    disp.display()

	# Callback fires when conected to MQTT broker.
def on_connect(client, userdata, flags, rc):
    print('Connected with result code {0}'.format(rc))
    # Subscribe (or renew if reconnect).
    client.subscribe('temp_humidity')


# Callback fires when a published message is received.
def on_message(client, userdata, msg):
	# Decode temperature and humidity values from binary message paylod.
    t,h = [float(x) for x in msg.payload.decode("utf-8").split(',')]
    print('{0}°C {1}%'.format(t, h))
    display_data(t, h)  # Display data on OLED display.


client = mqtt.Client()
client.on_connect = on_connect  # Specify on_connect callback
client.on_message = on_message  # Specify on_message callback
client.connect('localhost', 1883, 60)  # Connect to MQTT broker (also running on Pi).

# Processes MQTT network traffic, callbacks and reconnections. (Blocking)
client.loop_forever()
The first code which called the dht_publish.py that I posted in the beginning.

Re: ESP32 and MQTT

Posted: Mon Feb 17, 2020 7:21 am
by kevinkk525
you are not checking if the wlan is connected before you connect to your mqtt broker. Therefore it is possible that the connection fails because the wlan wasn't ready yet.
Put something in it like:

Code: Select all

while not wlan.isconnected():
    time.sleep(1)

Re: ESP32 and MQTT

Posted: Tue Feb 18, 2020 8:06 am
by Ivanhosa13
I am sorry to bother you , but where do you want me to put that code, in which script. I tried to put it in the end of the first script which is the dht_publish and nothing happens still the same thing. Also tried to put that code in the main script that ran on the pi 3 but it gave me an error. That wlan is undefined. Again I am so sorry, I am new to all these stuff

Re: ESP32 and MQTT

Posted: Tue Feb 18, 2020 11:04 am
by kevinkk525
Since waiting for the wlan to be correctly connected only makes sense before you connect to your broker, you have to put that code after the wlan.connect code:

Code: Select all

import network
import time
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("<your ssid>", "<password>")
while not station.isconnected():
    time.sleep(1)

Re: ESP32 and MQTT

Posted: Wed Feb 19, 2020 4:43 am
by Ivanhosa13
I am very thankful for your help , but I tried it and I didn’t work. I was thinking if you can help to put a one script that connect to the WiFi first than connect to the mqtt instead of two script.

Re: ESP32 and MQTT

Posted: Wed Feb 19, 2020 6:11 am
by DJShadow1966
Hello

Here is some code I use -
First off all my main.py

Code: Select all

import network, ntptime, utime, machine

sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.config(dhcp_hostname="ComputerTest2")
sta_if.connect('SSID', 'password')
print("Connecting ")
while not sta_if.isconnected():
    print(".", end="")
    utime.sleep(1)

try:
    ntptime.settime()
except:
    pass

import mqtt.py

and the the mqtt.py which I use to connect to the mqtt broker

Code: Select all

import time, ubinascii, machine, network, esp, esp32, am2320
from umqtt.robust import MQTTClient
from machine import Pin, I2C
from time import sleep

def handle_interrupt(pin):
    global motion
    motion = True
    global interrupt_pin
    interrupt_pin = pin 

def sub_cb(topic, msg):
  if topic == b'notification' and msg == b'received':
    print('ESP received hello message')

def connect_and_subscribe():
  global client_id, mqtt_server, topic_sub
  client = MQTTClient(client_id, mqtt_server)
  client.set_callback(sub_cb)
  client.connect()
  client.subscribe(topic_sub)
  return client

def restart_and_reconnect():
  print('Failed to connect to MQTT broker. Reconnecting...')
  time.sleep(10)
  machine.reset()
  
# pir = Pin(18, Pin.IN) # Pir sensor output on Pin 18
led = Pin(2, Pin.OUT) # Set for pin 2 Blue led temporary then change to Pin 19
i2c = I2C(1, scl=Pin(5), sda=Pin(4), freq=400000)
senam2320 = am2320.AM2320(i2c)
savtrig = 0
motion = True

mqtt_server = '192.168.168.209'
client_id = ubinascii.hexlify(machine.unique_id())
topic_sub = 'Computer-Desk-IOT'

last_message = 0
message_interval = 5
counter = 0
period = 0

esp.osdebug(None)
import gc
gc.collect()

try:
  client = connect_and_subscribe()
except OSError as e:
  restart_and_reconnect()

# pir.irq(trigger=Pin.3, handler=handle_interrupt)

while True:
    client.check_msg()
    if (time.time() - last_message) > message_interval:
        try:
            senam2320.measure()
        except:
            pass
        if motion:
            trig = pir.value()
            if (trig == 0):
                if (savtrig == 1):
                    period = time.time() - savtime
                    if (period >= 120):
                        savtrig = 0
                        savtime = time.time()

            if (trig == 1):
                savtrig = pir.value()
                savtime = time.time()        
        
        client.publish("desk/Temp", str(senam2320.temperature()))
        client.publish("desk/Humidity", str(senam2320.humidity()))
        # client.publish("pir/PIR", str(savtrig))
        last_message = time.time()
        counter += 1
        led.value(not led.value())
        sleep(0.5)
        led.value(not led.value())
        sleep(9.5)
        gc.collect()
I know it is a bit dirty coding but works for me and when I get time going to clean it up

Regards Mike

Re: ESP32 and MQTT

Posted: Wed Feb 19, 2020 6:52 am
by Ivanhosa13
Thank you for the help , I have a question, For the mqtt script, is it just for the temperature sensor or do you have other sensors that are connected to it.

Re: ESP32 and MQTT

Posted: Wed Feb 19, 2020 7:27 am
by DJShadow1966
Hello

On the code there currently is only one sensor that does humidty and Temperature, the code is part of my master code for multiple ESP32's dotted around my house thats why I have #ed out some code, it is still a work in progress.

If I get some free time today I am going to be working on it to streamline it and add comments.

Regards Mike