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 support@ccsinfo.com

Another CAN Bus Problem ...! [SOLVED]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 15, 2014 12:45 pm     Reply with quote

Quote:
#include <18F46K80.h>

#fuses NOPROTECT, PUT, BROWNOUT, NOWDT, NOPLLEN, CANC
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, parity=N, bits=8)

#include <can-18xxx8.c>


There is a Can bus driver designed for the "80" series PICs:
c:\program files\picc\drivers\can-18f4580.c
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Wed Jan 15, 2014 6:03 pm     Reply with quote

ho really ?!....and do you think this is why I can't receive my messages on my second board ??
I'll check the difference between the two different libraries later. Thank you for answering to me...
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Fri Jan 17, 2014 4:19 am     Reply with quote

I've tried with this new one library...but nothing different. It still work with "CAN_RX_ALL" RX mode, but nothing with "CAN_RX_VALID" RXB0CON state.
In conclusion, this new one library doesn't solve my problem, and seems to function as the can-18xxx8 library....So it's my masks and/or my filters which are badly configured. Or my sent message which is not correctly sent...
I'm totally lost...I still investigate it.

Greg
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Tue Jan 21, 2014 1:17 am     Reply with quote

Just to up... I still be totally lost...If someone has an idea. Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 21, 2014 1:22 am     Reply with quote

Quote:
I changed the transceiver associated to board#1, and suddenly, I can
clearly see the signal, on the transceiver pins, on the CANH, CANH signal
which is clearly the invert of the CANL signal. The signal runs until the
microcontroller board #2 but....

I still have no response from board #2 !!!

What about the transceiver on board #1 ? Did you check it out in the
same way ? I mean, prove that board #1 has output on CANH and CANL ?

------------

Also, just a minute here. I just took a look at your schematic again.
This is a repeat of another thread. You have left off all kinds of
required capacitors and power and ground connections from the PIC.
- Vdd and Vss on pins 32 and 31 are not connected to anything.
- You're missing the required 10 uF / 16v ceramic chip capacitor on the
Vcap pin. (Not aluminum electrolytic).
Section 2 of the 18F46K80 data sheet explains all this stuff in detail.

I don't think we can do anything more until you get all this stuff fixed.
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Tue Jan 21, 2014 3:57 am     Reply with quote

I can clearly see the CAN signal on the transceiver #1, until the CANRX pin of board #2, so my board and transceiver #1 works well. I can post the screenshots of my scope of the signal also...if it's necessary.

My Vdd and Vss pins are already connected on pins 11 and 12, I did think I had to also connect the 31 an 32 pins...

I wired my microcontroller for microcontroller programmation, that's why I missed required capacitors, it's true ...

I will fix it as soon as possible...

Thank you again.
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Tue Feb 18, 2014 2:08 am     Reply with quote

Hello,

I come back with my CAN bus after many research. I rewire my PICs as there :



I rewired the two Vss and Vdd pins on C3 and C17 capacitors, and L2 self. I also rewired the MCLR and a 0.1uF capacitor to ground on pin6.

I closely read this post:

http://www.ccsinfo.com/forum/viewtopic.php?t=48915&highlight=18f46k80

and I still got the sames troubles...

My PICs works finely on loopback mode each one. On normal mode, they works finely but only CAN_RX_ALL mode, not in CAN_RX_VALID mode.

I've try with a 8 bytes buffer, and the ID, the datas and I got it:



What does mean a valid message ? Why my "unvalid" messages comes perfectly but they aren't considerate as "valid"..?

I'm ready to make a new test board so that I don't understand nothing......


Here is my code :

Code:

#include <loop2.h>

#fuses HSM, NOPROTECT, PUT, BROWNOUT, NOWDT, NOPLLEN, CANC, SOSC_DIG, NOIESO, NOFCMEN
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, parity=N, bits=8)

#include <can-18F4580.c>

#define BOARD1_ID  24
#define BOARD2_ID  25

