Как прочитать входящие ШЕСТНАДЦАТИРИЧНОЕ значение из serial метод read ()?

Краткое описание истории возникновения проблемы

Общаясь со старыми VersaStat II использовал интерфейсы gpib порт, а через gpib порта PCI карты перестал работать, но там был другой порт 25-контактный RS232 последовательный порт связи , но даже сейчас, жаль компьютеры abending последовательный порт к счастью, есть еще Андроиде виртуальный COM-порт который может использоваться с современный ноутбук так ESP32 микроконтроллера был выбран для общения с данным устройством беспроводной связи (может позже перейти на hc05 с модуля и т. д.).

Устранение проблемы разности напряжений

Теперь есть большая проблема, что последовательный порт esp32 использует +3,3 В или логику 1 и 0 В для логики 0, но в порту rs232 логика 0-это +3 В ~ +12 В, а логика 1-это -3 В ~ -12 В также неопределенная область ± 3В. Чтобы преодолеть эту проблему, я использовал следующую схему с оптронами.

Вот принципиальная схема

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

Код

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

BluetoothSerial SerialBT;
int speedsend = 9600;

void setup() {
  Serial.begin(speedsend);
  Serial2.begin(speedsend);
  SerialBT.begin("ESP32SERIAL");
  delay(500);
}

void loop() {

  if (Serial2.available()) {
//incoming data from the device
    int i = Serial2.read();
    SerialBT.write(i);
    Serial.println(i); // To check what is coming as output
  }
  if (SerialBT.available()) {
    Serial2.write(SerialBT.read());
  }

}

Но я не вижу никаких значимых символов в putty (Bluetooth COM-порт) в Arduino Serial Я вижу некоторые цифры в шестнадцатеричном представлении. Так ли общаются старые устройства?

Эта ссылка показывает, как шестнадцатеричные числа коррелируют с символами ASCII

https://www.rapidtables.com/convert/number/hex-to-ascii.html

Как исправить эту проблему я делаю что-то не так здесь параметры схемы и т. Д.

Пример связи с устройством

Для начала команда ID должна дать номер как 2532 в соответствии с книгой после преобразования она дает мне 32 32 34 32 0 0 , 2242, глядя на серийные номера Arduino с помощью веб-сайта преобразования, показанного в приведенном выше URL-адресе. Вот как я заметил, что он дает мне шестнадцатеричные числа.

Вот раздел интерфейса PDF rs232c PDF Оригинальная книга тоже шла с ID командной страницей.

https://drive.google.com/file/d/1BHhIsloF4voMxoFeSlz1GsjwfgHwgsPJ/view?usp=sharing

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

https://drive.google.com/file/d/1z0NUOe17SpVYTIBfEE8s0EKStfLKKv_-/view?usp=sharing

, 👍0

Обсуждение

