99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

手把手教你如何自制輪式機(jī)器人

GReq_mcu168 ? 來(lái)源:博客 ? 作者:繆宇飏,myyerrol ? 2021-06-07 15:36 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

擊上方“果果小師弟”,選擇“置頂/星標(biāo)公眾號(hào)”

摘要:制作這個(gè)項(xiàng)目的起因是大一下學(xué)期那會(huì)兒我通過(guò)學(xué)校圖書館里的《無(wú)線電》雜志開始接觸Raspberry Pi卡片式計(jì)算機(jī)和Arduino微控制器,其中Raspberry Pi給當(dāng)初什么都不懂的我留下了非常深刻的印象:一個(gè)信用卡大小的板子竟然可以跑帶有圖形界面的GNU/Linux操作系統(tǒng)。

在強(qiáng)烈探索欲的驅(qū)使下,我從網(wǎng)上購(gòu)買了兩塊Element14的Raspberry Pi一代Model B(現(xiàn)在早已經(jīng)絕版了)板子以及其他相關(guān)配件,開始在Raspbian系統(tǒng)上自學(xué)Python和各種傳感器的使用方法,后來(lái)為了檢驗(yàn)一下自己的學(xué)習(xí)成果,于是我便花費(fèi)幾周的時(shí)間做了這個(gè)簡(jiǎn)單的輪式機(jī)器人。雖然它涉及的原理并不復(fù)雜,但是對(duì)于那會(huì)兒剛開始接觸嵌入式的我來(lái)說(shuō),能成功搭建一個(gè)完整的機(jī)器人系統(tǒng)還是挺有挑戰(zhàn)性的。

概述簡(jiǎn)單輪式機(jī)器人其實(shí)是一個(gè)比較傳統(tǒng)的入門級(jí)智能小車,它擁有藍(lán)牙遠(yuǎn)程遙控、超聲波避障、紅外邊緣檢測(cè)和紅外巡線(未完成)等功能,可以完成一些有趣的小實(shí)驗(yàn)。此外,簡(jiǎn)單輪式機(jī)器人的軟件是開源的,具體代碼可以從我的GitHub倉(cāng)庫(kù)上獲得。

原理硬件以下是該簡(jiǎn)單輪式機(jī)器人的硬件系統(tǒng)連接圖:

085fd136-c655-11eb-9e57-12bb97331649.png

核心主控

系統(tǒng)的硬件核心主控分別為Arduino和Raspberry Pi。其中Arduino主要負(fù)責(zé)接收紅外光電測(cè)距模塊的數(shù)據(jù),并控制裝有超聲波模塊的單軸舵機(jī)云臺(tái)的旋轉(zhuǎn);而Raspberry Pi則可通過(guò)電機(jī)驅(qū)動(dòng)模塊來(lái)完成對(duì)四個(gè)直流減速電機(jī)轉(zhuǎn)向和轉(zhuǎn)速的控制,此外它還能接收超聲波模塊和從Arduino串口發(fā)送上來(lái)的紅外光電測(cè)距模塊的數(shù)據(jù)來(lái)判斷當(dāng)前機(jī)器人的前方和兩側(cè)是否遇到障礙物,若機(jī)器人與障礙物之間的距離小于一個(gè)特定的閾值,則Arduino和Raspberry Pi會(huì)分別改變LED的顏色并啟動(dòng)蜂鳴器來(lái)發(fā)出警報(bào)。

當(dāng)然,肯定會(huì)有人問(wèn):為什么我不能僅用Raspberry Pi來(lái)作為機(jī)器人的核心主控,非要再用一個(gè)Arduino呢?其實(shí)根據(jù)本項(xiàng)目的實(shí)際需求,確實(shí)只用一個(gè)Raspberry Pi就夠了,不過(guò)對(duì)于我來(lái)說(shuō)使用Arduino主要出于以下三個(gè)原因的考慮:

Raspberry Pi一代Model B板子的GPIO引腳數(shù)量只有26個(gè),就算復(fù)用一些帶有特殊功能的引腳,引腳資源依舊比較緊張。

Raspberry Pi官方提供的GPIO庫(kù)雖然含有PWM函數(shù),但是實(shí)際在控制舵機(jī)的時(shí)候可能是由于軟件模擬的PWM方波還不夠穩(wěn)定,導(dǎo)致舵機(jī)抖動(dòng)得比較厲害。

可以學(xué)習(xí)Python的串口編程。

因此,綜合以上三個(gè)方面我選擇了Arduino和Raspberry Pi雙核心主控的系統(tǒng)架構(gòu)。

外部電源

因?yàn)闀r(shí)間比較緊張,所以我沒有在電源管理上花費(fèi)太多的功夫。對(duì)于Arduino,我使用的是能裝下6個(gè)1.5V干電池的的電池盒給其供電,而對(duì)于Raspberry Pi耗電量較大的需求,我是從大學(xué)舍友那借了一個(gè)充電寶來(lái)解決問(wèn)題的,不過(guò)雖然供電可以了,但是由于充電寶的重量比較大,導(dǎo)致四個(gè)輪子受壓偏大,使得遙控的精準(zhǔn)度受到了一定的影響。

