Thanks for the quick response. I didn't supply any more details becauses the problem is unique to the 8566 chip itself. I was hoping to find someone who has had experience with it.
I don't find much at all on Google except for the chip's spec sheet, and one simple Arduino sketch for testing it. The test sketch just writes to each segment of the digits with loops. But it does not address the extra bit for each digit that I need to write to.
I would be glad to supply all kinds of detail. A link to the specs/app notes for the PCF8566 and my C++ class that works well except for this one problem.
Referring to Fig. 11 in the Specs, they show what happens to a given digit byte that is sent to the chip. My chip is being used in the 1:3 mode, so notice that a byte is broken up into 3 bit pieces and stored into successive memory locations in the chip, The hardware mapping on my the board I am using maps the DP bit to a down arrow symbol under the digit. The spec shows that the second MSB is DP, but in my hardware, that is mapped to that down arrow. As seen in the stock photo below of the original receiver. Notice that in Fig. 11, the third bit in the location n+2 is "x" which means "don't care". Since those three locations come from a given byte that is sent, that x position is the 9th bit.
My question is, how do I send the 9th bit properly without messing up the other bits in the PCF8655 memory. In the code below, my method setDecimalPointRaw() is my attempt at doing it. It doesn't work.

And here is my code. Except for the decimal point, this code works fine for displaying a string on the 8 digit 7 segment display. With this and other code, I can simulate the original operation of the front panel, except for the DP.
From my .h file, here is the mapping for the existing hardware:
/* Display Ram
-----------------
| n | n+1 | n+2 |
|----------------
BP 0 | f | a | b |
1 | e | g | c |
2 | ^ | d | dp |
3 | x | x | x |
-----------------
Transmit MSB LSB
fe^agdbc
*/
/* LED segments
aaa
f b
f b
ggg
e c
e c
ddd dp
v
v v
v v
*/
#include <Wire.h>
#include "K2PCF8566.h"
K2PCF8566::K2PCF8566(int address) {
i2cSlave = address;
_carets = 0x00;
_decimalPoint = 0;
for (int i = 0; i < 8; i++) {
_textMessage[i] = 0;
}
}
void K2PCF8566::init() {
_startMsg();
_write(PCF_CMD_SET_MODE | PCF_MODE_ENABLE | PCF_MODE_MULTIPLEX_3);
_endMsg();
SetTextMessage(_textMessage);
Serial.println("init PCF8566");
}
void K2PCF8566::SetTextMessage(const char* textMessage) {
for (int i = 0; i < 8; i++) {
if (textMessage[i] != 0) {
_textMessage[i] = textMessage[i];
}
else {
_textMessage[i] = ' ';
}
}
textToLedBytes();
ledBytesToSegments();
setMemory();
setDecimalPointRaw();
}
void K2PCF8566::SetCaret(uint8_t caret, bool onOff) {
if (onOff == true) _carets |= (1 << caret);
else _carets &= ~(1 << caret);
}
void K2PCF8566::SetDecimalPoint(uint8_t pos) {
_decimalPoint = (pos > 8) ? 8 : pos;
}
void K2PCF8566::textToLedBytes() {
for (int i = 0; i < 8; i++) {
switch (_textMessage[i]) {
case '0': _ledBytes[i] = LED_0; break;
case '1': _ledBytes[i] = LED_1; break;
case '2': _ledBytes[i] = LED_2; break;
case '3': _ledBytes[i] = LED_3; break;
case '4': _ledBytes[i] = LED_4; break;
case '5': _ledBytes[i] = LED_5; break;
case '6': _ledBytes[i] = LED_6; break;
case '7': _ledBytes[i] = LED_7; break;
case '8': _ledBytes[i] = LED_8; break;
case '9': _ledBytes[i] = LED_9; break;
case 'u': _ledBytes[i] = LED_u; break;
case 'U': _ledBytes[i] = LED_U; break;
case 'l': _ledBytes[i] = LED_l; break;
case 'L': _ledBytes[i] = LED_L; break;
case 'c': _ledBytes[i] = LED_c; break;
case 'C': _ledBytes[i] = LED_C; break;
case 'h': _ledBytes[i] = LED_h; break;
case 'H': _ledBytes[i] = LED_H; break;
case 'b': _ledBytes[i] = LED_b; break;
case ' ': _ledBytes[i] = LED_Space; break;
default: _ledBytes[i] = LED_Space;
}
bool caretOn = (((1 << i) & _carets) > 0);
_ledBytes[i] = (caretOn) ? _ledBytes[i] | CARET_BIT : _ledBytes[i] & ~CARET_BIT;
}
// Serial.println(_ledBytes[0], BIN);
}
void K2PCF8566::ledBytesToSegments() {
for (int i = 0; i < 8; i++) {
int j = i * 3;
_segments[j] = _ledBytes[i] & 0xe0;
_segments[j + 1] = (_ledBytes[i] << 3) & 0xe0;
_segments[j + 2] = (_ledBytes[i] << 6) & 0xe0;
}
}
void K2PCF8566::setMemory() {
// unsigned char bits = 0b00100000;
_startMsg();
delayMicroseconds(10);
_write(PCF_CMD_SELECT_DEVICE(0) | PCF_CONTINUE);
_write(PCF_CMD_LOAD_DATA_POINTER(0));
for (int i = 0; i < 8; i++) {
_write(_ledBytes[i]);
}
_endMsg();
}
void K2PCF8566::setDecimalPointRaw() {
Serial.println("dp ");
Serial.println(_decimalPoint);
if (_decimalPoint == 0) return;
uint8_t memOffset = ((_decimalPoint - 1) * 3) + 2;
uint8_t msg = ((_segments[memOffset] & 0xe0) | 0x20)
| ((_segments[memOffset + 1] & 0xe0) >> 3)
| ((_segments[memOffset + 2] & 0xe0) >> 6);
_startMsg();
delay(1);
_write(PCF_CMD_SELECT_DEVICE(0) | PCF_CONTINUE);
delay(1);
_write(PCF_CMD_LOAD_DATA_POINTER(0));
delay(1);
_write(msg);
delay(1);
_endMsg();
delay(1);
}
void K2PCF8566::_write(char msg) {
Wire.write(msg);
}
void K2PCF8566::_startMsg() {
Wire.beginTransmission(i2cSlave);
}
void K2PCF8566::_endMsg() {
int error = Wire.endTransmission();
if (error != 0) {
Serial.print("Error endTransmission() == ");
Serial.println(error);
}
}
//© 2021 GitHub, Inc.