极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 41479|回复: 15

幼浅问题请教,怎么修改成:按键点亮LED,再按键关闭LED

[复制链接]
发表于 2015-4-12 14:10:55 | 显示全部楼层 |阅读模式
本人刚开始学习Arduino,照着一些例子做没难度,但稍微修改一下就遇到问题了,可能比较肤浅,还望诸位能给予指教!
这段代码是《Arduino开发实战指南》书中的一段,我想改成按下键一次点亮LED,再按下键一次关闭LED。

在digitalWrite(13,LOW);上加入:

if(KeySum=2);
              {
              digitalWrite(13,LOW);
                KeySum = 0;
              }

但这样行不通,是什么原因?

另外while(1)怎么理解?(1)的意思书中都没有说明,是代表真吗?就是不用计算判断,必须进入下面的循环语句吗?

delay(50);这样判断按键的闭合与断开的抖动是否就可以了?还是有更好的方法?



《Arduino开发实战指南》书中的一段代码
------------------------------------------------

/*
数字I/O口实验
按键2,按键按下时,13脚LED点亮,同时向串口发送合计按键次数
当松开按键时,LED熄灭。
*/

//记录按键次数
int KeySum = 0;

void setup()
{
    Serial.begin(9600);
    pinMode(13,OUTPUT);
    pinMode(2,INPUT_PULLUP);
}

void loop()
{
    if(LOW==digitalRead(2))
    {
        delay(50);
        if(LOW==digitalRead(2))
        {
            digitalWrite(13,HIGH);
            KeySum++;
            Serial.print(KeySum,DEC);    //DEC:十进制,以ASCII文本打印到串口输出
            while(1)
            {
                if(HIGH==digitalRead(2))
                    {
                        delay(50);
                        if(HIGH==digitalRead(2))
                        break;        //break用于退出while循环
                    }
            }
                digitalWrite(13,LOW);
        }
    }
}
   
               




回复

使用道具 举报

发表于 2015-4-12 15:11:42 | 显示全部楼层
你应该好好学学C语言的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-12 17:08:43 | 显示全部楼层
本帖最后由 阿瑞 于 2015-4-12 17:21 编辑
彩色大冰棍丶 发表于 2015-4-12 15:11
你应该好好学学C语言的


学习C语言没错,本人也曾经用VB写过一些小程序,但却没有今Arduino困扰我。
请给予具体指教,或推荐哪本书曾讨论这三个相近问题,由衷感激!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-12 17:29:53 | 显示全部楼层
while(1)代表无限次重复执行while语句的循环,在网上查到了,不过很奇怪,在C语言书上并没有提到,本站的Arduino语法手册也没有相对应的说法。
回复 支持 反对

使用道具 举报

发表于 2015-4-12 19:16:52 | 显示全部楼层



(1)你的问题在没有做”去抖动处理”
  "delay(50);这样判断按键的闭合与断开的抖动.."
  Yes !
这是最简单方法!

  更好的方法请自己在本论坛搜寻 “去抖”, 或用百度搜寻 “Arduino 去抖”

(2)Arduino 用 C/C++ 混和,
所有 C/C++ 语法 99.99% 都可以用,
while(38) {
//..
}
表示这 Loop 永不停止, 只要 while ( 不是 0 ) { } 都是
这与以下相同:
for( ;; ) {
//..
}
永不停止那不是无法停止啰 ?
错 ! 因你可以这样:
while(38) {
//..
  if(吃饱了 || 很不爽) break;   // || 表示 or (或者)
}
// Loop 内的  break 会跳到这
同样用 for Loop 也是:
for( ;; ) {
//..
if(吃饱了 || 很不爽) break;   // || 表示 or (或者)
}
// Loop 内的  break 会跳到这

回复 支持 反对

使用道具 举报

发表于 2015-4-12 19:24:23 | 显示全部楼层

如果要用硬件处理去抖动,
可以用电容, 如下图
参考


