#include <U8g2lib.h>
#include <Wire.h>
// U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //1.3寸的OLED屏幕。
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //0.96寸的OLED显示器的驱动
const int BUTTON_UP_PIN = 12; // 设置“向上”按钮的输入引脚
const int BUTTON_DOWN_PIN = 13; // 设置“向下”按钮的输入引脚
const int delayTime = 50; // 定义滑动速度,数值越小速度越快
int numY = 6; // 数字初始y坐标
int startNum1 = 1; // 显示的第一个数字为1
char str[3]; //用于将数值转为字符串
int numSpacing = 14; //数字间距
void setup() {
u8g2.begin();
pinMode(BUTTON_UP_PIN, INPUT_PULLUP);//设置“向上”按钮为输入上拉模式
pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);//设置“向下”按钮为输入上拉模式
showNum(); //显示内容初始化
}
//滚动数字(x坐标,y坐标,y方向数字间隔距离,剪裁窗口起始Y坐标,剪裁窗口结束Y坐标,字体)
void rollNum(int x, int y, int windowY0, int windowY1, const uint8_t *font)
{
u8g2.setFont(font); // 设置字体大小
u8g2.setClipWindow(x - 5, windowY0, 43, windowY1); //设置剪裁窗口大小
for (int i = 0; i < 5; i++) { // 显示5个数字
int num = startNum1 + i;
if (num > 59) { // 循环显示,末尾数字和开头数字相连
num -= 60;
}
sprintf(str, "%02d", num); //将数字转为2位字符数组
u8g2.drawStr(x, y + i * numSpacing, str); // 在指定的位置绘制字符串
}
u8g2.setClipWindow(0, 0, 128, 64); // 恢复剪裁窗口为整个屏幕
}
//数字循环滚动(y坐标地址,数字间距)
void numLoop(int &y)
{ if (digitalRead(BUTTON_UP_PIN) == LOW) { //如果按下向上按钮,数字向上滚动
for (int j = 0; j < 7; j++) {
y -= 2; // y坐标每次移动的像素数,决定数字移动的速度
if (y <= 5) { // 如果数字滚动到屏幕最上面,重置显示的第一个数字和y坐标值
startNum1++;
if (startNum1 > 59) { // 显示的最大数字为59,重置数字让末尾数字和开头数字相连
startNum1 = 0;
}
y = 5 + numSpacing; //重置Y坐标,加上数字间距在数字重置时让滑动效果顺滑,不会有顿挫感
}
showNum();
delay(delayTime); // 滑动速度延时
}
} else if (digitalRead(BUTTON_DOWN_PIN) == LOW) { //如果按下向上按钮,数字向上滚动
for (int k = 0; k < 7; k++) {
y += 2; //向下移动
if (y >= 9) { // Y坐标向下移动到合适的位置后,重置显示的第一个数字和y坐标值
startNum1--;
if (startNum1 < 0) { // 显示的最小数为0,重置数字让末尾数字和开头数字相连
startNum1 = 59;
}
y = 10 - numSpacing; //重置Y坐标,加上数字间距在数字重置时让滑动效果顺滑,不会有顿挫感
}
showNum();
delay(delayTime); // 滑动速度延时
}
}
}
//显示数字
void showNum(void) {
u8g2.clearBuffer(); // 清空缓存
rollNum(22, numY, 10, 54, u8g2_font_ncenB08_tf); //字体较小
rollNum(20, numY, 22, 36, u8g2_font_ncenB10_tf); //中间字体较大,起到放大效果
u8g2.drawFrame(12, 22, 32, 16); //绘制空心方形
u8g2.sendBuffer(); // 发送缓存
}
void loop() {
numLoop(numY);
}