Serial.print() / Serial Monitor issue. Not detecting zeros

Hello,

I have an issue in regards to the mcp_can.h library. I would like to recieve a message with an extended Identifier (29-bit). The problem appears to occour when I recieve my data frame with zeros next to each other in a hex data type.

What I should recieve: 0 x 43 96 00 00 40 80 00 00

What I actually recieve: 0 x 43 96 0_ 0_ 40 80 0_ 0_ (the underscores are there to underline that zeros are missing) hence the full message is as follows: 0x439600408000.

As you can see I'm missing 2 bytes of information in total given that half of that byte (4 bits) is filled with one zero and the other half is missing.

Here is the screenshot Arudino IDE Serial monitor (incorrect length).

incorrectlengthdata

Also, as a matter of fact, when I put only zeros into the Serial.print() , hence:

Serial.print(0x0000000000000000 , HEX)

I recieve only 8 "zeros".

Could anyone suggest how to fix this error?

Leading zeroes are not printed, I think that that is your main issue.

So for a byte, you can use something like

if (dataByte < 0x10)
{
  Serial.print("0");
}
Serial.println(databyte);

Regarding Serial.print(0x0000000000000000 , HEX), Serial.print does not support 64-bit numbers, at least not on the AVR architecture; which board are you using? It does not quite explain why you see 8 digits, I would expect 1 digit.

are you generating that message yourself or does it come from the library?
is everything packed together or there are spaces?

That message is supposed to be sent from a module node (in this case an ACDC module which I can communicate with via CAN communication protocol (CCP). For test purposes I'm utilizing an arbitrary SW to recreate the module message (Rx) - hence I'm generating that message myself. Subsequently that message is being recieved onto my Arduino Uno board (through MCP2515 module). To answer your second question, there are no spaces inbetween the bytes/bits. The message is send through unsigned data type with 64 bits (8-byte DATA length of CAN message) being filled.

I'm using the Arduino Uno board with MCP2515 Serial-CAN communication module. I'm attaching a screenshot showing the 8-digits of zeros sequence while printing 0x0000000000000000

OK but it seems you are not generating it in the right way.
try something like this

uint64_t message1 = 0xDEADBEEFBADCAFFE;
uint64_t message2 = 0x0102030405060708;

void sendMessage(uint64_t& m) {
  uint8_t* mPtr = (uint8_t*) &m;
  Serial.print(F("message : 0x"));
  for (int8_t i = (sizeof m) - 1; i >= 0; i--) {
    if (*(mPtr + i) < 0x10) Serial.write('0');
    Serial.print(*(mPtr + i), HEX);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200); Serial.println();
  sendMessage(message1);
  sendMessage(message2);
}

void loop() {}

if all goes well you should see

message : 0xDEADBEEFBADCAFFE
message : 0x0102030405060708

and if you want to deal with various parameter's sizes you could use a template

uint64_t message1 = 0xDEADBEEFBADCAFFE;
uint64_t message2 = 0x0102030405060708;
uint32_t message3 = 0x01020304;
uint16_t message4 = 0x0102;
uint8_t  message5 = 0x01;

struct __attribute__((packed)) {
  uint16_t x;
  uint32_t y;
} structMessage = {0xDEAD, 0xBADCAFFE};

template <typename T>
void sendMessage(T& m) {
  uint8_t* mPtr = (uint8_t*) &m;
  Serial.print(F("message : 0x"));
  for (int8_t i = (sizeof m) - 1; i >= 0; i--) {
    if (*(mPtr + i) < 0x10) Serial.write('0');
    Serial.print(*(mPtr + i), HEX);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200); Serial.println();
  sendMessage(message1);
  sendMessage(message2);
  sendMessage(message3);
  sendMessage(message4);
  sendMessage(message5);
  sendMessage(structMessage);
}

void loop() {}

this should generate

message : 0xDEADBEEFBADCAFFE
message : 0x0102030405060708
message : 0x01020304
message : 0x0102
message : 0x01
message : 0xBADCAFFEDEAD

so the compiler generates different functions based on the type of the parameter and that works for many types including structures

as I start from the higher byte this is suited for little endian representation (our compiler uses little endian) and for structures you have to take into account the layout of the data .

*(mPtr + i) can be simplified to mPtr[i] (or i[mPtr] if you want to be sadistic).

I like to stick to pointer dereferencing when I declare a pointer, it feels more natural. but yes you could

So I have made some progress with that. Thank you!

I can print the entire data frame (with the trailing/leaing zeros) in place and everythinga until that point is fine. To place the required zeros I used the String type as following:

void ArrayAssigment_Module_Info_VoIo_Req()
{
for (int i = 0; i < 4; i++){
Module_Info_VoIo_Req_DATA[i] = Rx.Data[i];
String str1;
if(Module_Info_VoIo_Req_DATA[i] < 0x10 )
{
str1 = String(0x00 , HEX);
}
String str2 = (str1 + String(Module_Info_VoIo_Req_DATA[i] , HEX));
const char* charstr1 = str2.c_str();
Serial.print(charstr1);
Serial.print("\n");
Serial.println();
}
}

I've used type const char* to convert string type into char (" "). The output is as follows...
goodouputstring

As you can see, I recieve 8bit of values at each of the 4 bytes presented.

Now here comes the tricky part and problem at the same time. I would like to convert either String or const char* type into an int type (used toInt() fnc for that), in order to get that data a value. Unfortunetly I recieved my data with the zeros still missing at byte 3 and 4 (as seen on the screenshot above). (The problem continues but now cirtiria have changed).)

I was thinking about a solution for that and came up with a plan to insert a value (a zero), given a condition which states that - at a given byte, only one value (which must be equal to zero) exists, hence a zero must be implemented. Maybe a 'mask' of a sort would be useful? Would you please tell me if this makes sense to you? And if it does/doesn't, would someone be willing to help me out and leading me onto the efficient method of writing this code up?

Thank you so much for your help... again!

what a waste of memory...

may be you don't listen to the byte stream correctly?

you could test if the data is empty then you know...

without seeing the whole code it's hard to provide guidance

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.