Does Serial.read() move to the next byte after reading?

-------------------------Goal------------------------------------

I’m trying to use ASCII symbols to relay instructions to the Arduino via serial.

For instance, one of my goals is to control an RGB LED strip. The commands are to be as follows:

i) initialize: After catching an ‘i’, it starts storing data in the buffer.
s) stop: it will continue to store data in the buffer until the buffer is full or it receives ‘s’.
r/g/b) red/green/blue: This redirects the pointer to one of these variables using a switch.

Then it takes a string of numbers, converts them to an int, and stores them in the address pointed to by the pointer.

So, for instance I would send a string of bytes: ir255sig192sib64s

Initialize. Set to Red. Store 255. Stop. (Actual order: Initialize and store. Stop. Read stored data which says: Set to Red. Store 255.)
Initialize. Set to Green. Store 192. Stop.
Initialize. Set to Blue. Store 64. Stop.

--------------/Goal-----------------------

But before I really dig in deep, I have a quick question.

When Serial.read() is called, does it go straight to the next byte in the serial buffer?

If so, it could complicate things, because it wouldn’t check the value of the byte before passing it into the buffer. It would check a value, then pass the NEXT value into the buffer regardless of what it is. Sync issues galore.

And is there a way I can bypass this functionality and check the same byte several times?

Here’s my code thus far:

char pBuffer[256] = {0};
int i = 0;

void setup() {
Serial.begin(115200);
}

void loop() {
if(Serial.read() = 'i')
{
  i = 0;  
  while(  (Serial.read() != 's') & (Serial.available() < 256)  )
  {
    pBuffer[i] = Serial.read();
    i++;
  }
  Serial.flush();
}
Serial.flush();
}

Edit: I was just thinking: Would it work to store Serial.read() in a variable and then check the variable multiple times?

When Serial.read() is called, does it go straight to the next byte in the serial buffer?

Yes, it does.

If so, it could complicate things, because it wouldn't check the value of the byte before passing it into the buffer.

That's what Serial.peek() is for.

And is there a way I can bypass this functionality and check the same byte several times?

Possibly.

Edit: I was just thinking: Would it work to store Serial.read() in a variable and then check the variable multiple times?

Yes.

Well, I got it semi-working using the code below, but I’ll have to give Serial.peek() a look.

char pBuffer[256] = {0};
char ReadByte = '0';
int i = 0;
boolean NewData = 0;


void setup() {
Serial.begin(115200);
}

void loop() {
  
  ReadByte = Serial.read();
if(ReadByte == 'i')
{
  ReadByte = Serial.read();
  i = 0;  
  while(  (ReadByte != 's') & (Serial.available() < 256)  )
  {
    pBuffer[i] = ReadByte;
    i++;
    ReadByte = Serial.read();
  }
  Serial.flush();
  NewData = 1;
}
Serial.flush();


if(NewData == 1)
{
  for(i=0; i<10; i++)
  {
    Serial.print(pBuffer[i]);
  }
  Serial.println();
  NewData = 0;
  memset(pBuffer,0,sizeof(pBuffer));
}

However, if I get “ÿÿÿÿÿÿÿÿÿÿ” for every first set, then it starts working correctly on the second or third set.

So in other words, i1234567890s gives me ÿÿÿÿÿÿÿÿÿÿÿÿÿ.

But i1si2si3si4si5si6si7si8si9si0s gives me

ÿÿÿÿÿÿÿÿÿÿÿÿ
2 (or 2ÿÿÿÿÿÿÿÿÿ)
3
4
5
6
7
8
9
0

You are not using if (Serial.available()>0) or similar before reading to see if there is valid serial data to read. Hence, junk out. Check asciitable.com, probably find the character you are getting is equivalent to 0xFF.

Awesome, that did it! Thanks! Here’s my current code. I still have a lot more to do before it’s completely ready for other functions, but it’s ready for controlling colors.

char Buffer[256] = {0};
int bufSize = 0;
int numBytes = 0;
int iter = 0; //General int used for counting loops.
boolean NewData = 0; //If the data has been changed, this becomes true.

int Red = 0;
int Green = 0;
int Blue = 0;
int Safety = 0;
int* Color = &Safety;

int RedPin = 2;
int GreenPin = 3;
int BluePin = 4;



//---------------------------------------------------

/*
Checks for serial input. Reads said input for instructions.

'i': starts reading from serial buffer to buf[]
's': stops reading from buffer.

Returns the number of bytes written.

*/

char ReadByte;        //stores a byte to check, rather than reading directly from serial buffer.

int Parse(char buf[]) 
{
  ReadByte = Serial.read();
  if(ReadByte == 'i')
  {
    while(Serial.available() ==0);
    
    ReadByte = Serial.read();
        
    iter = 0;
    while( (ReadByte != 's') & (Serial.available() < bufSize) ) // Read bytes into buffer until 's' is detected or the buffer is full.
    {
      if (Serial.available()>0)
      { 
        buf[iter] = ReadByte;
        ReadByte = Serial.read();
        iter++;
      }
    }
    Serial.flush();
  }
  
  Serial.flush();
  NewData = 1; //To show that new data is now available.
  return iter;
}

//----------------------------------------

void showBuffer(char buf[], int bufFill)
{
  for(iter = 0; iter < bufFill; iter++)
  {
    Serial.print(buf[iter]);
  }
  Serial.println();
}

//--------------------------------------

void setup() {
Serial.begin(115200);

bufSize = sizeof(Buffer);

pinMode(RedPin, OUTPUT);
pinMode(GreenPin, OUTPUT);
pinMode(BluePin, OUTPUT);
}

//---------------------------------------

void loop() {
  
  if(Serial.available() > 0)
  {
    numBytes = Parse(Buffer);
  }
  
  
 if(NewData == 1)
 {
  if(Buffer[0] == 'r' | Buffer[0] == 'g' | Buffer[0] == 'b')
  {
    switch(Buffer[0])
    {
      case 'r':
                Color = &Red;
                break;
      case 'g':
                Color = &Green;
                break;
      case 'b':
                Color = &Blue;
                break;
    }
    *Color = ((Buffer[1] - '0') * 100) + ((Buffer[2] - '0') * 10) + (Buffer[3] - '0');
    
  Serial.print("Color is now: ");
  Serial.print(Red);
  Serial.print(',');
  Serial.print(Green);
  Serial.print(',');
  Serial.print(Blue);
  Serial.println();
  
  analogWrite(RedPin, Red);
  analogWrite(GreenPin, Green);
  analogWrite(BluePin, Blue);
  
  }
  

   
  memset(Buffer,0,bufSize);
  NewData = 0;
 }

  
}
    Serial.flush();
  }
  
  Serial.flush();

Block until the outgoing serial buffer has been emptied. Why is that necessary?