User | Revision | Line number | New contents of line |
kevin |
0:bc8591a28ec2
|
1
|
#include "mbed.h"
|
kevin |
0:bc8591a28ec2
|
2
|
#include "TextLCD.h"
|
kevin |
0:bc8591a28ec2
|
3
|
// included in libmbed rev14
|
kevin |
0:bc8591a28ec2
|
4
|
#include "CAN.h"
|
kevin |
0:bc8591a28ec2
|
5
|
|
kevin |
0:bc8591a28ec2
|
6
|
//enable additional serial debug messages
|
kevin |
0:bc8591a28ec2
|
7
|
//#define DEBUG_CAN_TX 1
|
kevin |
0:bc8591a28ec2
|
8
|
#define DEBUG_IR_RAW 1
|
kevin |
0:bc8591a28ec2
|
9
|
|
kevin |
0:bc8591a28ec2
|
10
|
AnalogIn ain(p20);
|
kevin |
0:bc8591a28ec2
|
11
|
DigitalOut led1(LED1);
|
kevin |
0:bc8591a28ec2
|
12
|
DigitalOut led2(LED2);
|
kevin |
0:bc8591a28ec2
|
13
|
DigitalOut led3(LED3);
|
kevin |
0:bc8591a28ec2
|
14
|
DigitalOut led4(LED4);
|
kevin |
0:bc8591a28ec2
|
15
|
TextLCD lcd(p14, p15, p16, p17, p18, p19, p21, 8);
|
kevin |
0:bc8591a28ec2
|
16
|
|
kevin |
0:bc8591a28ec2
|
17
|
Ticker TickerSerialTx;
|
kevin |
0:bc8591a28ec2
|
18
|
Ticker TickerLcdUpdate;
|
kevin |
0:bc8591a28ec2
|
19
|
Ticker TickerCanTx;
|
kevin |
0:bc8591a28ec2
|
20
|
|
kevin |
0:bc8591a28ec2
|
21
|
// conversion from IR sensor input voltage to nominal gas value
|
kevin |
0:bc8591a28ec2
|
22
|
#define CAN_GAS_MAX 4000
|
kevin |
0:bc8591a28ec2
|
23
|
#define CAN_GAS_MIN 700
|
kevin |
0:bc8591a28ec2
|
24
|
#define IR_MIN 0.28
|
kevin |
0:bc8591a28ec2
|
25
|
#define IR_MAX 0.76
|
kevin |
0:bc8591a28ec2
|
26
|
// 0.12 - 0.13 idle update: seen 0.02 ..
|
kevin |
0:bc8591a28ec2
|
27
|
// 0.76 max
|
kevin |
0:bc8591a28ec2
|
28
|
|
kevin |
0:bc8591a28ec2
|
29
|
// CAN defines
|
kevin |
0:bc8591a28ec2
|
30
|
#define CAN_ID_EGAS_CTRL 0x700
|
kevin |
0:bc8591a28ec2
|
31
|
#define CAN_DLC_EGAS_CTRL 1
|
kevin |
0:bc8591a28ec2
|
32
|
#define CAN_ID_EGAS_NOMINAL_VALUE 0x701
|
kevin |
0:bc8591a28ec2
|
33
|
#define CAN_DLC_EGAS_NOMINAL_VALUE 2
|
kevin |
0:bc8591a28ec2
|
34
|
#define CAN_BYTE_HIGH_EGAS_NOMINAL_VALUE 1
|
kevin |
0:bc8591a28ec2
|
35
|
#define CAN_BYTE_LOW_EGAS_NOMINAL_VALUE 0
|
kevin |
0:bc8591a28ec2
|
36
|
|
kevin |
0:bc8591a28ec2
|
37
|
// CAN_RS pin at Philips PCA82C250 can bus controller.
|
kevin |
0:bc8591a28ec2
|
38
|
// activate transceiver by pulling this pin to GND.
|
kevin |
0:bc8591a28ec2
|
39
|
// (Rise and fall slope controlled by resistor R_s)
|
kevin |
0:bc8591a28ec2
|
40
|
// (+5V result in tranceiver standby mode)
|
kevin |
0:bc8591a28ec2
|
41
|
// For further information see datasheet page 4
|
kevin |
0:bc8591a28ec2
|
42
|
DigitalOut can_Pca82c250SlopePin(p28);
|
kevin |
0:bc8591a28ec2
|
43
|
// We use can on mbed pins 29(CAN_TXD) and 30(CAN_RXD).
|
kevin |
0:bc8591a28ec2
|
44
|
CAN can2(p30, p29);
|
kevin |
0:bc8591a28ec2
|
45
|
|
kevin |
0:bc8591a28ec2
|
46
|
// value which will be sent via can
|
kevin |
0:bc8591a28ec2
|
47
|
unsigned short u16_CanGasNominal = CAN_GAS_MIN;
|
kevin |
0:bc8591a28ec2
|
48
|
// IR sensor value
|
kevin |
0:bc8591a28ec2
|
49
|
float f_IrDistance = 0.0;
|
kevin |
0:bc8591a28ec2
|
50
|
// 2 can objects for TX
|
kevin |
0:bc8591a28ec2
|
51
|
CANMessage can_MsgTx_EgasCtrl;
|
kevin |
0:bc8591a28ec2
|
52
|
CANMessage can_MsgTx_EgasNominalValue;
|
kevin |
0:bc8591a28ec2
|
53
|
|
kevin |
0:bc8591a28ec2
|
54
|
|
kevin |
0:bc8591a28ec2
|
55
|
void CanSendEgas() {
|
kevin |
0:bc8591a28ec2
|
56
|
// idle
|
kevin |
0:bc8591a28ec2
|
57
|
if ( (f_IrDistance > IR_MAX) || (f_IrDistance < IR_MIN) ) {
|
kevin |
0:bc8591a28ec2
|
58
|
u16_CanGasNominal = CAN_GAS_MIN;
|
kevin |
0:bc8591a28ec2
|
59
|
}
|
kevin |
0:bc8591a28ec2
|
60
|
// valid input range
|
kevin |
0:bc8591a28ec2
|
61
|
else {
|
kevin |
0:bc8591a28ec2
|
62
|
u16_CanGasNominal = (unsigned short)( (((CAN_GAS_MAX-CAN_GAS_MIN)*(f_IrDistance-IR_MIN))/(IR_MAX-IR_MIN))+CAN_GAS_MIN );
|
kevin |
0:bc8591a28ec2
|
63
|
}
|
kevin |
0:bc8591a28ec2
|
64
|
// debug
|
kevin |
0:bc8591a28ec2
|
65
|
//printf("u16_CanGasNominal: %d\n\r", u16_CanGasNominal);
|
kevin |
0:bc8591a28ec2
|
66
|
|
kevin |
0:bc8591a28ec2
|
67
|
if (can2.write(can_MsgTx_EgasCtrl)) {
|
kevin |
0:bc8591a28ec2
|
68
|
#ifdef DEBUG_CAN_TX
|
kevin |
0:bc8591a28ec2
|
69
|
printf("CanTx--> id: 0x%x dlc: %d data: ", can_MsgTx_EgasCtrl.id, can_MsgTx_EgasCtrl.len);
|
kevin |
0:bc8591a28ec2
|
70
|
for (char i=0; i<can_MsgTx_EgasCtrl.len; i++) {
|
kevin |
0:bc8591a28ec2
|
71
|
printf("%x ", can_MsgTx_EgasCtrl.data[i]);
|
kevin |
0:bc8591a28ec2
|
72
|
}
|
kevin |
0:bc8591a28ec2
|
73
|
printf("\n\r");
|
kevin |
0:bc8591a28ec2
|
74
|
#endif
|
kevin |
0:bc8591a28ec2
|
75
|
}
|
kevin |
0:bc8591a28ec2
|
76
|
|
kevin |
0:bc8591a28ec2
|
77
|
can_MsgTx_EgasNominalValue.data[CAN_BYTE_LOW_EGAS_NOMINAL_VALUE] = (unsigned char)(u16_CanGasNominal);
|
kevin |
0:bc8591a28ec2
|
78
|
can_MsgTx_EgasNominalValue.data[CAN_BYTE_HIGH_EGAS_NOMINAL_VALUE] = (unsigned char)(u16_CanGasNominal>>8);
|
kevin |
0:bc8591a28ec2
|
79
|
if (can2.write(can_MsgTx_EgasNominalValue)) {
|
kevin |
0:bc8591a28ec2
|
80
|
#ifdef DEBUG_CAN_TX
|
kevin |
0:bc8591a28ec2
|
81
|
printf("CanTx--> id: 0x%x dlc: %d data: ", can_MsgTx_EgasNominalValue.id, can_MsgTx_EgasNominalValue.len);
|
kevin |
0:bc8591a28ec2
|
82
|
for (char i=0; i<can_MsgTx_EgasNominalValue.len; i++) {
|
kevin |
0:bc8591a28ec2
|
83
|
printf("%x ", can_MsgTx_EgasNominalValue.data[i]);
|
kevin |
0:bc8591a28ec2
|
84
|
}
|
kevin |
0:bc8591a28ec2
|
85
|
printf("\n\r");
|
kevin |
0:bc8591a28ec2
|
86
|
#endif
|
kevin |
0:bc8591a28ec2
|
87
|
}
|
kevin |
0:bc8591a28ec2
|
88
|
|
kevin |
0:bc8591a28ec2
|
89
|
}
|
kevin |
0:bc8591a28ec2
|
90
|
|
kevin |
0:bc8591a28ec2
|
91
|
void SerialSendIrDistance() {
|
kevin |
0:bc8591a28ec2
|
92
|
printf("f_IrDistance: %f\r\n", f_IrDistance);
|
kevin |
0:bc8591a28ec2
|
93
|
}
|
kevin |
0:bc8591a28ec2
|
94
|
|
kevin |
0:bc8591a28ec2
|
95
|
void LcdPrintIrDistance() {
|
kevin |
0:bc8591a28ec2
|
96
|
lcd.printf("IrDist: %f", f_IrDistance);
|
kevin |
0:bc8591a28ec2
|
97
|
}
|
kevin |
0:bc8591a28ec2
|
98
|
|
kevin |
0:bc8591a28ec2
|
99
|
int main() {
|
kevin |
0:bc8591a28ec2
|
100
|
// 500kbit/s
|
kevin |
0:bc8591a28ec2
|
101
|
can2.frequency(500000);
|
kevin |
0:bc8591a28ec2
|
102
|
// activate external can transceiver
|
kevin |
0:bc8591a28ec2
|
103
|
can_Pca82c250SlopePin = 0;
|
kevin |
0:bc8591a28ec2
|
104
|
// init everything
|
kevin |
0:bc8591a28ec2
|
105
|
can_MsgTx_EgasCtrl.id = CAN_ID_EGAS_CTRL;
|
kevin |
0:bc8591a28ec2
|
106
|
can_MsgTx_EgasCtrl.len = CAN_DLC_EGAS_CTRL;
|
kevin |
0:bc8591a28ec2
|
107
|
can_MsgTx_EgasCtrl.data[0] = 1;
|
kevin |
0:bc8591a28ec2
|
108
|
can_MsgTx_EgasNominalValue.data[CAN_BYTE_LOW_EGAS_NOMINAL_VALUE] = (unsigned char)(u16_CanGasNominal);
|
kevin |
0:bc8591a28ec2
|
109
|
can_MsgTx_EgasNominalValue.data[CAN_BYTE_HIGH_EGAS_NOMINAL_VALUE] = (unsigned char)(u16_CanGasNominal>>8);
|
kevin |
0:bc8591a28ec2
|
110
|
can_MsgTx_EgasNominalValue.id = CAN_ID_EGAS_NOMINAL_VALUE;
|
kevin |
0:bc8591a28ec2
|
111
|
can_MsgTx_EgasNominalValue.len = CAN_DLC_EGAS_NOMINAL_VALUE;
|
kevin |
0:bc8591a28ec2
|
112
|
|
kevin |
0:bc8591a28ec2
|
113
|
#ifdef DEBUG_IR_RAW
|
kevin |
0:bc8591a28ec2
|
114
|
TickerSerialTx.attach(&SerialSendIrDistance, 0.35);
|
kevin |
0:bc8591a28ec2
|
115
|
#endif
|
kevin |
0:bc8591a28ec2
|
116
|
TickerLcdUpdate.attach(&LcdPrintIrDistance, 0.75);
|
kevin |
0:bc8591a28ec2
|
117
|
TickerCanTx.attach(&CanSendEgas, 0.1);
|
kevin |
0:bc8591a28ec2
|
118
|
|
kevin |
0:bc8591a28ec2
|
119
|
while (1) {
|
kevin |
0:bc8591a28ec2
|
120
|
// get new distance from sensor
|
kevin |
0:bc8591a28ec2
|
121
|
f_IrDistance = ain.read();
|
kevin |
0:bc8591a28ec2
|
122
|
|
kevin |
0:bc8591a28ec2
|
123
|
// show distance with the 4 leds
|
kevin |
0:bc8591a28ec2
|
124
|
led1 = (f_IrDistance > 0.11) ? 1 : 0;
|
kevin |
0:bc8591a28ec2
|
125
|
led2 = (f_IrDistance > 0.30) ? 1 : 0;
|
kevin |
0:bc8591a28ec2
|
126
|
led3 = (f_IrDistance > 0.47) ? 1 : 0;
|
kevin |
0:bc8591a28ec2
|
127
|
led4 = (f_IrDistance > 0.74) ? 1 : 0;
|
kevin |
0:bc8591a28ec2
|
128
|
}
|
kevin |
0:bc8591a28ec2
|
129
|
}
|
kevin |
0:bc8591a28ec2
|
130
|
|
kevin |
0:bc8591a28ec2
|
131
|
// TODO: no global variables |