• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16f690, initialisation of ports, LEDS,reading from a pin

Status
Not open for further replies.
PIC16f690, initialisation of ports, LEDS,reading from a pin

I want an LED connected to pin RAO to glow if pin RA1==0

when i run my code the LED keeps pulsing on and off regardless of what value RA1 equals to.

could someone plz help me. Thanks

Code:
#include <pic.h>
#include "pic.h"
#include "delay.h"
#include "math.h"
#include <stdio.h>
#include <stdlib.h>

void init(void)
{  
	TRISB=0x00; 
	TRISC=0xFC;
	ANSEL=0;        // Set inputs to digital
       TRISA=0x02;	//making pin RA1 input
}

void main(void)
{
    init();	// initialise I/O ports, LCD
    while(1)                        //  Loop forever
  {

    if(RA1==0)          		//if receiver detects something then output is active low
      		{PORTA=0x01;}	//light up led connected to RA0 if detect object
    else 
      		{PORTA=0x00;}	//dont light led if no detection
  } 
}
 

be80be

Well-Known Member
He is toggling the whole porta and hasn't set porta up right
What C are you using ?
 
im a "she" hehe. im using hi-tech c pic lite in mplab. Im a beginner. Plz assist me.
 
Last edited:

kpatz

New Member
Try this:

Code:
#include <pic.h>
#include "pic.h"
#include "delay.h"
#include "math.h"
#include <stdio.h>
#include <stdlib.h>

void init(void)
{  
	TRISB=0x00; 
	TRISC=0xFC;
	ANSEL=0;        // Set inputs to digital
       TRISA=0x0A;	//making pin RA1 and RA3 input (RA3 is always an input)
}

void main(void)
{
    init();	// initialise I/O ports, LCD
    while(1)                        //  Loop forever
  {

    if(RA1==0)          		//if receiver detects something then output is active low
      		{RA0=1;}	//light up led connected to RA0 if detect object
    else 
      		{RA0=0;}	//dont light led if no detection
  } 
}
By using RA0 instead of PORTA you're just setting the one bit for your LED.

Also, what do you have connected to RA1? If it's a switch or button, you should use a pull-up resistor, or the built-in weak pullup on RA1, which you can enable by adding to your init() function:

Code:
  WPUA1 = 1;
  RABPU = 0;
 

be80be

Well-Known Member
This code works if you set the hardware up right.
Code:
#include <pic.h>

void init(void)
{  
	TRISA=0x2;
	TRISB=0x00; 
	TRISC=0x00;
	ANSEL=0;        // Set inputs to digital
}

void main(void)
{
    init();	// initialise I/O ports, LCD
    while(1)                        //  Loop forever
  {

    if(RA1==0)          		//if receiver detects something then output is active low
      		{PORTA=0x01;}	//light up led connected to RA0 if detect object
    else 
      		{PORTA=0x00;}	//dont light led if no detection
  } 
}
Here how i set it up
 

Attachments

be80be

Well-Known Member
To me this looks better
Code:
#include <pic.h>

void init(void)
{  
	TRISA=0x2;
	TRISB=0x00; 
	TRISC=0x00;
	ANSEL=0;        // Set inputs to digital
}

void main(void)
{
    init();	// initialise I/O ports, 
    while(1)                        //  Loop forever
  {

    if(RA1==0)          		//if receiver detects something then output is active low
      		{RA0=1;}	//light up led connected to RA0 if detect object
    else 
      		{RA0=0;}	//dont light led if no detection
  } 
}
 
Last edited:
sorry didnt respond quicker, i was learning for a test which i wrote 2day. RA1 has an infrared receiver module(TSOP48) connected to it. The output is active low. I never connect a switch there. I tried your code Kpatz but the LED is still pulsing continuously. thanks Be80be and Kpatz for taking time to try and help me.
 
Last edited:

Gayan Soyza

Active Member
Hey fantabulous68 I thought you have connected an IR module on your input.Of course it will toggle when it receives IR pulses :)

If you are checking from a switch don't forget to put a pull up resister on the input pin like 4.7K.
 
