Society of Robots - Robot Forum

Software => Software => Topic started by: Yr0gErG on September 19, 2010, 08:45:51 PM

Title: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 19, 2010, 08:45:51 PM
Hi guys I really really need help with AD conversion. I'm using a PIC18f4520 microcontroller and i have absolutely no clue what codes and functions to use (I'm using C programming and MPLAB IDE btw)... don't even know what all the PORTA TRISA and ADCON0 ADCON1 stuff's about. Please advise!

Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 19, 2010, 08:51:57 PM
Check this tutorial:
http://www.gooligum.com.au/tutorials.html (http://www.gooligum.com.au/tutorials.html)

Since you are just beginning with PICs start with the Base-line PICs and study the tutorials through to the mid-range PICs. Use the SIMulator in MPLAB to run the code examples along with the data sheet for the PIC in the tutorial.

The Assembler section is important in understanding how the PICs work. Don't skip them.
Also download the Mid-Range family Reference Manual from Microchip's website. This contains lots of good information and explanations.
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 20, 2010, 07:18:06 PM
Thanks for the help, but a lot of the material covered is more for boards which are not in the 18f family... Is there a list of tutorials specific to 18f4520 or similar? the compilers don't support my board and many commands don't work
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 20, 2010, 08:09:54 PM
Almost all of the features in the base-line and mid-range PICs are also in the 18F series. But the 18F's have many more features and many more ways to goof up their set-up. So, anything learned on the simpler PICs can be applied to the 18F's. Do walk before you attempt to run.
Quote
don't even know what all the PORTA TRISA and ADCON0 ADCON1 stuff's about.
You will learn about all of this if you study the gooligum tutorial from the beginning.

There are also free compilers for the 12F, 16F and 18F PICs that you can download. These compilers are fully integrated with the MPLAB IDE that includes a very good simulator. So you don't need any board or other hardware to learn to program PICs.

The only document I know of that is specific to the PIC18F4520 is the data sheet. The Microchip document 'The Mid-Range Family Reference Manual' is good with better examples and explanations of many PIC features. Another place to look for 18F4520 Family (PIC18F2420, 2520, 4420 & 4520) examples is the App Notes and maybe demo boards documents.
Also read through these two threads on the Microchip User's forum. They have many links to more info:
http://www.microchip.com/forums/tm.aspx?m=391727 (http://www.microchip.com/forums/tm.aspx?m=391727)
http://www.microchip.com/forums/tm.aspx?m=358912 (http://www.microchip.com/forums/tm.aspx?m=358912)

Quote
the compilers don't support my board and many commands don't work
What board do you have? The compiler never supports a "board", you do by the way you write the code.
Which programmer hardware? I hope its a Microchip device instead of a third-party programmer.
What commands don't work? Where did you get these 'commands'?
How long have you been programming in C?
Are you getting errors in the C code or something else?
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 20, 2010, 09:05:09 PM
i'm going through the gooligum tutorial 1 : basic digital I/O and when i try to compile the program for flashing LEDs i get this:

Executing: "C:\Program Files (x86)\HI-TECH Software\PICC-18\PRO\9.63\bin\picc18.exe" -otest5.cof -mtest5.map --summary=default --output=default --chip=18F4520 -P --runtime=default --opt=default -D__DEBUG=1 -g --asmlist "--errformat=Error   [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
HI-TECH C PRO for the PIC18 MCU Family (Lite)  V9.63PL3
Copyright (C) 1984-2009 HI-TECH SOFTWARE
(1273) Omniscient Code Generation not available in Lite mode (warning)
Advisory[1233] Employing 18F4520 errata work-arounds:
Advisory[1234]  * Corrupted fast interrupt shadow registers
Error   [939] ; . no file arguments

My .c file looks like this:

#include <htc.h>
#define _XTAL_FREQ   4000000
#include "delay.h"
__CONFIG (MCLREN & UNPROTECT & WDTDIS & INTRC);

void main ()

{
TRIS = 0b11101;

for (;;){
   PORTA = 1;
   
   __delay_ms (100);
   
   PORTA =0;
   
   __delay_ms (100);
   }
}

