Skip to content

Commit 4d6ffd9

Browse files
authored
Merge pull request #8 from jshiv/feature/add_multiplex_decoding
Feature/add multiplex decoding
2 parents a76019b + 24b187a commit 4d6ffd9

File tree

2 files changed

+107
-45
lines changed

2 files changed

+107
-45
lines changed

README.md

Lines changed: 87 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,63 +22,109 @@ can-go makes use of the Linux SocketCAN abstraction for CAN communication.
2222

2323
### Decoding CAN messages
2424

25-
Decoding CAN messages from byte arrays can be done using `can.Payload`
25+
Decoding CAN messages from byte arrays can be done using `can.Payload`
2626

2727
```go
2828
func main() {
29-
// DBC file
30-
var dbcFile = []byte(`
31-
VERSION ""
29+
// DBC file
30+
var dbcFile = []byte(`
31+
VERSION ""
3232
NS_ :
3333
BS_:
3434
BU_: DBG DRIVER IO MOTOR SENSOR
3535
36-
BO_ 1530 DisconnectState: 14 MOTOR
37-
SG_ LockCountRearRight : 91|20@0+ (1,0) [0|1048575] "" IO
38-
SG_ DisconnectStateRearRight : 95|4@0+ (1,0) [0|5] "" IO
39-
SG_ CurrentRearRight : 79|16@0+ (1,0) [0|65535] "" IO
40-
SG_ DisconnectStateRearRightTarget : 64|1@0+ (1,0) [0|1] "" IO
41-
SG_ TargetSpeedRearRight : 63|15@0+ (0.125,-2048) [-2048|2047.875] "rad/s" IO
42-
SG_ LockCountRearLeft : 35|20@0+ (1,0) [0|1048575] "" IO
43-
SG_ DisconnectStateRearLeft : 39|4@0+ (1,0) [0|5] "" IO
44-
SG_ CurrentRearLeft : 23|16@0+ (1,0) [0|65535] "" IO
45-
SG_ DisconnectStateRearLeftTarget : 8|1@0+ (1,0) [0|1] "" IO
46-
SG_ TargetSpeedRearLeft : 7|15@0+ (0.125,-2048) [-2048|2047.875] "rad/s" IO
47-
48-
VAL_ 1530 DisconnectStateRearRight 0 "Undefined" 1 "Locked" 2 "Unlocked" 3 "Locking" 4 "Unlocking" 5 "Faulted" ;
49-
VAL_ 1530 DisconnectStateRearLeft 0 "Undefined" 1 "Locked" 2 "Unlocked" 3 "Locking" 4 "Unlocking" 5 "Faulted" ;
36+
BO_ 400 MOTOR_STATUS: 3 MOTOR
37+
SG_ MOTOR_STATUS_wheel_error : 0|1@1+ (1,0) [0|0] "" DRIVER,IO
38+
SG_ MOTOR_STATUS_speed_kph : 8|16@1+ (0.001,0) [0|0] "kph" DRIVER,IO
39+
40+
BO_ 200 SENSOR_SONARS: 8 SENSOR
41+
SG_ SENSOR_SONARS_mux M : 0|4@1+ (1,0) [0|0] "" DRIVER,IO
42+
SG_ SENSOR_SONARS_err_count : 4|12@1+ (1,0) [0|0] "" DRIVER,IO
43+
SG_ SENSOR_SONARS_left m0 : 16|12@1+ (0.1,0) [0|0] "" DRIVER,IO
44+
SG_ SENSOR_SONARS_middle m0 : 28|12@1+ (0.1,0) [0|0] "" DRIVER,IO
45+
SG_ SENSOR_SONARS_right m0 : 40|12@1+ (0.1,0) [0|0] "" DRIVER,IO
46+
SG_ SENSOR_SONARS_rear m0 : 52|12@1+ (0.1,0) [0|0] "" DRIVER,IO
47+
SG_ SENSOR_SONARS_no_filt_left m1 : 16|12@1+ (0.1,0) [0|0] "" DBG
48+
SG_ SENSOR_SONARS_no_filt_middle m1 : 28|12@1+ (0.1,0) [0|0] "" DBG
49+
SG_ SENSOR_SONARS_no_filt_right m1 : 40|12@1+ (0.1,0) [0|0] "" DBG
50+
SG_ SENSOR_SONARS_no_filt_rear m1 : 52|12@1+ (0.1,0) [0|0] "" DBG
5051
`)
5152

