Hi everyone,
I'm very new so I hope you bear* with me :). I'm working on a project I've found on YouTube (link: https://youtu.be/1O_1gUFumQM?si=rvuEjOq1rsucmCTi) but currently I'm stuck on it. To start what I want to do:
With Home Assistant send command to ESP32 Wroom to close or open blinds via mqtt protocol. Components I'm using:
- ESP32 Wroom
- DRV8825 stepper motor driver
- 28BYJ-48 5V stepper motor (modified)
- 5V power supply
- 12V power supply
The ground of the power supply's is connected. The 28BYJ-48 is modified so it's now a bipolar stepper motor (by cutting the middle trace and not using the red wire). I can send a command to the ESP32 and the motor start vibrating and I can visually see its trying to go in one direction but its not moving otherwise.
What I have tried to fix it:
- Changing the coils (A1<--> A2, B1<-->B2).
- Changing the speed and adding microstepping in the code.
- Trying different motor and a different driver.
- Confirmed the motor is indeed running bipolar by measuring the resistance in the coils (can provide if needed).
Don't know if it is relevant but when I take out the 12V power supply and the motor is still running, when power almost runs out it suddenly moves as expected right before it runs out.
I have the following code for the ESP32. Its a bit different from the code in the tutorial because of the difference in components:
#include <Ticker.h> //https://github.com/marcelloromani/Arduino-SimpleTimer/tree/master/SimpleTimer
#include <WiFi.h> //if you get an error here you need to install the ESP8266 board manager
#include <ESPmDNS.h> //if you get an error here you need to install the ESP8266 board manager
#include <PubSubClient.h> //https://github.com/knolleary/pubsubclient
#include <ArduinoOTA.h> //https://github.com/esp8266/Arduino/tree/master/libraries/ArduinoOTA
#include <AH_EasyDriver.h> //http://www.alhin.de/arduino/downloads/AH_EasyDriver_20120512.zip
/***************** START USER CONFIG SECTION *********************************/
/***************** START USER CONFIG SECTION *********************************/
/***************** START USER CONFIG SECTION *********************************/
/***************** START USER CONFIG SECTION *********************************/
#define USER_SSID "Routers"
#define USER_PASSWORD ",Password>"
#define USER_MQTT_SERVER "<IP_Adress>"
#define USER_MQTT_PORT 1883
#define USER_MQTT_USERNAME "<mqttuser>"
#define USER_MQTT_PASSWORD "<mqttpassword>"
#define USER_MQTT_CLIENT_NAME "BlindsMCU" // Used to define MQTT topics, MQTT Client ID, and ArduinoOTA
#define STEPPER_SPEED 35 //Defines the speed in RPM for your stepper motor
#define STEPPER_STEPS_PER_REV 1028 //Defines the number of pulses that is required for the stepper to rotate 360 degrees
#define STEPPER_MICROSTEPPING 0 //Defines microstepping 0 = no microstepping, 1 = 1/2 stepping, 2 = 1/4 stepping
#define DRIVER_INVERTED_SLEEP 1 //Defines sleep while pin high. If your motor will not rotate freely when on boot, comment this line out.
#define STEPS_TO_CLOSE 12 //Defines the number of steps needed to open or close fully
#define STEPPER_DIR_PIN 12 //D6
#define STEPPER_STEP_PIN 13 //D7
#define STEPPER_SLEEP_PIN 14 //D5
#define STEPPER_MICROSTEP_1_PIN 27 //14
#define STEPPER_MICROSTEP_2_PIN 26 //12
/***************** END USER CONFIG SECTION *********************************/
/***************** END USER CONFIG SECTION *********************************/
/***************** END USER CONFIG SECTION *********************************/
/***************** END USER CONFIG SECTION *********************************/
/***************** END USER CONFIG SECTION *********************************/
WiFiClient espClient;
PubSubClient client(espClient);
Ticker stepperTicker;
Ticker checkinTicker;
AH_EasyDriver shadeStepper(STEPPER_STEPS_PER_REV, STEPPER_DIR_PIN ,STEPPER_STEP_PIN,STEPPER_MICROSTEP_1_PIN,STEPPER_MICROSTEP_2_PIN,STEPPER_SLEEP_PIN);
//Global Variables
bool boot = true;
int currentPosition = 0;
int newPosition = 0;
char positionPublish[50];
bool moving = false;
char charPayload[50];
const char* ssid = USER_SSID ;
const char* password = USER_PASSWORD ;
const char* mqtt_server = USER_MQTT_SERVER ;
const int mqtt_port = USER_MQTT_PORT ;
const char *mqtt_user = USER_MQTT_USERNAME ;
const char *mqtt_pass = USER_MQTT_PASSWORD ;
const char *mqtt_client_name = USER_MQTT_CLIENT_NAME ;
//Functions
void setup_wifi() {
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect()
{
int retries = 0;
while (!client.connected()) {
if(retries < 150)
{
Serial.print("Attempting MQTT connection...");
if (client.connect(mqtt_client_name, mqtt_user, mqtt_pass))
{
Serial.println("connected");
if(boot == false)
{
client.publish(USER_MQTT_CLIENT_NAME"/checkIn","Reconnected");
}
if(boot == true)
{
client.publish(USER_MQTT_CLIENT_NAME"/checkIn","Rebooted");
}
// ... and resubscribe
client.subscribe(USER_MQTT_CLIENT_NAME"/blindsCommand");
client.subscribe(USER_MQTT_CLIENT_NAME"/positionCommand");
}
else
{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
retries++;
// Wait 5 seconds before retrying
delay(5000);
}
}
if(retries > 149)
{
ESP.restart();
}
}
}
void callback(char* topic, byte* payload, unsigned int length)
{
Serial.print("Message arrived [");
String newTopic = topic;
Serial.print(topic);
Serial.print("] ");
payload[length] = '\0';
String newPayload = String((char *)payload);
int intPayload = newPayload.toInt();
Serial.println(newPayload);
Serial.println();
newPayload.toCharArray(charPayload, newPayload.length() + 1);
if (newTopic == USER_MQTT_CLIENT_NAME"/blindsCommand")
{
if (newPayload == "OPEN")
{
client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", "0", true);
}
else if (newPayload == "CLOSE")
{
int stepsToClose = STEPS_TO_CLOSE;
String temp_str = String(stepsToClose);
temp_str.toCharArray(charPayload, temp_str.length() + 1);
client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", charPayload, true);
}
else if (newPayload == "STOP")
{
String temp_str = String(currentPosition);
temp_str.toCharArray(positionPublish, temp_str.length() + 1);
client.publish(USER_MQTT_CLIENT_NAME"/positionCommand", positionPublish, true);
}
}
if (newTopic == USER_MQTT_CLIENT_NAME"/positionCommand")
{
if(boot == true)
{
newPosition = intPayload;
currentPosition = intPayload;
boot = false;
}
if(boot == false)
{
newPosition = intPayload;
}
}
}
void processStepper()
{
if (newPosition > currentPosition)
{
#if DRIVER_INVERTED_SLEEP == 1
shadeStepper.sleepON();
#endif
#if DRIVER_INVERTED_SLEEP == 0
shadeStepper.sleepOFF();
#endif
shadeStepper.move(80, FORWARD);
currentPosition++;
moving = true;
}
if (newPosition < currentPosition)
{
#if DRIVER_INVERTED_SLEEP == 1
shadeStepper.sleepON();
#endif
#if DRIVER_INVERTED_SLEEP == 0
shadeStepper.sleepOFF();
#endif
shadeStepper.move(80, BACKWARD);
currentPosition--;
moving = true;
}
if (newPosition == currentPosition && moving == true)
{
#if DRIVER_INVERTED_SLEEP == 1
shadeStepper.sleepOFF();
#endif
#if DRIVER_INVERTED_SLEEP == 0
shadeStepper.sleepON();
#endif
String temp_str = String(currentPosition);
temp_str.toCharArray(positionPublish, temp_str.length() + 1);
client.publish(USER_MQTT_CLIENT_NAME"/positionState", positionPublish);
moving = false;
}
Serial.println(currentPosition);
Serial.println(newPosition);
}
void checkIn()
{
client.publish(USER_MQTT_CLIENT_NAME"/checkIn","OK");
}
//Run once setup
void setup() {
Serial.begin(115200);
shadeStepper.setMicrostepping(STEPPER_MICROSTEPPING); // 0 -> Full Step
shadeStepper.setSpeedRPM(STEPPER_SPEED); // set speed in RPM, rotations per minute
#if DRIVER_INVERTED_SLEEP == 1
shadeStepper.sleepOFF();
#endif
#if DRIVER_INVERTED_SLEEP == 0
shadeStepper.sleepON();
#endif
WiFi.mode(WIFI_STA);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
ArduinoOTA.setHostname(USER_MQTT_CLIENT_NAME);
ArduinoOTA.begin();
delay(10);
stepperTicker.attach_ms(((1 << STEPPER_MICROSTEPPING)*5800)/STEPPER_SPEED, processStepper);
checkinTicker.attach(90, checkIn); // 90 seconds
}
void loop()
{
if (!client.connected())
{
reconnect();
}
client.loop();
ArduinoOTA.handle();
}
Thank you all in advance for your help. If I need to provide other data or if I'm listing this wrong please let me know I will change it ASAP.
Greetings.

