Implemented oneshot adc reading
This commit is contained in:
@@ -35,4 +35,5 @@ idf_component_register(
|
|||||||
${APP_SOURCES}
|
${APP_SOURCES}
|
||||||
INCLUDE_DIRS
|
INCLUDE_DIRS
|
||||||
.
|
.
|
||||||
|
REQUIRES esp_adc
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -273,6 +273,45 @@ static void state_machine_loop(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emgPrinter() {
|
||||||
|
TickType_t previousWake = xTaskGetTickCount();
|
||||||
|
while (1) {
|
||||||
|
emg_sample_t sample;
|
||||||
|
emg_sensor_read(&sample);
|
||||||
|
for (uint8_t i = 0; i < EMG_NUM_CHANNELS; i++) {
|
||||||
|
printf("%d", sample.channels[i]);
|
||||||
|
if (i != EMG_NUM_CHANNELS - 1) printf(" | ");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
vTaskDelayUntil(&previousWake, pdMS_TO_TICKS(100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appConnector() {
|
||||||
|
/* Create command queue */
|
||||||
|
g_cmd_queue = xQueueCreate(10, sizeof(command_t));
|
||||||
|
if (g_cmd_queue == NULL) {
|
||||||
|
printf("[ERROR] Failed to create command queue!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Launch serial input task */
|
||||||
|
xTaskCreate(
|
||||||
|
serial_input_task,
|
||||||
|
"serial_input",
|
||||||
|
4096, /* Stack size */
|
||||||
|
NULL, /* Parameters */
|
||||||
|
5, /* Priority */
|
||||||
|
NULL /* Task handle */
|
||||||
|
);
|
||||||
|
|
||||||
|
printf("[PROTOCOL] Waiting for host to connect...\n");
|
||||||
|
printf("[PROTOCOL] Send: {\"cmd\": \"connect\"}\n\n");
|
||||||
|
|
||||||
|
/* Run main state machine */
|
||||||
|
state_machine_loop();
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Application Entry Point
|
* Application Entry Point
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -300,26 +339,6 @@ void app_main(void)
|
|||||||
|
|
||||||
printf("[INIT] Done!\n\n");
|
printf("[INIT] Done!\n\n");
|
||||||
|
|
||||||
/* Create command queue */
|
emgPrinter();
|
||||||
g_cmd_queue = xQueueCreate(10, sizeof(command_t));
|
// appConnector();
|
||||||
if (g_cmd_queue == NULL) {
|
|
||||||
printf("[ERROR] Failed to create command queue!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Launch serial input task */
|
|
||||||
xTaskCreate(
|
|
||||||
serial_input_task,
|
|
||||||
"serial_input",
|
|
||||||
4096, /* Stack size */
|
|
||||||
NULL, /* Parameters */
|
|
||||||
5, /* Priority */
|
|
||||||
NULL /* Task handle */
|
|
||||||
);
|
|
||||||
|
|
||||||
printf("[PROTOCOL] Waiting for host to connect...\n");
|
|
||||||
printf("[PROTOCOL] Send: {\"cmd\": \"connect\"}\n\n");
|
|
||||||
|
|
||||||
/* Run main state machine */
|
|
||||||
state_machine_loop();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
* Set to 1 while waiting for EMG sensors to arrive.
|
* Set to 1 while waiting for EMG sensors to arrive.
|
||||||
* Set to 0 when ready to use real sensors.
|
* Set to 0 when ready to use real sensors.
|
||||||
*/
|
*/
|
||||||
#define FEATURE_FAKE_EMG 1
|
#define FEATURE_FAKE_EMG 0
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* GPIO Pin Definitions - Servos
|
* GPIO Pin Definitions - Servos
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
* EMG Configuration
|
* EMG Configuration
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#define EMG_NUM_CHANNELS 4 /**< Number of EMG sensor channels */
|
#define EMG_NUM_CHANNELS 1 /**< Number of EMG sensor channels */
|
||||||
#define EMG_SAMPLE_RATE_HZ 1000 /**< Samples per second per channel */
|
#define EMG_SAMPLE_RATE_HZ 1000 /**< Samples per second per channel */
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|||||||
@@ -8,6 +8,18 @@
|
|||||||
#include "emg_sensor.h"
|
#include "emg_sensor.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "esp_adc/adc_oneshot.h"
|
||||||
|
#include "esp_adc/adc_cali.h"
|
||||||
|
#include "esp_adc/adc_cali_scheme.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
adc_oneshot_unit_handle_t adc1_handle;
|
||||||
|
adc_cali_handle_t cali_handle = NULL;
|
||||||
|
|
||||||
|
const uint8_t emg_channels[EMG_NUM_CHANNELS] = {ADC_CHANNEL_1};
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@@ -19,10 +31,44 @@ void emg_sensor_init(void)
|
|||||||
/* Seed random number generator for fake data */
|
/* Seed random number generator for fake data */
|
||||||
srand((unsigned int)esp_timer_get_time());
|
srand((unsigned int)esp_timer_get_time());
|
||||||
#else
|
#else
|
||||||
/* TODO: Configure ADC channels when sensors arrive */
|
// 1. --- ADC Unit Setup ---
|
||||||
/* adc1_config_width(EMG_ADC_WIDTH); */
|
adc_oneshot_unit_init_cfg_t init_config1 = {
|
||||||
/* adc1_config_channel_atten(ADC_EMG_CH0, EMG_ADC_ATTEN); */
|
.unit_id = ADC_UNIT_1,
|
||||||
/* ... */
|
.ulp_mode = ADC_ULP_MODE_DISABLE,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
|
||||||
|
|
||||||
|
// 2. --- ADC Channel Setup (GPIO 1?) ---
|
||||||
|
// Ensure the channel matches your GPIO in pinmap. For ADC1, GPIO1 is usually not CH0.
|
||||||
|
// Check your datasheet! (e.g., on S3, GPIO 1 is ADC1_CH0)
|
||||||
|
adc_oneshot_chan_cfg_t config = {
|
||||||
|
.bitwidth = ADC_BITWIDTH_DEFAULT, // 12-bit for S3
|
||||||
|
.atten = ADC_ATTEN_DB_12, // Allows up to ~3.1V
|
||||||
|
};
|
||||||
|
for (uint8_t i = 0; i < EMG_NUM_CHANNELS; i++)
|
||||||
|
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, emg_channels[i], &config));
|
||||||
|
|
||||||
|
// 3. --- Calibration Setup (CORRECTED for S3) ---
|
||||||
|
// ESP32-S3 uses Curve Fitting, not Line Fitting
|
||||||
|
adc_cali_curve_fitting_config_t cali_config = {
|
||||||
|
.unit_id = ADC_UNIT_1,
|
||||||
|
.atten = ADC_ATTEN_DB_12,
|
||||||
|
.bitwidth = ADC_BITWIDTH_DEFAULT,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&cali_config, &cali_handle));
|
||||||
|
|
||||||
|
// while (1) {
|
||||||
|
// int raw_val, voltage_mv;
|
||||||
|
|
||||||
|
// // Read Raw
|
||||||
|
// ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, ADC_CHANNEL_1, &raw_val));
|
||||||
|
|
||||||
|
// // Convert to mV using calibration
|
||||||
|
// ESP_ERROR_CHECK(adc_cali_raw_to_voltage(cali_handle, raw_val, &voltage_mv));
|
||||||
|
|
||||||
|
// printf("Raw: %d | Voltage: %d mV\n", raw_val, voltage_mv);
|
||||||
|
// vTaskDelay(pdMS_TO_TICKS(500));
|
||||||
|
// }
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,19 +79,23 @@ void emg_sensor_read(emg_sample_t *sample)
|
|||||||
#if FEATURE_FAKE_EMG
|
#if FEATURE_FAKE_EMG
|
||||||
/*
|
/*
|
||||||
* Generate fake EMG data:
|
* Generate fake EMG data:
|
||||||
* - Base value around 512 (middle of 10-bit range, matching Python sim)
|
* - Base value around 1650 (middle of 3.3V millivolt range)
|
||||||
* - Random noise of +/- 50
|
* - Random noise of +/- 50
|
||||||
* - Mimics real EMG baseline noise
|
* - Mimics real EMG baseline noise
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < EMG_NUM_CHANNELS; i++) {
|
for (int i = 0; i < EMG_NUM_CHANNELS; i++) {
|
||||||
int noise = (rand() % 101) - 50; /* -50 to +50 */
|
int noise = (rand() % 101) - 50; /* -50 to +50 */
|
||||||
sample->channels[i] = (uint16_t)(512 + noise);
|
sample->channels[i] = (uint16_t)(1650 + noise);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* TODO: Real ADC reads when sensors arrive */
|
int raw_val, voltage_mv;
|
||||||
/* sample->channels[0] = adc1_get_raw(ADC_EMG_CH0); */
|
for (uint8_t i = 0; i < EMG_NUM_CHANNELS; i++) {
|
||||||
/* sample->channels[1] = adc1_get_raw(ADC_EMG_CH1); */
|
ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, emg_channels[i], &raw_val));
|
||||||
/* ... */
|
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(cali_handle, raw_val, &voltage_mv));
|
||||||
|
sample->channels[i] = (uint16_t) voltage_mv;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user