Coding
Project program code
Arduino cc software is used to write a program.
If we use the example from Day 7 – “Touch sensor sends e-mail when critical level is detected” and add two more LED, we can to make a demonstration of how we can remotely control the IoT device via a WEB page from our phone or computer.
This example use the same Adafruit feed and TFTT trigger, like in Day 7 – Example
For this example, the LEDs are connected to pins 4, 26 and 27 through resistors to ground.
The code for this example
/////////////////////////////////
#include "FreeRTOS.h"
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#include "WiFi.h"
////////////////////////////////////////////////
// Multitasking procedures definition //
////////////////////////////////////////////////
void loopServer( void *pvParameters );
void loopTouch( void *pvParameters );
//////////////////////////////////////////////
int i;
int x;
int y;
int flagA;
int selectedNet;
int timeout;
int touchlevel;
int loopServer();
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "Angel_Toshkov"
#define AIO_KEY "1112c220cfbb49b1b1c88f40b942631f"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
boolean MQTT_connect();
boolean MQTT_connect() {
int8_t ret;
if (mqtt.connected()) {
return true;
} uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) {
mqtt.disconnect();
delay(2000);
retries--;
if (retries == 0) {
return false;
}
} return true;
}
Adafruit_MQTT_Publish touchsensor = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/touchsensor");
//WEB serwer part - Instructor must replace with current network credentials of Lab
WiFiServer server(80);
String header;
String output26State = "off";
String output27State = "off";
const int output4 = 25;
const int output26 = 26;
const int output27 = 27;
///////////////////////////////////////////////
void setup()
{
i = 0;
x = 0;
y = 0;
flagA = 1;
selectedNet = 1; // 1 - Network 1, 2 - Network 1
timeout = 100;
touchlevel = 30;
// WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); // Disable brownout detector
Serial.begin(115200);
delay (1000);
pinMode(output4, OUTPUT); //LED on D4
pinMode(output26, OUTPUT); //LED on D26
pinMode(output27, OUTPUT); //LED on 27
digitalWrite(output4, LOW);
digitalWrite(output26, LOW);
digitalWrite(output27, LOW);
digitalWrite(output26, HIGH);
delay(300);
digitalWrite(output26, LOW);
digitalWrite(output27, HIGH);
delay(300);
digitalWrite(output27, LOW);
Serial.println("START");
Serial.println("Connecting...");
// ***** Internet connection cycle. Tests two networks. If it connects to either, it exits the loop.
WiFi.disconnect();
while (!(WiFi.status() == WL_CONNECTED)) {
digitalWrite(output26, HIGH);
digitalWrite(output27, HIGH);
Serial.println("");
if (selectedNet == 1 ) {
WiFi.begin("Valentina", "tinatina2000");
selectedNet = 2 ;
Serial.print("Try to connect with Network 1.");
} else {
WiFi.begin("Angel_6s", "valentina");
// selectedNet = 1 ;
Serial.print("Try to connect with Network 1.");
}
x = 40000; // Network connection timeout 20 sec. is good for phone
while (!(WiFi.status() == WL_CONNECTED) and x > 1) {
if (y < 1) {
Serial.print(".");
y = 1000;
} else {
y --;
}
delay(1);
x --;
}
digitalWrite(output26, LOW);
digitalWrite(output27, LOW);
}
Serial.println("");
Serial.println("Connection is OK.");
Serial.print("Network: ");
if ( selectedNet == 2 ) {
Serial.println("Network 2.");
} else {
Serial.println("Network 1.");
}
Serial.println("Ypur IP е:");
Serial.println((WiFi.localIP()));
server.begin();
Serial.println("Looks for Touch sensor state");
delay (10000);
///////////////////////////
//Task definitions //
///////////////////////////
xTaskCreate(
loopTouch
, "Touch" // A name just for humans
, 12800 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL // Parameter that is passed to the input of the task
, 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );
xTaskCreate(
loopServer
, "Web" // A name just for humans
, 12800 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL //Parameter that is passed to the input of the task
, 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
, NULL );
}
///////////////////////////////////
void loop() // Program body
{
// vTaskDelay (10);
delay(1);
}
//////////////////////////////////////////////
// Procedure for processing the readings of the D4 touch sensor
void loopTouch(void *pvParameters)
{
(void) pvParameters;
while (true) {
delay (50); // This delay is necessary in order for the Watch Dog interruption not to work
if ( (i = (touchRead(T5))) < touchlevel) {
delay (50); // This delay is needed to eliminate false signals from the sensor
if ( (i = (touchRead(T5))) < touchlevel) { // The second If protects the sensor from false fluctuations. Min. 50 milliseconds contact to work.
digitalWrite(output4, HIGH);
if (flagA < 1) {
flagA = timeout;
if (MQTT_connect()) {
if (touchsensor.publish(i)) {
Serial.print("DO NOT TOUCH MY SHEEP !!!. Touch level: ");
Serial.print(i);
Serial.println(". I am sending a message on the Internet.");
} else {
Serial.println(". Problem with Adafruit driver");
}
}
Serial.println("");
} else {
flagA --;
}
}
} else {
flagA = 0;
digitalWrite(output4, LOW);
}
}
vTaskDelete( NULL );
}
////////////////////////////////
void loopServer(void *pvParameters)
{
(void) pvParameters;
while (true) {
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
if (header.indexOf("GET /26/on") >= 0) {
Serial.println("GPIO 26 on");
output26State = "on";
digitalWrite(output26, HIGH);
} else if (header.indexOf("GET /26/off") >= 0) {
Serial.println("GPIO 26 off");
output26State = "off";
digitalWrite(output26, LOW);
} else if (header.indexOf("GET /27/on") >= 0) {
Serial.println("GPIO 27 on");
output27State = "on";
digitalWrite(output27, HIGH);
} else if (header.indexOf("GET /27/off") >= 0) {
Serial.println("GPIO 27 off");
output27State = "off";
digitalWrite(output27, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<html lang=\"bg-BG\"><head>");
client.println("<meta charset=\"UTF-8\">");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #4CAF50; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #555555;}</style></head>");
// Web Page Heading
client.println("<body><h1>Hello.</h1>");
client.println("<body><h1>This is the Sheep web server</h1>");
// Display current state, and ON/OFF buttons for GPIO 26
client.println("<p>GPIO 26 - State: " + output26State + "</p>");
// If the output26State is off, it displays the ON button
if (output26State == "off") {
client.println("<p><a href=\"/26/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/26/off\"><button class=\"button button2\">OFF</button></a></p>");
}
// Display current state, and ON/OFF buttons for GPIO 27
client.println("<p>GPIO 27 - State: " + output27State + "</p>");
// If the output27State is off, it displays the ON button
if (output27State == "off") {
client.println("<p><a href=\"/27/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/27/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
vTaskDelete( NULL );
}
// Резултат ор WiFi.status() == WL_CONNECTED)
// WL_CONNECTED i status 3
// WL_CONNECT_FAILED - 4
// WL_DISCONNECTED – 6
****************************************************
LAB – Coding and testing