[Это](https://forum.arduino.cc/index.php?topic=103418.0) может быть, вам это поможет, @Python Schlange

ваш вопрос не имеет никакого отношения к arduino ... это общий вопрос программирования, @jsotola

ваша проблема заключается не в покрытии hex в ascii ... это шестнадцатеричное преобразование текста в десятичное, @jsotola

Устройство передает шестнадцатеричные значения как в таблице, @Avon97

@Avon97 Если вы можете предоставить ссылку на руководство по эксплуатации устройства, мы могли бы сами проверить, что именно получает посылка. В коротком поиске в Google я нашел только руководства для версии 3 или 4, но не для версии 2., @chrisl

@chrisl Теперь я полностью отредактировал этот вопрос, @Avon97

в Arduino Serial я вижу некоторые числа в шестнадцатеричном представлении.- ...Нет, не знаешь. Вы используете println()` для целого числа, которое дает десятичное представление. Чтобы получить шестнадцатеричное представление, вы должны специально запросить шестнадцатеричное представление. Ваши числа десятичные. 32-это пробел., @Majenko

У вас есть miss understand @Majenko используется Arduino Serial смотрите, что происходит с переменной `i, потому что в putty Bluetooth Serial не имеет значимого результата, и вы правы 32 is space Я вижу, что в Bluetooth Serial in putty он идет как`__"_`, как я помню. ( подчеркивание-пробел), @Avon97


3 ответа


Лучший ответ:

1

Во-первых, вам не нужна эта действительно сложная схема оптрона. Вам просто нужен обычный чип MAX3232 (обратите внимание на дополнительные 3: это версия 3,3 В), вот для чего они предназначены: преобразование логического уровня RS232 в 3,3 В. Вы можете купить прорывные модули за копейки на вашем любимом рынке (ali-express, ebay и т. Д.).

Что касается вашего чтения, то ваше предположение, что ваши числа шестнадцатеричны, совершенно неверно. Они десятичные, а не шестнадцатеричные.

Вы считываете данные с удаленного устройства и сохраняете каждый байт в целочисленной переменной. Затем вы печатаете эту целочисленную переменную с помощью функции Serial.println(). Это всегда даст вам десятичное представление числовой целочисленной переменной.

Ваш ответ 32 32 34 32 0 0 , 2242 на мой наметанный глаз выглядит как плохая коммуникация. Возможно, это вызвано вашей схемой оптрона (немедленно измените ее на MAX3232), а может быть, вызвано несоответствием в вашей скорости передачи данных, количестве битов или настройках четности.

,

Спасибо, я должен сначала проверить связь с моим старым компьютером Core 2 duo, он имеет встроенный последовательный порт Да, вы можете быть правы, он имеет что-то делать с ошибкой связи, @Avon97

Действительно, это была плохая ошибка связи, я подключил его к компьютеру (COM-порт) напрямую, теперь он работает нормально, @Avon97


3

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

Когда вы просто пишете целое число , например 32, оно будет интерпретироваться компилятором как десятичное число. Десятичное число 32 равно шестнадцатеричному 20, которое является пробелом в ASCII.

Решение: Запишите свое число в виде десятичного значения следующим образом:

int i = 0x32;

0x, предшествующий значению, пометит его как шестнадцатеричное представление.

,

Но я получаю 32 из метода `int i = Serial2.read (); если мне 32, как это исправить, @Avon97

Получаете ли вы байт с десятичным значением 32 или получаете шестнадцатеричные данные в кодировке ASCII (это будет 2 символа, один 3" и один 2")? Если устройство посылает десятичное значение 32 в одном байте, то почему оно должно означать шестнадцатеричное 32? Так что же именно вы получаете?, @chrisl

Я получаю значение 2 получает как 32 к int i, @Avon97

Ты не ответил на мой вопрос. Получаете ли вы ASCII-символ `2"? Как именно вы проверили, что " я " для вас равно 32 (шестнадцатеричное или десятичное?)?, @chrisl

Когда я отправляю идентификатор команды из Putty, я получаю значения 32 32 34 32 0 0 в прочитать () метод по одной переменной я`, когда я преобразовать его в 2 2 4 2 или заказать 2242 говорит, что я должен сделать что-то вроде 2532, представляющий VersaStat 2 ТМ с ардуино int для преобразования в ASCII, это не имеет никакого смысла вообще. Кроме того, если я посылаю неправильные команды, в устройстве загорается индикатор ошибки, который выключается после того, как я посылаю правильную команду. Вот как я думаю, что это должен быть символ 2 для 32, @Avon97

Как это связано с замазкой? Можете ли вы показать больше своего кода? Если 32 -> '2', то это выглядит так, как будто вы ищете десятичное преобразование в ASCII. Преобразование hex в ASCII 0x32 приведет вас к ' '., @Dave X

@DaveX это что-то вроде этого `if (Serial2.available()) { int i = Serial2.read(); Serial.println(i); }`, @Avon97

Вы можете использовать Serial.println(i,DEC);, Serial.println(i,HEX); или Serial.write(i);Serial.println ();, чтобы повторить то, что вы получаете на Serial2 в различных форматах., @Dave X


3

Если 32-это шестнадцатеричное число, его число DEC будет 50, что является 2 в Arduino chars

Я все еще не понимаю,как вы будете получать числа,которые имеют A,B,C, D, F в шестнадцатеричных числах, таких как J, который является 4A в шестнадцатеричном представлении, эти команды должны работать, но не уверены, что для символа, который имеет английскую букву в шестнадцатеричном представлении.

Мой код

int i = 32; // какое вообще число

String string = String(i);

char *endptr; // хмм что-то с концовкой!

int out = strtol(string.c_str(), &endptr, 16);

Это даст вам 50 (для переменной out), что равно 2 символам Arduino ASCII

Я также тестировал 57 в шестнадцатеричном формате то есть W получает 87 а W обратно Arduino way

Нашел этот веб сайт Arduino official community form вот где я получил этот метод strtol

https://forum.arduino.cc/index.php?topic=500358.0

,

Вы можете передать nullptr для второго аргумента strtol', если на самом деле не собираетесь использовать его ни для чего. Тем не менее, если вы пишете надежный и не являющийся примером код, вы, как правило, *do* хотите использовать конечный указатель вместе с errno`, чтобы увидеть, произошел ли сбой "strtol", а также убедиться, что значение типа "long", возвращаемое "strtol", на самом деле соответствует диапазону типа любой переменной, которой вы в конечном счете назначаете это значение., @timemage