Individual fields on the LCD

27 Aug 2012

I want to integrate a time on an LCD screen, I would like to label it with a few lines of LCD individual fields, or two can be simultaneously described.

I use two buttons (on the testbed), one to count up the numbers and one to move to the next. (for example, 12:50:31, then the 12 should flash and you can press buttonA to start counting the hours, then press buttonB to move to the minutes, and so on)

How do I reach to individual fields on the LCD screen, with lcd.locate(0.2) for example, I can only appeal to the whole line from the selected column.

Please help. :)

28 Aug 2012

You can use lcd.locate(column, row) to move the cursor to a specific column & row and printf the value you want to show on that location. Use the format string to control the nr of positions you want to overwrite.

int hours, minutes, seconds;

int main() {
    hours=12;
    minutes=50;
    seconds=31;

    lcd.locate(0, 2); // row 2, column 0

    // show time, use 2 positions per field, show leading zeros
    lcd.printf("%02d:%02d:%02d", hours, minutes, seconds);
    
    wait(2);

    minutes++;

    lcd.locate(3, 2); // select row 2, column 3 for minutes
    lcd.printf("%02d", minutes);
}

Standard LCDs do not support multiple flashing characters. You have to take care of that in your code by writing/erasing them in a delayloop or timerloop.

27 Aug 2012

Some LCDs have a flashing cursor character that will invert the character that it overlays as it flashes.

For instance, if you are using a NewHaven Display NHD-0420D3Z-FL-GBW , you can send an 0xFE, 0x4B, to enable the cursor, then send an 0xFE, 0x45, followed by cell position to set the location of the cursor.

I'm not pedaling NewHaven, I just used on in a project, and liked it because it gave me the choice to communicate via serial, I2C, or SPI, and it worked well.

28 Aug 2012

If your LCD is based on a standard HD44780 chip, the chip has blinking cursor capability.

Please try to run following program.

#include "mbed.h"
#include "TextLCD_20X4.h"

TextLCD_20X4 lcd(p21, p22, p26, p25, p24, p23); // rs, e, d0, d1, d2, d3
DigitalIn button1(p16);
DigitalIn button2(p17);
Ticker sw_check;

int SW0,SW1,SW2,BUTTON;

void check_sw() {   // called every 5 msec
    int work;

    SW0 = SW1;      // shift previous status
    SW1 = SW2;      // shift previous status
    // get new status
    SW2 = button1.read()+(button2.read()<<1);
//    following sequence detects switch press edge
//    HIGH(SW0) -> LOW(SW1) -> LOW(SW2)
    work = (SW0&~SW1)&~SW2;
    if (work) {
        BUTTON |= work; // update button status
    } // if
}


int main() {
    int hours, minutes, seconds, position;

    hours=12;
    minutes=50;
    seconds=31;
    position=0;

    button1.mode(PullUp);
    button2.mode(PullUp);
    SW0 = 0x0f;
    SW1 = 0x0f;
    SW2 = 0x0f;
    BUTTON = 0;

    sw_check.attach_us(&check_sw, 5000);    // status check every 5 msec

    lcd.cls();
    lcd.writeCommand(0x0D); // blink cursor

    while(1) {
        lcd.locate(0,0);
        lcd.printf("%02d:%02d:%02d", hours, minutes, seconds);
        lcd.locate(position*3+1,0);     // set cursor position
        if ( BUTTON&0x01 ) {    // button1 pressed
            BUTTON &= 0xfe;     // clear button status
            switch (position){
                case 0:
                    hours++;
                    if (hours == 24 ) hours = 0;
                    break;
                case 1:
                    minutes++;
                    if (minutes == 60) minutes = 0;
                    break;
                case 2:
                    seconds++;
                    if (seconds == 60) seconds = 0;
                    break;
            } // switch
        } // if

        if ( BUTTON&0x02 ) {    // button2 pressed
            BUTTON &= 0xfd;     // clear button status
            position++;
            if (position == 3) position = 0;
        } // if
        wait(0.1);
    } // while
}  // main

The button circuit is very simple. Just connect a switch between a port and the GND.

Hope this helps.

がんばってください

28 Aug 2012

Neal Horman wrote:

Some LCDs have a flashing cursor character that will invert the character that it overlays as it flashes.

Yoshi Mimura wrote:

If your LCD is based on a standard HD44780 chip, the chip has blinking cursor capability.

