在网上找到一个案例,用摇杆控制两个步进电机,注释为法语,通过翻译软件和自己对代码的理解进行了翻译。
源代码见文章最后部分。
以下是代码解析:
/*
* Controllo di due motori passo passo con Arduino e un Joystick
* 用Arduino和操纵杆控制马达
* Autore : Andrea Lombardo
* Web : http://www.lombardoandrea.com
* Post : http://wp.me/p27dYH-KQ
*/
//Inclusione delle librerie 包含一下库
#include <AccelStepper.h>
#include <Bounce2.h>
//definizione delle costanti dei pin di Arduino arduino 引脚定义
const int ledEnable = 13; // LED控制引脚
const int pinSwEnable = 7; //摇杆按键接线引脚
const int pinEnable = 8; //A4988驱动使能引脚定义
unsigned long debounceDelay = 10; //去抖动延时
const int jX = A0; //摇杆X轴引脚定义
const int stepX = 3; //步进电机X脉冲输出引脚
const int dirX = 4; //步进电机X方向控制引脚
long speedX, valX, mapX; //电机X相关变量
const int jY = A1; //摇杆Y轴引脚定义
const int stepY = 5; //步进电机Y脉冲输出引脚
const int dirY = 6; //步进电机Y方向控制引脚
long speedY, valY, mapY; //电机X相关变量
//AccelStepper 库使用的变量
const int maxSpeed = 1000; //Arduino UNO受晶振限制最大到4000
const int minSpeed = 0; //电机最小速度
const float accelerazione = 50.0; //加速度
const int treshold = 30; //栅域
long tresholdUp, tresholdDown; //变量
boolean abilitato, muoviX, muoviY, enable; //移动变量
Bounce btnEnable = Bounce(); //使用一个库,检测按键抖动
//AccelStepper库电机定义
AccelStepper motoreX(AccelStepper::DRIVER, stepX, dirX);
AccelStepper motoreY(AccelStepper::DRIVER, stepY, dirY);
void setup() {
//变量初始化
speedX = speedY = 0;
enable = false;
//引脚模式定义
pinMode(ledEnable, OUTPUT);
pinMode(pinEnable, OUTPUT);
pinMode(pinSwEnable, INPUT_PULLUP); //按键定义输入,并置高
digitalWrite(ledEnable, enable);
digitalWrite(pinEnable, !enable); //A4988拉高
//使用按键去抖的一个什么库,检测按键是否按下
btnEnable.attach(pinSwEnable); //检测摇杆按键
btnEnable.interval(debounceDelay); //按键检测间隔,去抖时间间隔
//确定摇杆的位置值
tresholdDown = (maxSpeed / 2) - treshold;//之前treshold赋值30 470
tresholdUp = (maxSpeed / 2) + treshold; //530
//配置步进电机参数
motoreX.setMaxSpeed(maxSpeed);//设置最大速度
motoreX.setSpeed(minSpeed);//设置运行速度
motoreX.setAcceleration(accelerazione);//设置加速度
motoreY.setMaxSpeed(maxSpeed);
motoreY.setSpeed(minSpeed);
motoreY.setAcceleration(accelerazione);
}
void loop() {
checkEnable();
digitalWrite(ledEnable, enable); //控制LED
digitalWrite(pinEnable, !enable); //控制电机驱动使能端
//获取摇杆两个方向的模拟变量值
valX = analogRead(jX);
valY = analogRead(jY);
//对从摇杆上获取的值进行速度变换
mapX = map(valX, 0, 1023, minSpeed, maxSpeed);
mapY = map(valY, 0, 1023, minSpeed, maxSpeed);
pilotaMotori(mapX, mapY);
}
void pilotaMotori(long mapX, long mapY) {
if (mapX <= tresholdDown) {
//变换的X速度小于470
speedX = -map(mapX, tresholdDown, minSpeed, minSpeed, maxSpeed);//小于470为负方向
muoviX = true;
} else if (mapX >= tresholdUp) {
//变换的X速度大于530
speedX = map(mapX, maxSpeed, tresholdUp, maxSpeed, minSpeed);//大于530为正方向
muoviX = true;
} else {
//电机不动
speedX = 0;
muoviX = false;
}
if (mapY <= tresholdDown) {
speedY = -map(mapY, tresholdDown, minSpeed, minSpeed, maxSpeed);
muoviY = true;
} else if (mapY >= tresholdUp) {
speedY = map(mapY, maxSpeed, tresholdUp, maxSpeed, minSpeed);
muoviY = true;
} else {
speedY = 0;
muoviY = false;
}
if (muoviX) {
motoreX.setSpeed(speedX);
motoreX.run();
} else {
motoreX.stop();
}
if (muoviY) {
motoreY.setSpeed(speedY);
motoreY.run();
} else {
motoreY.stop();
}
}
void checkEnable() {//按键检测
btnEnable.update();
if (btnEnable.fell()) {
enable = !enable;
}
}
法国人的逻辑是真不易一样。
/*
* Controllo di due motori passo passo con Arduino e un Joystick
* 用Arduino和操纵杆控制马达
* Autore : Andrea Lombardo
* Web : http://www.lombardoandrea.com
* Post : http://wp.me/p27dYH-KQ
*/
//Inclusione delle librerie 包含一下库
#include <AccelStepper.h>
#include <Bounce2.h>
//definizione delle costanti dei pin di Arduino arduino引脚定义
const int ledEnable = 13; //il led on board ci mostrerà lo stato di attivazione dei motori
const int pinSwEnable = 7; //il bottone presente nel modulo joystick che abilita o disabilita il controllo
const int pinEnable = 8; //i pin che comandano lo stato ENABLE dei driver A4988 sono in collegati in serie per questo basta un solo pin per gestirli entrambi
unsigned long debounceDelay = 10; //millisecondi per il debonuce del bottone
const int jX = A0; //pin analogico che legge i valori per le X
const int stepX = 3; //pin digitale che invia i segnali di STEP al driver delle X
const int dirX = 4; //pin digitale che invia il segnale DIREZIONE al driver delle X
long speedX, valX, mapX; //variabili di gestione movimenti motore X
const int jY = A1; //pin analogico che legge i valori per le Y
const int stepY = 5; //pin digitale che invia i segnali di STEP al driver delle Y
const int dirY = 6; //pin digitale che invia il segnale DIREZIONE al driver delle Y
long speedY, valY, mapY; //variabili di gestione movimenti motore Y
//variabili utilizzate dalla libreria AccelStepper
const int maxSpeed = 1000; //stando alla documentazione della libreria questo valore può essere impostato fino a 4000 per un Arduino UNO
const int minSpeed = 0; //velocità minima del motore
const float accelerazione = 50.0; //numero di step al secondo in accelerazione
const int treshold = 30; //la lettura dei potenziometri non è mai affidabile al 100%, questo valore aiuta a determinare il punto da considerare come "Stai fermo" nei movimenti
long tresholdUp, tresholdDown; //variabili di servizio per espletare il compito descritto sopra
boolean abilitato, muoviX, muoviY, enable; //variabili di gestione dei movimenti
Bounce btnEnable = Bounce(); //istanzia un bottone dalla libreria Bounce
//istanzia i motori
AccelStepper motoreX(AccelStepper::DRIVER, stepX, dirX);
AccelStepper motoreY(AccelStepper::DRIVER, stepY, dirY);
void setup() {
//inizializza valori
speedX = speedY = 0;
enable = false;
//definizione delle modalità dei pin
pinMode(ledEnable, OUTPUT);
pinMode(pinEnable, OUTPUT);
pinMode(pinSwEnable, INPUT_PULLUP); //l'input dello switch ha bisogno di essere settato come INPUT_PULLUP
digitalWrite(ledEnable, enable);
digitalWrite(pinEnable, !enable); //I driver A4988 disabilitano i comandi al motore se sul pin ENABLE ricevono un segnale HIGH per questo motivo il valore è opposto a quello del LED
//configura il bottone del joystick utilizzando la libreria Bounce
btnEnable.attach(pinSwEnable);
btnEnable.interval(debounceDelay);
//calcola range valori entro i quali considerare la posizione del joystick come "Stai fermo"
tresholdDown = (maxSpeed / 2) - treshold;
tresholdUp = (maxSpeed / 2) + treshold;
//configura parametri dei motori
motoreX.setMaxSpeed(maxSpeed);
motoreX.setSpeed(minSpeed);
motoreX.setAcceleration(accelerazione);
motoreY.setMaxSpeed(maxSpeed);
motoreY.setSpeed(minSpeed);
motoreY.setAcceleration(accelerazione);
}
void loop() {
//esegui funzione di controllo e lettura del bottone che determina lo stato di abilitazione
checkEnable();
digitalWrite(ledEnable, enable); //mostra stato di abilitazione tramite il led su pin 13
digitalWrite(pinEnable, !enable); //imposta valore opposto sui pin ENABLE dei driver
//esegui lettura analogica dei valori provenienti dai potenziometri del joystick
valX = analogRead(jX);
valY = analogRead(jY);
//mappa i valori letti in funzione della velocità inima e massima
mapX = map(valX, 0, 1023, minSpeed, maxSpeed);
mapY = map(valY, 0, 1023, minSpeed, maxSpeed);
//esegui funzione di comando dei motori
pilotaMotori(mapX, mapY);
}
void pilotaMotori(long mapX, long mapY) {
if (mapX <= tresholdDown) {
//x va indietro
speedX = -map(mapX, tresholdDown, minSpeed, minSpeed, maxSpeed);
muoviX = true;
} else if (mapX >= tresholdUp) {
//x va avanti
speedX = map(mapX, maxSpeed, tresholdUp, maxSpeed, minSpeed);
muoviX = true;
} else {
//x sta fermo
speedX = 0;
muoviX = false;
}
if (mapY <= tresholdDown) {
//y va giù
speedY = -map(mapY, tresholdDown, minSpeed, minSpeed, maxSpeed);
muoviY = true;
} else if (mapY >= tresholdUp) {
//y va su
speedY = map(mapY, maxSpeed, tresholdUp, maxSpeed, minSpeed);
muoviY = true;
} else {
//y sta fermo
speedY = 0;
muoviY = false;
}
if (muoviX) {
motoreX.setSpeed(speedX);
motoreX.run();
} else {
motoreX.stop();
}
if (muoviY) {
motoreY.setSpeed(speedY);
motoreY.run();
} else {
motoreY.stop();
}
}
void checkEnable() {
btnEnable.update();
if (btnEnable.fell()) {
enable = !enable;
}
}