Merge pull request #6370 from Leuselator/A4988_Stepper

A4988 stepper
This commit is contained in:
Theo Arends 2019-09-08 18:14:07 +02:00 committed by GitHub
commit 17eb9727a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 622 additions and 3 deletions

19
lib/A4988_Stepper/README.adoc Executable file
View File

@ -0,0 +1,19 @@
Stepper Library for Tasmota
This Class allows you to control bipolar stepper motors. To use it you will need an A4988-StepperDriverCircuit, connected at least with 2 GPIO's (direction and step) and of cause a stepper motor.
== License ==
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

24
lib/A4988_Stepper/keywords.txt Executable file
View File

@ -0,0 +1,24 @@
#######################################
# Syntax Coloring Map For Test
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
A4988_Stepper KEYWORD1 A4988_Stepper
#######################################
# Methods and Functions (KEYWORD2)
#######################################
doMove KEYWORD2
doRotate KEYWORD2
setRPM KEYWORD2
setSPR KEYWORD2
setMIS KEYWORD2
version KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,9 @@
name=A4988_Stepper
version=0.0.1
author=Tim Leuschner
maintainer=Tim Leuschner <tim@feuer.land>
sentence=Allows Tasmota to control stepper motors, connected to A4988-StepperDriverCircuit.
paragraph=This library allows you to control bipolar stepper motors, controlled by A4988-stepperDriverCircuit.
category=Device Control
url=
architectures=*

View File

@ -0,0 +1,155 @@
/*
This library 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 library 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/>.
Drives a bipolar motor, controlled by A4988 stepper driver circuit
*/
//
#include "Arduino.h"
#include "A4988_Stepper.h"
A4988_Stepper::A4988_Stepper( int m_spr
, int m_rpm
, short m_mis
, short m_dir_pin
, short m_stp_pin
, short m_ena_pin
, short m_ms1_pin
, short m_ms2_pin
, short m_ms3_pin ) {
last_time = 0; // time stamp in us of the last step taken
motor_SPR = m_spr; // StepsPerRevolution
motor_RPM = m_rpm; // RoundsPerMinute
motor_MIS = m_mis; // Microsteps w/o effect if MS1-MS3 not connected - then full steps anyway
motor_dir_pin = m_dir_pin;
motor_stp_pin = m_stp_pin;
motor_ena_pin = m_ena_pin;
motor_ms1_pin = m_ms1_pin;
motor_ms2_pin = m_ms2_pin;
motor_ms3_pin = m_ms3_pin;
adjustDelay();
adjustPins();
adjustMicrosteps();
}
void A4988_Stepper::adjustPins(void) {
// setup the pins on the microcontroller:
pinMode(motor_dir_pin, OUTPUT);
pinMode(motor_stp_pin, OUTPUT);
if (motor_ena_pin <99) {
pinMode(motor_ena_pin, OUTPUT);
digitalWrite(motor_ena_pin, HIGH);
}
if ((motor_ms1_pin<99)&&(motor_ms2_pin<99)&&(motor_ms3_pin<99)) {
pinMode(motor_ms1_pin, OUTPUT);
pinMode(motor_ms2_pin, OUTPUT);
pinMode(motor_ms3_pin, OUTPUT);
}
}
void A4988_Stepper::adjustMicrosteps() {
if ((motor_ms1_pin<99)&&(motor_ms2_pin<99)&&(motor_ms3_pin<99)) {
unsigned short i = 0;
while (i < 5){
if (motor_MIS & (1<<i)){
unsigned short mask = MIS_TABLE[i];
digitalWrite(motor_ms1_pin, 1&mask?HIGH:LOW);
digitalWrite(motor_ms2_pin, 2&mask?HIGH:LOW);
digitalWrite(motor_ms3_pin, 4&mask?HIGH:LOW);
break;
}
i++;
}
} else {
motor_MIS = 1;
}
}
void A4988_Stepper::adjustDelay(void) {
motor_delay = 60L * 1000L * 1000L / motor_SPR / motor_RPM / motor_MIS/2;
}
void A4988_Stepper::setMIS(short oneToSixteen) {
motor_MIS = oneToSixteen;
adjustMicrosteps();
adjustDelay();
}
short A4988_Stepper::getMIS(void) {
return motor_MIS;
}
void A4988_Stepper::setRPM(int howManyRounds) {
motor_RPM = howManyRounds;
adjustDelay();
}
int A4988_Stepper::getRPM(void) {
return motor_RPM;
}
void A4988_Stepper::setSPR(int howManySteps){
motor_SPR = howManySteps;
adjustDelay();
}
int A4988_Stepper::getSPR(void) {
return motor_SPR;
}
void A4988_Stepper::enable(){
if (motor_ena_pin < 99) {digitalWrite(motor_ena_pin, LOW);}
}
void A4988_Stepper::disable(){
if (motor_ena_pin < 99) {digitalWrite(motor_ena_pin, HIGH);}
}
void A4988_Stepper::doMove(long howManySteps)
{
long steps_togo = abs(howManySteps); // how many steps to take
bool lastStepWasHigh = false;
digitalWrite(motor_dir_pin, howManySteps>0?LOW:HIGH);
enable();
while (steps_togo > 0) {
delay(0); // don't get watchdoged in loop
unsigned long now = micros();
// move if delay has passed:
if (now - last_time >= motor_delay) {
digitalWrite(motor_stp_pin, lastStepWasHigh?LOW:HIGH);
lastStepWasHigh = !lastStepWasHigh;
// remeber step-time
last_time = now;
if (!lastStepWasHigh) steps_togo--; // same here - only HIGH moves, if pulled LOW step is completed...
}
}
disable();
}
void A4988_Stepper::doRotate(long howManyDegrees)
{ long lSteps = 0;
lSteps = motor_SPR*motor_MIS*howManyDegrees/360;
doMove(lSteps);
}
void A4988_Stepper::doTurn(float howManyTimes)
{ long lSteps = 0;
lSteps = howManyTimes*motor_SPR;
doMove(lSteps);
}
int A4988_Stepper::version(void)
{
return 1;
}

