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

А ежли как я, фома не верующий?

ну ты жеж веришь, что вино должно получиться? )))

Нельзя так глубоко рыть.

Верю. Только если придерживаться технологии, а не абы как.
До этого с рук сходило, а тут…(

то-есть перекись льёшь?

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

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

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

#define STEP_PIN         2
#define DIR_PIN          5
#define ENABLE_PIN       8
#define limitPin         9
#define button1          4
#define button2          7



void setup(){                
Serial.begin(115200);
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание
pinMode(2, OUTPUT);   
pinMode(5, OUTPUT);
pinMode(8, OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
}


int A = 0;
int T = 1;



ISR(PCINT1_vect, ISR_NOBLOCK){  //ISR(PCINT1_vect) если нет джойстика
static char EncPrev=0;      //предыдущее состояние энкодера
static char EncPrevPrev=0;  //пред-предыдущее состояние энкодера
  char EncCur = 0;
  if(!(PINC & (1 << PC0))){EncCur  = 1;} //опрос фазы 1 энкодера
  if(!(PINC & (1 << PC1))){ EncCur |= 2;} //опрос фазы 2 энкодера
  if(EncCur != EncPrev)             //если состояние изменилось,
  {
    if(EncPrev == 3 &&        //если предыдущее состояние 3
       EncCur != EncPrevPrev )      //и текущее и пред-предыдущее не равны,
       
	   
    {
      if  (EncCur == 2)          //если текущее состояние 2,
        (enc++,    digitalWrite(DIR_PIN , 0),  Step());
        
      else                          //иначе
        (enc--,    digitalWrite(DIR_PIN , 1),  Step());
    }
    EncPrevPrev = EncPrev;          //сохранение пред-предыдущего состояния
    EncPrev = EncCur;               //сохранение предыдущего состояния
  }


  }

 void Step() {		
	    digitalWrite(ENABLE_PIN , LOW);
        digitalWrite(STEP_PIN    , HIGH);
	    delayMicroseconds(T);
        digitalWrite(STEP_PIN    , LOW);
        motor_position++;
} 

void loop() {
if (!digitalRead(4)) {delay(5);
digitalWrite(8, LOW);}

if (!digitalRead(7)) {delay(5);
digitalWrite(8, HIGH);}

    A = analogRead(A4);
    Serial.println(A);
    if (A > 520) {
       digitalWrite(8, LOW);
      T = map(A, 520, 1123, 500, 0);
      pinMode(5, OUTPUT);
       digitalWrite(5, 1);
      Step();
    }
    if (A < 480) {
       digitalWrite(8, LOW);
      T = map(A, 480, 0, 500, 0);
      pinMode(5, OUTPUT);
       digitalWrite(5, 0);
      Step();
    }
    if (A > 480 & A < 520) {       
      pinMode(5, OUTPUT);
       digitalWrite(5, 0);
      pinMode(2, OUTPUT);
       digitalWrite(2, 0);
    } 
     if (!digitalRead(9)) { 	                      
	      digitalWrite(ENABLE_PIN , LOW);        
		    digitalWrite(DIR_PIN    , LOW);
		    for (int i = 0; i < 200; i++) {                
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(1000);
        digitalWrite(STEP_PIN    , LOW);
        } 
        delay(2000);
        asm volatile("jmp 0x00");		
      
    } 			
}

ты бы не на ютубе размещал всё же

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

Рутуб, ВКвидео

Возможно, дело не в энкодере, а в управлении мотором.
Убрал лишнее, на мой взгляд, добавил вывод енкодера в сериал. Проверьте, на сколько значений уходит и возвращается позиция энкодера.

Спойлер
//Энкодер на пинах А0, А1. Используется внутренняя подтяжка.
volatile int enc, motor_position;

#define STEP_PIN         2
#define DIR_PIN          5
#define ENABLE_PIN       8
#define limitPin         9
#define button1          4
#define button2          7

#define checkBtnPeriod     4 //период опроса кнопок,ms

int A = 0;
volatile int T = 1;
uint32_t timeMillis = 0;

void setup(){                
Serial.begin(115200);
pinMode(A0,INPUT_PULLUP);
pinMode(A1,INPUT_PULLUP);
PCIFR=PCIFR; PCICR=1<<PCIE1; //разрешить прерывание
PCMSK1=1<<PCINT8 | 1<<PCINT9; //выбрать вход на котором сработает прерывание
pinMode(2, OUTPUT);   
pinMode(5, OUTPUT);
pinMode(8, OUTPUT);
pinMode(4, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(9, INPUT_PULLUP);
}


ISR(PCINT1_vect /*, ISR_NOBLOCK*/){  //ISR(PCINT1_vect) если нет джойстика
static char EncPrev=0;      //предыдущее состояние энкодера
static char EncPrevPrev=0;  //пред-предыдущее состояние энкодера
  char EncCur = 0;
  if(!(PINC & (1 << PC0))){EncCur  = 1;} //опрос фазы 1 энкодера
  if(!(PINC & (1 << PC1))){ EncCur |= 2;} //опрос фазы 2 энкодера
  if(EncCur != EncPrev)             //если состояние изменилось,
  {
    if(EncPrev == 3 &&        //если предыдущее состояние 3
       EncCur != EncPrevPrev )      //и текущее и пред-предыдущее не равны,
       
	   
    {
      if  (EncCur == 2)          //если текущее состояние 2,
        (enc++,  digitalWrite(DIR_PIN , 0),  Step());
        
      else                          //иначе
        (enc--,  digitalWrite(DIR_PIN , 1),  Step());
    }
    EncPrevPrev = EncPrev;          //сохранение пред-предыдущего состояния
    EncPrev = EncCur;               //сохранение предыдущего состояния
  }


  }

 void Step() {		
	    digitalWrite(ENABLE_PIN , LOW);
        digitalWrite(STEP_PIN    , HIGH);
	    delayMicroseconds(T);
        digitalWrite(STEP_PIN    , LOW);
        motor_position++;
} 

void loop() {
static int16_t enc_m = 0;
if(millis() - timeMillis >= checkBtnPeriod)//опрос кнопок и джойстика
{                            //каждые 4мс
  timeMillis = millis();
if (!digitalRead(4)) {/*delay(5)*/;
digitalWrite(8, LOW);}

if (!digitalRead(7)) {/*delay(5)*/;
digitalWrite(8, HIGH);}

    A = analogRead(A4);
    //Serial.println(A);
    if(enc != enc_m)
    Serial.println(enc);
    if (A > 520) {
    //   digitalWrite(8, LOW);
      T = map(A, 520, 1123, 500, 0);
    //  pinMode(5, OUTPUT);
     //  digitalWrite(5, 1);
     // Step();
    }
    if (A < 480) {
     //  digitalWrite(8, LOW);
      T = map(A, 480, 0, 500, 0);
     // pinMode(5, OUTPUT);
      // digitalWrite(5, 0);
     // Step();
    }
    if (A > 480 && A < 520) { //не & а  &&      
    //  pinMode(5, OUTPUT);
       digitalWrite(5, 0);
   //  pinMode(2, OUTPUT);
       digitalWrite(2, 0);
    } 
        
  enc_m = enc;		   
 }
 	if (!digitalRead(9)) { 	                      
	      digitalWrite(ENABLE_PIN , LOW);        
		    digitalWrite(DIR_PIN    , LOW);
		    for (int i = 0; i < 200; i++) {                
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(1000);
        digitalWrite(STEP_PIN    , LOW);
        } 
        delay(2000);
        asm volatile("jmp 0x00");		
      	
  }
}

P.S. Немного подправил

спасибо , немного погодя попробую ,
я потихоньку разбираюсь. с цифровыми пинами и составил код в пять строк который начал показывать так же точно . но почему то у джойстика стала одна скорость. и лимит редко по разному показывает
но я отстрою .
как с джойстиком разберусь и лимитом сразу выложу
у меня еще оказывается на цифре энкодер работает только нв 2,3 пинах я пробовал на всех
возможно и это была позавчерашняя причина почему я не смог код на цифре запустить от Леонида Ивановича .

некоторые моменты я проверил .
Что бы вернуть джойстик … вернул и некоторые параметры .
#define checkBtnPeriod 1
поставил 1 так квк джойстик на 4 и выше очень медленно крутил мотор
1 мсек . это часто но на точность никак не влияет.

убрал костыль …
“”"
delay(2000);
asm volatile(“jmp 0x00”);
“”"
что бы посмотреть что поменялось .
вроде как поменялось . тес ты с прогоном джойстика и без него сделал раз 50
вроде как теперь с первого раза проход например в 16000 шагов двигателя при 12000 мм мин возвращает мотор на ту же позицию
не теряя сотки
такое было со второго и последующих прогонов . а первый раз он мог потерять и десятку . и даже пару мм . поэтому я и поставил легкий ресет .
джойстик вроде без нареканий работает . но есть условия .
я должен джойстиком довести каретку до концевика и когда она отедет от него в ноль могу запускать прогон туда сюда при этом условии ничего не теряется с первого и последующих раз прогонов .
если я не доведу до концевика . результат бывает разный по патерям .
еще условие . если я руками подведу каретку в любое место и отправлю прогон .то тоже будет потеря мм

далее
я забыл проверить без этого параметра
ISR_NOBLOCK*/
позже проверю

вы спрашивали про потери на энкодере . 16000 шагов _1500 тиков и обратно также 16000_0 возврат и сотые мм возвращаются в своё первоначальное состояния
с точностью нормально
дребезга нет
буду думать как руками двигать или джойстиком не доезжая концевика . ведь в принтере и такая задача может быть когда с середины нужно начать печать.

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

далее сделал код на цифровых пинах 2-3
работает хорошо .
точность такая же высокая без пропусков
вопросы с джойстиком и концевиком решил
костыль в виде ресета стоит . без него не получается с первого раза прогнать прогон туда сюда .
попробую ваш код применить у себя
меня и ресет устраивает но бывает он раз из десяти не срабатывает.

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

Вот такой простой код получился .

#define enc_A   2   
#define enc_B   3 
#define STEP_PIN    4   
#define DIR_PIN     7    
#define ENABLE_PIN  8
#define limitPin    9
#define button1     6
#define button2     5

volatile long temp, motor_position, enc;
int T = 1;
int A = 0;
void setup (){
    Serial.begin (115200);
    pinMode(enc_A, INPUT_PULLUP);
    pinMode(enc_B, INPUT_PULLUP);
    pinMode(STEP_PIN, OUTPUT);
    pinMode(DIR_PIN, OUTPUT);
	  pinMode(ENABLE_PIN , OUTPUT);
    pinMode(4, INPUT_PULLUP);
	  pinMode(5, INPUT_PULLUP);
    pinMode(6, INPUT_PULLUP);
    pinMode(9, INPUT_PULLUP);
    attachInterrupt(0, encPinA, CHANGE);
    enc = 0;
}
    
void encPinA() {
   if( enc != temp ){
     Serial.println (enc);
     temp = enc;
    }
  
  if (digitalRead(enc_A) == digitalRead(enc_B))
   {if (enc < 0; enc--); 
    (digitalWrite(DIR_PIN , 1),  Step());
    } else
  {(enc++,    digitalWrite(DIR_PIN , 0),  Step());} 
}

void Step() {		
	    digitalWrite(ENABLE_PIN , LOW);
        digitalWrite(STEP_PIN    , HIGH);
	    delayMicroseconds(T);
        digitalWrite(STEP_PIN    , LOW);
        motor_position++;
        enc = 0;

}


void loop()  {  
if (!digitalRead(5)) {delay(5);
digitalWrite(8, LOW);}

if (!digitalRead(6)) {delay(5);
digitalWrite(8, HIGH);}

    A = analogRead(A4);
    if (A > 520) {
       digitalWrite(8, LOW);
      T = map(A, 520, 1123, 500, 0);
       (digitalWrite(DIR_PIN , 1),  Step());
    }
    if (A < 480) {
       digitalWrite(8, LOW);
      T = map(A, 480, 0, 500, 0);
       (digitalWrite(DIR_PIN , 0),  Step());
    }
    if (A > 480 && A < 520) {
       (digitalWrite(DIR_PIN , 0),  digitalWrite(STEP_PIN, 0));
    }
	
     if (!digitalRead(9)) {
        digitalWrite(ENABLE_PIN , HIGH);
        delay(150);	                      
	    digitalWrite(ENABLE_PIN , LOW);        
		digitalWrite(DIR_PIN    , LOW);
		for (int i = 0; i < 200; i++) {                
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(1000);
        digitalWrite(STEP_PIN    , LOW);
        }
     if (!digitalRead(9)) 
        delay(100);
        asm volatile("jmp 0x00");	      
    } 			
}

PS, код что выше негодный . вчера хорошо работал сегодня плохо считывает .
НЕ ИСПОЛЬЗУЙТЕ ЕГО ДЛЯ ТОЧНЫХ РАБОТ ,
БУДЕТ НОВЫЙ КОД НА ТЕХ ЖЕ ПИНАХ …

код работает хорошо , нет дребезга . точность в сотку зависит от энкодера и деления шага
у меня 1\8 1 тик энкодера 2 сотки
на 1\16 будет 1 к 1 без погрешности не считая прибора

Encpder привязан на pin D2 и D3
joystick на A4
шаговый мотор на
STEP_PIN = 4 , DIR_PIN = 7 , ENABLE_PIN 8
Limit pin = 9
Кнопка удержания шаговика pin 5
Кнопка снятия с удержания шаговика pin 6
const int R360 = 200; мне такое число шагов устраивает что бы при лимите мотор отъезжал на 4 мм .

Далее , буду еще тестить и оптимизировать код . смотреть на его поведения . ведь при желании недочет всегда можно высосать а это мне нравиться .
можно закоментить вывод в принт для быстродействия , но мне всего хватает
Serial.println(enc);

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

   
#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);
PCIFR=PCIF2; PCICR=1<<PCIE2;               //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19;            //выбрать вход на котором сработает прерывание 
}
const int STEP_PIN = 4;
const int DIR_PIN = 7;
const int move_delay = 3;
const int R360 = 200;
int T = 1;
int A = 0;

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++, digitalWrite(DIR_PIN, 0), Step());   //шаг вверх
   else                                          //иначе
    (enc--, digitalWrite(DIR_PIN, 1), Step());   //шаг вниз
}
EncPrevPrev = EncPrev;                           //сохранение пред-предыдущего состояния
EncPrev = EncCur;                                //сохранение предыдущего состояния
}
}

void Step() 
{
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN, LOW);
motor_position++;
}

void loop() {
Serial.println(enc); 

if (!digitalRead(5)) {delay(5);
digitalWrite(8, LOW);}

if (!digitalRead(6)) {delay(5);
digitalWrite(8, HIGH);}

    A = analogRead(A4);
    if (A > 520) {
       digitalWrite(8, LOW);
      T = map(A, 520, 1123, 500, 0);
      pinMode(7, OUTPUT);
       digitalWrite(7, 1);
      Step();
    }
    if (A < 480) {
       digitalWrite(8, LOW);
      T = map(A, 480, 0, 500, 0);
      pinMode(7, OUTPUT);
       digitalWrite(7, 0);
      Step();
    }
    if (A > 480 && A < 520) {       
      pinMode(7, OUTPUT);
       digitalWrite(7, 0);
      pinMode(4, OUTPUT);
       digitalWrite(4, 0);
    } 
     if (!digitalRead(9)) {
        digitalWrite(ENABLE_PIN , HIGH);
        delay(150);	                      
	      digitalWrite(ENABLE_PIN , LOW);        
		    digitalWrite(DIR_PIN    , LOW);
		    for (int i = 0; i < R360; i++) {                
        digitalWrite(STEP_PIN    , HIGH);
        delayMicroseconds(1000);
        digitalWrite(STEP_PIN    , LOW);
        }
     if (!digitalRead(9)) 
         delay(100);
        asm volatile("jmp 0x00");	      
    } 			
}

