Let’s experiment with the Virtual Shield tool for Arduino, found in the last Microsoft operating system, for the purpose of creating a smartphone based geo-fence application, that would activate a relay when the phone is found inside a certain area.
In the two previous installments we introduced you to the projects connected with Microsoft’s entrance into the Makers’ world, and in particular we dwelled upon Windows’ distribution for Raspberry Pi: it is named Windows 10 IoT Core and created for the purpose of simplifying the applications’ development cycle. We will see now what has been done for Arduino instead, and in particular we will see the usage of Windows Virtual Shield, by creating a simple project in order to show its potentialities. What we want to create, even in its simplicity, can be used in real contexts: it is a relay that is activated when being near a determined spot. Already in the previous article we quoted this kind of usage for Virtual Shield, as a solution for the opening remote control (to be used to open the garage’s gate in the place of the classic remote control). In the project here described, it will be Arduino (installed in the car) to send the command on our behalf when we are nearby, by using a smartphone supplied with a GPS receiver (this last one will supply the data concerning the position).
Needed materials
The project requires the following devices:
Arduino Uno or a compatible board;
- a Bluetooth FT1018M module having RN42 (that we presented in number 168 of the magazine);
- a smartphone having a Windows Phone 10 preview (for example, Lumia 520, Lumia 635/630 are okay);
- a PC having Windows 10 installed.
Given that this is an educational project concerning Windows Virtual Shield, we will use a breadboard on which we will build the relay circuit, commanded by Arduino. The external components with which we will interface Arduino are simply a relay, and as much is needed in order to obtain its activation (in practice, a transistor and a resistor).
Environment preparation
The environment preparation is quite articulated and can be divided in three main steps
- configuration of the development environment on the PC;
- smartphone configuration;
- Arduino IDE configuration.
Let’s start by preparing the development environment on the Windows 10-based PC: for this purpose we should download and install Visual Studio 2015. Once the development environment has been installed, we will use it in order to install the “Virtual Shield for Arduino” Universal App on the mobile phone. This App (supplied in the source form) will deal with the management of the communication with Arduino, by exposing the sensors and the components used by the phone. The App sources are available on GitHub; for those who know GitHub already, it is possible to make a clone of the repository (Visual Studio directly supports GitHub from the environment). For those who are not familiar with GitHub, the easiest approach is the one to download the zip with the sources and to double click on Shield.sln, so to open them with Visual Studio.
Once the sources have been loaded with Visual Studio, it is the time to try to execute “Build”; if no errors have been detected, you will have completed the PC configuration.
Let’s move onto the mobile phone, then: in this case the operation is a bit easier. The ideal would be that of possessing a smartphone we don’t use as our main phone, since at the moment this article is published the Windows 10 version for smartphones is still in a preview phase and Microsoft does not guarantee on its reliability: to install it means to accept the risk that the mobile phone might operate poorly.
In order to install Windows 10 preview, it is enough to download “Windows Insider” from the App Store. Once executed, the application goes on in a semiautomatic way, the only requirement being the one to be registered to the Insider Preview program, but even this registration is a free one and can be done by following the indications from the App. Before starting the Windows 10 preview installation process, the App will ask us to choose between “Fast” or “Slow” updates: in the first case the system will receive updates more often, but they will potentially be less stable ones; in the second case, there will be less updates, but they will be more stable ones. For our test, both conditions will be fine, thus we will let you choose as you prefer.
Once the installation is complete, we are ready to connect the phone to the computer and, to install “Virtual Shield for Arduino” by using Visual Studio; if the previous steps have been carried out without problems, the operation simply consists in clicking on the small arrow akin to “play”, close to the “Device” writing: it can be found in the upper bar.
An important notice: it may happen that Visual Studio will send an error warning, since the version for which the project has been configured is one that follows the operating system found on the phone; unfortunately this is a known problem and one has to act manually in order to solve it. In the case you find yourself in this condition, as a first thing you will have to take notice of the version detected on the phone by Visual Studio, that will be shown at the same time of the error warning. After that, please open the Shield.csproj file via notepad: it is inside the sources folder, and please insert the read version in the TargetPlatformMinVersion tag; as an example, if we read 10.0.10149.0 we will have to set the tag like this <TargetPlatformMinVersion>10.0.10149.0</TargetPlatformMinVersion>. This is needed in order to indicate that the minimal version that is supported by the project is the specified one and, since it corresponds to the phone’s one, the problem will not occur again.
All that is left to do now is to configure the Arduino part: as a first thing we have to download one of IDE’s new versions (from 1.6 and up). Once the IDE has been installed, we have to downloadArduinoJson library; luckily in the new versions the LibraryManager has been included.
It may be accessed from the menu Sketch->Include Libraries->Manage Libraries…: with this command a pop-up is opened, from which to choose the library to install; by filtering ArduinoJson the library we are looking for will be shown and it will be enough to give the Install command to install it.
The final step is the one to download and install the libraries for the virtual shield, and unfortunately, since they have not yet been included in the Library Manager, we have to proceed with the manual installation. Luckily, the operation is not an excessively complex one: you just have to download the repository and to copy the whole content in the folder in which the IDE keeps all the libraries (typically Documents\Arduino\libraries).
The ever-present Hello World
Once we have reached this stage, we should have our environment ready for the first test that, as tradition dictates, will be the classic Hello World. “Almost” is the key word here, since we haven’t fiddled with the hardware yet. Actually in this first stage, the one of the diagram’s application, it is enough to connect the Bluetooth module to the Arduino board.
The first test is a very simple one and consists in creating a sketch that will use the phone’s display in order to write “Hello World”.
The code to load is the one in Listing 1.
Listing1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#include <ArduinoJson.h>
#include <VirtualShield.h>
#include <Text.h>
VirtualShield shield;
Text screen = Text(shield);
void refresh(ShieldEvent* shieldEvent)
{
screen.clear();
screen.printAt(1, “Hello World”);
}
void setup()
{
shield.setOnRefresh(refresh);
shield.begin();
}
void loop()
{
shield.checkSensors();
}
|
Briefly, the item of the VirtualShield kind is created (in the example it is named shield), it represents the communication interface with the phone. The item is used along with the Text class, that shows the functions needed to interact with the phone’s display. One of the example’s peculiarities is that the calls needed to display the text are not made directly in the loop function, but they are in the refresh function; in turn this is transferred as a parameter to the setOnRefresh method. Such a mechanism delegates to the shield item the function’s call when it is needed (for example, when starting the program or after the bluetooth connection). In order to see the sample work, it is needed to couple the Bluetooth module to the phone: the procedure is the classic one followed in order to couple Bluetooth devices. From the settings, please select “Devices” and then “Bluetooth” and from this screen the Bluetooth is activated (if turned off), waiting for some seconds while the other devices in the operating range are activated. The device’s name to be coupled will be something like RN42-1234 (with 1234 being different for each module); by selecting it the coupling will be carried out.
Let’s start now the “Virtual Shield for Arduino” app on the phone, at the start of it a black screen will be shown in figure.
This is the proper behaviour, since the black area is the one made available to Arduino, in order to show text or graphical contents; down and on the right the usual key having three dots “…” is found, it indicates that there is a drop-down menu. Let’s select it and a menu having some buttons will be shown, among them the one we’re interested in is “Settings”.
The “Connections” section is the one we are looking for, in which all the the Bluetooth devices coupled with our mobile phone will be shown; among them there will be our module. Let’s select it, and by pressing “Connect” we will end our preparation phase. At this stage, by returning to the main screen (with the back key) we should see “Hello World” appearing, as sent from our sketch loaded on Arduino.
The project
But let’s see now how to activate a relay when we are getting close to a certain area.
The circuit to be created is the one in Fig. 5, there we will find a transistor being used in switching mode, for the purpose of commanding a relay. The remote control’s transmitter button is connected to the two terminal block’s contacts, that depend on the exchange normally opened by the relay (C-NA). When the relay is excited, the contact will turn out to be closed and will activate the transmission on behalf of the remote control, that will send the opening command for the automatic gate.
The logical steps describing the circuit’s operations are:
the recurring reading of the GPS position;
the calculation of the distance, with respect to a determined spot (the gate to be opened);
relay activation, if the distance is under a prearranged threshold.
As for the position reading, we will use a class of the Virtual Shield that has been specifically designed for this purpose; as for Text, it is initialized by transferring the shield item, which it will use in order to communicate with the phone:
Geolocator gps = Geolocator(shield);
The GPS variable represents the item we are using in order to read the position; the periodic reading will happen by means of the previously seen callback mechanism. In our sketch’s setup we will have the call set the function needed in order to read the position: it will be periodically called; in our case we will make a reading every 15 seconds. Please note that it is important to balance this time, so to avoid too frequent readings that would hinder the autonomy, since we are talking about a battery powered device. At the same time, if our readings are too sparse, we will determine delays in the relay’s activation, with respect to the input in the objective’s proximity area. As a measure of caution, we should get closer only after having seen the gate opening.
The code line that sets the callback is gps.setOnEvent(gpsEvent).
Let’s see then the gpsEvent function, that is the one we required to be called when there are updates in the position reading: it is related in Listing 2.
Listing2
1
2
3
4
5
6
7
8
9
10
11
12
13
|
void gpsEvent(ShieldEvent* shieldEvent)
{
float distance = calc_dist(gps.Latitude, gps.Longitude, myLatitude, myLongitude);
String diststr = String(“Distanza “) + String(distance) + String(“ mt”);
screen.printAt(3, diststr);
if (distance < threshold){
screen.printAt(5, “Rele’ ON”, GREEN);
digitalWrite(PIN_RELE, HIGH);
} else {
screen.printAt(5, “Rele’ OFF”, RED);
digitalWrite(PIN_RELE, HIGH);
}
}
|
The coordinates related to the position are made available in gps.Latitude and gps.Longitude; previously we will have set two more coordinates (corresponding to the spot with respect to which to calculate the distance; in the source they are myLatitude and myLongitude) in the source. The function then calculates the difference between the read coordinates and the reference ones; because of this we will call another function, calc_dist, that uses a mathematical formula in order to carry out the relevant calculations (the function is reported in the complete source that you will find in Listing 4). Once the distance has been obtained, we will create a string (diststr) that we will use in order to show what has been read on the mobile phone’s display. The veritable heart of the function is the test that checks if the distance variable is under the prearranged threshold (indicated by threshold) and, in case, it activates the relay connected to the pin defined by PIN_RELE. The example is deliberately a simplified one: when we enter the relevant area (that we may consider as a “geo-fence”), the relay remains excited until we remain inside of it; obviously it is possible to introduce to introduce something to manage this condition, but we preferred to keep the code readable. locking the callback is not enough though: if we do not set a periodic call that triggers the position reading. As is natural in an Arduino program, this activity is carried out in the loop: we can see it in Listing 3, that relates the corresponding code section.
Listing3
1
2
3
4
5
6
7
8
9
10
|
const long interval = 1000 * 15;
long nextGPS = 0;
void loop()
{
if (millis() > nextGPS) {
nextGPS = millis() + interval;
gps.get();
}
shield.checkSensors();
}
|
Listing4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <ArduinoJson.h>
#include <VirtualShield.h>
#include <Text.h>
#include <Colors.h>
#include <Geolocator.h>
VirtualShield shield;
Text screen = Text(shield);
Geolocator gps = Geolocator(shield);
float myLatitude = 45.092949;
float myLongitude = 7.523704;
float threshold = 50;
int PIN_RELE = 7;
void gpsEvent(ShieldEvent* shieldEvent)
{
float distance = calc_dist(gps.Latitude, gps.Longitude, myLatitude, myLongitude);
String diststr = String(“Distanza “) + String(distance) + String(“ mt”);
screen.printAt(3, diststr);
if (distance < threshold){
screen.printAt(5, “Rele’ ON”, GREEN);
digitalWrite(PIN_RELE, HIGH);
} else {
screen.printAt(5, “Rele’ OFF”, RED);
digitalWrite(PIN_RELE, HIGH);
}
}
void setup()
{
shield.begin();
screen.clear(ARGB(0,0,0));
screen.printAt(1, “Rele’ Geolocalizzato”);
gps.setOnEvent(gpsEvent);
pinMode(PIN_RELE, OUTPUT);
}
const long interval = 1000 * 15;
long nextGPS = 0;
void loop()
{
if (millis() > nextGPS) {
nextGPS = millis() + interval;
gps.get();
}
shield.checkSensors();
}
float calc_dist( float flat1, float flon1, float flat2, float flon2)
{
float dist_calc=0;
float dist_calc2=0;
float diflat=0;
float diflon=0;
diflat=radians(flat2-flat1);
flat1=radians(flat1);
flat2=radians(flat2);
diflon=radians((flon2)-(flon1));
dist_calc = ( sin (diflat/2.0)* sin (diflat/2.0));
dist_calc2= cos (flat1);
dist_calc2*= cos (flat2);
dist_calc2*= sin (diflon/2.0);
dist_calc2*= sin (diflon/2.0);
dist_calc +=dist_calc2;
dist_calc=(2* atan2 ( sqrt (dist_calc), sqrt (1.0-dist_calc)));
dist_calc*=6371000.0;
return dist_calc;
}
|
The request to read the position’s coordinates is carried out via the gps.get() call, in order to manage the reading frequency we use the millis() function, so to carry out the call only when at least 15 seconds from the previous request have passed.
Conclusions
Those among you who are experienced with Arduino might be wondering about the difference between using Virtual Shield and a GPS shield that is physically mounted on the board.
From an operational point of view we will have the same results, but the usage of Windows Virtual Shield brings a series of advantages.
First of all, the hardware interface for Arduino is much simpler: in our case it comes down to connecting a Bluetooth module and a relay. Moreover, our project uses the smartphone’s display in order to show some messages; if we wanted to create the project in a “classic” way, we would have had to worry about interfacing a display and maybe to acquire a case, in order to place it (also considering that the typical use case for our project is the one of a remote control for the gate opening, to be placed in a car, as we already anticipated in the introduction). Because of this usage, we need that Arduino is capable of accessing the geolocation data, only when we are in the car as well. To use an integrated GPS module would make sense in the case of an anti-theft alarm, but in this case we may avoid buying the component.
Finally, the fact of using a virtual shield (that has a very large series of sensors available) gives us the possibility to extend our project in the future, without having to act on the circuit. For example, we could make it produce a sound or synthesize a vocal message when we get close to the gate: for such a purpose, just a few more code lines in the sketch would be needed.