View previous topic :: View next topic |
Author |
Message |
mayai
Joined: 19 Dec 2009 Posts: 8
|
adc multiple channel |
Posted: Sat Dec 19, 2009 3:21 am |
|
|
Hello friends I'm new here. I need your help. Thanks in advance.
Okay my problem is that I am developing a mobile robot that solves a maze by using ultrasonic, infrared sensor, etc. The problem is I know how to use the multiple channel but I failed to manipulate the data to get the motor function according to the logic.
Here is the idea:
There are 2 sensors, so meaning that it have 4 logic:
Code: |
sensor 1 sensor2 motor1 motor2
0 0 0 0
0 1 0 1
1 0 1 0
1 1 1 1
|
I know that we can do it directly from sensor to motor but in my case I don't actually use 2 sensors, but 4 sensors and 2 output, so in order to make this function I have to use logic control.
Here is the coding that I developed. It seems not to be functioning properly. It doesn't go to the subroutine maybe????
Code: |
#include <16F877A.H>
#device adc=10
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000) //20MHz
#define 1 PIN_C0
#define 2 PIN_C1
#byte PORTB=6
#byte PORTC=7
void fwd()
{
(output_high(pin_b1) && output_high(pin_b1));
delay_ms(20);
(output_low(pin_b0) && output_low(pin_b1));
}
void stp()
{
delay_ms(20);
output_low(pin_b0) && output_low(pin_b1);
}
void rgt()
{
output_high(pin_b1);
delay_ms(20);
output_low(pin_b0) && output_low(pin_b1);
}
void lft()
{
output_high(pin_b0);
delay_ms(20);
output_low(pin_b0) && output_low(pin_b1);
}
void machai()
{
if (output_low(pin_C0) && output_high(pin_C1))
{
fwd();
}
else if (output_low(pin_C0) && output_high(pin_C1))
{
rgt();
}
else if (output_high(pin_C0) && output_low(pin_C1))
{
lft();
}
else if (output_high(pin_C0) && output_high(pin_C1))
{
stp();
}
}
void main()
{
int adc_value0,adc_value1;
int i;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);
set_tris_b(0b00000000);
set_tris_c(0b00000011);
set_tris_a(0b00000011);
portc=0;
portb=0;
while(1)
{
for(i=0;i<2;i++)
{
set_adc_channel(0); //set to read channel a0 next
delay_us(20);
adc_value0 = read_adc(); //get 10 bit readig for channel 0
if (adc_value0<128) output_low(pin_C0);
if (adc_value0>128) output_high(pin_C0);
delay_ms(500);
set_adc_channel(1); //set to read channel a1 next
delay_us(20);
adc_value1 = read_adc(); //get 10 bit readig for channel 1
if (adc_value1<128) output_low(pin_C1);
if (adc_value1>128) output_high(pin_C1);
delay_ms(500);
machai();
}
}
}
|
Thanks a million. |
|
|
Ttelmah Guest
|
|
Posted: Sat Dec 19, 2009 11:14 am |
|
|
Your values to store the ADC reading, need to be _int16_ or larger, not 'int'.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Dec 19, 2009 12:34 pm |
|
|
Quote: | output_low(pin_b0) && output_low(pin_b1); |
The output_low() function doesn't return a value. You can't do valid
logical operations on the functions when they don't return a value.
Your code above is wrong.
Quote: | if (output_low(pin_C0) && output_high(pin_C1))
{
fwd();
} |
You have large numbers of statements like this. Again, output_x
does not return a value. You can't do "if" tests on it. It won't work.
Please read the manual and look at example code.
Quote: | #include <16F877A.H>
#device adc=10
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000) //20MHz |
XT is not the correct oscillator fuse for a 20 MHz crystal. The oscillator
won't run. You must use HS for 20 MHz operation. This is in the PIC
data sheet. You can't just "jump into" PICs. Everything is important.
You have to read the CCS compiler manual and the PIC data sheet. |
|
|
mayai
Joined: 19 Dec 2009 Posts: 8
|
|
Posted: Sat Dec 19, 2009 3:32 pm |
|
|
Currently the initial code has been repaired. The problem is I still don't get the idea of the if() function. Could you give me a hint please. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Sat Dec 19, 2009 4:39 pm |
|
|
mayai wrote: | Currently the initial code has been repaired. The problem is I still don't get the idea of the if() function. Could you give me a hint please. |
the *IF* statement is considered a conditional -- for flow control.
IF (some expression is TRUE) THEN
DO SOME STUFF
ELSE
DO SOMETHING ELSE (although the ELSE is optional)
Every IF must have an expression to evaluate.
Typically, those items to be evaluated are variables of a certain quality or value or a function that returns a value.
Example:
if ( somevar == 1) {
DO THIS
}
So if somevar is ANY value but 1, "DO THIS" will never occur.
You could also write:
if ( somevar != 1) {
DO THIS
}
Now the situation is that if somevar is ANY value but 1, DO THIS *will* occur.
In the case of a function, the function MUST RETURN A VALUE.
kbhit() is a good example.
if ( kbhit() ) {
c = getc();
}
If kbhit is true (RS232 has received a character), then go get that
character and store in variable 'c'. If kbhit is FALST (0), then do nothing.
Get the idea now?
-Ben
p.s. If you are as unclear on the 'if' as you describe, you seriously should consider getting some books for basic programming in C. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Dec 19, 2009 5:03 pm |
|
|
If you are wanting to know the state of the output pin you would use the
input_state() procedure as illustrated in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=35956 _________________ Google and Forum Search are some of your best tools!!!! |
|
|
mayai
Joined: 19 Dec 2009 Posts: 8
|
|
Posted: Sun Dec 20, 2009 5:56 am |
|
|
so far this is the best i could do... maybe if u can tell me what is the proper way to manipulate the data using if i can finished this programs...
that is the only main problem that i've encountered...
Code: |
#include <16f877a.h>
#device adc=8
#use delay(clock=20000000)
#fuses hs, noprotect,nowdt,nolvp
#define 1 PIN_C0
#define 2 PIN_C1
#byte PORTB=6
#byte PORTC=7
void fwd()
{
output_high(pin_b0);
output_high(pin_b1);
delay_ms(200);
output_low(pin_b0);
output_high(pin_b1);
}
void stp()
{
}
void rgt()
{
output_high(pin_b1);
delay_ms(200);
output_low(pin_b1);
}
void lft()
{
output_high(pin_b0);
delay_ms(200);
output_low(pin_b0);
}
void machai()
{
if ((input_state(PIN_C0) == 0) && (input_state(PIN_C1) == 0))
{
fwd();
}
else if ((input_state(PIN_C0) == 0) && (input_state(PIN_C1) == 1))
{
rgt();
}
else if ((input_state(PIN_C0) == 1) && (input_state(PIN_C1) == 0))
{
lft();
}
else if ((input_state(PIN_C0) == 1) && (input_state(PIN_C1) == 1))
{
stp();
}
delay_ms(20);
}
void main()
{
int16 adc_value0,adc_value1;
int16 i;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);
set_tris_b(0b00000000);
set_tris_c(0b00000011);
set_tris_a(0b00000011);
portc=0;
portb=0;
while(1)
{
for(i=0;i<2;i++)
{
set_adc_channel(0); //set to read channel a0 next
delay_us(20);
adc_value0 = read_adc(); //get 10 bit readig for channel 0
if (adc_value0<128) input_state(PIN_C0) == 0 ;
if (adc_value0>128) input_state(PIN_C0) == 1;
delay_ms(500);
set_adc_channel(1); //set to read channel a1 next
delay_us(20);
adc_value1 = read_adc(); //get 10 bit readig for channel 1
if (adc_value1<128) input_state(PIN_C1) == 0 ;
if (adc_value1>128) input_state(PIN_C1) == 1;
delay_ms(500);
machai();
}
}
}
|
|
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Dec 20, 2009 9:25 am |
|
|
OK, the next set of comments on your code:
What are you accomplishing with this?
void fwd()
{
output_high(pin_b0);
output_high(pin_b1);
delay_ms(200);
output_low(pin_b0);
output_high(pin_b1);
}
What do you see wrong with the following lines?
Code: |
if (adc_value0<128) input_state(PIN_C0) == 0 ;
if (adc_value0>128) input_state(PIN_C0) == 1;
|
There are more lines like the above that need to be fixed as well. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
mayai
Joined: 19 Dec 2009 Posts: 8
|
|
Posted: Sun Dec 20, 2009 1:05 pm |
|
|
Dear friends, with your help I have this following coding.
Code: |
#include <16f877a.h>
#device adc=8
#use delay(clock=20000000)
#fuses hs, noprotect,nowdt,nolvp
#define 1 PIN_C0
#define 2 PIN_C1
#byte PORTB=6
#byte PORTC=7
void fwd()
{
output_high(pin_b0);
output_high(pin_b1);
delay_ms(5000);
output_low(pin_b0);
output_low(pin_b1);
}
void stp()
{
delay_ms(5000);
output_low(pin_b0);
output_low(pin_b1);
}
void rgt()
{
output_high(pin_b1);
delay_ms(5000);
output_low(pin_b1);
}
void lft()
{
output_high(pin_b0);
delay_ms(5000);
output_low(pin_b0);
}
void main()
{
int16 adc_value0,adc_value1;
int16 i;
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_DIV_32);
set_tris_b(0b00000000);
set_tris_c(0b00000011);
set_tris_a(0b00000011);
portc=0;
portb=0;
while(1)
{
for(i=0;i<2;i++)
{
set_adc_channel(0); //set to read channel a0 next
delay_us(20);
adc_value0 = read_adc(); //get 10 bit readig for channel 0
if (adc_value0<128) output_low(pin_c0);
if (adc_value0>128) output_high(pin_c0);
delay_ms(500);
set_adc_channel(1); //set to read channel a1 next
delay_us(20);
adc_value1 = read_adc(); //get 10 bit readig for channel 1
if (adc_value1<128) output_low(pin_c1);
if (adc_value1>128) output_high(pin_c1);
delay_ms(500);
{
if ((input_state(PIN_C0) == 0) && (input_state(PIN_C1) == 0))
{
fwd();
}
else if ((input_state(PIN_C0) == 0) && (input_state(PIN_C1) == 1))
{
rgt();
}
else if ((input_state(PIN_C0) == 1) && (input_state(PIN_C1) == 0))
{
lft();
}
else if ((input_state(PIN_C0) == 1) && (input_state(PIN_C1) == 1))
{
stp();
}
delay_ms(20);
}
}
}
}
|
It looks like the code is running as desired. But as for suggestions for a better coding please do not hesistate. Thanks for all your help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Dec 20, 2009 3:02 pm |
|
|
Quote: | I still don't get the idea of the if() function. |
Here is a good, quick C tutorial for beginners, if you have future questions on C:
http://phy.ntnu.edu.tw/~cchen/ctutor.pdf |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Mon Dec 21, 2009 10:13 am |
|
|
mayai wrote: | Dear friends, with your help I have this following coding.
Code: |
set_tris_b(0b00000000);
set_tris_c(0b00000011);
set_tris_a(0b00000011);
|
|
From page 207 of the manual:
This[set_tris_x()] must be used with FAST_IO and when I/O ports are accessed as memory such as when a #BYTE directive is used to access an I/O PORT. Where is your FAST_IO statement?
Do you really need FAST_IO? Just let the compiler do it for you with standard IO. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Dec 21, 2009 4:10 pm |
|
|
Many beginners think they must set the TRIS registers themselves. With some compilers this may be true, but the CCS compilers usually take care of this automatically.
It is only those few cases where the utmost in speed is needed and you have to use fast_io that you must also use the set_tris functions. You can almost always ignore the set_tris functions and just let the compiler take care of its own business. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Mon Dec 21, 2009 4:31 pm |
|
|
I think the most important part is to know when and where the differences lay.
It's easy to get into a situation with code that maybe someone else wrote or it's a quirk of the of compiler that does or DOESN'T do it for you so that when things don't work, you know have some idea of what to look for.
:D
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|