Не описание, а поток не сформированных мыслей.
Пока в голове порядок не наведешь, так и будет херня получаться.

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

Добавил в код функцию , уйти на ноль .
нажав на кнопку на Pin 5 каретка самостоятельно выставляется в нулевое положения .

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

   
#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);
PCIFR=PCIF2; PCICR=1<<PCIE2;               //разрешить прерывание
PCMSK2=1<<PCINT18 | 1<<PCINT19;            //выбрать вход на котором сработает прерывание 
}
const int STEP_PIN = 4;
const int DIR_PIN = 7;
const int R360 = 200;                         //шагов на полный оборот
int T = 1;
int A = 0;

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++, digitalWrite(DIR_PIN, 0), Step());   //шаг вверх
   else                                          //иначе
    (enc--, digitalWrite(DIR_PIN, 1), Step());   //шаг вниз
}
EncPrevPrev = EncPrev;                           //сохранение пред-предыдущего состояния
EncPrev = EncCur;                                //сохранение предыдущего состояния
}
}

void Step() 
{
digitalWrite(ENABLE_PIN, LOW);
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(T);
digitalWrite(STEP_PIN, LOW);
motor_position++;
}

void loop() {
Serial.println(enc); 

    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);
    if (A > 520) {
      T = map(A, 520, 1123, 500, 0);
      digitalWrite(7, 1);
      Step();
    }
    if (A < 480) {
      T = map(A, 480, 0, 500, 0);
      digitalWrite(7, 0);
      Step();
    }
    if (A > 480 && A < 520) { 
      digitalWrite(7, 0);
      digitalWrite(4, 0);
    } 
    if (!digitalRead(9)) {	                      
	  digitalWrite(ENABLE_PIN, LOW);        
      digitalWrite(DIR_PIN, LOW);
	  for (int i = 0; i < R360; i++) {                
      digitalWrite(STEP_PIN, HIGH);
      delayMicroseconds(800);
      digitalWrite(STEP_PIN, LOW);
      }
    }

      if (!digitalRead(9)) {  
        delay(2000);
      asm volatile("jmp 0x00");
      }
    
					
}

У тебя там “нуля” в принципе нет.
Для выхода в “ноль” нормальные люди используют z-метки энкодера

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

тебе нужен любой в качестве отсчета + один корпус JK триггера и будут тебе метки