ADD: control via uart. Send two int16 (4 bytes) to usart 2 to control the motors with an arduino or a raspberry pi

This commit is contained in:
Niklas Fauth 2018-06-11 14:29:39 +02:00
parent 9332f59f82
commit b3fe48a832
6 changed files with 786 additions and 1005 deletions

View File

@ -14,12 +14,15 @@
// ################################################################################ // ################################################################################
#define DEBUG_SERIAL_USART2 // left sensor board cable, disable if ADC or PPM is used! #define DEBUG_SERIAL_USART3 // left sensor board cable, disable if ADC or PPM is used!
//#define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuck) is used! //#define DEBUG_SERIAL_USART3 // right sensor board cable, disable if I2C (nunchuck) is used!
#define DEBUG_BAUD 115200 // UART baud rate #define DEBUG_BAUD 115200 // UART baud rate
//#define DEBUG_SERIAL_SERVOTERM //#define DEBUG_SERIAL_SERVOTERM
#define DEBUG_SERIAL_ASCII // human readable output. i.e. "345;1337;0;0\n\r" #define DEBUG_SERIAL_ASCII // human readable output. i.e. "345;1337;0;0\n\r"
#define CONTROL_SERIAL_USART2
#define CONTROL_BAUD 9600
//#define DEBUG_I2C_LCD // standard 16x2 or larger text-lcd via i2c-converter on right sensor board cable //#define DEBUG_I2C_LCD // standard 16x2 or larger text-lcd via i2c-converter on right sensor board cable
#define TIMEOUT 5 // number of wrong / missing commands before emergency off #define TIMEOUT 5 // number of wrong / missing commands before emergency off
@ -27,7 +30,7 @@
// ################################################################################ // ################################################################################
// ###### CONTROL VIA RC REMOTE ###### // ###### CONTROL VIA RC REMOTE ######
// left sensor board cable. Channel 1: steering, Channel 2: speed. // left sensor board cable. Channel 1: steering, Channel 2: speed.
//#define CONTROL_PPM // use PPM-Sum as input. disable DEBUG_SERIAL_USART2! //#define CONTROL_PPM // use PPM-Sum as input. disable DEBUG_SERIAL_USART2!
//#define PPM_NUM_CHANNELS 6 // total number of PPM channels to receive, even if they are not used. //#define PPM_NUM_CHANNELS 6 // total number of PPM channels to receive, even if they are not used.
@ -41,7 +44,7 @@
// ###### CONTROL VIA NINTENDO NUNCHUCK ###### // ###### CONTROL VIA NINTENDO NUNCHUCK ######
// left sensor board cable. keep cable short, use shielded cable, use ferrits, stabalize voltage in nunchuck, use the right one of the 2 types of nunchucks, add i2c pullups. // left sensor board cable. keep cable short, use shielded cable, use ferrits, stabalize voltage in nunchuck, use the right one of the 2 types of nunchucks, add i2c pullups.
#define CONTROL_NUNCHUCK // use nunchuck as input. disable DEBUG_SERIAL_USART3! //#define CONTROL_NUNCHUCK // use nunchuck as input. disable DEBUG_SERIAL_USART3!
// ################################################################################ // ################################################################################

View File

