8 Android, Arduino, ESP-01, and NodeMCU ESP-12E Wireless Sensor and Remote Control Projects – A DIY Smart Home Guide: Tools for Automating Your Home Monitoring and Security Using Arduino, ESP8266, and Android

CHAPTER 8

Android, Arduino, ESP-01, and NodeMCU ESP-12E Wireless Sensor and Remote Control Projects

In this chapter I cover wireless projects that involve the Android, Arduino with ESP-01, and the NodeMCU. I start off covering the ArduCAM Mini OV2640 2MP Plus camera which is a newer version of the ArduCAM camera that I covered earlier in the book. I then use this updated camera version in a hands-on example that involves a wireless Arduino-based video surveillance system. Next, I expand on this Arduino server-based framework in another hands-on example where I add an infrared motion sensor and an alarm system. This new system is able to take a photo whenever the motion sensor is tripped and to send this image to the Android controller for display. Next, I discuss a multi-client basic framework that is based on the NodeMCU server and Arduino clients. I then give a general overview of version 2.0 of the basic wireless framework program for Android. Next, I present the additional code needed for the Android basic wireless framework version 2.0. Then I cover the new basic framework version 2.0 for the NodeMCU server. Next, I show an example of setting up the Arduino for station/client mode. The rest of the chapter is then dedicated to using hands-on examples to illustrate the NodeMCU server and the multi-client system.

The hands-on examples relating to the NodeMCU server-based systems are as follows:

   Hands-on example: The ArduCAM OV2640 2MP Mini Plus camera Arduino Mega 2560 client surveillance system with NodeMCU server

   Hands-on example: The ArduCAM OV2640 2MP Mini Plus infrared motion detection Arduino Mega 2560 client surveillance and alarm system with NodeMCU server

   Hands-on example: The infrared motion detection alarm system using the NodeMCU server

   Hands-on example: The ArduCAM OV2640 2MP Mini Plus and infrared motion detection Arduino Mega 2560 client surveillance and alarm system with NodeMCU server with an infrared motion detection alarm system

The ArduCAM Mini OV2640 2MP Plus

The ArduCAM Mini OV2640 2MP Plus is a more recent version of the Mini OV2640. The important thing to take note of is that there appears to be a hardware change that requires a software change in order to correctly read in an image from the camera’s FIFO memory. The front of this camera is shown in Figure 8-1.

Figure 8-1   The ArduCAM Mini OV2640 2 MP Plus digital camera.

Hands-on Example: The Wireless ArduCAM Mini 2MP Plus Camera Surveillance System

This hands-on example covers the building and the operation of an ArduCAM Mini OV2640 2MP Plus digital camera-based surveillance system.

Parts List

   1 Android cell phone

   1 Arduino Mega 2560 microcontroller

   1 5- to 3.3-V step-down voltage regulator

   1 Logic level converter from 5 to 3.3 V

   1 ESP-01 Wi-Fi module

   1 Arduino development station such as a desktop or a notebook

   1 Breadboard

   1 ArduCAM OV2640 Mini Plus camera

   1 Package of wires both male-to-male and female-to-male to connect the components

Setting Up the Hardware

Step-Down Voltage Regulator Connections

1.   Connect the Vin pin on the voltage regulator to the 5-V power pin on the Arduino Mega 2560.

2.   Connect the Vout pin on the voltage regulator to a node on your breadboard represented by a horizontal row of empty slots. This is the 3.3-V power node that will supply the 3.3-V power to the ESP-01 module as well as provide the reference voltage for the logic level shifter.

3.   Connect the GND pin on the voltage regulator to the GND pin on the Arduino or form a GND node similar to the 3.3-V power node in the previous step.

ESP-01 Wi-Fi Module Connections

1.   Connect the Tx or TxD pin to the Rx3 pin on the Arduino Mega 2560. This is the receive pin for the serial hardware port 3.

2.   Connect the EN or CH_PD pin to the 3.3-V power node from the step-down voltage regulator.

3.   Connect the IO16 or RST pin to the 3.3-V power node from the step-down voltage regulator.

4.   Connect the 3V3 or VCC pin to the 3.3-V power node from the step-down voltage regulator.

5.   Connect the GND pin to the ground pin or node.

6.   Connect the Rx or RxD pin to pin B0 on the 3.3-V side OF the logic level shifter. The voltage from this pin will be shifted from 5 V from the Arduino to 3.3 V for the ESP-01 module.

Logic Level Shifter

1.   Connect the 3.3-V pin to the 3.3-V power node from the step-down voltage regulator.

2.   Connect the GND pin on the 3.3-V side to the ground node for the Arduino.

3.   Connect the B0 pin on the 3.3-V side to Rx or RxD pin on the ESP-01. This corresponds to the A0 pin on the 5-V side.

4.   Connect the 5-V pin to the 5-V power pin on the Arduino.

5.   Connect the GND pin on the 5-V side to the ground node for the Arduino.

6.   Connect the A0 pin on the 5-V side to Tx3 pin on the Arduino. This pin corresponds to the B0 pin on the 3.3-V side.

ArduCAM OV2640 Mini Plus

1.   Connect the CS pin to digital pin 8 on the Arduino.

2.   Connect the SDA pin to digital pin 20 on the Arduino.

3.   Connect the SCL pin to digital pin 21 on the Arduino.

4.   Connect the MISO pin to digital pin 50 on the Arduino.

5.   Connect the MOSI pin to digital pin 51 on the Arduino.

6.   Connect the SCK pin to digital pin 52 on the Arduino.

7.   Connect the VCC pin to the 5-V node for the circuit.

8.   Connect the GND pin to the common ground node for the circuit.

See Figure 8-2.

Figure 8-2   The ArduCAM OV2640 Mini Plus surveillance system.

Setting Up the Software

The code for the ArduCAM Mini Plus camera surveillance system is the same as for the older version of the Mini camera presented earlier in the book except for some of the code in the ReadFifoBurst() function that controls how the image from the camera’s frame buffer is read in.

The ReadFifoBurst() Function

The ReadFifoBurst() function is modified to accommodate the ArduCAM Mini Plus camera. The key change is that the image header is now checked for. In the older version of the camera the first byte read in was a dummy byte that was not part of the image data. In the new version of the camera the first byte may be part of the image header. Thus, the old code would need to be modified.

See Listing 8-1. The code changes are highlighted in bold print.

Operating the System

Download the ArduCAM Mini Plus server version project for this chapter and install it on your Arduino. This camera system operates the same way as the camera surveillance system using the older ArduCAM mini version presented earlier in this book.

Hands-on Example: The Wireless ArduCAM Mini OV2640 2MP Plus Camera and HC-SR501 Infrared Motion Detector Surveillance and Alarm System for the Arduino Mega 2560 Server

In this hands-on example I will show you how to build and operate a wireless surveillance and alarm system for an Arduino Mega 2560 server using an ArduCAM OV2640 Mini 2MP Plus camera and HC-SR501 infrared motion detector. An Android cell phone will be used as the wireless controller for the system.

Parts List

   1 Android cell phone

   1 Arduino Mega 2560 microcontroller

   1 5- to 3.3-V step-down voltage regulator

   1 Logic level converter from 5 to 3.3 V

   1 ESP-01 Wi-Fi module

   1 Arduino development station such as a desktop or a notebook

   1 Breadboard

   1 ArduCAM OV2640 Mini Plus camera

   1 HC-SR501 infrared motion detector

   1 Package of wires to connect the components

Setting Up the Hardware

Step-Down Voltage Regulator Connections

1.   Connect the Vin pin on the voltage regulator to the 5-V power pin on the Arduino Mega 2560.

