Возможно ли реализовать ?

kentokent
Offline
Зарегистрирован: 12.03.2011

Нужна помощь, есть моторчик с встроенным переменным резистором, он подключен, данные с переменного резистора я получил, а вот код не могу написать)),сразу скажу я профан полный в программировании, я хочу что бы при 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);
}         
}


 

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

 Интересный моторчик. Если это моторчик от проигрывателя типа магнитофон или плеер, то хочу разочаровать - переменный резистор там нужен для регулировки встроеннго ШИМ регулятора скорости. То есть когда ты вращаешь этот переменник ты управляешь шимом. И скорее всего из-за этого у тебя проблемы. Но тут и я могу ошибаться, но советую всеже присмотреться, есть ли там какое либо подобие платы с SMD деталюшками.

kentokent
Offline
Зарегистрирован: 12.03.2011

Я ерунду ляпнул, это не моторчик а сервопривод, внутри двигатель постоянного тока с червячной передачей и ползунковый резистор обратной связи. двигатель питается от 2-ой цепи с помощью драйвера двигателя КР1128КТ4. И у меня сто процентов беда с кодом ) 

Zaliv
Offline
Зарегистрирован: 05.03.2011

 Я пока не очень понял, как ты им управляешь, но вижу несколько странных моментов в строке 23, ты проверяешь, что значение меньше чем минимум 450, а в строке 32, ты проверяешь, что значение больше чем 900, а если значение посередине, то ничего не надо делать?

Zaliv
Offline
Зарегистрирован: 05.03.2011

 Еще со скобками, странная история, в 22 строке if (digitalRead (key1) == 1), а дальше не открывается скобка, ты используй правило отступов, в зависимости от уровня вложенности, будет виднее, что ты делаешь, внутри чего.

Zaliv
Offline
Зарегистрирован: 05.03.2011

 Так я глюканул, в последнем посте, там скобка необязательна, но все равно форматирование, сильно добавляет читаемости
 

#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);
  }         
}

 

Modular
Offline
Зарегистрирован: 05.03.2011

Согласен, не очень понятно, как именно должно происходить управление, и в твоем, коде ты даже не пытаешь считать количество нажатий, а я так понял, ты их хочешь считать? Ты напиши какие положения заслонки должны быть для каких случаев, я так понимаю, от них все зависит.

kentokent
Offline
Зарегистрирован: 12.03.2011

Я этот скреч писал, чтобы хотя бы реализовать- при первом нажатии мотор едет вправо до у пора, после второго влево до упора, ну ща пока в магазин ходил, подумал, а если при начале работы программы мотор будет автоматически двигатся в крайнее левое положение например, и после этого уже начинать отсчет типо 1 нажатие val_2position второе нажатие val_3position, третье val_right, четвертое обратно возвращаться в val_left, может кто нибудь скинуть пример?  как количество нажатий кнопок считать ? и как реализовать чтобы после 4 нажатия программа опять начала заново отсчитывать ? и самый главный вопрос можно ли объявить переменную не целое число, а промежуток чисел например val_left что бы был промежутком от 450-500

#define level 2

int enl = 6; // enable
int key1 = 12; // номер порта первой кнопки
int motorleft = 2; // номер первого порта для сигнала управления двигателем (влево)
int motorright = 4; // номер второго порта для сигнала управления двигателем (вправо)
int val_left = 450; //  Уровень крайнего левого положения заслонки
int val_2position = 650; // 2 положение
int val_3position = 750; // 3 положение
int val_right = 900; // Уровень крайнего правого положения заслонки

 

icms
Offline
Зарегистрирован: 22.03.2011

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);
    }
  }

}

 ну как то так , может всё таки с кодом будет проще, счётчик кнопки я ввёл но ничего сним не делал так как не совсем понял задачу

kentokent
Offline
Зарегистрирован: 12.03.2011

icms, спасибо большое, да на самом деле сначало все было как ты написал, просто я уже столько раз код переписывал изпользуя разные операторы, что совсем запутался, ну сейчас попробую исходить из того что ты написал, ещё раз спасибо

Modular
Offline
Зарегистрирован: 05.03.2011

 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); //в реальности он не нужен, т.к. вращение займет время 
  }    
}

 

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

Приветствую.

 

Давай попробуем немного иначе если я правильно понял конструкцию порт 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); // остановить мотор
}

 

Alexander
Offline
Зарегистрирован: 25.04.2010

Тут на форуме появилась удобная кнопочка для вставки исходного кода (красные скобочки с подписью code). Если ею пользоваться, то форматирование будет так как сейчас (я просто помодерировал немного и подправил Ваше сообщение).

kentokent
Offline
Зарегистрирован: 12.03.2011

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); 
  }    
}

Probelzaelo
Offline
Зарегистрирован: 15.04.2011

 ЖК дисплей это просто ужас как хорошо, но с ним вопросов возникнет примерно столько же как с двигателем. ;))

Судя по описанию мелкосхемы там только силовые ключи. Поэтому чтобы заставить ШД вращаться видимо придется что то делать и с другими входами, а именно заняться подачей на них управляющих шаговых импульсов, на вскидку обнаружилась библиотека для управления ШД - steper. Для ее освоения весьма полезно будет ознакомиться с сайтами http://wiring.org.co/reference/libraries/Stepper/Stepper.html и http://rln.nnov.ru/index.php?pid=55 там описано как пользовать библиотеку для обработки ШД. Вероятно для управления ШД вам придется задействовать аж 4 порта контроллера. А сигналы Е1 и Е2 просто подключить к +5.