Tasmota/sonoff/xdrv_25_A4988_Stepper.ino

173 lines
5.1 KiB
Arduino
Raw Normal View History

/*
2019-09-08 02:28:19 +01:00
xdrv_25_A4988_Stepper.ino - A4988-StepMotorDriverCircuit- support for Sonoff-Tasmota
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_A4988_Stepper
#include <A4988_Stepper.h>
2019-09-07 20:37:01 +01:00
#define XDRV_25 25
2019-09-08 02:28:19 +01:00
enum A4988Errors { A4988_NO_ERROR, A4988_NO_JSON_COMMAND, A4988_INVALID_JSON, A4988_MOVE, A4988_ROTATE, A4988_TURN};
short A4988_dir_pin = pin[GPIO_MAX];
short A4988_stp_pin = pin[GPIO_MAX];
short A4988_ms1_pin = pin[GPIO_MAX];
short A4988_ms2_pin = pin[GPIO_MAX];
short A4988_ms3_pin = pin[GPIO_MAX];
short A4988_ena_pin = pin[GPIO_MAX];
int A4988_spr = 0;
float A4988_rpm = 0;
2019-09-07 19:38:06 +01:00
short A4988_mis = 0;
A4988_Stepper* myA4988 = nullptr;
void A4988Init(void)
{
A4988_dir_pin = pin[GPIO_A4988_DIR];
A4988_stp_pin = pin[GPIO_A4988_STP];
A4988_ena_pin = pin[GPIO_A4988_ENA];
A4988_ms1_pin = pin[GPIO_A4988_MS1];
A4988_ms2_pin = pin[GPIO_A4988_MS2];
A4988_ms3_pin = pin[GPIO_A4988_MS3];
A4988_spr = 200;
A4988_rpm = 30;
2019-09-07 13:09:44 +01:00
A4988_mis = 1;
myA4988 = new A4988_Stepper( A4988_spr
, A4988_rpm
2019-09-07 13:09:44 +01:00
, A4988_mis
, A4988_dir_pin
, A4988_stp_pin
, A4988_ena_pin
, A4988_ms1_pin
, A4988_ms2_pin
, A4988_ms3_pin );
}
2019-09-08 02:28:19 +01:00
const char kA4988Commands[] PROGMEM = "|"
"MOTOR";
2019-09-07 20:37:01 +01:00
void (* const A4988Command[])(void) PROGMEM = { &CmndMOTOR};
uint32_t MOTORCmndJson(void)
{
2019-09-08 02:28:19 +01:00
// MOTOR {"doMove":200}
// MOTOR {"doRotate":360}
// MOTOR {"doTurn":1.0}
uint32_t returnValue =A4988_NO_JSON_COMMAND;
char parm_uc[12];
char dataBufUc[XdrvMailbox.data_len];
UpperCase(dataBufUc, XdrvMailbox.data);
RemoveSpace(dataBufUc);
2019-09-08 02:28:19 +01:00
if (strlen(dataBufUc) < 8) { returnValue =A4988_INVALID_JSON; }
2019-09-07 19:38:06 +01:00
DynamicJsonBuffer jsonBuf;
JsonObject &json = jsonBuf.parseObject(dataBufUc);
2019-09-08 02:28:19 +01:00
if (json.success()) {
UpperCase_P(parm_uc, PSTR(D_JSON_MOTOR_SPR));
if (json.containsKey(parm_uc)){
int howManySteps =strtoul(json[parm_uc],nullptr,10);
myA4988->setSPR(howManySteps);
returnValue = A4988_NO_ERROR;
}
UpperCase_P(parm_uc, PSTR(D_JSON_MOTOR_RPM));
if (json.containsKey(parm_uc)){
int howManyRounds =strtoul(json[parm_uc],nullptr,10);
myA4988->setRPM(howManyRounds);
returnValue = A4988_NO_ERROR;
}
UpperCase_P(parm_uc, PSTR(D_JSON_MOTOR_MIS));
if (json.containsKey(parm_uc)){
short oneToSixteen =strtoul(json[parm_uc],nullptr,10);
myA4988->setMIS(oneToSixteen);
returnValue = A4988_NO_ERROR;
}
UpperCase_P(parm_uc, PSTR(D_JSON_MOTOR_MOVE));
if (json.containsKey(parm_uc)){
long stepsPlease = strtoul(json[parm_uc],nullptr,10);
myA4988->doMove(stepsPlease);
returnValue = A4988_MOVE;
}
UpperCase_P(parm_uc, PSTR(D_JSON_MOTOR_ROTATE));
if (json.containsKey(parm_uc)){
long degrsPlease = strtoul(json[parm_uc],nullptr,10);
myA4988->doRotate(degrsPlease);
returnValue = A4988_ROTATE;
}
UpperCase_P(parm_uc, PSTR(D_JSON_MOTOR_TURN));
if (json.containsKey(parm_uc)){
float turnsPlease = strtod(json[parm_uc],nullptr);
myA4988->doTurn(turnsPlease);
returnValue = A4988_TURN;
}
} else returnValue =A4988_INVALID_JSON;
return returnValue;
}
void CmndMOTOR(void){
2019-09-07 19:38:06 +01:00
uint32_t error;
if (XdrvMailbox.data_len) {
2019-09-08 02:28:19 +01:00
if (strstr(XdrvMailbox.data, "}") == nullptr) {
error = A4988_NO_JSON_COMMAND;
} else {
error = MOTORCmndJson();
}
}
A4988CmndResponse(error);
}
void A4988CmndResponse(uint32_t error){
2019-09-07 19:38:06 +01:00
switch (error) {
case A4988_NO_JSON_COMMAND:
ResponseCmndChar(PSTR("No command!"));
2019-09-08 02:28:19 +01:00
break;
case A4988_MOVE:
ResponseCmndChar(PSTR("Stepping!"));
break;
case A4988_ROTATE:
ResponseCmndChar(PSTR("Rotating!"));
break;
case A4988_TURN:
ResponseCmndChar(PSTR("Turning!"));
2019-09-07 19:38:06 +01:00
break;
default: // A4988_NO_ERROR
ResponseCmndDone();
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
2019-09-07 20:37:01 +01:00
bool Xdrv25(uint8_t function)
{
bool result = false;
if ((pin[GPIO_A4988_DIR] < 99) && (pin[GPIO_A4988_STP] < 99)) {
switch (function) {
case FUNC_INIT:
A4988Init();
break;
case FUNC_COMMAND:
result = DecodeCommand(kA4988Commands, A4988Command);
break;
}
}
return result;
}
#endif