Button Interfacing

Post here to discuss the PIC microcontroller tutorials.

Moderators: Chuckt, Garth, bitfogav

Post Reply
User avatar
captalex
decided to stick around...
decided to stick around...
Posts: 28
Joined: Mon Mar 21, 2011 3:00 am
Contact:

Button Interfacing

Post by captalex » Wed Jun 08, 2011 6:36 pm

hello guys, i've hooked up the button to the PIC18F4550 as instructed in tutorial 4, but i just can't get my head around assembly. i have a single led on port RC4 and a push button attached to port RA0. can any one provide me with the code in Mikro C or similar, or with the HEX file. thanks.

User avatar
brad
Site Admin
Site Admin
Posts: 2576
Joined: Fri Mar 26, 2010 10:30 pm

Re: Button Interfacing

Post by brad » Wed Jun 08, 2011 9:40 pm

I'd love to help you out but I haven't done anything in mikro C.

Perhaps bitfogav might be able to shed some light?

Have you thought about coming over to the wonderful world of Swordfish Basic? :D

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Thu Jun 09, 2011 4:26 am

Im not familiar with miKroC either, But an example Code I made for AVR C which setups 2 buttons and two leds, buttons connected to PORTB and leds on PORTD.

I agree with Brad, have you looked at Swordfish Basic? much easier to learn, plus im sure me and Brad will help you :)

Code: Select all

// F_CPU tells util/delay.h our clock frequency
#define F_CPU 8000000UL   // Clock frequency (8MHz)

// Include AVR Libraries
#include <avr/io.h>     
#include <util/delay.h>

// Functions
int set_PORTD_bit(int position, int value);

int main(void)
{
  int temp, temp1;

  // Set Port D output
  DDRD = 0b11111111;
  // make Port B input
  DDRB = 0b00000000;

  // Set up a forever loop
  for ( ; 1==1 ; )
  {
    // Bitwise AND the state of the pins of
    // PORT B with 0000 0001 (PB0)
    // In other words, set 'temp' to be 
    // the value of PINB's bit #1.
    // 'temp' will therefore only ever be 0x01 or 0x00.
    temp = (PINB & 0x01);        // button one
	temp1 = (PINB & 0x80);       // button two

    // If the button one is pushed (i.e. that bit is 0) 
    // then turn the LED on with a function.
    if ( temp == 0 )
    {
        set_PORTD_bit(0,1);  // LED on (LED is on PD0)
    }
    else
    {
        set_PORTD_bit(0,0);  // LED off (LED is on PD0)
    }

	// If the button two is pushed (i.e. that bit is 0) 
    // then turn the LED on with a function.
    if ( temp1 == 0 )
    {
        set_PORTD_bit(1,1);  // LED on (LED is on PD1)
    }
    else
    {
        set_PORTD_bit(1,0);  // LED off (LED is on PD1)
    }
  }
  return 1;
}

// Function code
int set_PORTD_bit(int position, int value)
{
  // Sets or clears the bit in position 'position' 
  // either high or low (1 or 0) to match 'value'.
  // Leaves all other bits in PORTD unchanged.
                
  if (value == 0)
  {
    PORTD &= ~(1 << position);      // Set bit position low
  }
  else
  {
    PORTD |= (1 << position);       // Set high, leave others alone
  }

  return 1;
} 

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Thu Jun 09, 2011 4:48 am

If you was to use Swordfish then something has this is what you use?.

Code: Select all

Device = 18F4550 
Clock = 8

// Include Modules
Include "InternalOscillator.bas" 
Include "utils.bas"

// configure port pins
Dim led1 As PORTD.0     // LED1
Dim button1 As PORTB.1     // Button1

    // check button
Sub check_button() 
    If  button1 = 0 Then 
        High(led1)         // Turn On LED
        DelayMS(50)      // debounce for button 
    Else
        Low(led1)          // Turn Off LED
    End If
End Sub 
  
    // Make all Pins digital I/O's 
SetAllDigital                       
TRISD = %00000000    // set PORTD Output
TRISB = %11111111    // set PORTB Input

   //  prog starts here
While true 
    check_button 
Wend 

User avatar
captalex
decided to stick around...
decided to stick around...
Posts: 28
Joined: Mon Mar 21, 2011 3:00 am
Contact:

Re: Button Interfacing

Post by captalex » Fri Jun 10, 2011 9:34 am

