More elegant, less resource hungy way of state change detection

Hy, Im wondering if there is more elegant way, faster, less resource hungry state change detection method.
Right now Im using following method:

char value;
char lastValue;

if (value != lastValue)
{
//code to execute
lastValue = value;
}

It works good and all, but when working on big project it takes alot of code and resources...

Is there any better way to do it?

Thank you

How exactly do you propose to test 2 values (current vs. previous) without allocating variable space for 2 values and actually doing the test?

If you don't like global variables, you can bury them inside a function

bool testSomething() {
  static char lastValue;
  char value = readValueSomehow();
  bool ret = false;
  if ( value != lastValue )  return true;
  lastValue = value;
  return ret;
}

but the cost of this "elegance" would be a bit more code.

Hy,
I was thinking if maybee there is a function like onStateChange or something similar.

I dont mind code being big, I was thinking if there is something mainly for speed.
I`m integrading usb playback / bluetooth in factory BMW e39 radio and I have alot of going on in my code (Wire.write for display with text scroll, Wire.read for 8-bit expander (fascia buttons), Serial.Write/Read for mp3/bluetooth board, mode switching between FM / usb / bluetooth, detection if radio is set to FM or Tape, another Serial.Read for K-line (to read multifunction steering wheel commands), switching between arduino and mcu from radio)...

Just mode selection / button state detection slows loop down and I`m still adding stuff.

Code goes like if mode button is pressed change between 3 modes (radio usb bluetooth), if mode is radio do that and dont do that, if mode is usb do that and not that.... and so on.

I started from zero and after about 2 months of coding and adding stuff code started to slow down, affecting lcd scroll refresh time and button detection.

i2c transmissions are WAY slower than any processing the MCU is doing. It sounds like this may be a case of premature optimization.

I already limited the i2c transmissions... I use interrupt pin of 8-bit expander to use i2c read only when needed, I write to display only when needed, but writing to display happens every loop because of text scroll... Base code was writing text to display with scrolling and it was fast tho.

Why write to LCD faster than a human eye will notice a change? Write 2 to 5 times per second. That lowers the load on the execution.

If that is true then either loop() is running really slowly (why ?) or the scrolling is happening so fast that the text is unreadable

Why don't you write to the screen only when something on it changes, such as scrolling text or a change of displayed value ?

"State change detection" is obviously not the problem with your code.

Check if the display can use SPI, or has an 8 bit parallel data transfer option, either of which is much faster than I2C.

2 Likes

Rewriting it so you have a function that can handle different inputs will reduce the size of the code.

For each input that requires state change detection, you will have to store some data, no way around that. If value and lastValue are integers, reduce them to bytes. You can also combine the states of 8 inputs into one byte, I haven't checked how much you will save in both program and ram.

Hello
Keep it simple and stupid and declare a struct for the button and a method to handle the button struct.
May you can made a structured array in case of multile buttons.
Have a nice day and enjoy coding in C++.

Nope, its very little code and it shares processor time fairly with everything else (not hogging the processor).

Perhaps with more information I might see the point you are trying to make. Even with loop polling hundreds of things, its still running at on a processor at MHz speeds, so you should still see loop iterate thousands of times/second. I suspect there are other things in loop that are causing the latency you experience.

However perhaps you might get some benefit from pin change interrupts to drive the various button inputs and so forth. Using interrupts avoids the need for polling, which is I think what you are getting at. However pin change interrupts are a very board-specific feature (usable on the Uno, but not the Mega, for instance).

I made it work. I overlooked delay(300); in the code that was there from the beginning when this code was just a base code for printing to display from String and I should had deleted it about a month ago... anyway I removed that delay and also made code to write to display every third loop and with delay(100); I also added smal delays in tactical places under if statements and now its working perfect.

Why not only write to the display when you need to, ie when something has changed and even then don't update the whole display, just what has changed. What is the purpose of the delay() ?

Why ?

Because I dont have generic character LCD where I would just enable text scroll, I have dot matrix display (original on BMW e39 radio), basicly I had to write my own code, based on datasheet.
Only way to make text scroll is programmatically.

In some cases I need delays, for example when USB mode gets selected arduino sends the command for USB mode to sound module, after that it sends command to query filename of playing song, I need delay in between to give sound module the time to execute start of USB mode before querying for filename.

Maybe you need a delay, but that does not mean that you need a delay()