電機(jī)驅(qū)動(dòng)

機(jī)器人的電機(jī)驅(qū)動(dòng)部分采用傳統(tǒng)的L293D芯片,它是一款單片集成的高電壓、高電流、四通道電機(jī)驅(qū)動(dòng)芯片,其內(nèi)部包含有兩個(gè)雙極型H橋電路,可通過(guò)設(shè)置IN1和IN2輸入引腳的邏輯電平來(lái)控制電機(jī)的旋轉(zhuǎn)方向,而EN使能引腳可連接到一路PWM上,通過(guò)調(diào)整PWM方波的占空比便可調(diào)整電機(jī)的轉(zhuǎn)速。

數(shù)據(jù)感知

為了能實(shí)現(xiàn)最基本的避障功能,我們需要為機(jī)器人配備有一些傳感器。這里我使用的傳感器為HC-SR04超聲波測(cè)距模塊和紅外光電避障模塊,其中紅外光電避障模塊具有一對(duì)紅外線發(fā)射與接收管,運(yùn)行時(shí)發(fā)射管會(huì)發(fā)射出一定頻率的紅外線,當(dāng)檢測(cè)方向遇到障礙物后,紅外線會(huì)反射回來(lái)被接收管接收,經(jīng)過(guò)比較電路處理之后,信號(hào)輸出接口會(huì)輸出一個(gè)低電平信號(hào),這樣只要在程序中對(duì)該接口的電平進(jìn)行判斷便能得知機(jī)器人是否距離障礙物比較近。

與紅外光電避障模塊的工作原理類似,超聲波模塊能夠向空中發(fā)射超聲波信號(hào),當(dāng)其檢測(cè)到反射回來(lái)的信號(hào)后,只需將超聲波從發(fā)射到接收所用的時(shí)間乘上聲速再除以二便能得到機(jī)器人和障礙物之間的距離,從而為之后的機(jī)器人避障做好準(zhǔn)備。

軟件Raspberry Pi庫(kù)代碼

simple_wheeled_robot_lib.py

該庫(kù)代碼實(shí)現(xiàn)了GPIO引腳初始化函數(shù)、LED燈設(shè)置函數(shù)、蜂鳴器設(shè)置函數(shù)、電機(jī)控制函數(shù)、超聲波測(cè)距函數(shù)和LCD1602顯示函數(shù),其中LCD1602顯示函數(shù)調(diào)用了Python的SMBUS庫(kù)來(lái)完成IIC數(shù)據(jù)通信,從而能將字符串顯示在屏幕上(注意:SMBUS和IIC協(xié)議之間是存在區(qū)別的,但在Raspberry Pi上兩者概念基本等同)。

import time

import smbus

import RPi.GPIO as gpio

motor_run_left = 17

motor_run_right = 10

motor_direction_left = 4

motor_direction_right = 25

led_left = 7

led_right = 8

ultrasonic_trig = 23

ultrasonic_echo = 24

servo = 11

buzzer = 18

lcd_address = 0x27

data_bus = smbus.SMBus(1)

class SimpleWheeledRobot:

def __init__(self):

gpio.setmode(gpio.BCM)

gpio.setup(motor_run_left, gpio.OUT)

gpio.setup(motor_run_right, gpio.OUT)

gpio.setup(motor_direction_left, gpio.OUT)

gpio.setup(motor_direction_right, gpio.OUT)

gpio.setup(led_left, gpio.OUT)

gpio.setup(led_right, gpio.OUT)

def set_motors(self, run_left, direction_left, run_right, direction_right):

gpio.output(motor_run_left, run_left)

gpio.output(motor_run_right, run_right)

gpio.output(motor_direction_left, direction_left)

gpio.output(motor_direction_right, direction_right)

def set_led_left(self, state):

gpio.output(led_left, state)

def set_led_right(self, state):

gpio.output(led_right, state)

def go_forward(self, seconds):

if seconds == 0:

self.set_motors(1, 1, 1, 1)

self.set_led_left(1)

self.set_led_right(1)

else:

self.set_motors(1, 1, 1, 1)

time.sleep(seconds)

gpio.cleanup()

def go_reverse(self, seconds):

if seconds == 0:

self.set_motors(1, 0, 1, 0)

self.set_led_left(0)

self.set_led_right(0)

else:

self.set_motors(1, 0, 1, 0)

time.sleep(seconds)

gpio.cleanup()

def go_left(self, seconds):

if seconds == 0:

self.set_motors(0, 0, 1, 1)

self.set_led_left(1)

self.set_led_right(0)

else:

self.set_motors(0, 0, 1, 1)

time.sleep(seconds)

gpio.cleanup()

def go_right(self, seconds):

if seconds == 0:

self.set_motors(1, 1, 0, 0)

self.set_led_left(0)

self.set_led_right(1)

else:

self.set_motors(1, 1, 0, 0)

time.sleep(seconds)

gpio.cleanup()

def go_pivot_left(self, seconds):

if seconds == 0:

self.set_motors(1, 0, 1, 1)

