极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 51165|回复: 17

乞丐版ATmega8L的实践——敲击开关(arduino自动开关茶桌)

[复制链接]
发表于 2012-5-1 02:05:37 | 显示全部楼层 |阅读模式
关键字:敲击开关 自动茶台 蛐蛐叫声 ATmega8L



早就想改下我办公室的自动茶台了。早年用数字电路4017搭的控制器一直不稳定,后来索性改成遥控工作了,可这不符合我追求完美的习惯。

说说初衷:经过声控、磁控、触摸、遥控、金属按钮等多种方案理性评估后,还是感性的认为,敲击控制的开关在这种场合比较有感觉。于是我又胡乱的搜了一圈,证明大脑短路的还是自己——没有发现有人设计过这种开关,可能是大家觉得这个设计不够炫,很白痴吧。。。但是,我喜欢


一接触Arduino,我就罗列了一堆想做的东西,敲击开关的应用是首当其冲的。不过Arduino成品板做这么简单的应用,有些大材小用了。自从上一次我的乞丐版ATmega8L烧制成功,觉得这个价位和功能特别适合这种应用。不是简单的成本问题,只是觉得用这个价位实现这个功能更有乐趣。

电路部分也无需多说,在上次的ATmega8L最小系统板子上直接焊接了两路三极管结构驱动的继电器输出,用来驱动茶台的开合;常规供电是12V的,加了个7805的电源电路用来对MCU供电;传感器是几年前从电子市场上买的报警器用的震动传感器,拆开后发现实质是压电陶瓷片配合运放电路的模块,灵敏度可调。


传感器,买了很久了。当时价格好像是¥15

另外需要说明的是,以前有一路扩展功能(茶台隔板的水平移动,使用储物空间)因为机械部分材料不可靠被拆掉了,程序中已经预留了接口,以后再改结构恢复。

在上期做的乞丐版8L洞洞板上直接焊接的三极管,继电器,稳压IC。裁掉周边多余的,刚好装入以前的遥控接收外壳。

背面看惨不忍睹...

控制部分总共花费< ¥25

完整的功能实现:

1.系统接电启动,蜂鸣器发出三声蛐蛐低音叫声,然后停顿后发出两声高音叫声,表示系统已经启动。
关于声音部分,有个花絮:我一直接受不了有源蜂鸣器产生的单一”嘀“的噪声,本来打算用音符体现,结果调用一个音符库就要6k左右空间,对于8k的容量来说,是不可能完成的任务。如果没有音符,我能接受的就是高级轿车安全带提示的咚咚声,但我一直不知是怎么实现的,据说用了和弦芯片。希望有了解的同学给扫下盲。经过无意间的实践,居然歪打正着的把铃音调成了蛐蛐叫声。
而且音色还算正点。但最理想的状态是不接有源蜂鸣器的保护贴纸,就会产生蛐蛐叫的效果,揭了以后像是另一种虫子,本地叫“油葫芦”,不过声音太大,不实用。细节决定成败,在提示音的问题上,用最简单的几行代码做了个蛐蛐效果,而且重要的是在这个场合比较合适,超过了我最喜欢的“咚咚”声(用在仪器上会更好)。
言归正传,此时系统已经启动成功开始待命了。


2.茶台展开:用手有节奏的拍击桌面三次,表示茶台展开指令,蜂鸣器发出两声高音蛐蛐叫声,继电器工作,驱动推杆电机将茶台展开。如果敲击一次,或者二次,四次、五次。。。茶台会认为是干扰信号,发出三声低音蛐蛐叫声,重新等待指令。

3.茶台隔板平移,展开储物空间。(这个功能目前因为机械原因暂时没有加入,但程序中已经体现)这是下一个逻辑,茶台展开时才会启用。用手有节奏的拍击桌面两次,蜂鸣器发出两声高音蛐蛐叫声,继电器工作,驱动电机工作,将茶台隔板平移,展开储物空间,这时,可以把藏在储物空间里的好茶拿出来了。!-_-  这里的电机,以前是上学时花3块钱买的处理110v步进电机,以后准备换成同步电机。舵机其实可以直接用,但速度太快,不优雅。。。(从没用过舵机,不知能不能加入pwm调速功能)

然后,再拍两次,隔板平移归位,此时就可以泡茶了。

如果在隔板移开的情况下,拍了三次,或者别的次数,茶台都会忽略,发出三声低音叫声,表示抗议。

4.茶台恢复。茶喝完了,在隔板归位的前提下,或者你只是无聊试试,根本没有拍出隔板,再拍三次,继电器工作,推杆电机换相,茶台关闭,得瑟结束。中间设计了一个友善的停顿,防止夹手。

照片在相机里没导出,回头补上。

