• AVR Freaks

Hot!Using PIC16(L)F15323 with HC-SR04 sensor

Author
Christopher_Ash
New Member
  • Total Posts : 14
  • Reward points : 0
  • Joined: 2019/01/31 07:08:56
  • Location: 0
  • Status: offline
2019/02/25 16:06:30 (permalink)
0

Using PIC16(L)F15323 with HC-SR04 sensor

Hello,
   I am trying to create an Ultra Sonic sensor using a PIC16LF15323 using a HC-SR04. It currently is not working as the only value I am getting from my circuit is 0. I assume my problem is a configuration problem as I have gotten this code to work on a PIC16LF877A. I am using I2C to read the value from the sensor (which works fine). My code is attached below. Any help that you can give is greatly appreciated. Also feel free to ask any questions or give any criticism of my work. Thank you for your time. 
 
/*
 * File: newmain.c
 * Author: Christopher
 *
 * Created on January 30, 2019, 1:00 PM
 */
// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = OFF // Clock Switch Enable bit (The NOSC and NDIV bits cannot be changed by user software)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)

// CONFIG2
#pragma config MCLRE = OFF // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will not cause a reset)

// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)

// CONFIG4
#pragma config BBSIZE = BB512 // Boot Block Size Selection bits (512 words boot block size)
#pragma config BBEN = OFF // Boot Block Enable bit (Boot Block disabled)
#pragma config SAFEN = OFF // SAF Enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block Write Protection bit (Application Block not write protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block not write protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration Register not write protected)
#pragma config WRTSAF = OFF // Storage Area Flash Write Protection bit (SAF not write protected)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/Vpp must be used for programming)

// CONFIG5
#pragma config CP = OFF // UserNVM Program memory code protection bit (UserNVM code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#define _XTAL_FREQ 12000000

#include <xc.h>


short z;
short distance;

void __interrupt() ISR(void)
{
    if(SSP1IF == 1){
        SSP1CON1bits.CKP = 0; //holds clock low
        
        if ((!SSP1STATbits.D_nA)&&(!SSP1STATbits.R_nW)){ //If last byte was Address plus write
            z = SSP1BUF; //read SSPBUF to clear BF
          
        }
        
        else if(SSP1STATbits.R_nW){
             z = SSP1BUF; //read SSPBUF to clear it
             SSPOV = 0; //clears overflow bit
             BF = 0;
             SSP1BUF = distance;
             SSP1CON1bits.CKP = 1;
             while(SSP1STATbits.BF); //waits for data to send
             
               
            
           
                
             
            }
           
    SSP1CON1bits.CKP = 1; //releases clock
    SSPOV = 0; //clears overflow bit
    SSP1IF = 0; //sets the interrupt flag back to zero
    }
    
    return;
}



void I2C_Slave_Init(short address){
    TRISAbits.TRISA4 = 1; //sets clock pin (SCL) RA4 as an input
    TRISAbits.TRISA5 = 1; //sets data pin (SDA) RA5 as an input
    SSP1STAT = 0X00;
    SSP1BUF = 0x00; //clears buffer register
    SSP1ADD = address;
    SSP1CON1 = 0b00110110; //Enables serial port (bit 6) and Releases clock (bit 5) and I2C save mode (bits 3 - 0)
    SSP1CON2 = 0b00000000;
    SSP1CON3 = 0b00000000;
   
    GIE = 1; //enables global interrupts
    PEIE = 1; //enable peripheral interrupts
    SSP1IF = 0; // sets the interrupt flag for I2C is low
    SSP1IE = 1; //enables I2C interrupts
    
    return;
    
}

void I2C_Pin_Init(){
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCK = 0x00; //unlock the peripheral select module
    RA4PPS = 0x15; //Changes the RA4 output to SCL
    RA5PPS = 0x16; //Changes the RA5 output to SDA
    SSP1CLKPPS = 0x04; //Changes the SCL input pin to RA4
    SSP1DATPPS = 0x05; //Changes the SDA input pin to RA5
    PPSLOCK = 0x55;
    PPSLOCK = 0xAA;
    PPSLOCK = 0x01; //locks the peripheral select module
    ANSELAbits.ANSA0 = 0;
    ANSELAbits.ANSA1 = 0;
    ANSELAbits.ANSA2 = 0;
    ANSELAbits.ANSA4 = 0;
    ANSELAbits.ANSA5 = 0;
    
}

void Timer_Init(){
    
    T0EN = 0; //ensures timer 0 is off
    T016BIT = 1; //ensures timer 0 is a 16bit timer
    T0CON1 = 0b01000000; //sets clock source to Fosc/4 and sychronizes the counter to the system clock with 1:1 prescaler
}

void US_Sensor_Init(){
    TRISAbits.TRISA0 = 1; //sets RA0 as an input for US sensor echo
    TRISAbits.TRISA1 = 0; //sets RA1 as an input for US sensor Trig
    PORTAbits.RA1 = 0; //ensures RA0 is low
    
}

void main(void){
    OSCFRQ = 0x04; //sets internal oscillator to 12MHz
    
    int time_us_over_3;
    int d;
                    
    I2C_Pin_Init();
    I2C_Slave_Init(0x04);
    Timer_Init();
    US_Sensor_Init();
      
    while(1){
        TMR0H = 0; //clear timer 0
        TMR0L = 0;
        PORTAbits.RA1 = 1; //Set trigger pin high
        __delay_us(110); //delay for 110us
        PORTAbits.RA1 = 0; //Set trigger pin low
        
        while(PORTAbits.RA0 == 0); //wait for echo to go high to start counting
        T0EN = 1; //start timer
        while(PORTAbits.RA0 == 1); //wait for echo to go low to stop counting
        T0EN = 0; //stop counting
        time_us_over_3 = (TMR1L | (TMR1H << 8)); //time it took for the pulse to reach back
        d = time_us_over_3 * 0.01715*3; //converting the time into distance
        if(d > 255){ //ensuring that data can be sent over one byte
            d = 255;
        }
        distance = d;
        __delay_ms(1000);
         
    }
   
    return;
}