2.   Connect the Vout pin on the voltage regulator to a node on your breadboard represented by a horizontal row of empty slots. This is the 3.3-V power node that will supply the 3.3-V power to the ESP-01 module as well as provide the reference voltage for the logic level shifter.

3.   Connect the GND pin on the voltage regulator to the GND pin on the Arduino or form a GND node similar to the 3.3-V power node in the previous step.

ESP-01 Wi-Fi Module Connections

1.   Connect the Tx or TxD pin to the Rx3 pin on the Arduino Mega 2560. This is the receive pin for the serial hardware port 3.

2.   Connect the EN or CH_PD pin to the 3.3-V power node from the step-down voltage regulator.

3.   Connect the IO16 or RST pin to the 3.3-V power node from the step-down voltage regulator.

4.   Connect the 3V3 or VCC pin to the 3.3-V power node from the step-down voltage regulator.

5.   Connect the GND pin to the ground pin or node.

6.   Connect the Rx or RxD pin to pin B0 on the 3.3-V side of the logic level shifter. The voltage from this pin will be shifted from 5 V from the Arduino to 3.3 V for the ESP-01 module.

Logic Level Shifter

1.   Connect the 3.3-V pin to the 3.3-V power node from the step-down voltage regulator.

2.   Connect the GND pin on the 3.3-V side to the ground node for the Arduino.

3.   Connect the B0 pin on the 3.3-V side to Rx or RxD pin on the ESP-01. This corresponds to the A0 pin on the 5-V side.

4.   Connect the 5-V pin to the 5-V power pin on the Arduino.

5.   Connect the GND pin on the 5-V side to the ground node for the Arduino.

6.   Connect the A0 pin on the 5-V side to Tx3 pin on the Arduino. This pin corresponds to the B0 pin on the 3.3-V side.

ArduCAM OV2640 Mini Plus

1.   Connect the CS pin to digital pin 8 on the Arduino.

2.   Connect the SDA pin to digital pin 20 on the Arduino.

3.   Connect the SCL pin to digital pin 21 on the Arduino.

4.   Connect the MISO pin to digital pin 50 on the Arduino.

5.   Connect the MOSI pin to digital pin 51 on the Arduino.

6.   Connect the SCK pin to digital pin 52 on the Arduino.

7.   Connect the VCC pin to the 5-V node for the circuit.

8.   Connect the GND pin to the common ground node for the circuit.

The HC-SR501 Infrared Motion Detector

1.   Connect the Vcc pin on the motion detector to the 5-V power node on the Arduino Mega 2560.

2.   Connect the GND pin on the motion detector to the GND node on the Arduino.

3.   Connect the Out pin on the motion detector to digital pin 7 on the Arduino.

See Figure 8-3.

Figure 8-3   The wireless surveillance and infrared motion detection system.

Setting Up the Software

The key code change for this example is that when the alarm is tripped the number of hits will be updated but no text string will be sent to the Android device. The Android device must now poll the alarm system to determine if the alarm has been tripped. The ProcessSensor() function is changed to reflect this. The code that handles the tripping of the alarm system is shown in bold print in Listing 8-2. The code that sends a text string to the Android indicating that the alarm has been tripped has been removed.

The hits command is changed slightly so that the beginning of the return value of a hits command starts with "HITS DETECTED:" followed by the number of times that alarm system has been tripped. See Listing 8-3.

The reset command is modified by removing the code that returns an acknowledgment string to the Android. See Listing 8-4.

Operating the System

Download and install on your Android device the basic framework application version 2.0. There should be an Android Studio version and a directly installable Android APK file. Next, download and install on your Arduino device the “ArducamMiniPlus-MotionDetector-ESP01-Server.ino” project file for this chapter. Bring up the Arduino’s Serial Monitor. You should see something similar to the following:

Connect your Android cell phone to the access point located on the ESP-01 module. Start up the Android basic framework application version 2.0. Connect to the TCP server running on the ESP-01 module using the application. On the Serial Monitor you should see the Android connecting to the server. The name of the Android device should be changed to the name that you have specified for the wireless network. In my case the name of my Android device is “verizon”. Finally, an “OK” string should be sent back to the Android device indicating that the name change was successful.

With the new version of the Android basic wireless framework you will be able to select the network device or target that you will send commands to. The default target for commands is the server which you just connected to. Select “Monitor Target Device” to select the server as one of the devices that will be monitored. Select the “Camera Status Target Device” menu item and select “Set to Camera Available” to have the camera on the server take a photo whenever the motion detector is tripped. Turn off the call out and the emergency text message options.

Next, activate the alarm system on the server using the Android application. After the default wait time of 10 seconds the alarm is activated.

Next, under the “Network Monitoring” menu select the “Activate Network Monitoring” option to start the monitoring of the alarm status of the monitored devices that were selected previously. In this case it would be just the server that has the motion detector and the camera. A hits command is sent to the server to determine if the alarm has been tripped. If the return value is 0 then no motion has been detected.

Next, trip the alarm by putting your hand in front of the motion sensor and camera and moving it around. Once the alarm has been tripped then the next hits command should return a nonzero number of hits that have been detected.

Next, after processing the “HITS DETECTED” value a reset command is issued to the server to set the number of alarm trips back to zero.

Next, since the server has a camera a take photo command is issued to the server. In my case the camera resolution was set to qvga so a qvga command was sent to the server. The Arduino receives this command, takes the photo, and sends back the size in bytes of the image that was taken. In my case the number of bytes was 6152.

Next, a GetImageData command is issued by the Android to the server in order to retrieve the actual image data. The Arduino receives this command and sends the data in chunks up to the maximum allowable packet size which is 2048.

Test out the alarm a few more times to verify that the motion detector and image capture features of the alarm system work correctly.

Finally, turn off the network monitoring and then deactivate the alarm using the Android application.

The Basic Android, Arduino with ESP-01, and NodeMCU Wireless Multi-Client Framework

In this section I will give an overview of the multi-client framework where one Android cell phone can serve as the controller for multiple devices. These devices can have sensors and alarm systems on them and can be controlled and monitored from the Android device. The server for our multi-client wireless framework will be the NodeMCU. The NodeMCU will be able to connect up to 4 clients at one time. One of the clients will be the Android controller. The alarm system on each device can be polled by the Android controller. If the alarm on the device has been tripped then an emergency text message can be sent out and if the device has a camera then a picture can be taken of the object that caused the alarm to be tripped. See Figure 8-4.

Figure 8-4   An example of the Android, Arduino with ESP-01, and NodeMCU basic wireless multi-client framework.

Overview of the Android Basic Wireless Framework Version 2.0 Application

For the 2.0 version of the Android basic wireless framework you can get a list of clients that are connected to the server. You are also able to switch the destination device for the commands you send using the application to one of these clients or to the server. The destination device that will receive the commands is called the “Target”. In Figure 8-5 the target device is circled and is by default the server.

Figure 8-5   The targeted device on Android basic wireless framework 2.0.

In order to find the clients that are currently connected to the server you would select the “Refresh Clients” menu item. To select one of the clients that are connected to the server or the server itself as the target device you would select the “Switch Target Device” menu item and then select the device you want to send commands to.

Another key change is that the alarm systems located on devices will not automatically send a text string to the Android controller when an alarm is tripped. Instead they will have the status of their alarms polled so that they will send the Android controller the number of alarm trips that have occurred since the last time the device was polled. To select a device for monitoring you must first choose the device as the target and then select “Monitor Target Device” to put this in a list of devices that will have the status of their alarms monitored. To remove a device from the list of monitored devices select the device as the target and select “Unmonitor Target Device” from the menu. If the monitored device has a camera then you can select the “Set To Camera Available” menu option under the “Camera Status Target Device” menu to take a picture whenever the alarm is tripped on the device. Figure 8-6 shows that both the device called client1 which has a camera and the device that is the server which does not have a camera will be monitored for changes in their alarm tripped status.

