displaying on SSD1306, 128x64 pixels OLED

Dependencies:   microbit

Display.cpp

Committer:
bvirk
Date:
2020-02-25
Revision:
10:8bf77efd1579
Parent:
9:d15f84b277f3
Child:
12:b4d5e007640e

File content as of revision 10:8bf77efd1579:

#include "MicroBit.h"
#include "Display.h"

/**
  * When constructed from MicroBit's  MicroBitDisplay of a not yet initialized 
  * MicroBit object - that must be done before using the Display instance.
  *
  * @param uDpl is e.g. MicroBit's  MicroBitDisplay
  */
Display::Display(MicroBitDisplay & uDpl) : uDisplay(uDpl)  {
    clearStick();
    }

/**
  * Clears the display and its buffer 
  */
void Display::clear() {
    uDisplay.image.clear();
    clearStick();
    }

/**
  * The stick's length is represented by the count of digits being 1.
  * @param size in range [0,24]
  */
void Display::setStick(uint8_t length) {
     curLength = length;
     paintStick(&Display::lessCurLength);
     }   

/**
  * Set a single dot
  *
  * @param position in [0,24] for showing that single dot.
  */
void Display::setFlag(uint8_t position) {
    showbit = position;
    paintStick(&Display::orPoint);
    }

/**
  * Puts a bitpattern in a row
  *
  * @param rowNr in [0,4] for selected row
  * @param rowContent in [0,31] to be shown binary
  */
void Display::toRow(uint8_t rowNr, uint8_t rowContent) {
    this->rowNr=rowNr;
    showbit=rowContent;
    paintStick(&Display::bitplot);
    }

/**
  * 25 bits showed in the display as a whole.
  *
  * @param bits25 contains the 25 bit to be showed
  */
void Display::toRows(uint32_t bits25) {    
    showbit=bits25;
    paintStick(&Display::simplePlot);
    }

/**
  * Vertdecimal is intended for showing a single number in [00000,99999],
  * vertical read from top to bottom.
  *
  * @param r0 bottom row - row 0 
  * @param r1 row 1
  * @param r2 row 2
  * @param r3 row 3 
  * @param r4 top row - row 4
  */
void Display::vertDecimal(uint8_t r0,uint8_t r1,uint8_t r2,uint8_t r3,uint8_t r4) {
    vertDecimal(r0,r1,r2,r3,r4,false);
    }

/**
  * Vertdecimal is intended for showing a single number in [00000,99999],
  * vertical read from top to bottom.
  * 
  * @param r0 bottom row - row 0 
  * @param r1 row 1
  * @param r2 row 2
  * @param r3 row 3 
  * @param r4 top row - row 4
  * @param leftDotOn turns left dot on. leftdot is not used to represent a digit in base 10 numbers.
  */
void Display::vertDecimal(uint8_t r0,uint8_t r1,uint8_t r2,uint8_t r3,uint8_t r4, bool b15On) {
    Ledrows lr(r0,r1,r2,r3,r4,b15On);
    showbit = lr.all;
    paintStick(&Display::simplePlot);
    }

/**
  * Binary Clock, hours in top rows (4 for multiplum of 10, 3 for remainer)
  * minuts in bottom rows (1 for multiplum of 10, 0 for remainer)
  *
  * @param minuts of the day
  */
void Display::vertClock(uint16_t minuts) {
    uint8_t hours = minuts/60;
    minuts -= 60*hours;
    uint8_t h1 = hours/10;
    uint8_t m1 = minuts/10;
    vertDecimal(minuts-10*m1,m1,16,hours-10*h1,h1,false);
}
    
/**
  * Binary Clock, hours in row 4 (top row)
  * minuts in rows 3 and 2  (3 for multiplum of 10, 2 for remainer)
  * seconds in rows 1 and 0 (1 for multiplum of 10, 0 for remainer) 
  *
  * @param second of the day
  */
void Display::vertSecClock(uint32_t seconds) {
    uint8_t hours = seconds/3600;
    uint8_t minuts = (seconds - 3600*hours)/60;
    seconds -= 3600*hours+60*minuts;
    uint8_t m1 = minuts/10;
    int8_t s1 = seconds/10;
    vertDecimal(seconds-10*s1,s1,minuts-10*m1,m1,hours,false);
}
    
// private function 

void Display::paintStick(bool(Display::*getState)(uint8_t)) {
    for (int8_t pos = 0; pos < 25; pos++) {
        bool value = (this->*getState)(pos);
        if (stick[pos] != value) {
            stick[pos] = value;
            uDisplay.image.setPixelValue(
                4 - pos % 5,4 - pos / 5,value ? 1 : 0);
        }
    }
}

void Display::clearStick() {
    for (uint8_t i = 0 ; i < 25; i++)
    stick[i]=false; 
}

bool Display::orPoint(uint8_t stickPos) {    
    return showbit == stickPos ? 1 : stick[stickPos];
    }

bool Display::simplePlot(uint8_t stickPos) {
    return ((1 << stickPos) & showbit) > 0 ? true : false;
    }

bool Display::bitplot(uint8_t stickPos) {
    return stickPos < 5*(rowNr+1) && stickPos >= 5*rowNr  
        ? (((1 << (stickPos-5*rowNr)) & showbit) > 0
            ? true
            : false)
        : stick[stickPos];
    }

bool Display::lessCurLength(uint8_t num) {
    return num < curLength;
    }