|
|
View previous topic :: View next topic |
Author |
Message |
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
keypad routine for automatic fan controller |
Posted: Wed Sep 01, 2010 2:45 am |
|
|
Hi everyone, I want to ask if it's applicable to use keypad for my automatic fan controller project. The keypad will act like air-conditioner system.
My actual project:
Automatic fan controller based on LM35 sensor and Ultrasonic sensor.
The system act based on LM35 sensor and motion sensor to run the AC motor.
LM35 sensor = detect temperature
LCD = display temperature
2 ultrasonic sensor = detect human
Overall the entire system is working properly.
The system operate based on condition of human existence. I also provided counter routine to count the human that enter the room. If the count > 0 the system will be on, if the count = 0 the system will shut down.
Here I planned to make an adjustment by using keypad---like air-conditional mechanism. Can it be done? And how?
Sorry for my english.
This keypad purposely aim if the user want to change the speed of the motor (Before this, just depend on temperature detected).
Like if temp < 20 = speed slow
20<temp<30= medium
temp>30= fast
Something like that.
Anyone? Please...any idea. |
|
|
jbmiller
Joined: 07 Oct 2006 Posts: 73 Location: Greensville,Ontario
|
|
Posted: Wed Sep 01, 2010 5:14 am |
|
|
Since you already have the other parts of the program running you're almost done!.
Create a new program to test the fan controller only. Depending on the fan you have create a PWM program that accepts an integer(0-255) to control the duty cycle(0-100%).Once that is working, then add the keypad routine to input the fan speed value. Once that is working, then merge the fan speed and keypad routines into your original program.
There are lots of examples of PWM and KPD routines here and 'on the Web'. |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Wed Sep 15, 2010 7:32 am |
|
|
Hi again,
With the keypad driver given...I managed to make it work.
Right now, the problem is I don't get on how to interact it with lm35 value detected.
The keypad... when press 1 =1 and same goes with other, but how about to make it more than 2 digit; like 29 ....
Then, if that can be made out, isn't the value pressed can be useful in calculation...like...LM35= 30 and keypad pressed 24. Can both be use for mathematical operation like subtraction (30-24)?
- the value given in keypad driver seem to be in char character...sorry for my weakness,...anyone? |
|
|
daraos
Joined: 16 Oct 2008 Posts: 18 Location: Chile
|
|
Posted: Wed Sep 15, 2010 8:57 am |
|
|
so you need to get data from the keypad
You'll need a ENTER key to tell the program when you're done entering numbers
create a variable to hold the data and with each number pressed, do something like this:
if(key_pressed>=0 && key_pressed<=9){
key=(key*10) + key_pressed
when you press ENTER, set the fan at "key" speed |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Wed Sep 15, 2010 11:40 am |
|
|
Thanks for idea. But maybe it was my own weakness. I don't quite get it.
You said key = key*10 + key pressed.
Key? What value? Where can I get that value?
Truly sorry for this trouble. Can you make it much clear?
The situation that I planned would be like this:
Assume LM35 capture 29 degree, then the fan will run at medium speed.
But the user want to adjust the speed by placing desired temperature like 25 degree. So here, I would like to subtract the value.
The result of the subtraction will determine the speed.
Bigger margin - lead the speed become much faster.
Less margin - lead the speed to become slow. |
|
|
daraos
Joined: 16 Oct 2008 Posts: 18 Location: Chile
|
|
Posted: Wed Sep 15, 2010 12:03 pm |
|
|
Sorry, I posted in a hurry and wasn't able to finish.
Let's say that the value you read from the keys is stored in a variable named KEY.
I'm assuming that you have a keypad with numbers 0-9 and at least another key, for example the "#" key, so let's use that key as ENTER.
The # key returns a value, 11 for example.
When you have the value read from the keypad, use this:
Code: |
if(key>=0 && key<=10){ //the key pressed is a number, not enter
temporary=(temporary*10) + key;
}
else if(key==10){ //an ENTER is pressed
fan_value=temporary;
temporary=0; //reset the value entered from the keypad so it can accept a new value
}
|
so: temporary must be declared globally if you put this inside a function.
fan_value is the value you want to put in the pwm, and this value only changes when you press enter (#). |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Wed Sep 15, 2010 9:23 pm |
|
|
Code: | if(key>=0 && key<=10){ //the key pressed is a number, not enter
temporary=(temporary*10) + key; |
If I pressed the keypad like 5, then the temporary will produce = 5 + temporaryA*10.
My question at this stage temporaryA is what value...isn't 0?
Then if I pressed the enter, how is it becoming 11? Still blur...
Sorry for my weakness. |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Wed Sep 15, 2010 9:25 pm |
|
|
Code: |
if(key>=0 && key<=10){ //the key pressed is a number, not enter
temporary=(temporary*10) + key; |
If I pressed, the keypad like 5, then the temporary will produce = 5 + temporaryA*10.
My question at this stage temporaryA is what value...isn't 0?
Then if I pressed the enter, how it becoming 11? Still blur....
Sorry for my weakness. |
|
|
daraos
Joined: 16 Oct 2008 Posts: 18 Location: Chile
|
|
Posted: Thu Sep 16, 2010 8:52 am |
|
|
The value of TEMPORARY is 0 when the program starts and is reset to 0 when you press ENTER.
So, you start your program and temporary=0
Press 3 ==> temporary = temporary*10 + key ==> temporary=0*10 + 3 ==> temporary=3
Press 7 ==> temporary = temporary*10 + key ==> temporary=3*10 + 7 ==> temporary=37
Press enter ==> the value from temporary is passed to the pwm and temporary is reset to 0, so you're ready to enter another number. |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Sun Sep 26, 2010 11:30 am |
|
|
Code: |
#include <16F877A.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#include "C:\Users\deli\Desktop\keypad\LCD\Flexlcd2.c"
#include "C:\Users\deli\Desktop\keypad\Keypad\kbd.c"
#define toint(c) ((int)((c)-'0'))
//#include "flex_lcd.c"
//#include "KBD.c"
//#include "flex_lcd.c"
//#include "KBD.c"
void main()
{
int temp=0;
char k;
while(1){
k=0;
temp=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"test");
while (1){
k=kbd_getc(); // returns typ 'char'
if(k!=0) { // I put this '{' and now it is working
if(k>=0&&k<=9){
temp=10*temp+toint(k);
lcd_gotoxy(1,2);
printf(lcd_putc,"%d",temp);
if(temp>50) // if the desired temp exceed 50..the temperature return to 0 value
{
temp=0; }
} // end of loop if(k!=0)
if(k=='D') break;
}
}
}
}
|
here i code just to check Keypad and LCD
the code..compile without error
but the LCD just produce nothing' just black
anyone? |
|
|
daraos
Joined: 16 Oct 2008 Posts: 18 Location: Chile
|
|
Posted: Sun Sep 26, 2010 12:07 pm |
|
|
I'm on my phone, so I don't have access to the lcd code, but I think that the lcd needs to be initiated, I think is lcd_init(), check in the lcd.h file |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Sun Sep 26, 2010 6:30 pm |
|
|
lcd driver that i used
Code: | // flex_lcd.c
// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver. Change these
// pins to fit your own board.
#define LCD_DB4 PIN_D0
#define LCD_DB5 PIN_D1
#define LCD_DB6 PIN_D2
#define LCD_DB7 PIN_D3
#define LCD_E PIN_D7
#define LCD_RS PIN_D5
#define LCD_RW PIN_D6
// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.
#define USE_LCD_RW 1
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 60 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1,2);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif |
|
|
|
daraos
Joined: 16 Oct 2008 Posts: 18 Location: Chile
|
|
Posted: Sun Sep 26, 2010 8:40 pm |
|
|
there it is, add
lcd_init();
inside main, before the while(1) |
|
|
delifadzli
Joined: 12 Apr 2010 Posts: 27
|
|
Posted: Sun Sep 26, 2010 10:08 pm |
|
|
Finally it works....
Code: |
#include <16F877A.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#include "C:\Users\deli\Desktop\keypad\LCD\Flexlcd2.c"
#include "C:\Users\deli\Desktop\keypad\Keypad\kbd.c"
#define toint(c) ((int)((c)-'0'))
//#include "flex_lcd.c"
//#include "KBD.c"
//#include "flex_lcd.c"
//#include "KBD.c"
void main()
{
int temp;
char k;
lcd_init();
kbd_init();
while(1){
k=0;
temp=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"test");
while (1){
k=kbd_getc(); // returns typ 'char'
if(k!=0) { // I put this '{' and now it is working
if(k>=48&&k<=57){
temp=10*temp+toint(k);
lcd_gotoxy(1,2);
printf(lcd_putc,"%d",temp);
if(temp>50) // if the desired temp exceed 50..the temperature return to 0 value
{
temp=0;
lcd_gotoxy(1,2);
printf(lcd_putc,"X");}
} // end of loop if(k!=0)
if(k=='D') break;
}
}
}
} |
thank you for helping me in this problem .... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|