Implement a remote control for rc robot
Posted: Mon Mar 28, 2016 8:24 am
Hello,
I'd like to get a webinterface for my rc robot.
Therefore I need a basic control with a forward, backward, turn left, turn right button.
I searched a while and found something and merged this with my code. This is nearly perfect for my project:
But I want to have this kind of control: As long as I pushed the button on the webinterface, a digital output has to be enabled. Just if I release the button, the digital output has to be disabled.
How can I optimize my code, to get this behaviour?
Best regards
I'd like to get a webinterface for my rc robot.
Therefore I need a basic control with a forward, backward, turn left, turn right button.
I searched a while and found something and merged this with my code. This is nearly perfect for my project:
Code: Select all
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define DEBUG_STATE false // Serielle Ausgaben aktivieren
#define ONE_WIRE_BUS D4 // Anschluss des DS18B20 Sensors
#define OUTPUTTURNLEFT D5 // Ausgang für manuelles Fahren - links fahren
#define OUTPUTTURNRIGHT D6 // Ausgang für manuelles Fahren - rechts fahren
#define OUTPUTMOVEFORWARD D7 // Ausgang für manuelles Fahren - vorwärts fahren
#define OUTPUTMOVEBACKWARD D8 // Ausgang für manuelles Fahren - rückwärts fahren
#define INPUT_LICHTSCHRANKE A0 // Anschluss der Lichtschranke
#define INPUT_ALARM D3 // Alarmeingang
#define LICHTSCHRANKE_SENSE 200 // Schwellwert, ab dem erkannt wird
#define SCALE_FAKTOR_LICHTSCHRANKE 3.8 // Umwandlung erkannter Löcher in cm (1x entspricht 5cm)
#define TEMPERATURE_PRECISION 9 // Auflösungsgenauigkeit des Temperatursensors
// WLAN Einstellungen
const char *ssid_ap = "RobbiNetz";
const char *password_ap = "esgibtkeinpasswort";
// Instanziierung der benötigten Klassen
OneWire oneWire(ONE_WIRE_BUS); // Instanz für 1-Wire Handling des DS18B20
DallasTemperature sensors(&oneWire); // Instanz für 1-Wire Handling des DS18B20
DeviceAddress outsideThermometer; // Adressinstanz für den DS18B20
ESP8266WebServer server(80); // HTTP Server Instanz mit Portadresse 80
// Variablendeklarationen
float tempTemperatur; // Gespeicherte Temperatur
String termOUT; // Hilfsstring für Temperaturberechnung
int sensorValue1 = 0; // Eingelesener Lichtschrankenwert
int inputLichtschrankeCount = 0; // Zählvariable wie häufig schon ein rising edge kam
int totalTrack = 0; // Entsprechend zurückgelegte Strecke
String trackUnit = "cm"; // Maßeinheit der zurückgelegten Strecke
bool inputState = 0; // Hilfsvariablen für Detektierung Rising Edge
bool lastInputState = 0; // Hilfsvariablen für Detektierung Rising Edge
bool alarmState = false; // Eingelesener Alarmstatus
String alarmString =""; // Beschreibung des Alarms
boolean bBackward = false;
void handleManualMode(){
// Webinterface für manuelle Steuerung implementieren
char temp[1000];
snprintf(temp, 1000,
"<html><head><style>\
body { background-color: #FFFFFF; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
<title>Webinterface Robbi - Manuelle Steuerung</title></head>\
<body><table border='1' bordercolor='#000000'>\
<tr><td colspan='3'><h1 align='center'>Webinterface Robbi</h1><h3 align='center'>Manuelle Steuerung</h3></td><tr><td></td><td align='center'>\
<input type=button value=VORAUS onmousedown=location.href='/manual?=voraus'>\
</td><td></td></tr>\
<tr><td align='center'>\
<input type=button value=LINKS onmousedown=location.href='/manual?=links'>\
</td><td></td><td align='center'>\
<input type=button value=RECHTS onmousedown=location.href='/manual?=rechts'>\
</td></tr>\
<tr><td></td><td align='center'>\
<input type=button value=ZURÜCK onmousedown=location.href='/manual?=zuruck'>\
</td><td></td></tr><tr><td align='center' colspan='3'><a href=/ >Zurück zur Übersicht</a></td></tr>\
</table></body></html>\
");
server.send(200, "text/html", temp);
}
void handleRoot() {
char temp[1000];
int sec = millis() / 1000;
int min = sec / 60;
int hr = min / 60;
uint8 index = termOUT.indexOf('.');
int restOUT = termOUT.substring(index+1).toInt();
int temperatureOUT = termOUT.toInt();
snprintf(temp, 1000,
"<html>\
<head>\
<meta http-equiv='refresh' content='1'/>\
<title>Webinterface Robbi</title>\
<style>\
body { background-color: #FFFFFF; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
</style>\
</head>\
<body>\
<table border='1' bordercolor='#000000'>\
<tr>\
<td colspan='2'>\
<h1 align='center'>Webinterface Robbi</h1>\
<h3 align='center'>Übersichtsseite</h3>\
</td>\
</tr>\
<tr>\
<td>\
Uptime: </td><td>%02d:%02d:%02d\
</td>\
</tr>\
<tr><td>\
Aussentemperatur:</td><td> %02d.%01d°C\
</td></tr>\
<tr><td>\
Zurückgelegte Strecke:</td><td>%02d cm\
</td></tr>\
<tr><td>\
Alarmstatus:</td><td>%s\
</td></tr>\
<tr><td align='center' colspan='2'><a href=/manual >Zur manuellen Steuerung</a></td></tr>\
</table>\
</body>\
</html>",
hr, min % 60, sec % 60, temperatureOUT,restOUT, totalTrack, alarmString.c_str()
);
server.send(200, "text/html", temp);
}
void handleNotFound() {
String message = "File Not Found\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);
}
void setup() {
pinMode(INPUT_ALARM, INPUT);
Serial.begin(115200);
// Modus AccessPoint
WiFi.softAP(ssid_ap, password_ap);
// HTTP Anfragen -> Funktionen
server.on("/", handleRoot);
server.on("/manual", handleManualMode);
server.on("/about", []() {
server.send(200, "text/plain", "Studienprojekt an der DHBW Mosbach\nJulian Reddemann\nMarc Kappelt");
});
server.onNotFound(handleNotFound);
server.begin();
sensors.begin();
Serial.println(sensors.getDeviceCount(), DEC);
oneWire.reset_search();
if (!oneWire.search(outsideThermometer)) Serial.println("Thermometer gefunden!");
sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);
sensors.requestTemperatures();
// Definiere Lichtschrankeneingang
pinMode(INPUT_LICHTSCHRANKE, INPUT);
}
void loop() {
readLichtschranke(); // Wertet die Informationen der Lichtschranke aus
server.handleClient();
sensors.requestTemperatures();
tempTemperatur = sensors.getTempC(outsideThermometer);
termOUT = String(tempTemperatur, 1);
}
void readLichtschranke(){
// Routine für Auslesen der Lichtschranke
sensorValue1 = analogRead(A0);
alarmState = digitalRead(INPUT_ALARM);
// Alarmbeschreibung in String schreiben
if (alarmState == HIGH){
alarmString = "aktiv";
}
else {
alarmString = "inaktiv";
}
if (sensorValue1>LICHTSCHRANKE_SENSE)
{
// Lichtschranke frei -> Loch erkannt
inputState = true;
}
else{
inputState = false;
}
// Rising Edge detektieren
if (inputState != lastInputState){
if (sensorValue1>LICHTSCHRANKE_SENSE){
inputLichtschrankeCount++;
}
}
lastInputState = inputState;
// Zurückgelegte Strecke ermitteln
totalTrack = (inputLichtschrankeCount*SCALE_FAKTOR_LICHTSCHRANKE)-SCALE_FAKTOR_LICHTSCHRANKE;
if (DEBUG_STATE)
{
Serial.print(sensorValue1);
Serial.print("\t\t\t");
Serial.print(inputLichtschrankeCount);
Serial.print("\t\t\t");
Serial.println(totalTrack);
}
}
But I want to have this kind of control: As long as I pushed the button on the webinterface, a digital output has to be enabled. Just if I release the button, the digital output has to be disabled.
How can I optimize my code, to get this behaviour?
Best regards