15. Interface and Application Programming



assignment
   individual assignment:
      write an application that interfaces a user with an
         input &/or output device that you made
   group assignment:
      compare as many tool options as possible


individual assignment:


This week I programmed an App to control a RGB-Led and Power-Leds.


For programming the App I used the MIT App inventor:


https://appinventor.mit.edu/


On top of the screen I added a button to show and connect to the available Bluetooth devices.

And below I added buttons and sliders for each colour of the RGB-Led.



Then I programmed the App using the Blocks. Use the button in the top right corner to change between Designer and Blocks.





Finally I put together an Arduino Code for an Esp32:


// Bluetooth Part von Beispiel Code "SerialToSerialBL"


//This example code is in the Public Domain (or CC0 licensed, at your option.)

//By Evandro Copercini - 2018


//This example creates a bridge between Serial and Classical Bluetooth (SPP)

//and also demonstrate that SerialBT have the same functionalities of a normal Serial


#include "BluetoothSerial.h"


//#define USE_PIN // Uncomment this to use PIN during pairing. The pin is specified on the line below

// von mir auskommentiert: const char *pin = "1234"; // Change this to more secure PIN.


String device_name = "MicsEPS32_38Pin";


#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)

#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it

#endif


#if !defined(CONFIG_BT_SPP_ENABLED)

#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.

#endif


BluetoothSerial SerialBT;

// Code für APP:

int incomingValue; //Erstellen einer Variable vom Datentyp Integer

char incomingText; //Erstellen einer Variable vom Datentyp char

const int LED_rot = 5; //Pin 5 wird als Pin der roten LED definiert (indirekt per Konstantsromquelle)

const int LED_gruen = 4; //Pin 4 wird als Pin der grünen LED definiert (indirekt per Konstantsromquelle)

const int LED_blau = 2; //Pin 2 wird als Pin der blauen LED definiert (indirekt per Konstantsromquelle)


void setup() //der folgende Block wird nur einmal zum Start des Arduinos ausgeführt

