0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

手把手教你如何自制轮式机器人

GReq_mcu168 来源:博客 作者:缪宇飏,myyerrol 2021-06-07 15:36 次阅读

击上方“果果小师弟”,选择“置顶/星标公众号”

摘要:制作这个项目的起因是大一下学期那会儿我通过学校图书馆里的《无线电》杂志开始接触Raspberry Pi卡片式计算机和Arduino微控制器,其中Raspberry Pi给当初什么都不懂的我留下了非常深刻的印象:一个信用卡大小的板子竟然可以跑带有图形界面的GNU/Linux操作系统

在强烈探索欲的驱使下,我从网上购买了两块Element14的Raspberry Pi一代Model B(现在早已经绝版了)板子以及其他相关配件,开始在Raspbian系统上自学Python和各种传感器的使用方法,后来为了检验一下自己的学习成果,于是我便花费几周的时间做了这个简单的轮式机器人。虽然它涉及的原理并不复杂,但是对于那会儿刚开始接触嵌入式的我来说,能成功搭建一个完整的机器人系统还是挺有挑战性的。

概述简单轮式机器人其实是一个比较传统的入门级智能小车,它拥有蓝牙远程遥控、超声波避障、红外边缘检测和红外巡线(未完成)等功能,可以完成一些有趣的小实验。此外,简单轮式机器人的软件是开源的,具体代码可以从我的GitHub仓库上获得。

原理硬件以下是该简单轮式机器人的硬件系统连接图:

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

核心主控

系统的硬件核心主控分别为Arduino和Raspberry Pi。其中Arduino主要负责接收红外光电测距模块的数据,并控制装有超声波模块的单轴舵机云台的旋转;而Raspberry Pi则可通过电机驱动模块来完成对四个直流减速电机转向和转速的控制,此外它还能接收超声波模块和从Arduino串口发送上来的红外光电测距模块的数据来判断当前机器人的前方和两侧是否遇到障碍物,若机器人与障碍物之间的距离小于一个特定的阈值,则Arduino和Raspberry Pi会分别改变LED的颜色并启动蜂鸣器来发出警报。

当然,肯定会有人问:为什么我不能仅用Raspberry Pi来作为机器人的核心主控,非要再用一个Arduino呢?其实根据本项目的实际需求,确实只用一个Raspberry Pi就够了,不过对于我来说使用Arduino主要出于以下三个原因的考虑:

Raspberry Pi一代Model B板子的GPIO引脚数量只有26个,就算复用一些带有特殊功能的引脚,引脚资源依旧比较紧张。

Raspberry Pi官方提供的GPIO库虽然含有PWM函数,但是实际在控制舵机的时候可能是由于软件模拟的PWM方波还不够稳定,导致舵机抖动得比较厉害。

可以学习Python的串口编程

因此,综合以上三个方面我选择了Arduino和Raspberry Pi双核心主控的系统架构。

外部电源

因为时间比较紧张,所以我没有在电源管理上花费太多的功夫。对于Arduino,我使用的是能装下6个1.5V干电池的的电池盒给其供电,而对于Raspberry Pi耗电量较大的需求,我是从大学舍友那借了一个充电宝来解决问题的,不过虽然供电可以了,但是由于充电宝的重量比较大,导致四个轮子受压偏大,使得遥控的精准度受到了一定的影响。

电机驱动

机器人的电机驱动部分采用传统的L293D芯片,它是一款单片集成的高电压、高电流、四通道电机驱动芯片,其内部包含有两个双极型H桥电路,可通过设置IN1和IN2输入引脚的逻辑电平来控制电机的旋转方向,而EN使能引脚可连接到一路PWM上,通过调整PWM方波的占空比便可调整电机的转速。

数据感知

为了能实现最基本的避障功能,我们需要为机器人配备有一些传感器。这里我使用的传感器为HC-SR04超声波测距模块和红外光电避障模块,其中红外光电避障模块具有一对红外线发射与接收管,运行时发射管会发射出一定频率的红外线,当检测方向遇到障碍物后,红外线会反射回来被接收管接收,经过比较电路处理之后,信号输出接口会输出一个低电平信号,这样只要在程序中对该接口的电平进行判断便能得知机器人是否距离障碍物比较近。

与红外光电避障模块的工作原理类似,超声波模块能够向空中发射超声波信号,当其检测到反射回来的信号后,只需将超声波从发射到接收所用的时间乘上声速再除以二便能得到机器人和障碍物之间的距离,从而为之后的机器人避障做好准备。

软件Raspberry Pi库代码

simple_wheeled_robot_lib.py

