LEGO扩展教程#
1. 足球机器人#
1.1. 实验简介:#
足球运动是一种大家非常喜爱的运动。让 机器人去踢足球,听起来像天方夜谭似的。机器人也能去踢足球? 是的,足球机器人可以做到像我们人一样去组成团队进行踢足球比赛,比如:一年一度的RoboCup机器人世界杯—RoboCup足球赛等。在本实验中,我们利用乐高积木搭建了一款足球机器人,并且使用足球机器人把小足球送进足球门里。
1.2. 足球机器人形态安装步骤#
先将两个光敏传感器拆下

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装(注意红圈内凸起朝右)

完成

安装所需零件

安装

完成

安装所需零件

安装(注意调整夹爪角度,使其闭合朝前)

完成

安装所需零件

注意在安装前需要先调节舵机角度为180度
将舵机的线接到PCB上板的S2接口,如下表:
舵机 |
小车PCB板 |
|---|---|
棕线 |
G |
红线 |
5V |
橙黄线 |
S2(A0) |
Arduino代码:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
void setup() {
myservo.attach(A0); // attaches the servo on pin A0 to the servo object
myservo.write(0); // tell servo to go to position
delay(1000);
myservo.write(90); // tell servo to go to position
delay(1000);
myservo.write(180); // tell servo to go to position
delay(1000);
}
void loop() {
}
上面的Arduino代码在资料中有提供,打开舵机的调整代码并烧录到Beetlebot的主板,完成。代码如下图位置:

KidsBlock(Scratch)代码:
也可以使用Scratch代码来调整舵机初始角度:

KidsBlock(Scratch)代码在资料中也有提供,打开舵机的调整代码并烧录到Beetlebot的主板,完成。代码如下图位置:

安装(齿轮安装时保持夹爪为闭合朝前状态)

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

足球小将形态完成

乐高舵机接线图
将舵机的线接到PCB上板的S2接口,如下表:
舵机 |
小车PCB板 |
|---|---|
棕线 |
G |
红线 |
5V |
橙黄线 |
S2(A0) |

1.3. 足球门安装步骤#
安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

1.4. Arduino代码:#
ESP8266代码

