Помогите написать скетч для ШД
- Войдите на сайт для отправки комментариев
Вс, 02/07/2017 - 23:14
Здравствуйте! Помогите написать скетч под конкретную задачу. И так, что требуется: есть 2 кнопки, 3 потенциометра один драйвер (dir/step) и один ШД, Arduino Pro Mini
Принцип работы:
При кратковременном нажатиии на кнопку К1 ШД совершает Х1 оборотов по часовой стрелке и сразу
(или с паузой t) Х2 оборотов против часовой стрелки. То есть выполняется подпрограмма.
Х1 задается положением резистора R1, Х2 положением резистора R2.
При длительном нажатии на кнопку К1 бесконечно повторяется выполнение подпрограммы с промежутками Т(0-3с). Промежутки (паузы) Т задаются резистором R3.
При нажатии кнопки К2 ШД вращается против часовой стрелки постоянно, пока нажата кнопка К2.
К сожалению я совсем не Дока в программировании, поэтому прошу у вас помощи. Спасибо!
Вам в раздел Ищу исполнителя
Мне помощь нужна! Пару лет назад сам писал, а теперь подзабыл...
Мне помощь нужна! Пару лет назад сам писал, а теперь подзабыл...
Программирование это как езда на велосипеде, если научился, то забыть не возможно.
Мне помощь нужна! Пару лет назад сам писал, а теперь подзабыл...
Помогают тем, кто сам что-то пытается сделать и задаёт конкретные вопросы. А Вы хотите, чтобы всё сделали за Вас и дали готовый код. В таком случае - Ищу исполнителя
напомню: если двигатель 2-полярный (4 проводный интерфейс, две обмотки A и B), то управлять полным шагом можно в виде повтора последовательности из 4 шагов: Ш1) A+, задержка; Ш2) A-, задержка; Ш3) B-, задержка; Ш4) B+, задержка, где A+/ B+ (или A-/ B-) = подача положительной (отрицательной) полярности на обмотку A /B.
С микрошагами и удержанием в промежуточном положении несколько сложнее. Если напишешь программу для полношагового управления, помогу дальше.
Спасибо! Найду свои старые скетчи, попробую вспомнить. Если что, отпишусь.
p.s. Вот нашел старый скетч, переделанный из какого то примера. Крутит мотор вправо-влево от 2-х кнопок. Скорость задается переменным резистором. Немного не то что надо. Как его переделать, чтобы отсчитывал шаги и количество шагов задавалось резистором (или может кодировать количество шагов перемычками)?
#include <AccelStepper.h> // Define the stepper and the pins it will use AccelStepper stepper1(1, 9, 8); // Define our three input button pins #define LEFT_PIN 3 #define RIGHT_PIN 2 // Define our analog pot input pin #define SPEED_PIN 0 // Define our maximum and minimum speed in steps per second (scale pot to these) #define MAX_SPEED 500 #define MIN_SPEED 0.1 void setup() { // The only AccelStepper value we have to set here is the max speeed, which is higher than we'll ever go stepper1.setMaxSpeed(50000.0); // Set up the three button inputs, with pullups pinMode(LEFT_PIN, INPUT_PULLUP); pinMode(RIGHT_PIN, INPUT_PULLUP); } void loop() { static float current_speed = 0.0; // Holds current motor speed in steps/second static int analog_read_counter = 1000; // Counts down to 0 to fire analog read static char sign = 0; // Holds -1, 1 or 0 to turn the motor on/off and control direction static int analog_value = 0; // Holds raw analog value. // If a switch is pushed down (low), set the sign value appropriately // Если переключатель опущен вниз (низкий), установить соответствующий знак значение if (digitalRead(LEFT_PIN) == 0) { sign = 1; } else if (digitalRead(RIGHT_PIN) == 0) { sign = -1; } else if (digitalRead(RIGHT_PIN) != 0) { sign = 0; } // We only want to read the pot every so often (because it takes a long time we don't // want to do it every time through the main loop). if (analog_read_counter > 0) { analog_read_counter--; } else { analog_read_counter = 3000; // Now read the pot (from 0 to 1023) analog_value = analogRead(SPEED_PIN); // Give the stepper a chance to step if it needs to stepper1.runSpeed(); // And scale the pot's value from min to max speeds current_speed = sign * ((analog_value/1023.0) * (MAX_SPEED - MIN_SPEED)) + MIN_SPEED; // Update the stepper to run at this new speed stepper1.setSpeed(current_speed); } // This will run the stepper at a constant speed stepper1.runSpeed(); }Всем спасибо за помощь! На редкость отзывчивый форум!
Начните с изучения простых примеров действий, прилагаемых к библиотеке ШД AccelStepper https://github.com/bildr-org/AccelStepper
//This is an example of how you would control 1 stepper #include <AccelStepper.h> int motorSpeed = 9600; //maximum steps per second (about 3rps / at 16 microsteps) int motorAccel = 80000; //steps/second/second to accelerate int motorDirPin = 2; //digital pin 2 int motorStepPin = 3; //digital pin 3 //set up the accelStepper intance //the "1" tells it we are using a driver AccelStepper stepper(1, motorStepPin, motorDirPin); void setup(){ stepper.setMaxSpeed(motorSpeed); stepper.setSpeed(motorSpeed); stepper.setAcceleration(motorAccel); stepper.moveTo(32000); //move 32000 steps (should be 10 rev) } void loop(){ //if stepper is at desired location if (stepper.distanceToGo() == 0){ //go the other way the same amount of steps //so if current position is 400 steps out, go position -400 stepper.moveTo(-stepper.currentPosition()); } //these must be called as often as possible to ensure smooth operation //any delay will cause jerky motion stepper.run(); }посмотрите в примере как переместить вал на заданное количество шагов и понемногу добавляйте в пример свой код - условия и направления перемещения
// define a constant value named stepPin and assign the value 9 to it - this value will not change during our code // this assumes digital pin 9 of your Arduino is attached to the step input of your driver // определяем значение константы по имени продвижение и присвойте значение 9 к нему - это значение не изменится в ходе нашего кода // при этом предполагается, что цифровой контакт 9 части вашего Arduino крепится к шагу ввода драйвера #define stepPin 9 // define a constant value named dirPin and assign the value 8 to it - this value will not change during our code // this assumes digital pin 8 of your Arduino is attached to the step input of your driver // определяем значение константы по имени штырь и присвоить значение 8 - это значение не изменится в ходе нашего кода // при этом предполагается, что цифровой вывод 8 части вашего Arduino крепится к шагу ввода драйвера #define dirPin 8 // define the pins on which we've put our N.O. buttons // определить штыри, на которых мы поместили наши кнопки Н.О. #define button1 2 #define button2 3 // setup() loop, the Arduino only runs through this once // настройка() петли, Arduino только проходит через этот раз void setup() { // digital pins on the Arduino can only be either set as an output or input - in our case we want to send data to the driver, so we choose output // цифровых пинов на Arduino можно только либо установить в качестве выходного или входного сигнала - в нашем случае мы хотим отправить данные на водителя, поэтому мы выбираем выходной pinMode(stepPin , OUTPUT); pinMode(dirPin , OUTPUT); // define our button pins as input pullup type // определения наша кнопка булавки в качестве входного типа подтяжки pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); // let's set an initial value of low to both our step and dir pins, we could easily write false or 0 instead of LOW // зададим начальное значение минимума как шаг штырей и дира, мы могли бы легко написать false или 0, а не низкий digitalWrite(stepPin , LOW); digitalWrite(dirPin , LOW); } // loop() loop, the Arduino continuously cycles through this as fast as it can // петля() петли, Ардуино постоянно циклов через это как можно быстрее void loop() { if (digitalRead(button1) == LOW && digitalRead(button2) == HIGH) { // if button1 is pressed and button2 is not pressed если нажата кнопка button1 и button2 не нажимается digitalWrite(dirPin, LOW); // move in the LOW direction двигаться в низких направлении } else if (digitalRead(button1) == HIGH && digitalRead(button2) == LOW) { // if btton1 is not pressed and button2 is pressed если btton1 не нажата и button2 нажата digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction // Makes 200 pulses for making one full cycle rotation for(int x = 0; x < 400; x++) { digitalWrite(stepPin,HIGH); delayMicroseconds(500); digitalWrite(stepPin,LOW); delayMicroseconds(500); } delay(10); // One second delay digitalWrite(dirPin,LOW); //Changes the rotations direction // Makes 400 pulses for making two full cycle rotation for(int x = 0; x < 100; x++) { digitalWrite(stepPin,HIGH); delayMicroseconds(500); digitalWrite(stepPin,LOW); delayMicroseconds(500); } delay(10); } }Может так
#define stepPin 9 #define dirPin 8 #define button1 2 #define button2 3 bool f_step; bool kn_bt1; bool kn_bt2; uint32_t temp = millis(); int mu_step = 800; void setup() { pinMode(stepPin , OUTPUT); pinMode(dirPin , OUTPUT); pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); digitalWrite(stepPin , LOW); digitalWrite(dirPin , LOW); } void loop() { if (digitalRead(button1) == LOW ) { kn_bt1 = 1; kn_bt2 = 0; } if (digitalRead(button2) == LOW) { kn_bt1 = 0; kn_bt2 = 1; mu_step = 800; digitalWrite(dirPin, HIGH); } else { kn_bt2 = 0; digitalWrite(dirPin, LOW); } if (kn_bt1 && millis() - temp >= 500) { temp = millis(); f_step = !f_step; mu_step--; if (mu_step == 0 && digitalRead(dirPin) == LOW) { digitalWrite(dirPin, HIGH); mu_step = 200; } if (mu_step == 0 && digitalRead(dirPin) == HIGH) { digitalWrite(dirPin, LOW); kn_bt1=0; } if (mu_step > 0) digitalWrite(stepPin, f_step); } if (kn_bt2 && millis() - temp >= 500) { temp = millis(); f_step = !f_step; digitalWrite(stepPin, f_step); } }Такие конструкции , как в строке 41 неудобны и могут приводит к проблемам из-за повторной обработки программой loop этой же нажатой кнопки и дребезга (в схеме предусмотрена антидребезговая цепь?).
Чтобы преждевременно не обрабатывать еще раз нажатие той кнопки, после выполнения нужного действия ( вращения мотора, а оно тоже занимает время) применяют таймаут, в течение которого обработка нажатий этой кнопки (или всех кнопок) игнорируется.
Чтобы не превращать loop в свалку, в будущем лучше обрабатывать нажатия и отпускания кнопок в прерываниях и записывать их в буфер. Чтение и опустошение буфера будет выполнять главная программа looр.
Рекомендую не торопиться и для начала освоить обработку нажатия кнопок. У двух кнопок могут быть 4 состояния, из которых надо рассматривать как минимум 3, а не 2 как в вашей программе.
//#define stepPin 9 //#define dirPin 8 #define button1 2 #define button2 3 // любые свободные выводы, в том числе 13 со встроенным в плату светодиодом #define LED1 6 #define LED2 8 void setup() { pinMode(LED1 , OUTPUT); pinMode(LED2 , OUTPUT); pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); digitalWrite(LED1 , HIGH) ; delay(200); digitalWrite(LED1 , LOW); digitalWrite(LED2 , HIGH) ; delay(200); digitalWrite(LED2 , LOW); } void loop() { boolean b1, b2; b1=digitalRead(button1); b2=digitalRead(button2); if((b1==LOW) && (b2==HIGH)) {digitalWrite(LED1, HIGH); digitalWrite(LED2, LOW);} else; // нажата b1 if((b1==HIGH)&& (b2== LOW)) {digitalWrite(LED1, LOW); digitalWrite(LED2, HIGH);} else; // нажата b2 if((b1==HIGH)&& (b2== HIGH)) {digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH);} else; // b1 b2 не нажаты if((b1==LOW) && (b2== LOW)) {digitalWrite(LED1, LOW); digitalWrite(LED2, LOW);} else; // b1 b2 нажаты delay(250); // таймаут в четверть секунды digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); //гасим LED1 LED2 и возвращаемся в опрос кнопок в loop }Не тот алгоритм: от одной кнопки крутится в одну сторону постоянно, от другой в другую, пока держишь кнопку.
Не тот алгоритм: от одной кнопки крутится в одну сторону постоянно, от другой в другую, пока держишь кнопку.
Не может быть в отладчике он считает 400 в одну сторону 100 в другую а вторая крутит пока держиш, все как вы просили в #9 (Вперед шагает на 400 шагов, назад на 100. В принципе то что надо. Как правильно задействовать кнопку на пине 2, чтобы при нажатии на нее мотор постоянно крутился обратно)
#define stepPin 9 #define dirPin 8 #define button1 2 #define button2 3 bool f_step; bool kn_bt1; bool kn_bt2; uint32_t temp = millis(); int mu_step = 800; void setup() { pinMode(stepPin , OUTPUT); pinMode(dirPin , OUTPUT); pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); digitalWrite(stepPin , LOW); digitalWrite(dirPin , LOW); } void loop() { if (digitalRead(button1) == LOW ) { kn_bt1 = 1; kn_bt2 = 0; } if (digitalRead(button2) == LOW) { kn_bt1 = 0; kn_bt2 = 1; mu_step = 800; digitalWrite(dirPin, HIGH); } else { kn_bt2 = 0; digitalWrite(dirPin, LOW); } if (kn_bt1 && millis() - temp >= 2) { temp = millis(); f_step = !f_step; mu_step--; if (mu_step == 0 && digitalRead(dirPin) == LOW) { digitalWrite(dirPin, HIGH); mu_step = 200; } if (mu_step == 0 && digitalRead(dirPin) == HIGH) { digitalWrite(dirPin, LOW); kn_bt1=0; } if (mu_step > 0) digitalWrite(stepPin, f_step); } if (kn_bt2 && millis() - temp >= 2) { temp = millis(); f_step = !f_step; digitalWrite(stepPin, f_step); } }Спасибо за помощь. Вот снял видео, как твой код работает: https://cloud.mail.ru/public/8YeU/DevHnZp6P
А вот как должно работать, но мой код кривой: https://cloud.mail.ru/public/AbPE/eJ2pi3Mwa
Да я как раз и пытаюсь и понять и разобраться, но знаний не хватает.
ДА прошу прощения, вкралась ошибочка
#define stepPin 9 #define dirPin 8 #define button1 2 #define button2 3 bool f_step; bool kn_bt1; bool kn_bt2; uint32_t temp = millis(); int mu_step = 800; void setup() { pinMode(stepPin , OUTPUT); pinMode(dirPin , OUTPUT); pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); digitalWrite(stepPin , LOW); digitalWrite(dirPin , LOW); } void loop() { if (digitalRead(button1) == LOW ) { kn_bt1 = 1; kn_bt2 = 0; digitalWrite(dirPin, LOW); } if (digitalRead(button2) == LOW) { kn_bt1 = 0; kn_bt2 = 1; mu_step = 800; digitalWrite(dirPin, HIGH); } else { kn_bt2 = 0; } if (kn_bt1 && millis() - temp >= 2) { temp = millis(); f_step = !f_step; mu_step--; if (mu_step <= 0 && digitalRead(dirPin) == LOW) { digitalWrite(dirPin, HIGH); mu_step = 200; } if (mu_step <= 0 && digitalRead(dirPin) == HIGH) { digitalWrite(dirPin, LOW); kn_bt1=0; } if (mu_step > 0) digitalWrite(stepPin, f_step); } if (kn_bt2 && millis() - temp >= 2) { temp = millis(); f_step = !f_step; digitalWrite(stepPin, f_step); } }ДА прошу прощения, вкралась ошибочка
Ну уж если у местных Гуру ошибки случаются, то что же про меня говорить! Спасибо за помощь, но...
При первом нажатии на КН1 мотор крутится на 1 оборот, потом возвращается на 1/4 обратно. При повторном нажатии на КН1 мотор крутится только на 1/4 оборота, потом возвращается на 1/4 обратно. При нажатии на КН2 мотор крутится в обраном направлении сколько надо. После этого КН1 один раз работает правильно, потом только на 1/4 оборота. https://cloud.mail.ru/public/NDsk/5hYu5D8MP
А можно добавить паузу между циклами при длительном нажатии на КН1?
Начнем с того что я не гуру а такойже любитель как и ВЫ. Во вторых это называется отладка. Пробуйте так
#define stepPin 9 #define dirPin 8 #define button1 2 #define button2 3 bool f_step; bool kn_bt1; bool kn_bt2; uint32_t temp = millis(); int mu_step = 800; void setup() { pinMode(stepPin , OUTPUT); pinMode(dirPin , OUTPUT); pinMode(button1, INPUT_PULLUP); pinMode(button2, INPUT_PULLUP); digitalWrite(stepPin , LOW); digitalWrite(dirPin , LOW); } void loop() { if (digitalRead(button1) == LOW ) { kn_bt1 = 1; kn_bt2 = 0; digitalWrite(dirPin, LOW); } if (digitalRead(button2) == LOW) { kn_bt1 = 0; kn_bt2 = 1; mu_step = 800; digitalWrite(dirPin, HIGH); } else { kn_bt2 = 0; } if (kn_bt1 && millis() - temp >= 2) { temp = millis(); f_step = !f_step; mu_step--; if (mu_step <= 0 && digitalRead(dirPin) == LOW) { digitalWrite(dirPin, HIGH); mu_step = 200; } if (mu_step <= 0 && digitalRead(dirPin) == HIGH) { digitalWrite(dirPin, LOW); mu_step = 800; kn_bt1=0; } if (mu_step > 0) digitalWrite(stepPin, f_step); } if (kn_bt2 && millis() - temp >= 2) { temp = millis(); f_step = !f_step; digitalWrite(stepPin, f_step); } }Восара! Я просто стоя аплодирую ТС! Тебя развели на халявное написание кода ленивому недоумку, а ты еще извиняешься? АБАЛДЕТЬ!
Цыганка развела на деньги, а ты, типа: "Простите, что что купюры мятые...".
Я, как доктор, могу заявить, что острые пароксизмы наглости, почти на 100% купируются "на..уй терапией". Очень рекомендую. Также эффективно при дамских истериках.
Начнем с того что я не гуру а такойже любитель как и ВЫ. Во вторых это называется отладка. Пробуйте так
Ну, по стравнению со мной, ГУРУ!
Заработало! Большое спасибо!Путался втиснуть паузу между циклами delay(500), так тормозит все... Теперь буду пробовать потенциометры прилаживать...
Vosara!
Большое спасибо за помощь!
Что же касается написавшего комментарий "доктора" то, видимо от жадности и сильно жмущей короны, ему совсем поплохело! Не стоит на таких даже обращать внимание!
Еще раз спасибо за помощь!
Спасибо за понимание! Как доделаю проект, покажу, что получилось!
боюсь расстроить вас... мир не совершенен.
Путался втиснуть паузу между циклами delay(500), так тормозит все...
Вам вместо задержки нужно вставить блокировку кнопки , чтобы она не срабатывала до отпускания. Примерный код привожу а вставите его сами
bool f_button1 = 0; //Создаем переменную if (digitalRead(button1) == LOW && !f_button1 == 0) { f_button1 = 1; } if (f_button1 == 1 && digitalRead(button1) == HIGH) { f_button1 = 0; }Спасибо!