Adjust GPIO-pins and conf, Invert currentsensor, Buzzer

motorctl, currentsensor:
    - add config option for inverted current sensor
    - adjust loglevels

config:
    - Adjust gpio pins to actual wiring (not breakout board for testing)
    - Add min pulse durations for speedsensors (measurements with scope)
    - Adjust config to currently mounted encoders

control, buzzer:
    - adjust beeping
    - Add feature for optinal delay to buzzer class:
      have some pause after beeps instead of immediately
      continuing with next queued sequence
This commit is contained in:
jonny_l480
2024-02-26 22:57:22 +01:00
parent 5b198824f2
commit bf481ae8ea
10 changed files with 50 additions and 30 deletions

View File

@@ -46,12 +46,18 @@ buzzer_t::buzzer_t(gpio_num_t gpio_pin_f, uint16_t msGap_f){
//=========== beep ===========
//============================
//function to add a beep command to the queue
//use default/configured gap when no custom pause duration is given:
void buzzer_t::beep(uint8_t count, uint16_t msOn, uint16_t msOff){
beep(count, msOn, msOff, msGap);
}
void buzzer_t::beep(uint8_t count, uint16_t msOn, uint16_t msOff, uint16_t msDelayFinished){
//create entry struct with provided data
struct beepEntry entryInsert = {
count = count,
msOn = msOn,
msOff = msOff
count,
msOn,
msOff,
msDelayFinished
};
// Send a pointer to a struct AMessage object. Don't block if the
@@ -96,7 +102,7 @@ void buzzer_t::processQueue(){
vTaskDelay(entryRead.msOff / portTICK_PERIOD_MS);
}
//wait for minimum gap between beep events
vTaskDelay(msGap / portTICK_PERIOD_MS);
vTaskDelay(entryRead.msDelay / portTICK_PERIOD_MS);
}
}else{ //wait for queue to become available
vTaskDelay(50 / portTICK_PERIOD_MS);

View File

@@ -27,24 +27,27 @@ class buzzer_t {
//--- functions ---
void processQueue(); //has to be run once in a separate task, waits for and processes queued events
//add entry to queue processing beeps, last parameter is optional to delay the next entry
void beep(uint8_t count, uint16_t msOn, uint16_t msOff, uint16_t msDelayFinished);
void beep(uint8_t count, uint16_t msOn, uint16_t msOff);
//void clear(); (TODO - not implemented yet)
//void createTask(); (TODO - not implemented yet)
//--- variables ---
uint16_t msGap; //gap between beep entries (when multiple queued)
private:
//--- functions ---
void init();
//--- variables ---
uint16_t msGap; //gap between beep entries (when multiple queued)
gpio_num_t gpio_pin;
struct beepEntry {
uint8_t count;
uint16_t msOn;
uint16_t msOff;
uint16_t msDelay;
};
//queue for queueing up multiple events while one is still processing

View File

@@ -29,10 +29,11 @@ float getVoltage(adc1_channel_t adc, uint32_t samples){
//=============================
//======== constructor ========
//=============================
currentSensor::currentSensor (adc1_channel_t adcChannel_f, float ratedCurrent_f){
currentSensor::currentSensor (adc1_channel_t adcChannel_f, float ratedCurrent_f, bool isInverted_f){
//copy config
adcChannel = adcChannel_f;
ratedCurrent = ratedCurrent_f;
isInverted = isInverted_f;
//init adc
adc1_config_width(ADC_WIDTH_BIT_12); //max resolution 4096
adc1_config_channel_atten(adcChannel, ADC_ATTEN_DB_11); //max voltage
@@ -58,6 +59,9 @@ float currentSensor::read(void){
current = 0;
}
//invert calculated current if necessary
if (isInverted) current = -current;
ESP_LOGI(TAG, "read sensor adc=%d: voltage=%.3fV, centerVoltage=%.3fV => current=%.3fA", (int)adcChannel, voltage, centerVoltage, current);
return current;
}

View File

@@ -7,12 +7,13 @@
class currentSensor{
public:
currentSensor (adc1_channel_t adcChannel_f, float ratedCurrent);
currentSensor (adc1_channel_t adcChannel_f, float ratedCurrent, bool inverted = false);
void calibrateZeroAmpere(void); //set current voltage to voltage representing 0A
float read(void); //get current ampere
private:
adc1_channel_t adcChannel;
float ratedCurrent;
bool isInverted;
uint32_t measure;
float voltage;
float current;

View File

@@ -29,7 +29,7 @@ void task_motorctl( void * ptrControlledMotor ){
//=============================
//constructor, simultaniously initialize instance of motor driver 'motor' and current sensor 'cSensor' with provided config (see below lines after ':')
controlledMotor::controlledMotor(motorSetCommandFunc_t setCommandFunc, motorctl_config_t config_control, nvs_handle_t * nvsHandle_f):
cSensor(config_control.currentSensor_adc, config_control.currentSensor_ratedCurrent) {
cSensor(config_control.currentSensor_adc, config_control.currentSensor_ratedCurrent, config_control.currentInverted) {
//copy parameters for controlling the motor
config = config_control;
//pointer to update motot dury method
@@ -108,7 +108,7 @@ void controlledMotor::handle(){
//--- receive commands from queue ---
if( xQueueReceive( commandQueue, &commandReceive, timeoutWaitForCommand / portTICK_PERIOD_MS ) ) //wait time is always 0 except when at target duty already
{
ESP_LOGD(TAG, "[%s] Read command from queue: state=%s, duty=%.2f", config.name, motorstateStr[(int)commandReceive.state], commandReceive.duty);
ESP_LOGV(TAG, "[%s] Read command from queue: state=%s, duty=%.2f", config.name, motorstateStr[(int)commandReceive.state], commandReceive.duty);
state = commandReceive.state;
dutyTarget = commandReceive.duty;
receiveTimeout = false;
@@ -159,7 +159,7 @@ void controlledMotor::handle(){
//increase timeout once when duty is the same (once)
if (timeoutWaitForCommand == 0)
{ // TODO verify if state matches too?
ESP_LOGW(TAG, "[%s] already at target duty %.2f, slowing down...", config.name, dutyTarget);
ESP_LOGI(TAG, "[%s] already at target duty %.2f, slowing down...", config.name, dutyTarget);
timeoutWaitForCommand = TIMEOUT_QUEUE_WHEN_AT_TARGET; // wait in queue very long, for new command to arrive
}
vTaskDelay(20 / portTICK_PERIOD_MS); // add small additional delay overall, in case the same commands get spammed
@@ -168,7 +168,7 @@ void controlledMotor::handle(){
else if (timeoutWaitForCommand != 0)
{
timeoutWaitForCommand = 0; // dont wait additional time for new commands, handle fading fast
ESP_LOGW(TAG, "[%s] duty changed to %.2f, resuming at full speed", config.name, dutyTarget);
ESP_LOGI(TAG, "[%s] duty changed to %.2f, resuming at full speed", config.name, dutyTarget);
// adjust lastRun timestamp to not mess up fading, due to much time passed but with no actual duty change
timestampLastRunUs = esp_timer_get_time() - 20*1000; //subtract approx 1 cycle delay
}
@@ -197,7 +197,7 @@ void controlledMotor::handle(){
if (state == motorstate_t::BRAKE){
ESP_LOGD(TAG, "braking - skip fading");
motorSetCommand({motorstate_t::BRAKE, dutyTarget});
ESP_LOGI(TAG, "[%s] Set Motordriver: state=%s, duty=%.2f - Measurements: current=%.2f, speed=N/A", config.name, motorstateStr[(int)state], dutyNow, currentNow);
ESP_LOGD(TAG, "[%s] Set Motordriver: state=%s, duty=%.2f - Measurements: current=%.2f, speed=N/A", config.name, motorstateStr[(int)state], dutyNow, currentNow);
//dutyNow = 0;
return; //no need to run the fade algorithm
}
@@ -261,7 +261,7 @@ void controlledMotor::handle(){
ESP_LOGD(TAG, "waiting dead-time... dir change %s -> %s", motorstateStr[(int)statePrev], motorstateStr[(int)state]);
if (!deadTimeWaiting){ //log start
deadTimeWaiting = true;
ESP_LOGW(TAG, "starting dead-time... %s -> %s", motorstateStr[(int)statePrev], motorstateStr[(int)state]);
ESP_LOGI(TAG, "starting dead-time... %s -> %s", motorstateStr[(int)statePrev], motorstateStr[(int)state]);
}
//force IDLE state during wait
state = motorstate_t::IDLE;
@@ -269,7 +269,7 @@ void controlledMotor::handle(){
} else {
if (deadTimeWaiting){ //log end
deadTimeWaiting = false;
ESP_LOGW(TAG, "dead-time ended - continue with %s", motorstateStr[(int)state]);
ESP_LOGI(TAG, "dead-time ended - continue with %s", motorstateStr[(int)state]);
}
ESP_LOGV(TAG, "deadtime: no change below deadtime detected... dir=%s, duty=%.1f", motorstateStr[(int)state], dutyNow);
}

View File

@@ -48,6 +48,7 @@ typedef struct motorctl_config_t {
adc1_channel_t currentSensor_adc;
float currentSensor_ratedCurrent;
float currentMax;
bool currentInverted;
uint32_t deadTimeMs; //time motor stays in IDLE before direction change
} motorctl_config_t;