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

жена говорит, что ей нужна какая-то особая доска для кухни, в магазинах нет, придётся делать и, стоить это будет раз в пять больше, чем купить готовое )))

какие вектора? Что за бред?

Тут полное ЕЕ, он сначало на “перезагрузку” зачем-то уходил, потом решил на прерывание по смене состояния ходить “0х0А”, там каша масляная.
Вопрос решился в #4, но мы тут все наблюдаем поток сознания, сходил на канал Ютуб, посмотрел - :face_with_peeking_eye:

как хотим, так и едем

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

2 лайка

Ну да))
Вот видишь тут ещё одному, все это покое не даёт, родственники штоли :face_with_open_eyes_and_hand_over_mouth:

Доброго дня, спасибо Вадиму, в данный момент мне этот код очень нужен, я пошел с другой стороны, взял плоттер Epson А1 формата, epson 7890, разобрал его, и сейчас уже собрал всю механику, стол, пришло время arduino, сейчас только начал вникать, хорошо, что есть от чего отталкиваться. Я правильно понимаю, что если этот скетч залить в arduino uno, подключить шаговик и энкодер, без кнопок и запустить, то при вращение энкодера шаговик должен работать? или нужно кнопками еще что-то включить? Но энкодер у меня соответственно будет Epson, с питанием от основной платы принтера, я так понимаю, нужно arduino подключить тоже от питания принтера, что бы у них общая земля была?

Да, все верно вы поняли, земля общая, а кнопки и джоййстик для удобства, энкодер все норм работает только закоменти строку плюс движения энкодера что бы принтер при прочистке не дергал напрасно шаговик, я уже попробовал в деле без чернил все работает, шаговик нужно ставить на 1/4 шага и далее подбирать милисекунды, я пока занят домашкой немного некогда показать все в деле и доделать станок как разгребу подробно дополню все.
У меня энкодер не принтовский так как припаевать провода к плате я не умею оставил паралельный и закрепил его с боку примерно такое фото.

Доброго дня всем форумчанам .
Продолжаю заниматься планшетным принтером .
за это время я проделал много опытов и не все получилось.
не получилось .
1.
сделать передачу от encoder к шаговому двигателю .чтобы оборот или шаг encoder соответствовал шагу stepper motor nema17 .
от этого все распечатки получаются с искажениями . на распечатках видно .

  1. не смог правильно задействовать кнопку pin концевика датчика начала и окончании бумаги .
    в этом вопросе я изучал как ведет себя принтер и когда мне вручную нажимать и отпускать кнопку .
    но для начала нужно доделать первый пункт дописать код .

Есть и хорошие новости .
код до настроек и для удобства использования принтера что я встроил работает без сбоев .
а это
два концевика Limit стола . джойстик для более точного подъезда стола . кнопка отправки на печать и обнуления encoder посредством reboot , и другого кода пропуска поиска бумаги и окончании печати и обнуления encoder . Работает.

Напомню .
схема состоит из платы mks DLC v2.0 контролер AVR 328 то есть
обычная arduino uno 328 . с нависными драйвером a4988
Encoder optical 600 PPR на оборот . на фото у принтера видно .
2 limit нормально закрытые .
arduino джойстик .
кнопки botton .
stepper motor nema 17.
и сам Принтер Hp Deskjet 2330
выбор пал на него так как это
Проект для меня. изучения работы этого станка и он пока прототип более глобального проекта .
Простой . проще только простой карандаш .
Дешевый брал на Авито 3 шт по 300 руб
Можно на нем использовать пигментные чернила .

Сам код почти не изменился

//Энкодер на пинах 2, 3. Используется внутренняя подтяжка.
volatile long int enc;

#include <avr/wdt.h>                    // Библиотека часть компилятора avr-gcc
#define ENABLE_PIN  8
#define limitPin    9
#define button1     6
#define button2     5

void setup(){                
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(ENABLE_PIN , OUTPUT);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
pinMode(10, INPUT_PULLUP);



PCIFR=PCIF2; PCICR=1<<PCIE2;               //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19;            //выбрать вход на котором сработает прерывание 
}



uint32_t timer = 0;
void(* resetFunc) (void) = 0;
const int STEP_PIN = 4;
const int DIR_PIN = 7;
const int R360 = 200;                        
int T = 10;
int A = 0;
int ST = enc/3;

ISR(PCINT2_vect){
static char EncPrev=0;                           //предыдущее состояние энкодера
static char EncPrevPrev=0;                       //пред-предыдущее состояние энкодера
  char EncCur = 0;
  if(!(PIND & (1 << PD2))){EncCur  = 1;}         //опрос фазы 1 энкодера
  if(!(PIND & (1 << PD3))){ EncCur |= 2;}        //опрос фазы 2 энкодера
  if(EncCur != EncPrev)                          //если состояние изменилось,
{ if(EncPrev == 3 &&                             //если предыдущее состояние 3
    EncCur != EncPrevPrev )                      //и текущее и пред-предыдущее не равны,
 
  { 
  if(EncCur == 2) 
    
      (enc++, digitalWrite(DIR_PIN, LOW), digitalWrite(ENABLE_PIN, LOW));
      
      
      else                          
        (enc-- , digitalWrite(ENABLE_PIN, HIGH));
        if (enc < 0) {
      enc = 0;}
        
      }
    if (enc > 1 & enc < 1000){
      if (ST < 3) {
     digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
     digitalWrite(STEP_PIN, LOW);}
	 
	 }
	 
  Serial.println(enc);    
      
EncPrevPrev = EncPrev;                           //сохранение пред-предыдущего состояния
EncPrev = EncCur;                                //сохранение предыдущего состояния
}
}


void Step()                                      //  функция вращеия мотора
{
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN, LOW);
}
void reboot() {                                 // функция  сторожевого таймера
  wdt_disable();
  wdt_enable(WDTO_15MS);
  while (1) {}
}
void loop() {
 
 

    if (!digitalRead(5)) {                         // кнока ухода в нулевое положеия 
      digitalWrite(ENABLE_PIN, LOW);   
	  digitalWrite(DIR_PIN, HIGH); 
      for (int i = 0; (!digitalRead(9)) < 1; i++) {                 
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(500);
      digitalWrite(STEP_PIN, LOW);
      }
	}

    if (!digitalRead(6)){                         // снятия с удержаия мотора
       digitalWrite(8, HIGH);	
      }

    A = analogRead(A4);                           //  pin joystick
    if (A > 520) {
      T = map(A, 520, 1123, 500, 0);
      digitalWrite(7, 1);
      Step();
    }
    if (A < 480) {
      T = map(A, 480, 0, 500, 0);                 // 500, 0); шкала перерасчета 
      digitalWrite(7, 0);
      Step();
    }
    if (A > 480 && A < 520) {                     // 480 <  Serial.println(A); < 520
      digitalWrite(7, 0);
      digitalWrite(4, 0);
    } 

    if (!digitalRead(10)) {	                      //pin коцевика
       digitalWrite(ENABLE_PIN, LOW);        
      digitalWrite(DIR_PIN, HIGH);
	    for (int i = 0; i < R360; i++) {                
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(1000);                  // скорость отьеда от limit
      digitalWrite(STEP_PIN, LOW);
      }
    }
    
    if (!digitalRead(9)) {	                      //pin коцевика
       digitalWrite(ENABLE_PIN, LOW);        
      digitalWrite(DIR_PIN, LOW);
	    for (int i = 0; i < R360; i++) {                
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(1000);                  // скорость отьеда от limit
      digitalWrite(STEP_PIN, LOW);
      }
      { delay(1000);
      reboot();                                 // сброс таймера
      }
    }
}

несколько фото с искажениями .

с этого кода я убрал все лишнее что бы можно более нагляднее
видеть как встроить передачу . примерно такую
volatile long int enc; // глобальная куда будет скидываться пики от энкодера
int ST = enc/2.04; // свое значения .
ST переменная получаемого нужное количества шагов ШД по отношению к импульсам энкодера [ Мне подсказал человек у которого код но другой работает хорошо . а как в этом коде далее продолжить я не догоняю чтобы это связать с ШД ]
2.04 условная цифра . нужно подобрать .

//Энкодер на пинах 2, 3.


volatile long int enc;
#define ENABLE_PIN  8

void setup(){                
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(ENABLE_PIN , OUTPUT);


PCIFR=PCIF2; PCICR=1<<PCIE2;               //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19;            //выбрать вход на котором сработает прерывание 
}

uint32_t timer = 0;
const int STEP_PIN = 4;
const int DIR_PIN = 7;
int ST = enc/3;

ISR(PCINT2_vect){
static char EncPrev=0;                           //предыдущее состояние энкодера
static char EncPrevPrev=0;                       //пред-предыдущее состояние энкодера
  char EncCur = 0;
  if(!(PIND & (1 << PD2))){EncCur  = 1;}         //опрос фазы 1 энкодера
  if(!(PIND & (1 << PD3))){ EncCur |= 2;}        //опрос фазы 2 энкодера
  if(EncCur != EncPrev)                          //если состояние изменилось,
{ if(EncPrev == 3 &&                             //если предыдущее состояние 3
    EncCur != EncPrevPrev )                      //и текущее и пред-предыдущее не равны,
 
  { 
  if(EncCur == 2) 
    
      (enc++, digitalWrite(DIR_PIN, LOW), digitalWrite(ENABLE_PIN, LOW));
      
      
      else                          
        (enc-- , digitalWrite(ENABLE_PIN, HIGH));
        if (enc < 0) {
      enc = 0;}
        
      }
    if (enc > 300 & enc < 1000){
      if (ST < 3) {
     digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
     digitalWrite(STEP_PIN, LOW);}
	 
	 }
	 
  Serial.println(enc);    
      
EncPrevPrev = EncPrev;                           //сохранение пред-предыдущего состояния
EncPrev = EncCur;                                //сохранение предыдущего состояния
}
}

void loop() {
}

ПРОШУ ПОМОЩИ , ПОМОГИТЕ ДОПИСАТЬ ЭТОТ БЛОК КОДА

volatile long int enc; // глобальная куда будет скидываться количества шагов от энкодера
int ST = enc/2.04; // свое значения .
ST переменная получаемого нужное количества шагов ШД по отношению к импульсам энкодера
А далее связать с ШД :
ВРОДЕ ЭТОГО

