I'm programming with arduino 1.0.5 in lunix/windows
With this piece of code:
void readSerialString () {
char buffer[8];
if(Serial.available()) {
while (Serial.available()){
sb = Serial.read();
buffer[indexB] = sb;
indexB++;
}
}
Serial.println(buffer);
}
I'm trying to send (by serial terminal) a message that can be seen in hexadecimal.
For exemple if I write: "\xaa\x22\xa1"
It will not read as hexadecimal, will it?
How can I let the program read the string in input as hexadecimal?
No your mistaking the data and it s format.
do you have access to printf ? If so use printf("%x",char) to see a char as hexadecimal.
Arduino solution
Serial.print(78, HEX) gives "4E"
see http://arduino.cc/en/Serial/Print
[edit]
I need the contrary of print. I need that the string that has been token from the serial terminal is interpreted as hex.
To do this use read(), but you will have to implement the convertion function from ascii HEX to data, as an HEX data for a byte hols on 2 chars, my function take two chars as input)
char hex_ascii_to_databyte(char c1, char c2){
char res=0;
if(c1>=48 && c1<=57) res = c1-48;
else if(c1>=65&& c1<=70) res = c1 - 65 + 0xa;
else if(c1>=97&& c1<=102) res = c1 - 97 + 0xa;
else{//error
}
//idem c2 in res2
res=res<<4;
res+=res2;
return res;
}
for each hex read, call twice read (to read the 2 ascii chars) then call this func
Related
I am parsing an OLE object in doors.
The representation mixes ascii characters and objdata (hex value of ASCII chars) numbers:
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang2057{\fonttbl{\f0\fnil\fcharset0 Tahoma;}}
{\*\generator Riched20 10.0.17134}\viewkind4\uc1
\pard\f0\fs20{\object\objemb{\*\objclass Package}\objw4620\objh810{\*\objdata
01050000
02000000
08000000
5061636b61676500
00000000
00000000
d5c40000
02005f30306132636633392d323936612d346263612d396539342d383039343437336133343035
I am able to detect where my file starts using regex and objdata field.
Since my file extension is *.ole, I am going to search for the ".ole" string at the beginning of the objdata field (the long line starting with 0200) and backwards search for the 0200 hex string that.
My question is:
How can I convert from hex representation back to ascii a string in DXL?
Are there functions to perform this task? a simple cast would be enough? Or shall I write my own function to perform this task?
I wasn't able to find any hint on the ref manual, also some keyword or "RTFM page" would be gladly appreciated.
K.R.
The only support that I know of that might help you are char charOf(int asciiCode) and int(char ch).
I have not been able to spot ".OLE" (2E 4F 4C 45) or ".ole" (2E 6F 6C 65) in the line you posted, but assuming that these characters (or a combination of upper and lower characters) exist, one approach would be to walk through the objdata character for character (using a Buffer and an integer variable which loops over every character, something like int i = 0; int high; int low; Char c; while (...) { high = int(buf[i]); low = int(buf[i+1]); c = calculate_character_from_integers(high, low); i+=2; if c = ... then ...} and with this approach, whenever you have a new line, have another integer variable that points to the beginning of the line, and when you have something like "current character is 45 or 65 and the character before is 4C or 6C and the one before is 4F or 6F and the one before is 2E, then concatenate the file name from the start of the line." Not sure whether there are any scripts or snippets out in the wild that help here, perhaps you find something in the IBM DeveloperWorks DXL forums (hurry, they will cease to exist in two weeks)
I had to write a function from scratch based on Mike's reply and an old thread on IBM forums by user Mathias Mamsch.
I have many doubts on the buffer handling, buts it works fine for my purposes:
This functions performs the Hex2ascii translations of the string.
string Hex2Ascii(string &stringIn){
Buffer buf = create
string hexval
while(length(stringIn)>0){
hexval = iterateOnString(stringIn)
//print(charOf(intOfHex))
//print hexval
//print charOf(intOfHex(hexval))
buf += charOf(intOfHex(hexval))
}
return stringOf buf
}
It invokes other two functions; iterateOnString returns two chars to form a byte to be converted and removes it from the original string:
string iterateOnString(string &stringIn){
string StringOut
int x = length(stringIn)
if(x<2){
return ""
}
StringOut = stringIn[0:1]
stringIn = stringIn[2:]
return StringOut
}
then intOfHex converts the hex to int value, then the result is passed to charOf()
int intOfHex( string s ) {
if( "0x" == s[0:1] ) {
return intOf( realOf( eval_ "return_ (" s ") \"\"" ) )
} else {
return intOf( realOf( eval_ "return_ (0x" s ") \"\"" ) )
}
}
Any hint, optimization proposal or critic is welcome.
K.R.
I'm using an android app to send values to control servos.
Code:
char inputData[4];
char buffer[3];
void loop()
{
if(Serial.available() > 3) {
for (int i = 0; i < 4; i++){
inputData[i] = Serial.read();
}
char buffer[4];
buffer[0] = inputData[1];
buffer[1] = inputData[2];
buffer[2] = inputData[3];
buffer[3] = '\0';
int angle = atoi(buffer);
Serial.write(angle);
}
}
Issue: I'm getting the values + A-F letters to address each servo - A10, A180, B30 etc. Now the trouble is turning this to an actual integer. As you can see I've declared a character array to store the integers in and as suggested in a post on the arduino forum, I added a \0 at the end of the array. Currently, the Atoi returns random characters, mostly squares and some random numbers. I've tried even assigning them to a string and then .toInt() but same issue there, mostly squares.
Any ideas?
Thanks!
Use print or println to see the number as text. write sends it as byte and Serial Monitor shows a symbol with that ASCII code.
I am trying to create a software lighting desk by using Qt and Arduino with a DMX Shield. I've been able to establish communication between these two and can send commands over to Arduino Mega (at the moment the communication goes only one way). I am periodically (every 200 ms) sending values of 11 faders to Mega as a String.
eg.: A123 B234 C050 ... J222 M255
The values in the string above are variables based on the position of the sliders and should be used to adjust the values of light intensities saved into each fader on the Mega side. The Letters in each section identify corresponding fader. A = fader1, B = fader2, ... Just for clarity: I can bring up a light/s at a specific intensity -> these intensities are then assigned to a fader and when that fader is moved I want these values to adjust and be sent out to the actual lights/dimmers. The calculations work fine but my Mega would eventually become unresponsive.
I think my problem is parsing the incoming string. I have tried the strtok() method and readStringUntil() to no avail. It is also difficult to monitor the incoming strings in Serial Monitor as this is used for the communication with Qt.
Would be happy for any kind of help. Please ask questions if anything is unclear.
Edit:
This is one of my attempts at solutions
const char delim[2] = " ";
char *token;
if(Serial.available())
{
//incomingMessage = Serial.readString();
incomingMessage = Serial.readStringUntil("\n"); // read the whole string until newline
//Serial.println(incomingMessage);
const char* str = incomingMessage.c_str(); // convert it to a C String terminated by a null character "\0"
//Serial.println(str);
token = strtok(str, delim); // first part is a first section until delimiter occurs "-space- "
//Serial.println(token);
LX_Rated.commandLineResolve(token); // resolve it
while( token != NULL ) { // continue splitting and resolving the incoming message until it reaches the end
token = strtok(NULL, delim);
LX_Rated.commandLineResolve(token);
}
}
Edit2:
I have confirmed that I receive the whole string sent by Qt. When I try to tokenise it using the strtok() function and print out the first token I get back the whole string, the other tokens are empty. I don't see any mistake in my code here. I even tried to slow down the sending of the string from Qt to one per 5 sec. Does anybody have any idea what is going on? I don't see why this standard function doesn't work as expected. Please see the amended code below.
if(Serial.available()) {
incomingMessage = Serial.readStringUntil("\n");
Serial.println("ok");
Serial.flush();
char* nullTerminatedIncomingMessage = incomingMessage.c_str();
const char delimiter = " ";
char* token;
char* token1;
char* token2;
//char* secondToken;
token = strtok(nullTerminatedIncomingMessage, delimiter);
token1 = strtok(NULL, delimiter);
token2 = strtok(NULL, delimiter);
Serial.println(token); // print the first section
//Serial.println(incomingMessage);
Serial.flush();
Serial.println(token1);
Serial.flush();
Serial.println(token2);
Serial.flush();
//while(token != NULL)
// secondToken = strtok(NULL, delimiter);
//Serial.println(secondToken);
//Serial.flush();
incomingMessage = "";
}
Your mistake - at the very least - is in assuming that all the input is available when you expect it. You need to defer processing until an entire line has been assembled. Serial.readStringUntil blocks until an entire line is available, and that's not what you expect. You essentially need to replace Serial.available() with Serial.lineAvailable(), except the latter is not implemented.
This answer contains a complete solution to your issue - including both Qt and Arduino code - and an Arudino emulation layer. It might be a good starting point, especially that you can easily co-debug both Qt and Arduino projects from within one application and using one debugger!
As for difficulty in monitoring communication, you can(in Qt) dump everything you read into console and do the same for everything you write into the serial port. It will show in the console tab of QtCreator
#include <QDebug>
...
qDebug() << "whatever" << endl;
Aso for parsing the data you read from to serial port, take a look at this to see how to easily split the sliders info into individual strings(with QRegExp)
How Can I Split a String According To Delimiters in Qt?
I can't possibly guess why your arduino would be unresponsive without the code.
EDIT:
Is it possible, when you generate the string in Qt, that you separate the tokens by something other than space? Maybe tab("\t") or something? strtok accepts multiple delimiters in the delimiter string, may be something to try.
If that is not the case, there is the unlikely possibility that something's wrong with the strtok(...) function(btw. it modifies the original string, that in itself could be a problem). Also, strtok could return a NULL pointer, you don't seem to handle that case(some wrong input - print a message). You could try this as an alternative to normal strtok:
/**
* #brief custom strtok replacement with the same interface
* It does not modify the original string
* Token length is limited to 63 characters
* #param ptr pointer to the string or NULL
* #param delim delimiting character(only the first character will be used)
*/
const char * my_strtok(const char * ptr, const char * delim) {
// Persistent variables, it will remember pointer to the processed string
static const char * src;
static char buffer[64]; // Token is limited to 63 characters
if(ptr) { // Remember the pointer, if a new one was supplied
src = ptr;
}
if(src == NULL || *src == '\0')// Invalid / empty string / no next token - return NULL
return NULL;
char i = 0;
for(i = 0; i < 63 && *src != delim[0]; i++) {// Copy token until delimiter or end of buffer
buffer[i] = *(src++);
}
if(*src == delim[0]) // Skip over the delimiter to the begining of the next token
++src;
buffer[i] = '\0'; // Any returned string must be terminated
return buffer;
}
#include <cstdlib>
#include <cstring>
#include <cassert>
void test() {
const char * str1 = "123 456 asdf jkl;";
assert(strcmp("123", my_strtok(str1, " ")) == 0);
assert(strcmp("456", my_strtok(NULL, " ")) == 0);
assert(strcmp("asdf", my_strtok(NULL, " ")) == 0);
assert(strcmp("jkl;", my_strtok(NULL, " ")) == 0);
assert(NULL == my_strtok(NULL, " "));
assert(NULL == my_strtok(NULL, " "));
assert(strcmp("123", my_strtok(str1, " ")) == 0);
}
I'm able to send some characters in blue tooth to my android device.
But after scanning my finger and send the finger.fingerID value to android device,
Only a special character was sent.
So it came to me that the value is Integer and tried to convert it to character but still getting some error.
When I run my code here, I immediately getting back to void setup();
int getFingerprintIDez() {
uint8_t p = finger.getImage();
if (p != FINGERPRINT_OK) return -1;
p = finger.image2Tz();
if (p != FINGERPRINT_OK) return -1;
p = finger.fingerFastSearch();
if (p != FINGERPRINT_OK) return -1;
// found a match!
Serial.print("Found ID #"); Serial.print(finger.fingerID);
Serial.print(" with confidence of "); Serial.println(finger.confidence);
String toStr;
char toChar[2];
toStr=String(finger.fingerID);
toStr.toCharArray(toChar, toStr.length());
BTSerial.write(toChar);
Serial.print(toChar);
return finger.fingerID;
}
Your toChar buffer is too small for a string that could possibly be 5 characters long. You should allocate 10 bytes instead, more than enough to hold any result.
toCharArray does not null-terminate the string so even if write() accepts null-terminated strings alone (it doesn't), it would run off the end of the string looking for a null. write() accepts either a single character or a pointer to a char array and the number of characters to be written.
You don't need to go through all this hassle; merely call:
BT.print(finger.fingerID);
And the built-in Print class will handle the conversion messiness for you.
I am programming Arduino and I am trying to Serial.print() bytes in hexadecimal format "the my way" (keep reading for more information).
That is, by using the following code
byte byte1 = 0xA2;
byte byte2 = 0x05;
byte byte3 = 0x00;
Serial.println(byte1, HEX);
Serial.println(byte2, HEX);
Serial.println(byte3, HEX);
I get the following output in the Serial Monitor:
A2
5
0
However I would like to output the following:
A2
05
00
In words, I would like to print the "full" hexadecimal value including 0s (05 instead of 0 and 00 instead of 0).
How can I make that?
Simple brute force method, is to write a routine as:
void p(char X) {
if (X < 16) {Serial.print("0");}
Serial.println(X, HEX);
}
And in the main code:
p(byte1); // etc.
sorry - not enough reputation to comment but found previous answer is not fully correct. Actually, the nice light way to code it should be :
void p(byte X) {
if (X < 10) {Serial.print("0");}
...
giving the code:
void p(byte X) {
if (X < 10) {Serial.print("0");}
Serial.println(X, HEX);
}
And in the main code:
p(byte1); // etc.
hope this helps
Use sprintf to print into a buffer (two chars per byte + null terminator):
byte byte1 = 0xA2;
byte byte2 = 0x05;
byte byte3 = 0x00;
char s[7];
sprintf(s, "%02x\n%02x\n%02x", byte1, byte2, byte3);
Serial.println(s);
Added new lines in between to get each on new line. About '%02x', the % means here comes formatting information, 0 means to pad with 0, 2 means pad input until 2 characters wide and x means give me this as hexadecimal.
For other formatting options see http://linux.die.net/man/3/sprintf
The lowest footprint in Memory, Code and runtime would be classic bit playing
byte b;
Serial.print(b>>4, HEX);
Serial.print(b&0x0F,HEX);
Which is working fine on any 8bit type. For any other mask also the first line to
Serial.print((b>>4)&0x0F, HEX);
Try this:
//Converts the upper nibble of a binary value to a hexadecimal ASCII byte.
//For example, btohexa_high(0xAE) will return 'A'.
unsigned char btohexa_high(unsigned char b)
{
b >>= 4;
return (b>0x9u) ? b+'A'-10:b+'0';
}
//Converts the lower nibble of a binary value to a hexadecimal ASCII byte.
// For example, btohexa_low(0xAE) will return 'E'.
unsigned char btohexa_low(unsigned char b)
{
b &= 0x0F;
return (b>9u) ? b+'A'-10:b+'0';
}
And in main code:
comand_mod=0xA1; //example variable
Serial.print(btohexa_high(comand_mod));
Serial.print(btohexa_low(comand_mod));
wow! 7 years ago and I felt here, my answer might be useful for you (hopefully not anymore) or others looking for the answers like me.
Use "Serial.write()" to send a hex byte over serial.
All Serial.print() eg. println, printf, sprint, print will "print" your value in ASCII.