Last edited:
My design is an infrared liquid level detector. Im in the beginning stages of my design. I want to get the led indicator working for now. The hardware for my proximity detection circuit is working. When an object is detected the receiver IC outputs a low which is fed INTO pin RA1. i want an LED connected to RA0 to glow when detection occurs. All the LCD functions work.

Im having some problems with my code. I suspect the problem lies in my init function and main program. tink my initialisation of portA is wrong and maybe the order in which i call ledindicator function.



1) The LEDindicator function doesnt work when i join it as a entire program with the LCD funtion. It only works separately. I need it to work together

Please assist me in getting the code working. Thanx

yeah thanks Gayan Soyza, i realised that when the microcontroller function generates 40KHz, the LED blinks on and off real fast HOWEVER, with the NEW code that im using below. The LED is permanently ON at all times. i only want the led to glow when an object is detected. eg if detect object then LED glows, if dont detect then led doesnt glow. i dont want the led permanently on.. What should i do? im generating a 40khz pulse at RA2 and that is an output from the microcontroller. The receiver module is connected to RA1. when it detects an object it outpus a low which is fed into the microcontroller. The LED is connected to RA0.


Code:
#include <pic.h>
#include "pic.h"
#include "delay.h"
#include "math.h"
#include <stdio.h>
#include <stdlib.h>
 
void FloatToStr(float , char[]);
void DelayMs(unsigned char);
void lcd_cmd(unsigned char);
void lcd_data(unsigned char); 
void lcd_clear(void);
void lcd_puts(const char[]);
void lcd_goto_L1(void);
void lcd_goto_L2(void);
void lcd_cursor(unsigned char);
void lcd_init(void);
void enable_interrupt(void);
void interrupt isr(void);
void calc_distance(void);
void init(void);
void read_input_sw(void);
void home_screen(void);
void _40KhzTransmit(void); 
void IndicatorLED(void);

#define LCD_RS RC0		//LCD RS pin
#define LCD_EN RC1		//LCD EN pin
#define LCD_STROBE()	LCD_EN = 1; asm("nop"); asm("nop"); LCD_EN = 0

char input_sw;
unsigned char i,j,k;
char temp[8];

///////////////////////CONVERT FLOAT TO STRING///////////////////
// This function was taken from the CAVR library. It was modified slightly
// to suit our design.
void FloatToStr(float n, char str[])
{
float scale;
unsigned char d,f;
f=0;i=0;
if (n<0.0) {n=-n; str[f]='-'; f++;};
n=n+0.005;
scale=1.0;
while (n>=scale) {scale=scale*10.0; ++i;};
if (i==0) {str[f]='0'; f++;}
else
while (i--)
	  {
      scale=floor(0.5+scale/10.0);
      d=(unsigned char) (n/scale);
      str[f]=d+'0';
      n=n-scale*d;
	  f++;
      };

str[f]='.';
f++;
for (j=0;j<=1;j++) //2 decimal points
      {
      n=n*10.0;
      d=(unsigned char) n;
      str[f]=d+'0';
      n=n-d;
	  f++;
	  };
str[f]='\0';
}
///////////////////END CONVERT FLOAT TO STRING///////////////////

/////////////////////////////DELAY///////////////////////////////
void DelayMs(unsigned char cnt)
{
#if	XTAL_FREQ <= 2MHZ
	do {
		DelayUs(996);
	} while(--cnt);
#endif

#if    XTAL_FREQ > 2MHZ	
	unsigned char	p;
	do {
		p = 4;
		do { 
			DelayUs(250);
		} while(--p);
	} while(--cnt);
#endif
}

void DelayS(unsigned char cnt)
{
	for (j=0; j<(cnt*10); j++)
		DelayMs(100);
}
///////////////////////////DELAY END/////////////////////////////

//////////////////////////////LCD SETUP//////////////////////////
/* send a command to the LCD */
void lcd_cmd(unsigned char c)
{
	DelayMs(20); //wait for LCD to be ready
	LCD_RS = 0;	 //write instruction
	PORTB = (c & 0xF0); //load upper nibble on LCD data lines
	LCD_STROBE(); //send instruction to LCD
	PORTB = ((c << 4) & 0xF0); //load upper nibble on LCD data lines
	LCD_STROBE(); //send instruction to LCD   	
}

