• I'm not sure if column has to be open drain, because it is connecting to the anodes. Matter of fact you do not need to set any pin modes, because Espruino does automatic modes, and all are outputs.

    To figure out arrangements of bits in buffer, I create a 5(cols) x 7(rows) x 1(color) Graphics object and put a buffer over it which takes 8 bytes with last 5 bits unused. The drawings are rectangles of height 1, width 1, 2, 3 and 5 in rows 0 and 1. For each drawings the buffer is printed in the log.

    var g = Graphics.createArrayBuffer(5,7,1,{vertic­al_byte:false});
    var b = new Uint8Array(g.buffer);
        
    function onInit() {
      g.clear(); g.drawRect(0,0,0,0); // top row 1 dot (1st)
      console.log(b);
      g.clear(); g.drawRect(0,0,1,0); // top row 2 dots (1st and 2nd)
      console.log(b);
      g.clear(); g.drawRect(0,0,2,0); // top row 3 dots (1st, 2nd and 3rd)
      console.log(b);
      g.clear(); g.drawRect(0,0,4,0); // top row 5 dots (all)
      console.log(b);
      g.clear(); g.drawRect(0,1,0,1); // 2nd row 1 dot
      console.log(b);
      g.clear(); g.drawRect(0,1,1,1); // 2nd row 2 dots
      console.log(b);
      g.clear(); g.drawRect(0,1,2,1); // 2nd row 3 dots
      console.log(b);
      g.clear(); g.drawRect(0,1,4,1); // 2nd row 5 dots
      console.log(b);
    }
    
    setTimeout(onInit,1000);
    

    Log output - with some formatting - is as expected:

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v00 (c) 2018 G.Williams
    >
    new Uint8Array([  1, 0, 0, 0, 0])
    new Uint8Array([  3, 0, 0, 0, 0])
    new Uint8Array([  7, 0, 0, 0, 0])
    new Uint8Array([ 31, 0, 0, 0, 0])
    new Uint8Array([ 32, 0, 0, 0, 0])
    new Uint8Array([ 96, 0, 0, 0, 0])
    new Uint8Array([224, 0, 0, 0, 0])
    new Uint8Array([224, 3, 0, 0, 0])
    > 
    

    We see that the 1st row - row 0 - uses the first five (5) LSB bits in first byte - byte 0. We also see that 2nd row - row 1 - straddles the first and second byte - byte 0 and 1 - with first three (3) bits in byte 0 and the remaining two (2) bits in byte 1.

    With this bit arrangement in the buffer it is difficult to write an algorithm that puts out the bits nicely... yes, we can do some 'streaming' to make sure we always - 7 times - have 5 bits per row to put out - with a lot of pushing and shoving around bits (shift, mask, shift, etc...).

    The Graphics class though allows us a vertical vs the horizontal bit arrangement... and we do not even really loose space: still 5 bytes, one for each column. Since we care about only one text row, it becomes very simple...

    The Graphics declaration is 8 bits per column (multiple of 8 in height):

    var g = Graphics.createArrayBuffer(5,8,1,{vertic­al_byte:true});
    

    And the respective console output is:

             |_| espruino.com
     2v00 (c) 2018 G.Williams
    >
    new Uint8Array([1, 0, 0, 0, 0])
    new Uint8Array([1, 1, 0, 0, 0])
    new Uint8Array([1, 1, 1, 0, 0])
    new Uint8Array([1, 1, 1, 1, 1])
    new Uint8Array([2, 0, 0, 0, 0])
    new Uint8Array([2, 2, 0, 0, 0])
    new Uint8Array([2, 2, 2, 0, 0])
    new Uint8Array([2, 2, 2, 2, 2])
    > 
    

    The buffer bytes are just perfect to be pushed out column by column...

    A separate algorithm just pushes the buffer out with a refresh rate defined by an interval. After all columns are put out, column selector has to be disabled to have not the last one be lit for the whole time between the refresh interval.

    I have a very simple 5x7 (actually only 5x3) RED LED matrix with row anodes and column cathodes from end 70's/early 80's that I used to demo and explain CharliePlexing... and I will use it again here - in the next post. LEDs were still a cost factor - at least for a student budget - dim lit, and some colors were not even on the market yet... ;-) see History of LED.

About

Avatar for allObjects @allObjects started