mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
301 lines
5.5 KiB
C++
301 lines
5.5 KiB
C++
//
|
|
// FILE: HT16K33.cpp
|
|
// AUTHOR: Rob Tillaart
|
|
// VERSION: 0.1.4
|
|
// DATE: 2019-02-07
|
|
// PURPOSE: Class for HT16K33
|
|
//
|
|
// HISTORY:
|
|
// 0.1.0 - 2019-02-07 initial version
|
|
// 0.1.1 - 2019-02-07 first stable version
|
|
// 0.1.2 - 2019-02-11 optimized performance
|
|
// 0.1.3 - 2019-10-07 fixed clear, added suppressLeadingZeroPlaces();
|
|
// 0.1.4 - 2019-11-28 added displayRaw(), displayVULeft(), displayVURight()
|
|
//
|
|
// Released to the public domain
|
|
//
|
|
|
|
#include "HT16K33.h"
|
|
|
|
#define HT16K33_ON 0x21 // 0=off 1=on
|
|
#define HT16K33_STANDBY 0x20 // bit xxxxxxx0
|
|
|
|
#define HT16K33_DISPLAYON 0x81 // 0=off 1=on
|
|
#define HT16K33_DISPLAYOFF 0x80 // bit xxxxxxx0
|
|
|
|
#define HT16K33_BLINKON1HZ 0x85 // 00=off 01=2Hz 10=1Hz 11=0.5Hz
|
|
#define HT16K33_BLINKOFF 0x81 // bit xxxxx21x
|
|
|
|
#define HT16K33_BRIGHTNESS 0xE0 // mask to be ored with 0x00 - 0x0F
|
|
|
|
#define HT16K33_SPACE 16
|
|
#define HT16K33_NONE 17
|
|
|
|
// TODO PROGMEM ?
|
|
static const uint8_t charmap[] = {
|
|
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
|
|
0x00, // space
|
|
};
|
|
|
|
////////////////////////////////////////////////////
|
|
|
|
HT16K33::HT16K33()
|
|
{
|
|
}
|
|
|
|
void HT16K33::begin(const uint8_t address)
|
|
{
|
|
_addr = address;
|
|
displayOn();
|
|
displayClear();
|
|
suppressLeadingZeroPlaces(3);
|
|
for (uint8_t i = 0; i < 5; i++)
|
|
{
|
|
_displayCache[i] = HT16K33_NONE;
|
|
}
|
|
}
|
|
|
|
void HT16K33::displayOn()
|
|
{
|
|
writeCmd(HT16K33_ON);
|
|
writeCmd(HT16K33_DISPLAYON);
|
|
brightness(8);
|
|
}
|
|
|
|
void HT16K33::displayOff()
|
|
{
|
|
writeCmd(HT16K33_DISPLAYOFF);
|
|
writeCmd(HT16K33_STANDBY);
|
|
}
|
|
|
|
void HT16K33::blink(uint8_t val)
|
|
{
|
|
if (val > 0x03) val = 0x00;
|
|
writeCmd(HT16K33_BLINKOFF | (val << 1) );
|
|
}
|
|
|
|
void HT16K33::brightness(uint8_t val)
|
|
{
|
|
if (val > 0x0F) val = 0x0F;
|
|
writeCmd(HT16K33_BRIGHTNESS | val);
|
|
}
|
|
|
|
void HT16K33::suppressLeadingZeroPlaces(uint8_t val)
|
|
{
|
|
_leadingZeroPlaces = val > 4 ? 4 : val;
|
|
}
|
|
//////////////////////////////////////////
|
|
//
|
|
// display functions
|
|
//
|
|
void HT16K33::displayClear()
|
|
{
|
|
uint8_t x[4] = {HT16K33_SPACE, HT16K33_SPACE, HT16K33_SPACE, HT16K33_SPACE};
|
|
display(x);
|
|
displayColon(false);
|
|
}
|
|
|
|
// 0000..9999
|
|
// TODO negative numbers
|
|
// DIV10 & DIV100 optimize?
|
|
void HT16K33::displayInt(int n)
|
|
{
|
|
uint8_t x[4], h, l;
|
|
h = n / 100;
|
|
l = n - h * 100;
|
|
x[0] = h / 10;
|
|
x[1] = h - x[0] * 10;
|
|
x[2] = l / 10;
|
|
x[3] = l - x[2] * 10;
|
|
display(x);
|
|
}
|
|
|
|
// 0000..FFFF
|
|
void HT16K33::displayHex(uint16_t n)
|
|
{
|
|
uint8_t x[4], h, l;
|
|
h = n >> 8;
|
|
l = n & 0xFF;
|
|
x[3] = l & 0x0F;
|
|
x[2] = l >> 4;
|
|
x[1] = h & 0x0F;;
|
|
x[0] = h >> 4;
|
|
display(x);
|
|
}
|
|
|
|
// 00:00 .. 99:99
|
|
void HT16K33::displayTime(uint8_t left, uint8_t right)
|
|
{
|
|
uint8_t x[4];
|
|
x[0] = left / 10;
|
|
x[1] = left - x[0] * 10;
|
|
x[2] = right / 10;
|
|
x[3] = right - x[2] * 10;
|
|
display(x);
|
|
displayColon(false);
|
|
}
|
|
|
|
// only 0.000 .. 9999.
|
|
// TODO -999..-0.00
|
|
// TODO x.yEz
|
|
void HT16K33::displayFloat(float f)
|
|
{
|
|
int pt = 0;
|
|
// uint8_t neg = 0;
|
|
// if (f < 0) { neg = -1; f = -f; }
|
|
if (f > 9999 || f < 0 ) return;
|
|
int w = round(f);
|
|
if (w > 9) pt = 1;
|
|
if (w > 99) pt = 2;
|
|
if (w > 999) pt = 3;
|
|
if (f >= 1)
|
|
{
|
|
while (f < 1000) f *= 10;
|
|
w = round(f);
|
|
}
|
|
else
|
|
{
|
|
w = round(f * 1000);
|
|
}
|
|
|
|
uint8_t x[4], h, l;
|
|
h = w / 100;
|
|
l = w - h * 100;
|
|
x[0] = h / 10;
|
|
x[1] = h - x[0] * 10;
|
|
x[2] = l / 10;
|
|
x[3] = l - x[2] * 10;
|
|
display(x, pt);
|
|
}
|
|
|
|
void HT16K33::displayTest(uint8_t del)
|
|
{
|
|
for (int i = 0; i < 256; i++)
|
|
{
|
|
writePos(0, i);
|
|
writePos(1, i);
|
|
writePos(2, i);
|
|
writePos(3, i);
|
|
writePos(4, i);
|
|
delay(del);
|
|
}
|
|
}
|
|
|
|
void HT16K33::displayRaw(uint8_t *arr)
|
|
{
|
|
writePos(0, arr[0]);
|
|
writePos(1, arr[1]);
|
|
writePos(3, arr[2]);
|
|
writePos(4, arr[3]);
|
|
}
|
|
|
|
void HT16K33::displayVULeft(uint8_t val)
|
|
{
|
|
uint8_t ar[4];
|
|
for (int idx = 3; idx >=0; idx--)
|
|
{
|
|
if (val >= 2)
|
|
{
|
|
ar[idx] = 0x36; // ||
|
|
val -= 2;
|
|
}
|
|
else if (val == 1)
|
|
{
|
|
ar[idx] = 0x06; // _|
|
|
val = 0;
|
|
}
|
|
else ar[idx] = 0x00; // __
|
|
}
|
|
displayRaw(ar);
|
|
}
|
|
|
|
void HT16K33::displayVURight(uint8_t val)
|
|
{
|
|
uint8_t ar[4];
|
|
for (uint8_t idx = 0; idx < 4; idx++)
|
|
{
|
|
if (val >= 2)
|
|
{
|
|
ar[idx] = 0x36; // ||
|
|
val -= 2;
|
|
}
|
|
else if (val == 1)
|
|
{
|
|
ar[idx] = 0x30; // |_
|
|
val = 0;
|
|
}
|
|
else ar[idx] = 0x00; // __
|
|
}
|
|
displayRaw(ar);
|
|
}
|
|
|
|
void HT16K33::display(uint8_t *arr)
|
|
{
|
|
if (_leadingZeroPlaces)
|
|
{
|
|
for (uint8_t i = 0; i < _leadingZeroPlaces; i++)
|
|
{
|
|
if (arr[i] != 0) break;
|
|
arr[i] = HT16K33_SPACE;
|
|
}
|
|
}
|
|
writePos(0, charmap[arr[0]]);
|
|
writePos(1, charmap[arr[1]]);
|
|
writePos(3, charmap[arr[2]]);
|
|
writePos(4, charmap[arr[3]]);
|
|
}
|
|
|
|
void HT16K33::display(uint8_t *arr, uint8_t pnt)
|
|
{
|
|
writePos(0, charmap[arr[0]], pnt == 0);
|
|
writePos(1, charmap[arr[1]], pnt == 1);
|
|
writePos(3, charmap[arr[2]], pnt == 2);
|
|
writePos(4, charmap[arr[3]], pnt == 3);
|
|
}
|
|
|
|
void HT16K33::displayColon(uint8_t on)
|
|
{
|
|
writePos(2, on ? 2 : 0);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
void HT16K33::writeCmd(uint8_t cmd)
|
|
{
|
|
Wire.beginTransmission(_addr);
|
|
Wire.write(cmd);
|
|
Wire.endTransmission();
|
|
}
|
|
|
|
void HT16K33::writePos(uint8_t pos, uint8_t mask)
|
|
{
|
|
if (_displayCache[pos] == mask) return;
|
|
Wire.beginTransmission(_addr);
|
|
Wire.write(pos * 2);
|
|
Wire.write(mask);
|
|
Wire.endTransmission();
|
|
_displayCache[pos] = mask;
|
|
}
|
|
|
|
void HT16K33::writePos(uint8_t pos, uint8_t mask, bool pnt)
|
|
{
|
|
if (pnt) mask |= 0x80;
|
|
writePos(pos, mask);
|
|
}
|
|
|
|
// -- END OF FILE --
|