cheers guys, i really want to learn swordfish, but my programming background was started in C, and time wouldnt let me combine both at the moment, when i am done with my current lcd pong game project. i will try and see what swordfish has to offer.


hey bitfogav!.
i have this code written in mikro c, but i think the problem might be my hardware, i have a push button across the breadboard bridge, one pin goes to pin RC2 with a 10k resistor connected to the ground and the other pin connected to the ground, in my code the button goes high when the button is released. dont know what is wrong!

Code: Select all

  // Example reads RB0, to which the button is connected; on transition from 1 to 0 (release of button), PORTD is inverted:

int oldstate;                                    // Old state flag

void main() {

      ADCON1 = 0x0F;            // Set AN pins to Digital I/O
      CMCON  |= 7;                              // Disable comparators
  TRISA = 1;                                // set RA0 pin as input

  TRISC = 0x00;                                  // Configure PORTC as output
  PORTC = 0xAA;                                  // Initial PORTC value
  oldstate = 0;

  do {
    if (Button(&PORTA, 0, 1, 0)) {               // Detect logical one    if button is high set oldstate to 1
      oldstate = 1;                              // Update flag
    }
    if (oldstate && Button(&PORTA, 0, 1, 1)) {   // Detect one-to-zero transition   if 1 and aero button has been released   invert output at C
      PORTC = ~PORTC;                            // Invert PORTC
      oldstate = 0;                              // Update flag
    }
  } while(1);                                    // Endless loop
}

User avatar
brad
Site Admin
Site Admin
Posts: 2576
Joined: Fri Mar 26, 2010 10:30 pm

Re: Button Interfacing

Post by brad » Fri Jun 10, 2011 8:17 pm

Have you double checked the output of the button with a logic probe?

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Sat Jun 11, 2011 3:01 am

captalex wrote:i think the problem might be my hardware, i have a push button across the breadboard bridge, one pin goes to pin RC2 with a 10k resistor connected to the ground and the other pin connected to the ground, in my code the button goes high when the button is released. dont know what is wrong!

Like Brad said check your button output?, But you say you got a 10k resistor going to ground and the pin of the button and the other button pin going to ground??. that to me sounds like it would't work, your just get a logic 0 to your microchip pin.

Try something like this picture I made up, the resistor goes to your power (5volt) and the other button pin goes to ground, you should then have a logic 1 at the PIC pin until you press the button, and then you should have a logic 0 at the PIC pin while the button is being pressed.
buttoncircuit.jpg
buttoncircuit.jpg (6.55 KiB) Viewed 13190 times

User avatar
captalex
decided to stick around...
decided to stick around...
Posts: 28
Joined: Mon Mar 21, 2011 3:00 am
Contact:

Re: Button Interfacing

Post by captalex » Sat Jun 11, 2011 8:16 am

no brad,
i dont have access to a logical probe, any other methods.?.

yes bitfogav,
i have tried that it displays the ON text that i sent to it but when i push the button it doesnt execute the next statement. :roll:

Code: Select all

/* when button is pressed led comes on and text is written to the lcd screen*/


int oldstate=0;                                    // Old state flag
 void main() {

      TRISA = 1;                                // set RA0 pin as input
      TRISC.F2 = 0x00;                                  // Configure PORTC as output
      PORTC = 0;                                  // Initial PORTC value      for led
      
      ADCON1 = 0x0F;      // Set AN pins to Digital I/O
      Glcd_Init(&PORTB, 0, 1, 2, 3, 5, 4, &PORTD);  //Glcd_Init_EP4,see Autocomplete//(CONTROL PORT,cs1,cs2,(d/i)/rs),r/w,rst,en,DATAPORT)
      Glcd_Fill(0x00);  //clear  screen



  do {
  if (Button(&PORTA, 0, 1, 1)) {               // Detect logical one    if button is high set oldstate to 1
    oldstate = 1;                              // Update flag
    Glcd_Write_Text("ON",45,3, 1);
  }
  if (oldstate && Button(&PORTA, 0, 1, 0)) {   // Detect one-to-zero transition   if 1 and aero button has been released   invert output at C
    PORTC = ~PORTC;                            // Invert PORTC
    oldstate = 0;                              // Update flag
    Glcd_Write_Text("OFF",45,3, 1);
  }
} while(1);                                    // Endless loop

}

 
Attachments
push button.rar
this is a pic of my button connection
(539.73 KiB) Downloaded 355 times

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Sat Jun 11, 2011 10:17 am

