In questo secondo articolo ci occuperemo della programmazione del robot e come creare l’app di controllo per Android.
Se ti sei perso la prima parte relativa alla parte di elettronica visita https://www.lutritech.it/come-costruire-un-robot-wifi/
Qui lo sketch da caricare sul robot con l’IDE di Arduino. Ricordatevi prima di scaricare tutte le librerie necessarie, impostare il vostro token di Blynk e scegliere la piattaforma corretta dal gestore di schede.
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <DNSServer.h>
#include <BlynkSimpleEsp8266.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include "bender.h" //contiene il codice per animare il display con bender
#include <Servo.h>
#define HTTP_WEB_PORT 80
#define WIFI_RETRY_DELAY 500
#define MAX_WIFI_INIT_RETRY 50
#define MOTORE_SX_PIN1 D0
#define MOTORE_SX_PIN2 D1
#define MOTORE_DX_PIN1 D2
#define MOTORE_DX_PIN2 D3
#define PINZA_PIN D4 //D4 PER GESTIONE PINZA ROBOT
#define AVANTI 1
#define INDIETRO 0
#define BUZZERPIN D5 //D5 è IN PIN PER IL CLACSON
//configurazine Blynk
char auth[] = "Mettete il vostro token di Blynk";
int posizionePinza = 0;
IPAddress local_IP(192, 168, 10, 10); //192.168.10.10 E' L'INDIRIZZO CHE SI ASSEGNA QUANDO VA IN MODALITà DI CONFIG
IPAddress gateway(192, 168, 10, 10);
IPAddress subnet(255, 255, 255, 0);
ESP8266WebServer http_server(HTTP_WEB_PORT);
Servo myservo; // oggetto myservo
void setup(void) {
Serial.begin(115200);
pinMode(MOTORE_SX_PIN1, OUTPUT);
pinMode(MOTORE_SX_PIN2, OUTPUT);
pinMode(MOTORE_DX_PIN1, OUTPUT);
pinMode(MOTORE_DX_PIN2, OUTPUT);
pinMode(BUZZERPIN, OUTPUT); //PIN PER IL CLACSON
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//reset saved settings
//wifiManager.resetSettings(); //PUò SERVIRE IN CASO DI TEST
//set custom ip for portal
wifiManager.setAPStaticIPConfig(local_IP, gateway, subnet);
//fetches ssid and pass from eeprom and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
wifiManager.autoConnect("RobotCar-01");
//or use this for auto generated name ESP + ChipID
//wifiManager.autoConnect();
//MOSTRO IL MAC ADDRESS DELLA SCHEDA ARDUINO
Serial.printf("MAC address = %s\n", WiFi.softAPmacAddress().c_str());
Serial.println(WiFi.hostname());
Blynk.config(auth);
config_server_routing();
http_server.begin();
Serial.println("RoboCar HTTP Server Started");
robocar_pinza_aperta();
}
void config_server_routing() {
http_server.on("/", HTTP_GET, []() {
http_server.send(200, "text/html", "Benvenuto sul ESP8266 RoboCar Web Server");
});
http_server.on("/robocar", HTTP_GET, muovi_robocar);
}
void muovi_robocar() {
String comando = String(http_server.arg(0));
Serial.print("Ricevuto comando = ");
Serial.println(comando);
http_server.send(200, "text/html", "robocar - comando ricevuto");
if (comando == "0")
robocar_fermo();
else if (comando == "1")
robocar_avanti();
else if (comando == "2")
robocar_indietro();
else if (comando == "4")
robocar_sinistra();
else if (comando == "3")
robocar_destra();
else if (comando == "5")
robocar_clacson();
else if (comando == "6")
robocar_gira_antiorario();
else if (comando == "7")
robocar_gira_orario();
else if (comando == "8")
robocar_pinza_aperta();
else if (comando == "9")
robocar_pinza_chiusa();
else Serial.println("Comando non riconosciuto");
}
void motore_sx_avanti() {
Serial.println("motore_sx avanti");
digitalWrite(MOTORE_SX_PIN1, HIGH);
digitalWrite(MOTORE_SX_PIN2, LOW);
}
void motore_sx_indietro() {
Serial.println("motore_sx indietro");
digitalWrite(MOTORE_SX_PIN1, LOW);
digitalWrite(MOTORE_SX_PIN2, HIGH);
}
void motore_sx_fermo() {
Serial.println("motore_sx fermo");
digitalWrite(MOTORE_SX_PIN1, LOW);
digitalWrite(MOTORE_SX_PIN2, LOW);
}
void motore_dx_avanti() {
Serial.println("motore_dx avanti");
digitalWrite(MOTORE_DX_PIN1, HIGH);
digitalWrite(MOTORE_DX_PIN2, LOW);
}
void motore_dx_indietro() {
Serial.println("motore_dx indietro");
digitalWrite(MOTORE_DX_PIN1, LOW);
digitalWrite(MOTORE_DX_PIN2, HIGH);
}
void motore_dx_fermo() {
Serial.println("motore_dx fermo");
digitalWrite(MOTORE_DX_PIN1, LOW);
digitalWrite(MOTORE_DX_PIN2, LOW);
}
void robocar_avanti() {
Serial.println("vado avanti");
motore_sx_avanti();
motore_dx_avanti();
}
void robocar_indietro() {
Serial.println("vado indietro");
motore_sx_indietro();
motore_dx_indietro();
}
void robocar_destra() {
Serial.println("giro a sinistra");
motore_dx_avanti();
}
void robocar_sinistra() {
Serial.println("giro a destra");
motore_sx_avanti();
}
void robocar_fermo() {
motore_sx_fermo();
motore_dx_fermo();
}
void robocar_gira_orario() {
Serial.println("giro ORARIO");
motore_dx_avanti();
motore_sx_indietro();
}
void robocar_gira_antiorario() {
Serial.println("giro ANTIORARIO");
motore_dx_indietro();
motore_sx_avanti();
}
void robocar_clacson() {
tone(BUZZERPIN, 440, 1000);
delay(500);
}
BLYNK_WRITE(V4)// leggo l'indirizzo di chi sta usando l'applicazione
{
String pinValue = param.asStr();
Serial.print("Coordinate GPS: ");
Serial.println(pinValue);
}
BLYNK_WRITE(V5)
{
int pinValue = param.asInt(); // assigning incoming value from pin V5 to a variable
switch (pinValue)
{
case 0: { //fermo
Serial.println("fermo");
robocar_fermo();
break;
}
case 1: { //avanti
Serial.println("avanti");
robocar_avanti();
break;
}
case 2: { //indietro
Serial.println("indietro");
robocar_indietro();
break;
}
case 3: { //sx
Serial.println("sx");
robocar_destra();
break;
}
case 4: { //dx
Serial.println("dx");
robocar_sinistra();
break;
}
case 5: { //clacson
Serial.println("clacson");
robocar_clacson();
break;
}
case 6: { //antioriario
Serial.println("antioriario");
robocar_gira_antiorario();
break;
}
case 7: { //oriario
Serial.println("oriario");
robocar_gira_orario();
break;
}
case 8: { //pinza aperta
Serial.println("apro pinza");
robocar_pinza_aperta();
break;
}
case 9: { //pinza chiusa
Serial.println("chiudo pinza");
robocar_pinza_chiusa();
break;
}
default:
Serial.println("altro comando");
break;
}
}
void robocar_pinza_aperta() {
myservo.attach(PINZA_PIN);
delay(300);
myservo.write(5);
delay(300);
myservo.detach();
}
void robocar_pinza_chiusa() {
myservo.attach(PINZA_PIN);
delay(300);
myservo.write(170);
delay(300);
myservo.detach();
}
void loop(void) {
Blynk.run();
http_server.handleClient();
}
Usare la libreria WifiManager ha dato un tocco di professionalità e usabilità al robottino, infatti con questa non bisogna modificare lo sketch inserendo il nuovo ssid e la password per poi ricompilare e caricare il nuovo firmware.
C’è un Webserver in ascolto sulla porta 80 che riceve i comandi inviati dall’app con questa sintassi:
http://indirizzoIP/robocar?comando=
Dopo l’uguale andrà un numero mappato come nel codice, con 0 ad esempio il robot è fermo. Questo sistema di trasmissione dei comandi serve quando collegate il robot al vostro smartphone in modalità HotSpot/Router WIFI, i due dovranno essere ad un certo raggio 10..20 metri per poter comunicare.
Se non avete problemi potete usare la connessione a internet in quel caso allora viene letta la variabile V5 dal cloud di Blynk
BLYNK_WRITE(V5)
{
int pinValue = param.asInt(); // assigning incoming value from pin V5 to a variable
switch (pinValue)
Analogamente a prima, a seconda del valore che assume pinValue, verrà lanciato un comando. Ho usato lo stesso mapping, ad esempio se pinValue vale zero allora il robot rimane fermo.
L’applicazione da costruire su Blynk è molto semplice: è composta da uno slider e da una label:
La parte inerente la programmazione robot è terminata.
Programmazione dell’applicazione di controllo
Passiamo alla parte della progettazione dell’applicazione Android. Ho utilizzato Mit App Inventor per la prima volta e devo dire che è proprio un bellissimo strumento. Si divide in due parti: progettazione e blocchi. La prima permette la composizione dell’interfaccia utente e dell’impaginazione, mentre la seconda permette di utilizzare le funzioni di questi oggetti appena inseriti con una logica.
Un esempio: quando finisco di cliccare il pulsante mi riporta alla pagina iniziale.
Qui sotto trovate come si presenta l’interfaccia grafica:
Mentre qui potete intravedere la logica dell’applicazione (blocchi)
Per vostra fortuna non dovete scrivere tutto da zero! Se lasciate un commento qui in fondo e vi iscrivete al canale youtube (attivando la campanella delle notifiche) vi lascio in privato il progetto .AIA da importare e personalizzare.
Passiamo alla configurazione dell’applicazione di IP Webcam, dopo averla installata per la vostra sicurezza vi consiglio di impostare un login, una password e di cambiare la porta. Mi raccomando di aprire la porta sul vostro router in modo tale che sia visibile dall’esterno (facendo un port forward).
Terminato il tutto cliccate su “Avvio del server” e posizionatelo sopra il robot.
Buon divertimento!
Ho caricato il video su youtube che potete vedere direttamente qui sotto:
Spero che questo progetto ti sia piaciuto, ho dedicato molto del mio tempo libero per portarlo avanti e sono molto soddisfatto del mio lavoro.
A te non costa nulla, ma sarei lieto se condividessi sui social questa pagina oppure il video su youtube.