12V 16 Kanal Bluetooth Relay Remote control Switch Funkfernschalter für Android

Heimautomatisierung ist das nächste große Ding liest man immer wieder in der Fachpresse und viele glauben, dass intelligente Geräte künftiges das Zuhause erobern werden. Schon jetzt sind viele Smart-Homes mit Philips-Hue, Alexa, Google Home, Homematic etc. angefüllt. Die Steuerung von Licht, Heizkörpern, Jalousien und Steckdosen werden von intelligenten Anwendungen übernommen, die aufs Wort hören und abhängig von Zeit oder Sensorwerten die Geräte steuern.

So geht morgens um 6 Uhr der Radiowecker an und das Licht wird im Schlafzummer immer heller. Spätestens um 6:30 Uhr gehen dann aber endgültig die Jalousien rauf und es riecht schon nach Kaffee aus der Küche. Alle Geräte sind miteinander verbunden oder wenigstens aus dem Internet über diverse mehr oder weniger sichere Cloud Dienste erreichbar.

Ich persönlich bin ein großer Fan dieser modernen Errungenschaften und versuche mein Leben mit Hilfe all dieser Gizmos zu vereinfachen oder zu verbessern. Doch es gibt noch immer so viele unzählige Geräte, die nicht über die Cloud erreichbar sind oder besser nicht erreichbar sein sollen. Dazu zählt z.B. das Schloss der Eingangstür oder andere sicherheitsrelevante Komponenten die nicht jedes Mal nach China funken sollen, wenn ein Ereignis eintrifft. Natürlich gibt es auch dafür Lösungen, aber ganz sicher ist man nur, wenn man es selbst macht.

12V 16 Kanal Bluetooth Relais Remote Control Switch Funkfernschalter

Hier kommt nun das 12V 16 Kanal Bluetooth Relais Remote Control Switch Funkfernschalter für Android ins Spiel. Diese Elektronik kann fertig aufgebaut bei Amazon oder Ebay für weniger als 30€ (Aktueller Preis bei ebay 25€) gekauft werden. Zusätzlich benötigt wird nur ein 12 Volt Netzteil, dass man auch für eine Handvoll Euro kaufen kann. Mit dem Board kann man dann bis zu 16 Relais Schalten. Wobei jeder Relais-Schalter mit 250V 10A belastete werden kann.

Jedes Relais verfügt über 3 Anschlüsse.

  • NO: Offenere Relais Schalter Kontakt
    Dieser Kontakt ist nicht mit COM verbunden, bis der Relais eingeschaltet wird
  • COM: Relais Schalter Eingang
    Com Port des Relais Schalters
  • NC: Geschlossener Relais Schalter Kontakt
    Der Kontakt ist mit COM verbunden, bis der Relais eingeschaltet wird. Dann wird die Verbindung unterbrochen.

Mit Hilfe eines “USB to TTL232” Adapters ist es möglich, das Bluetooth Modul zu konfigurieren. Neben dem BK3231 Bluetooth Board ist ein Male-Header mit den 3 Anschluss-Pinns RXD, TXD und GND. Über einen USB-TTL232 Adpater können hier AT-Kommandos mit einer fixen Budrate von 9600 BPS gesendet werden. Jedes AT-Kommando muss mit einem CRLF abgeschlossen werden.

Es gibt 3 Befehle, die von dem BK3231 Bluetooth Board unterstützt werden.

  • Test Kommando
    Befehl: AT
    Antwort: OK
    Parameter: Keine
    Das Test-Kommando dient nur dazu, um die Verbindung zu prüfen.
  • Bluetooth Name ändern
    Befehl: AT+NAME<Parameter>
    Antwort: +NAME=<Parameter>
    Parameter: Bluetooth Name
    Mit dem AT+NAME Befehle kann der Bluetooth Name geändert werden. Wird der Name nicht geändert ist das Bluetooth Modul unter dem Namen „SPP-CA“ sichtbar.
  • Bluetooth Pairing Code ändern
    Befehl: AT+PIN<Parameter>
    Antwort: +PIN=< Parameter>
    Parameter: Pairing Code

    Wird der Pin Code nicht geändert, ist der Default Pin-Code 1234. Es ist aber sinnvoll, diesen vor dem Einsatz im Live-Betrieb zu ändern, da sonst kein Schutz vor unberechtigtem Zugriff existiert.

Das Board kommt mit einer Reihe von Word Dokumenten, die sich auf ein 8 Relais Board beziehen. Recherchiert man etwas im Netz, findet man schnell heraus, dass der BK3231 Bluetooth Chip aber noch mehr AT-Befehle verseht, auf die ich hier aber nicht weiter eingehen werde.

