text-lcd-20x4-cursor-i2c

bjbaylon/utilities-for-menus/text-lcd-20x4-cursor-i2c

No description
text-lcd-20x4-cursor-i2c
@/text-lcd-20x4-cursor-i2c
ADDRbyte
I²C address of the expander chip.
BLboolean
Backlight enable/disable
L1string
Text for the first line
L2string
Text for the second line
L3string
Text for the third line
L4string
Text for the fourth line
CURboolean
Cursor display enable/disable.
BLINKboolean
Cursos flash enable/disable.
Cxnumber
Cursor x positiom (from 0 to 19).
Cynumber
Cursor y positiom (from 0 to 3).
UPDpulse
Triggers new write
text-lcd-20x4-cursor-i2c
ADDR
BL
L1
L2
L3
L4
CUR
BLINK
Cx
Cy
UPD
DONE
DONEpulse
Fires when write is done
To use the node in your project you should have the bjbaylon/utilities-for-menus 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

#pragma XOD error_raise enable

{{#global}}
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
{{/global}}

struct State {
    LiquidCrystal_I2C* lcd;
};

{{ GENERATED_CODE }}

void printLine(LiquidCrystal_I2C* lcd, uint8_t lineIndex, XString str) {
    lcd->setCursor(0, lineIndex);
    uint8_t whitespace = 20;
    for (auto it = str.iterate(); it; ++it, --whitespace)
        lcd->write(*it);

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

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

    State* state = getState(ctx);
    auto lcd = state->lcd;
    if (!state->lcd) {
        uint8_t addr = getValue<input_ADDR>(ctx);
        if (addr > 127) {
            raiseError(ctx);
            return;
        }
        state->lcd = lcd = new LiquidCrystal_I2C(addr, 20, 4);
        lcd->begin();
    }

    printLine(lcd, 0, getValue<input_L1>(ctx));
    printLine(lcd, 1, getValue<input_L2>(ctx));
    printLine(lcd, 2, getValue<input_L3>(ctx));
    printLine(lcd, 3, getValue<input_L4>(ctx));
    lcd->setBacklight(getValue<input_BL>(ctx));
    emitValue<output_DONE>(ctx, 1);

    lcd->setCursor(getValue<input_Cx>(ctx), getValue<input_Cy>(ctx));
        if(getValue<input_CUR>(ctx)){
            lcd->cursor();
        }
        else {
            lcd->noCursor();
        }
        
        if(getValue<input_BLINK>(ctx)){
            lcd->blink();
        }
        else {lcd->noBlink();}
}