smart_car
一、声源定位
smart_car
smart_car的github代码下载
smart_car的video
树莓派USB与PC实现串口通信
python实时绘图
程序实现树莓派自启动
1、github上下载smart_car
图片中pixels可实现直接运行测试麦克风阵列的驱动是否完全安装好,smart_raspberry是主函数,但其中运行的库文件太多(如opencv)目前暂时不需要,因此小编自己新建了一个主函数,实际代码如下:
2、复制驱动库
(1)将/home/pi/voice-engine下的的库文件voice_engine复制至smart_car文件夹下
(2)报错头文件文件找不到解决方案(类似问题以此类推)
from .gcc_phat import gcc_phat 改为 from voice_engine.gcc_phat import gcc_phat
3、替换文件
将smart_car下的doa_respeaker_4mic_array和gcc_phat文件替换voice_engine下的同名文件,使其改为非关键字“snowboy”输出定位信息,麦克风阵列周围有声响时用print(amtitude,position)输出角度信息,并有相应位置的led灯闪烁(程序可实现)
4、程序运行
主要运行的main函数如下所示:并且运行后角度和位置输出在输出窗口可查看:
5、实验现象
当有声响时,响应位置的灯亮起,图片下方顶部的灯亮绿色,其他的灯为蓝色:
贴代码,是否需要加压缩包
二、串口数据发送
树莓派-pypi-UART串口
Python串口编程(转载)
Python字符串转十六进制进制互转
线程与进程的区别
1、write函数
从串口发送数据
[串口对象].write([单字节数组])
发送的数据必须是单字节数据,可以是单字节组成的list,也可以是单字节编码的字符串(如ASCII、UTF-8)。返回的是写入的字节数。
例1,发送16进制数据:
list1 = [0x01,0x02,0x03,0x10]
ser.write(list1)
会把这几个16进制数依次通过串口发出,另一端会接收到一模一样的数据。
例2,发送单字节编码的字符串:
ser.write(b’abcdefg’)
把字符串’abcdefg’的ascii码发出,另一端收到:0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67。
2、发送数据
程序初始设置好串口条件,在doa函数中调用设置的串口变量str实现写数据
str.write(position)
注意:如果需要将doa_thread和serial_thread同时进行是不可取的,这样会导致doa线程被阻挡,同时不能在线程中设置for循环,对线程而言速度运算要求过高,如果for循环运算阻挡了,线程将无法进行。
3、树莓派自启动
超声波模块使用
int led = 13;
float duration;
float distance;
//int srfPin = 8;
const int TrigPin = 8;
const int EchoPin = 7;
void setup()
{
Serial.begin(9600);
pinMode(led, OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(TrigPin,OUTPUT);
pinMode(EchoPin,INPUT);
Serial.println("Ultrasonic sensor");
}
void loop()
{
delay(100); // wait for a second
if (Serial.available()>0)
{
char cmd = Serial.read();
//Serial.print(cmd);
switch (cmd)
{
case '1':
Forward();
break;
case '2':
Back();
break;
case '3':
Turn_left();
break;
case '4':
Turn_right();
break;
//case '6':
// Measure();
default:
Stop();
}
}
Measure();
}
void Forward()
{
digitalWrite(9,HIGH);
digitalWrite(10,LOW);
digitalWrite(5,HIGH);
digitalWrite(6,LOW);
}
void Back()
{
digitalWrite(9,LOW);
digitalWrite(10,HIGH);
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
}
void Turn_right()
{
digitalWrite(9,LOW);
digitalWrite(10,HIGH);
digitalWrite(5,HIGH);
digitalWrite(6,LOW);
}
void Turn_left()
{
digitalWrite(9,HIGH);
digitalWrite(10,LOW);
digitalWrite(5,LOW);
digitalWrite(6,HIGH);
}
void Stop()
{
digitalWrite(9,LOW);
digitalWrite(10,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
}
void Measure()
{
digitalWrite(TrigPin, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(TrigPin, LOW);
duration = pulseIn(EchoPin, HIGH);
distance = duration/58;
Serial.print(":");
Serial.print(distance);
Serial.println(";");
delay(50);
}
软件安装:arduino
4、python
import serial
import time
import socket
import sys
import threading
import random
import os
import time
import struct
import serial
import numpy as np
import datetime
#import sqlite3
from voice_engine.source import Source
from voice_engine.channel_picker import ChannelPicker
from voice_engine.doa_respeaker_4mic_array import DOA
from pixels import pixels
ser = serial.Serial("/dev/ttyUSB0",9600,timeout=0.5)
ser.write(b"Raspberry pi is ready")
HOST = "0.0.0.0"
PORT = 9004
SOCK_ADDR = (HOST, PORT)
exit_now = 0
distance = 0
moving = False
last_movement_timestamp = datetime.datetime.now()
doa_valid = True
amplitute = 0
position = 0
def exit_signal_handle(sig,stack_frame): #no
global exit_now
print ("EXIT sig")
exit_now = 1
class serial_thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global amplitute,position
self.running = True
while self.running:
try:
while True:
#print(amplitute,position)
#ser.write(amplitute,position)
count = ser.inWaiting()
if count!=0:
recv = ser.read(count)
ser.write(recv)
ser.flushInput()
time.sleep(1)
except :
ser.close()
def stop(self):
self.running = False
class doa_thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global moving,last_movement_timestamp,doa_valid,amplitute,position
src = Source(rate=16000, channels=4, frames_size=320)
#ch1 = ChannelPicker(channels=4, pick=1)
doa = DOA(rate=16000)
#src.link(ch1)
src.link(doa)
src.recursive_start()
self.running = True
while self.running:
try:
time.sleep(1)
current_timestamp = datetime.datetime.now()
if doa_valid == True and ((current_timestamp - last_movement_timestamp).seconds > 2):
position, amplitute = doa.get_direction()
#str_position = ''.join([chr(i) for i in [int(b, 16) for b in position.split(' ')]])
print(position)
#ser.write(position)
if amplitute > 2000:
pixels.wakeup(position)
if position > 0 and position < 180:
pivot_right()
time.sleep(position/200)
stop()
elif position >= 180 and position < 360:
pivot_left()
position = 360 - position
time.sleep(position/200)
stop()
time.sleep(2)
else:
pixels.speak()
else:
pixels.think()
except:
print(sys.exc_info())
src.recursive_stop()
def hexShow(argv):
result = ''
hLen = len(argv)
for i in xrange(hLen):
hvol = ord(argv[i])
hhex = '%02x'%hvol
result += hhex+' '
print (result)
def stop(self):
self.running = False
def main():
global moving,last_movement_timestamp,doa_valid,distance,amplitute,position
doa_th = doa_thread()
doa_th.start()
#ser_th = serial_thread()
#ser_th.start()
doa_th.stop()
doa_th.join()
#ser_th.stop()
#ser_th.join()
if __name__ == "__main__":
main()