self.set_led_left(1)

self.set_led_right(0)

else:

self.set_motors(1, 0, 1, 1)

time.sleep(seconds)

gpio.cleanup()

def go_pivot_right(self, seconds):

if seconds == 0:

self.set_motors(1, 1, 1, 0)

self.set_led_left(0)

self.set_led_right(1)

else:

self.set_motors(1, 1, 1, 0)

time.sleep(seconds)

gpio.cleanup()

def stop(self):

self.set_motors(0, 0, 0, 0)

self.set_led_left(0)

self.set_led_right(0)

def buzzing(self):

gpio.setup(buzzer, gpio.OUT)

gpio.output(buzzer, True)

for x in range(5):

gpio.output(buzzer, False)

time.sleep(0.1)

gpio.output(buzzer, True)

time.sleep(0.1)

def get_distance(self):

gpio.setmode(gpio.BCM)

gpio.setup(ultrasonic_trig, gpio.OUT)

gpio.setup(ultrasonic_echo, gpio.IN)

gpio.output(ultrasonic_trig, False)

while gpio.input(ultrasonic_echo) == 0:

start_time = time.time()

while gpio.input(ultrasonic_echo) == 1:

stop_time = time.time()

duration = stop_time - start_time

distance = (duration * 34300) / 2

gpio.cleanup()

return distance

def send_command(self, command):

buf = command & 0xF0

buf |= 0x04

data_bus.write_byte(lcd_address, buf)

time.sleep(0.002)

buf &= 0xFB

data_bus.write_byte(lcd_address, buf)

buf = (command & 0x0F) 《《 4

buf |= 0x04

data_bus.write_byte(lcd_address, buf)

time.sleep(0.002)

buf &= 0xFB

data_bus.write_byte(lcd_address, buf)

def send_data(self, data):

buf = data & 0xF0

buf |= 0x05

data_bus.write_byte(lcd_address, buf)

time.sleep(0.002)

buf &= 0xFB

data_bus.write_byte(lcd_address, buf)

buf = (data & 0x0F) 《《 4

buf |= 0x05

data_bus.write_byte(lcd_address, buf)

time.sleep(0.002)

buf &= 0xFB

data_bus.write_byte(lcd_address, buf)

def initialize_lcd(self):

try:

self.send_command(0x33)

time.sleep(0.005)

self.send_command(0x32)

time.sleep(0.005)

self.send_command(0x28)

time.sleep(0.005)

self.send_command(0x0C)

time.sleep(0.005)

self.send_command(0x01)

except:

return False

else:

return True

def clear_lcd(self):

self.send_command(0x01)

def print_lcd(self, x, y, lcd_string):

if x 《 0:

x = 0

if x 》 15:

x = 15

if y 《 0:

y = 0

if y 》 1:

y = 1

address = 0x80 + 0x40 * y + x

self.send_command(address)

for lcd_char in lcd_string:

self.send_data(ord(lcd_char))

def move_servo_left(self):

servo_range = 13

gpio.setmode(gpio.BCM)

gpio.setup(servo, gpio.OUT)

pwm = gpio.PWM(servo, 100)

pwm.start(0)

while servo_range 《= 23:

pwm.ChangeDutyCycle(servo_range)

servo_range += 1

time.sleep(0.5)

pwm.stop()

def move_servo_right(self):

servo_range = 13

gpio.setmode(gpio.BCM)

gpio.setup(servo, gpio.OUT)

pwm = gpio.PWM(servo, 100)

pwm.start(0)

while servo_range 》= 0:

pwm.ChangeDutyCycle(servo_range)

servo_range -= 1

time.sleep(0.5)

pwm.stop()

Raspberry Pi測(cè)試代碼1

simple_wheeled_robot_run_1.py

該代碼調(diào)用了上面自己編寫的機(jī)器人代碼庫(kù),主要實(shí)現(xiàn)了超聲波距離檢測(cè)函數(shù)和鍵盤遙控函數(shù),其中鍵盤遙控函數(shù)里面又根據(jù)所按按鍵的不同調(diào)用并組合上面代碼庫(kù)中的不同函數(shù)來(lái)完成某些特定的功能(比如機(jī)器人遇到障礙物后首先會(huì)發(fā)出警報(bào),然后再進(jìn)行相應(yīng)的規(guī)避運(yùn)動(dòng)等)。

import time

import serial

import random

import Tkinter as tk

import RPi.gpio as gpio

from simple_wheeled_robot_lib import SimpleWheeledRobot

simple_wheeled_robot = SimpleWheeledRobot()

simple_wheeled_robot.initialize_lcd()

port = “/dev/ttyUSB0”

serial_to_arduino = serial.Serial(port, 9600)

serial_from_arduino = serial.Serial(port, 9600)

serial_from_arduino.flushInput()

serial_to_arduino.write(‘n’)

def detecte_distance():

distance = simple_wheeled_robot.get_distance()

if distance 》= 20:

# Light up the green led.

serial_to_arduino.write(‘g’)

elif distance 》= 10:

# Light up the yellow led.

serial_to_arduino.write(‘y’)