当年的视频,比较完整,后来把隔板功能去掉了,换成了能储水的小茶台,最近准备恢复。
视频需要头部左倾90度观赏。


video url   http://player.youku.com/player.php/sid/XMTIxMDIwNzk2/v.swf


代码是在深夜在神志不清前,写了两个多小时。很乱,逻辑更乱,期待达人给优化一下。
输出后hex是5103字节,还算满意。我把编译后的hex附上,有8L的可以直接用USBISP线烧进去。

  1. //Knocking switch by Thomas 2012.04.28

  2. int sensorPin = A0;    // 指定震动传感器输入端口
  3. int BeepPin = 8;        // 指定有源蜂鸣器输出端口
  4. int b3Pin1 = 3;         // 指定b3功能输出继电器端口,给推杆电机换向用。
  5. int b3Pin2 = 4;         // 指定b3功能输出继电器端口,给推杆电机换向用。
  6. int b2Pin = 2;           // 指定b2功能输出继电器端口,此功能以后启用。
  7. int iv = 0;                 // input value 输入数值置零
  8. int si=0;                   // 输入编码号置零
  9. unsigned long time=0; //计时器清零
  10. unsigned long t0=0;    //
  11. unsigned long t1=0;    //敲击时间
  12. unsigned long t11=0;  //空闲时间
  13. int taMax=837;            //时间常数初始化
  14. int taMin=400;             //时间常数初始化
  15. int ba=2500;               //敲击失效等待时间
  16. int tcMax=190;           //敲击时间上限
  17. int tcMin=90;              //敲击时间下线
  18. int b2status=0;          //功能模块互锁逻辑参数
  19. int b3status=0;          //功能模块互锁逻辑参数
  20. boolean tw=false;       //敲击逻辑开关
  21. boolean bw=false;       //等待逻辑开关
  22. boolean b2lock=true;  //功能模块互锁逻辑开关
  23. boolean b3lock=false; //功能模块互锁逻辑开关

  24. void setup() {
  25.   pinMode(BeepPin, OUTPUT);   //初始化端口
  26.   pinMode(b2Pin, OUTPUT);
  27.   pinMode(b3Pin1, OUTPUT);
  28.   pinMode(b3Pin2, OUTPUT);
  29.       beep_long();                      //蛐蛐开叫,证明系统运行。
  30.       delay(1000);
  31.       beep_short();
  32. }

  33. void loop() {
  34.   iv = analogRead(sensorPin);  //监测传感器
  35.   time = millis();                       //计时器基准
  36.   if(iv<tcMin){                         //是否触发判断
  37.     if(tw==false){                     //各种逻辑顺序...
  38.       tw=true;
  39.       bw=false;
  40.       t0=time;
  41.     }
  42.   }
  43.   else if(iv>tcMax){ //如果触发

  44.     if(tw==true){  //如果触发并启动等待判断
  45.       t1=time-t0;
  46.       tw=false;

  47.       if(t1>taMin&&t1<taMax){  //有效触发时间窗口
  48.         si++;
  49.         bw=true;
  50.         t11=time+ba;
  51.       }
  52.       else{
  53.         si=0;
  54.         t1=0;
  55.       }
  56.     }

  57.     if(bw==true){  //如果敲击后,判断空闲时间
  58.       if(time>t11){
  59.         bw=false;
  60.         btSwitch(); //空闲时间过后,根据敲击次数调用相应代码
  61.         si=0;
  62.       }
  63.     }
  64.     else{
  65.       t11=time+ba;  
  66.     }
  67.   }
  68. }


  69. void btSwitch(void){
  70.   switch (si) {
  71.   case 1:
  72.     beep_long();    //敲击1次,蛐蛐长叫表示抗议。
  73.     break;
  74.   case 2:
  75.     if(b2lock==false){
  76.       beep_short();  //敲击2次,蛐蛐短叫表示成功触发,隔板动作。前提是,已经执行过敲击3次指令。
  77.       doSlide();
  78.     }
  79.     break;
  80.   case 3:
  81.     if(b3lock==false){
  82.       beep_short();
  83.       doOpen();         //敲击3次,蛐蛐短叫,为你开门,如果开门后,被敲击2次,激活隔板平移功能,开门功能被锁定,只接受2次敲击指令,直到隔板恢复。
  84.     }
  85.     break;
  86.   default:
  87.     beep_long();
  88.     //多敲无益,蛐蛐长叫表示抗议。
  89.     break;
  90.   }
  91. }

  92. void doOpen(){                        //茶台展开功能
  93.   if(b3status==0){
  94.     b3status=1;
  95.     b2lock=false;
  96.     digitalWrite(b3Pin1, HIGH);   // 1号继电器工作,推杆电机伸出
  97.     delay(10000);                      //10秒工作延迟
  98.     digitalWrite(b3Pin1, LOW);   // 1号继电器停止工作
  99.   }
  100.   else{
  101.     b3status=0;
  102.     b2lock=true;
  103.     digitalWrite(b3Pin2, HIGH);   // 2号继电器工作,换相,推杆电机缩回
  104.     delay(5000);                        // 5秒的工作延迟
  105.     digitalWrite(b3Pin2, LOW);   // 友善的停顿1秒,防止夹手
  106.     delay(1000);
  107.     digitalWrite(b3Pin2, HIGH);   // 恢复供电3秒,让推杆电机继续缩回归零
  108.     delay(3000);
  109.     digitalWrite(b3Pin2, LOW);   // 2号继电器停止工作   
  110.   }
  111. }

  112. void doSlide(){                          //隔板滑动功能,没写完,硬件完善后再做
  113.   if(b2status==0){
  114.     b2status=1;
  115.     b3lock=true;
  116.   }
  117.   else{
  118.     b2status=0;
  119.     b3lock=false;
  120.   }
  121. }

  122. void beep_long(){                    //蛐蛐叫声,表示错误。
  123.   for(int j=0;j<3;j++){
  124.     for(int i=0;i<5;i++){
  125.       digitalWrite(BeepPin, HIGH);   
  126.       delay(20);         
  127.       digitalWrite(BeepPin, LOW);   
  128.       delay(20);              
  129.     }
  130.     delay(800);              
  131.   }
  132. }

  133. void beep_short(){                  //蛐蛐叫声,表示成功。
  134.   for(int j=0;j<2;j++){
  135.     for(int i=0;i<2;i++){
  136.       digitalWrite(BeepPin, HIGH);  
  137.       delay(20);            
  138.       digitalWrite(BeepPin, LOW);   
  139.       delay(20);            
  140.     }
  141.     delay(500);   
  142.   }
  143. }