52-
// Create payload from hex string
53-
byteStringHex := "8000000420061880000005200600"
54-
p, _ := can.PayloadFromHex(byteStringHex)
53+
// Create payload from hex string
54+
byteStringHex := "004faf"
55+
p, _ := can.PayloadFromHex(byteStringHex)
5556

56-
// Load example dbc file
57-
c, _ := generate.Compile("test.dbc", dbcFile)
58-
db := *c.Database
57+
// Load example dbc file
58+
c, _ := generate.Compile("test.dbc", dbcFile)
59+
db := *c.Database
5960

60-
// Decode message frame ID 1530
61-
message, _ := db.Message(uint32(1530))
62-
decodedSignals := message.Decode(&p)
63-
for _, signal := range decodedSignals {
64-
fmt.Printf("Signal: %s, Value: %f, Description: %s\n", signal.Signal.Name, signal.Value, signal.Description)
65-
}
61+
// Decode message frame ID 400
62+
message, _ := db.Message(uint32(400))
63+
decodedSignals := message.Decode(&p)
64+
for _, signal := range decodedSignals {
65+
fmt.Printf("Signal: %s, Value: %f, Description: %s\n", signal.Signal.Name, signal.Value, signal.Description)
66+
}
6667
}
6768
```
6869

6970
```
70-
Signal: TargetSpeedRearLeft, Value: 0.000000, Description:
71-
Signal: DisconnectStateRearLeftTarget, Value: 0.000000, Description:
72-
Signal: CurrentRearLeft, Value: 4.000000, Description:
73-
Signal: LockCountRearLeft, Value: 1560.000000, Description:
74-
Signal: DisconnectStateRearLeft, Value: 2.000000, Description: Unlocked
75-
Signal: TargetSpeedRearRight, Value: 0.000000, Description:
76-
Signal: DisconnectStateRearRightTarget, Value: 0.000000, Description:
77-
Signal: CurrentRearRight, Value: 5.000000, Description:
78-
Signal: LockCountRearRight, Value: 1536.000000, Description:
79-
Signal: DisconnectStateRearRight, Value: 2.000000, Description: Unlocked
80-
```
71+
Signal: MOTOR_STATUS_wheel_error, Value: 0.000000, Description:
72+
Signal: MOTOR_STATUS_speed_kph, Value: 44.879000, Description:
73+
```
74+
75+
#### Multiplexed Signals
76+
77+
```go
78+
func main() {
79+
// DBC file
80+
var dbcFile = []byte(`
81+
VERSION ""
82+
NS_ :
83+
BS_:
84+
BU_: DBG DRIVER IO MOTOR SENSOR
85+
86+
BO_ 400 MOTOR_STATUS: 3 MOTOR
87+
SG_ MOTOR_STATUS_wheel_error : 0|1@1+ (1,0) [0|0] "" DRIVER,IO
88+
SG_ MOTOR_STATUS_speed_kph : 8|16@1+ (0.001,0) [0|0] "kph" DRIVER,IO
89+
90+
BO_ 200 SENSOR_SONARS: 8 SENSOR
91+
SG_ SENSOR_SONARS_mux M : 0|4@1+ (1,0) [0|0] "" DRIVER,IO
92+
SG_ SENSOR_SONARS_err_count : 4|12@1+ (1,0) [0|0] "" DRIVER,IO
93+
SG_ SENSOR_SONARS_left m0 : 16|12@1+ (0.1,0) [0|0] "" DRIVER,IO
94+
SG_ SENSOR_SONARS_middle m0 : 28|12@1+ (0.1,0) [0|0] "" DRIVER,IO
95+
SG_ SENSOR_SONARS_right m0 : 40|12@1+ (0.1,0) [0|0] "" DRIVER,IO
96+
SG_ SENSOR_SONARS_rear m0 : 52|12@1+ (0.1,0) [0|0] "" DRIVER,IO
97+
SG_ SENSOR_SONARS_no_filt_left m1 : 16|12@1+ (0.1,0) [0|0] "" DBG
98+
SG_ SENSOR_SONARS_no_filt_middle m1 : 28|12@1+ (0.1,0) [0|0] "" DBG
99+
SG_ SENSOR_SONARS_no_filt_right m1 : 40|12@1+ (0.1,0) [0|0] "" DBG
100+
SG_ SENSOR_SONARS_no_filt_rear m1 : 52|12@1+ (0.1,0) [0|0] "" DBG
101+
`)
102+
103+
// Create payload from hex string
104+
byteStringHex := "01af79f4aa3b459f"
105+
p, _ := can.PayloadFromHex(byteStringHex)
106+
107+
// Load example dbc file
108+
c, _ := generate.Compile("test.dbc", dbcFile)
109+
db := *c.Database
81110

111+
// Decode message frame ID 200
112+
message, _ := db.Message(uint32(200))
113+
decodedSignals := message.Decode(&p)
114+
for _, signal := range decodedSignals {
115+
fmt.Printf("Signal: %s, Value: %f, Description: %s\n", signal.Signal.Name, signal.Value, signal.Description)
116+
}
117+
}
118+
```
119+
120+
```
121+
Signal: SENSOR_SONARS_mux, Value: 1.000000, Description:
122+
Signal: SENSOR_SONARS_err_count, Value: 2800.000000, Description:
123+
Signal: SENSOR_SONARS_no_filt_left, Value: 114.500000, Description:
124+
Signal: SENSOR_SONARS_no_filt_middle, Value: 273.500000, Description:
125+
Signal: SENSOR_SONARS_no_filt_right, Value: 133.900000, Description:
126+
Signal: SENSOR_SONARS_no_filt_rear, Value: 254.800000, Description:
127+
```
82128

