简介
实验剩了一个jetson nano 开发板,闲着也是闲着,拿过来搞点好玩的,jetson nano 和树莓派差不多,加个L298N电机驱动板模块,买两个直流电机就行,目前图省事儿使用无线键盘控制,缺点是不知道程序目前的执行状态,后面考虑加个led指示灯
一、jetson nano 小车 1.0版本
1.1主要硬件
jetson nano主控板一个
L298N电机驱动板模块
直流电机*2
直流电源 7号电池*4
1.2接线方式
1.3 代码
电机调节就不细讲了,可以看文章:树莓派控制直流电机_树莓派3b+控制直流电机正反转-CSDN博客
控制代码:
import time
import RPi.GPIO as GPIO # 引入GPIO模块
import tty, sys, select, termios
def getKey(settings):
tty.setraw(sys.stdin.fileno())
rlist = select.select([sys.stdin], [], [], 0.1)
if rlist:
key = sys.stdin.read(1)
else:
key = ""
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
return key
# 前进
def Forward():
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
GPIO.output(INT3, GPIO.HIGH)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(INT1, GPIO.HIGH)
GPIO.output(INT2, GPIO.LOW)
# 后退
def Back():
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.HIGH)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.HIGH)
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
# 右转
def Right():
GPIO.output(INT1, GPIO.HIGH)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
def Left():
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(INT3, GPIO.HIGH)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
def stop():
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(ENA, GPIO.LOW)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENB, GPIO.LOW)
ENA = 38 #定义对应的引脚变量(等一下用)
INT1 = 37
INT2 = 35
INT3 = 33
INT4 = 31
ENB = 29
GPIO.setmode(GPIO.BOARD) # 使用BCM编号方式
GPIO.setup(ENA, GPIO.OUT) # 将连接ENA的GPIO引脚设置为输出模式
GPIO.setup(INT1, GPIO.OUT) # 将连接IN1的GPIO引脚设置为输出模式
GPIO.setup(INT2, GPIO.OUT) # 将连接IN2的GPIO引脚设置为输出模式
GPIO.setup(INT3, GPIO.OUT) # 将连接IN3的GPIO引脚设置为输出模式
GPIO.setup(INT4, GPIO.OUT) # 将连接IN4的GPIO引脚设置为输出模式
GPIO.setup(ENB, GPIO.OUT) # 将连接INB的GPIO引脚设置为输出模式
print('ready')
while True:
setting = termios.tcgetattr(sys.stdin)
InPut = getKey(setting)
if InPut == 'w': #如果键盘输入w,则电机正转
Forward()
print('前进')
elif InPut == 's': #如果键盘输入s,则电机反转
Back()
print('后退')
elif InPut == 'd':
Left()
print('左转')
elif InPut == 'a':
Right()
print('右转')
elif InPut == 'q': #如果键盘输入的数值为q,退出
stop()
print('退出程序')
break
else :
stop()
print("Input Error,Please give a true index!!")
GPIO.cleanup()
二、jetson nano小车 1.1版本 加装摄像头
加装一个usb摄像头,基于flask框架写了一个前端web,将摄像头数据传到前端,可以在同一局域网下的手机设备、电脑设备、平板设备看到小车的视角
后端代码:
from flask import Flask, Response, render_template
import cv2
from threading import Thread
import RPi.GPIO as GPIO
import tty, sys, select, termios
# 定义对应的GPIO引脚
ENA = 38
INT1 = 37
INT2 = 35
INT3 = 33
INT4 = 31
ENB = 29
GPIO.setmode(GPIO.BOARD)
GPIO.setup(ENA, GPIO.OUT)
GPIO.setup(INT1, GPIO.OUT)
GPIO.setup(INT2, GPIO.OUT)
GPIO.setup(INT3, GPIO.OUT)
GPIO.setup(INT4, GPIO.OUT)
GPIO.setup(ENB, GPIO.OUT)
app = Flask(__name__)
camera = cv2.VideoCapture(0)
def generate_frames():
while True:
ret, frame = camera.read()
#将视频流转成图像用于传向前端
frame = cv2.imencode('.jpg', frame)[1].tobytes()
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
@app.route('/')
def index():
return render_template('index.html')
@app.route('/video_feed')
def video_feed():
return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
#小车控制
def getKey(settings):
tty.setraw(sys.stdin.fileno())
rlist = select.select([sys.stdin], [], [], 0.1)
if rlist:
key = sys.stdin.read(1)
else:
key = ""
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, settings)
return key
def carControl():
print('ready')
while True:
setting = termios.tcgetattr(sys.stdin)
InPut = getKey(setting)
if InPut == 'w': # 如果键盘输入w,则电机正转
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
GPIO.output(INT3, GPIO.HIGH)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(INT1, GPIO.HIGH)
GPIO.output(INT2, GPIO.LOW)
#print('前进')
elif InPut == 's': # 如果键盘输入s,则电机反转
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.HIGH)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.HIGH)
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
#print('后退')
elif InPut == 'd':
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(INT3, GPIO.HIGH)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
#print('左转')
elif InPut == 'a':
GPIO.output(INT1, GPIO.HIGH)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENA, GPIO.HIGH)
GPIO.output(ENB, GPIO.HIGH)
#print('右转')
elif InPut == 'q': # 如果键盘输入的数值为q,退出
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(ENA, GPIO.LOW)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENB, GPIO.LOW)
#print('退出程序')
break
else:
GPIO.output(INT1, GPIO.LOW)
GPIO.output(INT2, GPIO.LOW)
GPIO.output(ENA, GPIO.LOW)
GPIO.output(INT3, GPIO.LOW)
GPIO.output(INT4, GPIO.LOW)
GPIO.output(ENB, GPIO.LOW)
#print("Input Error,Please give a true index!!")
if __name__ == '__main__':
# 创建线程
car = Thread(target=carControl, args=())
car.daemon = True
car.start()
app.run(host='0.0.0.0', port="5000", threaded=True)
while True:
pass
前端代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>smart car</title>
</head>
<body>
<img id="stream" src="{{ url_for('video_feed') }}">
</body>
</html>
效果:
视频后续上传(转弯速度太快,摄像头太晃,后期控制一下转弯速度,并对外观升级一下):