lcd-melt-rus

amperka/colony/lcd-melt-rus

i2c MT-16S2H-8 liquid crystal driver with utf8 to cyrillic convertor. Uses 1st font page.
lcd-melt-rus
@/lcd-melt-rus
i2c MT-16S2H-8 liquid crystal driver with utf8 to cyrillic convertor. Uses 1st font page.
ADDRbyte
I²C address of expander chip
BLboolean
Backlight enable/disable
L1string
Text for the first line
L2string
Text for the second line
UPDpulse
lcd-melt-rus
DONE
ADDR
BL
L1
L2
UPD
DONEpulse
Fires when write is done
To use the node in your project you should have the amperka/colony library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.

C++ implementation

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

nodespace {
    // cyrillic substitution codes from 1st font page
    const unsigned char partd0[] = {
        0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4,0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f,0xa8,
        0x50,0x43,0x54,0xa9,0xaa,0x58,0xe1,0xab,0xac,0xe2,0xad,0xae,0x62,0xaf,0xb0,0xb1,
        0x61,0xb2,0xb3,0xb4,0xe3,0x65,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0x6f,0xbe
    };
    const unsigned char partd1[] = {
        0x70,0x63,0xbf,0x79,0xe4,0x78,0xe5,0xc0,0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7
    };

    void printLine(LiquidCrystal_I2C* lcd, uint8_t lineIndex, XString str) {
        unsigned char prefix = 0x00;
        unsigned char current = 0x00;
        lcd->setCursor(0, lineIndex);
        uint8_t whitespace = 16;
        for (auto it = str->iterate(); it; ++it) {
            current = *it;
            switch(current) {
                // utf8 prefixes
                case 0xd0: /* break; - realy not needed here */
                case 0xd1: prefix = current; break;
                default:
                    // other codes
                    switch(prefix) {
                        case 0xd0:
                            if(current == 0x81) {
                                lcd->write(0xa2); // Ё
                            } else {
                                if(current >= 0x90 && current <= 0xbf) { // А-Яа-п
                                    lcd->write(partd0[current - 0x90]);
                                } else {
                                    lcd->write(current);
                                }
                            }
                            break;
                        case 0xd1:
                            if(current == 0x91) {
                                lcd->write(0xb5); // ё
                            } else {
                                if(current >= 0x80 && current <= 0x8f) { // р-я
                                    lcd->write(partd1[current - 0x80]);
                                } else {
                                    lcd->write(current);
                                }
                            }
                            break;
                        case 0x00:
                            lcd->write(current); // non cyrillic
                            break;
                    }
                    whitespace--;
                    prefix = 0x00;
                    break;
            }
        }

        // Clear the rest of the line
        while (whitespace--)
            lcd->write(' ');
    }
}

node {
    LiquidCrystal_I2C* lcd;

    void evaluate(Context ctx) {
        if (!isInputDirty<input_UPD>(ctx))
            return;

        if (!lcd) {
            uint8_t addr = getValue<input_ADDR>(ctx);
            lcd = new LiquidCrystal_I2C(addr, 16, 2);
            lcd->begin();
        }

        printLine(lcd, 0, getValue<input_L1>(ctx));
        printLine(lcd, 1, getValue<input_L2>(ctx));
        lcd->setBacklight(getValue<input_BL>(ctx));
        emitValue<output_DONE>(ctx, 1);
    }
}