elif distance 《 10:

# Light up the red led.

serial_to_arduino.write(‘r’)

simple_wheeled_robot.buzzing()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_reverse(2)

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_pivot_right(2)

# Check the distance between wall and car‘s both sides.

serial_to_arduino.write(’k‘)

data_from_arduino = serial_from_arduino.readline()

data_from_arduino_int = int(data_from_arduino)

# Car is too close to the left wall.

if data_from_arduino_int == 01:

simple_wheeled_robot.buzzing()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_right(2)

# Car is too close to the right wall.

elif data_from_arduino_int == 10:

simple_wheeled_robot.buzzing()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_left(2)

def input_key(event):

simple_wheeled_robot.__init__()

print ’Key‘, event.char

key_press = event.char

seconds = 0.05

if key_press.lower() == ’w‘:

simple_wheeled_robot.go_forward(seconds)

elif key_press.lower() == ’s‘:

simple_wheeled_robot.go_reverse(seconds)

elif key_press.lower() == ’a‘:

simple_wheeled_robot.go_left(seconds)

elif key_press.lower() == ’d‘:

simple_wheeled_robot.go_right(seconds)

elif key_press.lower() == ’q‘:

simple_wheeled_robot.go_pivot_left(seconds)

elif key_press.lower() == ’e‘:

simple_wheeled_robot.go_pivot_right(seconds)

elif key_press.lower() == ’o‘:

gpio.cleanup()

# Move the servo in forward directory.

serial_to_arduino.write(’o‘)

time.sleep(0.05)

elif key_press.lower() == ’h‘:

gpio.cleanup()

# Light up the logo.

serial_to_arduino.write(’h‘)

elif key_press.lower() == ’j‘:

gpio.cleanup()

# Turn off the logo.

serial_to_arduino.write(’j‘)

elif key_press.lower() == ’p‘:

gpio.cleanup()

# Move the servo in reverse directory.

serial_to_arduino.write(’p‘)

time.sleep(0.05)

elif key_press.lower() == ’i‘:

gpio.cleanup()

serial_to_arduino.write(’m‘)

# Enter the random run mode.

serial_to_arduino.write(’i‘)

for z in range(20):

x = random.randrange(0, 5)

if x == 0:

for y in range(30):

detecte_distance()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_forward(0.05)

elif x == 1:

for y in range(30):

detecte_distance()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_left(0.05)

elif x == 2:

for y in range(30):

detecte_distance()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_right(0.05)

elif x == 3:

for y in range(30):

detecte_distance()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_pivot_left(0.05)

elif x == 4:

for y in range(30):

detecte_distance()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_pivot_right(0.05)

data_from_arduino = serial_from_arduino.readline()

data_from_arduino_int = int(data_from_arduino)

if data_from_arduino_int == 1111:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_forward(0.05)

if data_from_arduino_int == 1111:

simple_wheeled_robot.__init__()

simple_wheeled_robot.stop()

elif data_from_arduino_int == 0000:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_forward(0.05)

elif data_from_arduino_int == 0100:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_left(0.05)

elif data_from_arduino_int == 1000 or

data_from_arduino_int == 1100:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_left(0.08)

elif data_from_arduino_int == 0010:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_right(0.05)

elif data_from_arduino_int == 0001 or

data_from_arduino_int == 0011:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_right(0.08)

serial_to_arduino.write(’l‘)

elif key_press.lower() == ’u‘:

gpio.cleanup()

simple_wheeled_robot.print_lcd(1, 0, ’UltrasonicWare‘)

simple_wheeled_robot.print_lcd(1, 1, ’Distance:%.lf CM‘ %

simple_wheeled_robot.get_distance())

else:

pass

distance = simple_wheeled_robot.get_distance()

if distance 》= 20:

serial_to_arduino.write(’g‘)

elif distance 》= 10:

serial_to_arduino.write(’y‘)

elif distance 《 10:

serial_to_arduino.write(’r‘)

simple_wheeled_robot.buzzing()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_reverse(2)

serial_to_arduino.write(’k‘)

data_from_arduino = serial_from_arduino.readline()

data_from_arduino_int = int(data_from_arduino)

if data_from_arduino_int == 1:

simple_wheeled_robot.buzzing()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_right(2)

elif data_from_arduino_int == 10:

simple_wheeled_robot.buzzing()

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_left(2)

try:

command = tk.Tk()

command.bind(’《KeyPress》‘, input_key)

command.mainloop()

except KeyboardInterrupt:

gpio.cleanup()

Raspberry Pi測(cè)試代碼2

simple_wheeled_robot_run_2.py

該代碼實(shí)現(xiàn)的功能比較簡(jiǎn)單,僅測(cè)試了機(jī)器人的電機(jī)遙控和超聲波避障兩個(gè)功能。

import Tkinter as tk

import RPi.GPIO as gpio

from simple_wheeled_robot_lib import SimpleWheeledRobot

simple_wheeled_robot = SimpleWheeledRobot()

simple_wheeled_robot.initialize_lcd()

def input_key(event):

print ’Key‘, event.char