该库代码实现了GPIO引脚初始化函数、LED灯设置函数、蜂鸣器设置函数、电机控制函数、超声波测距函数和LCD1602显示函数,其中LCD1602显示函数调用了Python的SMBUS库来完成IIC数据通信,从而能将字符串显示在屏幕上(注意:SMBUS和IIC协议之间是存在区别的,但在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测试代码1

simple_wheeled_robot_run_1.py

该代码调用了上面自己编写的机器人代码库,主要实现了超声波距离检测函数和键盘遥控函数,其中键盘遥控函数里面又根据所按按键的不同调用并组合上面代码库中的不同函数来完成某些特定的功能(比如机器人遇到障碍物后首先会发出警报,然后再进行相应的规避运动等)。

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测试代码2

simple_wheeled_robot_run_2.py

该代码实现的功能比较简单,仅测试了机器人的电机遥控和超声波避障两个功能。

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测试代码3

simple_wheeled_robot_run_3.py

该代码实现的功能与上面的测试代码2类似,只不过图形界面本代码里使用的是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测试代码

simple_wheeled_robot.ino

该代码从逻辑上比较好理解,在setup()函数初始化引脚的模式和串口波特率后,主函数loop()会不断地从串口中读取字符数据,并根据字符的不同进行不同的处理工作。

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);

}

总结这个简单轮式机器人是大一那会儿我对自己课外所学知识的一个应用。虽然现在回过头再来看自己当初做的项目,感觉技术原理非常简单,远没有我之后研究的ROS和MoveIt!那么复杂,但是通过整个制作过程,我学会了如何根据项目需求去网上购买相关的材料。

如何将主控等硬件设备安装在机器人机械结构最合理的位置上,如何使用IDE编写Arduino程序,如何在Raspberry Pi上使用Python语言来读取硬件数据并控制硬件,如何实现简单的串口通信等等。我一直认为兴趣是最好的老师。

当你开始接触一个全新的领域时,兴趣可以成为你克服各种困难并鼓舞你前进的强大动力。当然,除了兴趣,更重要的是亲自动手实践,书上的东西讲得再好也是别人的,不是你的,就算重复造轮子也有着其无法替代的重要意义,因为并不是每个人都能造得出轮子,通过学习并实践前人所学习过的知识,你会收获别人不会有的宝贵经验!

最后,个人认为智能小车对于广大刚开始接触机器人的初学者来说确实是一个非常好的练手项目,你可以根据自己的喜好和技术水平的高低来定制属于你自己的智能小车,实现你想要的各种功能。总之,对于我来说。

通过本次项目我开始真正喜欢上了嵌入式开发并逐渐走上了专业化的道路,每个人都应该有自己的梦想,那这个简单轮式机器人就是我梦想的起点,激励着我不断向前!当然,也希望大家能在制作机器人的道路上玩得开心并有所收获!

文章作者:缪宇飏,myyerrol 转载于:https://myyerrol.io/zh-cn/2018/05/15/diy_robots_1_simple_wheeled_robot/

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • PWM
    PWM
    +关注

    关注

    114

    文章

    5190

    浏览量

    214059
  • 电机
    +关注

    关注

    142

    文章

    9023

    浏览量

    145570
  • 函数
    +关注

    关注

    3

    文章

    4332

    浏览量

    62669
  • 代码
    +关注

    关注

    30

    文章

    4790

    浏览量

    68655
  • GPIO
    +关注

    关注

    16

    文章

    1204

    浏览量

    52133