@ -17,6 +17,12 @@ extern I2C_HandleTypeDef hi2c2;
DMA_HandleTypeDef hdma_i2c2_rx; DMA_HandleTypeDef hdma_i2c2_rx;
DMA_HandleTypeDef hdma_i2c2_tx; DMA_HandleTypeDef hdma_i2c2_tx;
typedef struct{
float motorR;
float motorL;
//uint32_t crc;
} Serialcommand;
#ifdef CONTROL_PPM #ifdef CONTROL_PPM
uint16_t ppm_captured_value[PPM_NUM_CHANNELS + 1] = {500, 500}; uint16_t ppm_captured_value[PPM_NUM_CHANNELS + 1] = {500, 500};
uint16_t ppm_captured_value_buffer[PPM_NUM_CHANNELS+1] = {500, 500}; uint16_t ppm_captured_value_buffer[PPM_NUM_CHANNELS+1] = {500, 500};
@ -24,8 +30,16 @@ uint32_t ppm_timeout = 0;
bool ppm_valid = true; bool ppm_valid = true;
volatile Serialcommand command;
#define IN_RANGE(x, low, up) (((x) >= (low)) && ((x) <= (up))) #define IN_RANGE(x, low, up) (((x) >= (low)) && ((x) <= (up)))
#ifdef CONTROL_SERIAL_USART2
void Telemetry_Init(){
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, 8);
}
#endif
void PPM_ISR_Callback() { void PPM_ISR_Callback() {
// Dummy loop with 16 bit count wrap around // Dummy loop with 16 bit count wrap around
uint16_t rc_delay = TIM2->CNT; uint16_t rc_delay = TIM2->CNT;

View File

@ -34,11 +34,21 @@ extern ADC_HandleTypeDef hadc2;
extern volatile adc_buf_t adc_buffer; extern volatile adc_buf_t adc_buffer;
//LCD_PCF8574_HandleTypeDef lcd; //LCD_PCF8574_HandleTypeDef lcd;
extern I2C_HandleTypeDef hi2c2; extern I2C_HandleTypeDef hi2c2;
extern UART_HandleTypeDef huart2;
int cmd1; // normalized input values. -1000 to 1000 int cmd1; // normalized input values. -1000 to 1000
int cmd2; int cmd2;
int cmd3; int cmd3;
typedef struct{
int16_t motorR;
int16_t motorL;
//uint32_t crc;
} Serialcommand;
volatile Serialcommand command;
uint8_t button1, button2; uint8_t button1, button2;
int steer; // global variable for steering. -1000 to 1000 int steer; // global variable for steering. -1000 to 1000
@ -122,6 +132,11 @@ int main(void) {
Nunchuck_Init(); Nunchuck_Init();
#endif #endif
#ifdef CONTROL_SERIAL_USART2
UART_Control_Init();
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, 4);
#endif
#ifdef DEBUG_I2C_LCD #ifdef DEBUG_I2C_LCD
I2C_Init(); I2C_Init();
HAL_Delay(50); HAL_Delay(50);
@ -148,7 +163,7 @@ int main(void) {
while(1) { while(1) {
HAL_Delay(5); HAL_Delay(5);
#ifdef CONTROL_NUNCHUCK #ifdef CONTROL_NUNCHUCK
Nunchuck_Read(); Nunchuck_Read();
cmd1 = CLAMP((nunchuck_data[0] - 127) * 8, -1000, 1000); // x - axis. Nunchuck joystick readings range 30 - 230 cmd1 = CLAMP((nunchuck_data[0] - 127) * 8, -1000, 1000); // x - axis. Nunchuck joystick readings range 30 - 230
@ -169,7 +184,7 @@ int main(void) {
// ADC values range: 0-4095, see ADC-calibration in config.h // ADC values range: 0-4095, see ADC-calibration in config.h
cmd1 = CLAMP(adc_buffer.l_tx2 - ADC1_MIN, 0, ADC1_MAX) / (ADC1_MAX / 1000.0f); // ADC1 cmd1 = CLAMP(adc_buffer.l_tx2 - ADC1_MIN, 0, ADC1_MAX) / (ADC1_MAX / 1000.0f); // ADC1
cmd2 = CLAMP(adc_buffer.l_rx2 - ADC2_MIN, 0, ADC2_MAX) / (ADC2_MAX / 1000.0f); // ADC2 cmd2 = CLAMP(adc_buffer.l_rx2 - ADC2_MIN, 0, ADC2_MAX) / (ADC2_MAX / 1000.0f); // ADC2
// use ADCs as button inputs: // use ADCs as button inputs:
button1 = (uint8_t)(adc_buffer.l_tx2 > 2000); // ADC1 button1 = (uint8_t)(adc_buffer.l_tx2 > 2000); // ADC1
button2 = (uint8_t)(adc_buffer.l_rx2 > 2000); // ADC2 button2 = (uint8_t)(adc_buffer.l_rx2 > 2000); // ADC2
@ -177,6 +192,11 @@ int main(void) {
timeout = 0; timeout = 0;
#endif #endif
#ifdef CONTROL_SERIAL_USART2
cmd1 = CLAMP((int16_t)command.motorR, -1000, 1000);
cmd2 = CLAMP((int16_t)command.motorL, -1000, 1000);
#endif
// ####### LOW-PASS FILTER ####### // ####### LOW-PASS FILTER #######
steer = steer * (1.0 - FILTER) + cmd1 * FILTER; steer = steer * (1.0 - FILTER) + cmd1 * FILTER;

View File

@ -43,8 +43,85 @@ TIM_HandleTypeDef htim_left;
ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2; ADC_HandleTypeDef hadc2;
I2C_HandleTypeDef hi2c2; I2C_HandleTypeDef hi2c2;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
volatile adc_buf_t adc_buffer; volatile adc_buf_t adc_buffer;
#ifdef CONTROL_SERIAL_USART2
void UART_Control_Init() {
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_USART2_CLK_ENABLE();
/* DMA1_Channel6_IRQn interrupt configuration */
//HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 6);
//HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 5, 6);
HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);
/* DMA1_Channel7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 5, 7);
HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
huart2.Instance = USART2;
huart2.Init.BaudRate = CONTROL_BAUD;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
// huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
__HAL_RCC_DMA1_CLK_ENABLE();
/* USER CODE BEGIN USART2_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
GPIO_InitStruct.Pull = GPIO_PULLUP; //GPIO_NOPULL;
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //GPIO_MODE_AF_PP;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral DMA init*/
hdma_usart2_rx.Instance = DMA1_Channel6;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR; //DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_rx);
__HAL_LINKDMA(&huart2,hdmarx,hdma_usart2_rx);
hdma_usart2_tx.Instance = DMA1_Channel7;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart2_tx);
__HAL_LINKDMA(&huart2,hdmatx,hdma_usart2_tx);
}
#endif
#ifdef DEBUG_SERIAL_USART3 #ifdef DEBUG_SERIAL_USART3
void UART_Init() { void UART_Init() {
__HAL_RCC_USART3_CLK_ENABLE(); __HAL_RCC_USART3_CLK_ENABLE();

View File

@ -40,6 +40,9 @@ extern DMA_HandleTypeDef hdma_i2c2_rx;
extern DMA_HandleTypeDef hdma_i2c2_tx; extern DMA_HandleTypeDef hdma_i2c2_tx;
extern I2C_HandleTypeDef hi2c2; extern I2C_HandleTypeDef hi2c2;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
/* USER CODE BEGIN 0 */ /* USER CODE BEGIN 0 */
/* USER CODE END 0 */ /* USER CODE END 0 */
@ -223,6 +226,33 @@ void EXTI3_IRQHandler(void)
} }
#endif #endif
#ifdef CONTROL_SERIAL_USART2
void DMA1_Channel6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
/* USER CODE END DMA1_Channel4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
/* USER CODE END DMA1_Channel4_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel5 global interrupt.
*/
void DMA1_Channel7_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
/* USER CODE END DMA1_Channel5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
/* USER CODE END DMA1_Channel5_IRQn 1 */
}
#endif
/******************************************************************************/ /******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers */ /* STM32F1xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */ /* Add here the Interrupt Handlers for the used peripherals. */

File diff suppressed because it is too large Load Diff