I was just referencing the remote and cannot take the credit for that - I thought the work was so good that I wanted to share it with all of you.
Anyways, I'm planning to install my autopilot tomorrow. I'm using an ESP32 with the +3v3 pin and the tx gpio. I have followed the advices above, but instead of sending to serial OPENCPN is sending APB to network UDP on IP 10.10.10.112 (my ESP address) and port 3001. In addition I have included OTA (over the air) because my device is located behind a staircase. With OTA I can reprogram my ESP32 at any time over wifi without having to connect the ESP32 to a USB. I can also use serial monitor over wifi. As an example, I'll need to program in a hard IP-address at some point later and I'm also planning to add autopilot wind direction control.
For power, I'm using a RC plane/helicopter UBEC set at 6V. They are incredibly efficient, safe, silent and cheap. I'm using the VIN and GND pins.
Code:
/*
*
*
*/
#include "AsyncUDP.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
#define led 2 //D pin (Build-in LED for Devkit V1)
const char* host = "esp32";
const char* ssid = "******raspberry ssid*********";
const char* password = "*******raspberry password***********";
int count = 0;
int count_wifi = 0;
AsyncUDP udp;
WebServer server(80);
/*
* Login page
*/
const char* loginIndex =
"<form name='loginForm'>"
"<table width='20%' bgcolor='A09F9F' align='center'>"
"<tr>"
"<td colspan=2>"
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
"<br>"
"</td>"
"<br>"
"<br>"
"</tr>"
"<td>Username:</td>"
"<td><input type='text' size=25 name='userid'><br></td>"
"</tr>"
"<br>"
"<br>"
"<tr>"
"<td>Password:</td>"
"<td><input type='Password' size=25 name='pwd'><br></td>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
"</tr>"
"</table>"
"</form>"
"<script>"
"function check(form)"
"{"
"if(form.userid.value=='admin' && form.pwd.value=='admin')"
"{"
"window.open('/serverIndex')"
"}"
"else"
"{"
" alert('Error Password or Username')/*displays error message*/"
"}"
"}"
"</script>";
/*
* Server Index Page
*/
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress', function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"}, false);"
"return xhr;"
"},"
"success:function(d, s) {"
"console.log('success!')"
"},"
"error: function (a, b, c) {"
"}"
"});"
"});"
"</script>";
/*
* setup function
*/
void setup(void) {
pinMode(led,OUTPUT);
Serial.begin(4800);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while(1) {
delay(1000);
}
}
if(udp.connect(IPAddress(10,10,10,1), 3333)) {
Serial.println("UDP connected");
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
//reply to the client
packet.printf("Got %u bytes of data", packet.length());
});
//Send unicast
udp.print("Hello Server!");
}
//use mdns for host name resolutio
if (!MDNS.begin(host)) { //http://esp32.local
Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
//return index page which is stored in serverIndex
server.on("/", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", loginIndex);
});
server.on("/serverIndex", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", serverIndex);
});
//handling uploading firmware file //
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
// flashing firmware to ESP//
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
}
});
server.begin();
}
/*
*
*
*
* VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP VOID LOOP
*
*
*
*
*
*/
void loop()
{
server.handleClient();
digitalWrite(led, LOW);
delay(100);
if (udp.listen(3001)) {
udp.onPacket([](AsyncUDPPacket packet) {
Serial.write(packet.data(), packet.length());
digitalWrite(led, HIGH);
}
);
}
// } else {
// Serial.println("failed"); // WiFi.reconnect(); // ESP.restart();
// WiFi.mode(WIFI_STA);
// WiFi.begin(ssid, password);
// }
}
When you install the ESP32 into the Arduino IDE library there is a ton of examples included. Have a look at the examples if you want to understand the code.