1#include <Servo.h>
2
3
4
5
6
7#define SHARP_PIN PA0
8
9#define SERVO_PIN PA9
10
11#define DISTANCE_MAX 150
12
13#define SERVO_STEP 2
14
15#define MEAS_DELAY_MS 30
16
17
18
19
20
21
22#define MSG_SYNC (0x55AA)
23
24#define MSG_CHECKSUM_START (0x55)
25
26#define MSG_MAX_SIZE (64)
27
28
29typedef struct
30{
31 uint16_t sync;
32 uint8_t checkSum;
33 uint8_t cmd;
34} S_MSG_HEADER;
35
36
37typedef struct
38{
39 uint16_t distanceMax;
40 uint16_t sampleNum;
41} S_MESSAGE_PARAMETERS;
42
43
44typedef struct
45{
46 uint16_t angle;
47 uint16_t distance;
48} S_MESSAGE_OBSTACLE;
49
50
51typedef enum
52{
53 eMESSAGE_PARAMETERS,
54 eMESSAGE_OBSTACLE,
55} E_MESSAGE_CMD;
56
57
58void sendMessage(uint8_t cmd, void* data)
59{
60
61 static struct
62 {
63 S_MSG_HEADER header;
64 uint8_t data[MSG_MAX_SIZE];
65 } sendData;
66 uint8_t msgSize;
67
68
69 switch (cmd)
70 {
71 case eMESSAGE_PARAMETERS:
72 msgSize = sizeof(S_MESSAGE_PARAMETERS);
73 break;
74 case eMESSAGE_OBSTACLE:
75 msgSize = sizeof(S_MESSAGE_OBSTACLE);
76 break;
77 }
78
79
80 sendData.header.cmd = cmd;
81 sendData.header.sync = MSG_SYNC;
82 sendData.header.checkSum = MSG_CHECKSUM_START;
83
84
85 for (uint8_t i = 0; i < msgSize; i++)
86 {
87 sendData.data[i] = ((uint8_t*)(data))[i];
88 sendData.header.checkSum += sendData.data[i];
89 }
90
91
92 Serial.write((uint8_t*)&sendData, sizeof(S_MSG_HEADER) + msgSize);
93}
94
95
96
97
98
99typedef struct {
100 float distance;
101 float adcVal;
102} S_DIST_ADC_MAP;
103
104
105
106
107S_DIST_ADC_MAP distAdcMap[] = {
108 {12, 3599},
109 {20, 3122},
110 {30, 2295},
111 {40, 1733},
112 {50, 1381},
113 {60, 1191},
114 {70, 1000},
115 {80, 855},
116 {90, 751},
117 {100, 662},
118 {110, 606},
119 {120, 559},
120 {130, 517},
121 {140, 465},
122 {150, 418},
123};
124
125
126float getDistance(float adcVal)
127{
128 float distance = DISTANCE_MAX;
129
130
131 for (int i = 1; i < (sizeof(distAdcMap)/sizeof(S_DIST_ADC_MAP)); i++)
132 {
133 if (adcVal > distAdcMap[i].adcVal)
134 {
135 float factor = (adcVal - distAdcMap[i].adcVal)/(distAdcMap[i-1].adcVal - distAdcMap[i].adcVal);
136 distance = factor * (distAdcMap[i-1].distance - distAdcMap[i].distance) + distAdcMap[i].distance;
137 break;
138 }
139 }
140
141 return distance;
142}
143
144
145
146
147
148Servo myServo;
149int servoVal = 0;
150int servoDir = SERVO_STEP;
151S_MESSAGE_OBSTACLE msgObstacle;
152S_MESSAGE_PARAMETERS msgParameters;
153
154void setup()
155{
156 Serial.begin(115200);
157 myServo.attach(SERVO_PIN);
158 myServo.write(servoVal);
159
160 msgParameters.distanceMax = DISTANCE_MAX;
161 msgParameters.sampleNum = (180/SERVO_STEP);
162}
163
164void loop()
165{
166 float adcVal;
167 float distance;
168
169
170 if (servoVal == 0)
171 sendMessage(eMESSAGE_PARAMETERS, &msgParameters);
172
173
174 adcVal = 0.0f;
175 for (int i = 0; i < 10; i++)
176 adcVal += analogRead(SHARP_PIN);
177 adcVal /= 10.0f;
178 distance = getDistance(adcVal);
179
180
181 msgObstacle.angle = servoVal;
182 msgObstacle.distance = (uint16_t)distance;
183 sendMessage(eMESSAGE_OBSTACLE, &msgObstacle);
184
185
186 if (servoVal >= 180)
187 servoDir = -SERVO_STEP;
188 else if (servoVal <= 0)
189 servoDir = +SERVO_STEP;
190
191 servoVal += servoDir;
192 myServo.write(servoVal);
193
194
195 delay(MEAS_DELAY_MS);
196}