83129
### Receiving CAN frames
84130

pkg/descriptor/message.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,28 @@ func (m *Message) Decode(p *can.Payload) []DecodedSignal {
4747
copy(data[:], p.Data)
4848
}
4949

50-
numSignals := len(m.Signals)
50+
// Check for multiplexing
51+
var multiplexerValue uint
52+
multiplexerSignal, isMultiplexed := m.MultiplexerSignal()
53+
if isMultiplexed {
54+
if m.Length > 8 {
55+
multiplexerValue = uint(multiplexerSignal.DecodePayload(p))
56+
} else {
57+
multiplexerValue = uint(multiplexerSignal.Decode(data))
58+
}
59+
}
5160

52-
signals := make([]DecodedSignal, numSignals)
53-
for i, signal := range m.Signals {
61+
var signals []DecodedSignal
62+
for _, signal := range m.Signals {
5463
var valueDesc string
5564
var value float64
65+
66+
if signal.IsMultiplexed {
67+
if signal.MultiplexerValue != multiplexerValue {
68+
continue
69+
}
70+
}
71+
5672
if m.Length > 8 {
5773
valueDesc, _ = signal.UnmarshalValueDescriptionPayload(p)
5874
value = signal.DecodePayload(p)
@@ -67,7 +83,7 @@ func (m *Message) Decode(p *can.Payload) []DecodedSignal {
6783
Signal: signal,
6884
}
6985

70-
signals[i] = s
86+
signals = append(signals, s)
7187
}
7288
return signals
7389
}

0 commit comments

Comments
 (0)