回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

选择困难症解决器 简单

头像 猪宅 2020.05.19 1834 0

你是否还在为中午吃什么晚上吃什么而苦恼? ⊙﹏⊙

是时候做一个随机数生成装置来解救选择困难星人!~( ̄0 ̄)/

材料清单

  • DFRduino UNO R3 X1 链接
  • IO 传感器扩展板 V7.1 X1 链接
  • 数字大按钮模块 黄色 X1 链接
  • Shiftout LED Kit(Arduino兼容) X1 链接
  • 数字蜂鸣器模块(Arduino兼容) X1 链接

步骤1 一切的开始 v1.0

简单的1.0版本我们先拿官方的教程来用一下。


详细教程参见:

Arduino教程中级 项目十三 数字骰子

https://mc.dfrobot.com.cn/thread-13581-1-1.html

project-image
代码
int latchPin = 8;  //数字口8连接到74HC595芯片的使能引脚
int clockPin = 3;  //数字口3连接到74HC595芯片的时钟引脚
int dataPin = 9;   //数字口9连接到74HC595芯片的数据引脚
int buttonPin = 2; // 按钮连接到数字口2
//代表数字0~9
byte Tab[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int number;
long randNumber;
void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  randomSeed(analogRead(0));   //设置一个随机数产生源模拟口0
}
void loop(){
    randNumber = random(10);   //产生0~9之间的随机数
showNumber(randNumber);    //显示该随机数
//一旦有按键按下,显示该数,并保持到松开为止
    while(digitalRead(buttonPin) == HIGH){  
       delay(100);
    }
}
//该函数用于数码管显示
void showNumber(intnumber){
     digitalWrite(latchPin, LOW);
     shiftOut(dataPin, clockPin, MSBFIRST,Tab[number]);
     digitalWrite(latchPin, HIGH);
     delay(80);
} 

试过的童鞋都知道,以上代码有个问题就是需要手一直按着;

为了贯彻懒癌晚期的方针,那么,有没有只按一下的方案?

project-image




步骤2 能不能更好点!v2.0

首先我们回忆一下那里可以用按钮的点按来控制设备呢?

没错,就是做小台灯的那一部分!


参考:

Arduino教程中级 项目三 Mini台灯

https://mc.dfrobot.com.cn/thread-12814-1-1.html

在上面的例子里我们用到了一部分按键控制的代码:

代码
//reading用来存储buttonPin的数据
  int reading = digitalRead(buttonPin);
  
  // 一旦检测到数据发生变化,记录当前时间
  if (reading != lastButtonState) {
      lastDebounceTime= millis();
  }
  
  // 等待50ms,再进行一次判断,是否和当前button状态相同
// 如果和当前状态不相同,改变button状态
// 同时,如果button状态为高(也就是被按下),那么就改变led的状态
  if ((millis() - lastDebounceTime) >debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
      if (buttonState == HIGH) {
          ledState= !ledState;
      }
    }

首先增加一些变量:

int buttonState; // buttonState记录按键状态

int lastButtonState = LOW; // lastbuttonState记录按键前一个状态

long lastDebounceTime = 0;

long debounceDelay = 50; //去除抖动时间


我们可以把控制灯开关的部分换成控制数字暂停


if (buttonState == HIGH) { ledState= !ledState; }

换成

if(buttonState == HIGH){ showNumber(randNumber); delay(3000); }

//暂停间隔3000ms,即3s


得到以下代码

代码
//选择困难症解决器 v2.0

int latchPin = 8;  //数字口8连接到74HC595芯片的使能引脚
int clockPin = 3;  //数字口3连接到74HC595芯片的时钟引脚
int dataPin = 9;   //数字口9连接到74HC595芯片的数据引脚
int buttonPin = 2; // 按钮连接到数字口2

int buttonState;                 // buttonState记录按键状态
int lastButtonState = LOW;       // lastbuttonState记录按键前一个状态
long lastDebounceTime = 0;
long debounceDelay = 50;         //去除抖动时间