Figure 8-6   The devices that will be monitored for alarm tripped status.

To activate the monitoring of the wireless network select the “Activate Network Monitoring” under the “Network Monitoring” menu item. This will determine if the alarm in each device in the monitored devices list has been tripped by sending a hits command. If the hits command returns a 1 or greater value then the alarm has been tripped. If the alarm was tripped then send a reset command to the device to set the total number of trips back to 0. If the device has a camera then take a photo with the camera and send this photo back to the android for display. While the wireless network of devices is being monitored the lower right window displays the device being polled and a picture will be taken with a camera located on this device when an intruder is detected. See Figure 8-7.

Figure 8-7   Polling a device when network monitoring is on.

Code Additions for the Android Basic Wireless Framework Version 2.0

This section covers the addition code for version 2.0 of the Android basic wireless framework.

The MaxClients variable holds the maximum number of clients that can be connected to the server which is by default 4.

int MaxClients = 4;

The m_NumberClients variable holds the current number of clients that are connected to the server and is set by default to 0. Refreshing the clients will update this variable to the current status.

int m_NumberClients = 0;

The m_Clients variable is an array of strings that represents the names of the clients that are currently connected to the server.

The m_TargetDevice variable holds the name of the network device being sent commands from the Android basic wireless framework application and is set by default to the server.

String m_TargetDevice = "Server";

The m_NetworkGroupID variable holds the group ID of a client that is connected to the server and is used in selecting a target device by the user.

int m_NetworkGroupID = 11;

The m_NetworkItemID variable holds the ID of a client that is connected to the server. This is set to the same value for all clients.

int m_NetworkItemID = 22;

The m_NetworkMonitoringOn variable is true when network monitoring is on and the devices in the monitored devices list are being polled for their alarm status. The default value is set to false.

boolean m_NetworkMonitoringOn = false;

The PollingState enumeration describes the polling state of the devices in the monitored devices list.

The Max_Monitored_Devices variable holds the maximum number of devices that can be monitored which is the maximum number of clients that are able to connect to the server plus the server itself.

The m_MonitoredDevices variable holds an array of strings that represents the names of the devices that will have their alarm systems monitored for alarm trips.

The m_CameraAvailability variable holds the availability status for the camera that may be attached to a monitored device.

The m_MonitoredDevicesPollingState variable holds the current polling state of the monitored devices.

The m_MonitoredDevicesAvailability variable holds the availability state of the corresponding slot in the m_MonitoredDevices variable array. A value of true indicates that the slot in the m_MonitoredDevices array is available and a value of false indicates that the slot is unavailable and already contains a valid device.

The m_NumberValidMonitoredDevices variable holds the number of valid devices held in the m_MonitoredDevices array.

int m_NumberValidMonitoredDevices = 0;

The m_ValidMonitoredDevices variable holds the indices from the m_MonitoredDevices array that represents valid devices.

The m_CurrentPolledDevice variable holds a number that represents the current device being polled and is used as an index into the m_ValidMonitoredDevices array that returns a number that is used again as an index into the m_MonitoredDevices array to determine the name of the device currently being polled.

int m_CurrentPolledDevice = 0;

The m_PollingTimeOut variable holds the time in milliseconds that polling will time out for a device if no response is received. The polling time out value is set by default to 30 seconds.

The m_TimeBeginPoll variable holds the time just before a device starts to be polled.

long m_TimeBeginPoll = 0;

The m_PollingTakePhoto variable is true if the current device that is being polled has been set by the user to have a camera activated for taking a photo after the alarm has been tripped.

boolean m_PollingTakePhoto = false;

The m_MonitorDevicesHandler variable is the alarm monitoring handler for the devices in the monitored devices’ list. It is called repeatedly at fixed time intervals if network monitoring is activated.

The m_MonitoredDevicesRunnable variable holds the actual code that is executed during the network monitoring of devices in the monitored devices list.

The m_MonitoredDevicesInterval variable holds the time between processing of the devices in the monitored devices list and is set by default to 1000 milliseconds or 1 second.

Modifying the onCreate() Function

The onCreate() function in the MainActivity class is modified.

The m_MonitoredDevicesRunnable variable is defined here and the function that is defined is the run() function which does the following:

1.   Handles the polling of the devices in the monitored devices’ list by calling the NetworkAlarmPollingHandler() function.

2.   If network monitoring is active then the monitor devices’ handler executes this run() function again after m_MonitoredDevicesInterval number of microseconds.

See Listing 8-5.

The data structures that are used to keep track of the devices that need to be tracked for network monitoring are initialized by calling the InitMonitoredDevicesDataStructure() function.

The NetworkAlarmPollingHandler() Function

The NetworkAlarmPollingHandler() function monitors the alarm status of the devices in the monitored devices’ list by doing the following:

1.   If network monitoring is not on then exit the function.

2.   If the number of valid monitored devices is zero then exit the function.

3.   Gets the information for the device that is currently being polled or is set to be polled.

4.   If the device is currently not being polled then do the following:

1.   Save the current time as the time that the polling for this device has started.

2.   Update the polling state of this device to polling in progress.

3.   Set the target device to this current device that is being polled.

4.   Send a hits command to the microcontroller to retrieve the current state of the alarm system on the microcontroller.

5.   If the device is currently being polled then do the following:

1.   Calculate the elapsed time since the start of polling the device.

2.   If the elapsed time is greater than the timeout time then set the polling status of the device to not started and set the currently polled device to the next device in the list of monitored devices. If the next device index is greater or equal to the number of valid monitored devices then reset the next device index back to 0.

6.   If the polling of the device has finished then do the following:

1.   Set the currently polled device to the next device in the list of monitored devices. If the next device index is greater or equal to the number of valid monitored devices then reset the next device index back to 0.

2.   Set the poll status of the device that just finished polling to not started.

7.   Update the information window on the Android application by calling the UpdateCommandTextView() function.

See Listing 8-6.

The UpdateCommandTextView() Function

The UpdateCommandTextView() function is modified by doing the following:

1.   The list of monitored devices is retrieved by calling the GetMonitoredDevices() function.

2.   If network monitoring is on then display the current device that is being polled and if a photo is to be taken on the alarm tripping.

3.   Additions are made to the information window adding in network monitoring-related and monitored devices’ information.

See Listing 8-7. The additional code is shown in bold print.

The GetMonitoredDevices() Function

The GetMonitoredDevices() function returns a string that contains the list of devices that will have their alarm systems monitored when the network monitoring feature is turned on by the user.

See Listing 8-8.

The GetCurrentPolledDevice() Function

The GetCurrentPolledDevice() function returns the name of the device on the wireless network that is currently being polled by the Android controller. See Listing 8-9.

The InitMonitoredDevices DataStructure() Function

The InitMonitoredDevicesData Structure() function initializes the data structures needed for the list of devices that will have their alarm systems monitored during network monitoring. See Listing 8-10.

Menu Additions

For version 2.0 of the Android basic wireless framework we add in the following new main menu items:

1.   A "Refresh Clients" menu item.

2.   A "Switch Target Device" menu item.

3.   A "Monitor Target Device" menu item.

4.   An "Unmonitor Target Device" menu item.

5.   A "Camera Status Target Device" menu item.

6.   A "Network Monitoring" menu item.

See Listing 8-11.

The onOptionsItemSelected() Function

New menu items and code were added to the onOptionsItemSelected() function which include the following:

1.   Code was added to detect the user’s selection of a network device such as a client or server and to set the target device to this new selection.

2.   If the user selects the refresh clients menu item then retrieve the list of current clients connected to the server by calling the SendCommandToServer("list") function with the list command.

3.   If the user selects the switch target device menu item then a list of network devices is shown by calling the DisplayNetwork(item) function with the currently selected menu item as a parameter.

4.   If the user selects the monitor target device menu item then the current target device is added to the list of devices that will be monitored when network monitoring is turned on. A call to the AddDevice ToMonitoredDevices(m_TargetDevice) function with the target device as the parameter actually adds the device. The information window is also updated.

5.   If the user selects the unmonitor target device menu item then the current target device is removed from the list of devices that will be monitored when network monitoring is activated. The RemoveMonitoredDevice (m_TargetDevice) function with the target device set as the parameter is called to actually implement the removal. The information window is also updated.

6.   If the user selects the camera as being available to the target device and the target device is already being monitored then the camera status is changed by calling the SetCameraStatus(m_Target Device,true) function with the target device and the value true as parameters. The information window is also updated.

7.   If the user selects the camera as being unavailable to the target device and the target device is already being monitored then the camera status is changed by calling the SetCameraStatus(m_TargetDevice,false) function with the target device and false as parameters. The information window is also updated.

8.   If the user activates network monitoring then the network monitoring is turned on by doing the following:

1.   The number of valid monitored devices is determined by calling the GetValidMonitoredDevices() function.

2.   If the number of valid monitored devices is greater than 0 then set the global network monitoring variable to true, set the current polled device to 0, reset the polling state on all the monitored devices, and initialize the running of the monitored devices’ handler.

3.   Updating the information window.

9.   If the user deactivates network monitoring then the global network monitoring variable is set to false and the information window is updated.

See Listing 8-12. The new code is shown in bold print.

The DisplayNetwork Function

The DisplayNetwork function displays all the devices on the wireless network by doing the following:

1.   Retrieving the submenu from the current menuitem object.

2.   Deleting all the items in the submenu.

3.   Adding in the server as the first selection in the submenu.

4.   Adding in the clients that are connected to the server as the remaining submenu item selections.

See Listing 8-13.

The AddDeviceToMonitoredDevices() Function

The AddDeviceToMonitoredDevices() function adds a device to the list of devices that will be monitored when network monitoring is active by doing the following:

1.   Finding if the device is already in the list of monitored devices. If it is already in the list then exit the function.

2.   Finding an empty slot in the list of monitored devices’ array by calling FindMonitoredDeviceEmptySlot() function.

3.   If an empty slot exists then put the device name in the list of monitored devices and mark the slot as being not available.

See Listing 8-14.

The FindMonitoredDevice() Function

The FindMonitoredDevice() function attempts to find the input string that represents the name of the device. It returns a value of 0 or greater if the device is found which is the index where the device is located in the monitored devices array and –1 if it is not found.

See Listing 8-15.

The FindMonitored DeviceEmpty Slot() Function

The FindMonitoredDeviceEmptySlot() function returns the index of the first empty slot in the list of monitored devices m_MonitoredDevices or –1 if all the slots are full and contain valid devices. See Listing 8-16.

The RemoveMonitoredDevice() Function

The RemoveMonitoredDevice() function removes a device from the list of monitored devices and resets the slot that the device previously occupied to its default values. See Listing 8-17.

The SetCameraStatus() Function

The SetCameraStatus() function sets the availability of the camera on a device that is in the list of devices to be monitored by doing the following:

1.   Finding the index that the device is located in by calling the FindMonitoredDevice(device) function with the device name as the parameter.

2.   If the index is equal to or greater than 0 then the device is found, so set the corresponding value of the m_CameraAvailability array to the function’s input parameter variable status.

See Listing 8-18.

The GetValidMonitoredDevices() Function

The GetValidMonitoredDevices() function returns the number of valid devices that are in the list of monitored devices. It also fills the m_ValidMonitoredDevices array with the indices of the valid devices that are in the m_MonitoredDevices array. See Listing 8-19.

The ResetMonitoredDevices PollingState() Function

The ResetMonitoredDevicesPollingState() function resets the polling state of all the monitored devices to the not started state. See Listing 8-20.

The ReceiveDisplayTextData() Function

The ReceiveDisplayTextData() function receives incoming text data from the server and is modified for version 2.0 by doing the following:

1.   If the incoming data from the server contains the sub string "ActiveClients:" then call the SetClients(DataTrimmed) function with the incoming data to process the list of clients that are connected to the server.

2.   If the incoming data from the server contains the sub string "HITS DETECTED:" then this is the response to the hits command issued by the network monitoring handler from the device that is being polled. To process this data do the following:

1.   If network monitoring is not on then exit the function.

2.   Find the number of hits detected from the number after the colon in the string.

3.   If the number of hits is greater than 0 then do the following:

1.   Set the alarm to the tripped state.

2.   Play a sound effect to indicate that the alarm has been tripped.

3.   Process the alarm event by calling the ProcessAlarmTripped() function.

4.   Switch the target device to the device that is being polled.

5.   Send the reset command to set the number of hits to 0 on the target device by calling the SendCommand("reset") function with the “reset” string as the parameter.

6.   If a camera for the target device is available for use then do the following:

1.   Send a command to take a photo to the target device by calling the SendTakePhotoCommand() function.

2.   Set the PollingFinished variable to false since we are not done receiving data from the currently polled device. Specifically we still need to receive the image from the camera.

3.   Set the m_PollingTakePhoto to true to indicate the device that is currently being polled will take a photo.

4.   If polling is finished then set the polling status for the device currently being polled to finished.

See Listing 8-21. The new code is highlighted in bold print.

The SetClients() Function

The SetClients() function parses the input string which is the result of the list command. The function determines the number of clients as well as the name of each client which is put in the m_Clients array. The list of clients is also shown in the debug message window. See Listing 8-22.

Modifying the run() Function

The run() function is modified for version 2.0 of the basic wireless framework. The key code addition is in the code that handles the processing of a completed image data transfer. After the photo has finished being displayed then the polling status of the device that is currently being polled is changed to finished. See Listing 8-23. The code changes are highlighted in bold print.

Basic Framework 2.0 for the NodeMCU Server

This section covers the basic framework 2.0 code for the NodeMCU server which is designed to work with the Android basic wireless framework code version 2.0 in a multi-client environment that can transmit both text and binary data. This section will cover only the changes made from the previous version of the NodeMCU server.

The BinaryDataSource variable holds the name of client that will be the source of the binary data that will be transferred.

String BinaryDataSource = "";

The BinaryDataDest variable holds the name of the client that will receive the binary data that will be sent by the source.

String BinaryDataDest = "";

The BinaryDataSize variable is the size of the binary data to be transferred in bytes.

int BinaryDataSize = 0;

The TotalBinaryDataSent variable holds the total number of bytes that have been transmitted so far from the source client to the destination client.

int TotalBinaryDataSent = 0;

The BinaryMode variable is true if binary transfer mode is active and false otherwise.

boolean BinaryMode = false;

Modifying the ProcessIncoming ClientData() Function

The ProcessIncomingClientData() function processes incoming commands from clients.

The addition to this function involves recognizing and processing the command to specify a binary transfer mode. The format for the binary command is as follows:

BIN:DestClientName:SizeOfBinaryData

If an incoming command contains “BIN:” then start the processing for a binary command by doing the following:

