HT16K33 backpack - cpp to spin

rogersydrogersyd Posts: 198
edited July 2014 in Propeller 1 Vote Up0Vote Down
Hi all.

I am working on a clock project and decided to leverage the adafruit HT16K33 backpack to drive the 4 digit 7 seg display.

http://www.adafruit.com/datasheets/ht16K33v110.pdf
http://www.adafruit.com/products/878

Here is a slightly modified version of the HT16K33 driver found in the OBX (Thanks to topher_cantrell for the object). This particular driver was written for a 8x8 bi-color version of the backpack, and the methods i need are excluded. I am struggling with converting the CPP code (also below) to write a 4 digit number to the backpack. I am communicating with the backpack ok, as demonstrated via the "dimming" repeat loop, but i just cant figure out who to send the data located in the buffer to the display. CPP may as well be greek to me, although i am getting better at deciphering it. Does anyone have any experience with the HT16K33 chip that could provide some guidance here? Thanks for any advice.
con
  led = 0

var   
  byte ADDR        ' Backpack I2C address
  byte PIN_SCL     ' I/O pin connected to SCL (SDA is very next pin)
  
  ' 8x8 bicolor specific
  byte raster[16]  ' Raster buffer for (x,y) graphics

OBJ
  i2c : "Basic_I2C_Driver_1"    

pub start|delaytime,br

   dira[led]:=1
   init($70,3)
   writeDisplay($0,16,@buffer)'(register,count,data)
   repeat
     outa[led]:=1
     repeat br from %0000 to %0011
      !outa[Led]                     ' toggle the pin state
      setBrightness(br)           ' Max brightness
      waitcnt(clkfreq/5 + cnt)                         ' wait
     repeat br from %0010 to %0001
      !outa[Led]                     ' toggle the pin state
      setBrightness(br)           ' Max brightness
      waitcnt(clkfreq/5 + cnt)

PUB init(i2cAddress,pinSCL)
'' Initialize the object with the given I2C-address and hardware pins.
'' The driver I am using requires SDA to be the next pin after SCL.
'   
  ADDR := i2cAddress
  PIN_SCL := pinSCL   

  i2c.Initialize(PIN_SCL)

  setOscillator(1)            ' Start the oscillator
  setBlink(1,0)               ' Power on, no blinking
  setBrightness(%0000)           ' Max brightness

PUB setOscillator(on) | address
'' Turn the oscillator on (or off)
'
'  0010_xxx_p
'
  address := ADDR << 1 ' # R/-W bit = 0 (write)
  on := on & 1
  on := on | $20
  
  i2c.Start(PIN_SCL)
  i2c.Write(PIN_SCL,address)
  i2c.Write(PIN_SCL,on)
  i2c.Stop(PIN_SCL)              

PUB setBlink(power,rate)  | address
'' Set the display power and blink rate
''   rate = 00 = Off
''          01 = 2Hz
''          10 = 1Hz
''          11 = 0.5Hz
'
'  1000_x_rr_p
'
  address := ADDR << 1 ' # R/-W bit = 0 (write)
  rate := rate & 3
  rate := rate << 1
  power := power & 1
  rate := rate | power
  rate := rate | $80
  
  i2c.Start(PIN_SCL)
  i2c.Write(PIN_SCL,address)
  i2c.Write(PIN_SCL,rate)
  i2c.Stop(PIN_SCL)    

PUB setBrightness(level) | address
'' Set the display brightness
'' level: 0000=minimum, 1111=maximum
'
'  1110_vvvv
'
  address := ADDR << 1 ' # R/-W bit = 0 (write)
  level := level & 15
  level := level | $E0
  
  i2c.Start(PIN_SCL)
  i2c.Write(PIN_SCL,address)
  i2c.Write(PIN_SCL,level)
  i2c.Stop(PIN_SCL)
pub writeDigitRaw(bitmask)

{writeDigitRaw(uint8_t d, uint8_t bitmask)
  if (d > 4) return;
  displaybuffer[d] = bitmask}

