Reading characters from Serial1

Hi.

I’m using Sparkfun’s OpenLog to read/write to an SD card from a photon/p1.

To read from the SD card, I am interfacing with Serial1, and running the following:


String totalString = "";
  for(int timeOut = 0 ; timeOut < 1000 ; timeOut++) {
    while(Serial1.available()) {
      char tempString[sizeFile]; // sizeFile is the size of the file we are reading, in bytes
      int spot = 0;
      while(Serial1.available()) {
            tempString[spot++] = Serial1.read();
            if(spot > sizeFile) break;
      }

      totalString += tempString;
    }

    delay(1);
  }

The file that I am reading has the text, I Zm9vYmFy, base64 for foobar.

So, when I print totalString, I get Zm9vYmFy as expected. When I ask for the length, I get something greater, and when I iterate through it, I see empty strings ("") in a variety of places:

Serial.print("subString.length()=");
Serial.println(subString.length());
for (int i = 0; i < subString.length(); ++i)
  {
    String s = String(subString.charAt(i));
    Serial.print("s=");
    Serial.print(s);
    Serial.print(" s.length()=");
    Serial.print(s.length());
    Serial.print(" s.equals('')=");
    Serial.println(s.equals(""));
    if (s == "") {
      subString.remove(i, 1);
    }
  }

// Output
>> subString.length()=12
s= s.length()=1 s.equals('')=0
s=Z s.length()=1 s.equals('')=0
s= s.length()=1 s.equals('')=0
s=m s.length()=1 s.equals('')=0
s= s.length()=1 s.equals('')=0
s=9 s.length()=1 s.equals('')=0
s= s.length()=1 s.equals('')=0
s=v s.length()=1 s.equals('')=0
s=Y s.length()=1 s.equals('')=0
s=m s.length()=1 s.equals('')=0
s=F s.length()=1 s.equals('')=0
s=y s.length()=1 s.equals('')=0

How can I reliably determine that a sting is empty, or that it equals ""? Thanks in advance!

1 Like

Hi @gemfarmer

I’ve started a proof of concept sketch based on your code that might help you out.

Hi @nrobinson2000,

Thanks for your response. I’m curious to know more about your thought process here. Why, for instance did you remove the additional while loop and the for loop surrounding lines 34-40? Do you suspect that is causing the null character array item?

Thanks!

I feel like the additional while loop and for loop are unnecessary and possibly introduce undesired behavior. (I haven’t tested the code on a Photon yet.)

Also I feel like you could achieve the input and output with only the char array and not a String object.

2 Likes

I would go with @nrobinson2000 approach - c char array is a much better approach than using string object. There are many C string.h library functions you can use to move, search and parse the char array.

Why are you using openlog to read/write to an SD and not SDfat library?

Lastly, it is not clear to me what problem you are trying to solve here - read some log entries (terminated with ?, size?) and then convert from base64 to binary?

1 Like

@armor @nrobinson2000 Thanks for the response. I’m using OpenLog instead of SDFat because we only have access to UART, not txrx. OP on this thread is part of the same project, if you want more details. It might end up being more stable to using SDFat, but we have limited options at this time.

As for the issue that I’m trying to solve. First, I’ll be more clear about what we are doing:

  1. On our app, we are allowing users to download a firmware file, which we will encode the hexadecimal to base64 to make reading the characters from Serial more reliable. The file will go onto an SD card.
  2. Read characters from SD card using OpenLog, Serial1.
  3. Decode base64 and store as uint8_t
  4. flash 512 byte chunks using the system_update API.

The issue that we are having is at #2 reading the Serial1 from the SD card reliably. The rest is working.

As for char array vs String, I’m open to both options. Basically I need to be able to read only ASCII-safe characters and save to a char array or uint8_t byte array without null characters. The example above is to illustrate that we are storing null characters. I’m not quite sure how to remove those. Any ideas?

@gemfarmer, since you are using OpenLog, I assume that your are using the read File + START+ LENGTH TYPE command to read chunks of the data file. I also assume you have specified TYPE as ASCII. Given this, you can use a timed while() loop to read LENGTH number of character from OpenLog into a buffer of size LENGTH + 1. The timed portion is to allow the loop to timeout if nothing is received for, say, 100ms. The +1 on the buffer length is to make room for an ASCII string terminator (zero value byte) at the end of the buffer so you can print it like a string. The zero can also be used to delimit the buffer when you convert it from Base64 to binary. To get 512 bytes of binary data, you will need to read 683 ASCII bytes from the file.

The zeros that you originally posted about may have been an artifact of the totalString += tempString; concatenation.

2 Likes