And i've done a very basic course on C programming years ago for barely a school semester, so i think a hello world is what i can do at best  :-\
Title: Re: PIC18f4520 A/D conversion
Post by: paulstreats on September 21, 2010, 04:38:27 AM
Hi,

 Here is a basic code to get your 18F4520 working. It just turns portD pin0 on and off repeatedly.

Its done in the C18 compiler provided by microchip you can download it free from their website if you havent got it.

Code: [Select]

#include <p18f4520.h>
#include <delays.h>

//////CONFIG BITS////////////////

#pragma config WDT = OFF //watchdog timer
#pragma config OSC = HS //oscillator set to high speed
#pragma config LVP = OFF //low voltage program off
#pragma config MCLRE = ON //mclr pin active (frees up RE3)


//////////////////////////////////


#define flasher PORTDbits.RD0 // this sets the word
//flasher to represent
//pin0 on port D

void main(){
TRISD = 0b00000000; //set all pins on port D to be output
PORTD = 0b00000000; //set all pins on port D to be low (0v)

while(1){
if(flasher == 0){ //if the pin is off
flasher = 1; //turn it on (send 5v out of the pin)
}
else{
flasher = 0; //otherwise it must already be
//on so turn it off (set the pin to 0v)
}

Delay10KTCYx(80); //set a delay (adjusting the value)
//in brackets adjusts the speed
//of the port turning on and off)

}




}

Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 21, 2010, 06:46:00 AM
Code: [Select]
#include "delay.h"Do you have the delay.h and the delay.c files in the same directory as you source code? If not the compiler will not find them since the header name in in quotes ("").

Code: [Select]
TRIS = 0b11101;Your PIC has several ports with several TRIS registers. You need to use the correct register name, TRISA for port A's direction control. Also Port A has analog features that must be disabled to use the ports for digital IO. This is covered in the Gooligum mid-range tutorial and in the I/O Ports section of the DS.

I don't see an oscillator configuration in your __CONFIG statement. Look in the oscillator and special features section of the data sheet for what you need and in the HiTech Manual for the legal config names for the PIC you are using.

paulstreats,
 Your code is for the C18 compiler. The OP is using the Hi-tech compiler and there are many differences with the compiler directives and available functions. For example the config bits are set with:
Code: [Select]
__CONFIG (MCLREN & UNPROTECT & WDTDIS & INTRC);in HiTech
and with:
Code: [Select]
#pragma config WDT = OFF //watchdog timer
#pragma config OSC = HS //oscillator set to high speed
#pragma config LVP = OFF //low voltage program off
#pragma config MCLRE = ON //mclr pin active (frees up RE3)
in C18.

I mention this to ensure the OP doesn't get any more confused.
Title: Re: PIC18f4520 A/D conversion
Post by: paulstreats on September 21, 2010, 08:32:02 AM
I did mention in my post about which compiler it is for, and where it can be downloaded for free (with less reduction of features than the one the OP is using).

 To me, it makes more sense to use the microchip C18 compiler rather than the hitec ones since microchip make the pic's too. There is also a dedicated support forum for the c18 compiler on the microchip website too.

 Also the C18 compiler comes with generic program examples too(unfortunately hidden away in the install path and with little reference to them anywhere). Once you find them, they can help you get started.

I also have many code examples that I can share for the 18f4520 from before I migrated to a combination of 18f4550's and arm's, just let me know what you are interested in doing and they will be easy enough to create a simplified easy to understand mini snippets.
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 21, 2010, 09:01:42 PM
well basically i'm creating a robot that can sense distance from a wall when its moving backwards and stop once the required distance is reached. I'm using a Sharp GP2D12 IR Sensor for this and assuming that the robot is always well within the working range
there are several things to take note as well:
1. there are 3 distances the robot needs to stop at
2. it needs to be as accurate as possible, probably 1-2mm deviation max