PUB writeDisplay(register,count,data) | address
'' Write a number of data values beginning with the
'' given register.

  address := ADDR << 1 ' # R/-W bit = 0 (write)
  i2c.Start(PIN_SCL)
  i2c.Write(PIN_SCL,address)
  i2c.Write(PIN_SCL,register)
    
  repeat while count>0
    i2c.Write(PIN_SCL,byte[data])
    data := data +1
    count := count -1
  
  i2c.Stop(PIN_SCL)

 { writeDisplay(void)
  Wire.beginTransmission(i2c_addr);
  Wire.write((uint8_t)0x00); // start at address $00

  for (uint8_t i=0; i<8; i++)
    Wire.write(displaybuffer[i] & 0xFF);
    Wire.write(displaybuffer[i] >> 8);

  Wire.endTransmission();
  }

'
' Specific to the adafruit 8x8 bicolor backpack.
' Leave them out or tweak them.
'

'' The 8x8 bicolor matrix is wired as follows:
''   register 0: Row 0/green (LSB is left pixel, MSB is right pixel)
''   register 1: Row 0/red (LSB is left pixel, MSB is right pixel)
''   register 2: Row 1/green (LSB is left pixel, MSB is right pixel)
''   etc
''
'' Turn both red and green on to make orange

PUB clearRaster | ix
  repeat ix from 0 to 15
    raster[ix] := 0
    
PUB drawRaster
  writeDisplay(0,16,@raster)


DAT
Buffer    byte "1234",0
one byte "1",0

CPP code from ADAFRUIT
/*************************************************** 
  This is a library for our I2C LED Backpacks

  Designed specifically to work with the Adafruit LED Matrix backpacks 
  ----> http://www.adafruit.com/products/
  ----> http://www.adafruit.com/products/

  These displays use I2C to communicate, 2 pins are required to 
  interface. There are multiple selectable I2C addresses. For backpacks
  with 2 Address Select pins: 0x70, 0x71, 0x72 or 0x73. For backpacks
  with 3 Address Select pins: 0x70 thru 0x77

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

#ifdef __AVR_ATtiny85__
 #include <TinyWireM.h>
 #define Wire TinyWireM
#else
 #include <Wire.h>
#endif
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

#ifndef _BV
  #define _BV(bit) (1<<(bit))
#endif

static const uint8_t numbertable[] = {
	0x3F, /* 0 */
	0x06, /* 1 */
	0x5B, /* 2 */
	0x4F, /* 3 */
	0x66, /* 4 */
	0x6D, /* 5 */
	0x7D, /* 6 */
	0x07, /* 7 */
	0x7F, /* 8 */
	0x6F, /* 9 */
	0x77, /* a */
	0x7C, /* b */
	0x39, /* C */
	0x5E, /* d */
	0x79, /* E */
	0x71, /* F */
};

