revert mission timer to 32 bit, add signal level monitoring
This commit is contained in:
205
main.c
205
main.c
@@ -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) {
|
||||||
char *colon = strchr(buf, ':');
|
int length = 0, rssi = 0, snr = 0;
|
||||||
if (colon) {
|
char *base64 = NULL;
|
||||||
colon++;
|
|
||||||
while (*colon == ' ') colon++; // skip spaces
|
|
||||||
printf("Detected base64 payload: %s\n", colon);
|
|
||||||
|
|
||||||
decoded = base64_decode(colon, strlen(colon) - 1, &decoded_len);
|
// Match the format: L<int> R<int> S<int>: <base64>
|
||||||
if (decoded != NULL) {
|
if (sscanf(buf, "Got DownLink data L%d R%d S%d", &length, &rssi, &snr) == 3) {
|
||||||
printf("Decoded data (%zu bytes):\n", decoded_len);
|
char *colon = strchr(buf, ':');
|
||||||
handle_downlink_packet(decoded, decoded_len);
|
if (colon) {
|
||||||
} else {
|
colon+= 2;
|
||||||
printf("Base64 decode failed\n");
|
base64 = malloc(strlen(colon) + 1);
|
||||||
}
|
memcpy(base64, colon, strlen(colon));
|
||||||
if (decoded != NULL) {
|
//printf("Detected base64 payload: %s\n", base64);
|
||||||
free(decoded);
|
//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) {
|
} else if (strncmp(buf, "Got 2400mhZ frame on", 20) == 0) {
|
||||||
char *colon = strchr(buf, ':');
|
// Parse RSSI and base64 string
|
||||||
if (colon) {
|
char *payload = NULL;
|
||||||
colon++;
|
if (sscanf(buf, "Got 2400mhZ frame on %d", &rssi24) == 1) {
|
||||||
while (*colon == ' ') colon++; // skip spaces
|
//printf("RSSI: %d dBm\n", rssi24);
|
||||||
printf("Detected base64 payload: %s\n", colon);
|
//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 (base64_decode(payload, strlen(payload), &decoded_len) == NULL) {
|
||||||
if (decoded != NULL) {
|
handle_frame(decoded, decoded_len);
|
||||||
printf("Decoded data (%zu bytes):\n", decoded_len);
|
} else {
|
||||||
handle_frame(decoded, decoded_len);
|
fprintf(stderr, "Base64 decode failed\n");
|
||||||
} else {
|
}
|
||||||
printf("Base64 decode failed\n");
|
|
||||||
}
|
free(payload); // %ms allocates memory, free it
|
||||||
if (decoded != NULL) {
|
free(base64);
|
||||||
free(decoded);
|
|
||||||
}
|
}
|
||||||
|
} 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;
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user