Compare commits

...

7 Commits

17 changed files with 648 additions and 331 deletions

View File

@@ -1,6 +1,6 @@
{
"C_Cpp.intelliSenseEngine": "default",
"idf.espIdfPath": "/home/bruno/esp/master/esp-idf",
"idf.espIdfPath": "/home/bruno/esp/v5.4.1/esp-idf",
"idf.pythonInstallPath": "/usr/bin/python",
"idf.openOcdConfigs": [
"board/esp32s3-builtin.cfg"

View File

@@ -2,7 +2,7 @@ dependencies:
idf:
source:
type: idf
version: 5.5.0
version: 5.4.1
k0i05/esp_bme680:
component_hash: 2df0cb14d4425565a8745d4a96bfaa8ff7e90bbec3e208a073821406dded23c8
dependencies:

View File

@@ -25,6 +25,8 @@ idf_component_register(SRCS
"components/servocontroller.h"
"components/radio.c"
"components/radio.h"
"components/sdcard.c"
"components/sdcard.h"
"main.c"
INCLUDE_DIRS ".")

View File

@@ -15,80 +15,85 @@
typedef struct __attribute__((packed))
{
char syncPhrase[10];
uint32_t packetIndex;
uint8_t packetType;
uint32_t missionTimer;
char syncPhrase[10]; //10
uint32_t packetIndex; //14
uint8_t packetType; //15
uint32_t missionTimer; //19
uint32_t CRCCheck;
} 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;
int16_t accelerationX;//21
int16_t accelerationY; //23
int16_t accelerationZ;//25
int16_t gyroX;//27
int16_t gyroY;//29
int16_t gyroZ;//31
int16_t magnetX;//33
int16_t magnetY;//35
int16_t magnetZ;//37
int16_t accelerometer_temperature;//39
// CCS data
uint16_t eCO2;
uint16_t tvoc;
uint8_t currentCCS;
uint16_t rawCCSData;
uint16_t eCO2;//41
uint16_t tvoc;//43
uint8_t currentCCS;//44
uint16_t rawCCSData;//46
// INA data
uint16_t volts;
uint16_t current;
uint16_t power;
uint16_t volts;//48
uint16_t current;//50
uint16_t power;//52
// 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;
uint32_t temperature;//56
uint16_t humidity;//58
uint32_t pressure;//62
uint16_t gas;//64
bool gas_valid;//later
bool heater_stable;//later
uint8_t gas_range;//65
uint8_t gas_index;//66
float air_temperature; /*!< air temperature in degrees celsius */
float relative_humidity; /*!< relative humidity in percent */
float barometric_pressure; /*!< barometric pressure in hecto-pascal */
float gas_resistance; /*!< gas resistance in ohms */
uint16_t iaq_score; /*!< air quality index (0..500) */
float temperature_score;
float humidity_score;
float gas_score;
float air_temperature; /*!< air temperature in degrees celsius */ //70
float relative_humidity; /*!< relative humidity in percent */ //74
float barometric_pressure; /*!< barometric pressure in hecto-pascal */ //78
float gas_resistance; /*!< gas resistance in ohms */ //82
uint16_t iaq_score; /*!< air quality index (0..500) */ //84
float temperature_score; //88
float humidity_score; //92
float gas_score; //96
// 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)
uint32_t time_seconds; // Seconds since start of day //100
int32_t latitude_centi_degrees; // Latitude * 10,000 //104
int32_t longitude_centi_degrees; // Longitude * 10,000 //108
int16_t altitude_centi_meters; // Altitude * 100 //110
uint8_t fix_quality; //111
uint8_t num_satellites; //112
uint16_t date_yyddmm; // YYDDMM (from GPRMC) //114
uint16_t speed_centi_knots; // Speed * 100 (from GPRMC) //116
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
int32_t predicted_latitude_centi_degrees; // Latitude * 10,000 //120
int32_t predicted_longitude_centi_degrees; // Longitude * 10,000 //124
int16_t predicted_altitude_centi_meters; // Altitude * 100 //126
// ADC DATA
int32_t NH3;
int32_t CO;
int32_t NO2;
int32_t UVC;
int32_t NH3; //130
int32_t CO; //134
int32_t NO2; //138
int32_t UVC; //142
int16_t currentServoA;
int16_t targetServoA;
int16_t currentServoB;
int16_t targetServoB;
int16_t currentServoA; //144
int16_t targetServoA; //146
int16_t currentServoB; //148
int16_t targetServoB; //150
uint8_t presentDevices;
uint8_t telemetryIndex; //151
} TelemetryPacket;
@@ -97,6 +102,7 @@ typedef struct __attribute__((packed))
char syncPhrase[10];
uint32_t packetIndex;
uint8_t packetType;
uint32_t CRCCheck;
} UplinkPacket;
typedef struct __attribute__((packed))

View File

