CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

keypad routine for automatic fan controller

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

keypad routine for automatic fan controller
PostPosted: Wed Sep 01, 2010 2:45 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 01, 2010 5:14 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 15, 2010 7:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 15, 2010 8:57 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 15, 2010 11:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 15, 2010 12:03 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 15, 2010 9:23 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Sep 15, 2010 9:25 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Sep 16, 2010 8:52 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 11:30 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 12:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 6:30 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 8:40 pm     Reply with quote

there it is, add

lcd_init();

inside main, before the while(1)
delifadzli



Joined: 12 Apr 2010
Posts: 27

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 10:08 pm     Reply with quote

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 .... Very Happy
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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