Как проверить UART?

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

Здравствуйте. Прошу помощи ибо что-то в тупике. Плата arduino nano. Через USB вход прошивки загружаются без проблем.

1. Я правильно понимаю, что если прошивки через штатный usb заливаются, то uart у нее рабочий?

Гуглил вопрос как проверить UART, и ответ: "замкнуть RX-TX и отправить чего нибудь в порт, если вернулось то исправно".

Замкнул, накатал такой код

#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 8); // RX, TX
byte i=0;
byte j=0;

void setup() {
  Serial.begin(9600);
  delay(1000);
  mySerial.begin (9600);
  delay(1000);
}

void loop() {
  Serial.print(i);
  if(Serial.available()>0){
    j=Serial.read();
    mySerial.print(i);
    mySerial.print(" - ");
    mySerial.print(i,HEX);
    mySerial.print(" | ");
    mySerial.print(j);
    mySerial.print(" - ");
    mySerial.println(j,HEX);
  }
  delay(1000);
  i++;
}

на software serial получаю такие данные:

0 - 0 | 50 - 32
1 - 1 | 50 - 32
2 - 2 | 55 - 37
3 - 3 | 50 - 32
4 - 4 | 50 - 32
5 - 5 | 56 - 38
6 - 6 | 50 - 32
7 - 7 | 50 - 32
8 - 8 | 57 - 39
9 - 9 | 50 - 32
4 - 4 | 52 - 34
5 - 5 | 53 - 35
6 - 6 | 54 - 36
7 - 7 | 55 - 37
8 - 8 | 56 - 38
9 - 9 | 57 - 39
10 - A | 49 - 31
11 - B | 48 - 30
12 - C | 49 - 31
13 - D | 49 - 31
14 - E | 49 - 31
15 - F | 50 - 32
16 - 10 | 49 - 31
17 - 11 | 51 - 33

Т.е. i выводится правильно - software serial работает корректно. А в j данные выглядят как случайный мусор вне зависимости замкнуты RX и TX или нет.

2. Почему так?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

Пока что из двух посылок:

1. Ардуина прошивается, следовтельно UART исправен.

2. Вы в консоли получаете что-то невразумительное.

Следует очевидный вывод:

Вы что-то делаете неправильно. Что именно - без схемы сказать нельзя.

КашыLot
Offline
Зарегистрирован: 24.05.2017

Ev_geniy пишет:
Т.е. i выводится правильно - software serial работает корректно. А в j данные выглядят как случайный мусор вне зависимости замкнуты RX и TX или нет.

В j результат чтения порта, а где запись в порт ?

С чего бы i выводиться неправильно, если она  переменная цикла и не связана с Serial ?

 

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

andriano пишет:

Вы что-то делаете неправильно. Что именно - без схемы сказать нельзя.

Ок. Схема такая. После прошивки к компу цепляется только FTDI.

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

КашыLot пишет:

В j результат чтения порта, а где запись в порт ?

В строке 14

КашыLot пишет:

С чего бы i выводиться неправильно, если она  переменная цикла и не связана с Serial ?

Это я к тому, что Software serial отрабатывает корректно.

gena
Offline
Зарегистрирован: 04.11.2012

Попробуйте добавить задержки в конце 14-й и в конце 15- строк.

 

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

Добавлял задержки на 1, 5, 10, 50, 100 мс - не помогает. Пробовать другие, наверное, смысла нет.

gena
Offline
Зарегистрирован: 04.11.2012

А не попробывать бы Serial.flush()?

КашыLot
Offline
Зарегистрирован: 24.05.2017

Ev_geniy пишет:
В строке 14
Это не запись байта, а печать ASCII строки в порт. Например байт 0xFF (255) распечатается в виде трех  ASCII символов "2", "5", "5" , а 0x0F (15)   как "1", "5".

Замените .print на .write 

okta
Offline
Зарегистрирован: 10.01.2015

Правильно вам подсказывают, то, что вы видите в j - это не мусор, это ASCII коды символов "0"=48 "1"=49  и т.д. Кроме того, цифра 10 будет передаваться как два символа (два байта), а считываете из буфера один. Но второй то байт остается в буфере, и будет считан на втором проходе (а тем временем в буфер упало еще сколько-то байт)...

Итого, решения два: вычитывать каждый раз весь буфер while(Serial.avalible()){читаем что там пришло}, но при этом понимать, что получаем не просто число, а строку кодированную ASCII. Либо, как сказали выше, использовать write. Кстати, вычитывать буфер полностью будет правильнее и в этом случае.

И еще одно. После строки 14 нужна задержка - иначе не успеют данные в буфер упасть.

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

Gena, КашыLot, okta спасибо! Разобрался, заработало! С print/write я конечно лоханулся :) У меня были подозрения, что данные таки доходят, но в некой кодировке. Но так и не уловил закономерность. Только после комментария про буфер все встало на свои места :)

Раз уж открыл тему, прикладываю рабочие примеры.

Отправляем/получаем строку в ASCII:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 8); // RX, TX
byte i=0;