static const uint16_t alphafonttable[] PROGMEM =  {

0b0000000000000001,
0b0000000000000010,
0b0000000000000100,
0b0000000000001000,
0b0000000000010000,
0b0000000000100000,
0b0000000001000000,
0b0000000010000000,
0b0000000100000000,
0b0000001000000000,
0b0000010000000000,
0b0000100000000000,
0b0001000000000000,
0b0010000000000000,
0b0100000000000000,
0b1000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0001001011001001,
0b0001010111000000,
0b0001001011111001,
0b0000000011100011,
0b0000010100110000,
0b0001001011001000,
0b0011101000000000,
0b0001011100000000,
0b0000000000000000, //  
0b0000000000000110, // !
0b0000001000100000, // "
0b0001001011001110, // #
0b0001001011101101, // $
0b0000110000100100, // %
0b0010001101011101, // &
0b0000010000000000, // '
0b0010010000000000, // (
0b0000100100000000, // )
0b0011111111000000, // *
0b0001001011000000, // +
0b0000100000000000, // ,
0b0000000011000000, // -
0b0000000000000000, // .
0b0000110000000000, // /
0b0000110000111111, // 0
0b0000000000000110, // 1
0b0000000011011011, // 2
0b0000000010001111, // 3
0b0000000011100110, // 4
0b0010000001101001, // 5
0b0000000011111101, // 6
0b0000000000000111, // 7
0b0000000011111111, // 8
0b0000000011101111, // 9
0b0001001000000000, // :
0b0000101000000000, // ;
0b0010010000000000, // <
0b0000000011001000, // =
0b0000100100000000, // >
0b0001000010000011, // ?
0b0000001010111011, // @
0b0000000011110111, // A
0b0001001010001111, // B
0b0000000000111001, // C
0b0001001000001111, // D
0b0000000011111001, // E
0b0000000001110001, // F
0b0000000010111101, // G
0b0000000011110110, // H
0b0001001000000000, // I
0b0000000000011110, // J
0b0010010001110000, // K
0b0000000000111000, // L
0b0000010100110110, // M
0b0010000100110110, // N
0b0000000000111111, // O
0b0000000011110011, // P
0b0010000000111111, // Q
0b0010000011110011, // R
0b0000000011101101, // S
0b0001001000000001, // T
0b0000000000111110, // U
0b0000110000110000, // V
0b0010100000110110, // W
0b0010110100000000, // X
0b0001010100000000, // Y
0b0000110000001001, // Z
0b0000000000111001, // [
0b0010000100000000, // 
0b0000000000001111, // ]
0b0000110000000011, // ^
0b0000000000001000, // _
0b0000000100000000, // `
0b0001000001011000, // a
0b0010000001111000, // b
0b0000000011011000, // c
0b0000100010001110, // d
0b0000100001011000, // e
0b0000000001110001, // f
0b0000010010001110, // g
0b0001000001110000, // h
0b0001000000000000, // i
0b0000000000001110, // j
0b0011011000000000, // k
0b0000000000110000, // l
0b0001000011010100, // m
0b0001000001010000, // n
0b0000000011011100, // o
0b0000000101110000, // p
0b0000010010000110, // q
0b0000000001010000, // r
0b0010000010001000, // s
0b0000000001111000, // t
0b0000000000011100, // u
0b0010000000000100, // v
0b0010100000010100, // w
0b0010100011000000, // x
0b0010000000001100, // y
0b0000100001001000, // z
0b0000100101001001, // {
0b0001001000000000, // |
0b0010010010001001, // }
0b0000010100100000, // ~
0b0011111111111111,

};
void Adafruit_LEDBackpack::setBrightness(uint8_t b) {
  if (b > 15) b = 15;
  Wire.beginTransmission(i2c_addr);
  Wire.write(HT16K33_CMD_BRIGHTNESS | b);
  Wire.endTransmission();  
}

void Adafruit_LEDBackpack::blinkRate(uint8_t b) {
  Wire.beginTransmission(i2c_addr);
  if (b > 3) b = 0; // turn off if not sure
  
  Wire.write(HT16K33_BLINK_CMD | HT16K33_BLINK_DISPLAYON | (b << 1)); 
  Wire.endTransmission();
}

Adafruit_LEDBackpack::Adafruit_LEDBackpack(void) {
}

void Adafruit_LEDBackpack::begin(uint8_t _addr = 0x70) {
  i2c_addr = _addr;

  Wire.begin();

  Wire.beginTransmission(i2c_addr);
  Wire.write(0x21);  // turn on oscillator
  Wire.endTransmission();
  blinkRate(HT16K33_BLINK_OFF);
  
  setBrightness(15); // max brightness
}

void Adafruit_LEDBackpack::writeDisplay(void) {
  Wire.beginTransmission(i2c_addr);
  Wire.write((uint8_t)0x00); // start at address $00

  for (uint8_t i=0; i<8; i++) {
    Wire.write(displaybuffer[i] & 0xFF);    
    Wire.write(displaybuffer[i] >> 8);    
  }
  Wire.endTransmission();  
}