Zusätzlich zu der Doku bekommt man auch noch ein paar kleinere APK Dateien die man auf einem Android Handy installieren kann.

  • 4CH Bluetooth APP V1.apk
  • 4CH Bluetooth APP V2.apk
  • 4CH Bluetooth APP V3.apk

Der Name lässt es schon erahnen. Die Android Apps heißen 4 Channel Bluetooth App. Das in dem Word Dokument angegebene Video https://www.youtube.com/watch?v=WLZYHfcZi2E zeigt, dass die Apps aber universell einsetzbar sind, da die Buttons frei mit Codes definiert werden können. Die Steuerung ist denkbar einfach. Es muss nur ein Code an das Bluetooth Modul gesendet werden, um eine Relais zu aktivieren oder zu deaktivieren. Jedes der 16 Relais auf dem Board hat einen eigenen Channel, der von A bis P adressiert wird. Und jeder Channel kann die Befehle 0-4 verarbeiten. Wobei die Nummern folgende Bedeutung haben.

  • 0: (Momentary)
    Relais-Schalte für einen kurzen Moment schließen und sofort wieder öffnen
  • 1: (Self-locking)
    Relais wird getoggelt. Ist das Relais vorher an wird es ausgeschaltet. Ist es aus wird es eingeschaltet.
  • 2: (Interlock)
    Schließ das entsprechende Relais und öffnet gleichzeitig alle anderen.
  • 3: (Open)
    Relais-Schalter öffnen
  • 4: (Close)
    Relais-Schalter schließen

Sendet man also den Befehl „A4“ per Bluetooth an den BK3231 Chip wird das Relais Nummer 1 geschlossen, sendet man B2 wird Relais 2 geschlossen und alle anderen geöffnet etc..

Das Ganze habe ich dann in eine Android App gegossen und schon ist eine simple Beispielanwendung fertig, mit der man bis zu 16 Geräte schalten kann, ohne dass man Angst haben muss, dass jeder im Internet mithören kann. Da die Kommunikation auf Bluetooth basiert was eine Reichweite von ca. 10 Metern hat. Dank der Open Source App kann man sich auch den Quellcode in Ruhe ansehen und sicher sein, dass die App keine Daten durch das Netz versendet.

Das Github Repository zu dem 16 Kanal Bluetooth Relais Remote Switch Funkfernschalter für Android ist unter https://github.com/msoftware/Eletechsup-BT22A16-App zu finden. Diese App habe ich ausschließlich für das „eletechsup BT22A16 16 Channel Bluetooth Relay“ Board realisiert. Es ist gut möglich, dass diese App auch mit anderen SPP-S kompatiblen Bluetooth Relais Boards anderer Hersteller funktioniert, aber evtl. müssen hier einige Anpassungen in Bezug auf die Befehle gemacht werden.

Android App

Die Android App zum Steuern des 16 Kanal Bluetooth Relais Boards besteht aus 2 Activities. Die MainActivity enthält alle Buttons mit denen pro Relais die 5 Funktionen (0-4) aufgerufen werden können. Mit der DeviceList Activity wird das Bluetooth Device ausgewählt. Bevor das Bluetooth Relais Borard ausgewählt werden kann, muss es in den Bluetooth Settings des Handys gekoppelt werden. Dies erfolgt mit dem Pin Code 1234. Der Pin Code kann aber über das entsprechende AT-Kommando geändert werden.

Wird in der DeviceList ein Gerät ausgewählt, wird die Mac-Adresse des Bluetooth Devices an die Main Activity zurückgegeben und eine Verbindung hergestellt. Der Java-Code für die Bluetooth Verbindung befindet sich in der Klasse Bluetooth.java.

Die Bluetooth.java Klasse enthält alle Funktionen um eine Verbindung mit einem SPP Bluetooth herzustellen, die Verbindung zu trennen und Daten zu senden. Eine zusätzliche Library ist hier nicht nötig. Auch der für Bluetooth SPP typische UUID String „00001101-0000-1000-8000-00805F9B34FB“ befindet sich in der Bluetooth Klasse.

package com.jentsch.bluetooth.relay.board.bt22a16;

import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;

import java.io.IOException;
import java.util.UUID;

public class Bluetooth {

    private BluetoothActivity bluetoothActivity;

    BluetoothAdapter myBluetooth = null;
    BluetoothSocket btSocket = null;

    public boolean isBtConnected() {
        return isBtConnected;
    }

    private boolean isBtConnected = false;
    static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    String address = null;

    SharedPreferences sharedPreferences;
    SharedPreferences.Editor editor;

    public Bluetooth(BluetoothActivity bluetoothActivity) {
        this.bluetoothActivity = bluetoothActivity;
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(bluetoothActivity);
        editor = sharedPreferences.edit();

        IntentFilter disconnectedFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        bluetoothActivity.registerReceiver(mReceiver, disconnectedFilter);

        address = sharedPreferences.getString("address", "undefined");
        if (!address.equals("undefined"))
            new ConnectBT().execute();
    }