特别注意: 需要先将项目代码
中的用户Wifi名称和用户Wifi密码改成你们自己的Wifi名称和Wifi密码。
ESP8266串口WIFI ESP-01模块的UTXD引脚是由Arduino Nano主板的IO口RX(0)控制,URXD引脚是由Arduino Nano主板的IO口TX(1)控制。
//**********************************************************************************
/*
ESP8266_Code
*/
// generated by KidsBlock
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
//#include <WiFi.h>
#ifndef STASSID
#define STASSID "ChinaNet-2.4G-0DF0" //the name of user's Wifi
#define STAPSK "ChinaNet@233" //the password of the user's wifi
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
//IPAddress local_IP(192,168,4,22);
//IPAddress gateway(192,168,4,22);
//IPAddress subnet(255,255,255,0);
//
//const char *ssid = "ESP8266_AP_TEST";
//const char *password = "12345678";
WiFiServer server(80);
String unoData = "";
int ip_flag = 0;
int ultra_state = 1;
String ip_str;
void setup() {
Serial.begin(9600);
// WiFi.mode(WIFI_AP); //设置工作在AP模式
//
// WiFi.softAPConfig(local_IP, gateway, subnet); //设置AP地址
// while(!WiFi.softAP(ssid, password)){}; //启动AP
// Serial.println("AP启动成功");
//
// Serial.print("IP address: ");
// Serial.println(WiFi.softAPIP()); // 打印IP地址
//
// WiFi.softAPsetHostname("myHostName"); //设置主机名
// Serial.print("HostName: ");
// Serial.println(WiFi.softAPgetHostname()); //打印主机名
//
// Serial.print("mac Address: ");
// Serial.println(WiFi.softAPmacAddress()); //打印mac地址
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("IP ADDRESS: ");
Serial.println(WiFi.localIP());
if (!MDNS.begin("esp8266")) {
//Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
// Serial.println("mDNS responder started");
server.begin();
//Serial.println("TCP server started");
MDNS.addService("http", "tcp", 80);
ip_flag = 1;
}
void loop() {
//Serial.println(WiFi.softAPgetStationNum()); //打印客户端连接数
if(ip_flag == 1)
{
for(int i=3; i>0; i--)
{
Serial.print("IP: ");
Serial.print(WiFi.localIP());
Serial.println('#');
delay(500);
}
ip_flag = 0;
}
MDNS.update();
WiFiClient client = server.available();
if (!client) {
return;
}
//Serial.println("");
while (client.connected() && !client.available()) {
delay(1);
}
String req = client.readStringUntil('\r');
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
//Serial.print("Invalid request: ");
//Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
int len_val = String(req).length();
String M_req = String(req).substring(0,6);
//Serial.println(M_req);
if(M_req == "/btn/u")
{
String s_M_req = String(req).substring(5,len_val);
Serial.print(s_M_req);
Serial.print("#");
}
if(M_req == "/btn/v")
{
String s_M_req = String(req).substring(5,len_val);
Serial.print(s_M_req);
Serial.print("#");
}
client.flush();
String s;
if (req == "/") {
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
s += ipStr;
s += "</html>\r\n\r\n";
//Serial.println("Sending 200");
Serial.println(WiFi.localIP());
Serial.write('*');
client.println(WiFi.localIP());
ip_flag = 0;
}
else if(req == "/btn/F")
{
Serial.write('F');
client.println(F("F"));
}
else if(req == "/btn/B")
{
Serial.write('B');
client.println(F("B"));
}
else if(req == "/btn/L")
{
Serial.write('L');
client.println(F("L"));
}
else if(req == "/btn/R")
{
Serial.write('R');
client.println(F("R"));
}
else if(req == "/btn/S")
{
Serial.write('S');
client.println(F("S"));
}
else if(req == "/btn/a")
{
Serial.write('a');
client.println(F("a"));
}
else if(req == "/btn/b")
{
Serial.write('b');
client.println(F("b"));
}
else if(req == "/btn/c")
{
Serial.write('c');
client.println(F("c"));
}
else if(req == "/btn/d")
{
Serial.write('d');
client.println(F("d"));
}
else if(req == "/btn/e")
{
Serial.write('e');
client.println(F("e"));
}
else if(req == "/btn/f")
{
Serial.write('f');
client.println(F("f"));
}
else if(req == "/btn/g")
{
Serial.write('g');
client.println(F("g"));
}
else if(req == "/btn/z")
{
Serial.write('z');
client.println(F("z"));
}
else if(req == "/btn/i")
{
Serial.write('i');
client.println(F("i"));
}
else if(req == "/btn/j")
{
Serial.write('j');
client.println(F("j"));
}
else if(req == "/btn/k")
{
Serial.write('k');
client.println(F("k"));
}
else if(req == "/btn/y")
{
Serial.write('y');
client.println(F("y"));
}
else if(req == "/btn/l")
{
Serial.write('l');
client.println(F("l"));
}
else if(req == "/btn/m")
{
Serial.write('m');
client.println(F("m"));
}
else if(req == "/btn/n")
{
Serial.write('n');
client.println("n");
}
else if(req == "/btn/o")
{
Serial.write('o');
client.println(F("o"));
}
else if(req == "/btn/p")
{
Serial.write('p');
client.println(F("p"));
}
else if(req == "/btn/q")
{
Serial.write('q');
client.println("q");
}
else if(req == "/btn/x")
{
Serial.write('x');
client.println(F("x"));
}
else if(req == "/btn/1")
{
Serial.write('1');
client.println(F("1"));
}
else if(req == "/btn/2")
{
Serial.write('2');
client.println("2");
}
else if(req == "/btn/3")
{
Serial.write('3');
client.println(F("3"));
}
else if(req == "/btn/4")
{
Serial.write('4');
client.println("4");
}
else if(req == "/btn/5")
{
Serial.write('5');
client.println(F("5"));
}
else if(req == "/btn/0")
{
Serial.write('0');
client.println("0");
}
else {
//s = "HTTP/1.1 404 Not Found\r\n\r\n";
//Serial.println("Sending 404");
}
client.print(F("IP : "));
client.println(WiFi.localIP());
}
//**********************************************************************************
Wifi名称和Wifi密码修改后,确保USB转ESP-01S
WIFI模块串口测试扩展板上的拨码开关已经拨到Uart Download
端,并且也确定USB转ESP-01S
WIFI模块串口测试扩展板已经插入电脑的USB口。然后按照 Arduino 教程中的
Project 16
中的方法设置板型和COM口,IDE右下角显示对应板型和COM口,再点击
将ESP8266
代码上传到ESP8266串口WIFI
ESP-01模块上,上传成功。(注意:如果上传失败,在板型和COM口没问题情况下,将USB转ESP-01S
WIFI模块串口测试扩展板从电脑的USB口拔下来再次插到电脑的USB口)
ESP8266 代码上传成功后,先将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来,再将ESP8266串口WIFI ESP-01模块从USB转ESP-01S WIFI模块串口测试扩展板上拔下来。
Arduino Nano 实验代码

注意: 打开IDE后,一定要先设置好板型和COM口。如果家里没有WIFI需要打开手机热点共享WIFI。
#include <Servo.h>
Servo lgservo;
#define ML 4
#define ML_PWM 6
#define MR 2
#define MR_PWM 5
#define servo2 A0
char val;
char wifiData;
void setup() {
Serial.begin(9600);
pinMode(ML, OUTPUT);
pinMode(ML_PWM, OUTPUT);
pinMode(MR, OUTPUT);
pinMode(MR_PWM, OUTPUT);
lgservo.attach(A0);
lgservo.write(180);
delay(1000);
lgservo.write(160);
}
void loop() {
if(Serial.available() > 0)
{
val = Serial.read();
Serial.print(val);
}
switch(val)
{
case 'F': car_forward(); break;
case 'B': car_back(); break;
case 'L': car_left(); break;
case 'R': car_right(); break;
case 'S': car_stop(); break;
case 'p': lgservo.write(180); break;
case 'x': lgservo.write(160); break;
}
}
void car_forward()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,127);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,127);
}
void car_back()
{
digitalWrite(ML,HIGH);
analogWrite(ML_PWM,127);
digitalWrite(MR,HIGH);
analogWrite(MR_PWM,127);
}
void car_left()
{
digitalWrite(ML,HIGH);
analogWrite(ML_PWM,150);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,105);
}
void car_right()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,105);
digitalWrite(MR,HIGH);
analogWrite(MR_PWM,150);
}
void car_stop()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,0);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,0);
}
1.5. KidsBlock(Scratch)代码:#
ESP8266 代码:

注意: 如果家里没有WIFI,需要打开手机热点共享WIFI.

特别注意: 需要将ESP8266代码
中的Wifi名称和Wifi密码改成你们自己的Wifi名称和Wifi密码。
A. Wifi名称和Wifi密码修改后,确保USB转ESP-01S WIFI模块串口测试扩展板上的拨码开关已经拨到Uart Download 端,并且也确定USB转ESP-01S WIFI模块串口测试扩展板已经插入电脑的USB口,然后点击kidsblock软件上的“上传” 按钮 。将ESP8266代码上传到ESP8266串口WIFI ESP-01模块上,上传成功。(注意:如果上传失败,在板型和COM口没问题下,将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来再次插到电脑的USB口)

B. ESP8266代码上传成功后,先将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来,再将ESP8266串口WIFI ESP-01模块从USB转ESP-01S WIFI模块串口测试扩展板上拔下来。
USB线连接电脑和Arduino Nano主板:

Beetlebot页面设置:
更换开发板,点击
进入设备选择页面,点击
“套件”,选中 Beetlebot 3in1 Robot for Arduino ,单击“连接”。



Arduino Nano实验代码:


1.6. 实验场景:#
将足球门(乐高造型已搭好)放在地上某个固定的位置,APP连上WiFi。
2.
将小足球放在足球机器人的夹子中间,按住按钮
使夹子夹住小足球,同时操作小车方向按钮
使足球机器人把小足球送到离足球门一小段距离处再松开按钮
。这样,小足球掉在地上且往前滚,看看小足球是否会滚进足球门里?如果没有,就反复上面的操作,使小足球最终进入足球门里。
3. 如果你们小伙伴们也拥有这款足球机器人,可以和小伙伴们一起进行足球比赛,每一个足球机器人都夹着小足球,大家都操作各自的APP上的小车方向按钮,看看谁能最终把足球送到足球门里。
2. 投石攻城车#
2.1. 实验简介#
投石攻城车在古代主要用于围攻和防守要塞,主要是用木头制作的,是利用配重物的重力发射,把石头抛出去。我们也制作了一款投石攻城车,是由车和乐高积木搭建而成的,车上装有舵机和齿轮,长臂末端有乐高搭建的凹槽是用于装投射物。发射时,舵机转动带动齿轮把长臂向后推,把投射物放入凹槽中,当舵机转动一定角度带动齿轮把长臂完全升起时,投射物从凹槽中飞出。
2.2. 攻城战车形态安装步骤#
安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装前需调节舵机角度为0°
将舵机的线接到PCB上板的S2接口,如下表:
舵机 |
小车PCB板 |
|---|---|
棕线 |
G |
红线 |
5V |
橙黄线 |
S2(A0) |
Arduino代码:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
void setup() {
myservo.attach(A0); // attaches the servo on pin A0 to the servo object
myservo.write(0); // tell servo to go to position
delay(1000);
myservo.write(90); // tell servo to go to position
delay(1000);
myservo.write(0); // tell servo to go to position
delay(1000);
}
void loop() {
}
上面的Arduino代码在资料中有提供,打开舵机的调整代码并烧录到Beetlebot的主板,完成。代码如下图位置。

KidsBlock(Scratch)代码:
也可以使用下面的Scratch-KidsBlock代码来调整舵机初始化角度。

