Show Posts
Pages: [1] 2 3
1  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: Add to Reference for LiquidCrystal w/ 4 data lines on: February 24, 2009, 02:28:01 pm
Hello,

I would like to see an option in the 4bit LiquidCrystal library to disable the rw pin.

Cheers
KiWiX
2  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 11, 2009, 05:10:25 pm
Hi deli,

okay now i understand your intention more.
This is another way it should work as i suggested.

My intention is to write a slot car race timer and I wanted
to set up the race parmeters and the start the race. But
now I think it's a cool idea to use the select key to start
the race (inMainProgram) by select key, in every position
in menu.

In the next days I will rewrite some routines and then i can
give you a solution for your requirements.

But at the moment I'm very occupied by my job so it could last some days.

Cheers
KiWiX
3  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 11, 2009, 04:18:51 pm
Okay,

I understand that now. But what should happen with the setting?
Will you have another loop which will work based on that setting?
For the lighing you can my choose between
OFF - 10% - 20 % - 30% - ... - 80% - 90% - ON
instead of ON/OFF and Dimming with a third level.
That would save one menu level.

That could look like this on then display:

Lighning
Level:         OFF >

Lighning
Level:       < 50% >

Lighning
Level:       < 100%

But that will include (on my current idea of the menu), that the lighning level is set immediatly.

Maybe you can describe a little bit more, what the "reef control" should do, at least.

Cheers
KiWiX
4  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 11, 2009, 03:55:43 pm
Hi deli,

I reviewed the code and maybe I understood:

1. You want to choose between
    Temerpature, lighning, Timer settings, Light color, Salinity and PH
2. If you press v key i.e at temperature you see Temp:
3.a If you now press * key, the you want to see the value
      Room or Tank
3.b If you press < or > then you can change between Room or tank. If you now press * key the it should display the value required.

Is that right? And you won't do anything else?

If this is what you want, you can throw away every like inMainProgramm and you can change the behaviour of
the case selectkey in the main loop.

If so, I could change the code to that behavior.

Cheers
KiWiX
5  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 11, 2009, 03:34:24 pm
@deli:

could you please describe more, what you want to do.

Do you want to overwrite the setting in the second menu level with the values of the seonsor?

My Idea was to this

1. - choose category
      only works with < > to choose
      v key to option level
2. option level
      only works with < > to choose
      ^ key to category level
      v key to go to program mode
