?效果
基于STM32單片機的桌面寵物機器人
概要
語音模塊:ASR PRO,通過天問block軟件燒錄語音指令
主控芯片:STM32F103C8T6 使用HAL庫
屏幕:0.96寸OLED屏,用來顯示表情
4個舵機,用來當作四只腿
底部一個面包板
?分析
初始化代碼,使用TIM3定時器的四個通道輸出PWM驅動舵機,控制腿部的運動
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);OLED_Init();OLED_Clear();OLED_ShowImage(0, 0, 128, 64, BMP1);mode_stand();
ASR PRO獲取到語音后通過串口通信把數據發送到STM32,在單片機內使用中斷的方式獲取語音數據,,然后根據語音指令判斷當前的動作
while (1) {HAL_UART_Receive_IT(&huart1, &command, 1);if (command == 0x32) { // 前進mode_forward();} else if (command == 0x31) {mode_slowstand();} else if (command == 0x33) { // 后退mode_behind();} else if (command == 0x34) { // 左轉mode_left();} else if (command == 0x35) { // 右轉mode_right();} else if (command == 0x36) { // 前后搖擺mode_swing_qianhou();} else if (command == 0x37) { // 左右搖擺mode_swing_zuoyou();} else if (command == 0x38) { // 跳舞mode_dance();} else if (command == 0x39) { // 立正mode_stand();} else if (command == 0x41) { // 起身mode_slowstand();} else if (command == 0x61) { // 坐下mode_strech();} else if (command == 0x63) { // 伸懶腰mode_lanyao();} else if (command == 0x64) { // 抬頭mode_headup();} else if (command == 0x65) { // 趴下睡覺mode_sleeppa();} else if (command == 0x66) { // 臥下睡覺mode_sleepwo();} else if (command == 0x68) { // 睡覺mode_sleepwo();}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}
分別展示對應的表情和動作,OLED直接用的現成的庫
#include "Mode.h"
#include <stdlib.h>
#include "Movement.h"
#include "OLED.h"
#include "gpio.h"
#include "main.h"extern uint8_t command;
uint8_t previousCommand = 0;void mode_forward(void) // 前進
{OLED_ShowImage(0, 0, 128, 64, BMP2); // 前進臉move_forward();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}
void mode_behind(void) // 后退
{OLED_ShowImage(0, 0, 128, 64, BMP2); // 前進臉move_behind();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}
void mode_left(void) // 左轉
{OLED_ShowImage(0, 0, 128, 64, BMP3); // 左轉臉move_left();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}
void mode_right(void) // 右轉
{OLED_ShowImage(0, 0, 128, 64, BMP4); // 右轉臉move_right();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}void mode_swing_qianhou(void) // 前后搖擺
{OLED_ShowImage(0, 0, 128, 64, BMP11); // 迷糊臉move_shake_qianhou();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}
void mode_swing_zuoyou(void) // 左右搖擺
{OLED_ShowImage(0, 0, 128, 64, BMP11); // 迷糊臉move_shake_zuoyou();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}void mode_dance(void) // 跳舞
{OLED_ShowImage(0, 0, 128, 64, BMP5); // 特殊臉move_dance();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;
}
void mode_stand(void) // 立正
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_stand();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;command = 0;HAL_Delay(1000);
}
void mode_slowstand(void) // 起身
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_slow_stand(previousCommand);HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;command = 0;
}
void mode_strech(void) // 坐下
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_slow_stand(previousCommand);OLED_ShowImage(0, 0, 128, 64, BMP2); // 前進臉,move_stretch();OLED_ShowImage(0, 0, 128, 64, BMP12); // 貓貓臉HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;command = 0;
}
void mode_twohands(void) // 交替抬手
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_stand();move_two_hands();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;command = 0;
}
void mode_lanyao(void) // 懶腰
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_slow_stand(previousCommand);OLED_ShowImage(0, 0, 128, 64, BMP9); // 開心臉lan_yao();OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;command = 0;
}
void mode_headup(void) // 抬頭
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_slow_stand(previousCommand);OLED_ShowImage(0, 0, 128, 64, BMP10); // 調皮臉move_head_up();HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);previousCommand = command;command = 0;
}
void mode_sleeppa(void) // 趴下睡覺
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_slow_stand(previousCommand);if (rand() % 2) { // 隨機產生兩種表情中的一種OLED_ShowImage(0, 0, 128, 64, BMP6); // 普通睡覺臉} else {OLED_ShowImage(0, 0, 128, 64, BMP8); // 酣睡臉}move_sleep_p();previousCommand = command;command = 0;
}
void mode_sleepwo(void) // 臥下睡覺
{OLED_ShowImage(0, 0, 128, 64, BMP1); // 立正臉move_slow_stand(previousCommand);if (rand() % 2) { // 隨機產生兩種表情中的一種OLED_ShowImage(0, 0, 128, 64, BMP6); // 普通睡覺臉} else {OLED_ShowImage(0, 0, 128, 64, BMP8); // 酣睡臉}move_sleep_w();previousCommand = command;command = 0;
}
void mode_nanshou(void) // 難受
{OLED_ShowImage(0, 0, 128, 64, BMP2); // 前進臉move_sleep_w();previousCommand = command;command = 0;
}
部分動作實現,分別設置對應腿的角度,通過延時達到效果
void move_stand(void) { // 站立Servo_SetAngle1(90);Servo_SetAngle2(90);Servo_SetAngle3(90);Servo_SetAngle4(90);HAL_Delay(500);
}void move_forward(void) { // 前進Servo_SetAngle1(135);Servo_SetAngle4(45);HAL_Delay(movedelay);Servo_SetAngle2(45);Servo_SetAngle3(135);HAL_Delay(movedelay);Servo_SetAngle1(90);Servo_SetAngle4(90);HAL_Delay(movedelay);Servo_SetAngle2(90);Servo_SetAngle3(90);HAL_Delay(movedelay);Servo_SetAngle2(135);Servo_SetAngle3(45);HAL_Delay(movedelay);Servo_SetAngle1(45);Servo_SetAngle4(135);HAL_Delay(movedelay);Servo_SetAngle2(90);Servo_SetAngle3(90);HAL_Delay(movedelay);Servo_SetAngle1(90);Servo_SetAngle4(90);HAL_Delay(movedelay);
}void move_behind(void) { // 后退Servo_SetAngle1(45);Servo_SetAngle4(135);HAL_Delay(movedelay);Servo_SetAngle2(135);Servo_SetAngle3(45);HAL_Delay(movedelay);Servo_SetAngle1(90);Servo_SetAngle4(90);HAL_Delay(movedelay);Servo_SetAngle2(90);Servo_SetAngle3(90);HAL_Delay(movedelay);Servo_SetAngle2(45);Servo_SetAngle3(135);HAL_Delay(movedelay);Servo_SetAngle1(135);Servo_SetAngle4(45);HAL_Delay(movedelay);Servo_SetAngle2(90);Servo_SetAngle3(90);HAL_Delay(movedelay);Servo_SetAngle1(90);Servo_SetAngle4(90);HAL_Delay(movedelay);
}