{

Serial.begin(115200); //Startet die serielle Verbindung und setzt die Datenrate auf 9600 Bit/s

pinMode(LED_rot, OUTPUT); //Pin zum Steuern der roten LED wird als OUTPUT konfiguriert

pinMode(LED_gruen, OUTPUT); //Pin zum Steuern der grünen LED wird als OUTPUT konfiguriert

pinMode(LED_blau, OUTPUT); //Pin zum Steuern der blauen LED wird als OUTPUT konfiguriert


SerialBT.begin(device_name); //Bluetooth device name

Serial.printf("The device with name \"%s\" is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str());

//Serial.printf("The device with name \"%s\" and MAC address %s is started.\nNow you can pair it with Bluetooth!\n", device_name.c_str(), SerialBT.getMacString()); // Use this after the MAC method is implemented


// Pin von mir auskommentiert:

// #ifdef USE_PIN

// SerialBT.setPin(pin);

// Serial.println("Using PIN");

// #endif

}


void loop() //Block der loop-Funktion wird schleifenweise ausgeführt (Endlosschleife)

{

// Serial.available zu SerialBT.available:

// if(Serial.available() > 0) //[8, 16] über RX/TX Pin wird geprüft, ob Daten von dem Bluetooth Modul erhalten werden

//{ //ist dies der Fall, wird der folgende Code-Block ausgeführt


if(SerialBT.available())

{


// hier auch BT hinter Serial hinzugefügt:

incomingValue = SerialBT.parseInt(); //[8, 17] nächste gültige Integer Zahl aus den empfangenen Daten des Bluetooth Moduls...

//...wird in die Variable "IncomingValue" geschrieben

incomingText = SerialBT.read(); //[8] char-Anteil der durch das Bluetooth Moduls empfangene Daten wird in die...

//...Variable "IncomingText" geschrieben


// Serial.write(SerialBT.read()); // schreibe über Bluetooth empfangene Daten in den Seriellen Monitor


switch(incomingText) //switch Funktion prüft, ob der Wert der Variablen "IncomingText" mit den folgenden...

{ //...Fällen ("cases") übereinstimmt und führt die entsprechenden Code-Blöcke aus

case'A': //folgender Code-Block wird ausgeführt, wenn ein 'A' empfangen wurde

{ //'A' wurde gesendet, wenn die RED ON-/RED OFF-Buttons in der App betätigt wurden

if(incomingValue == 1) //wenn die empfangene Zahl in der Variablen "IncomingValue" gleich 1 ist...

{ //...welche bei Drücken des RED ON Buttons in der App gesendet wird...

digitalWrite(LED_rot, HIGH); //...werden 5 V am Pin 10 ausgegeben und führen dazu, dass die Konstantstromquelle...

//...die rote Power LED vollständig mit 700 mA versorgt und damit einschaltet

}

else if(incomingValue == 0) //wenn die empfangene Zahl in der Variablen "IncomingValue" gleich 0 ist...

{ //...welche bei Drücken des RED OFF Buttons in der App gesendet wird...

digitalWrite(LED_rot, LOW); //...werden 0 V am Pin 10 ausgegeben und führen dazu, dass die Konstantstromquelle...

//...die rote Power LED mit 0 mA versorgt und damit ausschaltet

}

break; //signalisiert das Ende des case-Blocks nach Ausführen des Codes darin

}

case 'B': //folgender Code-Block wird ausgeführt, wenn ein 'B' empfangen wurde

{ //'B' wurde gesendet, wenn die GREEN ON-/GREEN OFF-Buttons in der App betätigt wurden

if(incomingValue == 1) //wenn die empfangene Zahl in der Variablen "IncomingValue" gleich 1 ist...

{ //...welche bei Drücken des GREEN ON Buttons in der App gesendet wird...

digitalWrite(LED_gruen, HIGH); //...werden 5 V am Pin 6 ausgegeben und führen dazu, dass die Konstantstromquelle...

//...die grüne Power LED vollständig mit 700 mA versorgt und damit einschaltet

}

else if(incomingValue == 0) //wenn die empfangene Zahl in der Variablen "IncomingValue" gleich 0 ist...

{ //...welche bei Drücken des GREEN OFF Buttons in der App gesendet wird...

digitalWrite(LED_gruen, LOW); //...werden 0 V am Pin 6 ausgegeben und führen dazu, dass die Konstantstromquelle...

//...die grüne Power LED mit 0 mA versorgt und damit ausschaltet

}

break; //signalisiert das Ende des case-Blocks nach Ausführen des Codes darin

}

case 'C': //folgender Code-Block wird ausgeführt, wenn ein 'C' empfangen wurde

{ //'C' wurde gesendet, wenn die BLUE ON-/BLUE OFF-Buttons in der App betätigt wurden

if(incomingValue == 1) //wenn die empfangene Zahl in der Variablen "IncomingValue" gleich 1 ist...

{ //...welche bei Drücken des BLUE ON Buttons in der App gesendet wird...

digitalWrite(LED_blau, HIGH); //...werden 5 V am Pin 5 ausgegeben und führen dazu, dass die Konstantstromquelle...

//...die blaue Power LED vollständig mit 700 mA versorgt und damit einschaltet

}

else if(incomingValue == 0) //wenn die empfangene Zahl in der Variablen "IncomingValue" gleich 0 ist...

{ //...welche bei Drücken des BLUE OFF Buttons in der App gesendet wird...

digitalWrite(LED_blau, LOW); //...werden 0 V am Pin 5 ausgegeben und führen dazu, dass die Konstantstromquelle...

//...die blaue Power LED mit 0 mA versorgt und damit ausschaltet

}

break; //signalisiert das Ende des case-Blocks nach Ausführen des Codes darin

}


case 'D': //folgender Code-Block wird ausgeführt, wenn ein 'D' empfangen wurde

{

analogWrite(LED_rot, incomingValue); //[8] ein PWM Signal wird an Pin 10, in Höhe der empfangenen Zahl, welche...

//...mittels Schieberegler in der App eingestellt wurde, ausgegeben...

//...und dimmt damit per Konstantstromquelle die rote Power LED

break; //signalisiert das Ende des case-Blocks nach Ausführen des Codes darin

}


case 'E': //folgender Code-Block wird ausgeführt, wenn ein 'E' empfangen wurde

{

analogWrite(LED_gruen, incomingValue); //[8] ein PWM Signal wird an Pin 6, in Höhe der empfangenen Zahl, welche...

//...mittels Schieberegler in der App eingestellt wurde, ausgegeben

//...und dimmt damit per Konstantstromquelle die grüne Power LED

break; //signalisiert das Ende des case-Blocks nach Ausführen des Codes darin

}


case 'F': //folgender Code-Block wird ausgeführt, wenn ein 'F' empfangen wurde

{

analogWrite(LED_blau, incomingValue); //[8] ein PWM Signal wird an Pin 5, in Höhe der empfangenen Zahl, welche...

//...mittels Schieberegler in der App eingestellt wurde, ausgegeben

//...und dimmt damit per Konstantstromquelle die blaue Power LED

break; //signalisiert das Ende des case-Blocks nach Ausführen des Codes darin

}


default: //wenn keiner der, mit Bedingungen verknüpften, Buchstaben, empfangen wurde,...

break; //wird kein Code ausgeführt und die Schleife erneut gestartet

}

}

} //der Zustand der einzelnen LEDs bleibt, wenn keine Änderungen dazu per...

//...App gesendet wurde, gleich und ermöglicht verschiedenste...

//...Farbkombinationen in unterschiedlichen Zyklen der Schleife





Here you see the setup. The Esp32 is connected to a PCB with the RGB-Led and connectors to connect to power leds. In the image only one power led is shown. The driver of the power led can be powered by 5V, so I conneted it to an USB port.




The pin of the RGB-Led for the blue colour is connected to the led driver for 3 Watt leds (the star shaped PCB at the top).


Here you see the device in action. The led driver works apposite to the RGB-Led. Meaning, when PWM is low the power led is on and off if PWM is high:





Further, I controlled the leds on my XiaoEsp32-S3 Board over Wlan:

Here you can download the used code (you have to input your Wlan informations befor upload):

Download link

And here you find a good tutorial how to control an Esp32 over Wifi:

https://randomnerdtutorials.com/esp32-web-server-arduino-ide/

group assignment:

For the group assignment I adjusted a code to control the RGB-Led over Wifi using the same set up. 

For the code, I used this example as a guide: 

https://randomnerdtutorials.com/esp32-web-server-arduino-ide/


I added a third button for the third colour:



/*********

Rui Santos

Complete project details at https://randomnerdtutorials.com

*********/


// Load Wi-Fi library

#include <WiFi.h>


// Replace with your network credentials

const char* ssid = "SSID"; // insert your SSID in the inverted commas

const char* password = "PASSWORD"; // insert your Password in the inverted commas


// Set web server port number to 80

WiFiServer server(80);


// Variable to store the HTTP request

String header;


// Auxiliar variables to store the current output state

String output26State = "off";

String output27State = "off";

String output2State = "off";


// Assign output variables to GPIO pins

const int output26 = 4; // 26 zu 4

const int output27 = 5; // 27 zu 5

const int output2 = 15; // neu


// Current time

unsigned long currentTime = millis();

// Previous time

unsigned long previousTime = 0;

// Define timeout time in milliseconds (example: 2000ms = 2s)

const long timeoutTime = 2000;


void setup() {


Serial.begin(115200);

// Initialize the output variables as outputs

pinMode(output26, OUTPUT);

pinMode(output27, OUTPUT);

pinMode(output2, OUTPUT);

// Set outputs to LOW

digitalWrite(output2, LOW);

digitalWrite(output26, LOW);

digitalWrite(output27, LOW);


// Connect to Wi-Fi network with SSID and password

Serial.print("Connecting to ");

Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

// Print local IP address and start web server

Serial.println("");

Serial.println("WiFi connected.");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

server.begin();

}


void loop(){

WiFiClient client = server.available(); // Listen for incoming clients


if (client) { // If a new client connects,

currentTime = millis();

previousTime = currentTime;

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() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected

currentTime = millis();

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);

// neu:

} else if (header.indexOf("GET /2/on") >= 0) {

Serial.println("GPIO 2 on");

output2State = "on";

digitalWrite(output2, HIGH);

} else if (header.indexOf("GET /2/off") >= 0) {

Serial.println("GPIO 2 off");

output2State = "off";

digitalWrite(output2, LOW);

}


// Display the HTML web page

client.println("<!DOCTYPE html><html>");

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>ESP32 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>");



// neu:

// Display current state, and ON/OFF buttons for GPIO 2

client.println("<p>GPIO 2 - State " + output2State + "</p>");

// If the output2State is off, it displays the ON button

if (output2State=="off") {

client.println("<p><a href=\"/2/on\"><button class=\"button\">ON</button></a></p>");

} else {

client.println("<p><a href=\"/2/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("");

}

}




Here you see a video of the device in action:


First I took the same pins as for Bluetooth, but the led on pin 2 flickered and did not respond to changes on the webpage. After changing to pin 15 it worked.


Under the following link you find helpful informations which pins of the Esp32 you should use and which you should not use.


https://randomnerdtutorials.com/esp32-pinout-reference-gpios/


Comparison:


Both possibilities to control the RGB-led worked well.

Here is a short general comparison between Bluetooth and Wifi:


Bluetooth:

- less energy necessary

- smaller range

- no password needed (advantage or disadvantage)


Wifi:

- more energy needed

- larger range

- password needed

- usually a router is necessary


I think Wifi modules are more often included in microcontrollers.

The Esp32 has Wifi as well as Bluetooth.

For the control of high power consumers I prefer to use Wifi, because I think its more secure.


For programming I like the MIT App inventor much more than to program html in the Arduino code, because you have a graphical user interface. But you also can write Apps using Wifi with the MIT App inventor, but I did not tried this so far.