#define  BOUTON            PIN_A0           // Bouton poussoir
#define  LED0              PIN_B3           // LED verte de droite, coté connecteur RJ11
#define  LED1              PIN_B2           // LED rouge du milieu du boitier
#define  LED2              PIN_B1           // LED verte de gauche, coté connecteur RS232

// Uncomment this line to compile code for Board #1.
// Comment it out to compile for Board #2.
//#define BOARD1   1


//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];


   printf("\r\n Start !\r\n");

set_tris_a(*0xF92 | 0x01);
set_tris_b((*0xF93 | 0x0F));   //b0, b1 b2 and b3 are out

can_init();

output_low(LED0);
output_low(LED1);
output_low(LED2);


#ifdef BOARD1   // For Board #1
while(1)
  {
  delay_ms(2500);
 
   strcpy(buffer, "87654321");   // Wait for a character

   // Transmit it to board #2.
   if(can_putd(BOARD2_ID, buffer, 8, 1, 1, 0))
   {
      printf("\r\nBUFFER:%s\r\n", buffer);
   }
  }
#else  // For Board #2
while(1)
  {
   output_low(LED0);
   output_low(LED1);
   output_low(LED2);
   delay_ms(2500);
   
   if(can_kbhit())  // Message available ?
     {
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD2_ID)  // Is it for this board ?
           {
            // If so, echo back the character.
            output_high(LED0);
            output_high(LED1);
            output_high(LED2);
            printf("\r\nBUFFER:%s\r\n",buffer);
            printf("\r\nID:%ld\r\n",rx_id);
            printf("\r\nSIZE:%d\r\n",rx_len);
            //can_putd(BOARD1_ID, buffer[0], 1, 1, 1, 0);
           }
         }
      }
  }
#endif
 
}


If someone knows where my problem comes from...Thank U

Greg
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Tue Feb 18, 2014 9:15 am     Reply with quote

It's me, again and again. I checked the rxstat structure that contains the function can_getd(...). It contains lot of informations, as which filter is used, which buffer is used, and many more. The last one is a boolean field that tell if it's an invalid ID or not. And it is !

[img]
http://imageshack.com/a/img31/4952/lthp.jpg
[/img]

So it definitely comes from the IDs. But as you can see on the picture, The board ID is correct (here I put 25 for the reception Board). I use extended IDs, as told in the "ext" field of this rxstat structure. But changing standard or extended IDs does not really solve my problem.
I know that IDs are not just integer put into a variable....can_put_id() and can_get_id() has been implemented, so it's probably more complicated than just put a number into a variable....So does it come from the can_set_id() function ? can_get_id() function ? extended or standard ? I go back to my crazy CAN test board to still investigate...

See you soon...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 18, 2014 11:10 am     Reply with quote

One problem you have is this one:
Quote:

int8 buffer[8];

strcpy(buffer, "87654321");

strcpy puts a 0x00 byte at the end of the copied characters, because
a string in C requires a 0x00 byte to mark the end of the string.
So your code above is over-writing the next variable assigned by
the compiler, which is causing strange problems. We can see this
in your printout, with missing first characters.

If you want to put an 8-byte string into your buffer, you need to increase
the buffer size to 9 bytes to hold the 0x00 byte at the end. Example:
Code:
int8 buffer[9];


I will try to look at the rest of your problems. I notice that you have
changed several things from my "two board" test program here
http://www.ccsinfo.com/forum/viewtopic.php?t=29627&start=7
and you have changed the can_init() routine in can-18F4580.c.
I mean, you changed can-18F4580.c in ways that you didn't mention
in your posts. This may be causing part of your problems.
I will look into it.
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Wed Feb 19, 2014 1:31 am     Reply with quote

Thank you for the over-writing issue, I totally missed it. I changed a lot of things in your "two boards" test program because the communication doesn't work even between board #1 and #2 in the first "way" to go. So I focused on a "simple" communication, so just board #1 to board #2.

About the CAN library, I just modified the can_init() function, and more particularly the "CAN_RX_MODE", and add the I/O settings in this function