void Adafruit_LEDBackpack::clear(void) {
  for (uint8_t i=0; i<8; i++) {
    displaybuffer[i] = 0;
  }
}

/******************************* QUAD ALPHANUM OBJECT */

Adafruit_AlphaNum4::Adafruit_AlphaNum4(void) {

}

void Adafruit_AlphaNum4::writeDigitRaw(uint8_t n, uint16_t bitmask) {
  displaybuffer[n] = bitmask;
}

void Adafruit_AlphaNum4::writeDigitAscii(uint8_t n, uint8_t a,  boolean d) {
  uint16_t font = pgm_read_word(alphafonttable+a);

  displaybuffer[n] = font;

  /*
  Serial.print(a, DEC);
  Serial.print(" / '"); Serial.write(a);
  Serial.print("' = 0x"); Serial.println(font, HEX);
  */

  if (d) displaybuffer[n] |= (1<<15);
}

/******************************* 24 BARGRAPH OBJECT */

Adafruit_24bargraph::Adafruit_24bargraph(void) {

}

void Adafruit_24bargraph::setBar(uint8_t bar, uint8_t color) {
  uint16_t a, c;
 
  if (bar < 12)
    c = bar / 4;
  else 
    c = (bar - 12) / 4;

  a = bar % 4;
  if (bar >= 12)
    a += 4;
    
  //Serial.print("Ano = "); Serial.print(a); Serial.print(" Cath = "); Serial.println(c);
  if (color == LED_RED) {
    // Turn on red LED.
    displaybuffer[c] |= _BV(a);
    // Turn off green LED.
    displaybuffer[c] &= ~_BV(a+8);
  } else if (color == LED_YELLOW) {
    // Turn on red and green LED.
    displaybuffer[c] |= _BV(a) | _BV(a+8);
  } else if (color == LED_OFF) {
    // Turn off red and green LED.
    displaybuffer[c] &= ~_BV(a) & ~_BV(a+8);
  } else if (color == LED_GREEN) {
    // Turn on green LED.
    displaybuffer[c] |= _BV(a+8);
    // Turn off red LED.
    displaybuffer[c] &= ~_BV(a);
  } 
}


/******************************* 8x8 MATRIX OBJECT */

Adafruit_8x8matrix::Adafruit_8x8matrix(void) : Adafruit_GFX(8, 8) {
}

void Adafruit_8x8matrix::drawPixel(int16_t x, int16_t y, uint16_t color) {
  if ((y < 0) || (y >= 8)) return;
  if ((x < 0) || (x >= 8)) return;

 // check rotation, move pixel around if necessary
  switch (getRotation()) {
  case 1:
    swap(x, y);
    x = 8 - x - 1;
    break;
  case 2:
    x = 8 - x - 1;
    y = 8 - y - 1;
    break;
  case 3:
    swap(x, y);
    y = 8 - y - 1;
    break;
  }

  // wrap around the x
  x += 7;
  x %= 8;


  if (color) {
    displaybuffer[y] |= 1 << x;
  } else {
    displaybuffer[y] &= ~(1 << x);
  }
}

/******************************* 8x8 BICOLOR MATRIX OBJECT */

Adafruit_BicolorMatrix::Adafruit_BicolorMatrix(void) : Adafruit_GFX(8, 8) {
}

