利用arduino UNO配合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()

猜你喜欢

转载自blog.csdn.net/q310139033/article/details/108888650