View File

@ -0,0 +1,73 @@
/*
This library 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 library 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/>.
*/
#ifndef A4988_Stepper_h
#define A4988_Stepper_h
class A4988_Stepper {
public:
// constructor:
A4988_Stepper( int motor_spr
, int motor_rpm
, short motor_mis
, short motor_dir_pin
, short motor_stp_pin
, short motor_ena_pin
, short motor_ms1_pin
, short motor_ms2_pin
, short motor_ms3_pin
);
void setRPM (int whatRPM );
int getRPM (void );
void setMIS (short OneToSixteen);
short getMIS (void );
void setSPR (int howMany );
int getSPR (void );
void doMove (long steps_to_move);
void doRotate(long degrs_to_turn);
void doTurn (float howManyTimes);
void enable (void );
void disable (void );
int version (void );
const unsigned short MIS_TABLE[5] = {0b000,0b001,0b010,0b011,0b111};
private:
void adjustDelay(void);
void adjustPins(void);
void adjustMicrosteps(void);
unsigned long motor_delay; // delay between steps, in ms
int motor_SPR; // Steps Per Revolution
int motor_RPM; // Rounds Per Minute
short motor_MIS; // Micro Steps
// motor pins:
short motor_dir_pin;
short motor_stp_pin;
short motor_ena_pin;
short motor_ms1_pin;
short motor_ms2_pin;
short motor_ms3_pin;
unsigned long last_time; // timestamp of last pincycle of last step
};
#endif

View File

@ -456,6 +456,18 @@
#define D_JSON_ZIGBEEZNPSENT "ZigbeeZNPSent"
#define D_JSON_ZIGBEEZCLRECEIVED "ZigbeeZCLReceived"
#define D_JSON_ZIGBEEZCLSENT "ZigbeeZCLSent"
// Commands xdrv_25_A4988_Stepper.ino
#ifdef USE_A4988_Stepper
#define D_CMND_MOTOR "MOTOR"
#define D_JSON_MOTOR_MOVE "doMove"
#define D_JSON_MOTOR_ROTATE "doRotate"
#define D_JSON_MOTOR_TURN "doTurn"
#define D_JSON_MOTOR_SPR "setSPR"
#define D_JSON_MOTOR_RPM "setRPM"
#define D_JSON_MOTOR_MIS "setMIS"
#endif
/********************************************************************************************/
#define D_ASTERISK_PWD "****"

View File

@ -597,6 +597,13 @@
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"
#define D_UNIT_CENTIMETER "cm"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "А"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "А"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "安"

View File

@ -596,6 +596,12 @@
#define D_SENSOR_IBEACON_RX "iBeacon RX"
#define D_SENSOR_RDM6300_RX "RDM6300 RX"
#define D_SENSOR_CC1101_CS "CC1101 CS"
#define D_SENSOR_A4988_DIR "A4988 DIR"
#define D_SENSOR_A4988_STP "A4988 STP"
#define D_SENSOR_A4988_ENA "A4988 ENA"
#define D_SENSOR_A4988_MS1 "A4988 MS1"
#define D_SENSOR_A4988_MS2 "A4988 MS2"
#define D_SENSOR_A4988_MS3 "A4988 MS3"
// Units
#define D_UNIT_AMPERE "安"

View File

