Why CAN FD communication not working with two nodes - can-bus

I'm trying to communicate with an actuator device via CAN FD connection, with the help of a Raspberry 4b and a Waveshare CAN hat.
While they are separated, using a tester I read the correct frames on both devices.
But when the Raspberry and the actuator are connected, I receive frames with unexpected ID, data and size on the Raspberry.
The code:
import time
import os
import can
import cantools
def startBus():
os.system('sudo ip link set can0 up type can bitrate 500000 dbitrate 5000000 restart-ms 1000 berr-reporting on fd on')
time.sleep(0.1)
global can0
can0 = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000, dbitrate=5000000 receive_own_messages=False, local_loopback=True,
fd=True, can_filters=None, ignore_rx_error_frames=False)
def shutDownBus():
os.system('sudo ifconfig can0 down')
print('shut down')
def periodicSend():
print('sendPeriodic')
messageID1 = 0xC0FFEE
data1 = [0, 1, 2, 3, 4, 5, 6, 7]
msg1 = can.Message(arbitration_id=messageID1,
is_fd=True,
data=data1,
is_extended_id=False)
messageID2 = 0xC0FFFF
data2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
msg2 = can.Message(arbitration_id=messageID2,
is_fd=True,
data=data2,
is_extended_id=False)
task1 = can0.send_periodic(msg1, 0.01)
if not isinstance(task1, can.ModifiableCyclicTaskABC):
task1.stop()
return
task2 = can0.send_periodic(msg2, 0.01)
if not isinstance(task2, can.ModifiableCyclicTaskABC):
task2.stop()
return
def listen():
print("listening")
for message in can0:
print(message)
# Calling the functions:
shutDownBus()
time.sleep(1)
startBus()
periodicSend()
listen()
x = False
while not x: time.sleep(0.1)
The contents of the received frames:
Timestamp: 1667826218.955793 ID: 0088 S Rx E DL: 8 00 00 94 00 00 00 00 00 Channel: can0
Timestamp: 1667826218.955... ID: 0088 S Rx E DL: 8 00 00 90 00 00 00 00 00 Channel: can0
Timestamp: 1667826218.955... ID: 0088 S Rx E DL: 8 00 00 04 00 00 00 00 00 Channel: can0
Timestamp: 1667826218.955... ID: 0088 S Rx E DL: 8 00 00 02 00 00 00 00 00 Channel: can0
And so on, the third byte keeps changing.
These are different from what I am expecting and what I am seeing on the tester (the tester shows the correct frames).
I tried to change the bitrates (500k and 5000k), though I'm rather sure these are correct.
It does not look like a hardware issue, as when separated, both are sending the expected frames.
Setting the ignore_rx_error_frames to False makes the messages disappear, but obviously it is not the solution.
Changing the local_loopback has no visible effect.
Some seemingly similar issues were related to the ACK bit (Sending messages with different ID on a pcan can bus, using python can), but 1) I don't see where and how I could manipulate this and 2) already the very first frame on the bus is not what I am expecting.
Any ideas would be greatly appreciated.

The solution was to adjust the sample-point and the dsample-point parameters when setting up the CAN interface:
sudo ip link set can1 up type can bitrate 500000 dbitrate 5000000 restart-ms 1000 berr-reporting on fd on sample-point .8 dsample-point .8
Apparently CAN FD is more sensitive to these parameters.

Related

Unable to get the correct CRC16 with a given Polynomial

