DTG printer / принтер планшетный

прототип dtg. планшетного принтера . собрал стенд . добавил две кнопки на ось Y и limit .
Нужна помощь !!! В написании кода с optical rotary encoder 600 pr и stepper motor nema17. для передачи сигнала от optical rotary encoder на шаговый двигатель с учетом регулирования шагов на оборот для синхронизации
теперь nema 8 крутит rotary optical encoder 600 pw на скорости 16000 мм мин наверное как у принтера движок крутит
пробовал 2 кода ниже будут и видио к ним ка энкодер справляется на ура с ними .
подскажите как далее прикрутить шаговый мотор к этому коду en . step. dir , с регулировкой числа шагов в самом скетчи .

Вписал все в один код .
все работает но код на мотор работает не так
он с каждого 3 тика энкодера должен делать один шаг а он работает так на + или - энкодера попал сигнал туда и. крутит движок при этом все кнопки и концевик остаются рабосими
мне нужно поправить код в этом месте
с 126 по 166 строку
там я делал и по таймеру и по шагам результат не меняется

код дак я думаю должен работать так упрощеннй вариант
если энкодер +1 тик
то
digitalWrite(DIR_PIN , LOW);
for (делаем 1 шаг мотор ) {

если энкодер -1 тик
то
digitalWrite(DIR_PIN , HIGH);
for (делаем 1 шаг мотор ) {

**`//Эта переменная будет увеличиваться или уменьшаться в зависимости от вращения энкодера.
volatile long temp, counter = 0;

//Пины управления шаговиком
#define STEP_PIN         2
#define DIR_PIN          5
#define ENABLE_PIN       8

//Пин кнопки
#define start_button1 7
#define start_button2 4
#define limitPin 9

//Пин энкодера
#define encA 6
#define encB 3

//Здесь можно настроить время поворота и паузы
#define move_forward_time 5    //время прямого хода в мсек
#define move_back_time 5       //время обратного хода в мсек
#define pause_time 10          //время паузы в мсек
#define frequency 600              //Время между импульсами в мксек. 1000 мксек = 1 мсек = 0.001 сек.
                                   //Частота следования импульсов 1/0.001 = 1 кГц,
                                   //Не рекомендуется устанавливать время меньше 100 мсек,
                                  // т.к. частота будет 10 кГц

//Таймер для millis()
uint32_t timer = 0;


//Логический флаг для рабочего режима
bool flag = 1;

void setup() {
  Serial.begin (9600);
  pinMode(6, INPUT_PULLUP);              // внутренний входной контакт подтягивания 6 
  pinMode(3, INPUT_PULLUP);              // внутренний входной контакт подтягивания 3
  attachInterrupt(0, ai0, RISING);
  attachInterrupt(1, ai1, RISING);

  pinMode(start_button1, INPUT_PULLUP);  //Подтягиваем кнопку к питанию
  pinMode(start_button2, INPUT_PULLUP);  //Подтягиваем кнопку к питанию
  pinMode(limitPin, INPUT_PULLUP);

  pinMode(STEP_PIN   , OUTPUT);           //Настраиваем пины управления
  pinMode(DIR_PIN    , OUTPUT);
  pinMode(ENABLE_PIN , OUTPUT);

  digitalWrite(ENABLE_PIN , HIGH);        //Выключаем мотор, чтобы не грелся


}

  void loop () {

  if( counter != temp ){
  Serial.println (counter);
  temp = counter;
  }

//КОД КОГДА  КНОПКА PIN7 НАЖАТА  И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР

  if (!digitalRead(start_button1)) {       //Если нажали на кнопку
    digitalWrite(ENABLE_PIN , LOW);       //Включаем мотор
    flag = 1;                             //Активируем флаг рабочего режима
    timer = millis();                     //Запускаем таймер
  }

  if (flag) {                                 //Если флаг активирован
    digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения


    for (int i = 0; i < 16; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот
      digitalWrite(STEP_PIN    , HIGH);
      delayMicroseconds(frequency);
      digitalWrite(STEP_PIN    , LOW);
    } while (millis() - timer < move_forward_time);
    flag = 0;                                 //Гасим флаг
    digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
  }

//КОД КОГДА  КНОПКА PIN4 НАЖАТА  И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР

  if (!digitalRead(start_button2)) {       //Если нажали на кнопку
    digitalWrite(ENABLE_PIN , LOW);       //Включаем мотор
    flag = 1;                             //Активируем флаг рабочего режима
    timer = millis();                     //Запускаем таймер
  }

  if (flag) {                                 //Если флаг активирован
    digitalWrite(DIR_PIN    , LOW);         //Задаем направление вращения


    for (int i = 0; i < 16; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот
      digitalWrite(STEP_PIN    , HIGH);
      delayMicroseconds(frequency);
      digitalWrite(STEP_PIN    , LOW);
    } while (millis() - timer < move_forward_time);
    flag = 0;                                 //Гасим флаг
    digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
    }

//КОД КОГДА LIMIT PIN9 ВКЛЮЧЕН  И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР

      if (!digitalRead(limitPin)) {           //Если нажали на кнопку     
        flag = 1;                              //Активируем флаг рабочего режима
        if (flag) {                           //Если флаг активирован
        digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
        digitalWrite(DIR_PIN    , LOW);
        for (int i = 0; i < 100; i++) {          //Выполняем нужное число шагов
      
        digitalWrite(ENABLE_PIN , LOW);      //Выключаем движок, чтобы не грелся; 
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(frequency);
        digitalWrite(STEP_PIN    , LOW);
        }
        flag = 0;                                 //Гасим флаг
        digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
    
      }         
  
    }
  
//КОД КОГДА ЭНКОДЕР ВРАЩАЕТСЯ PIN6 И PIN3   И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР 
    
  if(digitalRead(6)==LOW) {
  flag = 1;                                      //Активируем флаг рабочего режима
  timer = millis();                                //Запускаем таймер

    if (flag) {                                     //Если флаг активирован
        digitalWrite(DIR_PIN    , LOW);
        for (int i = 0; i < 5; i++) {                 //Выполняем нужное число шагов
      
        digitalWrite(ENABLE_PIN , LOW);                //Включаем мотор;
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(frequency);
        digitalWrite(STEP_PIN    , LOW);
        }  while (millis() - timer < move_back_time);   //ВРЕМЯ ВЫПОЛНЕНИЯ КОДА
        flag = 0;                                        //Гасим флаг
        digitalWrite(ENABLE_PIN , HIGH);                //Выключаем движок, чтобы не грелсяелся

    }

    }
   if(digitalRead(3)==LOW) {
  flag = 1;                                                //Активируем флаг рабочего режима
  timer = millis();                                       //Запускаем таймер

    if (flag) {                                          //Если флаг активирован
        digitalWrite(DIR_PIN    , HIGH);
        for (int i = 0; i < 5; i++) {                   //Выполняем нужное число шагов
      
        digitalWrite(ENABLE_PIN , LOW);                //Включаем мотор
        delayMicroseconds(frequency);
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(frequency);
        digitalWrite(STEP_PIN    , LOW);
        }  while (millis() - timer < move_back_time);   //ВРЕМЯ ВЫПОЛНЕНИЯ КОДА
        flag = 0;                                        //Гасим флаг
        digitalWrite(ENABLE_PIN , HIGH);                 //Выключаем движок, чтобы не грелсяелся

    }
  }

  }

//КОД КОГДА ЭНКОДЕР ВРАЩАЕТСЯ PIN6 И PIN3   И ПОДАЕТ СИГНАЛ НА МОНИТОР

  void ai0() {
  if(digitalRead(3)==LOW) {
  counter++;
  }else{
  counter--; 
  }
  }


  void ai1() {
  if(digitalRead(6)==LOW) {
  counter++;
  }else{
  counter--; 
  }
  }`**



Не уж то тяжело, прежде чем писать, посмотреть как люди пишут. Как код вставляют… Или Дэбальцево? ППЦ!

1 лайк

@vadim72

Какая помощь вам нужна? - дать денег на учебник русского языка?

if(!tic_encoder%2) { делаем шаг мотора}

То есть отрицания остатка от деления на 2 равным 0. Другими словами четное число.
А нужно:

  • 3 (хотя сработает на 2), 6 (но сработает на 4 и 6) и так далее.

Чем
if ( ! tic_encoder % 3 ) { делаем шаг мотора}

не устроило?)))

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

