I'm trying to create a component for ESPHome.
I'm getting:
ERROR ID esp32_esp32internalgpiopin_6 is already registered
With this config:
...
external_components:
- source:
type: git
url: https://github.com/Defozo/esphome
ref: dev
components: [ tmc2130 ]
refresh: 3s
spi:
clk_pin: 18
mosi_pin: 23
miso_pin: 19
stepper:
- platform: tmc2130
id: my_stepper
step_pin: 21
dir_pin: 16
cs_pin: 26
r_sense: 0.11
microsteps: 16
rms_current: 1500
stepper.py
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import spi
from esphome.const import CONF_ID, CONF_CS_PIN
from esphome.core import coroutine
DEPENDENCIES = ['spi']
AUTO_LOAD = ['sensor']
tmc2130_ns = cg.esphome_ns.namespace('tmc2130')
TMC2130Component = tmc2130_ns.class_('TMC2130Component', cg.Component, spi.SPIDevice)
CONF_TOFF = "toff"
CONF_BLANK_TIME = "blank_time"
CONF_RMS_CURRENT = "rms_current"
CONF_MICROSTEPS = "microsteps"
CONF_TCOOLTHRS = "tcoolthrs"
CONF_THIGH = "thigh"
CONF_SEMIN = "semin"
CONF_SEMAX = "semax"
CONF_SEDN = "sedn"
CONF_SGT = "sgt"
CONF_R_SENSE = "r_sense"
CONF_STEP_PIN = "step_pin"
CONF_DIR_PIN = "dir_pin"
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(TMC2130Component),
cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_STEP_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_DIR_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_RMS_CURRENT): cv.positive_int,
cv.Required(CONF_R_SENSE): cv.float_,
cv.Optional(CONF_TOFF, default=4): cv.int_range(min=0, max=15),
cv.Optional(CONF_BLANK_TIME, default=24): cv.int_range(min=16, max=54),
cv.Optional(CONF_RMS_CURRENT, default=1500): cv.positive_int,
cv.Optional(CONF_MICROSTEPS, default=16): cv.int_range(min=0, max=256),
cv.Optional(CONF_TCOOLTHRS, default=0xFFFFF): cv.hex_int,
cv.Optional(CONF_THIGH, default=0): cv.hex_int,
cv.Optional(CONF_SEMIN, default=5): cv.int_range(min=0, max=15),
cv.Optional(CONF_SEMAX, default=2): cv.int_range(min=0, max=15),
cv.Optional(CONF_SEDN, default=0b01): cv.int_range(min=0, max=0b11),
cv.Optional(CONF_SGT, default=7): cv.int_range(min=-64, max=63),
}).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema())
async def to_code(config):
cs_pin = await cg.gpio_pin_expression(config[CONF_CS_PIN])
step_pin = await cg.gpio_pin_expression(config[CONF_STEP_PIN])
dir_pin = await cg.gpio_pin_expression(config[CONF_DIR_PIN])
r_sense = config[CONF_R_SENSE]
var = cg.new_Pvariable(config[CONF_ID], cs_pin, r_sense)
await cg.register_component(var, config)
await spi.register_spi_device(var, config)
cg.add_library('TMCStepper', '0.7.3')
cg.add(var.set_step_pin(step_pin))
cg.add(var.set_dir_pin(dir_pin))
cg.add(var.set_toff(config[CONF_TOFF]))
cg.add(var.set_blank_time(config[CONF_BLANK_TIME]))
cg.add(var.set_rms_current(config[CONF_RMS_CURRENT]))
cg.add(var.set_microsteps(config[CONF_MICROSTEPS]))
cg.add(var.set_tcoolthrs(config[CONF_TCOOLTHRS]))
cg.add(var.set_thigh(config[CONF_THIGH]))
cg.add(var.set_semin(config[CONF_SEMIN]))
cg.add(var.set_semax(config[CONF_SEMAX]))
cg.add(var.set_sedn(config[CONF_SEDN]))
cg.add(var.set_sgt(config[CONF_SGT]))
tmc2130.cpp
#include "tmc2130.h"
#include "esphome/core/log.h"
#include <TMCStepper.h>
namespace esphome {
namespace tmc2130 {
static const char *const TAG = "tmc2130";
TMC2130Component::TMC2130Component(uint8_t cs_pin, float r_sense)
: driver_(cs_pin, r_sense) {}
void TMC2130Component::setup() {
ESP_LOGD(TAG, "Setting up TMC2130...");
pinMode(EN_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW); // Enable driver by default
this->driver_.begin(); // Initiate SPI
// Configuration values are now set from the YAML file
this->driver_.toff(this->toff_);
this->driver_.blank_time(this->blank_time_);
this->driver_.rms_current(this->rms_current_); // Set motor RMS current
this->driver_.microsteps(this->microsteps_);
this->driver_.TCOOLTHRS(this->tcoolthrs_);
this->driver_.THIGH(this->thigh_);
this->driver_.semin(this->semin_);
this->driver_.semax(this->semax_);
this->driver_.sedn(this->sedn_);
this->driver_.sgt(this->sgt_);
// Setup timer
this->timer_ = timerBegin(0, 80, true); // Use the first timer
timerAttachInterrupt(this->timer_, &onTimer, true); // Attach the interrupt function
timerAlarmWrite(this->timer_, 1000, true); // Set the alarm
timerAlarmEnable(this->timer_); // Enable the alarm
}
void TMC2130Component::set_toff(uint8_t toff) { this->toff_ = toff; }
void TMC2130Component::set_blank_time(uint8_t blank_time) { this->blank_time_ = blank_time; }
void TMC2130Component::set_rms_current(uint16_t rms_current) { this->rms_current_ = rms_current; }
void TMC2130Component::set_microsteps(int microsteps) { this->microsteps_ = microsteps; }
void TMC2130Component::set_tcoolthrs(uint32_t tcoolthrs) { this->tcoolthrs_ = tcoolthrs; }
void TMC2130Component::set_thigh(uint32_t thigh) { this->thigh_ = thigh; }
void TMC2130Component::set_semin(uint8_t semin) { this->semin_ = semin; }
void TMC2130Component::set_semax(uint8_t semax) { this->semax_ = semax; }
void TMC2130Component::set_sedn(uint8_t sedn) { this->sedn_ = sedn; }
void TMC2130Component::set_sgt(int8_t sgt) { this->sgt_ = sgt; }
void TMC2130Component::set_r_sense(float r_sense) { this->driver_.rsense(r_sense); }
void TMC2130Component::loop() {
// This method can be used to update the component state in each loop iteration
// For example, handling dynamic speed adjustments or other runtime tasks
}
void TMC2130Component::dump_config() {
ESP_LOGCONFIG(TAG, "TMC2130 Component Configuration:");
ESP_LOGCONFIG(TAG, " - Toff: %u", this->toff_);
ESP_LOGCONFIG(TAG, " - Blank Time: %u", this->blank_time_);
ESP_LOGCONFIG(TAG, " - RMS Current: %u", this->rms_current_);
ESP_LOGCONFIG(TAG, " - Microsteps: %d", this->microsteps_);
ESP_LOGCONFIG(TAG, " - TCOOLTHRS: %u", this->tcoolthrs_);
ESP_LOGCONFIG(TAG, " - THIGH: %u", this->thigh_);
ESP_LOGCONFIG(TAG, " - SEMIN: %u", this->semin_);
ESP_LOGCONFIG(TAG, " - SEMAX: %u", this->semax_);
ESP_LOGCONFIG(TAG, " - SEDN: %u", this->sedn_);
ESP_LOGCONFIG(TAG, " - SGT: %d", this->sgt_);
}
void TMC2130Component::set_speed(int speed) {
// Adjust timer alarm based on speed
if (speed > MAX_SPEED && speed < MIN_SPEED) {
uint32_t timer_speed = map(speed, 0, 100, MIN_SPEED, MAX_SPEED); // Map speed to timer range
timerAlarmWrite(this->timer_, timer_speed, true);
}
}
void TMC2130Component::set_direction_forward(bool forward) {
motor_direction_ = forward;
digitalWrite(DIR_PIN, motor_direction_ ? HIGH : LOW); // Set direction
}
void TMC2130Component::enable_motor(bool enable) {
// Enable or disable motor by controlling EN_PIN
digitalWrite(EN_PIN, !enable); // LOW to enable, HIGH to disable
}
static void IRAM_ATTR onTimer() {
digitalWrite(STEP_PIN, !digitalRead(STEP_PIN)); // Toggle the step pin
}
} // namespace tmc2130
} // namespace esphome
tmc2130.h
#include "esphome/core/component.h"
#include "esphome/core/hal.h"
#include <TMCStepper.h>
namespace esphome {
namespace tmc2130 {
class TMC2130Component : public Component {
public:
void setup() override;
void dump_config() override;
void set_toff(uint8_t toff);
void set_blank_time(uint8_t blank_time);
void set_rms_current(uint16_t rms_current);
void set_microsteps(int microsteps);
void set_tcoolthrs(uint32_t tcoolthrs);
void set_thigh(uint32_t thigh);
void set_semin(uint8_t semin);
void set_semax(uint8_t semax);
void set_sedn(uint8_t sedn);
void set_sgt(int8_t sgt);
void set_direction_forward(bool forward);
void set_r_sense(float r_sense);
protected:
TMC2130Stepper driver_;
uint8_t toff_;
uint8_t blank_time_;
uint16_t rms_current_;
int microsteps_;
uint32_t tcoolthrs_;
uint32_t thigh_;
uint8_t semin_;
uint8_t semax_;
uint8_t sedn_;
int8_t sgt_;
bool motor_direction_{true};
float r_sense_;
};
} // namespace tmc2130
} // namespace esphome
I don't understand the error. Where am I defining this esp32_esp32internalgpiopin_6? Can someone help?