C - BYTE manipulation for display

157 Views Asked by At

This is a programming question which has hardware limitations. I am working on a reverse engineering / hacking project of a "smart" thermostat. (which was not so smart, but it will be able to handle MQTT traffic.)

My problem is with the built in LED matrix display. There are 5 seven segments, two of those have DP as well and 19 icons all around the display.

Normally I would resolve the display like this:

 #define MAKE_BINARY(a,b,c,d,e,f,g,h) (((a)<<7)|(b)<<6)|((c)<<5)|((d)<<4)|((e)<<3|((f)<<2)|((g<<1)|h))
    
    
 static unsigned char int_to_7leds [] = {
  MAKE_BINARY (0,0,0,0,0,0,1,1), // 0
  MAKE_BINARY (1,0,0,1,1,1,1,1), // 1
  MAKE_BINARY (0,0,1,0,0,1,0,1), // 2
  MAKE_BINARY (0,0,0,0,1,1,0,1), // 3
  MAKE_BINARY (1,0,0,1,1,0,0,1), // 4
  MAKE_BINARY (0,1,0,0,1,0,0,1), // 5
  MAKE_BINARY (0,1,0,0,0,0,0,1), // 6
  MAKE_BINARY (0,0,0,1,1,1,1,1), // 7
  MAKE_BINARY (0,0,0,0,0,0,0,1), // 8
  MAKE_BINARY (0,0,0,0,1,0,0,1), // 9

However, there is a slight problem with this. there are five 74HC595 shift registers on the board, which are tied to the LEDs like this: enter image description here

This is not something you would normally want to do when designing stuff, at least I try to keep it like 8 bits (1 SR) / 7 segment and at the end take care of the rest.

As I have already mentioned this is pure hacking, I do not have the original code or the schematics. I would like to ask for some help on how to manipulate the 7 bytes to break it down to something like:

  • 5 characters
  • 21 boolean variables to set everything else

I have started to think about a 56 bit long variable and a huge switch-case structure to set each of the characters, but there should be some other nicer solution out there.

Thank you for reading this!

All suggestions are welcome.

1

There are 1 best solutions below

0
On

First of all thank you guys and girls for all the comments, I have figured it out in the meantime. So shifting out is just simple bit banging, that why I have posted this here and not into the electronics section.

So I have made the following:

int * resolve_chars(char input, int *ch){

switch (input)
{
case 0:
  // statements
        ch[0] = 1;
        ch[1] = 1;
        ch[2] = 1;
        ch[3] = 1;
        ch[4] = 1;
        ch[5] = 1;
        ch[6] = 0;
  break;
case 1:
.
.
.

This is a very long switch-case function that returns the ch in the end.

I have prepared variables for the icons and arrays for each of the characters (+a helper, because C cannot return arrays as it turned out...)

c1 = resolve_chars( - SINLE CHAR TO BE RESOLVED - , c1h);

This gives me bitmap, for this I simply have to shift out 7 BYTES to update the whole display.

        GPIO_SetBits(GPIOE, GPIO_Pin_3); //OE 
        SetDisplayState(0, MAKE_BINARY (c4_dp,back,hand,no_7,power,settings,no_1,c1[3])); //6
        SetDisplayState(0, MAKE_BINARY (rect,c5[2],c5[1],c5[6],c5[0],c5[3],c5[5],c5[4])); //5
        SetDisplayState(0, MAKE_BINARY (kor,c4[2],c4[1],c4[6],c4[0],c4[3],c4[5],c4[4])); //4
        SetDisplayState(0, MAKE_BINARY (c3_dp,c3[2],c3[1],c3[6],c3[0],lock,c3[5],c3[4])); //3
        SetDisplayState(0, MAKE_BINARY (fan,c2[2],c2[1],c2[6],c2[0],lang,c2[5],c2[4])); //2
        SetDisplayState(0, MAKE_BINARY (ora,c1[2],c1[1],c1[6],c1[0],akku,c1[5],c1[4])); //1  
        SetDisplayState(0, MAKE_BINARY (c3[3],no_7,no_6,no_4,no_3,logo,no_2,c2[3])); //0
        GPIO_ResetBits(GPIOE, GPIO_Pin_3); //OE 

And voilá, its working: enter image description here

Now I can focus on the communicaiton with the onboard ESP8266EX