T6963c lib with multiple screens

I’ve been working with this library:

Following the instructions provided here:

I’m using one Arduino Mega and 3 New haven displays (NHD-240128WG-AFTI-VZ#C5 - datasheet)

I managed to get one screen working, so I know the library works and the wiring is good.
Then I attached 2 more screens all the wiring is parallell, except the the chip enable. So my idea was that I constantly send data to all of the screens and then specify which one with the chip enable.

Problem is that the required pins are coded in the library and unlike with LiquidCrystal library you don’t pass the pins in the constructor. So making 3 instances of the library won’t work. (since then only one screen will work)
I solved this by changing the library, I added a function setCE(byte ce) with which I could change the chip enable pin. So then I cycled through the screens. (This works) There is an annoyance though, every time I change the enable pin I have to run initialize() again. So I didn’t really like this solution.

I’d prefer if I had 3 instances of the screen (just like with the LiquidCrystal lib). I’ve tried this (kept all the pins the same and just specified which pin is the enable pin per screen), but then the last screen that is initialized is shown on all 3 screens. (in other words the data from the screen I initialize last is displayed on all 3 screens).

I’ve also tried rewriting the library using digitalWrite, pinMode, etc in an attempt to simplify it since the current library uses port manipulation which isn’t easy to wrap my head around seeing as this is my first project. But then the screens do nothing. Here is the code:


#ifndef MediaWallSimple_h
#define MediaWallSimple_h

#include "Arduino.h"

#define MediaWall_CURSOR_PATTERN_SELECT 0xA //cursor patter select command prefix or with desired size-1.
#define MediaWall_DISPLAY_MODE 0x90 
#define MediaWall_MODE_SET 0x80
#define MediaWall_SET_CURSOR_POINTER 0x21
#define MediaWall_SET_OFFSET_REGISTER 0x22
#define MediaWall_SET_ADDRESS_POINTER 0x24
#define MediaWall_SET_TEXT_HOME_ADDRESS 0x40
#define MediaWall_SET_TEXT_AREA 0x41
#define MediaWall_SET_GRAPHIC_HOME_ADDRESS 0x42
#define MediaWall_SET_GRAPHIC_AREA 0x43
#define MediaWall_SET_DATA_AUTO_WRITE 0xB0
#define MediaWall_SET_DATA_AUTO_READ 0xB1
#define MediaWall_AUTO_RESET 0xB2

#define MediaWall_DATA_READ_AND_INCREMENT 0xC1
#define MediaWall_DATA_READ_AND_DECREMENT 0xC3

#define MediaWall_SCREEN_PEEK=0xE0
#define MediaWall_SCREEN_COPY=0xE8

#define MediaWall_SCREEN_INVERSE=0xD0

class MediaWallSimple {
    // Constructor
    MediaWallSimple(uint8_t wr, uint8_t rd, uint8_t ce, uint8_t cd,
               uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
               uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
    void init(uint8_t wr, uint8_t rd, uint8_t ce, uint8_t cd,
              uint8_t d[8]);
    // Write Text
    void TextGoTo(unsigned char x, unsigned char y);
    void writeString(char * string);
    void begin();
    // Write Text
    void SetAddressPointer(unsigned int address);
    void WriteDisplayData(uint8_t x);
    void writeChar(char charCode);
    // Send data
    void send(uint8_t value, uint8_t mode);
    void pulseEnable(void);
    void write8bits(uint8_t value);
    // Pins
    uint8_t _wr;
    uint8_t _rd;
    uint8_t _ce;
    uint8_t _cd;
    uint8_t _data[8];
    // Text vars
    unsigned int _TA; // Text Area = Horizontal Pixels / Font width
    unsigned int _TH; // Text Home



#include "MediaWallSimple.h"


MediaWallSimple::MediaWallSimple(uint8_t wr, uint8_t rd, uint8_t ce, uint8_t cd,
                       uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
                       uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) {
    uint8_t data [] = {d0, d1, d2, d3, d4, d5, d6, d7};
    init(wr,rd,ce,cd, data);

// Fontwidth = 6
// Pix horizontal = 240
// Pix vert = 128

void MediaWallSimple::init(uint8_t wr, uint8_t rd, uint8_t ce, uint8_t cd,
                      uint8_t d[8]) {
    _wr = wr;
    _rd = rd;
    _ce = ce;
    _cd = cd;
    for (int i = 0; i < 8; i++) {
        _data[i] = d[i];
        pinMode(_data[i], OUTPUT);
    pinMode(_wr, OUTPUT);
    pinMode(_rd, OUTPUT);
    pinMode(_ce, OUTPUT);
    pinMode(_cd, OUTPUT);
    _TA = 240 / 6; // Text Area: Horizontal pixels / fontwidth
    _TH = 0; // text home

void MediaWallSimple::begin() {

void MediaWallSimple::send(uint8_t value, uint8_t mode) { // Mode HIGH: Command, LOW: Data
    digitalWrite(_cd, mode);

void MediaWallSimple::WriteDisplayData(uint8_t x) {
	send(x, LOW);

void MediaWallSimple::writeChar(char charCode) {
    WriteDisplayData(charCode - 32);

void MediaWallSimple::writeString(char * string) {

void MediaWallSimple::SetAddressPointer(unsigned int address) {
    send(address & 0xFF, LOW);
    send(address >> 8, LOW);
    send(MediaWall_SET_ADDRESS_POINTER, HIGH);

void MediaWallSimple::TextGoTo(unsigned char x, unsigned char y) {
    unsigned int address;
    address = _TH +  x + (_TA * y);

void MediaWallSimple::pulseEnable(void) {
    digitalWrite(_ce, HIGH);
    digitalWrite(_ce, LOW);
    digitalWrite(_ce, HIGH);

void MediaWallSimple::write8bits(uint8_t value) {
    digitalWrite(_wr, LOW);
    digitalWrite(_rd, HIGH);
    for (int i = 0; i < 8; i++) {
        //pinMode(_data[i], OUTPUT);
        digitalWrite(_data[i], (value >> i) & 0x01);

I probably could get all 3 screens working in the manner I desire if I wire each one separately to the Arduino Mega, but the idea is that you could keep adding screens so using less pins is better.

Could anybody give me some advice on what to do? Can I change the library to work like LiquidCrystal? Is it better to use 3 instances or would 1 be good enough? What is happening in initialize() that makes it mandatory to run it every time?