A Bit of This, a Byte of That

From the narrative earlier you my have worked out we can no longer just write a value to a buffer and expect the digit we require to magically appear in a soft LED glow. No, the value of 0x5B we were using in our example must now be split across all 8 buffers (each buffer represents the same segment across all of the digits). I’ll use the value 2013 to demonstrate. In binary and hex the digits are represented as follows

value g f e d c b a hex
2 1 0 1 1 0 1 1 0x5B
0 0 1 1 1 1 1 1 0x3F
1 0 0 0 0 1 1 0 0x06
3 1 0 0 1 1 1 1 0x4F

Now we transform it to represent the data as it needs to be written to the buffers for common anode displays

a3 a2 a1 a0 hex
c0 1 0 1 1 0x0B
c1 1 1 1 1 0x0F
c2 1 1 1 0 0x0E
c3 1 0 1 1 0x0B
c4 0 0 1 1 0x03
c5 0 0 1 0 0x02
c6 1 0 0 1 0x09
c7 0 0 0 0 0x00

a0-a3 = digits 1-4 respectively

To achieve this I took the Adafruit_SevenSegment.py file and reworked it to my needs.  Firstly I added some bit flipping code from here https://wiki.python.org/moin/BitManipulation

  # setBit() returns an integer with the bit at 'offset' set to 1.
  def setBit(self, int_type, offset):
    mask = 1 << offset
    return(int_type | mask)

  # clearBit() returns an integer with the bit at 'offset' cleared.
  def clearBit(self, int_type, offset):
    mask = ~(1 << offset)
    return(int_type & mask) 

Added a function to control an individual segment

  def setSegState(self, anode, cathode, state):
    rowBuffer = self.disp.getBufferRow(cathode)
    if (state==False):
        rowBuffer = self.clearBit(rowBuffer, anode)
    else:
        rowBuffer = self.setBit(rowBuffer, anode)
    self.disp.setBufferRow(cathode, rowBuffer, True)

Then reworked the writeDigitRaw function to use them

  def writeDigitRaw(self, charNumber, value):
    "Sets a digit using the raw 16-bit value"
    if (charNumber > 15):
      return
    # Set the appropriate digit, pad to 8 binary digits
    valueBin = bin(int(value))[2:].rjust(8,'0')
    row = len(valueBin) - 1
    for digit in valueBin:
      self.setSegState(anode=charNumber,cathode=row,state=(digit=='1'))
      row-=1

I had now recreated the ability to reference a digit and provide a hex representation of the segments that needed to be shown.

Next…

Leave a Reply