a breakdown on the subprograms needed for this feat would be greatly appreciated thanks!
Title: Re: PIC18f4520 A/D conversion
Post by: paulstreats on September 21, 2010, 09:16:21 PM
I can help you by providing functions to read the sharp sensor within cm range, but I think 1-2mm range deviation is reaching way beyond the hardware capabilities.

 Even with more accurate sensor feedback, without knowing more about the drive system (like do you have encoders and if so what is the precisions or are you using stepper motors for precision movement aswell as what is the gearing or what is the wheel diameter) any particular distance motions would be difficult to provide you with.

 Even using the sharp sensor as a feedback system (ie not having encoders or stepper motors), I dont think its possible to gain this much precision
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 22, 2010, 08:48:16 AM
I'll second Paul's evaluation of the IR distance. The output value of the Sharp, voltage for a distance, is dependent of the nature of the surface being detected. I have found that a very shiny surface, at an angle not near 90°, may not even be detected at all.
This uncertainty most be taken into account when writing code.
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 22, 2010, 10:46:01 AM
the robot will have 2 DC motors connected to a set of 2 wheels of diameter 68mm with a motor controller as well
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 22, 2010, 11:20:09 AM
That's what my little Bot does also. I posted my code for the PIC16F874 some time back. It is written in HiTech C so there is much that will easily port to an 18F pic. You can find it in this thread (third post from the bottom):
http://www.societyofrobots.com/robotforum/index.php?topic=11042.0 (http://www.societyofrobots.com/robotforum/index.php?topic=11042.0)
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 22, 2010, 06:25:08 PM
How about a matt finish white block? That shouldn't give bad readings will it?
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 23, 2010, 07:38:57 AM
How about a matt finish white block? That shouldn't give bad readings will it?

That probably is about the best surface for consistent readings.
Title: Re: PIC18f4520 A/D conversion
Post by: paulstreats on September 23, 2010, 01:25:31 PM
what I really want you to understand is that the output of the sharp I/r when converted through a 10bit a/d converter will NOT produce a mm precision (the fact that sharp IR receivers are noisy and so have a degree of error before the conversion means that a precision of around  2 - 3 cm at least is much more realistic)
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 23, 2010, 09:40:32 PM
@waltr: could you explain your P_bot code to me please? I've been staring at it for a few nights but I am unsure about certain parts, like


   bitset( action_flags, SHARP_bump_f);
   NOP();
   NOP1();
   
   SendString(&s);
   s[0] = 'e';
   s[1] = 'f';
   s[2] = 'g';
   s[3] = 0x00;
   SendString(&s);

and