复制代码

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2012-5-1 22:53:34 | 显示全部楼层
{:soso_e113:} 这个arduino作品。。真是好~~~我也喜欢喝茶。。。。不过现在还没茶具,都拿保温杯随便泡泡=.=
回复 支持 反对

使用道具 举报

发表于 2012-5-1 23:51:16 | 显示全部楼层
==!eggpain{:soso_e141:}
回复 支持 反对

使用道具 举报

发表于 2012-5-2 10:44:48 | 显示全部楼层
灰常给力!
回复 支持 反对

使用道具 举报

发表于 2012-5-9 16:59:46 | 显示全部楼层
设计东西请从需求出发。。
回复 支持 反对

使用道具 举报

发表于 2012-5-9 21:31:04 | 显示全部楼层
创客精神!
回复 支持 反对

使用道具 举报

发表于 2012-5-18 23:36:16 | 显示全部楼层
你太个性了。说实话,我目前刚学,手上的板子也就是2560加上一堆传感器,1快蓝牙,一堆元器件(本人偶尔拿洞洞板做一些不成器的东东)。
一直喜欢做些低成本的趣味东东,你这篇真的是不谋而合,用2560搞这个就会是自己都觉得奢侈,哈哈。 用8L真的是不心疼了。
回复 支持 反对

使用道具 举报

发表于 2012-5-29 13:23:05 | 显示全部楼层
本帖最后由 piaozhiling 于 2012-5-29 13:26 编辑

文章写的非常好,但,视频没有看到,真是损失,所以,还不敢,制造的东西的水平。手机看不到视频链接,希望能把视频链接附在视频的下面,以免我们这些手机党没办法看。
回复 支持 反对

使用道具 举报

发表于 2012-9-6 22:36:21 | 显示全部楼层
看到了,不错的创意
回复 支持 反对

使用道具 举报

发表于 2012-10-22 09:48:23 | 显示全部楼层
good job,我感兴趣的是机械部分,可惜没看到啊
回复 支持 反对

使用道具 举报

发表于 2012-10-22 12:20:42 | 显示全部楼层
电路部分只要简单写写程序就出来了,我也感兴趣机械部分的设计
回复 支持 反对

使用道具 举报

发表于 2012-11-7 10:29:33 | 显示全部楼层
拍三下打开抽屉真是太酷了!!!
回复 支持 反对

使用道具 举报

发表于 2012-12-7 11:20:11 | 显示全部楼层
这个太实用了。但是不知道机械部分是如何完成的呢
回复 支持 反对

使用道具 举报

发表于 2013-3-9 22:49:22 | 显示全部楼层
哈哈哈 咋感觉有点喜感呢··
回复 支持 反对

使用道具 举报

发表于 2013-3-31 12:07:31 | 显示全部楼层
题外话,您的手好嫩啊,咳咳,我也想看看机械部分怎么安装的里面,
回复 支持 反对

使用道具 举报

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

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

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 15:38 , Processed in 0.056649 second(s), 33 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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