I can't test with that specific hardware.
But this is something I copy/pasted and it gives "somehow" output on my display
The idea is following:
the font from the libray is just used to get the needed segments.
based on your anode variables we split into two 16bit bitmaps. and activate the bitmaps for the two cathodes per digit.
so the change is a custom class with a very specific write function.
/*******************************************************************************
Prototype for LTC-637D1P display with custom wiring to a HT16K33
Noiasca HT16K33
by noiasca
Sketch Version 2023-02-10
On startup you should see some text on your display
In the loop all printable Characters will be shown.
*******************************************************************************/
#include <NoiascaHt16k33.h> // include the noiasca HT16K33 library - download from http://werner.rothschopf.net/
//Noiasca_ht16k33_hw_14 display = Noiasca_ht16k33_hw_14(); // object for 14 segments - 8 digits
//create your own class from the library internal abstract class
class Custom_ht16k33 : public Noiasca_ht16k33 {
protected:
uint8_t _lastBitmap; // last written bitmap (if we have to reprint for the decimal point)
public:
// custom write method for 7 segment
size_t write(uint8_t value) {
// define segments
//const uint16_t bitmask_0_DP = 1 << 15; // Doppelpunkt
//const uint16_t bitmask_1_AL = 1 << 15; // Punkt rechts unten
//const uint16_t bitmask_0_pm = 1 << 14; // Punkt links oben
//const uint16_t bitmask_1_am = 1 << 14; // Punkt links unten
// const uint16_t bitmask_0_ = 1 << 13; // noch frei
const uint16_t bitmask_1_1b = 1 << 13;
const uint16_t bitmask_0_1a = 1 << 12;
const uint16_t bitmask_1_1g = 1 << 12;
const uint16_t bitmask_0_1d = 1 << 11;
const uint16_t bitmask_1_1e = 1 << 11;
const uint16_t bitmask_0_2e = 1 << 10;
const uint16_t bitmask_1_1c = 1 << 10;
const uint16_t bitmask_0_2d = 1 << 9;
const uint16_t bitmask_1_2c = 1 << 9;
const uint16_t bitmask_0_2f = 1 << 8;
const uint16_t bitmask_1_2a = 1 << 8;
const uint16_t bitmask_0_2g = 1 << 7;
const uint16_t bitmask_1_2b = 1 << 7;
const uint16_t bitmask_0_3a = 1 << 6;
const uint16_t bitmask_1_3f = 1 << 6;
const uint16_t bitmask_0_3b = 1 << 5;
const uint16_t bitmask_1_3g = 1 << 5;
const uint16_t bitmask_0_3c = 1 << 4;
const uint16_t bitmask_1_3d = 1 << 4;
const uint16_t bitmask_0_4e = 1 << 3;
const uint16_t bitmask_1_3e = 1 << 3;
const uint16_t bitmask_0_4g = 1 << 2;
const uint16_t bitmask_1_4b = 1 << 2;
const uint16_t bitmask_0_4d = 1 << 1;
const uint16_t bitmask_1_4c = 1 << 1;
const uint16_t bitmask_0_4f = 1 << 0;
const uint16_t bitmask_1_4a = 1 << 0;
// no separate dot handling - deleted
if (value > 31 && value < 128) // write printable ASCII characters to display
{
uint8_t cathodeA = 0; // the real segments are distributed to two cathodes
uint8_t cathodeB = 0;
uint16_t bitmapA = 0; // each cathode drives it's own bitmap with segments
uint16_t bitmapB = 0;
// now read the logical segments from the internal font as 8bit byte,
uint8_t segments = pgm_read_byte_near(charTable + value - 32); // the table starts with the first printable character at 32
// now distribute the 8bit segment to two 16bit segments
for (int i = 0; i < 8; i++)
{
uint8_t segment = segments & (1 << i); // the actual segment
// MISSING: ... byte 0 mit BV=1 muss auf segment a finden
switch (_currentPosition) {
case 0:
switch (segment) {
case _BV(0): bitmapB |= bitmask_0_1a; break; // "S1a", // should be S0a as we start counting with 0 in c++
case _BV(1): bitmapB |= bitmask_1_1b; break; // "S1b",
case _BV(2): bitmapB |= bitmask_1_1c; break; // "S1c",
case _BV(3): break; // ???
case _BV(4): bitmapB |= bitmask_1_1e; break; // "S1e", // ???
case _BV(5): bitmapA |= bitmask_0_1d; break; // "S1f", // ???
case _BV(6): bitmapB |= bitmask_1_1g; break; // "S1g",
}
break;
case 1:
switch (segment) {
case _BV(0): bitmapB |= bitmask_1_2a; break; // "S2a",
case _BV(1): bitmapB |= bitmask_1_2b; break; // "S2b",
case _BV(2): bitmapB |= bitmask_1_2c; break; // "S2c",
case _BV(3): bitmapA |= bitmask_0_2d; break; // "S2d",
case _BV(4): bitmapA |= bitmask_0_2e; break; // "S2e",
case _BV(5): bitmapA |= bitmask_0_2f; break; // "S2f",
case _BV(6): bitmapA |= bitmask_0_2g; break; // "S2g",
}
break;
case 2:
switch (segment) {
case _BV(0): bitmapA |= bitmask_0_3a; break; // "S3a",
case _BV(1): bitmapA |= bitmask_0_3b; break; // "S3b",
case _BV(2): bitmapA |= bitmask_0_3c; break; // "S3c",
case _BV(3): bitmapB |= bitmask_1_3d; break; // "S3d",
case _BV(4): bitmapB |= bitmask_1_3e; break; // "S3e",
case _BV(5): bitmapB |= bitmask_1_3f; break; // "S3f",
case _BV(6): bitmapB |= bitmask_1_3g; break; // "S3g",
}
break;
case 3:
switch (segment) {
case _BV(0): bitmapB |= bitmask_1_4a; break; // "S4a",
case _BV(1): bitmapB |= bitmask_1_4b; break; // "S4b",
case _BV(2): bitmapB |= bitmask_1_4c; break; // "S4c",
case _BV(3): bitmapA |= bitmask_0_4d; break; // "S4d",
case _BV(4): bitmapA |= bitmask_0_4e; break; // "S4e",
case _BV(5): bitmapA |= bitmask_0_4f; break; // "S4f",
case _BV(6): bitmapA |= bitmask_0_4g; break; // "S4g",
}
break;
}
}
// get the two cathodes for each position
switch (_currentPosition) {
case 0: cathodeA = 0; cathodeB = 1; break;
case 1: cathodeA = 2; cathodeB = 3; break;
case 2: cathodeA = 4; cathodeB = 5; break;
case 3: cathodeA = 6; cathodeB = 7; break;
}
//finally output to display:
writeLowLevel(cathodeA, bitmapA);
writeLowLevel(cathodeB, bitmapB);
_lastPosition = _currentPosition; // tbc: not needed as we do not have a dot/comma handling in this write
_currentPosition++;
if (_currentPosition >= _numDigits * _numDevices) _currentPosition = 0;
// MISSING: handling of two _lastBitmap to care about the state of the 4 dots
}
return 1; // assume sucess
}
};
Custom_ht16k33 display;
const uint8_t i2cAddress = 0x76; // the I2C address of the first module (from 0x70 to 0x77)
const uint8_t numOfDevices = 2; // how many modules have you installed on the I2C Bus
const uint16_t wait = 1000; // wait milliseconds between demo
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println(F("\nstrandtest 14 segment "));
Wire.begin(); // start the I2C interface
display.begin(i2cAddress, numOfDevices); // I2C adress of first display, total number of devices
Serial.println(F("ON Test"));
display.clear(); // clear display
display.print(F("ALFABETADELT")); // if the text is to long or your display (chain) you will only see the last letters
delay(1000);
}
void test1() {
display.clear(); // weil vorher etwas mit "print" geschrieben wurde --> löscht
display.writeLowLevel(0, 0xFFFF);
display.writeLowLevel(2, 0xFFFF);
display.writeLowLevel(4, 0xFFFF);
display.writeLowLevel(6, 0xFFFF);
delay(wait);
display.clear(); // löscht 100%ig die mit "writeLowLevel" geschriebenen Sachen
display.writeLowLevel(1, 0xFFFF);
display.writeLowLevel(3, 0xFFFF);
display.writeLowLevel(5, 0xFFFF);
display.writeLowLevel(7, 0xFFFF);
delay(wait);
display.writeLowLevel(1, 0); // löscht klarerweise auch
display.writeLowLevel(3, 0);
display.writeLowLevel(5, 0);
display.writeLowLevel(7, 0);
}
void test() {
// put your main code here, to run repeatedly:
Serial.println(F("Printable characters"));
for (uint8_t counter = 32; counter < 128; counter++) {
display.clear();
display.print(counter); // print the numerical ANSI code of the character
display.write(counter); // print the character for the ANSI code
delay(wait);
}
}
void loop() {
test();
}
I assume a lot to adopt/debug for your ^^
the four dots will need some work, but first, the digits should show correct characters...