спасибо за дельный совет . сегодня потестю .

сделал новые тесты и выложил новое видео

рабочий код но еще допиливать буду .
еще две ставить кнопки. и мотор на ось Z
врлде нормально работает код, но я на самом деле еще не знаю как он должен быть
поэтому хочется идеально чтобы потом не возвращаться к нему
интересует только этот цикл.
//КОД КОГДА ЭНКОДЕР ВРАЩАЕТСЯ PIN6 И PIN3 И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР

//Эта переменная будет увеличиваться или уменьшаться в зависимости от вращения энкодера.
volatile long temp, motor_position, counter;

//Пины управления шаговиком
#define STEP_PIN         2
#define DIR_PIN          5
#define ENABLE_PIN       8

//Пин кнопки
#define start_button1 7
#define start_button2 4
#define limitPin 9

//Пин энкодера
#define encoder_a 6 
#define encoder_b 3

//Здесь можно настроить время поворота и паузы
#define move_forward_time 5   //время прямого хода в мсек
#define move_back_time 5     //время обратного хода в мсек
#define pause_time 60          //время паузы в мсек
#define frequency 600              //Время между импульсами в мксек. 1000 мксек = 1 мсек = 0.001 сек.
                                   //Частота следования импульсов 1/0.001 = 1 кГц, 
                                   //Не рекомендуется устанавливать время меньше 100 мсек,
								  // т.к. частота будет 10 кГц

