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

Can-bus, 18F2580+MCP2551. Loopback ok, real can not working.
Goto page Previous  1, 2, 3  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 Sep 23, 2009 6:13 pm     Reply with quote

I built the circuits, compiled it with PCH vs. 4.099, and it all works
perfectly. I modified my two PicDem2-Plus boards to add sockets
for MCP2551 chips (with 120 ohm termination resistors). I have a
3-pin, 12 inch (30.5 cm) cable connected between the two boards
with wires for CANH, CANL, and GND. I have the Rs pin on each
MCP2551 connected to ground. The Vref pin is unconnected.

To test it, I started up a terminal program such as TeraTerm and typed in
some text (random asdf, followed by Hello There). It all works.
Quote:
asdfasdfadsffas Hello there


Here's the code. This is the same as in the original post,
http://www.ccsinfo.com/forum/viewtopic.php?t=29627&start=6
except that the #include for the driver was changed to can-18F4580.c
because we are using the 18F2580, which is part of the 18F4580 family.
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
 
}

My advice is:

1. Check your connections. Make sure there is a ground wire between
the two boards.

2. Make sure that you really are compiling two versions of the code,
one for Board #1 and another for Board #2. To compile for #1,
you use this line:
Quote:
#define BOARD1 1

To compile for #2, you use this line:
Quote:
// #define BOARD1 1

Note that it's commented out for #2. The #define is not changed in any
way, except that it's commented out. It's not changed to '2', or 'FALSE'
or anything like that.

3. Final suggestion: Do it exactly like this, with the RS-232 terminal
for input and output. Don't use a debugger. Don't use a simulator.
Don't single-step through it or use breakpoints. Just run it.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Wed Sep 23, 2009 8:24 pm     Reply with quote

PCM programmer wrote:

My advice is:

1. Check your connections. Make sure there is a ground wire between
the two boards.

2. Make sure that you really are compiling two versions of the code,
one for Board #1 and another for Board #2. To compile for #1,
you use this line:
Quote:
#define BOARD1 1

To compile for #2, you use this line:
Quote:
// #define BOARD1 1

Note that it's commented out for #2. The #define is not changed in any
way, except that it's commented out. It's not changed to '2', or 'FALSE'
or anything like that.

3. Final suggestion: Do it exactly like this, with the RS-232 terminal
for input and output. Don't use a debugger. Don't use a simulator.
Don't single-step through it or use breakpoints. Just run it.


1: Check

2: Check

3: Heh... I just realized I don't have serial port in any of my PCs(laptops). I guess I need to buy some kind of adapter for that.

In the meanwhile:
If I change the board #1 program slightly

Code:
 buffer[0] = getc();   // Wait for a character

Changed to
Code:
delay_ms(1000);
buffer[0] = 'x';


and
Code:
putc(buffer[0]);  // If so, display the char

changed to
Code:
printf("%c",buffer[0]);


With those changes board #1 sends character 'x' once a second and if board #2 responds, prints reply to serial LCD.

This should work too, right?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 23, 2009 8:31 pm     Reply with quote

Get a USB to RS232 adapter for your laptop. Example:
http://siig.com/ViewProduct.aspx?pn=JU-CB1S12-S3
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 8:43 am     Reply with quote

PCM programmer wrote:
Get a USB to RS232 adapter for your laptop. Example:
http://siig.com/ViewProduct.aspx?pn=JU-CB1S12-S3


I tested this with USB-serial-adapter I found behind my mythtv-box. Cool

If I test with both boards: nothing

If I put board#1 to loopback mode: nothing.

If I modify board#1 code so that it sends character to serial TX every time it receives character to serial RX, I get characters to terminal screen --> connection between PC and PIC works.

PCM: Can you post the schematics of your test circuit? Question
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 2:06 pm     Reply with quote

Quote:

Can you post the schematics of your test circuit?

It's the same as your schematic, except that I don't use a resistor on
the Rs pins. They are connected to ground.
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Thu Sep 24, 2009 10:12 pm     Reply with quote

PCM programmer wrote:

It's the same as your schematic, except that I don't use a resistor on
the Rs pins. They are connected to ground.


So now our circuits are identical.

There must be something wrong in board#1 because loopback did not work.
I switched boards and now loopback works. Sort of.

Terminal (PC) sends character 'a' (0x61) to board, board sees it as 'O' (0x4F) and sends it to CAN loopback where putc-function sends it back to PC.
PC shows character 'X' (0x58).

PC terminal sw is using 9600 8N1, as well is Pic.

Can someone explain this to me?

I will build yet another board tomorrow and continue with it.

Edit: I just built a null-modem cable and verified connection between two PCs. Works just fine, all sent characters are received as expected.
Problem is not in PC side. Interesting.

Edit2:

When using just this simple loop:
Code:
while(1)
  {
   buffer[0] = getc();   // Wait for a character

   putc(buffer[0]);
}

Sending 'a' from PC terminal produces 'X' to terminal.

Usually this kind of behaviour is caused by baudrate mismatch between devices but I don't think it is the case this time. I tested changing baudrates in terminal side and in PIC-side. No effect.

Definition in 18F2580.c line 105 says:
Code:
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

Baudrate is 9600 and I suppose other parameters are 8-N-1 if they are not defined there?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 25, 2009 12:08 pm     Reply with quote

Quote:
When using just this simple loop:

while(1)
{
buffer[0] = getc(); // Wait for a character

putc(buffer[0]);
}

Sending 'a' from PC terminal produces 'X' to terminal.

Post your complete test program, which has the code shown above in it.
Post the compiler version that you are using.
Post a description of your RS232 hardware on your board.
i.e., Are you using a Max232A or similar type of chip ?
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Sun Sep 27, 2009 8:59 pm     Reply with quote

PCM programmer wrote:

Post your complete test program, which has the code shown above in it.
Post the compiler version that you are using.
Post a description of your RS232 hardware on your board.
i.e., Are you using a Max232A or similar type of chip ?


It is your test code with this modification:
Code:

#include <18F2580.h>
#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=20000000)
//#use rs232(baud=115200,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();
//can_set_mode(CAN_OP_LOOPBACK);
printf("Starttaillaan...");

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

   // 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
 
}


Compiler version:
halibatsuiba wrote:

Allright. Now I have PCH version 4.099 but...


Circuit is the same what you have, and now I have Rs tied to ground too.


PCM programmer wrote:

It's the same as your schematic, except that I don't use a resistor on
the Rs pins. They are connected to ground.


About RS232 hw: I replaced MAX232 in my circuit and now code above echoes everything back properly. Looks like I had defective MAX232.

If I set Board #1 to loopback mode, everything is echoed back to terminal as well.

Still nothing if I try to communicate with board #2 over CAN.
I rebuilt board #2 with all new components.

Debugging continues... Cool
halibatsuiba



Joined: 12 Aug 2009
Posts: 30

View user's profile Send private message

PostPosted: Sun Sep 27, 2009 10:10 pm     Reply with quote

halibatsuiba wrote:

Debugging continues... Cool


Whadda'y'know...

I could not think of anything else to try so I built another board #2 to a brand new breadboard and...

It works!
I can send characters from terminal over RS232 to board #1, board #1 sends them over CAN bus to board #2 who, in turn, echoes them back to terminal via board #1.
Shocked

[With voice of TV commercial]: "It works, It really works!"

Looks like there is two rows shorted in my old trusted currently-in-the-trashcan breadboard! Embarassed

Thank you, PCM, very much for your help in this issue.
ivrj



Joined: 17 Mar 2009
Posts: 7

View user's profile Send private message

PostPosted: Wed Oct 14, 2009 4:29 pm     Reply with quote

I am also having the same problem.

My board #1 stops on:

Quote:
while(!can_kbhit());


I've modified the source to be easy to debug:
Code:

#include <18F2580.h>
#fuses HS, NOPROTECT, PUT, BROWNOUT, NOWDT, NOLVP
#use delay(clock=4000000)
#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,i;               
   int8 buffer[8];
   
   can_init();
   // starting
   
   for(i = 0; i < 13; i++)
   {
           
            output_toggle(pin_a1);
            delay_ms(90);
            output_toggle(pin_a0);
            output_toggle(pin_a1);
            delay_ms(90);
            output_toggle(pin_a0);
   }
   output_low(pin_a0);
   output_low(pin_a1);
   delay_ms(400);
   #ifdef BOARD1   // For Board #1
   while(1)
   {
      printf("Press a key\r");
      output_high(pin_a0);
      buffer[0] = getc();   // Wait for a character
      printf("lido:%s ", buffer[0]);
      output_low(pin_a0);
      // Transmit it to board #2.
      if(can_putd(BOARD2_ID, buffer, 1, 1, 1, 0))
      {
         printf("Sending a msg\r");
         for(i = 0; i < 6; i++)
         {
            output_toggle(pin_a0);
            delay_ms(100);
           
         }
         output_low(pin_a0);
      }
      else
      {
         printf("Msg sending fail\r");
         for(i = 0; i < 15; i++)
         {
             output_toggle(pin_a0);
             delay_ms(50);
             output_low(pin_a0);
         }
      }
      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))
      { 
         printf("msg received\r");
         for(i = 0; i < 10; i++)
         {
            output_toggle(pin_a1);
            delay_ms(50);
           
         }
         output_low(pin_a1);
         if(rx_id == BOARD1_ID)  // Is it for this board ?
         {
            for(i = 0; i < 15; i++)
            {
               output_toggle(pin_a1);
               delay_ms(50);
               
            }
            output_low(pin_a1);
            printf("msg:" );
            putc(buffer[0]);  // If so, display the char
         }
      }
   }
#else  // For Board #2
   while(1)
   {
      if(can_kbhit())  // Message available ?
      {
         for(i = 0; i < 6; i++)  // blink a received led
            {
               output_toggle(pin_a0);
               delay_ms(100);
               
            }
            output_low(pin_a0);
         // If so, get the message.
         if(can_getd(rx_id, buffer, rx_len, rxstat))
         {
           
            if(rx_id == BOARD2_ID)  // Is it for this board ?
            {
               for(i = 0; i < 14; i++)  // blink a received led
               {
                  output_toggle(pin_a0);
                  delay_ms(50);
                 
               }
               output_low(pin_a0);
               // If so, echo back the character.
               can_putd(BOARD1_ID, buffer, 1, 1, 1, 0);
            }
          }
       }
   }
#endif
 
}


I just changed the oscilator from 20mhz to 4mhz.


I still have some doubts on the circuit, can somebody post the real circuit schematic?

Just to show my circuit:

is something wrong with him?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Oct 14, 2009 5:18 pm     Reply with quote

It worked for me. I changed the software in the 18F2580 test code,
http://www.ccsinfo.com/forum/viewtopic.php?t=40202&start=22
so that the #use delay() was 4 MHz instead of 20 MHz.

Check your connections and make sure you compiled the software
separately for board #1 and board #2. Make sure you know how
to do that. Make sure your RS232 cable is connected to board #1.
ivrj



Joined: 17 Mar 2009
Posts: 7

View user's profile Send private message

PostPosted: Thu Oct 15, 2009 8:09 am     Reply with quote

PCM programmer wrote:
It worked for me. I changed the software in the 18F2580 test code,
http://www.ccsinfo.com/forum/viewtopic.php?t=40202&start=22
so that the #use delay() was 4 MHz instead of 20 MHz.

Check your connections and make sure you compiled the software
separately for board #1 and board #2. Make sure you know how
to do that. Make sure your RS232 cable is connected to board #1.



I get other 2 20mhz crystal, changed back to the original code and changed delay to 20000000, but isn't working.

PCM programmer wrote:
Does your schematic represent real hardware ? Because, there is no
MCLR circuit. There are no 100 nF ceramic caps on the Vdd pins on any
chip. Also, I would jumper the Rs pins on the MCP2551 chips to ground
for the inital tests.


where I connect the 100nF ceramic capacitors?
ivrj



Joined: 17 Mar 2009
Posts: 7

View user's profile Send private message

PostPosted: Thu Oct 15, 2009 8:19 am     Reply with quote

Error found!

I crossed the can-l can-h lines!

now it´s working fine!

Thank u PCM!!!!
takyonxxx



Joined: 11 Mar 2011
Posts: 1

View user's profile Send private message

MCP2551 ISIS LIBRARY
PostPosted: Fri Mar 11, 2011 7:47 am     Reply with quote

HELLO..
I NEED MCP2551 ISIS LIBRARY, I SAW FROM THE PICTURE THAT YOU USE IT ON PROTEUS. PLEASE I NEED IT. MAY YOU SEND IT TO ME?
OR GIVE ME A LINK.
THANKS...
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 Previous  1, 2, 3  Next
Page 2 of 3

 
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