1.   Set binary mode to true.

2.   Set the binary data source to the client that issued the BIN command.

3.   Process the binary command by calling the ProcessBinaryCommand(message) function by sending the function the portion of the command that is after the “BIN:” part of the incoming command string.

4.   Send a text string back to the calling client indicating the binary transfer mode has been enabled.

5.   Exit the function.

See Listing 8-24. The changes are highlighted in bold print.

The ProcessBinaryCommand() Function

The ProcessBinaryCommand() function parses the binary transfer command sent by the source client. The string that is parsed is of the form:

DestClientName:SizeOfBinaryData

The destination client name for the binary transfer and the size of the binary data in bytes are retrieved. Debug information is also printed out to the Serial Monitor. See Listing 8-25.

The ProcessConnectedClients() Function

The ProcessConnectedClients() function processes incoming data if it is available for all the clients that are connected to the server. Code is added to the function that processes binary data by doing the following:

1.   When data is available for reading from a connected client and if the client is the binary data source and binary mode is on then process the incoming binary data from the client by calling the ProcessBinaryData() function.

2.   Otherwise process the incoming data from the client as text data.

See Listing 8-26. The modifications are shown in bold print.

The ProcessBinaryData() Function

The ProcessBinaryData() function processes the incoming binary data from a client by doing the following:

1.   Find the indices in the Clients array that correspond to the client that is the binary data source and the client that is the binary data destination.

2.   While the source client has data that is available for reading then do the following:

1.   Read in a byte of the data from the source client.

2.   Write out a byte of data to the destination client.

3.   Update the total number of bytes of binary data transferred.

3.   If the total number of bytes transferred is greater than or equal to the size of the binary data that is to be transferred then do the following:

1.   Print out the total number of bytes transferred to the Serial Monitor.

2.   Send a text string to the source client that indicates that binary transfer has completed.

3.   Reset the variables that control the binary data transfer to their initial states.

See Listing 8-27.

Example of Setting Up the Arduino with ESP-01 for Station/Client Mode

The setup() function sets the ESP-01 module for station mode by doing the following:

1.   Initializing debugging with the Serial Monitor at 9600 baud.

2.   Initializing serial communications with the ESP-01 module on serial port 3 at 115,200 baud.

3.   Delaying program execution for 1000 milliseconds or 1 second.

4.   Initializing sensors and other hardware. In this specific case a camera is initialized by calling the InitializeCamera() function.

5.   Turning off the Arduino’s built-in LED to indicate that the system has not yet become active.

6.   Enabling single connection mode by calling the SendATCommand(F("AT+CIPMUX=0\r\n")) function with the parameter as shown.

7.   Setting the mode to station mode by calling the SendATCommand(F("AT+CWMODE_CUR= 1\r\n")) function with the parameter shown.

8.   Joining the access point by sending the join access point command which is AT+CWJAP_CUR="ESP8266-12E-AP"," robtestESP12E" to the ESP-01 module.

9.   Starting the connection to the TCP server by sending the command which is AT+CIPSTART="TCP","192.168.4.1",80 to the ESP-01 module.

10. Setting the name of the client by calling the SendTCPMessage(ClientName) function.

11. Turning on the built-in LED on the Arduino if there are no errors and printing the error status to the Serial Monitor.

See Listing 8-28.

Hands-on Example: The ArduCAM OV2640 2MP Mini Plus Camera Arduino Mega 2560 Client Surveillance System with NodeMCU Server

In this hands-on example I demonstrate how to build and operate a wireless surveillance system based on an Android controller, a NodeMCU server, and an Arduino client that contains an ArduCAM OV2640 Mini Plus camera. See Figure 8-8.

Figure 8-8   The Android, NodeMCU server, and Arduino ArduCAM camera client system.

Parts List

   1 Android cell phone

   1 NodeMCU microcontroller

   1 Arduino Mega 2560 microcontroller

   1 5- to 3.3-V step-down voltage regulator

   1 Logic level converter from 5 to 3.3 V

   1 ESP-01 Wi-Fi module

   1 Arduino development station such as a desktop or a notebook

   1 Breadboard (minimum)

   1 ArduCAM OV2640 Mini Plus camera

   1 Package of wires both male-to-male and female-to-male to connect the components

Setting Up the Hardware

Step-Down Voltage Regulator Connections

1.   Connect the Vin pin on the voltage regulator to the 5-V power pin on the Arduino Mega 2560.

2.   Connect the Vout pin on the voltage regulator to a node on your breadboard represented by a horizontal row of empty slots. This is the 3.3-V power node that will supply the 3.3-V power to the ESP-01 module as well as provide the reference voltage for the logic level shifter.

3.   Connect the GND pin on the voltage regulator to the GND pin on the Arduino or form a GND node similar to the 3.3-V power node in the previous step.

ESP-01 Wi-Fi Module Connections

1.   Connect the Tx or TxD pin to the Rx3 pin on the Arduino Mega 2560. This is the receive pin for the serial hardware port 3.

2.   Connect the EN or CH_PD pin to the 3.3-V power node from the step-down voltage regulator.

3.   Connect the IO16 or RST pin to the 3.3-V power node from the step-down voltage regulator.

4.   Connect the 3V3 or VCC pin to the 3.3-V power node from the step-down voltage regulator.

5.   Connect the GND pin to the ground pin or node.

6.   Connect the Rx or RxD pin to pin B0 on the 3.3-V side of the logic level shifter. The voltage from this pin will be shifted from 5 V from the Arduino to 3.3 V for the ESP-01 module.

Logic Level Shifter

1.   Connect the 3.3-V pin to the 3.3-V power node from the step-down voltage regulator.

2.   Connect the GND pin on the 3.3-V side to the ground node for the Arduino.

3.   Connect the B0 pin on the 3.3-V side to Rx or RxD pin on the ESP-01. This corresponds to the A0 pin on the 5-V side.

4.   Connect the 5-V pin to the 5-V power pin on the Arduino.

5.   Connect the GND pin on the 5-V side to the ground node for the Arduino.

6.   Connect the A0 pin on the 5-V side to Tx3 pin on the Arduino. This pin corresponds to the B0 pin on the 3.3-V side.

ArduCAM OV2640 Mini Plus

1.   Connect the CS pin to digital pin 8 on the Arduino.

2.   Connect the SDA pin to digital pin 20 on the Arduino.

3.   Connect the SCL pin to digital pin 21 on the Arduino.

4.   Connect the MISO pin to digital pin 50 on the Arduino.

5.   Connect the MOSI pin to digital pin 51 on the Arduino.

6.   Connect the SCK pin to digital pin 52 on the Arduino.

7.   Connect the VCC pin to the 5-V node for the circuit.

8.   Connect the GND pin to the common ground node for the circuit.

See Figure 8-9.

Figure 8-9   The ArduCAM OV2640 Mini Plus camera Arduino client surveillance system with NodeMCU server.

Setting Up the Software

This section will cover the new code specific for the client version of this camera surveillance system. Code that remains the same from the server version was already discussed and will not be covered here.

The ClientName is the name of this client which is by default client1.

String ClientName = "client1";

The TimeStarted variable holds the time that a command was last sent by the client to the server.

unsigned long TimeStarted = 0;

The TimeDelayed variable holds the time in milliseconds since the last command was sent to the server by this client.

unsigned long TimeDelayed = 0;

The PingInterval variable holds the time in milliseconds between pings to the server from this client. It is set by default to 120 seconds or 2 minutes. If the client does not send any data to the server for a time period of 2 minutes then a ping will be sent to the server. Pings are needed to keep the client connected to the server.

