4

I'm hoping that someone can help me diagnose this odd behavior that I'm experiencing. I'm programming for the Arduino Due and using the Adafruit FONA modem. The code in question submits an array of bytes to be sent over the modem. sendData is taking an unsigned char[] which I cast to void*. data_len is the number of bytes written to the buffer rather than the size of the buffer itself.

The board I'm working with doesn't use printf/sprintf to print to stdout. Instead this is done using Serial.print and Serial.println. Serial here is an Arduino class, not the standard C++ class. sprintf_ByteArray I wrote to examine the contents of a byte buffer, with the results reflected as hex bytes.

As I mentioned my ultimate goal here is to write data to the modem. This is done in the fonaSerial->println and fonaSerial->write calls. The first issues a modem command with the size of the data to be written. The second writes the data.

But I'm experiencing something screwy. The result of printing data and String message is displayed below. Inexplicably to me, message only contains the last 119 bytes of data. At first, this didn't surprise me as data includes null bytes and I assumed that those were somehow to blame. But, message actually includes null bytes! And, I would have expected message to represent the first N bytes of data, up until the first null byte.

Lastly: I end by casting data to a uint8_t* and passing to fonaSerial->write. Initially I had been passing a String but after I had trouble casting I decided to try this alternative tack. I then send this data to a server I'm running. The server only gets a payload of 119 bytes too.

For the record, earlier I successfully sent a smaller payload. I have no idea what I'm doing now that is causing the problem.

bool sendData(void *data, size_t data_len) {    
  char tmp[1024] = {0};
  Serial.print("data_len=");Serial.println(data_len);
  sprintf_ByteArray(tmp, (unsigned char*) data, data_len);
  Serial.print("Payload (void*)=");Serial.println(tmp);
  String message = (const char*) data;
  Serial.print("Payload (String)=");Serial.println(message);

  fonaSerial->print(F("AT+CIPSEND="));
  fonaSerial->println(data_len);

  fona.readline(3000);
  fonaSerial->write((uint8_t*) data, data_len);
  fonaSerial->flush();

  fona.readline(3000); // wait up to 3 seconds to send the data
  Serial.print (F("\t<--- ")); Serial.println(fona.replybuffer);

  return (strcmp(fona.replybuffer, "SEND OK") == 0);
}

Payload (void*)= 8a a5 62 69 64 00 69 63 6f 6e 64 69 74 69 6f 6e 01 67 62 61 74 74 65 72 79 18 1d 65 73 74 61 74 65 02 69 74 69 6d 65 73 74 61 6d 70 19 0f 95 a5 62 69 64 01 69 63 6f 6e 64 69 74 69 6f 6e 01 67 62 61 74 74 65 72 79 18 42 65 73 74 61 74 65 62 69 74 69 6d 65 73 74 61 6d 70 19 0f 97 a5 62 69 64 02 69 63 6f 6e 64 69 74 69 6f 6e 00 67 62 61 74 74 65 72 79 18 29 65 73 74 61 74 65 06 69 74 69 6d 65 73 74 61 6d 70 19 0f 98 a5 62 69 64 03 69 63 6f 6e 64 69 74 69 6f 6e 01 67 62 61 74 74 65 72 79 18 26 65 73 74 61 74 65 01 69 74 69 6d 65 73 74 61 6d 70 19 0f 99 a5 62 69 64 04 69 63 6f 6e 64 69 74 69 6f 6e 01 67 62 61 74 74 65 72 79 18 2f 65 73 74 61 74 65 62 69 74 69 6d 65 73 74 61 6d 70 19 0f 9a a5 62 69 64 05 69 63 6f 6e 64 69 74 69 6f 6e 01 67 62 61 74 74 65 72 79 18 1d 65 73 74 61 74 65 06 69 74 69 6d 65 73 74 61 6d 70 19 0f 9c a5 62 69 64 18 42 69 63 6f 6e 64 69 74 69 6f 6e 18 75 67 62 61 74 74 65 72 79 18 69 65 73 74 61 74 65 18 6c 69 74 69 6d 65 73 74 61 6d 70 1a 67 6e 69 64 a5 62 69 64 18 20 69 63 6f 6e 64 69 74 69 6f 6e 18 6c 67 62 61 74 74 65 [72 79 18 6f 65 73 74 61 74 65 18 74 69 74 69 6d 65 73 74 61 6d 70 1a 00 6e 39 20 a5 62 69 64 62 69 63 6f 6e 64 69 74 69 6f 6e 00 67 62 61 74 74 65 72 79 18 40 65 73 74 61 74 65 74 69 74 69 6d 65 73 74 61 6d 70 19 0f a0 a5 62 69 64 74 69 63 6f 6e 64 69 74 69 6f 6e 00 67 62 61 74 74 65 72 79 18 43 65 73 74 61 74 65 74 69 74 69 6d 65 73 74 61 6d 70 19 0f a1]

