My code is relatively long, and I thought posting a targeted section would improve readability. Apologies if I was incorrect in that, but there's no need to be rude. Here is the entire code. It's not the tidiest I fear, I usually clean up my code properly once I've mostly finished with it.
#include <Arduino.h>
#include "nvs_flash.h"
#include "esp_mac.h"
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_netif.h"
#include "esp_now.h"
#include "esp_camera.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <RTClib.h>
#include <Wire.h>
RTC_DS1307 rtc;
Adafruit_MPU6050 imu;
// CAMERA PINS
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 10
#define SIOD_GPIO_NUM 40
#define SIOC_GPIO_NUM 39
#define Y9_GPIO_NUM 48
#define Y8_GPIO_NUM 11
#define Y7_GPIO_NUM 12
#define Y6_GPIO_NUM 14
#define Y5_GPIO_NUM 16
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 17
#define Y2_GPIO_NUM 15
#define VSYNC_GPIO_NUM 38
#define HREF_GPIO_NUM 47
#define PCLK_GPIO_NUM 13
#define LED_GPIO_NUM 21
#define CONFIG_LESS_INTERFERENCE_CHANNEL 11
#define CONFIG_SEND_FREQUENCY 40 // in hz
#define IMU_SIZE 61
#define TIME_SIZE 24
#define FILENAME_SIZE 26
// mac addresses
static const uint8_t MAC_ADDR_SEND[] = {0x1a, 0x00, 0x00, 0x00, 0x00, 0x00};
static const uint8_t MAC_ADDR_RECV[] = {0x1a, 0x01, 0x00, 0x00, 0x00, 0x00};
static const uint8_t MAC_ADDR_BROAD[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
uint8_t pkt_count = 0;
// define tasks
void task_write_all(void *pvParameters);
void task_save_imu(void *pvParameters);
void task_send_csi(void *pvParameters);
static portMUX_TYPE lock = portMUX_INITIALIZER_UNLOCKED;
// global variables
int imu_idx = 0;
int imu_switch = 0;
int imu_idx_last = 0;
char imu_data0[50][IMU_SIZE+TIME_SIZE];
char imu_data1[50][IMU_SIZE+TIME_SIZE];
unsigned long new_time = 0;
unsigned long old_time = 0;
bool wifi_good;
bool rtc_good;
bool sd_good;
bool cam_good;
bool imu_good;
bool report_esp_error(esp_err_t err)
{
if(err == ESP_OK)
{
return false;
}
else
{
Serial.printf("Error: %s\n", esp_err_to_name(err));
return true;
}
}
bool imu_setup()
{
if (!imu.begin(0x69))
{
Serial.println("Failed to find IMU");
return false;
}
Serial.println("IMU Found!");
imu.setAccelerometerRange(MPU6050_RANGE_2_G);
Serial.println("Accelerometer range set to: +- 2G");
imu.setGyroRange(MPU6050_RANGE_250_DEG);
Serial.println("Gyro range set to: +- 250 deg/s");
imu.setFilterBandwidth(MPU6050_BAND_44_HZ);
Serial.println("Filter bandwidth set to: 44 Hz");
return true;
}
bool rtc_setup()
{
if (!rtc.begin())
{
Serial.println("Failed to find RTC");
return false;
}
Serial.println("RTC Found!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
old_time = millis();
return true;
}
bool cam_setup()
{
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.frame_size = FRAMESIZE_UXGA;
config.pixel_format = PIXFORMAT_JPEG; // for streaming
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 12;
config.fb_count = 1;
// if PSRAM IC present, init with UXGA resolution and higher JPEG quality
// for larger pre-allocated frame buffer.
if(config.pixel_format == PIXFORMAT_JPEG)
{
if(psramFound())
{
config.jpeg_quality = 10;
config.fb_count = 2;
config.grab_mode = CAMERA_GRAB_LATEST;
} else
{
// Limit the frame size when PSRAM is not available
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
}
else
{
// Best option for face detection/recognition
config.frame_size = FRAMESIZE_240X240;
#if CONFIG_IDF_TARGET_ESP32S3
config.fb_count = 2;
#endif
}
// camera init
if (report_esp_error(esp_camera_init(&config))) return false;
/*esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK)
{
Serial.printf("Camera init failed with error 0x%x", err);
return false;
}*/
return true;
}
bool sd_setup()
{
// Initialize SD card
if(!SD.begin(21))
{
Serial.println("Card Mount Failed");
return false;
}
uint8_t cardType = SD.cardType();
// Determine if the type of SD card is available
if(cardType == CARD_NONE)
{
Serial.println("No SD card attached");
return false;
}
Serial.print("SD Card Type: ");
if(cardType == CARD_MMC)
{
Serial.println("MMC");
} else if(cardType == CARD_SD){
Serial.println("SDSC");
} else if(cardType == CARD_SDHC){
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
return true;
}
bool wifi_setup()
{
// NVS SETUP //
// try to initialise the default NVS partition
esp_err_t errcode = nvs_flash_init();
// if necessary, clear the flash and re-initialise
if (errcode == ESP_ERR_NVS_NO_FREE_PAGES || errcode == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
report_esp_error(nvs_flash_erase());
errcode = nvs_flash_init();
}
// if there is still something wrong, report and abort
if (report_esp_error(errcode)) return false;
// WIFI SETUP //
// setup the default event loop, for handling WiFi events
if (report_esp_error(esp_event_loop_create_default())) return false;
// initialise the TCP/IP stack
if (report_esp_error(esp_netif_init())) return false;
// initialise the WiFi configuration to default config values
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
// initialise WiFi resources, and start the WiFi task
if (report_esp_error(esp_wifi_init(&config))) return false;
// set the WiFi to run in station mode
if (report_esp_error(esp_wifi_set_mode(WIFI_MODE_STA))) return false;
// set the WiFi configuration storage as RAM
if (report_esp_error(esp_wifi_set_storage(WIFI_STORAGE_RAM))) return false;
// set the bandwidth to HT40
if (report_esp_error(esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT40))) return false;
// start WiFi, following current settings
if (report_esp_error(esp_wifi_start())) return false;
// set the ESP-NOW rate
if (report_esp_error(esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_MCS0_SGI))) return false;
// set power saving type to none
if (report_esp_error(esp_wifi_set_ps(WIFI_PS_NONE))) return false;
// set the primary and secondary channels
if (report_esp_error(esp_wifi_set_channel(CONFIG_LESS_INTERFERENCE_CHANNEL, WIFI_SECOND_CHAN_BELOW))) return false;
// set the MAC address
if (report_esp_error(esp_wifi_set_mac(WIFI_IF_STA, MAC_ADDR_SEND))) return false;
// initialise ESP-NOW
if (report_esp_error(esp_now_init())) return false;
// set the ESP-NOW primary master key
if (report_esp_error(esp_now_set_pmk((uint8_t *)"pmk1234567890123"))) return false;
// define the receiver as an ESP-NOW peer
esp_now_peer_info_t recv =
{
.channel = CONFIG_LESS_INTERFERENCE_CHANNEL,
.ifidx = WIFI_IF_STA,
.encrypt = false
};
memcpy(recv.peer_addr, MAC_ADDR_BROAD, sizeof(uint8_t[6]));
// add the peer to the ESP-NOW network
if (report_esp_error(esp_now_add_peer(&recv))) return false;
// finally, report on the sending parameters
Serial.printf("Channel: %d\nFrequency: %d Hz\nMAC address: " MACSTR "\n", CONFIG_LESS_INTERFERENCE_CHANNEL, CONFIG_SEND_FREQUENCY, MAC2STR(MAC_ADDR_SEND));
return true;
}
void generate_timestamp(char* timestamp, DateTime* now, bool img, unsigned long milli = 0)
{
if(img)
{
if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d", now->year(), now->month(), now->day(), now->hour(), now->minute(), now->second()); //00000
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), now->hour(), now->minute(), 0, now->second()); //00001
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), now->hour(), 0, now->minute(), 0, now->second()); //00011
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), now->hour(), 0, now->minute(), now->second()); //00010
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), 0, now->hour(), 0, now->minute(), now->second()); //00110
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), 0, now->hour(), 0, now->minute(), 0, now->second()); //00111
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), 0, now->hour(), now->minute(), 0, now->second()); //00101
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d", now->year(), now->month(), now->day(), 0, now->hour(), now->minute(), now->second()); //00100
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), 0, now->hour(), now->minute(), now->second()); //01100
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), 0, now->hour(), now->minute(), 0, now->second()); //01101
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), 0, now->second()); //01111
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), now->second()); //01110
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), now->hour(), 0, now->minute(), now->second()); //01010
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), now->hour(), 0, now->minute(), 0, now->second()); //01011
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), now->hour(), now->minute(), 0, now->second()); //01001
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d", now->year(), now->month(), 0, now->day(), now->hour(), now->minute(), now->second()); //01000
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), now->hour(), now->minute(), now->second()); //11000
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), now->hour(), now->minute(), 0, now->second()); //11001
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), now->hour(), 0, now->minute(), 0, now->second()); //11011
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), now->hour(), 0, now->minute(), now->second()); //11010
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), now->second()); //11110
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), 0, now->second()); //11111
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), now->minute(), 0, now->second()); //11101
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), now->minute(), now->second()); //11100
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), 0, now->hour(), now->minute(), now->second()); //10100
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), 0, now->hour(), now->minute(), 0, now->second()); //10101
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), 0, now->hour(), 0, now->minute(), 0, now->second()); //10111
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), 0, now->hour(), 0, now->minute(), now->second()); //10110
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), now->hour(), 0, now->minute(), now->second()); //10010
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), now->hour(), 0, now->minute(), 0, now->second()); //10011
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), now->hour(), now->minute(), 0, now->second()); //10001
}
else
{
sprintf(timestamp, "%d%d%d%d%d%d%d", now->year(), 0, now->month(), now->day(), now->hour(), now->minute(), now->second()); //10000
}
}
else
{
if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d:%d:%d:%d:%lu", now->year(), now->month(), now->day(), now->hour(), now->minute(), now->second(), milli); //00000
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d:%d:%d:%d%d:%lu", now->year(), now->month(), now->day(), now->hour(), now->minute(), 0, now->second(), milli); //00001
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d:%d:%d%d:%d%d:%lu", now->year(), now->month(), now->day(), now->hour(), 0, now->minute(), 0, now->second(), milli); //00011
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d:%d:%d%d:%d:%lu", now->year(), now->month(), now->day(), now->hour(), 0, now->minute(), now->second(), milli); //00010
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d:%d%d:%d%d:%d:%lu", now->year(), now->month(), now->day(), 0, now->hour(), 0, now->minute(), now->second(), milli); //00110
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d:%d%d:%d%d:%d%d:%lu", now->year(), now->month(), now->day(), 0, now->hour(), 0, now->minute(), 0, now->second(), milli); //00111
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d:%d%d:%d:%d%d:%lu", now->year(), now->month(), now->day(), 0, now->hour(), now->minute(), 0, now->second(), milli); //00101
}
else if(now->month() >= 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d:%d%d:%d:%d:%lu", now->year(), now->month(), now->day(), 0, now->hour(), now->minute(), now->second(), milli); //00100
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d%d:%d:%d:%lu", now->year(), now->month(), 0, now->day(), 0, now->hour(), now->minute(), now->second(), milli); //01100
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d%d:%d:%d%d:%lu", now->year(), now->month(), 0, now->day(), 0, now->hour(), now->minute(), 0, now->second(), milli); //01101
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d%d:%d%d:%d%d:%lu", now->year(), now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), 0, now->second(), milli); //01111
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d%d:%d%d:%d:%lu", now->year(), now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), now->second(), milli); //01110
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d:%d%d:%d:%lu", now->year(), now->month(), 0, now->day(), now->hour(), 0, now->minute(), now->second(), milli); //01010
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d:%d%d:%d%d:%lu", now->year(), now->month(), 0, now->day(), now->hour(), 0, now->minute(), 0, now->second(), milli); //01011
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d:%d:%d%d:%lu", now->year(), now->month(), 0, now->day(), now->hour(), now->minute(), 0, now->second(), milli); //01001
}
else if(now->month() >= 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d:%d%d:%d:%d:%d:%lu", now->year(), now->month(), 0, now->day(), now->hour(), now->minute(), now->second(), milli); //01000
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d:%d:%d:%lu", now->year(), 0, now->month(), 0, now->day(), now->hour(), now->minute(), now->second(), milli); //11000
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d:%d:%d%d:%lu", now->year(), 0, now->month(), 0, now->day(), now->hour(), now->minute(), 0, now->second(), milli); //11001
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d:%d%d:%d%d:%lu", now->year(), 0, now->month(), 0, now->day(), now->hour(), 0, now->minute(), 0, now->second(), milli); //11011
}
else if(now->month() < 10 && now->day() < 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d:%d%d:%d:%lu", now->year(), 0, now->month(), 0, now->day(), now->hour(), 0, now->minute(), now->second(), milli); //11010
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d%d:%d%d:%d:%lu", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), now->second(), milli); //11110
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d%d:%d%d:%d%d:%lu", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), 0, now->minute(), 0, now->second(), milli); //11111
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d%d:%d:%d%d:%lu", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), now->minute(), 0, now->second(), milli); //11101
}
else if(now->month() < 10 && now->day() < 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d%d:%d%d:%d:%d:%lu", now->year(), 0, now->month(), 0, now->day(), 0, now->hour(), now->minute(), now->second(), milli); //11100
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d%d:%d:%d:%lu", now->year(), 0, now->month(), now->day(), 0, now->hour(), now->minute(), now->second(), milli); //10100
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d%d:%d:%d%d:%lu", now->year(), 0, now->month(), now->day(), 0, now->hour(), now->minute(), 0, now->second(), milli); //10101
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d%d:%d%d:%d%d:%lu", now->year(), 0, now->month(), now->day(), 0, now->hour(), 0, now->minute(), 0, now->second(), milli); //10111
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() < 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d%d:%d%d:%d:%lu", now->year(), 0, now->month(), now->day(), 0, now->hour(), 0, now->minute(), now->second(), milli); //10110
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() >= 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d:%d%d:%d:%lu", now->year(), 0, now->month(), now->day(), now->hour(), 0, now->minute(), now->second(), milli); //10010
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() < 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d:%d%d:%d%d:%lu", now->year(), 0, now->month(), now->day(), now->hour(), 0, now->minute(), 0, now->second(), milli); //10011
}
else if(now->month() < 10 && now->day() >= 10 && now->hour() >= 10 && now->minute() >= 10 && now->second() < 10)
{
sprintf(timestamp, "%d:%d%d:%d:%d:%d:%d%d:%lu", now->year(), 0, now->month(), now->day(), now->hour(), now->minute(), 0, now->second(), milli); //10001
}
else
{
sprintf(timestamp, "%d:%d%d:%d:%d:%d:%d:%lu", now->year(), 0, now->month(), now->day(), now->hour(), now->minute(), now->second(), milli); //10000
}
}
}
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
imu_good = imu_setup();
rtc_good = rtc_setup();
cam_good = cam_setup();
sd_good = sd_setup();
wifi_good = wifi_setup();
xTaskCreatePinnedToCore(
task_send_csi, "Task Send CSI" // A name just for humans
,
3072 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`
,
NULL // Task parameter which can modify the task behavior. This must be passed as pointer to void.
,
3 // Priority
,
NULL // Task handle is not used here - simply pass NULL
,
0
);
xTaskCreatePinnedToCore(
task_save_imu, "Task Save IMU" // A name just for humans
,
4096 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`
,
NULL // Task parameter which can modify the task behavior. This must be passed as pointer to void.
,
3 // Priority
,
NULL // Task handle is not used here - simply pass NULL
,
0
);
xTaskCreatePinnedToCore(
task_write_all, "Task Write All" // A name just for humans
,
8192 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`
,
NULL // Task parameter which can modify the task behavior. This must be passed as pointer to void.
,
2 // Priority
,
NULL // Task handle is not used here - simply pass NULL
,
1
);
}
void loop()
{
// put your main code here, to run repeatedly:
}
void task_send_csi(void *pvParameters)
{
esp_now_peer_info_t recv;
esp_now_get_peer(MAC_ADDR_BROAD, &recv);
const TickType_t xDelay = (1000 / CONFIG_SEND_FREQUENCY) / portTICK_PERIOD_MS;
for(;;)
{
// send a packet
//esp_err_t errcode = ;
report_esp_error(esp_now_send(recv.peer_addr, &pkt_count, sizeof(uint8_t)));
/*if(errcode != ESP_OK)
{
Serial.print("ESP-NOW send error: ");
Serial.println(esp_err_to_name(errcode));
}*/
// wait the specified time before sending again
vTaskDelay( xDelay );
}
vTaskDelete( NULL );
}
void task_save_imu(void *pvParameters)
{
const TickType_t xDelay = (1000 / CONFIG_SEND_FREQUENCY) / portTICK_PERIOD_MS;
char line[IMU_SIZE + TIME_SIZE]{};
//char data[60];
char timestamp[TIME_SIZE]{};
unsigned long time;
sensors_event_t a, g, temp;
DateTime now;
for(;;)
{
imu.getEvent(&a, &g, &temp);
now = rtc.now();
new_time = millis();
time = new_time - old_time;
memset(timestamp, '\0', TIME_SIZE);
generate_timestamp(timestamp, &now, false, time);
sprintf(line, "%s,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f", timestamp, a.acceleration.x, a.acceleration.y, a.acceleration.z, g.gyro.x, g.gyro.y, g.gyro.z);
//strcpy(line, timestamp);
//sprintf(data, ",%.6f,%.6f,%.6f,%.6f,%.6f,%.6f", a.acceleration.x, a.acceleration.y, a.acceleration.z, g.gyro.x, g.gyro.y, g.gyro.z);
//strcat(line, data);
if(imu_switch == 0)
{
taskENTER_CRITICAL(&lock);
strcpy(imu_data0[imu_idx], line);
imu_idx++;
taskEXIT_CRITICAL(&lock);
}
else
{
taskENTER_CRITICAL(&lock);
strcpy(imu_data1[imu_idx], line);
imu_idx++;
taskEXIT_CRITICAL(&lock);
}
vTaskDelay( xDelay );
}
vTaskDelete( NULL );
}
void task_write_all(void *pvParameters)
{
const TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
char filename[FILENAME_SIZE]{};
char timestamp[TIME_SIZE]{};
DateTime now;
File img_file;
File imu_file;
for(;;)
{
Serial.println("started write all");
taskENTER_CRITICAL(&lock);
imu_idx_last = imu_idx;
imu_idx = 0;
imu_switch = 1 - imu_switch;
old_time = millis();
taskEXIT_CRITICAL(&lock);
if(sd_good)
{
now = rtc.now();
memset(timestamp, '\0', TIME_SIZE);
memset(filename, '\0', FILENAME_SIZE);
generate_timestamp(timestamp, &now, true);
sprintf(filename, "/image%s.jpg", timestamp);
camera_fb_t *fb = esp_camera_fb_get();
if (!fb)
{
Serial.println("Failed to get camera frame buffer");
}
Serial.printf("Writing files: %s\n", filename);
img_file = SD.open(filename, FILE_WRITE);
//imu_file = SD.open("/imu_data.csv", FILE_APPEND);
if(!img_file)
{
Serial.println("Failed to open image file for writing");
}
//if(!imu_file)
//{
// Serial.println("Failed to open imu file for writing");
//}
Serial.println("Files loaded");
if(img_file.write(fb->buf, fb->len) == fb->len)
{
Serial.println("Image write succeeded");
}
else
{
Serial.println("Image write failed");
}
img_file.close();
// Release image buffer
esp_camera_fb_return(fb);
Serial.println("Image saved");
//Serial.println("Writing csv");
//if(imu_switch == 0)
//{
// for(int i=0;i<imu_idx_last;i++)
// {
// imu_file.println(imu_data1[i]);
// }
//}
//else
//{
// for(int i=0;i<imu_idx_last;i++)
// {
// imu_file.println(imu_data0[i]);
// }
}
// imu_file.close();
// Serial.println("imu csv saved");
//}
else
{
Serial.println("Unknown SD card failure");
}
vTaskDelay( xDelay );
}
vTaskDelete( NULL );
}