@@ -6,11 +6,14 @@
#include "string.h"
#include "esp_timer.h"
#include "esp_rom_crc.h"
#include <hw/buscfg.h>
#include "sensors.h"
#include "sdcard.h"
#define TAG "LoRa"
#define ACK_TIMEOUT_MS 500 // Wait 300ms for ACK
#define MAX_RETRIES 3
#define ACK_TIMEOUT_MS 250 // Wait 300ms for ACK
#define MAX_RETRIES 1
uint32_t packetIndexTX = 0;
uint32_t packetIndexRX = 0;
@@ -44,31 +47,52 @@ void setup_lora(void)
}
}
uint8_t spreadingFactor = 6;
uint8_t spreadingFactor = 8;
uint8_t bandwidth = SX126X_LORA_BW_250_0;
uint8_t codingRate = SX126X_LORA_CR_4_8;
uint16_t preambleLength = 8;
uint16_t preambleLength = 4;
bool crcOn = true;
bool invertIrq = false;
LoRaConfig(spreadingFactor, bandwidth, codingRate, preambleLength, 0, crcOn, invertIrq);
}
static void prepare_downbound_packet(DownBoundPacket *packet, uint8_t type, uint64_t missionTimer)
static void prepare_downbound_packet(DownBoundPacket *packet, uint8_t type, uint64_t missionTimer, uint32_t crc)
{
memset(packet, 0, sizeof(DownBoundPacket));
packet->missionTimer = missionTimer;
packet->packetIndex = packetIndexTX++;
ESP_LOGI(TAG_RADIO, "Sending downbound packet with index %ld", packetIndexTX - 1);
packet->packetType = type;
packet->CRCCheck = crc;
strcpy(packet->syncPhrase, "PlechDole");
}
static void send_packet_without_retries(uint8_t *data, uint16_t size)
{
if (xSemaphoreTake(loraRadioMutex, portMAX_DELAY) == pdTRUE)
{
writeFile(sensFile, data, size);
if (!LoRaSend(data, size, SX126x_TXMODE_SYNC))
{
ESP_LOGW(TAG, "LoRaSend failed");
xSemaphoreGive(loraRadioMutex);
}
else
{
ESP_LOGI(TAG, "%d byte packet sent", size);
xSemaphoreGive(loraRadioMutex);
}
}
}
static void send_packet_with_retries(uint8_t *data, uint16_t size)
{
for (int retry = 0; retry <= MAX_RETRIES; retry++)
{
if (xSemaphoreTake(loraRadioMutex, portMAX_DELAY) == pdTRUE)
{
writeFile(sensFile, data, size);
for (int retry = 0; retry <= MAX_RETRIES; retry++)
{
if (!LoRaSend(data, size, SX126x_TXMODE_SYNC))
{
@@ -106,7 +130,8 @@ void prepare_and_send_telemetry(uint64_t missionTimer)
uint8_t bufOut[256] = {0};
DownBoundPacket downboundPacket;
prepare_downbound_packet(&downboundPacket, DownlinkPacketType_Telemetry, missionTimer);
uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)&telemetryPacket, sizeof(telemetryPacket));
prepare_downbound_packet(&downboundPacket, DownlinkPacketType_Telemetry, missionTimer, crc);
uint16_t offset = 0;
memcpy(bufOut + offset, &downboundPacket, sizeof(downboundPacket));
@@ -114,7 +139,71 @@ void prepare_and_send_telemetry(uint64_t missionTimer)
memcpy(bufOut + offset, &telemetryPacket, sizeof(telemetryPacket));
offset += sizeof(telemetryPacket);
send_packet_with_retries(bufOut, offset);
if (csvFile != NULL) {
fprintf(csvFile,
"%llu,%lu,%u,%u," // missionTimer, packetIndex, telemetryIndex, packetType
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," // MPU
"%u,%u,%d,%u," // CCS
"%u,%u,%u,%lu,%u,%lu,%u," // INA, BME basic
"%s,%s,%u,%u," // bools and gas index/range
"%.2f,%.2f,%.2f,%.2f," // Bosch env data
"%u,%.2f,%.2f,%.2f," // IAQ + scores
"%lu,%ld,%ld,%d,%u,%u,%u,%u," // GPS data
"%ld,%ld,%d," // Predicted GPS
"%ld,%ld,%ld,%ld," // ADC
"%d,%d,%d,%d," // Servo
"%u\n", // presentDevices
missionTimer,
downboundPacket.packetIndex,
telemetryPacket.telemetryIndex,
downboundPacket.packetType,
telemetryPacket.accelerationX, telemetryPacket.accelerationY, telemetryPacket.accelerationZ,
telemetryPacket.gyroX, telemetryPacket.gyroY, telemetryPacket.gyroZ,
telemetryPacket.magnetX, telemetryPacket.magnetY, telemetryPacket.magnetZ,
telemetryPacket.accelerometer_temperature,
telemetryPacket.eCO2, telemetryPacket.tvoc, telemetryPacket.currentCCS, telemetryPacket.rawCCSData,
telemetryPacket.volts, telemetryPacket.current, telemetryPacket.power,
telemetryPacket.temperature, telemetryPacket.humidity, telemetryPacket.pressure, telemetryPacket.gas,
telemetryPacket.gas_valid ? "Yes" : "No",
telemetryPacket.heater_stable ? "Yes" : "No",
telemetryPacket.gas_range, telemetryPacket.gas_index,
telemetryPacket.air_temperature, telemetryPacket.relative_humidity,
telemetryPacket.barometric_pressure, telemetryPacket.gas_resistance,
telemetryPacket.iaq_score,
telemetryPacket.temperature_score, telemetryPacket.humidity_score, telemetryPacket.gas_score,
telemetryPacket.time_seconds,
telemetryPacket.latitude_centi_degrees,
telemetryPacket.longitude_centi_degrees,
telemetryPacket.altitude_centi_meters,
telemetryPacket.fix_quality,
telemetryPacket.num_satellites,
telemetryPacket.date_yyddmm,
telemetryPacket.speed_centi_knots,
telemetryPacket.predicted_latitude_centi_degrees,
telemetryPacket.predicted_longitude_centi_degrees,
telemetryPacket.predicted_altitude_centi_meters,
telemetryPacket.NH3, telemetryPacket.CO, telemetryPacket.NO2, telemetryPacket.UVC,
telemetryPacket.currentServoA, telemetryPacket.targetServoA,
telemetryPacket.currentServoB, telemetryPacket.targetServoB,
telemetryPacket.presentDevices);
fflush(csvFile);
fsync(fileno(csvFile)); // Critical: this ensures actual write to disk
}
printf("Sending %d byte packet hehe\n", offset);
send_packet_without_retries(bufOut, offset);
packetReadiness = 0;
}
@@ -122,14 +211,16 @@ static void build_and_send_ack(uint32_t ackIndex, uint32_t crc32Checksum, uint64
{
uint8_t bufOut[256] = {0};
DownBoundPacket downboundPacket;
prepare_downbound_packet(&downboundPacket, DownlinkPacketType_ACK, missionTimer);
ACKPacket ackPacket = {
.packetIndex = ackIndex,
.crc32Checksum = crc32Checksum,
};
uint32_t crc = esp_rom_crc32_le(0, (uint8_t *)&ackPacket, sizeof(ackPacket));
DownBoundPacket downboundPacket;
prepare_downbound_packet(&downboundPacket, DownlinkPacketType_ACK, missionTimer, crc);
uint16_t offset = 0;
memcpy(bufOut + offset, &downboundPacket, sizeof(downboundPacket));
offset += sizeof(downboundPacket);
@@ -167,13 +258,23 @@ void process_uplink_packet(uint8_t *data, uint8_t len, uint64_t missionTimer)
return;
}
ESP_LOGI(TAG, "Got uplink packet of type %d, index %d", uplinkPacket.packetType, uplinkPacket.packetIndex);
ESP_LOGI(TAG, "Got uplink packet of type %d, index %ld", uplinkPacket.packetType, uplinkPacket.packetIndex);
uint8_t *payload = data + sizeof(UplinkPacket);
uint8_t payloadRXLen = len - sizeof(UplinkPacket);
uint32_t crc = esp_rom_crc32_le(0, payload, payloadRXLen);
if (crc != uplinkPacket.CRCCheck)
{
ESP_LOGE(TAG, "Received BAD CRC for packet %ld, crc is %ld, should be %ld", uplinkPacket.packetIndex, crc, uplinkPacket.CRCCheck);
return;
}
if (uplinkPacket.packetType == UplinkPacketType_ACK)
{
ESP_LOGI(TAG, "Received ACK for packet %d", uplinkPacket.packetIndex);
ESP_LOGI(TAG, "Received ACK for packet %ld", uplinkPacket.packetIndex);
ackReceived = true;
lastAckIndex = uplinkPacket.packetIndex;
return;
@@ -194,6 +295,7 @@ void process_uplink_packet(uint8_t *data, uint8_t len, uint64_t missionTimer)
{
SystemControlPacket sysCtrl;
memcpy(&sysCtrl, data + sizeof(UplinkPacket), sizeof(SystemControlPacket));
setPowerMode(sysCtrl.powerMode);
// TODO: Process sysCtrl
}
else
@@ -213,12 +315,12 @@ void process_uplink_packet(uint8_t *data, uint8_t len, uint64_t missionTimer)
}
else if (uplinkPacket.packetIndex > packetIndexRX + 1)
{
ESP_LOGW(TAG, "Skipped %d packets", uplinkPacket.packetIndex - (packetIndexRX + 1));
ESP_LOGW(TAG, "Skipped %ld packets", uplinkPacket.packetIndex - (packetIndexRX + 1));
packetIndexRX = uplinkPacket.packetIndex;
}
else
{
ESP_LOGW(TAG, "Duplicate packet: %d", (packetIndexRX + 1) - uplinkPacket.packetIndex);
ESP_LOGW(TAG, "Duplicate packet: %ld", (packetIndexRX + 1) - uplinkPacket.packetIndex);
}
}
@@ -251,14 +353,17 @@ void lora_receive_task(void *pvParameters)
void lora_comms_task(void *pvParameters)
{
ESP_LOGI(TAG, "lora_comms_task started");
// while (foundDevices[0] != 2) {
// vTaskDelay(10);
// }
// Initialize the semaphore for radio access (binary semaphore, 1 = available)
loraRadioMutex = xSemaphoreCreateMutex();
xSemaphoreGive(loraRadioMutex); // Set semaphore as available
const int64_t interval_us = 400000; // 400 ms
ESP_LOGI(TAG, "lora_comms_task started");
setup_lora();
ESP_LOGI(TAG, "lora_comms_task continuing");
xTaskCreate(
lora_receive_task,
"LoraReceiveTask",
@@ -266,6 +371,7 @@ void lora_comms_task(void *pvParameters)
NULL,
(tskIDLE_PRIORITY + 2),
NULL);
ESP_LOGI(TAG, "loraInit");
while (1)
{
int64_t start_time = esp_timer_get_time();
@@ -277,6 +383,8 @@ void lora_comms_task(void *pvParameters)
prepare_and_send_telemetry(start_time);
}
const int64_t interval_us = ((powerMode == HIGH_POWER_MODE) ? 10000 : 10000000); // 10 ms or 10 000 ms
int64_t end_time = esp_timer_get_time();
int64_t elapsed = end_time - start_time;
@@ -286,49 +394,3 @@ void lora_comms_task(void *pvParameters)
}
}
}
// void lora_comms_task(void *pvParameters)
// {
// const int64_t interval_us = 400000; // 100 ms
// int64_t start_time, end_time, elapsed;
// setup_lora();
// uint8_t bufIn[256];
// while (1)
// {
// start_time = esp_timer_get_time();
// if (packetReadiness)
// {
// ESP_LOGI(TAG, "Preparing telemetry");
// prepare_and_send_telemetry(start_time);
// }
// uint8_t rxLen = LoRaReceive(bufIn, sizeof(bufIn));
// if (rxLen > 0)
// {
// ESP_LOGI(TAG, "%d byte packet received", rxLen);
// process_uplink_packet(bufIn, rxLen, start_time);
// int8_t rssi, snr;
// GetPacketStatus(&rssi, &snr);
// ESP_LOGI(TAG, "rssi=%d[dBm], snr=%d[dB]", rssi, snr);
// }
// int lost = GetPacketLost();
// if (lost != 0)
// {
// ESP_LOGW(TAG, "%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));
// }
// }
// }

