Plucking portions of data from serial stream to display on LCD

Thank you for the information. I swear I have been searching with every permutation you can think of in Google and have probably read through or skimmed over a hundred web pages and I never once saw a straight forward reference like this anywhere.

It works great after a small bit of adjustment. Thanks again!

I was getting closer to the answer. I was exploring the for loops but I didn't think of intertwining the two strings like that in one loop. I was trying to somehow basically do a sub loop.

It's great to have a place like this to get help.

also:

you just blew my mind with this

Serial.print("importantStuff: [");
Serial.print(importantStuff);
Serial.println("]");

I didn't know you could insert statements within statements like that across lines. Wild...

This is what I have so far. I know it's ugly. :blush:

My question is why the outgoing serial control portion at the top does not work after adding in the bottom portion that deals with the LCD. If I comment out the :

while (Serial.available() <20);
through the...
lcd.print(freqLine);

Button and volume controls will then transmit their corresponding codes appropriately.

// these constants won't change:
const int sensorMin = 0;      // volume minimum
const int sensorMax = 1000; // volume maximum  orig setting 600 // include the library code:
#include "Wire.h"
#include "LiquidCrystal.h"  // initialize the library with the numbers of the interface pins LiquidCrystal lcd(0);

#define INPIN1 2  //Arrow up button
#define INPIN2 3  //Arrow down button
int state1 = HIGH;
int state2 = HIGH;
int previousvolume = 0;
int incomingByte = 0;
char freqLine[10];
LiquidCrystal lcd(0);

void setup() {

  lcd.begin(20, 4);
  Serial.begin(9600);
  UCSR0C = UCSR0C | B00111000; // modded to change to odd parity so it matches the Micom standard of 8-odd-1
  pinMode(INPIN1, INPUT);  //arrow up 
  pinMode(INPIN2, INPUT); //arrow down
}
void loop() {

  // read the volume pot 
  int sensorReading = analogRead(A0);   // map the sensor range to a range of eight options across the volume range:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 15);
  int volume = range;

  //buttonState = digitalRead(buttonPin); // read arrow up button state

    delay(10); // debounces switches
  int val1 = digitalRead(INPIN1);
  int val2 = digitalRead(INPIN2);

  {
    if (val1 == HIGH)
    {
      byte UPBUTTON[10] = {
        0x24,0x05,0x18,0x36,0xFE,0x7B,0xEF,0x01,0xE0,0x03 }; // up button command
      Serial.write(UPBUTTON, 10); // will write the array of bytes to the serial port in raw hex form (length 10)
      delay(20);
      byte RELEASEBUTTON[10] = {
        0x24,0x05,0x18,0x36,0xFF,0x7B,0xEF,0x01,0xE1,0x03 }; // release button command
      Serial.write(RELEASEBUTTON, 10); // will write the array of bytes to the serial port in raw hex form (length 10)
      delay(50);

    }
    if (val2 == HIGH)
    {
      byte DWNBUTTON[10] = {
        0x24,0x05,0x18,0x36,0xDF,0x7B,0xEF,0x01,0xC1,0x03                              } // up button command
      ;
      Serial.write(DWNBUTTON, 10); // will write the array of bytes to the serial port in raw hex form (length 10)
      delay(20);
      byte RELEASEBUTTON[10] = {
        0x24,0x05,0x18,0x36,0xFF,0x7B,0xEF,0x01,0xE1,0x03                              } // release button command
      ;
      Serial.write(RELEASEBUTTON, 10); // will write the array of bytes to the serial port in raw hex form (length 10)
      delay(50);
    }
  }

  // Volume control section starts below
  if (previousvolume != range){
    switch (range) { 

    case 0:    // lowest volume level (muted)
      {
        byte vol0[8] = {
          0x24,0x03,0x18,0x2B,0x00,0x00,0x6A,0x03                                        } // volume level 0 in hex
        ;
        Serial.write(vol0, 8); 
        previousvolume = 0;
      }
      break;

    case 1:   // 5
      {
        byte vol10[8] = {
          0x24,0x03,0x18,0x2B,0x05,0x00,0x6F,0x03                                        } // volume level 05 in hex
        ;
        Serial.write(vol10, 8); 
        previousvolume = 1;
      }
      break;

    case 2:
      // 6
      {
        byte vol5[8] = {
          0x24,0x03,0x18,0x2B,0x06,0x00,0x70,0x03                                        } // volume level 06 in hex
        ;
        Serial.write(vol5, 8); 
        previousvolume = 2;
      }
      break;


    case 3:    // 7
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x07,0x00,0x71,0x03                                        } // volume level 07 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = range;
      }
      break;

    case 4:    // 8
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x08,0x00,0x72,0x03                                        } // volume level 08 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 4;
      }
      break;

    case 5:    // 9
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x09,0x00,0x73,0x03                                        } // volume level 09 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 5;
      }
      break;

    case 6:    // 10
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x10,0x00,0x7A,0x03                                        } // volume level 10 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 6;
      }
      break;

    case 7:    // 12
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x12,0x00,0x7C,0X03                                        } // volume level 12 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 7;
      }
      break;

    case 8:    // 14
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x14,0x00,0x7E,0x03                                        } // volume level 14 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 8;
      }
      break;

    case 9:    // 16
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x16,0x00,0x80,0x03                                        } // volume level 16 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 9;
      }
      break;

    case 10:    // 18
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x20,0x00,0x8A,0x03                                        } // volume level 18 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 10;
      }
      break;

    case 11:    // 25
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x25,0x00,0x8F,0x03                                        } // volume level 25 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 11;
      }
      break;

    case 12:    // 30
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x30,0x00,0x9A,0x03                                        } // volume level 30 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 12;
      }
      break;

    case 13:    // 40
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x40,0x00,0xAA,0x03                                        } // volume level 40 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 13;
      }
      break;

    case 14:    // 90
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0x90,0x00,0xFA,0x03                                        } // volume level 90 in hex
        ;
        Serial.write(vol20, 8); 
        previousvolume = 14;
      }
      break;

    case 15:    // 100
      {
        byte vol20[8] = {
          0x24,0x03,0x18,0x2B,0xB0,0x00,0x1A,0x03                                        } // volume level B0 in hex as FF is ridiculous!
        ;
        Serial.write(vol20, 8); 
        previousvolume = 15;
      }
      break;
    }
  }



  char buffer[20];
  if (Serial.available() <20);
  {
    // Do nothing
  }
  while (Serial.available() <20);
  int i;
  for (i=0;i<20;i++)
  {
    buffer[i] = Serial.read();
    buffer[i+1] = '\0';
  }
  char freqArray[10];
  for(int i=7, j=0; i<=17; i++, j++)
  {
    lcd.setCursor(0, 1);
    freqLine[j] = buffer[i]; 
    freqLine[j+1] = '\0'; // Keep NULL terminated
  }
  
  lcd.print(freqLine);

}

