From 62c4d0a909ee04d58f7221318f67b292f131b266 Mon Sep 17 00:00:00 2001 From: bruno Date: Mon, 5 May 2025 09:01:04 +0200 Subject: [PATCH] revert mission timer to 32 bit, add signal level monitoring --- main.c | 205 ++++++++++++++++++++++++++++++++++++------------------ packets.h | 2 +- 2 files changed, 138 insertions(+), 69 deletions(-) diff --git a/main.c b/main.c index 9946fe3..1f972d6 100644 --- a/main.c +++ b/main.c @@ -8,11 +8,14 @@ #include #include #include +#include #include "packets.h" #include "base.h" FILE *csvFile; +int rssi24 = 0; + void write_grayscale_bmp(FILE *f, const uint8_t *pixels, int width, int height) { 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) -void printTelemetryPacketNcurses(TelemetryPacket *packet, DownBoundPacket *down) { +void printTelemetryPacketNcurses(TelemetryPacket *packet, DownBoundPacket *down, int rssi868, int snr) { clear(); int row = 0; // Time 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 if (packet->presentDevices & MPU9250_PRESENT_BIT) { @@ -348,8 +351,8 @@ void handle_frame(uint8_t *buf, size_t rxLen) { offset = 0; } // Debug: print key values - printf("[DEBUG] offset: %zu, currentByteIndex: %d, rxLen: %d, seq: %d, total_chunks: %d\n", - offset, currentByteIndex, rxLen, seq, total_chunks); + //printf("[DEBUG] offset: %zu, currentByteIndex: %d, rxLen: %d, seq: %d, total_chunks: %d\n", + //offset, currentByteIndex, rxLen, seq, total_chunks); // Calculate length safely 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)) { - printf("Received packet too small to be valid."); + //printf("Received packet too small to be valid."); return; } 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 if (strncmp(down.syncPhrase, DownlinkSync, strlen(DownlinkSync)) != 0) { - printf("Invalid sync phrase, ignoring packet."); + //printf("Invalid sync phrase, ignoring packet."); return; } @@ -416,7 +446,7 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) { uint32_t crcCheck = crc32_le(0, payload, payloadSize); 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; } @@ -424,12 +454,43 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) { case DownlinkPacketType_Telemetry: if (payloadSize >= 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, - "%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 + "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f," // MPU "%u,%u,%d,%u," // CCS "%u,%u,%u,%u,%u,%u,%u," // INA, BME basic "%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 "%u\n", // presentDevices - down.missionTimer, - down.packetIndex, - telemetryPacket.telemetryIndex, - down.packetType, - + down.missionTimer, down.packetIndex, telemetryPacket.telemetryIndex, down.packetType, rssi868, snr, rssi24, telemetryPacket.accelerationX, telemetryPacket.accelerationY, telemetryPacket.accelerationZ, telemetryPacket.gyroX, telemetryPacket.gyroY, telemetryPacket.gyroZ, telemetryPacket.magnetX, telemetryPacket.magnetY, telemetryPacket.magnetZ, telemetryPacket.accelerometer_temperature, - + ax, ay, az, gx, gy, gz, mx, my, mz, temp, telemetryPacket.eCO2, telemetryPacket.tvoc, telemetryPacket.currentCCS, telemetryPacket.rawCCSData, - telemetryPacket.volts, telemetryPacket.current, telemetryPacket.power, telemetryPacket.temperature, telemetryPacket.humidity, telemetryPacket.pressure, telemetryPacket.gas, @@ -490,18 +546,18 @@ void handle_downlink_packet(uint8_t *buf, uint8_t rxLen) { fflush(csvFile); fsync(fileno(csvFile)); // Critical: this ensures actual write to disk } else { - printf("Telemetry packet too small (%u bytes)", payloadSize); + //printf("Telemetry packet too small (%u bytes)", payloadSize); } break; case DownlinkPacketType_Ping: - printf("Ping packet received!"); + //printf("Ping packet received!"); // Optionally respond with pong here break; case DownlinkPacketType_ACK: - printf("ACK packet received!"); + //printf("ACK packet received!"); break; default: - printf("Unknown packet type: %u", down.packetType); + //printf("Unknown packet type: %u", down.packetType); break; } } @@ -556,7 +612,7 @@ int subMain() { csvFile = fopen((const char *) csvName, "w"); - int fd = open_serial("/dev/ttyUSB2"); + int fd = open_serial("/dev/ttyUSB0"); if (fd < 0) return 1; char buf[8192]; @@ -568,54 +624,67 @@ int subMain() { unsigned char *decoded; size_t decoded_len; - printTelemetryPacketNcurses(&telemetryPacket, &down); + printTelemetryPacketNcurses(&telemetryPacket, &down, 0, 0);; while (1) { char ch; size_t n = read(fd, &ch, 1); if (n > 0) { - //printf("%c", ch); + ////printf("%c", ch); if (ch == '\n') { buf[buf_pos] = '\0'; if (strncmp(buf, "Got DownLink data", 17) == 0) { - char *colon = strchr(buf, ':'); - if (colon) { - colon++; - while (*colon == ' ') colon++; // skip spaces - printf("Detected base64 payload: %s\n", colon); + int length = 0, rssi = 0, snr = 0; + char *base64 = NULL; - decoded = base64_decode(colon, strlen(colon) - 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) { - free(decoded); + // Match the format: L R S: + if (sscanf(buf, "Got DownLink data L%d R%d S%d", &length, &rssi, &snr) == 3) { + char *colon = strchr(buf, ':'); + if (colon) { + colon+= 2; + base64 = malloc(strlen(colon) + 1); + 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(base64, strlen(base64) - 1, &decoded_len); + if (decoded != NULL) { + //printf("Decoded data (%zu bytes):\n", decoded_len); + handle_downlink_packet(decoded, decoded_len, rssi, snr); + free(decoded); + } else { + //printf("Base64 decode failed for\nPAY:%s\nBUF: %s\n", base64, buf); + } + free(base64); } + + } else { + //printf("Failed to parse DownLink line\n"); } - } else if (strncmp(buf, "Got 2400mhZ frame", 17) == 0) { - char *colon = strchr(buf, ':'); - if (colon) { - colon++; - while (*colon == ' ') colon++; // skip spaces - printf("Detected base64 payload: %s\n", colon); + } 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, ':'); + if (colon) { + colon+= 2; + char *base64 = malloc(strlen(colon) + 1); + 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 (decoded != NULL) { - printf("Decoded data (%zu bytes):\n", decoded_len); - handle_frame(decoded, decoded_len); - } else { - printf("Base64 decode failed\n"); - } - if (decoded != NULL) { - free(decoded); + if (base64_decode(payload, strlen(payload), &decoded_len) == NULL) { + handle_frame(decoded, decoded_len); + } else { + fprintf(stderr, "Base64 decode failed\n"); + } + + free(payload); // %ms allocates memory, free it + free(base64); } + } else { + fprintf(stderr, "Failed to parse RSSI and payload\n"); } } buf_pos = 0; @@ -637,16 +706,16 @@ int subMain() { int main(int argc, char *argv[]) { init_crc32_table(); -// initscr(); // Start ncurses mode -// start_color(); // Enable color -// use_default_colors(); -// init_pair(1, COLOR_CYAN, -1); -// init_pair(2, COLOR_GREEN, -1); -// init_pair(3, COLOR_YELLOW, -1); -// init_pair(4, COLOR_RED, -1); -// init_pair(5, COLOR_CYAN, -1); -// init_pair(6, COLOR_MAGENTA, -1); -// curs_set(0); // Hide cursor + initscr(); // Start ncurses mode + start_color(); // Enable color + use_default_colors(); + init_pair(1, COLOR_CYAN, -1); + init_pair(2, COLOR_GREEN, -1); + init_pair(3, COLOR_YELLOW, -1); + init_pair(4, COLOR_RED, -1); + init_pair(5, COLOR_CYAN, -1); + init_pair(6, COLOR_MAGENTA, -1); + curs_set(0); // Hide cursor int x = subMain(); endwin(); // End ncurses mode return x; diff --git a/packets.h b/packets.h index cc265c8..1c9b551 100644 --- a/packets.h +++ b/packets.h @@ -24,7 +24,7 @@ typedef struct __attribute__((packed)) char syncPhrase[10]; uint32_t packetIndex; uint8_t packetType; - uint64_t missionTimer; + uint32_t missionTimer; uint32_t CRCCheck; } DownBoundPacket;