128
main/components/sdcard.c Normal file
View File

@@ -0,0 +1,128 @@
#include "sdcard.h"
void writeFile(FILE *f, const void *data, size_t size)
{
if (f != NULL)
{
fwrite(data, size, 1, f);
fflush(f);
fsync(fileno(f)); // Critical: this ensures actual write to disk
}
}
FILE *csvFile = NULL;
FILE *sensFile = NULL;
void initSD(void)
{
esp_err_t ret;
// Options for mounting the filesystem.
// If format_if_mount_failed is set to true, SD card will be partitioned and
// formatted in case when mounting fails.
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 100,
.allocation_unit_size = 16 * 1024};
sdmmc_card_t *card;
const char mount_point[] = MOUNT_POINT;
ESP_LOGI(TAGSD, "Initializing SD card");
// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
// Please check its source code and implement error recovery when developing
// production applications.
ESP_LOGI(TAGSD, "Using SPI peripheral");
// By default, SD card frequency is initialized to SDMMC_FREQ_DEFAULT (20MHz)
// For setting a specific frequency, use host.max_freq_khz (range 400kHz - 20MHz for SDSPI)
// Example: for fixed frequency of 10MHz, use host.max_freq_khz = 10000;
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
host.slot = SPI3_HOST;
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = HSPI_SD_CS;
slot_config.host_id = host.slot;
ESP_LOGI(TAGSD, "Mounting filesystem");
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
ESP_LOGE(TAGSD, "Failed to mount filesystem. "
"If you want the card to be formatted, set the CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
}
else
{
ESP_LOGE(TAGSD, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.",
esp_err_to_name(ret));
}
return;
}
ESP_LOGI(TAGSD, "Filesystem mounted");
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
int index = 0;
FILE *f = fopen(COUNTER_FILE, "r");
if (f)
{
fscanf(f, "%d", &index);
fclose(f);
}
// === 2. Increment and write back ===
f = fopen(COUNTER_FILE, "w");
if (!f)
{
ESP_LOGE(TAGSD, "Failed to open counter file");
return;
}
index++;
if (f != NULL)
{
fprintf(f, "%d", index);
fflush(f);
fsync(fileno(f)); // Critical: this ensures actual write to disk
fclose(f);
ESP_LOGI(TAGSD, "Index is now %d", index);
}
// === 3. Make folder ===
char folder_path[MAX_PATH - 20];
snprintf(folder_path, MAX_PATH, MOUNT_POINT "/%d", index);
mkdir(folder_path, 0777); // safe if exists already
// === 4. Create CSV and BIN ===
char csv_path[MAX_PATH], bin_path[MAX_PATH];
snprintf(csv_path, MAX_PATH, "%s/data.csv", folder_path);
snprintf(bin_path, MAX_PATH, "%s/data.bin", folder_path);
csvFile = fopen(csv_path, "w");
sensFile = fopen(bin_path, "wb");
if (csvFile != NULL)
{
fprintf(csvFile,
"missionTimer,packetIndex,telemetryIndex,packetType,"
"accX,accY,accZ,gyroX,gyroY,gyroZ,magX,magY,magZ,accTemp,"
"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");
fflush(csvFile);
fsync(fileno(csvFile)); // Critical: this ensures actual write to disk
}
}

