View previous topic :: View next topic |
Author |
Message |
criss_m
Joined: 09 Mar 2006 Posts: 9 Location: Chile
|
canbus - adc |
Posted: Sat Aug 28, 2010 11:45 am |
|
|
Good day Coders:
I have 2 small circuits (18F258+mcp2551) which I've already test :
- Both circuits send and receive can data fine.
- I made some code to trigger leds from one board to the other...
- I use version 4.093
------------------------------------
My problem, if I try to:
- Sample the value of the RA0 ADC
- Put it in the canbus
- Get it on the other board
- Send it to the UART
The code actually works, but only in the first loop:
- It sends the correct value the first time.
- After it repeats the first sample value...(ex: 127 127 127)
- If I reset the sender board it will sample (refresh) the new value of ADC , but still repeat the first sample.
Any ideas ? Why I'm not getting the new sample each time ??
pd: I tried adding delays.
Thanks for reading
--------------------------------------
Code for receiver board (18F258+mcp2551 + uart)
Code: |
#include <18F258.h>
#fuses HS,NOWDT,NOPROTECT
#use delay (clock=20000000)
#include <can-18xxx8.c>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main()
{
float var1=562.289;
int var2=876;
int32 rx_id;
int buffer[2];
int rx_len;
struct rx_stat rxstat;
//set_tris_a(11111111);
can_init();
printf("Prueba 1 Can Bus\n");
output_high(PIN_A0);
while(TRUE)
{
if ( can_kbhit() )
{
if(can_getd(rx_id, &buffer[0], rx_len, rxstat))
{
if ( rx_id ==0x202)
{
printf("%u\n\r",buffer[0]);
output_high(PIN_A0);
delay_ms(50);
output_low(PIN_A0);
delay_ms(50);
}
}
}
}
}
|
Code for emitter board (18F258+mcp2551 + adc pot)
Code: |
#include <18F258.h>
#fuses HS,NOWDT,NOPROTECT
#use delay (clock=20000000)
#include <can-18xxx8.c>
void main() {
int i;
can_init();
setup_port_a(RA0_ANALOG);
delay_ms(100);
setup_adc(ADC_CLOCK_INTERNAL);
delay_ms(100);
set_adc_channel(0);
delay_ms(100);
while(1)
{
i = read_adc();
delay_ms(100);
can_putd(0x202, &i, 1, 1, 1, 0);
output_high(PIN_A1);
delay_ms(100);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 28, 2010 6:15 pm |
|
|
In CCS, an 'int' is an 8-bit unsigned integer. It can only hold 0 to 255.
For the rest of your code, you should look at the Ex_can.c example file.
In the transmitter portion of that code, CCS calls the can_tbe() function
to check if the transmitter is ready to accept data. You're not doing that.
They also have a lot of diagnostic messages in there. I suggest that you
at least initially, try to closely follow the CCS code. Also, increase the
receive buffer to 8 bytes, just for safety. Get it working in a baseline
fashion, then modify it to suit your needs later. |
|
|
criss_m
Joined: 09 Mar 2006 Posts: 9 Location: Chile
|
|
Posted: Sun Aug 29, 2010 1:12 am |
|
|
Thanks PCM programmer:
I'll try.
By the way:
What does the "&" mean ?
in :
Code: |
can_getd(rx_id, &buffer[0], rx_len, rxstat)
can_putd(0x202, &i, 1, 1, 1, 0);
|
|
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Sun Aug 29, 2010 7:04 am |
|
|
criss_m wrote: |
By the way:
What does the "&" mean ?
in :
Code: |
can_getd(rx_id, &buffer[0], rx_len, rxstat)
can_putd(0x202, &i, 1, 1, 1, 0);
|
|
That's the "address of" operator. It gets the address that the variable is stored at. In the case of the code you showed this allows can_getd to figure out where buffer[0] is stored so that it can write to it. |
|
|
criss_m
Joined: 09 Mar 2006 Posts: 9 Location: Chile
|
|
Posted: Thu Sep 09, 2010 3:40 am |
|
|
Hello Boys...
ive followed testing , i added can_tbe() condition for the transmiter code:
i found out that.
-My code seems to work but after sending 6 frames , it stops.
- It looks like the transmiter buffer gets full or something.
Any Ideas how to fix it ???
Code: |
while(TRUE)
{
if ( can_tbe()) {
set_adc_channel(0);
i=read_adc();
buffer[0]=i;
can_putd(0x202,buffer,8, 1, 1, 0);
}
}
|
|
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Thu Sep 09, 2010 5:12 am |
|
|
criss_m wrote: | Hello Boys...
ive followed testing , i added can_tbe() condition for the transmiter code:
i found out that.
-My code seems to work but after sending 6 frames , it stops.
- It looks like the transmiter buffer gets full or something.
Any Ideas how to fix it ???
|
Yes, I have an idea. Try to get the receiving end to actually acknowledge the canbus frames. If it does not then you will tie up all of your transmit buffers trying to constantly resend the messages within them over and over.
Basically, do you have something else on the canbus and is it reading the frames? |
|
|
criss_m
Joined: 09 Mar 2006 Posts: 9 Location: Chile
|
|
Posted: Thu Sep 09, 2010 5:54 am |
|
|
yes i have another board , reciving the frames:
here is the important part of the code on the receiver node:
Code: |
#int_canrx0
can_isr0()
{
int buffer[8], rx_len, rx_stat;
int32 rx_id;
disable_interrupts(GLOBAL);
cligne();cligne();
if(can_getd(rx_id,buffer, rx_len,rx_stat))
{
if(rx_id == 0x202) // si bonne ID
{
printf("%u\n\r",buffer[0]);
printf("%u\n\r",buffer[1]);
printf("%u\n\r",buffer[2]);
printf("%u\n\r",buffer[3]);
printf("%u\n\r",buffer[4]);
printf("%u\n\r",buffer[5]);
printf("%u\n\r",buffer[6]);
printf("%u\n\r",buffer[7]);
printf("------------------------");
}
}
RXB0CON.rxful=0;
RXB1CON.rxful=0;
enable_interrupts(GLOBAL);
}
|
Obviously im not i aknowledging the cabus frames....(any example code?)
Thanks for the hint collink!!!!!!!!!!!!!!! |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Thu Sep 09, 2010 7:02 am |
|
|
criss_m wrote: | yes i have another board , reciving the frames:
here is the important part of the code on the receiver node:
Obviously im not i aknowledging the cabus frames....(any example code?)
Thanks for the hint collink!!!!!!!!!!!!!!! |
Your code includes explicit disabling of interrupts and reenabling. DO NOT DO THIS. Completely remove that code. That is, remove these lines:
Code: |
disable_interrupts(GLOBAL);
cligne();cligne();
RXB0CON.rxful=0;
RXB1CON.rxful=0;
enable_interrupts(GLOBAL);
|
Now, when I say acknowledge I mean that the hardware must do that. This is done by successfully receiving a frame. You appear to be properly doing that (other than the issue I highlighted above.)
So, is the receiving end getting the frames? That is, are you getting output from your printf statements or do you never see any output? |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Thu Sep 09, 2010 7:05 am |
|
|
I take back what I said about your receive code being correct... You might be making the canbus receiver code puke by not calling it right. You need to pass the address to the buffer. Your call to can_getd should look like:
Code: |
if(can_getd(rx_id,&buffer, rx_len,rx_stat))
|
Note the addition of a & to your original line. |
|
|
criss_m
Joined: 09 Mar 2006 Posts: 9 Location: Chile
|
|
Posted: Fri Sep 10, 2010 2:45 am |
|
|
I activated can debug..
my code are the EX_CAN_CCS_A.C EX_CAN_CCS_B.C
here is the output in the sender board:
Running...
CAN_PUTD(): BUFF=0 ID=00000202 LEN=1 PRI=1 EXT=1 RTR=0
DATA = 00
CAN_PUTD(): BUFF=1 ID=00000400 LEN=3 PRI=1 EXT=1 RTR=0
DATA = 1E 7F 02
CAN_PUTD(): BUFF=2 ID=00000202 LEN=1 PRI=1 EXT=1 RTR=0
DATA = 01
CAN_PUTD() FAIL: NO OPEN TX BUFFERS
CAN_PUTD() FAIL: NO OPEN TX BUFFERS
CAN_PUTD() FAIL: NO OPEN TX BUFFERS |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Fri Sep 10, 2010 6:11 am |
|
|
Your most recent post suggests that nothing is acknowledging the frames you are sending. Is your other device (the receiver in this case) getting the frames and displaying them or isn't it? It would appear that it isn't as it is not doing frame acknowledgement. If it IS getting them then chances are you've somehow set the receiving device to listen only mode or to blindly accept all frames no matter how mangled. In both cases it will not acknowledge frames. |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Sep 13, 2010 11:40 am |
|
|
could it be that the terminating resistors are missing? |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
|
Posted: Mon Sep 13, 2010 11:44 am |
|
|
pmuldoon wrote: | could it be that the terminating resistors are missing? |
That's certainly a possibility but you can get away with horrific sins when it comes to terminating resistors. If the line resistance is anything from like 20 ohms to 350 ohms it will probably work with just two devices on the bus. That is, if you aren't in a noisy environment. The noisier the environment the more critical the termination, line quality, and speed.
Though the OP hasn't been by in a while. Maybe the problem is fixed? |
|
|
pmuldoon
Joined: 26 Sep 2003 Posts: 218 Location: Northern Indiana
|
|
Posted: Mon Sep 13, 2010 11:49 am |
|
|
Yeah, just a guess. It can be an easy oversight if your swapping boards around in developement and pull the brd with the tacked-on resistor out of the system.
Funny thing is, the very first thing he said was that the communication was working fine. From the probs you pointed out, it doesnt seem like that was possible. |
|
|
|