length 471

Payload (String)= 72 79 18 6f 65 73 74 61 74 65 18 74 69 74 69 6d 65 73 74 61 6d 70 1a 00 6e 39 20 a5 62 69 64 62 69 63 6f 6e 64 69 74 69 6f 6e 00 67 62 61 74 74 65 72 79 18 40 65 73 74 61 74 65 74 69 74 69 6d 65 73 74 61 6d 70 19 0f a0 a5 62 69 64 74 69 63 6f 6e 64 69 74 69 6f 6e 00 67 62 61 74 74 65 72 79 18 43 65 73 74 61 74 65 74 69 74 69 6d 65 73 74 61 6d 70 19 0f a1

length 119

Ruslan
  • 122
  • 1
  • 14
Chris
  • 1,090
  • 2
  • 11
  • 22
  • Arduino is neither C nor C++. – too honest for this site Sep 22 '15 at 22:15
  • 2
    @Olaf Acutually, it is C++. The IDE just hides this by wrapping your code in some other headers and stuff before sending it to avr-gcc. It's perfectly possible to make use of Arudino code using just avr-gcc and your own programmer chip. It's a bit of a pain, but I've done it before. – zstewart Sep 22 '15 at 22:18
  • @zstewart: Either way, it is definitively not C and the code is not passed unmodified to the compiler, but manipulated/augmented similar to early C++ or Objective-C. It will not compile/link unmodified with a C++ compiler. – too honest for this site Sep 22 '15 at 22:24
  • 1
    @Chris I don't know, but could it be that there are buffers involved in the printing which are overfilled sooner than the data is read? In that case, I would expect a long write to fill over earlier data with the latest information. E.g if you're sending data over serial, but not reading it as soon as it arrives, the serial buffer may act as a queue, and discard older byes when it is full. – zstewart Sep 22 '15 at 22:24
  • Please provide an [mcve]. Also note that there are two sides involved, but you only show (part of) one side. – too honest for this site Sep 22 '15 at 22:26
  • 2
    if it is C or C++ tagging it so will increase visibility – Giorgi Moniava Sep 22 '15 at 22:34
  • @zstewart that's an interesting hypothesis to test. at first glance 119 bytes still seems like an odd number but i'll have to look further into it. – Chris Sep 22 '15 at 22:52
  • 2
    It seems to me there are 3 areas to investigate. First of all, if your String object is getting constructed correctly. Does the String class have a "length" or "size" property/function? Is the result what you expect? The second area is whether Serial.println is sending the value of your string correctly to the serial port. Construct a similar length string manually and print it using the same code (in place of your current code that prints the String for consistency). Finally, as mentioned above, the buffer for the Serial output may be full and dumping data. Try remove the first... – Mick Waites Sep 23 '15 at 06:18
  • 1
    ...print where you send the void* data and see if the String then prints as you'd expect it to. The buffer one may be the problem. You say 119 bytes is an odd number, but you are sending 1800+ bytes of data to Serial.print (if the output you have included is pretty much verbatim). There may be a 1024 byte buffer with some of the buffer getting emptied before the 2nd print is attempted. – Mick Waites Sep 23 '15 at 06:19
  • You'll have to show us the code for sprintf_ByteArray() because what you're showing doesn't make sense. If it is correctly representing what's in the data buffer, then the String constructed from that data could not possibly look like the Payload you show below it. There's a nul (00) after the 5th character in your data, so the string should be 5 characters long. Also, show us the output of data_len= print, too, so that we have that information. Lastly, you show Payload in a format that looks like a hex dump. That does not appear to be the actual output of your program. – frankleonrose Jan 17 '17 at 16:28

1 Answers1

0

try this 'to_string' converter:

String to_string(unsigned char *data,unsigned int len){
    String memtmp="";
    unsigned char tmpdata;
    for(unsigned int i=0;i<len;i++){
        tmpdata=*(data+i);
        memtmp+=String(tmpdata,HEX);
        memtmp+=" ";
    }
    return memtmp;
}

I hope this can help. Good luck!

simonecocco
  • 100
  • 9