void setup() {
  Serial.begin(9600);
  delay(100);
  mySerial.begin (9600);
  delay(100);
}

void loop() {
  Serial.print(i);
  delay(10);
  if(Serial.available()>0){
    byte j=0;
    byte buf[3];
    while(Serial.available()){
      buf[j]=Serial.read();
      j++;
    }
    mySerial.print(i);
    mySerial.print(" [ ");
    for(byte k=0;k<j;k++){
      mySerial.print(buf[k]);
      if(k<j-1)mySerial.print(" | ");
    }
    mySerial.println(" ] ");
  }
  delay(100);
  i++;
}

И отправляем/получаем байты:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(9, 8); // RX, TX
byte i=0;

void setup() {
  Serial.begin(9600);
  delay(100);
  mySerial.begin (9600);
  delay(100);
}

void loop() {
  Serial.write(i);
  delay(10);
  if(Serial.available()>0){
    byte j=Serial.read();
    mySerial.print(i);
    mySerial.print(" | ");
    mySerial.println(j);
  }
  delay(100);
  i++;
}

Я правильно понимаю, что рекомендация "вычитывать буфер" для второго кода - это вроде как просто перестраховка? Или там более глубокий смысл есть?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ev_geniy, то, что Вы разобрались с программной частью - это хорошо. Нехорошо то, что Вы закорачиваете между собой контакты TX1 и RX0, которые у Ардуино Нано не свободны, а подключекны к микросхеме преобразователя USB-UART. Соответственно два выхода борются между собой - кто сильнее.

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

andriano, вот это новость. Можно подробнее кто там с кем борется и, главное, почему, если (я вам выше писал про это) USB порт отключен.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ev_geniy, как Вы отключаете USB порт? Режете дорожки?

КашыLot
Offline
Зарегистрирован: 24.05.2017

Ev_geniy пишет:
andriano, вот это новость. Можно подробнее кто там с кем борется и, главное, почему, если USB порт отключен.

1. USB порт отключен снаружи, но внутри схемы остается соединенным  с преобразователем USB-UART

2. Нежелательно прямое соединение выводов, которые могут быть программно определены как выходы. Но в случае с Nano,  линии RX и TX выведены от контроллера на внешний разъем через токоограничительные резисторы 1К и максимальный возможный ток не превысит  VCC/1000, это примерно 5/1000=5 мА

Как внутрисхемно устроен UART-USB не знаю, но если если его вывод №1 (RX) не способен переходить в состояние низкоомного выхода, то больших проблем от замыкания RX  c TX нет.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

КашыLot пишет:

Как внутрисхемно устроен UART-USB не знаю, но если если его вывод №1 (RX) не способен переходить в состояние низкоомного выхода, то больших проблем от замыкания RX  c TX нет.

Как он устроен, я тоже не знаю (тем более, что в разных модификащиях Ардуино он разный), но я думаю, что

Serial.begin(9600);

переключает его контакт, идущий к RX1 Ардуино, из высокоимпедансного состояния в рабочее. А что думаете по этому поводу Вы?

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

КашыLot, да, собственно, подобную инфу я и читал до того как замкнуть контакты, т.к. были опасения, что может поплохеть либо микросхеме контроллера, либо микросхеме ch340g на которой в моей nano сделан USB-UART. Ни где криминала на эту тему не нашел. Даже наоборот, несколько раз натыкался, что так тестровали работоспособность UART.

andriano, переключает контакт чего? Микросхемы USB-UART? Что-то меня берут сильные сомнения, что конкретно в моем случае контроллер хоть как-то управляет поведением ch340g. Хотя, нет, видимо ошибаюсь. Скорость то он обмена задает...

Ev_geniy
Offline
Зарегистрирован: 24.05.2017

Да, подумав, все же, вполне реально может быть там КЗ. Хоть и идет оно через килоомный резистор, но, наверное, это все же не очень хорошо... Когда паял на ch340g свой USB-UART переходник, там 1к резисторы в схеме на RX/TX были. Видимо микросхема на это рассчитана, надо еще ДШ почитать/вспомнить.

КашыLot
Offline
Зарегистрирован: 24.05.2017

andriano пишет:
Как он устроен, я тоже не знаю (тем более, что в разных модификащиях Ардуино он разный), но я думаю, что

Serial.begin(9600);

переключает его контакт, идущий к RX1 Ардуино, из высокоимпедансного состояния в рабочее. А что думаете по этому поводу Вы?

Выходы всегда низкоомные, но автор не замыкал выход на питание или общий провод

КашыLot
Offline
Зарегистрирован: 24.05.2017

Ev_geniy пишет:
Да, подумав, все же, вполне реально может быть там КЗ. Хоть и идет оно через килоомный резистор, но, наверное, это все же не очень хорошо... Когда паял на ch340g свой USB-UART переходник, там 1к резисторы в схеме на RX/TX были. Видимо микросхема на это рассчитана, надо еще ДШ почитать/вспомнить.
Будет сильнейшее  КЗ с током 5 мА