if (bittest(timeout_flags, Sys_tick_f) == 1) {   // 99ms tasks
         Sys_tick_counter = Sys_tick;
         bitclr(timeout_flags,Sys_tick_f);
         Sys_task_counter++;
         Num_tries = 0;
      //   if (Sys_task_counter > 19) {            // 2 second tasks
         if (Sys_task_counter > 40) {            // 4 second tasks
            Sys_task_counter = 0;
            bitclr(action_flags, PIR_timeout_f);   //
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 23, 2010, 09:50:50 PM
btw, how do i compare the values taken from the IR sensor to match the distance away from a block? convert the analog input into digital and then compare or something else? any a list of the main steps involved to achieve this would be very helpful thanks!
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 24, 2010, 08:19:06 AM
Ahh, you caught some of the experimenting in the code. The first section of code you are asking about really does nothing important. I was testing syntax. I put code lines to test syntax after all the initiaizations but before the main loop, I just forgot to delelte these before posting the code.  But here are the explanations of what each piece would do.

The bitset(...) is a MACRO defined further up in the code. action_flags is a byte that holds a collection of bits that allow passing of conditions between different parts of the code. You will see a bitset() in one part of the code, like the TMR0 ISR, then a bittest() in another part of the code where action actually takes place.

The SendString() sectio was again a test of syntax but also lets me know that the serial communications to the PC is working. SendString() is a function that to, guess what, send a string out the UART. The UART connects to the PC for diagnostic.

Next section:
This is in the main loop and allows tasks to execute are a slower rate. Look in the TMR0 ISR for the decrementing of Sys_tick_counter, which is reset each time the Sys_tick_f flag is set by the ISR to Sys_tick. For the defined value this happens every 99msec. The Sys_tick_f is also cleared (remeber it is only set by the TMR0 ISR) and then increments the Sys_task_counter which is tested for being a value next. This value is a multiple of the TRM0 Sys_tick and allows other tasks the execute are an even slower rate.
The Num_tries = 0; is a reset of a counter used in the FindClearPath() function. It is used the change the backing up and turning values so the Bot doesn't get stuck in a corner and have a way for the code to exit that function and get back the the main loop.

The 4 second task is for the PIR sensor. This sensor has a very slow response and uses this flag to not check the PIR for some time after being triggered.

Your IR and ADC question:
Look in my Get_Sharp() function, line #1227. This calls the GetADC( ch#) function to read the voltage of the Sharp sensor. Then does compares to pre-defined ADC values, such as Sharp_4in, and returns a value for various pre-defined distances, D_3in for example. The defines start on line #357.

This code can be run in the MPLAB SIMulator and is what I used to debug it. Parts require stimulus inputs that can be tricky to set-up. The ISR's however will get called and the main loop will run.

Is any of these code the best way to do it: NO but it does work.
There are many other ways to write this code. It does make heavy use of interrupts to ensure time critical tasks always get executed like the PWM for the motor speed.

Hope you understood my explanations.
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 26, 2010, 08:20:22 AM
How did you get those predefined hexadecimal ADC values like #define Sharp_2in   0x70   // 2.2V? did you get them by trial and error? if so how would you collect such data? record down the hexadecimal value after it converts a certain analog voltage input at a predefined distance?
Also, i've been observing that the IR sensor has problems detecting distances furthur than 30cm... I'll need it to operate btwn 10-60cm though, any thoughts why? thanks again
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 26, 2010, 08:53:04 AM
I used the voltage vs. distance plot in the Sharp data sheet. Typed the values into an Excel spreadsheet, created a plot then fitted a curve with the fitting equation. From the equation I made a table of voltage vs distance then converted the voltage to an ADC reading.
ADC value = Vin * 256 / Vref
I use 256 since I left justify the ADC result and only use 8 bits of the ADC's output instead of the full 10 bits. This is easier coding as its a byte, dropping the lowest 2 bits reduces the noise in the ADC measurement and 8 bits is more than enough resolution since there are variations in the measurement due to the objects being detected.

The fitted equation for the Sharp I use is: Distance = 61.7 * (voltage)^1.14
This wouldn't be easy to calculate within a small uController in any reasonable amount of time so I just use a table of values.

These were then checked measuring the Sharp's output with a voltmeter and the distance with a tape measure.

Quote
IR sensor has problems detecting distances furthur than 30cm... I'll need it to operate btwn 10-60cm though, any thoughts why? thanks again
All of the Sharp sensors beam spreads out with distance from the sensor. This makes detecting smaller objects very hard as the object is moved further from the sensor. Ambient light does decrease the sensor's sensitivity somewhat and the reflectivity on the object has an effect on the maximum range.
What size, color and texture object are you working with?
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 26, 2010, 05:18:12 PM
the object is a 10cmX10cmX4cm white platform. the IR sensor would start off around 10cm+ away and move away... stopping at the 15cm, 35cm and 55cm marks
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 28, 2010, 05:02:49 PM
And what is your result for the 10cm box at those distances?

Try checking the distance to a wall.

It is very possible that a Sharp sensor won't do what you need. If it doesn't then check out ultrasonic distance sensors.
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 28, 2010, 05:10:04 PM
is there any method to make the Sharp sensor beam more focused then? like shielding etc
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 28, 2010, 09:24:17 PM
No there isn't that I know of.
Title: Re: PIC18f4520 A/D conversion
Post by: Yr0gErG on September 29, 2010, 04:37:44 AM
ok, so if i were to use this ultrasonic sensor, would the C programming differ a lot, if any?
Title: Re: PIC18f4520 A/D conversion
Post by: waltr on September 29, 2010, 07:45:45 AM
Yes, read up on the ultrasonic sensors for distance measurements. There are a few different kinds in the control circuits. The simplest must be pulsed by your processor then time when the pulse returns. Other have circuits built-in that do most of this. Here are some links on popular sensors:
http://www.maxbotix.com/MaxSonar-EZ1__FAQ.html (http://www.maxbotix.com/MaxSonar-EZ1__FAQ.html)
http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/ProductID/92/List/1/Default.aspx?SortField=ProductName,ProductName (http://www.parallax.com/Store/Sensors/ObjectDetection/tabid/176/ProductID/92/List/1/Default.aspx?SortField=ProductName,ProductName)