• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <memory.h>
4 
5 /*
6  * Copyright (C) 2022 HiHope Open Source Organization .
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http:// www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  *
18  * limitations under the License.
19  */
20 
21 #include "ohos_init.h"
22 #include "cmsis_os2.h"
23 #include "iot_gpio.h"
24 #include "hi_io.h"
25 #include "hi_time.h"
26 #include "hi_adc.h"
27 #include "iot_errno.h"
28 #include "robot_hcsr04.h"
29 #include "robot_l9110s.h"
30 #include "robot_sg90.h"
31 #include "trace_model.h"
32 #include "robot_control.h"
33 
34 #define     GPIO5 5
35 #define     FUNC_GPIO 0
36 #define     IOT_IO_PULL_UP 1
37 #define     VLT_MIN                     (100)
38 #define     OLED_FLAG_ON                ((unsigned char)0x01)
39 #define     OLED_FLAG_OFF               ((unsigned char)0x00)
40 unsigned short  g_gpio5_adc_buf[ADC_TEST_LENGTH] = {0 };
41 unsigned int    g_gpio5_tick = 0;
42 unsigned int    g_car_control_demo_task_id = 0;
43 unsigned char   g_car_status = CAR_STOP_STATUS;
44 
switch_init(void)45 void switch_init(void)
46 {
47     IoTGpioInit(GPIO5);
48     hi_io_set_func(GPIO5, FUNC_GPIO);
49     IoTGpioSetDir(GPIO5, IOT_GPIO_DIR_IN);
50     hi_io_set_pull(GPIO5, IOT_IO_PULL_UP);
51 }
52 
GetCarStatus(void)53 unsigned char GetCarStatus(void)
54 {
55     return g_car_status;
56 }
57 
58 // 按键中断响应函数
gpio5_isr_func_mode(void)59 void gpio5_isr_func_mode(void)
60 {
61     printf("gpio5_isr_func_mode start\n");
62     unsigned int tick_interval = 0;
63     unsigned int current_gpio5_tick = 0;
64 
65     current_gpio5_tick = hi_get_tick();
66     tick_interval = current_gpio5_tick - g_gpio5_tick;
67 
68     if (tick_interval < KEY_INTERRUPT_PROTECT_TIME) {
69         return NULL;
70     }
71     g_gpio5_tick = current_gpio5_tick;
72 
73     if (g_car_status == CAR_STOP_STATUS) {
74         g_car_status = CAR_TRACE_STATUS;                 // 寻迹
75         printf("trace\n");
76     } else if (g_car_status == CAR_TRACE_STATUS) {
77         g_car_status = CAR_OBSTACLE_AVOIDANCE_STATUS;    // 超声波
78         printf("ultrasonic\n");
79     } else if (g_car_status == CAR_OBSTACLE_AVOIDANCE_STATUS) {
80         g_car_status = CAR_STOP_STATUS;                  // 停止
81         printf("stop\n");
82     }
83 }
84 
get_gpio5_voltage(void * param)85 unsigned char get_gpio5_voltage(void *param)
86 {
87     int i;
88     unsigned short data;
89     unsigned int ret;
90     unsigned short vlt;
91     float voltage;
92     float vlt_max = 0;
93     float vlt_min = VLT_MIN;
94     float a = 1.8;
95     float c = 4096.0;
96     int b = 4;
97     float vlt_1 = 0.6;
98     float vlt_2 = 1.0;
99 
100     hi_unref_param(param);
101     memset_s(g_gpio5_adc_buf, sizeof(g_gpio5_adc_buf), 0x0, sizeof(g_gpio5_adc_buf));
102     for (i = 0; i < ADC_TEST_LENGTH; i++) {
103         ret = hi_adc_read(HI_ADC_CHANNEL_2, &data, HI_ADC_EQU_MODEL_4, HI_ADC_CUR_BAIS_DEFAULT, 0xF0);
104 		// ADC_Channal_2  自动识别模式  CNcomment:4次平均算法模式 CNend
105         if (ret != IOT_SUCCESS) {
106             printf("ADC Read Fail\n");
107             return  NULL;
108         }
109         g_gpio5_adc_buf[i] = data;
110     }
111 
112     for (i = 0; i < ADC_TEST_LENGTH; i++) {
113         vlt = g_gpio5_adc_buf[i];
114         voltage = (float)vlt * a * b / c;
115 		/* vlt * 1.8* 4 / 4096.0为将码字转换为电压 */
116         vlt_max = (voltage > vlt_max) ? voltage : vlt_max;
117         vlt_min = (voltage < vlt_min) ? voltage : vlt_min;
118     }
119     printf("vlt_max is %f\r\n", vlt_max);
120     if (vlt_max > vlt_1 && vlt_max < vlt_2) {
121         gpio5_isr_func_mode();
122     }
123 }
124 
125 // 按键中断
interrupt_monitor(void)126 void interrupt_monitor(void)
127 {
128     unsigned int  ret = 0;
129     /* gpio5 switch2 mode */
130     g_gpio5_tick = hi_get_tick();
131     ret = IoTGpioRegisterIsrFunc(GPIO5, IOT_INT_TYPE_EDGE, IOT_GPIO_EDGE_FALL_LEVEL_LOW, get_gpio5_voltage, NULL);
132     if (ret == IOT_SUCCESS) {
133         printf(" register gpio5\r\n");
134     }
135 }
136 
137 /* Judge steering gear */
engine_go_where(void)138 static unsigned int engine_go_where(void)
139 {
140     float left_distance = 0;
141     float right_distance = 0;
142     unsigned int time = 100;
143     /* 舵机往左转动测量左边障碍物的距离 */
144 
145     engine_turn_left();
146     hi_sleep(time);
147     left_distance = GetDistance();
148     hi_sleep(time);
149 
150     /* 归中 */
151     regress_middle();
152     hi_sleep(time);
153 
154     /* 舵机往右转动测量右边障碍物的距离 */
155     engine_turn_right();
156     hi_sleep(time);
157     right_distance = GetDistance();
158     hi_sleep(time);
159 
160     /* 归中 */
161     regress_middle();
162     if (left_distance > right_distance) {
163         return CAR_TURN_LEFT;
164     } else {
165         return CAR_TURN_RIGHT;
166     }
167 }
168 
169 /* 根据障碍物的距离来判断小车的行走方向
170 1、距离大于等于20cm继续前进
171 2、距离小于20cm,先停止再后退0.5s, 再继续进行测距, 再进行判断
172 */
173 /* Judge the direction of the car */
car_where_to_go(float distance)174 static void car_where_to_go(float distance)
175 {
176     unsigned int time = 500;
177     if (distance < DISTANCE_BETWEEN_CAR_AND_OBSTACLE) {
178         car_stop();
179         hi_sleep(time);
180         car_backward();
181         hi_sleep(time);
182         car_stop();
183         unsigned int ret = engine_go_where();
184         printf("ret is %ud\r\n", ret);
185         if (ret == CAR_TURN_LEFT) {
186             car_left();
187             hi_sleep(time);
188         } else if (ret == CAR_TURN_RIGHT) {
189             car_right();
190             hi_sleep(time);
191         }
192         car_stop();
193     } else {
194         car_forward();
195         }
196 }
197 
198 /* car mode control func */
car_mode_control_func(void)199 static void car_mode_control_func(void)
200 {
201     float m_distance = 0.0;
202     regress_middle();
203     unsigned int time = 20;
204     while (1) {
205         if (g_car_status != CAR_OBSTACLE_AVOIDANCE_STATUS) {
206             printf("car_mode_control_func 1 module changed\n");
207             regress_middle();
208             break;
209         }
210 
211         /* 获取前方物体的距离 */
212         m_distance = GetDistance();
213         car_where_to_go(m_distance);
214         hi_sleep(time);
215     }
216 }
217 
RobotCarTestTask(void * param)218 void *RobotCarTestTask(void* param)
219 {
220     printf("switch\r\n");
221     switch_init();
222     interrupt_monitor();
223     unsigned int time = 20;
224 
225     while (1) {
226         switch (g_car_status) {
227             case CAR_STOP_STATUS:
228                 car_stop();
229                 break;
230             case CAR_OBSTACLE_AVOIDANCE_STATUS:
231                 car_mode_control_func();
232                 break;
233             case CAR_TRACE_STATUS:
234                 trace_module();
235                 break;
236             default:
237                 break;
238         }
239         IoTWatchDogDisable();
240         osDelay(time);
241     }
242 }
243 
RobotCarDemo(void)244 void RobotCarDemo(void)
245 {
246     osThreadAttr_t attr;
247 
248     attr.name = "RobotCarTestTask";
249     attr.attr_bits = 0U;
250     attr.cb_mem = NULL;
251     attr.cb_size = 0U;
252     attr.stack_mem = NULL;
253     attr.stack_size = CAR_CONTROL_DEMO_TASK_STAK_SIZE;
254     attr.priority = CAR_CONTROL_DEMO_TASK_PRIORITY;
255 
256     if (osThreadNew(RobotCarTestTask, NULL, &attr) == NULL) {
257         printf("[Ssd1306TestDemo] Failed to create RobotCarTestTask!\n");
258     }
259 }
260 APP_FEATURE_INIT(RobotCarDemo);
261