26
main/components/sdcard.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef SDCARD_COMPONENT
#define SDCARD_COMPONENT
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#include "../hw/buscfg.h"
#define TAGSD "SDSubsys"
#define COUNTER_FILE "cnt.txt"
#define MOUNT_POINT "/sdcard"
void writeFile(FILE *f, const void *data, size_t size);
extern FILE *csvFile;
extern FILE *sensFile;
#define MAX_PATH 80
void initSD(void);
#endif

View File

@@ -4,12 +4,28 @@
#include "../hw/gps.h"
#include "servocontroller.h"
#include <sys/unistd.h>
#include <sys/stat.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#define MOUNT_POINT "/sdcard"
#define MAX_LINE_LENGTH 64
#define BLINK_GPIO 2
// uint8_t powerMode = LOW_POWER_MODE;
uint8_t powerMode = HIGH_POWER_MODE;
static uint8_t s_led_state = 0;
uint8_t foundDevices[128];
uint8_t prevDevices[128];
uint8_t telemetryIndex = 1;
const uint8_t expectedAdressesCount = 5;
const uint8_t expectedAdresses[] = {MCP23018_ADDRESS, BME680_ADDRESS, CCS811_ADDRESS, MPU9250_ADDRESS, INA260_ADDRESS};
uint8_t foundDevices[5];
uint8_t prevDevices[5];
static void configure_led(void)
{
@@ -17,74 +33,120 @@ static void configure_led(void)
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT);
}
// void update_devices() {
// memcpy(prevDevices, foundDevices, sizeof(prevDevices));
// memset(foundDevices, 0, sizeof(foundDevices));
// for (uint8_t i = 0; i < 128; i++)
// {
// fflush(stdout);
void update_devices()
{
memcpy(prevDevices, foundDevices, sizeof(prevDevices));
for (uint8_t i = 0; i < expectedAdressesCount; i++)
{
fflush(stdout);
// esp_err_t ret = i2c_master_probe(i2c0_bus_hdl, i, 20);
esp_err_t ret = i2c_master_probe(i2c0_bus_hdl, expectedAdresses[i], 20);
// if (ret == ESP_OK)
// {
// foundDevices[i] = 1;
if (ret == ESP_OK)
{
if (foundDevices[i] == 0)
{
foundDevices[i] = 1;
}
// printf("Found device at 0x%02X\n", i);
// }
// }
// }
}
else
{
foundDevices[i] = 0;
if (i == 1 && powerMode != HIGH_POWER_MODE)
{
continue;
}
printf("Not found device at 0x%02X\n", expectedAdresses[i]);
}
}
}
// void init_connected() {
// for (uint8_t i = 0; i < 128; i++) {
// if (foundDevices[i] != prevDevices[i]) {
// if (foundDevices[i]) {
// switch (i)
// {
// case MCP23018_ADDRESS:
// /* code */
// if (mcp23018_init() == ESP_OK) {
// foundDevices[i] = 2;
// }
// break;
void setPowerMode(uint8_t powerModeIn)
{
powerMode = powerModeIn;
if (foundDevices[0] == 2)
{
if (powerMode == HIGH_POWER_MODE)
{
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_WAKE, 0);
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_POWER, 1);
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_MICS_POWER, 1);
}
else
{
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_WAKE, 1);
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_POWER, 0);
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_MICS_POWER, 0);
}
}
}
// case INA260_ADDRESS:
// if (ina260_init() == ESP_OK) {
// foundDevices[i] = 2;
// }
// /* code */
// break;
void init_connected()
{
// case CCS811_ADDRESS:
// if (ccs811_init() == ESP_OK) {
// foundDevices[i] = 2;
// }
// /* code */
// break;
for (uint8_t i = 0; i < expectedAdressesCount; i++)
{
if (foundDevices[i] != prevDevices[i])
{
if (foundDevices[i])
{
esp_err_t ret = ESP_FAIL;
bool foundUsed = true;
switch (i)
{
case MCP23018_ADDRESS:
/* code */
ret = mcp23018_init();
setPowerMode(powerMode);
mcp3550_spi_init();
break;
// case MPU9250_ADDRESS:
// if (mpu9250_init() == ESP_OK) {
// foundDevices[i] = 2;
// }
// /* code */
// break;
case INA260_ADDRESS:
ret = ina260_init();
/* code */
break;
// case BME680_ADDRESS:
// if (bme680b_init() == ESP_OK) {
// foundDevices[i] = 2;
// }
// /* code */
// break;
case CCS811_ADDRESS:
ret = ccs811_init();
/* code */
break;
// default:
// break;
// }
// }
// }
// }
// }
case MPU9250_ADDRESS:
ret = mpu9250_init();
/* code */
break;
case BME680_ADDRESS:
ret = bme680b_init();
/* code */
break;
default:
foundUsed = false;
break;
}
if (foundUsed)
{
if (ret == ESP_OK)
{
foundDevices[i] = 2;
}
else
{
printf("Device init error at 0x%02X - %s\n", expectedAdresses[i], esp_err_to_name(ret));
}
}
}
}
}
}
void i2c_sensors_task(void *pvParameters)
{
memset(foundDevices, 0, sizeof(foundDevices));
memset(prevDevices, 0, sizeof(prevDevices));
@@ -93,17 +155,15 @@ void i2c_sensors_task(void *pvParameters)
ccs811_init();
ina260_init();
// update_devices();
// init_connected();
// initialize the xLastWakeTime variable with the current time.
const int64_t interval_us = 100000; // 100 ms
const int64_t interval_us = 50000; // 50 ms
int64_t start_time, end_time, elapsed;
//
// initialize i2c device configuration
mcp3550_spi_init();
configure_led();
int16_t accel[3], gyro[3], temp, magnet[3];
@@ -119,13 +179,22 @@ void i2c_sensors_task(void *pvParameters)
uint16_t power;
bme680_data_t bmeData;
mics_adc_data_t ADCData;
// task loop entry point
for (;;)
{
start_time = esp_timer_get_time(); // µs since boot
uint8_t presentDevices = 0xFF;
// update_devices();
// init_connected();
//
// handle sensor
presentDevices |= BME680_PRESENT_BIT;
if (BME680_DEV_HANDLE)
{
esp_err_t result = bme680_get_data(BME680_DEV_HANDLE, &bmeData);
@@ -150,10 +219,12 @@ void i2c_sensors_task(void *pvParameters)
bme680b_init();
}
presentDevices |= CCS811_PRESENT_BIT;
ccs811_get_data(&eCO2, &tvoc, &currentCCS, &rawData);
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);
presentDevices |= MPU9250_PRESENT_BIT;
if (mpu9250_read_sensor_data(MPU9250_DEV_HANDLE, accel, gyro, &temp, magnet) == ESP_OK)
{
mpu9250_convert_data(accel, gyro, temp, magnet, accel_f, gyro_f, &temp_f, magnet_f);
@@ -168,33 +239,18 @@ void i2c_sensors_task(void *pvParameters)
ESP_LOGE(TAG_MPU, "Failed to read sensor data");
}
presentDevices |= INA260_PRESENT_BIT;
ina260_readParams(&volts, &current, &power);
ina260_printParams(volts, current, power);
presentDevices |= MCP23018_PRESENT_BIT;
float VREFVoltage = 2.5;
// mics_adc_data_t ADCData;
// memset(&ADCData, 0, sizeof(ADCData));
mics_adc_data_t ADCData = mcp3550_read_all(VREFVoltage);
ADCData = mcp3550_read_all(VREFVoltage);
log_mics_adc_values(&ADCData);
//int32_t nh3val = mcp3550_read(MCP_CS_ADC_NH3);
//ESP_LOGI(TAG_BME, "MICS NH3: %ld -> %fV", nh3val, mcp3550_to_voltage(nh3val, VREFVoltage));
//gpio_set_level(BLINK_GPIO, s_led_state);
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CS_ADC_UVC, s_led_state);
/* Toggle the LED state */
s_led_state = !s_led_state;
end_time = esp_timer_get_time();
elapsed = end_time - start_time;
if (elapsed < interval_us)
if (packetReadiness == 0)
{
vTaskDelay(pdMS_TO_TICKS((interval_us - elapsed) / 1000));
}
if (packetReadiness == 0) {
memset(&telemetryPacket, 0, sizeof(telemetryPacket));
telemetryPacket.accelerationX = accel[0];
telemetryPacket.accelerationY = accel[1];
@@ -219,7 +275,6 @@ void i2c_sensors_task(void *pvParameters)
telemetryPacket.current = current;
telemetryPacket.power = power;
telemetryPacket.temperature = bmeData.raw_data.temperature;
telemetryPacket.humidity = bmeData.raw_data.humidity;
telemetryPacket.pressure = bmeData.raw_data.pressure;
@@ -261,9 +316,20 @@ void i2c_sensors_task(void *pvParameters)
telemetryPacket.currentServoA = servoState.currentServoA;
telemetryPacket.currentServoB = servoState.currentServoB;
telemetryPacket.presentDevices = presentDevices;
telemetryPacket.telemetryIndex = telemetryIndex++;
}
packetReadiness = 1;
s_led_state = !s_led_state;
end_time = esp_timer_get_time();
elapsed = end_time - start_time;
if (elapsed < interval_us)
{
vTaskDelay(pdMS_TO_TICKS((interval_us - elapsed) / 1000));
}
}
//
// free resources

