0

Brief description about the problem History

Communicating with a old VersaStat II used GPIB port but the GPIB ports PCI card stopped working but there was a another port 25 pin rs232 Serial communication port but even now, too bad computers are abending the Serial port luckily there is still virtual Blutooth COM port which can be used with a modern laptop so ESP32 microcontroller was selected to communicate with this device wirelessly (might later go for HC05 module etc.).

Fixing the voltage difference problem

Now there is a big problem the esp32 Serial uses +3.3 V or logic 1 & 0 V for logic 0 But in the rs232 port logic 0 is +3 V ~ +12 V and logic 1 is -3 V ~ -12 V also ± 3V undefined region. To overcome this problem I have used the following circuit with optocouplers.

Here is the circuit diagram

enter image description here

The following code was used to communicate with the device easy as seems

Code

#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());
  }

}

But I see no meaningful characters in putty (Bluetooth COM port) in Arduino Serial I see some numbers in HEX representation. Is this the way old devices communicate?

This link show how HEX numbers correlate with ASCII characters

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

How to fix this issue am I doing something wrong in here the circuit parameters etc.

Communication Example with device

For a start the ID command should give a number as 2532 according to book after the conversion it gives me 32 32 34 32 0 0 , 2242 looking at the Arduino Serial numbers with the help of the converting web site shown in above url. That's how I noticed It gives me HEX numbers.

Here is the PDF rs232c Interface section PDF the original Book came with ID command page too.

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

Another book looks same but not from the book came with

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

8
  • This might help you – Python Schlange Feb 19 at 8:15
  • 1
    your question is unrelated to the arduino ... it is a general programming question – jsotola Feb 19 at 16:56
  • your problem is not hex to ascii coversion ... it is hex text to decimal coversion – jsotola Feb 19 at 16:58
  • Device transmits HEX values like in table – Avon97 Feb 19 at 17:00
  • 1
    @Avon97 If you can provide a link for the manual of the device, we could check ourselves, what exactly gets send. In a short google search I only found manuals for version 3 or 4, but not for 2. – chrisl Feb 21 at 0:42
1

Firstly you don't need that really complex optocoupler circuit. You just need a run-of-the-mill MAX3232 chip (note the extra 3 in there: it's the 3.3V version), that's what they're designed for: RS232 to 3.3V logic level conversion. You can pick up breakout modules for pennies on your favourite marketplace (ali-express, ebay, etc).

As for your reading, your assumption that your numbers are hexadecimal is completely wrong. They're decimal, not hexadecimal.

You read the data from the remote device and store each byte in an integer variable. Then you print that integer variable using Serial.println(). That will always give you a decimal representation of the numeric integer variable.

Your response of 32 32 34 32 0 0 , 2242 to my trained eye looks like bad communication. Maybe caused by your optocoupler circuit (change that for a MAX3232 immediately), or maybe caused by a mismatch in your baud rate, bit count, or parity settings.

2
  • Thank you, I have to check the communication first with my old core 2 duo computer first, it has a built in Serial port Yeah you may be right it has do something with communication error – Avon97 Feb 24 at 14:20
  • Indeed it was bad communication error I did connect it to the computer (COM port) directly now it works fine – Avon97 May 1 at 13:50
4

Your problem is, that you try to provide a HEX value, but you are actually providing a decimal value.

When you just write a whole number like 32, it will be interpreted by the compiler as a decimal number. The decimal number 32 is equal to HEX 20, which is a space character in ASCII.

Solution: Write your number as decimal value like this:

int i = 0x32;

The 0x preceding the value will mark it as a hexadecimal representation.

8
  • But I get 32 from the method int i = Serial2.read(); if i is 32 how to fix this – Avon97 Feb 19 at 9:01
  • Are you getting a byte with the decimal value 32, or are you receiving ASCII encoded hex data (That would be 2 characters, one '3' and one '2')? If the device send the decimal value 32 in one byte, why would it mean hexadecimal 32 with that? So what exactly are you receiving? – chrisl Feb 19 at 9:17
  • I am receiving value 2 gets as 32 to int i – Avon97 Feb 19 at 9:22
  • 1
    You didn't really answer my question. Are you receiving the ASCII character '2'? How exactly did you check, that i is 32 (hex or decimal?) for you? – chrisl Feb 19 at 9:51
  • 2
    You could use Serial.println(i,DEC);, Serial.println(i,HEX); or Serial.write(i);Serial.println(); to echo what you receive on Serial2 out on Serial in different formats. – Dave X Feb 19 at 17:40
3

If 32 is a HEX number its DEC number will be 50 which is a 2 in Arduino chars

I still don't understand is how you will receive numbers which has a A,B,C,D,F in HEX numbers like J which is 4A in HEX these commands should work but not sure for character which has a English letter in HEX representation.

My code

int i = 32; // what ever number

String string = String(i);

char *endptr; // hmm something to do with ending!

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

This will give you 50 (for out variable) which is 2 in Arduino ASCII chars

I also tested for 57 in HEX which is W gets 87 and W back Arduino way

Found this web site Arduino official community form thats where I got this method strtol

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

1
  • 1
    You're allowed to pass nullptr for strtol's second argument if you don't actually intend on using it for anything. That said, if you're writing robust and non-example code, you typically do want to use the end pointer along with errno to see whether or not strtol failed, as well as making sure the long type value that strtol returns actually fits within the range of the type of whatever variable you ultimately assign that value to. – timemage Feb 20 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.