Stepper Motor controlled via ESP and Homebridge
Posted:
Sun Feb 23, 2020 2:42 pm
by idna001
Hello,
I am new here, and it would be nice, if somenone can help me in my current Project.
I want to drive a stepper motor remote with an an ESP.
And I wnat to controll it via Homebridge over my raspi.
So first I am unsure if that works with the Hardware I have already:
An ESP8266, an DRV8825 stepper driver and a NEMA 17 stepper motor, a raspi with homebridge already installed (used for steering lights)
A software used in electric shutters or from a height adjustable desk should be similar to my project, or?
But I haven´t found anything so far...
Has anybody solved a similar task?
Or have some hints for my project?
Thanks in advance
idna
Re: Stepper Motor controlled via ESP and Homebridge
Posted:
Mon Feb 24, 2020 11:06 am
by Barnabybear
Hi, I use this to control roller blinds on my house windows. It’s not quite what you want but it might give you some ideas.
Code: Select all/*
* STILL UNDER DEVELOPMENT - mostly works 23/08/16.
* V1.0
*
* This sketch will drive a 28BYJ-48 stepper motor
* with ULN2003 to open & close a roller blind,
* or anything realy.
* The coils A,B,C & D are on GPIO's 12, 13, 14 & 15.
* with 4.7K pull down resistors.
* GPIO's 0 & 2 are used as manual control,
* LOW active with 10K pull ups.
* GPIO 2 toggles the blind open & closed,
* dependant on it's current state.
* GPIO 0 will enter inch mode, the blind
* can be inched to a known open postion
* postion with GPIO 2 & then stored as open.
* After GPIO 0 first press - inch closed,
* after GPIO 0 second press - inch open,
* after GPIO 0 third press - exit inch mode &
* store in EEPROM as open.
* Remote access is via the following commands:
* http://server_ip/gpio/0 will open the blinds,
* http://server_ip/gpio/1 will close the blinds.
*
* 'open_length' sets the number of steps required
* to open or close the blind.
*/
#include <ESP8266WiFi.h>
#include <EEPROM.h>
const char* ssid = "<access point name>";
const char* password = "<accesspoint password";
int coilA = 12;
int coilB = 13;
int coilC = 14;
int coilD = 15;
int manual_operate = 2;
int manual_inch = 0;
int step_number = 1;
int step_delay = 2000;
long open_length = 35000;
int flag_current = 0;
byte flag_last = 1;
int flag_adjust = 0;
// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// set outputs.
pinMode(coilA, OUTPUT);
pinMode(coilB, OUTPUT);
pinMode(coilC, OUTPUT);
pinMode(coilD, OUTPUT);
pinMode(manual_operate, INPUT);
pinMode(manual_inch, INPUT);
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
//WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.println(WiFi.localIP());
EEPROM.begin(1);
Serial.println("EEPROM value is ");
Serial.println(EEPROM.read(0));
Serial.println("flag_last is ");
Serial.println(flag_last);
}
void loop() {
// Check if a client has connected or
// manual opperation required.
// Check for remote request.
WiFiClient client = server.available();
if (!client) { // if no remote request check manual buttons.
delay(100);
// Check for GPIO 0 low - enter inch mode.
if (!digitalRead(manual_inch)) { // if GPIO 0 low.
manual_adjust(); // jump to void manual_adjust.
}
// Check for GPIO 2 low reverse blind postion.
// if open, close if closed, open.
if (!digitalRead(manual_operate)) { // if GPIO 2 low.
flag_last = EEPROM.read(0);
switch (flag_last) { // select dependant on blind currently open or closed.
case 1: // blind currently open.
close(); // jump to void close().
break;
case 2: // blind currently closed.
open(); // jump to void open().
break;
}
}
return;
}
// If remote request.
// Read the first line of the request.
String req = client.readStringUntil('\r');
Serial.println(req);
client.flush();
// Match the request
int val;
if (req.indexOf("/blind/open") != -1)
flag_current = 1; // set flag to open blind.
else if (req.indexOf("/blind/close") != -1)
flag_current = 2; // set flag to close blind.
else {
Serial.println("invalid request");
client.print("HTTP/1.1 404\r\n");
client.stop();
return;
}
client.flush();
// Prepare the response
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n";
switch (flag_current) { // select dependant on request.
case 1:
s += "The blind is open";
break;
case 2:
s += "The blind is closed";
break;
}
s += "</html>\n";
// Send the response to the client
client.print(s);
delay(100);
Serial.println("Client disonnected");
switch (flag_current) { // select dependant on request.
case 1:
flag_last = EEPROM.read(0);
open(); // jump to void open().
break;
case 2:
flag_last = EEPROM.read(0);
close(); // jump to void close().
break;
}
}
//************ Manual adjust (inch mode)************
void manual_adjust() {
Serial.println("Enter inch mode");
flag_adjust = 2; // set flag to close.
delay(1000);
yield();
while (flag_adjust > 0) { // adjust flag set to open or close (1 or 2).
if (!digitalRead(manual_inch)) { // GPIO 0 low.
flag_adjust = flag_adjust - 1; // reduce flag by 1 (step through options).
if (flag_adjust < 0) { // check flag for negative value.
flag_adjust = 0; // set flag to 0 if negative.
}
delay(1000);
}
switch (flag_adjust) { // inch open or closed dependant on adjust flag (set above).
case 1: // open
while (!digitalRead(manual_operate)) { // if GPIO 2 low.
for (step_number = 1; step_number < 9; step_number++) {
output_write(); // move stepper one set of moves in open direction.
delayMicroseconds(step_delay);
yield();
}
}
case 2: // close
while (!digitalRead(manual_operate)) { // if GPIO 2 low.
for (step_number = 8; step_number > 0; step_number--) {
output_write(); // move stepper one set of moves in closed direction.
delayMicroseconds(step_delay);
yield();
}
}
yield();
}
}
// adjust flag is 0, turn off outputs & drop out of loop.
Serial.println("Exit inch mode, outputs off");
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
EEPROM.write(0, 1); // blind in open postion
EEPROM.commit();
Serial.println("EEPROM value is ");
Serial.println(EEPROM.read(0));
Serial.println("flag_last is ");
Serial.println(flag_last);
}
//************ Open Loop ************
void open() {
if (flag_last == 0 || flag_last == 2) { // check for power up or blind closed.
Serial.println("opening blind");
for (long dist_loop = 0; dist_loop < open_length; dist_loop++) { // number of steps to open blind.
++step_number;
if (step_number > 8) step_number = 1;
output_write(); // jump to void output write().
delayMicroseconds(step_delay);
yield();
}
// final write to turn all outputs off.
Serial.println("move complete, outputs off");
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
flag_current = 0; // set current move flag to 0 = none.
EEPROM.write(0, 1); // set current / last postion flag to 1 = open.
EEPROM.commit();
}
}
//************ Close Loop ************
void close() {
if (flag_last == 0 || flag_last == 1) { // check for power up or blind open.
Serial.println("closing blind");
for (long dist_loop = 0; dist_loop < open_length; dist_loop++) { // number of steps to close blind.
--step_number;
if (step_number < 1) step_number = 8;
output_write(); // jump to void output write().
delayMicroseconds(step_delay);
yield();
}
// final write to turn all outputs off.
Serial.println("move complete, outputs off");
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
flag_current = 0; // set current move flag to 0 = none.
EEPROM.write(0, 2); // set current / last postion flag to 2 = closed.
EEPROM.commit();
}
}
//************ Output write ************
void output_write() {
switch (step_number) {
case 1:
digitalWrite(coilA, HIGH);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
break;
case 2:
digitalWrite(coilA, HIGH);
digitalWrite(coilB, HIGH);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
break;
case 3:
digitalWrite(coilA, LOW);
digitalWrite(coilB, HIGH);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
break;
case 4:
digitalWrite(coilA, LOW);
digitalWrite(coilB, HIGH);
digitalWrite(coilC, HIGH);
digitalWrite(coilD, LOW);
break;
case 5:
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, HIGH);
digitalWrite(coilD, LOW);
break;
case 6:
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, HIGH);
digitalWrite(coilD, HIGH);
break;
case 7:
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, HIGH);
break;
case 8:
digitalWrite(coilA, HIGH);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, HIGH);
break;
default:
digitalWrite(coilA, LOW);
digitalWrite(coilB, LOW);
digitalWrite(coilC, LOW);
digitalWrite(coilD, LOW);
break;
}
}
Re: Stepper Motor controlled via ESP and Homebridge
Posted:
Mon Feb 24, 2020 12:36 pm
by idna001
Thanks for the Sketch!
It seems to be similar to what I have in mind....
I have a few Questions about that:
Do you have wiring diagram?
How do you control it? Just by switches and not from Homebridge?
Thanks for help
idna