Возможно ли реализовать ?
- Войдите на сайт для отправки комментариев
Нужна помощь, есть моторчик с встроенным переменным резистором, он подключен, данные с переменного резистора я получил, а вот код не могу написать)),сразу скажу я профан полный в программировании, я хочу что бы при 1 нажатии на кнопку моторчик принимал одну позицию при втором нажатии вторую позицию при третьем третью и на четвертом нажатии возвращался в 1 положение, я уже пробовал switch case, if else видимо я вообще не в том направлении мыслю. Народ помогите плиз а то я уже себе голову сломал, сейчас когда моторчик не в правом положении, он доходит до правого и выключается, и при втором нажатии, он вместо того что бы начать крутится в обратную сторону, крутится в туже, и только когда нажата кнопка
И ещё вопрос: можно ли задать переменную не просто целое число а например промежуток чисел между 400-450 ?
#define level 2
int enl = 6; // enable
int key1 = 12; // номер порта первой кнопки
int motorleft = 2; // номер первого порта для сигнала управления двигателем (влево)
int motorright = 4; // номер второго порта для сигнала управления двигателем (вправо)
int val_min = 450; // объявление переменной. Уровень крайнего левого положения заслонки
int val_max = 900; // объявление переменной. Уровень крайнего правого положения заслонки
int val_centr = 650; // объявление переменной. Уровень среднего положения заслонки
void setup()
{
pinMode (enl, OUTPUT); // enable
pinMode (key1, INPUT); // порт первой кнопки настроить на вход
pinMode (motorleft, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход
pinMode (motorright, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход
digitalWrite(motorleft,0); // Выключить первый порт управления двигателем
digitalWrite(motorright,0); // Выключить второй порт управления двигателем
}
void loop() // основная часть программы
{
if (digitalRead (key1) == 1) // если нажата кнопка
if (level < 450)
{
digitalWrite(enl,1);
digitalWrite(motorright,1); // включить двигатель в левом направлении движения
while (analogRead(level)>=val_max) // выполнять, пока заслонка не примет нужное положение
{}
digitalWrite(motorright,0); // Выключить двигатель
digitalWrite(enl,0);
}
else if (level > 900)
{
digitalWrite(enl,1);
digitalWrite(motorleft,1); // включить двигатель в левом направлении движения
while (analogRead(level)<val_min) // выполнять, пока заслонка не примет нужное положение
{}
digitalWrite(motorleft,0); // Выключить двигатель
digitalWrite(enl,0);
}
}
Интересный моторчик. Если это моторчик от проигрывателя типа магнитофон или плеер, то хочу разочаровать - переменный резистор там нужен для регулировки встроеннго ШИМ регулятора скорости. То есть когда ты вращаешь этот переменник ты управляешь шимом. И скорее всего из-за этого у тебя проблемы. Но тут и я могу ошибаться, но советую всеже присмотреться, есть ли там какое либо подобие платы с SMD деталюшками.
Я ерунду ляпнул, это не моторчик а сервопривод, внутри двигатель постоянного тока с червячной передачей и ползунковый резистор обратной связи. двигатель питается от 2-ой цепи с помощью драйвера двигателя КР1128КТ4. И у меня сто процентов беда с кодом )
Я пока не очень понял, как ты им управляешь, но вижу несколько странных моментов в строке 23, ты проверяешь, что значение меньше чем минимум 450, а в строке 32, ты проверяешь, что значение больше чем 900, а если значение посередине, то ничего не надо делать?
Еще со скобками, странная история, в 22 строке if (digitalRead (key1) == 1), а дальше не открывается скобка, ты используй правило отступов, в зависимости от уровня вложенности, будет виднее, что ты делаешь, внутри чего.
Так я глюканул, в последнем посте, там скобка необязательна, но все равно форматирование, сильно добавляет читаемости
#define level 2 int enl = 6; // enable int key1 = 12; // номер порта первой кнопки int motorleft = 2; // номер первого порта для сигнала управления двигателем (влево) int motorright = 4; // номер второго порта для сигнала управления двигателем (вправо) int val_min = 450; // объявление переменной. Уровень крайнего левого положения заслонки int val_max = 900; // объявление переменной. Уровень крайнего правого положения заслонки int val_centr = 650; // объявление переменной. Уровень среднего положения заслонки void setup() { pinMode (enl, OUTPUT); // enable pinMode (key1, INPUT); // порт первой кнопки настроить на вход pinMode (motorleft, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход pinMode (motorright, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход digitalWrite(motorleft,0); // Выключить первый порт управления двигателем digitalWrite(motorright,0); // Выключить второй порт управления двигателем } void loop() // основная часть программы { if (digitalRead (key1) == 1) // если нажата кнопка if (level < 450) { digitalWrite(enl,1); digitalWrite(motorright,1); // включить двигатель в левом направлении движения while (analogRead(level)>=val_max) // выполнять, пока заслонка не примет нужное положение {} digitalWrite(motorright,0); // Выключить двигатель digitalWrite(enl,0); } else if (level > 900) { digitalWrite(enl,1); digitalWrite(motorleft,1); // включить двигатель в левом направлении движения while (analogRead(level)<val_min) // выполнять, пока заслонка не примет нужное положение {} digitalWrite(motorleft,0); // Выключить двигатель digitalWrite(enl,0); } }Согласен, не очень понятно, как именно должно происходить управление, и в твоем, коде ты даже не пытаешь считать количество нажатий, а я так понял, ты их хочешь считать? Ты напиши какие положения заслонки должны быть для каких случаев, я так понимаю, от них все зависит.
Я этот скреч писал, чтобы хотя бы реализовать- при первом нажатии мотор едет вправо до у пора, после второго влево до упора, ну ща пока в магазин ходил, подумал, а если при начале работы программы мотор будет автоматически двигатся в крайнее левое положение например, и после этого уже начинать отсчет типо 1 нажатие val_2position второе нажатие val_3position, третье val_right, четвертое обратно возвращаться в val_left, может кто нибудь скинуть пример? как количество нажатий кнопок считать ? и как реализовать чтобы после 4 нажатия программа опять начала заново отсчитывать ? и самый главный вопрос можно ли объявить переменную не целое число, а промежуток чисел например val_left что бы был промежутком от 450-500
Cамый главный вопрос можно ли объявить переменную не целое число, а промежуток чисел например val_left что бы был промежутком от 450-500
нужено просто использовать двойную проверку типа
if (level=>450){ if (level=<500){ ну а тут то что нужно сделать } }ничего не понял что у тебя происходит с переменной level ? она обявлена как номер аналогового порта, но дальше конструкция непонятная if (level < 450) т.е присвоено значение 2 а ты спрашиваеш не меньше ли оно 450, нужно содать переменную например levelres и в неё опрашивать твой порт т.е. levelres=analogRead(level);
а далеше опрос так if (levelres < 450)
вот сдесь
if (digitalRead (key1) == 1) // если нажата кнопка if (level < 450) { digitalWrite(enl,1); digitalWrite(motorright,1); после первого условия всё таки нужна круглая скобка если ты хочеш что бы всё внутренность выполнялась по условиюсейчас попробую всё слепить в кучу
#define level 2 int enl = 6; // enable int key1 = 12; // номер порта первой кнопки int motorleft = 2; // номер первого порта для сигнала управления двигателем (влево) int motorright = 4; // номер второго порта для сигнала управления двигателем (вправо) int val_min = 450; // объявление переменной. Уровень крайнего левого положения заслонки int val_max = 900; // объявление переменной. Уровень крайнего правого положения заслонки int val_centr = 650; // объявление переменной. Уровень среднего положения заслонки int levelres;// переменная для значения положения заслонки int bcount;// счётчик нажатий кнопки void setup() { pinMode (enl, OUTPUT); // enable pinMode (key1, INPUT); // порт первой кнопки настроить на вход pinMode (motorleft, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход pinMode (motorright, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход digitalWrite(motorleft,0); // Выключить первый порт управления двигателем digitalWrite(motorright,0); // Выключить второй порт управления двигателем } void loop(){ // основная часть программы levelres=analogRead(level);// считываем значение положения двигателя if (digitalRead (key1) == 1){ // если нажата кнопка bcount++;// увеличиваем заначение счётчика нажатия кнопки if (levelres>450){ if (levelres<500){ digitalWrite(enl,1); while (analogRead(level)>=val_max) {// крутим мотор пока выполняется условие digitalWrite(motorright,1); // включить двигатель в левом направлении движения } digitalWrite(motorright,0); // Выключить двигатель } } else if (level > 900) { digitalWrite(enl,1); while (analogRead(level)<val_min) // выполнять, пока заслонка не примет нужное положение { digitalWrite(motorleft,1); // включить двигатель в левом направлении движения } digitalWrite(motorleft,0); // Выключить двигатель digitalWrite(enl,0); } } }ну как то так , может всё таки с кодом будет проще, счётчик кнопки я ввёл но ничего сним не делал так как не совсем понял задачу
icms, спасибо большое, да на самом деле сначало все было как ты написал, просто я уже столько раз код переписывал изпользуя разные операторы, что совсем запутался, ну сейчас попробую исходить из того что ты написал, ещё раз спасибо
icms уже написал, но я тут все равно повешу, упрощенный код, для случая, подсчета нажатий в цикле без самого управления двигателем
int pressCount = 0; //подсчет нажатий int buttonPin = 12; void setup() {Serial.begin(9600);} void loop() { if (digitalRead (buttonPin) == HIGH) { // если нажата кнопка, то все ниже if (pressCount ==3) //если уже нажато 3 раза, то это четвертый pressCount = 0; // обнуляем на четвертый раз else pressCount++; switch (pressCount){ case 0: Serial.println("0"); //тут все, что надо для случая когда обнулили, т.е на 4ый раз break; case 1: Serial.println("1"); //тут все, что надо для случая первого нажатия break; case 2: Serial.println("2"); //второго break; case 3: Serial.println("3"); //третьего break; } delay(300); //в реальности он не нужен, т.к. вращение займет время } }Приветствую.
Давай попробуем немного иначе если я правильно понял конструкцию порт enl(6) включает двигатель, port motorleft(3) и motorright(4) заведуют направлением вращения предлогаю добавить 3 светодиода, чтобы не гадать какой режим выбран, и еще одну кнопку для перебора режимов в обратную сторону ( не обязательно)
#define level 2 // не знаю к чему это здесь, оставлено без изменения int enl = 6; // enable int POS = 0; // аналоговый порт 0. измерение положения заслонки int val_pos=500; // текущее, измеряемое положение заслонки int motorleft = 3; // номер первого порта для сигнала управления двигателем (влево) int motorright = 4; // номер второго порта для сигнала управления двигателем (вправо) int gist=3; // вносим допуск на погрешность позиционирования заслонки против износа механизма за счет погрешностей измерения int valve[] = {0L, 450L, 650L, 900L, 0L}; // заданные стандартные положения заслонки // int val_min = valve[1]; // объявление переменной. Уровень крайнего левого положения заслонки // int val_centr = valve[2]; // объявление переменной. Уровень среднего положения заслонки // int val_max = valve[3]; // объявление переменной. Уровень крайнего правого положения заслонки int led1 = 7; // индикация выбранной позиции 1 int led2 = 8; // индикация выбранной позиции 2 int led3 = 9; // индикация выбранной позиции 3 int key2 = 2; // номер порта первой кнопки INT0 int key3 = 3; // номер порта второй кнопки INT1 volatile int keystate2 = LOW; volatile int keystate3 = LOW; int keymode=1; // Номер заданной позиции // Обработка прерывания "INT0" (нажата Кнопка 2) void keypres2() { keystate2 = !keystate2; if (keystate2 > HIGH ) { keymode += 1; if (keymode > 3) { keymode = 1; } } } // Обработка прерывания "INT1" (нажата Кнопка 3) void keypres3() { keystate3 = !keystate3; if (keystate3 > HIGH ) { keymode -= 1; if (keymode < 1) { keymode = 3; } } } void setup() { pinMode(led1, OUTPUT); // индикация выбранной позиции 1 pinMode(led2, OUTPUT); // индикация выбранной позиции 2 pinMode(led3, OUTPUT); // индикация выбранной позиции 3 pinMode(enl, OUTPUT); // enable pinMode(motorleft, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход pinMode(motorright, OUTPUT); // порт сигнала управления двигателем (влево), настроить на выход pinMode(key1, INPUT); // порт первой кнопки настроить на вход pinMode(key2, INPUT); // порт первой кнопки настроить на вход digitalWrite(enl,0); // отключение хода ? digitalWrite(motorleft,0); // Выключить первый порт управления двигателем digitalWrite(motorright,0); // Выключить второй порт управления двигателем attachInterrupt(0, keypres2, RISING); // Запуск ожидания кнопки2 // attachInterrupt(1, keypres3, RISING); // Запуск ожидания кнопки3. можно обойтись и одной. } void loop() // основная часть программы { digitalWrite(enl,0); // остановить мотор digitalWrite(motorleft,0);} // отключить движение влево digitalWrite(motorright,0);} // отключить движение вправо digitalWrite(led1,0); // выключить 1 digitalWrite(led1,0); // выключить 2 digitalWrite(led1,0); // выключить 3 digitalWrite(6+keymode,1); // включить индикатор текущего режима val_pos=analogRead(POS); IF (val_pos>=valve[keymode]+gist) { digitalWrite(motorleft,1) // включить движение влево while (analogRead(POS)>=valve[keymode]){ // Двигать влево пока заслонка не примет нужное положение digitalWrite(enl,1); // включить движение } digitalWrite(enl,0); // остановить мотор digitalWrite(motorleft,0); // отключить движение влево } IF (val_pos<=valve[keymode]-gist) { digitalWrite(motorright,1); // включить движение вправо while (analogRead(POS)<=valve[keymode]){ // Двигать вправо пока заслонка не примет нужное положение digitalWrite(enl,1); // включить движение } digitalWrite(enl,0); // остановить мотор digitalWrite(motorright,0); // отключить движение вправо } digitalWrite(enl,0); // остановить мотор }Тут на форуме появилась удобная кнопочка для вставки исходного кода (красные скобочки с подписью code). Если ею пользоваться, то форматирование будет так как сейчас (я просто помодерировал немного и подправил Ваше сообщение).
Probelzaelo, icms, Modular спасибо вам большое за помощь
Но у меня так ничего и не получилось)) но Probelzelo) сейчас ответил на остававшиеся у меня вопросы на которые не успели ответить остальные, просто сегодня мне попался шаговый двигатель от печки Приоры http://auto-geo.ru/shop/product_info.php?cPath=38&products_id=42697 и с помощью когда Modulara я реализовал все что мне было нужно буквально за 5 минут )) сейчас я жду ЖК дисплей через который я буду выводить информацию так что я думаю это только начало ))
про Enable: я использую драйвер двигателя L293d Точне КР1128КТ4, в дата-шите написано что это: Управление третьим состоянием 1 и 2 каналов, во всех примерах что я видел на него подавался, и я так понимал что это активирует чип, но сегодня когда я подключил шаговый двигатель от Приоры я забыл вписать туда enable, и только потом заметил что он и без него работает, и вообще я филолог, у меня тут мир полных открытий )) кстати я обязательно доделаю и с тем редуктором, русские не сдаются)) а сейчас хочу порадоваться тому что сделал и что работает ))
Вот кстати код, написан на основе кода который написал Modular, может ошибки есть какие ?)
#include <Stepper.h> #define STEPS 360 Stepper stepper(STEPS, 3, 4, 5, 2); int pol = 5; int x = 0 ; int pressCount = 0; //подсчет нажатий int buttonPin = 12; //порт кнопки void setup() { Serial.begin(9600); stepper.setSpeed(30); } void loop() { if (digitalRead (buttonPin) == HIGH) { // если нажата кнопка, то все ниже if (pressCount ==3) //если уже нажата 3 раза, то это четвертый pressCount = 0; // обнуляем на четвертый раз else pressCount++; switch (pressCount){ case 0: Serial.println("0"); //вернутся в 1 положение { stepper.step(1000); } break; case 1: Serial.println("1"); //2 положение заслонки { stepper.step(-360); } break; case 2: Serial.println("2"); //3 положение заслонки { stepper.step(-240); } break; case 3: Serial.println("3"); //4 положение заслонки { stepper.step(-400); } break; } delay(300); } }ЖК дисплей это просто ужас как хорошо, но с ним вопросов возникнет примерно столько же как с двигателем. ;))
Судя по описанию мелкосхемы там только силовые ключи. Поэтому чтобы заставить ШД вращаться видимо придется что то делать и с другими входами, а именно заняться подачей на них управляющих шаговых импульсов, на вскидку обнаружилась библиотека для управления ШД - steper. Для ее освоения весьма полезно будет ознакомиться с сайтами http://wiring.org.co/reference/libraries/Stepper/Stepper.html и http://rln.nnov.ru/index.php?pid=55 там описано как пользовать библиотеку для обработки ШД. Вероятно для управления ШД вам придется задействовать аж 4 порта контроллера. А сигналы Е1 и Е2 просто подключить к +5.