I think you are confused by the output? std::cout << (char)<char_code>;
is probably displaying the char_code as number (so for the char 65 (ASCII 'A') it will run number formatter and display '6' and '5' ("65") instead of "A")?
You should probably allocate some reasonably huge char buffer like char uartInput[1024];
, then read the characters into it till it's either full, or some termination mark is reached. Let's say you will send string "Hello"
from android as ASCII bytes terminated by zero, that means that over the wire will go these bytes: 72, 101, 108, 108, 111, 0
(any internal UART protocol bits removed).
So those values will be read by the serialGetchar
, stored into uartInput
, and then you can show them as ASCII string, for that a mere std::cout << uartInput;
should work (as cout can handle ASCII char[] zero terminated string well), or printf("%s", uartInput);
is other option with the *printf
functions family (I like these a tad more, although they are not C++ like).
Make sure the bytes sent from Android are in expected format (i.e. ASCII encoded, zero terminated, in order you expect them). For more robust application probably add some checksums and error handling, some data structure markers and protocol version numbers can be handy too, etc...
Edit (on new code version):
You look to be still confused what is ASCII, string, character and number in computer. I will try to show it with some code examples.
printf("%d ", 65);
// will output three glyphs from font forming visually "65 "
//first is "6" (ASCII code 0x36 = 54)
//second is "5" (ASCII code 0x35 = 53)
//third is space " " (ASCII code 0x20 = 32)
// (^^ usually a font glyph consisting of zero pixels drawn :))
printf("%c ", 65);
// will output two glyphs from font forming visually "A "
//first is "A" (ASCII code 0x41 = 65)
//second is space " " (ASCII code 0x20 = 32)
char charZeroTerminatedString[] = "Hello";
// will allocate somewhere in memory 6 bytes, with values set to:
// 72, 101, 108, 108, 111, 0
// symbol charZeroTerminatedString itself is an address of byte containing the value 72
// so 'H' == 72 == charZeroTerminatedString[0], 111 == charZeroTerminatedString[4]
// or 72 == *charZeroTerminatedString, 111 == *(charZeroTerminatedString+4)
printf("%s\n", charZeroTerminatedString);
// will output six (five+one control) glyphs from font forming visually "Hello" + newline
// First is "H" (value 0x48 = 72 in memory)
// ...
// Sixth "\n" glyph is not as much as glyph,
// as control character just moving virtual cursor to new line
So finally your loop can look like this:
#include <cstring>
//...
constexpr int UART_INPUT_MAX_SIZE = 1024;
char uartInput[UART_INPUT_MAX_SIZE+1];
//^^ +1 to have zero terminator even for 1024+ chars sent
//...
while (true) {
// clear the buffer for next receiving.
int uartInputIndex = 0;
memset(uartInput, 0, UART_INPUT_MAX_SIZE+1);
// now receive data, till they are available
// Or whole string is received
while (serialDataAvail(conexion) > -1 &&
uartInputIndex < UART_INPUT_MAX_SIZE) {
uartInput[uartInputIndex] = serialGetchar(conexion);
if (0 == uartInput[uartInputIndex]) break; //zero terminator received
++uartInputIndex;
}
if (0 == uartInputIndex) break; //No more strings received
printf("%s\n", uartInput); // some string received
// Either terminated by zero in byte stream
// or by serialDataAvail reporting no more data
}
Please bear in mind, that sending data over serial port takes some time, so exiting your loop while serialDataAvail reports zero available bytes may be too soon, as the rest of the data may be still on it's way trough the wire. So you should have some structural protocol designed to recognize ending of transmission, or have some delays along with time-out mechanism to wait for whole transmission.
The example code works well for me, when I was feeding it with instant fake complete data (in serialDataAvail
and serialGetchar
), but it will fail on real serial port communication to wait for whole data transmission.