View File

@@ -18,9 +18,17 @@
#include "../hw/mpu9250.h"
#include "esp_log.h"
#define LOW_POWER_MODE 0
#define HIGH_POWER_MODE 1
extern uint8_t powerMode;
extern uint8_t foundDevices[128];
extern uint8_t prevDevices[128];
extern uint8_t foundDevices[5];
extern uint8_t prevDevices[5];
void init_connected();
void update_devices();
void setPowerMode(uint8_t powerModeIn);
void i2c_sensors_task(void *pvParameters);

View File

@@ -8,11 +8,17 @@
#define ESP_RXD0 GPIO_NUM_44
#define ESP_TXD0 GPIO_NUM_43
#define MCP23018_ADDRESS 0x20
#define INA260_ADDRESS 0x40
#define BME680_ADDRESS 0x76
#define CCS811_ADDRESS 0x5A
#define MPU9250_ADDRESS 0x68
#define BME680_ADDRESS 0x76
#define INA260_ADDRESS 0x40
#define MCP23018_ADDRESS 0x20
#define BME680_PRESENT_BIT (1 << 0)
#define CCS811_PRESENT_BIT (1 << 1)
#define MPU9250_PRESENT_BIT (1 << 2)
#define INA260_PRESENT_BIT (1 << 3)
#define MCP23018_PRESENT_BIT (1 << 4)
#define ESP_CONNECTOR_P1 MCP3550_MISO_GPIO
#define ESP_CONNECTOR_P2 MCP3550_MOSI_GPIO

View File

@@ -33,10 +33,6 @@ esp_err_t ccs811_init()
{
esp_err_t ret =i2c_master_bus_add_device(i2c0_bus_hdl, &CCS811_DEV_CFG, &CCS811_DEV_HANDLE);
if (ret != ESP_OK) {return ret;}
ret = mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_WAKE, 0);
if (ret != ESP_OK) {return ret;}
ret = mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_CCS811_POWER, 1);
if (ret != ESP_OK) {return ret;}
vTaskDelay(10 / portTICK_PERIOD_MS);
uint8_t reset_seq[4] = {0x11, 0xE5, 0x72, 0x8A};
ret = i2c_write_register(CCS811_DEV_HANDLE, CCS811_REG_SW_RESET, reset_seq, sizeof(reset_seq)); // Reset

