Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

CANBus ...


  • Please log in to reply
19 replies to this topic

#1 greg

greg

    Advanced Member

  • Members
  • PipPipPip
  • 169 posts
  • LocationChicago, IL

Posted 26 September 2011 - 11:38 PM

So what are the chances of a new 'duino product that supports CANBus on the board vs having to buy a $50 shield? I could REALLY use CANBUS connectivity and would prefer to use my netduino over the Fez (which supports it on the board). Come on Walker - help a guy out! :)

#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 27 September 2011 - 03:42 AM

Hi Greg.
This CANBUS shield seems okay for the Netduino, since it uses the SPI.
I browsed quickly the datasheet, and it seems that there's no problems to interface.

Now, you answer me:
  • why you must use CANBUS?
  • why using Netduino over Fez?
Cheers
Biggest fault of Netduino? It runs by electricity.

#3 greg

greg

    Advanced Member

  • Members
  • PipPipPip
  • 169 posts
  • LocationChicago, IL

Posted 27 September 2011 - 12:57 PM

Hi Greg.
This CANBUS shield seems okay for the Netduino, since it uses the SPI.
I browsed quickly the datasheet, and it seems that there's no problems to interface.

Now, you answer me:

  • why you must use CANBUS?
  • why using Netduino over Fez?
Cheers


The whole point was to not have spend more than the netduino on a shield.

CANBus is required for some model railroad control bus communication.

As for Fez vs Netduino - I prefer the netduino - its open firmware vs closed.

#4 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 27 September 2011 - 05:04 PM

It is hard to be sure that everything will goes fine. You should -at least- analyze the shield commands and determine whether they can sent by the Netduino SPI. In other words, you should simulate the final program by starting the code. As soon you bump to some difficulty, that's a point to solve. Even before purchasing the shield. I have planned to interfacing a railroad model, but it will be via infrared. Hope it helps. Cheers
Biggest fault of Netduino? It runs by electricity.

#5 Daxl-B

Daxl-B

    Member

  • Members
  • PipPip
  • 10 posts

Posted 30 September 2011 - 02:55 PM

Hi, I am working on migrating the MCPC2515 library developed by Frank Kienast to work with the Netduino. I am using a Netduino plus with the sparkfun CAN shield, I have already test it using an Arduino and the same shield, but I am having trouble reading the SPI with the Netduino.

I am trying to minimize the dependency on SecretLabs libraries in order to keep the code compatible with other Micro .Net framework devices so I am only using these namespaces:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

This is my SPI initialization:

public bool InitCAN(BaudRate baudConst)
{
// Configure SPI
config = new SPI.Configuration(Pins.GPIO_PIN_D10 , LOW, 10, 10, HIGH, LOW, 16000, SPI.SPI_module.SPI1);
spi = new SPI(config);
}


And this is how I am trying to read from a register:

private byte readReg(byte regno)
{
byte[] val = new byte[1];
byte[] regnn = new byte[] { regno };
byte[] readbb = new byte[] { 0x00 };

spi.Write(READ);
spi.Write(regnn);
spi.WriteRead(readbb, val);
return val[0];
}


But for some reason I get only 0xFF each time I read the registry I unplug the shield and run the code and I read 0xff as well, any ideas what I might be doing wrong?

Thanks;
Dan

#6 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 30 September 2011 - 02:57 PM

LOW and HIGH constants, do they exist? Shouldn't it be true or false?
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#7 Daxl-B

Daxl-B

    Member

  • Members
  • PipPip
  • 10 posts

Posted 30 September 2011 - 03:23 PM

LOW and HIGH constants, do they exist? Shouldn't it be true or false?


Oh, I defined them:
private bool LOW = false;
private bool HIGH = true;

#8 Daxl-B

Daxl-B

    Member

  • Members
  • PipPip
  • 10 posts

Posted 05 October 2011 - 01:11 PM

I think I got it to work, my issue was on the level of clock while on idle state, anyway I have complete an initial code that works here: http://code.google.c.../downloads/list I test this code on a Netduino Plus and with the SF CAN-Bus shield, it transmit standard and extended messages (no remote or flow control for the moment) and receives only standard messages, I will keep working on improving the code but it may take a while, in any case this should be a good start point to any one that wants to use the CAN shield with Netduino.

#9 Mike P

Mike P

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts
  • LocationAuckland, New Zealand

Posted 07 October 2011 - 07:57 AM

Hi Dan,
I think I can help you with a few things here.
The Spec sheet for MCP2515 gives the max SPI bus speed as 10MHz. Your configuration has a value of 16000 which is 16MHz. Try using 1000 10000 or less.
From the figure below the clock idle state is false and the clock edge is true.
Attached File  MCPRead.png   27.42KB   30 downloads
However this chip supports both SPI Mode 0,0 and mode 1,1. So clock idle=true will also work. There is a bug with the current firmware that only affects clockidle=false so I would recommend you use clock idle=true
There is a bug with the current firmware that only affects clockidle=TRUE so I would recommend you use clock idle=FALSE (Sorry for the confusion)

Lastly the timing diagram(FIGURE 12-10) and the table that accompanies it (TABLE 13-6) show the maximum clock rate is 10MHz and the CS Setup Time and the CS Hold Time must be a minimum of 50ns.
Using a value of 0 for both these settings in your configuration will result in delays far exceding 50ns
So your config line should be:
config = new SPI.Configuration(Pins.GPIO_PIN_D10 , FALSE, 0, 0, TRUE, TRUE, 10000, SPI.SPI_module.SPI1);
config = new SPI.Configuration(Pins.GPIO_PIN_D10 , FALSE, 0, 0, FALSE, TRUE, 10000, SPI.SPI_module.SPI1);

Now for the read command.
Section 12.3 of the datasheet explains the read register process. It says that "The read operation is terminated by raising the CS pin"
It also says "
The MCP2515 expects the first byte after lowering CS to be the instruction/command byte. This implies that CS must be raised and then lowered again to invoke another command."
By writing using 3 operations as you are doing the chip select will be raised between each operation.
So you need to combine the read instruction, address data and reading the result into one writeread operation.
The following code should do this:
        SPI.Configuration xSPIConfig;
        SPI xspi;
        xSPIConfig = new SPI.Configuration(Pins.GPIO_PIN_D10, false, 0, 0, false, true, 10000, SPI.SPI_module.SPI1);
        xspi = new SPI(xSPIConfig);
        private byte readReg(byte regno)
        {
            byte[] writeBuffer = new byte[] {0x03, regno};
            byte[] readBuffer = new byte[1];
            xspi.WriteRead(writeBuffer,readBuffer,2);
            return readBuffer[0];
        }
You can find some more info in the Wiki
Using-SPI-Write-and-WriteRead

Edited by Mike P, 26 October 2011 - 03:29 AM.


#10 Daxl-B

Daxl-B

    Member

  • Members
  • PipPip
  • 10 posts

Posted 26 October 2011 - 02:08 AM

Hi Dan,
I think I can help you with a few things here.[...]



Hi Mike;

Thanks for the tips, it took my a little bit to test them because I did want to fully understand them (has been a while since a read a datasheet in so detail) and also waiting for my saleae logic to see the SPI (I love these "toys" :). I have just update the project on google, now it support TX and RX of 8 bytes extended and standard messages. I will work later on having remote frames implemented I am now trying to build a small TCP server to serve the CAN data into a PC application, but I have found issues with netduino plus network so I am reading other posts in the forum before annoying with already ask-answered questions.

cya around.
Dan

#11 Mike P

Mike P

    Advanced Member

  • Members
  • PipPipPip
  • 41 posts
  • LocationAuckland, New Zealand

Posted 26 October 2011 - 03:31 AM

I must have been half asleep when I wrote my earlier response. It was full of mistakes. I've edited it and fixed the errors. Regards, Mike Paauwe

#12 speedy913

speedy913

    New Member

  • Members
  • Pip
  • 6 posts

Posted 05 December 2012 - 03:18 AM

I am trying to run this code on a Netduino with the new Net Framework 4.2. I downloaded the original code (version 0.41), and copied it into a application I am developing for the Netduino. At the last line (spiBUS = new SPI(configSPI);) of code in the code snippet below, I get the following error:

A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.SPOT.Hardware.dll



namespace System
{
    /// <summary>
    /// Represents a class that handles the CAN tranceiver MCP2515.
    /// </summary>
    public class MCP2515
    {   	
	... // set up some variables
	
      	//private SPI spi;
 	private SPI spiBUS;

	public bool InitCAN(enBaudRate baudrate)
        {
            // Configure SPI            
            //var configSPI = new SPI.Configuration(SLAVESELECT, LOW, 0, 0, HIGH, HIGH, 10000, SPI.SPI_module.SPI1);

            SPI.Configuration configSPI = new SPI.Configuration(
                                    Pins.GPIO_PIN_D10,  // SS-pin
                                    false,              // SS-pin active state
                                    0,                  // The setup time for the SS port
                                    0,                  // The hold time for the SS port
                                    false,              // The idle state of the clock
                                    true,       		// The sampling clock edge
                                    10000,              // The SPI clock rate in KHz
                                    SPI_Devices.SPI1    // The used SPI bus (refers to a MOSI MISO and SCLK pinset)
                                );
            
            spiBUS = new SPI(configSPI);
	
		... // additional code to follow

	}

	// Additional Functions

}

What would cause this error? How would I go about fixing the error? When I change the last line to the following, I do not get an error at this location, but need the SPI to be a global variable as it is used in further functions.

	SPI spiBUS = new SPI(configSPI);


#13 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 05 December 2012 - 03:30 AM

Hi speedy913, Where in your code are you declaring spiBUS now? I see the variable named "spi" but not one named "spiBUS". Also...in NETMF, the chipSelect pin is reserved when the SPI object is created. Not sure what other code might be accessing pins, but you may want to double-check that Pins.GPIO_PIN_D10 is not used elsewhere. Finally: are you using the new 4.2.1 SDK with a Netduino Plus 2 project (using SecretLabs.NETMF.Hardware.Netduino.dll instead of ...NetduinoPlus.dll in your references)? Chris

#14 speedy913

speedy913

    New Member

  • Members
  • Pip
  • 6 posts

Posted 05 December 2012 - 06:24 AM

Thank you for the quick reply Chris! I am working on one of my first Netduino projects, and really appreciate all the help!

Hi speedy913,

Where in your code are you declaring spiBUS now? I see the variable named "spi" but not one named "spiBUS".


Sorry for the confusion, I have been working with a few versions of the code, trying to debug the problem. I edited the code in the previous post to show where "spiBUS" was defined.

Also...in NETMF, the chipSelect pin is reserved when the SPI object is created. Not sure what other code might be accessing pins, but you may want to double-check that Pins.GPIO_PIN_D10 is not used elsewhere.


I have checked that I am not using any other pin declarations than the following in my application:
// Set up 75HC595 Register for status LEDs
   	static OutputPort data = new OutputPort(Pins.GPIO_PIN_D3, false);   	//  75HC595  Pin 14
   	static OutputPort latch = new OutputPort(Pins.GPIO_PIN_D4, false);   	// 75HC595  Pin 12
   	static OutputPort clock = new OutputPort(Pins.GPIO_PIN_D5, false);      // 75HC595  Pin 11

   	// initialize the analog pins for the sensors (temperature and three delta pressure)
   	static AnalogInput DP_AWD_L = new AnalogInput(AnalogChannels.ANALOG_PIN_A0);        // Pin A0
   	static AnalogInput DP_AWD_R = new AnalogInput(AnalogChannels.ANALOG_PIN_A1);        // Pin A1
   	static AnalogInput DP_PILOT = new AnalogInput(AnalogChannels.ANALOG_PIN_A2);        // Pin A2

Finally: are you using the new 4.2.1 SDK with a Netduino Plus 2 project (using SecretLabs.NETMF.Hardware.Netduino.dll instead of ...NetduinoPlus.dll in your references)?


I updated my Netduino (not plus or plus 2) to the .NET Micro Framework v4.2 SDK using this forum. Here are the references I am using.
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

Does SPI need to be set up in another manner with the newer framework? I feel like the error has to do with the way the variable "spiBUS" is defined... Is there any more information I could provide to help solve this issue?

Again here is the popup error message:


An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.SPOT.Hardware.dll


And the error from Output Window in Debug mode:

A first chance exception of type 'System.InvalidOperationException' occurred in Microsoft.SPOT.Hardware.dll
An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.SPOT.Hardware.dll



#15 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 05 December 2012 - 07:39 AM

Hi speedy913, There are a lot of things that could be happening here :) The most likely scenario is a bad setting. Can you narrow down the issue to a simple repro case (less than 20 lines of code)? And then post that entire <=20 line program? We can then diagnose the issue here, and help you continue on your path... Chris

#16 speedy913

speedy913

    New Member

  • Members
  • Pip
  • 6 posts

Posted 05 December 2012 - 06:47 PM

Chris,

Here is my code in the simplest form I could make it. I have the onboard LED blink, and have the SPI configured through a timer. I am still getting the same error at the line "spiBUS = new SPI(sonfigSPI);"

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace CAN_SPI_Test
{
    public class Program
    {
        static OutputPort LED = new OutputPort(Pins.ONBOARD_LED, false);
        
        public static void Main()
        {
            var CANTimer = new Timer(new TimerCallback(checkCANmessages), null, 3 * 1000, 2 * 1000);    // Timer to call CAN tx/rx

            while (true)
            {
                LED.Write(true);
                Thread.Sleep(250);
                LED.Write(false);
                Thread.Sleep(250);
            }

        }

        static void checkCANmessages(object data)
        {
            MCP2515 CANHandler = new MCP2515();
            CANHandler.InitCAN();
        }

	}

	public class MCP2515
	{
        public SPI spiBUS;
        
        public bool InitCAN()
        {
            // Configure SPI            
            SPI.Configuration configSPI = new SPI.Configuration(Pins.GPIO_PIN_D10,  // SS-pin
                                    false,              // SS-pin active state
                                    0,                  // The setup time for the SS port
                                    0,                  // The hold time for the SS port
                                    true,   			// The idle state of the clock
                                    true,   			// The sampling clock edge
                                    10000,              // The SPI clock rate in KHz
                                    SPI_Devices.SPI1);    // The used SPI bus (refers to a MOSI MISO and SCLK pinset)     				

            spiBUS = new SPI(configSPI);

            // Write reset to the CAN transceiver.
            spiBUS.Write(new byte[] { 0xC0 });

            return true;
   		}
    }
}


#17 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 05 December 2012 - 07:11 PM

Hi speedy, Be sure to dispose of your spiBUS object. Otherwise that will wait until the garbage collector comes along from the time to time. At first glance I think that the object is trying to secure the SPI bus--while a previous instance of your timer created a SPI bus object which is already reserving your chip select pin. BTW, your CANHandler will also be disposed "sometime" by the garbage collector, since it's created in a timer-launched function which then goes away once it has executed. Chris

#18 speedy913

speedy913

    New Member

  • Members
  • Pip
  • 6 posts

Posted 05 December 2012 - 10:23 PM

Hi speedy,

Be sure to dispose of your spiBUS object. Otherwise that will wait until the garbage collector comes along from the time to time.

At first glance I think that the object is trying to secure the SPI bus--while a previous instance of your timer created a SPI bus object which is already reserving your chip select pin.

BTW, your CANHandler will also be disposed "sometime" by the garbage collector, since it's created in a timer-launched function which then goes away once it has executed.

Chris


Disposing the spiBUS object worked!!! Sure did learn my new fun fact for the day. I have updated my original code and it runs without error! Thank you for the help Chris!!!

Since I plan on only running the CAN timer and SPI every 60 seconds at a minimum (more likely to be every 5 minutes), would it be better to initialize and dispose of the SPI object each timer cycle or initialize it once in the main function? My application is a mobile (battery powered) data collecting routine that will run every 1-5 minutes, therefore power consumption is also a key factor in the design...

#19 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 05 December 2012 - 10:57 PM

Hi Speedy,

Disposing the spiBUS object worked!!! Sure did learn my new fun fact for the day. I have updated my original code and it runs without error! Thank you for the help Chris!!!

Since I plan on only running the CAN timer and SPI every 60 seconds at a minimum (more likely to be every 5 minutes), would it be better to initialize and dispose of the SPI object each timer cycle or initialize it once in the main function? My application is a mobile (battery powered) data collecting routine that will run every 1-5 minutes, therefore power consumption is also a key factor in the design...

For your current application with these bigger chips...I'd just initialize the bus once at the beginning.

Chris

#20 dosborn278

dosborn278

    New Member

  • Members
  • Pip
  • 3 posts

Posted 23 August 2013 - 01:21 PM

I'm trying to use the netduino-mcp2515 library with a netduino plus 2 and the canbus shield from sparkfun to communicate over obd-II with my car, but I can't seem to get a response back from the vehicle.  I put a multimeter on the pins that send the message from the canbus card and it seems to be sending the message out properly.  Has anyone gotten this setup to work?






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.