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:u7 [2019/08/08 16:00] – pczekalski | en:iot-open:remotelab:sut:generalpurpose2:u7 [2020/07/20 09:00] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ==== U7: ==== | + | ==== U7: Controlling fan speed and servo angle via MQTT ==== |
| - | //Give few words about this scenario. Provide some objectives | + | In this scenario, you will learn how to remotely control fan speed using PWM and how to control servo angle using MQTT messages. This scenario is a practical extension to the scenario U4 where you learned, how to receive and handle MQTT messages. |
| === Target group === | === Target group === | ||
| - | //This hands-on lab guide is intended for the Beginners/ | + | Undergraduate |
| === Prerequisites === | === Prerequisites === | ||
| - | //Provide prerequisite readings/ | + | We assume you already know how to: |
| + | * handle LCD screen to present information, | ||
| + | * connect to the existing WiFi network: internal.IOT, | ||
| + | * receive and handle MQTT messages using '' | ||
| + | * additionally we will ask you to install and use an MQTT client of your choice. We suggest using MQTT Spy, but any MQTT client that will let you subscribe to the MQTT messages is OK. You connect it to the public IP of the MQTT broker | ||
| + | MQTT broker present in the internal.IOT network is also visible under public address. So whenever you subscribe to the MQTT message using VREL node that is connected to the internal.IOT network, you may publish to it using other devices connected to the internal.IOT, | ||
| + | <note important> | ||
| + | |||
| + | <note warning> | ||
| + | |||
| === Scenario === | === Scenario === | ||
| - | // | + | In this scenario, you will handle incoming MQTT messages (one for controlling fan, other for servo, opening |
| === Result === | === Result === | ||
| - | //Describe expected result when scenario is finished.// | + | You should be able to remotely control fan rotation speed and flap angle (0..90 degrees), observe connection status and incoming MQTT messages for your device on the LCD screen. |
| === Start === | === Start === | ||
| - | //Write starting conditions, i.e. what to do at the beginning, what to pay attention before beginning, how the mechanical part should look like, etc.// | + | 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 and storing current PWM for servo and fan. Remember |
| + | |||
| + | Servo is controlled using GPIO pin D5 (GPIO14) while the fan is controlled using GPIO pin D8 (GPIO15). As servo we use is a small one, it is powered and controlled directly through the ESP8266 while in case of the FAN, it is controlled indirectly, using a transistor. | ||
| + | |||
| + | <note warning> | ||
| + | <note tip> | ||
| === Steps === | === Steps === | ||
| - | // Write some extra information if i.e. some steps are optional otherwise cancel this paragraph (but do not remove header).// | + | Following |
| == Step 1 == | == Step 1 == | ||
| - | //Describe activities done in Step 1.// | + | Include all necessary libraries. We use PubSubClient library to contact MQTT broker. The minimum set here is: |
| + | <code c> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | ... | ||
| + | </code> | ||
| + | Here we use '' | ||
| + | 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> | ||
| + | // MQTT messages | ||
| + | #define MQTTClientName " | ||
| + | #define servoTopic ...<some topic for servo> | ||
| + | // i.e. including your name | ||
| + | #define fanTopic | ||
| + | // i.e. including your name | ||
| + | |||
| + | //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 " | ||
| + | </ | ||
| + | Finally, declare GPIOs pin numbers connecting to the servo and fan: | ||
| + | <code c> | ||
| + | //Hardware | ||
| + | #define PWMFanPin D8 | ||
| + | #define servoPin D5 | ||
| + | </code> | ||
| + | == Step 3 == | ||
| + | Declare '' | ||
| + | Additionally, | ||
| + | <code c> | ||
| ... | ... | ||
| + | Servo servo; | ||
| + | ... | ||
| + | </ | ||
| - | == Step n == | + | Later, in your initialisation section (possibly in '' |
| - | //Describe activities done in Step n.// | + | <code c> |
| + | ... | ||
| + | void setup() | ||
| + | { | ||
| + | ... | ||
| + | // Servo and PWM fan | ||
| + | servo.attach(servoPin); | ||
| + | servo.write(0); | ||
| + | pinMode(PWMFanPin, | ||
| + | analogWrite(PWMFanPin, | ||
| + | ... | ||
| + | </ | ||
| + | |||
| + | Note - here you see how to control servo and fan. In the case of the servo, we use a '' | ||
| + | |||
| + | == Step 4 == | ||
| + | Implement MQTT callback - a function that is being called, whenever there comes an MQTT message. You should have subscribed only to the selected MQTT messages (one for the fan, other for the servo) so only those messages may trigger your callback function. Anyway, it is a matter to distinguish, | ||
| + | <code c> | ||
| + | void mqttCallback(char* topic, byte* payload, unsigned int length) { | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(" | ||
| + | lcd.setCursor(0, | ||
| + | lcd.print(" | ||
| + | String sTopic(topic); | ||
| + | if(sTopic.startsWith(servoTopic)) | ||
| + | { | ||
| + | | ||
| + | for(int i=0; i< length; i++) | ||
| + | { | ||
| + | buffer[i] = (char)payload[i]; | ||
| + | } | ||
| + | buffer[length]=' | ||
| + | srv = atoi(buffer); | ||
| + | servo.write(srv); | ||
| + | lcd.setCursor(9, | ||
| + | sprintf(buffer," | ||
| + | lcd.print(buffer); | ||
| + | } | ||
| + | if(sTopic.startsWith(fanTopic)) | ||
| + | { | ||
| + | | ||
| + | for(int i=0; i< length; i++) | ||
| + | { | ||
| + | buffer[i] = (char)payload[i]; | ||
| + | } | ||
| + | buffer[length]=' | ||
| + | fan = atoi(buffer); | ||
| + | analogWrite(PWMFanPin, | ||
| + | lcd.setCursor(7, | ||
| + | sprintf(buffer," | ||
| + | lcd.print(buffer); | ||
| + | } // give it some unique topic i.e. including your name | ||
| + | } | ||
| + | </ | ||
| + | As you see, we do not only receive the value but also drive LCD display to present it. Still you may inject some validation code, particularly for the servo, i.e. check if incoming MQTT payload for the servo message is more than 90 degres then truncate it not to break the device physically. | ||
| + | == Step 5 == | ||
| + | Remember to bind your MQTT callback function to the MQTT PubSubClient. Perhaps you will do it in the '' | ||
| + | <code c> | ||
| + | ... | ||
| + | client.setCallback(mqttCallback); | ||
| + | ... | ||
| + | </ | ||
| === Result validation === | === Result validation === | ||
| - | //Provide some result validation methods, for self assesment.// | + | Observe flap moving out and in. As the fan is mounted perpendicular to the video camera, you cannot observe rotation directly (video stream is too slow to present it on the other hand). You can observe value on the analogue gauge to the right but also indirectly through the flap mounted in the corresponding air receiving node (RX). Those are VREL1 and VREL3 for sending nodes VREL2 and VREL4 respectively. You will see the air stream pushing the flap thus you can monitor the airflow. |
| === FAQ === | === FAQ === | ||
| - | This section | + | **What |
| - | When using the printed version of this manual please refer to the latest online version of this document | + | **What is the valid range for controlling the servo?**: The valid range is from 0 to 90 degrees. Exceeding 90 degrees can break the construction! Never go beyond 90 degrees! |
| - | //Provide some FAQs in the following form:\\ | + | |
| - | **Question?**: Answer. | + | |
| - | // | + | |