if (enc > 300 & enc < 1000){     // в этих пределах ШД работает
     if (ST < 3) {                        // это мой мудреж 
    digitalWrite(STEP_PIN, HIGH);   // так я обычно шагаю 
   // delayMicroseconds(1);
    digitalWrite(STEP_PIN, LOW);}

с этой у меня посчиталось но все тормазило но отпечаталось правильно
enc = pulseInLong(3, 0);
но как я это применил я забыл .

Каков физический смысл числа в ST?

ST переменная
есть энкодер 600 имп.
есть ШД . в зависимости от деления драйвера у него разное количество импульсов или STEP_PIN на оборот .
Например без деления 200 импульсов или шагов с делителем 1/8
это уже 200 на 8 = 1600 имп.
За 1 оборот энкодера 600 имп. принтер делает оборот вала или шагов по оси Y неизвестное число (у всех принтеров думаю по разному)
нам нужно подобрать такое число шагов ST (STEP_PIN) чтобы
при одном импульсе энкодера ST соответствовало какому то количества импульсов ШД . что бы это соответствовало правильному отпечатанному изображению .
Теперь математика .
считаем импульсы энкодера и записываем их в temp так как arduino в реальном времени говорят не справиться .
записываем:
volatile long int enc; // число импульсов считаное pinMode(3,INPUT_PULLUP); или кодом (enc) EncCur |= 2;
добавляем переменную (STEP)
int ST = (enc/3.75); // 3.75 это число подбирается вручную если лень метки энкодера и зубья шестеренок от принтера посчитать и потом метки поделить на зубья . ,
далее мне нужно как то переменную ST задействовать в шаге ШД.

допустим пишем :

enc = pulseInLong(3, 0);
int ST = enc/3.75;
if(STпредыдущее  != STтекущее)  //если состояние изменилось
{  if(STпредыдущее== 3 &&                             //если предыдущее состояние 3
  {  STтекущее != STпред-предыдущее )                      //и текущее и пред-предыдущее не равны,
{ if(STтекущее == 2)
// тогда делаем шаг
digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
     digitalWrite(STEP_PIN, LOW);}

как то так
может все нужно проще организовать ?

Возможно, я чего-то не понимаю, но одному импульсу энкодера должно соответствовать целое число шагов ШД, иначе как не считай - ошибка неизбежна

а как в принтере механика импульсы энкодера делим на зубья .
и кодом можно
мы же получаем переменную ST, При которой

if(STPrev == 3 &&                             //если предыдущее состояние ST 3
    STCur != STPrevPrev )                      //и текущее и пред-предыдущее не равны,
// тогда шагаем 
if (ST > 30 & ST < 2000){   //
     digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
     digitalWrite(STEP_PIN, LOW);}

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

volatile long int enc;

#define ENABLE_PIN  8

void setup(){                
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(ENABLE_PIN , OUTPUT);


PCIFR=PCIF2; PCICR=1<<PCIE2;               //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19;            //выбрать вход на котором сработает прерывание 
}

uint32_t timer = 0;
const int STEP_PIN = 4;
const int DIR_PIN = 7;
int ST = enc/3;

ISR(PCINT2_vect){
static char EncPrev=0;                           //предыдущее состояние энкодера
static char EncPrevPrev=0;                       //пред-предыдущее состояние энкодера
  char EncCur = 0;
static char STPrev=0;                           //предыдущее состояние ST
static char STPrevPrev=0;                        //пред-предыдущее состояние ST
 char STCur = 0
  
  
  if(!(PIND & (1 << PD2))){EncCur  = 1;}         //опрос фазы 1 энкодера
  if(!(PIND & (1 << PD3))){ EncCur |= 2;}        //опрос фазы 2 энкодера
  if(!(ST & (1 << STPrev))){STCur  = 1;}         //опрос предыдущее состояние ST
  if(!(ST & (1 << STPrevPrev))){ STCur |= 2;}    //опрос пред-предыдущее состояние ST
  
  if(EncCur != EncPrev)                          //если состояние изменилось,
  if(STCur != STPrev)                          //если состояние изменилось
  
{ if(EncPrev == 3 &&                             //если предыдущее состояние 3
    EncCur != EncPrevPrev )                      //и текущее и пред-предыдущее не равны,
	if(STPrev == 3 &&                             //если предыдущее состояние ST 3
    STCur != STPrevPrev )                      //и текущее и пред-предыдущее не равны,
	
	
 
  { 
  if(EncCur == 2) 
  if(STCur == 2)
  
    
      (enc++, digitalWrite(DIR_PIN, LOW), digitalWrite(ENABLE_PIN, LOW));
	  (ST++, digitalWrite(DIR_PIN, LOW), digitalWrite(ENABLE_PIN, LOW));
      
      
      else                          
        (enc-- , digitalWrite(ENABLE_PIN, HIGH));
        if (enc < 0) {
      enc = 0;}
        
      }
    if (ST > 30 & ST < 2000){   //
     digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
     digitalWrite(STEP_PIN, LOW);}
	 
	 }
	 
  Serial.println(enc);
   Serial.println(ST); 
      
EncPrevPrev = EncPrev;                           //сохранение пред-предыдущего состояния
EncPrev = EncCur;                                //сохранение предыдущего состояния
}
}
void loop() {}


Что-бы говорить конкретно - нужна полная схема устройства.

Если число шагов на оборот двигателя кратно числу импульсов на оборот энкодера - то никаких дробей не будет

Для упрощения я с кода все выкинул , оставил энкодер и ШД .
и arduino AVR328
По коду видно
enc сидит
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
ШД. на
#define ENABLE_PIN 8
const int STEP_PIN = 4;
const int DIR_PIN = 7;
задача ;
enc ++ = ST ++ умножить на STEP_PIN //++ импульс
ST моя переменная

как велосипед
enc = пидали Бол. Звезда есть
определить заднее колесо малую звезду == ST
Накинуть цепь - запитать этот механизм в коде .
велосипед наверное все видели .

У велосипеда колесо можно остановить между зубьями. ШД только делает шаги. На 0.13 “шагнуть” не сможет))

