This commit is contained in:
2025-04-22 20:35:29 +02:00
parent 9104869ecf
commit 5853bf849f
17 changed files with 1704 additions and 941 deletions

View File

@@ -0,0 +1,88 @@
#ifndef PACKETS_STRUCTS
#define PACKETS_STRUCTS
#include "stdint.h"
typedef struct __attribute__((packed))
{
uint32_t packetIndex;
uint8_t packetType;
uint32_t missionTimer;
} DownBoundPacket;
typedef struct __attribute__((packed))
{
// MPU data
int16_t accelerationX;
int16_t accelerationY;
int16_t accelerationZ;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
int16_t magnetX;
int16_t magnetY;
int16_t magnetZ;
int16_t accelerometer_temperature;
// CCS data
uint16_t eCO2;
uint16_t tvoc;
uint8_t currentCCS;
uint16_t rawCCSData;
// INA data
uint16_t volts;
uint16_t current;
uint16_t power;
// BME DATA
uint32_t temperature;
uint16_t humidity;
uint32_t pressure;
uint16_t gas;
bool gas_valid;
bool heater_stable;
uint8_t gas_range;
uint8_t gas_index;
// GPS DATA
uint32_t time_seconds; // Seconds since start of day
int32_t latitude_centi_degrees; // Latitude * 10,000
int32_t longitude_centi_degrees; // Longitude * 10,000
int16_t altitude_centi_meters; // Altitude * 100
uint8_t fix_quality;
uint8_t num_satellites;
uint16_t date_yyddmm; // YYDDMM (from GPRMC)
uint16_t speed_centi_knots; // Speed * 100 (from GPRMC)
int32_t predicted_latitude_centi_degrees; // Latitude * 10,000
int32_t predicted_longitude_centi_degrees; // Longitude * 10,000
int16_t predicted_altitude_centi_meters; // Altitude * 100
// ADC DATA
int32_t NH3;
int32_t CO;
int32_t NO2;
int32_t UVC;
int16_t currentServoA;
int16_t targetServoA;
int16_t currentServoB;
int16_t targetServoB;
} TelemetryPacket;
typedef struct __attribute__((packed))
{
uint32_t packetIndex;
uint8_t packetType;
} UplinkPacket;
typedef struct __attribute__((packed))
{
uint8_t powerMode;
uint8_t controlMode;
uint16_t servoA;
uint16_t servoB;
} SystemControlPacket;
#endif

View File