http://www.ganssle.com/debouncing-pt2.htm

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2015-4-12 19:41:08 | 显示全部楼层
Try this:




  1. // Toggle Switch 压放式开关 – by [email][email protected][/email]
  2. // 开关接 Pin 8, LED 灯接 Pin 9
  3. int sPin = 8;  // 只可以读取 0 LOW  or 1 HIGH
  4. int ledPin = 9;   //  改 13 即为内建的黄灯
  5. int sVal = 0; // 读取传感器得到的值 sensorValue
  6. int oldVal;
  7. int bounce = 168;   // 去抖动, 间隔时间大约 0.168 秒; 自己调整 !
  8. long prevTime = 0; // previous time we read
  9. int light = LOW; // 关灯 light = 0;
  10. void setup() {
  11.    pinMode(sPin, INPUT); // 读取开关
  12.    pinMode(ledPin, OUTPUT);
  13.    pinMode(13, OUTPUT); digitalWrite(13, 0);  // 关掉 pin 13的 LED
  14.    digitalWrite(ledPin, light); // 关掉  LED
  15.    Serial.begin(9600);
  16.    oldVal = digitalRead(sPin);  // 0 ~ 1
  17.    prevTime = millis( );  // 读取执行到现在的时间
  18. }
  19. void onOff( ); // toggle 开关灯; 先宣告等下再写内容
  20. void loop( ) {
  21.    sVal = digitalRead(sPin);  // 0 ~ 1
  22.    if(sVal == oldVal) return;
  23.    if(millis( ) - prevTime < bounce) return;
  24.    oldVal = sVal;
  25.    if(sVal)  {  // 不是 0 LOW
  26.       onOff( );  
  27.       prevTime = millis( );
  28.    }
  29.    delay(18); // up to you :-)
  30.    Serial.println(sVal);
  31. }
  32. void onOff( ) {
  33.    light = ! light;  // 或 light = 1 - light;
  34.    digitalWrite(ledPin, light); // 开或关
  35. }
复制代码



回复 支持 反对

使用道具 举报

发表于 2015-4-12 20:44:17 | 显示全部楼层
还去了解一下单片机键盘的思路吧
回复 支持 反对

使用道具 举报

发表于 2015-4-12 22:40:21 | 显示全部楼层
使用Bounce2可以去抖动
https://github.com/thomasfredericks/Bounce2
回复 支持 反对

使用道具 举报

发表于 2015-4-12 23:02:52 | 显示全部楼层
以下代码,每运行一次loop,就会切换led的输出。把loop更换成按键触发,将会形成按键一下点亮LED,再按键按一下关闭LED了。
  1. int led = 13;
  2. int state = 0;
  3. void setup() {
  4.     pinMode(led, OUTPUT);
  5. }
  6. void loop() {
  7.     digitalWrite(led, (state) ? HIGH : LOW);
  8.     state = !state;
  9.     delay(1000);
  10. }
复制代码

.
回复 支持 反对

使用道具 举报

发表于 2015-4-13 16:53:21 来自手机 | 显示全部楼层
本帖最后由 ofourme 于 2015-4-13 18:17 编辑

if(KeySum=2);               {               digitalWrite(13,LOW);                 KeySum = 0;               }

改为:

if(KeySum&1)
{
    digitalWrite(13,LOW);
}
else
{
    digitalWrite(13,1);
}
回复 支持 反对

使用道具 举报

发表于 2015-4-13 16:58:46 | 显示全部楼层
attachInterrupt(pbIn,stateChange,FALLING);

可以用中断
回复 支持 反对

使用道具 举报

发表于 2015-4-13 18:58:38 | 显示全部楼层
公孙林 发表于 2015-4-13 16:58
attachInterrupt(pbIn,stateChange,FALLING);

可以用中断


attachInterrupt( ) 并没有解决按钮抖动的问题喔 !
回复 支持 反对

使用道具 举报

发表于 2015-4-15 10:03:18 | 显示全部楼层
阿瑞 发表于 2015-4-12 17:29
while(1)代表无限次重复执行while语句的循环,在网上查到了,不过很奇怪,在C语言书上并没有提到,本站的Ar ...

1表示真   while(1)表示   循环条件一直为真,则会一直执行
回复 支持 反对

使用道具 举报

发表于 2015-4-15 10:13:15 | 显示全部楼层
tsaiwn 发表于 2015-4-12 19:24
如果要用硬件处理去抖动,
可以用电容, 如下图
参考

这个办法好啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-28 23:02 , Processed in 0.055962 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表