View Full Version : SONAR Sensor Software Driver
MikeDubreuil
26-01-2006, 20:21
For anyone interested in using a SONAR sensor I have completed a software driver for it. If anyone has any questions feel free to post in this thread.
Once I develop a personal website I will post the software there. Until that time it can be found by using the link in this thread. SONAR_0.1.zip (http://nutrons.dbrl.net/SONAR_0.1.zip)
The introduction from the readme:
Introduction:
This source code in sonar.c and sonar.h are a driver for several consumer
available sonar ultrasonic range finder sensors. Tested to work with this
software is the Parallax Inc. PING)) Ultrasonic Rangefinder and the Vex
Robotics Ultrasonic Range Finder.
This software was written for the Innovation First Inc. Mini Robot Controller.
Unmodified this software utilizes Interrupt 1 and Timer 3. Other controllers
may be used including Innovation First Inc.'s full size robot controller as
well as other PIC microcontrollers with modifications. The documentation refers
to the controlling microcontroller simply as the controller.
This software works by triggering the sonar sensor causing it to send an
acoustic ping. Once the ping hits an object it will reflect back towards the
sensor. The sonar sensor represents the distance to the object with a pulse
width equal to the time it took for the ping to hit the object and return back.
This software measures the pulse width and converts the time to a distance in
inches.
Eldarion
29-01-2006, 14:16
Thanks for posting the driver code. I had to finnagle the timer interrupt routine a tad to get it to work on the full-size FRC, but otherwise it has made my job much easier!
Thanks! :)
Tom Bottiglieri
29-01-2006, 17:44
Yeah, thanks alot Mike. It works perfectly.
This saved me hours of coding, and I'm sure it will do the same for many others.
CronosPrime1
08-02-2006, 21:07
Why is this code so complicated? I really don't see why you need all of this. I don't know anything about programming the range finder, but it seems to me that you should just be able to send the range finder a 0 or a 1 to trigger it and then measure with a timer the time it takes for the pulse to come back. Why is there all this complicated stuff? Is it really needed? I'm not criticizing, I just want to know for my own sake.
scitobor 617
08-02-2006, 22:03
Why is this code so complicated? I really don't see why you need all of this. I don't know anything about programming the range finder, but it seems to me that you should just be able to send the range finder a 0 or a 1 to trigger it and then measure with a timer the time it takes for the pulse to come back. Why is there all this complicated stuff? Is it really needed? I'm not criticizing, I just want to know for my own sake.
I did not write the code but I have read it and it does not seem to have any unnecessary parts. In my opinion it is written very cleanly and only contains the minimum amount of code needed to correctly use an ultrasonic range finder. You are right on target about what must be done to use a range finder, however I believe once you start coding it you will have a very similar solution. The only thing that I see that can be taken out of this code is some of the error checking but error checking is good practice since it means that you have thought of and prepared for things that can go wrong.
MikeDubreuil
09-02-2006, 09:53
Why is this code so complicated? I really don't see why you need all of this. I don't know anything about programming the range finder, but it seems to me that you should just be able to send the range finder a 0 or a 1 to trigger it and then measure with a timer the time it takes for the pulse to come back. Why is there all this complicated stuff? Is it really needed? I'm not criticizing, I just want to know for my own sake.
Since I wrote it I can answer most questions you have on it. For the most part as Alan said the driver does not have any unnecessary lines of code. However, I can address some of the issues that make it a little more complicated than most pieces of software.
Two I/O pins being used- this was a necessary evil that I found while writing the software for the Parallax PING))) sensor. I just couldn't get a single I/O pin to change between an output to an input with an interrupt fast enough. I would lose the sonar sensors signal. I didn't know about the Vex Robotics range finder until after originally writing the software. The VEX and Parallax units are very similar if not identical. I think the Vex engineers may have ran into the same problem I did and decided to use two cables.
Design- There's a variable that holds the current state of the sonar and functions in the source code file to handle a hardware interrupt and a timer interrupt. The other option would have been one function which triggers the sonar sensor and then loops until the sonar sensor is finished responding. The problem with that design would be that you would be wasting processor time for around 20 mS waiting. This means no other code could be running, the input/output might not happen and the Master uP could think your user program has gone haywire and shut it down.
Any other questions, feel free to ask ;)
MikeDubreuil
18-02-2006, 23:35
I have an updated version of the SONAR software driver that supports the 2006 Robot Controller. Get it here: SONAR_0.3.zip (http://nutrons.dbrl.net/SONAR_0.3.zip)
gnormhurst
08-03-2006, 13:21
I have an updated version of the SONAR software driver that supports the 2006 Robot Controller. Get it here: SONAR_0.3.zip (http://nutrons.dbrl.net/SONAR_0.3.zip)
Thank you, thank you, thank you! for writing this code. I'm planning to try it soon (I found a VEX sonar unit at RadioShack last night).
I've been scanning the code to understand it a little. And I found something strange: at one point sonar_status is set to SONAR_REST, but there is no case statement looking for SONAR_REST. In fact, SONAR_REST appears nowhere else in the code except in the .h file where it is created.
Is SONAR_REST a remnant from a previous version? Won't the code get lost if sonar_status is set to SONAR_REST?
-Norm
MikeDubreuil
08-03-2006, 14:34
Is SONAR_REST a remnant from a previous version? Won't the code get lost if sonar_status is set to SONAR_REST?
The code doesn't get lost when the status is set to SONAR_REST. Shortly after the status is set to rest on line 206 the timer is started. In the timer interrupt service routine the status is set to SONAR_OFF. After that occurs, the sonar can be pulsed again with Ping_Sonar(). I found the rest was necessary to allow the sensor to work correctly.
I'm glad you like the software. Please let us know how your testing turns out.
gnormhurst
08-03-2006, 18:50
I'm glad you like the software. Please let us know how your testing turns out.
A couple of quick questions. I'm installing the code without the benefit of hardware to try it on (that will be in a couple of days).
In your README it says
4. Add the following code to the if block in user_routines_fast.c/InterruptHandlerLow()
else if (PIR2bits.TMR3IF && PIE2bits.TMR3IE)
{
Timer_Interrupt_Sonar();
} I did, and I think I did it correctly (code is below).
But step 3 puzzles me.
3.) Add Hardware_Interrupt_Sonar() to the if statement that handles the INT2 pin
in user_routines_fast.c/InterruptHandlerLow()
My attempt to interpret step three also appears in the code below.
Here is my modified InterruptHandlerLow (). The mods are in color.
#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD /* You may want to save additional symbols. */
void InterruptHandlerLow ()
{
unsigned char int_byte;
if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) /* The INT2 pin is RB2/DIG I/O 1. */
{
Hardware_Interrupt_Sonar(); ////// <--- added to support sonar
INTCON3bits.INT2IF = 0;
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) /* The INT3 pin is RB3/DIG I/O 2. */
{
INTCON3bits.INT3IF = 0;
}
else if (INTCONbits.RBIF && INTCONbits.RBIE) /* DIG I/O 3-6 (RB4, RB5, RB6, or RB7) changed. */
{
int_byte = PORTB; /* You must read or write to PORTB */
INTCONbits.RBIF = 0; /* and clear the interrupt flag */
} /* to clear the interrupt condition. */
// the following added to support sonar:
//
else if ( PIR2bits.TMR3IF && PIE2bits.TMR3IE )
{
Timer_Interrupt_Sonar();
}
else
{
CheckUartInts(); /* For Dynamic Debug Tool or buffered printf features. */
}
}Comments appreciated.... including comments on i/o pin conflicts that I'm not noticing... Thanks!
Instead of a new thread I'll post here. There is a new sonar ranging sensor on the market. New sonar (http://www.maxbotix.com/) The interesting points as I see it are - Nice price, narrower cone of detection, and 3 ways to interface. RS232, analog voltage and the normal pulse timing. Too late for this year but may be a worthy addition to next years sensor selection.
MikeDubreuil
10-03-2006, 13:39
Comments appreciated.... including comments on i/o pin conflicts that I'm not noticing... Thanks!
Perfect :)
jeffmorris
10-03-2006, 15:52
How do I connect the PING))) sensor made for Parallex robots to the VEX Micro Controller and program the sensor in EasyC 2.0?
gnormhurst
16-03-2006, 16:34
Perfect :)
IT WORKS! Cool. Thanks so much for the code.
NOTE: ERROR IN VEX SONAR DATA SHEET! The data sheet that comes with the VEX sonar kit has an error. It says, The connector labelled "OUTPUT" is the trigger output of the Vex microcontroller;... and The connector Labelled "INPUT" is the echo response from the ultrasonic detector; this is the line through which the Vex microcontroller receives output from the detector, ...
Well, that seemed backwards to me, but I carefully hooked up the "OUTPUT" to the digital_io_16 port on the FRC, which your code uses to signal the unit to ping, and hooked the "INPUT" to the INT2 (digital_io_1) port on the FRC. It didn't work. I checked everything else, then switched the two wires. Then it worked. THE VEX DOCUMENTATION IS BACKWARDS. The device's wire marked "output" is indeed the output of the device.
One way to tell that it's hooked up right and the software is pinging it is to hold the device up to your ear and listen to it. When I got it working I could hear a faint "tictictictic..." coming from the device. I did not hear that before I switched the wires.
Thanks again. Now I have to write new autonomous code that I can't test on the robot until we get to the next regional.
gnormhurst
06-04-2006, 15:52
Just a further update on the sonar system. We were successful in using the sonar to control our distance to the corner goal (our doors won't open if we're too close, and the balls won't go in if we're too far away). We used sonar both in autonomous and as a driver control (driver initiates "autonomous" using a button. Control is returned when the balls have been dumped or the driver hits the "abort" button.) We even got a Xerox Creativity Award for the system. :D
But here's why I'm writing this note...
We had a strange problem. The sonar system would give steady values until we enabled autonomous, and then the values would start to drop: 150, 150, 150, [start auto] 150, 150, 130, 115, 90, 75, ... All this while the robot was on blocks and unable to move!
I figured it was some bizzare resource interrupt limitation timing thing. Until I discovered that it would do this just by me running the motors. It took a mechanical engineer to put his hand on the frame and say, "I bet it's picking up vibration from the motors!" We removed the sonar unit and held it -- the problem went away. We ended up mounting the unit on a block of foam (a block we made by cutting up one of those balls from the game).
Oddly, the autonomous code seemed to work anyway. It only did this for long distances -- at short distances ( < 30" ) we didn't see this problem.
So, everyone --- be careful how you mount the sonar unit -- it can pick up vibrations and give bad readings!
Thanks again for the driver code -- we never would have been able to complete this in time without it!
-Norm
Tom Bottiglieri
06-04-2006, 15:56
Just a further update on the sonar system. We were successful in using the sonar to control our distance to the corner goal (our doors won't open if we're too close, and the balls won't go in if we're too far away). We used sonar both in autonomous and as a driver control (driver initiates "autonomous" using a button. Control is returned when the balls have been dumped or the driver hits the "abort" button.) We even got a Xerox Creativity Award for the system. :D
But here's why I'm writing this note...
We had a strange problem. The sonar system would give steady values until we enabled autonomous, and then the values would start to drop: 150, 150, 150, [start auto] 150, 150, 130, 115, 90, 75, ... All this while the robot was on blocks and unable to move!
I figured it was some bizzare resource interrupt limitation timing thing. Until I discovered that it would do this just by me running the motors. It took a mechanical engineer to put his hand on the frame and say, "I bet it's picking up vibration from the motors!" We removed the sonar unit and held it -- the problem went away. We ended up mounting the unit on a block of foam (a block we made by cutting up one of those balls from the game).
Oddly, the autonomous code seemed to work anyway. It only did this for long distances -- at short distances ( < 30" ) we didn't see this problem.
So, everyone --- be careful how you mount the sonar unit -- it can pick up vibrations and give bad readings!
Thanks again for the driver code -- we never would have been able to complete this in time without it!
-Norm
What were you trying to read a distance off when this happened? Sometimes the sensor gets screwy readings when it is pointed at a curved object. Silly sound waves.
gnormhurst
27-04-2006, 18:31
What were you trying to read a distance off when this happened? Sometimes the sensor gets screwy readings when it is pointed at a curved object. Silly sound waves.
We were pointing it at a wall in the Drexel gym. Big, flat and perpendicular to the robot's axis. The test we did of removing the sonar unit from the robot and just holding it there, an inch from where it was mounted, seemed to be conclusive proof that it was indeed vibration pickup from the robot. Further, mounting it on foam stopped the problem.
SPEAKING OF MOUNTING IT ON FOAM: be careful how you mount it to the foam. Just putting a block of foam behind the unit and screwing it down through the foam doesn't work: the screws transmit the vibration from the frame directly to the sonar unit. You must mount the unit to the foam, then mount the foam to the robot's frame. This gives isolation.
DonRotolo
27-04-2006, 21:01
Instead of a new thread I'll post here. There is a new sonar ranging sensor on the market. New sonar (http://www.maxbotix.com/) The interesting points as I see it are - Nice price, narrower cone of detection, and 3 ways to interface. RS232, analog voltage and the normal pulse timing. Too late for this year but may be a worthy addition to next years sensor selection.
Darn it, I went and started a new thread (http://www.chiefdelphi.com/forums/showpost.php?p=494309) before I saw this post!
In my defense: Gdeaver's post didn't show up on a search.
Anyway: The code to measure the pulse is very cool, but that new sensor also gives an analog voltage at 10 mV/inch - just a simple analog input and you're done...
Don
cprogrammer
14-07-2006, 19:23
This may just be on one of those days again but how do you hook up the vex sonar sensor to the EDU robot.
Mark McLeod
14-07-2006, 22:33
This may just be on one of those days again but how do you hook up the vex sonar sensor to the EDU robot.
You need to adapt the male connections on the Vex ultrasonic sensor to the male connections on the EDU. Either a female-female cable or replace the Vex ultrasonic cable ends with female connectors. You can also use those Y-cables that come in the FRC KOP each year to do the job.
Other than that you hook it up to the same digital output and interrupt input as used on the Vex.
Chermaine
19-07-2006, 02:20
I was compiling SONAR_0.3 using MPLAB C18 and it was not successful.
Followings are the errors detected from the codes in sonar.c.
At function initialize_sonar()
1) SONAR_OUTPUT_CONFIG = OUTPUT
-->symbol 'TRISJbits' has not been defined
-->struct or union object designator expected
-->lvalue required
2) SONAR_OUTPUT = 0
-->symbol 'LATJbits' has not been defined
-->struct or union object designator expected
-->lvalue required
At function ping_sonar ()
3) SONAR_OUTPUT = 1
-->symbol 'LATJbits' has not been defined
-->struct or union object designator expected
-->lvalue required
4) SONAR_OUTPUT = 0
-->symbol 'LATJbits' has not been defined
-->struct or union object designator expected
-->lvalue required
I thought maybe the problem lies with the definition in sonar.h for both SONAR_OUTPUT_CONFIG and SONAR_OUTPUT (see following 2 lines)
# define SONAR_OUTPUT rc_dig_out16
# define SONAR_OUTPUT_CONFIG digital_io_16
It seems to me that the define statements is referring to the hardware part or maybe the MPLAB C18 compiler is unable to read it?
Would anyone reading this can share which compiler they use and how to go about solving this problem?
pls help. Thank you. :)
Chermaine
29-09-2006, 23:18
I have managed to solve the previous post questions.
At present,
I have modify the software code for my project application. I am using a PIC18F452 microcontroller for the ping sensor. Everything works fine until programming the USART code. The hyper terminal characters does not change when the distance of the object changes.
Can you help me? I have a very close deadline to meet.
Follow is the code i added prior to Mike's codes:
#include <p18f452.h> // version 1.1
#include <usart.h>
#include "sonar.h"
/* Set configuration bits
* - set HS oscillator
* - disable watchdog timer
* - disable low voltage programming
*/
#pragma romdata CONFIG
_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_HS_1H,
_CONFIG2L_DEFAULT,
_CONFIG2H_DEFAULT & _WDT_OFF_2H,
_CONFIG3H_DEFAULT,
_CONFIG4L_DEFAULT & _LVP_OFF_4L,
_CONFIG5L_DEFAULT,
_CONFIG5H_DEFAULT,
_CONFIG6L_DEFAULT,
_CONFIG6H_DEFAULT,
_CONFIG7L_DEFAULT,
_CONFIG7H_DEFAULT);
#pragma romdata
int i;
int distance;
void main(void)
{
int i=0;
Initialize_Sonar();
Ping_Sonar();
Hardware_Interrupt_Sonar();
Timer_Interrupt_Sonar();
Get_Sonar_Distance();
OpenUSART (USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 129); // open USART with baud of 9600
while(i<10)
{
putrsUSART("A");
putrsUSART(distance);
putrsUSART("B");
i++;
}
}
bear24rw
30-09-2006, 00:01
Im not sure if im right about this but try this...
I put the whole thing in an endless loop..
#include <p18f452.h> // version 1.1
#include <usart.h>
#include "sonar.h"
/* Set configuration bits
* - set HS oscillator
* - disable watchdog timer
* - disable low voltage programming
*/
#pragma romdata CONFIG
_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_HS_1H,
_CONFIG2L_DEFAULT,
_CONFIG2H_DEFAULT & _WDT_OFF_2H,
_CONFIG3H_DEFAULT,
_CONFIG4L_DEFAULT & _LVP_OFF_4L,
_CONFIG5L_DEFAULT,
_CONFIG5H_DEFAULT,
_CONFIG6L_DEFAULT,
_CONFIG6H_DEFAULT,
_CONFIG7L_DEFAULT,
_CONFIG7H_DEFAULT);
#pragma romdata
int distance;
void main(void)
{
Initialize_Sonar();
while (1) // Endless loop
{
Ping_Sonar();
Hardware_Interrupt_Sonar();
Timer_Interrupt_Sonar();
distance = Get_Sonar_Distance(); // Get distance and update variable
OpenUSART (USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 129); // open USART with baud of 9600
putrsUSART("A");
putrsUSART(distance);
putrsUSART("B");
}
}
Try that and see if it works...
Good Luck
MikeDubreuil
30-09-2006, 08:11
I think you may have overlooked this section in the readme:
Software Use:
Call Ping_Sonar() to update the distance reading. Call Get_Sonar_Distance() to return the distance between the sonar sensor and an object in inches.
The functions: Hardware_Interrupt_Sonar() and Timer_Interrupt_Sonar() are only meant to be called internally in the sonar software. You only need to call two functions: Ping_Sonar() updates the distance between the sonar sensor and an object and Get_Sonar_Distance which will return the distance in inches.
I'm not familiar with your application but give this a shot. Note that I added comments about adding a time delay. It may take up to 50mS for the sonar to find an object.
]
#include <p18f452.h> // version 1.1
#include <usart.h>
#include "sonar.h"
/* Set configuration bits
* - set HS oscillator
* - disable watchdog timer
* - disable low voltage programming
*/
#pragma romdata CONFIG
_CONFIG_DECL(_CONFIG1H_DEFAULT & _OSC_HS_1H,\
_CONFIG2L_DEFAULT,\
_CONFIG2H_DEFAULT & _WDT_OFF_2H,\
_CONFIG3H_DEFAULT,\
_CONFIG4L_DEFAULT & _LVP_OFF_4L,\
_CONFIG5L_DEFAULT,\
_CONFIG5H_DEFAULT,\
_CONFIG6L_DEFAULT,\
_CONFIG6H_DEFAULT,\
_CONFIG7L_DEFAULT,\
_CONFIG7H_DEFAULT);
#pragma romdata
int i;
int distance;
void main(void)
{
int i=0;
Initialize_Sonar();
OpenUSART (USART_TX_INT_OFF &
USART_RX_INT_ON &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH, 129); // open USART with baud of 9600
Ping_Sonar();
/* You might want to consider adding a time delay here */
while(i<10)
{
distance = Get_Sonar_Distance();
Ping_Sonar();
putrsUSART("A");
putrsUSART(distance);
putrsUSART("B");
i++;
/* You might want to consider adding a time delay here */
}
}
daveydaycart
03-02-2007, 22:48
I've been trying to get this working today on the FRC Robot Controller. I've never programmed interrupts before though, so I'm at a stand-still as to what to do. I think I have the initialization for the pin driven interrupt done correctly, but I'm at a complete loss for how to get the timer working. Any help would be appreciated.
MikeDubreuil
04-02-2007, 08:04
I think I have the initialization for the pin driven interrupt done correctly, but I'm at a complete loss for how to get the timer working. Any help would be appreciated.
I'm assuming you're using MPlab and not EasyC to program your robot. Where did you get your version of the default code? Also does the particular version you are using have a name? For instance, "2007 Default Code from IFIrobotics.com" or "Camera code version 2.0 from kevin.org". A link so I can download the default code would be helpful as well.
daveydaycart
04-02-2007, 17:08
Yes, I'm using MPlab to program. I got my default code from kevin.org, it is his camera code version 2.1.
Thanks for your help!
MikeDubreuil
05-02-2007, 10:50
I got my default code from kevin.org, it is his camera code version 2.1.
In the file user_routines_fast.c you have to change the function InterruptHandlerLow(). Add the following code to the IF statement.
else if (PIR2bits.TMR3IF && PIE2bits.TMR3IE) // timer 3 interrupt?
{
PIR2bits.TMR3IF = 0;
Timer_Interrupt_Sonar(); // Call SONAR Timer Interrupt Handler
}
else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) // external interrupt 1?
{
INTCON3bits.INT2IF = 0;
Hardware_Interrupt_Sonar(); // Call SONAR hardware interrupt handler
}
daveydaycart
05-02-2007, 18:34
oooh I think it may be that when I added your code to InterruptHandlerLow() I didn't reset the interrupt flag within the two "else if" statements. I'll add that tonight and see if it works. Thanks!
Tom Bottiglieri
14-02-2007, 21:29
Hey guys,
Version 0.3 of this software DOES NOT work with Kevin Watson's PWM driver.
I'm guessing its a dependancy on Timer 3.
So, dont use it, or fix it.
--Tom
demarais*1153*
09-10-2007, 20:20
I've been trying to figure this code using Vex Ultrasound, for FRC. Have you updated this code at all since last post (MikeDubreuil)? Is this code still incompatible with Kevin's PWM driver? Also I'm having trouble figuring what digital input and output ports... I've looked through the sonar.h and the sonar.c , with no avail. Thank You -- mDemarais **Team 1153**
For anyone interested in using a SONAR sensor I have completed a software driver for it.
Wow... that would have saved me some work... I had to write a driver for these sensors last year... :rolleyes:
Cool stuff! How'd you make all the interrupt code independent of the user_routines_fast.c file which contains the interrupt vectors? Are you just calling functions? Is that making hiccups in your pulse timing?
-q
emersont49
18-10-2007, 15:03
I have a coupleof the old Polaroid Sonar modules. Will this work with them?
ctorloey
23-10-2007, 22:01
Hi all,
I need some programming help for the sonar, any help would be nice. We need it to return a number for the distance.
please help me or my team mate demarais*1153*
thanks
More specifically, to flesh out my teammates questions, we're using the vex sonar in our FRC robot, which has two pwm type plugs labeled INPUT and OUTPUT. We're not quite sure which locations these two wires should be plugged in at the controller, which the above sonar code is expecting.
emersont49: Are you talking about the ones that were on the old Polaroid cameras, or whatever developed from that? I don't think they are the same.
We have a couple of the Vex Ultrasonic Range Finder kits (http://www.vexlabs.com/vex-robotics-ultrasonic-range-finder-kit.shtml), which I believe are similar to the ones from Parallax.com (http://www.parallax.com/detail.asp?product_id=28015).
Qbranch: The sonar code's seem to be rather simple programming-wise, with help from the readme file. Call one routine to start the action, then call another routine to get the distance.
Our problem is where to plug the wires in. Or are we doing the code wrong? Or, like Tom Bottiglieri suggests (and I vaguely remember something of the sort, but hoping it wasn't true), it doesn't work with Kevin's PWM driver. There are too many unknowns, hardware and software, and it looks like we've got some grunt work ahead of us, and some hours with interrupts.
Too bad we can't plug the vex ultrasonic unit into the vex controller, then connect that to the FRC controller. Might be an easier path to take --- ?
I think there's been lots of activity since I last visited this thread, and suggestions. Thanks to all. And, not to beat a dead horse, but has anybody got *any* ultrasonic to work on FRC?
Qbranch: The sonar code's seem to be rather simple programming-wise, with help from the readme file. Call one routine to start the action, then call another routine to get the distance.
...
I think there's been lots of activity since I last visited this thread, and suggestions. Thanks to all. And, not to beat a dead horse, but has anybody got *any* ultrasonic to work on FRC?
Roger, I had a different method of timing for the Sonar than this driver uses, hence why mine was a little more complicated. I was using a CCP module in input capture mode to do cycle (nanosecond) precise timing. But, yes, you essentially get the same result, except i was reading out in tenths (of an inch) on a stationary robot and fairly stable 50 thousandths increments on an overhead cart.
To answer your other question... we sure did get an ultrasonic sensor to work. Our team as an offseason project finished a fully ultrasonic autonomous mode that worked flawlessly (and finished juuuuuust under 15 seconds :o ). Now, it did take a TON of data processing (band-pass filtering, trend/slope aquisition, line reconstruction, and curve fitting to be specific) which is part of why about 1 whole second is used just calculating after a scan is taken (we mounted our ultrasonic sensor on an airplane servo). We did use a PING))) sensor from Parallax. If you want more info just post.
-q
MikeDubreuil
05-11-2007, 11:47
we're using the vex sonar in our FRC robot, which has two pwm type plugs labeled INPUT and OUTPUT. We're not quite sure which locations these two wires should be plugged in at the controller, which the above sonar code is expecting.
When I wrote this software for my capstone project in college it was using the Vex sensor (http://www.vexlabs.com/vex-robotics-ultrasonic-range-finder-kit.shtml). I chose the Vex sensor because of it's protective case. Wiring the Vex sensor to an FRC controller requires some simple electrical work. In the software SONAR_OUTPUT, is actually the control input to the Vex sonar device. The output of the rangefinder is connected to an interrupt capable digital i/o pin on the FRC controller.
Vex Rangefinder Input Cable
Red = +5V
Black = GND
Yellow = Control = SONAR_OUTPUT (rc dig i/o 16) = Driving this high causes the SONAR to send echo
Vex Rangefinder Output Cable
Red = +5V
Black = GND
Orage = Signal = Hardware_Interrupt_Sonar() = Interupt 1 (software needs interrupt 1)
Hi team 1153 posting. I would just like to extend a gracious thank you to everyone who helped, as we got our sonar up and running tonight. Now onto new problems. Our Sonar is giving us data in spurts so our Displays look like
Distance = 5
Distance = 0
Distance = 5
Distance = 0
Distance = 5
Distance = 0
Distance = 5
Distance = 0
Distance = 5
Distance = 0
etc.
Does anyone know why t has these jumps to zero? We followed through the code that it seems to be coming from Timer3 being equal to 0 at certain points, but we would like to know if that is the case or what is causing it to go to zero and if possible how to fix this issue. Many thanks team 1153.
MikeDubreuil
07-11-2007, 07:39
Distance = 0
Distance = 5
Distance = 0
etc.
Does anyone know why t has these jumps to zero?
You'll need to provide more information for me to understand the problem. Is 5 the correct distance? Where does Ping_Sonar() and Get_Sonar_Distance() get called in your code? I seem to remember while developing the code that many print statements in the code cause bizarre results, watch out for that too.
I know that this discussion is focused on the VEX sonar but, the Matbotix sonar sensor is a much better sensor. It has been redisigned and is offered in several versions with different cones of detection. The nice thing about programming these sonars is that they offer a analog voltage output. A simple A to D call is all that is needed. They are 25$ plus shipping. Check out Sparkfun electronic for the differnt models and some links to FAQ and data sheet. The Sharp IR proximity sensor are similiar to the sonar but, better for some uses.
http://www.sparkfun.com/commerce/categories.php?cPath=23_84
Unfortunately I didn't grab the code from last night so I don't remember exactly how "B_Dubbs" set it up (and he is hopefully at school right now and can't answer).
Generally it was counting down each loop and at one number it would do the Ping_Sonar() and a (lower) number it would do the Get_Sonar_Distance(). Originally it was 38 and 19, but I was trying to get him to go down to 3 and 1. My reasoning being that the Ping needs time to, er, ping before doing the Get.
We didn't have too many printfs, just printing out the distance and (at one time) printing out the raw number in Get_Sonar_Distance(). The output was pretty regular.
The numbers were approximately the distance, though I was just eye-balling it from afar. I tried to find out how far a distance it could reach but the numbers were only going up to 12 or 14. (I'm hoping for a bigger distance.) When it was working it would alternate a number-distance with a zero.
We are using 2006 (pre-Kevin's PWM routine) code, BTW.
Going back to my DOS days programming with INT 27h, I recall that you can daisy-chain programs to an interrupt address. Thinking ahead to making this code work with 2007 code, can this daisy-chaining work with IFI's code?
Mike, I want to also thank you for your time. I also want to thank you for an opportunity for me (at least) to dive into FRC interrupts -- it looks like fun!
Gdeaver: I'll put your suggestion into the Subcommittee in charge of Acquisitions (Sonars and Sodas sector) :D We're only using vex sonars as we have a couple from years past.
People have been PM'ing me about my single-pin ultrasonic driver for the Parallax PING))) (http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/CategoryID/51/List/0/Level/a/ProductID/92/Default.aspx?SortField=ProductName%2cProductName)u ltrasonic sensor module.
I've cut out most of the signal processing, noise filtering, and object tracking code that I wrote, but there is enough here to get you your pulse-timing (raw distances). If you have questions post, please don't PM since many end up asking the same questions.
I realize it isn't the prettiest code, but then again I was never intending on posting it when it was written... :o
Enjoy... I attached the related files below. *cringes waiting for flood of 'this is bad programming convention' posts* :ahh:
-q
Protronie
08-11-2007, 14:39
Enjoy... I attached the related files below. *cringes waiting for flood of 'this is bad programming convention' posts* :ahh:
-q
Your right... it ain't pretty but it works and thats what matters...
thanks for posting! :cool:
Hey, it has plenty of good comments -- is that what you mean by "bad programming convention"? :) Thanks Qbranch!
We did get Mike's sonar code working last night (oh, the simple errors we made) -- the places we can now go!
______________________________
It's kind of fun to do the impossible. -Walt Disney
gnormhurst
15-01-2008, 10:33
Back in 2006 I installed Mike's sonar driver and it worked great. I followed his instructions for modifying InterruptHandlerLow () and everything was good.
I want to do it again, but when I look at the current code, InterruptHandlerLow () looks very different!
Can someone have a quick look at this and tell me if I have created any obvious conflicts? My modifications are in color.
Thanks!
Norm
void InterruptHandlerLow ()
{
if (PIR1bits.RC1IF && PIE1bits.RC1IE) // rx1 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_ONE_RX
Rx_1_Int_Handler(); // call the rx1 interrupt handler (in serial_ports.c)
#endif
}
else if (PIR3bits.RC2IF && PIE3bits.RC2IE) // rx2 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_TWO_RX
Rx_2_Int_Handler(); // call the rx2 interrupt handler (in serial_ports.c)
#endif
}
else if (PIR1bits.TX1IF && PIE1bits.TX1IE) // tx1 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_ONE_TX
Tx_1_Int_Handler(); // call the tx1 interrupt handler (in serial_ports.c)
#endif
}
else if (PIR3bits.TX2IF && PIE3bits.TX2IE) // tx2 interrupt?
{
#ifdef ENABLE_SERIAL_PORT_TWO_TX
Tx_2_Int_Handler(); // call the tx2 interrupt handler (in serial_ports.c)
#endif
}
// the following added to support sonar:
//
else if (INTCON3bits.INT2IF && INTCON3bits.INT2IE)/* The INT2 pin is RB2/DIG I/O 1. */
{
Hardware_Interrupt_Sonar();
INTCON3bits.INT2IF = 0;
}
else if ( PIR2bits.TMR3IF && PIE2bits.TMR3IE )
{
Timer_Interrupt_Sonar();
}
}
Okay, now I'm getting a little annoyed. It's time to get this sonar working once and for all!
We got Qbranch's code working with our 2006 robot and code. We haven't tried it with newer code, but the major difference I believe was Kevin Watson's updated PWM routine. (Sorry, I don't have the code in front of me to quote chapter and verse.) It's been a month since I stuck my toe into the wonderful world of interrupts, but now I want to dive in and get it done. I'm going to throw some programmers at this and see how far we get this time.
Jungle_Ed
16-01-2008, 14:12
Hey I just got assigned to a 2008 FRC team. I am going to try using Mike 0.3 code then Qbranch's Code. Anyone, please let me know of you get some ok readings for the Sonar on and FRC robot, and I will be sure to do the same.
gnormhurst
16-01-2008, 14:32
We got the Vex sonar working last night using Mike's driver. I'm really impressed by the whole thing -- it can see a 3' x 4' board at about 15 feet!
Note: the documentation that came with the Sonar sensor I got (from Radio Shack, back when they sold Vex stuff) had the "input" and "output" functions backwards. See my earlier post (http://www.chiefdelphi.com/forums/showthread.php?p=471859&highlight=backwards#post471859) in this thread.
The wire marked "input" is an input to the sonar, and it needs to come from a rc_digital_io_NN pin configured as an output. You need to set a couple of macros in sonar.h to tell it which pin you are using for the sonar input.
The output needs to go to a digital_io pin that acts as an interrupt. We used rc_digital_io_01. I think that is the default in Mike's code.
We got the Vex sonar working last night using Mike's driver. I'm really impressed by the whole thing -- it can see a 3' x 4' board at about 15 feet!
Beware of off-axis error! Depending on what sensor you're using (Parallax PING))) is pretty much your best bet) the further a wall is off axis the worse your measurements will be.
For example, if you were, say, following along a wall and servoing off of the distance from the wall (no idea why you'd want to do that :rolleyes: ) you're robot will swerve further and further until it crashes, because, each time the robot veers left or right it alters the distance the ping sensor percieves, even though the distance has barely changed. This escalates until, like I said, you crash.
Instead (and we've used this in the past) use encoders to drive your robot straigh, and use ultrasonics for obstacle detection/avoidance.
Getting a reliable distance to anything at any angle is our current goal at 1024.
-q
cprogrammer
31-01-2008, 09:27
I have a quick question Mike Dubreuil. YOu ping the sonar with Ping_Sonar and turn the timer on. Then once it interrupts it goed into Hardware_Interrupt_Sonar an into the switch statement for SONAR_WAIT status and you turn the timer on again. Then it goes into the switch statement for SONAR_TIMING for the next interrupt and get phase width as a measurement. Is the phase_width the time it takes for the actuall sound wave to go through the sonar, not the echo from the wall? If it is the echo value, then why start the timer in SONAR_WAIT?
Thanks Stephen
I have the code setup as gnornhurst posted in the "SONAR Sensor Software Driver" and i'm using rc_dig_out16 for input and digital IO port 1 for "output", but I'm getting a "Cannot find Sonar" error.
I was wondering if there were any additional code changes you needed to make to get this to work with this year's Kevin Watson code?
Thanks.
Last nite, I set to work adding a second sonar. Because of the limited time, I just made a second copy of Mike's sonar.c and sonar.h (which we are using for the first sonar). I named the second copy sonar2.c & h and changed the global variable names. While checking around to find what else I should change (which interupts and pins I should use), I found out that Mike has written another sonar named jvex_sonar.c routine that handles four sonars (at http://www.koders.com/c/fid735E99BB5CF57F640EC97964B212A8B5A82C4454.aspx).
What the story with that routine? Would I be better off starting with that code or continue with my approach?
dadamson
13-02-2008, 08:49
I was wondering if there were any additional code changes you needed to make to get this to work with this year's Kevin Watson code?
After a fair bit of wrestling yesterday, we got the 0.3 Sonar driver talking to Kevin W's 3.0 code. We ripped out references to his pwm.h, mostly (except for #includes) in ifi_frc.c Both it and the sonar driver want to use timer 3.
We, about 2 hours ago, have gotten all of our sonars to work with Kevin's encoder code. We did this by using both Mike's and Kevin's code together. Once we get everything perfectly straightened out, we could post it.
mandrews281
06-03-2008, 19:26
After a fair bit of wrestling yesterday, we got the 0.3 Sonar driver talking to Kevin W's 3.0 code. We ripped out references to his pwm.h, mostly (except for #includes) in ifi_frc.c Both it and the sonar driver want to use timer 3.
I'm trying the same thing with the Vex sensor and haven't had much luck. I ripped out ALL the pwm references and if I interpret the code correctly (a big if), it's using interrupt2, so I've connected the sensor to dig_in_02. Depending on which output/input I connect to dig_out_16/in_02, I get software malfunction or reversed I get an occasional "device not detected" (usually when I press or release the trigger). Anyway, in all cases the pulse_width (and therefore the distance) is 0.
Any chance of getting more details what you did so I can see what am I doing wrong? Thanks
eaglesfan10
08-03-2008, 11:03
Any ideas on how to make an ultrasonic sensor work with Kevin's new 2008 code? I know it handles interrupts differently, and I really don't have a great understanding on how to use interrupts. We're using a Vex UltraSonic Sensor (and it looks like it's digital).
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.