极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: 奶妃

【关于内部中断】求教如何在loop中控制LED亮5s后灭掉

[复制链接]
 楼主| 发表于 2015-4-15 22:45:20 | 显示全部楼层
Super169 发表于 2015-4-15 09:17
你有認真看我的回覆嗎?

http://www.geek-workshop.com/forum.php?mod=redirect&goto=findpost&ptid= ...

我又回头仔细琢磨了一下您教我的方法,又换了个写法。
但是还是不行,millis() - t71的输出不是0就是1;是我还没有理解您的意思么?可以请求指出我的错误么?

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-15 22:54:29 | 显示全部楼层
i7456 发表于 2015-4-15 22:44
if(flag == 0)
sorry,应该是这样

啊啊啊啊。照着改了”==“以后就出现了跟别的地方一样的问题
就是t72 = millis() - t71的输出不是0就是1,根本达不到5000!不知道是不是 millis()赋值问题呢?
我试着将其中的t71赋值改成这样:t71 == millis(),但是后果就是t71输出为0

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

发表于 2015-4-16 00:19:01 | 显示全部楼层
奶妃 发表于 2015-4-15 22:54
啊啊啊啊。照着改了”==“以后就出现了跟别的地方一样的问题
就是t72 = millis() - t71的输出不是0就是1 ...

if(flag == 0){
    t71 = millis();
    flag = 1;
  }
按12楼修改后的来,你自己不要乱改
回复 支持 反对

使用道具 举报

发表于 2015-4-16 01:16:29 | 显示全部楼层
奶妃 发表于 2015-4-15 22:54
啊啊啊啊。照着改了”==“以后就出现了跟别的地方一样的问题
就是t72 = millis() - t71的输出不是0就是1 ...

你知道 = 跟 == 的分別嗎?

先把基本的弄清楚, 否則, 就是做出來了也不會知道是什麼原因.