@ -528,6 +528,7 @@
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
//#define USE_HRE // Add support for Badger HR-E Water Meter (+1k4 code)
//#define USE_A4988_Stepper // Add support for A4988 stepper-motor-driver-circuit (+10k5 code)
/*********************************************************************************************\
* Debug features

View File

@ -258,6 +258,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
#undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code)
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
#undef USE_A4988_Stepper // Disable support for A4988_Stepper
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // FIRMWARE_CLASSIC
@ -387,6 +388,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
#undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code)
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
#undef USE_A4988_Stepper // Disable support for A4988_Stepper
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
@ -481,6 +483,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
#undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code)
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
#undef USE_A4988_Stepper // Disable support for A4988_Stepper
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // FIRMWARE_BASIC
@ -562,6 +565,7 @@ char* ToHex_P(const unsigned char * in, size_t insz, char * out, size_t outsz, c
#undef USE_RF_SENSOR // Disable support for RF sensor receiver (434MHz or 868MHz) (+0k8 code)
#undef USE_SM16716 // Disable support for SM16716 RGB LED controller (+0k7 code)
#undef USE_HRE // Disable support for Badger HR-E Water Meter (+1k4 code)
#undef USE_A4988_Stepper // Disable support for A4988_Stepper
#undef DEBUG_THEO // Disable debug code
#undef USE_DEBUG_DRIVER // Disable debug code
#endif // FIRMWARE_MINIMAL

View File

@ -194,6 +194,12 @@ enum UserSelectablePins {
GPIO_RDM6300_RX, // RDM6300 RX
GPIO_IBEACON_TX, // HM17 IBEACON TX
GPIO_IBEACON_RX, // HM17 IBEACON RX
GPIO_A4988_DIR, // A4988 direction pin
GPIO_A4988_STP, // A4988 step pin
GPIO_A4988_ENA, // A4988 enabled pin
GPIO_A4988_MS1, // A4988 microstep pin1
GPIO_A4988_MS2, // A4988 microstep pin2
GPIO_A4988_MS3, // A4988 microstep pin3
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality
@ -267,6 +273,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_ZIGBEE_TXD "|" D_SENSOR_ZIGBEE_RXD "|"
D_SENSOR_RDM6300_RX "|"
D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|"
D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" D_SENSOR_A4988_MS2 "|" D_SENSOR_A4988_MS3 "|"
;
// User selectable ADC0 functionality
@ -689,6 +696,15 @@ const uint8_t kGpioNiceList[] PROGMEM = {
GPIO_HRE_CLOCK,
GPIO_HRE_DATA,
#endif
#ifdef USE_A4988_Stepper
GPIO_A4988_DIR, // A4988 direction pin
GPIO_A4988_STP, // A4988 step pin
// folowing are not mandatory
GPIO_A4988_ENA, // A4988 enabled pin
GPIO_A4988_MS1, // A4988 microstep pin1
GPIO_A4988_MS2, // A4988 microstep pin2
GPIO_A4988_MS3, // A4988 microstep pin3
#endif
};
const uint8_t kModuleNiceList[] PROGMEM = {

View File

@ -441,11 +441,12 @@ void GetFeatures(void)
#ifdef USE_SML_M
feature5 |= 0x00000008; // xsns_53_sml.ino
#endif
#ifdef USE_INA226
feature5 |= 0x00000010; // xsns_54_ina226.ino
#endif
// feature5 |= 0x00000020;
#ifdef USE_A4988_Stepper
feature5 |= 0x00000020; // xdrv_25_A4988.ino
#endif
// feature5 |= 0x00000040;
// feature5 |= 0x00000080;

View File

@ -0,0 +1,172 @@
/*
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>
#define XDRV_25 25
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;
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;
A4988_mis = 1;
myA4988 = new A4988_Stepper( A4988_spr
, A4988_rpm
, A4988_mis
, A4988_dir_pin
, A4988_stp_pin
, A4988_ena_pin
, A4988_ms1_pin
, A4988_ms2_pin
, A4988_ms3_pin );
}
const char kA4988Commands[] PROGMEM = "|"
"MOTOR";
void (* const A4988Command[])(void) PROGMEM = { &CmndMOTOR};
uint32_t MOTORCmndJson(void)
{
// 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);
if (strlen(dataBufUc) < 8) { returnValue =A4988_INVALID_JSON; }
DynamicJsonBuffer jsonBuf;
JsonObject &json = jsonBuf.parseObject(dataBufUc);
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){
uint32_t error;
if (XdrvMailbox.data_len) {
if (strstr(XdrvMailbox.data, "}") == nullptr) {
error = A4988_NO_JSON_COMMAND;
} else {
error = MOTORCmndJson();
}
}
A4988CmndResponse(error);
}
void A4988CmndResponse(uint32_t error){
switch (error) {
case A4988_NO_JSON_COMMAND:
ResponseCmndChar(PSTR("No command!"));
break;
case A4988_MOVE:
ResponseCmndChar(PSTR("Stepping!"));
break;
case A4988_ROTATE:
ResponseCmndChar(PSTR("Rotating!"));
break;
case A4988_TURN:
ResponseCmndChar(PSTR("Turning!"));
break;
default: // A4988_NO_ERROR
ResponseCmndDone();
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
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

View File

@ -167,7 +167,7 @@ a_features = [[
"USE_MAX31865","USE_CHIRP","USE_SOLAX_X1","USE_PAJ7620"
],[
"USE_BUZZER","USE_RDM6300","USE_IBEACON","USE_SML_M",
"USE_INA226","","","",
"USE_INA226","USE_A4988_Stepper","","",
"","","","",
"","","","",
"","","","",