3. program mode
     * (select) to start main program
     by setting inMainProgram = true
     now you can have a different behavior for
     < > ^v and * (cause you can go to a else part, which isn't
    implemented at the moment

I caught you code and compiled it and uploaded to my test Freeduino and there are some other problems with your code I think.

Bute first please answer me, how, when and where your want to display the values of your sensors, then I can maybe explain, what you have to do.

Cheers
KiWiX
6  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 11, 2009, 03:26:35 pm
Hi deli,

at first, I don't think that you really want to do this:

Code:
case rightKey:
            switch (programMode)
            {
                case programMode1:
                    if (selectKey)
                    lcd.setCursor(6, 1);
                    lcd.print("Room");
                    break;

I think that you desired this here
Code:
case rightKey:
            switch (programMode)
            {
                case programMode1:
                    if (selectKey)
                          {
                           lcd.setCursor(6, 1);
                             lcd.print("Room");
                          }
                    break;
 
7  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 11, 2009, 03:24:17 pm
@barcud: Thanks. But you won't believe, I spend more than 2days :-)
8  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 03, 2009, 01:58:47 am
Ah.

That's right, In the main loop I check for a defined var.
I take a look at it, it's better to check for the size of the
array, so it's easier to modify the menu.

A new to do for the next days :-)

KiWiX
9  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 02, 2009, 05:47:38 am
Hi,

does the sample code runs on your device, now?

KiWiX
10  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: March 01, 2009, 06:32:30 am
Yes!
11  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: February 28, 2009, 05:49:06 pm
Okay,

Here's an example, you can try:

Code:
// ===================================================================
// Example for LCD Keypad Shield from  http://www.nuelectronics.com/
// -------------------------------------------------------------------
// * Modified to use a patched LiquidCrystal library
// * Alternative routine to detect keys
// ===================================================================
#include <stdio.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 14, 9, 4, 5, 6, 7);
// ===================================================================
// hardware settings
#define rightKey  0
#define upKey     1
#define downKey   2
#define leftKey   3
#define selectKey 4
#define NUM_KEYS  5
// ===================================================================
// Program parameters
#define minOpt1   5
#define maxOpt1 999
int valueOpt1 = 15;

#define minOpt2   1
#define maxOpt2  99
int valueOpt2 = 10;

#define programMode1 0
#define programMode2 1
#define programMode3 2
int programMode    =  programMode1;

boolean inMainProgram  =  false;

int programmSequence = 0;
#define sequenceModeSelect  0
#define sequenceModeOption  1
#define sequenceModeProgram 2

// first menu line - description of menu level
char sequenceHeader[3][17]  = {"Mode select     ", "Option select   ", "Program start   "};

// second menu line - mode select
char sequenceModes[3][17]   = {"  Mode 1       >", "< Mode 2       >", "< Mode 3        "};
// second menu line - options settings
char sequenceOptions[3][17] = {"Option 1:  ", "Option 2:   ", "no options      "};

void setup()
{
    // initial lcd display while initialize and pc detection
    lcd.clear();
    lcd.print("Freeduino  0.0.1");
    
    programmSequence = sequenceModeSelect;
    inMainProgram = false;
    
    delay(2000);
    updateScreen();
}

// ===================================================================
// main loop with new key detection
int keyEvent  = -1;
int lastEvent = -1;
int countEvent = 0;

//Key message
char msgs[5][3] = {
    "> ",
    "^ ",
    "v ",
    "< ",
    "* " };

void updateScreen()
{
    lcd.clear();
    lcd.print(sequenceHeader[programmSequence]);
    lcd.setCursor(0,1);
    switch(programmSequence)
    {
        case sequenceModeSelect:
            menuModeSelect( keyEvent );
            break;
        case sequenceModeOption:
            menuOptionSelect( keyEvent );
            break;
        case sequenceModeProgram:
            break;        
    }
}

void loop()
{
    int keyEvent = detectKey();
    if (keyEvent >= 0)
    {
        switch (keyEvent)
        {
            case upKey:
                if (!inMainProgram)
                {
                    if (programmSequence > sequenceModeSelect)
                        programmSequence--;
                    updateScreen();
                }
                break;
            case downKey:
                if (!inMainProgram)
                {
                    if (programmSequence < sequenceModeProgram)
                        programmSequence++;
                    updateScreen();
                }
                break;
            case rightKey:
            case leftKey:
                if (!inMainProgram)
                {
                    switch (programmSequence)
                    {
                        case sequenceModeSelect:
                            menuModeSelect( keyEvent );
                            break;
                        case sequenceModeOption:
                            menuOptionSelect( keyEvent );
                            break;
                        case sequenceModeProgram:
                            break;
                    }
                }
                break;
            case selectKey:
                lcd.setCursor(0, 1);
                if (lastEvent != keyEvent)
                {
                    lastEvent = keyEvent;
                    countEvent=0;
                }
                else
                    countEvent++;
                lcd.print(msgs[keyEvent]);
                lcd.print(countEvent);
                break;
        }
    }
}

// ===================================================================
// Menu tools

void menuModeSelect( int keyEvent )
{
    switch (keyEvent)
    {
        case rightKey:
            if (programMode < programMode3)
                programMode++;
            break;
        case leftKey:
            if (programMode > programMode1)
                programMode--;
            break;
    }
    lcd.setCursor(0,1);
    lcd.print( sequenceModes[programMode] );
}

void menuOptionSelect( int keyEvent )
{
    char cbuf[4] = "   ";
    lcd.setCursor(0,1);
    lcd.print(sequenceOptions[programMode]);
    switch (keyEvent)
    {
        case rightKey:
            switch (programMode)
            {
                case programMode1:
                    if (valueOpt1 < maxOpt1)
                        valueOpt1++;
                    break;
                case programMode2:
                    if (valueOpt2 < maxOpt2)
                        valueOpt2++;
                    break;
            }
            break;
        case leftKey:
            switch (programMode)
            {
                case programMode1:
                    if (valueOpt1 > minOpt1)
                        valueOpt1--;
                    break;
                case programMode2:
                    if (valueOpt2 > minOpt2)
                        valueOpt2--;
                    break;
            }
            break;
    }
    switch(programMode)
    {
        case programMode1:
            if (valueOpt1 > minOpt1)
                lcd.print("<");
            else
                lcd.print(" ");
            sprintf(cbuf,"%3d",valueOpt1);
            lcd.print(cbuf);
            if (valueOpt1 < maxOpt1)
                lcd.print(">");
            else
                lcd.print(" ");
            break;
        case programMode2:
            if (valueOpt2 > minOpt2)
                lcd.print("<");
            else
                lcd.print(" ");
            sprintf(cbuf,"%2d",valueOpt2);
            lcd.print(cbuf);
            if (valueOpt2 < maxOpt2)
                lcd.print(">");
            else
                lcd.print(" ");
            break;
    }
}

// ===================================================================
// Lcd tools

void clearLine(int line)
{
    lcd.setCursor(0,line);
    lcd.print("                ");
    lcd.setCursor(0,line);
}

// ===================================================================
// Define a custom char in lcd
int defineCharacter(int ascii, int *data) {
    int baseAddress = (ascii * 8) + 64;  
    // baseAddress = 64 | (ascii << 3);
    lcd.command(baseAddress);
    for (int i = 0; i < 8; i++)
        lcd.write(data[i]);
    lcd.command(128);
    return ascii;
}

// ===================================================================
// Convert ADC value to key number

int adc_key_val[NUM_KEYS] ={ 30, 150, 360, 535, 760 };
int get_key(unsigned int input)
{
    int k;
    for (k = 0; k < NUM_KEYS; k++)
    {
        if (input < adc_key_val[k])
            return k;
    }
    if (k >= NUM_KEYS)
        k = -1; // No valid key pressed
    return k;
}

// ===================================================================
// new key detection routine, without delays!

int     lastKeyEvent = 0;
int     curKeyEvent  = 0;
int     keyToReturn  = 0;
boolean keyToProcess = false;
int     adc_key_in   = 0;

int detectKey()
{
    keyToReturn = -1;
    adc_key_in = analogRead(0);         // read the value from the sensor  
    curKeyEvent = get_key(adc_key_in);      // convert into key press
    if (curKeyEvent != lastKeyEvent)
    {
        if (!keyToProcess)
        {
            lastKeyEvent = curKeyEvent;
            keyToProcess = true;
        }
        else
        {
            keyToReturn = lastKeyEvent;
            lastKeyEvent = -1;
            keyToProcess = false;
        }
    }
    return keyToReturn;
}

// ===================================================================

The menu will have 3 levels
1. Choose program mode
    1st and 2nd mode has options, 3rd not
2. Select the value
   1st program mode has a value between 5 and 999
   2nd program mode has a value between 1 and 99
   3rd program mode don't have an option
3. Start your program

About the menu and LCD keypad:
1. you have to patch LiquidCrystal (I told before)
2. i use an alternative routine to detect a key pressed,
   without blocking the main loop, so it looks a bit different

So copy & paste, compile, upload and test and then try to read and learn :-)

Cheers
KiWiX


--modified 23:55

I forget, it works different as you mentioned above:

- with right and left you change the values
- with up and down you change the menu level

But if you understand my code, you could simple change the behavior :-)

