Interpret Data/Clock going into a LCD Display Driver

To preface, I am completely new to electronics. I'm more a software guy.

I have a project that I am working on that I need some insight on how to accomplish. Basically I have an LCD display out of a older vehicle that I want to update to something more modern using a Nano and Adafruit display. My issue comes from trying to interpret the data/clock info going into the LCD Driver chip on the board. All I have is the data sheet for the LCD Driver IC MSM6544 Datasheet(PDF) - OKI electronic componets

I assume I can use any inputs on the nano to connect the data and clock inputs, I just don't know from the code perspective how to decipher the data/clock into something I can use.

The driver chip itself is only using 28 of the segments 29-42 are not being used.

Any insight, code samples, etc are appreciated. Like I said I'm completely new so excuse my terminology, ignorance and all that.

Find out what each segment means. Are these segments of a 4 digit 7 segment display, and/or special symbols?

I'm not interfacing with that chip driver at all. I'm grabbing the signal prior to it at pin 18 & 19 which are the clock and data signals going into the chip.

I found the following that I was able to modify some and it seems to work in showing me what I need but the data coming in is not consistent.

const int clockPin = 2;
const int dataPin = 8;
const int bitNum = 43;

byte dataState = 0;
byte BjCmnd[bitNum];
int i = 0;
int j = 0;
volatile boolean clkDetect = false; 

void setup() 
{
  Serial.begin(2400); 
  pinMode(clockPin, INPUT);
  pinMode(dataPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(clockPin), Activity, CHANGE);
}

void loop() 
{
  if (clkDetect == true)
  { 
    capture(); 
  }
}

void Activity()
{
  clkDetect = true;
}

void capture()
{
  if (digitalRead(dataPin) == HIGH)
  {  
    dataState = 1;
  }
  else
  {
    dataState = 0;
  }

  BjCmnd[i] = dataState;
  clkDetect = false;
  if (i == bitNum)
  {
    i = 0;
    CmndReceived();
  }
  else
  {
    i++;  
  }
}

void CmndReceived() 
{
  for (j=0; j<= bitNum; j++)
  {
    Serial.print(BjCmnd[j]);
  }
  Serial.println("");
}

When the unit is off I get the below data in the serial monitor which is what I expect

10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000

But then randomly it will start to shift and I'm not sure why

10000000000000000000000110000000000000000000
00100000000000000000000001100000000000000000
00000000000011000000000000000000000000000000
10000000000000000000000011100000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
00000010000000000000000000000111000000000000
00000000000000000110000000000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000110000000000000000000
10000000000000000000000001100000000000000000
00000100000000000000000000001100000000000000

Clock triggers on the rising edge only. If you handle the data only in loop() then you don't need an interrupt at all.

You have to watch for the LOAD signal when the received bits are valid and ready for further processing. Also watch the very last bit state whether the bits go into A or B register.

Yeah, I have it set to rising, just copied the wrong version.

The LOAD signal doesn't look to be used. I scoped it and went through all the functions and it never gets pulled high. So looks like what I have coming in for the data/clock is all there is.

The LCD is from a vehicle climate control. Has a bunch of symbols and 3 - 7 segments displaying temperature.

Catch it in an interrupt handler.

What is the clock frequency as measured by your scope?
That you are seeing a repeating pattern of 44 (43) digits is a good sign.
I agree with the comment that you need the load pin as well to be sure the data is kept in sync. It must be provided anyway for the display to function correctly. In such cases a logic analyser is usually better than an oscilloscope to see what is happening.
It could be, however, that if no new data is to be shown on the display, the load pin will be held low. In that case you must try to organise a capture when the controller is sending new data to be displayed.
Incidentally, the for statement in your code reads past the end of the array.

add the load line to pin 6 and added the below, made no change to the output on the serial monitor. It never gets pulled high.

  attachInterrupt(digitalPinToInterrupt(loadPin), Activity, RISING);

Your entire logic has to be updated.

As a simple test write to the monitor if clkDetect becomes true.

Not sure how to capture the clock frequency, barely know how to use a scope outside of verifying a signal. When I scoped the clock wire in auto mode the frequency is between 0.4 and 1.27 khz.

I added the load pin and it changed nothing as it never gets pulled high. but it is there now.

Not sure what you mean by organizing a capture. Currently I'm testing with the unit is the off mode as in that mode it always displays the same thing Once I am able to lock down a consistent data pattern to use as a reference I can then analyze the rest of the functionality.

What do you mean it is reading past the end of the array?

The only time it outputs to the serial monitor is when clkDetect = true.

hence getting the below output

1000000000000000000000000110000000000000000
1000000000000000000000011000000000000000000
1000000000000000000000011000000000000000000
1000000000000000000000011000000000000000000
1000000000000000000000011000000000000000000
1000000000000000000000011000000000000000000
0000000000000000000001100000000000000000000
1000000000000000000000001100000000000000000
1000000000000000000000011000000000000000000

Are you sure that pin 6 can generate an interrupt? Which controller?