//Таймер для millis()
uint16_t timer = 0;


//Логический флаг для рабочего режима
bool flag = 1;

void setup() {
  Serial.begin (230400);
  pinMode(6, INPUT_PULLUP);              // внутренний входной контакт подтягивания 6   
  pinMode(3, INPUT_PULLUP);              // внутренний входной контакт подтягивания 3
  attachInterrupt(0, ai0, RISING);
  attachInterrupt(1, ai1, RISING);
  
  pinMode(start_button1, INPUT_PULLUP);  //Подтягиваем кнопку к питанию
  pinMode(start_button2, INPUT_PULLUP);  //Подтягиваем кнопку к питанию
  pinMode(limitPin, INPUT_PULLUP);

  pinMode(STEP_PIN   , OUTPUT);           //Настраиваем пины управления
  pinMode(DIR_PIN    , OUTPUT);
  pinMode(ENABLE_PIN , OUTPUT);

  digitalWrite(ENABLE_PIN , HIGH);        //Выключаем мотор, чтобы не грелся
  digitalWrite(encoder_a, HIGH);
  digitalWrite(encoder_b, HIGH);
  

}

  void loop () {
 
  if( counter != temp ){
  Serial.println (counter);
  temp = counter;
  }

//КОД КОГДА  КНОПКА PIN7 НАЖАТА  И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР

  if (!digitalRead(start_button1)) {       //Если нажали на кнопку
    digitalWrite(ENABLE_PIN , LOW);       //Включаем мотор
    flag = 1;                             //Активируем флаг рабочего режима
    timer = millis();                     //Запускаем таймер
  }

  if (flag) {                                 //Если флаг активирован
    digitalWrite(DIR_PIN    , HIGH);         //Задаем направление вращения


    for (int i = 0; i < 8; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот
      digitalWrite(STEP_PIN    , HIGH);
      delayMicroseconds(frequency);
      digitalWrite(STEP_PIN    , LOW);
    } while (millis() - timer < move_forward_time);
    flag = 0;                                 //Гасим флаг
    digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
  }

//КОД КОГДА  КНОПКА PIN4 НАЖАТА  И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР
  
  if (!digitalRead(start_button2)) {       //Если нажали на кнопку
    digitalWrite(ENABLE_PIN , LOW);       //Включаем мотор
    flag = 1;                             //Активируем флаг рабочего режима
    timer = millis();                     //Запускаем таймер
  }

  if (flag) {                                 //Если флаг активирован
    digitalWrite(DIR_PIN    , LOW);         //Задаем направление вращения


    for (int i = 0; i < 8; i++) {          //Выполняем нужное число шагов 200*16 = 3200 шагов оборот
      digitalWrite(STEP_PIN    , HIGH);
      delayMicroseconds(frequency);
      digitalWrite(STEP_PIN    , LOW);
    } while (millis() - timer < move_forward_time);
    flag = 0;                                 //Гасим флаг
    digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
	}

//КОД КОГДА LIMIT PIN9 ВКЛЮЧЕН  И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР
  
      if (!digitalRead(limitPin)) {           //Если нажали на кнопку  
		digitalWrite(DIR_PIN    , LOW);
		for (int i = 0; i < 100; i++) {          //Выполняем нужное число шагов  
		
        digitalWrite(ENABLE_PIN , LOW);      //Выключаем движок, чтобы не грелся;	
	    digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(frequency);
        digitalWrite(STEP_PIN    , LOW);                                 //Гасим флаг
        digitalWrite(ENABLE_PIN , HIGH);        //Выключаем движок, чтобы не грелся
	   
      }   		
	
    } 
	
//КОД КОГДА ЭНКОДЕР ВРАЩАЕТСЯ PIN6 И PIN3   И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР	
  	
  if (counter > 0)  {
    digitalWrite(DIR_PIN    , HIGH);
		digitalWrite(ENABLE_PIN , LOW);
    digitalWrite(STEP_PIN    , HIGH);
    digitalWrite(STEP_PIN    , LOW);
    _delay_us(500);
    motor_position++;
    counter = 0;
    }
  else if (counter < 0)  {
    digitalWrite(DIR_PIN    , LOW);
		digitalWrite(ENABLE_PIN , LOW);
    digitalWrite(STEP_PIN    , HIGH);
    digitalWrite(STEP_PIN    , LOW);
    _delay_us(500);
    motor_position--;
    counter = 0;
    }
  
  } 
  
