Проблемы связи с Nextion с Arduino Uno ch340g

Доброго времени суток.

Столкнулся с проблемой, ответа на который на просторах интернета найти не удалось…

Суть проблемы:

есть Uno R3 с преобразователем atmega16u2,

есть китайская Uno c CH340G,

есть экран Nextion NX8048p070_11.
И есть код, который отлично работает как задумано на старой Uno atmega 16u2, а на китайской ch340g отказывается принимать данные с экрана..

драйвер ch341 устанавливал/переустанавливал - не помогает..

Использовал заведомо рабочую mega 2560, проверял на всех 4х портах - не помогает.

В чем может загвоздка, если на одной все работает а вторая молчит?

int in2 = 5;  //пин двигателя пилы		
int in3 = 6;  //пин зажима пилы		
int in4 = 7;  //пин зажима коретки		
int PUL1 = 9;  //пин перемешения каретки		
int DIR1 = 8;  //пин перемещения каретки		
int PUL2 = 11;  //пин перемещения пилы		
int DIR2 = 10;  //пин перемещения пилы		

String data;
char inc;
String params[10];
int d=0;

  long maxlength=20000;   //максимальная дистанция отьезда
  long alllength=0;       //необходимая длина трубки
  int quality=0;          //количество штук
  long length=0;          //промежуточная переменная
  int speed=270;          //скорость вращения
  long L=0;               //промежкточная переменная измерения остаточной длины

////////////////////////////// конец команды///////////////////////
void comandEnd() {
  for (int i = 0; i < 3; i++) {
    Serial.write(0xff);
  }
}
/////////////////////////////////////отправка команды///////////////////
void SendInt(String dev, int data)
{
  Serial.print(dev);   // Отправляем данные dev(номер экрана, название переменной) на Nextion
  Serial.print("=");   // Отправляем данные =(знак равно, далее передаем сами данные) на Nextion 
  Serial.print(data);  // Отправляем данные data(данные) на Nextion
  comandEnd();
  dev = "";    // Очищаем переменную
  data = "";   // Очищаем переменную
}
///////////////////////////////////перезод на новую страницу/////////////////
void Nextpage(String dev)
{
Serial.print("page");
Serial.print(" ");
Serial.print(dev);
comandEnd();
  dev = ""; 
}

////////////////////////////////////////////////////////
void Waiting(String search)
{
  while(params[0].indexOf(search)<0)
  {  //проверка старта экранаю Когда приходит Start выходитм из петли и  идем по программе
    if(Serial.available()==false){
    }
    else
    Reading();

    }
  
}
/////////////////////////////////////////////////////////////
void Reading(){
  int i=0;
  int p=0;
  int l=0;
  while(Serial.available()){
    p=Serial.read();
    Serial.println(char(p));
    delay(100);
    if(p==33){
      delay(200);
      params[i].remove(0);
      params[i]=data;
      Serial.println(params[i]);
      delay(200);
      i++;
      data="";
    }
    else
    data+=char(p);
    
  }
}
////////////////////////////////////////пауза//////////////////////////////////
void Pause(){
  Serial.println(params[0]);
if(params[0].indexOf("Pause")>0)
  while(params[0].indexOf("Pauseoff")<0)
    Reading();
}
/////////////////////////////////////////////////////////////////////////////////
void Stop(){

  
}
////////////////////////////////////////////////////////
void setup()		
{		
  pinMode (in2, OUTPUT);//  Двигатель пилы		
  pinMode (in3, OUTPUT);//  Зажим пилы		
  pinMode (in4, OUTPUT);//  Основной зажим каретки		
  pinMode (DIR1, OUTPUT);// Двигатель перемещение каретки		
  pinMode (PUL1, OUTPUT);// Двигатель перемещение каретки		
  pinMode (DIR2, OUTPUT);// Двигатель перемещение пилы		
  pinMode (PUL2, OUTPUT);// Двигатель перемещение пилы		

  /////////новый блок
  Serial.begin(9600);
}		

void loop()
{
///////////////////////////////ожидание ответа экрана//////////////////
Serial.println("Старт");
Waiting("Start");
  delay(150);
Serial.println("Проверка пройдена");
delay(500);
while(d<=100){  // запорняем прогресс бар
SendInt("page0.j0.val",d);
d+=10;
delay(100);
comandEnd();
}
delay(3000);
Nextpage("page1");
delay(100);   //внести свич кейс для выбора внесений параметров
Waiting("params");
Serial.println("params yes");
Serial.println(params[0]);
delay(1000);
 //конец блока загрузки данных
  alllength=params[1].toInt(); 
  quality=params[2].toInt();
Serial.println(alllength);
Serial.println(quality);
 ////////////////////////////////////////// Первый отпил ////////////////////////////////
      digitalWrite(in3, HIGH);      // вкл. зажим пилы		
      digitalWrite(in4, HIGH);      // вкл. осн.зажима каретки		
      delay(  300 );		
      digitalWrite(in2, HIGH);     // вкл. двигателя пилы	
    movesaw(6300,1700,HIGH);
    movesaw(6300, 300, LOW);
      digitalWrite(in2, LOW);     // откл. двигателя пилы		
      digitalWrite(in4, LOW);     // откл. осн.зажима каретки		
      delay( 200 ); 
////////////////////////////////////// Основная программа //////////////////////////////////   
  for (int i = 0; i < 	quality ; i++) {  // кол-во циклов
  Serial.println(i);
  length=alllength;
    do{
      digitalWrite(in4, LOW);      // откл. зажима каретки		
      delay(  200  );
      if(length>maxlength){
      L=maxlength;}
      else{
      L=length;}
    movedetail(L, speed, HIGH);
      delay(  200  );		
      digitalWrite(in4, HIGH);      // вкл. осн.зажима каретки
      delay(300);
      digitalWrite(in3, LOW);      // откл. зажим пилы		
      delay(  200  );
    movedetail(L, speed, LOW);
      length=length-maxlength;
      delay(  200  );		
      digitalWrite(in3, HIGH);      // вкл. зажима пилы
      delay(300);
   }while(length>0);
    digitalWrite(in2, HIGH);     // вкл. двигателя пилы	
    movesaw(6300,1700,HIGH);
    movesaw(6300, 300, LOW);
    digitalWrite(in2, LOW);     // откл. двигателя пилы		
    digitalWrite(in4, LOW);     // откл. осн.зажима каретки		
    delay(  200  );  
    /////////////////////////////пауза и стоп/////////////////////////////////////////////
  Pause();
  }
  ///// дописать  выталкивание детали

  pinMode (in2, INPUT);//  Двигатель пилы		
  pinMode (in3, INPUT);//  Зажим пилы		
  pinMode (in4, INPUT);//  Основной зажим каретки		
  pinMode (DIR1, INPUT);// Двигатель перемещение каретки		
  pinMode (PUL1, INPUT);// Двигатель перемещение каретки		
  pinMode (DIR2, INPUT);// Двигатель перемещение пилы		
  pinMode (PUL2, INPUT);// Двигатель перемещение пилы	
}
////////////////////////////////////////////////// функции //////////////////////////////////////////
void  movesaw(int length, int speed, char move){ // функция поднятия пилы //1-расстояние, 2-скорость, 3-движение
    for (int i = 0; i < length ; i++) {  //  быстрый подъем для отпила    
      digitalWrite(DIR2, move );    // LOW - движение вверх, HIGH - вниз
      digitalWrite(PUL2, HIGH);   
      delayMicroseconds(speed);  // скорость подьема   
      digitalWrite(PUL2, LOW);
      Reading();
       }  
  }
void movedetail(long length, int speed, char move){ //движение каретки //1-расстояние, 2-скорость, 3- направление
  int sp=350;
  for (long i = 0; i <  length	; i++) { // откат каретки на захват трубки
      if (i>500){ // условие разгона
        sp=speed;
      }
      digitalWrite(DIR1, move);		// LOW - движение от пилы к двинателю, HIGH - к пиле
      digitalWrite(PUL1, HIGH);		
      delayMicroseconds(sp);  // скорость отката		
      digitalWrite(PUL1, LOW);
      Reading();	
  }
}

в delay и в пропусках, буфер наверное можно создать для накопления сообщений, и может что еще…
опишите пж свой опыт с ардуино, сколько времени вы с ней сидели ?
не со своим проектом, а вообще

У вас этот дисплей в виде шилда?
Если да - проверь распиновку (наименование выводов) на одной уно и на другой. Сравни. Скорее всего различие какое-то имеется.

Прошу прощения..

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

тогда лично для меня это задача становится невыполнимой)))

меня неоднократно выручал этот парсер данных, как вы его встроите не знаю…

int a = 0;
int b = 0;
int c = 0;

void setup() {
Serial.begin(115200); // Инициализация последовательного порта на скорости 115200 бод
}

void loop() {
if (Serial.available() > 0) { // Проверяем, есть ли доступные данные
String input = Serial.readStringUntil('\n'); // Читаем строку до символа новой строки
// Проверяем, начинается ли строка с 'R' и содержит 'G' и 'B'
if (input.startsWith("R") && input.indexOf('G') > 1 && input.indexOf('B') > 1) {
// Извлекаем значения
int rIndex = input.indexOf('R') + 1;
int gIndex = input.indexOf('G');
int bIndex = input.indexOf('B');
// Извлекаем числа из строки
a = input.substring(rIndex, gIndex).toInt();
b = input.substring(gIndex + 1, bIndex).toInt();
c = input.substring(bIndex + 1).toInt();

Serial.print(a);
Serial.print(' ');
Serial.print(b);
Serial.print(' ');
Serial.print(c);
Serial.print(' ');
}
}
}//конец

вот ответ от ии может сработает…

void Reading() {
  static String dataBuffer = ""; // Статический буфер, чтобы данные не терялись между вызовами
  while (Serial.available()) {
    char c = Serial.read();
    // Проверяем, не является ли это концом команды (0xFF)
    if (c == (char)0xFF) {
      // Простейшая проверка на тройной 0xFF.
      // В реальности нужен более надежный метод, но для начала сойдет.
      if (dataBuffer.length() > 0 && dataBuffer.charAt(dataBuffer.length() - 1) == (char)0xFF) {
        // Мы уже накопили два 0xFF подряд? (Упрощенно)
        // Пропускаем, так как это окончание.
      } else {
        dataBuffer += c;
      }
    } else {
      dataBuffer += c;
    }
    // Здесь НЕТ delay!
  }

  // Теперь проверяем, есть ли в буфере полная команда, заканчивающаяся тремя 0xFF
  if (dataBuffer.endsWith(String((char)0xFF) + String((char)0xFF) + String((char)0xFF))) {
    // Нашли полную команду! Убираем маркер конца.
    String fullCommand = dataBuffer.substring(0, dataBuffer.length() - 3);
    
    // Разбираем команду (аналог вашего разбора по '!')
    int separatorIndex = fullCommand.indexOf('!');
    if (separatorIndex != -1) {
      // Допустим, формат "команда!параметр"
      params[0] = fullCommand.substring(0, separatorIndex);
      params[1] = fullCommand.substring(separatorIndex + 1);
    } else {
      params[0] = fullCommand;
    }
    Serial.println("Получено: " + params[0]); // Для отладки
    
    // Очищаем буфер для следующей команды
    dataBuffer = "";
  }
  
  // Небольшая защита от "мусора", если буфер слишком большой, но нет конца команды
  if (dataBuffer.length() > 100) {
    dataBuffer = "";
  }
}

Замените вашу функцию Reading() **на эту

ну может и еще кто что подскажет**…

Нет, дисплей не в виде шилда. отдельная плата имеющая rx-tx для общения с ардуино и ей подобными.

Подключение выполнено подобно этой схеме.

Ну так вам чип UART мешает общению !

Пробуйте SoftwareSerial на других ногах или 328PB с двумя serial …

1 лайк

Спасибо, сейчас попробую. Не думал все же, что проблема в коде..

Но меня если честно смущает именно факт, что на старой Uno все замечательнейшим образом работает, а на китайских новых ничерта не пашет… дабы исключить неисправность, случайность и совпадение пробовал запускать на 2х mega 2560 и uno..

Сделайте джампер на Rx - что бы можно было включать при прошивке и отключать при работе

пробовал через softserial - результат - не работает :grin:

пробовал на mega 2560 на всех портах - не работает..(на двух мегах пробовал)

Когда вы подключаете экран к пинам RX TX, ch340 вообще никак не участвует в обмене. Поэтому ваше предположение неверно.
Может на китайской плате просто контакты плохие и в них провода болтаются? Вообще Уно не лучший выбор для поделок - берите лучше Нано

Если я Вас правильно понял, в общении через последовательный порт (rx-tx) ch340 вообще не участвует, а участвует только при контакте, например, с пк при загрузке скетча/мониторинге порта?

Именно так, ch340 это мост между последовательным портом и USB. Без USB он не задействован.

Код довольно кривой. Откуда он?
Например строки 34-35 делают совсем не то, что написано в комментарии

спасибо за внесение ясности!

код в общем самописный, но функция, на строки которой вы указали, взята целиком с просторов всемогущего интернета))

При вызове функции таким образом аргументы (String dev, int data) сначала копируются во временные переменные и все действия внутри функции выполняются не с переменными основной программы, а с копиями. Если функция изменяет значения переменных, это касается только копий, внешняя переменная не меняется.
Поэтому очищать переменные перед выходом нет никакого смысла, это не работает.

Ну а строчка

data = "";  

это просто ошибка, data это целое, и присваивать ее пустой строке это бред

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

Что-то я Вам не верю.
В коде вся работа происходит с Serial, а Serial1 ... Serial3 нигде не используются.

NB! Всегда приводите именно тот код, который обсуждаете!

я превел. мне не нужно использовать все 4 порта одновременно.. когда пробовал на меге в коде менял сериал на сериал1,2,3 результат одинаков, так же как и при использовании softserial..
Но опять же в голове один и тот же вопрос. Почему на одной уно код абсолютно корректно работает, а на остальных НЕТ!?..

1 лайк
  1. Этого кода Вы не привели.
  2. На Меге нет смысла (а иногда и возможности) использовать SoftSerial.
  3. Схему Вы также забыли привести.

А я где-то потерял свой хрустальный шар, так что не взыщите…