CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

High accuracy SRF04 Sonar distance chip for remote RS232

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Arizona Chris



Joined: 20 Dec 2014
Posts: 69
Location: Arizona

View user's profile Send private message Visit poster's website

High accuracy SRF04 Sonar distance chip for remote RS232
PostPosted: Fri Sep 04, 2015 7:47 pm     Reply with quote

Greetings all,

Been doing a lot of work with remote sensors that take the computational loading off the main processor to keep my ROM space in check. This one uses a PIC16F628 for the sensor chip, and here I am using as an example to send it to a 16F887 chip. I can use this PIC now that I have my wonderful Mach X programmer! ;)

The key here is to account for what happens when a sensors 232 data stops transmitting due to a fault. the getc command will of course wait forever for a 232 input, and your main processor locks up. But by using the function khbit we can prevent this. I set a half second delay in if no 232 input is recieved. I purposly used a non UART input to show that you can have many sensors on one master chip and do it with a software 232. Thanks for looking.

You can see schematics, photos of the setup, and layouts on my web page here:

http://www.schursastrophotography.com/PICprojects/SonarChip090315.html

First the sonar chip code

Code:


//****************************************************************************
//Chris Schur
//(Sonar Chip 16F628)
//Date:  8/23/15
//****************************************************************************

/*Description of this Program:

This program sends raw serial data at 9600kb out to be reciveved by the main
processor every 100ms. */


//I/O Designations ---------------------------------------------------
// RA0:  sonar TRIG Output
// RA1:  sonar Pulse Input
// RA2: 
// RA3: 
// RA4:  (Open Collector output)
// RA5:  (MCLR)
// RA6:  Xtal  Output
// RA7:  Xtal  Input

// RB0: rs232 output to main uC
// RB1:  GREEN LED output
// RB2:  BLUE LED output
// RB3: 
// RB4: 
// RB5: 
// RB6: 
// RB7: 


//--------------------------------------------------------------------

//Include Files:
#include <16F628.h>  //Normally chip, math, etc.  used is here.

//Directives and Defines:
//#device ADC=10  //Set ADC when used to 10 bit = 0 - 1023
#fuses NOPROTECT,HS,NOWDT   //xtal is used
#use delay(crystal=10MHz)   //xtal speed
#use fast_io(ALL)          //must define tris below in main when using this

//for LCD:
//#use rs232(baud=9600, xmit=Pin_B3, bits=8, parity=N,stream=SERIALNH)
//for data out to main processor:
#use rs232(baud=9600, xmit=Pin_B0, bits=8, parity=N,STREAM=SONAR)


//****************************************************************************
//Global Variables:
int16  sonarmeas = 0;     //distance in inches from internal horns 
float sonardist = 0;
int highbyte,lowbyte;   //high byte and low byte for serial data

//****************************************************************************
 
   
//Functions/Subroutines, Prototypes:

int16 sonar1 (int16 sonarpulse, int16 sonartime, int16 d); //get sonar dist.

//****************************************************************************
//-- Main Program
//****************************************************************************

void main(void) {

   // Set TRIS I/O directions, define analog inputs, compartors:
      set_tris_A(0b01111110);
      set_tris_B(0b11110000);
     
      //(analog inputs digital by default) 

   //Initialize variables and Outputs:  --------------------------------------
   output_low(Pin_B0);  //status off
   output_low(Pin_B1);
   output_low(Pin_B2);
   output_low(Pin_B3);
   
   //Setup for timers, PWM, and other peripherals:
   
   //----------------------------------------------------------------

//MAIN LOOP:

while (true)   {

//get sonar current dist:
sonarmeas = sonar1(0,0,0);  //call up sonar1 function, variables start at 0
//sonardist = (float) sonarmeas / 155;  //convert to inches-change typedef

//Next send the raw measurement data out serially:
//Convert to two 8 bit integers to send:
lowbyte = MAKE8(sonarmeas,0);
highbyte = MAKE8(sonarmeas,1);

delay_ms(100);     //space between trig pulses

//trig pip for oscilloscope  to see data clearly
output_high(Pin_B2);
delay_us(10);
output_low(Pin_B2);

//send data serially:
   fputc(lowbyte,SONAR);
   //delay_ms(5);
   fputc(highbyte,SONAR);
   //delay_ms(10);
   

    } 
 
}

//********* Functions which have prototypes at top of program ****************
int16 sonar1 (int16 sonarpulse, int16 sonartime, int16 d)  {

setup_timer_1( T1_INTERNAL | T1_DIV_BY_2 );//must be inside function!!!!!

//max 52.6ms  = 65000 x .8uS res per count

output_high(Pin_A0);   //send trig pulse
delay_us(10);
output_low(Pin_A0);

delay_us(200); //this delay is added to end 70uS before the rising edge of echo
         
//start isr to time out if no echo:
SET_TIMER1(0);      //reset to zero on timer counter.
//clear_interrupt (INT_TIMER1);  //you must do this or it will have int allready.
//enable_interrupts (INT_TIMER1);  //turn on TIMER1 interrupt

//now look for L to H transition:
while (input(Pin_A1) == 0);  //wait for 0 to 1

//reset timer:
SET_TIMER1(0);      //reset to zero on timer counter.

//now look for H to L transition:
while (input(Pin_A1) == 1);  //wait for 1 to 0

//turn off isr:
//disable_interrupts (INT_TIMER1);  //turn off TIMER1 interrupt

sonarpulse = get_timer1();
sonartime = sonarpulse * .8;  //actual uS pulse width

if (sonartime > 18000)  //max range is 18ms = 116" = 9.7 feet.
      sonartime = 18000;    //set to max if beyond range.
     
//d = sonartime / 155;   //18000/155= 116;

return sonartime;

}