The size of the sketch is ~5kB

--modified 23:58
There was a small bug in line 193

-- modified 23:59
if someone has tips to optimize this code, please post them here
12  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: February 27, 2009, 09:13:24 am
Oh, the duplicate case error is an easy one :-)

Just imagine, that the compiler replaces all define values with the given value, so your

case rightKey2:
case rightKey3:
case rightKey3:

Will be translated to

case 0:
case 0:
case 0:

and now your compiler is right :-)

Cheers
KiWiX
13  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: February 26, 2009, 03:16:14 pm
Hi,
creating custom characters is really simple:

This code is only tested with the LiquidCrystal library of Arduino 0013, which I've patched (commented out every line which uses the read/write pin, deleted the original .o file and recompiled the sketch) to work with the lcd keypad shield.

First you have to define your character, like this

Code:
int custom_0[] = { 0x15, 0x1a, 0x15, 0x1a, 0x15, 0x10, 0x10, 0x10}; // checked flag

You can define up to 8 custom characters.

Next include this small function:
Code:
// Define a custom char in lcd
int defineCharacter(int ascii, int *data) {
    int baseAddress = (ascii * 8) + 64;  
    // baseAddress = 64 | (ascii << 3);
    lcd.command(baseAddress);
    for (int i = 0; i < 8; i++)
        lcd.write(data[i]);
    lcd.command(128);
    return ascii;
}