I am aware of the blinking cursor/flashing single character option. However, the question was how to show flashing double digits for '12' hours etc. That is not supported by the HD44780 or its clones and can only be done in software. You do find 'attribute' features for every individual character on some other display devices like Smart LED displays. Anyhow, a blinking cursor on the first digit is probably good enough in this case.

29 Aug 2012

ありがとう

Thank you :)

10 Oct 2017

Hi

I would like to ask.

Regarding to Yoshi Mimura's coding, may I know how to code with 3 push buttons or 4 or more than that?

I try to rearrange the coding into this :

I use 3 push button

  1. include "mbed.h"
  2. include "TextLCD.h"

DigitalIn button1(PC_9); DigitalIn button2(PB_8); DigitalIn button3(PB_9);

DigitalOut lcdD4(PA_9), lcdD5(PA_8), lcdD6(PB_10), lcdD7(PB_4); DigitalOut lcdEN(PC_7), lcdRS(PB_6);

TextLCD lcd(PB_6, PC_7, PA_9, PA_8, PB_10, PB_4 , TextLCD::LCD16x2 ); rs, e, d4-d7

--------------------------

class Stepper { public: Stepper(PinName p0, PinName p1, PinName p2, PinName p3) : m(p0, p1, p2, p3), delay(4), direction(1), on(false), currentMagnet(0) { } void setDelay(int d) { if (d < 4) { delay = 4; } else { delay = d; } if (on) { t.attach_us(callback(this, &Stepper::tick), 1000*delay); } } void toggleDirection(void) { direction = (4-direction); } void toggleOn(void) { on = ! on; if (on) { number_of_turns = -1; t.attach_us(callback(this, &Stepper::tick), 1000*delay); } else { t.detach(); m = 0; } } void rotate(int n) { if (on) { t.detach(); m = 0; } direction = 1; if (n < 0) { direction = 3; n = -n; } on = true; number_of_turns = 4*n; 1 complete "turn" is a cycle through 4 magnets t.attach_us(callback(this, &Stepper::tick), 1000*delay); } void tick(void); private: BusOut m; int delay; int direction; bool on; int currentMagnet; Ticker t; int number_of_turns; };

void Stepper::tick(void) { m = (1 << currentMagnet); currentMagnet = (currentMagnet + direction)%4; if (number_of_turns == -1) return; continuous until stopped number_of_turns; reduce counter by 1 if (number_of_turns == 0) { stop when we get to 0 t.detach(); m = 0; } }

------------------------

int SW0,SW1,SW2,BUTTON; Ticker sw_check;

void check_sw() { called every 5 msec int work;

SW0 = SW1; shift previous status SW1 = SW2; shift previous status, shift previous status get new status SW2 = button1.read() + (button2.read()<<1) + (button3.read()<<2) ; following sequence detects switch press edge HIGH(SW0) -> LOW(SW1) -> LOW(SW2) work = (SW0&SW1)&SW2 ; work = (SW0&SW1)&SW2; if (work) { BUTTON |= work; update button status } if }

------------------------

int main() {

int i , j , k ,totalnum, position ;

i = 0 ; j = 0 ; k = 0 ; totalnum = 0 ; position=0;

button1.mode(PullUp); button2.mode(PullUp); button3.mode(PullUp); SW0 = 0x0f; SW1 = 0x0f; SW2 = 0x0f; BUTTON = 0;

sw_check.attach_us(&check_sw, 5000); status check every 5 msec lcd.cls();

Stepper sm(PC_0, PC_1, PC_2, PC_3); while (1) {

lcd.locate(0,0); lcd.printf("Set: %d %d %d \n",i,j,k); lcd.locate(position+1,0); lcd.writeCommand(0x0E); blink cursor lcd.locate(0,1); lcd.printf("Detected: ");

if ( BUTTON&0x01 ) { button1 pressed BUTTON &= 0xfe; clear button status switch (position){ case 0: i++; if (i == 10 ) i = 0; break; case 1: j++; if (j == 10) j = 0; break; case 2: k++; if (k == 10) k = 0; break; } switch } if

if ( BUTTON&0x02 ) { button2 pressed

BUTTON &= 0xfd; clear button status position++; if (position == 3) position = 0;

} if

if ( BUTTON&0x03 ) { button3 pressed

BUTTON &= 0xfc; clear button status sm.toggleOn(); totalnum = (i*100) + (j*10) + k ; sm.rotate(totalnum);

} if

wait(0.1);

}while(1)

} main

But it doesnt work...

Please Help Me