Without fully understanding miKroC syntax all I can suggest is what happens if you change your bit of code from this:

Code: Select all

  if (Button(&PORTA, 0, 1, 1)) {               // Detect logical one    if button is high set oldstate to 1
    oldstate = 1;                              // Update flag
    Glcd_Write_Text("ON",45,3, 1);
  }
  if (oldstate && Button(&PORTA, 0, 1, 0)) {   // Detect one-to-zero transition   if 1 and aero button has been released   invert output at C
    PORTC = ~PORTC;                            // Invert PORTC
    oldstate = 0;                              // Update flag
    Glcd_Write_Text("OFF",45,3, 1);
  }
To this?:

Code: Select all

 if (Button(&PORTA, 0, 1, 1)) {               
    //oldstate = 1;                 
    Glcd_Write_Text("ON",45,3, 1);
  }
  if (Button(&PORTA, 0, 1, 0)) {   
    PORTC = ~PORTC;                            
    //oldstate = 0;                             
    Glcd_Write_Text("OFF",45,3, 1);
  }

User avatar
captalex
decided to stick around...
decided to stick around...
Posts: 28
Joined: Mon Mar 21, 2011 3:00 am
Contact:

Re: Button Interfacing

Post by captalex » Sat Jun 11, 2011 8:04 pm

Yay guys, i did it!! , i connected one leg of the button to ground as you suggested, i then connected the other leg to PORT A + a 10k resistor on this leg goes to +5v , i'm just happy:D

i wrote new code, and scrapped the mikroc Button function altogether.
thanks guys for your help. this is the code.

Code: Select all


 #include "button_Control.h"

#define Pressed 0
void main()
{

      ADCON1 = 0x0F;      // Set AN pins to Digital I/O
      Glcd_Init(&PORTB, 0, 1, 2, 3, 5, 4, &PORTD);  // (CONTROL PORT,cs1,cs2,(d/i)/rs),r/w,rst,en,DATAPORT)
      Glcd_Fill(0x00);  //clear  screen
      
TRISC = 0; // PORTC outputs
PORTC.F2 = 0; // Turn OFF all LEDs   on portC2
TRISA.F0 = 0xFF; // RA0 input

      for(;;) // Endless loop
      {
      if(Switch_up != Pressed) // Is switch pressed ?
          {
           Glcd_Write_Text("OFF",45,3, 1); // Turn OFF LED
           PORTC.F2=0;          // Turn ON  LED
           Delay_us(1000); // Delay
          }
      else
      {
          Delay_us(1000); // Delay 3 second
          PORTC.F2=0xFF;          // Turn ON  LED
          Glcd_Write_Text("ON",45,3, 1);
          Glcd_Fill(0);
      }
      }
}



and for the button header file

Code: Select all

    

/* header file for the button presses, must be added in game*/

#define Switch_up PORTA.F0
#define Switch_right PORTA.F1
#define Switch_down PORTA.F2
#define Switch_left PORTA.F3
#define Switch_Start PORTA.F4


...

User avatar
captalex
decided to stick around...
decided to stick around...
Posts: 28
Joined: Mon Mar 21, 2011 3:00 am
Contact:

Re: Button Interfacing

Post by captalex » Sun Jun 12, 2011 1:26 am

now guys, i want to make a switch statement loop, that checks what button was pressed and returns a specified action for it. e.g if up is presses move pixel up 2 pixels. this is my code

Code: Select all


 int Button=1;
 switch (Button)
 {
     case Switch_up:    head_y--; break;
     case Switch_right: head_x++; break;
     case Switch_down:  head_y++; break;
     case Switch_left:  head_x--; break;
     case Switch_Start: begin+++ break;

 }

do help.

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Sun Jun 12, 2011 6:49 am

captalex wrote:Yay guys, i did it!! , i connected one leg of the button to ground as you suggested, i then connected the other leg to PORT A + a 10k resistor on this leg goes to +5v
...
Im sure thats what I said to do in the previous post above?

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Sun Jun 12, 2011 6:57 am

captalex wrote:now guys, i want to make a switch statement loop, that checks what button was pressed and returns a specified action for it. e.g if up is presses move pixel up 2 pixels. this is my code

Code: Select all


 int Button=1;
 switch (Button)
 {
     case Switch_up:    head_y--; break;
     case Switch_right: head_x++; break;
     case Switch_down:  head_y++; break;
     case Switch_left:  head_x--; break;
     case Switch_Start: begin+++ break;

 }