Yes, but problem is that I overlooked that delay(300); and had been writing the code for a long time with that delay in place... Everything worked fine, I made alot of things in my code the way that it must be excuted in the same loop or values my change further down the loop.
Now "correcting the code" would take me alot of time.
I got the wanted result: stability and speed.

There is alot going in my code and changing one thing can lead into failure if I dont change few things with it.
I might correct that mistake in the future but for now I will let it be.

In the end if my "music addon module" works as it should once I get everything sorted I will save the code somewhere in case I will need a backup in the future, but will likely forget about its content and never mess with it again.

I will post a code if anyone wants to take a look at it to get a feel of what Im talking about, but keep in mind that Im a beginner in coding, sure I coded some little things in the past, but nothing as advanced as this. I know that I should use voids, maybee make a library, use for loops and so on. But for me if it works it works. I learned alot and will keep in mind to make some things different in my next projects to come.

#include <Wire.h>
#include <DFRobot_BT401.h>
//#include <softwareSerial.h>

//SoftwareSerial debugSerial(2, 3); // RX, TX
char rort = 1; //Radio = 0, Tape = 1
char mode = 1;
char queryMode = 1;
char queryDirSIZE = 1;
char INTERRUPT = 1;
char buttonPressed = 0;
char PP = 0;
char FRD = 0;
char RWD = 0;
char MOD = 0;
char FRDcounter = 0;
char FRDcounterTrigger = 0;
char RWDcounter = 0;
char RWDcounterTrigger = 0;
char FRDactivated = 0;
char RWDactivated = 0;

int displayRefresh = 0;


char queryFileName = 0;

String nowPlaying;
String songNUMBER;
String lastsongNUMBER;
String dirSIZE;
String lastdirSIZE;
String newdirSIZE;
String newsongNUMBER;

//long lastDebounceTime = 0;
//long debounceDelay = 200; //občutljivost gumba

int period = 1000;
unsigned long time_now = 0;

char acolumn = 0;
char bcolumn = 1;
char ccolumn = 2;
char dcolumn = 3;
char ecolumn = 4;
char fcolumn = 5;
char gcolumn = 6;
char hcolumn = 7;
char icolumn = 8;




String inputText;
char inputText_len;
String smallDisplay;
char smallDisplay_len;


constexpr size_t numColumns = 5;  //number of bytes -columns for 1 character


//Pretty self-explenatory -here I store all my characters.
void getColumns(char c, uint8_t columns[numColumns]);

const uint8_t upperCase[][numColumns] PROGMEM = {
  {0X7E, 0X11, 0X11, 0X11, 0X7E}, // Column codes for 'A'
  {0X7F, 0X49, 0X49, 0X49, 0X36}, // Column codes for 'B'
  {0X3E, 0X41, 0X41, 0X41, 0X22}, // Column codes for 'C'
  {0X7F, 0X41, 0X41, 0X22, 0X1C}, // Column codes for 'D'
  {0X7F, 0X49, 0X49, 0X49, 0X41}, // Column codes for 'E'
  {0X7F, 0X09, 0X09, 0X09, 0X01}, // Column codes for 'F'
  {0X3E, 0X41, 0X49, 0X49, 0X7A}, // Column codes for 'G'
  {0X7F, 0X08, 0X08, 0X08, 0X7F}, // Column codes for 'H'
  {0X00, 0X41, 0X7F, 0X41, 0X00}, // Column codes for 'I'
  {0X20, 0X40, 0X41, 0X3F, 0X01}, // Column codes for 'J'
  {0X7F, 0X08, 0X14, 0X22, 0X41}, // Column codes for 'K'
  {0X7F, 0X40, 0X40, 0X40, 0X40}, // Column codes for 'L'
  {0X7F, 0X02, 0X0C, 0X02, 0X7F}, // Column codes for 'M'
  {0X7F, 0X04, 0X08, 0X10, 0X7F}, // Column codes for 'N'
  {0X3E, 0X41, 0X41, 0X41, 0X3E}, // Column codes for 'O'
  {0X7F, 0X09, 0X09, 0X09, 0X06}, // Column codes for 'P'
  {0X3E, 0X41, 0X41, 0X61, 0X3E}, // Column codes for 'Q'
  {0X7F, 0X09, 0X19, 0X29, 0X46}, // Column codes for 'R'
  {0X46, 0X49, 0X49, 0X49, 0X31}, // Column codes for 'S'
  {0X01, 0X01, 0X7F, 0X01, 0X01}, // Column codes for 'T'
  {0X3F, 0X40, 0X40, 0X40, 0X3F}, // Column codes for 'U'
  {0X07, 0X18, 0X60, 0X18, 0X07}, // Column codes for 'V'
  {0X3F, 0X40, 0X38, 0X40, 0X3F}, // Column codes for 'W'
  {0X63, 0X14, 0X08, 0X14, 0X63}, // Column codes for 'X'
  {0X07, 0X08, 0X70, 0X08, 0X07}, // Column codes for 'Y'
  {0X61, 0X51, 0X49, 0X45, 0X43} // Column codes for 'Z'
};

