ADC app added, nunchuk RPM filter, FW version added, feedback on appconf and mcconf set

This commit is contained in:
Benjamin Vedder 2015-05-04 23:25:43 +02:00
parent 85f0073105
commit 5a5ccfb4c3
11 changed files with 492 additions and 9 deletions

View File

@ -39,6 +39,10 @@ void app_init(app_configuration *conf) {
app_ppm_start(); app_ppm_start();
break; break;
case APP_ADC:
app_adc_start();
break;
case APP_UART: case APP_UART:
hw_stop_i2c(); hw_stop_i2c();
app_uartcomm_start(); app_uartcomm_start();
@ -50,6 +54,12 @@ void app_init(app_configuration *conf) {
app_uartcomm_start(); app_uartcomm_start();
break; break;
case APP_ADC_UART:
hw_stop_i2c();
app_adc_start();
app_uartcomm_start();
break;
case APP_NUNCHUK: case APP_NUNCHUK:
app_nunchuk_start(); app_nunchuk_start();
break; break;
@ -87,6 +97,7 @@ const app_configuration* app_get_configuration(void) {
void app_set_configuration(app_configuration *conf) { void app_set_configuration(app_configuration *conf) {
appconf = *conf; appconf = *conf;
app_ppm_configure(&appconf.app_ppm_conf); app_ppm_configure(&appconf.app_ppm_conf);
app_adc_configure(&appconf.app_adc_conf);
app_uartcomm_configure(appconf.app_uart_baudrate); app_uartcomm_configure(appconf.app_uart_baudrate);
app_nunchuk_configure(&appconf.app_chuk_conf); app_nunchuk_configure(&appconf.app_chuk_conf);
} }

View File

@ -35,6 +35,10 @@ void app_set_configuration(app_configuration *conf);
// Standard apps // Standard apps
void app_ppm_start(void); void app_ppm_start(void);
void app_ppm_configure(ppm_config *conf); void app_ppm_configure(ppm_config *conf);
void app_adc_start(void);
void app_adc_configure(adc_config *conf);
float app_adc_get_decoded_level(void);
float app_adc_get_voltage(void);
void app_uartcomm_start(void); void app_uartcomm_start(void);
void app_uartcomm_configure(uint32_t baudrate); void app_uartcomm_configure(uint32_t baudrate);
void app_nunchuk_start(void); void app_nunchuk_start(void);

336
applications/app_adc.c Normal file
View File

@ -0,0 +1,336 @@
/*
Copyright 2012-2015 Benjamin Vedder benjamin@vedder.se
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* app_adc.c
*
* Created on: 1 may 2015
* Author: benjamin
*/
#include "app.h"
#include "ch.h"
#include "hal.h"
#include "stm32f4xx_conf.h"
#include "mcpwm.h"
#include "timeout.h"
#include "utils.h"
#include "comm_can.h"
#include "hw.h"
#include <math.h>
// Settings
#define MAX_CAN_AGE 0.1
#define MIN_MS_WITHOUT_POWER 500
#define FILTER_SAMPLES 5
// Threads
static msg_t adc_thread(void *arg);
static WORKING_AREA(adc_thread_wa, 1024);
// Private variables
static volatile adc_config config;
static volatile float ms_without_power = 0;
static volatile float decoded_level = 0.0;
static volatile float read_voltage = 0.0;
void app_adc_configure(adc_config *conf) {
config = *conf;
ms_without_power = 0.0;
}
void app_adc_start(void) {
chThdCreateStatic(adc_thread_wa, sizeof(adc_thread_wa), NORMALPRIO, adc_thread, NULL);
}
float app_adc_get_decoded_level(void) {
return decoded_level;
}
float app_adc_get_voltage(void) {
return read_voltage;
}
static msg_t adc_thread(void *arg) {
(void)arg;
chRegSetThreadName("APP_ADC");
// Set servo pin as an input with pullup
palSetPadMode(HW_ICU_GPIO, HW_ICU_PIN, PAL_MODE_INPUT_PULLUP);
for(;;) {
// Sleep for a time according to the specified rate
systime_t sleep_time = CH_FREQUENCY / config.update_rate_hz;
// At least one tick should be slept to not block the other threads
if (sleep_time == 0) {
sleep_time = 1;
}
chThdSleep(sleep_time);
// Read the external ADC pin and convert the value to a voltage.
float pwr = (float)ADC_Value[ADC_IND_EXT];
pwr /= 4095;
pwr *= V_REG;
read_voltage = pwr;
// Optionally apply a mean value filter
if (config.use_filter) {
static float filter_buffer[FILTER_SAMPLES];
static int filter_ptr = 0;
filter_buffer[filter_ptr++] = pwr;
if (filter_ptr >= FILTER_SAMPLES) {
filter_ptr = 0;
}
pwr = 0.0;
for (int i = 0;i < FILTER_SAMPLES;i++) {
pwr += filter_buffer[i];
}
pwr /= FILTER_SAMPLES;
}
// Map and truncate the read voltage
pwr = utils_map(pwr, config.voltage_start, config.voltage_end, 0.0, 1.0);
utils_truncate_number(&pwr, 0.0, 1.0);
// Optionally invert the read voltage
if (config.voltage_inverted) {
pwr = 1.0 - pwr;
}
decoded_level = pwr;
// Read the servo pin and optionally invert it.
bool button_val = !palReadPad(HW_ICU_GPIO, HW_ICU_PIN);
if (config.button_inverted) {
button_val = !button_val;
}
switch (config.ctrl_type) {
case ADC_CTRL_TYPE_CURRENT_REV_CENTER:
case ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_CENTER:
case ADC_CTRL_TYPE_DUTY_REV_CENTER:
// Scale the voltage and set 0 at the center
pwr *= 2.0;
pwr -= 1.0;
break;
case ADC_CTRL_TYPE_CURRENT_REV_BUTTON:
case ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_BUTTON:
case ADC_CTRL_TYPE_DUTY_REV_BUTTON:
// Invert the voltage if the button is pressed
if (button_val) {
pwr = -pwr;
}
break;
default:
break;
}
// Apply a deadband
utils_deadband(&pwr, config.hyst, 1.0);
float current = 0;
bool current_mode = false;
bool current_mode_brake = false;
const volatile mc_configuration *mcconf = mcpwm_get_configuration();
bool send_duty = false;
// Use the filtered and mapped voltage for control according to the configuration.
switch (config.ctrl_type) {
case ADC_CTRL_TYPE_CURRENT:
case ADC_CTRL_TYPE_CURRENT_REV_CENTER:
case ADC_CTRL_TYPE_CURRENT_REV_BUTTON:
current_mode = true;
if (pwr >= 0.0) {
current = pwr * mcconf->l_current_max;
} else {
current = pwr * fabsf(mcconf->l_current_min);
}
if (fabsf(pwr) < 0.001) {
ms_without_power += (1000.0 * (float)sleep_time) / (float)CH_FREQUENCY;
}
break;
case ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_CENTER:
case ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_BUTTON:
current_mode = true;
if (pwr >= 0.0) {
current = pwr * mcconf->l_current_max;
} else {
current = fabsf(pwr * mcconf->l_current_min);
current_mode_brake = true;
}
if (pwr < 0.001) {
ms_without_power += (1000.0 * (float)sleep_time) / (float)CH_FREQUENCY;
}
break;
case ADC_CTRL_TYPE_DUTY:
case ADC_CTRL_TYPE_DUTY_REV_CENTER:
case ADC_CTRL_TYPE_DUTY_REV_BUTTON:
if (fabsf(pwr) < 0.001) {
ms_without_power += (1000.0 * (float)sleep_time) / (float)CH_FREQUENCY;
}
if (!(ms_without_power < MIN_MS_WITHOUT_POWER && config.safe_start)) {
mcpwm_set_duty(pwr);
send_duty = true;
}
break;
default:
continue;
}
// If safe start is enabled and the output has not been zero for long enough
if (ms_without_power < MIN_MS_WITHOUT_POWER && config.safe_start) {
static int pulses_without_power_before = 0;
if (ms_without_power == pulses_without_power_before) {
ms_without_power = 0;
}
pulses_without_power_before = ms_without_power;
mcpwm_set_current(0.0);
continue;
}
// Reset timeout
timeout_reset();
// Find lowest RPM (for traction control)
float rpm_local = mcpwm_get_rpm();
float rpm_lowest = rpm_local;
if (config.multi_esc) {
for (int i = 0;i < CAN_STATUS_MSGS_TO_STORE;i++) {
can_status_msg *msg = comm_can_get_status_msg_index(i);
if (msg->id >= 0 && UTILS_AGE_S(msg->rx_time) < MAX_CAN_AGE) {
float rpm_tmp = msg->rpm;
if (fabsf(rpm_tmp) < fabsf(rpm_lowest)) {
rpm_lowest = rpm_tmp;
}
}
}
}
// Optionally send the duty cycles to the other ESCs seen on the CAN-bus
if (send_duty && config.multi_esc) {
float duty = mcpwm_get_duty_cycle_now();
for (int i = 0;i < CAN_STATUS_MSGS_TO_STORE;i++) {
can_status_msg *msg = comm_can_get_status_msg_index(i);
if (msg->id >= 0 && UTILS_AGE_S(msg->rx_time) < MAX_CAN_AGE) {
comm_can_set_duty(msg->id, duty);
}
}
}
if (current_mode) {
if (current_mode_brake) {
mcpwm_set_brake_current(current);
// Send brake command to all ESCs seen recently on the CAN bus
for (int i = 0;i < CAN_STATUS_MSGS_TO_STORE;i++) {
can_status_msg *msg = comm_can_get_status_msg_index(i);
if (msg->id >= 0 && UTILS_AGE_S(msg->rx_time) < MAX_CAN_AGE) {
comm_can_set_current_brake(msg->id, current);
}
}
} else {
// Apply soft RPM limit
if (rpm_lowest > config.rpm_lim_end && current > 0.0) {
current = mcconf->cc_min_current;
} else if (rpm_lowest > config.rpm_lim_start && current > 0.0) {
current = utils_map(rpm_lowest, config.rpm_lim_start, config.rpm_lim_end, current, mcconf->cc_min_current);
} else if (rpm_lowest < -config.rpm_lim_end && current < 0.0) {
current = mcconf->cc_min_current;
} else if (rpm_lowest < -config.rpm_lim_start && current < 0.0) {
rpm_lowest = -rpm_lowest;
current = -current;
current = utils_map(rpm_lowest, config.rpm_lim_start, config.rpm_lim_end, current, mcconf->cc_min_current);
current = -current;
rpm_lowest = -rpm_lowest;
}
float current_out = current;
bool is_reverse = false;
if (current_out < 0.0) {
is_reverse = true;
current_out = -current_out;
current = -current;
rpm_local = -rpm_local;
rpm_lowest = -rpm_lowest;
}
// Traction control
if (config.multi_esc) {
for (int i = 0;i < CAN_STATUS_MSGS_TO_STORE;i++) {
can_status_msg *msg = comm_can_get_status_msg_index(i);
if (msg->id >= 0 && UTILS_AGE_S(msg->rx_time) < MAX_CAN_AGE) {
if (config.tc) {
float rpm_tmp = msg->rpm;
if (is_reverse) {
rpm_tmp = -rpm_tmp;
}
float diff = rpm_tmp - rpm_lowest;
current_out = utils_map(diff, 0.0, config.tc_max_diff, current, 0.0);
if (current_out < mcconf->cc_min_current) {
current_out = 0.0;
}
}
if (is_reverse) {
comm_can_set_current(msg->id, -current_out);
} else {
comm_can_set_current(msg->id, current_out);
}
}
}
if (config.tc) {
float diff = rpm_local - rpm_lowest;
current_out = utils_map(diff, 0.0, config.tc_max_diff, current, 0.0);
if (current_out < mcconf->cc_min_current) {
current_out = 0.0;
}
}
}
if (is_reverse) {
mcpwm_set_current(-current_out);
} else {
mcpwm_set_current(current_out);
}
}
}
}
return 0;
}

View File

@ -40,6 +40,7 @@
#define OUTPUT_ITERATION_TIME_MS 1 #define OUTPUT_ITERATION_TIME_MS 1
#define MAX_CURR_DIFFERENCE 5.0 #define MAX_CURR_DIFFERENCE 5.0
#define MAX_CAN_AGE 0.1 #define MAX_CAN_AGE 0.1
#define RPM_FILTER_SAMPLES 8
// Threads // Threads
static msg_t chuk_thread(void *arg); static msg_t chuk_thread(void *arg);
@ -230,12 +231,27 @@ static msg_t output_thread(void *arg) {
// If c is pressed and no throttle is used, maintain the current speed with PID control // If c is pressed and no throttle is used, maintain the current speed with PID control
static bool was_pid = false; static bool was_pid = false;
// Filter RPM to avoid glitches
static float filter_buffer[RPM_FILTER_SAMPLES];
static int filter_ptr = 0;
float rpm_filtered = mcpwm_get_rpm();
filter_buffer[filter_ptr++] = rpm_filtered;
if (filter_ptr >= RPM_FILTER_SAMPLES) {
filter_ptr = 0;
}
rpm_filtered = 0.0;
for (int i = 0;i < RPM_FILTER_SAMPLES;i++) {
rpm_filtered += filter_buffer[i];
}
rpm_filtered /= RPM_FILTER_SAMPLES;
if (chuck_d.bt_c && out_val == 0.0) { if (chuck_d.bt_c && out_val == 0.0) {
static float pid_rpm = 0.0; static float pid_rpm = 0.0;
if (!was_pid) { if (!was_pid) {
was_pid = true; was_pid = true;
pid_rpm = mcpwm_get_rpm(); pid_rpm = rpm_filtered;
} }
if ((is_reverse && pid_rpm < 0.0) || (!is_reverse && pid_rpm > 0.0)) { if ((is_reverse && pid_rpm < 0.0) || (!is_reverse && pid_rpm > 0.0)) {

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2012-2014 Benjamin Vedder benjamin@vedder.se Copyright 2012-2015 Benjamin Vedder benjamin@vedder.se
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -53,7 +53,7 @@ static volatile ppm_config config;
static volatile int pulses_without_power = 0; static volatile int pulses_without_power = 0;
// Private functions // Private functions
void update(void *p); static void update(void *p);
void app_ppm_configure(ppm_config *conf) { void app_ppm_configure(ppm_config *conf) {
config = *conf; config = *conf;
@ -79,7 +79,7 @@ static void servodec_func(void) {
chSysUnlockFromIsr(); chSysUnlockFromIsr();
} }
void update(void *p) { static void update(void *p) {
chSysLockFromIsr(); chSysLockFromIsr();
chVTSetI(&vt, MS2ST(2), update, p); chVTSetI(&vt, MS2ST(2), update, p);
chEvtSignalI(ppm_tp, (eventmask_t) 1); chEvtSignalI(ppm_tp, (eventmask_t) 1);

View File

@ -1,5 +1,6 @@
APPSRC = applications/app.c \ APPSRC = applications/app.c \
applications/app_ppm.c \ applications/app_ppm.c \
applications/app_adc.c \
applications/app_sten.c \ applications/app_sten.c \
applications/app_gurgalof.c \ applications/app_gurgalof.c \
applications/app_uartcomm.c \ applications/app_uartcomm.c \

View File

@ -239,7 +239,12 @@ static msg_t cancom_status_thread(void *arg) {
comm_can_transmit(app_get_configuration()->controller_id | ((uint32_t)CAN_PACKET_STATUS << 8), buffer, send_index); comm_can_transmit(app_get_configuration()->controller_id | ((uint32_t)CAN_PACKET_STATUS << 8), buffer, send_index);
} }
chThdSleep(CH_FREQUENCY / app_get_configuration()->send_can_status_rate_hz); systime_t sleep_time = CH_FREQUENCY / app_get_configuration()->send_can_status_rate_hz;
if (sleep_time == 0) {
sleep_time = 1;
}
chThdSleep(sleep_time);
} }
return 0; return 0;

View File

@ -115,6 +115,14 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
len--; len--;
switch (packet_id) { switch (packet_id) {
case COMM_FW_VERSION:
ind = 0;
send_buffer[ind++] = COMM_FW_VERSION;
send_buffer[ind++] = FW_VERSION_MAJOR;
send_buffer[ind++] = FW_VERSION_MINOR;
commands_send_packet(send_buffer, ind);
break;
case COMM_GET_VALUES: case COMM_GET_VALUES:
ind = 0; ind = 0;
send_buffer[ind++] = COMM_GET_VALUES; send_buffer[ind++] = COMM_GET_VALUES;
@ -241,6 +249,10 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
conf_general_store_mc_configuration(&mcconf); conf_general_store_mc_configuration(&mcconf);
mcpwm_set_configuration(&mcconf); mcpwm_set_configuration(&mcconf);
ind = 0;
send_buffer[ind++] = COMM_SET_MCCONF;
commands_send_packet(send_buffer, ind);
break; break;
case COMM_GET_MCCONF: case COMM_GET_MCCONF:
@ -328,6 +340,21 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
appconf.app_ppm_conf.tc = data[ind++]; appconf.app_ppm_conf.tc = data[ind++];
appconf.app_ppm_conf.tc_max_diff = (float)buffer_get_int32(data, &ind) / 1000.0; appconf.app_ppm_conf.tc_max_diff = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.ctrl_type = data[ind++];
appconf.app_adc_conf.hyst = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.voltage_start = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.voltage_end = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.use_filter = data[ind++];
appconf.app_adc_conf.safe_start = data[ind++];
appconf.app_adc_conf.button_inverted = data[ind++];
appconf.app_adc_conf.voltage_inverted = data[ind++];
appconf.app_adc_conf.rpm_lim_start = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.rpm_lim_end = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.multi_esc = data[ind++];
appconf.app_adc_conf.tc = data[ind++];
appconf.app_adc_conf.tc_max_diff = (float)buffer_get_int32(data, &ind) / 1000.0;
appconf.app_adc_conf.update_rate_hz = buffer_get_uint16(data, &ind);
appconf.app_uart_baudrate = buffer_get_uint32(data, &ind); appconf.app_uart_baudrate = buffer_get_uint32(data, &ind);
appconf.app_chuk_conf.ctrl_type = data[ind++]; appconf.app_chuk_conf.ctrl_type = data[ind++];
@ -343,6 +370,10 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
conf_general_store_app_configuration(&appconf); conf_general_store_app_configuration(&appconf);
app_set_configuration(&appconf); app_set_configuration(&appconf);
timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current); timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current);
ind = 0;
send_buffer[ind++] = COMM_SET_MCCONF;
commands_send_packet(send_buffer, ind);
break; break;
case COMM_GET_APPCONF: case COMM_GET_APPCONF:
@ -371,6 +402,21 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
send_buffer[ind++] = appconf.app_ppm_conf.tc; send_buffer[ind++] = appconf.app_ppm_conf.tc;
buffer_append_int32(send_buffer, (int32_t)(appconf.app_ppm_conf.tc_max_diff * 1000.0), &ind); buffer_append_int32(send_buffer, (int32_t)(appconf.app_ppm_conf.tc_max_diff * 1000.0), &ind);
send_buffer[ind++] = appconf.app_adc_conf.ctrl_type;
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.hyst * 1000.0), &ind);
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.voltage_start * 1000.0), &ind);
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.voltage_end * 1000.0), &ind);
send_buffer[ind++] = appconf.app_adc_conf.use_filter;
send_buffer[ind++] = appconf.app_adc_conf.safe_start;
send_buffer[ind++] = appconf.app_adc_conf.button_inverted;
send_buffer[ind++] = appconf.app_adc_conf.voltage_inverted;
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.rpm_lim_start * 1000.0), &ind);
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.rpm_lim_end * 1000.0), &ind);
send_buffer[ind++] = appconf.app_adc_conf.multi_esc;
send_buffer[ind++] = appconf.app_adc_conf.tc;
buffer_append_int32(send_buffer, (int32_t)(appconf.app_adc_conf.tc_max_diff * 1000.0), &ind);
buffer_append_uint16(send_buffer, appconf.app_adc_conf.update_rate_hz, &ind);
buffer_append_uint32(send_buffer, appconf.app_uart_baudrate, &ind); buffer_append_uint32(send_buffer, appconf.app_uart_baudrate, &ind);
send_buffer[ind++] = appconf.app_chuk_conf.ctrl_type; send_buffer[ind++] = appconf.app_chuk_conf.ctrl_type;
@ -426,6 +472,14 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
commands_send_packet(send_buffer, ind); commands_send_packet(send_buffer, ind);
break; break;
case COMM_GET_DECODED_ADC:
ind = 0;
send_buffer[ind++] = COMM_GET_DECODED_ADC;
buffer_append_int32(send_buffer, (int32_t)(app_adc_get_decoded_level() * 1000000.0), &ind);
buffer_append_int32(send_buffer, (int32_t)(app_adc_get_voltage() * 1000000.0), &ind);
commands_send_packet(send_buffer, ind);
break;
case COMM_GET_DECODED_CHUK: case COMM_GET_DECODED_CHUK:
ind = 0; ind = 0;
send_buffer[ind++] = COMM_GET_DECODED_CHUK; send_buffer[ind++] = COMM_GET_DECODED_CHUK;