KidsBlock(Scratch)代码在资料中也有提供,打开舵机的调整代码并烧录到Beetlebot的主板,完成。代码如下图位置:

安装(安装姿态与右图保持一致)

完成

安装所需零件

安装

完成

舵机接线图

2.3. Arduino代码#
ESP8266代码:

特别注意: 需要先将项目代码
中的用户Wifi名称和用户Wifi密码改成你们自己的Wifi名称和Wifi密码。
ESP8266串口WIFI ESP-01模块的UTXD引脚是由Arduino Nano主板的IO口RX(0)控制,URXD引脚是由Arduino Nano主板的IO口TX(1)控制。
//**********************************************************************************
/*
ESP8266_Code
*/
// generated by KidsBlock
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
//#include <WiFi.h>
#ifndef STASSID
#define STASSID "ChinaNet-2.4G-0DF0" //the name of user's Wifi
#define STAPSK "ChinaNet@233" //the password of the user's wifi
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
//IPAddress local_IP(192,168,4,22);
//IPAddress gateway(192,168,4,22);
//IPAddress subnet(255,255,255,0);
//
//const char *ssid = "ESP8266_AP_TEST";
//const char *password = "12345678";
WiFiServer server(80);
String unoData = "";
int ip_flag = 0;
int ultra_state = 1;
String ip_str;
void setup() {
Serial.begin(9600);
// WiFi.mode(WIFI_AP); //设置工作在AP模式
//
// WiFi.softAPConfig(local_IP, gateway, subnet); //设置AP地址
// while(!WiFi.softAP(ssid, password)){}; //启动AP
// Serial.println("AP启动成功");
//
// Serial.print("IP address: ");
// Serial.println(WiFi.softAPIP()); // 打印IP地址
//
// WiFi.softAPsetHostname("myHostName"); //设置主机名
// Serial.print("HostName: ");
// Serial.println(WiFi.softAPgetHostname()); //打印主机名
//
// Serial.print("mac Address: ");
// Serial.println(WiFi.softAPmacAddress()); //打印mac地址
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("IP ADDRESS: ");
Serial.println(WiFi.localIP());
if (!MDNS.begin("esp8266")) {
//Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
// Serial.println("mDNS responder started");
server.begin();
//Serial.println("TCP server started");
MDNS.addService("http", "tcp", 80);
ip_flag = 1;
}
void loop() {
//Serial.println(WiFi.softAPgetStationNum()); //打印客户端连接数
if(ip_flag == 1)
{
for(int i=3; i>0; i--)
{
Serial.print("IP: ");
Serial.print(WiFi.localIP());
Serial.println('#');
delay(500);
}
ip_flag = 0;
}
MDNS.update();
WiFiClient client = server.available();
if (!client) {
return;
}
//Serial.println("");
while (client.connected() && !client.available()) {
delay(1);
}
String req = client.readStringUntil('\r');
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
//Serial.print("Invalid request: ");
//Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
int len_val = String(req).length();
String M_req = String(req).substring(0,6);
//Serial.println(M_req);
if(M_req == "/btn/u")
{
String s_M_req = String(req).substring(5,len_val);
Serial.print(s_M_req);
Serial.print("#");
}
if(M_req == "/btn/v")
{
String s_M_req = String(req).substring(5,len_val);
Serial.print(s_M_req);
Serial.print("#");
}
client.flush();
String s;
if (req == "/") {
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
s += ipStr;
s += "</html>\r\n\r\n";
//Serial.println("Sending 200");
Serial.println(WiFi.localIP());
Serial.write('*');
client.println(WiFi.localIP());
ip_flag = 0;
}
else if(req == "/btn/F")
{
Serial.write('F');
client.println(F("F"));
}
else if(req == "/btn/B")
{
Serial.write('B');
client.println(F("B"));
}
else if(req == "/btn/L")
{
Serial.write('L');
client.println(F("L"));
}
else if(req == "/btn/R")
{
Serial.write('R');
client.println(F("R"));
}
else if(req == "/btn/S")
{
Serial.write('S');
client.println(F("S"));
}
else if(req == "/btn/a")
{
Serial.write('a');
client.println(F("a"));
}
else if(req == "/btn/b")
{
Serial.write('b');
client.println(F("b"));
}
else if(req == "/btn/c")
{
Serial.write('c');
client.println(F("c"));
}
else if(req == "/btn/d")
{
Serial.write('d');
client.println(F("d"));
}
else if(req == "/btn/e")
{
Serial.write('e');
client.println(F("e"));
}
else if(req == "/btn/f")
{
Serial.write('f');
client.println(F("f"));
}
else if(req == "/btn/g")
{
Serial.write('g');
client.println(F("g"));
}
else if(req == "/btn/z")
{
Serial.write('z');
client.println(F("z"));
}
else if(req == "/btn/i")
{
Serial.write('i');
client.println(F("i"));
}
else if(req == "/btn/j")
{
Serial.write('j');
client.println(F("j"));
}
else if(req == "/btn/k")
{
Serial.write('k');
client.println(F("k"));
}
else if(req == "/btn/y")
{
Serial.write('y');
client.println(F("y"));
}
else if(req == "/btn/l")
{
Serial.write('l');
client.println(F("l"));
}
else if(req == "/btn/m")
{
Serial.write('m');
client.println(F("m"));
}
else if(req == "/btn/n")
{
Serial.write('n');
client.println("n");
}
else if(req == "/btn/o")
{
Serial.write('o');
client.println(F("o"));
}
else if(req == "/btn/p")
{
Serial.write('p');
client.println(F("p"));
}
else if(req == "/btn/q")
{
Serial.write('q');
client.println("q");
}
else if(req == "/btn/x")
{
Serial.write('x');
client.println(F("x"));
}
else if(req == "/btn/1")
{
Serial.write('1');
client.println(F("1"));
}
else if(req == "/btn/2")
{
Serial.write('2');
client.println("2");
}
else if(req == "/btn/3")
{
Serial.write('3');
client.println(F("3"));
}
else if(req == "/btn/4")
{
Serial.write('4');
client.println("4");
}
else if(req == "/btn/5")
{
Serial.write('5');
client.println(F("5"));
}
else if(req == "/btn/0")
{
Serial.write('0');
client.println("0");
}
else {
//s = "HTTP/1.1 404 Not Found\r\n\r\n";
//Serial.println("Sending 404");
}
client.print(F("IP : "));
client.println(WiFi.localIP());
}
//**********************************************************************************
Wifi名称和Wifi密码修改后,确保USB转ESP-01S
WIFI模块串口测试扩展板上的拨码开关已经拨到Uart Download
端,并且也确定USB转ESP-01S
WIFI模块串口测试扩展板已经插入电脑的USB口。然后按照 Arduino 教程中的
Project 16
中的方法设置板型和COM口,IDE右下角显示对应板型和COM口,再点击
将ESP8266
代码上传到ESP8266串口WIFI
ESP-01模块上,上传成功。(注意:如果上传失败,在板型和COM口没问题情况下,将USB转ESP-01S
WIFI模块串口测试扩展板从电脑的USB口拔下来再次插到电脑的USB口)
ESP8266 代码上传成功后,先将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来,再将ESP8266串口WIFI ESP-01模块从USB转ESP-01S WIFI模块串口测试扩展板上拔下来。
Arduino Nano 实验代码

注意: 打开IDE后,一定要先设置好板型和COM口。如果家里没有WIFI需要打开手机热点共享WIFI。
#include <Servo.h>
Servo lgservo;
#define ML 4
#define ML_PWM 6
#define MR 2
#define MR_PWM 5
#define servo2 A0
char val;
char wifiData;
boolean servo_flag = 1;
void setup() {
Serial.begin(9600);
pinMode(ML, OUTPUT);
pinMode(ML_PWM, OUTPUT);
pinMode(MR, OUTPUT);
pinMode(MR_PWM, OUTPUT);
lgservo.attach(A0);
lgservo.write(0);
}
void loop() {
if(Serial.available() > 0)
{
val = Serial.read();
Serial.print(val);
}
switch(val)
{
case 'F': car_forward(); break;
case 'B': car_back(); break;
case 'L': car_left(); break;
case 'R': car_right(); break;
case 'S': car_stop(); break;
case 'p': lgservo.write(55);servo_flag = 1; break;
case 'x': servo_down(); break;
}
}
void servo_down()
{
while( servo_flag == 1)
{
for(int i=55; i>0; i--)
{
lgservo.write(i);
delay(2);
}
servo_flag = 0;
}
}
void car_forward()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,255);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,255);
}
void car_back()
{
digitalWrite(ML,HIGH);
analogWrite(ML_PWM,0);
digitalWrite(MR,HIGH);
analogWrite(MR_PWM,0);
}
void car_left()
{
digitalWrite(ML,HIGH);
analogWrite(ML_PWM,150);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,105);
}
void car_right()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,105);
digitalWrite(MR,HIGH);
analogWrite(MR_PWM,150);
}
void car_stop()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,0);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,0);
}
2.4. KidsBlock(Scratch)代码:#
ESP8266 代码:

注意: 如果家里没有WIFI,需要打开手机热点共享WIFI.

特别注意: 需要将ESP8266代码
中的Wifi名称和Wifi密码改成你们自己的Wifi名称和Wifi密码。
A. Wifi名称和Wifi密码修改后,确保USB转ESP-01S WIFI模块串口测试扩展板上的拨码开关已经拨到Uart Download 端,并且也确定USB转ESP-01S WIFI模块串口测试扩展板已经插入电脑的USB口,然后点击kidsblock软件上的“上传” 按钮 。将ESP8266代码上传到ESP8266串口WIFI ESP-01模块上,上传成功。(注意:如果上传失败,在板型和COM口没问题下,将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来再次插到电脑的USB口)

B. ESP8266代码上传成功后,先将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来,再将ESP8266串口WIFI ESP-01模块从USB转ESP-01S WIFI模块串口测试扩展板上拔下来。
USB线连接电脑和Arduino Nano主板:

Beetlebot页面设置:
更换开发板,点击
进入设备选择页面,点击
“套件”,选中 Beetlebot 3in1 Robot for Arduino ,单击“连接”。



Arduino Nano实验代码:


2.5. 实验场景#
1. 在场地用乐高积木搭建几个目标物(目标物A,B,C,D,E),目标物在投石攻城车前方且都隔一段距离。APP连上WiFi。
2.
操作小车方向按钮
使投石攻城车正对目标物A一段距离,按住按钮
,舵机转动一定角度带动齿轮升起长臂把乐高积木块抛出去;松开按钮
,舵机转动带动齿轮把长臂向后推。看看乐高积木块是否打击到目标物A?如果没有,就反复操作小车方向按钮
、按住或松开按钮
,调整投石攻城车与目标物A之间的距离,使抛出去的乐高积木块刚好可以打击到目标物A。
3.
打击目标物B,C,D,E的操作方法和上面的一样。按住按钮
,舵机转动一定角度带动齿轮升起长臂把乐高积木块抛出去。
3. 搬运机器人#
3.1. 实验简介#
在众多的工业机器人中,搬运机器人无疑是应用率较高的机器人之一,不管是在工业制造、仓储物流、烟草、医药、食品、化工等行业领域,还是在邮局、图书馆、港口码头、机场、停车场等场景,都可以见到搬运机器人的身影。在本实验中,我们也利用乐高积木搭建了一款搬运机器人来搬运东西。
3.2. 搬运机器人形态安装步骤#
将超声波云台拆下

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装