The BinaryDataSize variable holds the size of the image that needs to be transmitted to the Android controller and is set by default to 0.

long BinaryDataSize = 0;

The setup() Function

The setup() function is the same as the example client set-up function shown in Listing 8-28.

The loop() Function

The loop() function processes incoming commands from the Android controller by calling the ProcessESP01Notifications() function. See Listing 8-29.

The ProcessESP01Notifications() Function

The ProcessESP01Notifications() function is modified from previous versions by adding in code for a ping handler that does the following:

1.   Calculates the time since the last command was sent to the server.

2.   If the time calculated in step 1 is greater than the ping interval then do the following:

1.   Send a ping command to the server by calling the SendTCPMessage ("ping\n") function with “ping\n” as the parameter.

2.   Set the TimeStarted variable which holds the time that the last command was sent to the server to the current time by calling the millis() function.

See Listing 8-30. Code additions are shown in bold print.

The CheckAndProcessIPD() Function

The CheckAndProcessIPD() function processes incoming data to this client. The data is of the format

+IPD,<Data Length>:<Data>

An example of incoming data would be the camera command qvga which tells the camera to take a photo of qvga resolution. The number 5 is the length of the data which includes a newline character at the end.

+IPD,5:QVGA

The function processes incoming data by doing the following:

1.   If the incoming data contains the substring “+IPD” then continue with the function otherwise exit the function.

2.   Parse the incoming data to find the data length and the data portions of the string.

3.   Print out the data length and the data that were found from step 2 to the Serial Monitor.

4.   If a “>” symbol is found then assume that we need to process a command of the form Command>ReturnClientName where a command is given to this client and the return data must be sent to the ReturnClientName client by doing the following:

1.   The ReturnClientname string value is parsed and saved based on the position of the “>” character.

2.   The Command value is parsed and saved based on the position of the “>” character.

3.   The command is processed by calling the ProcessCommand() function and the return value is stored in the ResponseString string variable.

4.   If the ResponseString is not empty then do the following:

1.   If the ResponseString is “BIN” then send the binary transfer command to the server. The command is of the form BIN:DestClientName:SizeOfBinaryData.

2.   If the ResponseString is not “BIN” then send a response string to the server of the form ReturnClient:ResponseString. This sends the ResponseString to the client specified after the “>” character.

3.   Send the actual response to the server by calling the SendTCPMessage() function.

4.   Set the TimeStarted variable to the current time to indicate that the client has just sent data to the server.

5.   If the incoming data is "Client ID Recieved ...\n" then send a ping command to the server and reset the TimeStarted variable to the current time to indicate that outgoing TCP activity just occurred.

5.   If the incoming data is "PING_OK\n" then print out a debug message to the Serial Monitor indicating that the server has received the client’s ping and has responded.

6.   If the incoming data contains the substring "Binary Transfer Enabled" then the binary mode was successfully set at the server, so start the image binary data transfer by calling the ReadFifoBurst() function and printing out a debug message to the Serial Monitor.

7.   If the incoming data contains the substring "Binary Transfer Finished." then the binary transfer to the server has completed. Print out the full message to the Serial Monitor.

8.   If the incoming data is not recognized as a case of one of the above then the command is unknown. Print out an error message to the Serial Monitor and the actual incoming data.

See Listing 8-31.

The ProcessCommand() Function

The ProcessCommand() function processes commands that are sent to the client by doing the following:

1.   If the command is “ping” then set the string to be returned to the caller to "Client_PING_OK\n".

2.   If the command is “vga” then do the following:

1.   If the current camera resolution is not set to vga then set the current camera resolution to vga by calling the SetCameraResolution() function.

2.   Capture the image using the camera by calling the CaptureImage() function.

3.   Get the string that will be used to transmit the image size of the photo that was just taken by calling the TransmitImageSize() function.

3.   If the command is “qvga” then do the following:

1.   If the current camera resolution is not set to qvga then set the current camera resolution to qvga by calling the SetCameraResolution() function.

2.   Capture the image using the camera by calling the CaptureImage() function.

3.   Get the string that will be used to transmit the image size of the photo that was just taken by calling the TransmitImageSize() function.

4.   If the command is “qqvga” then do the following:

1.   If the current camera resolution is not set to qqvga then set the current camera resolution to qqvga by calling the SetCameraResolution() function.

2.   Capture the image using the camera by calling the CaptureImage() function.

3.   Get the string that will be used to transmit the image size of the photo that was just taken by calling the TransmitImageSize() function.

5.   If the command is "GetImageData" then request that the server prepare for a binary data transfer by setting the function’s return string to “BIN”.

6.   If the command is not recognized as one of the previous commands then return a string indicating that the command is unknown.

See Listing 8-32.

The TransmitImageSize() Function

The TransmitImageSize() function is modified from previous versions by doing the following:

1.   The function now returns a string.

2.   The size of the image captured by the camera is now the same as the value retrieved from the myCAM.read_fifo_length() function and not 1 byte less like in the previous version.

3.   The size of the captured image is saved in the BinaryDataSize variable.

4.   A string is returned that holds the size of the image and is in a form designed to be transmitted and read by the Android controller.

See Listing 8-33. The code modifications are highlighted in bold print.

Operating the System

Download and install version 2.0 of the Android basic wireless framework to your Android cell phone if you have not done so already. Download and install the basic framework 2.0 server project for the NodeMCU on your NodeMCU device. Finally, download and install the client version of the ArduCAM mini surveillance system on your Arduino Mega 2560. Connect your Android device to the access point running on the NodeMCU microprocessor. Run the Android basic wireless framework and connect to the TCP server running on the NodeMCU. Turn on the Arduino client and start up the Serial Monitor. The Arduino client should connect to the Wi-Fi access point running on the NodeMCU and then connect to the TCP server running on the NodeMCU. Upon connecting to the TCP server the Arduino client should set its name to client1. The NodeMCU should send an acknowledgment text string to the Arduino that the client ID was received. After receiving the acknowledgment the Arduino should send a ping command to the server. The server should reply with a “PING_OK” text string. You should see something similar to the following on the Serial Monitor for the Arduino client:

Using the Android application refresh the clients. Switch the target device to the client that has the camera which should be client1. Type in qvga into the phone entry textbox and hit the “Send Data” button to send this command to the target device which should send the command qvga and redirect the output back to the Android cell phone which is the controller. The name of my Android device is verizon, so the command that will be received by the Arduino client should be qvga>verizon. Next, a photo is taken by the camera and the size of the image in bytes is transferred to the Android controller using the command verizon:6152 which sends the size of the image to my verizon device. After the Android controller receives the image size it issues a command which tells the client to send the binary data. The command is GetImageData>verizon in my case where the output of the GetImageData command is redirected to my verizon Android controller. In order to transmit binary data the client must first request binary mode, define the destination of the binary data and the size of the binary data which in my case the command is BIN:verizon:6152. The server then notifies the client that the binary transfer mode has been enabled. Once the client receives this notification it sends the binary data to the server which redirects it to the destination client. Once all the binary data has been transferred the server sends the client a text string that acknowledges that the binary transfer has completed and the total number of bytes that were transferred. The image that was taken by the ArduCAM camera should appear on your Android device. You should also see something similar to the following on your Serial Monitor:

Next, take a picture using qqvga mode by sending the qqvga command to client1. Enter qqvga in the phone text entry box and press “Send Data” to send the command to the target device which should be set to client1. You should see something similar to the following show up on the Serial Monitor. Once the image data has finished being transferred it should be displayed on your Android’s screen.

Next, take a photo at the vga camera resolution by sending a vga command to client1. The lightning may be low at first so take a photo several times to get a clear fully lit image.

