通过蓝牙远程控制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); }
这个作品其实可以小型化之后做那种智能家居的灯。单个灯可能价格比较多,多路比较合算吧。