Skip to content

Added "width" parameter which sets number of characters in ht16k33 display module #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions components/ht16k33_alpha/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ display:
scroll_speed: 250ms
scroll_dwell: 2s
scroll_delay: 3
size: 4
lambda: |-
it.print("ABCD");
secondary_displays:
Expand All @@ -40,3 +41,5 @@ display:

`secondary_display:` is a list of i2c devices where `address:` is required and `i2c_id:` is optional unless there is more than one i2c bus.

`size:` number of characters in module, default is 4.

6 changes: 6 additions & 0 deletions components/ht16k33_alpha/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
CONF_SCROLL = "scroll"
CONF_SCROLL_SPEED = "scroll_speed"
CONF_SCROLL_DWELL = "scroll_dwell"
CONF_SWAP_BITS = "swap_bits"
CONF_SCROLL_DELAY = "scroll_delay"
CONF_SECONDARY_DISPLAYS = "secondary_displays"
CONF_SIZE = "size"

CONFIG_SECONDARY = cv.Schema({
cv.GenerateID(): cv.declare_id(i2c.I2CDevice)
Expand All @@ -23,10 +25,12 @@
cv.GenerateID(): cv.declare_id(HT16K33AlphaDisplay),
cv.Optional(CONF_CONTINUOUS, default=False): cv.boolean,
cv.Optional(CONF_SCROLL, default=False): cv.boolean,
cv.Optional(CONF_SWAP_BITS, default=False): cv.boolean,
cv.Optional(CONF_SCROLL_SPEED, default='250ms'): cv.positive_time_period_milliseconds,
cv.Optional(CONF_SCROLL_DWELL, default='2s'): cv.positive_time_period_milliseconds,
cv.Optional(CONF_SCROLL_DELAY, default='3'): cv.float_range(min=1),
cv.Optional(CONF_SECONDARY_DISPLAYS): cv.ensure_list(CONFIG_SECONDARY),
cv.Optional(CONF_SIZE, default=4): cv.int_range(min=1, max=8)
}).extend(cv.polling_component_schema('1s')).extend(i2c.i2c_device_schema(0x70))

