How to measure environmental factors (temperature, light, humidity, ...) in a field located kilometers away from any electric socket and any Wifi network? The first solution coming to mind is to use an Android phone and to connect Yoctopuce sensors by USB. This solution works (as illustrated here), but to power this type of installation, you need to use a solar panel and a battery of a relatively large size. To perform some measures for a relatively short period of time (a few weeks), there is a simpler and probably cheaper alternative: using a Wifi connection between the phone and the sensor instead of a USB one.
USB connection
The USB connection between an Android phone and a Yoctopuce module functions very well and enables an application to interact with the physical world (for instance to control a lamp, or to check air quality in a specific location). Unfortunately, only up scale phones have On The Go (OTG) USB support, which is needed to use a USB sensor. It's hard to find a phone with a reliable USB support for less than 200€.
The phone is responsible for the USB communication, and must power the USB hub plus the two Yoctopuce modules.
But the biggest issue is autonomy: with USB, it's the phone which must power all the peripheral devices. As the SDK doesn't allow you to deactivate the USB port, the OS can never go into deep sleep and goes on using the CPU to maintain USB communications. Concretely, if you connect a USB hub and two Yoctopuce modules, you'll never have an autonomy longer than 24 hours because the phone battery must permanently power the CPU and the connected USB devices. Hence the need for a rather large solar panel and a large battery.
Wifi connection
The other possibility is to use a YoctoHub-Wireless and a Wifi connection. You configure the phone for use as a secure Wifi access point (with a WPA key), and you configure the YoctoHub-Wireless to connect itself automatically on this Wifi network. Of course, as the YoctoHub-Wireless doesn't have a battery, you power it with a simple small USB battery.
The phone creates a Wifi network. The YoctoHub-Wireless, which is powered by its own battery, registers itself on this network
This solution has numerous advantages:
- you can use a way cheaper lower end phone
- the sensors and the phone are not connected by a cable anymore (so it's easier to move the sensors away)
- you can deactivate the Wifi network when not in a communication phase from the application
- when there is no communication, the phone can go into deep sleep (and thus consume even less)
- the YoctoHub-Wireless has a real time clock (RTC) enabling it to go into deep sleep (and to limit its power consumption to 15uA
- the YoctoHub-Wireless is able to stop powering the connected modules (as it is the case when into deep sleep)
One may think that using a WiFi connection is less efficient than USB, but it is not the case: the YoctoHub-Wireless consumption is equivalent to a standard USB hub (approx. 100mA), so the only extra consumption is the WiFi interface of the phone. But as WiFi makes it possible to put into deep sleep the phone and the sensors between measures, the average consumption is significantly reduced.
In this configuration, the YoctoHub-Wireless is in deep sleep and consumes only 15uA. The two other Yoctopuce modules don't consume anything because they are not even powered.
Implementation example
The following example is very basic, it's an application which performs temperature, humidity, atmospheric pressure, and light measures every three hours and stores them on the phone.
The first step is to configure the phone Wifi access point and to configure the YoctoHub-Wireless to connect itself on this network. When this step is done, the two machines can communicate with one another. To check that everything is working, open the Android web browser and connect yourself on the YoctoHub-Wireless web interface using the IP address that the phone assigned to it.
When done, the second step consists in writing the Android code which manages the wake/sleep phases, including activation and deactivation of the Wifi network to spare the batteries. In details, this is what you have to do:
- activate the Wifi network
- wait for the YoctoHub-Wireless to connect itself on the Wifi network and detect its IP address
- initialize the Yoctopuce API to connect itself to the YoctoHub-Wireless
- perform the measures
- compute the time of the next running sequence
- program the YoctoHub-Wireless to wake up for the next running sequence
- put the YoctoHub-Wireless into deep sleep
- program an alarm to restart the service at the time of the next running sequence
- store the measures in the SQLite database
- deactivate the Wifi network
- stop running the service
All this is done in the background by and Android service running as a background task. A small and simple application allows you to control the service and to use the measured values (in the present case, we'll only display them in order to keep the code as simple as possible).
Source code
The complete source code for this example is available on Github. We comment here a few points specific to the Yoctopuce modules.
To contact the hub by Wifi when it wakes up, we register the YoctoHub-Wireless with its IP address with YAPI.RegisterHub("xxx.xxx.xxx.xxx"). You obtain the IP address by analyzing the /proc/net/arp file.
ArrayList<String> ips = apGetIPs();
// test all IP that are connected to the WiFi HotSpot
for (String ip : ips) {
try {
// test if this IP is a YoctoHub-Wireless
YAPI.RegisterHub(ip);
ok = true;
} catch (YAPI_Exception e) {
// the IP is not Yoctopuce hub
}
}
} while (!ok && timeout > System.currentTimeMillis());
if (ok) {
// get value from all sensors
YHumidity yHumidity = YHumidity.FirstHumidity();
if (yHumidity != null) {
result.setHumidity(yHumidity.get_currentValue());
}
YTemperature yTemperature = YTemperature.FirstTemperature();
if (yTemperature != null) {
result.setTemperature(yTemperature.get_currentValue());
}
YPressure yPressure = YPressure.FirstPressure();
if (yPressure != null) {
result.setPressure(yPressure.get_currentValue());
}
YLightSensor yLightSensor = YLightSensor.FirstLightSensor();
if (yLightSensor != null) {
result.setLight(yLightSensor.get_currentValue());
}
}
To program the wake up times, be careful to use Android UTC time to avoid problems with daylight saving times and time zones. Another trap is the time unit: Android works in milliseconds, while the Yoctopuce API uses seconds to manage time.
YWakeUpMonitor hub = YWakeUpMonitor.FirstWakeUpMonitor();
if (hub != null) {
// create Pending intent to start this service again
Intent intent = new Intent(this, BgSensorsService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// compute next wake up time (seconds since EPOCH)
long now = System.currentTimeMillis() / 1000;
long nextWakeup = (now + WAKEUP_INTERVAL);
// Program the next wake for YoctoHub-Wireless
hub.set_nextWakeUp(nextWakeup);
// put the YoctoHub-Wireless in deep sleep until next wake up
hub.set_sleepCountdown(2);
// Program the Android Alarm manager to start this service again
// at the next wake up time.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
am.set(AlarmManager.RTC, nextWakeup * 1000, pendingIntent);
} else {
am.setExact(AlarmManager.RTC, nextWakeup * 1000, pendingIntent);
}
}
When first running, you must make sure that the YoctoHub-Wireless is awake to try to connect itself to the Wifi network. If it is not the case, simply press the YoctoHub-Wireless Wake button. From then on, the hub is programmed to go to sleep until the next call.
Conclusion
This new way to use the YoctoHub-Wireless without a home Wifi network opens new possibilities to perform measures in isolated locations, without having to set up a large solar installation. It's particularly suited when you need to follow measures for a specific duration (for example during the thaw, or when trees are bearing fruits). If you want to set up Yoctopuce modules in isolated locations for a low price, it's a good solution.