I can confirm that CAN works great.
I have 3 pages of CAN articles I was in the process of doing, but didn't seem much point after the last project I published didn't even get an acknowledgement, so I just stepped back from it.
But here's one of them, which is a combined sender/receiver script which doesn't require any additional hardware other than the CAN transceivers, and uses the last byte of the devices IP address as the CAN node ID (although it can be changed using a textbox$ during operation if wished).
It's been a couple of months since I last used the script, and I've merely copied and pasted it below for you... so just remember that it was unfinished and still needed tweaking, and that I haven't run it for ages.
Once you're able to send via CAN using web controls it's easy enough to add some hardware.
Code: [Local Link Removed for Guests]
'Same CAN script but only one device will TX or RX at any time
'Local (RX) CAN ID defaults to the local IP node number, but can be changed
'Target (TX) CAN ID defaults to 631, but can be changed
'The local screen shows any local onHTMLchange component changes,
' so the slider changes the meter, and the buttons change the LEDs
'CANsend button sends current local values to the remote CAN device
' so both devices can interact via CAN to change outputs of each other
' first data byte is being used to send the Senders (TX) ID
localIP$ = WORD$(IP$,1)
nodeIP$ = WORD$(localIP$,4,".")
RXid = val(nodeIP$) 'this device
TXid = 631 'target device
canlength=0
ret = CAN.SETUP(500, 26, 5, 1) '500Kb/sec, TX, RX, mode, [filter]
if ret>0 then wlog "Error " + str$(ret): end
dim byte(8)
'senderID=0 'ID of sending device shown as last received sender by receiving device
s1=0 'web slider (0 to 255)
m1=0 'web meter (0 to 255)
but1=0 'web button1
but2=0 'web button2
led1=1 'web LED1
led2=1 'web LED2
htmleventvar$=""
gosub screen
onhtmlchange screenchanged
oncanbus canRX
wlog "CAN " + nodeIP$ + " waiting..."
wait
screen:
cls
a$="<br>"
a$=a$ + "local CAN ID=" + textbox$(RXid) + "<br><br>"
a$=a$ + slider$(s1,0,254) + " " + meter$(m1,0,254) + "<br>"
a$=a$ + led$(led1)+" " + button$(" led 1 ",but1change) + "<br>"
a$=a$ + led$(led2)+" " + button$(" led 2 ",but2change) + "<br><br>"
a$=a$ + "target CAN ID=" + textbox$(TXid) + "<br><br>"
a$=a$ + " " + button$(" CANSend ",CANsend) + "<br><br>"
a$=a$ + "last received msg: byte0="+str$(byte(0))+", 1="+str$(byte(1))+", 2="+str$(byte(2))+", 3="+str$(byte(3))+", 4="+str$(byte(4))+", 6="+str$(byte(6))+", 7="+str$(byte(7))+"<br><br>"
html a$
return
screenchanged:
if htmleventvar$="s1" then m1=s1
refresh
return
but1change:
led1= 1-led1
refresh
return
but2change:
led2= 1-led2
refresh
return
canRX:
wlog "CAN msg received"
id=can.ident
wlog "ID="+str$(id)
if id=RXid then wlog "This is the correct target"
flags=can.flags
canlength=can.len
wlog "msg len="+str$(canlength)
for c=0 to canlength-1
byte(c) = can.byte(c)
wlog "byte " + str$(c) + " = " + str$(byte(c))
next c
senderID=can.byte(0)
m1=can.byte(1)
led1=can.byte(2)
led2=can.byte(3)
refresh
gosub screen
return
canTX:
CANsend:
'ret = CAN.WRITE( id, can_flags [,b0 [,b1 [,b2 [,b3 [,b4 [,b5 [,b6 [,b7 ]]]]]]]])
ret = can.write(TXid,0,RXid,m1,led1,led2,5,0,dateunix(date$),timeunix(time$)) 'b0 is being used to include senders ID
if ret >0 then wlog "Warning - transmit failure" else wlog "msg sent to ID " + str$(TXid)
return
end '---------- End -------------