mirror of https://github.com/rusefi/bldc.git
ADC app added, nunchuk RPM filter, FW version added, feedback on appconf and mcconf set
This commit is contained in:
parent
85f0073105
commit
5a5ccfb4c3
|
@ -39,6 +39,10 @@ void app_init(app_configuration *conf) {
|
|||
app_ppm_start();
|
||||
break;
|
||||
|
||||
case APP_ADC:
|
||||
app_adc_start();
|
||||
break;
|
||||
|
||||
case APP_UART:
|
||||
hw_stop_i2c();
|
||||
app_uartcomm_start();
|
||||
|
@ -50,6 +54,12 @@ void app_init(app_configuration *conf) {
|
|||
app_uartcomm_start();
|
||||
break;
|
||||
|
||||
case APP_ADC_UART:
|
||||
hw_stop_i2c();
|
||||
app_adc_start();
|
||||
app_uartcomm_start();
|
||||
break;
|
||||
|
||||
case APP_NUNCHUK:
|
||||
app_nunchuk_start();
|
||||
break;
|
||||
|
@ -87,6 +97,7 @@ const app_configuration* app_get_configuration(void) {
|
|||
void app_set_configuration(app_configuration *conf) {
|
||||
appconf = *conf;
|
||||
app_ppm_configure(&appconf.app_ppm_conf);
|
||||
app_adc_configure(&appconf.app_adc_conf);
|
||||
app_uartcomm_configure(appconf.app_uart_baudrate);
|
||||
app_nunchuk_configure(&appconf.app_chuk_conf);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,10 @@ void app_set_configuration(app_configuration *conf);
|
|||
// Standard apps
|
||||
void app_ppm_start(void);
|
||||
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_configure(uint32_t baudrate);
|
||||
void app_nunchuk_start(void);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -40,6 +40,7 @@
|
|||
#define OUTPUT_ITERATION_TIME_MS 1
|
||||
#define MAX_CURR_DIFFERENCE 5.0
|
||||
#define MAX_CAN_AGE 0.1
|
||||
#define RPM_FILTER_SAMPLES 8
|
||||
|
||||
// Threads
|
||||
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
|
||||
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) {
|
||||
static float pid_rpm = 0.0;
|
||||
|
||||
if (!was_pid) {
|
||||
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)) {
|
||||
|
|
|
@ -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
|
||||
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;
|
||||
|
||||
// Private functions
|
||||
void update(void *p);
|
||||
static void update(void *p);
|
||||
|
||||
void app_ppm_configure(ppm_config *conf) {
|
||||
config = *conf;
|
||||
|
@ -79,7 +79,7 @@ static void servodec_func(void) {
|
|||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
void update(void *p) {
|
||||
static void update(void *p) {
|
||||
chSysLockFromIsr();
|
||||
chVTSetI(&vt, MS2ST(2), update, p);
|
||||
chEvtSignalI(ppm_tp, (eventmask_t) 1);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
APPSRC = applications/app.c \
|
||||
applications/app_ppm.c \
|
||||
applications/app_adc.c \
|
||||
applications/app_sten.c \
|
||||
applications/app_gurgalof.c \
|
||||
applications/app_uartcomm.c \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
54
commands.c
54
commands.c
|
@ -115,6 +115,14 @@ void commands_process_packet(unsigned char *data, unsigned char len) {
|
|||
len--;
|
||||
|
||||
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:
|
||||
ind = 0;
|
||||
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);
|
||||
mcpwm_set_configuration(&mcconf);
|
||||
|
||||
ind = 0;
|
||||
send_buffer[ind++] = COMM_SET_MCCONF;
|
||||
commands_send_packet(send_buffer, ind);
|
||||
break;
|
||||
|
||||
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_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_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);
|
||||
app_set_configuration(&appconf);
|
||||
timeout_configure(appconf.timeout_msec, appconf.timeout_brake_current);
|
||||
|
||||
ind = 0;
|
||||
send_buffer[ind++] = COMM_SET_MCCONF;
|
||||
commands_send_packet(send_buffer, ind);
|
||||
break;
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
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:
|
||||
ind = 0;
|
||||
send_buffer[ind++] = COMM_GET_DECODED_CHUK;
|
||||
|
|
|
@ -152,19 +152,34 @@ void conf_general_read_app_configuration(app_configuration *conf) {
|
|||
|
||||
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.hyst = 0.15;
|
||||
conf->app_ppm_conf.pulse_start = 1.0;
|
||||
conf->app_ppm_conf.pulse_end = 2.0;
|
||||
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_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_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_chuk_conf.ctrl_type = CHUK_CTRL_TYPE_CURRENT;
|
||||
|
|
|
@ -25,6 +25,10 @@
|
|||
#ifndef CONF_GENERAL_H_
|
||||
#define CONF_GENERAL_H_
|
||||
|
||||
// Software version
|
||||
#define FW_VERSION_MAJOR 1
|
||||
#define FW_VERSION_MINOR 0
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
/*
|
||||
|
|
39
datatypes.h
39
datatypes.h
|
@ -145,8 +145,10 @@ typedef struct {
|
|||
typedef enum {
|
||||
APP_NONE = 0,
|
||||
APP_PPM,
|
||||
APP_ADC,
|
||||
APP_UART,
|
||||
APP_PPM_UART,
|
||||
APP_ADC_UART,
|
||||
APP_NUNCHUK,
|
||||
APP_NRF,
|
||||
APP_CUSTOM
|
||||
|
@ -179,6 +181,36 @@ typedef struct {
|
|||
float tc_max_diff;
|
||||
} 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
|
||||
typedef enum {
|
||||
CHUK_CTRL_TYPE_NONE = 0,
|
||||
|
@ -212,6 +244,9 @@ typedef struct {
|
|||
// PPM application settings
|
||||
ppm_config app_ppm_conf;
|
||||
|
||||
// ADC application settings
|
||||
adc_config app_adc_conf;
|
||||
|
||||
// UART application settings
|
||||
uint32_t app_uart_baudrate;
|
||||
|
||||
|
@ -221,7 +256,8 @@ typedef struct {
|
|||
|
||||
// Communication commands
|
||||
typedef enum {
|
||||
COMM_GET_VALUES = 0,
|
||||
COMM_FW_VERSION = 0,
|
||||
COMM_GET_VALUES,
|
||||
COMM_SET_DUTY,
|
||||
COMM_SET_CURRENT,
|
||||
COMM_SET_CURRENT_BRAKE,
|
||||
|
@ -242,6 +278,7 @@ typedef enum {
|
|||
COMM_REBOOT,
|
||||
COMM_ALIVE,
|
||||
COMM_GET_DECODED_PPM,
|
||||
COMM_GET_DECODED_ADC,
|
||||
COMM_GET_DECODED_CHUK,
|
||||
COMM_FORWARD_CAN
|
||||
} COMM_PACKET_ID;
|
||||
|
|
Loading…
Reference in New Issue