完成

安装所需零件

安装前需调节舵机角度为180°
将舵机的线接到PCB上板的S2接口,如下表:
舵机 |
小车PCB板 |
|---|---|
棕线 |
G |
红线 |
5V |
橙黄线 |
S2(A0) |
Arduino代码:
#include <Servo.h>
Servo myservo; // create servo object to control a servo
void setup() {
myservo.attach(A0); // attaches the servo on pin A0 to the servo object
myservo.write(0); // tell servo to go to position
delay(1000);
myservo.write(90); // tell servo to go to position
delay(1000);
myservo.write(180); // tell servo to go to position
delay(1000);
}
void loop() {
}
上面的Arduino代码在资料中有提供,打开舵机的调整代码并烧录到Beetlebot的主板,完成。代码如下图位置:

KidsBlock(Scratch)代码:
也可以使用下面的Scratch-KidsBlock代码来调整舵机初始化角度.

KidsBlock(Scratch)代码在资料中也有提供,打开舵机的调整代码并烧录到Beetlebot的主板,完成。代码如下图位置:

安装(安装姿势与右图一致)

完成

安装所需零件

安装

安装

完成

完成

完成

舵机接线图
舵机接到板子上的S2接口

3.3. Arduino代码#
ESP8266代码:

特别注意: 需要先将项目代码
中的用户Wifi名称和用户Wifi密码改成你们自己的Wifi名称和Wifi密码。
ESP8266串口WIFI ESP-01模块的UTXD引脚是由Arduino Nano主板的IO口RX(0)控制,URXD引脚是由Arduino Nano主板的IO口TX(1)控制。
//**********************************************************************************
/*
ESP8266_Code
*/
// generated by KidsBlock
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
//#include <WiFi.h>
#ifndef STASSID
#define STASSID "ChinaNet-2.4G-0DF0" //the name of user's Wifi
#define STAPSK "ChinaNet@233" //the password of the user's wifi
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
//IPAddress local_IP(192,168,4,22);
//IPAddress gateway(192,168,4,22);
//IPAddress subnet(255,255,255,0);
//
//const char *ssid = "ESP8266_AP_TEST";
//const char *password = "12345678";
WiFiServer server(80);
String unoData = "";
int ip_flag = 0;
int ultra_state = 1;
String ip_str;
void setup() {
Serial.begin(9600);
// WiFi.mode(WIFI_AP); //设置工作在AP模式
//
// WiFi.softAPConfig(local_IP, gateway, subnet); //设置AP地址
// while(!WiFi.softAP(ssid, password)){}; //启动AP
// Serial.println("AP启动成功");
//
// Serial.print("IP address: ");
// Serial.println(WiFi.softAPIP()); // 打印IP地址
//
// WiFi.softAPsetHostname("myHostName"); //设置主机名
// Serial.print("HostName: ");
// Serial.println(WiFi.softAPgetHostname()); //打印主机名
//
// Serial.print("mac Address: ");
// Serial.println(WiFi.softAPmacAddress()); //打印mac地址
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("IP ADDRESS: ");
Serial.println(WiFi.localIP());
if (!MDNS.begin("esp8266")) {
//Serial.println("Error setting up MDNS responder!");
while (1) {
delay(1000);
}
}
// Serial.println("mDNS responder started");
server.begin();
//Serial.println("TCP server started");
MDNS.addService("http", "tcp", 80);
ip_flag = 1;
}
void loop() {
//Serial.println(WiFi.softAPgetStationNum()); //打印客户端连接数
if(ip_flag == 1)
{
for(int i=3; i>0; i--)
{
Serial.print("IP: ");
Serial.print(WiFi.localIP());
Serial.println('#');
delay(500);
}
ip_flag = 0;
}
MDNS.update();
WiFiClient client = server.available();
if (!client) {
return;
}
//Serial.println("");
while (client.connected() && !client.available()) {
delay(1);
}
String req = client.readStringUntil('\r');
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
//Serial.print("Invalid request: ");
//Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
int len_val = String(req).length();
String M_req = String(req).substring(0,6);
//Serial.println(M_req);
if(M_req == "/btn/u")
{
String s_M_req = String(req).substring(5,len_val);
Serial.print(s_M_req);
Serial.print("#");
}
if(M_req == "/btn/v")
{
String s_M_req = String(req).substring(5,len_val);
Serial.print(s_M_req);
Serial.print("#");
}
client.flush();
String s;
if (req == "/") {
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
s += ipStr;
s += "</html>\r\n\r\n";
//Serial.println("Sending 200");
Serial.println(WiFi.localIP());
Serial.write('*');
client.println(WiFi.localIP());
ip_flag = 0;
}
else if(req == "/btn/F")
{
Serial.write('F');
client.println(F("F"));
}
else if(req == "/btn/B")
{
Serial.write('B');
client.println(F("B"));
}
else if(req == "/btn/L")
{
Serial.write('L');
client.println(F("L"));
}
else if(req == "/btn/R")
{
Serial.write('R');
client.println(F("R"));
}
else if(req == "/btn/S")
{
Serial.write('S');
client.println(F("S"));
}
else if(req == "/btn/a")
{
Serial.write('a');
client.println(F("a"));
}
else if(req == "/btn/b")
{
Serial.write('b');
client.println(F("b"));
}
else if(req == "/btn/c")
{
Serial.write('c');
client.println(F("c"));
}
else if(req == "/btn/d")
{
Serial.write('d');
client.println(F("d"));
}
else if(req == "/btn/e")
{
Serial.write('e');
client.println(F("e"));
}
else if(req == "/btn/f")
{
Serial.write('f');
client.println(F("f"));
}
else if(req == "/btn/g")
{
Serial.write('g');
client.println(F("g"));
}
else if(req == "/btn/z")
{
Serial.write('z');
client.println(F("z"));
}
else if(req == "/btn/i")
{
Serial.write('i');
client.println(F("i"));
}
else if(req == "/btn/j")
{
Serial.write('j');
client.println(F("j"));
}
else if(req == "/btn/k")
{
Serial.write('k');
client.println(F("k"));
}
else if(req == "/btn/y")
{
Serial.write('y');
client.println(F("y"));
}
else if(req == "/btn/l")
{
Serial.write('l');
client.println(F("l"));
}
else if(req == "/btn/m")
{
Serial.write('m');
client.println(F("m"));
}
else if(req == "/btn/n")
{
Serial.write('n');
client.println("n");
}
else if(req == "/btn/o")
{
Serial.write('o');
client.println(F("o"));
}
else if(req == "/btn/p")
{
Serial.write('p');
client.println(F("p"));
}
else if(req == "/btn/q")
{
Serial.write('q');
client.println("q");
}
else if(req == "/btn/x")
{
Serial.write('x');
client.println(F("x"));
}
else if(req == "/btn/1")
{
Serial.write('1');
client.println(F("1"));
}
else if(req == "/btn/2")
{
Serial.write('2');
client.println("2");
}
else if(req == "/btn/3")
{
Serial.write('3');
client.println(F("3"));
}
else if(req == "/btn/4")
{
Serial.write('4');
client.println("4");
}
else if(req == "/btn/5")
{
Serial.write('5');
client.println(F("5"));
}
else if(req == "/btn/0")
{
Serial.write('0');
client.println("0");
}
else {
//s = "HTTP/1.1 404 Not Found\r\n\r\n";
//Serial.println("Sending 404");
}
client.print(F("IP : "));
client.println(WiFi.localIP());
}
//**********************************************************************************
Wifi名称和Wifi密码修改后,确保USB转ESP-01S
WIFI模块串口测试扩展板上的拨码开关已经拨到Uart Download
端,并且也确定USB转ESP-01S
WIFI模块串口测试扩展板已经插入电脑的USB口。然后按照 Arduino 教程中的
Project 16
中的方法设置板型和COM口,IDE右下角显示对应板型和COM口,再点击
将ESP8266
代码上传到ESP8266串口WIFI
ESP-01模块上,上传成功。(注意:如果上传失败,在板型和COM口没问题情况下,将USB转ESP-01S
WIFI模块串口测试扩展板从电脑的USB口拔下来再次插到电脑的USB口)
ESP8266 代码上传成功后,先将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来,再将ESP8266串口WIFI ESP-01模块从USB转ESP-01S WIFI模块串口测试扩展板上拔下来。
Arduino Nano 实验代码

注意: 打开IDE后,一定要先设置好板型和COM口。如果家里没有WIFI需要打开手机热点共享WIFI。
#include <Servo.h>
Servo lgservo;
#define ML 4
#define ML_PWM 6
#define MR 2
#define MR_PWM 5
#define servo2 A0
char val;
char wifiData;
void setup() {
Serial.begin(9600);
pinMode(ML, OUTPUT);
pinMode(ML_PWM, OUTPUT);
pinMode(MR, OUTPUT);
pinMode(MR_PWM, OUTPUT);
lgservo.attach(A0);
lgservo.write(180);
}
void loop() {
if(Serial.available() > 0)
{
val = Serial.read();
Serial.print(val);
}
switch(val)
{
case 'F': car_forward(); break;
case 'B': car_back(); break;
case 'L': car_left(); break;
case 'R': car_right(); break;
case 'S': car_stop(); break;
case 'p': lgservo.write(130); break;
case 'x': lgservo.write(180); break;
}
}
void car_forward()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,127);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,127);
}
void car_back()
{
digitalWrite(ML,HIGH);
analogWrite(ML_PWM,127);
digitalWrite(MR,HIGH);
analogWrite(MR_PWM,127);
}
void car_left()
{
digitalWrite(ML,HIGH);
analogWrite(ML_PWM,150);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,105);
}
void car_right()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,105);
digitalWrite(MR,HIGH);
analogWrite(MR_PWM,150);
}
void car_stop()
{
digitalWrite(ML,LOW);
analogWrite(ML_PWM,0);
digitalWrite(MR,LOW);
analogWrite(MR_PWM,0);
}
3.4. KidsBlock(Scratch)代码:#
ESP8266 代码:

注意: 如果家里没有WIFI,需要打开手机热点共享WIFI.

特别注意: 需要将ESP8266代码
中的Wifi名称和Wifi密码改成你们自己的Wifi名称和Wifi密码。
A. Wifi名称和Wifi密码修改后,确保USB转ESP-01S WIFI模块串口测试扩展板上的拨码开关已经拨到Uart Download 端,并且也确定USB转ESP-01S WIFI模块串口测试扩展板已经插入电脑的USB口,然后点击kidsblock软件上的“上传” 按钮 。将ESP8266代码上传到ESP8266串口WIFI ESP-01模块上,上传成功。(注意:如果上传失败,在板型和COM口没问题下,将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来再次插到电脑的USB口)

B. ESP8266代码上传成功后,先将USB转ESP-01S WIFI模块串口测试扩展板从电脑的USB口拔下来,再将ESP8266串口WIFI ESP-01模块从USB转ESP-01S WIFI模块串口测试扩展板上拔下来。
USB线连接电脑和Arduino Nano主板:


3.5. 实验场景#
1.
在投石攻城车项目实验中,投石攻城车抛乐高积木块击打目标物A、B、C、D散落满地的一些乐高积木。
2.
APP连上WiFi,操作小车方向按钮
使搬运机器人移动到散落满地的乐高积木旁。
3.
用手拣一些小的乐高积木块放到铲斗上,操作小车方向按钮
使搬运机器人把乐高积木搬运到原始位置。按住按钮
,舵机转动一定角度带动齿轮使铲斗升起,这样,运送的乐高积木块就掉下来。
重复上面的操作方法,把所有的乐高积木块都搬运到原始位置。