Thanks again.

The various arrays do not take up less space because they are local. You should consider making them global arrays.

You should consider removing the useless { and } where they occur. They scream clueless. Of course, the tricky part is determining which ones are needed, which ones are optional, and which ones are useless.

{ <-- Useless
if (val1 == HIGH)
{ <-- Optional
byte UPBUTTON[10] = { <-- Necessary

If I comment out the :

while (Serial.available() <20);
through the...
lcd.print(freqLine);

The while() loop will wait for 20 characters to arrive. That's probably not what you want to do. More likely, you want to do something only if there are at least to characters ready to be read. Blocking waiting for them may be the source of your problem.

Since you check for serial data on every pass through loop, I am sure that it is the blocking wait that is killing you.

Oh, I see what you mean. I had been throwing around { } like a madman. I went through and cleaned up a ton of them then made the volume arrays global at the top and compressed everything down. It's so much cleaner now and allowed me to see quite a few glaring errors I was unable to clearly see before.

I still need to figure out the "broken" serial issue but this has been a tremendous help so far.

Thanks once again!

I'm having synchronization issues.

The data packets always start with 0x24. Checksum second to the last right before the 0x03. They always end with 0x03. However, there is often a 0x03 in the middle somewhere.

The length of the data packet is indicated by the byte at position 1 right after the start of line (less the checksum and end of line) so we could just factor two less at all times.

Checksum is sum of everything less the checksum itself of course and the end of line marker 03. I'm thinking I could forego any checksumming since the probability of errors is very low.

I've been trying to figure out a reliable way to flag for start of line 0x24, look to byte position 1 and then read forward to the appropriate position where the 0x03 end of line marker should be. If it's present then go forward and process the information through the FOR loops and distill out the interesting data then send that to the LCD.

Something similar to : 24 08 03 48 45 4C 4C 4F A2 03

24 is start of line
08 is length (less the checksum and the end of line marker 03)
03 (if this is 03 it should be placed at LCD line 0,1) (if it's 04 then place the data received on LCD line 0,2)
48 45 4C 4C 4F displays "hello"
A2 is checksum
03 is end of data packet

As it is now without any packet marker discrimination or accountability for varying packet length from packets destined for other display areas I'm getting garbage at the front and back as well as the interesting data being shifted around on the LCD with each incoming packet.

I'm at a loss as to how to begin to write something to handle this.

Thanks for reading.

Read the serial stream until you find a 24.
Wait for a byte to be available.
Read the byte, which will tell you how many interesting bytes are coming.
Wait until that number of bytes is available (or until too much time has elapsed).
Read the n interesting bytes. The nth interesting byte should be 0x03. If it is, you got, and can use, and good packet. If not, disregard that packet, and start over, looking for a 24.

I found that the device is padding the data at times before and after the packets depending on how I'm interfacing to it. I kept wondering how such basic concepts didn't seem to work. I kept seeing garbage intermixed and was about to beat my head against the desk.

Thanks for your patience with all the dumb questions.

Edited to disregard erroneous info...

PaulS:
Read the serial stream until you find a 24.
Wait for a byte to be available.
Read the byte, which will tell you how many interesting bytes are coming.
Wait until that number of bytes is available (or until too much time has elapsed).
Read the n interesting bytes. The nth interesting byte should be 0x03. If it is, you got, and can use, and good packet. If not, disregard that packet, and start over, looking for a 24.

I'm basically stuck at this point:

Wait until that number of bytes is available (or until too much time has elapsed).
Read the n interesting bytes.

The rest makes sense to me but I'm a bit lost as to what way to use the length byte determine how much to read.