Code:

set_tris_c((*0xF94 & 0xBF ) | 0x80);


So finally, here is my can_init() routine, which I didn't change a lot :

Code:

void can_init(void) {
   can_set_mode(CAN_OP_CONFIG);   //must be in config mode before params can be set
   can_set_baud();
   curfunmode=CAN_FUN_OP_LEGACY;

   // RXB0CON
   //    filthit0=0
   //    jtoff=0
   //      rxb0dben=1   buffer zero will overflow into buffer one
   //      rxrtrro=0
   //      rxm1:0=0      will receive all valid IDs
   RXB0CON=0;
   RXB0CON.rxm=CAN_RX_ALL;
   RXB0CON.rxb0dben=CAN_USE_RX_DOUBLE_BUFFER;
   RXB1CON=RXB0CON;

   CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
   CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;
   CIOCON.tx2src=CAN_CANTX2_SOURCE;       //added for PIC18F6585/8585/6680/8680
   CIOCON.tx2en=CAN_ENABLE_CANTX2;        //added for PIC18F6585/8585/6680/8680

   can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 0
   can_set_id(RXFILTER0, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 0
   can_set_id(RXFILTER1, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 0

   can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID);  //set mask 1
   can_set_id(RXFILTER2, 0, CAN_USE_EXTENDED_ID);  //set filter 0 of mask 1
   can_set_id(RXFILTER3, 0, CAN_USE_EXTENDED_ID);  //set filter 1 of mask 1
   can_set_id(RXFILTER4, 0, CAN_USE_EXTENDED_ID);  //set filter 2 of mask 1
   can_set_id(RXFILTER5, 0, CAN_USE_EXTENDED_ID);  //set filter 3 of mask 1

   // set dynamic filters
   can_set_id(RXFILTER6, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER7, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER8, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER9, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER10, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER11, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER12, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER13, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER14, 0, CAN_USE_EXTENDED_ID);
   can_set_id(RXFILTER15, 0, CAN_USE_EXTENDED_ID);

   set_tris_c((*0xF94 & 0xBF ) | 0x80); // C7 as input and C6 as output
 
   can_set_mode(CAN_OP_NORMAL);
}


I know exchanging files here is not allowed, so don't ask to you to give me back the original file. But I never modify things I don't understand. Anyway, I don't really know if my problem is software or hardware. I even changed my two PICs, maybe a factory default...but nothing.

I really start to become crazy...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 20, 2014 12:28 am     Reply with quote

I was able to make my two board CAN bus test program work. I only
have one 18F46K80, so I used that on Board #2. I used an 18F2580
on Board #1. I didn't have two 8 MHz crystals so I used two 20 MHz
crystals. I can type into TeraTerm and see the typing OK.

I have posted a link to a photo of my test setup at the bottom. I am using
jumper wires as the "can bus". But I have MCP2551's and 120 ohm
resistors at each end. Note that I have a black ground jumper between
the two boards. This article says the CAN Bus needs one:
http://www.edn.com/electronics-blogs/dev-monkey-blog/4408712/Does-The-CAN-Bus-Need-a-Common-Ground-

I edited the can_init() routine in can-18F4580.c to set the correct TRISC,
the same as you did. That's the only change I made to that file. I left
this line unchanged:
Code:
RXB0CON.rxm=CAN_RX_VALID;


One problem in your early code was that you didn't specify a fuse for
your 8 MHz crystal. So the compiler used the INTRC_HP fuse by default.
You were not running off the crystal but rather the internal oscillator.
Possibly this was the source of your problem (too many errors).
But you fixed that problem by using the HSM fuse in your later code.

Here is the program for Board #2 which has the 18F46K80:
Code:

#include <18F46K80.h>
#fuses HSH, NOPROTECT, PUT, BROWNOUT, NOWDT, NOPLLEN
#fuses CANC  // *** Baklou is using CANC
#use delay(clock=20000000)

#include <can-18F4580.c>  // Use correct driver

#define BOARD1_ID  24
#define BOARD2_ID  25

// Uncomment this line to compile code for Board #1.
// Comment it out to compile for Board #2.
//#define BOARD1   1   

//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];

can_init();

#ifdef BOARD1   // For Board #1
while(1)
  {
   buffer[0] = getc();   // Wait for a character

   // Transmit it to board #2.
   can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte

   // Wait for the char to be echoed back.
   while(!can_kbhit());

   if(can_getd(rx_id, buffer, rx_len, rxstat))
     {
      if(rx_id == BOARD1_ID)  // Is it for this board ?
        {
         putc(buffer[0]);  // If so, display the char
        }
      }
  }
#else  // For Board #2
while(1)
  {
   if(can_kbhit())  // Message available ?
     {
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD2_ID)  // Is it for this board ?
           {
            // If so, echo back the character.
            can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
           }
         }
      }
  }
