• Add a Display to Improve Your Code Skills by a Factor of 8192!

    Andy Geppert12/15/2023 at 13:55 0 comments

    If you are reading this, you are probably somewhat familiar with programming and maybe curious about adding a small display to your project. As I continue down the learning path, I have found that adding a small display to my projects is not just beneficial on the surface. It’s the next level up from adding a blinking LED as a heartbeat to your project code. The benefits can extend into the architecture and structure of the code I write. I'll share some of my journey now.

    By their nature, microcontrollers are a small black box. Unless you add connections to the outside world, you will have no idea whether the microcontroller is operating correctly. One of the first things you will discover is that adding an LED to an output line and toggling it ON and OFF at the end of your code loop helps you see that the code is executing and the microcontroller is alive. Here is an example in Arduino:

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    void loop() {
      // Your code does stuff here
      digitalWrite(LED_BUILTIN, HIGH);
      delay(100);
      digitalWrite(LED_BUILTIN, LOW);
    }

    However, if your code is simple and not doing much, it will execute VERY quickly and you may not see the LED blinking - it could appear to be on steadily. And if your code is doing a lot of stuff, that 100 millisecond delay is blocking the code from running for a significant amount of time. You might think your code has locked up. 

    So the next step is to control the blink rate with a timer. And since this LED is effectively supposed to indicate if the MCU is alive, a blink rate that looks like a heartbeat is an appropriate little challenge. Here’s what that could look like:

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    void loop() {
      // Your code does stuff here
      HeartBeat();
    }
    
    void HeartBeat() {
      static unsigned long HeartBeatSequence[] = {150,150,150,550}; // On, off, on, off 
      static unsigned HeartBeatSequencePosition = 0;
      static unsigned long NowTime = 0;
      static uint8_t LED_HEARTBEAT_STATE = 1;
      static unsigned long ledHeartBeatTimer = 0;
      NowTime = millis();
      if ((NowTime - ledHeartBeatTimer) >= HeartBeatSequence[HeartBeatSequencePosition])
      {
        LED_HEARTBEAT_STATE = !LED_HEARTBEAT_STATE;
        ledHeartBeatTimer = NowTime;
        HeartBeatSequencePosition++;
        if(HeartBeatSequencePosition>3) {HeartBeatSequencePosition = 0;}
      }
      digitalWrite(LED_BUILTIN, LED_HEARTBEAT_STATE); 
    }

    Now you have an intuitive indication of the MCU status, along with non-blocking and efficient code, all wrapped up in a useful little function. A win inside AND outside of the microcontroller!

    As helpful as a blinking LED is, a small display could be 8192 times more helpful. How? Well 64 pixels X 128 pixels = 8192 little tiny LEDs to control as you see fit! Yeah, an exaggeration, but you get the point.

    Now you can start to define modes or states of operation, and display a corresponding number and description. You can display the version of the firmware that is loaded, and the voltage of the system. And this is where I ended up with the core memory projects - adding clarity about the operational state and instructions with the display.

    Eventually I'll get the code refactored and suitable for instruction. Right now it's a "work in progress" but you can check it out if you'd like:

    https://github.com/ageppert/Core64/tree/master/Firmware-PlatformIO/Core64/src