A la UAB vam començar a fer el projecte de radar amb el motor servo i el sensor de distància. Ho acabem?
Per si de cas, un petit recordatori.
Includes:
#include <ESP32Servo.h>
Variables:
Servo myServo;
int pin_servo=27; //Pin del motor
int angle=0; //L'angle inicial del motor
int pas=5; //Quants graus gira cada cop el motor
int temps=500;
Inicialitzacions:
//Inici radar
myServo.attach(pin_servo);
Per sempre:
//El que fem cada X temps
myServo.write(angle);
angle=angle+pas;
if (angle==180 || angle==0)
{
pas=pas*-1;
}
delay(temps);
Variables:
int pin_echo=25;
int pin_trigger=26;
Inicialitzacions:
pinMode(pin_trigger,OUTPUT);
pinMode(pin_echo,INPUT);
Per sempre:
delay(50);
digitalWrite(pin_trigger,LOW);
delayMicroseconds(4);
digitalWrite(pin_trigger,HIGH);
delayMicroseconds(10);
digitalWrite(pin_trigger,LOW);
duration=pulseIn(pin_echo,HIGH);
Serial.println(duration*0.0171);
Molt similar al d'abans, però ara a més generarem la imatge del radar!
#include <WiFi.h>
#include <WebServer.h>
#define LED_BUILTIN 2
const int led = LED_BUILTIN;
//Variables del WIFI i del servidor web
const char *ssid = "Wifi-ESP32-GRUPXX"; //Configurar
WebServer server(80);
//Inici svg radar
int distancies[200];
const int origen_x0=300,origen_y0=300;
int last_angle,svg_step;
void ini_svg(int step)
{
svg_step = step;
for(int x=0;x<200;x++)
{
distancies[x]=-1;
}
}
void guardar_distancia(int angle,int dist)
{
if (angle>=0 && angle<=180)
{
if (dist>5)
{
distancies[angle]=dist;
}
else
{
distancies[angle]=-1;
}
last_angle = angle;
}
}
String generar_svg(int angle,int step)
{
String svg = "<?xml version='1.0' standalone='no'?>\
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\
<svg width='600' height='300' style='background-color:black' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink= 'http://www.w3.org/1999/xlink'>\
<path d='M5,300 a1,1 0 0,1 590,0' stroke='white' stroke-width='2' fill='transparent' />\
<path d='M155,300 a1,1 0 0,1 290,0' stroke='white' stroke-width='2' fill='transparent' />";
int x,y;
float r;
char text[200];
r = radians(angle);
x = cos(r)*300 + origen_x0;
y = -sin(r)*300 + origen_y0;
sprintf(text,"<line x1='300' y1='300' x2='%d' y2='%d' style='stroke:red;stroke-width:3' />\n",x,y);
svg = svg + text;
for(int i=0;i*step<=180;i++)
{
if (distancies[i*step]<0)
{
continue;
}
r = radians(i*step);
x = cos(r)*distancies[i*step] + origen_x0;
y = -sin(r)*distancies[i*step] + origen_y0;
sprintf(text,"<circle r='5' cx='%d' cy='%d' fill='green' />\n",x,y);
svg = svg + text;
}
svg = svg + "<text x='300' y='300' fill='white' text-anchor='middle' font-size='30'>SiX</text>\
</svg>";
return svg;
}
// Final svg radar
// Inici Wifi
const char *ssid = "Wifi-ESP32-GRUPX";
WebServer server(80);
void handleRoot() {
digitalWrite(led, HIGH); // encender LED
char temp[800];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;
snprintf(temp, 800,
"<html>\
<head>\
<meta http-equiv='refreshhhh' content='1'/>\
<title>ESP32 Demo</title>\
<style>\
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
<script>\
setInterval(function() {\
var myImageRadar = document.getElementById('radar');\
myImageRadar.src = '/radar.svg?rand=' + Math.random();\
}, 500);\
</script>\
</head>\
<body>\
<h1>Hola desde ESP32!</h1>\
<p>Uptime: %02d:%02d:%02d</p>\
<img src=\"/radar.svg\" id=\"radar\" />\
</body>\
</html>",
hr, min % 60, sec % 60
);
server.send(200, "text/html", temp);
digitalWrite(led, LOW);
}
void handleNotFound() {
digitalWrite(led, HIGH);
String message = "Archivo no encontrado\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
digitalWrite(led, LOW);
}
void handleInline(){
server.send(200, "text/plain", "Usted a accedido al recurso ``inline''");
}
void drawGraph() {
String out = generar_svg(last_angle,svg_step);
server.send(200, "image/svg+xml", out);
}
//Final Wifi
//Inicialitzem port sèrie
Serial.begin(115200);
while(!Serial);
Serial.println();
//Inici configuració WIFI i Servidor
Serial.println("Configurando punto de acceso...");
WiFi.softAP(ssid);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.on("/", handleRoot);
server.on("/radar.svg", drawGraph);
server.on("/inline", handleInline);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
//Final configuració WIFI i servidor
//Comprovem i gestionem les respostes del WIFI
server.handleClient();
//Guardem la distància per fer la imatge del radar!
guardar_distancia(angle,distancia);
En ficar-ho tot junt, ens trobarem amb un problema: si al per sempre (loop) fiquem un delay, no funcionaran les altres parts del programa que s'han d'anar executant de forma constant. Com per exemple que es mostrin la pàgina web.
void loop() {
//Comprovem i gestionem les respostes de la pàgina Web
server.handleClient();
/* el codi del radar */
delay(1000); //Durant un segon NO es gestionaran les pàgines web! :-(
}
En comptes d'esperar, comptarem el temps que passa, per veure quan hem de moure el radar!
Variables:
unsigned long next = millis()+temps;
Per sempre:
server.handleClient();
//Delay
if (next < millis())
{
//El que fem cada X temps: girar motor i comprovar distancia!
// ...
// ...
next=millis()+temps;
}