#endif
 
}


This is the Board #1 code:
Code:

#include <18F2580.h>
#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include <can-18F4580.c>  // Use correct driver

#define BOARD1_ID  24
#define BOARD2_ID  25

// Uncomment this line to compile code for Board #1.
// Comment it out to compile for Board #2.
#define BOARD1   1   

//======================================
void main()
{
struct rx_stat rxstat;
int32 rx_id;
int32 tx_id;
int8 rx_len;               
int8 buffer[8];

can_init();

#ifdef BOARD1   // For Board #1
while(1)
  {
   buffer[0] = getc();   // Wait for a character

   // Transmit it to board #2.
   can_putd(BOARD2_ID, buffer, 1, 1, 1, 0);

   buffer[0] = 0;   // Clear the buffer byte

   // Wait for the char to be echoed back.
   while(!can_kbhit());

   if(can_getd(rx_id, buffer, rx_len, rxstat))
     {
      if(rx_id == BOARD1_ID)  // Is it for this board ?
        {
         putc(buffer[0]);  // If so, display the char
        }
      }
  }
#else  // For Board #2
while(1)
  {
   if(can_kbhit())  // Message available ?
     {
      // If so, get the message.
      if(can_getd(rx_id, buffer, rx_len, rxstat))
        {
         if(rx_id == BOARD2_ID)  // Is it for this board ?
           {
            // If so, echo back the character.
            can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
           }
         }
      }
  }
#endif
 
}

The photo in the link below shows the test setup. The green and yellow
jumper wires are needed because my MCP2551 is hardwired to the CAN
bus pins on PortB. To test the PortC pins (which you are using), I
jumpered them over.
http://s27.postimg.org/itynzzckj/Two_CAN_bus_boards.jpg
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Thu Feb 20, 2014 9:31 am     Reply with quote

You really miss nothing ! lol effectively I made this mistake, and I saw it leaving the NOFCMEN fuse.
Anyway, after checking all of the stuffs, I think this only can be the oscillator frequency which is the problem...because it's the only thing which differs in my project than yours (and all the others) and as written on the can-18F4680 library, all the defaults settings are defined for this clock frequency...And I effectively still use this defaults settings...
I order a delivery for 20Mhz frequency oscillators, I will tell you this tomorrow.

Thank you a lot
baklou



Joined: 10 Jan 2014
Posts: 22

View user's profile Send private message

PostPosted: Mon Feb 24, 2014 4:00 am     Reply with quote

Hello everybody,

I come back again and for the last time. Instead of waiting for a new oscillator, I calculate again the good values to have a 125 Kbps CAN bus. And nothing has changed.
So I decided to change again my two transceivers, because of the previous issue I met, I was wondering...
And it is. It was my f***ing transceivers...from the beginning. Sorry to be so angry but on six transceivers ordered, I had at least two of them which was wrong....

Anyway, thanks to PCM Programmer to allow me his time and his advices.

Good news for a Monday morning Smile

Thanks Greg
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Mon Feb 24, 2014 10:56 am     Reply with quote

Well, that's a good start to the week !! Very Happy

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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