Next, turn on the surveillance feature from the Android application. You should get a continuous stream of images from the camera. You can select different resolutions from the “Resolution Settings” menu.

Hands-on Example: The ArduCAM OV2640 2MP Mini Plus Infrared Motion Detection Arduino Mega 2560 Client Surveillance and Alarm System with NodeMCU Server

In this hands-on example I show you how to build a wireless surveillance and motion detection system using an Android cell phone, a NodeMCU server, and an Arduino Mega 2560 client that controls an ArduCAM OV2640 2MP Mini Plus camera and an HC-SR501 infrared motion detector. Note: If you have previously constructed the Arduino server-based ArduCAM camera and infrared motion sensor project then you can use that same Arduino, ArduCAM, and motion sensor hardware setup and just change the software that is installed. See Figure 8-10.

Figure 8-10   The Android, NodeMCU server, and Arduino client ArduCAM Mini Plus camera and infrared motion detection surveillance and alarm system.

Parts List

   1 Android cell phone

   1 NodeMCU microcontroller

   1 Arduino Mega 2560 microcontroller

   1 5- to 3.3-V step-down voltage regulator

   1 Logic level converter from 5 to 3.3 V

   1 ESP-01 Wi-Fi module

   1 Arduino development station such as a desktop or a notebook

   1 Breadboard

   1 ArduCAM OV2640 Mini Plus camera

   1 HC-SR501 infrared motion detector

   1 Package of wires to connect the components with both male-to-male and male-to-female wire connections

Setting Up the Hardware

Step-Down Voltage Regulator Connections

1.   Connect the Vin pin on the voltage regulator to the 5-V power pin on the Arduino Mega 2560.

2.   Connect the Vout pin on the voltage regulator to a node on your breadboard represented by a horizontal row of empty slots. This is the 3.3-V power node that will supply the 3.3-V power to the ESP-01 module as well as provide the reference voltage for the logic level shifter.

3.   Connect the GND pin on the voltage regulator to the GND pin on the Arduino or form a GND node similar to the 3.3-V power node in the previous step.

ESP-01 Wi-Fi Module Connections

1.   Connect the Tx or TxD pin to the Rx3 pin on the Arduino Mega 2560. This is the receive pin for the serial hardware port 3.

2.   Connect the EN or CH_PD pin to the 3.3-V power node from the step-down voltage regulator.

3.   Connect the IO16 or RST pin to the 3.3-V power node from the step-down voltage regulator.

4.   Connect the 3V3 or VCC pin to the 3.3-V power node from the step-down voltage regulator.

5.   Connect the GND pin to the ground pin or node.

6.   Connect the Rx or RxD pin to pin B0 on the 3.3-V side of the logic level shifter. The voltage from this pin will be shifted from 5 V from the Arduino to 3.3 V for the ESP-01 module.

Logic Level Shifter

1.   Connect the 3.3-V pin to the 3.3-V power node from the step-down voltage regulator.

2.   Connect the GND pin on the 3.3-V side to the ground node for the Arduino.

3.   Connect the B0 pin on the 3.3-V side to Rx or RxD pin on the ESP-01. This corresponds to the A0 pin on the 5-V side.

4.   Connect the 5-V pin to the 5-V power pin on the Arduino.

5.   Connect the GND pin on the 5-V side to the ground node for the Arduino.

6.   Connect the A0 pin on the 5-V side to Tx3 pin on the Arduino. This pin corresponds to the B0 pin on the 3.3-V side.

ArduCAM OV2640 Mini Plus

1.   Connect the CS pin to digital pin 8 on the Arduino.

2.   Connect the SDA pin to digital pin 20 on the Arduino.

3.   Connect the SCL pin to digital pin 21 on the Arduino.

4.   Connect the MISO pin to digital pin 50 on the Arduino.

5.   Connect the MOSI pin to digital pin 51 on the Arduino.

6.   Connect the SCK pin to digital pin 52 on the Arduino.

7.   Connect the VCC pin to the 5-V node for the circuit.

8.   Connect the GND pin to the common ground node for the circuit.

The HC-SR501 Infrared Motion Detector

1.   Connect the Vcc pin on the motion detector to the 5-V power node on the Arduino Mega 2560.

2.   Connect the GND pin on the motion detector to the GND node on the Arduino.

3.   Connect the Out pin on the motion detector to digital pin 7 on the Arduino.

See Figure 8-11.

Figure 8-11   The Arduino client with ArduCAM camera and motion detector.

Setting Up the Software

The key new code change for this hands-on example is that when the alarm is tripped the number of hits will be updated but a text string is NOT sent to the Android controller. The alarm system will now be polled instead by the Android controller. The key function that is modified is the ProcessSensor() function. The code block highlighted in Listing 8-34 has been modified so that only the number of hits is updated.

The ProcessCommand() Function

The ProcessCommand() function is modified by adding in recognition of motion sensor-related commands which are:

1.   The string “ACTIVATE_ALARM” which activates the motion sensor alarm system.

2.   The string “DEACTIVATE_ALARM” which deactivates the motion sensor alarm system.

3.   The string “hits” which returns the number of times the alarm has been tripped.

4.   The string “reset” which sets the number of hits to 0.

5.   The string “wait=” which sets the initial waiting time in milliseconds before the alarm is activated.

See Listing 8-35. The new code is highlighted in bold print.

Operating the Alarm and Surveillance System

Download and install version 2.0 of the Android basic wireless framework to your Android cell phone if you have not done so already. Download and install the basic framework 2.0 server project for the NodeMCU on your NodeMCU device. Finally, download and install the client version of the ArduCAM mini surveillance and motion detection alarm system on your Arduino Mega 2560. Connect your Android device to the access point running on the NodeMCU microprocessor. Run the Android basic wireless framework and connect to the TCP server running on the NodeMCU. Turn on the Arduino client and start up the Serial Monitor. The Arduino client should connect to the Wi-Fi access point running on the NodeMCU and then connect to the TCP server running on the NodeMCU. Upon connecting to the TCP server the Arduino client should set its name to client1. The NodeMCU should send an acknowledgment text string to the Arduino that the client ID was received. After receiving the acknowledgment the Arduino should send a ping command to the server. The server should reply with a “PING_OK” text string. You should see something similar to the following on the Serial Monitor for the Arduino client:

Listing 8-34   The ProcessSensor() Function

Listing 8-35   The ProcessCommand() Function

Refresh the clients using the Android application and then switch the target device for the commands to the client1 device that operates the camera and the motion detector. Next, test the ability of the camera to capture an image by sending a qvga command to client1. You should see something like the following on your Serial Monitor and then you should see the actual captured image appear on your Android device:

Next, set up client1 for network monitoring by adding it to the list of monitored devices by selecting the “Monitor Target Device” menu item. Have client1 take a photo whenever the alarm is tripped by selecting the “Set to Camera Available” option under the “Camera Status Target Device” menu. You should see the client1 device listed under the “Monitored Devices:” text located in the information window. Scroll all the way down the information window to view the list of monitored devices. You should also see a “CAMERA_YES” value to indicate that a photo will be taken whenever the motion sensor alarm is tripped.

Next, activate the alarm using the android application. You should see an activate alarm command coming into the client with the result being redirected to the Android controller which is in my case named verizon. In 10 seconds the alarm should be fully active. The output of your Serial Monitor should be similar to the following:

Next, start the monitoring of the alarm system on client1 by selecting the “Activate Network Monitoring” option under the “Network Monitoring” menu item. The Android controller will now continuously poll client1 by sending the “hits” command. The client1 device should start receiving the “hits” command and should reply with the number of hits or alarm trips that have occurred.

Next, trip the infrared motion sensor alarm by putting your hand in front of the sensor and holding it there for a few seconds. This will allow time for the polling to recognize that the alarm has been tripped and to send a take photo command to client1. Once the motion sensor detects motion it updates the number of hits. The next time client1 is polled it returns the updated number of hits which will be 1. The Android controller then sends the command to client1 to reset the number of hits to 0. The Android controller then sends a take photo command to client1. In my case the specific take photo command was “vga”. The image was then transferred to my Android device. The following is similar to what you should see on your own Serial Monitor:

Hands-on Example: The Infrared Motion Detection Alarm System Using the NodeMCU Server

In this hands-on example I will show you how to build a wireless motion detector alarm system using an Android, a NodeMCU server, and an infrared motion sensor. See Figure 8-12.

Figure 8-12   The NodeMCU server infrared motion detection alarm system.

Parts List

   1 Android cell phone

   1 NodeMCU microprocessor

   1 HC-SR501 infrared motion sensor

   1 Package of wires to connect the components

   1 Breadboard (optional)

Setting Up the Hardware

1.   Connect the Vcc pin on the motion detector to the Vin pin on the NodeMCU. Note that when connected to the USB port the Vin pin on the NodeMCU provides a 5-V output on most brands.

2.   Connect the GND pin on the motion detector to a GND pin on the NodeMCU.

3.   Connect the Out pin on the motion detector to pin D1 on the NodeMCU.

See Figure 8-13.

Figure 8-13   The wireless NodeMCU server motion detection alarm system.

Setting Up the Software

The key code change for this hands-on example is that the alarm system is now polled. So instead of sending a text string to the Android controller when the alarm is tripped the code will just update the number of hits. See the highlighted code block in Listing 8-36 to see the changes.

Operating the Alarm System

Download and install on your Android cell phone the basic framework version 2.0 if you have not done so already. Download and install the basic framework 2.0 with motion detection for the NodeMCU. Turn on the NodeMCU and turn on the Serial Monitor. Connect the Android to the Wi-Fi access point running on the NodeMCU. Run the Android application and connect to the TCP server running on the NodeMCU. You should see the NodeMCU server receive the Android controller’s name or clientID. In my case the name was “lg”. You should see something similar to the following on your Serial Monitor:

Listing 8-36   The ProcessSensor() Function

Next, refresh the clients using the Android application. This refreshing actually issues a list command to the NodeMCU server which returns the clients that are currently connected to the server.

Next, make sure that the server is selected as the target device. Activate the alarm on the server using the Android application. After waiting for 10 seconds the alarm system on the NodeMCU server becomes active.

Next, turn off the emergency call outs and emergency text messages and add the server to the list of monitored devices. Activate network monitoring. This will start to continuously poll the alarm system on the server by issuing “hits” commands. The hits command should return a 0 when no motion has been detected. Next, trip the alarm by waving your hand in front of the motion sensor. A debug message should be printed to the Serial Monitor. The next time a “hits” command is received it will return a 1 as the number of hits detected and trigger a sound effect being played on the Android device. After the Android processes the return value from the hits commands it will send a “reset” command that will set the number of hits back to 0.

Finally, deactivate the alarm using the Android application and exit the application by pressing the back key.

Hands-on Example: The ArduCAM OV2640 2MP Mini Plus and Infrared Motion Detection Arduino Mega 2560 Client Surveillance and Alarm System with NodeMCU Server with an Infrared Motion Detection Alarm System

In this hands-on example I show you how to use the NodeMCU server-based infrared motion sensor alarm system with an Arduino client-based surveillance and infrared motion-based alarm system. An Android cell phone with version 2.0 of the basic wireless framework is used as the controller for this wireless system. See Figure 8-14.

Figure 8-14   The NodeMCU alarm system and Arduino surveillance and alarm system.

Parts List

   1 Android cell phone

   1 NodeMCU microcontroller

   1 Arduino Mega 2560 microcontroller

   1 5- to 3.3-V step-down voltage regulator

   1 Logic level converter from 5 to 3.3 V

   1 ESP-01 Wi-Fi module

   2 Arduino development stations with the Arduino IDE installed

   1 Breadboard

   1 ArduCAM OV2640 Mini Plus camera

   2 HC-SR501 infrared motion detectors

   1 Package of wires to connect the components with both male-to-male and male-to-female wire connections

Setting Up the Hardware

1.   To build the NodeMCU server-based HC-SR501 infrared motion detection system refer to the previous hands-on example in this chapter that covers this system.

2.   To build the Arduino Mega 2560 client-based HC-SR501 and ArduCAM Mini Plus infrared motion detection and surveillance system refer to the previous hands-on example in this chapter that covers this system.

Setting Up the Software

The software for this hands-on example is the same as was used earlier in this chapter for the relevant hands-on examples involving the NodeMCU with motion detector and Arduino client with motion detector and camera.

Operating the System

Connect the Android to the Wi-Fi access point running on the NodeMCU. Start up the Android’s basic wireless framework version 2.0 and connect to the TCP server running on the NodeMCU. Refresh the clients using the application and select the switch target device menu item and you should see the server, and the Android device that you just used to connect to the TCP server as options. Start up the Arduino client that has the motion sensor and camera attached to it. The Arduino client should join the Wi-Fi access point on the NodeMCU and then connect to the TCP server running on the NodeMCU. After the Arduino client is connected to the NodeMCU refresh the clients using the Android application. You should now be able to select between the server, the Android device, and the Arduino client1 as target devices. Select client1 as the target device. Add client1 to the list of monitored devices. Also set the camera to be available on client1 so that when the alarm is tripped on client1 a photo will also be taken. Send a take photo command such as “qvga” to client1 to make sure that the camera is working correctly and an image is returned to the Android controller. Activate the alarm on client1 using the Android basic wireless framework application. Next, change the target device to the server. Add the server to the list of monitored devices. Activate the alarm on the server. Finally, turn on network monitoring using the Android application. The application will now continuously retrieve and monitor the alarm status on the server and client1.

Summary

In this chapter I have covered wireless sensing and remote control systems involving the Android, Arduino, ESP-01 module, and the NodeMCU microprocessor. I started by discussing the ArduCAM Mini OV2640 2MP Plus camera which is the newest version of the Mini OV2640 2MP model of the camera. I used this new camera in a hands-on example that demonstrated a surveillance system. Next, I extended this surveillance system and added an infrared motion detection and an alarm system. Next, I presented a new basic Android, Arduino with ESP-01, and NodeMCU server-based wireless multi-client framework. I then discussed an overview of the Android basic wireless framework version 2.0 application. Next, I covered the new code additions for the Android basic wireless framework version 2.0. I then discussed the new basic framework 2.0 for the NodeMCU server. Finally, I showed an example of setting up the Arduino with an ESP-01 module for station/client mode. The rest of the chapter consists of hands-on examples that demonstrate the new NodeMCU server-based multi-client system.

The hands-on example are as follows:

   Hands-on example: The ArduCAM OV2640 2MP Mini Plus camera Arduino Mega 2560 client surveillance system with NodeMCU server

   Hands-on example: The ArduCAM OV2640 2MP Mini Plus infrared motion detection Arduino Mega 2560 client surveillance and alarm system with NodeMCU server

   Hands-on Example: The infrared motion detection alarm system using the NodeMCU server

   Hands-on example: The ArduCAM OV2640 2MP Mini Plus and infrared motion detection Arduino Mega 2560 client surveillance and alarm system with NodeMCU server with an infrared motion detection alarm system