key_press = event.char

seconds = 0.05

if key_press.lower() == ’w‘:

simple_wheeled_robot.go_forward(seconds)

elif key_press.lower() == ’s‘:

simple_wheeled_robot.go_reverse(seconds)

elif key_press.lower() == ’a‘:

simple_wheeled_robot.go_left(seconds)

elif key_press.lower() == ’d‘:

simple_wheeled_robot.go_right(seconds)

elif key_press.lower() == ’q‘:

simple_wheeled_robot.go_pivot_left(seconds)

elif key_press.lower() == ’e‘:

simple_wheeled_robot.go_pivot_right(seconds)

elif key_press.lower() == ’o‘:

simple_wheeled_robot.move_servo_left()

elif key_press.lower() == ’p‘:

simple_wheeled_robot.move_servo_right()

else:

pass

distance = simple_wheeled_robot.get_distance()

simple_wheeled_robot.print_lcd(1, 0, ’UltrasonicWare‘)

simple_wheeled_robot.print_lcd(1, 1, ’Distance:%.lf CM‘ % distance)

print “Distance: %.1f CM” % distance

if distance 《 10:

simple_wheeled_robot.__init__()

simple_wheeled_robot.go_reverse(2)

try:

command = tk.Tk()

command.bind(’《KeyPress》‘, input_key)

command.mainloop()

except KeyboardInterrupt:

gpio.cleanup()

Raspberry Pi測(cè)試代碼3

simple_wheeled_robot_run_3.py

該代碼實(shí)現(xiàn)的功能與上面的測(cè)試代碼2類似,只不過(guò)圖形界面本代碼里使用的是Pygame而不是之前的Tkinter。

import sys

import pygame

from pygame.locals import *

import RPi.GPIO as gpio

from simple_wheeled_robot_lib import SimpleWheeledRobot

simple_wheeled_robot = SimpleWheeledRobot()

pygame.init()

screen = pygame.display.set_mode((800, 800))

font = pygame.font.SysFont(“arial”, 64)

pygame.display.set_caption(’SimpleWheeledRobot‘)

pygame.mouse.set_visible(0)

while True:

gpio.cleanup()

for event in pygame.event.get():

if event.type == QUIT:

sys.exit()

if event.type == KEYDOWN:

time = 0.03

if event.key == K_UP or event.key == ord(’w‘):

simple_wheeled_robot.go_forward(time)

elif event.key == K_DOWN or event.key == ord(’s‘):

simple_wheeled_robot.go_reverse(time)

elif event.key == K_LEFT or event.key == ord(’a‘):

simple_wheeled_robot.go_left(time)

elif event.key == K_RIGHT or event.key == ord(’d‘):

simple_wheeled_robot.go_right(time)

elif event.key == ord(’q‘):

simple_wheeled_robot.go_pivot_left(time)

elif event.key == ord(’e‘):

simple_wheeled_robot.go_pivot_right(time)

Arduino測(cè)試代碼

simple_wheeled_robot.ino

該代碼從邏輯上比較好理解,在setup()函數(shù)初始化引腳的模式和串口波特率后,主函數(shù)loop()會(huì)不斷地從串口中讀取字符數(shù)據(jù),并根據(jù)字符的不同進(jìn)行不同的處理工作。

int distance;

int distance_left;

int distance_right;

int motor_value;

int motor_value_a;

int motor_value_b;

int motor_value_c;

int motor_value_d;

int motor_a = 6;

int motor_b = 7;

int motor_c = 8;

int motor_d = 9;

int servo = 5;

int led = 2;

int led_red = 13;

int led_yellow = 12;

int led_green = 11;

int distance_sensor_left = 3;

int distance_sensor_right = 4;

char data;

uint16_t angle = 1500;

void setup()

{

// Set serial’s baud rate.

Serial.begin(9600);

pinMode(motor_a, INPUT);

pinMode(motor_b, INPUT);

pinMode(motor_c, INPUT);

pinMode(motor_d, INPUT);

pinMode(servo, OUTPUT);

pinMode(led , OUTPUT);

pinMode(led_red, OUTPUT);

pinMode(led_yellow, OUTPUT);

pinMode(led_green, OUTPUT);

pinMode(distance_sensor_left, INPUT);

pinMode(distance_sensor_right, INPUT);

pinMode(A0, OUTPUT);

pinMode(A1, OUTPUT);

pinMode(A2, OUTPUT);

pinMode(A3, OUTPUT);

pinMode(A4, OUTPUT);

pinMode(A5, OUTPUT);

}

void loop()

