掷骰子是常见的娱乐项目。今天让给我们一起用Beetle RP2350来掷骰子。

硬件介绍
1、Beetle RP2350 开发板
Beetle RP2350 是一款基于RP2350芯片设计的高性能迷你体积的开发板,有2路ADC,分别是A0对应IO26,A1对应IO27。
2、0.96 OLED屏

0.96寸OLED显示模块采用SSD1306驱动芯片,有128x64个自发光的白色像素点,采用I2C通信。
连接电路

程序编写
1、 安装Beetle RP2350 开发板
步骤 1:添加开发板管理器网址
打开 Arduino IDE 后,点击菜单栏中的 文件 -> 首选项。
在弹出的 首选项 窗口中,找到 附加开发板管理器网址 输入框。
输入 Beetle RP2350 开发板的支持包链接。通常可以在开发板的官方文档或者社区中找到对应的链接。对于 RP2350 开发板,一般使用的链接是 https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json。
点击 确定 保存设置。

步骤 2:安装 Beetle RP2350 开发板支持
点击菜单栏中的 工具 -> 开发板 -> 开发板管理器,在开发板管理器窗口中,等待索引更新完成。
在搜索框中输入 RP2350。
在搜索结果中找到 Raspberry Pi Pico/RP2040/RP2350 并点击 安装 按钮。

等待安装过程完成,这可能需要一些时间,具体取决于你的网络速度。
步骤 3:选择 Generic RP2350 开发板
安装完成后,点击菜单栏中的 工具 -> 开发板,在开发板列表中选择 Generic RP2350。

步骤 4:选择端口
将 Beetle RP2350 开发板通过 USB 线连接到计算机。点击菜单栏中的 工具 -> 端口,选择与开发板对应的端口。
完成以上步骤后,你就可以在 Arduino IDE 中使用 Beetle RP2350 开发板进行编程和开发了。你可以编写代码并上传到开发板上运行。
2、安装U8g2库
在库管理器的搜索框中输入 U8g2,然后在搜索结果中找到对应的库。点击 安装 按钮,等待安装完成。

主要程序代码及说明
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(
U8G2_R0,
U8X8_PIN_NONE,
5, // SCL-D5
4 // SDA-D4
);
enum DiceState {INIT, ROLLING, RESULT};
DiceState state = INIT;
unsigned long startTime = 0;
int diceValue = 0;
const int ROLL_TIME = 1500; // 滚动持续时间(ms)
const int SHOW_TIME = 3000; // 结果显示时间(ms)
void setup() {
Serial.begin(9600);
u8g2.begin();
randomSeed(analogRead(26));
}
void loop() {
switch(state) {
case INIT:
state = ROLLING;
startTime = millis();
break;
case ROLLING:
if(millis() - startTime < ROLL_TIME) {
diceValue = random(1, 7);
} else {
state = RESULT;
startTime = millis();
}
break;
case RESULT:
if(millis() - startTime > SHOW_TIME) {
// state = INIT; // 如需多次运行,可取消注释此行
}
break;
}
updateDisplay();
delay(50); // 降低刷新率
}
void updateDisplay() {
u8g2.clearBuffer();
// 绘制骰子边框
const int SIZE = 50; // 骰子尺寸
const int X = (128 - SIZE) / 2;
const int Y = (64 - SIZE) / 2;
u8g2.drawFrame(X, Y, SIZE, SIZE);
u8g2.drawFrame(X+1, Y+1, SIZE-2, SIZE-2);
// 绘制点数
if(state == RESULT) {
drawDots(diceValue, X, Y, SIZE);
u8g2.setFont(u8g2_font_10x20_tf);
u8g2.setCursor(59, 60);
// u8g2.print(diceValue);
} else {
drawDots(random(1, 7), X, Y, SIZE);
}
u8g2.sendBuffer();
}
void drawDots(int value, int x, int y, int size) {
const int PAD = size / 5; // 内边距
const int DOT = size / 6; // 点直径
const int SPACE = (size - 2*PAD - DOT) / 2; // 点间距
// 清空内部区域
u8g2.setDrawColor(0);
u8g2.drawBox(x+2, y+2, size-4, size-4);
u8g2.setDrawColor(1);
// 计算中心点偏移量
int cx = x + size/2;
int cy = y + size/2;
// 绘制各点数
switch(value) {
case 1:
drawDot(cx, cy, DOT);
break;
case 2:
drawDot(cx - SPACE, cy - SPACE, DOT);
drawDot(cx + SPACE, cy + SPACE, DOT);
break;
case 3:
drawDot(cx - SPACE, cy - SPACE, DOT);
drawDot(cx, cy, DOT);
drawDot(cx + SPACE, cy + SPACE, DOT);
break;
case 4:
drawDot(cx - SPACE, cy - SPACE, DOT);
drawDot(cx + SPACE, cy - SPACE, DOT);
drawDot(cx - SPACE, cy + SPACE, DOT);
drawDot(cx + SPACE, cy + SPACE, DOT);
break;
case 5:
drawDot(cx - SPACE, cy - SPACE, DOT);
drawDot(cx + SPACE, cy - SPACE, DOT);
drawDot(cx, cy, DOT);
drawDot(cx - SPACE, cy + SPACE, DOT);
drawDot(cx + SPACE, cy + SPACE, DOT);
break;
case 6:
drawDot(cx - SPACE, cy - SPACE, DOT);
drawDot(cx + SPACE, cy - SPACE, DOT);
drawDot(cx - SPACE, cy, DOT);
drawDot(cx + SPACE, cy, DOT);
drawDot(cx - SPACE, cy + SPACE, DOT);
drawDot(cx + SPACE, cy + SPACE, DOT);
break;
}
}
void drawDot(int x, int y, int size) {
u8g2.drawCircle(x, y, size/2, U8G2_DRAW_ALL);
}
评论