View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 08, 2010 4:50 pm |
|
|
I did the first part of your program for you. Let's see if you can finish it.
This program combines your two programs. In "Normal" mode, it
displays the A/D value on the LCD. When you press a key on the
keypad, it goes into "Setup" mode. Then you can enter 3 numbers.
When you press a 4th key, it exits Setup mode and goes back to normal
mode.
In the keypad driver file, the debounce factor must be set to 0.
(It was 33). Example:
Code: |
#define KBD_DEBOUNCE_FACTOR 0
|
Code: |
#include <16F877.H>
#device adc=10
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include "flex_lcd.c"
#include "flex_kbd.c"
// Wait for a key to be pressed. Then return it.
char keypad_getc(void)
{
char retval;
while(1)
{
retval = kbd_getc();
if(retval)
return(retval);
delay_ms(10);
}
}
//--------------------------------------
void lcd_setcursor_vb(short visible, short blink)
{
lcd_send_byte(0, 0xC | (visible<<1) | blink);
}
//======================================
void main()
{
char k;
int16 adc_value;
float volts;
float setup;
int8 loop_count;
int8 setup_count;
lcd_init();
kbd_init();
setup_adc (ADC_CLOCK_DIV_8);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_us(20);
loop_count = 0;
while(1)
{
// Update LCD every 500 ms (50 * 10ms = 500ms)
if(loop_count++ == 50)
{
loop_count = 0;
adc_value = read_adc();
volts = (adc_value * 5) / 1023.0;
printf(lcd_putc, "\fVOLT: %3.2f", volts);
}
// Poll keypad driver every 10 ms
k = kbd_getc();
// Press any key to go into Setup mode.
if(k)
{
printf(lcd_putc, "\fSETUP: ");
lcd_setcursor_vb(TRUE, TRUE); // LCD cursor on
setup_count = 0;
// Get setup number in this loop. Example 1.23
while(1)
{
k = keypad_getc(); // Wait for keypress
lcd_putc(k); // Display key
setup_count++;
if(setup_count == 1) // After first number,
lcd_putc('.'); // display decimal point
// If user has entered 3 numbers, then exit the loop.
if(setup_count == 3)
{
lcd_setcursor_vb(FALSE, FALSE); // LCD cursor off
break;
}
}
// Wait for any keypress to exit Setup mode.
keypad_getc();
}
delay_ms(10);
}
}
|
|
|
|
thinkpositivex23
Joined: 20 Dec 2009 Posts: 7
|
Program not function |
Posted: Sun May 02, 2010 7:54 pm |
|
|
Thank for your reply PCM programmer. For your information I already compile the previous program n it function the keypad not display the number that I press....
Below program show the lcd will display the voltage VOLT:..... at normal condition, and after 500ms the LCD display " Enter voltage" : at setup condition. The user able to enter the value and the value is shown on the lcd then after the 3 number is press the lcd back to normal condition and display the status of volt.
What should I add in the program after 3 number is press on the LCD to ensure that lcd back to normal condition.
Code: |
#include <16f877a.h>
#device adc =10;
#fuses XT,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#define use_portb_kbd TRUE
#include <LCD.C>
#include <KBD.C>
// Wait for a key on the keypad to be pressed. Then return it.
char wait_kbd_getc(void)
{
char retval;
while(1)
{
retval = kbd_getc();
if(retval)
return(retval);
delay_ms(10);
}
}
void main()
{
int16 adc_value;
float volts;
float setup;
char k;
lcd_init();
kbd_init();
setup_adc (ADC_CLOCK_DIV_32);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_us(10);
while(1)
{
adc_value = read_adc(); // read value adc
volts = (float)(adc_value * 5)/1023.0; // 1023.0 display float on LCD
setup = volts*2.4; // ratio between 12v/5v
printf(lcd_putc, "\fVOLT:%3.2f", setup);
delay_ms(500);
// delay 500 ms,display ENTER VOLTAGE on LCD//
lcd_putc("\f ENTER VOLTAGE:\n");
while (TRUE)
{
k=kbd_getc();
if(k!=0)
if(k=='*')
lcd_putc('\f');
else
lcd_putc(k);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun May 02, 2010 9:17 pm |
|
|
I think you are asking how to break out of the while() loop if you get a key.
Just add a break statement for the 'else' condition, as shown below.
Code: | while(TRUE)
{
k=kbd_getc(); // Wait for key to be pressed
if(k=='*')
lcd_putc('\f');
else
{
lcd_putc(k);
break; // Break out of loop if get 0-9 or # keys.
}
}
|
Also, you don't need to test if k!=0. That's because the kbd_getc()
function only returns if it gets a non-zero value from the kbd.c driver.
I have deleted the line that tests for k!=0. |
|
|
thinkpositivex23
Joined: 20 Dec 2009 Posts: 7
|
not function |
Posted: Mon May 03, 2010 1:45 pm |
|
|
I already compile program as below but I am not able to enter the
voltage because the display enter voltage is display in short time...what
should I add in program to ensure that the user able to enter the value ?
Code: |
#include <16f877a.h>
#device adc =10;
#fuses XT,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#define use_portb_kbd TRUE
#include <LCD.C>
#include <KBD.C>
// Wait for a key on the keypad to be pressed. Then return it.
char wait_kbd_getc(void)
{
char retval;
while(1)
{
retval = kbd_getc();
if(retval)
return(retval);
delay_ms(10);
}
}
void main()
{
int16 adc_value;
float volts;
float setup;
char k;
lcd_init();
kbd_init();
setup_adc (ADC_CLOCK_DIV_32);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_us(10);
while(1)
{
adc_value = read_adc(); // read value adc
volts = (float)(adc_value * 5)/1023.0; // 1023.0 display float on LCD
setup = volts*2.4; // ratio between 12v/5v
printf(lcd_putc, "\fVOLT:%3.2f", setup);
delay_ms(500);
// delay 500 ms,display ENTER VOLTAGE on LCD//
lcd_putc("\f ENTER VOLTAGE:\n");
}
while(TRUE)
{
k=kbd_getc(); // Wait for key to be pressed
if(k=='*')
lcd_putc('\f');
else
{
lcd_putc(k);
break; // Break out of loop if get 0-9 or # keys.
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 03, 2010 1:51 pm |
|
|
How many numbers do you want the user to enter for the voltage ?
Is it just one number, such as '3' ? |
|
|
thinkpositivex23
Joined: 20 Dec 2009 Posts: 7
|
|
Posted: Mon May 03, 2010 8:23 pm |
|
|
I want to enter 2 decimal places such as... "3.70". Below is my circuit...
Uploaded with ImageShack.us |
|
|
thinkpositivex23
Joined: 20 Dec 2009 Posts: 7
|
|
Posted: Tue May 04, 2010 8:24 am |
|
|
helo PCM programmer...i need guide from you.....plz help me |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 04, 2010 2:27 pm |
|
|
I wrote some code for you in a earlier post in this thread. It gets 3
numbers. I've done enough on this thread. |
|
|
thinkpositivex23
Joined: 20 Dec 2009 Posts: 7
|
update lcd |
Posted: Tue May 04, 2010 3:59 pm |
|
|
i already compile the previous coding but i can't enter the 2 decimal places....
please check my code...
Code: |
#include <16f877a.h>
#device adc =10;
#fuses XT,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=20000000)
#define use_portb_kbd TRUE
#include <LCD.C>
#include <KBD.C>
// Wait for a key on the keypad to be pressed. Then return it.
char wait_kbd_getc(void)
{
char retval;
while(1)
{
retval = kbd_getc();
if(retval)
return(retval);
delay_ms(10);
}
}
//--------------------------------------
void lcd_setcursor_vb(short visible, short blink)
{
lcd_send_byte(0, 0xC | (visible<<1) | blink);
}
//======================================
void main()
{
int16 adc_value;
float volts;
float setup;
char k;
int8 loop_count;
int8 setup_count;
lcd_init();
kbd_init();
setup_adc (ADC_CLOCK_DIV_32);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_us(10);
while(1)
{
// Update LCD every 500 ms (50 * 10ms = 500ms)
if(loop_count++ == 900)
{
loop_count = 0;
adc_value = read_adc(); // read value adc
volts = (float)(adc_value * 5)/1023.0; // 1023.0 display float on LCD
setup = volts*2.4; // ratio between 12v/5v
printf(lcd_putc, "\fVOLT:%3.2f", setup);
}
// Poll keypad driver every 10 ms
k = kbd_getc();
// Press # key to go setup mode
if(k=='#')
{
printf(lcd_putc, "\fENTER VOLTAGE: ");
lcd_setcursor_vb(TRUE,TRUE); //LCD cursor on
setup_count = 0;
// Get setup number in this loop. Example 1.23
while (1)
{
k=wait_kbd_getc(); // wait key press
lcd_putc(k); // display key
setup_count++;
if(setup_count == 1) // After first number,
lcd_putc('.');
// If user has entered 3 numbers, then exit the loop.
if(setup_count == 3)
{
lcd_setcursor_vb(FALSE, FALSE); // LCD cursor off
break;
}
}
// Wait for any keypress to exit Setup mode.
wait_kbd_getc();
}
delay_ms(10);
}
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed May 05, 2010 3:06 am |
|
|
Code: | // Update LCD every 500 ms (50 * 10ms = 500ms)
if(loop_count++ == 900) | Loop_count is an int8, it can only count up to 255. Change to an int16.
Also your comments and code don't match.
Note:
You might have thought this part of the code to work correct but that's only by chance. The 900 value is truncated to an int8 --> 900 dec == 0x384, trunk to int8 becomes 0x84 == 132 dec.
So instead of updating each 500ms it updates every 1.3s but this is easy to overlook.
What is your problem in creating the value with 2 decimal places?
Your current code will accept the user to enter 3 digits and you show these on the screen. So the only thing left to do is to assemble these 3 digits into a single variable. Is this the step you have problems with? |
|
|
|