const uint8_t lowerCase[][numColumns] PROGMEM = {
  {0X20, 0X54, 0X54, 0X54, 0X78}, // Column codes for 'a'
  {0X7F, 0X48, 0X48, 0X48, 0X30}, // Column codes for 'b'
  {0X38, 0X44, 0X44, 0X44, 0X44}, // Column codes for 'c'
  {0X30, 0X48, 0X48, 0X48, 0X7F}, // Column codes for 'd'
  {0X38, 0X54, 0X54, 0X54, 0X58}, // Column codes for 'e'
  {0X00, 0X08, 0X7E, 0X09, 0X02}, // Column codes for 'f'
  {0X48, 0X54, 0X54, 0X54, 0X3C}, // Column codes for 'g'
  {0X7F, 0X08, 0X08, 0X08, 0X70}, // Column codes for 'h'
  {0X00, 0X00, 0X7A, 0X00, 0X00}, // Column codes for 'i'
  {0X20, 0X40, 0X40, 0X39, 0X00}, // Column codes for 'j'
  {0X00, 0X7F, 0X10, 0X28, 0X44}, // Column codes for 'k'
  {0X00, 0X41, 0X7F, 0X40, 0X00}, // Column codes for 'l'
  {0X7C, 0X04, 0X18, 0X04, 0X7C}, // Column codes for 'm'
  {0X7C, 0X08, 0X04, 0X04, 0X78}, // Column codes for 'n'
  {0X30, 0X48, 0X48, 0X30, 0X00}, // Column codes for 'o'
  {0X7C, 0X14, 0X14, 0X14, 0X08}, // Column codes for 'p'
  {0X7F, 0X04, 0X04, 0X04, 0X03}, // Column codes for 'q'
  {0X7C, 0X08, 0X04, 0X04, 0X08}, // Column codes for 'r'
  {0X48, 0X54, 0X54, 0X54, 0X24}, // Column codes for 's'
  {0X04, 0X04, 0X3F, 0X44, 0X24}, // Column codes for 't'
  {0X3C, 0X40, 0X40, 0X40, 0X3C}, // Column codes for 'u'
  {0X1C, 0X20, 0X40, 0X20, 0X1C}, // Column codes for 'v'
  {0X3C, 0X40, 0X30, 0X40, 0X3C}, // Column codes for 'w'
  {0X44, 0X28, 0X10, 0X28, 0X44}, // Column codes for 'x'
  {0X04, 0X48, 0X30, 0X18, 0X04}, // Column codes for 'y'
  {0X44, 0X64, 0X54, 0X4C, 0X44} // Column codes for 'z'
};

const uint8_t numerals[][numColumns] PROGMEM = {
  {0X3E, 0X45, 0X49, 0X51, 0X3E}, // Column codes for '0'
  {0X00, 0X42, 0X7F, 0X40, 0X00}, // Column codes for '1'
  {0X42, 0X61, 0X51, 0X49, 0X46}, // Column codes for '2'
  {0X22, 0X41, 0X49, 0X49, 0X36}, // Column codes for '3'
  {0X18, 0X14, 0X12, 0X7F, 0X10}, // Column codes for '4'
  {0X27, 0X45, 0X45, 0X45, 0X39}, // Column codes for '5'
  {0X3E, 0X49, 0X49, 0X49, 0X30}, // Column codes for '6'
  {0X01, 0X71, 0X09, 0X05, 0X03}, // Column codes for '7'
  {0X36, 0X49, 0X49, 0X49, 0X36}, // Column codes for '8'
  {0X06, 0X49, 0X49, 0X49, 0X3E} // Column codes for '9'
};