我不太肯定你 b 的意思, 如果在任何情況下, 5s 後都要關掉的話, 檢測 flag 的句子就不要放到 if 之內, 直接放 loop 之內就好了.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-16 10:05:54 | 显示全部楼层
i7456 发表于 2015-4-16 00:19
if(flag == 0){
    t71 = millis();
    flag = 1;

0 0我照着你说的改了~然后改了之后发现t71的值还是在不停改变,最后发现只要将你写的代码最后一句flag = 0去掉~就可以了!我想应该是因为flag = 0之后这段程序又循环回去给t71重新赋值了~
>.<哇真是解决了我好几天的问题~真的很感谢!!非常!非常!感谢你!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-16 10:07:38 | 显示全部楼层
Super169 发表于 2015-4-16 01:16
你知道 = 跟 == 的分別嗎?

先把基本的弄清楚, 否則, 就是做出來了也不會知道是什麼原因.

非常非常感谢您一直的帮助!我的问题解决了QUQ!!= 跟 ==我是大概知道的,但是因为没有系统学过所以知道的略糊。最后还是非常感谢!
回复 支持 反对

使用道具 举报

发表于 2015-4-16 10:47:48 | 显示全部楼层
奶妃 发表于 2015-4-16 10:05
0 0我照着你说的改了~然后改了之后发现t71的值还是在不停改变,最后发现只要将你写的代码最后一句flag =  ...

由於沒有完整的程式, 很難推斷你是那裡出了問題, flag = 0 的設定是有需要的.
flag 的值應該是用來代表燈的狀元, 亮的時間就設定為1, 關掉就要即時設為 0.
問題是在於你檢測狀況, 以及為設定 的時機.  先想清楚流程, 什麼時間設定, 什麼時候開/關.

不過, 由於我不太肯定 b 的作用, 在 #12 中,  line 12-16 (即t72 開始的一部份), 如果跟 b 無關的話, 應該放在 if (b==1) 之外會比較好.
回复 支持 反对

使用道具 举报

发表于 2015-4-16 10:51:42 | 显示全部楼层
奶妃 发表于 2015-4-16 10:07
非常非常感谢您一直的帮助!我的问题解决了QUQ!!= 跟 ==我是大概知道的,但是因为没有系统学过所以知道 ...

解決問題不是重點, 了解問題的原因才是最重要.

依你 #20 所說, 你的流程應該是有問題的.
雖然現在很少人會去畫 flowchart, 但把簡單的流程畫出來, 會有助思考問題的.
回复 支持 反对

使用道具 举报

发表于 2015-4-16 13:17:35 | 显示全部楼层
同意 Super169 的观点,遇到不会的问题,想要在论坛上得到帮助,最重要的是把你的问题、需求表述清楚。用文字表达,经常是不能完全描述清楚、或者有歧义的。
如果能把需求用flowchart描述清楚,写程序的思路也就有了,一般自己也就知道问题怎么解决。所以不要着急写代码,先要想明白自己想实现什么,再把目标分解,逐步的实现。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-4-18 11:03:33 | 显示全部楼层
i7456 发表于 2015-4-16 13:17
同意 Super169 的观点,遇到不会的问题,想要在论坛上得到帮助,最重要的是把你的问题、需求表述清楚。用文 ...

感谢前辈们的指导,我下次写程序前一定先想好问题>.<。
(这次写程序只做了自己会的简单的流程图)
回复 支持 反对

使用道具 举报

发表于 2015-4-18 12:39:22 | 显示全部楼层
本帖最后由 tsaiwn 于 2015-4-18 12:50 编辑
奶妃 发表于 2015-4-18 11:03
感谢前辈们的指导,我下次写程序前一定先想好问题>.



你看看这样写法是不是就不需要画 flowchart 流程图  ?
只要一直往下看,
先假设函数有照宣称的功能做事, 需要时再去看看或检查函数内容
记住一个原则: 尽量把事情写成函数, 每个函数尽量少于 35行甚至30行 !
  1. /// 每个函数尽量不要超过 35 行, 这意人比较容易看懂
  2. // 用以下  lightTime = 5000; 表示 5 秒方便修改
  3. const int lightTime = 5000; // 5 秒亮灯时间 for LED 7
  4. const int T2 = 6;
  5. const int E2 = 7;
  6. float distance2;
  7. int led1 = 4;
  8. int led2 = 8;
  9. int led6 = 9;
  10. int led7 = 10;
  11. int b = 0;   // 1 表示距离在 [8, 15] cm 内
  12. unsigned long t71;
  13. unsigned long t72;  // 这其实没用到
  14. int flag = 0; // 0 表示还没亮; 1 表示亮灯中, 3 表示已经亮过且又灭了
  15. ///
  16. void setup()
  17. {
  18. //超声波测距模块2
  19. //初始化串口通信及连接SR04的引脚
  20.         Serial.begin(9600);
  21.         pinMode(T2, OUTPUT);
  22. //设置输入状态
  23.         pinMode(E2, INPUT);
  24.         pinMode(led2,OUTPUT);
  25.         pinMode(led6,OUTPUT);
  26.         pinMode(led7,OUTPUT);
  27.         digitalWrite(led2,LOW);
  28.         digitalWrite(led6,LOW);
  29.         digitalWrite(led7,LOW);
  30. } // setup(

  31. void loop()
  32. {
  33.   //超声波测距模块2, 取得距离 distance2
  34.    distance2 = getDist(T2, E2);   // trigger pin 是 T2; E2 是 Echo pin
  35.    Serial.println(String("distance2=") + distance2 + " cm");
  36.    delay(500);
  37.   //第二部分过程控制LED1,LED2,LED6,LED7
  38.    b = 0;  // 假设距离不在 [8, 15] 内
  39.    if((distance2 >= 8)&&(distance2 <= 15)) b = 1;   // 发现在 [8, 15] 内 !
  40.    Serial.println( String("b=") + b);
  41.    if(b == 1) tryLight( );  //  8 cm <= distance2 <= 15 cm
  42.    check7( );  // b 不是 1 也要检查 LED 7; 如果有亮灯, 则时间到了要灭灯
  43. } // loop(
  44. void tryLight( ) {
  45.    digitalWrite(led1,LOW);
  46.    digitalWrite(led2,HIGH);
  47.    digitalWrite(led6,HIGH);
  48.    light7( );  // see below, 如果还没亮过, 点亮 LED7 并开始计时 t71
  49. }
  50. ////////
  51. void light7( ) {
  52.    if(flag == 3) return;  // Led 7 已经打开又关闭, 立即返回, 不再往下
  53.    if(flag == 0) {  // Led 7 还没亮灯过
  54.       digitalWrite(led7,HIGH);
  55.       flag = 1;  // 改为 1 表示亮灯
  56.       t71 = millis( ); // 记住亮灯时间
  57.       return;
  58.    }
  59.    // 会到这, 表示 flag 一定是 1, 所以不必检查了
  60.    // 当然要写 if(flag == 1 ) {... } 也可以啦
  61.    check7( );  // 查看亮灯时间是否已经超过 lightTime (5秒)
  62. } // light7(
  63. void check7( ) {
  64.     if(flag != 1) return;  // LED7 灯没亮, 直接返回
  65.     if( millis( ) - t71  < lightTime) return; // 时间还没到 ! lightTime 是 5000 表示 5 秒
  66.     // 到这表示 millis( ) - t71 已经 大于 or 等于 lightTime
  67.     flag = 3;  //  表示已经点亮且又亮灯超过 5 秒
  68.     digitalWrite(led7, LOW);  // 关闭 LED7
  69.     Serial.print("t72=");
  70.     Serial.println( millis( ) - t71 );   // 实际上根本用不到 t72 :-)
  71. } // check7(
  72. float getDist(int pinTrig, int ePin) {  // trigger pin, echo pin
  73.    //产生一个10us的高脉冲去触发 trigger pin  (pinTrig)
  74.    digitalWrite(pinTrig, LOW);
  75.    delayMicroseconds(2);
  76.    digitalWrite(pinTrig, HIGH);
  77.    delayMicroseconds(10);
  78.    digitalWrite(pinTrig, LOW);
  79.    //检测脉冲宽度,并计算出距离
  80.    float ans  = pulseIn(ePin, HIGH) / 58.00;
  81.    return ans;
  82. } // getDist
复制代码
回复 支持 反对

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-5-18 01:25 , Processed in 0.041702 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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