通过蓝牙远程控制LED的开和关,同时演示了通过PWM控制LED的明暗。控制LED的开和关是通过继电器实现的。实际上继电器可以控制最大10A,270V交流的设备,比如照明电路,电动机之类的。不过这个只是原型,直接复用MCU的5V电源。
整体比较难的部分在于蓝牙控制。也就是常说的那种上位机和下位机程序的编写。这里上位机是安卓手机的蓝牙控制端。下位机是连接到Arduino的蓝牙控制芯片。我使用的是BC04,主从一体。这里只需要从模式即可。以下是上位机界面。
安卓中相关的API
// test if device support bluetooth BluetoothAdapter.getDefaultAdapter() != null; // scan device IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mDeviceReceiver, filter); mBluetoothAdapter.startDiscovery(); // stop discovery mBluetoothAdapter.cancelDiscovery(); // UUID private static final UUID sUUID = UUID.fromString(“00001101-0000-1000-8000-00805 F9B34FB"); // connect to device mBluetoothDevice = bluetoothAdapter.getRemoteDevice(address); mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceR ecord(sUUID); mBluetoothSocket.connect();
通讯协议,这个是第一版的,其实之后发现BC04会有额外的数据出来,所以有第二版的同步头,不过这里就不写了。之后的小车上有用到。
| Protocol | Request | Response |
|---|---|---|
| TEST | [1:LENGTH][1:PROTOCOL_CODE] | [1:LENGTH][1:RETURN_CODE] |
| SIMPLE_SWITCH | [1:LENGTH][1:PROTOCOL_CODE] [1:SWITCH_VALUE] | [1:LENGTH][1:RETURN_CODE] |
| SIMPLE_PWM | [1:LENGTH][1:PROTOCOL_CODE] [1:PWM_VALUE] | [1:LENGTH][1:RETURN_CODE] |
因为上位机部分的代码比较多,这里就不列了。这里只列一下Arduino部分的代码,也就是下位机的。
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#define PIN_RELAY 4
#define PIN_PWM_LED 3
#define STATUS_WAIT_LEN 0
#define STATUS_WAIT_PT 1
#define STATUS_WAIT_PL 2
#define STATUS_DONE 3
#define PT_TEST 1
#define PT_SIMPLE_SWITCH 2
#define PT_SIMPLE_PWM 3
LiquidCrystal_I2C lcd(0x27, 16, 2);
int dataLength;
int protocolType;
int payload;
int workingStatus;
int cursorPos = 0;
void setup() {
pinMode(PIN_RELAY, OUTPUT);
pinMode(PIN_PWM_LED, OUTPUT);
Serial.begin(115200);
workingStatus = STATUS_WAIT_LEN;
lcd.init();
lcd.backlight();
}
void loop() {
if(workingStatus == STATUS_DONE) {
switch(protocolType){
case PT_TEST:
replyCode(48);
break;
case PT_SIMPLE_SWITCH:
digitalWrite(PIN_RELAY, payload == 1 ? HIGH : LOW);
replyCode(48);
break;
case PT_SIMPLE_PWM:
if(payload < 0) payload = 0;
if(payload > 255) payload = 255;
analogWrite(PIN_PWM_LED, payload);
replyCode(48);
break;
}
workingStatus = STATUS_WAIT_LEN;
}
if(Serial.available()) {
if(workingStatus == STATUS_WAIT_LEN) {
dataLength = Serial.read();
lcd.clear();
lcd.print(dataLength);
lcd.print(' ');
workingStatus = STATUS_WAIT_PT;
} else if(workingStatus == STATUS_WAIT_PT) {
protocolType = Serial.read();
lcd.print(protocolType);
lcd.print(' ');
if(dataLength > 1) {
workingStatus = STATUS_WAIT_PL;
} else {
workingStatus = STATUS_DONE;
}
} else if(workingStatus == STATUS_WAIT_PL) {
payload = Serial.read();
lcd.print(payload);
workingStatus = STATUS_DONE;
}
}
}
void replyCode(byte code) {
Serial.write(1);
Serial.write(code);
}
这个作品其实可以小型化之后做那种智能家居的灯。单个灯可能价格比较多,多路比较合算吧。