const uint8_t symbolsa[][numColumns] PROGMEM = {
  {0X00, 0X00, 0X5F, 0X00, 0X00}, // Column codes for '!'
  {0X00, 0X03, 0X00, 0X03, 0X00}, // Column codes for '"'
  {0X14, 0X7F, 0X14, 0X7F, 0X14}, // Column codes for '#'
  {0X24, 0X2A, 0X7F, 0X2A, 0X12}, // Column codes for '$'
  {0X23, 0X13, 0X08, 0X64, 0X62}, // Column codes for '%'
  {0X36, 0X49, 0X55, 0X22, 0X50}, // Column codes for '&'
  {0X04, 0X02, 0X02, 0X01, 0X00}, // Column codes for '''
  {0X00, 0X1C, 0X22, 0X41, 0X00}, // Column codes for '('
  {0X00, 0X41, 0X22, 0X1C, 0X00}, // Column codes for ')'
  {0X14, 0X08, 0X3E, 0X08, 0X14}, // Column codes for '*'
  {0X08, 0X08, 0X3E, 0X08, 0X08}, // Column codes for '+'
  {0X00, 0X00, 0X50, 0X30, 0X00}, // Column codes for ','
  {0X08, 0X08, 0X08, 0X08, 0X08}, // Column codes for '-'
  {0X00, 0X60, 0X60, 0X00, 0X00}, // Column codes for '.'
  {0X20, 0X10, 0X08, 0X04, 0X02} // Column codes for '/'
};

const uint8_t symbolsb[][numColumns] PROGMEM = {
  {0X00, 0X7F, 0X41, 0X41, 0X00}, // Column codes for '['
  {0X02, 0X04, 0X08, 0X10, 0X20}, // Column codes for '\'
  {0X00, 0X41, 0X41, 0X7F, 0X00}, // Column codes for ']'
  {0X04, 0X02, 0X01, 0X02, 0X04}, // Column codes for '^'
  {0X00, 0X00, 0X00, 0X00, 0X00}, // Column codes for '_'
  {0X00, 0X01, 0X02, 0X04, 0X00} // Column codes for '`'

};

const uint8_t symbolsc[][numColumns] PROGMEM = {
  {0X08, 0X36, 0X41, 0X41, 0X00}, // Column codes for '{'
  {0X00, 0X00, 0X7F, 0X00, 0X00}, // Column codes for '|'
  {0X00, 0X41, 0X41, 0X36, 0X08}, // Column codes for '}'
  {0X01, 0X02, 0X01, 0X20, 0X00}, // Column codes for '~'
};

const uint8_t equalSymbol [numColumns] PROGMEM = {0x14, 0x14, 0x14, 0x14, 0x14};

const uint8_t afnaSymbol [numColumns] PROGMEM = {0x32, 0x49, 0x71, 0x41, 0x3E};

const uint8_t space[numColumns] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00};

const uint8_t unknown[numColumns] PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00};



DFRobot_BT401 bt;

void setup() {

  pinMode(10, INPUT_PULLUP); //INTERRUPT
  pinMode(11, OUTPUT); // ADG411 pin for ibus and MCU -LOGIC 1 = mcu and ibus OFF, LOGIC 0 = on...
  pinMode(12, INPUT_PULLUP); // Radio or Tape - 0 = Radio, 1 = Tape
  char btnrd;
  rort = 1;
  do {
    delay(300);
    rort = digitalRead(12);
  } while (rort == 0);
  Wire.begin(); // Wire communication begin
  Serial.begin(256000); // The baudrate of Serial monitor is set in 9600
  Wire.beginTransmission(0x20);
  Wire.write(0x9c);
  Wire.endTransmission();     // stop transmitting
  /////////////////////////////////////////////////////////
  // Serial.begin(115200);
  //debugSerial.begin(9600);

  /*Delay 2s for the BT401 to start*/
  while (!bt.begin(Serial)) {
    delay(300);
  }
  bt.setVOl(30);
  bt.switchFunction(bt.eUDisk);
  delay(100);

  bt.setPlayMode(bt.eDeviceCycle);
}