View File

@@ -26,11 +26,11 @@ void gps_init()
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
.rx_flow_ctrl_thresh = 122,
};
ESP_ERROR_CHECK(uart_param_config(GPS_UART_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(GPS_UART_NUM, GPS_TXD, GPS_RXD, GPS_RTS, GPS_CTS));
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_param_config(GPS_UART_NUM, &uart_config));
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_pin(GPS_UART_NUM, GPS_TXD, GPS_RXD, GPS_RTS, GPS_CTS));
const int uart_buffer_size = (1024 * 2);
ESP_ERROR_CHECK(uart_driver_install(GPS_UART_NUM, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_driver_install(GPS_UART_NUM, uart_buffer_size, uart_buffer_size, 10, &uart_queue, 0));
}
@@ -49,9 +49,9 @@ void gps_task(void *arg)
line[line_pos] = '\0';
if (line[0] == '$') {
ESP_LOGV(TAG, "Received NMEA: %s", line);
ESP_LOGI(TAG, "Received NMEA: %s", line);
if (strstr(line, "$GPGGA") == line) {
if (strstr(line, "$GNGGA") == line) {
parse_gpgga(line);
parse_gpgga_to_struct(line, &gpsDataOut);
} else if (strstr(line, "$GPRMC") == line) {
@@ -72,8 +72,7 @@ void gps_task(void *arg)
}
}
void parse_gpgga(const char *nmea)
{
void parse_gpgga(const char *nmea) {
char *fields[15];
char temp[GPS_LINE_MAX_LEN];
strncpy(temp, nmea, GPS_LINE_MAX_LEN);
@@ -108,12 +107,11 @@ void parse_gpgga(const char *nmea)
// Altitude
const char *altitude = fields[9];
ESP_LOGI(TAG, "[GPGGA] Time: %s, Lat: %s %s, Lon: %s %s, Fix: %s, Sats: %s, Alt: %sm",
printf("[GPGGA] Time: %s, Lat: %s %s, Lon: %s %s, Fix: %s, Sats: %s, Alt: %sm\n",
utc_time, lat, lat_dir, lon, lon_dir, fix_quality, num_satellites, altitude);
}
void parse_gprmc(const char *nmea)
{
void parse_gprmc(const char *nmea) {
char *fields[13];
char temp[GPS_LINE_MAX_LEN];
strncpy(temp, nmea, GPS_LINE_MAX_LEN);
@@ -137,7 +135,7 @@ void parse_gprmc(const char *nmea)
const char *speed_knots = fields[7];
const char *date = fields[9];
ESP_LOGI(TAG, "[GPRMC] Date: %s, Time: %s, Lat: %s %s, Lon: %s %s, Speed: %s knots, Status: %s",
printf("[GPRMC] Date: %s, Time: %s, Lat: %s %s, Lon: %s %s, Speed: %s knots, Status: %s\n",
date, utc_time, lat, lat_dir, lon, lon_dir, speed_knots, status);
}
@@ -154,17 +152,22 @@ static uint32_t time_to_seconds_struct(const char *time_str) {
// Function to convert DMS (degrees minutes.decimalminutes) to centi-degrees
static int32_t dms_to_centi_degrees_struct(const char *dms_str, const char *direction) {
if (dms_str == NULL || direction == NULL || strlen(dms_str) < 7) return 0;
char degrees_str[4] = {0};
char minutes_decimal_str[10] = {0};
strncpy(degrees_str, dms_str, 2);
strncpy(minutes_decimal_str, dms_str + 2, strlen(dms_str) - 2);
double degrees = atof(degrees_str);
double minutes = atof(minutes_decimal_str);
double decimal_degrees = degrees + (minutes / 60.0);
if (direction[0] == 'S' || direction[0] == 'W') {
decimal_degrees *= -1.0;
char data_str[20] = {0};
char *dataStr = data_str;
for (int i = 0; i < 20; i++) {
if (dms_str[i] == 0) {
break;
}
return (int32_t)(decimal_degrees * 10000);
if (dms_str[i] == '.') {
continue;
}
*(dataStr++) = dms_str[i];
}
int32_t degrees = atoi(data_str);
if (direction[0] == 'S' || direction[0] == 'W') {
degrees *= -1;
}
return degrees;
}
// Function to convert altitude string to centi-meters
@@ -190,8 +193,7 @@ static uint16_t date_to_yyddmm_struct(const char *date_str) {
}
// Function to parse GPGGA NMEA string and return the struct
void parse_gpgga_to_struct(const char *nmea, gps_binary_struct_t *data)
{
void parse_gpgga_to_struct(const char *nmea, gps_binary_struct_t *data) {
char *fields[15];
char temp[GPS_LINE_MAX_LEN];
strncpy(temp, nmea, GPS_LINE_MAX_LEN);
@@ -212,13 +214,12 @@ void parse_gpgga_to_struct(const char *nmea, gps_binary_struct_t *data)
data->num_satellites = atoi(fields[7]);
data->altitude_centi_meters = altitude_to_centi_meters_struct(fields[9]);
} else {
ESP_LOGW(TAG, "GPGGA: Not enough fields to parse struct");
printf("GPGGA: Not enough fields to parse struct");
}
}
// Function to parse GPRMC NMEA string and return the struct
void parse_gprmc_to_struct(const char *nmea, gps_binary_struct_t *data)
{
void parse_gprmc_to_struct(const char *nmea, gps_binary_struct_t *data) {
char *fields[13];
char temp[GPS_LINE_MAX_LEN];
strncpy(temp, nmea, GPS_LINE_MAX_LEN);
@@ -239,6 +240,6 @@ void parse_gprmc_to_struct(const char *nmea, gps_binary_struct_t *data)
data->speed_centi_knots = speed_to_centi_knots_struct(fields[7]);
// Fix quality and num_satellites are typically in GPGGA, so they might be 0 here.
} else {
ESP_LOGW(TAG, "GPRMC: Not enough fields to parse struct");
printf("GPRMC: Not enough fields to parse struct");
}
}

View File

@@ -8,21 +8,26 @@ i2c_device_config_t INA260_DEV_CFG = {
i2c_master_dev_handle_t INA260_DEV_HANDLE;
void ina260_reset() {
void ina260_reset()
{
i2c_write_register_16(INA260_DEV_HANDLE, 0x00, 0x0FFF); // set ina max averaging and max time
}
esp_err_t ina260_init()
{
esp_err_t ret = i2c_master_bus_add_device(i2c0_bus_hdl, &INA260_DEV_CFG, &INA260_DEV_HANDLE);
if (ret != ESP_OK) {return ret;}
if (ret != ESP_OK)
{
ESP_LOGE(TAG_INA, "%s", esp_err_to_name(ret));
return ret;
}
ESP_LOGI(TAG_INA, "hehedstesfsewscdsfsrgerpodsvhdrsivhriuvjdreiv");
return i2c_write_register_16(INA260_DEV_HANDLE, INA260_CONFIG_REGISTER,
CONFIG_AVG_1024 | CONFIG_VBUSCT_8_244MS | CONFIG_ISHCT_8_244MS | CONFIG_MODE_CURRENT_VOLTAGE_CONTINOUS); // set ina max averaging and max time
}
esp_err_t i2c_master_read_register_transmit_receive(i2c_master_dev_handle_t device_handle, uint8_t reg_addr, uint8_t *data, size_t data_len) {
esp_err_t i2c_master_read_register_transmit_receive(i2c_master_dev_handle_t device_handle, uint8_t reg_addr, uint8_t *data, size_t data_len)
{
esp_err_t ret;
// The register address is what we want to send first (the "transmit" part)
@@ -39,7 +44,8 @@ esp_err_t i2c_master_read_register_transmit_receive(i2c_master_dev_handle_t devi
read_buffer, read_size,
I2C_TIMEOUT_MS_VALUE);
if (ret == ESP_OK) {
if (ret == ESP_OK)
{
// Copy the data from the temporary read buffer to the output buffer
memcpy(data, read_buffer, read_size);
}
@@ -48,6 +54,8 @@ esp_err_t i2c_master_read_register_transmit_receive(i2c_master_dev_handle_t devi
}
void ina260_readParams(uint16_t *volt, uint16_t *cur, uint16_t *pow)
{
if (INA260_DEV_HANDLE)
{
*volt = 0;
*cur = 0;
@@ -56,7 +64,7 @@ void ina260_readParams(uint16_t *volt, uint16_t *cur, uint16_t *pow)
{
uint8_t reg_value[2] = {0}; // Buffer for storing register data
ESP_ERROR_CHECK(i2c_master_read_register_transmit_receive(INA260_DEV_HANDLE, reg_addr, reg_value, sizeof(reg_value)));
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_read_register_transmit_receive(INA260_DEV_HANDLE, reg_addr, reg_value, sizeof(reg_value)));
// Perform the register read
switch (reg_addr)
{
@@ -75,6 +83,7 @@ void ina260_readParams(uint16_t *volt, uint16_t *cur, uint16_t *pow)
}
}
}
}
void ina260_printParams(uint16_t volt, uint16_t cur, uint16_t pow)
{

View File

@@ -16,9 +16,7 @@ uint8_t gpiob_state = 0x00; // All LOW initially
esp_err_t mcp23018_set_pin(i2c_master_dev_handle_t dev_handle, uint8_t pin, uint8_t value)
{
// while(foundDevices[MCP23018_ADDRESS] != 2) {
// vTaskDelay(1);
// }
ESP_LOGI(TAG_MCP, "Setting %d to %d", pin, value);
esp_err_t ret = ESP_FAIL;
if (pin < 8)
{

View File

@@ -19,18 +19,17 @@ spi_device_handle_t mcp3550_handle;
void mcp3550_spi_init()
{
spi_device_interface_config_t devcfg = {
.clock_speed_hz = 100000,
.mode = 0,
.spics_io_num = -1, // We handle CS manually
.queue_size = 1,
};
// spi_device_interface_config_t devcfg = {
// .clock_speed_hz = 100000,
// .mode = 0,
// .spics_io_num = -1, // We handle CS manually
// .queue_size = 1,
// };
ESP_ERROR_CHECK(spi_bus_add_device(SPI2_HOST, &devcfg, &mcp3550_handle));
// ESP_ERROR_CHECK_WITHOUT_ABORT(spi_bus_add_device(SPI2_HOST, &devcfg, &mcp3550_handle));
// Set MISO pin for input (needed for polling)
gpio_set_direction(MCP3550_MISO_GPIO, GPIO_MODE_INPUT);
mcp23018_set_pin(MCP23018_DEV_HANDLE, MCP_MICS_POWER, 1); // CS HIGH
}
@@ -133,9 +132,13 @@ int32_t mcp3550_read(uint8_t cs_pin)
int64_t start = esp_timer_get_time();
uint32_t timeout_us = MCP3550_TIMEOUT_MS * 1000;
ESP_LOGI(TAG_MCP, "Starting read from ADC CS %d", cs_pin);
// CS LOW
mcp23018_set_pin(MCP23018_DEV_HANDLE, cs_pin, 0);
vTaskDelay(pdMS_TO_TICKS(10));
// Wait for DR (MISO LOW)
while (gpio_get_level(MCP3550_MISO_GPIO)) {
if ((esp_timer_get_time() - start) > timeout_us) {

View File

@@ -25,6 +25,7 @@
#include "hw/mcp23018.h"
#include "hw/mpu9250.h"
#include "hw/buscfg.h"
#include "components/sdcard.h"
#include "hw/gps.h"
@@ -36,18 +37,20 @@ void app_main(void)
ESP_LOGI("BOOT", "BRN Systems incorporated CanSat flight firmware build at %s %s", __DATE__, __TIME__);
/* instantiate i2c master bus 0 */
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c0_bus_cfg, &i2c0_bus_hdl));
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_new_master_bus(&i2c0_bus_cfg, &i2c0_bus_hdl));
spi_bus_config_t MCPBusCfg = {
.mosi_io_num = -1,
.miso_io_num = MCP3550_MISO_GPIO,
.sclk_io_num = MCP3550_SCK_GPIO,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4,
};
ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &MCPBusCfg, SPI_DMA_DISABLED));
// spi_bus_config_t MCPBusCfg = {
// .mosi_io_num = -1,
// .miso_io_num = MCP3550_MISO_GPIO,
// .sclk_io_num = MCP3550_SCK_GPIO,
// .quadwp_io_num = -1,
// .quadhd_io_num = -1,
// .max_transfer_sz = 4,
// };
// ESP_ERROR_CHECK_WITHOUT_ABORT(spi_bus_initialize(SPI2_HOST, &MCPBusCfg, SPI_DMA_DISABLED));
gpio_pullup_en(HSPI_MISO_GPIO);
gpio_pullup_en(HSPI_SD_CS);
spi_bus_config_t HighSpeedBusCfg = {
// CONNECTED to LoRa and SD card
.mosi_io_num = HSPI_MOSI_GPIO,
@@ -57,12 +60,15 @@ void app_main(void)
.quadhd_io_num = -1,
.max_transfer_sz = 64, // probably change
};
ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &HighSpeedBusCfg, SPI_DMA_CH_AUTO));
ESP_ERROR_CHECK_WITHOUT_ABORT(spi_bus_initialize(SPI3_HOST, &HighSpeedBusCfg, SPI_DMA_CH_AUTO));
/* scan i2c devices on i2c master bus 0 and print results */
ESP_ERROR_CHECK(i2c_master_bus_detect_devices(i2c0_bus_hdl));
ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_bus_detect_devices(i2c0_bus_hdl));
mcp23018_init();
initSD();
void servoControllerInit();
ESP_LOGI(TAG, "BEGIN ESP TASKS");

View File

@@ -426,39 +426,39 @@ static inline esp_err_t bme680_get_cal_factors(bme680_handle_t handle) {
ESP_ARG_CHECK( handle );
/* bme680 attempt to request T1-T3 calibration values from device */
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0xe9, &handle->dev_cal_factors->par_T1) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x8a, (uint16_t *)&handle->dev_cal_factors->par_T2) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x8c, (uint8_t *)&handle->dev_cal_factors->par_T3) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0xe9, &handle->dev_cal_factors->par_T1) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x8a, (uint16_t *)&handle->dev_cal_factors->par_T2) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x8c, (uint8_t *)&handle->dev_cal_factors->par_T3) );
/* bme680 attempt to request H1-H7 calibration values from device */
ESP_ERROR_CHECK( bme680_i2c_read_from(handle, 0xe2, rx, BIT16_UINT8_BUFFER_SIZE) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_from(handle, 0xe2, rx, BIT16_UINT8_BUFFER_SIZE) );
handle->dev_cal_factors->par_H1 = (uint16_t)(((uint16_t)rx[1] << 4) | (rx[0] & 0x0F));
ESP_ERROR_CHECK( bme680_i2c_read_from(handle, 0xe1, rx, BIT16_UINT8_BUFFER_SIZE) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_from(handle, 0xe1, rx, BIT16_UINT8_BUFFER_SIZE) );
handle->dev_cal_factors->par_H2 = (uint16_t)(((uint16_t)rx[0] << 4) | (rx[1] >> 4));
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xe4, (uint8_t *)&handle->dev_cal_factors->par_H3) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xe5, (uint8_t *)&handle->dev_cal_factors->par_H4) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xe6, (uint8_t *)&handle->dev_cal_factors->par_H5) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xe7, &handle->dev_cal_factors->par_H6) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xe8, (uint8_t *)&handle->dev_cal_factors->par_H7) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xe4, (uint8_t *)&handle->dev_cal_factors->par_H3) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xe5, (uint8_t *)&handle->dev_cal_factors->par_H4) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xe6, (uint8_t *)&handle->dev_cal_factors->par_H5) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xe7, &handle->dev_cal_factors->par_H6) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xe8, (uint8_t *)&handle->dev_cal_factors->par_H7) );
/* bme680 attempt to request P1-P10 calibration values from device */
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x8e, &handle->dev_cal_factors->par_P1) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x90, (uint16_t *)&handle->dev_cal_factors->par_P2) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x92, (uint8_t *)&handle->dev_cal_factors->par_P3) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x94, (uint16_t *)&handle->dev_cal_factors->par_P4) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x96, (uint16_t *)&handle->dev_cal_factors->par_P5) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x99, (uint8_t *)&handle->dev_cal_factors->par_P6) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x98, (uint8_t *)&handle->dev_cal_factors->par_P7) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x9c, (uint16_t *)&handle->dev_cal_factors->par_P8) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0x9e, (uint16_t *)&handle->dev_cal_factors->par_P9) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xa0, &handle->dev_cal_factors->par_P10) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x8e, &handle->dev_cal_factors->par_P1) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x90, (uint16_t *)&handle->dev_cal_factors->par_P2) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x92, (uint8_t *)&handle->dev_cal_factors->par_P3) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x94, (uint16_t *)&handle->dev_cal_factors->par_P4) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x96, (uint16_t *)&handle->dev_cal_factors->par_P5) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x99, (uint8_t *)&handle->dev_cal_factors->par_P6) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x98, (uint8_t *)&handle->dev_cal_factors->par_P7) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x9c, (uint16_t *)&handle->dev_cal_factors->par_P8) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0x9e, (uint16_t *)&handle->dev_cal_factors->par_P9) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xa0, &handle->dev_cal_factors->par_P10) );
/* bme680 attempt to request G1-G3 calibration values from device */
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xed, (uint8_t *)&handle->dev_cal_factors->par_G1) );
ESP_ERROR_CHECK( bme680_i2c_read_word_from(handle, 0xeb, (uint16_t *)&handle->dev_cal_factors->par_G2) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0xee, (uint8_t *)&handle->dev_cal_factors->par_G3) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xed, (uint8_t *)&handle->dev_cal_factors->par_G1) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_word_from(handle, 0xeb, (uint16_t *)&handle->dev_cal_factors->par_G2) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0xee, (uint8_t *)&handle->dev_cal_factors->par_G3) );
/* bme680 attempt to request gas range and switching error values from device */
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x02, &handle->dev_cal_factors->res_heat_range) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x02, &handle->dev_cal_factors->res_heat_range) );
handle->dev_cal_factors->res_heat_range = (handle->dev_cal_factors->res_heat_range & 0x30) / 16;
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x00, (uint8_t *)&handle->dev_cal_factors->res_heat_val) );
ESP_ERROR_CHECK( bme680_i2c_read_byte_from(handle, 0x04, (uint8_t *)&handle->dev_cal_factors->range_switching_error) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x00, (uint8_t *)&handle->dev_cal_factors->res_heat_val) );
ESP_ERROR_CHECK_WITHOUT_ABORT( bme680_i2c_read_byte_from(handle, 0x04, (uint8_t *)&handle->dev_cal_factors->range_switching_error) );
handle->dev_cal_factors->range_switching_error = (handle->dev_cal_factors->range_switching_error & 0xf0) / 16;
/*