//代表数字0~9
byte Tab[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int number;
long randNumber;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  randomSeed(analogRead(0));   //设置一个随机数产生源模拟口0
}

void loop(){
  randNumber = random(10);   //产生0~9之间的随机数
  showNumber(randNumber);    //显示该随机数
    
 //reading用来存储buttonPin的数据
  int reading = digitalRead(buttonPin);
  
 // 一旦检测到数据发生变化,记录当前时间
  if (reading != lastButtonState) {
      lastDebounceTime= millis();
  }
  
// 等待50ms,再进行一次判断,是否和当前button状态相同
// 如果和当前状态不相同,改变button状态
// 同时,如果button状态为高(也就是被按下),那么就改变led的状态
  if ((millis() - lastDebounceTime) >debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
     if(buttonState == HIGH){  
      showNumber(randNumber);    //显示该随机数
       delay(3000);
      }
    }
  }
  
  lastButtonState = reading; // 改变button前一个状态值
       
}
//该函数用于数码管显示
void showNumber(int number){
     digitalWrite(latchPin, LOW);
     shiftOut(dataPin, clockPin, MSBFIRST,Tab[number]);
     digitalWrite(latchPin, HIGH);
     delay(80);
}

大概效果如下

然后,怎么感觉有点单调呢?

project-image

是的没有错,一直按手都麻了,能不能来点“高雅的”音乐?

首先我们在数字6上加上一个蜂鸣器模块让他能发声

project-image

需要增加一些变量

float sinVal;

int toneVal;

int buzzerPin = 6 ;


音乐的代码:

//声调1

for(int i=0; i

代码
//选择困难症解决器 v2.1
int latchPin = 8;  //数字口8连接到74HC595芯片的使能引脚
int clockPin = 3;  //数字口3连接到74HC595芯片的时钟引脚
int dataPin = 9;   //数字口9连接到74HC595芯片的数据引脚
int buttonPin = 2; // 按钮连接到数字口2

int buttonState;                 // buttonState记录按键状态
int lastButtonState = LOW;     // lastbuttonState记录按键前一个状态
long lastDebounceTime = 0;
long debounceDelay = 50;        //去除抖动时间

//代表数字0~9
byte Tab[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int number;
long randNumber;

//蜂鸣器的变量
float sinVal;            
int toneVal;  
int buzzerPin = 6 ;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  randomSeed(analogRead(0));   //设置一个随机数产生源模拟口0
  pinMode(buzzerPin, OUTPUT);  // 蜂鸣器引脚设置
  Serial.begin(9600);        //设置波特率为9600 bps
}
void loop(){
  randNumber = random(10);   //产生0~9之间的随机数
  showNumber(randNumber);    //显示该随机数   
 
 //reading用来存储buttonPin的数据
  int reading = digitalRead(buttonPin);
  
 // 一旦检测到数据发生变化,记录当前时间
  if (reading != lastButtonState) {
      lastDebounceTime= millis();
  }
  
// 等待50ms,再进行一次判断,是否和当前button状态相同
// 如果和当前状态不相同,改变button状态
// 同时,如果button状态为高(也就是被按下),那么就改变led的状态
  if ((millis() - lastDebounceTime) >debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
     if(buttonState == HIGH){  
      showNumber(randNumber);    //显示该随机数
      
            //声调1
               
            toneVal = 661 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(200);
            toneVal = 742 ;  
            tone(buzzerPin, toneVal);
            delay(50);
            toneVal = 1665 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(100);
            
            
       /*声调2
        for(int i=0; i<2; i++){         
            toneVal = 0 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(10);
            toneVal = 833 ;  
            tone(buzzerPin, toneVal);
            delay(10);
            }  */
      
      noTone(buzzerPin); //关闭蜂鸣器
      delay(3000);
      }
    }
  }
  

  lastButtonState = reading; // 改变button前一个状态值
    
}

//该函数用于数码管显示
void showNumber(int number){
     digitalWrite(latchPin, LOW);
     shiftOut(dataPin, clockPin, MSBFIRST,Tab[number]);
     digitalWrite(latchPin, HIGH);
     delay(80);
}

