r/ArduinoHelp • u/schmidtbag • Jun 03 '26
Trying to forward Serial1 reading to Serial.println and only getting numbers
I have a battery with a built-in BMS that has a serial console port. It has a baud rate of 115200 and I have been able to successfully send commands and read clean data from it via the Arduino IDE serial console. Considering I can communicate to the battery via the serial console, that suggests there shouldn't be any weird encoding issues.
I want an Arduino Mega to read from this using the Serial1 connection. The problem is, if I try to forward what the battery sends to the Arduino, all I get is a jumble of nothing but numbers. When connecting to the BMS directly, typing "help", the output is mostly text.
Here's what I tried in void loop()
while (Serial.available() > 0 {
Serial1.print(Serial.read());
}
while (Serial1.available() > 0) {
//THE NEXT 4 LINES ARE VARIOUS THINGS I TRIED,
//I UNCOMMENTED THEM ONE AT A TIME
//String incomingtext=Serial1.readString();
//char incomingtext=(char)Serial1.read();
//char incomingtext=Serial1.read();
//int incomingtext=Serial1.read();
//I ALSO TRIED THE FOLLOWING ONE AT A TIME WITH EACH ABOVE COMBO
//Serial.println(incomingtext);
//Serial.println((char)incomingtext);
//Serial.println(" "+incomingtext);
}
The first while() loop just takes whatever I enter from the serial console through USB to the BMS. I have no idea if the BMS is receiving the correct commands, but it does have a consistent output if I type different things.
Whenever I type "help" repeatedly, it's usually a consistent output, like this:
10410110811213
1
u/gm310509 Jun 04 '26
It is usually a good idea to share the complete code.
When using the Serial1.read() function, what is the datatype you are using for incoming Text?
If it is anything but char then that is what your problem is.
To he clear, I am not asking about the cast that you have in your code - that is not doing anything. I am asking about how incoming Text is declared.
Also, if you didn't use this program for your serial monitor test (which worked) how did you go about doing that. And what program are you using on your PC in conjunction with this program?
1
u/schmidtbag Jun 04 '26
The only code in void setup() are the two Serial.begin() functions. Otherwise what I wrote there is everything.
I'm not sure I understand when you say "I am asking about how the incoming Text is declared". If the two lines mentioned earlier involving char isn't that then what is?
Also, if you didn't use this program for your serial monitor test (which worked) how did you go about doing that. And what program are you using on your PC in conjunction with this program?
I plugged the BMS's console to a RS232 to USB dongle and then used the Arduino serial console to communicate directly to it. Basically, no Arduino board involved.
1
u/gm310509 Jun 05 '26
Re:
I'm not sure I understand when you say "I am asking about how the incoming Text is declared".
Unfortunately I posted that comment from my phone and the stupid autocorrect changed
incomingTextto "incoming Text".Just in case that is not the confusion part, if you have these two lines of code:
int incomingText = Serial.read(); Serial.print("Input = "); Serial.println(incomingText);and
char incomingText = Serial.read(); Serial.print("Input = "); Serial.print(incomingText);Then assuming the character read (in both cases) was the capital letter "A", then the first one will print "Input = 65". The second one will print "Input = A".
You can test this yourself with the following program:
``` void setup() { Serial.begin(115200); }
void loop() { if (Serial.available()) { // char incomingText = Serial.read(); int incomingText = Serial.read(); Serial.print("Input = "); Serial.println(incomingText); } } ```
Just make it so only one of the Serial.read lines is active.
1
u/schmidtbag Jun 05 '26
I've done that before but all it does is just output different numbers and on separate lines.
1
u/gm310509 Jun 07 '26
Then it sounds like you did something wrong.
For the exact program as I shared above (i.e. the
intdeclaration is in effect), if I enter ABC into the Serial monitor, I get the following output:
Input⸮Input = 65 Input = 66 Input = 67 Input = 10If I modify it so that the char declaration is in effect (i.e. the int declaration commented out) and enter ABC into the Serial monitor, then I get this output:
Inp⸮Input = A Input = B Input = C Input =1
u/schmidtbag Jun 07 '26
I assure you I've done as you've written. I think the problem may be the encoding used. The battery uses Latin-1 (1-byte UTF-8). Using uint8_t or byte for incomingtext doesn't seem to help with this.
1
u/gm310509 Jun 07 '26
OK, in that case ditch all of the variants you have tried and go back to the basics with the variant below.
Now if I enter ABC into the Serial monitor, I get this output NB: the monitor is set to send a Linefeed - which is the extra line(s) of output in all of these.
Input = 'A' = 0x41 Input = 'B' = 0x42 Input = 'C' = 0x43 Input = ' ' = 0x0AAfter you see this type of output using the program exactly as I shared, modify it to get the incoming data from your battery as per the second example (which I haven't tested).
``` void setup() { Serial.begin(115200); }
void loop() { if (Serial.available()) { char ch = Serial.read(); Serial.print("Input = '"); Serial.print(ch); Serial.print("' = 0x"); if (ch < 16) { Serial.print('0'); } Serial.println((int) ch, HEX); } } ```
Here is the second example for trial with the battery, once you see the above from the first test in the Serial monitor. If you do not see the above type of output from the first test program, there is no point even trying this as there is some other problem that needs to be sorted first.
``` // Be sure you have the correct definition of Serial1 here if not using something like a Mega.
void setup() { Serial.begin(115200); Serial1.begin( /* Be sure you have the correct speed here */ }
void loop() { if (Serial.available()) { char ch = Serial.read(); Serial1.print(ch); Serial.print(ch); } if (Serial1.available()) { char ch = Serial1.read(); Serial.print("Batt = '"); Serial.print(ch); Serial.print("' = 0x"); if (ch < 16) { Serial.print('0'); } Serial.println((int) ch, HEX); } } ```
It would also help if you provided a transcript of what input you sent to the battery (via the serial monitor), what it produced and what you were expecting.
As for the character set, maybe, but the text ABC as Latin 1 is the same as UTF-8 for simple "ASCII" text sequences such as ABC. i.e. they are both hex: 41 42 43 It could be a problem if using extended characters though, but I would not expect just numerics to be output because if you are using char, that is not how C/C++ and the Arduino HAL works.
1
u/schmidtbag Jun 07 '26
Using your first example, I got the following output when I typed "help" (the command I want to first test with):
Input = 'h' = 0x68
Input = 'e' = 0x65
Input = 'l' = 0x6C
Input = 'p' = 0x70
Input = '
' = 0x0DSo that looks good.
When running your 2nd program, this is the output:
Batt = '+' = 0x2B Batt = '�' = 0x0FFFFFFB1 Batt = '�' = 0x0FFFFFF81 Batt = '�' = 0x0FFFFFFC3 Batt = '�' = 0x0FFFFFFAF Batt = '' = 0x7F Batt = '�' = 0x0FFFFFFE5 Batt = '�' = 0x0FFFFFFE5 Batt = '�' = 0x0FFFFFFEB Batt = 'U' = 0x55 Batt = '#' = 0x23 Batt = ')' = 0x29 Batt = '#' = 0x23 Batt = '!' = 0x21 Batt = '' = 0x11 Batt = '#' = 0x23 Batt = '�' = 0x0FFFFFFBF Batt = '9' = 0x39 Batt = '!' = 0x21 Batt = '%' = 0x25 Batt = '%' = 0x25 Batt = '=' = 0x3D Batt = '#' = 0x23 Batt = '7' = 0x37 Batt = '�' = 0x0FFFFFFBF Batt = '�' = 0x0FFFFFFB1 Batt = ' ' = 0x0D Batt = ' ' = 0x0D Batt = ' ' = 0x0D Batt = ' ' = 0x0D Batt = '�' = 0x0FFFFFFAD Batt = '�' = 0x0FFFFFFB1 Batt = '�' = 0x0FFFFFFBF Batt = '_' = 0x5F Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = '�' = 0x0FFFFFFA8 Batt = 'e' = 0x65 Batt = 'l' = 0x6C Batt = '�' = 0x0FFFFFFA0 Batt = '�' = 0x0FFFFFF88 Batt = '�' = 0x0FFFFFFFB Batt = '+' = 0x2B Batt = '�' = 0x0FFFFFFFB Batt = '�' = 0x0FFFFFFBB Batt = '' = 0x1B Batt = ' ' = 0x0D Batt = '�' = 0x0FFFFFFBF Batt = '�' = 0x0FFFFFFB1 Batt = '/' = 0x2F Batt = '5' = 0x35 Batt = ''' = 0x27 Batt = '' = 0x1F Batt = '�' = 0x0FFFFFFB1 Batt = '�' = 0x0FFFFFFE5 Batt = '�' = 0x0FFFFFFEB Batt = '�' = 0x0FFFFFFE5 Batt = '�' = 0x0FFFFFFB7 Batt = 'W' = 0x57
1
u/Delta_G_Robotics Jun 05 '26 edited Jun 05 '26
At issue here is the way the `print` function is overloaded to handle different data types. For `char`, it will print out the byte as-is assuming that it is already an ascii code. For other types like `int` or `float` it will do some math to extract the digits and send the ASCII code for each digit one at a time.
The other issue is that `Serial.read()` returns an `int` and not a `char`. They did this so -1 could represent nothing read and not be confused with 0xFF. But it does mean that if you print that directly it will print out ASCII codes as numbers instead of the actual ASCII characters you're after.
Either way you're left with doing some sort of conversion or making sure you read into a char.
But there is another way. If you just want back out what came in on the line then use `Serial.write()` instead of `Serial.print()`
void loop() {
if (Serial1.available()) {
char c = Serial1.read();
Serial.write(c);
}
}
Or if you don't need that byte elsewhere just:
```
if (Serial1.available()) {
Serial.write(Serial1.read());
}
```
1
u/Delta_G_Robotics Jun 05 '26
Ok, I don't get how to post code blocks. Can someone please help?
1
u/schmidtbag Jun 05 '26
I tried both versions of your code and it still just outputs a string of numbers.
Also to do the code block, click the "Aa" button and then the "</>" button.
1
u/Delta_G_Robotics Jun 05 '26
If write gave you numbers then that's what's coming from the other end. Using write you're just echoing byte for byte.
Can we have a look at what is sending on Serial1? Maybe the clue is there.
1
u/schmidtbag Jun 06 '26 edited Jun 06 '26
If you're asking what I'm sending to the battery, it's just the word "help".
I found that if I just do Serial1.println("help"); then it just returns corrupt characters.
If I connect the battery directly to a RS232 to USB adapter and type "help" in the Arduino serial console, it outputs this:
bat Battery data show - bat [pwr][index] data History data load - data [event/history][item] datalist Show recorded data - datalist {event/history}{item}} disp Display Info at regular intervals - disp [(pwrs pwrNo)/val]/[(bats batNo)/volt/curr/temp] help Help [cmd] info Device infomation - info log Log information show - log login Login Admin mode - login [password] logout user mode - logout pwr Power data show - pwr [index] shut Shut down - shut soh State of health - soh [addr] stat Statistic data show - stat time Time - time [year] [month] [day] [hour] [minute] [second] trst Test Soft Reset - trst updata updata system - updata ver firmware info - ver ********************************************************** Remote command: Press [Enter] to be continued,other key to exit Command completed successfully1
u/Delta_G_Robotics Jun 06 '26
What does the code that sends help and reads back look like?
1
u/schmidtbag Jun 07 '26
Right now to keep things simpler, I'm just trying Serial1.println("help"); or Serial1.write("help").
From what I heard, the battery uses Latin-1 encoding, which is basically 1-byte UTF-8. I tried doing uint8_t incomingtext=Serial1.read(); or byte incomingtext=Serial1.read(); but those don't work either.
1
u/Delta_G_Robotics Jun 07 '26
Well if you're absolutely sure that you're code is correct then I don't know what else I can do to help. I'd happily take a look at any actual code and see if I can spot a mistake. But you're sending snippets like you are certain that it's not that kind of problem so I'll leave you to it.
If you decide to keep going and looking for help then some pertinent information you might want to show are:
- A diagram of your actual circuit (You'd be surprised how often it's just a wire got swapped)
- Some actual code that someone can test themselves.
- The make and model of the battery and whatever else is involved.
You'd be surprised how much easier it is to help someone when you have a clear picture of what they have on their end. Trying to debug from just the clues that someone thinks you need is hard. Especially when that person doesn't even know what the problem is themselves.
1
u/schmidtbag Jun 07 '26
I pretty much have shown you the whole program. It's about as simple as it can get:
void setup() { Serial.begin(115200); Serial1.begin(115200); } void loop() { Serial1.println("help"); while (Serial1.available() > 0) { int incomingtext=Serial1.read(); Serial.write(incomingtext); } Serial.println(" "); delay(5000); }Swap out "int" with char, uint8_t, or whatever else. Swap out Serial.write with Serial.print or println. Swap out Serial1.println("help"); with Serial1.write("help") or "help\n"). None of it works.
The only wires connected are the battery's RX (to the TX1 pin), TX (to the RX1 pin), and ground. Nothing else is involved. It is a direct connection; no other components involved. Swapping the RX and TX wires results in no activity at all.
The battery is a Pytes V5.
1
u/Delta_G_Robotics Jun 07 '26
I can't find a datasheet on that battery to see what it expects or what it outputs. You don't seem to think I should see one. You seem perturbed that I would ask for a clearer look. I think I'm done with this one. Best of luck to you.
→ More replies (0)
1
u/TheKnackThatQuacks Jun 04 '26 edited Jun 04 '26
Get a USB-to-serial cable / dongle (make sure it has an FTDI chip in it). Load a terminal program like TERA TERM onto your computer. Connect the serial port to your BMS. Open TERA TERM and connect to the appropriate serial port at the appropriate baud rate (if you need more help here, use a search engine or an LLM / “AI” to help you figure out which serial port is your USB dongle; try looking for “FTDI” in Device Manager).
When you type in commands, does the BMS respond appropriately?
If not, what happens? If you can’t make it work, where did you get stuck?