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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user