{

if (Serial.available()) {

switch(Serial.read()) {

// Light up the logo.

case ‘h’: {

digitalWrite(A0, HIGH);

digitalWrite(A1, HIGH);

digitalWrite(A2, HIGH);

digitalWrite(A3, HIGH);

digitalWrite(A4, HIGH);

digitalWrite(A5, HIGH);

break;

}

// Turn off the logo.

case ‘j’: {

digitalWrite(A0, LOW);

digitalWrite(A1, LOW);

digitalWrite(A2, LOW);

digitalWrite(A3, LOW);

digitalWrite(A4, LOW);

digitalWrite(A5, LOW);

break;

}

// Move the servo in forward directory.

case ‘o’ : {

angle += 50;

if (angle 》 2500) {

angle = 2500;

}

break;

}

// Move the servo in reverse directory.

case ‘p’ : {

angle -= 50;

if (angle 《 500) {

angle = 500;

}

break;

}

case ‘n’: {

digitalWrite(led, HIGH);

break;

}

case ‘m’: {

digitalWrite(led, LOW);

break;

}

case ‘g’: {

// When the distance between objects and car is far enough,

// light the green led.

digitalWrite(led_green, HIGH);

digitalWrite(led_yellow, LOW);

digitalWrite(led_red, LOW);

break;

}

case ‘y’: {

// When the distance between objects and car is near enough,

// light the yellow led.

digitalWrite(led_yellow, HIGH);

digitalWrite(led_green, LOW);

digitalWrite(led_red, LOW);

break;

}

case ‘r’: {

// When the distance between objects and car is very near,

// light the red led.

digitalWrite(led_red, HIGH);

digitalWrite(led_yellow, LOW);

digitalWrite(led_green, LOW);

break;

}

case ‘k’: {

// Return distance sensor‘s state between objects and car.

distance_left = digitalRead(distance_sensor_left);

distance_right = digitalRead(distance_sensor_right);

distance = distance_left * 10 + distance_right ;

Serial.println(distance, DEC);

break;

}

case ’i‘: {

while (1) {

// Return motor’s state to raspberry pi.

motor_value_a = digitalRead(motor_a);

motor_value_b = digitalRead(motor_b);

motor_value_c = digitalRead(motor_c);

motor_value_d = digitalRead(motor_d);

motor_value = motor_value_a * 1000 + motor_value_b * 100 +

motor_value_c * 10 + motor_value_d;

Serial.println(motor_value, DEC);

delay(1000);

data = Serial.read();

if (data == ‘l’) {

break;

}

}

}

default:

break;

}

}

// Delay enough time for servo to move position.

digitalWrite(servo, HIGH);

delayMicroseconds(angle);

digitalWrite(servo, LOW);

delay(15);

}

總結(jié)這個(gè)簡(jiǎn)單輪式機(jī)器人是大一那會(huì)兒我對(duì)自己課外所學(xué)知識(shí)的一個(gè)應(yīng)用。雖然現(xiàn)在回過(guò)頭再來(lái)看自己當(dāng)初做的項(xiàng)目,感覺技術(shù)原理非常簡(jiǎn)單,遠(yuǎn)沒有我之后研究的ROS和MoveIt!那么復(fù)雜,但是通過(guò)整個(gè)制作過(guò)程,我學(xué)會(huì)了如何根據(jù)項(xiàng)目需求去網(wǎng)上購(gòu)買相關(guān)的材料。

如何將主控等硬件設(shè)備安裝在機(jī)器人機(jī)械結(jié)構(gòu)最合理的位置上,如何使用IDE編寫Arduino程序,如何在Raspberry Pi上使用Python語(yǔ)言來(lái)讀取硬件數(shù)據(jù)并控制硬件,如何實(shí)現(xiàn)簡(jiǎn)單的串口通信等等。我一直認(rèn)為興趣是最好的老師。

當(dāng)你開始接觸一個(gè)全新的領(lǐng)域時(shí),興趣可以成為你克服各種困難并鼓舞你前進(jìn)的強(qiáng)大動(dòng)力。當(dāng)然,除了興趣,更重要的是親自動(dòng)手實(shí)踐,書上的東西講得再好也是別人的,不是你的,就算重復(fù)造輪子也有著其無(wú)法替代的重要意義,因?yàn)椴⒉皇敲總€(gè)人都能造得出輪子,通過(guò)學(xué)習(xí)并實(shí)踐前人所學(xué)習(xí)過(guò)的知識(shí),你會(huì)收獲別人不會(huì)有的寶貴經(jīng)驗(yàn)!

最后,個(gè)人認(rèn)為智能小車對(duì)于廣大剛開始接觸機(jī)器人的初學(xué)者來(lái)說(shuō)確實(shí)是一個(gè)非常好的練手項(xiàng)目,你可以根據(jù)自己的喜好和技術(shù)水平的高低來(lái)定制屬于你自己的智能小車,實(shí)現(xiàn)你想要的各種功能??傊?,對(duì)于我來(lái)說(shuō)。

通過(guò)本次項(xiàng)目我開始真正喜歡上了嵌入式開發(fā)并逐漸走上了專業(yè)化的道路,每個(gè)人都應(yīng)該有自己的夢(mèng)想,那這個(gè)簡(jiǎn)單輪式機(jī)器人就是我夢(mèng)想的起點(diǎn),激勵(lì)著我不斷向前!當(dāng)然,也希望大家能在制作機(jī)器人的道路上玩得開心并有所收獲!