//КОД КОГДА ЭНКОДЕР ВРАЩАЕТСЯ PIN6 И PIN3   И ПОДАЕТ СИГНАЛ НА МОНИТОР

  
 
 
  void ai0()  {
    if (digitalRead(6) == digitalRead(3))
    {
        counter--;
    }
    else
    {
        counter++;
    }
  }

  void ai1()  {
    if (digitalRead(6) != digitalRead(3))
    {
        counter--;
    }
    else
    {
        counter++;
    }
  }

подскажите кто знает.
я могу во всем коде управлять нагрузкой на шаговый двигатель или снимать ее .
digitalWrite(ENABLE_PIN , LOW);
но мне кажется нужно сделать так что бы он всегда был под нагрузкой. и только она могла перейти в
digitalWrite(ENABLE_PIN , HIGH);
при условии что если encoder. в течении 1 мин не будедет выдавать больше например 10 тиков двигатель переходит в состояния
digitalWrite(ENABLE_PIN , HIGH);
и как это может сказаться на рабочем цикле когда энкодер

читал что избавится от digitalWrite код на. arduino uno. может заработать до 72 раз быстрее
может кто глянет что там лишнего

Есть, куда эту скорость пристроить?

пока нет . но вдруг потом толкать придется .
для общего развития спросил

тут почитаешь, там всё просто

 PORTD &= ~_BV(PD1);	// установить "0" (низкий уровень) на выводе PD1,

 PORTD |= _BV(PD1);	// установить "1" (высокий уровень) на выводе PD1,
1 лайк

спасибо я попробую

ua6em
спасибо за подсказку !
if(counter%2) { делаем шаг мотора}

получился интересный опыт

я избавился от этого прерывания
_delay_us(500);
до этого без него не работало

вроде как на каждый тик мотор стал по другому реагировать и на мониторе на кривой видно что код считывается с каждого второго тика
надо еще несколько опытов поставить .


//КОД КОГДА ЭНКОДЕР ВРАЩАЕТСЯ PIN6 И PIN3   И ПОДАЕТ СИГНАЛ НА ШАГОВЫЙ МОТОР	
  	
  if (counter > 0)  {
    digitalWrite(DIR_PIN    , HIGH);
		digitalWrite(ENABLE_PIN , LOW);
    digitalWrite(STEP_PIN    , HIGH);
	if(counter%2) {
      digitalWrite(STEP_PIN    , LOW);
      
      motor_position++;
      counter = 0;
    }
	}
  else if (counter < 0)  {
    digitalWrite(DIR_PIN    , LOW);
		digitalWrite(ENABLE_PIN , LOW);
    digitalWrite(STEP_PIN    , HIGH);
	if(counter%2) {
      digitalWrite(STEP_PIN    , LOW);
      motor_position--;
      counter = 0;
    }
	}
  
  }
  

Ну так поставь под тем постом моим - вопрос решён, мне + в карму )))

1 лайк

И что потом? С этой кармой.

тестил сегодня разные варианты с
if(counter%2) {
и с
_delay_us(200);

так вот . if(counter%2) { во много раз. точнее . но я из 20 - 30 прокручивания оси. по 10 мм уз раз подряд итого примерно 300 мм я иногда теряю иногда приобретая от 0.2 до 1.5 мм
то есть за одно два туда сюда дерганья каретки примерно со скоростью 7000ммм мин я теряю 0.02 - 0.1 мм а иногда повторяемость выше
нужно еще проверить на 16 и 32 шага
сейас у меня 1\8 шага
не знаю , для принтера подойдет или будет полосить нужно собирать принтер и пробовать .
для лебедки такая точность точно подойдет .

здесь принтер @lilik сделал, может что скажет

Так энкодер для обратной связи ставят обычно… Пока с него тик не получит система, степает мотором. Тогда и отклонений меньше.

ну не всегда жеж неурожай винограда, а как без кармы вино делать? скиснет…

Ничего не скажу, уровень совсем другой и подход :slight_smile:
Посмотрим на картинки, когда до них очередь дойдёт.