void Adafruit_BicolorMatrix::drawPixel(int16_t x, int16_t y, uint16_t color) {
  if ((y < 0) || (y >= 8)) return;
  if ((x < 0) || (x >= 8)) return;

  switch (getRotation()) {
  case 1:
    swap(x, y);
    x = 8 - x - 1;
    break;
  case 2:
    x = 8 - x - 1;
    y = 8 - y - 1;
    break;
  case 3:
    swap(x, y);
    y = 8 - y - 1;
    break;
  }

  if (color == LED_GREEN) {
    // Turn on green LED.
    displaybuffer[y] |= 1 << x;
    // Turn off red LED.
    displaybuffer[y] &= ~(1 << (x+8));
  } else if (color == LED_RED) {
    // Turn on red LED.
    displaybuffer[y] |= 1 << (x+8);
    // Turn off green LED.
    displaybuffer[y] &= ~(1 << x);
  } else if (color == LED_YELLOW) {
    // Turn on green and red LED.
    displaybuffer[y] |= (1 << (x+8)) | (1 << x);
  } else if (color == LED_OFF) {
    // Turn off green and red LED.
    displaybuffer[y] &= ~(1 << x) & ~(1 << (x+8));
  }
}

/******************************* 7 SEGMENT OBJECT */

Adafruit_7segment::Adafruit_7segment(void) {
  position = 0;
}

void Adafruit_7segment::print(unsigned long n, int base)
{
  if (base == 0) write(n);
  else printNumber(n, base);
}

void Adafruit_7segment::print(char c, int base)
{
  print((long) c, base);
}

void Adafruit_7segment::print(unsigned char b, int base)
{
  print((unsigned long) b, base);
}

void Adafruit_7segment::print(int n, int base)
{
  print((long) n, base);
}

void Adafruit_7segment::print(unsigned int n, int base)
{
  print((unsigned long) n, base);
}

void  Adafruit_7segment::println(void) {
  position = 0;
}

void  Adafruit_7segment::println(char c, int base)
{
  print(c, base);
  println();
}

void  Adafruit_7segment::println(unsigned char b, int base)
{
  print(b, base);
  println();
}

void  Adafruit_7segment::println(int n, int base)
{
  print(n, base);
  println();
}

void  Adafruit_7segment::println(unsigned int n, int base)
{
  print(n, base);
  println();
}

void  Adafruit_7segment::println(long n, int base)
{
  print(n, base);
  println();
}

void  Adafruit_7segment::println(unsigned long n, int base)
{
  print(n, base);
  println();
}

void  Adafruit_7segment::println(double n, int digits)
{
  print(n, digits);
  println();
}

void  Adafruit_7segment::print(double n, int digits)
{
  printFloat(n, digits);
}


size_t Adafruit_7segment::write(uint8_t c) {

  uint8_t r = 0;

  if (c == '\n') position = 0;
  if (c == '\r') position = 0;

  if ((c >= '0') && (c <= '9')) {
    writeDigitNum(position, c-'0');
    r = 1;
  }

  position++;
  if (position == 2) position++;

  return r;
}

void Adafruit_7segment::writeDigitRaw(uint8_t d, uint8_t bitmask) {
  if (d > 4) return;
  displaybuffer[d] = bitmask;
}

void Adafruit_7segment::drawColon(boolean state) {
  if (state)
    displaybuffer[2] = 0x2;
  else
    displaybuffer[2] = 0;
}

void Adafruit_7segment::writeColon(void) {
    Wire.beginTransmission(i2c_addr);
    Wire.write((uint8_t)0x04); // start at address $02
    
    Wire.write(displaybuffer[2] & 0xFF);
    Wire.write(displaybuffer[2] >> 8);

    Wire.endTransmission();
}

void Adafruit_7segment::writeDigitNum(uint8_t d, uint8_t num, boolean dot) {
  if (d > 4) return;

  writeDigitRaw(d, numbertable[num] | (dot << 7));
}

void Adafruit_7segment::print(long n, int base)
{
  printNumber(n, base);
}

void Adafruit_7segment::printNumber(long n, uint8_t base)
{
    printFloat(n, 0, base);
}