文章作者:繆宇飏,myyerrol 轉(zhuǎn)載于:https://myyerrol.io/zh-cn/2018/05/15/diy_robots_1_simple_wheeled_robot/

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • PWM
    PWM
    +關(guān)注

    關(guān)注

    116

    文章

    5493

    瀏覽量

    219233
  • 電機(jī)
    +關(guān)注

    關(guān)注

    143

    文章

    9293

    瀏覽量

    149324
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4379

    瀏覽量

    64780
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4899

    瀏覽量

    70653
  • GPIO
    +關(guān)注

    關(guān)注

    16

    文章

    1280

    瀏覽量

    54023

原文標(biāo)題:干貨|手把手教你自制輪式機(jī)器人

文章出處:【微信號(hào):mcu168,微信公眾號(hào):硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    【精選直播】手把手教你做PC第十二課:WIFI 驅(qū)動(dòng)框架適配

    手把手教你做PC》系列直播課再度開播!《KaihongOS筆記本電腦開發(fā)實(shí)戰(zhàn)第十二課:WIFI驅(qū)動(dòng)框架適配》將于07月02日19:00開播↑掃碼入群,領(lǐng)課程講義資料包↑深開鴻資深工程師親臨直播間
    的頭像 發(fā)表于 07-01 08:08 ?80次閱讀
    【精選直播】<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>做PC第十二課:WIFI 驅(qū)動(dòng)框架適配

    輪式移動(dòng)機(jī)器人電機(jī)驅(qū)動(dòng)系統(tǒng)的研究與開發(fā)

    【摘 要】以嵌入式運(yùn)動(dòng)控制體系為基礎(chǔ),以移動(dòng)機(jī)器人為研究對(duì)象,結(jié)合三輪結(jié)構(gòu)輪式移動(dòng)機(jī)器人,對(duì)二輪差速驅(qū)動(dòng)轉(zhuǎn)向自主移動(dòng)機(jī)器人運(yùn)動(dòng)學(xué)和動(dòng)力學(xué)空間模型進(jìn)行了分析和計(jì)算,研究和設(shè)計(jì)了自主移動(dòng)
    發(fā)表于 06-11 14:30

    手把手教你如何調(diào)優(yōu)Linux網(wǎng)絡(luò)參數(shù)

    在高并發(fā)網(wǎng)絡(luò)服務(wù)場(chǎng)景中,Linux內(nèi)核的默認(rèn)網(wǎng)絡(luò)參數(shù)往往無(wú)法滿足需求,導(dǎo)致性能瓶頸、連接超時(shí)甚至服務(wù)崩潰。本文基于真實(shí)案例分析,從參數(shù)解讀、問(wèn)題診斷到優(yōu)化實(shí)踐,手把手教你如何調(diào)優(yōu)Linux網(wǎng)絡(luò)參數(shù),支撐百萬(wàn)級(jí)并發(fā)連接。
    的頭像 發(fā)表于 05-29 09:21 ?194次閱讀

    正點(diǎn)原子Linux系列全新視頻教程來(lái)啦!手把手教你MP257開發(fā)板,讓您輕松入門!

    正點(diǎn)原子Linux系列全新視頻教程來(lái)啦!手把手教你MP257開發(fā)板,讓您輕松入門! 一、視頻觀看 正點(diǎn)原子手把手教你學(xué)STM32MP257-第1期:https://www.bilib
    發(fā)表于 05-16 10:42

    GPU顯卡維修避坑指南:手把手教你識(shí)別行業(yè)套路!

    的今天,高端顯卡維修已成“暴利暗流”。虛高報(bào)價(jià)、偷換配件、技術(shù)陷阱……用戶稍有不慎,輕則損失數(shù)萬(wàn),重則設(shè)備報(bào)廢。今天小助手將揭露行業(yè)亂象,手把手教你識(shí)別套路,并推薦
    的頭像 發(fā)表于 04-02 20:31 ?907次閱讀
    GPU顯卡維修避坑指南:<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>識(shí)別行業(yè)套路!

    《零基礎(chǔ)開發(fā)AI Agent——手把手教你用扣子做智能體》

    《零基礎(chǔ)開發(fā)AI Agent——手把手教你用扣子做智能體》是一本為普通人量身打造的AI開發(fā)指南。它不僅深入淺出地講解了Agent的概念和發(fā)展,還通過(guò)詳細(xì)的工具介紹和實(shí)戰(zhàn)案例,幫助讀者快速掌握
    發(fā)表于 03-18 12:03

    手把手教你做星閃無(wú)人機(jī)—KaihongOS星閃無(wú)人機(jī)開發(fā)實(shí)戰(zhàn)》系列課程課件匯總

    為助力開發(fā)者迅速掌握『KaihongOS輕量系統(tǒng)開發(fā)技術(shù)』與『星閃無(wú)線通信技術(shù)』,實(shí)現(xiàn)快速上手與深度體驗(yàn),“開鴻Developer社區(qū)”攜手“電子發(fā)燒友”再次聯(lián)合推出《手把手教你做星閃無(wú)人機(jī)
    發(fā)表于 03-18 10:33

    手把手教你做PC-KaihongOS筆記本電腦開發(fā)實(shí)戰(zhàn)》課件匯總

    ”攜手“電子發(fā)燒友”聯(lián)合推出了 《KaihongOS手把手系列直播課程》,該系列課程以實(shí)際產(chǎn)品為案例,詳細(xì)講解每個(gè)產(chǎn)品的開發(fā)全流程。 此次首發(fā)內(nèi)容是《手把手教你做PC-KaihongOS筆記本電腦開發(fā)
    發(fā)表于 03-18 10:25

    【第三章 警報(bào)聯(lián)動(dòng)】手把手教你玩轉(zhuǎn)新版正點(diǎn)原子云

    本帖最后由 jf_85110202 于 2025-3-13 14:43 編輯 【第三章 警報(bào)聯(lián)動(dòng)】手把手教你玩轉(zhuǎn)新版正點(diǎn)原子云 新版原子云網(wǎng)址:原子云(點(diǎn)擊登錄原子云) 原子云特色功能:設(shè)置
    發(fā)表于 03-12 16:05

    開發(fā)者集結(jié)!《手把手教你做星閃無(wú)人機(jī)》第二課開講啦!

    開發(fā)者集結(jié)!《手把手教你做星閃無(wú)人機(jī)》第二課開講啦!
    的頭像 發(fā)表于 02-17 19:40 ?368次閱讀
    開發(fā)者集結(jié)!《<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>做星閃無(wú)人機(jī)》第二課開講啦!

    手把手教你做星閃無(wú)人機(jī)》即將開播,鎖定15日晚七點(diǎn)!

    ”再次聯(lián)合推出《手把手教你做星閃無(wú)人機(jī)—KaihongOS星閃無(wú)人機(jī)開發(fā)實(shí)戰(zhàn)》系列課程,該課程與《手把手教你做PC—KaihongOS筆記本電腦開發(fā)實(shí)戰(zhàn)》同步并行,
    的頭像 發(fā)表于 01-13 19:42 ?515次閱讀
    《<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>做星閃無(wú)人機(jī)》即將開播,鎖定15日晚七點(diǎn)!

    手把手教你做PC》課程即將啟動(dòng)!深開鴻引領(lǐng)探索KaihongOS筆記本電腦開發(fā)實(shí)戰(zhàn)

    ”攜手“電子發(fā)燒友”聯(lián)合推出了《KaihongOS手把手系列直播課程》,該系列課程以實(shí)際產(chǎn)品為案例,詳細(xì)講解每個(gè)產(chǎn)品的開發(fā)全流程。此次首發(fā)內(nèi)容是《手把手教你做PC-
    的頭像 發(fā)表于 01-06 20:46 ?571次閱讀
    《<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>做PC》課程即將啟動(dòng)!深開鴻引領(lǐng)探索KaihongOS筆記本電腦開發(fā)實(shí)戰(zhàn)

    Air780E模組LuatOS開發(fā)實(shí)戰(zhàn) —— 手把手教你搞定數(shù)據(jù)打包解包

    本文要說(shuō)的是低功耗4G模組Air780E的LuatOS開發(fā)實(shí)戰(zhàn),我將手把手教你搞定數(shù)據(jù)打包解包。
    的頭像 發(fā)表于 12-03 11:17 ?621次閱讀
    Air780E模組LuatOS開發(fā)實(shí)戰(zhàn) —— <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>搞定數(shù)據(jù)打包解包

    七騰機(jī)器人:防爆輪式機(jī)器人-四輪八驅(qū)全新上線

    今日,七騰機(jī)器人有限公司(以下簡(jiǎn)稱“七騰機(jī)器人”)推出全新產(chǎn)品:防爆輪式機(jī)器人-四輪八驅(qū)。該款產(chǎn)品是七騰輪式巡檢
    的頭像 發(fā)表于 10-21 16:32 ?547次閱讀
    七騰<b class='flag-5'>機(jī)器人</b>:防爆<b class='flag-5'>輪式</b><b class='flag-5'>機(jī)器人</b>-四輪八驅(qū)全新上線

    手把手教你通過(guò)宏集物聯(lián)網(wǎng)工控屏&amp;網(wǎng)關(guān)進(jìn)行協(xié)議轉(zhuǎn)換,將底層PLC/傳感器的數(shù)據(jù)轉(zhuǎn)換為TCP協(xié)議并傳輸?shù)接脩?/a>

    手把手教你通過(guò)宏集物聯(lián)網(wǎng)工控屏&網(wǎng)關(guān)進(jìn)行協(xié)議轉(zhuǎn)換,將底層PLC/傳感器的數(shù)據(jù)轉(zhuǎn)換為TCP協(xié)議并傳輸?shù)接脩艚K端
    的頭像 發(fā)表于 08-15 13:29 ?1096次閱讀
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>通過(guò)宏集物聯(lián)網(wǎng)工控屏&amp;網(wǎng)關(guān)進(jìn)行協(xié)議轉(zhuǎn)換,將底層PLC/傳感器的數(shù)據(jù)轉(zhuǎn)換為TCP協(xié)議并傳輸?shù)接脩? />    </a>
</div>                    </div>
                    <div   id=