I want to add a step to check integrity of some bytes over serial. I dont know how i can combine the char and the bytes to send as a singe message to the receiver.
This is how i tried and it failed.
send,
struct a {
int a= 25;
};
a b;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
Serial.print("ABCDEF");
Serial.write((byte*)&b, sizeof(b)); //cast to bytes
}
recv,
struct a {
int a;
};
a b;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
while (Serial.available()) {
char verifyStart[7];
char buffer[300];
Serial.readBytes((char*)buffer, sizeof(6));
strncpy (verifyStart, (char*)buffer, 6);//6 bytes
verifyStart[6] = 0; //null terminate
Serial.println(verifyStart);
if (strcmp(verifyStart, "ABCDEF") == 0) {
memcpy(&b, buffer + 6 , sizeof(b));
}
}
id like to extract the char string from the first 6 bytes. then use string compare to know what to do.
How do i send the message how id like, how can i receive it?
I know im only reading 6 bytes into buffer. i was initially just trying to receive the char. But why does it print in my serial console like this,
OOPS.. that was indeed the issue, but now how shall i send the message with the preceding char string. "ABCDEFstructbytes" Can it be done in 1 serial print/write?
readbytes will wait until it receives the amount of bytes i specify. so i guess its okay to make multiple write with serial? i wonder how to do it with 1 print. i didn't find a way to concatenate the char string with the structbytes in a single write. '
This seems to work for sending,
struct a {
int a = 25;
};
a b;
unsigned long now = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
if (millis() - now >= 1000) {
Serial.print("ABCDEF");
Serial.write((byte*)&b, sizeof(b));
Serial.print("ABCDE>");
now = millis();
}
}
recv,
struct a {
int a;
};
a b;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Boot");
}
void loop() {
if (Serial.available()) {
char verifyStart[7];
char buffer[300];
int len = Serial.readBytesUntil( '>', buffer, 60);
Serial.println(len);
strncpy (verifyStart, buffer, 6);//6 bytes
verifyStart[6] = 0; //null terminate
Serial.println(verifyStart);
if (strcmp(verifyStart, "ABCDEF") == 0) {
memcpy(&b, buffer + 6 , sizeof(b));
Serial.println(b.a);
}
}
}
Im open to suggestions, i know there's probably a better way to do this.
Using > to indicate end of bytes, but what happens when the terminating/">" char not seen. does sketch block until timeout?
Okay now im having strange problem. when i send 16 bytes to the receiver buffer then the struct, then another 16 bytes. i copy the first and last 16 bytes into verifyStart and verifyEnd null terminate it. but if i try to print both "verifyStart & verifyEnd the serial monitor only prints verifyEnd.
If i comment out verifyEnd then verifyStart prints correctly. What did i do wrong this time?
struct a {
int a = 25;
uint32_t var[50];
};
a b;
bool c = 1;
unsigned long bps = 0;
unsigned long now = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(500000);
Serial.println(sizeof(b));
}
void loop() {
// put your main code here, to run repeatedly:
//
delay(1000);
// if(c){
Serial.print("reqDataStruct001");
Serial.write((byte*)&b, sizeof(b));
Serial.print("ENDOFBYTESTREAMS>");
bps++;
//}
// if (millis() - now >= 1000) {
// //Serial.println(bps);
// c = 0;3
// now = millis();
// }
}
Im afraid ill get some undefined behavior because im getting unexplained results in the serial monitor already.
i revised the code to use 1 buffer for the verify string and the results in the serial monitor are as expected. Is this acceptable? i think i am extracting the bytes from the buffer right? but i thought i was last time to. and the problem on happened when using serial print.
struct a {
int a;
uint32_t var[50];
};
a b;
unsigned long bps = 0;
char buffer[803];
void setup() {
Serial.begin(500000);
Serial.println("Boot");
}
void loop() {
if (Serial.available()) {
// char verifyStart[16];
// char verifyEnd[16];
char verify[32];
int len = Serial.readBytesUntil( '>', buffer, 803);
bps += len;
Serial.println(len);
strncpy (verify, buffer, 16);//6 bytes
strncpy (verify + 16, buffer + (len - 16) , 16 );//6 bytes
Serial.println(verify);
}
}
EDIT: I think i forgot the null terminator
The C library function **char *strncpy(char dest, const char src, size_t n) copies up to n characters from the string pointed to, by src to dest . In a case where the length of src is less than that of n, the remainder of dest will be padded with null bytes.
Does this mean i don't need to null terminate "verify" manually when using strncpy?
Please help me clear up this confusion. im copying over 32bytes in the array. but the array starts at [0] right? so when i initialize char array[32] this gies me 33 bytes?
If i increase the size of the array by one byte does the null terminator go at 32 or 33? I think 32. b ut am confused if array starts a 0 then [32] i thought would be 33 0-32
No, there are 32 elements in the array with indexes from 0 to 31.
If i increase the size of the array by one byte does the null terminator go at 32 or 33?
The null terminator goes in element 32. There is no element 33.
Zero based counting is sometimes not intuitive because we have 10 fingers and always start counting at 1 and go to ten, instead of starting at 0 and going to 9.