revert mission timer to 32 bit, add signal level monitoring

This commit is contained in:
2025-05-05 09:01:04 +02:00
parent 45872bc035
commit 62c4d0a909
2 changed files with 138 additions and 69 deletions

187
main.c
View File

@@ -8,11 +8,14 @@
#include <ncurses.h> #include <ncurses.h>
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include <ctype.h>
#include "packets.h" #include "packets.h"
#include "base.h" #include "base.h"
FILE *csvFile; FILE *csvFile;
int rssi24 = 0;
void write_grayscale_bmp(FILE *f, const uint8_t *pixels, int width, int height) { void write_grayscale_bmp(FILE *f, const uint8_t *pixels, int width, int height) {
if (!f || !pixels || width <= 0 || height <= 0) return; if (!f || !pixels || width <= 0 || height <= 0) return;
@@ -66,14 +69,14 @@ void write_grayscale_bmp(FILE *f, const uint8_t *pixels, int width, int height)
#define MAG_SCALE (4912.0f / 32760.0f) #define MAG_SCALE (4912.0f / 32760.0f)
void printTelemetryPacketNcurses(TelemetryPacket *packet, DownBoundPacket *down) { void printTelemetryPacketNcurses(TelemetryPacket *packet, DownBoundPacket *down, int rssi868, int snr) {
clear(); clear();
int row = 0; int row = 0;
// Time // Time
attroff(COLOR_PAIR(6)); attroff(COLOR_PAIR(6));
mvprintw(row++, 0, "Timestamp: %lu", down->missionTimer); mvprintw(row++, 0, "Timestamp: %lu, 868RSSI: %d, 868SNR: %d, 24RSSI: %d", down->missionTimer, rssi868, snr, rssi24);
// MPU9250 // MPU9250
if (packet->presentDevices & MPU9250_PRESENT_BIT) { if (packet->presentDevices & MPU9250_PRESENT_BIT) {
@@ -348,8 +351,8 @@ void handle_frame(uint8_t *buf, size_t rxLen) {
offset = 0; offset = 0;
} }
// Debug: print key values // Debug: print key values
printf("[DEBUG] offset: %zu, currentByteIndex: %d, rxLen: %d, seq: %d, total_chunks: %d\n", //printf("[DEBUG] offset: %zu, currentByteIndex: %d, rxLen: %d, seq: %d, total_chunks: %d\n",
offset, currentByteIndex, rxLen, seq, total_chunks); //offset, currentByteIndex, rxLen, seq, total_chunks);
// Calculate length safely // Calculate length safely
size_t length = rxLen - currentByteIndex - ((seq == total_chunks - 1) ? 1 : 2); size_t length = rxLen - currentByteIndex - ((seq == total_chunks - 1) ? 1 : 2);
@@ -393,20 +396,47 @@ void handle_frame(uint8_t *buf, size_t rxLen) {
} }
} }
void hexdump(const void *data, size_t size) {
const unsigned char *byte = (const unsigned char *)data;
for (size_t i = 0; i < size; i += 16) {
//printf("%08zx ", i); // print offset
// print hex bytes
for (size_t j = 0; j < 16; j++) {
if (i + j < size)
{
//printf("%02x ", byte[i + j]);
void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) { }
else {
//printf(" ");
}
}
//printf(" ");
// print ASCII representation
for (size_t j = 0; j < 16 && i + j < size; j++) {
unsigned char c = byte[i + j];
//printf("%c", isprint(c) ? c : '.');
}
//printf("\n");
}
}
void handle_downlink_packet(uint8_t *buf, uint8_t rxLen, int rssi868, int snr) {
//hexdump(buf, rxLen);
if (rxLen < sizeof(DownBoundPacket)) { if (rxLen < sizeof(DownBoundPacket)) {
printf("Received packet too small to be valid."); //printf("Received packet too small to be valid.");
return; return;
} }
memcpy(&down, buf, sizeof(DownBoundPacket)); memcpy(&down, buf, sizeof(DownBoundPacket));
printf("Downlink packet index: %u, type: %u", down.packetIndex, down.packetType); //printf("Downlink packet index: %u, type: %u", down.packetIndex, down.packetType);
// Verify sync phrase // Verify sync phrase
if (strncmp(down.syncPhrase, DownlinkSync, strlen(DownlinkSync)) != 0) { if (strncmp(down.syncPhrase, DownlinkSync, strlen(DownlinkSync)) != 0) {
printf("Invalid sync phrase, ignoring packet."); //printf("Invalid sync phrase, ignoring packet.");
return; return;
} }
@@ -416,7 +446,7 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) {
uint32_t crcCheck = crc32_le(0, payload, payloadSize); uint32_t crcCheck = crc32_le(0, payload, payloadSize);
if (crcCheck != down.CRCCheck) { if (crcCheck != down.CRCCheck) {
printf("Received BAD CRC for packet %u, crc is %u, should be %u", down.packetIndex, crcCheck, down.CRCCheck); //printf("Received BAD CRC for packet %u, crc is %u, should be %u\n", down.packetIndex, crcCheck, down.CRCCheck);
return; return;
} }
@@ -424,12 +454,43 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) {
case DownlinkPacketType_Telemetry: case DownlinkPacketType_Telemetry:
if (payloadSize >= sizeof(TelemetryPacket)) { if (payloadSize >= sizeof(TelemetryPacket)) {
memcpy(&telemetryPacket, payload, sizeof(TelemetryPacket)); memcpy(&telemetryPacket, payload, sizeof(TelemetryPacket));
printf("Telemetry packet received!"); //printf("Telemetry packet received!");
float ax = telemetryPacket.accelerationX / 16384.0f;
float ay = telemetryPacket.accelerationY / 16384.0f;
float az = telemetryPacket.accelerationZ / 16384.0f;
float gx = telemetryPacket.gyroX / 131.0f;
float gy = telemetryPacket.gyroY / 131.0f;
float gz = telemetryPacket.gyroZ / 131.0f;
float mx = telemetryPacket.magnetX * MAG_SCALE;
float my = telemetryPacket.magnetY * MAG_SCALE;
float mz = telemetryPacket.magnetZ * MAG_SCALE;
float temp = (telemetryPacket.accelerometer_temperature / 333.87f) + 21.0f;
printTelemetryPacketNcurses(&telemetryPacket, &down); printTelemetryPacketNcurses(&telemetryPacket, &down, rssi868, snr);
fprintf(csvFile, fprintf(csvFile,
"%lu,%u,%u,%u," // missionTimer, packetIndex, telemetryIndex, packetType "MissionTimer,PacketIndex,TelemetryIndex,PacketType,RSSI868,SNR868,RSSI24,"
"AccelerationRawX,AccelerationRawY,AccelerationRawZ,"
"GyroscopeRawX,GyroscopeRawY,GyroscopeRawZ,"
"MagnetometerRawX,MagnetometerRawY,MagnetometerRawZ,"
"MPURawTemp,"
"AccelerationX,AccelerationY,AccelerationZ,"
"GyroscopeX,GyroscopeY,GyroscopeZ,"
"MagnetometerX,MagnetometerY,MagnetometerZ,"
"MPUTemp,"
"eCO2,tVOC,currentCCS,rawCCS,"
"volts,current,power,rawtemperature,rawhumidity,rawpressure,rawgas,"
"gasValid,heaterStable,gasRange,gasIndex,"
"airTemp,relHumidity,baroPressure,gasResistance,"
"iaqScore,tempScore,humidityScore,gasScore,"
"gpsTime,latitude,longitude,altitude,fixQuality,numSatellites,date,speed,"
"predLatitude,predLongitude,predAltitude,"
"NH3,CO,NO2,UVC,"
"currentServoA,targetServoA,currentServoB,targetServoB,"
"presentDevices\n");
fprintf(csvFile,
"%u,%u,%u,%u,%d,%d,%d," // missionTimer, packetIndex, telemetryIndex, packetType
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," // MPU "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," // MPU
"%f,%f,%f,%f,%f,%f,%f,%f,%f,%f," // MPU
"%u,%u,%d,%u," // CCS "%u,%u,%d,%u," // CCS
"%u,%u,%u,%u,%u,%u,%u," // INA, BME basic "%u,%u,%u,%u,%u,%u,%u," // INA, BME basic
"%s,%s,%u,%u," // bools and gas index/range "%s,%s,%u,%u," // bools and gas index/range
@@ -441,19 +502,14 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) {
"%d,%d,%d,%d," // Servo "%d,%d,%d,%d," // Servo
"%u\n", // presentDevices "%u\n", // presentDevices
down.missionTimer, down.missionTimer, down.packetIndex, telemetryPacket.telemetryIndex, down.packetType, rssi868, snr, rssi24,
down.packetIndex,
telemetryPacket.telemetryIndex,
down.packetType,
telemetryPacket.accelerationX, telemetryPacket.accelerationY, telemetryPacket.accelerationZ, telemetryPacket.accelerationX, telemetryPacket.accelerationY, telemetryPacket.accelerationZ,
telemetryPacket.gyroX, telemetryPacket.gyroY, telemetryPacket.gyroZ, telemetryPacket.gyroX, telemetryPacket.gyroY, telemetryPacket.gyroZ,
telemetryPacket.magnetX, telemetryPacket.magnetY, telemetryPacket.magnetZ, telemetryPacket.magnetX, telemetryPacket.magnetY, telemetryPacket.magnetZ,
telemetryPacket.accelerometer_temperature, telemetryPacket.accelerometer_temperature,
ax, ay, az, gx, gy, gz, mx, my, mz, temp,
telemetryPacket.eCO2, telemetryPacket.tvoc, telemetryPacket.currentCCS, telemetryPacket.eCO2, telemetryPacket.tvoc, telemetryPacket.currentCCS,
telemetryPacket.rawCCSData, telemetryPacket.rawCCSData,
telemetryPacket.volts, telemetryPacket.current, telemetryPacket.power, telemetryPacket.volts, telemetryPacket.current, telemetryPacket.power,
telemetryPacket.temperature, telemetryPacket.humidity, telemetryPacket.pressure, telemetryPacket.temperature, telemetryPacket.humidity, telemetryPacket.pressure,
telemetryPacket.gas, telemetryPacket.gas,
@@ -490,18 +546,18 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) {
fflush(csvFile); fflush(csvFile);
fsync(fileno(csvFile)); // Critical: this ensures actual write to disk fsync(fileno(csvFile)); // Critical: this ensures actual write to disk
} else { } else {
printf("Telemetry packet too small (%u bytes)", payloadSize); //printf("Telemetry packet too small (%u bytes)", payloadSize);
} }
break; break;
case DownlinkPacketType_Ping: case DownlinkPacketType_Ping:
printf("Ping packet received!"); //printf("Ping packet received!");
// Optionally respond with pong here // Optionally respond with pong here
break; break;
case DownlinkPacketType_ACK: case DownlinkPacketType_ACK:
printf("ACK packet received!"); //printf("ACK packet received!");
break; break;
default: default:
printf("Unknown packet type: %u", down.packetType); //printf("Unknown packet type: %u", down.packetType);
break; break;
} }
} }
@@ -556,7 +612,7 @@ int subMain() {
csvFile = fopen((const char *) csvName, "w"); csvFile = fopen((const char *) csvName, "w");
int fd = open_serial("/dev/ttyUSB2"); int fd = open_serial("/dev/ttyUSB0");
if (fd < 0) return 1; if (fd < 0) return 1;
char buf[8192]; char buf[8192];
@@ -568,54 +624,67 @@ int subMain() {
unsigned char *decoded; unsigned char *decoded;
size_t decoded_len; size_t decoded_len;
printTelemetryPacketNcurses(&telemetryPacket, &down); printTelemetryPacketNcurses(&telemetryPacket, &down, 0, 0);;
while (1) { while (1) {
char ch; char ch;
size_t n = read(fd, &ch, 1); size_t n = read(fd, &ch, 1);
if (n > 0) { if (n > 0) {
//printf("%c", ch); ////printf("%c", ch);
if (ch == '\n') { if (ch == '\n') {
buf[buf_pos] = '\0'; buf[buf_pos] = '\0';
if (strncmp(buf, "Got DownLink data", 17) == 0) { if (strncmp(buf, "Got DownLink data", 17) == 0) {
int length = 0, rssi = 0, snr = 0;
char *base64 = NULL;
// Match the format: L<int> R<int> S<int>: <base64>
if (sscanf(buf, "Got DownLink data L%d R%d S%d", &length, &rssi, &snr) == 3) {
char *colon = strchr(buf, ':'); char *colon = strchr(buf, ':');
if (colon) { if (colon) {
colon++; colon+= 2;
while (*colon == ' ') colon++; // skip spaces base64 = malloc(strlen(colon) + 1);
printf("Detected base64 payload: %s\n", colon); memcpy(base64, colon, strlen(colon));
//printf("Detected base64 payload: %s\n", base64);
//printf("Length: %d, RSSI: %d dBm, SNR: %d\n", length, rssi, snr);
decoded = base64_decode(colon, strlen(colon) - 1, &decoded_len); decoded = base64_decode(base64, strlen(base64) - 1, &decoded_len);
if (decoded != NULL) {
printf("Decoded data (%zu bytes):\n", decoded_len);
handle_downlink_packet(decoded, decoded_len);
} else {
printf("Base64 decode failed\n");
}
if (decoded != NULL) { if (decoded != NULL) {
//printf("Decoded data (%zu bytes):\n", decoded_len);
handle_downlink_packet(decoded, decoded_len, rssi, snr);
free(decoded); free(decoded);
} else {
//printf("Base64 decode failed for\nPAY:%s\nBUF: %s\n", base64, buf);
} }
free(base64);
} }
} else if (strncmp(buf, "Got 2400mhZ frame", 17) == 0) {
} else {
//printf("Failed to parse DownLink line\n");
}
} else if (strncmp(buf, "Got 2400mhZ frame on", 20) == 0) {
// Parse RSSI and base64 string
char *payload = NULL;
if (sscanf(buf, "Got 2400mhZ frame on %d", &rssi24) == 1) {
//printf("RSSI: %d dBm\n", rssi24);
//printf("Payload (base64): %s\n", payload);
char *colon = strchr(buf, ':'); char *colon = strchr(buf, ':');
if (colon) { if (colon) {
colon++; colon+= 2;
while (*colon == ' ') colon++; // skip spaces char *base64 = malloc(strlen(colon) + 1);
printf("Detected base64 payload: %s\n", colon); memcpy(base64, colon, strlen(colon) + 1);
if (colon[strlen(colon) - 1] == '\r') {
colon[strlen(colon) - 1] = 0;
}
decoded = base64_decode(colon, strlen(colon), &decoded_len); if (base64_decode(payload, strlen(payload), &decoded_len) == NULL) {
if (decoded != NULL) {
printf("Decoded data (%zu bytes):\n", decoded_len);
handle_frame(decoded, decoded_len); handle_frame(decoded, decoded_len);
} else { } else {
printf("Base64 decode failed\n"); fprintf(stderr, "Base64 decode failed\n");
} }
if (decoded != NULL) {
free(decoded); free(payload); // %ms allocates memory, free it
free(base64);
} }
} else {
fprintf(stderr, "Failed to parse RSSI and payload\n");
} }
} }
buf_pos = 0; buf_pos = 0;
@@ -637,16 +706,16 @@ int subMain() {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
init_crc32_table(); init_crc32_table();
// initscr(); // Start ncurses mode initscr(); // Start ncurses mode
// start_color(); // Enable color start_color(); // Enable color
// use_default_colors(); use_default_colors();
// init_pair(1, COLOR_CYAN, -1); init_pair(1, COLOR_CYAN, -1);
// init_pair(2, COLOR_GREEN, -1); init_pair(2, COLOR_GREEN, -1);
// init_pair(3, COLOR_YELLOW, -1); init_pair(3, COLOR_YELLOW, -1);
// init_pair(4, COLOR_RED, -1); init_pair(4, COLOR_RED, -1);
// init_pair(5, COLOR_CYAN, -1); init_pair(5, COLOR_CYAN, -1);
// init_pair(6, COLOR_MAGENTA, -1); init_pair(6, COLOR_MAGENTA, -1);
// curs_set(0); // Hide cursor curs_set(0); // Hide cursor
int x = subMain(); int x = subMain();
endwin(); // End ncurses mode endwin(); // End ncurses mode
return x; return x;

View File

@@ -24,7 +24,7 @@ typedef struct __attribute__((packed))
char syncPhrase[10]; char syncPhrase[10];
uint32_t packetIndex; uint32_t packetIndex;
uint8_t packetType; uint8_t packetType;
uint64_t missionTimer; uint32_t missionTimer;
uint32_t CRCCheck; uint32_t CRCCheck;
} DownBoundPacket; } DownBoundPacket;