Посмотрите функцию map()

да , я ее пробовал несколько дней назад , но до нее нужно еще что то сделать .
я не смог разобраться .
и для map
нужны переменные энкодера и ШД.
SP = map (enc++, 0, 200, 0, 600); //200ШД И 600 ENC
потом их правильно вписать .
у меня нет базовых знаний для понимания что за чем вписывать

Почитайте описание функции

Здесь написано, что :
переменной SP присваивается значение переменной enc, из диапазона значений 0…200, переведённое в диапазон значений 0…600. После этого, значение enc увеличивается на 1.
Напишите простой скетч, с выводом в сериал, и посмотрите, как работает.

Опять ничего непонятно.
Что должно происходить с двигателем, когда вычислено ST = 855 / 3.75?

посмотрел и не понял . толи 1 к 1 мне так не надо
а на мониторе по другому 1 к неизвестно чему мне почти так надо
5 часов пробовал так и не понял .
нужно печать запускать а у нас ночь . 4 часа
так вот написал . ничего уже не соображаю.

volatile long int enc , ST = enc/1.04;

#define ENABLE_PIN  8
const int STEP_PIN = 4;
const int DIR_PIN = 7;
int L = 0;


void setup(){                
Serial.begin(115200);
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(ENABLE_PIN , OUTPUT);
PCIFR=PCIF2; PCICR=1<<PCIE2; //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19; //выбрать вход на котором сработает прерывание 
}


ISR(PCINT2_vect){
static char EncPrev=0;      //предыдущее состояние энкодера
static char EncPrevPrev=0;  //пред-предыдущее состояние энкодера
  char EncCur = 0;


  
  if(!(PIND & (1 << PD2))){EncCur  = 1;} //опрос фазы 1 энкодера
  if(!(PIND & (1 << PD3))){ EncCur |= 2;} //опрос фазы 2 энкодера
  if(EncCur != EncPrev)             //если состояние изменилось,
  {
    if(EncPrev == 3 &&        //если предыдущее состояние 3
       EncCur != EncPrevPrev )      //и текущее и пред-предыдущее не равны,
    {
      if(EncCur == 2)          //если текущее состояние 2,
        enc++;            //шаг вверх
      else                          //иначе
        enc--;            //шаг вниз
    }
    
 
if (enc > 0 && enc < 2000){ 
  enc = digitalRead(3);
enc  =  map (ST++, 0, 1600, 0, 600);

digitalWrite(DIR_PIN, LOW);
 digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
digitalWrite(STEP_PIN, LOW);
}
else
enc = digitalRead(2);
enc  =  map (ST--, 0, 1600, 0, 600);
digitalWrite(DIR_PIN, 1);
 digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
    // delayMicroseconds(1);
digitalWrite(STEP_PIN, LOW);


   
    EncPrevPrev = EncPrev;          //сохранение пред-предыдущего состояния
    EncPrev = EncCur;               //сохранение предыдущего состояния
  }
  
    Serial.print("  ST  - ");
    Serial.print(ST);
    Serial.print("  enc  - ");
    Serial.print(enc);


 
  
}
void loop() {



}

вывод монитора

 ST  - -115  enc  - -42  ST  - -116  enc  - -43  ST  - -117  enc  - -43  ST  - -118  enc  - -43  ST  - -119  enc  - -44  ST  - -120  enc  - -44  ST