[电子技术]蓝牙继电器控制


20141113_224136

通过蓝牙远程控制LED的开和关,同时演示了通过PWM控制LED的明暗。控制LED的开和关是通过继电器实现的。实际上继电器可以控制最大10A,270V交流的设备,比如照明电路,电动机之类的。不过这个只是原型,直接复用MCU的5V电源。

20141113_224246

整体比较难的部分在于蓝牙控制。也就是常说的那种上位机和下位机程序的编写。这里上位机是安卓手机的蓝牙控制端。下位机是连接到Arduino的蓝牙控制芯片。我使用的是BC04,主从一体。这里只需要从模式即可。以下是上位机界面。

device-2014-11-17-215455

device-2014-11-17-215528

安卓中相关的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);
}

这个作品其实可以小型化之后做那种智能家居的灯。单个灯可能价格比较多,多路比较合算吧。