SoftwareSerial Stream?

I’ve been reading around, and i think I know what my problem is, but I was reading here and it implies there are some un-clarities in the newest version of the development environment in my area of interest.

I’m driving an OLED display with UART. I send a command, and I wait for the responses: 0x06=0b110=good, 0x15=0b10101=bad, or other.

I am sending 3 commands presently (see code, commands are initialized in the arrays; autobaud, arr, and new_arr). Commands 1 and 2 return a 0b110, or good response. The third response i have intentionally programmed in a bad command. I’d like to turn this into a library, and i want it to perform as robustly as possible. The code works fine assuming there are no mistakes.

Now, the display returns only a single byte response, unless the display receives a series of unrecognized commands. My command 3, has 6 consecutive unrecognized commands, therefore the output should be 6 consecutive bad responses, I.e.: bad, bad, bad, bad, bad, bad; however, that is not the response.

The response, in binary, is as follows:
bytes Present:1010101
bytes Present:11111110
bytes Present:1010101
bytes Present:11111110
bytes Present:1010101
bytes Present:11111110

None of those values technically register as a “bad” response. They all register as “other”; however, it appears as though the “bad responses” may be contained in the binary output above. For example, line 1 has the output: 0b1010101, and a “bad response” output would be 0b10101. I think what is happening is related to streaming. If I read 1 single byte, as far as I can tell, I have no issues. I begin having problems when I need to read consecutive bytes. I am running this on Software serial so I can view output on the Serial Monitor. Does software serial have stream capability? If it did, do you think that would that help me? Documentation seems to imply that it might be useful assuming I was running hardware serial, because I could search the buffer for a very specific response.

Thanks! Any advice would be appreciated. Sorry for the wall of text. I think I described everything well enough, but here is my program for reference. Sorry it’s so cryptic:

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

uint8_t autobaud[]={0x55};               //command 1 autobaud
uint8_t arr[]={0x42, 0x10, 0xCC};      //command 2 change background to color 0x10CC
uint8_t new_arr[]={'9','9','7','9','9','1'}; // command 3 inproper input

void setup()
{
/********initialize**********/
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  digitalWrite(8,HIGH);
  delay(1);
  digitalWrite(8,LOW);
  delay(1);
  digitalWrite(8, HIGH);
  delay(1000);
  pinMode(13, OUTPUT);
  mySerial.begin(9600);
/********end initialize**********/

      dostuff(autobaud, sizeof(autobaud)); //execute command 1
      dostuff(arr, sizeof(arr));                    //execute command 2
      dostuff(new_arr, sizeof(new_arr));    //execute command 3
}

void loop(){serial_response();}

void dostuff(uint8_t *buffer, int len)
{
 mySerial.write(buffer, len);  // Serial.write wants the array pointer and the number of elements
 Serial.print("Command: ");
 Serial.write(buffer, len);
 Serial.println("|");
 serial_response();
}

void  serial_response(){
    while(mySerial.available() == 0); //Do nothing until there are bytes to be read.
    while(mySerial.available() !=0){
       Serial.print("bytes Present:"); //Serial.println(mySerial.available());

       byte incomingByte=0;
       incomingByte=mySerial.read();

    if(incomingByte==0x06){              //good response
        Serial.println(incomingByte, BIN); //when there are bytes, print them to the monitor. 
     }
    else if(incomingByte==0x15){       //bad response
        Serial.println(incomingByte, BIN);
     }
    else{                                           // other response   
        Serial.println(incomingByte, BIN);
     }
   }   
 }

Personally, I'd ditch the binary output, and use hex or decimal. Far easier to understand, in my opinion.

If the output from your device is 7 bits that tell you something, you need to mask the 1 bit you are not interested in.

I'm driving an OLED display with UART.

If you told us about this mystery device, perhaps we could tell how many bits make up the interesting part of the output.

Does software serial have stream capability?

You have access to the source code. Look for yourself to see if it has whatever you mean by stream capability.

The SoftwareSerial class derives from Stream, so the answer is probably yes, but it isn't clear what you mean by "stream capability".