I found it much easier to use a logic analyzer, china knock offs can be gotten for less then $10 us. They plug into the USB port of your computer. They work very well. I use Linux so I just keep a seperate screen for the logic analyzer etc. Other screens have the IDE, editor etc. The software decodes the data and will display in about any base you want.

Your array has 43 elements

const int bitNum = 43;
byte BjCmnd[bitNum];

Element 0 is the first and element 42 is the last.

This statement, however, assumes that there is an element 43:

for (j=0; j<= bitNum; j++) { . . .
So will use random data outside the original array.

By organising a test, I mean provoking the controller, what ever it is, to send "real" data to the display.
Assuming it is say a temperature gauge, that could mean warming the sensor so that a new value would appear on the display.
As I said, it could be that only when new data is available that the load pin is manipulated by the controller.

In general, your program will run very slowly. For example, you are printing at only 2400 baud.
That may not matter if the clock frequency is in the low kHz range but I suspect it is actually much higher.

Using a Nano. Swapped it over to pin 3, didn't know only specific pins could handle the interrupt. Redid the code to handle it.

const int clockPin = 2; // digital pin 2
const int loadPin = 3;
const int dataPin = 8;
const int bitNum = 43;

byte dataState = 0;
byte BjCmnd[bitNum];
int i = 0;
int j = 0;
volatile boolean clkDetect = false;  // Interrupt Note
volatile boolean loadDetect = false;  // Load Interrupt Note

void setup() 
{
  Serial.begin(9600); 
  pinMode(clockPin, INPUT);
  pinMode(dataPin, INPUT);
  pinMode(loadPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(clockPin), Activity, RISING);
  attachInterrupt(digitalPinToInterrupt(loadPin), Load, RISING);
}

void loop() 
{
    if (clkDetect == true)
    { 
      if (loadDetect == true)
      {
      capture(); 
      }
    } 
}

void Activity()
{
  clkDetect = true;
}

void Load()
{
  loadDetect = true;
}

void capture()
{
  if (digitalRead(dataPin) == HIGH)
  {  
    dataState = 1;
  }
  else
  {
    dataState = 0;
  }

  BjCmnd[i] = dataState;
  clkDetect = false;
  if (i == bitNum)
  {
    i=0;
    CmndReceived();
    
  }
  else
  {
    i++;  
  }
}

void CmndReceived() 
{
  for (j=0; j<= bitNum-1; j++)
  {
    Serial.print(BjCmnd[j]);
  }
  Serial.println("");
}

Didn't change anything with the data showing in the output monitor

Yeah, I missed that array indexing with the variable. Updated it to

for (j=0; j<= bitNum-1; j++)

All it did was remove an extra zero from the end. Didn't change anything else.

As for as the test, even when the unit is off, there is still sections of the LCD that are displaying in the off state. I figured this would be the easiest to run against as I would figures it would be a continuous unchanged data going into the display driver. When I turn the unit on it's a flood of
continually changing data.

1011011001000000000010110100000011111011010
1011011001000000000010110100000011111011010
1011011001000000000010110100000011111011010
1011011001000000000010110100000011111011010
1011011001000000000010110100000011111011010
1011011001000000000010110100000011111011010
1100100000000001011010000001111101101011000
0001011010000001111101101011000000100000010
0001111101101011000000100000010110110010000
0110000001000000101101100100000000001011010
0010000001011011001000000000010110100000011
1011011001000000000010110100000011111011010

I Also reduced the baud rate down to 2400 purposely so I could visually see any discrepancies in the data stream. at 9600 it's too fast. It's a non stop flow of the above over and over again.

From the Display Driver documentation regarding the input data

Data Input

The data input consists of the following three timing sections:

i) SEG-DATA section (42-bit)
ii) SEL bit section (1-bit)
iii) LOAD section

A total of 43 bits of 42-bit segment data and 1-bit select bit are taken in the 43-bit shift register at the rising edge of the clock.

The segment data corresponds to "L" (segment OFF) and "H" (segment ON). Input the segment data from SEG42 to SEG1 in this order.

I feel like I am missing something "probably a lot" in regards to that 1 bit shift register.

That means that loadDetect definitely was set, else the

[quote="just_a_noob, post:15, topic:1178133"]

      if (loadDetect == true)
      {
      capture(); 
      }

never would execute. Now synchronize the output of the output to loadDetect, i.e. copy or output the preceding bits on the Serial Monitor, ignore all other bits. And don't forget to reset loadDetect for the next input.

Just figured out how to quote... LOL

Not sure I follow on how to synchronize the outputs output.

Like This?

void loop() 
{
    if (clkDetect == true)
    { 
      if (loadDetect == true)
      {
      capture(); 
      }
      loadDetect = false;
    } 
}

You collect all bits on a clk pulse and on loadDetect transfer the preceding 21 bits into the register indicated by the last bit.

I'm sorry but I'm not following exactly what needs to be done here or what I need to change to accomplish it.