do help.

Why not use a IF statement?

Code: Select all

      for(;;) // Endless loop
      {
      if(Switch_up != Pressed)           
          {
           // do what you want when this button is pressed
          }
      elseif (Switch_down != Pressed) 
      {
       // do what you want when this button is pressed
      }
      elseif (Switch_left!= Pressed) 
      {
       // do what you want when this button is pressed
      }
      elseif (Switch_right != Pressed) 
      {
       // do what you want when this button is pressed
      }
      }

User avatar
captalex
decided to stick around...
decided to stick around...
Posts: 28
Joined: Mon Mar 21, 2011 3:00 am
Contact:

Re: Button Interfacing

Post by captalex » Sun Jun 12, 2011 9:02 am

bitfogav wrote:
captalex wrote:now guys, i want to make a switch statement loop, that checks what button was pressed and returns a specified action for it. e.g if up is presses move pixel up 2 pixels. this is my code

Code: Select all


 int Button=1;
 switch (Button)
 {
     case Switch_up:    head_y--; break;
     case Switch_right: head_x++; break;
     case Switch_down:  head_y++; break;
     case Switch_left:  head_x--; break;
     case Switch_Start: begin+++ break;

 }

do help.

Why not use a IF statement?

Code: Select all

      for(;;) // Endless loop
      {
      if(Switch_up != Pressed)           
          {
           // do what you want when this button is pressed
          }
      elseif (Switch_down != Pressed) 
      {
       // do what you want when this button is pressed
      }
      elseif (Switch_left!= Pressed) 
      {
       // do what you want when this button is pressed
      }
      elseif (Switch_right != Pressed) 
      {
       // do what you want when this button is pressed
      }
      }

hey bitfogav,
an if statement is good but i want to wrap them all into a single function say (button_check)such that when that function is called, all these conditions are checked accordingly.
i 'll try your if code. and yes it was your button picture that got the buttons working.
thanks man.

User avatar
bitfogav
Moderator
Moderator
Posts: 908
Joined: Sun Mar 28, 2010 9:03 pm
Location: United Kingdom
Contact:

Re: Button Interfacing

Post by bitfogav » Mon Jun 13, 2011 2:04 am

Well if its any good this is a small C program I made for AVR C: I used one button and 3 leds, when I pressed the button I wanted to use a Case (switch) statement to select which led to turn on.

Code: Select all

 
#define BIT(x) 	(1 << (x)) 
#define SETBITS(x,y) 	((x) |= (y)) 
#define SETBIT(x,y) 	SETBITS((x), (BIT((y)))) 
#define BITVAL(x,y) 	(((x)>>(y)) & 1) 

// include the avr library
#include <avr/io.h>
#include <util/delay.h>

// Delay function 
void delayms(uint16_t millis) 
	{
	while (millis) 
	{
		_delay_ms(1);
		millis--;
	}
}

// Main Program
int main( void ) 
	{

	DDRC |= 0xFF;				// set ALL PORTC Outputs
	DDRD |= 0xFF;				// set ALL PORTD Outputs
	DDRB = 0b00000001;			// set ALL PORTB Inputs except BIT 0 (Output)
	
	PORTC |= 0x00;				// clear PORTC pins, LOW	
	PORTD |= 0xFF;				// set PORTD pins, HIGH

	SETBIT(PORTB,0);			// power led ON


	unsigned char buttonCount = 0;

	// while loop
	while ( 1 ) 
	{
			// If the button is pushed 
		    // then increment our buttonCount variable

			if (BITVAL(PINB,1) == 0)
		    {
				buttonCount++;		// increment out variable counter
				delayms(100); 		// button debounce

				if (buttonCount == 4)	// if our variable = 4 then reset it
					{
						buttonCount = 0;	// reset our variable
					}
		    }
	
				switch (buttonCount)			// switch statements
				{	
					case 0:
						PORTC = 0;				// Clear PORTC
						break;					// break forces an exit from the statement body
					case 1:
						SETBIT(PORTC,1);		// set Led on PC1
						break;					// break forces an exit from the statement body
					case 2:
						SETBIT(PORTC,3);		// set Led on PC3
						break;					// break forces an exit from the statement body
					case 3:
						SETBIT(PORTC,5);		// set Led on PC5
						break;					// break forces an exit from the statement body
				}
					
	}
	return 0;
}

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest