send, receive, apply motorCommands works (proof of concept); add timeout

- board_control successfully sends motor commands to board_motorctl
- board_motorctl receives and applies motor commands
note: control pcb currently switches to HTTP mode after startup for testing
with data from ui

- partially commented in code that has to be reworked
- control: send commands via uart instead of to motor objects
- board motorctl handled motor: add timeout when no target data
  received (e.g. control pcb offline / uart bugged)
- board motorctl uart: receive motorCommands_t struct and apply data to
  target state of handled motors
- types: fix issue with global motorstateStr variable
This commit is contained in:
jonny_jr9
2023-08-30 09:01:44 +02:00
parent 59a4f8c13f
commit 1e544613ee
13 changed files with 562 additions and 500 deletions

View File

@@ -103,6 +103,8 @@ void setLoglevels(void){
esp_log_level_set("wifi", ESP_LOG_INFO);
esp_log_level_set("http", ESP_LOG_INFO);
esp_log_level_set("automatedArmchair", ESP_LOG_DEBUG);
esp_log_level_set("uart_common", ESP_LOG_INFO);
esp_log_level_set("uart", ESP_LOG_INFO);
//esp_log_level_set("current-sensors", ESP_LOG_INFO);
}
#endif
@@ -146,11 +148,12 @@ extern "C" void app_main(void) {
#ifdef UART_TEST_ONLY
//-------------------------------------------
//--- create tasks for uart communication ---
//-------------------------------------------
uart_init();
xTaskCreate(task_uartReceive, "task_uartReceive", 4096, NULL, 10, NULL);
xTaskCreate(task_uartSend, "task_uartSend", 4096, NULL, 10, NULL);
#endif
//--- main loop ---

View File

@@ -1,4 +1,6 @@
#include "motorctl.hpp"
#include "esp_log.h"
#include "types.hpp"
//tag for logging
static const char * TAG = "motor-control";
@@ -80,6 +82,8 @@ void controlledMotor::handle(){
ESP_LOGD(TAG, "Read command from queue: state=%s, duty=%.2f", motorstateStr[(int)commandReceive.state], commandReceive.duty);
state = commandReceive.state;
dutyTarget = commandReceive.duty;
receiveTimeout = false;
timestamp_commandReceived = esp_log_timestamp();
//--- convert duty ---
//define target duty (-100 to 100) from provided duty and motorstate
@@ -102,6 +106,14 @@ void controlledMotor::handle(){
}
}
//--- timeout, no data ---
//turn motors off if no data received for long time (e.g. no uart data / control offline)
if ((esp_log_timestamp() - timestamp_commandReceived) > 3000 && !receiveTimeout){
receiveTimeout = true;
state = motorstate_t::IDLE;
dutyTarget = 0;
ESP_LOGE(TAG, "TIMEOUT, no target data received for more than 3s -> switch to IDLE");
}
//--- calculate increment ---
//calculate increment for fading UP with passed time since last run and configured fade time

View File

@@ -77,4 +77,7 @@ class controlledMotor {
struct motorCommand_t commandReceive = {};
struct motorCommand_t commandSend = {};
uint32_t timestamp_commandReceived = 0;
bool receiveTimeout = false;
};

View File

@@ -1,4 +1,6 @@
#include "uart.hpp"
#include "config.hpp"
#include "types.hpp"
//===== uart board MOTORCTL =====
static const char * TAG = "uart";
@@ -8,24 +10,39 @@ static const char * TAG = "uart";
//====== task_uartReceive ======
//==============================
void task_uartReceive(void *arg){
ESP_LOGW(TAG, "receive task started");
//receive data from uart, detect associated struct and copy/handle the data
//TODO use queue instead of check interval?
uartData_test_t testData;
uartData_test_t dataTest;
motorCommands_t dataMotorCommands;
uint8_t receivedData[1024-1];
while(1){
//note: check has to be more frequent than pause time between sending
vTaskDelay(200 / portTICK_PERIOD_MS);
int len = uart_read_bytes(UART_NUM_1, receivedData, sizeof(uartData_test_t), 20 / portTICK_PERIOD_MS);
vTaskDelay(50 / portTICK_PERIOD_MS);
//read bytes (max 1023) until 20ms pause is happening
int len = uart_read_bytes(UART_NUM_1, receivedData, sizeof(receivedData), 20 / portTICK_PERIOD_MS);
uart_flush_input(UART_NUM_1);
if (len < 1) continue;
switch (len){
case sizeof(uartData_test_t):
testData = serialData2Struct<uartData_test_t>(receivedData);
ESP_LOGW(TAG, "received uartDataStruct len=%d DATA: timestamp=%d, id=%d, value=%.1f", len, testData.timestamp, testData.id, testData.value);
dataTest = serialData2Struct<uartData_test_t>(receivedData);
ESP_LOGW(TAG, "received uartDataStruct len=%d DATA: timestamp=%d, id=%d, value=%.1f", len, dataTest.timestamp, dataTest.id, dataTest.value);
break;
case sizeof(motorCommands_t):
dataMotorCommands = serialData2Struct<motorCommands_t>(receivedData);
ESP_LOGI(TAG, "received motorCommands struct len=%d left=%.2f%% right=%.2f%%, update target...", len, dataMotorCommands.left.duty, dataMotorCommands.right.duty);
//update target motor state and duty
motorLeft.setTarget(dataMotorCommands.left.state,
dataMotorCommands.left.duty);
motorRight.setTarget(dataMotorCommands.right.state,
dataMotorCommands.right.duty);
break;
//TODO add other received structs here
default:
ESP_LOGW(TAG, "received data len=%d cant be associated with configures struct", len);
ESP_LOGE(TAG, "received data len=%d cant be associated with configures struct", len);
break;
}
}
@@ -38,6 +55,7 @@ void task_uartReceive(void *arg){
//=============================
//TODO copy send task from board_control/uart.cpp
void task_uartSend(void *arg){
ESP_LOGW(TAG, "send task started");
while (1) {
vTaskDelay(500 / portTICK_PERIOD_MS);
}