now include something like this to setup()

Code:
void setup()
{
    lcd.clear();
    
    // set initial values for program
    defineCharacter(0, custom_0);

    lcd.write(0);
}

So, if you want to know, how you can define a custom char, please read this: http://www.geocities.com/dinceraydin/lcd/custom.htm

On a Mac I use "LCD Editor" to define custom characters and test strings for my menu. You can get it here:

http://www.macupdate.com/info.php/id/28724/lcd-editor

There are similar programs for windows, too, but I don't know any :-) There's a web based editor, too, but I didn't find it, maybe google can help :smiley

Cheers
KiWiX

-- modified

To patch LiquidCrystal (what I really commend) take a look to this thread:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235496289
14  Forum 2005-2010 (read only) / Syntax & Programs / Re: LCD keypad menu help on: February 25, 2009, 03:21:21 pm
Hello,

I'm playing with the LCD Keypad Shield, too.

I've modified it in the first step like this:

On top I've added some defines, like this:

on top of my program/sketch I've putted some define statements

Code:
#define rightKey    0
#define upKey       1
#define downKey     2
#define leftKey     3
#define selectKey   4
#define NUM_KEYS    5

the main loop I've done like this:
Code:
void loop()
{
    int key = 0;
    adc_key_in = analogRead(0);                  // read the value from the sensor  
    key = get_key(adc_key_in);                  // convert into key press
    if (key != oldkey)                        // if keypress is detected
    {
        delay(50);                        // wait for debounce time
        adc_key_in = analogRead(0);            // read the value from the sensor  
        key = get_key(adc_key_in);            // convert into key press
        if (key != oldkey)
        {
            digitalWrite(ledPIN,HIGH);
            oldkey = key;
            if (key >=0)
            {
                 lcd.cursorTo(2, 0); //line=2, x=0
                switch(key)
                {
                case upKey:
                    lcd.printIn(msgs[key]);
                    // your code here
                    break;
                case downKey:
                    lcd.printIn(msgs[key]);
                    // your code here
                    break;
                case rightKey:
                    lcd.printIn(msgs[key]);
                    // your code here
                    break;
                case leftKey:
                    lcd.printIn(msgs[key]);
                    // your code here
                    break;
                case selectKey:
                    lcd.printIn(msgs[key]);
                    // your code here
                    break;
                }
            }
            digitalWrite(ledPIN, LOW);
        }
    }
}

This does nearly the same, like the original code, but I think it's more readable :-)

Currently I'm working on a menu system, which work's nearly like your wish,
You can use up and down to select a menu topic, left and right to choose options and only in the last menu topic, you can start the programm by pressing the select key.

But this code from nuelectronics has some disadvantages:

* the modded 4 Bit library is ver slow, especially when positioning the cursor
   The LiquidCrystal library from Arduino 0013 ist much faster (in my tests the
   4bit library need 130ms for writing on the LCD while LiquidCrystal only needs
   2-3ms!) But you have to modify the distributed library, 'cause it requires the
   read/write pin of the display, which is fixed connected to ground on the LCD
   keypad shield.

* The key detection of this code, works with delays in the main loop, so the program
   can't do other things, while it's waiting for bounce time. My current program
   (in the state of a proof-of -concept) does the key detection and bounce time
   by comparing millis in the main loop, so the programm is able detect the
  key and save an "event" without stopping the main programm

* Some other things I've done in the last days/weeks is to define and display characters,
   so I can use little "Icons" instead of text messages. Another thing was to figure out,
   how you can use the chars from LCD character map, which have a ascii code greater
   then 127 (which is largern then the value of an unsigned char, which are used by
   Arduino char[] strings)
15  Forum 2005-2010 (read only) / Syntax & Programs / Re: How to make timing sequence? on: February 27, 2009, 09:09:06 am
Hi,

Quote
if ((lastTimer + timer) < millis() ) // isnt > the right solution?

No, you said you want to have it high in the first 4ms.

Quote
if ((lastTimer + looptime) <= millis() )  // isnt better to use == ?

No, I don't think so, 'cause you have to be on that part of your code at the right millisecond, but if your switching of LEDs need a little bit more time, you hit this statement anymore.

Cheers
KiWiX
Pages: [1] 2 3