Another CAN example

10 May

Another CAN example: In this example, we will send real (meaningful) data across the CAN bus. We will be connecting 1-Wire devices (a temp sensor and a switch) to each TINI so we need to use CAN0 on both modules (recall that CAN1 uses the same CPU and SIMM pins as the 1-Wire bus so we can’t access 1-Wire and CAN1 at the same time). See Figure 12-19. What we will do is connect a 1-Wire thermometer (DS1820) to one TINI and send that temperature in a CAN message to another TINI. On that other TINI we will examine the temperature, compare it to some limit value and turn on or off a 1-Wire switch (a DS2406) that controls some external device (in this case an LED, but it could be all sorts of meaningful things).

Figure 12-19: TINI CAN sensor and actuator
A common circuit was used for both TINIs, containing a DS2401 (silicon serial number), a DS1820 (thermometer) and a DS2406 (switch) connected to an LED. This is the same board that was used in the 1-Wire chapter. By using the same board on both TINIs we could send data either direction.

Figure 12-20: TINI CAN Sensor and Actuator 1-Wire devices
A schematic for this is shown below.

Figure 12-21: TINI CAN Sensor and Actuator schematic
The original thought behind this was that we could send temperature frames from TINI1 to TINI2 and we would use the serial numbers on each TINI as a means of identification using Remote Frame Requests. Lacking a functioning API for successful Remote Frame Requests, we abandon that idea but continued on with sending temperature in a data frame. Listed below are both the sending (CanTempSensor) and receiving (CanTempControl) programs. They are very similar to the previous two programs with the addition of the 1-Wire classes Switch and Thermometer that were introduced in Chapter 10 and a helper library called ByteUtils8 for converting various data types to byte arrays and back again so we can send them over a CAN network in data frames.

Listing 12-3: CanTempSensor

import com.dalsemi.comm.*;
import com.dalsemi.system.*;
public class CanTempSensor {
static CanBus myCanBus;
static boolean gotone = false;

static CanFrame myFrame = new CanFrame();
static CanFrame myKillFrame = new CanFrame();
static int TEMP_ID                                            = 0×432;
static int SWITCH_ID                                          = 0×123;
static int KILL_ID                                            = 0×666;
static byte[] buffer = { 0,0,0,0,0,0,0,0 };
static TemperatureFrame myTempFrame;
static SerialNumberFrame mySerialNumberFrame;
static void main( String args[] )
{
System.out.println( “CanTempSensor” );
try {
// Create a new CanBus object
myCanBus = new CanBus( CanBus.CANBUS0 );
myCanBus.resetController();
// Set up the CANBUS speed (125 Kbps)

myCanBus.setBaudRatePrescaler( 7 );
myCanBus.setTSEG1( 13 );
myCanBus.setTSEG2( 7 );
myCanBus.setSynchronizationJumpWidth( 1 );
// Connect the CabBus controller to the CanBus
myCanBus.enableController();
// Set up messagecenter 1
//myCanBus.setMessageCenterRXMode( 1 );
myCanBus.setMessageCenterTXMode( 10 );
//   No filtering

//myCanBus.setMessageCenterMessageIDMaskEnable( 1, true );
//myCanBus.setMessageCenterMessageIDMaskEnable( 10, true );
// Look for all addresses
myCanBus.set11BitGlobalIDMask(0xFFFFFFFF);
//Enable the MC
//myCanBus.enableMessageCenter( 1 );
myCanBus.enableMessageCenter( 10 );
}
catch( Exception e ) {
System.out.println( “Error in configuring CANBus” );
System.out.println( e );
}

System.out.println( “Finding 1-wire devices…” );
// Configure a TemperatureFrame using a DS 1820 temp sensor
myTempFrame = new TemperatureFrame( TEMP_ID );
System.out.println( “Temp sensor: “ + myTempFrame.temperature.ROM_ID );
// Snooze for 5 secs to give the receiver time to get started
TINIOS.sleepProcess( 3000 );
// Send 10 frames on the canbus
for( int i=0; i<10; i++ ){
System.out.print( “Sending frame “ + i + “: “ );
// read temp and stuff into frame
myTempFrame.updateTemperature();
System.out.println( myTempFrame.temperature.degC + “ C”);

try {
// Send the frame out to the bus
//myCanBus.sendFrame( myTempFrame );
myCanBus.sendDataFrame( TEMP_ID, false, myTempFrame.data );
}
catch (Exception e) { System.out.println( e ); }
TINIOS.sleepProcess( 2000 );
}
try {
// Send out a kill frame
System.out.println( “Sending Kill Frame” );
myKillFrame.setID( KILL_ID );
myCanBus.sendFrame( myKillFrame );

myCanBus.close();
}
catch( Exception e ) { System.out.println( e ); }
System.exit(0);

}
}
Compile this:
C:\> cd src
C:\> javac -bootclasspath %TINI_HOME%\bin\tiniclasses.jar -d ..\bin
CanTempSensor.java

C:\> cd ..
C:\> java -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency
-p                                                                %TINI_HOME%\bin\owapi_dependencies_TINI.jar
-f bin
-x                                                                %TINI_HOME%\bin\owapi_dep.txt
-o bin\CanTempSensor.tini
-d %TINI_HOME%\bin\tini.db

Listing 12-4: CanTempMonitor

import com.dalsemi.comm.*;
import com.dalsemi.system.*;
public class CanTempControl {
static CanBus myCanBus;
static CanFrame myFrame = new CanFrame();
static CanFrame myKillFrame = new CanFrame();
static int TEMP_ID                                                = 0×432;
static int SWITCH_ID                                              = 0×123;
static int KILL_ID                                                = 0×666;
static byte[] buffer = { 0,0,0,0,0,0,0,0 };
static TemperatureFrame myTempFrame;
static SerialNumberFrame mySerialNumberFrame;
static void main( String args[] )
{
System.out.println( “CanTempControl” );
try {
// Create a new CanBus object
myCanBus = new CanBus( CanBus.CANBUS0 );
// Set up the CANBUS speed (125 Kbps)
myCanBus.setBaudRatePrescaler( 7 );
myCanBus.setTSEG1( 13 );
myCanBus.setTSEG2( 7 );
myCanBus.setSynchronizationJumpWidth( 1 );
// Connect the CabBus controller to the CanBus
myCanBus.enableController();
// Set up messagecenter 1
myCanBus.setMessageCenterRXMode( 1 );
//myCanBus.setMessageCenterTXMode( 10 );

//   No filtering
myCanBus.setMessageCenterMessageIDMaskEnable( 1, true );
// Look for all addresses
myCanBus.set11BitGlobalIDMask(0xFFFFFFFF);
//Enable the MC
myCanBus.enableMessageCenter( 1 );
catch( Exception e ) {
System.out.println( “Error in configuring CANBus” );
System.out.println( e );
System.out.println( “Finding 1-wire devices…” );
// Configure a TemperatureFrame using a DS 1820 temp sensor
Switch mySwitch = new Switch();
System.out.println( “Switch:                                  “ + mySwitch.ROM_ID );
mySwitch.turnOff();
myTempFrame = new TemperatureFrame();
// Send 10 frames on the canbus
System.out.println( “Listening…” );
boolean done=false;
while(done==false){
try {
// Check for incomming frames
myCanBus.receive(myFrame);
catch (Exception e) { System.out.println( e ); }
if (myFrame.getID()==TEMP_ID) {
System.out.print( “Received frame “ + n++ + “: “ );
myTempFrame.setData( myFrame.getData() );
System.out.print( myTempFrame.getTemperature() +
“ deg C” );
if ( myTempFrame.getTemperature()>= 30.0 ) {
mySwitch.turnOn();
System.out.print( “   switch ON” );
}
else {
mySwitch.turnOff();
}
System.out.println();

} else
if (myFrame.getID()==KILL_ID) {
System.out.println( “Received a KillFrame, exiting…” );
done = true;
}
TINIOS.sleepProcess( 2000 );
}
try {
myCanBus.close();
mySwitch.turnOff();
}
catch (Exception e) { System.out.println( e ); }
System.exit(0);
}
}

Compile this:
C:\> cd src
C:\> javac -bootclasspath %TINI_HOME%\bin\tiniclasses.jar
-d ..\bin CanTempControl.java
C:\> cd ..
C:\> java -classpath %TINI_HOME%\bin\tini.jar;. BuildDependency
-p                                                                %TINI_HOME%\bin\owapi_dependencies_TINI.jar
-f bin
-x                                                                %TINI_HOME%\bin\owapi_dep.txt
-o bin\CanTempControl.tini
-d %TINI_HOME%\bin\tini.db

Notice that we have also defined a message frame called a KillFrame. This is an empty data frame that has the message ID of 0×666. The CanTempSensor sends this frame when it is done. When the CanTempControl program, sees this frame, it knows to perform an orderly exit.

FTP these two programs to your TINIs in your CAN network. Run the CanTempControl.tini first and then start CanTempSensor.tini on the other TINI. The output of each is shown below.

TINI1 /> java CanTempSensor.tini
CanTempSensor
Finding 1-wire devices…
Temp sensor:    700000004B8F1010
Sending frame 0: 27.5 C
Sending frame 1: 27.5 C
Sending frame 2: 29.0 C
Sending frame 3: 31.0 C
Sending frame 4: 31.5 C
Sending frame 5: 29.5 C
Sending frame 6: 28.5 C
Sending frame 7: 29.5 C
Sending frame 8: 30.5 C
Sending frame 9: 30.0 C
Sending Kill Frame

TINI2 /> java CanTempControl.tini
CanTempControl
Finding 1-wire devices…
Switch:                             CB00000017006112
Listening…

Received frame 0: 27.5 deg C
Received frame 1: 27.5 deg C
Received frame 2: 29.0 deg C
Received frame 3: 31.0 deg C   switch ON
Received frame 4: 31.5 deg C   switch ON
Received frame 5: 29.5 deg C
Received frame 6: 28.5 deg C
Received frame 7: 29.5 deg C
Received frame 8: 30.5 deg C   switch ON
Received frame 9: 30.0 deg C   switch ON
Received a KillFrame, exiting…

You can also watch the LED on the CanTempControl end and see that it does indeed turn on and off depending on the value of the temperature received. We added a 2- second delay between the sent data frames so there is enough time to actually cause a temperature change.

Summary
In this chapter we have discussed the details of the Controller Area Network. We have seen how to configure TINI to talk and listen to CAN data frames and we have implemented a CAN sensor device (CanTempSensor) and a CAN actuator (CanTempControl). To be compatible with most available CAN sensors, you will need to implement some of the higher-layer protocol that these devices use.

References
1.  A list of devices that use CAN,

http://www.omegas.co.uk/CAN/devices.htm

2.  MicroCAN Project,

http://www.emicros.com/microcan/

3.  CAN links,

http://www.chipcenter.com/circuitcellar/september99/C99r7.htm

4.CAN monitor,

http://www.precisielandbouw.nl/project/tini/CanMonitor.html

5.CAN Products List,

http://www.synergetic.com/catalog/can/

6.Caraca,

http://caraca.sourceforge.net/

7.CAN Specification,

http://www.infineon.com/us/micro/can/can2spec.pdf

8.CAN Protocol Introduction,

http://www.infineon.com/cmc_upload/migrated_files/document_files/

Application_Notes/CANPRES.pdf
9.Controller Area Network Basics,

http://www.microchip.com/Download/appnote/category/analog/can/

00713a.pdf
10. On-line Training Class – Introduction to CAN, Controller Area Network,

http://www.esacademy.com/faq/classes/CANIntro/

11. Home Automation Posts Concerning CAN,

http://ha.ro.nu/hypermail/index.html#51

12. The CAN Protocol,

http://www.kvaser.com/can/protocol/index.htm

13. CAN-based Higher Layer Protocols and Profiles,

http://www.ixxat.de/deutsch/knowhow/artikel/pdf/icc97.pdf

14. Motorola Semiconductor Application Note, AN1798
CAN Bit Timing Requirements,

http://e-www.motorola.com/brdata/PDFDB/docs/AN1798.pdf

Random Posts

Comments are closed.