聚豐項(xiàng)目 > 智能夜燈
一款夜燈,有兩個(gè)光源,既可以當(dāng)夜燈,也可以當(dāng)照明燈。 帶人體感應(yīng),自己寫(xiě)了個(gè)android上位機(jī),可以通過(guò)手機(jī)控制(懶人福音~(yú)~),可以設(shè)置定時(shí)關(guān)閉等。
用戶協(xié)議

用戶協(xié)議
團(tuán)隊(duì)成員
梁學(xué)友 開(kāi)發(fā)
1、主控芯片 nucleo stmf401開(kāi)發(fā)板
2、藍(lán)牙模塊 hc-06:用于與手機(jī)進(jìn)行藍(lán)牙通信
3、光線感應(yīng)模塊:用于感應(yīng)人體
4、led燈和燈帶:提供光源
5、三極管,電阻等:搭建外圍電路和電源電路
6、android手機(jī):運(yùn)行上位機(jī),控制夜燈
7、亞克力板,作品外殼
單片機(jī)部分軟件,使用的開(kāi)發(fā)平臺(tái)為mbed os,代碼及介紹如下:
#include "mbed.h"
#include "string"
//#include "stdlib.h"
//------------------------------------
// Hyperterminal configuration
// 9600 bauds, 8-bit data, no parity
//------------------------------------
//Serial pc(SERIAL_TX, SERIAL_RX);
Serial pc(D10,D2,115200);//與藍(lán)牙模塊通信的串口
DigitalOut myled(LED1);
DigitalOut nightled(A0);
DigitalOut lightingled(A1);
InterruptIn button(USER_BUTTON);
InterruptIn reshidian(D3);
Timeout timeout1;//定時(shí)器1,延時(shí)關(guān)閉時(shí)間
Timeout timeout2;//定時(shí)器2,定時(shí)關(guān)閉時(shí)間
Timer timer1;
Timer timer2;
Ticker ticker1;
unsigned int auto_close_time=300;//延時(shí)關(guān)閉時(shí)間
unsigned int clock_time=600;//定時(shí)關(guān)閉時(shí)間
unsigned char mode_flag=0;//運(yùn)行模式標(biāo)志,1-AutoMode,2-ControledMode
void AutoMode(void);
void ControledMode(void);
char str[]="000000000000000000";
int str_index=0;
void timeout1_evevt_1()
{
lightingled=false;
}
void timeout2_evevt_2()
{
lightingled=false;
}
//串口中斷處理函數(shù)
void echouart()
{
while(pc.readable())
{
str[str_index]=pc.getc();
str_index++;
if(str[str_index-1]=='$')
{
str_index=0;
//pc.printf(str);
//string s(&str[1],&str[str_index-1]);
switch(str[str_index])
{
case '0': /*pc.printf("lighting light on ");*/lightingled=true;break;
case '1':lightingled=false;break;
case '2':nightled=true;break;
case '3':nightled=false;break;
case '4':AutoMode();pc.printf("success!\r\n");break;
case '5':ControledMode();pc.printf("success!\r\n");break;
case '6':
auto_close_time=atoi(&str[1]);
auto_close_time*60;
pc.printf("success!\r\n");
break;
case '7':clock_time=atoi(&str[1]);
timeout2.attach(timeout2_evevt_2,clock_time*60);
pc.printf("success!\r\n");
break;
default:break;
}
int i=0;
while(i<10)
{
str[i]='0';
i++;
}
}
}
/*
while(pc.readable())
{
pc.putc(pc.getc());
}
*/
}
//按鍵中斷處理函數(shù),單擊,雙擊,長(zhǎng)按
void flip()
{
wait(0.03);
if(button==0)
{
timer1.start();
while(button==0)
{
if(timer1.read_ms()>2000)
{
timer1.stop();
timer1.reset();
if(mode_flag==0)
{
mode_flag=1;
ControledMode();
//pc.printf("controled\r\n");
}
else if(mode_flag==1)
{
mode_flag=0;
AutoMode();
//pc.printf("auto\r\n");
}
//pc.printf("statu_2-long_click\r\n");
while(button==0);
return;
}
}
if(timer1.read_ms()<=2000)
{
timer1.stop();
timer1.reset();
timer2.start();
button.disable_irq();
while(timer2.read_ms()<400)
{
if(button==0)
{
wait(0.03);
if(button==0)
{
timer2.stop();
timer2.reset();
//pc.printf("statu_1-double_click\r\n");
nightled=!nightled;
button.enable_irq();
break;
}
}
}
if(timer2.read_ms()>=400)
{
timer2.stop();
timer2.reset();
//pc.printf("statu_0-short_click\r\n");
lightingled=!lightingled;
button.enable_irq();
}
}
}
}
//D3,熱釋電傳感器信號(hào)中斷處理函數(shù),上升沿,檢測(cè)到有人
void flip2_1()
{
lightingled=true;
timeout1.attach(&timeout1_evevt_1,auto_close_time);
//myled=false;
}
//D3,熱釋電傳感器信號(hào)中斷處理函數(shù),下降沿,傳感器延時(shí)結(jié)束
void flip2_2()
{
lightingled=false;
timeout1.attach(&timeout1_evevt_1,auto_close_time);
myled=true;
}
//自動(dòng)運(yùn)行模式
void AutoMode()
{
myled=false;
reshidian.enable_irq();
}
//手動(dòng)控制模式
void ControledMode()
{
myled=true;
reshidian.disable_irq();
}
int main()
{
lightingled=true;
timeout1.attach(&timeout1_evevt_1,auto_close_time);
pc.attach(&echouart,SerialBase::RxIrq);//聲明窗口中斷處理函數(shù)
button.fall(&flip);//聲明按鍵中斷處理函數(shù)
reshidian.fall(&flip2_1);
AutoMode();
while(1)
{
}
}
手機(jī)App部分,使用的開(kāi)發(fā)平臺(tái)為android,開(kāi)發(fā)工具為android studio,開(kāi)發(fā)語(yǔ)言為JAVA,主要代碼及介紹如下:
(android代碼在這里顯示好像有問(wèn)題,源程序在附件,需要請(qǐng)聯(lián)系本人索要密碼)
com.example.john.myapplication;
android.content.BroadcastReceiver;
android.content.Context;
android.content.DialogInterface;
android.content.Intent;
android.content.IntentFilter;
android.os.Handler;
android.support.v7.app.AppCompatActivity;
android.os.Bundle;
android.text.TextUtils;
android.text.method.ScrollingMovementMethod;
android.view.View;
android.widget.*;
android.bluetooth.*;
android.bluetooth.BluetoothDevice;
android.bluetooth.BluetoothSocket;
java.io.IOException;
java.lang.reflect.Method;
java.util.ArrayList;
java.util.HashMap;
java.util.List;
java.util.Set;
java.util.UUID;
android.annotation.;
android.app.Activity;
android.bluetooth.BluetoothAdapter;
android.bluetooth.BluetoothDevice;
android.content.BroadcastReceiver;
android.content.Context;
android.content.Intent;
android.content.IntentFilter;
android.os.Build;
android.os.Bundle;
android.os.Handler;
android.os.Message;
android.view.Menu;
android.view.MenuItem;
android.view.View;
android.view.ViewConfiguration;
android.view.Window;
android.widget.AdapterView;
android.widget.ListView;
android.widget.Toast;
MainActivity AppCompatActivity{
BluetoothAdapter ;
TextView ;
ScrollView ;
;
String =;
;
Switch ;Switch ;Switch ;Switch ;ListView ;EditText ;EditText ;Button ;Button ;DeviceAdapter ;
List =ArrayList<>();BlueToothController =BlueToothController();
BluetoothDevice ;
BluetoothSocket =;
ConnectThread ;
=;onCreate(Bundle savedInstanceState) {
.onCreate(savedInstanceState);
setContentView(R.layout.);
=(Switch) findViewById(R.id.);
=(Switch) findViewById(R.id.);
=(Switch) findViewById(R.id.);
=(EditText)findViewById(R.id.);
=(EditText)findViewById(R.id.);
=(Button)findViewById(R.id.);
=(Button)findViewById(R.id.);
=(Switch) findViewById(R.id.);
=(ListView)findViewById(R.id.);
= BluetoothAdapter.();
= (TextView) findViewById(R.id.);
(== ) {
showToast();
;
}
= .getState();() {
:
.setText();
.setChecked();;
:
.setText();
;
:
.setText();
.setChecked();
;
:
.setText();
;
:
;
}
.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener() {
onCheckedChanged(CompoundButton buttonView, isChecked) {
(isChecked)
{
{.enable();
showToast();
.setText();}
(Exception e)
{
e.printStackTrace();
}
}
{
{
.disable();
showToast();
.setText();
}
(Exception e)
{e.printStackTrace();}
}
}
});
.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener() {
onCheckedChanged(CompoundButton buttonView, isChecked) {
(isChecked)
{
(!=)
{
.sendData((Instructs.+).getBytes());
}
{
showToast();
.setChecked();
}
}
{
(!=)
{
.sendData((Instructs.+).getBytes());
}
{
showToast();
.setChecked();
}
}
}
});
.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener() {
onCheckedChanged(CompoundButton buttonView, isChecked) {
(isChecked)
{
(!=)
{
.sendData((Instructs.+).getBytes());
}
{
showToast();
.setChecked();
}
}
{
(!=)
{
.sendData((Instructs.+).getBytes());
}
{
showToast();
.setChecked();
}
}
}
});
.setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener() {
onCheckedChanged(CompoundButton buttonView, isChecked) {
(isChecked)
{
(!=)
{
.sendData((Instructs.+).getBytes());
}
{
showToast();
.setChecked();
}
}
{
(!=)
{
.sendData((Instructs.+).getBytes());
}
{
showToast();
.setChecked();
}
}
}
});
.setOnClickListener(View.OnClickListener() {
onClick(View v) {
(!=)
{
String str=.getText().toString();
(TextUtils.(.getText()))
{
showToast();
;
}
(Integer.(str)>)
{
showToast();
;
}
.sendData((Instructs.+str+).getBytes());
}
{
showToast();
}
}
});
.setOnClickListener(View.OnClickListener() {
onClick(View v) {
(!=)
{
String str=.getText().toString();
(TextUtils.(.getText()))
{
showToast();
;
}
(Integer.(str)>)
{
showToast();
;
}
.sendData((Instructs.+str+).getBytes());
}
{
showToast();
}
}
});
getBonded();
registerBluetoothReceiver();
}
getBonded(){
Set devices = .getBondedDevices();ArrayAdapter BondedList=ArrayAdapter(,android.R.layout.);.clear();
BondedList.clear();(BluetoothDevice boneddevice : devices) {
(boneddevice.getName().equals())
{
.add(boneddevice);
BondedList.add(boneddevice.getName());}
}
.setAdapter(BondedList);
.setOnItemClickListener();}
registerBluetoothReceiver() {
IntentFilter filter = IntentFilter();
filter.addAction(BluetoothAdapter.);
filter.addAction(BluetoothAdapter.);
filter.addAction(BluetoothAdapter.);
filter.addAction(BluetoothDevice.);
filter.addAction(BluetoothAdapter.);
filter.addAction(BluetoothDevice.);
registerReceiver(, filter);
}
initUI() {
=.getBondedDeviceList();ArrayAdapter BondedList=ArrayAdapter(,android.R.layout.);
String[] arr=String[]{};
(i=;i<.size();i++)
{
arr[i]=.get(i).getName();
BondedList.add(arr[i]);
}
.setAdapter(BondedList);
}
BroadcastReceiver = BroadcastReceiver() {
onReceive(Context context, Intent intent) {
String Action = intent.getAction();
(..equals(Action)){
showToast();
}
(..equals(Action)){
BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.);
String name=device.getName();
showToast(name);
.setText(name);
}
(..equals(Action))
{
(.getState()==.)
getBonded();
(.getState()==.)
{
getBonded();
}
}
}
};
onDestroy() {
.onDestroy();
unregisterReceiver();
}
Handler = MyHandler();
AdapterView.OnItemClickListener = AdapterView.OnItemClickListener() {
onItemClick(AdapterView parent, View view, position, id) {
BluetoothDevice device=.get(position);
( != ) {
.cancel();}
showToast();
= ConnectThread(device, , );
.start();
}
};
connect(BluetoothDevice device)IOException{
String SPP_UUID=;
UUID uuid=UUID.(SPP_UUID);
BluetoothSocket socket=device.createRfcommSocketToServiceRecord(uuid);
socket.connect();
showToast();
}
showToast(String msg)
{
Toast.(,msg,Toast.).show();
}
MyHandler Handler {
String =String();
String =String();
handleMessage(Message msg) {
.handleMessage(msg);
(msg.) {
Constant.:
;
Constant.:
;
Constant.:
=String.(msg.);
[] ch=.toCharArray();
=+;
((ch[.length()-]==)&&(ch[.length()-]==))
{
showToast();
=;
}
;
Constant.:
showToast(+String.(msg.)+);
;
Constant.:
showToast();
;
Constant.:
;
}
}
}
};照明燈:上面的燈
夜燈:里面的燈

1、運(yùn)行:插上電就自動(dòng)運(yùn)行了~~
2、兩種運(yùn)行模式:
1)自動(dòng)模式,在這個(gè)模式下,可以自動(dòng)感應(yīng)人體,感應(yīng)到人體后,照明燈自動(dòng)點(diǎn)亮,延時(shí)一段時(shí)間后關(guān)閉。
2)手動(dòng)模式,就是不會(huì)自動(dòng)感應(yīng)人體,完全依靠按鍵和手機(jī)控制。
開(kāi)機(jī)默認(rèn)進(jìn)入自動(dòng)模式,按鍵長(zhǎng)按2s切換模式,進(jìn)入手動(dòng)模式(當(dāng)進(jìn)入手動(dòng)模式的時(shí)候,板子上綠色的指示燈會(huì)亮)
按鍵:兩個(gè)按鍵,突出的那個(gè)是控制按鍵,凹下去的那個(gè)是復(fù)位按鍵,相當(dāng)于重啟。
控制按鍵:?jiǎn)螕?/span>-照明燈開(kāi)關(guān)。雙擊-夜燈開(kāi)關(guān)(雙擊按兩下之間的時(shí)間間隔要小于0.4s)。長(zhǎng)按-模式切換。
使用步驟:
1,在手機(jī)設(shè)置里打開(kāi)藍(lán)牙,搜索設(shè)備,配對(duì)(藍(lán)牙設(shè)備名稱為DJ`s Light,配對(duì)密鑰1234或者0000)
2、配對(duì)完成后打開(kāi)APP,點(diǎn)擊列表里的設(shè)備就可以自動(dòng)連接,然后進(jìn)行相應(yīng)的控制操作

1、最上面textview顯示藍(lán)牙狀態(tài)
下面依次是藍(lán)牙開(kāi)關(guān),如果藍(lán)牙打開(kāi),listview里會(huì)顯示已配對(duì)并且可用的設(shè)備。點(diǎn)擊就可以連接,連接成功會(huì)有提示,然后就可以進(jìn)行控制。
2、Lighting light:照明燈開(kāi)關(guān)
3、Night light:夜燈開(kāi)關(guān)
4、手動(dòng)模式:手動(dòng)模式/自動(dòng)模式切換開(kāi)關(guān),成功會(huì)返回 “success!”。
5、延時(shí)關(guān)閉時(shí)間:自動(dòng)模式下照明燈感應(yīng)到人體開(kāi)啟后延時(shí)關(guān)閉的時(shí)間。手動(dòng)模式下失效。成功會(huì)返回 “success!”。
6、定時(shí)關(guān)閉時(shí)間:可以設(shè)置照明燈在某個(gè)時(shí)間后關(guān)閉(大于等于1分鐘,小于24小時(shí)-1440分鐘)成功會(huì)返回 “success!”。
android程序源代碼在附件,需要請(qǐng)聯(lián)系本人
演示效果:




(0.09 MB)下載