Sorry it's so cryptic

Even a test application can use better names than "dostuff".

PaulS: Personally, I'd ditch the binary output, and use hex or decimal. Far easier to understand, in my opinion.

If the output from your device is 7 bits that tell you something, you need to mask the 1 bit you are not interested in.

I thought that too, but I was/am concerned that bits may have been being overwritten or appended, and I thought that was more difficult to distinguish via HEX, so I thought I'd try binary. If you are interested, here is the output outputting in hex:

bytes Present:15 bytes Present:55 bytes Present:FE bytes Present:55 bytes Present:FE bytes Present:15

Got two bad responses (0x15) this time, as opposed to zero in the original post. This has me so confused :( I don't like this communication protocol.

Is masking like disregarding, or truncating? If you wish, you may look through the datasheet for yourself, but as far as I am aware, I shouldn't have to truncate anything. According to the datasheet, the handshake responses should be very plainly, 0x06 or 0x15.

PaulS:

I'm driving an OLED display with UART.

If you told us about this mystery device, perhaps we could tell how many bits make up the interesting part of the output.

What is it you would like to know? As I said, the device should return a negative response for each perceived incorrect command. I am sending it 6 consecutive known incorrect commands; therefore, I should receive 6 negative responses. I'm getting 6 responses, but the responses aren't exactly what I am expecting. I am expecting six consecutive 0x15's. If I send the device a 1 parameter command, correct or incorrect, i get the expected response of either 0x06 or 0x15. From what I can see, there is an issue between the target device sending a 1 byte response, versus the target device sending a multi-consecutive byte response. Since the display is visually doing everything it is supposed to, My guess regarding the problem is that the responses are getting boogered up when I try to read the bytes from the buffer. When you have 1 single byte by itself, there's not much to misinterpret.

PaulS:

Does software serial have stream capability?

You have access to the source code. Look for yourself to see if it has whatever you mean by stream capability.

The SoftwareSerial class derives from Stream, so the answer is probably yes, but it isn't clear what you mean by "stream capability".

Since it looks to me like my problem may be just reading the data from the buffer itself, I was exploring other modes of reading data beyond the function, read(). What I want to know is if and how I could use stream.readBytesUntil(), or any of the other stream functions for that matter, on a software serial port? Since I've never used it, I'm not exactly sure what stream is or how it's different from serial, so I'm not sure it will fix my problem, but I wanted to try them, if possible. I tried to implement some stream functions already, but the program wouldn't compile, so I've come to get more guidance.

I thought that too, but I was/am concerned that bits may have been being overwritten or appended

The smallest unit that can by sent via the serial port is a byte - 8 bits. Bits can get mangled/misread as a result of low voltages, noise, speed mismatch, etc.

Is masking like disregarding, or truncating?

Yes.

What is it you would like to know?

That link, days ago, would have been very helpful.

I don't understand your concern regarding reading multi-byte responses. From what I read of the data sheet, you get a one byte response - ACK or NAK, regardless of whether you sent a good command or a bad command.

uint8_t new_arr[]={'9','9','7','9','9','1'}; // command 3 inproper input

Since none of these represents a valid command, I would expect one bad command response. If you consistently get 4 bytes after a NAK, I wouldn't worry too much about them.

Personally, I'd be concentrating on writing code to send the thing good data.

Go back and look at Reply #17 in your original thread http://arduino.cc/forum/index.php/topic,105767.msg796227.html#msg796227.

The software serial library is not an exact replacement for the hardware UART that is built into the ATmega328. I don't believe that it has the buffer capability that the hardware device has and that may be a significant factor.

Don

floresta: Go back and look at Reply #17 in your original thread http://arduino.cc/forum/index.php/topic,105767.msg796227.html#msg796227.

The software serial library is not an exact replacement for the hardware UART that is built into the ATmega328. I don't believe that it has the buffer capability that the hardware device has and that may be a significant factor.

Don

Mystery solved! Thank you!

I think I have one more question on the robustness of my response function, but I want to do a bunch more testing, and get the code more in it's final form, so I'll save it for later.

Cheers!