Serial Read and Write Problem

Hi All,

I'm having a problem using a pro micro from sparkfun (https://www.sparkfun.com/products/12640), a ID-12LA RFID reader (RFID Reader ID-12LA (125 kHz) - SEN-11827 - SparkFun Electronics), and an OLED display from adafruit (Monochrome 128x32 I2C OLED graphic display : ID 931 : $17.50 : Adafruit Industries, Unique & fun DIY electronics and kits).

After a reset of the arduino when I read an RFID tag, the tag id, with some formatting, gets neatly printed to the serial monitor.

Also after a reset of the arduino when I type text into the serial monitor it gets printed to the OLED display.

The problem arises when I try to type text into the serial monitor AFTER having read an RFID tag. If I do that then the display shows a heart symbol and won't update with any other input I provide. Any subsequent RFID tags I read still get properly output to the serial monitor.

Any idea what the issue might be?

//OLED:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 

//RFID: 
int intTag1[13];
String name;
int index = 0;
boolean reading = true;
boolean gotATag = false;
int readByte;
char c;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);

  display.clearDisplay();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
}

void loop() {
  while(Serial1.available()){
    readByte = Serial1.read();

    if(readByte == 2) { 
      reading = true; //begining of tag
    }
    if(readByte == 3) {
      reading = false; //end of tag
      gotATag = true;
    }
    if(reading && readByte != 10){
      intTag1[index] = readByte;
      index ++;
    }
  }

  if(gotATag){
    index = 0;
    Serial.print("r");
    for(int i = 0; i < 13; i++){
      Serial.print(intTag1[i]);
    }
    Serial.print("-");
    gotATag = false; 
  }
  
  while(Serial.available() > 0){
    c = Serial.read();
    name += c;  
  }

  if(name.length() > 0){
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println(name);
    display.display();
    name = "";              
  }
}

Read this:

  while(Serial1.available()){

readByte = Serial1.read();

if(readByte == 2) {
      reading = true; //begining of tag
    }
    if(readByte == 3) {
      reading = false; //end of tag
      gotATag = true;
    }
    if(reading && readByte != 10){
      intTag1[index] = readByte;
      index ++;
    }
  }

There is no guarantee the whole tag will arrive during that loop.

There is no guarantee the whole tag will arrive during that loop.

So? The tag information is not reset until the start or end markers arrive.

Although, OP, you should be doing more in the block that is executed when the start tag arrives, like setting index to 0 and initializing the array.

PaulS:
So?

Oh well, I transfer my comments to this code:

 while(Serial.available() > 0){
    c = Serial.read();
    name += c;  
  }

  if(name.length() > 0){
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println(name);
    display.display();
    name = "";              
  }

There is no guarantee the whole name will arrive during that loop.

There is no guarantee the whole name will arrive during that loop.

That I'll agree with. But, by definition, apparently, whatever does arrive IS the whole value. Of course, it's crappy practice to not use end-of-packet markers. Only one regular on here recommends it, and he seems to be coming around.

Only one regular on here recommends it, and he seems to be coming around.

Maybe he'll stop advocating "delay" as well. We can only hope.

Of course, it's crappy practice to not use end-of-packet markers. Only one regular on here recommends it, and he seems to be coming around.

And there is a regular that always recommends using end of packet delimiters even if they are not sent by the device.

And there is a regular that always recommends using end of packet delimiters even if they are not sent by the device.

Well, it's a piece of crap if if doesn't, and is not worth talking to.

Virtually every device sends end of packet indicators, even if they are only a linefeed. That's the nature of serial communications.

Thanks for the link and the comments. I believe I've addressed both in the code below, but I'm afraid that the same problem persists. Perhaps I'm still making a conceptual error?

//OLED:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 

//RFID: 
int intTag1[13];
String name;
int index = 0;
boolean reading = true;
boolean gotATag = false;
boolean gotAName = false;
int readByte;
char readChar;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);

  display.clearDisplay();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.display();
}

void loop() {
  while(Serial1.available()){
    readByte = Serial1.read();

    if(readByte == 2) { 
      reading = true; //begining of tag
      index = 0;
    }
    if(readByte == 3) {
      reading = false; //end of tag
      gotATag = true;
    }
    if(reading && readByte != 10){
      intTag1[index] = readByte;
      index ++;
    }
  }

  if(gotATag){
    Serial.print("r");
    for(int i = 0; i < 13; i++){
      Serial.print(intTag1[i]);
    }
    Serial.print("-");
    gotATag = false; 
  }
  
  while(Serial.available() > 0){
    readChar = Serial.read();
    
    if(readChar != '\n'){
      name += readChar; 
    } else {
      gotAName = true;
    } 
  }

  if(gotAName){
    display.clearDisplay();
    display.setTextSize(2);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.println(name);
    display.display();
    name = "";     
    gotAName = false;    
  }
}

I can't see anything obvious, but if it were me I would change:

    if(reading && readByte != 10){

to:

    if(reading && readByte != 10 && index < 13){

If that doesn't solve it, put debugging prints in. For example, show each byte as it is received.

well... that was it, you solved it! I can't thank you enough - thanks!