利用arduino UNO配合Orangepi 4B实现制作机器人
-
- 在上一个博客的最后我提到了利用Orangepi 4B制作机器人(传送门)
- 在这部分需要有更多的准备
-
- 知识储备
- 硬件方面准备
- 软件方面准备
- 开始实作
-
- arduino单片机程序编写
- Orangepi 4B 程序编写
在上一个博客的最后我提到了利用Orangepi 4B制作机器人(传送门)
传送门
上一个博客的中心是Orangepi 4B
这个博客则是以arduino配合Orangepi 4B完成电机驱动舵机等的操作
在这部分需要有更多的准备
知识储备
1.C语言/C++基础
2.arduino IDE软件的基本操作
3.arduino中json库(ArduinoJson.h)和多线程库(scoop.h)的使用
4.arduino中UART通信的方法
5.python中串口通信库(pyserial)和线程库(threading)的使用
硬件方面准备
上一个博客(见上方传送门)中的所有硬件外加一张arduino uno单片机(mega328p)几根杜邦线、一个两路电机驱动芯片、两个电机,一个万向滚珠、一个底座(实际上底盘可以根据经济决定好坏)当然你也可以再加上一些采集模块让你的机器人功能更丰富,我这里加装了一个DHT11模块(温湿度采集)。
软件方面准备
下载arduino IDE软件可在arduino中文社区下载中文社区
里面集中着各种arduino大佬
需要准备库我给大家准备好了大家解压到Arduino\libraries目录下即可
集合下载地址提取码:3101
python环境下需要下载对线程库(threading)以及串口通信库(pyserial)
下载方式为打开终端输入以下命令
pip install threading
pip install pyserial
开始实作
arduino单片机程序编写
#include <ArduinoJson.h> //载入库文件
#include <math.h>
#include <SCoop.h>
#include <dht11.h>
#define DHT11PIN 10 //定义模块端口
dht11 DHT11; //实例化 DHT模块
int beep=8; //蜂鸣器引脚定义
int speedleft=5; //左电机速度引脚定义
int speedright=6; //右电机速度引脚定义
int left_motor_go=3; //左电机正转引脚定义
int right_motor_go=4; //右电机正转引脚定义
int left_motor_back=2; //左电机反转引脚定义
int right_motor_back=7; //右电机反转引脚定义
char control1="停止"; //储存小车控制命令,初始命令为停止
StaticJsonBuffer<200> jsonsendBuffer; //创建json buffer空间
JsonObject& root = jsonsendBuffer.createObject();//将root定义为json变量
String line =""; //创建字符串变量存储串口接收到的字符串
defineTaskLoop(myTask1) //任务线程1每隔一秒
{
DHT11.read(DHT11PIN); //读取温湿度
float tem=(float)DHT11.temperature; //将温度值赋值给tem
float hum=(float)DHT11.humidity; //将湿度值赋给hum
root["Tempeature"]=tem;
root["Humidity"]=hum;
root.printTo(Serial); //延时一段时间
sleep(1000); //延时一段时间
}
void forward()//小车前进
{
digitalWrite(left_motor_go,HIGH); //左电机正转
digitalWrite(left_motor_back,LOW);
digitalWrite(right_motor_go,HIGH); //右电机正转
digitalWrite(right_motor_back,LOW);
}
void backward()//小车后退
{
digitalWrite(left_motor_go,LOW); //左电机反转
digitalWrite(left_motor_back,HIGH);
digitalWrite(right_motor_go,LOW); //右电机反转
digitalWrite(right_motor_back,HIGH);
}
void right()//小车单轮左转
{
digitalWrite(left_motor_go,LOW); //左电机停止
digitalWrite(left_motor_back,LOW);
digitalWrite(right_motor_go,HIGH); //右电机正转
digitalWrite(right_motor_back,LOW);
}
void left() //小车单轮右转
{
digitalWrite(left_motor_go,HIGH); //左电机正转
digitalWrite(left_motor_back,LOW);
digitalWrite(right_motor_go,LOW); //右电机停止
digitalWrite(right_motor_back,LOW);
}
void stopcar()//停车
{
digitalWrite(left_motor_go,LOW); //左电机停止
digitalWrite(left_motor_back,LOW);
digitalWrite(right_motor_go,LOW); //右电机停止
digitalWrite(right_motor_back,LOW);
}
void goright()//小车原地左转
{
digitalWrite(left_motor_go,LOW); //左电机反转
digitalWrite(left_motor_back,HIGH);
digitalWrite(right_motor_go,HIGH); //右电机正转
digitalWrite(right_motor_back,LOW);
}
void goleft()//小车原地右转
{
digitalWrite(left_motor_go,HIGH); //左电机正转
digitalWrite(left_motor_back,LOW);
digitalWrite(right_motor_go,LOW); //右电机反转
digitalWrite(right_motor_back,HIGH);
}
void setup() { //初始化
Serial.begin(115200);
pinMode(speedleft,OUTPUT); //设置引脚输入输出
pinMode(speedright,OUTPUT);
pinMode(left_motor_go,OUTPUT);
pinMode(right_motor_go,OUTPUT);
pinMode(left_motor_back,OUTPUT);
pinMode(right_motor_back,OUTPUT);
pinMode(beep,OUTPUT);
analogWrite(speedleft,100); //输入模拟值进行设定速度
analogWrite(speedright,100);
mySCoop.start();
digitalWrite(right_motor_back,HIGH);
delay(1000)
digitalWrite(right_motor_back,LOW); //初始化完成蜂鸣器响一秒
}
void loop() {
if(control1="goon")
forward();
else if(control1="goback")
backward();
else if(control1="turnleft")
left();
else if(control1="turnright")
right();
else if(control1="turnturnleft")
goleft();
else if(control1="turnternright")
goright();
else if(control1="stop")
stopcar();
else
stopcar();
yield();
}
void serialEvent()
{
if(Serial.available()) //串口是否有数据?
{
String line = Serial.readStringUntil('\r');
StaticJsonBuffer<200> jsonreciveBuffer;
JsonObject& data1 = jsonreciveBuffer.parseObject(line);
control1=data1["control"];
data1.printTo(Serial); //测试时使用
}
}
}
Orangepi 4B 程序编写
依旧在是之前demo上修改
加上多线程函数创建线程监测从单片机发来的信息,并且加上对硬件控制的指令uart通信等
import threading
import serial
from time import sleep
ser = serial.Serial('/dev/ttyS4', 115200, timeout=0.5) #香橙派4B只开放使用uart4端口
def recv(serial):
while True:
data =serial.read(30)
if data != '':
Tempeature=json.loads(data).get('Tempeature');
Humidity=json.loads(data).get('Humidity');
interrupted = False
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
# 回调函数,语音识别在这里实现,修改也是在这里
def callbacks():
global detector
time.sleep(0.2)
your_text=['哎,我在,你说','我来啦,我来啦,我来啦~','我是你的语音助手小贝']
a=random.randint(1,3)
print('小贝'+your_text[a])
play('huda/xiaobeihuida'+ str(a) +'.wav') # 为唤醒词事先准备好的回答
time.sleep(0.2)
try:
a = get_text()
if a =='嗯' or '':
pass
else:
print('你:'+a)
if '前进' in a:
controldata={ 'control':'goon'}
control=json.dumps(controldata)
ser.writ(control)
b='前进'
elif '后退' in a:
controldata={ 'control':'goback'}
control=json.dumps(controldata)
ser.writ(control)
b='后退'
elif '左转' in a:
controldata={ 'control':'ternleft'}
control=json.dumps(controldata)
ser.writ(control)
b='左转'
elif '右转' in a:
controldata={ 'control':'ternright'}
control=json.dumps(controldata)
ser.writ(control)
b='右转'
elif '原地左转圈' in a:
controldata={ 'control':'turnternleft'}
control=json.dumps(controldata)
ser.writ(control)
b='原地左转圈'
elif '原地右转圈' in a:
controldata={ 'control':'turnternright'}
control=json.dumps(controldata)
ser.writ(control)
b='原地右转圈'
elif '停止' in a:
controldata={ 'control':'stop'}
control=json.dumps(controldata)
ser.writ(control)
b='停止'
elif '室内温度' in a:
b='当前室内温度为'+str(Tempeature)+'摄氏度'
elif '室内湿度' in a:
b='当前室内湿度为百分之'+str(Humidity)
else:
b =get_chat_text(a)
print('小贝:'+b)
c = get_voice(b)
play(c)
except Exception:
print('小贝:我没听清楚,请重新说一下')
c = get_voice('我没听清楚,请重新说一下')
play(c)
@contextmanager
def no_alsa_error():
try:
asound = cdll.LoadLibrary('libasound.so')
asound.snd_lib_error_set_handler(c_error_handler)
yield
asound.snd_lib_error_set_handler(None)
except:
yield
pass
def wake_up():
global detector
model = 'xiaobeixiaobei.pmdl' # 我的唤醒词为 小贝小贝
# 终止方法为ctrl+c
signal.signal(signal.SIGINT, signal_handler)
# 唤醒词检测函数,调整sensitivity参数可修改唤醒词检测的准确性
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('正在聆听... 请说唤醒词:小贝小贝')
# main loop
# 回调函数 detected_callback=snowboydecoder.play_audio_file
# 修改回调函数可实现我们想要的功能
detector.start(detected_callback=callbacks, # 自定义回调函数
interrupt_check=interrupt_callback,
sleep_time=0.03)
# 释放资源
detector.terminate()
#程序入口
if __name__ == "__main__":
thread = threading.Thread(target=recv,args=(ser,))
thread.start()
wake_up()