I2c, srf02, 16f688 -> ultrasonic rangefinder


+ Reply to Thread
Results 1 to 10 of 10
  1. #1
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263

    Default I2c, srf02, 16f688 -> ultrasonic rangefinder

    I'm noodling (finally) with an SRF02 ultrasonic rangefinder, communicating via I2C with a 16F688.

    I've used a similar program for an IR rangefinder, but I can't get this to work.

    Blinky tests: Done
    SRF02 indicator: Flashes about once per second
    Scope: Shows both SDA and SCL lines active about once per second
    Ultrasonic output: The SRF02 is "pinging", tested with an ultrasonic receiver connected to the scope.

    Everything external appears to work except getting the comparison done and/or the yellow LED to so indicate

    I've tried several variations, always coming back to a straightforward adaptation of code posted by jellis00 some time ago (thread is archived).

    Where have I gone wrong?

    Code:
    @ __config _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF & _CP_OFF & _CPD_OFF
    
                                            '      INPUTS:
    MODE    VAR PORTA.3                     ' MODE jumper; default is HIGH (MODE B)
                                            '      I2C INTERFACE:
    SDA     VAR PORTA.5                     ' Serial data
    SCL     VAR PORTA.4                     ' Serial clockS                 
                                            '      OUTPUTS:
    RELAY   VAR PORTA.0                     ' Relay driver
    GLED    VAR PORTC.1                     ' LED status indicator, green
    YLED    VAR PORTC.2                     ' LED status indicator, yellow
                                            '      VARIABLES:
    KLIX    VAR BYTE                        ' Generic counter variable
    FAR     VAR BYTE                        ' Analog value, MAX setting, PORTA.1
    NEAR    VAR BYTE                        ' Analog value, MIN setting, PORTA.2
    RANGE0  VAR BYTE
    RANGE1  VAR BYTE
    
    DEFINE  ADC_BITS        8               ' Number of bits in ADC result
    DEFINE  ADC_CLOCK       3               ' Set ADC clock source to RC
    DEFINE  ADC_SAMPLEUS    25              ' Set ADC sampling time in microseconds
    
    ANSEL =%00000110                        ' Enable ADC channels AN2-AN1
    CMCON0=%00000111                        ' Disable the comparators
    OSCCON=%01100000                        ' Configure oscillator 4MHz ($60)
    TRISA =%00001110                        ' Set ports A3-A2-A1 as inputs
    TRISC =%00000000                        ' Set all ports C as outputs
    
            RELAY=0 : KLIX=0                ' Set relay LOW and clear counter value
            GLED=0  : YLED=0                ' Set LEDs to OFF 
            
            IF MODE=0 THEN                  ' Wait 5 seconds to stabilize detector
                FOR KLIX=1 TO 5             ' During this time:
                    GLED=1 : PAUSE 500      ' Show MODE A by flashing green
                    GLED=0 : PAUSE 500
                    NEXT KLIX               '  or
                ELSE                        
                FOR KLIX=1 TO 5             ' Show MODE B by flashing yellow
                    YLED=1 : PAUSE 500
                    YLED=0 : PAUSE 500              
                    NEXT KLIX              
                ENDIF   
                                            
            GLED=1                          ' Set green LED ON for "Ready"
                                            '      DETECTOR
    MAIN:   I2CWRITE SDA,SCL,$E0,0,[80]     ' Request range in inches
            PAUSE 100                       ' Wait for ranging to finish
            I2CREAD SDA,SCL,$E0,2,[RANGE1,RANGE0]   ' Read range
            ADCIN 2,FAR                     ' Get the maximum setting
            ADCIN 1,NEAR                    ' Get the minimum ("window") setting
            IF ( RANGE0 < FAR AND RANGE0 > NEAR ) THEN
                GLED=0 : YLED=1
                ELSE
                GLED=1 : YLED=0
                ENDIF
            PAUSE 1000
            GOTO MAIN 
                
            END
    Last edited by RussMartin; - 24th February 2011 at 03:22.
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

  2. #2
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Code seems OK, perhaps too short the delay between the write I2C command and the read

    Did you place the pullup resistors on the SDA and SCL lines?

    Cheers

    Al.
    Last edited by aratti; - 24th February 2011 at 05:42.
    All progress began with an idea

  3. #3
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Thanks, Al.

    Quote Originally Posted by aratti View Post
    Code seems OK, perhaps too short the delay between the write I2C command and the read.
    It's the same delay used by jellis00, but I think he was running 18F devices and I don't know at what speed. (Or if that would make a difference.)

    Did you place the pullup resistors on the SDA and SCL lines?
    Yes; per the SRF02 specifications recommendation, I used 1.8K (see the schematic).

    Russ
    Attached Images Attached Images
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

  4. #4
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Russ, I think your problem is in the this line of code:

    SCL VAR PORTA.4 ' Serial clockS

    PortA.4 is an open collector pin and I think not suitable for I2C comm.

    Try to change pin.

    Cheers

    Al.
    All progress began with an idea

  5. #5
    Join Date
    Jun 2005
    Location
    Surrey, England
    Posts
    35


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Quote Originally Posted by RussMartin View Post

    IF ( RANGE0 < FAR AND RANGE0 > NEAR ) THEN

    [/code]
    PBP evaluates expressions progressively - try using parentheses:
    IF ((RANGE0 < FAR) AND (RANGE0 > NEAR)) THEN
    I am assuming FAR is actually greater than NEAR not vice versa?
    Peter

  6. #6
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Peter, thanks for chiming in. I added the parentheses. Still nothing, but it's a good point nevertheless.

    Yes, FAR is greater than NEAR. In fact, the way I have the pots configured, NEAR can never be greater than FAR.

    I just checked again; during the 5-second "blinky" phase, the SRF02 is quiescent. It then responds by pinging on command (I can "see" the ping with an ultrasonic receiver and a scope--and it's appearing about once a second, as it should).

    Al, is there an error in the 16F688 manual? I'm looking at Table 1-1 (page 6) and it shows A4 as TTL in, CMOS out. (In fact, I can't find an OC legend anywhere on the chart!)

    I'm fairly convinced the problem is somewhere in how I'm manipulating the data, or perhaps I have misdefined something.
    Last edited by RussMartin; - 24th February 2011 at 08:47.
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

  7. #7
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    You want to write directly to ADCON1 so you have at least Fosc/8 for 4MHz.

    ADCIN doesn't do this for you - so your AD conversion clock is way too fast with ADCON1 = 0 by default.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  8. #8
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Quote Originally Posted by Bruce View Post
    You want to write directly to ADCON1 so you have at least Fosc/8 for 4MHz.

    ADCIN doesn't do this for you - so your AD conversion clock is way too fast with ADCON1 = 0 by default.
    Thanks, Bruce.

    I've used ADC with other devices (12F683; 16F88; 16F1827) and always gotten by with the RC clock.

    Can I use DEFINE ADC_CLOCK 1? Or if I use ADCON1=%00010000, do I simply omit the DEFINE?
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

  9. #9
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Hi Russ,

    DEFINE ADC_CLOCK xx only works if the clock select bits are in ADCON0, so just write directly to ADCON1 to set the conversion clock. ADCON1 = %00110000 for RC, ADCON1 = %00010000 for Fosc/8 (recommended).
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  10. #10
    Join Date
    Aug 2006
    Location
    Omaha, Nebraska USA
    Posts
    263


    Did you find this post helpful? Yes | No

    Default Re: I2c, srf02, 16f688 -> ultrasonic rangefinder

    Thanks, everyone, for the suggestions.

    After a different diagnostic strategy, I discovered I had made a really dumb mistake.

    I accidentally swapped (from a working scrap of code a few days ago on a different sensor device) my ADCIN channels. In the code I originally attached,

    ADCIN 2,FAR
    ADCIN 1,NEAR

    should have been

    ADCIN 1,FAR
    ADCIN 2,NEAR

    My apologies to all, but still, THANKS!
    Russ
    N0EVC, xWB6ONT, xWN6ONT

    "Easy to use" is easy to say.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts