Grove Beginner Kits基础实验
Posted 卓晴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Grove Beginner Kits基础实验相关的知识,希望对你有一定的参考价值。
简 介: 本文就Arduino的基础实验以及与ESP8266连接进行了初步实验。并基于此,给出了基于人脸识别只能门锁系统的硬件设计。
关键词
: Arduino,ESP8266
§01 Arduino 外部接口
1、Auduino的硬件
(1)原理图
▲ Arduino UNO 原理图
(2)管脚定义
▲ Arduino 管脚定义
▲ Arduino UNO 管脚功能定义
2、参考历程
▲ 测试的实验平台 UNO
§02 基础验证实验
1、按钮与LED
程序直接由“文件
,示例
,digital
,Button
”生成。它利用数字口2左右输入,13 作为LED输出。
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop() {
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
使用杜邦线连接D2到VCC,GND,可以改变LED的状态。
2、所有IO口
在 详解Arduino Uno开发板的引脚分配图及定义(重要且基础) - Neo0820 - 博客园 给出了IO口的详细定义。
使用下面的代码,可以验证可以多达20个数字IO口可以被使用。
/*
**==============================================================================
** TEST1.C: -- by Dr. ZhuoQing, 2021-05-24
**
**==============================================================================
*/
//------------------------------------------------------------------------------
#define PIN_NUM 20
void setup() {
int i;
for(i = 0; i <PIN_NUM ; i ++) {
pinMode(i, OUTPUT);
}
}
void loop() {
int i;
for(i = 0; i < PIN_NUM; i ++) {
digitalWrite(i, HIGH);
}
delay(20);
for(i = 0; i < PIN_NUM; i ++) {
digitalWrite(i, LOW);
}
delay(20);
}
//==============================================================================
// END OF THE FILE : TEST1.C
//------------------------------------------------------------------------------
使用示波器观察到的第19个数字IO(PC5)上的波形:
▲ Arduino 第19个数字IO(PC5)上的波形
▲ 对应的Arduino数字IO定义
▲ Arduino模拟IO口也可以用作数字输入输出
3、PWM输出
为了能够控制舵机的运动,需要使用到PWM输出功能。这种方式也可以作为一种模拟量的输出替代品。
在Arduino官方网站给出了 PWM 的简要说明。利用 anlogWrite() 可以在对应的Pin管脚上产生所需要的PWM波形。
-
Uno, Nano, Mini产生PWM管脚
-
管脚:
3, 5, 6, 9, 10, 11
PWM 频率:
490 Hz (pins 5 and 6: 980 Hz)
(1)测试PWM波形输出
▲ 在PD3输出的PWM波形
const int PWM_PIN = 3;
void setup() {
pinMode(PWM_PIN, OUTPUT);
analogWrite(PWM_PIN, 128);
}
void loop() {
// analogWrite(PWM_PIN, 128);
delay(10);
}
如果将analogWrite()
函数放置在loop()
函数中,也可以产生相同的效果。
方波的频率为490Hz。那么如果用于驱动舵机,这个频率不合适。在 舵机的脉冲指令的频率对于舵机运动影响 测量过,对于普通的舵机,它的指令频率不能够超过400Hz,通常情况下取 50Hz~300Hz 之间的频率。
(2)修改PWM频率
在 Arduino-PWM-Frequency 给出通过在void setup()
函数中,修改 CS02,CS01,CS00
来调整对应的ATMEGA328的输出PWM频率。
//---------------------------------------------- Set PWM frequency for D5 & D6 -------------------------------
//NOTE: Changing this timer 0 affects millis() and delay!
//TCCR0B = TCCR0B & B11111000 | B00000001; // set timer 0 divisor to 1 for PWM frequency of 62500.00 Hz
//TCCR0B = TCCR0B & B11111000 | B00000010; // set timer 0 divisor to 8 for PWM frequency of 7812.50 Hz
TCCR0B = TCCR0B & B11111000 | B00000011; // set timer 0 divisor to 64 for PWM frequency of 976.56 Hz (The DEFAULT)
//TCCR0B = TCCR0B & B11111000 | B00000100; // set timer 0 divisor to 256 for PWM frequency of 244.14 Hz
//TCCR0B = TCCR0B & B11111000 | B00000101; // set timer 0 divisor to 1024 for PWM frequency of 61.04 Hz
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
//TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000010; // set timer 1 divisor to 8 for PWM frequency of 3921.16 Hz
TCCR1B = TCCR1B & B11111000 | B00000011; // set timer 1 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
//TCCR1B = TCCR1B & B11111000 | B00000100; // set timer 1 divisor to 256 for PWM frequency of 122.55 Hz
//TCCR1B = TCCR1B & B11111000 | B00000101; // set timer 1 divisor to 1024 for PWM frequency of 30.64 Hz
//---------------------------------------------- Set PWM frequency for D3 & D11 ------------------------------
//TCCR2B = TCCR2B & B11111000 | B00000001; // set timer 2 divisor to 1 for PWM frequency of 31372.55 Hz
//TCCR2B = TCCR2B & B11111000 | B00000010; // set timer 2 divisor to 8 for PWM frequency of 3921.16 Hz
//TCCR2B = TCCR2B & B11111000 | B00000011; // set timer 2 divisor to 32 for PWM frequency of 980.39 Hz
TCCR2B = TCCR2B & B11111000 | B00000100; // set timer 2 divisor to 64 for PWM frequency of 490.20 Hz (The DEFAULT)
//TCCR2B = TCCR2B & B11111000 | B00000101; // set timer 2 divisor to 128 for PWM frequency of 245.10 Hz
//TCCR2B = TCCR2B & B11111000 | B00000110; // set timer 2 divisor to 256 for PWM frequency of 122.55 Hz
//TCCR2B = TCCR2B & B11111000 | B00000111; // set timer 2 divisor to 1024 for PWM frequency of 30.64 Hz
通过下面的程序测试,D3输出122.5Hz的PWM波形:
const int PWM_PIN = 3;
void setup() {
TCCR2B = TCCR2B & B11111000 | B00000110;
pinMode(PWM_PIN, OUTPUT);
}
void loop() {
analogWrite(PWM_PIN, 128);
delay(10);
}
▲ 修改TCCR2B之后对应的PWM占空比
(3)控制舵机运行
控制舵机的角度是由PWM的脉冲的高电平的时间宽度决定,通常情况下是 1ms~2ms 之间的脉宽。
假定设PWM输出频率为
f
P
W
M
=
122.55
H
z
f_{PWM} = 122.55Hz
fPWM=122.55Hz,下面给出对应脉宽且1ms,1.5ms,2ms
。
PWM脉宽 | PWM设置值 | 实际输出时间(us) | 实测时间(us) |
---|---|---|---|
1ms | 31 | 0.992ms | 0.988 |
1.5ms | 47 | 1.504ms | 1.5ms |
2ms | 63 | 2.016ms | 2.01ms |
使用下面的代码控制PWM输出脉宽1ms 到 2ms切换;舵机发生旋转。
const int PWM_PIN = 3;
void setup() {
TCCR2B = TCCR2B & B11111000 | B00000110;
pinMode(PWM_PIN, OUTPUT);
}
void loop() {
delay(1000);
analogWrite(PWM_PIN, 63);
delay(1000);
analogWrite(PWM_PIN, 31);
}
▲ 控制舵机运行的情况
下图给出了小型舵机的三条引线的功能定义:
▲ 舵机的三根引线功能定义
4、串口输入输出
在 Arduino基础入门篇23—串口通讯 TonyCode 给出了 Arduino的串口使用方法。在 Arduino官网中也给出了Serial函数 的详细说明。
(1)串口输出
下面是测试代码:
const int PWM_PIN = 3;
void setup() {
TCCR2B = TCCR2B & B11111000 | B00000110;
pinMode(PWM_PIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
delay(100);
Serial.print("U");
}
测量TX输出管脚的波形为:
▲ 测量TX管脚的波形
(2)软件模拟UART
在 Using SoftwareSerial in Arduino for Serial Communication 介绍了Arduino 软件UART的使用方式。
详细的软件UART可以参见 Arduino的官网 SoftwareSerial 中的信息。
软件UART的限制:
- 在一个时间段,只有一个软件UART可以接收字符;
- 并不是所有的PIN都可以用于软件UART。
【Ⅰ.测试一个 Software UART】
代码来自于: Software Serial Example 。它演示了一个软件串口的输出的情况。
#include <SoftwareSerial.h>
//------------------------------------------------------------------------------
SoftwareSerial mySerial(2, 3);
void setup() {
mySerial.begin(38400);
}
//------------------------------------------------------------------------------
void loop() {
mySerial.write('U');
delay(10);
}
▲ 测量PD3管脚的波形
【Ⅱ.测试两个Software】
这个例子的代码来自于 Two Port Receive 。
#include <SoftwareSerial.h>
//------------------------------------------------------------------------------
SoftwareSerial portOne(10, 11);
SoftwareSerial portTwo(8, 9);
void setup() {
portOne.begin(9600);
portTwo.begin(115200);
}
//------------------------------------------------------------------------------
void loop() {
portOne.write('U');
portTwo.write('V');
delay(10);
}
▲ 测量PIN9对应的输出‘V’的波形
▲ 测量PIN11对应的输出‘V’的波形
为了使得所有的串口都在前面,即硬件串口为PD0,1, 两个软件串口分别为(2,3),(4,5)进行同样的测试,输出结果相同。
#include <SoftwareSerial.h>
//------------------------------------------------------------------------------
SoftwareSerial portOne(4, 5);
SoftwareSerial portTwo(2, 3);
void setup() {
portOne.begin(9600);
portTwo.begin(115200);
}
//------------------------------------------------------------------------------
void loop() {
portOne.write('U');
portTwo.write('V');
delay(10);
}
§03 连接外部模块
1、软件UART连接语音模块
使用在 语音合成模块 文本转TTS 真人发音 SYN6288的模块,测试语言合成模块的功能。
(1)测试英文和数字
使用(4,5)软件UART,发送语言合成到SYN6288语音模块。
#include <SoftwareSerial.h>
//------------------------------------------------------------------------------
SoftwareSerial portOne(4, 5);
SoftwareSerial portTwo(2, 3);
void setup() {
portOne.begin(9600);
portTwo.begin(115200);
}
//------------------------------------------------------------------------------
void loop() {
portOne.print("1234.45");
delay(2000);
}
直接输出英文字符串,与数字,都可以正确的发音。
▲ 测试电路板
(2)输出汉字
直接输出汉字则遇到问题。比如:
portOne.print("下午好!");
则输出错误的发音。要解决这问题,可以根据 ESP32-S的UART2的初始化需要注意的问题 的方式,将所需要转换的汉字转换成GBK二进制之后,再发送到串口。比如下面的代码就可以正确读出“清华大学”的汉字。
portOne.print("\\xc7\\xe5\\xbb\\xaa\\xb4\\xf3\\xd1\\xa7");
下面的代码发出“下午好”正确读音。
portOne.print("\\xcf\\xc2\\xce\\xe7\\xba\\xc3");
下面是带有外壳的TTS模块,请注意它的引脚对应的功能。可以使用上面相同的软件使其发出正确的含资产读音。
▲ 带有外壳的TTS模块
2、连接WiFi模块
WiFi模块使用 ESP-12F模块转接板测试版调试说明,下载MicroPython程序。ESP8266-12F ,这个模块在 ESP8266访问网站-urequest get方法 测试过,可以通过urequest与网站进行连接。
import machine
import urequests
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect('TENDA626A', 'gniqouhz')
print(wlan.ifconfig())
response = urequests.get("http://192.168.4.3:8000/lock/update/?type=LOCK&detail=AAAA")
print(response.text)
(1)将ESP8266模块UART0扩展
为了能够使用UART0既可以作为REPL的串口,又可以作为应用的串口,将UART0的输入通过肖特基二极管进行扩展。
▲ ESP8266 扩展口的定义
同时将下载板上的RXD上的电阻更换成肖特基二极管。这样外部的RXD便可以同样通过肖特基二极管与UART0的RXD相连了。
▲ 将下载板上的RXD上的电阻更换成肖特基二极管
(2)ESP8266>>Arduino
【Ⅰ.ESP8266代码】
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY -- by Dr. ZhuoQing 2021-05-24
#
# Note:
#============================================================
from machine import UART,Pin
import time
uart = UART(1, baudrate = 以上是关于Grove Beginner Kits基础实验的主要内容,如果未能解决你的问题,请参考以下文章
网易官方极客战记(codecombat)攻略-森林-Burlbole 树林-burlbole-grove
POJ 3182 The Grove [DP(spfa) 射线法]