-
-
Save devyte/ed3fa167d6a3b4296d2e074bdc865074 to your computer and use it in GitHub Desktop.
#include "stepperapi.h" | |
#include "Arduino.h" | |
#include "core_esp8266_waveform.h" | |
static bool | |
stepperStartCore(int pinPulse, uint32_t analogFreq) | |
{ | |
if (analogFreq == 0) | |
return stopWaveform(pinPulse); //for frequency = 0, stop the pulse train | |
if (analogFreq > 40000) | |
analogFreq = 40000; //clamp to 40KHz at the high end | |
uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq; | |
constexpr uint32_t analogScale = 1023; //set up in setup(), 255 default if not set up | |
uint32_t high = analogPeriod / (2 * analogScale); | |
uint32_t low = analogPeriod - high; | |
pinMode(pinPulse, OUTPUT); | |
if ((low == 0) || (high == 0)) | |
return false; //error | |
return startWaveformClockCycles(pinPulse, high, low, 0); //return whether start succeeded | |
} | |
bool | |
stepperStart(int pinEn, int pinPulse, uint32_t analogFreq) | |
{ | |
//enable stepper | |
pinMode(pinEn, OUTPUT); | |
digitalWrite(pinEn, HIGH); | |
return stepperStartCore(pinPulse, analogFreq); | |
} | |
bool | |
stepperStop(int pinEn, int pinPulse) | |
{ | |
if(!stopWaveform(pinPulse)) | |
return false; | |
//Disable stepper | |
pinMode(pinEn, OUTPUT); | |
digitalWrite(pinEn, LOW); | |
return true; | |
} | |
bool | |
stepperUpdateSpeed(int pinPulse, uint32_t newAnalogFreq) | |
{ | |
//update directly, no need to stop (see analogWrite() function body) | |
return stepperStartCore(pinPulse, newAnalogFreq); | |
} | |
#ifndef __STEPPERAPI_H__ | |
#define __STEPPERAPI_H__ | |
#include <cstdint> | |
bool | |
stepperStart(int pinEn, int pinPulse, uint32_t analogFreq); | |
bool | |
stepperStop(int pinEn, int pinPulse); | |
bool | |
stepperUpdateSpeed(int pinPulse, uint32_t newAnalogFreq); | |
#endif |
#ifndef __STEPPERCLASS_H__ | |
#define __STEPPERCLASS_H__ | |
#include "stepperapi.h" | |
class Stepper | |
{ | |
private: | |
int pinEn; | |
int pinPulse; | |
bool running; | |
public: | |
Stepper(int pinEn, int pinPulse) | |
: pinEn(pinEn), | |
pinPulse(pinPulse), | |
running(false) | |
{} | |
//disables the pins | |
~Stepper() | |
{ | |
if(running) | |
{ | |
stepperStop(pinEn, pinPulse); | |
releasePins(); | |
} | |
} | |
//Enables the pins for OUTPUT | |
bool start(uint32_t speed) | |
{ | |
if(stepperStart(pinEn, pinPulse, speed)) | |
{ | |
running = true; | |
return true; | |
} | |
return false; | |
} | |
//disables the stepper (En=false) | |
//Does not release the pins, i.e.: they remain in OUTPUT mode | |
bool stop() | |
{ | |
if(stepperStop(pinEn, pinPulse) | |
{ | |
running = false; | |
return true; | |
} | |
return false; | |
} | |
//speed=0 stops the pulse without doing EN=false | |
bool updateSpeed(uint32_t speed) | |
{ | |
return stepperUpdateSpeed(pinPulse, speed); | |
} | |
//Disables the pins, i.e. they go back to INPUT mode and therefore float | |
void releasePins() | |
{ | |
pinMode(pinEn, INPUT); | |
pinMode(pinPulse, INPUT); | |
} | |
bool isRunning() | |
{ | |
return running; | |
} | |
}; | |
#endif |
#include "Arduino.h" | |
#include "stepperclass.h" | |
namespace | |
{ | |
constexpr int pinEnS1 = 5; | |
constexpr int pinPulseS1 = 4; | |
constexpr int pinEnS2 = 0; | |
constexpr int pinPulseS2 = 2; | |
constexpr int pinEnS3 = 16; | |
constexpr int pinPulseS3 = 13; | |
constexpr int pinAlarm = 12; | |
constexpr int pinLinkageSensor = 14; | |
constexpr int pinRelay = 15; | |
Stepper stepper1(pinEnS1, pinPulseS1); | |
Stepper stepper2(pinEnS2, pinPulseS2); | |
Stepper stepper3(pinEnS3, pinPulseS3); | |
bool startFlag1 = false; | |
bool startFlag2 = false; | |
bool startFlag3 = false; | |
bool stopFlag1 = false; | |
bool stopFlag2 = false; | |
bool stopFlag3 = false; | |
bool updateFlag1 = false; | |
bool updateFlag2 = false; | |
bool updateFlag3 = false; | |
//The unit of these speeds is Hz, i.e.: pulses/second | |
uint32 speed1; | |
uint32 speed2; | |
uint32 speed3; | |
} | |
void | |
handleStepper(Stepper &stepper, bool &startFlag, bool &stopFlag, bool &updateFlag, uint32_t speed) | |
{ | |
if(startFlag) //from ui | |
{ | |
if(!stepper.start(speed)) | |
{ | |
//error starting | |
} | |
startFlag = false; | |
} | |
if(stopFlag) //from ui | |
{ | |
if(!stepper.stop()) | |
{ | |
//error stopping | |
} | |
stopFlag = false; | |
} | |
if(updateFlag) //from ui | |
{ | |
if(!stepper.updateSpeed(speed)) | |
{ | |
//error updating speed | |
} | |
updateFlag = false; | |
} | |
} | |
void | |
setup() | |
{ | |
//set up wifi, webserver, etc | |
} | |
void | |
loop() | |
{ | |
//startFlag, stopFlag, speed would be initially set from a webserver handler | |
//updateFlag and speed would then be set whenever a speed update is available, | |
//e.g.: gps gives new position => calculate speed set point in Hz (speedX = setPointVariableX / 10) => updateFlag = true | |
handleStepper(stepper1, startFlag1, stopFlag1, updateFlag1, speed1); | |
handleStepper(stepper2, startFlag2, stopFlag2, updateFlag2, speed2); | |
handleStepper(stepper3, startFlag3, stopFlag3, updateFlag3, speed3); | |
} |
{
if(startFlag) //from ui
{
uint32_t speed = setPointVariable / 10; //from ui
stepperStart(pinEn, pinPulse, speed);
startFlag = false;
}
if(stopFlag) //from ui
{
stepperStop(pinEn, linPulse);
stopFlag = false;
}
if(updateFlag) //from ui
{
uint32_t speed = setPointVariable / 10; //from ui
stepperUpdateSpeed(pinPulse, speed);
updateFlag = false;
}
}
Looks easy enough so far.
Where does "startWaveformClockCycles" come from?
That's a core function that already exists
Ok, fleshed it out a bit now. I think you should be able to integrate with your current code. If you run into trouble, let me know.
BTW, the unit of speed above is Hz, you may need to convert from rpm or whatever you're using.
Pending: solve the low end speed < 100Hz
For speed below 100Hz, can we count waves and only let every 10th wave through?
That's called a frequency divider, i.e.: you divide by some integer. Not with the current code. It might be one way to do it, but it has certain complexities
code is updated
Latest errors.
Arduino: 1.8.12 (Linux), Board: "LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:3MB OTA:~512KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:2:32: error: 'uint32_t' has not been declared
stepperStartCore(int pinPulse, uint32_t analogFreq)
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStartCore(int, int)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:11:3: error: 'uint32_t' was not declared in this scope
uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq;
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:11:12: error: expected ';' before 'analogPeriod'
uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq;
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:13:12: error: expected ';' before 'analogScale'
uint32_t analogScale = 1023; //set up in setup(), 255 default if not set up
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:15:12: error: expected ';' before 'high'
uint32_t high = (analogPeriod / 2) / analogScale;
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:16:12: error: expected ';' before 'low'
uint32_t low = analogPeriod - high;
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:17:21: error: 'OUTPUT' was not declared in this scope
pinMode(pinPulse, OUTPUT);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:17:27: error: 'pinMode' was not declared in this scope
pinMode(pinPulse, OUTPUT);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:18:7: error: 'low' was not declared in this scope
if (low == 0) {
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:21:7: error: 'high' was not declared in this scope
if (high == 0) {
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:24:42: error: 'high' was not declared in this scope
if (startWaveformClockCycles(pinPulse, high, low, 0)) {
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:24:48: error: 'low' was not declared in this scope
if (startWaveformClockCycles(pinPulse, high, low, 0)) {
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:24:54: error: 'startWaveformClockCycles' was not declared in this scope
if (startWaveformClockCycles(pinPulse, high, low, 0)) {
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: At global scope:
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:30:39: error: 'uint32_t' has not been declared
stepperStart(int pinEn, int pinPulse, uint32_t analogFreq)
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStart(int, int, int)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:33:18: error: 'OUTPUT' was not declared in this scope
pinMode(pinEn, OUTPUT);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:33:24: error: 'pinMode' was not declared in this scope
pinMode(pinEn, OUTPUT);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:34:23: error: 'HIGH' was not declared in this scope
digitalWrite(pinEn, HIGH);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:34:27: error: 'digitalWrite' was not declared in this scope
digitalWrite(pinEn, HIGH);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:36:41: error: 'stepperStartPulse' was not declared in this scope
stepperStartPulse(pinPulse, analogFreq);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStop(int, int)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:42:24: error: 'stopWaveForm' was not declared in this scope
stopWaveForm(pinPulse);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:45:18: error: 'OUTPUT' was not declared in this scope
pinMode(pinEn, OUTPUT);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:45:24: error: 'pinMode' was not declared in this scope
pinMode(pinEn, OUTPUT);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:46:23: error: 'LOW' was not declared in this scope
digitalWrite(pinEn, LOW);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:46:26: error: 'digitalWrite' was not declared in this scope
digitalWrite(pinEn, LOW);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: At global scope:
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:50:34: error: 'uint32_t' has not been declared
stepperUpdateSpeed(int pinPulse, uint32_t newAnalogFreq)
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperUpdateSpeed(int, int)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:52:24: error: 'stopWaveForm' was not declared in this scope
stopWaveForm(pinPulse);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:53:44: error: 'stepperStartPulse' was not declared in this scope
stepperStartPulse(pinPulse, newAnalogFreq);
^
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
updated
Errors as of revision 14
Arduino: 1.8.12 (Linux), Board: "LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:3MB OTA:~512KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStartCore(int, uint32_t)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:27:54: error: 'startWaveformClockCycles' was not declared in this scope
if (startWaveformClockCycles(pinPulse, high, low, 0)) {
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStart(int, int, uint32_t)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:39:41: error: 'stepperStartPulse' was not declared in this scope
stepperStartPulse(pinPulse, analogFreq);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStop(int, int)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:45:24: error: 'stopWaveForm' was not declared in this scope
stopWaveForm(pinPulse);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperUpdateSpeed(int, uint32_t)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:55:24: error: 'stopWaveForm' was not declared in this scope
stopWaveForm(pinPulse);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:56:44: error: 'stepperStartPulse' was not declared in this scope
stepperStartPulse(pinPulse, newAnalogFreq);
^
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
updated
Added:
stepperapi.ccp line 1. removed space.
stepperapi.h line 7. added ;
then got these errors.
Arduino: 1.8.12 (Linux), Board: "LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:3MB OTA:~512KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperStop(int, int)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:46:24: error: 'stopWaveForm' was not declared in this scope
stopWaveForm(pinPulse);
^
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'void stepperUpdateSpeed(int, uint32_t)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:56:24: error: 'stopWaveForm' was not declared in this scope
stopWaveForm(pinPulse);
^
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
fixed the two lines and the F
Revision 18 compiles. Yay.
Updated:
- to stop a stepper from moving, call stepper.updateSpeed(0)
- to stop using a stepper, call stepper.stop(), this sets pinEn LOW
- calling stepper.updateSpeed() should now have the pulse train change smoothly on the next low->high transition
Found a coupkle of typo's but this one is out of my league.
Arduino: 1.8.12 (Linux), Board: "LOLIN(WEMOS) D1 R2 & mini, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), 4MB (FS:3MB OTA:~512KB), v2 Lower Memory, Disabled, None, Only Sketch, 921600"
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp: In function 'bool stepperStartCore(int, uint32_t)':
/home/chris/Arduino/libraries/stepperapi/stepperapi.cpp:10:33: error: 'stopWaveForm' was not declared in this scope
return stopWaveForm(pinPulse); //for frequency = 0, stop the pulse train
^
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
also a typo: F->f
what are the others?
line 43 in .ino needs another )
For your info:
Pin allocations:
Rx = GPS Tx
A0 = Booster output voltage sensor.
GPIO0 = Stepper2 Enable
GPIO2 = Stepper2 Pulse
GPIO4 = Stepper1 Pulse
GPIO5 = Stepper1 Enable
GPIO12 = Alarm input
GPIO13 = Stepper3 Pulse
GPIO14 = Linkage sensor
GPIO15 = Relay output
GPIO16 = Stepper3 Enable
setPointVariable / 10 is the rpm required at any given time.