Управление приводом
Щас практически на каждом китайском сервотестере стоит переменник и батарея кнопок. В общем случае там организован цикл с частотой 50 Гц. Первыми опрашиваются кнопки и от них серва либо уходит в заданное крайнее положение, либо начинает елозить из края в край. Опрос канала АЦП на время нажатия кнопки должен блокироваться. Когда кнопки отпущены, доходит очередь до переменника. Для резвого и вменяемого распределения ресурсов такие вещи лучше писать на ассемблере. Для задачи автора темы достаточно чего-то совсем мелкого, типа тини13а.
Управление приводом
Егор вот посмотри здесь ,правда там для сервы ,но может что то интересное для себя найдете там с права оглавление,есть и написанные программы под Пик контролер.
alex-exe.ru/radio/robotics/servo-pic/
Всем спасибо за советы, особенно Вам Дмитрий. Про Ардуино даже и не думал… Попробую на нем сделать.
Согласен, на концевиках проще всего, но моторчик в данном редукторе имеет хорошую инерцию, и после пары применений на схеме с концевиками, я этот редуктор скорей всего выкину.
Резистор вроде в ТЗ присутствовал всегда, см. вложение.
И не надо говорить, что я переобуваюсь… Хотя да, скорей всего я буду переобуваться, т.к. сам до конца не знаю что в итоге хочу получить, и я не только про привод…
Сам руковожу проектным отделом, самого бесят заказчики, которые дают невнятное ТЗ, а потом переобуваются в самый последний момент.
Согласен, на концевиках проще всего, но моторчик в данном редукторе имеет хорошую инерцию, и после пары применений на схеме с концевиками, я этот редуктор скорей всего выкину.
Погуглите фразу “кулачок механизм”.
Все, стоп. Забыли про концевики и кулачковые механизмы… Это не наш метод, и не интересно… Пока электриком работал на них насмотрелся.
Буду делать на Ардуино. Сижу изучаю…
Все, стоп. Забыли про концевики и кулачковые механизмы… Это не наш метод, и не интересно… Пока электриком работал на них насмотрелся.
Буду делать на Ардуино. Сижу изучаю…
Вы только не исчезайте , всётаки будет интересен результат
Буду делать на Ардуино. Сижу изучаю…
Хотите вместе поизвращаемся. 😃 Та китайская мандула с фото всё ещё в работе. И да. Больше чем ардуинку я к ней, видимо, не подключу.
P. S. У меня случай тяжелее. Она вот к чему прикручена. Сразу не бейте. Каждый сходит с ума по-своему. 😃 Там ещё и ROS распределённый а ардуинка нодой. Надо было его на помойку отпереть. Теперь жалко.
Что это? С одной стороны напоминает человеческий скелет… С другой - концептуальную вешалку
И то и другое верно. 😃 И вопрос хороший. Это нечто упрощённо подделывающее человеческую анатомию, из всякого мусора, но с компьютерами в башке и в заднице. Оно пластмассовое и гнётся. Ну бред короче, но забористый оказался. 😃
И снова обращаюсь к Вам за помощью, нужно проверить код… Двигаюсь конечно потихоньку, времени мало свободного, но все же двигаюсь…
Итак, решил начать с малого. Так сказать без всяких кнопок и прочего. Оставляю только мотор и потенциометр (так сказать код открытия):
int motorPin = 10; // мотор подключен к цифровому выводу 10
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int val = 0; // переменная для хранения считанного значения с потенциометраvoid setup() {
pinMode(motorPin, OUTPUT); // переключение вывода в режим “выход”
}
void loop() { // этот цикл выполняется бесконечное количество раз
val = analogRead(analogPin); // записываем в переменную показания с потенциометра
if (val<700) {
analogWrite(motorPin, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val>700&&val<1000) {
analogWrite(motorPin, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val>1000) {
analogWrite(motorPin, 0); // если переменная меньше больше 1000 отрубаем ШИМ
}
}
Я в правильном направлении двигаюсь?
/В правильном.
Только учтите
/
{Analogread() Щупает от 0 до 1023,
А AnalogWrite() может вписать только до 255.}
/Constrain между ними поставьте. doc.arduino.ua/ru/prog/Constrain
И только если это по кругу как пони.
Ну для начала.
что я делаю/
И снова здравствуйте, и снова нужна ваша помощь.
к предыдущему скетчу пытаюсь добавить кнопку:
int motorPin = 10; // мотор подключен к цифровому выводу 10
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int buttom1Pin = 22; // кнопка подключен к входу 22
int val = 0; // переменная для хранения считанного значения с потенциометра
int openn = 0; // переменная для хранения считанного значения с потенциометраvoid setup() {
pinMode(motorPin, OUTPUT); // переключение вывода в режим “выход”
}
void loop() { // этот цикл выполняется бесконечное количество раз
val = analogRead(analogPin); // записываем в переменную показания с потенциометра
if (digitalRead(buttom1Pin) == HIGH) {
do {
if (val<500) {
analogWrite(motorPin, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val>500&&val<1000) {
analogWrite(motorPin, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val>1000) {
analogWrite(motorPin, 0); // если переменная меньше больше 1000 отрубаем ШИМ
}
}while (val>1000);
}
}
Но, при симуляции в протеусе происходит следующее:
- начальные параметры, кнопка не нажата, переменник в нуле, мотор не крутится;
- при нажатии кнопки начинает вращатся мотор с максимальной скоростью;
- начинаю “крутить” переменник, скорость мотора изменяется согласно алгоритма скетча;
- при достижении переменника 100%, мотор останавливается.
Вроде все хорошо, но…
Если я правильно понимаю свой скетч, то после всех этих действий, изменении положения резистора и повторного нажатия кнопки цикл (do-while) должен запустится заново, и мотор снова должен вращатся по алгоритму, но этого почему-то не происходит…
В чем проблема?
Не знаю, смотрит кто нибудь эту тему или нет…
Переделал предыдущий скетч теперь все работает.
int motorPin1 = 10; // мотор подключен к цифровому выводу 10
int motorPin2 = 11; // мотор подключен к цифровому выводу 11 (реверс)
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int buttom1Pin = 22; // АЦЦ
int buttom2Pin = 23; // кнопка подключен к входу 22
int val = 0; // переменная для хранения считанного значения с потенциометра
int openn = 0; // переменная фиг знает для чегоvoid setup() {
pinMode(motorPin1, OUTPUT); // переключение вывода в режим “выход”
pinMode(motorPin2, OUTPUT); // переключение вывода в режим “выход”}
void loop() { // этот цикл выполняется бесконечное количество раз
val = analogRead(analogPin);
if (digitalRead(buttom2Pin)==HIGH && val<500 && openn == 0) {
openn = 1;
}
if (digitalRead(buttom2Pin)==HIGH && val>500 && openn == 0) {
openn = 2;
}if (openn == 1) {
if (val < 250) {
analogWrite(motorPin1, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val>250 && val < 1000) {
analogWrite(motorPin1, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
analogWrite(motorPin1, 0); // если переменная меньше больше 1000 отрубаем ШИМ
openn = 0;
}
}if (openn == 2) {
if (val > 500) {
analogWrite(motorPin2, 255); // если переменная меньше 700 включаем ШИМ на полную
}
if (val > 100 && val < 500) {
analogWrite(motorPin2, 150); // если переменная меньше от 700 до 1000 убавляем ШИМ на некоторое значение
}
if (val < 100) {
analogWrite(motorPin2, 0); // если переменная меньше больше 1000 отрубаем ШИМ
openn = 0;
}
}
}
Но теперь появились другие проблемы и новые исходные данные. Но это уже совсем другая история 😁
Продолжаю тему сам с собой 😁
В качестве контроллера выбрал Arduino Mega 2560 R3 (продавали в моем городе, не хотелось долго ждать с Али).
В качестве драйвера двигателя взята плата L298, спасибо за совет leons.
драйвер пока не пришел с алика, так что пока все тестирую в протеусе.
Схема которую собрал в протеусе (во вложении).
Далее код который написал:
// ----------------------------------------------------------------управления приводом
int motorPin1 = 24; // мотор подключен к цифровому выводу 10
int motorPin2 = 25; // мотор подключен к цифровому выводу 11 (реверс)
int motorPin3 = 10; // мотор подключен к цифровому выводу 10 (PWM)
int analogPin = A0; // потенциометр подключен к аналоговому выходу А0
int buttom1Pin = 22; // АЦЦ
int buttom2Pin = 23; // кнопка подключен к входу 23
int val = 0; // переменная для хранения считанного значения с потенциометра
int openn = 0; // переменная для хранения открытия по кнопке
int opennacc = 0; // переменная для хранения открытия по АССint led1 = 51;
int led2 = 52;
int led3 = 53;unsigned long currentTime;
unsigned long loopTime;//------------------------------------------------------------------------------------------------------
void setup() {
// ----------------------------------------------------------------управления приводом
pinMode(motorPin1, OUTPUT); // переключение вывода в режим “выход”
pinMode(motorPin2, OUTPUT); // переключение вывода в режим “выход”
pinMode(motorPin3, OUTPUT); // переключение вывода в режим “выход”
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);currentTime = millis(); // считываем время, прошедшее с момента запуска программы
loopTime = currentTime;//------------------------------------------------------------------------------------------------------
}
void loop() { // этот цикл выполняется бесконечное количество раз
// ----------------------------------------------------------------управления приводом
val = analogRead(analogPin);
currentTime = millis();if (digitalRead(buttom1Pin) == HIGH && opennacc == 0 && currentTime >= (loopTime + 10000)) {
opennacc = 1;
loopTime = currentTime;
}if (digitalRead(buttom1Pin) == LOW && currentTime >= (loopTime + 10000)) {
opennacc = 0;
loopTime = currentTime;
}if (digitalRead(buttom2Pin) == HIGH && val < 500 && openn == 0 && opennacc == 2) {
openn = 1;
}if (digitalRead(buttom2Pin) == HIGH && val > 500 && openn == 0 && opennacc == 2) {
openn = 2;
}if (opennacc == 1) { // открытия привода по АСС
if (val < 700) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 250 включаем ШИМ на полную
}
if (val >= 700 && val <= 1000) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
opennacc = 2; // открыт по АСС
}
}if (opennacc == 0) { // Закрытие привода по АСС
if (val > 300) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 500 включаем ШИМ на полную
}
if (val >= 20 && val <= 300) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 150); // если переменная от 100 до 500 убавляем ШИМ на некоторое значение
}
if (val < 20) {
digitalWrite(motorPin1, LOW);
digitalWrite(motorPin2, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 100 отрубаем ШИМ
opennacc = 0;
}
}if (openn == 1 && opennacc == 2) { //Открытие привода по кнопке
if (val < 700) {
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 250 включаем ШИМ на полную
}
if (val >= 700 && val <= 1000) {
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
digitalWrite(motorPin1, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
openn = 0;
}
}if (openn == 2) { // Закрытие привода по кнопке
if (val > 300) {
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 255); // если переменная больше 500 включаем ШИМ на полную
}
if (val >= 20 && val <= 300) {
digitalWrite(motorPin2, HIGH);
analogWrite(motorPin3, 150); // если переменная от 100 до 500 убавляем ШИМ на некоторое значение
}
if (val < 20) {
digitalWrite(motorPin2, LOW);
analogWrite(motorPin3, 0); // если переменная меньше меньше 100 отрубаем ШИМ
openn = 0;
}
}//-------------------------индикация переменной opennacc временно
if (opennacc == 0){
digitalWrite(led1, HIGH);
}else {digitalWrite(led1, LOW);
}if (opennacc == 1){
digitalWrite(led2, HIGH);
}else {digitalWrite(led2, LOW);
}if (opennacc == 2){
digitalWrite(led3, HIGH);
}else {digitalWrite(led3, LOW);
}
}
//------------------------------------------------------------------------------------------------------
Вроде все работает… Если не сложно, оцените пожалуйста, может чего лишнего понаписал…
Если не сложно, оцените пожалуйста, может чего лишнего понаписал…
Номера пинов принято указывать дефайнами, нет смысла хранить их в переменных.
#define MOTOR_PIN1 24; // мотор подключен к цифровому выводу 10
#define MOTOR_PIN2 25; // мотор подключен к цифровому выводу 11 (реверс)
...
соответственно в коде написать
...
pinMode(MOTOR_PIN1, OUTPUT); // переключение вывода в режим "выход"
...
я не большой специалист, но кажется такое:
if (opennacc == 1) { // открытия привода по АСС
if (val < 700) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 255); // если переменная меньше 250 включаем ШИМ на полную
}
if (val >= 700 && val <= 1000) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, HIGH);
analogWrite(motorPin3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
}
if (val > 1000) {
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin1, LOW);
analogWrite(motorPin3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
opennacc = 2; // открыт по АСС
}
}
можно упростить до такого:
if (opennacc == 1) { // открытия привода по АСС
digitalWrite(MOTOR_PIN1 HIGH);
digitalWrite(MOTOR_PIN2, LOW);
if (val < 700) analogWrite(MOTOR_PIN3, 255); // если переменная меньше 250 включаем ШИМ на полную
if (val >= 700 && val <= 1000) analogWrite(MOTOR_PIN3, 150); // если переменная меньше от 250 до 1000 убавляем ШИМ на некоторое значение
if (val > 1000) {
analogWrite(MOTOR_PIN3, 0); // если переменная меньше больше 1000 отрубаем ШИМ
digitalWrite(MOTOR_PIN1, LOW);
opennacc = 2; // открыт по АСС
}
}
еще вам нужно будет бороться с дребезгом контактов, которого в протеусе нет, а в железе будет.
Обычно для обработки кнопок пишут отдельную функцию типа getBTN(), которая фильтрует дребезг и возвращает их состояние, а основная программа уже вызывает эту функцию и действует согласно её ответа. На истину не претендую, просто мысли 😃
ОГО! Спасибо большое за советы! Можно поподробнее насчет функции getBTN()?
Можно поподробнее насчет функции getBTN()?
схематично как-то так:
void setup() {
// начальные настройки
}
void loop() {
// основной код
switch (getBTN()) {
case 0:
// действия еcли ничего не нажато
break;
case 1:
// действия еcли нажата кнопка 1
break;
case 2:
// действия еcли нажата кнопка 2
break;
}
}
byte getBTN() {
byte btn_state;
// опрос кнопок и фильтрация дребезга
return btn_state;
}
так можно отследить не только момент нажатия, но и удержание в нажатом состоянии и отпускание, если оно конечно нужно.
А для борьбы с дребезгом самое простое делать два опроса кнопки с небольшой задержкой, сравнивать результаты и фискировать нажатие только при их совпадении. Примеров в интернетах вагон arduinomaster.ru/…/ustranenie-drebezg-kontaktov-kn…