void Adafruit_7segment::printFloat(double n, uint8_t fracDigits, uint8_t base) 
{ 
  uint8_t numericDigits = 4;   // available digits on display
  boolean isNegative = false;  // true if the number is negative
  
  // is the number negative?
  if(n < 0) {
    isNegative = true;  // need to draw sign later
    --numericDigits;    // the sign will take up one digit
    n *= -1;            // pretend the number is positive
  }
  
  // calculate the factor required to shift all fractional digits
  // into the integer part of the number
  double toIntFactor = 1.0;
  for(int i = 0; i < fracDigits; ++i) toIntFactor *= base;
  
  // create integer containing digits to display by applying
  // shifting factor and rounding adjustment
  uint32_t displayNumber = n * toIntFactor + 0.5;
  
  // calculate upper bound on displayNumber given
  // available digits on display
  uint32_t tooBig = 1;
  for(int i = 0; i < numericDigits; ++i) tooBig *= base;
  
  // if displayNumber is too large, try fewer fractional digits
  while(displayNumber >= tooBig) {
    --fracDigits;
    toIntFactor /= base;
    displayNumber = n * toIntFactor + 0.5;
  }
  
  // did toIntFactor shift the decimal off the display?
  if (toIntFactor < 1) {
    printError();
  } else {
    // otherwise, display the number
    int8_t displayPos = 4;
    
    if (displayNumber)  //if displayNumber is not 0
    {
      for(uint8_t i = 0; displayNumber || i <= fracDigits; ++i) {
        boolean displayDecimal = (fracDigits != 0 && i == fracDigits);
        writeDigitNum(displayPos--, displayNumber % base, displayDecimal);
        if(displayPos == 2) writeDigitRaw(displayPos--, 0x00);
        displayNumber /= base;
      }
    }
    else {
      writeDigitNum(displayPos--, 0, false);
    }
  
    // display negative sign if negative
    if(isNegative) writeDigitRaw(displayPos--, 0x40);
  
    // clear remaining display positions
    while(displayPos >= 0) writeDigitRaw(displayPos--, 0x00);
  }
}

void Adafruit_7segment::printError(void) {
  for(uint8_t i = 0; i < SEVENSEG_DIGITS; ++i) {
    writeDigitRaw(i, (i == 2 ? 0x00 : 0x40));
  }
}

