festival_finder/20250815_basic_finder.ino/20250815_basic_finder.ino.ino
Tim Staat 488ad08e38 Send azimuth + configurable bearing correction
From this change on, the client adds its azimuth measurement
to the get paramters, so the server can do the correction.

Also the response parameter for locally correcting bearing
according to azimuth measurements is respected.

Some comments from copy paste stuff were deleted.
2025-09-04 17:28:36 +02:00

227 lines
5.6 KiB
C++

#include <U8g2lib.h>
#include <TinyGPSMinus.h>
#include <Wire.h>
#include <QMC5883LCompass.h>
#include "wifi_save.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <config_secrets.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // if you use Hardware I2C port, full framebuffer, size = 1024 bytes
QMC5883LCompass compass;
#define RXD2 16
#define TXD2 17
#define GPS_BAUD 9600
String webserviceAddress = "https://festival-finder.noe-danke.de/updateGPS";
String serverAvailableAddress = "https://festival-finder.noe-danke.de/";
bool connected = false;
bool use_bearing_correction = true;
HardwareSerial gpsSerial(2);
TinyGPSMinus gps;
byte triangles[][6] = {
{ 10, 48, 30, 48, 20, 16 },
{ 5, 43, 23, 51, 26, 17 },
{ 2, 36, 16, 50, 31, 21 },
{ 1, 29, 9, 47, 35, 26 },
{ 4, 22, 4, 42, 36, 32 },
{ 9, 17, 1, 35, 35, 38 },
{ 16, 14, 2, 28, 31, 43 },
{ 23, 13, 5, 21, 26, 47 },
{ 30, 16, 10, 16, 20, 48 },
{ 35, 21, 17, 13, 14, 47 },
{ 38, 28, 24, 14, 9, 43 },
{ 39, 35, 31, 17, 5, 38 },
{ 36, 42, 36, 22, 4, 32 },
{ 31, 47, 39, 29, 5, 26 },
{ 24, 50, 38, 36, 9, 21 },
{ 17, 51, 35, 43, 14, 17 },
{ 10, 48, 30, 48, 20, 16 }
};
void setup(void) {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
if (wifi_set_main()) {
Serial.println("Connect WIFI SUCCESS");
connected = true;
} else {
digitalWrite(LED_PIN, LOW);
Serial.println("Connect WIFI FAULT");
}
compass.init();
u8g2.begin(); // start a display.
gpsSerial.begin(GPS_BAUD, SERIAL_8N1, RXD2, TXD2);
Serial.println("Serial 2 started at 9600 baud rate");
}
void drawTriangles(byte i, char *time, char *distanceString) {
u8g2.clearBuffer();
u8g2.drawTriangle(triangles[i][0], triangles[i][1], triangles[i][2], triangles[i][3], triangles[i][4], triangles[i][5]);
u8g2.sendBuffer();
u8g2.setFont(u8g2_font_helvR08_tr);
u8g2.drawButtonUTF8(48, 64 - 40, U8G2_BTN_BW0, 0, 0, 0, "Last Update:");
u8g2.drawButtonUTF8(48, 64 - 30, U8G2_BTN_BW0, 0, 0, 0, time);
u8g2.drawButtonUTF8(48, 64 - 16, U8G2_BTN_BW0, 0, 0, 0, distanceString);
u8g2.sendBuffer();
delay(2000);
}
bool doHttpRequest(char *payload, char *latitude, char *longitude, char *gpsTime, char *az) {
HTTPClient http;
// Change space to 0
if(*(latitude + 6) == ' ')
*(latitude + 6) = '0';
String serverPath = webserviceAddress + "?long=" + longitude + "&lat=" + latitude + "&id=" + OWN_ID + "&req_id=" + REQ_ID + "&gpsDateTime=" + gpsTime + "&passkey=" + SERVER_PASSKEY + "&az=" + az;
Serial.println(serverPath);
http.begin(serverPath.c_str());
int httpResponseCode = http.GET();
if (httpResponseCode == 200 ) {
const char* cpayload = http.getString().c_str();
strcpy(payload, cpayload);
Serial.println(payload);
return true;
} else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
return false;
}
}
void checkWifiConnection() {
HTTPClient http;
http.begin(serverAvailableAddress);
int httpResponseCode = http.GET();
Serial.print("Server availablity test response code: ");
Serial.println(httpResponseCode);
if (httpResponseCode == 200) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
}
byte calculateBearing(float bearing) {
if(!use_bearing_correction) {
int iBearing = bearing;
return compass.getBearing(iBearing);
}
compass.read();
int relativeAngle = (int)(bearing - compass.getAzimuth());
relativeAngle += 360;
relativeAngle %= 360;
return (compass.getBearing(relativeAngle) + BEARING_CORRECTION + 16) % 16;
}
void setDistanceBearingString(char *time, char *distance, byte *bearing, const char *payload) {
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
const char* dist2 = doc["distance"];
const char* time2 = doc["lastUpdateTZ"];
use_bearing_correction = doc["bear_correction"];
strcpy(distance, dist2);
strcpy(time, time2);
*bearing = calculateBearing(String(doc["azimuth"]).toFloat());
}
void loop(void) {
checkWifiConnection();
while (gpsSerial.available() > 0) {
// get the byte data from the GPS
char gpsData = gpsSerial.read();
Serial.print(gpsData);
if (gps.encode(gpsData)) {
break;
}
}
Serial.println();
long unsigned date, time, age;
char *longitude, *latitude, *dateTime;
longitude = gps.get_longitude();
latitude = gps.get_latitude();
gps.get_datetime(&date, &time, &age);
Serial.println(latitude);
Serial.println(longitude);
char myPayloadResponse[128];
char timeString[10], dateString[10], dateTimeString[24], azString[11];
ltoa(time, timeString, 10);
ltoa(date, dateString, 10);
// for (int i = 0; i < 18; i++) {
// if (i < 7) {
// dateTimeString[i] = dateString[i];
// } else {
// dateTimeString[i] = timeString[i - 8];
// }
// }
strcpy(dateTimeString, dateString);
strcat(dateTimeString, timeString);
byte triangleIndex = 0;
char distanceArray[] = { 'N', 'o', ' ', 'S', 'e', 'r', 'v', 'e', 'r', '\0' };
char distanceString[16];
strcpy(distanceString, distanceArray);
char remoteTimeString[16];
strcpy(remoteTimeString, timeString);
compass.read();
int az = compass.getAzimuth();
sprintf(azString, "%ld", az);
if (doHttpRequest(myPayloadResponse, latitude, longitude, dateTimeString, azString))
setDistanceBearingString(remoteTimeString, distanceString, &triangleIndex, myPayloadResponse);
drawTriangles(triangleIndex, remoteTimeString, distanceString);
Serial.println("-------------------------------");
delay(1000);
}