Once the Tera Term Pro window is clear, nodeA posts the
operator menu. Note the liberal use of VT-100 commands in
the menu function shown here:
void menu(void)
{
printf(“%c[2J”,esc);
printf(“%c[1;1H CAN DEMO MENU Ver 07.01.07”,esc);
printf(“%c[4;12H 1 LED ON”,esc);
printf(“%c[5;12H 0 LED OFF”,esc);
}
The menu code you see here is embellished when
nodeB comes online. The result is shown in Figure 1.
When nodeB initially powers up, it turns off its LED and
sends a status message to nodeA. The nodeA CAN
firmware uses this code to parse and act on the nodeB
status message:
if(ECANReceiveMessage(&id, data, &dataLen, &canflags))
{
if(data[0] == nodeA)
{
if(data[1] == led_off)
printf(“%c[7;5H NODE B REPORTS LED IS OFF”,esc);
if(data[1] == led_on)
printf(“%c[7;5H NODE B REPORTS LED IS ON “,esc);
}
printf(“%c[8;5H NODE B ID = 0x%X”,esc,id);
}
Note that the value contained within the received CAN
ID variable is actually the sender’s CAN ID. We can use
the incoming CAN ID information to our advantage if we
want to. As you can see in Figure 1, I’ve chosen to display
the sender’s CAN ID in the Tera Term Pro window along
with the LED status message. Meanwhile, nodeB has
posted its own Tera Term Pro message to a PC connected
to its RS-232 port. The nodeB power-up message is shown
in Figure 2.
As the LED operator, we can send two messages
from nodeA to nodeB. We can turn on the nodeB LED
by entering a “1” in the Tera Term Pro terminal emulator
window. Conversely, we turn off the nodeB LED by entering a “0” (zero). The Tera Term Pro application sends our
ASCII character command to the nodeA RS-232 port. The
nodeA RS-232 driver picks up the incoming character and
places it into the nodeA RS-232 receive buffer. The nodeA
CAN firmware is constantly scanning the RS-232 buffer
for the presence of a character. Once a valid character
is received, the nodeA CAN firmware embarks on the
transmission of a standardized command message to
nodeB. Here’s the whole command code transmission code
segment:
if(CharInQueue())
{
bytein = recvchar();
switch(bytein)
{
case ‘1’:
dataLen = 0;
id = myid;
data[0] = nodeB;
++dataLen;
data[1] = led_on;
++dataLen;
while(!ECANSendMessage(id, data, dataLen,
ECAN_TX_STD_FRAME));
break;
case ‘0’:
dataLen = 0;
id = myid;
data[0] = nodeB;
++dataLen;
data[1] = led_off;
++dataLen;
while(!ECANSendMessage(id, data, dataLen,
ECAN_TX_STD_FRAME));
break;
}
}
Let’s walk through what happens when I enter a “1” in
the nodeA Tera Term Pro terminal emulator window. The
nodeA CAN driver firmware invokes the CharInQueue
function and determines that a character is waiting in the
nodeA RS-232 receive buffer. I’ve entered a 1, which is a
valid command character. The nodeA CAN firmware parses
the ASCII 1 and assembles and transmits an “LED ON” CAN
command message to nodeB.
Meanwhile, nodeB’s CAN firmware is scanning for
incoming CAN messages. Regardless of where the
incoming CAN message originated, nodeB will post an
incoming message status banner on its Tera Term Pro
window. Since we are in a controlled simulation, we know
that I sent a valid LED ON command message to nodeB. So,
the nodeB CAN firmware will pass the data[0] parse and
take the data[1] == led_on path in the nodeB CAN driver
code that follows:
FIGURE 3. There
should be nothing
here that you can’t
trace back to in the
CAN source code.
Piece of cake.
FIGURE 4. Again, you
should have no trouble in
figuring out the who-done-
its here. We are doing
simple work here with an
LED. The same code
structures we are using
to control an LED can be
applied to other more
complex applications,
as well.
SERVO 09.2007 57