I've encountered something strange where a value received from the hardware I have configured is being received as \014.
What I am doing is receiving a value from the hardware ranged from 1-12. This value is passed as a hex value and using 12 as an example, is sent from the hardware over USB as 0x0C. When it's received from the Qt application, the memory register shows:
when all I want it to show is temp "12" Qstring.
Qt code:
void device_reply(A *a, B *b)
{
device *config = static_cast<device *>(b->deviceConfig);
QString temp = a->Data.constData();
config->band = temp;
}
I've been trying various methods like trying to access the QChar value, convert to uint and back, tried .trimmed() with .right(2) and other values, and even tried removing the escape sequence \0 but none of these methods seem to work.
Solved.
The code 0x0C is not actually the hex representation, and is instead the ASCII representation which represents the "Form Feed" control character, not the number 12. To get the actual value of the hexadecimal string, you need to convert it to an integer then cast back to a string.
Code:
void device_reply(A *a, B *b)
{
device *config = static_cast<device *>(b->deviceConfig);
QString temp = a->Data.constData();
QByteArray hexTemp = temp.toLocal8bit();
config->band = QString::number((int)hexTemp[0]);
}
Related
How to send data in hex on SerialPort?
I used this function, I receive the "yes, I can write to port" but I do not receive the data I entered
QByteArray send_data;
if(serialPort->isWritable())
{
qDebug()<<"Yes, I can write to port!";
int size = sizeof(send_data);
serialPort->write(send_data,size);
}
send_data += static_cast<char>(0xAA);
serialPort->write(send_data);
Data are transmitted in binary (essentially a sequence of 0 and 1). No matter what. Showing data in hexadecimal rather than a string of characters is just a choice.
In the following example, you can see that the array string_c is initialized with the same string that you are using in your code. Next, I print the data in both, as hex and as a string. You can see that the only difference is in the way I decided to print the data. The source data is the same for both.
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void printCharInHexadecimal(const char* str, int len)
{
for (int i = 0; i < len; ++ i) {
uint8_t val = str[i];
char tbl[] = "0123456789ABCDEF";
printf("0x");
printf("%c", tbl[val / 16]);
printf("%c", tbl[val % 16]);
printf(" ");
}
printf("\n");
}
int main()
{
char string_c[] = "Yes, i can write to port";
// string printed in hex
printCharInHexadecimal(string_c, 24);
// same string printed as "text"
printf("%s\n",string_c);
return 0;
}
You can see the above code running here: https://onlinegdb.com/Y7fwaMTDoq
Note: I got the function printCharInHexadecimal from here: https://helloacm.com/the-c-function-to-print-a-char-array-string-in-hexadecimal/
As suspected, your use of sizeof is wrong. It is not returning the size of the contained data, it is returning a non-zero constant that is the size of a QByteArray object itself. Since that object was freshly constructed it should be empty, and any size you use in the first write other than zero will lead to undefined behavior. Use:
int size = (int)send_data.size();
Skip the first write entirely, and use the above for your second write.
You need to be clear about what you expect. 0xAA in your source code is simply an integer value using hex representation. It complies to exactly the same code regardless of the source code presentation: 0xAA == 170 == 0263.
If you actually intended to output a string of characters at run time representing a value in hexadecimal, you need to convert that value from an integer to a string. For example;
char hexbyte[3] ;
sprintf( hexbyte, "%02X", 170 ) ;
serialPort->write(send_data) ;
will output ASCII characters AA, whilst demonstrating the equivalence of 170 to 0xAA. That is the hex notation in the source does not affect the value or how it is stored or represented in the compiled machine code.
Background
I've written an Arduino function which receives strings in the format "a,b,c,d,e" over a serial connection, where a,b,c,d,e are integers, and I'm trying to update an array with these integers every time a new string is received. The data is received and parsed into individual integers fine, but the array won't update properly.
Attempt
Below is the code, I've left the getData() function out as all it does is receive the string from the serial connection and store it in an array of characters input (that part is working fine).
void setup() {
Serial.begin(9600);
}
void loop() {
getData();
if(parsed == false){
parseData(readings);
}
}
void parseData(int readings[]) {
x = 0;
char * split;
split = strtok(input,",");
while (split != NULL)
{
readings[x] = split;
split = strtok (NULL, ",");
x++;
}
parsed = true;
}
Problem
If I send a string like "6,7,8,9,0", the array readings[] is updated to [289,291,293,295,297] no matter what values I send, I have checked what values split takes inside the function and they are correct, however the line readings[x] = split; fails to update the array elements to anything other than those 5 numbers in that order. This is the case when the value of readings[n] is checked inside or outside the parseData function.
Also, if I send fewer than 5 integers in the string, e.g. a,b,c, only the first array elements will change and the others will remain at 0, e.g. [289,291,293,0,0]
Before I found out about passing array pointers to functions, the exact same thing was happening with slightly different code - when I called the function in the loop, I just used parseData();, and when I defined the function I just used void parseData(){
Question
Why isn't the array updating properly and how can I fix it?
Your readings is an array of integers.
And split is a pointer-to-char.
The statement
readings[x] = split
stores split, which is the address of a character, as an integer value.
If I write
const char *pointer = "42";
int address = pointer;
I am not storing the integer value 42 in address - I'm storing the number identifying the memory location of the first character in my string.
If you want to convert a string into an integer, you need to parse it with a function like strtol.
I am doing this IoT based project on displaying data to connected display( I've used the MAX7219 module, in this case) with the help of nodeMCU. The idea here is that the string which is stored in my firebase database is to be display on the led display.
I've had no trouble in getting the value from the database to my nodeMCU but there is this little problem with converting that string to char array since the code i am using( Max72xx_Message_serial, which was available as an example with the max72xx library) has used char array but i can only fetch the stored data in string format. I've modified that code so as to connect with firebase but the main issue is to convert the string fetched from the database to char array.
I tried toCharArray() but it still shows conversion error.
void readfromfirebase(void)
{
static uint8_t putIndex = 0;
int n=1;
while (Firebase.available())
{
newMessage[putIndex] = (char)Firebase.getString("Submit Message"); // this line produces the error
if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE-3)) // end of message character or full buffer
{
// put in a message separator and end the string
newMessage[putIndex++] = ' ';
newMessage[putIndex] = '\0';
// restart the index for next filling spree and flag we have a message waiting
putIndex = 0;
newMessageAvailable = true;
}
else if (newMessage[putIndex] != '\r')
// Just save the next char in next location
{putIndex++;}
n++;
}
}
I think you are confusing the types
getString returns a String object wich can be converted to a char[] using the methods of the String class.
I assume your newMessage is of type char[] or char*.
Then I would advise you to go for the String.c_str() method, because it returns a C style null-terminated string, meaning a char*.
See https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/c_str/ for reference.
It also sets the last character of the string to 0. So methods like strlen, strcmp etc will work.
! be carefull not to modify the array returned by c_str(), if you want to modify it you chould copy the char[] or use string.toCharArray(buf, len).
Your Code might then look like the following.
String msg = Firebase.getString("Submit Message");
newMessage = msg.c_str();
// rest of your code
If newMessage is a buffer storing multiple messages, meaning char* newMessage[3].
String msg = Firebase.getString("Submit Message");
newMessage[putIndex] = msg.c_str();
// rest of your code
Be careful, because you are storing multiple characters in an array, so use strcmp to compare these arrays!
If you are new to C I would recommend reading.
https://www.cprogramming.com/tutorial/c/lesson9.html
https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/ (as pointed out by #gre_gor)
I'm trying to collect data from a simple multimeter circuit, but instead of returning numbers my serial port is just outputting random Unicode symbols.
Here's my code:
void setup() {
pinMode(2, INPUT);
Serial.begin(1200);
int prevVal = 0;
int timeVar = 0;
}
void loop() {
int digisensorVal = digitalRead(2);
int anasensorVal = analogRead(2) * 100;
Serial.print("D" + digisensorVal);
Serial.print(",");
Serial.println("A" + anasensorVal);
delay(250);
}
And here's a sample of the output:
⸮L/⸮U⸮⸮⸮⸮⸮?⸮⸮⸮w⸮e⸮⸮⸮⸮1⸮⸮⸮⸮}⸮J⸮⸮⸮⸮⸮oޝ⸮Y⸮⸮⸮|s⸮⸮}⸮⸮⸮⸮⸮⸮⸮є6x⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮y[⸮⸮⸮⸮⸮?⸮v⸮=⸮⸮⸮-⸮^⸮Y_z⸮⸮d⸮⸮⸮%ܿjV⸮~O⸮⸮G⸮⸮⸮⸮e⸮⸮U⸮⸮~+0⸮⸮⸮hh⸮s⸮
⸮c⸮⸮⸮+⸮⸮io3:⸮5kλϣ
,⸮g⸮⸮⸮⸮⸮>⸮⸮
⸮yꨛ⸮v⸮N⸮⸮⸮=⸮⸮=⸮⸮⸮l⸮⸮g⸮g⸮⸮⸮⸮⸮s⸮U⸮⸮⸮⸮⸮⸮=⸮ܳt⸮⸮⸮}⸮⸮'⸮˾⸮k⸮⸮⸮⸮⸮⸮⸮{⸮ᦒ⸮⸮⸮⸮ϓ߿gVp⸮⸮⸮⸮Y⸮⸮O⸮/F⸮~⸮⸮⸮⸮q4⸮⸮_f⸮⸮⸮⸮⸮I|P⸮⸮⸮NE⸮~u⸮7⸮⸮⸮⸮g⸮⸮G~⸮⸮⸮⸮__#⸮⸮⸮⸮⸮⸮⸮C⸮⸮⸮k⸮T⸮o/⸮t^⸮~⸮{}⸮w⸮⸮⸮⸮'h=⸮ϸ~⸮⸮⸮⸮⸮⸮⸮?⸮s⸮s⸮l⸮o5⸮^⸮⸮⸮w9{]⸮⸮q~⸮⸮⸮,⸮⸮⸮c⸮2_⸮⸮⸮⸮o6k)ޏ⸮k⸮ׇ⸮i⸮⸮m⸮⸮:⸮⸮⸮⸮|⸮⸮??⸮⸮⸮⸮3⸮⸮⸮⸮⸮⸮⸮⸮⸮^⸮⸮ڏ⸮⸮⸮⸮l⸮⸮⸮⸮⸮⸮H⸮~⸮>⸮⸮z⸮⸮⸮⸮⸮OwM;⸮⸮l⸮⸮
⸮sr⸮S⸮⸮}⸮⸮⸮⸮ׂٶ⸮⸮~⸮{⸮⸮]⸮⸮⸮⸮⸮⸮⸮⸮i⸮⸮⸮⸮⸮[⸮⸮⸮⸮⸮Nz⸮⸮⸮⸮⸮k⸮⸮⸮⸮⸮g⸮k⸮⸮⸮i3ɵ⸮⸮~⸮⸮⸮⸮⸮]⸮2ϪWކ⸮i>⸮gu⸮⸮ӵ⸮?⸮̥⸮⸮m⸮⸮|⸮⸮⸮⸮Wɓ⸮⸮⸮[⸮⸮O㠑_⸮⸮⸮⸮⸮⸮⸮⸮⸮/⸮M⸮⸮_⸮⸮gwF⥷⸮⸮yn⸮P⸮⸮-⸮⸮⸮N⸮⸮⸮=⸮⸮⸮⸮⸮⸮⸮>J⸮}⸮⸮&⸮⸮⸮C⸮HG翎⸮/⸮⸮⸮⸮}⸮⸮⸮^⸮⸮,⸮)[⸮⸮⸮⸮⸮⸮У⸮⸮}⸮ޯ⸮⸮⸮⸮7⸮⸮⸮⸮ó⸮U:~⸮⸮ns⸮⸮z⸮⸮n⸮⸮G|ӳ⸮⸮}⸮⸮L⸮~⸮⸮KI⸮⸮G⸮⸮⸮⸮⸮⸮ӏ⸮⸮⸮⸮u6⸮W⸮⸮⸮⸮Ӊ۾⸮⸮9⸮zVΆ럿⸮⸮⸮ۘ⸮⸮T⸮<⸮⸮⸮⸮⸮⸮⸮/⸮⸮⸮⸮xG~⸮V⸮⸮u+N⸮⸮ݫ⸮⸮⸮cv~⸮⸮⸮W⸮
Serial.println("A" + anasensorVal);
This needs to be done in two lines. You're adding the sensor value to a pointer value and sending whatever garbage is pointed to at the memory location that adds up to. And it definitely isn't what you want. This isn't Java. You can't just add strings with a + like that.
With
Serial.println("A" + anasensorVal);
you are not actually printing number, but a string from some place in the memory starting at the address of "A" + value of "anasensorVal" and thus you will get some garbage.
You are trying to add an integer to a pointer to char(and likely move beyond the end of the string "A"), that's not what you want.
The usual way of formating output on arduino:
Serial.print("A");
Serial.println(anasensorVal);
Alternatively, you can define a stream operator for the Serial object, see https://playground.arduino.cc/Main/StreamingOutput how to do that and then format output like this:
Serial << "A" << anasensorVal;
Adding an int type and character type in Serial.print is messing up the format of the data you are trying to print to the monitor.
Friends
I want to integrate the following code into the main application code. The junk characters that come populated with the o/p string dumps the application
The following code snipette doesnt work..
void stringCheck(char*);
int main()
{
char some_str[] = "Common Application FE LBS Serverr is down";
stringCheck(some_str);
}
void stringCheck(char * newString)
{
for(int i=0;i<strlen(newString);i++)
{
if ((int)newString[i] >128)
{
TRACE(" JUNK Characters in Application Error message FROM DCE IS = "<<(char)newString[i]<<"++++++"<<(int)newString[i]);
}
}
}
Can someone please show me the better approaches to find junk characters in a string..
Many Thanks
Your char probably is represented signed. Cast it to unsigned char instead to avoid that it becomes a negative integer when casting to int:
if ((unsigned char)newString[i] >128)
Depending on your needs, isprint might do a better job, checking for a printable character, including space:
if (!isprint((unsigned char)newString[i]))
...
Note that you have to cast to unsigned char: input for isprint requires values between 0 and UCHAR_MAX as character values.