    public void setAddress (String address)
    {
        this.address = address;
        editor.putString("address", address).commit();
        new ConnectBT().execute();
    }

    //The BroadcastReceiver that listens for bluetooth broadcasts
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                disconnected(true);
            }
        }
    };

    public void btSendData(String s) {
        String lineBreak = "\n";
        if (isBtConnected) {
            try {
                btSocket.getOutputStream().write((s + lineBreak).getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            bluetoothActivity.msg("Bluetooth is not connected.");
        }
    }

    public void disconnect() {
        bluetoothActivity.unregisterReceiver(mReceiver);
        if (btSocket != null) {
            try {
                btSocket.getInputStream().close();
                btSocket.getOutputStream().close();
                btSocket.close(); //close connection
                disconnected(false);
            } catch (IOException e) {
                bluetoothActivity.msg("Error.");
            }
        } else {
            bluetoothActivity.msg("Bluetooth is not connected.");
            disconnected(false);
        }
    }

    private void disconnected (boolean notify)
    {
        isBtConnected = false;
        btSocket = null;
        bluetoothActivity.disconnected(notify);
    }

    private class ConnectBT extends AsyncTask<Void, Void, Void>  // UI thread
    {
        private boolean ConnectSuccess = true;

        @Override
        protected void onPreExecute() {
            ProgressDialog progress = ProgressDialog.show(bluetoothActivity, "Connecting...", "Please wait.");
            bluetoothActivity.setProgress(progress);
        }

        @Override
        protected Void doInBackground(Void... devices) {
            try {
                if (btSocket == null || !isBtConnected) {
                    myBluetooth = BluetoothAdapter.getDefaultAdapter();
                    BluetoothDevice btService = myBluetooth.getRemoteDevice(address);
                    btSocket = btService.createInsecureRfcommSocketToServiceRecord(myUUID);
                    BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
                    btSocket.connect();
                }
            } catch (IOException e) {
                ConnectSuccess = false;
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            if (!ConnectSuccess || btSocket == null) {
                bluetoothActivity.msg("Connection Failed.");
            } else {
                isBtConnected = true;
                bluetoothActivity.connected(true);
                try {
                    btSocket.getOutputStream().write("c\n".getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (NullPointerException e) {
                    disconnect();
                    new ConnectBT().execute();
                }
            }
            bluetoothActivity.dismissProgress();
        }
    }
}
package com.jentsch.bluetooth.relay.board.bt22a16;

import android.app.ProgressDialog;
import android.support.v7.app.AppCompatActivity;

abstract class BluetoothActivity extends AppCompatActivity {
    public abstract void connected (boolean notify);
    public abstract void disconnected (boolean notify);
    public abstract void msg(String s);
    public abstract void setProgress(ProgressDialog show);
    public abstract void dismissProgress();
}

Technische Details über das Board

Beschäftigt man sich ein wenig mit dem Board findet man schnell ein paar Details der Hardware heraus. So ist z.B. der BK3231 Chip auf dem Bluetooth SPP Board nicht besonders intelligent. Er übernimmt nur die Bluetooth Kommunikation zwischen dem Smartphone und dem eigentlichen Prozessor auf dem Bord (STC 15W204S). Einem 8-Bit Microkontroller basierend auf der 8051 Architektur (http://www.stcmcu.com/datasheet/stc/STC-AD-PDF/STC15-English.pdf) . Dieser übernimmt die Befehle (A0, B2, F4, etc.) und steuert darüber die 2 Schieberregister (74HC595) an. Mit einem 74HC595 Schieberegister lassen sich maximal 8 Ausgangspins gleichzeitig ansteuern. Durch die Kaskadierung von 2 Schieberegistern wird es möglich, 16 Relais anzusteuern. Da der 74HC595 für die Spule des Relais nicht genug Strom liefern kann, wird zwischen jeden Ausgang des Schieberegisters und das zugehörige Relais noch eine Darlington-Schaltung als Verstärker geschaltet. Jeder der zwei ULN2803 Chips enthält 8 Darlington-Schaltungen, die jeweils bis zu 500mA liefern können. Das ist mehr als ausreichend für die Relais-Spulen. Damit ist auch schon alles Wesentliche auf dem 12V – 16 Kanal Bluetooth Relay Remote Funkfernschalter Board gesagt. Zum Schluss noch ein kleines Video und eine Reihe von Bildern von der Beispielimplementierung der hier beschriebenen App und dem Board.

http://www.spezial.cz/pdf/Serial_Port_Adapter_AT_Commands.pdf