LIN_master  0.1
Arduino LIN master emulation with preemptive background operation
LIN_callback.ino
Go to the documentation of this file.
1 
10 // include files
11 #include "LIN_master3.h" // muDuino LIN via Serial3
12 #include "Tasks.h"
13 
14 // task scheduler periods [ms]
15 #define PRINT_PERIOD 1000 // period for status output
16 #define LIN_PERIOD 10 // LIN frame every N ms
17 
18 // pin to demonstrate background operation
19 #define PIN_TOGGLE 30
20 
21 // helper routine to print slave status
22 void printStatus(void);
23 
24 
25 // FED1.0 Daimler MRA2 LIN signals
26 uint8_t CoolFan_RPM = 0; // target speed request [%Nnom]
27 uint8_t CoolFan_RPM_Ack = 0; // target speed acknowledge [%Nnom]
28 uint8_t CoolFan_EmAct_Stat = 0; // status emergency mode
29 uint8_t CoolFan_RPM_Avg = 0; // actual speed [%Nnom]=[25rpm]
30 uint8_t CoolFan_OvrVolt_Stat = 0; // status overvoltage shutdown
31 uint8_t CoolFan_Voltage_Avg = 0; // supply voltage [0.2V]
32 uint8_t CoolFan_UnderVolt_Stat = 0; // status undervoltage shutdown
33 uint8_t CoolFan_Current_Avg = 0; // supply current [A]
34 uint8_t CoolFan_VoltDerat_Stat = 0; // status voltage derating
35 uint8_t CoolFan_cur_Temp = 0; // PCB temperature [C]
36 uint8_t CoolFan_TempDerat_Stat = 0; // status temperature derating
37 uint8_t CoolFan_Stiff_Stat = 0; // status sluggishness detection
38 uint8_t CoolFan_Blocking_Stat = 0; // status blocking detection
39 uint8_t CoolFan_Electr_Err = 0; // status internal error
40 uint8_t CoolFan_Mech_Err = 0; // status mechanical error
41 uint8_t CoolFan_OvrTemp_Err = 0; // status overtemperature
42 uint8_t CoolFan_Err_Group_ERR_Stat = 0; // collective error status
43 uint8_t CoolFan_Err_Group_SNA_Stat = 0; // status Tpcb or ADC error
44 uint8_t CoolFan_Type = 0; // cooler fan type
45 uint8_t RsErr_CF = 0; // ?
46 uint8_t WakeupStat_CF = 0; // ?
47 
48 
49 
50 void setup(void)
51 {
52  // show background operation
53  pinMode(PIN_TOGGLE, OUTPUT);
54 
55  // for user interaction via console
56  Serial.begin(115200); while(!Serial);
57 
58  // initialize LIN master (background operation)
59  LIN_master3.begin(19200, LIN_V2, true);
60 
61  // init task scheduler (also required for LIN master emulation!)
62  Tasks_Init();
63  Tasks_Add((Task) LIN_scheduler, LIN_PERIOD, 0);
64  Tasks_Add((Task) printStatus, PRINT_PERIOD, PRINT_PERIOD);
65  Tasks_Start();
66 
67 } // setup()
68 
69 
70 
71 void loop(void)
72 {
73  // toggle pin to show background operation
74  digitalWrite(PIN_TOGGLE, !digitalRead(PIN_TOGGLE));
75 
76  // set new RPM via keys
77  if (Serial.available())
78  {
79  uint8_t c = Serial.read();
80  switch(c)
81  {
82  // 1 -> reduce speed by 10%
83  case '1':
84  CoolFan_RPM = (uint8_t) max(0, (int) CoolFan_RPM - 10);
85  break;
86 
87  // 2 -> increase speed by 10%
88  case '2':
89  CoolFan_RPM = (uint8_t) min(127, (int) CoolFan_RPM + 10);
90  break;
91 
92  // 0 -> motor off
93  case '0':
94  CoolFan_RPM = 0;
95  break;
96 
97  } // switch key
98 
99  // print speed
100  Serial.print("new speed = ");
101  Serial.print(CoolFan_RPM*25);
102  Serial.println("rpm");
103 
104  } // key pressed
105 
106 } // loop()
107 
108 
109 
110 // actual LIN scheduler. Periodically called by task scheduler
111 void LIN_scheduler(void)
112 {
113  static uint8_t count = 0;
114  uint8_t id;
115  uint8_t numData;
116  uint8_t data[8];
117 
118  // debug
119  //count = 0;
120 
121  // FED1.0 Daimler MRA2: speed request
122  if (count == 0) {
123 
124  // assemble frame data
125  id = 0x3B;
126  numData = 2;
127  memset(data, 0, 8);
128  data[0] = CoolFan_RPM & 0x7f; // set speed from global variable. Clear bit 7 ("Notlaufuntredrueckung")
129 
130  // send master request
131  LIN_master3.sendMasterRequest(id, numData, data);
132 
133  // advance to next message
134  count++;
135 
136  } // count == 0
137 
138  else {
139 
140  // assemble frame data
141  id = 0x1B;
142  numData = 8;
143 
144  // get slave status & decode data
145  LIN_master3.receiveSlaveResponse(id, numData, statusDecode);
146 
147  // restart LIN scheduler
148  count=0;
149 
150  } // count == 1
151 
152 } // LIN_scheduler()
153 
154 
155 
156 // callback function to decode slave response signals
157 void statusDecode(uint8_t numData, uint8_t *data)
158 {
159  // extract status signals from slave response frame (
160  CoolFan_RPM_Ack = data[0] & 0x7F; // target speed [%Nnom]=[25rpm]
161  CoolFan_EmAct_Stat = bitRead(data[0],7); // status emergency mode
162  CoolFan_RPM_Avg = data[1] & 0x7F; // actual speed [%Nnom]=[25rpm]
163  CoolFan_OvrVolt_Stat = bitRead(data[1],7); // status overvoltage shutdown
164  CoolFan_Voltage_Avg = data[2] & 0x7F; // supply voltage [0.2V]
165  CoolFan_UnderVolt_Stat = bitRead(data[2],7); // status undervoltage shutdown
166  CoolFan_Current_Avg = data[3] & 0x7F; // supply current [A]
167  CoolFan_VoltDerat_Stat = bitRead(data[3],7); // status voltage derating
168  CoolFan_cur_Temp = data[4]; // PCB temperature [C]
169  CoolFan_TempDerat_Stat = bitRead(data[5],0); // status temperature derating
170  CoolFan_Stiff_Stat = bitRead(data[5],1); // status sluggishness detection
171  CoolFan_Blocking_Stat = bitRead(data[5],2); // status blocking detection
172  CoolFan_Electr_Err = bitRead(data[5],3); // status internal error
173  CoolFan_Mech_Err = bitRead(data[5],4); // status mechanical error
174  CoolFan_OvrTemp_Err = bitRead(data[5],5); // status overtemperature
175  CoolFan_Err_Group_ERR_Stat = bitRead(data[5],6); // collective error status
176  CoolFan_Err_Group_SNA_Stat = bitRead(data[5],7); // status Tpcb or ADC error
177  CoolFan_Type = data[6] & 0x0F; // cooler fan type
178  RsErr_CF = bitRead(data[7],5); // ?
179  WakeupStat_CF = (data[7] & 0xC0) >> 6; // ?
180 
181 } // statusDecode()
182 
183 
184 
185 // print slave response signals. Periodically called by task scheduler
186 void printStatus(void)
187 {
188  // LIN ok -> print some slave data
190  {
191  Serial.print("set speed: "); Serial.print(CoolFan_RPM_Ack*25); Serial.println("rpm");
192  Serial.print("act speed: "); Serial.print(CoolFan_RPM_Avg*25); Serial.println("rpm");
193  Serial.print("voltage: "); Serial.print(CoolFan_Voltage_Avg*0.2); Serial.println("V");
194  Serial.print("voltage: "); Serial.print(CoolFan_Current_Avg); Serial.println("A");
195  Serial.print("voltage: "); Serial.print((int)CoolFan_cur_Temp-0); Serial.println("C");
196  Serial.print("blocking: "); Serial.print((int)CoolFan_Blocking_Stat-0); Serial.println();
197  Serial.println();
198  }
199 
200  // print LIN error status
201  else {
202  Serial.print("LIN error (0x");
203  Serial.print(LIN_master3.error, HEX);
204  Serial.print("): ");
205 
207  Serial.print("statemachine ");
208 
210  Serial.print("echo ");
211 
213  Serial.print("timeout ");
214 
216  Serial.print("checksum ");
217 
219  Serial.print("misc ");
220 
221  Serial.println();
222 
223  } // error
224 
225  // reset latched error and flag for data received
227  LIN_master3.flagRxComplete = false;
228 
229 } // printStatus()
bool flagRxComplete
flag to indicate that data reception is complete. Must be cleared manually
Definition: LIN_master.h:142
void begin(uint16_t Baudrate, LIN_version_t Version, bool Background)
setup UART and LIN framework
Definition: LIN_master.cpp:24
LIN master emulation library for Serial3.
error reading LIN echo
Definition: LIN_master.h:70
error in LIN state machine
Definition: LIN_master.h:69
misc error, should not occur
Definition: LIN_master.h:73
LIN_error_t receiveSlaveResponse(uint8_t id, uint8_t numData, void(*Rx_handler)(uint8_t, uint8_t *))
receive a slave response frame with callback function
Definition: LIN_master.cpp:253
no error
Definition: LIN_master.h:68
LIN_error_t error
error state. Is latched until cleared
Definition: LIN_master.h:143
LIN protocol version 2.
Definition: LIN_master.h:51
LIN receive timeout.
Definition: LIN_master.h:71
LIN_error_t sendMasterRequest(uint8_t id, uint8_t numData, uint8_t *data)
send a master request frame
Definition: LIN_master.cpp:146
LIN checksum error.
Definition: LIN_master.h:72
LIN_Master_3 LIN_master3
instance of LIN master via Serial3
Definition: LIN_master3.cpp:17