Как заставить двигатели запускаться при нажатии кнопки, а затем проходить цикл с определенным порядком двигателя?
Я новичок в arduino и должен работать над школьным проектом. Мы подключили 3 двигателя (сервопривод, шаговый (180 градусов) и двигатель постоянного тока) к Arduino Uno, Adafruit motorshield и печатной плате. С помощью печатной платы мы смогли записать значения двигателей по отдельности и использовать эти значения для создания движения воспроизведения. Код, который мы получили для воспроизведения движения, приведен ниже (я уже заполнил свои значения для 3-х двигателей).
Вот что я хочу сделать с моторами:
Когда я нажимаю кнопку, я хочу "запустить" цикл двигательных движений
- сначала двигатель постоянного тока начинает совершать движение основанное на выбранных значениях
- Когда это прекратится через 5 секунд я хочу чтобы серводвигатель сделал свое движение
- Когда серводвигатель будет готов, я хочу, чтобы шаговый двигатель начал выполнять движение на основе выбранных значений в течение 5 секунд, а затем остановился.
Нам сказали не использовать задержку, и кто-то предложил использовать millis() вместо delay (), но так как я новичок, то понятия не имею, с чего начать.
Вот этот код:
// With this code it is possible to play back recorded motion paths for for motors connected to the Adafruit motorshield
#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Servo.h> // this is a library that allows you to drive servo's.
// variables
int modeChoice = 0;
int buttons = A2; // the three buttons share an analog pin, resitors provide different levels that point to which button is pressed
int slide = A1; // the slide is read through one analog pin, resitors provide different levels that point to which slide position is current
int rotation = A0; // the pin for the potentiometer
int buttonPressed = 0; // a variable to remember which button is pressed, it is used to control leds and motion memory position management
int buttonValRaw = 0; // a variable to store the raw analog reading of the buttons pin
int slideValRaw = 0; // a variable to sore the raw analog reading of the slide pin
int valButton = 0; // a variable to store the interpreted value, the exact pointer to a button
int valSlide = 0; // a variable to store the interpreted value, the exact pointer to a slide position
int idleState = 0; // a variable to toggle the servo idle behavior
int resetMotion = 0; // a variable to return the arrayPosition to 0 if a button is pushed so that the behaviour starts at the beginning
int motionVar1; // a variable to hold a motion position
int motionVar2; // another variable to hold a motion position
int mySensorArray[20]; // an array with 20 slots to store raw potentiometer readings (for filtering)
int sensorArrayPos = 0; // the array position of interest.
//////////////////////////////////////
int servoMotionArray_B1[50] = {95, 95, 95, 95, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // paste your 50 values in between the brackets
int DCMotionArray_B1[50] = {-85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85};
//recorded motions for position implementation
int StepperMotionArray_B1[50] = {-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200};
//////////////////////////////////////
int arrayPosition = 0;
unsigned long mainTimer = 0; // a variable to time recording and playback
int timeBetweenSamples = 100; // the time between samples.
unsigned long debounceTimer = 0; // a variable to control a timer interval for debouncing of the buttons
int lastValButton = 0; // a variable to help debouncing of the buttons
int debounceFlag = 0; // another variabel to help debouncing of the buttons
// Setup motors
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 16 steps per revolution (2048 positions) to motor port #1 (M1 and M2) -- you need to change this if your stepper is on port #2
Adafruit_StepperMotor *myStepper = AFMS.getStepper(16, 1);
// And connect a DC motor to port M3 -- you need to change this if your DC is on a different port
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);
Servo myservo1; // servo object (employs the servo library that was included above)
// these are dedicated functions to make the steppermotor move
void forwardstep1() {
myStepper->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
myStepper->onestep(BACKWARD, SINGLE);
}
//create aStepper object
AccelStepper aStepper(forwardstep1, backwardstep1); // use functions to step
// setup
void setup() {
Serial.begin(9600); // start serial communication with 9600 baud rate
AFMS.begin(); // create with the default frequency 1.6KHz
//AFMS.begin(1000); // OR with a different frequency, say 1KHz
myservo1.attach(9); // attach servo object to pin 9
// turn on motor M3
myMotor->setSpeed(0);
myMotor->run(RELEASE);
// setup the stepper
aStepper.setSpeed(0); // this is used in the 'speed' implementation
aStepper.setMaxSpeed(200.0); // these are used in the 'position' implementation
aStepper.setAcceleration(100.0);
aStepper.moveTo(0);
// synchronize the first timer cycle -- because the timer is starting at zero it generates negative values in the first 100 miliseconds after starting up when going through the timer cycle, creating potential erratic bahaviour-- giving it a delay at the end of the setup loop will eradicate this behaviour
delay(1000);
}
void doButtons() {
if (buttonPressed != 0) {
return;
}
else {
buttonValRaw = analogRead(buttons);
valButton = map (buttonValRaw, 49, 605, 0, 5);
int localButtonVal = valButton;
if (valButton > 7) {
return;
}
if (debounceFlag == 0) {
debounceTimer = millis();
debounceFlag = 1;
}
if (debounceTimer < millis() - 20) {
buttonValRaw = analogRead(buttons);
valButton = map (buttonValRaw, 49, 605, 0, 5);
if (valButton == localButtonVal) {
debounceFlag = 0;
switch (valButton) {
case 1:
buttonPressed = 1;
break;
case 2:
buttonPressed = 2;
break;
case 3:
buttonPressed = 3;
break;
default:
buttonPressed = 0;
break;
}
}
}
}
}
void loop() {
doButtons(); // this uses the buttons from the PCB, if you use your own implementation you need to reprogram this function
if (mainTimer < millis() - timeBetweenSamples) { // sampling only once per interval.
mainTimer = millis(); // time is rewritten to current millis starting a new interval.
if (buttonPressed == 0) { //'idle play'
if (idleState == 0) {
motionVar1 = servoMotionArray_B1[arrayPosition];
}
else if (idleState == 1){
motionVar1 = servoMotionArray_B1[arrayPosition];
}
motionVar2 = DCMotionArray_B1[arrayPosition];
myservo1.write(motionVar1);
if (motionVar2 < 0) {
myMotor->run(BACKWARD);
myMotor->setSpeed(abs(motionVar2));
}
else if (motionVar2 >= 0) {
myMotor->run(FORWARD);
myMotor->setSpeed(motionVar2);
}
arrayPosition++;
if (arrayPosition > 49) {
arrayPosition = 0;
idleState = !idleState;
}
}
if (buttonPressed == 1) { //2nd behaviour
if (resetMotion == 0) {
arrayPosition = 0;
resetMotion = 1;
myMotor->run(RELEASE); // release the DC motor, otherwise it will continue spinning at the last known RPM
}
motionVar1 = servoMotionArray_B3[arrayPosition];
motionVar2 = StepperMotionArray_B1[arrayPosition];
myservo1.write(motionVar1);
aStepper.moveTo(motionVar2);
arrayPosition++;
if (arrayPosition > 49) {
arrayPosition = 0;
buttonPressed = 0;
resetMotion = 0;
}
}
}
// one of these needs to be called to make the stepper motor work, comment out the one you do not need (position or speed)
//aStepper.run(); //stepper position implementation
aStepper.runSpeed(); //stepper speed implementation
}
@VKwochi, 👍1
1 ответ
Вы уже почти правы:
if (millis() - mainTimer >= timeBetweenSamples) {
mainTimer = millis();
// выполняется только один раз за интервал.
... действие для текущей позиции массива ...
arrayPosition++;
if (arrayPosition > 49) {
arrayPosition = 0;
buttonPressed = 0; // Show ends
}
}
- Код, из-за которого серводвигатель не работает!
- Как заставить сервопривод вращаться на угол больше 180°
- Обратная связь по положению для шагового двигателя
- Мотор для лебедки (с контроллером и внешним блоком питания)
- Серво не двигается
- Низкая скорость с шаговым двигателем
- НУЖНА помощь с серводвигателем
- Как использовать этот конкретный экран arduino