Comments

  • 7 Comments sorted by Date Added Votes
  • rogersydrogersyd Posts: 198
    edited July 2014 Vote Up0Vote Down
    I have made some progress on this one... device is now "counting" ok...

    Here is the code if it helps anyone else using this device:
    con
      led = 1
    
    var   
      byte ADDR        ' Backpack I2C address
      byte PIN_SCL     ' I/O pin connected to SCL (SDA is very next pin)
      
      ' 8x8 bicolor specific
      byte raster[16]  ' Raster buffer for (x,y) graphics
    
    OBJ
      i2c : "Basic_I2C_Driver_1"    
    
    pub start|delaytime,br
    
       dira[led]:=1
       init($70,10)
       repeat 5
           waitcnt(clkfreq/50 + cnt)
           !outa[led]
       counting
    
    pub counting|w,x,y,z
    
        w:=x:=y:=z:=0
        writeDigit($08,numbers[0])
        writeDigit($06,numbers[0])
        writeDigit($02,numbers[0])
        writeDigit($00,numbers[0])
       repeat
        if z++ > 8
           z:=0
           if y++ > 8
              y:=0
              if x++ > 8
                 x:=0
                 if w++ > 8
                    w:=x:=y:=z:=0
    
        writeDigit($08,numbers[z])
        writeDigit($06,numbers[y])
        writeDigit($02,numbers[x])
        writeDigit($00,numbers[w])
        waitcnt(clkfreq/20 + cnt)
    pub dim|br
       repeat
         outa[led]:=1
         repeat br from %0000 to %0011
          !outa[Led]                     ' toggle the pin state
          setBrightness(br)           ' Max brightness
          waitcnt(clkfreq/5 + cnt)                         ' wait
         repeat br from %0010 to %0001
          !outa[Led]                     ' toggle the pin state
          setBrightness(br)           ' Max brightness
          waitcnt(clkfreq/5 + cnt)
    
    PUB init(i2cAddress,pinSCL)
    '' Initialize the object with the given I2C-address and hardware pins.
    '' The driver I am using requires SDA to be the next pin after SCL.
    '   
      ADDR := i2cAddress
      PIN_SCL := pinSCL   
    
      i2c.Initialize(PIN_SCL)
    
      setOscillator(1)            ' Start the oscillator
      setBlink(1,0)               ' Power on, no blinking
      setBrightness(%0000)           ' Max brightness
    
    PUB setOscillator(on) | address
    '' Turn the oscillator on (or off)
    '
    '  0010_xxx_p
    '
      address := ADDR << 1 ' # R/-W bit = 0 (write)
      on := on & 1
      on := on | $20
      
      i2c.Start(PIN_SCL)
      i2c.Write(PIN_SCL,address)
      i2c.Write(PIN_SCL,on)
      i2c.Stop(PIN_SCL)              
    
    PUB setBlink(power,rate)  | address
    '' Set the display power and blink rate
    ''   rate = 00 = Off
    ''          01 = 2Hz
    ''          10 = 1Hz
    ''          11 = 0.5Hz
    '
    '  1000_x_rr_p
    '
      address := ADDR << 1 ' # R/-W bit = 0 (write)
      rate := rate & 3
      rate := rate << 1
      power := power & 1
      rate := rate | power
      rate := rate | $80
      
      i2c.Start(PIN_SCL)
      i2c.Write(PIN_SCL,address)
      i2c.Write(PIN_SCL,rate)
      i2c.Stop(PIN_SCL)    
    
    PUB setBrightness(level) | address
    '' Set the display brightness
    '' level: 0000=minimum, 1111=maximum
    '
    '  1110_vvvv
    '
      address := ADDR << 1 ' # R/-W bit = 0 (write)
      level := level & 15
      level := level | $E0
      
      i2c.Start(PIN_SCL)
      i2c.Write(PIN_SCL,address)
      i2c.Write(PIN_SCL,level)
      i2c.Stop(PIN_SCL)
    
    
    
    pub writeDigit(register,data)|address
    
      address := ADDR << 1 ' # R/-W bit = 0 (write)
      i2c.Start(PIN_SCL)
      i2c.Write(PIN_SCL,address)
      i2c.Write(PIN_SCL,register)
      i2c.Write(PIN_SCL,data)
      'i2c.Write(PIN_SCL,(byte[data]& $FF))
      'i2c.Write(PIN_SCL,(byte[data] >> 8))
      i2c.Stop(PIN_SCL)
    
    {{
     void Adafruit_7segment::writeDigitNum(uint8_t d, uint8_t num, boolean dot)
      if (d > 4) return;
      writeDigitRaw(d, numbertable[num] | (dot << 7));
     void Adafruit_AlphaNum4::writeDigitRaw(uint8_t n, uint16_t bitmask)
      displaybuffer[n] = bitmask;
    }}
    
    
    PUB writeDisplay(register,count,data) | address
    '' Write a number of data values beginning with the
    '' given register.
    
      address := ADDR << 1 ' # R/-W bit = 0 (write)
      i2c.Start(PIN_SCL)
      i2c.Write(PIN_SCL,address)
      i2c.Write(PIN_SCL,register)
        
      repeat while count>0
        i2c.Write(PIN_SCL,(byte[data]& $FF))
        i2c.Write(PIN_SCL,(byte[data] >> 8))
        data++ ':= data +1
        count-- ' := count -1
      
      i2c.Stop(PIN_SCL)
    
     { writeDisplay(void)
      Wire.beginTransmission(i2c_addr);
      Wire.write((uint8_t)0x00); // start at address $00
    
      for (uint8_t i=0; i<8; i++)
        Wire.write(displaybuffer[i] & 0xFF);
        Wire.write(displaybuffer[i] >> 8);
    
      Wire.endTransmission();
      }
    
    '
    ' Specific to the adafruit 8x8 bicolor backpack.
    ' Leave them out or tweak them.
    '
    
    '' The 8x8 bicolor matrix is wired as follows:
    ''   register 0: Row 0/green (LSB is left pixel, MSB is right pixel)
    ''   register 1: Row 0/red (LSB is left pixel, MSB is right pixel)
    ''   register 2: Row 1/green (LSB is left pixel, MSB is right pixel)
    ''   etc
    ''
    '' Turn both red and green on to make orange
    
    PUB clearRaster | ix
      repeat ix from 0 to 15
        raster[ix] := 0
        
    PUB drawRaster
      writeDisplay(0,16,@raster)
    
    
    DAT
    textBuffer    byte 8,0'8 byte buffer but can be initial text.
    one           byte "1",0
    numbers       byte %0000110000111111, %0000000000000110, %0000000011011011, %0000000011001111, %0000000011100110, %0010000001101101, %0000000011111101, %0000000000000111, %0000000011111111, %0000000011101111
    
  • JonnyMacJonnyMac Posts: 5,870
    edited July 2014 Vote Up0Vote Down
    I've got one of those 7-segment displays on loan from a friend. This object is not complete, but pretty close and may be helpful.

    EDIT: Found a small error in the alpha_bits() method -- please use the updated object file.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • rogersydrogersyd Posts: 198
    edited July 2014 Vote Up0Vote Down
    JonnyMac wrote: »
    I've got one of those 7-segment displays on loan from a friend. This object is not complete, but pretty close and may be helpful.

    Helpful?!?!
    It would have taken me weeks to write and debug all those methods - and it would be a mess.
    I think just about every project I build uses one of your objects, and I learn a lot by studying them. So once again, THANK YOU sir for your fine contributions to the community!
  • JonnyMacJonnyMac Posts: 5,870
    edited July 2014 Vote Up0Vote Down
    I'm glad I could help. I found a small "gotcha" in the object code -- please download the fix (above).
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • Hey Jon,
    I've been trying to get my 7 segment display (HT16K33) working with your code but I think I'm misusing it somehow. I am calling it like this:
    PUB display
    
    disp.start(%000, 24, 25)   'clock (white) = 24,  data (red) = 25
    repeat
        disp.direct_write(0,1)
        disp.direct_write(1,1)
        disp.direct_write(2,1)
        disp.direct_write(3,1)
        disp.put_buf(0, number[0])
        disp.put_buf(1, number[1])
        disp.put_buf(2, number[2])
        disp.put_buf(3, number[3])
        disp.refresh(4) 
         
          waitcnt( duration + cnt)
    

    I haven't soldered any of the jumpers on the back and I assume that means %000 is correct although I tried "000" and other combinations of values with no luck. Everything looks wired up ok and it has 5VDC on the power input.
    Can you (or anyone else) tell what I'm doing wrong?

    Thanks,
    Brian
  • Ok, I've tried a few more things it looks like I was missing, but still no luck getting any LEDs to light up:
    PUB display  
    
    disp.start(%000, 24, 25)   'clock (white) = 24,  data (red) = 25
    disp.display_on(1)
    disp.set_display(1, 0)
    num:=disp.digit(5)
    repeat
        disp.direct_write(0,num)
        disp.direct_write(1,num)
        disp.direct_write(2,1)
        disp.direct_write(3,1)
        disp.put_buf(0, number[0])
        disp.put_buf(1, number[1])
        disp.put_buf(2, number[2])
        disp.put_buf(3, number[3])
        'disp.refresh(4) 
         
          waitcnt( duration + cnt)
    

    These calls are me just trying anything to get an LED on. It looks like "bits" in the write command were supposed to come from the maps given by the "digit" method. Also I turned the display on.... Still I have nothing showing up.
    Thanks,
    Brian
  • Hey Jon,
    I've been trying to get my 7 segment display (HT16K33) working with your code but I think I'm misusing it somehow. I am calling it like this:
    I've attached an I2C bus scanner and a demo program that uses the 4x7 and 4x14 modules from Adafruit. This should help you see those devices in practice.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
Sign In or Register to comment.