Not sure if I should have started a new topic or not, but this is still the same project 10 months later so here it stays for now.
Where am I at? I now believe I can use a Wemos D1 mini as he only processor to control the stepper motor, receive data from a GPS, read a proximity sensor, and talk to a mobile device via wifi.
I eventually tried the accelStepper library which seems to control a stepper in a non-blocking way and now I can run a stepper at 3.2kHz without any interference from the wifi code. All other methods I tried using timers and microsecond delays produced an audible and visible "hickup" of the stepper motor at around 1Hz which according to what I have read coincides with the wifi tasks the esp8266 carries out while in wifi mode.
So, I can forget about SPI communication with another device.
I still have a long way to go and many problems to overcome but I am if nothing else, persistent.
I have started a new sketch by combining an accelStepper example, "Constant Speed" with a WebSocket script I use for a wifi gate controller.
The result is the wifi part of the script works great but when I activate the stepper via the remote device, it registers the change in motorStatus and prints to the serial monitor that this has in fact occurred but will not start the stepper. Refer line 164-176.
If I move the "stepper.runSpeed()" down to within the loop the stepper runs as it should.
This has got me baffled because I simple removed the H-bridge motor control from the original script and added the stepper control.
If anyone can shed some light I would be most appreciative.
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <Hash.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#define USE_SERIAL Serial
static const char ssid[] = "stepper";
static const char password[] = "";
MDNSResponder mdns;
static void writeStepperDriver(bool);
ESP8266WiFiMulti WiFiMulti;
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
//for motor control
#include <AccelStepper.h>
AccelStepper stepper(1, 4, 5);
//AccelStepper (DRIVER);
static const char PROGMEM INDEX_HTML[] = R"rawliteral(
<!DOCTYPE html>
<html>
<head>
<meta name = "viewport" content = "width = device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=0">
<title>Front Gate Controller</title>
<style>
"body { background-color: #74A5EE; font-family: Arial, Helvetica, Sans-Serif; Color: #FF6F00; }"
"h1 {text-align:center; Color: #FF6F00;}"
p {text-align:center;}
</style>
<script>
var websock;
function start() {
websock = new WebSocket('ws://' + window.location.hostname + ':81/');
websock.onrun = function(evt) { console.log('websock run'); };
websock.onstop = function(evt) { console.log('websock stop'); };
websock.onerror = function(evt) { console.log(evt); };
websock.onmessage = function(evt) {
console.log(evt);
var e = document.getElementById('ledstatus');
if (evt.data === 'motorStart') {
e.style.color = 'red';
}
else if (evt.data === 'motorStop') {
e.style.color = 'green';
}
else {
console.log('unknown event');
}
};
}
function buttonclick(e) {
websock.send(e.id);
}
</script>
</head>
<body onload="javascript:start();">
<table cellpadding="10%" cellspacing="10%" align="center" bgcolor="#74A5EE" width="100%" style="text-align: center; ">
<tr>
<td><span align="centre"><h1>XXXXXXXXXXX</h1></span></td>
</tr>
<tr>
<td><span align="centre"><h1>Seeder Controller</h1></span></td>
</tr>
<tr>
<td><div class="centre" id="ledstatus"><h1>Motor</h1></div></td>
</tr>
<tr>
<td><div class="centre"><button id="motorStart" type="button" onclick="buttonclick(this);"><h1>-RUN-</h1></button></div></td>
</tr>
<tr>
<td><centre><button id="motorStop" type="button" onclick="buttonclick(this);"><h1>-STOP-</h1></button></centre></td>
</tr>
</table>
</body>
</html>
)rawliteral";
float setpointVariable = 20;//Fixed at 20rpm for now.
long steps = 200;//steps per revolution
long microStep = 16;//microstepping
bool motorStatus;// Current gate status
// Commands sent through Web Socket
const char RUN[] = "motorStart";
const char STOP[] = "motorStop";
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
USE_SERIAL.printf("webSocketEvent(%d, %d, ...)\r\n", num, type);
switch (type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[%u] Disconnected!\r\n", num);
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
// Send the current LED status
if (motorStatus) {
webSocket.sendTXT(num, RUN, strlen(RUN));
}
else {
webSocket.sendTXT(num, STOP, strlen(STOP));
}
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[%u] get Text: %s\r\n", num, payload);
if (strcmp(RUN, (const char *)payload) == 0) {
writeStepperDriver(true);
}
else if (strcmp(STOP, (const char *)payload) == 0) {
writeStepperDriver(false);
}
else {
USE_SERIAL.println("Unknown command");
}
// send data to all connected clients
webSocket.broadcastTXT(payload, length);
break;
case WStype_BIN:
USE_SERIAL.printf("[%u] get binary length: %u\r\n", num, length);
hexdump(payload, length);
// echo data back to browser
webSocket.sendBIN(num, payload, length);
break;
default:
USE_SERIAL.printf("Invalid WStype [%d]\r\n", type);
break;
}
}
void handleRoot()
{
server.send_P(200, "text/html", INDEX_HTML);
}
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET) ? "GET" : "POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
static void writeStepperDriver(bool startMotor)
{
motorStatus = startMotor;
if (startMotor) {
Serial.print(" motor should start ");Serial.println(motorStatus);
stepper.runSpeed();
}
else {
Serial.print(" motor should stop ");Serial.println(motorStatus);
stepper.stop();
}
}
void setup()
{
pinMode(4, OUTPUT);//step pin
pinMode(5, OUTPUT);//dir pin
writeStepperDriver(false);
stepper.setMaxSpeed(3200);
stepper.setSpeed(3200);//pulses per second
USE_SERIAL.begin(115200);
//Serial.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for (uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\r\n", t);
USE_SERIAL.flush();
delay(1000);
}
// WiFiMulti.addAP(ssid, password);
//
// while (WiFiMulti.run() != WL_CONNECTED) {
// Serial.print(".");
// delay(100);
// }
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
USE_SERIAL.print("AP IP address: ");
USE_SERIAL.println(myIP);
USE_SERIAL.println("");
USE_SERIAL.print("Connected to ");
USE_SERIAL.println(ssid);
USE_SERIAL.print("IP address: ");
USE_SERIAL.println(WiFi.localIP());
if (mdns.begin("espWebSock", WiFi.localIP())) {
USE_SERIAL.println("MDNS responder started");
mdns.addService("http", "tcp", 80);
mdns.addService("ws", "tcp", 81);
}
else {
USE_SERIAL.println("MDNS.begin failed");
}
USE_SERIAL.print("Connect to http://espWebSock.local or http://");
USE_SERIAL.println(WiFi.localIP());
server.on("/", handleRoot);
server.onNotFound(handleNotFound);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop()
{
webSocket.loop();
server.handleClient();
//stepper.runSpeed();
}