async def to_code(config):
Expand All @@ -42,8 +46,10 @@ async def to_code(config):
if config[CONF_SCROLL]:
cg.add(var.set_scroll(True))
cg.add(var.set_continuous(config[CONF_CONTINUOUS]))
cg.add(var.set_swap_bits(config[CONF_SWAP_BITS]))
cg.add(var.set_scroll_speed(config[CONF_SCROLL_SPEED]))
cg.add(var.set_scroll_dwell(config[CONF_SCROLL_DWELL]))
cg.add(var.set_size(config[CONF_SIZE]))
cg.add(var.set_scroll_delay(int(config[CONF_SCROLL_DELAY] * config[CONF_SCROLL_SPEED].total_milliseconds)))
if CONF_SECONDARY_DISPLAYS in config:
for conf in config[CONF_SECONDARY_DISPLAYS]:
Expand Down
3 changes: 2 additions & 1 deletion components/ht16k33_alpha/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ static const uint16_t alphafonttable[] PROGMEM = {
0b0000000011011011, // 2
0b0000000010001111, // 3
0b0000000011100110, // 4
0b0010000001101001, // 5
// 0b0010000001101001, // 5
0b0000000011101101, // 5 fix
0b0000000011111101, // 6
0b0000000000000111, // 7
0b0000000011111111, // 8
Expand Down
29 changes: 26 additions & 3 deletions components/ht16k33_alpha/ht16k33_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ void HT16K33AlphaDisplay::setup() {

void HT16K33AlphaDisplay::loop() {
unsigned long now = millis();
int numc = this->displays_.size() * 8;
int numc = this->displays_.size() * this->size_ * 2;
int len = this->buffer_.size();
if (!this->scroll_ || (len <= numc))
return;
Expand All @@ -53,7 +53,7 @@ void HT16K33AlphaDisplay::loop() {
float HT16K33AlphaDisplay::get_setup_priority() const { return setup_priority::PROCESSOR; }

void HT16K33AlphaDisplay::display_() {
int numc = this->displays_.size() * 8;
int numc = this->displays_.size() * this->size_ * 2;
int len = this->buffer_.size();
uint8_t data[numc];
memset(data, 0, numc);
Expand All @@ -68,7 +68,7 @@ void HT16K33AlphaDisplay::display_() {
}
pos = 0;
for (auto *display : this->displays_) {
display->write_bytes(DISPLAY_COMMAND_SET_DDRAM_ADDR, data + pos, 8);
display->write_bytes(DISPLAY_COMMAND_SET_DDRAM_ADDR, data + pos, this->size_ * 2);
pos += 8;
}
}
Expand Down Expand Up @@ -107,6 +107,26 @@ float HT16K33AlphaDisplay::get_brightness() {
return this->brightness_ / 16.0;
}

uint16_t HT16K33AlphaDisplay::swapBits(uint16_t n, uint p1, uint p2) {
// Extract the bit at position p1
unsigned int bit1 = (n >> p1) & 1;

// Extract the bit at position p2
unsigned int bit2 = (n >> p2) & 1;

// If the bits are different, perform the swap
if (bit1 != bit2) {
// Create a mask to toggle the bits at p1 and p2
// If bit1 is 0 and bit2 is 1, set bit at p1 and clear bit at p2
// If bit1 is 1 and bit2 is 0, clear bit at p1 and set bit at p2
unsigned int xor_mask = (1U << p1) | (1U << p2);

// XOR the number with the mask to swap the bits
n ^= xor_mask;
}
return n;
}

void HT16K33AlphaDisplay::print(const char *str) {
uint16_t fontc = 0;
while (*str != '\0') {
Expand All @@ -120,6 +140,9 @@ void HT16K33AlphaDisplay::print(const char *str) {
fontc |= 0x4000;
str++;
}
if(this->swap_bits_) {
fontc = this->swapBits(fontc, 11, 13);
}
this->buffer_.push_back(fontc & 0xff);
this->buffer_.push_back(fontc >> 8);
}
Expand Down
5 changes: 5 additions & 0 deletions components/ht16k33_alpha/ht16k33_display.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ class HT16K33AlphaDisplay : public PollingComponent, public i2c::I2CDevice {
float get_setup_priority() const override;
void add_secondary_display(i2c::I2CDevice *display) { this->displays_.push_back(display); }
void set_scroll(bool scroll) { this->scroll_ = scroll; }
void set_swap_bits(bool swap_bits) { this->swap_bits_ = swap_bits; }
void set_continuous(bool continuous) { this->continuous_ = continuous; }
void set_scroll_speed(unsigned long scroll_speed) { this->scroll_speed_ = scroll_speed; }
void set_scroll_dwell(unsigned long scroll_dwell) { this->scroll_dwell_ = scroll_dwell; }
void set_scroll_delay(unsigned long scroll_delay) { this->scroll_delay_ = scroll_delay; }
void set_size(unsigned long size) { this->size_ = size; }
void update() override;
//// Clear display
void set_brightness(float level);
Expand All @@ -45,15 +47,18 @@ class HT16K33AlphaDisplay : public PollingComponent, public i2c::I2CDevice {
void command_(uint8_t value);
void call_writer() { this->writer_(*this); }
void display_();
uint16_t swapBits(uint16_t n, uint p1, uint p2);

std::vector<i2c::I2CDevice *> displays_ {this};
std::function<void(HT16K33AlphaDisplay &)> writer_;
bool scroll_ {false};
bool continuous_ {false};
bool swap_bits_ {false};
unsigned long scroll_speed_ {250};
unsigned long scroll_dwell_ {2000};
unsigned long scroll_delay_ {750};
unsigned long last_scroll_ {0};
unsigned long size_ {4};
std::vector<uint8_t> buffer_;
int offset_ {0};
uint8_t brightness_ = 16;
Expand Down