#define ROWS 6
#define COLS 4
//Matrix of output pins
int ledMat[ROWS][COLS] = {
{22, 23, 24, 25},
{26, 27, 28, 29},
{30, 31, 32, 33},
{34, 35, 36, 37},
{38, 39, 40, 41},
{42, 43, 44, 45}
};
//state of pin matrix
bool ledStat[ROWS][COLS];
//position of cursor
int cursorRow = 0; //当前选择LED的光标位置
int cursorCol = 0;
//column that user has choosen
int column;
//pins of pushButtons
const int inputPin = 2; // input按钮引脚
const int zeroPin = 3; // zero按钮引脚
const int jumpPin = 4; // jump按钮引脚
const int stopPin = 5; // jump按钮引脚
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
column = 0;
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
pinMode(ledMat[row][col], OUTPUT);
ledStat[row][col] = 0;
}
}
pinMode(inputPin, INPUT_PULLUP);
pinMode(zeroPin, INPUT_PULLUP);
pinMode(jumpPin, INPUT_PULLUP);
pinMode(stopPin, INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.print("This system is used to fill in positions in a table!\n");
Serial.print("Please select a colum(1~4):\n");
while(Serial.available() == 0) {}
column = Serial.parseInt();
while (Serial.available()) { Serial.read();}//丢掉换行符
Serial.println(column);
cursorRow = 0; // 光标初始在第一行
cursorCol = 0; // 用户输入的列数转换为索引(0-3)
if (column == 0) { //如果输入的是字符char,也将结束循环,因为默认输入的是数字
Serial.println("No table to be filled in, code ending!");
while (true) {} // 结束程序,进入无限循环
}
if (column < 1 || column > 4)
{
Serial.println("Invalid input! Please enter a number between 1 and 4.");
Serial.println("_____________________________________________________");
delay(1000);
return; // 如果输入无效,直接返回,等待下一次输入
}
while(1)
{
updateLEDs(ledStat, cursorRow, cursorCol);
inputPB();
zeroPB();
jumpPB();
stopPB();
Serial.println("Waiting for button press...");
delay(100);
}
}
/*========================================================================*/
void updateLEDs(bool ledStat[ROWS][COLS], int cursorRow, int cursorCol) {
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (row == cursorRow && col == cursorCol) {
// 光标LED闪烁
blink(ledMat[row][col], 100);
} else {
// 根据ledStat状态点亮或熄灭LED
digitalWrite(ledMat[row][col], ledStat[row][col] ? HIGH : LOW);
}
}
}
}
void blink(int led, long seconds)
{
digitalWrite(led, HIGH);
delay(seconds);
digitalWrite(led, LOW);
delay(seconds);
}
void inputPB() {
if (digitalRead(inputPin) == LOW) { // 检测按键是否按下(低电平有效)
delay(50); // 简单去抖动
if (digitalRead(inputPin) == LOW) { // 再次确认按键按下
// 1. 点亮当前光标位置的LED
ledStat[cursorRow][cursorCol] = 1;
// 2. 更新光标位置
if (cursorCol < column - 1) {
// 如果当前列小于用户输入的最大列数,光标移动到下一列
cursorCol++;
} else {
// 如果当前列是用户输入的最大列数,光标移动到下一行的第一列
cursorCol = 0;
cursorRow = (cursorRow + 1) % ROWS; // 如果已经是最后一行,回到第一行
}
Serial.println("Input button pressed: LED turned ON and cursor moved.");
while (digitalRead(inputPin) == LOW) {} // 等待按键释放
}
}
}
void zeroPB() {
if (digitalRead(zeroPin) == LOW) { // 检测按键是否按下(低电平有效)
delay(50); // 简单去抖动
if (digitalRead(zeroPin) == LOW) { // 再次确认按键按下
// 1. 熄灭当前光标位置的LED
ledStat[cursorRow][cursorCol] = 0;
// 2. 更新光标位置
if (cursorCol < column - 1) {
// 如果当前列小于用户输入的最大列数,光标移动到下一列
cursorCol++;
} else {
// 如果当前列是用户输入的最大列数,光标移动到下一行的第一列
cursorCol = 0;
cursorRow = (cursorRow + 1) % ROWS; // 如果已经是最后一行,回到第一行
}
Serial.println("Zero button pressed: LED turned OFF and cursor moved.");
while (digitalRead(zeroPin) == LOW) {} // 等待按键释放
}
}
}
void jumpPB() {
if (digitalRead(jumpPin) == LOW) { // 检测按键是否按下(低电平有效)
delay(50); // 简单去抖动
if (digitalRead(jumpPin) == LOW) { // 再次确认按键按下
// 更新光标位置到下一列的第一行
cursorCol = 0; // 移动到下一列,如果已经是最后一列,回到第一列
cursorRow = (cursorRow + 1) % ROWS; // 回到第一行
Serial.println("Jump button pressed: Cursor moved to next column.");
while (digitalRead(jumpPin) == LOW) {} // 等待按键释放
}
}
}
void stopPB() {
if (digitalRead(stopPin) == LOW) {
delay(50); // 简单去抖动
if (digitalRead(stopPin) == LOW) { // 确保按键真的被按下
Serial.println("Program stopped!");
delay(100); // 让消息有足够时间发送
cli(); // 关闭所有中断(彻底停住 Arduino)
while (true) {} // 进入死循环,程序完全停止
}
}
}