Hi,
i’m trying tu use a MKS DLC32 board to control peristaltic pumps (wich use stepper motor) and i have performance issue with the PollingComponent in esphome.
There is an esp32 wich is connected to an 75hc595 shift register, and the output of this shift register manage the stepper motor drivers (i use a4988).
I use a custom component with the PollingComponent class to control the drivers :
#include "esphome.h"
class DLC32HC595 : public PoollingComponent {
public:
// constructor
MyCustomSensor() : PollingComponent(1) {}
// HC595 input
// int latchPin = 17; // RCLK/Latch pin of 74HC595 is connected to Digital pin GPIO17
// int clockPin = 16; // SRCLK/Clock pin of 74HC595 is connected to Digital pin GPIO16
// int dataPin = 21; // SER/Data pin of 74HC595 is connected to Digital pin GPIO21
// HC595 output
int xyzenregidx = 0; // my_register index to control Enable for X,Y and Z
int xstepregidx = 1; // my_register index to control Step for X
int xdirregidx = 2; // my_register index to control direction for X
int zstepregidx = 3; // my_register index to control Step for Z
int zdirregidx = 4; // my_register index to control direction for Z
int ystepregidx = 5; // my_register index to control Step for Y
int ydirregidx = 6; // my_register index to control direction for Y
// idx 7 not used
byte my_register = B01010101; // Variable to hold the pattern of which Pins are currently turned on or off
void setup() override {
}
void update() override {
StepMotor();
}
void updateShiftRegister() {
id(spidev).enable();
id(spidev).write_byte(my_register);
id(spidev).disable();
}
void StepMotor() {
if ( Xrun->value() == true or Yrun->value() == true or Zrun->value() == true ) {
if ( bitRead(my_register, xyzenregidx) == 1 ) {
bitClear(my_register, xyzenregidx);
// ESP_LOGD("custom", "XYZ Enable register value is 0 (steppers are active with 0)");
}
}
else {
if ( bitRead(my_register, xyzenregidx) == 0 ) {
bitSet(my_register, xyzenregidx);
// ESP_LOGD("custom", "XYZ Enable register value is 1 (steppers are active with 0)");
}
}
if ( Xrun->value() ) {
bitToggle(my_register, xstepregidx);
}
if ( Yrun->value() ) {
bitToggle(my_register, ystepregidx);
}
if ( Zrun->value() ) {
bitToggle(my_register, zstepregidx);
}
updateShiftRegister();
}
};
And this is the Yaml :
esphome:
name: poolchemicaldispenser
friendly_name: PoolChemicalDispenser
includes:
- dlc32hc595spi.h
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
#logger:
# Enable Home Assistant API
api:
encryption:
key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
ota:
password: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
domain: .home
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Poolchemicaldispenser"
password: "xxxxxxxxxxxxxxxx"
captive_portal:
# Web Server: https://esphome.io/components/web_server.html
#web_server:
# local: true
# port: 80
# Global variables
globals:
- id: Xrun
type: bool
restore_value: no
initial_value: "false"
- id: Yrun
type: bool
restore_value: no
initial_value: "false"
- id: Zrun
type: bool
restore_value: no
initial_value: "false"
# Example configuration entry
switch:
- platform: template
name: "X motor"
id: X_switch
optimistic: true
turn_on_action:
- logger.log: "Setting X motor to run state"
- lambda: |-
id(Xrun) = true;
turn_off_action:
- logger.log: "Setting X motor to stop state"
- lambda: |-
id(Xrun) = false;
- platform: template
name: "Y motor"
id: Y_switch
optimistic: true
turn_on_action:
- logger.log: "Setting Y motor to run state"
- lambda: |-
id(Yrun) = true;
turn_off_action:
- logger.log: "Setting Y motor to stop state"
- lambda: |-
id(Yrun) = false;
- platform: template
name: "Z motor"
id: Z_switch
optimistic: true
turn_on_action:
- logger.log: "Setting Z motor to run state"
- lambda: |-
id(Zrun) = true;
turn_off_action:
- logger.log: "Setting Z motor to stop state"
- lambda: |-
id(Zrun) = false;
custom_component:
- lambda: |-
auto dlc32_board = new DLC32HC595();
return {dlc32_board};
components:
- id: dlc32_board_id
spi:
clk_pin: GPIO16
mosi_pin: GPIO21
interface: hardware
spi_device:
id: spidev
cs_pin: GPIO17
data_rate: 1MHz
mode: 3
bit_order: msb_first
With my logic analyser, i can see that the output of my shift register can’t be update less than 5ms despite the value i set in PollingComponent(1). When logger and web server is enable it’s worst.
did someone have any tips to run it quicker ?
i did a test without polling component, and with loop() instead of update() function, but it is worst (about 30ms).
thanks