#1

9 Replies Related Threads

    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/25 16:36:52 (permalink)
    +1 (1)
    Probably not your problem, but change every occurence of
    PORTAbits.RA1 =
    to
    LATAbits.LATA1 =
     
    Always write to LAT, read from PORT
     
    Get rid of that return at the end of the main() function.
    It's not hurting, but is totally pointless.
     
    How are you testing this?
    I see the only way to access your "distance" variable is via the I2C slave code, which means you're potentially debugging two things at once.
    I know you say the I2C is working, but have you tried running this code under a debugger?
     

    Nearly there...
    #2
    crosland
    Super Member
    • Total Posts : 1613
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 04:57:24 (permalink)
    0
    Christopher_Ash
    using a PIC16LF15323 ...  I have gotten this code to work on a PIC16LF877A. 


    Are those two PICs pin compatible? Otherwise you must have also changed some hardware.
     
    What boards are/were they on?
     
    Have you compared the datasheets and checked for subtleties in I/O setup, such as ANSEL bits?
    #3
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 05:14:14 (permalink)
    +1 (1)
    RA0 is also ICSPDAT.
    Hopefully the programmer is NOT connected while this test is being run.
     
    I would suggest changing
        T0CON1 = 0b01000000;
    to
        T0CON1 = 0b01010000;    //clock from Fosc/4, do NOT synch
    If you think about how a synchroniser works (it is basically a "D" latch), you should realise it's silly to try to synchronise a clock with itself.
     

    Nearly there...
    #4
    Christopher_Ash
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/01/31 07:08:56
    • Location: 0
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 08:32:27 (permalink)
    0
    Thank you all for your advice. @crosland The two PICs are not pin compatible. The code I placed here has already been ported for the PIC16LF15323. I may have missed some of the subtleties of porting the code such as configuration issues, which is why I asked for help with debugging it. 
     
    @qhb I am programming the PIC using a PICkit3. The programming circuit is separate from the Ultra Sonic sensor circuit. I changed the setting in T0CON1 and I am still getting the same result. I will use LEDs to debug the code because I think that it is getting stuck somewhere.
    #5
    crosland
    Super Member
    • Total Posts : 1613
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Bucks, UK
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 08:35:57 (permalink)
    +1 (1)
    I'll repeat the question, what about the hardware?
     
    That must be different if the PICs are not pin compatible.
     
    You need to give the complete picture if you want meaningful help.
    #6
    Christopher_Ash
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/01/31 07:08:56
    • Location: 0
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 09:36:43 (permalink)
    0
     @crosland The circuit I am using is the same as the the circuit I used with the other PIC the only difference is the pins that I am using to send a high to the HC-SR04 and the pin that I am using to check when the echo goes high and low.
     
    I am thinking that my problem could be 1 of 2 things:
    1) The PIC is not picking up when the echo pin goes high and low. This means that I did not set up the RA0 pin as an input correctly.
     
    2) The HC-SR04 is not seeing the triggering signal. The sensor requires a 10us TTL high for it to be triggered. In the code I have the trigger signal being sent from RA1 for 110us just incase of any timing issues. It could be that the HC-SR04 is not being triggered properly, hence why it is not sending out an echo signal. I measured the voltage output from RA1 and its is 3.2V which falls within the range of TTL high, so maybe the problem is the timing of the high?
    #7
    Christopher_Ash
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/01/31 07:08:56
    • Location: 0
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 09:48:55 (permalink)
    0
    Ok I found the problem. The code is currently stuck waiting for RA0 to go high, however the PIC is not recognising when RA0 is high. I connected the pin directly to 3.3V and the code still remains stuck waiting for RA0 to go high. So now I'm trying to figure out why it is not recognising that it is high. 
     
     
    P.S It's not that I set ANSELA = 0 after I am checking the pin to see if it is high. I tripple checked my code to make sure that I did not make the same mistake again. 
     
    post edited by Christopher_Ash - 2019/02/26 09:53:14
    #8
    Christopher_Ash
    New Member
    • Total Posts : 14
    • Reward points : 0
    • Joined: 2019/01/31 07:08:56
    • Location: 0
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 11:58:45 (permalink)
    +1 (1)
    Thank you everyone for your help. In the end I figured it out. In the 877A code I used timer 1 but when I ported the code I used timer 0 and I forgot to change this in the calculation for distance hence why I was always getting 0. My humblest apologies for this mistake and sorry for taking up your time. Thank you again for your help.
     
    This:
     time_us_over_3 = (TMR1L | (TMR1H << 8)); //time it took for the pulse to reach back


    Is supposed to be:
    time_us_over_3 = (TMR0L | (TMR0H << 8)); //time it took for the pulse to reach back

    post edited by Christopher_Ash - 2019/02/26 17:05:51
    #9
    qhb
    Superb Member
    • Total Posts : 9999
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: Using PIC16(L)F15323 with HC-SR04 sensor 2019/02/26 14:44:36 (permalink)
    0
    After fixing that, which value of T0CON1 worked (or didn't it matter?)
     

    Nearly there...
    #10
    Jump to:
    © 2019 APG vNext Commercial Version 4.5