一种外置的暴力宿舍关灯装置,使用外部机械舵机结构,免改造,易安装,实现方法暴力。人来即拆,人走即安。


本项目后来拿去参加比赛搞事了,详见[趴会儿Project]关于《掌握光明的女神★反物联网反智能暴力外置关灯器V2.0 by 夜露死苦》的一点后续

Table of Contents
1.背景&使用场景
也许你经常会遇到,宿舍11点熄灯,世界暗了。但是,大家沉浸在黑暗世界中,无人顾及将小小的照明开关关掉。
第二天5点30,李毅大帝降临人间,瞬间整个宿舍骤亮。
最终对灯光最敏感的人惺惺下地关灯。
没错,你是不是对灯光最敏感的那个倒霉鬼?说的就是你!
2.简述
本作品崇尚一种暴力的解决方法,基本思路即为外置舵机,直接定向旋转物理性地控制照明开关。
仔细想想,毕竟大学宿舍,时不时有消防安全检查。一方面如果拆了照明系统开关,内置继电器控制,是不科学的。一方面会被物业找麻烦,另一方面,也是最重要的,不安全,私改线路要是打火,太危险了。
为了避免发生不必要的麻烦,一种可即使拆卸的外置设备,打游击战还是很有必要的。
3.内容
3.1部件选用
3.1.1 主控
主控采用Arduino UNO R3 初期调试用。如果后期想要集成便携属性,减小体积可转为Arduino Nano等小体积版。
如果不考虑功耗,更进一步压缩成本,其实更可选用STC51系列的单片机系统。这玩意便宜,大家都用他来入门。只需把舵机的PWM等代码移植即可。
目前先不考虑大系统集成
----↓2016.8.27更新----
使用了兼容的Nano作为主控,缩小体积。
3.1.2 外部配件
想要在床上便捷关灯(或者故意先上床然后画蛇添足多此一举用遥控关灯),必不可少的是遥控模块。我也考虑了一些,比如红外模块。但是红外模块的迷之距离和遮挡失效属性,弃用。后来还是用315Mhz的遥控模块吧。没准甚至能楼下关灯。
最终采用 2272-M4 非锁四路无线遥控套件
因为对加密性没有要求,315Mhz的遥控对于我来说反而越模块化、越易用越好。
模块焊盘固定码,解码器和遥控器配好,按键既有电平变化。

舵机采用SG90微型舵机即可。
3.2 连接
本实例连接很简单。5v取自主控板,分别给接收解码模块和微型舵机供电(事实上,板载可驱动一个sg90微型舵机)。
IO口分别连接。
3.3代码段
v1.0
/*
趴会儿Project项目集 http://steinslab.io/archives/752
No.001 一种外置的暴力宿舍关灯装置
详见http://steinslab.io/archives/749
SPtuan@steinslab.io
*/
#include <Servo.h>
#include <Enerlib.h>
Servo switcher;
Energy energy;
int pos = 20;
int sig = 2;
int flag = 0;
int flag_temp = 0;
void signal0()
{
delay(1);
if (digitalRead(sig) == 1)
{
Serial.println("Signal!");
flag = (!flag);
while (digitalRead(sig) == 1);
}
changePosition();
flag_temp = flag;
Serial.println("tempflag!");
switcher.write(pos);
delay(2000);
}
int changePosition()
{
if (flag != flag_temp)
{
Serial.println("change position!");
if (flag == 0)
{
pos = 0;
Serial.println("change position0!");
return 0;
}
if (flag == 1)
{
pos = 180;
Serial.println("change position1!");
return 1;
}
}
}
void setup() {
Serial.begin(9600);
Serial.println("Servo test!");
switcher.attach(9);
pinMode(sig, INPUT);
switcher.write(90);
attachInterrupt(0, signal0, RISING);
delay(2000);
}
void loop() {
delay(1000);
energy.PowerDown();
}
----2016.8.27更新调试完毕的代码段v2.0----
/*
趴会儿Project项目集 http://steinslab.io/archives/752
No.001 一种外置的暴力宿舍关灯装置 2.0
详见http://steinslab.io/archives/749
SPtuan@steinslab.io
*/
#include <Servo.h>
#include <Enerlib.h>
Servo switcher;
Energy energy;
int pos = 20;
int sig = 2;
int flag = 0;
int flag_temp = 0;
void signal0()
{
if (digitalRead(sig) == 1)
{
Serial.println("Signal!");
flag = (!flag);
while (digitalRead(sig) == 1);
}
changePosition();
flag_temp = flag;
Serial.println("tempflag!");
}
int changePosition()
{
if (flag != flag_temp)
{
Serial.println("change position!");
if (flag == 0)
{
pos = 20;
Serial.println("change position0!");
}
if (flag == 1)
{
pos = 150;
Serial.println("change position1!");
}
switcher.write(pos);
//delay(2000); 不要在中断中使用delay()
return 0;
}
}
void setup() {
Serial.begin(9600);
Serial.println("Servo test!");
switcher.attach(9);
pinMode(sig, INPUT);
switcher.write(90);
attachInterrupt(0, signal0, RISING);
delay(2000);
}
void loop() {
delay(1000);
setup();
if (switcher.read() == 90)
energy.PowerDown();
}
3.4 遇到的问题
首先我尝试使用Arduino自带的Servo库,但是遇到了很大的问题。servo最终定位的舵机异常抖动,貌似未归位发出异响,这是我无法忍受的。后来换了自写的PWM控制函数,仍然抖动。
后来使用了中断方式获取遥控的信号。为了避免发出异响,并考虑到以后,为了免外接电源需加入省电模式,省电模式可由0号中断唤醒。两者配合最终解决问题。
----2016.8.27----
优化了代码。最后调试由于旋转尺度不够,不能保证将开关撞击到指定位置,设置了多余的转动角度。
优化了代码,使舵机臂每次击打后归中,为手动开灯关灯让路。
4.装配与效果
测试环境下的效果
关灯的原理太清楚了,让舵机微微转动15度即可关灯/开灯。
最终我再用pvc板子包装一下,换成Arduino nano或者51。舵机做个衣服上用的粘贴,就成最终版了。
----2016.8.27-----
为了防止人工开关灯时破坏装置,对用于关灯开灯的舵机臂进行改造。使用自带的两个云台壁,用跳线铰接,简单实用。

换用了兼容的第三方nano。在面包板上进行测试。(视频大小1.3MB)
测试完毕后,把各个组件在洞洞板上集成。背面焊了跳线,将5v和gnd引出。同时导出D9IO口用于舵机控制,给以后改造留个余地。背面焊工就不漏了,班门弄斧(视频大小1.5MB)


最终效果:(视频大小2MB)

5.参考资料
这家网站以图解的方式将睡眠模式讲得很透彻!赞!
[3] Arduino外部中断的使用
我在想 既然都做到这了 为什么不搞个定时熄灯就关灯的代码呢???
@HawkMaple 终于有人能精确吐槽这点了!这才是这篇文章最大的槽点啊!其实这个装置是用来报复室友的
好厉害~我都看不懂!
@Clarke 哈哈,学习单片机顺便做的一点小项目。这边一般都放比较严肃的。一时脑抽或者各种奇奇怪怪的东西都堆到misaka.cc了
哦哦!好有意思啊
懒才是第一生产力(笑
@printempw 大佬!!
后来我发现了,即使有了这个装置,每天早上醒来按动遥控按钮的还是我…好气啊
666,简单粗暴
点赞
@大树 贵客啊!欢迎欢迎!啪啪啪啪啪
@SPtuan 哈哈哈哈没有没有!其实总来看这些看不太懂的东西的~
水水水,狠狠狠,看不懂
@你冰雪可爱得崔神 ?????鏌
棒棒的
@星月 终于上来了!
狠
@fandy 别灌水啊喂()