/* send data to the LCD */
void lcd_data(unsigned char c)
{
	DelayMs(20); //wait for LCD to be ready
	PORTB = 0x00;
	LCD_RS = 1; //write data
    PORTB |= (c & 0xF0); //load upper nibble on LCD data lines     
	LCD_STROBE(); //send instruction to LCD
	PORTB &= 0x00; //load upper nibble on LCD data lines
	PORTB |= ( (c << 4) & 0xF0); 
	LCD_STROBE(); //send instruction to LCD
}

/*Clear the LCD*/
void lcd_clear(void)
{
	lcd_cmd(0x01); //command to clear LCD
}

/*write a string of chars to the LCD*/
void lcd_puts(const char s[])
{
	j = -1;
	while(s[++j]!=('\0')) // send characters until null character reached
		lcd_data(s[j]);
}

/*go to beginning of line 1*/
void lcd_goto_L1(void)
{
	lcd_cmd(0b10000000); // command to go to line 1
}

/*go to beginning of line 2*/
void lcd_goto_L2(void)
{
	lcd_cmd(0b11000000); // command to go to line 2
}

/*move cursor "x" positions to the right*/
void lcd_cursor(unsigned char x)
{
	lcd_cmd(((x)&0x7F)|0x80); 
}

/*initialise the LCD - put into 4 bit mode*/
void lcd_init(void)
{
	LCD_RS = 0;	
	LCD_EN = 0;
	DelayMs(20); //wait for LCD startup
	lcd_cmd(0x28);	// 4-bit mode
	lcd_cmd(0x08);	// display off
	lcd_cmd(0x01);	// clear display
	lcd_cmd(0x0C);	// disp. on, cursor off, cursor blink off
	lcd_cmd(0x06);	// entry mode
	lcd_cmd(0x80);  // initialise DDRAM address to zero
}
//////////////////////////LCD SETUP END//////////////////////////

void init(void)
{ 
	OSCCON|=0x60; //set fosc to 4Mhz
	TRISB=0x00; 
	TRISC=0xFC;
	ANSEL=0;	// 
	TRISA=0x02;	//
    //ANSELH=0x00;
	lcd_init(); //call LCD initialisation
	GIE=0; //disable global interrupt
}
 
  
void home_screen(void)
{
	lcd_clear();
	lcd_goto_L1();
	lcd_puts("INFRARED LIQUID"); //home screen message (line 1)
	lcd_goto_L2();
	lcd_puts("LEVEL DETECTOR"); //home screen message (line 2)

}

void _40KhzTransmit(void)
{	
	int t=0;
	int cnt=0;
	while(cnt<20)
		{	if (t==0)
			{
				PORTA=PORTA^0x04;  //toggles RA2
				DelayUs(13);
				cnt++;
				t=1;
			}
			else if (t==1)
			{	
				
				PORTA=PORTA^0x04;
				DelayUs(12);
				cnt++;
				t=0;
			}
		}
}

void IndicatorLED(void)
{ 


    while(1)                        //  Loop forever
  {


    if(RA1==0)          	//if receiver IC TSOP48 at pin RA1 detects something then output is active low
      		{PORTA=0x01;}	//light up led connected to RA0 if detect object
    else 
      		{PORTA=0x00;}	//dont light led if no detection

  } 
}

void main(void)
{
	init();	// initialise I/O ports, LCD
	while (1)
	IndicatorLED();
	home_screen();
	
}
 
Last edited:
i got it to do what i wanted. It just had to swap the order of the two functions in my main program. YAY :). Im a happy girl now

im going to start working on my timer 1 code. i need the time interval between the reflected and detected infrared light in order to calculate distance from object. :)
 

birdman0_o

Active Member
Let's do some theoretical;

Assuming the 16f690 is running at 20Mhz, and then using timer1 is activated after 1 cycle, that would be 1/5Mhz which is 200ns

Light travels at 300 000km/s
Therefore the minimum distance would be 60 m total (there and back) if you assume the LED can turn on and off within 1 cycle which I don't think it can :)
 
Last edited:
Try a Sharp rangefinder instead
im not allowed to use a sharp range finder. I have to design an infrared liquid level detector for my design course.
 
Last edited:
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top