@@ -2,206 +2,107 @@
#include "freertos/task.h"
#include "../hw/sx1262.h"
#include "radio.h"
#include "esp_log.h"
#include "string.h"
#include "esp_timer.h"
const char *msg = "Testing 123 test why is this not on air";
#define TAG "LoRa"
uint32_t packetIndex = 0;
TelemetryPacket telemetryPacket;
uint8_t packetReadiness = 0;
void lora_comms_task(void *pvParameters)
{
sx1262_init();
sx1262_resetStats();
ESP_LOGI(TAG_RADIO, "Setting standby RC");
sx1262_setStandby(SX1262_STANDBY_RC);
ESP_LOGI(TAG_RADIO, "Getting version");
unsigned char versDat[16];
sx1262_readRegister(0x0320, versDat, 16);
ESP_LOGI(TAG_RADIO, "Version: %s", versDat);
const int64_t interval_us = 100000; // 100 ms
int64_t start_time, end_time, elapsed;
LoRaInit();
int8_t txPowerInDbm = 20;
sx1262_get_status();
uint32_t frequencyInHz = 0;
frequencyInHz = 869525000;
ESP_LOGW(TAG, "Enable TCXO");
float tcxoVoltage = 2.2; // use TCXO
bool useRegulatorLDO = true; // use DCDC + LDO
// Read status
sx1262_get_status();
// LoRaDebugPrint(true);
if (LoRaBegin(frequencyInHz, txPowerInDbm, tcxoVoltage, useRegulatorLDO) != 0)
{
ESP_LOGE(TAG, "Does not recognize the module");
while (1)
{
vTaskDelay(1);
}
}
ESP_LOGI(TAG_RADIO, "Setting TCXO");
sx1262_setDIO3AsTCXOCtrl(SX1262_TCXO_VOLTAGE22dV, 320);
uint8_t spreadingFactor = 7;
uint8_t bandwidth = SX126X_LORA_BW_250_0;
uint8_t codingRate = SX126X_LORA_CR_4_8;
uint16_t preambleLength = 8;
uint8_t payloadLen = 0;
bool crcOn = true;
bool invertIrq = false;
LoRaConfig(spreadingFactor, bandwidth, codingRate, preambleLength, payloadLen, crcOn, invertIrq);
uint8_t bufIn[256]; // Maximum Payload size of SX1261/62/68 is 255
uint8_t bufOut[256]; // Maximum Payload size of SX1261/62/68 is 255
sx1262_get_status();
DownBoundPacket downboundPacket;
UplinkPacket uplinkPacket;
SystemControlPacket systemControlPacket;
ESP_LOGI(TAG_RADIO, "Setting Buffer base address");
sx1262_setBufferBaseAddress(0, 0);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting packet Type");
sx1262_setPacketType(SX1262_PACKET_TYPE_LORA);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting RXTX fallback mode");
sx1262_setRxTXFallbackMode(SX1262_FALLBACK_RC);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting CAD params");
sx1262_setCadParams(0x03, 0x16, 0x0A, 0, 0);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Clearing IRQ status");
sx1262_clearIrqStatus(0x43FF);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting Image rejection");
sx1262_calibrateImage(0xD7, 0xDB);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Calibrating Image rejection");
sx1262_calibrate(SX1262_CALIBRATION_ALL);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting regulator");
sx1262_setRegulatorMode(SX1262_REGULATOR_DC_DC_LDO);
sx1262_get_status();
uint8_t modType;
modType = sx1262_getPacketType();
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "ModType %d", modType);
sx1262_LoRaModulationParams_t loraModParams;
loraModParams.bandwidth = SX1262_LORA_BW_125;
loraModParams.codingRate = SX1262_LORA_CR_4_5;
loraModParams.lowDataRateOpt = 1;
loraModParams.spreadingFactor = SX1262_LORA_SF7;
ESP_LOGI(TAG_RADIO, "Setting modulation params");
sx1262_setLoRaModulationParams(&loraModParams);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting Sync word");
uint8_t syncWord[2] = {0x14, 0x24};
sx1262_writeRegister(SX1262_LORA_SYNC_WORD_MSB, syncWord, 2);
sx1262_get_status();
uint8_t ocpBuf[1] = {SX126X_OCP_LEVEL_SX1262};
ESP_LOGI(TAG_RADIO, "Setting overcurrent protection");
sx1262_writeRegister(SX126X_OCP_CONFIGURATION, ocpBuf, 1);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting RF Switch out");
sx1262_setDIO2AsRfSwitchCtrl(1);
sx1262_get_status();
sx1262_LoRaPacketParams_t loraPacketParams;
loraPacketParams.preambleLength = 10;
loraPacketParams.crcType = SX1262_CRC_ON;
loraPacketParams.headerType = SX1262_HEADER_TYPE_VARIABLE;
loraPacketParams.invertIQ = SX1262_STANDARD_IQ;
loraPacketParams.payloadLength = sizeof(msg);
ESP_LOGI(TAG_RADIO, "Setting packet params");
sx1262_setLoRaPacketParams(&loraPacketParams);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting frequency");
sx1262_setFrequency(869525000);
uint8_t clampConfig[1] = {0xDE};
ESP_LOGI(TAG_RADIO, "Setting TX clamp");
sx1262_writeRegister(SX126X_TX_CLAMP_CONFIG, clampConfig, 1);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting TX power");
sx1262_configure_tx_power(0x04, 0x07, 0x01, LORA_TX_POWER, SX1262_Ramp_200U);
sx1262_get_status();
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting standby XOSC");
sx1262_setStandby(SX1262_STANDBY_XOSC);
sx1262_get_status();
sx1262_setDioIrqParams(SX1262_IRQ_ALL, SX1262_IRQ_TXDone, 0, 0);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Setting buffer base address");
sx1262_setBufferBaseAddress(0, 0);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Writing message");
sx1262_writeBuffer(0, (uint8_t *)msg, sizeof(msg));
ESP_LOGI(TAG_RADIO, "Clearing IRQs");
sx1262_clearIrqStatus(SX1262_IRQ_ALL);
// sx1262_setTxContinuousWave();
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Getting modulation type...");
modType = sx1262_getPacketType();
ESP_LOGI(TAG_RADIO, "ModType %d", modType);
sx1262_get_status();
// ESP_LOGI(TAG_RADIO, "Enabling CW...");
// sx1262_setTxContinuousWave();
// sx1262_get_status();
uint8_t txModulation[1] = {0x04};
ESP_LOGI(TAG_RADIO, "Setting modulation thing");
sx1262_writeRegister(SX126X_TX_MODULATION, txModulation, 1);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Clearing IRQs");
sx1262_clearIrqStatus(SX1262_IRQ_ALL);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Enabling TX...");
sx1262_setMode(SX1262_TRANSMIT_MODE, 0);
sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Waiting for TX finish");
while (1)
{
if (gpio_get_level(LORA_DIO1))
start_time = esp_timer_get_time(); // µs since boot
if (packetReadiness == 1)
{
ESP_LOGI(TAG_RADIO, "Got IRQin");
uint16_t irqS = sx1262_getIrqStatus();
if (irqS & SX1262_IRQ_TXDone)
uint8_t downPacketSize = 0;
memset(bufOut, 0, sizeof(bufOut));
downboundPacket.missionTimer = start_time;
downboundPacket.packetIndex = packetIndex++;
downboundPacket.packetType = 1;
memcpy(bufOut, &downboundPacket, sizeof(downboundPacket));
downPacketSize += sizeof(downboundPacket);
memcpy(((uint8_t *)bufOut) + downPacketSize, &telemetryPacket, sizeof(telemetryPacket));
downPacketSize += sizeof(telemetryPacket);
ESP_LOGI(pcTaskGetName(NULL), "%d byte packet sent...", downPacketSize);
// Wait for transmission to complete
if (LoRaSend(bufOut, downPacketSize, SX126x_TXMODE_SYNC) == false)
{
break;
ESP_LOGE(pcTaskGetName(NULL), "LoRaSend fail");
} else {
packetReadiness = 0;
}
}
vTaskDelay(pdMS_TO_TICKS(10));
uint8_t rxLen = LoRaReceive(bufIn, sizeof(bufIn));
if (rxLen > 0)
{
ESP_LOGI(pcTaskGetName(NULL), "%d byte packet received:[%.*s]", rxLen, rxLen, bufIn);
int8_t rssi, snr;
GetPacketStatus(&rssi, &snr);
ESP_LOGI(pcTaskGetName(NULL), "rssi=%d[dBm] snr=%d[dB]", rssi, snr);
}
int lost = GetPacketLost();
if (lost != 0)
{
ESP_LOGW(pcTaskGetName(NULL), "%d packets lost", lost);
}
end_time = esp_timer_get_time();
elapsed = end_time - start_time;
if (elapsed < interval_us)
{
vTaskDelay(pdMS_TO_TICKS((interval_us - elapsed) / 1000));
}
}
// vTaskDelay(pdMS_TO_TICKS(2000));
// ESP_LOGI(TAG_RADIO, "Returning back to sleep");
// sx1262_setStandby(SX1262_STANDBY_XOSC);
// sx1262_get_status();
ESP_LOGI(TAG_RADIO, "Clearing IRQs");
sx1262_clearIrqStatus(SX1262_IRQ_TXDone);
sx1262_get_status();
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
}
// Set frequency to 868 MHz
// Set TX power to 22 dBm
// sx1262_setTxContinuousWave();
}

View File

@@ -9,6 +9,11 @@
#define TAG_RADIO "RADIO"
#include "packets.h"
void lora_comms_task(void *pvParameters);
extern TelemetryPacket telemetryPacket;
extern uint8_t packetReadiness;
#endif

View File

@@ -1,4 +1,8 @@
#include "sensors.h"
#include "esp_timer.h"
#include "radio.h"
#include "../hw/gps.h"
#include "servocontroller.h"
#define BLINK_GPIO 2
@@ -13,8 +17,9 @@ static void configure_led(void)
void i2c_sensors_task(void *pvParameters)
{
// initialize the xLastWakeTime variable with the current time.
TickType_t last_wake_time = xTaskGetTickCount();
const TickType_t I2C0_TASK_SAMPLING_RATE = 5;
const int64_t interval_us = 100000; // 100 ms
int64_t start_time, end_time, elapsed;
//
// initialize i2c device configuration
@@ -26,8 +31,8 @@ void i2c_sensors_task(void *pvParameters)
mcp3550_spi_init();
configure_led();
int16_t accel[3], gyro[3], temp;
float accel_f[3], gyro_f[3], temp_f;
int16_t accel[3], gyro[3], temp, magnet[3];
float accel_f[3], gyro_f[3], temp_f, magnet_f[3];
uint16_t eCO2;
uint16_t tvoc;
@@ -38,30 +43,32 @@ void i2c_sensors_task(void *pvParameters)
uint16_t current;
uint16_t power;
bme680_data_t bmeData;
// task loop entry point
for (;;)
{
packetReadiness = 2;
start_time = esp_timer_get_time(); // µs since boot
//
// handle sensor
if (BME680_DEV_HANDLE)
{
bme680_data_t data;
esp_err_t result = bme680_get_data(BME680_DEV_HANDLE, &data);
esp_err_t result = bme680_get_data(BME680_DEV_HANDLE, &bmeData);
if (result != ESP_OK)
{
ESP_LOGE(TAG_BME, "bme680 device read failed (%s)", esp_err_to_name(result));
}
else
{
data.barometric_pressure = data.barometric_pressure / 100;
ESP_LOGI(TAG_BME, "dewpoint temperature:%.2f °C", data.dewpoint_temperature);
ESP_LOGI(TAG_BME, "air temperature: %.2f °C", data.air_temperature);
ESP_LOGI(TAG_BME, "relative humidity: %.2f %%", data.relative_humidity);
ESP_LOGI(TAG_BME, "barometric pressure: %.2f hPa", data.barometric_pressure);
ccs811_set_env_data(data.air_temperature, data.relative_humidity);
ESP_LOGI(TAG_BME, "gas resistance: %.2f kOhms", data.gas_resistance / 1000);
ESP_LOGI(TAG_BME, "iaq score: %u (%s)", data.iaq_score, bme680_air_quality_to_string(data.iaq_score));
bmeData.barometric_pressure = bmeData.barometric_pressure / 100;
ESP_LOGI(TAG_BME, "dewpoint temperature:%.2f °C", bmeData.dewpoint_temperature);
ESP_LOGI(TAG_BME, "air temperature: %.2f °C", bmeData.air_temperature);
ESP_LOGI(TAG_BME, "relative humidity: %.2f %%", bmeData.relative_humidity);
ESP_LOGI(TAG_BME, "barometric pressure: %.2f hPa", bmeData.barometric_pressure);
ccs811_set_env_data(bmeData.air_temperature, bmeData.relative_humidity);
ESP_LOGI(TAG_BME, "gas resistance: %.2f kOhms", bmeData.gas_resistance / 1000);
ESP_LOGI(TAG_BME, "iaq score: %u (%s)", bmeData.iaq_score, bme680_air_quality_to_string(bmeData.iaq_score));
}
}
else
@@ -73,12 +80,13 @@ void i2c_sensors_task(void *pvParameters)
ESP_LOGI(TAG_CCS, "eCO₂: %d ppm, TVOC: %d ppb", eCO2, tvoc);
ESP_LOGI(TAG_CCS, "Current: %d μA, Raw voltage: %d V", currentCCS, rawData);
if (mpu9250_read_sensor_data(MPU9250_DEV_HANDLE, accel, gyro, &temp) == ESP_OK)
if (mpu9250_read_sensor_data(MPU9250_DEV_HANDLE, accel, gyro, &temp, magnet) == ESP_OK)
{
mpu9250_convert_data(accel, gyro, temp, accel_f, gyro_f, &temp_f);
mpu9250_convert_data(accel, gyro, temp, magnet, accel_f, gyro_f, &temp_f, magnet_f);
ESP_LOGI(TAG_MPU, "Accel: X=%.2f g, Y=%.2f g, Z=%.2f g", accel_f[0], accel_f[1], accel_f[2]);
ESP_LOGI(TAG_MPU, "Gyro: X=%.2f°/s, Y=%.2f°/s, Z=%.2f°/s", gyro_f[0], gyro_f[1], gyro_f[2]);
ESP_LOGI(TAG_MPU, "Magnet: X=%.2fμT, Y=%.2fμT, Z=%.2fμT", magnet_f[0], magnet_f[1], magnet_f[2]);
ESP_LOGI(TAG_MPU, "Temperature: %.2f °C", temp_f);
}
else
@@ -89,7 +97,7 @@ void i2c_sensors_task(void *pvParameters)
ina260_readParams(&volts, &current, &power);
ina260_printParams(volts, current, power);
float VREFVoltage = volts * 1.25 / 1000; //Mame vobec nieco na VREFE? Na scheme su len medzi sebou prepojene
float VREFVoltage = volts * 1.25 / 1000; // Mame vobec nieco na VREFE? Na scheme su len medzi sebou prepojene
mics_adc_data_t ADCData = mcp3550_read_all(5.0); // vref = 5.0V
log_mics_adc_values(&ADCData);
@@ -101,7 +109,74 @@ void i2c_sensors_task(void *pvParameters)
gpio_set_level(BLINK_GPIO, s_led_state);
/* Toggle the LED state */
s_led_state = !s_led_state;
vTaskDelaySecUntil(&last_wake_time, I2C0_TASK_SAMPLING_RATE);
end_time = esp_timer_get_time();
elapsed = end_time - start_time;
if (elapsed < interval_us)
{
vTaskDelay(pdMS_TO_TICKS((interval_us - elapsed) / 1000));
}
if (packetReadiness == 0) {
memset(&telemetryPacket, 0, sizeof(telemetryPacket));
telemetryPacket.accelerationX = accel[0];
telemetryPacket.accelerationY = accel[1];
telemetryPacket.accelerationZ = accel[2];
telemetryPacket.gyroX = gyro[0];
telemetryPacket.gyroX = gyro[1];
telemetryPacket.gyroX = gyro[2];
telemetryPacket.magnetX = gyro[0];
telemetryPacket.magnetX = gyro[1];
telemetryPacket.magnetX = gyro[2];
telemetryPacket.accelerometer_temperature = temp;
telemetryPacket.eCO2 = eCO2;
telemetryPacket.tvoc = tvoc;
telemetryPacket.currentCCS = currentCCS;
telemetryPacket.rawCCSData = rawData;
telemetryPacket.volts = volts;
telemetryPacket.current = current;
telemetryPacket.power = power;
telemetryPacket.temperature = bmeData.raw_data.temperature;
telemetryPacket.humidity = bmeData.raw_data.humidity;
telemetryPacket.pressure = bmeData.raw_data.pressure;
telemetryPacket.gas = bmeData.raw_data.gas;
telemetryPacket.gas_range = bmeData.raw_data.gas_range;
telemetryPacket.heater_stable = bmeData.raw_data.heater_stable;
telemetryPacket.gas_valid = bmeData.raw_data.gas_valid;
telemetryPacket.NH3 = ADCData.raw_nh3;
telemetryPacket.CO = ADCData.raw_co;
telemetryPacket.NO2 = ADCData.raw_no2;
telemetryPacket.UVC = ADCData.raw_uvc;
//TODO MOVE THIS TO A BETTER PLACE FOR SYNC
telemetryPacket.time_seconds = gpsDataOut.time_seconds;
telemetryPacket.latitude_centi_degrees = gpsDataOut.latitude_centi_degrees;
telemetryPacket.longitude_centi_degrees = gpsDataOut.longitude_centi_degrees;
telemetryPacket.fix_quality = gpsDataOut.fix_quality;
telemetryPacket.num_satellites = gpsDataOut.num_satellites;
telemetryPacket.altitude_centi_meters = gpsDataOut.altitude_centi_meters;
telemetryPacket.date_yyddmm = gpsDataOut.date_yyddmm;
telemetryPacket.speed_centi_knots = gpsDataOut.speed_centi_knots;
telemetryPacket.predicted_altitude_centi_meters = predictedPosition.altitude_centi_meters;
telemetryPacket.predicted_latitude_centi_degrees = predictedPosition.latitude_centi_degrees;
telemetryPacket.predicted_longitude_centi_degrees = predictedPosition.longitude_centi_degrees;
telemetryPacket.targetServoA = servoState.targetServoA;
telemetryPacket.targetServoB = servoState.targetServoB;
telemetryPacket.currentServoA = servoState.currentServoA;
telemetryPacket.currentServoB = servoState.currentServoB;
}
packetReadiness = 1;
}
//
// free resources

View File

@@ -0,0 +1,10 @@
#include "servocontroller.h"
#include "string.h"
ServoState servoState;
//TODO add a task and implement
void servoControllerInit() {
memset(&servoState, 0, sizeof(servoState));
}

View File

@@ -0,0 +1,19 @@
#ifndef SERVO_CONTROLLER_COMPONENT
#define SERVO_CONTROLLER_COMPONENT
#include "stdint.h"
typedef struct
{
int16_t currentServoA;
int16_t targetServoA;
int16_t currentServoB;
int16_t targetServoB;
} ServoState;
extern ServoState servoState;
void servoControllerInit();
#endif