Next here is the reciver code on an 887 chip

Code:

//****************************************************************************
//Chris Schur
//(sonar recieve 16F887)
//Date:  8/28/15
//****************************************************************************

/*Description of this Program:

This short program recieves the 9600 kb serial data from the sonar chip and converts
it to a distance in inches with two decimal places, then sends it to the serial LCD.*/


//I/O Designations ---------------------------------------------------
// RA0:  (AN0)  Sonar serial data input
// RA1:  (AN1)
// RA2:  (AN2)
// RA3:  (AN3)
// RA4:  (Open Collector output)
// RA5:  (AN4)
// RA6:  OSC OUT
// RA7:  OSC IN

// RB0:  (AN12,EXT INT)  Status LED output
// RB1:  (AN10)  LCD output
// RB2:  (AN8) 
// RB3:  (AN9)
// RB4:  (AN11)
// RB5:  (AN13)
// RB6: 
// RB7: 

// RC0: 
// RC1: 
// RC2: 
// RC3:  (SCLK)
// RC4:  (SDA)
// RC5: 
// RC6: 
// RC7:

// RD0:
// RD1:
// RD2:
// RD3:
// RD4:
// RD5:
// RD6:
// RD7:

// RE0:   (AN5)
// RE1:   (AN6)
// RE2:   (AN7)
// RE3:   (MCLR INPUT - Pull High)

//--------------------------------------------------------------------

//Include Files:
#include <16F887.h>  //Normally chip, math, etc.  used is here.

//Directives and Defines:
#device ADC=10  //Set ADC when used to 10 bit = 0 - 1023
#fuses NOPROTECT,HS,NOWDT   //xtal is used
#use delay(crystal=10MHz)   //xtal speed
#use fast_io(ALL)          //must define tris below in main when using this

//for LCD:
#use rs232(baud=9600, xmit=Pin_B1, bits=8, parity=N,stream=SERIALNH)

//For reciving sonar data on pin A0:
#use rs232(baud=9600, rcv=Pin_A0, bits=8, parity=N, DISABLE_INTS,stream=SONAR)
//Note: the "disable_ints is critical, turns off constant barrage of interrupts
//during the aquisition of data in the get command so timing is not affected.

//NO_ANALOGS is default in device file...(All I/Os are digital)


//***Global Variables:********************************************************
int16  sonarmeas = 0;     //distance in inches from internal horns 
float sonardist = 0;
int highbyte,lowbyte;   //high byte and low byte for serial data
int1 sonarbit;  //incoming data verification bit
int16 sonartimeout;  //counts of kbit delay increrments

//***Functions/Subroutines, Prototypes:***************************************
//Clears LCD Display:
void LCDCLR()  {
   fputc(0xFE,SERIALNH);   //Command Prefix
   fputc(0x51,SERIALNH);   //Clear screen
}

//Sets LCD to line 2 start point
void LCDLN2()  {
   fputc(0xFE,SERIALNH);   //Command Prefix
   fputc(0x45,SERIALNH);   //set cursor command
   fputc(0x40,SERIALNH);   //Set cursor to next line, pos 40 = start line 2
}

void GETSONAR(void);

//****************************************************************************
//***-- Main Program*********************************************************

void main(void) {

   // Set TRIS I/O directions, define analog inputs, compartors:
      set_tris_A(0b10111111);
      set_tris_B(0b11111100);
      set_tris_C(0b11111111);
      set_tris_D(0b11111111);
      set_tris_E(0b1111);

   //Initialize variables and Outputs:  --------------------------------------
 
   
   //Setup for timers, PWM, and other peripherals:
   
   //----------------------------------------------------------------



//Main Program


while (true)   {

GETSONAR();  //go get sonar data serially
     
  LCDCLR();   //clear screen
   delay_ms(10);
   fprintf(SERIALNH,"%f"sonardist);  //NOTE: %Lu in command is int16 only output
   delay_ms(250);
 
 output_high(Pin_B0);
 delay_ms(25);
 output_low(Pin_B0);
 delay_ms(25);

    }  //while
 
}  //main

//********* Functions which have prototypes at top of program ****************

void GETSONAR(void)  {
//test loop to see if data has come in lasting maximum of 1/2 second:

sonartimeout = 0;  //reset timeout

while (!kbhit(SONAR) && (++sonartimeout < 50000))  //half second wait IF NO SIGNAL
   delay_us(10);
   
if (kbhit(SONAR))  {   //We have a signal
   lowbyte = fgetc(SONAR);
   highbyte = fgetc(SONAR);
   sonarmeas = MAKE16(highbyte,lowbyte);  //RAW
   sonardist = (float) sonarmeas / 155;  //inches with 2 decimals
      }
}   

Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group