React Native Smart Switch App – Arduino – Part 2

This is second part of React Native Smart Switch App – Arduino tutorial series. You can check the first part of tutorial here . In the first part we create an app to turn bluetooth on and off and also detect the paired bluetooth devices. In this part of tutorial we will take things further and establish connection with bluetooth device and app. Also, send signal to control the device.

Lets first create bluetooth gadget that we will control with our app. Following are the things we will need to create a simple bluetooth gadget :

1) Arduino Uno board

2) USB cable

3) 6 male to male jumper cables

4) one 220ohm resistor

5) one LED light

6) breadboard (400 tie-point)

7) Bluetooth Module (HC-05/HM-10)

Now connect the 5v and ground of Arduino with 5v and ground of bluetooth module. Connect RX and TX of Aurdino with TX and RX of Bluetooth module respectively. Connect ground of Arduino with  anode of LED  and pin 13 of Aurdino with one side of 220 ohm resistor. Connect the other side of resistor with cathode of LED.

Now disconnect the RX and TX jumper cable from Arduino and upload the following code to it.

int flag = 0;
void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);

}

void loop() {
  // put your main code here, to run repeatedly:
  if(Serial.available() > 0){
    char data = Serial.read();
    //Serial.println(data);
    if(data == 'T'){
      if(flag == 0){
        digitalWrite(LED_BUILTIN,HIGH);
        flag = 1;
      }else{
        digitalWrite(LED_BUILTIN,LOW);
        flag = 0;
      }
    }
  }

}

Now reconnect the jumper cables back as it was.

In the above code, we have set pin 13 as output pin so that it glows the LED when we send signal for it. We have set the speed of (bluetooth) communication to 9600 baud (bits per second). In the loop we first check if some data is available and read the data. On every transmission of data (i.e. ‘T’) we just toggle the state of the output pin.

Now modify the React Native App code so that it is like the code below :

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  Button,
  FlatList,
  Switch,
  TouchableOpacity,
  ToastAndroid
} from 'react-native';
var _ = require('lodash');
import BluetoothSerial from 'react-native-bluetooth-serial'

export default class App extends Component<{}> {
  constructor (props) {
    super(props)
    this.state = {
      isEnabled: false,
      discovering: false,
      devices: [],
      unpairedDevices: [],
      connected: false,
    }
  }
  componentWillMount(){

    Promise.all([
      BluetoothSerial.isEnabled(),
      BluetoothSerial.list()
    ])
    .then((values) => {
      const [ isEnabled, devices ] = values

      this.setState({ isEnabled, devices })
    })

    BluetoothSerial.on('bluetoothEnabled', () => {

      Promise.all([
        BluetoothSerial.isEnabled(),
        BluetoothSerial.list()
      ])
      .then((values) => {
        const [ isEnabled, devices ] = values
        this.setState({  devices })
      })

      BluetoothSerial.on('bluetoothDisabled', () => {

         this.setState({ devices: [] })

      })
      BluetoothSerial.on('error', (err) => console.log(`Error: ${err.message}`))

    })

  }
  connect (device) {
    this.setState({ connecting: true })
    BluetoothSerial.connect(device.id)
    .then((res) => {
      console.log(`Connected to device ${device.name}`);
      
      ToastAndroid.show(`Connected to device ${device.name}`, ToastAndroid.SHORT);
    })
    .catch((err) => console.log((err.message)))
  }
  _renderItem(item){

    return(<TouchableOpacity onPress={() => this.connect(item.item)}>
            <View style={styles.deviceNameWrap}>
              <Text style={styles.deviceName}>{ item.item.name ? item.item.name : item.item.id }</Text>
            </View>
          </TouchableOpacity>)
  }
  enable () {
    BluetoothSerial.enable()
    .then((res) => this.setState({ isEnabled: true }))
    .catch((err) => Toast.showShortBottom(err.message))
  }

  disable () {
    BluetoothSerial.disable()
    .then((res) => this.setState({ isEnabled: false }))
    .catch((err) => Toast.showShortBottom(err.message))
  }

  toggleBluetooth (value) {
    if (value === true) {
      this.enable()
    } else {
      this.disable()
    }
  }
  discoverAvailableDevices () {
    
    if (this.state.discovering) {
      return false
    } else {
      this.setState({ discovering: true })
      BluetoothSerial.discoverUnpairedDevices()
      .then((unpairedDevices) => {
        const uniqueDevices = _.uniqBy(unpairedDevices, 'id');
        console.log(uniqueDevices);
        this.setState({ unpairedDevices: uniqueDevices, discovering: false })
      })
      .catch((err) => console.log(err.message))
    }
  }
  toggleSwitch(){
    BluetoothSerial.write("T")
    .then((res) => {
      console.log(res);
      console.log('Successfuly wrote to device')
      this.setState({ connected: true })
    })
    .catch((err) => console.log(err.message))
  }
  render() {

    return (
      <View style={styles.container}>
      <View style={styles.toolbar}>
            <Text style={styles.toolbarTitle}>Bluetooth Device List</Text>
            <View style={styles.toolbarButton}>
              <Switch
                value={this.state.isEnabled}
                onValueChange={(val) => this.toggleBluetooth(val)}
              />
            </View>
      </View>
        <Button
          onPress={this.discoverAvailableDevices.bind(this)}
          title="Scan for Devices"
          color="#841584"
        />
        <FlatList
          style={{flex:1}}
          data={this.state.devices}
          keyExtractor={item => item.id}
          renderItem={(item) => this._renderItem(item)}
        />
        <Button
          onPress={this.toggleSwitch.bind(this)}
          title="Switch(On/Off)"
          color="#841584"
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
  },
  toolbar:{
    paddingTop:30,
    paddingBottom:30,
    flexDirection:'row'
  },
  toolbarButton:{
    width: 50,
    marginTop: 8,
  },
  toolbarTitle:{
    textAlign:'center',
    fontWeight:'bold',
    fontSize: 20,
    flex:1,
    marginTop:6
  },
  deviceName: {
    fontSize: 17,
    color: "black"
  },
  deviceNameWrap: {
    margin: 10,
    borderBottomWidth:1
  }
});

In the above code, we are turning bluetooth on and off on tapping of Switch control. When bluetooth is tuned on it detects the nearby visible bluetooth devices. Once we find our device in the list, we tap on it and establish connection. Now when we tap the Switch button it turns LED on and if we tap again LED is turned off.

Video Tutorial