I am trying to read digits (number from 0 to 255) from Serial port, convert them to HEX String and send them using SoftwareSerial as HEX.
For example: when I send '60' trough the serial port, the SoftwareSerial will send '3C'
currently I am using the following code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 4); // RX, TX
String inputString = "";
boolean stringComplete = false;
int HexInt = 0;
String HexString = "00";
void setup() {
Serial.begin(115200);
mySerial.begin(38400);
inputString.reserve(200);
delay(500);
Serial.println("");
mySerial.println("");
}
void loop() {
serialEvent();
if(stringComplete) {
HexInt = inputString.toInt();
HexString = String(HexInt,HEX);
if (HexInt<16) HexString = "0" + HexString ;
HexString.toUpperCase();
mySerial.println(HexString);
Serial.println(inputString); //debug
stringComplete = false;
inputString = "";
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == '\n') continue;
if (inChar == '\r') {
stringComplete = true;
if (inputString == "") inputString = "NULL";
inputString.toUpperCase();
continue;
}
inputString += inChar;
}
}
My question is: Is there a more elegant / effective way to perform the same outcome?
1 Answer 1
You have the number. It's made up of two nibbles, each representing 4 bits (1 hex character).
If you want to do a manual conversion take the first nibble (AND with 240) add it's value to "0" then do the same for the lower nibble (AND with 15).
OR
What I would do is use:
char HexString[3];
sprintf(HexString,"%02X",HexInt);
since you're not dealing with floats, you're good to go.
OR
edit: I recalled a printf
function that we put together once before, I don't know if it would work with SoftwareSerial, so you might have to play around with it a bit, but as a 3rd option, you could try the following. I don't have access to an Arduino or compiler at the moment, otherwise I'd have a play with this right now.
Before your setup:
// Function that printf and related will use to print
int serial_putchar(char c, FILE* f) {
if (c == '\n') serial_putchar('\r', f);
return Serial.write(c) == 1? 0 : 1;
}
FILE serial_stdout;
In your setup, add:
// Set up stdout
fdev_setup_stream(&serial_stdout, serial_putchar, NULL, _FDEV_SETUP_WRITE);
stdout = &serial_stdout;
in your loop, change your assignment to:
HexString = printf("%02X",HexInt);
-
It should be
char HexString[3];
, you need space for the null terminator at the end of the string. And depending on the source of the data input it may make sense to either use snprintf or verify that the value is never outside the expected range. It pays to always be paranoid about buffer overflows.Andrew– Andrew2017年08月01日 16:34:44 +00:00Commented Aug 1, 2017 at 16:34 -
I usually have to think about these, but running a quick test in gcc confirms for a value of
0x05
,HexString[0]='0'
,HexString[1]='5'
,HexString[2]=0
.Madivad– Madivad2017年08月02日 00:41:07 +00:00Commented Aug 2, 2017 at 0:41 -
Exactly, an array that is 3 long not the 2 long that you are allocating.Andrew– Andrew2017年08月02日 09:06:18 +00:00Commented Aug 2, 2017 at 9:06
-
yes. you're right... edited :)Madivad– Madivad2017年08月02日 11:44:11 +00:00Commented Aug 2, 2017 at 11:44
-
thank you very much for the quick respond.. I tried using the Second solution but I have a different issue now. I am actually trying to sent the HexString + another String like this
mySerial.println("GR+" + HexString);
and I get an error regarding char and string cannot be added together.user28282– user282822017年08月03日 06:18:31 +00:00Commented Aug 3, 2017 at 6:18