void loop() {

  ////////////////////////////////////////////////////////////

  INTERRUPT = digitalRead(10);
  if (INTERRUPT == 0) {
    Wire.requestFrom(0x20, 1);    // request 6 bytes from slave device #8

    while (Wire.available()) { // slave may send less than requested
      char btnrd = Wire.read(); // receive a byte as character
      buttonPressed = btnrd;
      //  Serial.println(c, DEC);         // print the character

      if (btnrd == 28) {

        Wire.beginTransmission(0x20);
        Wire.write(0x1D);
        Wire.endTransmission();     // stop transmitting
        Wire.requestFrom(0x20, 1);    // request 6 bytes from slave device #8
        char btnrd = Wire.read(); // receive a byte as character
        buttonPressed = btnrd;
        //   ///   Serial.println(c, DEC);         // print the character


      }

      if (btnrd == -116) {

        Wire.beginTransmission(0x20);
        Wire.write(0x03);
        Wire.endTransmission();     // stop transmitting
        Wire.requestFrom(0x20, 1);    // request 6 bytes from slave device #8
        char btnrd = Wire.read(); // receive a byte as character
        buttonPressed = btnrd;
        //   ///   Serial.println(c, DEC);         // print the character

      }

      Wire.beginTransmission(0x20);
      Wire.write(0x9c);
      Wire.endTransmission();     // stop transmitting

    }
    if (FRDcounterTrigger == 1)
    {
      FRDcounterTrigger = 0;
      buttonPressed = 0;
      if (FRDcounter <= 9)
      {
        FRDcounter = -1;
        buttonPressed = 0;
      }
    }
    if (RWDcounterTrigger == 1)
    {
      RWDcounterTrigger = 0;
      buttonPressed = 0;
      if (RWDcounter <= 9)
      {
        RWDcounter = -1;
        buttonPressed = 0;
      }
    }
    if (FRDactivated == 1)
    {
      FRDactivated = 0;
    }
    if (RWDactivated == 1)
    {
      RWDactivated = 0;
    }
    INTERRUPT = 1;
  }
  if (FRDcounter == 12)
  {
    FRDcounter = 0;
    buttonPressed = 0;
  }
  if (RWDcounter == 12)
  {
    RWDcounter = 0;
    buttonPressed = 0;
  }


  //debugSerial.println(buttonPressed);
  if (buttonPressed == 3 && mode == 0) //radio
  {
    mode = 1;
    queryMode = 1;
    buttonPressed = 0;
    delay(50);

  }

  if (buttonPressed == 3 && mode == 1) //USB
  {
    mode = 2;
    queryMode = 1;
    buttonPressed = 0;
    delay(150);
  }

  if (buttonPressed == 3 && mode == 2) //BLUETOOTH
  {
    buttonPressed = 0;
    queryMode = 1;
    mode = 0;
    delay(150);
  }



  //Serial.println("MODE pressed");
  // modeSelected = 0;



  if (buttonPressed == 28 && mode != 0) //PLAY / PAUSE
  {
    //Serial.println("PLAY / PAUSE pressed");
    bt.playPause();

    buttonPressed = 0;
  }

  if (buttonPressed == 1 && mode != 0) //FRD
  {
    FRDcounterTrigger = 1;
  }

  if (FRDcounterTrigger == 1 && FRDcounter <= 10)
  {
    FRDcounter = FRDcounter + 1;

  }
  //debugSerial.println(FRDcounter, DEC);
  if (FRDcounter == -1)
  {
    bt.next();
    FRDcounter = 0;
    FRDcounterTrigger = 0;


  }

  if (FRDcounter == 10)
  {
    FRDactivated = 1;
    //fast forward command
    FRDcounterTrigger = 0;
    FRDcounter = 12;
  }
  if (FRDactivated == 1)
  {
    bt.FRD();
  }

  if (buttonPressed == 2 && mode != 0) //RWD
  {
    RWDcounterTrigger = 1;
  }

  if (RWDcounterTrigger == 1 && RWDcounter <= 10)
  {
    RWDcounter = RWDcounter + 1;

  }
  //debugSerial.println(RWDcounter, DEC);
  if (RWDcounter == -1)
  {
    bt.last();
    RWDcounter = 0;
    RWDcounterTrigger = 0;


  }

  if (RWDcounter == 10)
  {
    RWDactivated = 1;
    //fast forward command
    RWDcounterTrigger = 0;
    RWDcounter = 12;
  }
  if (RWDactivated == 1)
  {
    bt.RWD();
  }

  if (mode == 0 && queryMode == 1) //RADIO
  {
    inputText = "Radio";
    digitalWrite(11, LOW);
    queryMode = 0;
  }

  if (mode == 1 && queryMode == 1) //USB
  {
    digitalWrite(11, HIGH);
    bt.usbMode();
    delay(100);
    queryFileName = 1;
    queryDirSIZE = 1;
    queryMode = 0;
  }

  if (mode == 2 && queryMode == 1) //BLUETOOTH
  {
    digitalWrite(11, HIGH);
    bt.bluetoothMode();
    inputText = "Bluetooth";
    smallDisplay = "--:--";
    queryMode = 0;
    acolumn = 0;
    bcolumn = 1;
    ccolumn = 2;
    dcolumn = 3;
    ecolumn = 4;
    fcolumn = 5;
    gcolumn = 6;
    hcolumn = 7;
    icolumn = 8;
  }
  inputText_len = inputText.length() + 1;

  if (mode == 1 && queryDirSIZE == 1) {
    do {
      dirSIZE = (bt.dirSIZE());
      if (lastdirSIZE != dirSIZE) {
        lastdirSIZE = dirSIZE;
        newdirSIZE = dirSIZE;
      }
    } while (! newdirSIZE.startsWith("M2"));
    newdirSIZE.replace("M2+00000", "");
    if (newdirSIZE != "000") {
      queryDirSIZE = 0;
    }
    //debugSerial.println(dirSIZE);
  }


  if (mode == 1 && millis() >= time_now + period) {
    time_now += period;
    songNUMBER = (bt.songNUM());
    if (lastsongNUMBER != songNUMBER) {

      do {
        songNUMBER = (bt.songNUM());
        lastsongNUMBER = songNUMBER;
        newsongNUMBER = songNUMBER;
      } while (! newsongNUMBER.startsWith("MO"));
      newsongNUMBER.replace("MO+000000", "");
      queryFileName = 1;
      smallDisplay = newsongNUMBER + newdirSIZE;
      // debugSerial.println(smallDisplay);
      smallDisplay_len = smallDisplay.length() + 1;
    }
  }




  ///////////////////////////////////////////////////////////////

  if (queryFileName == 1)
  {
    do {
      nowPlaying = (bt.getFilename());

      inputText = nowPlaying;
      //inputText.trim();
      inputText.replace(".mp3", "  ");
      inputText_len = inputText.length() + 1;
    } while (! inputText.startsWith("MF+"));
    inputText.replace("MF+", "");
    acolumn = -1;
    bcolumn = 0;
    ccolumn = 1;
    dcolumn = 2;
    ecolumn = 3;
    fcolumn = 4;
    gcolumn = 5;
    hcolumn = 6;
    icolumn = 7;

    queryFileName = 0;
  }


  ///////////////////////////////////////////////////////////////////////////////////////////////////////

  displayRefresh = displayRefresh + 1;
  if (displayRefresh == 3) {
    displayRefresh = 0;
  }
  if (displayRefresh == 0) {
    char inputText_array[inputText_len];
    inputText.toCharArray(inputText_array, inputText_len);
    //Serial only for troubleshooting -I can remove it when it works.

    uint8_t ahr[numColumns];
    getColumns(inputText[acolumn], ahr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t bhr[numColumns];
    getColumns(inputText[bcolumn], bhr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t chr[numColumns];
    getColumns(inputText[ccolumn], chr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t dhr[numColumns];
    getColumns(inputText[dcolumn], dhr);  //This would store all 5 bytes (columns)of letter A in "xxx"

    uint8_t ehr[numColumns];
    getColumns(inputText[ecolumn], ehr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t fhr[numColumns];
    getColumns(inputText[fcolumn], fhr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t ghr[numColumns];
    getColumns(inputText[gcolumn], ghr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t hhr[numColumns];
    getColumns(inputText[hcolumn], hhr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    uint8_t ihr[numColumns];
    getColumns(inputText[icolumn], ihr);  //This would store all 5 bytes (columns)of letter A in "xxx"


    char smallDisplay_array[smallDisplay_len];
    smallDisplay.toCharArray(smallDisplay_array, smallDisplay_len);

    uint8_t smla[numColumns];
    getColumns(smallDisplay[0], smla);  //This would store all 5 bytes (columns)of letter A in "xxx"
    uint8_t smlb[numColumns];
    getColumns(smallDisplay[1], smlb);  //This would store all 5 bytes (columns)of letter A in "xxx"
    uint8_t smlc[numColumns];
    getColumns(smallDisplay[2], smlc);  //This would store all 5 bytes (columns)of letter A in "xxx"
    uint8_t smld[numColumns];
    getColumns(smallDisplay[3], smld);  //This would store all 5 bytes (columns)of letter A in "xxx"
    uint8_t smle[numColumns];
    getColumns(smallDisplay[4], smle);  //This would store all 5 bytes (columns)of letter A in "xxx"


    if (inputText_len > 10 && icolumn < inputText_len) {

      acolumn = (acolumn + 1);
      bcolumn = (bcolumn + 1);
      ccolumn = (ccolumn + 1);
      dcolumn = (dcolumn + 1);
      ecolumn = (ecolumn + 1);
      fcolumn = (fcolumn + 1);
      gcolumn = (gcolumn + 1);
      hcolumn = (hcolumn + 1);
      icolumn = (icolumn + 1);

    } else {
      acolumn = 0;
      bcolumn = 1;
      ccolumn = 2;
      dcolumn = 3;
      ecolumn = 4;
      fcolumn = 5;
      gcolumn = 6;
      hcolumn = 7;
      icolumn = 8;
    }

    //COMMANDS TO SET UP THE DISPLAY
    Wire.begin(); // join i2c bus
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x55);             // set_mode  -normal video, mixed mode, MUX 1:8
    Wire.endTransmission();     // stop transmitting

    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x3e); // RAM access
    Wire.endTransmission();     // stop transmitting

    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x7c); //set start bank 0
    Wire.endTransmission();     // stop transmitting

    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x62); //device select
    Wire.endTransmission();     // stop transmitting


    //WRITING TO DISPLAY STARTS HERE

    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x0F); //load x address

    Wire.write(bhr[3]);             // DATA column 10
    Wire.write(bhr[2]);             // DATA column 9
    Wire.write(bhr[1]);             // DATA column 8
    Wire.write(bhr[0]);             // DATA column 7
    Wire.write(0x00);             // DATA column 6
    Wire.write(ahr[4]);             // DATA column 5
    Wire.write(ahr[3]);             // DATA column 4
    Wire.write(ahr[2]);             // DATA column 3
    Wire.write(ahr[1]);             // DATA column 2
    Wire.write(ahr[0]);             // DATA column 1

    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x05); //load x address

    Wire.write(dhr[1]);             // DATA column 20
    Wire.write(dhr[0]);             // DATA column 19
    Wire.write(0x00);             // DATA column 18
    Wire.write(chr[4]);             // DATA column 17
    Wire.write(chr[3]);             // DATA column 16
    Wire.write(chr[2]);             // DATA column 15
    Wire.write(chr[1]);             // DATA column 14
    Wire.write(chr[0]);             // DATA column 13
    Wire.write(0x00);             // DATA column 12
    Wire.write(bhr[4]);             // DATA column 11

    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x00); //load x address

    Wire.write(0x00);             // DATA MISSING COLUMN -BLANK
    Wire.write(0x00);             // DATA column 24
    Wire.write(dhr[4]);             // DATA column 23
    Wire.write(dhr[3]);             // DATA column 22
    Wire.write(dhr[2]);             // DATA column 21

    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x61); //device select
    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x1f); //load x address

    Wire.write(fhr[3]);             // DATA column 34
    Wire.write(fhr[2]);             // DATA column 33
    Wire.write(fhr[1]);             // DATA column 32
    Wire.write(fhr[0]);             // DATA column 31
    Wire.write(0x00);             // DATA column 30
    Wire.write(ehr[4]);             // DATA column 39
    Wire.write(ehr[3]);             // DATA column 28
    Wire.write(ehr[2]);             // DATA column 27
    Wire.write(ehr[1]);             // DATA column 26
    Wire.write(ehr[0]);             // DATA column 25

    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x61); //device select
    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x14); //load x address

    Wire.write(hhr[2]);             // DATA column 45
    Wire.write(hhr[1]);             // DATA column 44
    Wire.write(hhr[0]);             // DATA column 43
    Wire.write(0x00);             // DATA column 42
    Wire.write(ghr[4]);             // DATA column 41
    Wire.write(ghr[3]);             // DATA column 40
    Wire.write(ghr[2]);             // DATA column 39
    Wire.write(ghr[1]);             // DATA column 38
    Wire.write(ghr[0]);             // DATA column 37
    Wire.write(0x00);             // DATA column 36
    Wire.write(fhr[4]);             // DATA column 35

    Wire.endTransmission();     // stop transmitting


    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x61); //device select
    Wire.endTransmission();     // stop transmitting



    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x0A); //load x address

    Wire.write(0x00);             // DATA column 55
    Wire.write(0x00);             // DATA column 54
    Wire.write(ihr[4]);             // DATA column 53
    Wire.write(ihr[3]);             // DATA column 52
    Wire.write(ihr[2]);             // DATA column 51
    Wire.write(ihr[1]);             // DATA column 50
    Wire.write(ihr[0]);             // DATA column 49
    Wire.write(0x00);             // DATA column 48
    Wire.write(hhr[4]);             // DATA column 47
    Wire.write(hhr[3]);             // DATA column 46

    Wire.endTransmission();     // stop transmitting



    //MALI DISPLAY -URA

    //ČETRTA
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x60); //device select
    Wire.endTransmission();     // stop transmitting
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x0A); //load x address

    Wire.write(0x00);
    Wire.write(smle[4]);             // DATA column 50
    Wire.write(smle[3]);             // DATA column 49
    Wire.write(smle[2]);             // DATA column 48
    Wire.write(smle[1]);             // DATA column 47
    Wire.write(smle[0]);             // DATA column 46


    Wire.endTransmission();     // stop transmitting

    //TRETJA
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x60); //device select
    Wire.endTransmission();     // stop transmitting
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x10); //load x address


    Wire.write(smld[4]);             // DATA column 50
    Wire.write(smld[3]);             // DATA column 49
    Wire.write(smld[2]);             // DATA column 48
    Wire.write(smld[1]);             // DATA column 47
    Wire.write(smld[0]);             // DATA column 50


    Wire.endTransmission();     // stop transmitting


    //DVOPIČJE ALI ČRTA
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x60); //device select
    Wire.endTransmission();     // stop transmitting
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x15); //load x address

    Wire.write(0x7F);             // 0x22 je dvopičje, 0x7F je črta

    Wire.endTransmission();     // stop transmitting

    //DRUGA
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x60); //device select
    Wire.endTransmission();     // stop transmitting
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x16); //load x address


    Wire.write(smlb[4]);             // DATA column 50
    Wire.write(smlb[3]);             // DATA column 49
    Wire.write(smlb[2]);             // DATA column 48
    Wire.write(smlb[1]);             // DATA column 47
    Wire.write(smlb[0]);             // DATA column 50


    Wire.endTransmission();     // stop transmitting

    //PRVA
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x60); //device select
    Wire.endTransmission();     // stop transmitting
    Wire.beginTransmission(0x3C); // transmit to device
    Wire.write(0x1c); //load x address


    Wire.write(smla[4]);             // DATA column 50
    Wire.write(smla[3]);             // DATA column 49
    Wire.write(smla[2]);             // DATA column 48
    Wire.write(smla[1]);             // DATA column 47
    Wire.write(smla[0]);             // DATA column 50


    Wire.endTransmission();     // stop

    //delay(200);


  }
  delay(100);
}
//I don`t get this part fully.
void getColumns(char c, uint8_t columns[numColumns]) {
  switch (c) {

    case 'A'...'Z':
      memcpy_P(&columns[0], &upperCase[c - 'A'][0], numColumns); //I think that this "A" changes depending if it`s case A or B or C ... something like if it`s "A" do that, if it`s "B" do that...
      break;

    case 'a'...'z':
      memcpy_P(&columns[0], &lowerCase[c - 'a'][0], numColumns);
      break;

    case '0'...'9':
      memcpy_P(&columns[0], &numerals[c - '0'][0], numColumns);
      break;

    case ' ':
      memcpy_P(&columns[0], &space[0], numColumns);
      break;

    case '!'...'/':
      memcpy_P(&columns[0], &symbolsa[c - '!'][0], numColumns);
      break;

    case '['...'`':
      memcpy_P(&columns[0], &symbolsb[c - '['][0], numColumns);
      break;

    case '{'...'~':
      memcpy_P(&columns[0], &symbolsc[c - '{'][0], numColumns);
      break;


    case '=':
      memcpy_P(&columns[0], &equalSymbol[0], numColumns);
      break;

    case '@':
      memcpy_P(&columns[0], &afnaSymbol[0], numColumns);
      break;



    default:
      memcpy_P(&columns[0], &unknown[0], numColumns);
      break;
  }

}

Also I`m using modified DFrobot bt401 library, I still need to add ibus read for steering wheel commands and few other things.

Comments that lie are worse than no comments at all

1 Like