这样一来,每次按下按钮就会有美妙的声音了,美滋滋~~



步骤3 终极方案

用了一段时间之后感觉每次按一下得到一个数字总要等几秒总,要么太快没看清数字,要么太慢等的人心烦;

能不能按键可以控制暂停与继续呢?


本来想从最里面的一个if{}的嵌套入手,百思不得其解,最后总管大局发现放一个逻辑选择的分支不就行了!

首先引入一个布尔变量changekey 他的值可以是true or false ;

true就执行random部分,false就执行暂停showNumber的部分;

最后按键的动作负责控制changekey的值是true or false;

顺便把按键的音调对换一下有个区别;


当当当~~最后的代码如下:

代码
//选择困难症解决器 v.3.0
int latchPin = 8;  //数字口8连接到74HC595芯片的使能引脚
int clockPin = 3;  //数字口3连接到74HC595芯片的时钟引脚
int dataPin = 9;   //数字口9连接到74HC595芯片的数据引脚
int buttonPin = 2; // 按钮连接到数字口2

int buttonState;                 // buttonState记录按键状态
int lastButtonState = LOW;     // lastbuttonState记录按键前一个状态
long lastDebounceTime = 0;
long debounceDelay = 50;        //去除抖动时间
bool changekey = true ;        //暂停与继续

//代表数字0~9
byte Tab[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int number;
long randNumber;

float sinVal;            
int toneVal;  
int buzzerPin = 6 ;
void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);
  randomSeed(analogRead(0));   //设置一个随机数产生源模拟口0
  pinMode(buzzerPin, OUTPUT);  // 蜂鸣器引脚设置
  Serial.begin(9600);        //设置波特率为9600 bps
}
void loop(){
int reading = digitalRead(buttonPin);//reading用来存储buttonPin的数据

if (changekey == true) {
  
  randNumber = random(10);   //产生0~9之间的随机数
  showNumber(randNumber);    //显示该随机数   
   
    if (reading != lastButtonState) {
      lastDebounceTime= millis();      // 一旦检测到数据发生变化,记录当前时间
  }
  
// 等待50ms,再进行一次判断,是否和当前button状态相同
// 如果和当前状态不相同,改变button状态
// 同时,如果button状态为高(也就是被按下),那么就改变led的状态
  if ((millis() - lastDebounceTime) >debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
     if(buttonState == HIGH){  
      
      changekey = !changekey ;
            //声调1                
            toneVal = 661 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(200);
            toneVal = 742 ;  
            tone(buzzerPin, toneVal);
            delay(50);
            toneVal = 1665 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(100);
            
      noTone(buzzerPin); //关闭蜂鸣器
      
    }
    }
  }
  lastButtonState = reading;
}

else{
  
     showNumber(randNumber);    //显示该随机数 
       
   //判断按钮状态
    if (reading != lastButtonState) {
      lastDebounceTime= millis();      // 一旦检测到数据发生变化,记录当前时间
  }

  if ((millis() - lastDebounceTime) >debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;
     if(buttonState == HIGH){  
      
      changekey = !changekey ;
            //声调2         
            toneVal = 1665 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(100);
            toneVal = 742 ;  
            tone(buzzerPin, toneVal);
            delay(50);
            toneVal = 661 ;   
            tone(buzzerPin, toneVal);//给蜂鸣器引脚一个声音
            delay(200);
            
      noTone(buzzerPin); //关闭蜂鸣器
        }
     }
  }
  lastButtonState = reading;
  
  }
      
    
    }

//该函数用于数码管显示
void showNumber(int number){
     digitalWrite(latchPin, LOW);
     shiftOut(dataPin, clockPin, MSBFIRST,Tab[number]);
     digitalWrite(latchPin, HIGH);
     delay(80);
}

试下效果


接下啦就可以完美地决定今天吃什么啦!╰(*°▽°*)╯

评论

user-avatar