View File

@ -152,19 +152,34 @@ void conf_general_read_app_configuration(app_configuration *conf) {
conf->app_to_use = APP_NONE; conf->app_to_use = APP_NONE;
conf->app_ppm_conf.ctrl_type = PPM_CTRL_TYPE_CURRENT; conf->app_ppm_conf.ctrl_type = PPM_CTRL_TYPE_NONE;
conf->app_ppm_conf.pid_max_erpm = 15000; conf->app_ppm_conf.pid_max_erpm = 15000;
conf->app_ppm_conf.hyst = 0.15; conf->app_ppm_conf.hyst = 0.15;
conf->app_ppm_conf.pulse_start = 1.0; conf->app_ppm_conf.pulse_start = 1.0;
conf->app_ppm_conf.pulse_end = 2.0; conf->app_ppm_conf.pulse_end = 2.0;
conf->app_ppm_conf.median_filter = false; conf->app_ppm_conf.median_filter = false;
conf->app_ppm_conf.safe_start = false; conf->app_ppm_conf.safe_start = true;
conf->app_ppm_conf.rpm_lim_start = 150000.0; conf->app_ppm_conf.rpm_lim_start = 150000.0;
conf->app_ppm_conf.rpm_lim_end = 200000.0; conf->app_ppm_conf.rpm_lim_end = 200000.0;
conf->app_ppm_conf.multi_esc = true; conf->app_ppm_conf.multi_esc = false;
conf->app_ppm_conf.tc = false; conf->app_ppm_conf.tc = false;
conf->app_ppm_conf.tc_max_diff = 3000.0; conf->app_ppm_conf.tc_max_diff = 3000.0;
conf->app_adc_conf.ctrl_type = ADC_CTRL_TYPE_NONE;
conf->app_adc_conf.hyst = 0.15;
conf->app_adc_conf.voltage_start = 0.9;
conf->app_adc_conf.voltage_end = 3.0;
conf->app_adc_conf.use_filter = true;
conf->app_adc_conf.safe_start = true;
conf->app_adc_conf.button_inverted = false;
conf->app_adc_conf.voltage_inverted = false;
conf->app_adc_conf.rpm_lim_start = 150000;
conf->app_adc_conf.rpm_lim_end = 200000;
conf->app_adc_conf.multi_esc = false;
conf->app_adc_conf.tc = false;
conf->app_adc_conf.tc_max_diff = 3000.0;
conf->app_adc_conf.update_rate_hz = 500;
conf->app_uart_baudrate = 115200; conf->app_uart_baudrate = 115200;
conf->app_chuk_conf.ctrl_type = CHUK_CTRL_TYPE_CURRENT; conf->app_chuk_conf.ctrl_type = CHUK_CTRL_TYPE_CURRENT;

View File

@ -25,6 +25,10 @@
#ifndef CONF_GENERAL_H_ #ifndef CONF_GENERAL_H_
#define CONF_GENERAL_H_ #define CONF_GENERAL_H_
// Software version
#define FW_VERSION_MAJOR 1
#define FW_VERSION_MINOR 0
#include "datatypes.h" #include "datatypes.h"
/* /*

View File

@ -145,8 +145,10 @@ typedef struct {
typedef enum { typedef enum {
APP_NONE = 0, APP_NONE = 0,
APP_PPM, APP_PPM,
APP_ADC,
APP_UART, APP_UART,
APP_PPM_UART, APP_PPM_UART,
APP_ADC_UART,
APP_NUNCHUK, APP_NUNCHUK,
APP_NRF, APP_NRF,
APP_CUSTOM APP_CUSTOM
@ -179,6 +181,36 @@ typedef struct {
float tc_max_diff; float tc_max_diff;
} ppm_config; } ppm_config;
// ADC control types
typedef enum {
ADC_CTRL_TYPE_NONE = 0,
ADC_CTRL_TYPE_CURRENT,
ADC_CTRL_TYPE_CURRENT_REV_CENTER,
ADC_CTRL_TYPE_CURRENT_REV_BUTTON,
ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_CENTER,
ADC_CTRL_TYPE_CURRENT_NOREV_BRAKE_BUTTON,
ADC_CTRL_TYPE_DUTY,
ADC_CTRL_TYPE_DUTY_REV_CENTER,
ADC_CTRL_TYPE_DUTY_REV_BUTTON
} adc_control_type;
typedef struct {
adc_control_type ctrl_type;
float hyst;
float voltage_start;
float voltage_end;
bool use_filter;
bool safe_start;
bool button_inverted;
bool voltage_inverted;
float rpm_lim_start;
float rpm_lim_end;
bool multi_esc;
bool tc;
float tc_max_diff;
uint32_t update_rate_hz;
} adc_config;
// Nunchuk control types // Nunchuk control types
typedef enum { typedef enum {
CHUK_CTRL_TYPE_NONE = 0, CHUK_CTRL_TYPE_NONE = 0,
@ -212,6 +244,9 @@ typedef struct {
// PPM application settings // PPM application settings
ppm_config app_ppm_conf; ppm_config app_ppm_conf;
// ADC application settings
adc_config app_adc_conf;
// UART application settings // UART application settings
uint32_t app_uart_baudrate; uint32_t app_uart_baudrate;
@ -221,7 +256,8 @@ typedef struct {
// Communication commands // Communication commands
typedef enum { typedef enum {
COMM_GET_VALUES = 0, COMM_FW_VERSION = 0,
COMM_GET_VALUES,
COMM_SET_DUTY, COMM_SET_DUTY,
COMM_SET_CURRENT, COMM_SET_CURRENT,
COMM_SET_CURRENT_BRAKE, COMM_SET_CURRENT_BRAKE,
@ -242,6 +278,7 @@ typedef enum {
COMM_REBOOT, COMM_REBOOT,
COMM_ALIVE, COMM_ALIVE,
COMM_GET_DECODED_PPM, COMM_GET_DECODED_PPM,
COMM_GET_DECODED_ADC,
COMM_GET_DECODED_CHUK, COMM_GET_DECODED_CHUK,
COMM_FORWARD_CAN COMM_FORWARD_CAN
} COMM_PACKET_ID; } COMM_PACKET_ID;