This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:iot-open:remotelab:sut:generalpurpose2:u3 [2019/10/29 22:23] – pczekalski | en:iot-open:remotelab:sut:generalpurpose2:u3 [2021/02/27 12:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ==== U3: Sending MQTT messages ==== | ||
| + | In this scenario, you will send MQTT message exposing temperature and humidity to the MQTT server available on the '' | ||
| + | === Target group === | ||
| + | Undergraduate / Bachelor / Engineering Students | ||
| + | === Prerequisites === | ||
| + | We assume you already know how to: | ||
| + | * handle DHT sensor to read temperature and humidity, | ||
| + | * handle LCD screen to present information, | ||
| + | * connect to the existing WiFi network: '' | ||
| + | * additionally we will ask you to install and use an MQTT client of your choice. We suggest using [[https:// | ||
| + | |||
| + | MQTT broker present in the '' | ||
| + | |||
| + | === Scenario === | ||
| + | In this scenario, you will connect to the infrastructure as a client (STA) and use the MQTT server to publish information about temperature, | ||
| + | <note important> | ||
| + | |||
| + | === Result === | ||
| + | You should be able to see connection status, temperature and humidity on the screen while your MQTT subscriber should be able to present you readings delivered via MQTT. It should be equal to the data presented in the LCD screen you observe locally, via video stream. | ||
| + | |||
| + | === Start === | ||
| + | Define some identifiers to separate and update AP's SSID and passphrase easily. To format lines for the LCD, we suggest using a char buffer of 20 characters (one full line) and some 2-3 integers for iterators. Remember to declare the LCD control class in your code. You do not need to instantiate the WiFi communication class - as you have only one interface here, it is a singleton class you can refer to directly using WiFi. Note - in this scenario, you connect only once. If your connection breaks, you will have no information about it here. To handle such a situation, there are multiple solutions: you can check in the loop() if the connection is OK and in case it is down, you can call your re-connecting function, or you can use one of the asynchronous handlers, triggered automatically via the WiFi manager. To use the latter approach, refer to the ESP8266 WiFi implementation for Arduino documentation. | ||
| + | |||
| + | === Steps === | ||
| + | Following steps do not present full code - you need to supply missing parts on your own! We do not present here how to connect to the WiFi AP. If you're in doubt, rever to the U1 scenario. We also do not present in details how to organise and print DHT11 sensor data on the LCD screen. Please refer to scenario B2 if you need a recall. | ||
| + | == Step 1 == | ||
| + | Include all necessary libraries. We use '' | ||
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | ... | ||
| + | </ | ||
| + | Declare some identifiers to let you easier handle necessary modifications and keep code clear: | ||
| + | <code c> | ||
| + | #define wifi_ssid " | ||
| + | #define wifi_password " | ||
| + | #define mqtt_server " | ||
| + | #define mqtt_user " | ||
| + | #define mqtt_password " | ||
| + | ... | ||
| + | </ | ||
| + | == Step 2 == | ||
| + | Declare some identifiers, | ||
| + | <note important> | ||
| + | <code c> | ||
| + | #define MQTTClientName ...<your client name>... | ||
| + | #define tempTopic | ||
| + | // i.e. including your name | ||
| + | #define humTopic | ||
| + | |||
| + | //MQTT last will | ||
| + | #define lastWillTopic ...<some topic for exposing state and last will> | ||
| + | // give it some unique topic | ||
| + | // i.e. including your name | ||
| + | #define lastWillMessage " | ||
| + | #define mqttWelcomeMessage " | ||
| + | </ | ||
| + | |||
| + | == Step 3 == | ||
| + | By the regular variables related to you WiFi Esp network client, DHT sensor, buffer for string processing and so on, here you need to configure an object additionally to handle communication with MQTT broker. As you may use many brokers in your app, you need to instantiate it yourself. The constructor accepts '' | ||
| + | <code c> | ||
| + | // WiFi & MQTT | ||
| + | WiFiClient espClient; | ||
| + | PubSubClient client(espClient); | ||
| + | </ | ||
| + | Configure your network client, remember to set '' | ||
| + | <code c> | ||
| + | client.setServer(mqtt_server, | ||
| + | </ | ||
| + | You can call it i.e. in the '' | ||
| + | |||
| + | == Step 4 == | ||
| + | If your WiFi client is working, your MQTT client is configured it is time to connect to the MQTT broker. It is a good idea to have this procedure separated to call as needed if your connection with MQTT broker goes down for any reason. Here we encapsulate it in the '' | ||
| + | <code c> | ||
| + | void reconnect() { | ||
| + | // Loop until we're reconnected | ||
| + | while (!client.connected()) { | ||
| + | if (client.connect(MQTTClientName, | ||
| + | | ||
| + | { | ||
| + | client.publish(lastWillTopic, | ||
| + | } else | ||
| + | { | ||
| + | // Wait 5 seconds before retrying | ||
| + | delay(5000); | ||
| + | } | ||
| + | } | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(" | ||
| + | } | ||
| + | </ | ||
| + | Function retries every 5 seconds, in case it is unable to connect to the MQTT broker.\\ | ||
| + | You can call it in the very beginning of the '' | ||
| + | <code c> | ||
| + | ... | ||
| + | if (!client.connected()) { | ||
| + | reconnect(); | ||
| + | } | ||
| + | ... | ||
| + | </ | ||
| + | == Step 5 == | ||
| + | Prepare a code that publishes MQTT messages. You will call it periodically within '' | ||
| + | |||
| + | Your publishing routine may look somehow like this: | ||
| + | <code c> | ||
| + | void mqttPublish() | ||
| + | { | ||
| + | hum = dht.readHumidity(); | ||
| + | temp = dht.readTemperature(); | ||
| + | if(client.connected()) | ||
| + | { | ||
| + | if (!(isnan(temp)||isnan(hum))) | ||
| + | { | ||
| + | client.publish(tempTopic, | ||
| + | // messages | ||
| + | client.publish(humTopic, | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | <note warning> | ||
| + | |||
| + | Finally your '' | ||
| + | <code c> | ||
| + | void loop() | ||
| + | { | ||
| + | if (!client.connected()) { | ||
| + | reconnect(); | ||
| + | } | ||
| + | client.loop(); | ||
| + | sprintf(buffer," | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(buffer); | ||
| + | sprintf(buffer," | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(buffer); | ||
| + | mqttPublish(); | ||
| + | delay(5000); | ||
| + | } | ||
| + | </ | ||
| + | the client.loop() is to handle incoming MQTT messages. There are none here but it is good practice to have it in your code. | ||
| + | |||
| + | === Result validation === | ||
| + | Observe connection progress on the LCD via video stream. Once WiFi and MQTT are connected you should be able to see temperature and humidity readings on the LCD and additionally those should be sent over the MQTT messages to the MQTT broker. Connect your MQTT client and subscribe to your messages (you may do it using a wildcard character) i.e. with means of the MQTT spy application. Remember to connect MQTT spy to public IP address unless you're a student physically present in our laboratory room and you have direct access to the '' | ||
| + | |||
| + | === FAQ === | ||
| + | **What topic should I choose?**: Up to you. Anyway, we suggest using non-trivial ones just not to overlap with other users.\\ | ||
| + | **Why MQTT broker uses two IP addresses? | ||