原文标题:干货|手把手教你自制轮式机器人

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【「具身智能机器人系统」阅读体验】2.具身智能机器人大模型

    近年来,人工智能领域的大模型技术在多个方向上取得了突破性的进展,特别是在机器人控制领域展现出了巨大的潜力。在“具身智能机器人大模型”部分,作者研究并探讨了大模型如何提升机器人的能力,大模型存在
    发表于 12-29 23:04

    源码开放 智能监测电源管理教程宝典!

    源码开放,今天我们学习的是电源管理系统的核心功能模块,手把手教你如何通过不同的技术手段实现有效的电源管理。
    的头像 发表于 12-11 09:26 264次阅读
    源码开放  智能监测电源管理教程宝典!

    Air780E模组LuatOS开发实战 —— 手把手教你搞定数据打包解包

    本文要说的是低功耗4G模组Air780E的LuatOS开发实战,我将手把手教你搞定数据打包解包。
    的头像 发表于 12-03 11:17 177次阅读
    Air780E模组LuatOS开发实战 —— <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>搞定数据打包解包

    鸿蒙机器人与鸿蒙开发板联动演示

    鸿蒙机器人与鸿蒙开发板联动演示,机器人的角色为迎宾机器人,开发板负责人宾客出现监听
    发表于 12-02 14:55

    手把手教你如何自制目标检测框架

    今天,给大家分享一篇来自知乎的一篇关于目标检测相关的一些内容, 本文基于Pytorch进行编写。
    的头像 发表于 11-14 16:39 216次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>如何<b class='flag-5'>自制</b>目标检测框架

    七腾机器人:防爆轮式机器人-四轮八驱全新上线

    今日,七腾机器人有限公司(以下简称“七腾机器人”)推出全新产品:防爆轮式机器人-四轮八驱。该款产品是七腾轮式巡检
    的头像 发表于 10-21 16:32 195次阅读
    七腾<b class='flag-5'>机器人</b>:防爆<b class='flag-5'>轮式</b><b class='flag-5'>机器人</b>-四轮八驱全新上线

    手把手教你通过宏集物联网工控屏&amp;网关进行协议转换,将底层PLC/传感器的数据转换为TCP协议并传输到用户

    手把手教你通过宏集物联网工控屏&网关进行协议转换,将底层PLC/传感器的数据转换为TCP协议并传输到用户终端
    的头像 发表于 08-15 13:29 527次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>通过宏集物联网工控屏&amp;网关进行协议转换,将底层PLC/传感器的数据转换为TCP协议并传输到用户

    Al大模型机器人

    金航标kinghelm萨科微slkor总经理宋仕强介绍说,萨科微Al大模型机器人有哪些的优势?萨科微AI大模型机器人由清华大学毕业的天才少年N博士和王博士团队开发,与同行相比具有许多优势:语言
    发表于 07-05 08:52

    手把手教你在orcad中设置CIS元器件数据库,提高工作效率

    元器件数据库,就是实现上述查找元件、放置元件时所需要调用的数据库。本文将手把手教你如何在orcad中配置CIS元器件数据库。
    的头像 发表于 06-15 17:27 6278次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>在orcad中设置CIS元器件数据库,提高工作效率

    手把手教你排序算法怎么写

    今天以直接插入排序算法,给大家分享一下排序算法的实现思路,主要包含以下部分内容:插入排序介绍插入排序算法实现手把手教你排序算法怎么写在添加新的记录时,使用顺序查找的方式找到其要插入的位置,然后将
    的头像 发表于 06-04 08:03 704次阅读
    <b class='flag-5'>手把手</b><b class='flag-5'>教你</b>排序算法怎么写

    手把手带你移植HAL库函数

    开发者更高效地进行嵌入式开发。手把手带你移植HAL库函数HAL库提供了一套抽象接口,使开发者无需直接操作底层硬件寄存器,就能实现对硬件的控制。这种抽象使得代码能够更
    的头像 发表于 05-18 08:04 1934次阅读
    <b class='flag-5'>手把手</b>带你移植HAL库函数

    防爆轮式巡检机器人作用和优势?

    在当今的工业领域,安全生产始终是至关重要的议题。而在一些具有爆炸风险的环境中,如石油、化工、燃气等行业,传统的人工巡检方式面临着诸多挑战。然而,随着科技的飞速发展,防爆轮式巡检机器人应运而生,为这些
    的头像 发表于 04-23 17:17 644次阅读
    防爆<b class='flag-5'>轮式</b>巡检<b class='flag-5'>机器人</b>作用和优势?

    农业轮式机器人三维环境感知技术研究进展

    子科技集团公司第五十四研究所等多家科研机构,开展了针对农业轮式机器人三维环境感知技术的研究。 作为未来农机装备的研究重点,农业轮式机器人正向着智能化与多功能化的方向发展。三维环境感知技
    的头像 发表于 02-22 17:05 402次阅读

    工程送样!手把手教你用好广和通RedCap模组FG131&amp;amp;FG132系列

    工程送样!手把手教你用好广和通RedCap模组FG131&FG132系列
    的头像 发表于 01-11 18:22 707次阅读
    工程送样!<b class='flag-5'>手把手</b><b class='flag-5'>教你</b>用好广和通RedCap模组FG131&amp;amp;FG132系列

    ​大象机器人首发万元级水星Mercury人形机器人系列

    水星Mercury机器人系列共有三款产品:水星Mercury A1 七轴协作机械臂和水星Mercury B1半人形双臂机器人以及 水星Mercury X1通用轮式人形机器人
    发表于 01-03 09:59 291次阅读
    ​大象<b class='flag-5'>机器人</b>首发万元级水星Mercury人形<b class='flag-5'>机器人</b>系列