I'm struggling with an old radiation sensor and his communication protocol.
The sensor is event driven, the master starts the communication with a data transmission or a data request.
Each data telegram uses a CRC16 to check only the variable data block and a CRC8 to check all the telegram.
My main problem is the crc16, According to the datasheet the poly used to check the data block is: CRC16 = X^14 + X^12 + X^5 + 1 --> 0x5021 ??
I captured some data with a valid CRC16 and tried to replicate the expected value in order to send my own data transmission, but I can't get the same value.
I'm using the sunshine CRC calculator trying any possible combination with that poly.
I also try CRC Reveng but no results.
Here are a few data with the correct CRC16:.
Data | CRC16 (MSB LSB)
14 00 00 0A | 1B 84
15 00 00 0C | 15 88
16 00 00 18 | 08 1D
00 00 00 00 | 00 00
00 00 00 01 | 19 D8
00 00 00 02 | 33 B0
01 00 00 00 | 5A DC
08 00 00 00 | c6 c2
10 00 00 00 | 85 95
80 00 00 00 | 0C EC
ff ff ff ff | f3 99
If I send an invalid CRC16 in the telegram, the sensor send a negative acknowledge with the expected value, so I can try any data in order to test or get more examples if needed.
if useful, the sensor uses a 8bit 8051 microprocessor, and this is an example of a valid CRC8 checked with sunshine CRC:
CRC8 = X^8 + X^6 + X^3 + 1 --> 0x49
Input reflected Result reflected
control byte | Data |CRC16 | CRC8
01 0E 01 00 24 2A 06 ff ff ff ff f3 99 |-> 0F
Any help is appreciated !
Looks like a typo on the polynomial. An n-bit CRC polynomial always starts with xn. Like your correct 8-bit polynomial. The 16-bit polynomial should read X16 + X12 + X5 + 1, which in fact is a very common 16-bit CRC polynomial.
To preserve the note in the comment, the four data bytes in the examples are swapped in each pair of bytes, which needs to be undone to get the correct CRC. (The control bytes in the CRC8 example are not swapped.)
So 14 00 00 0a becomes 00 14 0a 00, for which the above-described CRC gives the expected 0x1b84.
I would guess that the CRC is stored in the stream also swapped, so the message as bytes would be 00 14 0a 00 84 1b. That results in a sequence whose total CRC is 0.

Send CAN Message

I'm trying to use my smartphone to move my cars windows up and down. I recorded the CAN traffic two times by using AT MA. First time I just turned the ignition on. The second time I pushed the buttons for the electric windows.
I guess the PIDs for the window are the ones which didn’t occur in my first log file…
Now I want to try this by sending the bytes back but how can this be done with the ELM 327?
This is a message I received:
400 23 00 00 00 00 00 00 00
I already tried to set the header by doing:
AT SH 400
And then I wrote the remaining bytes to the stream:
23 00 00 00 00 00 00 00
But this seems not to be the cheat…
Cheers,
Stefan

APDU Write block commands on mifare 1K with ACR122U reader

Please,
I am trying to write a simple Binary Block to mifare 1k tag with a ACR122U reader.
I am trying write to block 01, 5 bytes, text:'teste' and read it back.
But I always get an error 6300 when update this block.
Any thoughts?
I am using windows 8.1/delphi xe8.
My log is:
SCardEstablishContext succeeded.
Card State changed in ACS ACR122U PICC Interface 0 to available
New reader found: ACS ACR122U PICC Interface 0
Card inserted in ACS ACR122U PICC Interface 0
ATR = 3B 8F 80 01 80 4F 0C A0 00 00 03 06 03 00 01 00 00 00 00 6A
SCardConnect (shared) succeeded.
Active Protocol: T=1
ISO 14443 A, Part3 Card Type: Mifare Standard 1K is detected
Sending APDU to card: FF 82 00 01 06 FF FF FF FF FF FF
SCardTransmit succeeded.
Card response status word: 9000 (OK)
Sending APDU to card: FF 86 00 00 05 01 00 01 60 01
SCardTransmit succeeded.
Card response status word: 9000 (OK)
Sending APDU to card: FF 86 00 00 05 01 00 01 60 01
SCardTransmit succeeded.
Card response status word: 9000 (OK)
Sending APDU to card: FF D6 00 01 05 74 65 73 74 65
SCardTransmit succeeded.
Card response status word: 6300 (State of non-volatile memory changed.)
This is easily resolved by reading the documentation.
You're writing to a block and you have to provide a complete block of information. The only option for Lc is x04 or x10 - four bytes or sixteen bytes. For the Mifare 1K, it's prettly clear that you need to supply 16 bytes. You have only 5 bytes of data, so pad the rest with zeros.
| CMD | block1 | 16 bytes | data ...
FF D6 00 01 10 74 65 73 74 65 00 00 00 00 00 00 00 00 00 00 00

NodeMCU fails to connect to Bluemix with TLS

