输入/输出
- 一、概述
- 1、硬件原理图
- Terminal引脚分布及功能
- Wio Terminal Grove端口引脚分配
- 二、使用Wio Terminal上的Grove模拟端口
- 1、RPI 模拟引脚
- 2、Grove引脚配置
- 3、示例
- 三、使用 Wio Terminal上的Grove数字端口
- 1、RPI 数字引脚
- 2、Grove引脚配置
- 将 Grove I2C 端口用作数字端口
- 3、示例
- 4、PWM 输出示例代码(伺服器)
- 5、UART 串行通信
- 四、在 Wio Terminal 上使用Grove I2C端口
- 1、端口配置
- 2、示例
- 五、在 Wio Terminal 上使用 SPI
- 1、端口配置
- 2、软件配置
- 六、Grove 端口
- 1、Wio Terminal 与 Grove - TDS 传感器
- 库安装
- 完整代码
- 2、Wio Terminal 配合 Grove - OLED 显示屏
- 库安装
- U8g2初始化
- 完整代码
- 3、Wio Terminal 与 Grove - 温度传感器
- 库安装
- 完整代码
- 4、Wio Terminal 与 Grove - GPS 传感器
- 库安装
- 完整代码
一、概述
1、硬件原理图
Terminal引脚分布及功能
Wio Terminal的SAMD51微控制器引出了40个GPIO引脚,这与Raspberry Pi的引脚布局相同。
要使用这些引脚,只需使用上面定义的引脚名称即可!有些引脚具有多功能,因此可以通过不同的方式引用。
For more information, please check variant.h for more information
Wio Terminal Grove端口引脚分配
正如你所看到的,Wio Terminal上有两个可用的Grove端口。一个是默认的I2C端口,另一个是可配置的数字/模拟引脚,它也可以用于PWM输出。两个Grove端口都可以用作数字端口。
二、使用Wio Terminal上的Grove模拟端口
本节展示了如何在 Wio Terminal 上使用模拟输入。要在 Wio Terminal 上使用模拟引脚,您必须使用 RPI 引脚。
1、RPI 模拟引脚
树莓派引脚定义为:
- RPI_A0 -> RPI_A8
2、Grove引脚配置
要使用 Grove 可配置 A/D 端口作为模拟端口,只需按以下方式定义:
void setup() {
pinMode(A0, INPUT);
}
现在,将 Grove 传感器连接到物理引脚!
3、示例
在此示例中,使用 Grove Loudness传感器进行演示:
void setup() {
Serial.begin(115200);
pinMode(A0, INPUT);
}
void loop() {
int loudness = analogRead(A0);
Serial.print("Loudness: ");
Serial.println(loudness);
delay(50);
}
三、使用 Wio Terminal上的Grove数字端口
本节展示了如何将 Wio Terminal 上的 Grove 端口用作数字端口。您可以使用此功能轻松玩转 Grove 生态系统!
1、RPI 数字引脚
树莓派引脚定义为:
- RPI_D0 -> RPI_D8
2、Grove引脚配置
要使用 Grove 可配置 A/D 端口作为数字端口,只需按以下方式定义:
void setup() {
pinMode(D0, INPUT); //Configure UART TX as Digital port
}
将 Grove I2C 端口用作数字端口
在 Wio Terminal 上,Grove I2C 端口也可以用作数字端口:
void setup() {
pinMode(PIN_WIRE_SCL, INPUT); //Defined SCL of I2C port as Digital Input
现在,将 Grove 传感器连接到物理 Grove 端口!
注意:要了解更多定义的引脚名称变体,请检查原理图和 variant.h 文件
3、示例
在此示例中,使用 Grove 按钮和 Grove LED 进行演示:
#define BUTTON D0 //Button to Grove UART Port
#define LED PIN_WIRE_SCL //LED to Grove I2C Port
void setup() {
Serial.begin(115200);
pinMode(BUTTON, INPUT);
pinMode(LED, OUTPUT);
}
void loop() {
int buttonState = digitalRead(BUTTON);
Serial.print("Button State: ");
Serial.println(buttonState);
if (buttonState == HIGH) {
digitalWrite(LED, HIGH);
}
else {
digitalWrite(LED, LOW);
}
delay(50);
}
4、PWM 输出示例代码(伺服器)
在此示例中,使用 Grove 伺服器来演示 PWM 输出:
#include <Servo.h>
Servo myservo;
int pos = 0;
void setup() {
myservo.attach(D0); //Connect servo to Grove Digital Port
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) {
// in steps of 1 degree
myservo.write(pos);
delay(15);
}
for (pos = 180; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(15);
}
}
注意:要在 Wio Terminal 上使用 Servo 库,请包含适用于 SAMD51 功能的 Adafruit 版本。
5、UART 串行通信
在 Wio Terminal 中的 USB Serial:Serial
扩展的UART接口:Serial1
四、在 Wio Terminal 上使用Grove I2C端口
本节展示了如何在 Wio Terminal 上使用 Grove I2C 端口,你可以简单地使用这个即插即用功能与 Grove 生态系统配合使用!
1、端口配置
要使用 Wio Terminal 上的 Grove I2C 端口,只需将使用 I2C 协议的 Grove 传感器连接到 Wio Terminal 上的物理 I2C 端口即可。
注意:请记得在 Arduino IDE 中包含传感器库。有关如何安装库的更多信息,请参考此链接。
2、示例
在这个例子中,我们使用 Grove LCD 来进行演示。这是从 RGB LCD 库中取出的“HelloWorld”示例。
#include <Wire.h>
#include "rgb_lcd.h"
rgb_lcd lcd;
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;
void setup()
{
// 设置 LCD 的列数和行数
lcd.begin(16, 2);
lcd.setRGB(colorR, colorG, colorB);
// 想LCD打印一条信息
lcd.print("hello, world!");
delay(1000);
}
void loop()
{
// 将光标设置到第1行第0列:
// (注意:第1行是第2行,因为计数从0开始):
lcd.setCursor(0, 1);
// 打印自复位以来的秒数:
lcd.print(millis()/1000);
delay(100);
}
五、在 Wio Terminal 上使用 SPI
本节将演示如何在 Wio Terminal 上使用 SPI(Serial Peripheral Interface,串行外设接口)。你可以使用它来控制其他设备!
1、端口配置
正如你所看到的,物理 SPI 引脚如下:
- MOSI -> GPIO 19
- MISO -> GPIO 21
- SCK -> GPIO 23
- SS -> GPIO 24
2、软件配置
在 Arduino 中,所有的 SPI 引脚都是预定义的,并且你可以按照以下方式访问它们:
- MOSI -> PIN_SPI_MOSI
- MISO -> PIN_SPI_MISO
- SCK -> PIN_SPI_SCK
- SS -> PIN_SPI_SS
六、Grove 端口
本节将介绍如何使用 Wio Terminal 与 Grove 生态系统 配合使用。
借助 Grove,您能够使用更简单的连接方式快速构建原型!
1、Wio Terminal 与 Grove - TDS 传感器
使用 Grove - TDS 传感器 与 Wio Terminal 在折线图上显示实时 TDS 读数
库安装
- 需安装LCD库与Line Charts库
完整代码
将 Grove TDS 传感器连接到 Wio Terminal 的 Grove D/A 引脚,上传代码并检查结果!
#include"seeed_line_chart.h" //include the library
TFT_eSPI tft;
#define max_size 50 //maximum size of data
doubles data; //Initilising a doubles type to store data
TFT_eSprite spr = TFT_eSprite(&tft); // Sprite
#define sensorPin A0 //Analog pin
int sensorValue = 0;
float tdsValue = 0;
float Voltage = 0;
void setup() {
pinMode(sensorPin, INPUT);
tft.begin();
tft.setRotation(3);
spr.createSprite(TFT_HEIGHT,TFT_WIDTH);
}
void loop() {
spr.fillSprite(TFT_WHITE);
sensorValue = analogRead(sensorPin);
Voltage = sensorValue*5/1024.0; //Convert analog reading to Voltage
tdsValue=(133.42*Voltage*Voltage*Voltage - 255.86*Voltage*Voltage + 857.39*Voltage)*0.5; //Convert voltage value to TDS value
if (data.size() == max_size) {
data.pop();//this is used to remove the first read variable
}
data.push(tdsValue); //read variables and store in data
//Settings for the line graph title
auto header = text(0, 0)
.value("TDS Reading")
.align(center)
.valign(vcenter)
.width(tft.width())
.thickness(3);
header.height(header.font_height() * 2);
header.draw(); //Header height is the twice the height of the font
//Settings for the line graph
auto content = line_chart(20, header.height()); //(x,y) where the line graph begins
content
.height(tft.height() - header.height() * 1.5) //actual height of the line chart
.width(tft.width() - content.x() * 2) //actual width of the line chart
.based_on(0.0) //Starting point of y-axis, must be a float
.show_circle(true) //drawing a cirle at each point, default is on.
.value(data) //passing through the data to line graph
.color(TFT_RED) //Setting the color for the line
.draw();
spr.pushSprite(0, 0);
delay(50);
}
2、Wio Terminal 配合 Grove - OLED 显示屏
如果你需要一个第二屏幕与Wio Terminal配合使用,Grove - OLED Display 0.96"将是一个完美的选择。它可以用来显示图形和数据,为Wio Terminal增加更多的交互功能。
库安装
- 在Arduino IDE中从库管理器安装U8g2库。
U8g2初始化
使用u8g2的软件I2C初始化OLED显示屏,并将SCL用作clock,SDA用作Data:
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
使用说明:
- 调用 u8g2.firstPage()。
- 开始一个 do-while 循环。
- 在循环体中:使用常规的绘图命令绘制内容。
- 只要 u8g2.nextPage() 返回 true,就继续循环。
如需更多信息,请访问 u8g2 的相关资源。
完整代码
将 Grove 0.96" OLED 显示屏连接到 Grove I2C 引脚并检查结果!
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
const unsigned char WAVE[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xF0,0x00,0xFF,0x00,0x0F,0xF0,0x00,
0xFC,0x03,0xFF,0xC0,0x3F,0xFC,0x00,
0xFE,0x07,0xFF,0xE0,0x7F,0xFE,0x00,
0x1F,0xFF,0x81,0xFF,0xF8,0x1F,0xC0,
0x0F,0xFF,0x00,0xFF,0xF0,0x0F,0xC0,
0x03,0xFC,0x00,0x3F,0xC0,0x03,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xE0,0x00,0x7E,0x00,0x07,0xE0,0x00,
0xF8,0x01,0xFF,0x80,0x1F,0xF8,0x00,
0xFC,0x03,0xFF,0xC0,0x3F,0xFC,0x00,
0xFF,0x0F,0xFF,0xF0,0xFF,0xFF,0x00,
0x1F,0xFF,0x81,0xFF,0xF8,0x1F,0xC0,
0x07,0xFE,0x00,0x7F,0xE0,0x07,0xC0,
0x01,0xF8,0x00,0x1F,0x80,0x01,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xF0,0x00,0xFF,0x00,0x0F,0xF0,0x00,
0xF8,0x01,0xFF,0x80,0x1F,0xF8,0x00,
0xFE,0x07,0xFF,0xE0,0x7F,0xFE,0x00,
0x3F,0xFF,0xC3,0xFF,0xFC,0x3F,0xC0,
0x0F,0xFF,0x00,0xFF,0xF0,0x0F,0xC0,
0x07,0xFE,0x00,0x7F,0xE0,0x07,0xC0,
0x00,0xF0,0x00,0x0F,0x00,0x00,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x80,0x00,0x18,0x00,0x01,0x80,0x00,
0xF0,0x00,0xFF,0x00,0x0F,0xF0,0x00,
0xFC,0x03,0xFF,0xC0,0x3F,0xFC,0x00,
0xFF,0x0F,0xFF,0xF0,0xFF,0xFF,0x00,
0x1F,0xFF,0x81,0xFF,0xF8,0x1F,0xC0,
0x0F,0xFF,0x00,0xFF,0xF0,0x0F,0xC0,
0x03,0xFC,0x00,0x3F,0xC0,0x03,0xC0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
void setup() {
u8g2.begin();
}
void loop() {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.drawXBMP(40, 0, 50, 50, WAVE);
u8g2.setCursor(20, 60);
u8g2.print("Wio Terminal");
} while (u8g2.nextPage());
}
3、Wio Terminal 与 Grove - 温度传感器
本节将介绍如何使用 Grove - 温度传感器与 Wio Terminal 配合,以显示实时的周围环境温度读数。
库安装
- 需安装LCD库与Line Charts库
完整代码
将 Grove 温度传感器连接到 Wio Terminal 的 Grove D/A 引脚,上传代码并检查结果!
#include"seeed_line_chart.h" //include the library
#include <math.h>
TFT_eSPI tft;
#define max_size 50 //maximum size of data
doubles data; //Initilising a doubles type to store data
TFT_eSprite spr = TFT_eSprite(&tft); // Sprite
const int B = 4275; // B value of the thermistor
const int R0 = 100000; // R0 = 100k
const int pinTempSensor = A0; // Grove - Temperature Sensor connect to A0
void setup() {
pinMode(pinTempSensor, INPUT);
tft.begin();
tft.setRotation(3);
spr.createSprite(TFT_HEIGHT,TFT_WIDTH);
}
void loop() {
spr.fillSprite(TFT_DARKCYAN);
int a = analogRead(pinTempSensor);
float R = 1023.0/a-1.0;
R = R0*R;
float temperature = 1.0/(log(R/R0)/B+1/298.15)-273.15; // convert to temperature via datasheet
if (data.size() == max_size) {
data.pop();//this is used to remove the first read variable
}
data.push(temperature); //read variables and store in data
//Settings for the line graph title
auto header = text(0, 0)
.value("Temperature Reading")
.align(center)
.color(TFT_WHITE)
.valign(vcenter)
.width(tft.width())
.thickness(2);
header.height(header.font_height() * 2);
header.draw(); //Header height is the twice the height of the font
//Settings for the line graph
auto content = line_chart(20, header.height()); //(x,y) where the line graph begins
content
.height(tft.height() - header.height() * 1.5) //actual height of the line chart
.width(tft.width() - content.x() * 2) //actual width of the line chart
.based_on(0.0) //Starting point of y-axis, must be a float
.show_circle(true) //drawing a cirle at each point, default is on.
.y_role_color(TFT_WHITE)
.x_role_color(TFT_WHITE)
.value(data) //passing through the data to line graph
.color(TFT_RED) //Setting the color for the line
.draw();
spr.pushSprite(0, 0);
delay(50);
}
4、Wio Terminal 与 Grove - GPS 传感器
本节将介绍如何使用 Grove - GPS Sensor 与 Wio Terminal 配合,以获取实时的 GPS 信息。GPS 传感器本身输出的是 NMEA 格式的 GPS 数据,我们将使用 TinyGPSPlus 库来解析这些数据,将其转换为可读的信息。
库安装
- 需安装TinyGPSPlus库
完整代码
将 Grove GPS 传感器连接到 Wio Terminal 的 Grove I2C 引脚(左侧),上传代码并在串行监视器(波特率:9600)中检查结果!
#include <TinyGPS++.h>
#include <wiring_private.h>
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device - Left side Grove connector.
// Left side Grove connector shares pins with I2C1 of 40 pin connector.
static Uart Serial3(&sercom3, PIN_WIRE_SCL, PIN_WIRE_SDA, SERCOM_RX_PAD_1, UART_TX_PAD_0);
void setup()
{
Serial.begin(115200);
Serial3.begin(GPSBaud);
pinPeripheral(PIN_WIRE_SCL, PIO_SERCOM_ALT);
pinPeripheral(PIN_WIRE_SCL, PIO_SERCOM_ALT);
}
void loop()
{
// This sketch displays information every time a new sentence is correctly encoded.
while (Serial3.available() > 0)
if (gps.encode(Serial3.read()))
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while(true);
}
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.year());
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
Serial.print(F("."));
if (gps.time.centisecond() < 10) Serial.print(F("0"));
Serial.print(gps.time.centisecond());
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
void SERCOM3_0_Handler()
{
Serial3.IrqHandler();
}
void SERCOM3_1_Handler()
{
Serial3.IrqHandler();
}
void SERCOM3_2_Handler()
{
Serial3.IrqHandler();
}
void SERCOM3_3_Handler()
{
Serial3.IrqHandler();
}