0

I am working on distance sensor with PIC16F877A.
I am using MPLAB IDE AND XC8 compiler.
My goal is to gradually turn on the right leds at certain distance levels, but the leds are blinking unstable. What am I doing wrong? distance/5

  • When it measures 5 cm, it is 5/5 and the result is 1 and 1 led is on.
  • When it measures 10 cm, it is 10/5 and the result is 2 and 2 leds are on.
  • When you measure 15 cm, it is 15/5 and the result is 3 and 3 LEDs are on.
  • When you measure 20 cm, it is 20/5 and the result is 4 and 4 leds are on.
  • If the distance is less than 5 cm or above 20 cm, no led lights are on

https://i.stack.imgur.com/fFKQg.png

#include <xc.h>
#include <pic16f877a.h> 
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
#define _XTAL_FREQ 4000000
#define trigger RC2
#define echo RC3

int calc_distance();

int calc_distance()
{
    int distance=0;
     
    trigger=1;
    __delay_us(10);
    trigger=0;
    
    while(!echo); // normally the echo pin is logic 0. If we toggle the zero and throw it into the while, it returns idle until the echo arrives (until the signal becomes logic 1).
    TMR1ON=1;//In the upper loop, while returning the command empty, echo comes and exits the upper loop and timer1 is activated.
    
    while(echo);
    TMR1ON=0;//
 
  distance=TMR1/58;
  return distance;
    
}



void main(void)
{
 
  int dist=0; // Create Distance Variable
  
 
  TRISB = 0x00;  // Set PORTB To Be Output Port (All The 8 Pins)
  
  PORTB = 0x00;  // Set PORTB To Be LOW For initial State
 
  TRISC2 = 0;     // Set RC2 To Be Output Pin ( Trigger )
  RC2 = 0;
  
  TRISC3 = 1;   // Set RC3 To Be Input Pin ( Echo )
  
  //--[ Configure Timer Module To Operate in Timer Mode ]--
  // Clear The Pre-Scaler Select Bits
  T1CKPS0=0;
  T1CKPS1=0;
  
  TMR1CS=0;// Choose The Local Clock As Clock Source
  
  
  while(1)
  {
    calc_distance();
    dist = calc_distance()/5;
    if(dist==1)
    {PORTB = 0x01; __delay_ms(50);}
    if(dist==2)
    {PORTB = 0x03; __delay_ms(50);}
    if(dist==3)
    {PORTB = 0x07; __delay_ms(50);}
    if(dist==4)
    {PORTB = 0x0F; __delay_ms(50);}
    else
    {PORTB = 0x00; __delay_ms(50);}
  }
  return;
}
tolik518
  • 119
  • 2
  • 14
Electronx
  • 103
  • 4
  • Hello electronx, your code does not account for any uncertainty. The real world is not nearly as certain as your code expects it to be, unfortunately. I would advise you to take `distance=TMR1` instead of dividing by 58 and then account for some uncertainty in your measurements: instead of comparing `if(dist==1)` do something like `if((dist>=40) && (dist<=75))` etc. – Marcos G. Nov 13 '21 at 16:42
  • In addition to ADC jitter and uncertain measurements, you can't really troubleshoot this without the hardware in mind. How is the sensor connected and how do you supply at etc. That's not a question for this site but for https://electronics.stackexchange.com – Lundin Nov 15 '21 at 09:38
  • Thanks for your suggestion Marcos, I understand the situation, but I'm still having trouble running the simulation. Sorry for posting in the wrong place, by the way. – Electronx Nov 15 '21 at 22:42

0 Answers0