I try to connect the NodeMCU with the IBM Bluemix IoT Foundation. The unsecured MQTT connect works splendid and pushes data from a BMP180 to the cloud. However, when I start using TLS it won't connect to the broker. I tried to make a TLS connection with mqtt.fx and it works fine, it seems like the NodeMCU is the problem.
If I run this code:
orgID="****"
BROKER = orgID..".<bluemix>"
BRPORT = 8883
CLIENTID = "d:"..orgID..":generic_esp:generic_esp_01"
print("ClientID: "..CLIENTID)
BRPWD = "***********"
BRUSER = "use-token-auth"
local function publish()
dofile('sensor.lc')
m:publish('iot-2/evt/esp8266/fmt/json',payload,1,0,
function(conn) print('Payload published') end)
end
m = mqtt.Client(CLIENTID, 120, BRUSER, BRPWD)
c = false
print('MQTT Init')
m:on('offline', function(con) print('mqtt offline'); c = false end)
m:connect(BROKER, BRPORT, 1, function(conn)
print('MQTT connected: '..BROKER..':'..BRPORT)
c = true
publish()
end)
tmr.alarm(1, 1000, 1, function()
if not c then
print('MQTT reconnecting')
m:close()
c = false
m:connect(BROKER, BRPORT, 1, function(conn) print('.. MQTT reconnected: '..BROKER..':'..BRPORT); c = true end)
end
if c then
publish()
end
end)
the esp8266 just prints "MQTT reconnecting" and can't connect.
Is something wrong with my code or is TLS not fully supported in NodeMCU 1.4, yet?
I've captured the your client hello in one of our test stands:
0000 16 03 02 00 33 01 00 00 2f 03 02 00 00 00 00 d0
0010 b1 a1 3a 07 1c 1b 3e f2 fc 03 91 d6 18 b5 ae 5d
0020 77 65 37 f5 07 10 45 d1 7e 1a ea 00 00 08 00 2f
0030 00 35 00 05 00 04 01 00
This looks like a TLS v1.1 client hello. Usually a client will hello with the "best" it can do and be negotiated downwards. In this case IoTF will simply close the connection because it only supports TLS 1.2. Please can you check that your device is setup to do TLS 1.2 ?

Flow control message while receiving CAN message with ELM327

I am trying to make a software, which runs under Windows and communicates with an ELM327 device. I created the first version and I went in my SMART ForTwo (SMART 451) vehicle and I managed to connect with the Instrument Cluster (Transmit CAN ID is 782, Receive CAN ID is 783). However I have a huge problem with Flow Control. Here is the log:
TX: ATI
RX: ELM327 v1.5a
TX: ATE0
RX: ATE0 OK
TX: ATSP6
RX: OK
TX: ATH1
RX: OK
TX: ATL1
RX: OK
TX: ATCFC1
RX: OK
TX: ATFCSM0
RX: OK
TX: ATAL
RX: OK
TX: ATSH782
RX: OK
TX: ATCRA783
RX: ?
TX: ATST64
RX: OK
TX: 1092
RX: 783 02 1A 87
TX: 1A87
RX: 783 10 16 5A 87 05 6E 00 08
I used another tool and I saw that the ELM327 device sends the Flow Control Frame, immediately. It is like this:
891.438 782 02 1A 87
891.444 783 10 16 5A 87 05 6E 00 08
891.444 782 30 00 00 00 00 00 00 00
As you can see - Flow Control frame is sent at exactly the same time as the First Frame, that is sent from the other device. I am sure that the other device has a problem to receive the "Flow Control" frame.
I studied the ELM327 documentation, but did not find any info about how to delay the Flow Control frame.
How should I correctly send the request "1A 87" and receive the response?
It's an old post but might help others!
This is my Experience with First Frame (FF) and Flow Control (FC) on MCP2515 connected with SPI.
First of all you should always send the FC message after the FF message and not in the same time.
Secondly the diagnostic reader can use the ID in the ECU response frame to continue communication with a specific ECU. In particular, multi-frame communication requires a response to the specific ECU ID rather than to ID 7DF. In the easy language you should not send your FF message with ID 7DF and you should address the exact ECU that you want to receive the consecutive frames. For instance requesting car VIN (based on real information from Golf VII):
7DF 02 09 00 00 00 00 00 00 //sending request
7E8 10 14 49 02 01 57 56 57 //receving from main ECU
7E0 30 00 00 00 00 00 00 00 //adressing the main ECU and not 7DF anymore !!
7E8 21 5A 5A 5A 41 55 5A 45 //consecutive messages are sending by 7E0!!
7E8 22 50 35 33 30 36 38 35
Hopefully it helps!
It's very easy, I guess..
Use the ATCFC0 command, and then you can process all the response frames from the control unit, and you need to manually send the flow control frame.

Resources