Added Stepper_UNIPOLAR and Stepper_UNL2003

ALSO:  Re-arranged include files so that StepperControl.h is now part of HomeSpan.h.   No need to include anything except for HomeSpan.h to use any of the Stepper Motor classes.  Must update documentation accordingly.

NOTE: Always including StepperControl.h DOES NOT increase size of compile if no stepper motors are instantiated.

To do:  Consider doing the same for Pixel, PWM, and RMT as well.
This commit is contained in:
Gregg 2024-02-07 22:44:22 -06:00
parent 27addd274e
commit dbb0f6565f
6 changed files with 182 additions and 11 deletions

View File

@ -52,6 +52,8 @@
#include "HapQR.h"
#include "Characteristics.h"
#include "extras/StepperControl.h"
using std::vector;
using std::unordered_map;
using std::list;

View File

@ -28,6 +28,7 @@
#pragma once
#include <Arduino.h>
#include "PwmPin.h"
[[maybe_unused]] static const char* STEPPER_TAG = "StepperControl";
@ -103,3 +104,11 @@ class StepperControl {
};
//////////////////////////
#include "Stepper_UNIPOLAR.h"
#include "Stepper_TB6612.h"
#include "Stepper_A3967.h"
struct Stepper_UNL2003 : Stepper_UNIPOLAR {
Stepper_UNL2003(int IN1, int IN2, int IN3, int IN4, std::pair<uint32_t, uint32_t> taskParams = {1,0}) : Stepper_UNIPOLAR(IN1,IN3,IN2,IN4,taskParams){}
};

View File

@ -37,10 +37,6 @@
// disabled (no current / high impedence). The EasyDriver board does NOT support
// the short brake mode.
#pragma once
#include "StepperControl.h"
//////////////////////////
struct Stepper_A3967 : StepperControl {

View File

@ -44,11 +44,6 @@
// In either configuration the motor outputs can be enabled (current running through the coils)
// disabled (no current / high impedence) or set to a short brake.
#pragma once
#include "StepperControl.h"
#include "PwmPin.h"
//////////////////////////
struct Stepper_TB6612 : StepperControl {

View File

@ -0,0 +1,167 @@
/*********************************************************************************
* MIT License
*
* Copyright (c) 2023 Gregg E. Berman
*
* https://github.com/HomeSpan/HomeSpan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
********************************************************************************/
// Implementation of a basic 4-wire controller for a center-tapped Unipolar Stepper Motor
// with two coils (Coil 1 and Coil 2) each having two driving inputs (A and B).
//
// Requires 4 pins on the ESP32 connected to an appropriate driver circuit, such as a set
// of Darlington transitors, that are in turn connected to each of the 4 Stepper Motor wires:
//
// * Coil 1, Input A (1A)
// * Coil 1, Input B (1B)
// * Coil 2, Input A (2A)
// * Coil 2, Input B (2B)
//
// When any of the pins are HIGH, the driver circuit should cause current to flow in the corresponding
// half of the coil. When the pin is set LOW, the driver circuit should stop the flow of current through
// that half of the coil. Supported modes and driving logic are as follows:
//
// FULL_STEP_ONE_PHASE (4 steps, where current flows only through ONE of the phases of ONE of the coils at each step):
//
// 1A 2A 1B 2B
// Step 1: HI -- -- --
// Step 2: -- HI -- --
// Step 3: -- -- HI --
// Step 4: -- -- -- HI
//
// FULL_STEP_TWO_PHASE (4 steps, where current flows through ONE of the phases of EACH of the coils at each step):
//
// 1A 2A 1B 2B
// Step 1: HI HI -- --
// Step 2: -- HI HI --
// Step 3: -- -- HI HI
// Step 4: HI -- -- HI
//
// HALF_STEP (8 steps that alternate between the 4 steps of the FULL_STEP modes above):
//
// 1A 2A 1B 2B
// Step 1: HI -- -- --
// Step 2: HI HI -- --
// Step 3: -- HI -- --
// Step 4: -- HI HI --
// Step 5: -- -- HI --
// Step 6: -- -- HI HI
// Step 7: -- -- -- HI
// Step 8: HI -- -- HI
// NOTE ORDER OF CONSTRUCTOR PARAMETERS: First the two pins that drive the A and B side of Coil 1,
// followed by the two pints that drive the A and B side of Coil 2.
// It does not matter which coil is defined as 1 or 2, nor which side is called A or B, as long as
// the first two parameters are for one of the coils and the second two are for the other coil.
// Note: This driver supports enabling and disabling all current flow, but does NOT support a short brake.
//////////////////////////
struct Stepper_UNIPOLAR : StepperControl {
int c1A, c1B, c2A, c2B;
uint8_t phase, nPhases;
double offset;
//////////////////////////
Stepper_UNIPOLAR(int coil1A, int coil1B, int coil2A, int coil2B, std::pair<uint32_t, uint32_t> taskParams = {1,0}) : StepperControl(taskParams.first,taskParams.second) {
c1A=coil1A;
c1B=coil1B;
c2A=coil2A;
c2B=coil2B;
pinMode(c1A,OUTPUT);
pinMode(c1B,OUTPUT);
pinMode(c2A,OUTPUT);
pinMode(c2B,OUTPUT);
setStepType(FULL_STEP_ONE_PHASE);
}
//////////////////////////
void onEnable() override {
setPins();
}
//////////////////////////
void onDisable() override {
digitalWrite(c1A,0);
digitalWrite(c1B,0);
digitalWrite(c2A,0);
digitalWrite(c2B,0);
}
//////////////////////////
void onStep(boolean direction) override {
if(direction)
phase=(phase+1)%nPhases;
else
phase=(phase+nPhases-1)%nPhases;
setPins();
}
//////////////////////////
void setPins(){
float levelA=cos(phase*TWO_PI/nPhases+offset)*100.0;
float levelB=sin(phase*TWO_PI/nPhases+offset)*100.0;
digitalWrite(c1A,levelA>0.01);
digitalWrite(c1B,levelA<-0.01);
digitalWrite(c2A,levelB>0.01);
digitalWrite(c2B,levelB<-0.01);
}
//////////////////////////
StepperControl *setStepType(int mode) override {
switch(mode){
case FULL_STEP_ONE_PHASE:
phase=0;
nPhases=4;
offset=0;
break;
case FULL_STEP_TWO_PHASE:
phase=0;
nPhases=4;
offset=TWO_PI/8.0;
break;
case HALF_STEP:
phase=0;
nPhases=8;
offset=0;
break;
default:
ESP_LOGE(STEPPER_TAG,"Unknown StepType=%d",mode);
}
return(this);
}
};

View File

@ -28,8 +28,10 @@
// This is a placeholder .ino file that allows you to easily edit the contents of this files using the Arduino IDE,
// as well as compile and test from this point. This file is ignored when the library is included in other sketches.
#include "Stepper_TB6612.h" // include the driver for a TB6612 chip
#include "Stepper_A3967.h"
//#include "Stepper_TB6612.h" // include the driver for a TB6612 chip
//#include "Stepper_A3967.h"
#include "StepperControl.h"
StepperControl *bigMotor;
StepperControl *smallMotor;