Energy Consumption of Wireless IoT Nodes (PDFDrive)
Energy Consumption of Wireless IoT Nodes (PDFDrive)
Nodes
Amen Hussain
Amen Hussain
I would also like to thank a good friend Knut Magnus for encouraging
me to write the Python script for automatic power consumption measure-
ment from the oscilloscope. This helped me in streamlining the power
measurement process.
Amen Hussain
Contents
List of Figures xi
1 Introduction 1
1.1 Problem Description . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.4 Publication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Report Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Background 7
2.1 Energy Monitoring using Shunt Resistor . . . . . . . . . . . . . . . . 8
2.2 Software based Energy Estimation . . . . . . . . . . . . . . . . . . . 9
2.3 Specialized Hardware based Approach . . . . . . . . . . . . . . . . . 10
2.4 CPU Instruction-set based Energy Estimation . . . . . . . . . . . . . 10
2.5 Energy Modeling using Parametric Approach . . . . . . . . . . . . . 11
2.6 Black-box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
vii
5 Energy Modeling 53
5.1 Energy Consumption Estimation Model . . . . . . . . . . . . . . . . 53
5.2 Run-time Logic for Energy Estimation . . . . . . . . . . . . . . . . . 55
References 85
Appendices
A Picoscope Python Script 89
4.1 mDot Current Consumption when Powering a single Light Emitting Diode
(LED) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.2 mDot Current Consumption when Powering two LEDs . . . . . . . . . . 21
4.3 mDot going into sleep mode . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.4 mDot not going into deep-sleep mode . . . . . . . . . . . . . . . . . . . 28
4.5 mDot Current Consumption during Sleep and Active States . . . . . . . 29
4.6 Noise Floor Waveform View . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.7 Noise Floor Spectral View . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.8 mDot current consumption during deep sleep mode . . . . . . . . . . . . 31
4.9 Issue in mDot Automatic Current Consumption in Deep Sleep Mode . . 32
4.10 mDot Transmit Cycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.11 Manual: mDot_senddata Energy Conumsption . . . . . . . . . . . . . . 36
4.12 Automatic: mDot_senddata() Energy Consumption . . . . . . . . . . . 37
4.13 Automatic: mDot_senddata() Power Consumption . . . . . . . . . . . . 38
4.14 Current Consumption when receiving LoRA frame of size 240B . . . . . 40
4.15 Current Consumption when receiving LoRA frame of size 120B . . . . . 40
4.16 Current Conumsption during Cryptographic Operation . . . . . . . . . . 43
4.17 mDot Cryptographic Energy Conumsption . . . . . . . . . . . . . . . . 44
4.18 mDot Cryptographic Power Consumption . . . . . . . . . . . . . . . . . 45
4.19 mDot Interfacing with Particle Sensor Schematic Diagram . . . . . . . . 47
4.20 mDot Temperature Sensor Current Waveform . . . . . . . . . . . . . . . 51
4.21 mDot Particle Sensor Current Waveform . . . . . . . . . . . . . . . . . . 52
xi
5.2 An abstract model of the energy consumption, with focus on the different
activity phases. Power and time axis are not to scale[THK17]. . . . . . 54
xiii
7.4 Particle Sensing: Energy Consumption Estimation for 10 Minutes under
Different Sensing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.5 Sensor Modes Parameters in Temperature Sensing Energy-Aware Appli-
cations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.6 Temperature Sensing: Energy Consumption Comparison under Different
Sensing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
7.7 Temperature Sensing: Energy Consumption Estimation for 10 Minutes
under Different Sensing Modes . . . . . . . . . . . . . . . . . . . . . . . 74
xv
A.5 Pyhton Script: Main Function . . . . . . . . . . . . . . . . . . . . . . 93
Chapter
Introduction
1
The wireless sensor nodes containing the capability to sense, process and send data
over a communication network are the backbone of the IoT. The IoT technology
enabled the smart objects to communicate with each other and this resulted in
communication anytime, any media, anywhere, and anything [AIM10]. It is being
forecasted that by 2020 there will be around 50 billion devices connected to IoT
networks [Cis]. These devices will be used in the design of new engineering solutions to
societal scale problems such as transportation, power metering, healthcare, agriculture,
home automation etc. These devices are wireless and possess stringent size constraints.
Since there is no cable attached to power these devices therefore, they run on limited
battery powered resources. It has become a daunting challenge to power these devices
so that they can run for several months or possibly years of unattended operation.
To address this issue, researchers focused on three different areas:
The available energy budget limits the amount of processing possible at the
sensing node. The available energy restricts how a sensor will operate. If the sensor
consumes relatively more power then the application attempts to acquire less sensing
data in order to conserve energy. Similarly, it also restricts how much data will be
transmitted via the sensing node. Lastly, the available energy resource also influences
the quality of sensing measurements. One can acquire more accurate sensing values
1
2 1. INTRODUCTION
if one can sense more often and this will increase the energy consumption of the
sensing node. If the sensing node is aware of its energy resources than it can shift to
an appropriate sensing mode. It can sense more often or rarely based on the available
energy resource. The energy awareness by the application allows the efficient use
of the sensing node. More importantly, it will also prevent the node to become
unresponsive due to lack of available energy.
On the other hand, the sensing nodes are subject to heterogeneous and non-
stationary environments [DRAP15]. When solar energy is used to power up the
sensing nodes the avaliable energy highly depends on the weather conditions. That
makes the available energy resource variable with respect to the current weather
conditions. Therefore, a sensing node should be able to change its sensing mode
dynamically.
Fig. 1.1, explains the general context of these sense application. It illustrates the
general architecture of an IoT periodic sensing application. This architecture can
be realized in a number of IoT applications such as a city-wide sensing system for
emissions of particles or CO2 [ADK+ 16], a climate monitoring system, or a tracking
system for animals.
Energy Planning
Upstream:
sensor data
LoRaWAN
energy consumption
Gateway
battery level
Downstream:
sensing mode
Sensor Nodes
In such applications, the cloud is responsible for data acquisition and management
of the sensing nodes. One can also perform energy planning in the cloud if all the
sensing nodes are sending their energy consumption along with the sensed data. The
cloud can instruct the sensing device to change to an appropriate sensing mode based
on the observed available energy resource.
1.1. PROBLEM DESCRIPTION 3
Since the power consumption of different activity phases depends on the attached
peripherals and they don’t change dynamically, therefore, we have decided to compute
the power consumption of such applications at design-time. Similarly, to incorporate
the dynamic nature of such applications we have introduced the run-time process
to measure the duration of these activity phases. When shifting to different sensing
modes, one can only modify the duration of the activity phases, therefore, which
has been incorporated by the run-time process. Thus, the presented approach takes
care of the dynamic nature of sensing nodes along with the influence on the power
consumption when different peripherals devices are activated simultaneously. The
presented approach is generic and applicable for all different IoT hardware platforms,
since it doesn’t require any specialized hardware. Our evaluation results show that
this approach of estimating energy consumption is quite accurate.
In this work, we will attempt to develop a model to predict the energy consumption
of applications running on an embedded hardware platform. We will establish a
model for specific IoT applications that consist of sensing cycles. In a sensing cycle,
an application goes into an active state, reads a sensor value, processes the sensed
data, transmits it to another node or gateway depending on the topology, and then
goes again into the sleep state.
Similarly, the states can be sleep, deep sleep, active, initializing peripherals etc. The
results of these experiments will be used as building blocks to establish the model to
predict the energy consumption of an application.
1.2 Methodology
Once, we established a sound knowledge about the IoT hardware platform and
the applications’ energy profiles, then we proposed a model for energy consumption
estimation by the sensing application. To evaluate the developed energy estimation
model, we developed different types of sensing applications with our proposed energy
estimation model. We performed a comparative analysis between the actual energy
consumption by the application with the estimated one proposed by developed model.
1.3. MOTIVATION 5
1.3 Motivation
1.4 Publication
Parts of this thesis has been published in the International Conference on Mo-
bile, Secure and Programmable Networking (MSPN’2017)4 with the title; Energy
Consumption Estimation for Energy-Aware, Adaptive Sensing Applications.
This thesis work consists of some experimental work, the design of our proposed
model, and evaluation of the proposed prototype for energy estimation. The report
has been organized as follows: Chapter 2 enumerates and summarizes some of the
existing techniques to estimate energy consumption of an application running on a
1 https://www.ntnu.edu/iik/aas
2 https://www.mbed.com/en/
3 http://www.contiki-os.org/
4 http://cedric.cnam.fr/workshops/mspn2017/index.html
6 1. INTRODUCTION
hardware platform. Chapter 3 describes the method selected to compute the power
consumption of the application running on the sensing node. Chapter 4 describes
the experimental work to understand the power and energy consumption by different
activity phases. Chapter 5 presents the energy estimation model. In Chapter 6 and 7
we developed two different types of sensing applications with diverse energy profiles
and presented our energy consumption estimation results. Chapter 8 presents how
our estimation model performs when we have used waspmote as the IoT hardware
platform and CO2 sensor. Chapter 9 presents the conclusion and how well our work
corresponds to the problem description.
Chapter
Background
2
The energy consumption of an embedded device can be acquired using various
approaches. However, we have broadly categorized these methods into the offline and
online approaches, and software and hardware approaches. In the online approach,
the energy consumption is estimated at the run-time, whereas in the offline approach
the energy consumption is estimated in a laboratory setting before deploying the
node in the network. Similarly, in the hardware-based approach a specialized
hardware is being used to measure the energy consumption, however, in the software-
based approach, the application software is being modified to estimate its energy
consumption. Both the software and the hardware approaches can be used in the
online and offline approaches to predict the cost of energy.
In recent years, a lot of research has been done in the energy profiling of mobile
computing platforms. The efficient use of energy by these computing devices is a
key factor for both device manufacturers and the application developers. Since these
handheld devices also run on batteries and the battery capacity of these devices is
strictly restricted to the constraints on device’s weight and size. Thus, it is critical
for these devices to optimally manage their power consumption [DMMJ16].
In the following sections we will discuss some of the existing techniques used to
measure power and energy consumption of mobile device, wireless sensor nodes and
other embedded devices. Since all of these devices run under a restricted battery
environment.
7
8 2. BACKGROUND
Carroll and Heiser [CH10], performed rigorous tests and then simulated several usage
scenarios to present the significance of the power drawn by various components: CPU,
memory, touchscreen, graphics hardware, audio, storage, and networking interfaces in
a mobile device. For energy profiling, they measured the physical power consumption
of each component. They inserted a sense resistor on the power supply rail for
the relevant component and used ohm’s law (V=I * R) to measure the current
consumption. Rice and Hay [RH10] conducted a study where they profiled energy
consumption of the devices connected to 802.11 wireless networks. To measure power
consumption, they used a similar approach as Carroll and Heiser. They inserted
a shunt resistor in series with the power supply and the mobile phone to measure
overall energy consumption by the mobile device. They used a high-precision 0.02Ω
resistor in series with battery terminal and its connector on the phone. In both
approaches, they used a shunt resistor in series with the component and power supply
to measure the current consumption. These two approaches fall into the category of
offline approach to estimate the energy consumption.
Pathaket et al. [PHZ+ 11] proposed a system-call based power consumption modeling
approach. They proposed that the power consumption is estimated based on the
system calls sent to the Operating System (OS). When an application wants to access
an I/O or memory driver this call goes through an OS and the proposed model
can estimate how much energy will be consumed after the completion of this call.
This model performs run-time power estimation and provides fine-grained as well as
application level energy consumption. We have categorized these two approaches in
the area of the software-based offline method to predict energy consumption.
Li and John [LJ03] developed an OS’s energy profile using a wide spectrum
of applications. They proposed various models to effectively estimate run-time
energy dissipation of an OS. Dzhagaryan et al. [DMMJ16] proposed an automated
energy measurement method for applications running on Android mobile and bare-
metal embedded computing devices. They exploited different hardware and software
aspects of the application and several other approaches to perform run-time power
measurement. For energy profiling, they used a battery simulator provided by the
National Instruments. The battery simulator provides an unobtrusive, high-resolution
and high-frequency sampling of the current drawn by the computing device.
F. Jalali et al. [JHA+ 16], proposed flow-based and time-based models to measure
energy consumption by a Nano Data Center (nDC). nDCs are highly distributed
servers that work on the peer-peer basis to host and transmit content and applications.
nDCs are becoming popular to be used as local servers for IoT services. In the flow-
based model, the equipment’s power consumption is calculated with respect to overall
data flows passing through the equipment. Similarly, in the time-based model, energy
consumption is measured in terms of time that an equipment spends when performing
a cloud service. Martinez et al. [MMVP15] presented a general methodology about
how to model the energy consumption of a node in a wireless network at a pre-
deployed or pre-production stage. In this approach, they took a system-level approach
and considered all the energy intensive processes like networking, sensing, processing,
and acquisition capabilities to estimate a node’s power consumption. Shnayder et
al. [SHC+ 04] presented a scalable simulation environment to estimate an accurate
per-node power consumption in a wireless sensor network.
10 2. BACKGROUND
Shin et al. [SSJ+ 02] also used the approach of using a specialized hardware
to provide power consumption. They proposed an integrated hardware connected
to the target embedded device and an associated software to deliver the data of
power consumption. They have used ARM7TDMI as the integrated hardware to
perform on-board energy measurements. Their model estimates an application’s
energy consumption in a hybrid fashion. The energy consumption of the CPU core is
directly measured by the integrated tool, however, to estimate the power consumption
of the memory, they have proposed a memory-power model. In this model, they
predict the memory’s power consumption by using collected memory traces of the
system’s memory power consumption. In this method, they have employed all
the four approaches; offline, online, software, and hardware, to estimate the power
consumption.
Acevedo et al. [APJCA10] proposed the use of static code simulation and micro-
processor’s power model, to predict the energy consumption of a program running
on an embedded device. Their model considered three types of energy costs; the
cost of execution of the instruction itself, the switching cost between instructions,
and the cost of cache-miss and branch misprediction. This is a one-time process
to estimate the power and energy of the applications running on a microprocessor.
One must perform this process again if the Micro-Controller Unit (MCU) has been
changed. In their work, they have shown that an error of energy estimation is 7%
and 14.6% respectively. This approach is suitable for static code analysis. Similarly,
this approach is also specific to estimate the cost of the processor itself and ignores
the energy consumption by peripheral devices.
consumption of processor core, Flash memory, memory controller, and SRAM. Their
experimental results were based on several embedded applications from MiBench
benchmark suite [GRE+ 01] and showed the estimation error is less than 6%.
Laurent et al. [LJSM04] proposed a technique that used the functional and para-
metric modeling of the processor to estimate the runtime power consumption. In
their approach, they extracted the important parameters of the target application
and platform that significantly contributed to the power consumption. Then they
developed some elementary assembly programs (called scenarios) and measured
their power and energy consumption. Finally, these values were used to develop a
regression model to estimate the power consumption for different application and
hardware platforms. They have used the offline software-based approach to create an
energy estimation model. In their approach, the average error in estimation varies
upon different applications and processors.
Ktari and Abid [KA07], also used the parametric models based on the architecture
and the algorithm to estimate energy consumption of Digital Signal Processing
Applications. The estimation errors of their model are 7.1% and 7.6% for finite impulse
response (FIR) application running on C6701 and C5501 processors respectively.
Similarly, they observed estimation errors of 4% and 6.6% for the applications that
computed Fast Fourier Transforms (FFT).
Bircher and John [BJ12] proposed that the processor’s performance counters can
be used to measure CPU’s power consumption. They used the performance-related
events within a microprocessor like cache misses and DMA transactions to determine
power consumption in memory, disk, and other subsystems outside microprocessor.
Based on performance matrix, they developed system-specific models to measure
the power consumption of six subsystems: microprocessor, graphics processing unit
(GPU), chipset, memory, I/O, and disk. Their results showed that these models
produced an average error less than 9% per subsystem by considering different
workloads.
2.6 Black-box
You et al. [cYHAC10] suggested an energy estimation technique that can model
energy consumption under various combinations of devices’ states without the use
12 2. BACKGROUND
of additional hardware. They have used the nominal power consumption from the
specifications of related devices to estimate the energy consumption. The technique
of relying on the datasheet specification for energy estimation is called black-box
energy estimation and it is suitable for the cases where you can’t connect any external
hardware to measure the power consumption.
Power Measurement Setup
Chapter
3
We have selected the shunt resistor approach as used by Carroll and Heiser [CH10] to
measure power consumption of the sensing application. They measured the physical
power consumption of each component by inserting a sense resistor on the power
supply rail for each relevant component. Since the tester knows the voltage provided
to each component therefore, they used ohm’s law V = I * R to measure the current
consumption. Once we know the current consumption the power can be computed
using formula P = V * I.
In our approach, we have used the shunt resistor approach to measure the
power consumption of each activity phase. Since the activity phases are defined by
the application. Therefore, we will observe the overall power consumption by the
application and then identify the distinct activity phases.
We selected the shunt-resistor approach for on-chip power measurement for two
reasons. Firstly, we wanted to develop a platform and target independent current
measurement setup. This method is considered best suited since it doesn’t restrict us
to use a specific hardware platform. Any device that allows us to use external power
supply to power up the target device can be used. Secondly, our main objective
was to physically measure the power consumed by an IoT node and didn’t want any
discrepancy in our measurements produced in a simulation environment.
13
14 3. POWER MEASUREMENT SETUP
– 4 channels
– 2 GS ultra-deep memory
We adopted two methods to measure the current drawn by the sensing application
running on IoT device. In the first approach, we are manually identifying the
boundaries of the activity phase on the oscilloscope using the PicoScope-6 software.
In this method, we are using the DC-Average function provided by the PicoScope-6
software to find the average current consumption in a given time range.
In the second approach, we wrote a Python script, that starts capturing data
when a threshold has been exceeded. The Python script samples the data from the
oscilloscope based on the set sampling frequency and the capture length. After the
data has been logged by the oscilloscope, the Python script finds the ending boundary
of the signal and calculates the mean and standard error of the captured waveform.
To generate a fixed threshold value, we used the PA_2 pin on mDot to signal the
oscilloscope to start capturing the data. In order to measure power consumption in
distinct activity phase the application developer can send signal on PA_2 before
entering and after exiting the activity phase. The python script uses these signal
values and computes the mean power and energy consumption in between the signals.
The complete Python script can be found in the Appendix. A. It takes following
values as input:
This script generates an excel report where it outputs the measurement of current,
power and energy consumption within a threshold signals. Following is the screenshot
of its output:
4
To analyze the power and energy consumption by different activity phases in a
sensing application, we will conduct various experiments in this chapter. These
activity phases are related to the GPIO, different energy modes, radio transmission
and reception, cryptographic operations, and sensor related operations. The experi-
ments in this chapter are conducted on mDot IoT hardware platform provided by
Multiconnect [Mul16]. The energy consumption in these experiments is calculated
by using following formula:
E = µ(P ) ∗ ∆t (4.1)
In the Eq. 4.1, µ(P) represents the mean power consumption and ’∆t’ expresses
the duration of an activity phase. To calculate E(P) we have used following formula:
Using the above formula, we calculated the variance in the energy consumption.
√
The standard error is square root of variance; σ(∆t, ImDot ) = σ 2 (∆t, ImDot ). In
the following experiments, we used the Eq. 4.3 to compute the standard error in the
energy.
17
18 4. POWER AND ENERGY CONSUMPTION ANALYSIS
2. Energy Modes: In this section, we will discuss the impact on the power
consumption of mDot by changing energy modes.
4.1 LED
The mDot is powered up by 5 V and the voltage observed across the GPIO pin is
2,7 V. The mDot has a microcontroller STM32F411RE which controls the GPIO of
mDot. The datasheet of STM32F411RE confirms that a GPIO can safely draw 20
mA of current. Therefore, using Eq. 4.4 the minimum value of the resistor should be
25 Ω [STM16].
In this experiment, we used a resistor of 56,20 Ω and as per the formula, the
current drawn by the LED during high state should be 8,89 mA. To compare the
energy consumption when the LED is high and low, a C++ program for mDot was
developed where the GPIO pin was configured in output mode and its state was
toggled after every 200 ms. Following is the code snippet:
Similarly, to investigate the energy consumption when two LEDs light up, follwoing
code snippet was used.
#include "mbed.h"
#include "mDot.h"
DigitalOut led1(PA_2);
DigitalOut led2(PA_0);
int main(){
while(true){
led1 = !led1;
led2 = !led2;
Thread::wait(200);
}
return 0;
}
Results: The results gathered from this experiment shows that the current con-
sumption is higher when the LED is powered ON. The current consumption by the
mDot is observed to be 32,02 mA when the LED is in the high state and 19,88 mA
when it is at a low state. Using the formula in the Eq. 4.2, the power consumption
during high and low states is 0,160 W and 0,099 W respectively. Similarly, to compute
energy consumption by the mDot Eq. 4.1 was used. The ∆tmDot in the current
scenario is the time mDot spent either in high or low state. Since in this experiment
the LED remains the high and low for 200 ms, therefore, ∆tmDot is 200 ms for both
the cases. The mDot consumes 0,0199 J of energy when the LED is in low-state and
0,032 J of energy when LED is in the high state. These results indicate that the
mDot consumes 0,0121 J of more energy when the LED is in the high state.
4.1. LED 21
Two LEDs were attached to the mDot, in order to verify that the energy con-
sumption increases linearly. We obtained following figure from the oscilloscope when
two LEDs were connected.
Tab. 4.1, shows that the current drawn by the LED is 12,14 mA that is 4 mA
higher than what was calculated. However, when two LEDs were used the current
drawn by the mDot doubles. Tab. 4.1 also confirms our hypothesis that the mDot
consumes more energy when the LED is at the high state. Similarly, the table also
proves our hypothesis that the energy consumption increases linearly by increasing
the number of LEDs.
4.2. ENERGY MODES 23
Hypothesis: The current consumption during sleep and deep sleep modes is less
than the active mode.
Method: To measure energy consumption during sleep mode we used the sleep Ap-
plication Program Interface (API)s provided by the mDot library.1 We implemented
a for loop equivalent of duration 292 ms to ensure that the mDot remains in the
active mode. We used the timer provided by mbed to find exact time during the
execution of the for loop. We have also used MTSLog to output the log messages
from the program running on mDot using the serial port. This is used to confirm
whether the mDot is entering different energy modes. Following code snippet shows
how to configure MTS logger in mDot source code:
1 https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/
24 4. POWER AND ENERGY CONSUMPTION ANALYSIS
#include "mbed.h"
#include "mDot.h"
#include "MTSLog.h"
Timer t;
while(true){
volatile int32_t j=0;
t.start();
for (; j<4; j++){
for (volatile int32_t i=0; i<1000000; i++);
}
t.stop();
logInfo("times in milliseconds: %d", t.read_ms());
t.reset();
}
return 0;
}
To read the log messages sent over USB by mDot, a Python script has been used.
This program reads the messages from mDot via a COM port and prints them on
a terminal. Algo. 4.4 presents the Python script that receives mDot messages and
outputs them to the terminal. This Python script takes the baud rate and port as
input.
4.2. ENERGY MODES 25
import time
import datetime
import sys
import serial
import io
import argparse
args = parser.parse_args()
except KeyboardInterrupt:
sys.stdout.write(’Interrupted’)
sys.stdout.flush()
Source code 4.5 C++ Program: Generate Event for Automatic Energy Measure-
ment
void generate_event()
{
DigitalOut signal(PA_2)
signal = 1;
wait_us(100);
signal = 0;
}
The Algo. 4.3 has been modified such that it computes the current consumption
during active mode.
int main(){
while(true){
volatile int32_t j=0;
generate_event();
for (; j<4; j++){
for (volatile int32_t i=0; i<1000000; i++);
}
generate_event();
The Python script was run with following values to calculate power and energy
consumption:
The next step was to measure current consumption during sleep mode. The
mDot sleep API is used to enter the sleep mode. The sleep API in mDot takes three
parameters. The first parameter specifies the number of seconds mDot remains in
sleep mode. The second parameter defines the wake-up event for the mDot. The
wake-up event for the mDot can be triggered by the real-time counter or an external
interrupt. When the wake-up event is set mDot::RTC_ALARM; it instructs
the mDot to wake-up after the interval specified in the first parameter. The last
parameter specifies whether or not the mDot will go to deep sleep. This API allows
us to enter either deep sleep(standby) or sleep(stop) mode. In the present scenario,
we have configured the mDot to enter the sleep mode for one second. Following is
the code snippet to measure current consumption in the sleep mode:
#include "mbed.h"
#include "mDot.h"
int main(){
mDot* dot = NULL;
while(true){
volatile int32_t j=0;
for (; j<4; j++){
for (volatile int32_t i=0; i<1000000; i++);
}
To calculate power and energy consumption, we used Python script with the
following input values:
We used MTSlog to display the log to confirm that mDot is going into sleep mode.
Moreover, we checked the how mDot behaves when we set the deep sleep to TRUE
by using the following API:
The following figures show the log output when sleep and deep sleep modes were
activated respectively.
Figure 4.3: mDot going into Figure 4.4: mDot not going into
sleep mode deep-sleep mode
Fig. 4.3 indicates that the mDot goes into sleep mode after every 1s. However,
Fig. 4.4 indicates that mDot does not support deep sleep mode. In this sub-section
we have developed the source code as well as current measurement instructions for
active, sleep and deep sleep modes and also confirmed that mDot doesn’t enter the
deep sleep mode.
Figure 4.5: mDot Current Consumption during Sleep and Active States
Fig. 4.5 shows that the sleep state can be further divided into three phases based
on the current consumption waveform. Therefore, we have divided the sleep state
into pre-, post- and main sleep phases. On a side note, we did some experiments
where we varied the duration of sleep state and discovered that the duration of these
phases remains constant.
Fig. 4.5 indicates that the mDot spends ∼ 161,91 ms in post-sleep phase and
draws ∼ 21,78 mA of current. The execution of for loop takes ∼ 292,5 ms and
consumes a current of ∼ 37,68 mA. Similarly, the pre-sleep phase takes ∼ 43,99
ms and consumes ∼ 12,48 mA of current. During the main sleep phase, the mDot
consumes ∼ 240,57 µA of current for the duration of ∼ 954,15 ms.
These values are manually measured by the author using the digital oscilloscope.
They are averaged over manually measured 10 samples from the oscilloscope using
the DC-Average function. Since the measurement obtained from the Python script
was an averaged value over the complete sleep state including the pre- and post-
phase; therefore, we have used the manual method to separately measure the current
consumption of theses pre- and post- phases.
30 4. POWER AND ENERGY CONSUMPTION ANALYSIS
Table 4.2: Sleep Mode Energy Consumption (E-05 in this table is equivalent to
×10−5 and so on.)
States Duration(ms) Current(A) Power(W) Energy(J)
Pre-Sleep 0,044±7,62E-05 0,012±6,65E-05 0,062±6,65E-05 0,0027±3,07E-06
Sleep 0,954±1,04E-03 2,41E-04±3,42E-05 0,001±3,42E-05 0,0011±3,26E-05
Post-Sleep 0,162±2,41E-03 0,022±1,59E-04 0,109±1,59E-04 0,018±5,84E-05
According to the developer’s guideline for mDot [Mulb], the current consumption
during sleep mode should be 50µA that is far less than the observed value. After
some investigation, it was observed that a noise floor is present in our readings
from the oscilloscope. We calculated that the oscilloscope measures a signal whose
DC-average value is 216.7µA. The presence of this noise will not allow us to measure
current consumption in the range of 50µA.
Fig. 4.6 and Fig. 4.7 represent the waveform and spectrum view of the observed
noise floor. The spectral view shows that the noise is maximum at near the frequency
of 0Hz which is DC signal.
Figure 4.6: Noise Floor Wave- Figure 4.7: Noise Floor Spectral
form View View
4.2. ENERGY MODES 31
Since the mDot is not entering the deep sleep mode, we expected to see no change
in the power consumption. However, the oscilloscope waveform view showed that
there are some variations in the current consumption of sleep and deep sleep modes.
Fig. 4.8 is the captured image from oscilloscope which shows the current drawn by
the mDot when deep sleep mode was set:
The waveforms of the post-sleep phase are identical in both sleep modes (sleep
and deep sleep). Similarly, by comparing Fig. 4.5 and Fig. 4.8 an inconsistency
during the execution of for loop can also be observed. In the sleep mode, the current
consumption remains at 37,65 mA throughout the completion of for-loop. However,
in the deep sleep mode, it goes to 37,75 mA for 70 ms and then drops to 28,22 mA
for 222,2 ms. This variation in the deep sleep mode results in current consumption
of 30,65 mA during the execution of for loop. Similarly, in the pre-sleep phase, we
see two levels of current consumption; one at 24,48 mA and the other one at 12,55
mA. This resulted in an increased consumption current of value 20,25 mA and an
increased duration of 129,7 ms in the deep sleep mode. Moreover, the current drawn
during the main deep sleep phase is 238.5 µA and the duration is 951 ms.
We used the manual method to measure current consumption in the deep sleep
mode because the PA_2 pin, to trigger the oscilloscope measurement, of mDot
remains high in deep sleep mode as shown in Fig. 4.9. In Fig. 4.9, the Channel B
represents the state of the PA_2 and the Channel A is the current consumption
waveform during the deep sleep operation. This will lead to an erroneous calculation
of current consumption in the deep sleep mode. Moreover, since the deep sleep mode
32 4. POWER AND ENERGY CONSUMPTION ANALYSIS
is again divided into three different phases; therefore, we used the manual method to
separately measure the current consumption.
Figure 4.9: Issue in mDot Automatic Current Consumption in Deep Sleep Mode
The current consumption for active mode is measured using Algo. 4.6, where
the mDot only executes a for loop. We have used the Python script to measure the
current consumption during the active phase.
Tab. 4.3 confirms that the mDot consumes more power in the active mode as
compared to the two sleep modes. However, we observe more energy consumption
4.3. PEER-TO-PEER RADIO TRANSMISSION 33
during deep sleep mode in contrast to sleep mode because our mDot version does not
deep sleep mode.
dot = mDot::getInstance();
dot->resetConfig();
if (dot->getJoinMode() != mDot::PEER_TO_PEER) {
dot->setJoinMode(mDot::PEER_TO_PEER);
}
frequency_band = dot->getFrequencyBand();
tx_frequency = 869850000;
tx_datarate = mDot::DR6;
tx_power = 4;
update_peer_to_peer_config_p2p(network_address, network_session_key,
data_session_key, tx_frequency,
tx_datarate, tx_power);
while (true) {
std::vector<uint8_t> tx_data;
if (!dot->getNetworkJoinStatus()) {
join_network_p2p();
}
for (uint32_t i=0; i<25; i++){
tx_data.push_back((i%60)+33);
}
dot->send(tx_data);
wait(1);
}
34 4. POWER AND ENERGY CONSUMPTION ANALYSIS
According to the specifications of LoRaWAN, the maximum frame size using the
configurations in this example is 243 bytes [SLE+ 15]. To support our hypothesis,
we used 10 frames of increasing lengths and measured the current drawn during
transmission. The mDot can transmit packets of different sizes by modifying the for
loop iterator defined in the Algo. 4.8. We will increase the length of the frame each
time by adding 24 more bytes and then use the oscilloscope to measure the current
drawn and the duration of these transmissions.
For each set of data frames, we manually measured the current drawn by mDot
using the oscilloscope. We took 10 samples for each data length and calculated
mean value. We also did an automated analysis of the current consumption by the
mDot using the Python script. In the automated analysis, we used a signal probe;
PA_2, to instruct the oscilloscope when to start capturing the data from the measure
probe. Algo. 4.9 presents the code snippet used for automatic energy consumption
measurement.
Source code 4.9 C++ Program: mDot LoRA peer-to-peer Automatic Measurement
while (true) {
std::vector<uint8_t> tx_data;
if (!dot->getNetworkJoinStatus()) {
join_network_p2p();
}
for (uint32_t i=0; i<25; i++){
tx_data.push_back((i%60)+33);
}
generate_event();
dot->send(tx_data);
generate_event();
wait(1);
}
During these experiments, we observed that the variations in the duration and
current consumption during pre- and post- radio transmission phases are negligible
when we increased the frame length. However, the duration of radio transmission
phase increased linearly with the frame size. Fig. 4.11 displays the variation of energy
consumption during these different phases with respect to frame length.
36 4. POWER AND ENERGY CONSUMPTION ANALYSIS
In Fig. 4.11, we observed that the current consumption during radio transmission
phase is almost linear. Similarly, the variation in the pre-transmit and pos-transmit
is insignificant. These small variations led to a conclusion that during these phases
the mDot is performing constant operations that are not related to the packet length.
Tab. 4.4 enlists the power consumption by these different phases under various frame
lengths.
Table 4.4: Power Consumption in Pre-, Post- and Main Transmission Phases (E-05
in this table is equivalent to ×10−5 and so on.)
PacketSize(B) PP re−T ransmit (W) PT ransmit (W) PP ost−T ransmit (W)
1 0,0789±4,80E-05 0,3247±3,15E-04 0,1908±6,01E-04
25 0,0768±8,43E-05 0,3244±2,79E-04 0,1856±9,61E-04
49 0,0769±6,14E-05 0,3191±8,88E-04 0,0570±0,018
73 0,0777±1,78E-05 0,3165±1,69E-04 0
97 0,0777±4,74E-05 0,3290±3,97E-05 0,1849±9,42E-04
121 0,0776±3,14E-05 0,3265±9,45E-05 0,1888±9,92E-04
145 0,0785±6,81E-05 0,3218±1,12E-04 0
169 0,0780±9,51E-05 0,3248±5,30E-05 0,1513±4,29E-04
193 0,0779±8,14E-05 0,3246±2,53E-04 0,1719±1,33E-03
217 0,0783±9,14E-05 0,3256±6,46E-05 0,1836±8,69E-04
241 0,0800±6,44E-05 0,3263±6,21E-05 0,1885±4,80E-04
4.3. PEER-TO-PEER RADIO TRANSMISSION 37
In this case, the threshold voltage is -0,3. The number of samples to collect from
the experiment is 10. The sampling frequency is 100 MHz. The voltage provided to
mDot was 5,0 V and the capture length is 280 ms. The capture length and sampling
frequency will be changed to gather data for different frame lengths. The Python
script for collecting power and energy consumption measurements was executed for
all the packet lengths. Fig. 4.12 presents the energy consumed by the mDot with
respect to different packet lengths.
Fig. 4.12 indicates that the energy consumption follows almost linear pattern
with respect to packet size. Similarly, we plotted the graph for power consumption
with respect to packet size. We observed a slight increase in the power consumption
Tab. 4.5 summarizes the data gathered from the automated analysis. These
results indicate that the energy consumption increases linearly and the relationship
between frame length and overall transmission duration is linear. We also found
during this experiment that the transmission phase can be divided into three phase;
pre-, post-, and main transmission phases.
4.4. PEER-TO-PEER RADIO RECEIVE 39
Method: To prove this hypothesis, we used the Algo. 4.8 and enabled the receive
event.
dot− > setEvents(&events)
The Algo. 4.9 for peer-to-peer communication indicates that the mDot joins the
network, then transmits the data and waits for 1 second. During this wait state the
mDot is interrupted with a receive event and the function PacketRx() defined in
mDotEvent.h file is called as given in Appendix. B.2. This function then switches
the control to the user defined call-back function MacEvent() that is defined in the
radio_event.h file as given in Appendix. B.3.
To confirm that the mDot is correctly receiving the sent bytes, we modified the
call-back function. In the call-back function when the mDot receives the desired
number of bytes, a pulse of 10 ms is generated on PA_2 GPIO pin. In the case of
failure, no pulse is generated in the receive phase. The generation of the pulse will
result in increased current consumption but we will ignore it during the measurement.
because mDot receive process is interrupt driven. This interrupt is defined inside the
library code and for the automatic measurements, we can’t generate a pulse in the
library code. Since we can’t mark the start of the receive event, therefore, we used
the manual method to gather data.
Results: After conducting the measurements for two different frame lengths we
received following waveforms on the oscilloscope:
Fig. 4.14 and Fig. 4.15 indicate that there is not much difference in the current
consumption when the frame length is reduced to half. The red curve in the Fig. 4.14
and Fig. 4.15 confirm that the packets have been received correctly by the mDot. To
compare their energy consumption, we also performed a manual data analysis where
we took 10 sample of data during frame receive event.
Tab. 4.6 proves that the frame size does not influence the energy consumption of
mDot in the process of receiving. The difference in the average duration is around
4.5. CRYPTOGRAPHY 41
1 ms which leads to a conclusion that after the receive event the mDot processes the
data and it might take more time to process 240 bytes as compared to 120 bytes.
4.5 Cryptography
#include "mbedtls/aes.h"
mbedtls_aes_context aes_enc;
// static key
unsigned char key[16] = "itzkbgulrcjmnv";
key[15] = ’x’;
2 https://www.mbed.com/en/technologies/security/mbed-tls/
42 4. POWER AND ENERGY CONSUMPTION ANALYSIS
#include "mbedtls/aes.h"
mbedtls_aes_context aes_dec;
// static key
unsigned char key[16] = "itzkbgulrcjmnv";
key[15] = ’x’;
We generated a variable length input by using a for loop. Following is the code
snippet to generate variable length input used during encryption.
crypographic operations; encryption and decryption, when the input data length is
16 bytes.
The Fig. 4.16 shows the current consumption during cryptographic operations,
where the data size is 16 bytes. By looking at this Fig. 4.16, it is clear that the
duration for encryption and decryption is in micro-seconds. Since the duration is so
small, therefore, the energy consumption during encryption and decryption will be
insignificant.
Tab. 4.7 summarizes the power and energy consumption of the mDot during
cryptographic operations while varying the length of input data. The data presented in
Tab. 4.7 is an average of 10 current consumption samples observed by the oscilloscope.
We have summed the current consumption during encryption and decryption processes
and presented the accumulated data in Tab. 4.7 as the current consumption during
both cryptographic operations. The data presented in Tab. 4.7 for power and energy
is also an accumulation over both operations.
44 4. POWER AND ENERGY CONSUMPTION ANALYSIS
Table 4.7: Cryptography: Energy and Power Consumption (E-05 in this table is
equivalent to ×10−5 and so on.)
Bytes Duration(s) Current(A) Power(W) Energy(J)
16 7,45E-05±8,09E-07 0,025±3,10E-04 0,128±3,10E-04 9,58E-06±3,11E-08
32 9,65E-05±1,00E-06 0,025±2,59E-04 0,129±2,59E-04 1,25E-05±3,60E-08
48 1,18E-04±7,66E-07 0,026±3,18E-04 0,132±3,18E-04 1,55E-05±4,26E-08
64 1,39E-04±4,91E-07 0,026±2,97E-04 0,132±2,97E-04 1,84E-05±4,34E-08
80 1,61E-04±8,26E-07 0,026±2,72E-04 0,132±2,72E-04 2,14E-05±4,92E-08
96 1,83E-04±1,31E-06 0,026±3,10E-04 0,132±3,10E-04 2,43E-05±6,67E-08
112 2,05E-04±1,18E-06 0,026±2,89E-04 0,133±2,89E-04 2,74E-05±6,72E-08
Fig. 4.17 and Fig. 4.18 show the energy and power consumption respectively
during cryptographic operations with respect to data length.
Fig. 4.17 proves our hypothesis that energy consumption increases linearly when
we increase the data length. However, due to the small durations of cryptographic
operations, one can conclude that the cryptographic operations in the mDot are an
energy efficient operations.
4.6 Sensors
Hypothesis: The temperature sensor will consume less energy than the particle
sensor.
Method: In this experiment, we have interfaced temperature sensor with the mDot.
We used DS18B20 1-Wire temperature sensor [Dal]. We configured PA_5 GPIO
pin of mDot to read temperature value from the sensor. We also inserted a 4,7 kΩ
resistor between the VDD and DQ pin of the temperature sensor.
46 4. POWER AND ENERGY CONSUMPTION ANALYSIS
Following is the code snippet used to interface the temperature sensor with
the mDot: The automatic analysis has been performed to capture the current
#include "mbed.h"
#include "DS1820.h"
#include "mDot.h"
int main(){
float temperature = 0.0;
probe.setResolution(9);
while( 1 ) {
generate_event(1);
//Start temperature conversion, wait until ready
probe.convertTemperature(true, DS1820::all_devices);
temperature = probe.temperature();
generate_event(1);
// Wait for one second
wait(2);
}
return 0;
}
Here the sampling frequency is reduced to 5 MHz and the capture duration to 1000
ms.
between Vcc and the pin-6 [SHA14]. The particle sensor uses a fan to capture dust.
We have used an NPN transistor to create a switch to control the fan. The mDot
will turn on the fan of the particle sensor during particle sensing and then turn it off.
The schematic diagram of particle sensor and the mDot is presented in Fig. 4.19.
A C++ program was written to interface the particle sensor with the mDot.
Three GPIO pins of the mDot were configured to read analog voltage corresponding
to the particles detected. PB0 of mDot is configured as an analog input. Another pin
PA_0 has been configured to turn on and off the particle sensor’s LED. Similarly, to
turn ON_OFF the fan, PA_3 of the mDot is configured as digital output. Following
is the code snippet to configure the GPIO:
DigitalOut fanCtrl(FAN_PIN);
DigitalOut ledpower(\gls{led}_PIN);
AnalogIn measure(MEASUREV_PIN);
48 4. POWER AND ENERGY CONSUMPTION ANALYSIS
Algo. 4.15 explains the process of sampling sensing data from the sensor.
Source code 4.15 C++ Program: Sensing Value from Particle Sensor
float getDustVoltageSample(void)
{
float dustVMeasured = 0.0;
ledpower = 0; // turn the \gls{led} on
As specified in the datasheet that one should sample data from the particle sensor
after every 10 ms [SHA14]. Therefore, we used SLEEP_TIME as 9680 µs to complete
10 ms duration before the next sample. Algo.4.16 explains the main function of this
sensor application.
4.6. SENSORS 49
#define FANFREESAMPLE 50
int main(void) {
float vS = 0; // stores reference voltage
float voMeasured = 0; // Stores measured output (0-1023) from sensor
float calcVoltage = 0; // Calculate actual voltage output from sensor
float dustDensity = 0;
The fan is turned ON and there is a delay of 500 ms. By increasing this delay we
will get a more precise value of dust density. For our experimental purposes, we have
fixed it to 500 ms.
50 4. POWER AND ENERGY CONSUMPTION ANALYSIS
Following code snippet has been used, to compute reference voltage Vs: The
Source code 4.17 C++ Program: Get Reference Voltage in Particle Sensor
float getVsWithOutFAN(void) {
fanCtrl = 0; // Turn off the fan
float vsMeasured_sum = 0;
int fanFreeSampleCtr = 0;
for (fanFreeSampleCtr = 0; fanFreeSampleCtr < ; fanFreeSampleCtr++)
vsMeasured_sum += (getDustVoltageSample() * 3300);
return vsMeasured_sum;
}
Python script was used to measure the current consumption during sensing phase.
As can be seen in the code snippet 4.15, the function generate_event() is being called
to capture the current consumption during one sensing phase. The Python script
was called with the following input values:
In this scenario, the sampling frequency is set to 5 MHz and the capture duration is
600 ms. Moreover, the threshold voltage is also changed to -0,25 V because the fan
is consuming more current.
Results: In this section, we will first discuss the results gathered by the temperature
sensor and then the particle sensor. The data gathered for the temperature sensor
show that the sensor takes around 800 ms to return the temperature value to the
mDot. Fig. 4.20 shows the current consumption waveform during temperature
sensing.
4.6. SENSORS 51
Each horizontal box in this figure represents 200 ms. The energy measure-
ment analysis of the temperature sensor shows that the sensor takes 763,53 ms
to compute the temperature value. The average current consumption by the
mDot is 17,26±5,97×10−5 mA. The average power consumption is calculated to be
0,0863±5,97×10−5 W and the average energy consumed is 0,066±5,90 J.
In the case of the particle sensor, our experiments confirmed that the mDot is
consuming around 158 mA of current. Fig. 4.21 presents the screenshot from the
oscilloscope that explains the waveform of current observed.
52 4. POWER AND ENERGY CONSUMPTION ANALYSIS
The data analysis of the particle sensor shows that the sensor takes 510,01±4,16E-
04 ms to send observed dust voltage where 500 ms is the fan running delay. Therefore,
if we increase the fan on duration, the sensing phase duration will be increased. The
average current consumption by the mDot is 98,59±3,07E-06 mA. The average power
consumption is calculated to be 0,493±3,07E-06 W and the average energy consumed
is 0,25±0,894 J. Tab. 4.8 shows that the particle sensor consumes more power and
To establish an energy estimation model, one need to understand the energy con-
sumption of different processes in a sensing application. We developed a temperature
sensing application, that sampled the temperature using DS18b20 temperature sen-
sor [Dal] interfaced with the mDot. The application sampled the temperature twice
with a wait of ∼0,1 seconds in between the two samples. Fig. 5.1 shows the current
consumption by the mDot when the temperature sensing application was running.
d d
en en ep
ep s -s le
e- st e-s
sle pr po pr
post-sleep sense wait sense send sleep
300
250
Power (mW)
200
150
100
50
0
0.15 0.75 0.1 0.75 2 0.07 4
Duration (s) 0.
01 02 04
0. 0.0
The vertical axis represents the power consumption. With the help of experiments
done in Chapt. 4, we could identify different phases in the application. Fig. 5.1
show that in the sleep phase, the mDot consumes ∼1,2 mW. We have labeled the
wake-up phase as post-sleep phase and it consumes ∼110 mW and its duration is
∼0,15 seconds. Similarly, the sensing phase consumes ∼86 mW of power and takes
53
54 5. ENERGY MODELING
∼0,75 s. The pre-send phase consumes ∼75 mW lasts for ∼0,012 s. The duration of
send phase is ∼0,07 s and it consumes ∼325 mW of power. The post-send phase has
a power consumption of ∼200 mW and the duration of ∼0,024 s. After the post-send
phase the mDot goes to the sleep phase and has a ∼0,004 s long pre-sleep phase that
consumes ∼100 mW of power.
The power consumption waveform in the Fig. 5.1 allowed us to define some distinct
phases in the sensing application. An abstraction of the actual power consumption
waveform is presented in the Fig. 5.2.
Power
send
sense sense
compute
pre-sleep
sleep sleep
t
Figure 5.2: An abstract model of the energy consumption, with focus on the
different activity phases. Power and time axis are not to scale[THK17].
The shaded boxes in the Fig. 5.2 represents the static block of energy that is part
of the main operation i.e. send or sleep. Before entering and waking up from the
sleep phase, we see some static waveforms. They were discovered in the Chapt. 4.
N
X
E= Pn ∗ ∆tn (5.1)
n=1
Where Pn and ∆tn represent the power consumption and the duration of the
phase n, and E is the total energy in one sensing cycle. N is the total number of
5.2. RUN-TIME LOGIC FOR ENERGY ESTIMATION 55
In our approach, we calculate the values of Pn and ∆tn at different times. The
power consumption of a phase and the duration of phase belong to two different
properties of a sensing application. The duration of an operation is application
dependent whereas the power consumption is the function of current drawn by the
hardware itself. Since at the design-time of an application the application developer
knows the hardware platform and the peripheral devices, therefore, we can estimate
the power consumption of different phases at the design-time using the measurement
setup specified in the Chapt. 3. However, to incorporate the run-time behavior of the
application the duration is calculated by the application using timer functionality.
The run-time calculation of the duration is also important because the planning
algorithm implemented in the cloud can change the duration and the occurrence of
different activity phases.
The ∆tn is the execution time of a phase running in an application. It is computed the
application itself at runtime. In the case of mDot hardware platfomr, an application
can provide the duration of an acrivity phase using timer.h library. For other IoT
hardware platforms one can find suitable APIs for duration calculation. timer.h
library is provided by the mbed-os. 1 Following APIs of timer.h has been used to get
the duration[ARM]:
The Algo. 5.1 explains the energy calculation instructions implemented inside
the application. It explains how to get timestamps for different activity phases and
the implementation of Eq. 5.1.
1 https://developer.mbed.org/handbook/Timer
56 5. ENERGY MODELING
In the next chapters we will develop and evaluate different types of energy-aware
periodic sensing applications.
Energy-Aware Application:
Increasing Sensing Phase
Chapter
6
In this chapter, we will develop some applications for mDot IoT hardware platform
where we will increase the occurrence of sensing phase as defined in Fig. 5.2 and
observe how our estimation model performs under such kind of applications. We will
implement the run-time logic as explained in the Algo. 5.1 in the application. We will
use the timer.h APIs to compute duration. The power consumption of each phase is
extracted from Chapt. 4. In these energy-aware applications, we will implement the
energy model defined in Eq. 5.1. To prove the correctness of our energy estimation
model we will compare our results with the actual energy consumption. We have
used the shunt resistor approach as defined in the Chapt. 3 to measure actual current
consumption. We have used the Python script to estimate the energy consumption
of a sensing cycle by these applications. The data gathered was an average over 10
samples.
We have categorized these applications based on the sensor used. In one category
of applications, we monitor and send the dust samples to a peer node. And in the
other category, the applications monitor and send the temperature samples to the
peer node. In this chapter, we will increase the number of sensing samples in one
sense cycle and see how our estimation model performs.
57
58 6. ENERGY-AWARE APPLICATION: INCREASING SENSING PHASE
It has been decided to run the same application by varying the number of times we
sample the particle sensor data. We will develop five different applications where the
sensor data sample frequency will be one, two, five, ten and twenty. Based on the
difference of sensor data sampling frequency we have decided to give following names
to our applications:
– SenseApp_MTS_MDOT_F411RE_1SS
– SenseApp_MTS_MDOT_F411RE_2SS
– SenseApp_MTS_MDOT_F411RE_5SS
– SenseApp_MTS_MDOT_F411RE_10SS
– SenseApp_MTS_MDOT_F411RE_20SS
In this approach, we built the energy consumption calculation model in our sensing
application. We implemented the model presented in Eq. 5.1 in the application.
The application transmits its energy consumption in one sense cycle along with the
particle density observed by the sensor to a peer node.
To implement the model defined in Eq. 5.1, we have used timer.h to get the
duration of operations from the application. The power consumption for each
operation calculated in Chapter 4 has been hard-coded in the application. In these
sample applications, we have enabled the receive operation and therefore, have added
a fixed duration for receive phase. Since the receive operation is event based and the
event service routine is defined inside the mDot library, therefore, we could not use
the timer.h APIs. Moreover, the static blocks of pre- and post- phases has not been
added separately in these applications. These static blocks have been included as
part of the main activity phase. The value of P_SENSOR is ∼493 mW, P_TX has a
value of ∼156,9 mW, P_SLEEP is ∼19,45 mW and the value of P_RX is ∼120 mW.
t_op.start();
send_data(tx_data);
t_op.stop();
duration[OP_2] = t_op.read_ms();
duration[OP_2] = duration[OP_2]/1000;
t_op.reset();
According to the Algo. 6.1, we are sending the energy consumption at the time
of transmission. At this instant, the energy consumption of transmission itself is
unknown along with the energy consumption of the sleep and receive operations. To
compensate for these values, we are adding up the energy consumption of transmitting,
receive and sleep operations of the previous cycle to the energy consumption of current
cycle’s sensing operation. This will allow us to transmit the energy consumption of
all operations however, they will overlap between current and previous sensing cycles.
Moreover, the first sample sent by the energy-aware application will be erroneous
and it must be discarded.
Since in these applications, the duration of one sensing sample is 10s and the
power consumption is ∼493 mW therefore, the sensing phase is contributing from
(98%-99%) in the energy consumption in such applications.
6.1. PARTICLE SENSOR 61
Tab. 6.1 provides the energy consumption sent by the application itself.
Table 6.1: Energy Consumption Sent by the Energy-Aware Particle Sensing Appli-
cation
Application Sensing Sample Frequency Energy(J)
SenseApp..._1SS 1 5,005±6,27×10−05
SenseApp..._2SS 2 9,933±0,0211
SenseApp..._5SS 5 24,737±0,0211
SenseApp..._10SS 10 49,412±0,0211
SenseApp..._20SS 20 98,762±0,0211
The energy-aware application developed in Sect. 8.3 is used for measuring actual
energy consumption using the oscilloscope. We used the shunt resistor approach
to measure current consumption by the mDot node. We used the Python script
defined in Appendix. A to measure energy consumption. To use python script for
automatic energy consumption measurement, we added generate_event() defined
in the Algo. 4.5. This function was added at the start and end of while(true) loop,
to get the boundaries of measurements. This script captured 10 samples from
the oscilloscope and computed an average energy consumption for the specified
application. Following is the command used to compute energy consumption when
sensing sample count was 20:
To measure the current consumption for all other applications, the capture size
was reduced accordingly. Tab. 6.2, gives the measured energy consumption using the
oscilloscope.
6.1.3 Conclusion
The results reported in Tab. 6.1, and 6.2 show that the difference between energy
consumption is insignificant for such kind of applications. Tab. 6.3 summarizes the
observed differences.
62 6. ENERGY-AWARE APPLICATION: INCREASING SENSING PHASE
Table 6.2: Energy Consumption Measurement using Oscilloscope for the Energy-
Aware Particle Sensing Application
Application Sensing Sample Frequency Energy(J)
SenseApp..._1SS 1 5,0748±7,979E-04
SenseApp..._2SS 2 9,9881±5,845E-04
SenseApp..._5SS 5 24,727±1,689E-03
SenseApp..._10SS 10 49,305±1,500E-03
SenseApp..._20SS 20 98,408±3,346E-03
Tab. 6.3, indicates that the percentage difference between the actual oscilloscope
reading and the energy-aware application is in the range (0,04-1,37)%. One reason
for such promising results can be that (98%-99%) of energy consumption in these
applications is due to the sensing operation. We got good results because our model
for energy consumption estimation for particle sensor is pretty efficient. From these
results, we can’t generalize that our energy estimation model works efficiently because
the energy profile in the current scenario is skewed towards the sensing phase.
The modification in the application is same as explained in the code snippet. 6.1,
however, to activate temperature sensor the for loop has been modified:
for (i=0;i<SENSING_SAMPLE;i++)
{
//Start temperature conversion, wait until ready
probe.convertTemperature(true, DS1820::all_devices);
temperature = probe.temperature();
temperature_sum += temperature;
temperature_sum2 += temperature * temperature;
stdErrorTemperature = (temperature_sum2 -
((temperature_sum *
temperature_sum)/(i+1)))/(i+1);
stdErrorTemperature = sqrt(stdErrorTemperature);
}
Moreover, in these applications, we have removed the receive phase from the
application. Same as particle sensor, the static blocks of pre- and post- phases has
not been added separately but they have been included as part of sleep and transmit
phase.
The value of P_SENSOR is ∼141,5 mW, P_TX has a value of ∼156,9 mW, and
P_SLEEP is ∼19,45 mW. Moreover, the cost of processing has been ignored since
the duration of processing phase is less than a µsecond.
The energy profiles of these applications are shown in Fig. 6.2. Since the temper-
64 6. ENERGY-AWARE APPLICATION: INCREASING SENSING PHASE
Table 6.4: Temperature Sensor Energy and Power Consumption with Transmission
Sensor Duration(s) Current(A) Power(W) Energy(J)
Temp 0,763±2,34E-06 0,028±3,75E-05 0,141±3,75E-05 0,108±7,22E-08
ature sensor doesn’t consume as much power as the particle sensor, therefore, the
energy distribution is not overly shadowed by the sensing phase. However, when we
increase the sensing samples within a sense cycle we observe that the sensing phase
starts to dominate the energy contribution.
Tab. 6.5 provides the energy consumption sent by the energy-aware temperature
sensing application.
To measure the actual energy consumption we used the shunt resistor approach for
measuring current consumption by the mDot node as defined in the Chapt. 3. We
used the Python script defined in Appendix. A to measure energy consumption as
explained in the Chapt. 3.
For all other applications, the capture size was reduced proportionally. Tab. 6.6,
gives the measured energy consumption using the oscilloscope.
6.2.3 Conclusion
The results reported in the Tab. 6.5, and 6.6 show that the difference between energy
consumption is insignificant. Tab. 6.7 summarizes the observed differences.
Tab. 6.7, indicates that the percentage difference between the actual oscillo-
scope reading and the energy-aware application is (0,16-1,40)%. The energy profile
of temperature sensing application; SenseApp_MTS_MDOT_F411RE_1TS, is a
66 6. ENERGY-AWARE APPLICATION: INCREASING SENSING PHASE
Table 6.6: Energy Consumption Measurement using Oscilloscope for the Energy-
Aware Temperature Sensing Application
Application Sensing Sample Frequency Energy(J)
SenseApp..._1TS 1 0,155±6,10E-04
SenseApp..._2TS 2 0,259±4,96E-04
SenseApp..._5TS 5 0,588±1,10E-03
SenseApp..._10TS 10 1,111±1,12E-03
SenseApp..._20TS 20 2,197±2,09E-03
In next chapter, we will further design new particle and temperature sensing
applications based on different sensing modes that can be set by the planning
algorithm implemented in the cloud and observe how our model performs under such
conditions.
Energy-Aware Application:
Different Sensing Modes
Chapter
7
As described in Chapt. 1, the energy-aware planning can be performed at the cloud
for efficient use of sensor nodes. By considering this functionality, we have defined
three sensing modes and developed energy-aware applications for these sensing modes.
Following describes these three modes:
– Extravagant: The sensing node has an excessive amount of energy. The sensing
node can send more data within a given time period.
– Thrifty: Energy resource is scarce. The sensing node should send sensor data
once in a while.
These different sensing modes have been characterized based on the available
energy at the sensing node. In order to operate in these different sensing modes,
we have changed the duty cycle and the frequency of sampling sensor data. The
cloud can choose any one of these modes based on the energy consumption data it
receives. In this chapter, we will develop energy-aware applications based on the
above-mentioned sensing modes. We will use temperature and particle sensors in
these applications. We will observe their energy profiles and gather the estimated
energy consumption. In the end, we will compare the estimated energy with the
actual oscilloscope measurements.
In the scenario of Particle Sensing, we have only modified the duty cycle (sleep
duration) to produce different sensing modes. Following table summarizes the
67
68 7. ENERGY-AWARE APPLICATION: DIFFERENT SENSING MODES
All the values presented in the Tab. 8.2 are with respect to one sensing cycle.
Source code 7.1 C++ Program: Energy Aware Application with Static Code
Blocks
float powerConsumption[4] ={P_SENSOR, P_ACTIVE, P_TX, P_SLEEP};
float staticEnergy[4]= {0,0,PRE_TX_ENERGY+POST_TX_ENERGY,
PRE_SLEEP_ENERGY+POST_SLEEP_ENERGY};
while(true){
t_op.start();
for (i=0; i<SENSING_SAMPLE; i++){
pDensity = getParticalDensity(vS);
......... get standard error and mean particle density ..........
}
pDensity = pDensity_sum/SENSING_SAMPLE;
t_op.stop();
duration[OP_1] = t_op.read();
t_op.reset();
t.start();
sprintf (buffer, "%f", pDensity);
for (i=0;buffer[i]!=0;i++)
tx_data.push_back(buffer[i]);
sprintf (buffer, "%f", stdErrorPDensity);
for (i=0;buffer[i]!=0;i++)
tx_data.push_back(buffer[i]);
energy = 0.0;
for (int i=0; i<4; i++){
energy += ((duration[i] * powerConsumption[i]) +
staticEnergy[i]);
sprintf (buffer, "OP%d:%f;",i+1 , ((duration[i]
* powerConsumption[i]) + staticEnergy[i]));
for (int ind=0;buffer[ind]!=0;ind++)
tx_data.push_back(buffer[ind]);
}
sprintf (buffer, "%f", energy);
for (i=0;buffer[i]!=0;i++)
tx_data.push_back(buffer[i]);
t.stop();
duration[OP_2] = t_op.read_us();
duration[OP_2] = duration[OP_2]/1000000;
t_op.start();
send_data(tx_data);
t_op.stop();
duration[OP_3] = t_op.read_ms();
duration[OP_3] = duration[OP_3]/1000 - (PRE_TX_DUR + POST_TX_DUR);
t_op.reset();
dot->sleep(SLEEP_DUR, mDot::RTC_ALARM, false);
duration[OP_4] = SLEEP_DUR - PRE_SLEEP_DUR;
}
70 7. ENERGY-AWARE APPLICATION: DIFFERENT SENSING MODES
Table 7.2: Power and Energy Consumption during Sleep Mode for Particle Sensor
State Duration(s) Current(A) Power(W) Energy(J)
Sleep 60,163±1,74E-03 9,15E-03±3,25E-05 0,046±3,25E-05 2,752±1,97E-03
In the these sensing applications, we have set the sleep phase to ∼45,7 mW.
The PRE_TX_ENERGY, POST_TX_ENERGY, PRE_SLEEP_ENERGY,
POST_SLEEP_ENERGY, PRE_TX_DUR, POST_TX_DUR, PRE_SLEEP_DUR,
and POST_SLEEP_DUR are set as explained in the Chapt. 4. While calculating
the duration of sleep phase, we didn’t subtract the post-sleep duration from the
sleep duration because it is not added to the main sleep phase. The complete source
code for these applications can be found in Appendix. C. To change among different
sensing modes, one needs to modify SLEEP_DUR and SENSING_SAMPLE in the
source code defined in Appendix. C.
Fig. 7.1 show the energy distribution of different phases under different sensing
modes. The data presented in the Fig. 7.1 is estimated over one sensing cycle.
7.1. PARTICLE SENSOR 71
7.1.2 Conclusion
In this sub-section, we will evaluate our energy estimation model for the particle
sensing applications. Tab. 7.3 provides a comparison between the energy estimation
by the application and the measured energy consumption using setup described in
the Chapt. 4.
The percentage difference for these applications is between 0,071% and 0,706%.
This confirms that our estimation model suits well for applications with such a varied
energy profiles as shown in Fig. 7.1. It is worth noting that the energy profiles
of these applications consist mainly of sensing and sleeping phases. Although we
achieved very good estimation results these results might vary if other activity phases
will contribute.
Tab. 7.3 shows that the energy consumption in the Thrifty mode is greater than
other modes. This is because the duration of one cycle of the Thrifty mode is 300 s
whereas in the Extravagant mode the duration is 20 s. If we compare the energy
consumption of all the three modes for 10 minutes it will be evident that the energy
consumption during the thrifty mode will be much less than the other two modes.
Following table presents the energy consumption estimation for 10 minutes:
Table 7.4: Particle Sensing: Energy Consumption Estimation for 10 Minutes under
Different Sensing Modes
Sensing Mode Durationonec ycle (s) # of Cycles per 600 s Estimated Energy(J)
Extravagant 20 30 165,15
Moderate 70 9 73,404
Thrifty 310 2 41,752
In the case of Temperature Sensing applications, we have modified both the duty
cycle (sleep duration) and the number of sensing samples to produce different sensing
modes. Following table summarizes the selection of different parameters in these
sensing modes:
All the values presented in the Tab. 7.5 are with respect to one sensing cycle.
7.2. TEMPERATURE SENSOR 73
These set of applications uses the same algorithm for energy estimation as specified
in Algo. 7.1. The only difference is the values of P_SENSOR and P_SLEEP. The
P_SENSOR is ∼141,5 mW and P_SLEEP is ∼1,2 mW as measured in the Chapt. 4.
Similar to the particle sensing applications we have added static blocks of energy
as can be seen in Fig. 5.2. There is no receive phase in these applications. The
packet size has also been increased similar to the above-mentioned particle sensing
applications. We developed three different applications associated with each sensing
mode and gathered their energy estimations. The complete source code for these
applications can be found in Appendix. D. To change among different sensing modes,
one needs to modify SLEEP_DUR and SENSING_SAMPLE in the source code
defined in Appendix. D. Fig. 7.2 show the energy distribution of different phases
under different sensing modes. The data presented in the Fig. 7.1 is estimated over
one sensing cycle.
7.2.2 Conclusion
In this sub-section, we will evaluate our energy estimation model. Tab. 7.6 provides
a comparison between the energy estimation by the application and the measured
energy consumption using setup described in the Chapt. 4.
The results obtained in these applications indicate that our estimation model
suites well for such kind of applications. Although the energy profiles of these
applications were quite diverse our model fitted well. It is worth mentioning that in
the temperature sensing applications, we observe that the transmission phase is also
contributing along with the sensing and sleeping phases. And our estimation model
still produced an insignificant error in estimation. These experiments increased our
confidence on our energy estimation model.
Similarly, to prove that Thrifty sensing mode consumes much less energy over
time we did similar kind of comparison as done in the previous section of particle
sensing. Following table presents the energy consumption estimation for 10 minutes:
8
In this chapter, we will develop a sensing application for waspmote1 IoT hardware
platform and compared how our estimation model performs under such type of appli-
cations. In these applications, we have used CO2 sensor to sense CO2 concentration
in the air.
1 http://www.libelium.com/products/waspmote/
75
76 8. ENERGY-AWARE APPLICATION: WASPMOTE
co2.ON();
PWR.deepSleep("00:00:00:10", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON);
co2Concentration = 0;
co2Concentration = co2.getConc();
co2.OFF();
Since the CO2 sensor for waspmote requires some time to heat up before measuring
the CO2 concentration. Therefore, for our experimental work, we have selected it
to be 10s. One can increase this value to get better CO2 concentration samples.
The first instruction declares the instance of CO2 sensor that is attached to the
SOCKET_A of the waspmote. The second instruction initializes the CO2 sensor.
Then the wapmote goes to the deep sleep state for 10 seconds while the sensors
remain on because we have set the last argument of this function to ALL_ON. The
function co2.getConc() returns the CO2 concentration and at the end, we turn off
the CO2 sensor.
8.1. APPLICATION LOGIC 77
frame.createFrame(BINARY);
frame.addSensor(SENSOR_GP_CO2, (double)co2Concentration);
errorLW = LoRaWAN.ON(SOCKET);
frequencyConfiguration();
errorLW = LoRaWAN.joinABP();
if(errorLW == 0)
{
//Send unconfirmed packet
errorLW = LoRaWAN.sendUnconfirmed(PORT, frame.buffer, frame.length);
// Error messages:
/*
* ’6’ : Module hasn’t joined a network
* ’5’ : Sending error
* ’4’ : Error with data length
* ’2’ : Module didn’t response
* ’1’ : Module communication error
*/
// Check status
if( errorLW == 0 ) {
USB.println(F("3. Send Unconfirmed packet OK"));
}
else {
USB.print(F("3. Send Unconfirmed packet error = "));
USB.println(errorLW, DEC);
}
}
else{
USB.print(F("2. Join network error = "));
USB.println(errorLW, DEC);
}
errorLW = LoRaWAN.OFF(SOCKET);
78 8. ENERGY-AWARE APPLICATION: WASPMOTE
In the Algo. 8.2, the first instruction configures the LoRaWAN communication
parameters. These parameters include device EUI, device address, network session
key, application session key, application key, adaptive data rate and retransmission
count for uplink confirmed packets. The details of these parameters can be found in
the LoRaWAN manual; as given in the reference [SLE+ 15]. The next two instructions
create a transmission frame and insert the value of CO2 concentration in the frame.
Then the LoRAWAN is enabled and the frequency of operation is configured. The
next instruction enables the waspmote to join in the Activation By Personalization
(ABP) mode. In this mode, the device address and the security keys are hard-coded
in the device and the device is activated using these hard-coded values. Finally, the
LoRaWAN packet is sent in unconfirmed mode. After that, we have some instructions
for debugging purposes and at the end, the LoRaWAN is turned off.
The third sleeping phase is quite simple. It is only one instruction where we
shift the operating mode to the deep sleep and turn off all the peripheral devices.
Following is the code snippet, where the waspmote goes to deep sleep for 20 seconds:
void generate_event(){
// setting event pin for oscillscope measurements
digitalWrite(DIGITAL3,1);
delay(100);
digitalWrite(DIGITAL3,0);
}
Table 8.1: Power and Energy Consumption of CO2 Sensing Application Running
on WASPMOTE
Activity Phase Duration(s) Current(A) Power(W) Energy(J)
Sense 11,07±7,48E-04 0,071±2,97E-05 0,357±2,97E-05 3,95±3,22E-04
Transmit 8,02±1,55E-03 0,057±5,61E-05 0,286±5,61E-05 2,30±4,58E-04
Sleep 19,71±3,24E-03 0,038±4,03E-05 0,189±4,03E-05 3,72±8,04E-04
Following code snippet explains the use of RTC timer to compute the duration of
each phase: The Algo. 8.5, shows that one activates the RTC and measure the current
Epoch time. Then one writes the code to perform operations inside an activity phase
i.e. sensing, sleeping, transmission, processing. After the activity phase ends one
again gets the time stamp and computes the duration in seconds in the activity
phase. The duration of each phase is stored in a globally defined variable Duration[].
Fig. 8.1, shows the oscilloscope dump of a sensing cycle of a CO2 energy-aware
sensing application under Moderate sensing mode.
The following figure provides the energy consumption distribution among the
activity phases by the three CO2 sensing applications:
Figure 8.2: CO2 Sensing: Energy Consumption Comparison under Different Sensing
Modes
82 8. ENERGY-AWARE APPLICATION: WASPMOTE
Tab. 8.3 provides a comparison between the energy estimation by the application
and the measure energy consumption using setup described in Chapt. 4.
Table 8.3: CO2 Sensing: Energy Consumption Comparison under Different Sensing
Modes
Sensing Mode Estimated Energy(J) Measured Energy(J) % Error
Extravagant 9,253±0 9,12±5,37E-04 1,47%
Moderate 10,288±0 9,995±7,76E-03 2,93%
Thrifty 29,088±0 29,761±4,34E-03 2,261%
These small differences presented in Tab. 8.3 in the energy estimation proves
that our energy estimation model provides a good estimation even we have changed
the hardware platform of sensing node. This shows that our energy consumption
estimation model is generic and independent of the underlying hardware platform.
Moreover, these results also prove that our energy estimation model fits well when un-
der various energy distributions of activity phases. Moreover, these results also prove
that our energy estimation model fits well when under various energy distributions
of activity phases.
Discussion and Conclusion
Chapter
9
The results from the Chapt. 6, 7 and 8 explain that the developed energy consumption
estimation model is suitable for various periodic sensing applications. The percentage
differences between the estimated energy consumption and the measured values for
all different sensing applications lie between 0,04% and 2,928%. That indicates that
the presented approach performs well as compared to other approaches presented in
the Chapt. 2.
The following figure presents the percentage error in the energy estimation under
different sensing modes running on different sensing nodes:
Figure 9.1: Percentage Error in Estimated Energy under Different Sensing Modes
Running on Different Sensing Devices
83
84 9. DISCUSSION AND CONCLUSION
Fig. 9.1 shows that the percentage error in the energy estimation of Waspmote
is greater than the other two in all the three sensing modes. The reason for this
behavior is that in the Waspmote, we didn’t add pre- and post- activity phases
separately. In the case of mDot, we ran various experiments as discussed in Chapt.
4 and concluded that the transmission and sleep operations consist of three activity
phases, i.e. pre- post- and main phases. Since we didn’t run such experiments on
Waspmote; therefore, we could not identify these static activity phases. The activity
phase identification approach in Waspmote was simple and this resulted in higher
estimation errors compared to its counterpart.
Our proposed model is generic and can be used for a variety of IoT hardware
platforms that can be powered up by external power supply. This approach is
applicable to all the IoT periodic sensing applications that have the APIs to compute
the duration of operations. The proposed technique takes care of the influences on
power consumption when different operations such as transmission, sensing, and
processing co-exist in an application. It also incorporates the dynamic nature of the
sensing application by including the run-time estimation phase.
[ADK+ 16] Dirk Ahlers, Patrick Driscoll, Frank Alexander Kraemer, Fredrik Anthonisen,
and John Krogstie. A Measurement-Driven Approach to Understand Urban
Greenhouse Gas Emissions in Nordic Cities. NIK Norsk Informatikkonferanse,
pages 1–12, November 2016.
[AIM10] Luigi Atzori, Antonio Iera, and Giacomo Motabito. The internet of things: A
survey. Computer Networks, 54(15):2787–2805, June 2010.
[APJCA10] O. Acevedo-Patiño, M. Jiménez, and A. J. Cruz-Ayoroa. Static simulation: A
method for power and energy estimation in embedded microprocessors. In 2010
53rd IEEE International Midwest Symposium on Circuits and Systems, pages
41–44, Aug 2010.
[ARM] ARMmbed timer. https://developer.mbed.org/handbook/Timer. Accessed: 2017-
03-30.
[BJ12] W. L. Bircher and L. K. John. Complete system power estimation using processor
performance events. IEEE Transactions on Computers, 61(4):563–577, April
2012.
[BSE13] M. Bazzaz, M. Salehi, and A. Ejlali. An accurate instruction-level energy estima-
tion model and tool for embedded systems. IEEE Transactions on Instrumentation
and Measurement, 62(7):1927–1934, July 2013.
[CH10] Aaron Carroll and Gernot Heiser. An analysis of power consumption in a
smartphone. In Proceedings of the 2010 USENIX Conference on USENIX Annual
Technical Conference, USENIXATC’10, pages 21–21, Berkeley, CA, USA, 2010.
USENIX Association.
[Cis] Evans, Dave the internet of things how the next evolution of the internet is
changing everything. http://www.cisco.com/c/dam/en_us/about/ac79/docs/
innov/IoT_IBSG_0411FINAL.pdf. Accessed: 2016.
[cYHAC10] D. c. You, Y. S. Hwang, Y. H. Ahn, and K. S. Chung. Energy consumption
prediction technique for embedded mobile device by using battery discharging
pattern. In 2010 2nd IEEE InternationalConference on Network Infrastructure
and Digital Content, pages 907–910, Sept 2010.
85
86 REFERENCES
[DMMJ16] Armen Dzhagaryan, Aleksandar Milenković, Mladen Milosevic, and Emil Jovanov.
An environment for automated measurement of energy consumed by mobile and
embedded computing devices. Measurement, 94:103 – 118, 2016.
[DRAP15] Gregory Ditzler, Manuel Roveri, Cesare Alippi, and Robi Polikar. Learning
in Nonstationary Environments: A Survey. IEEE Computational Intelligence
Magazine, 10(4):12–25, October 2015.
[JHA+ 16] F. Jalali, K. Hinton, R. Ayre, T. Alpcan, and R. S. Tucker. Fog computing may
help to save energy in cloud computing. IEEE Journal on Selected Areas in
Communications, 34(5):1728–1739, May 2016.
[JLL+ 14] Hrishikesh Jayakumar, Kangwoo Lee, Woo Suk Lee, Arnab Raha, Younghyun
Kim, and Vijay Raghunathan. Powering the internet of things. In Proceedings
of the 2014 International Symposium on Low Power Electronics and Design,
ISLPED ’14, pages 375–380, New York, NY, USA, 2014. ACM.
[KA07] J. Ktari and M. Abid. System level power and energy modeling for signal
processing applications. In 2007 2nd International Design and Test Workshop,
pages 218–221, Dec 2007.
[LJ03] Tao Li and Lizy Kurian John. Run-time modeling and estimation of operating
system power consumption. In Proceedings of the 2003 ACM SIGMETRICS
International Conference on Measurement and Modeling of Computer Systems,
SIGMETRICS ’03, pages 160–171, New York, NY, USA, 2003. ACM.
[LJSM04] Johann Laurent, Nathalie Julien, Eric Senn, and Eric Martin. Functional level
power analysis: An efficient approach for modeling the power consumption of
complex processors. In Proceedings of the Conference on Design, Automation
and Test in Europe - Volume 1, DATE ’04, pages 10666–, Washington, DC, USA,
2004. IEEE Computer Society.
89
90 A. PICOSCOPE PYTHON SCRIPT
def __init__(self):
self.ps = ps6000.PS6000(connect=False)
self.mCurr = []
self.mDur = []
self.sdCurr = []
self.numberOfSamples=0
self.captureLength = CLENGTH * 1E-3
self.threshold = THRESHOLD
self.samplingfreq = SAMPLINGFREQ
self.capturesampleNo = self.captureLength * (self.samplingfreq * 1E6)
def openScope(self):
self.ps.open()
def closeScope(self):
self.ps.close()
def armMeasure(self):
self.ps.runBlock()
91
Source code A.3 Energy Measurement Class: Calculating mean and standard error
def computeMeanAndStdevSubChannel(self,subChannelA, to):
self.mCurr.append(np.mean(subChannelA))
self.sdCurr.append(np.std(subChannelA))
fs = self.sampleRate / 1000
self.mDur.append(to / fs)
indices = []
for index in range(len(dataB)):
if dataB[index] >= THRESHOLD:
break;
fig = pl.figure()
pl.plot(dataA)
pl.savefig("fig\dataA"+str(self.numberOfSamples)+filename+".png")
fig.clf()
pl.close()
m += 2
sh.write(m,0,"Average", style=style)
sh.write(m,1,np.mean(self.mDur))
sh.write(m,2,np.mean(self.mCurr))
sh.write(m,3,np.mean(self.sdCurr))
power = np.mean(self.mCurr) * y
m+=3
sh.write(m,0,"Power(Watt)", style=style)
sh.write(m,1, power)
args = parser.parse_args()
THRESHOLD = args.threshold
SAMPLINGFREQ = args.samplingFreq
FILENAME = ".\Data\Report_" + args.experimentName + ".xls"
CLENGTH = args.captureLen
em = energyMeasure()
em.openScope()
try:
while em.numberOfSamples < 10:
em.armMeasure()
em.measure(args.experimentName)
em.output(FILENAME,args.experimentName,args.voltage,THRESHOLD)
except KeyboardInterrupt:
pass
em.closeScope()
mDot P2P Communication Header
Files
Appendix
B
B.1 dot_util.h
1 #i f n d e f __DOT_UTIL_H__
#d e f i n e __DOT_UTIL_H__
3
#i n c l u d e " mbed . h "
5 #i n c l u d e "mDot . h "
#i n c l u d e "MTSLog . h "
7 #i n c l u d e " MTSText . h "
#i n c l u d e " ISL29011 . h "
9 #i n c l u d e " example_config . h "
11 e x t e r n mDot∗ dot ;
13 void display_config ( ) ;
15 v o i d update_ota_config_name_phrase ( s t d : : s t r i n g network_name ,
s t d : : s t r i n g network_passphrase , u i n t 8 _ t frequency_sub_band , b o o l
public_network , u i n t 8 _ t ack ) ;
17 v o i d update_ota_config_id_key ( u i n t 8 _ t ∗ network_id , u i n t 8 _ t
∗ network_key , u i n t 8 _ t frequency_sub_band , b o o l public_network ,
u i n t 8 _ t ack ) ;
19 v o i d update_manual_config ( u i n t 8 _ t ∗ network_address , u i n t 8 _ t
∗ network_session_key , u i n t 8 _ t ∗ d a t a _ s e s s i o n _ k e y , u i n t 8 _ t
frequency_sub_band , b o o l public_network , u i n t 8 _ t ack ) ;
21 v o i d update_peer_to_peer_config ( u i n t 8 _ t ∗ network_address , u i n t 8 _ t
∗ network_session_key , u i n t 8 _ t ∗ d a t a _ s e s s i o n _ k e y , u i n t 3 2 _ t
t x _ f r e q u e n c y , u i n t 8 _ t t x _ d a t a r a t e , u i n t 8 _ t tx_power ) ;
23 v o i d update_network_link_check_config ( u i n t 8 _ t link_check_count ,
uint8_t link_check_threshold ) ;
25 void join_network ( ) ;
95
96 B. MDOT P2P COMMUNICATION HEADER FILES
27 v o i d sleep_wake_rtc_only ( b o o l d e e p s l e e p ) ;
33 void sleep_save_io ( ) ;
35 void sleep_configure_io ( ) ;
37 void sleep_restore_io ( ) ;
41 #e n d i f
B.2 mDotEvent.h
1 #i f n d e f MDOT_EVENT_H
#d e f i n e MDOT_EVENT_H
3
#i n c l u d e "mDot . h "
5 #i n c l u d e " MacEvents . h "
#i n c l u d e "MTSLog . h "
7 #i n c l u d e " MTSText . h "
9 t y p e d e f union {
u i n t 8 _ t Value ;
11 struct {
uint8_t :1;
13 uint8_t Tx : 1 ;
uint8_t Rx : 1 ;
15 uint8_t RxData : 1 ;
uint8_t RxSlot : 2 ;
17 uint8_t LinkCheck : 1 ;
uint8_t JoinAccept : 1 ;
19 } Bits ;
} LoRaMacEventFlags ;
21
t y p e d e f enum {
23 LORAMAC_EVENT_INFO_STATUS_OK = 0 ,
LORAMAC_EVENT_INFO_STATUS_ERROR,
25 LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT,
LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT,
27 LORAMAC_EVENT_INFO_STATUS_RX_ERROR,
LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL,
B.2. MDOTEVENT.H 97
29 LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL,
LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL,
31 LORAMAC_EVENT_INFO_STATUS_MIC_FAIL,
} LoRaMacEventInfoStatus ;
33
/∗ !
35 ∗ LoRaMAC e v e n t i n f o r m a t i o n
∗/
37 typedef struct {
LoRaMacEventInfoStatus S t a t u s ;
39 l o r a : : DownlinkControl C t r l ;
b o o l TxAckReceived ;
41 u i n t 8 _ t TxNbRetries ;
u i n t 8 _ t TxDatarate ;
43 u i n t 8 _ t RxPort ;
u i n t 8 _ t ∗ RxBuffer ;
45 uint8_t RxBufferSize ;
i n t 1 6 _ t RxRssi ;
47 u i n t 8 _ t RxSnr ;
u i n t 1 6 _ t Energy ;
49 u i n t 8 _ t DemodMargin ;
u i n t 8 _ t NbGateways ;
51 } LoRaMacEventInfo ;
53 c l a s s mDotEvent : p u b l i c l o r a : : MacEvents {
public :
55
mDotEvent ( )
57 :
LinkCheckAnsReceived ( f a l s e ) ,
59 DemodMargin ( 0 ) ,
NbGateways ( 0 ) ,
61 PacketReceived ( f a l s e ) ,
RxPort ( 0 ) ,
63 RxPayloadSize ( 0 ) ,
PongReceived ( f a l s e ) ,
65 PongRssi ( 0 ) ,
PongSnr ( 0 ) ,
67 AckReceived ( f a l s e ) ,
TxNbRetries ( 0 )
69 {
memset(& _ f l a g s , 0 , s i z e o f ( LoRaMacEventFlags ) ) ;
71 memset(& _info , 0 , s i z e o f ( LoRaMacEventInfo ) ) ;
}
73
v i r t u a l ~mDotEvent ( ) {
75 }
77 v i r t u a l v o i d MacEvent ( LoRaMacEventFlags ∗ f l a g s ,
LoRaMacEventInfo ∗ i n f o ) {
i f ( mts : : MTSLog : : g e t L o g L e v e l ( ) ==
mts : : MTSLog : : TRACE_LEVEL) {
98 B. MDOT P2P COMMUNICATION HEADER FILES
79 s t d : : s t r i n g msg = "OK" ;
s w i t c h ( i n f o −>S t a t u s ) {
81 c a s e LORAMAC_EVENT_INFO_STATUS_ERROR:
msg = "ERROR" ;
83 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
85 msg = "TX_TIMEOUT" ;
break ;
87 c a s e LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT:
msg = "RX_TIMEOUT" ;
89 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_RX_ERROR:
91 msg = "RX_ERROR" ;
break ;
93 c a s e LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
msg = " JOIN_FAIL " ;
95 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL:
97 msg = "DOWNLINK_FAIL" ;
break ;
99 c a s e LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
msg = "ADDRESS_FAIL" ;
101 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
103 msg = "MIC_FAIL" ;
break ;
105 default :
break ;
107 }
l o g T r a c e ( " Event : %s " , msg . c _ s t r ( ) ) ;
109
l o g T r a c e ( " F l a g s Tx : %d Rx : %d RxData : %d RxSlot : %d
LinkCheck : %d J o i n A c c e p t : %d " ,
111 f l a g s −>B i t s . Tx , f l a g s −>B i t s . Rx ,
f l a g s −>B i t s . RxData , f l a g s −>B i t s . RxSlot , f l a g s −>B i t s . LinkCheck ,
f l a g s −>B i t s . J o i n A c c e p t ) ;
l o g T r a c e ( " I n f o : S t a t u s : %d ACK: %d R e t r i e s : %d TxDR:
%d RxPort : %d RxSize : %d RSSI : %d SNR : %d Energy : %d Margin : %d
Gateways : %d " ,
113 i n f o −>S t a t u s , i n f o −>TxAckReceived ,
i n f o −>TxNbRetries , i n f o −>TxDatarate , i n f o −>RxPort ,
i n f o −>R x B u f f e r S i z e ,
i n f o −>RxRssi , i n f o −>RxSnr , i n f o −>Energy ,
i n f o −>DemodMargin , i n f o −>NbGateways ) ;
115 }
}
117
v i r t u a l v o i d TxDone ( u i n t 8 _ t dr ) {
119 RxPayloadSize = 0 ;
LinkCheckAnsReceived = f a l s e ;
121 PacketReceived = f a l s e ;
AckReceived = f a l s e ;
B.2. MDOTEVENT.H 99
123 PongReceived = f a l s e ;
TxNbRetries = 0 ;
125
logDebug ( " mDotEvent − TxDone " ) ;
127 memset(& _ f l a g s , 0 , s i z e o f ( LoRaMacEventFlags ) ) ;
memset(& _info , 0 , s i z e o f ( LoRaMacEventInfo ) ) ;
129
_ f l a g s . B i t s . Tx = 1 ;
131 _ i n f o . TxDatarate = dr ;
_ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_OK;
133 Notify () ;
}
135
void Notify ( ) {
137 MacEvent(& _ f l a g s , &_ i n f o ) ;
}
139
v i r t u a l v o i d TxTimeout ( v o i d ) {
141 logDebug ( " mDotEvent − TxTimeout " ) ;
143 _ f l a g s . B i t s . Tx = 1 ;
_ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT;
145 Notify () ;
}
147
v i r t u a l v o i d J o i n A c c e p t ( u i n t 8 _ t ∗ payload , u i n t 1 6 _ t s i z e ,
int16_t r s s i , int8_t snr ) {
149 logDebug ( " mDotEvent − J o i n A c c e p t " ) ;
151 _ f l a g s . B i t s . Tx = 0 ;
_flags . Bits . JoinAccept = 1 ;
153 _ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_OK;
Notify () ;
155 }
157 v i r t u a l v o i d J o i n F a i l e d ( u i n t 8 _ t ∗ payload , u i n t 1 6 _ t s i z e ,
int16_t r s s i , int8_t snr ) {
logDebug ( " mDotEvent − J o i n F a i l e d " ) ;
159
_ f l a g s . B i t s . Tx = 0 ;
161 _flags . Bits . JoinAccept = 1 ;
_ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL;
163 Notify () ;
}
165
v i r t u a l v o i d MissedAck ( u i n t 8 _ t r e t r i e s ) {
167 logDebug ( " mDotEvent − MissedAck : r e t r i e s %u " , r e t r i e s ) ;
TxNbRetries = r e t r i e s ;
169 _ i n f o . TxNbRetries = r e t r i e s ;
}
171
100 B. MDOT P2P COMMUNICATION HEADER FILES
v i r t u a l v o i d PacketRx ( u i n t 8 _ t p o r t , u i n t 8 _ t ∗ payload , u i n t 1 6 _ t
s i z e , i n t 1 6 _ t r s s i , i n t 8 _ t snr , l o r a : : DownlinkControl c t r l ,
uint8_t s l o t , uint8_t r e t r i e s = 0) {
173 logDebug ( " mDotEvent − PacketRx " ) ;
RxPort = p o r t ;
175 PacketReceived = true ;
189 _ f l a g s . B i t s . Tx = 0 ;
_ f l a g s . B i t s . Rx = 1 ;
191 _ f l a g s . B i t s . RxData = s i z e > 0 ;
_ f l a g s . B i t s . RxSlot = s l o t ;
193 _ i n f o . RxBuffer = p a y l o a d ;
_info . RxBufferSize = s i z e ;
195 _ i n f o . RxPort = p o r t ;
_ i n f o . RxRssi = r s s i ;
197 _ i n f o . RxSnr = s n r ;
_ i n f o . TxAckReceived = AckReceived ;
199 _ i n f o . TxNbRetries = r e t r i e s ;
_ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_OK;
201 Notify () ;
}
203
v i r t u a l v o i d RxDone ( u i n t 8 _ t ∗ payload , u i n t 1 6 _ t s i z e , i n t 1 6 _ t
r s s i , i n t 8 _ t snr , l o r a : : DownlinkControl c t r l , u i n t 8 _ t s l o t ) {
205 logDebug ( " mDotEvent − RxDone " ) ;
}
207
v i r t u a l v o i d Pong ( i n t 1 6 _ t m_rssi , i n t 8 _ t m_snr , i n t 1 6 _ t
s _ r s s i , i n t 8 _ t s_snr ) {
209 logDebug ( " mDotEvent − Pong " ) ;
PongReceived = t r u e ;
211 PongRssi = s _ r s s i ;
PongSnr = s_snr ;
213 }
217 LinkCheckAnsReceived = t r u e ;
DemodMargin = s_snr ;
219 NbGateways = s_gateways ;
221 _ f l a g s . B i t s . Tx = 0 ;
_ f l a g s . B i t s . LinkCheck = 1 ;
223 _ i n f o . RxRssi = m_rssi ;
_ i n f o . RxSnr = m_snr ;
225 _ i n f o . DemodMargin = s_snr ;
_ i n f o . NbGateways = s_gateways ;
227 _ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_OK;
Notify () ;
229 }
231 v i r t u a l v o i d RxTimeout ( u i n t 8 _ t s l o t ) {
// logDebug ( " mDotEvent − RxTimeout " ) ;
233
_ f l a g s . B i t s . Tx = 0 ;
235 _ f l a g s . B i t s . RxSlot = s l o t ;
_ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT;
237 Notify () ;
}
239
v i r t u a l v o i d RxError ( u i n t 8 _ t s l o t ) {
241 logDebug ( " mDotEvent − RxError " ) ;
251 v i r t u a l u i n t 8 _ t M e a su r e Ba t t er y ( v o i d ) {
return 255;
253 }
255 b o o l LinkCheckAnsReceived ;
u i n t 8 _ t DemodMargin ;
257 u i n t 8 _ t NbGateways ;
269 u i n t 8 _ t TxNbRetries ;
271 LoRaMacEventFlags& F l a g s ( ) {
return _flags ;
273 }
LoRaMacEventInfo& I n f o ( ) {
275 return _info ;
}
277
private :
279
LoRaMacEventFlags _ f l a g s ;
281 LoRaMacEventInfo _ i n f o ;
283 //
// /∗!
285 // ∗ MAC l a y e r e v e n t c a l l b a c k p r o t o t y p e .
// ∗
287 // ∗ \param [ IN ] f l a g s B i t f i e l d i n d i c a t i n g t h e MAC e v e n t s
occurred
// ∗ \param [ IN ] i n f o D e t a i l s about MAC e v e n t s o c c u r r e d
289 // ∗/
// v i r t u a l v o i d MacEvent ( LoRaMacEventFlags ∗ f l a g s ,
LoRaMacEventInfo ∗ i n f o ) {
291 // logDebug ( " mDotEvent " ) ;
//
293 // i f ( f l a g s −>B i t s . Rx) {
// logDebug ( " Rx " ) ;
295 //
// // Event O b j e c t must d e l e t e RxBuffer
297 // d e l e t e [ ] i n f o −>RxBuffer ;
// }
299 // }
//
301
};
303
#e n d i f // __MDOT_EVENT_H__
B.3 RadioEvent.h
#i f n d e f __RADIO_EVENT_H__
2 #d e f i n e __RADIO_EVENT_H__
4 #i n c l u d e " d o t _ u t i l . h "
#i n c l u d e " mDotEvent . h "
6
B.3. RADIOEVENT.H 103
c l a s s RadioEvent : p u b l i c mDotEvent
8 {
10 public :
RadioEvent ( ) {}
12
v i r t u a l ~ RadioEvent ( ) {}
14
/∗ !
16 ∗ MAC l a y e r e v e n t c a l l b a c k p r o t o t y p e .
∗
18 ∗ \param [ IN ] f l a g s B i t f i e l d i n d i c a t i n g t h e MAC e v e n t s o c c u r r e d
∗ \param [ IN ] i n f o D e t a i l s about MAC e v e n t s o c c u r r e d
20 ∗/
v i r t u a l v o i d MacEvent ( LoRaMacEventFlags ∗ f l a g s , LoRaMacEventInfo ∗
info ) {
22
i f ( mts : : MTSLog : : g e t L o g L e v e l ( ) == mts : : MTSLog : : TRACE_LEVEL) {
24 s t d : : s t r i n g msg = "OK" ;
s w i t c h ( i n f o −>S t a t u s ) {
26 c a s e LORAMAC_EVENT_INFO_STATUS_ERROR:
msg = "ERROR" ;
28 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
30 msg = "TX_TIMEOUT" ;
break ;
32 c a s e LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT:
msg = "RX_TIMEOUT" ;
34 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_RX_ERROR:
36 msg = "RX_ERROR" ;
break ;
38 c a s e LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
msg = " JOIN_FAIL " ;
40 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL:
42 msg = "DOWNLINK_FAIL" ;
break ;
44 c a s e LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
msg = "ADDRESS_FAIL" ;
46 break ;
c a s e LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
48 msg = "MIC_FAIL" ;
break ;
50 default :
break ;
52 }
l o g T r a c e ( " Event : %s " , msg . c _ s t r ( ) ) ;
54
l o g T r a c e ( " F l a g s Tx : %d Rx : %d RxData : %d RxSlot : %d
LinkCheck : %d J o i n A c c e p t : %d " ,
104 B. MDOT P2P COMMUNICATION HEADER FILES
56 f l a g s −>B i t s . Tx , f l a g s −>B i t s . Rx ,
f l a g s −>B i t s . RxData , f l a g s −>B i t s . RxSlot , f l a g s −>B i t s . LinkCheck ,
f l a g s −>B i t s . J o i n A c c e p t ) ;
l o g T r a c e ( " I n f o : S t a t u s : %d ACK: %d R e t r i e s : %d TxDR: %d
RxPort : %d RxSize : %d RSSI : %d SNR : %d Energy : %d Margin : %d
Gateways : %d " ,
58 i n f o −>S t a t u s , i n f o −>TxAckReceived ,
i n f o −>TxNbRetries , i n f o −>TxDatarate , i n f o −>RxPort ,
i n f o −>R x B u f f e r S i z e ,
i n f o −>RxRssi , i n f o −>RxSnr , i n f o −>Energy ,
i n f o −>DemodMargin , i n f o −>NbGateways ) ;
60 }
62 i f ( f l a g s −>B i t s . Rx) {
4 // P a r t i c a l S e n s o r
#d e f i n e FAN_PIN PA_3
6 #d e f i n e LED_PIN PA_0
#d e f i n e MEASUREV_PIN PB_0
8
#d e f i n e FANFREESAMPLE 50
10 #d e f i n e SAMPLING_TIME 280
#d e f i n e DELTA_TIME 40
12 #d e f i n e SLEEP_TIME 9680
14 #d e f i n e SENSING_SAMPLE 2
16 #d e f i n e P_ACTIVE 0.1536
#d e f i n e P_SENSOR 0.493
18 #d e f i n e P_TX 0.324745
#d e f i n e P_SLEEP 0.0457
20
#d e f i n e SLEEP_DUR 120
22 #d e f i n e PRE_SLEEP_DUR 0.04399
#d e f i n e SENSING_SAMPLE 1
24 #d e f i n e PRE_SLEEP_ENERGY 0.0027
#d e f i n e POST_SLEEP_ENERGY 0.0176
26
#d e f i n e PRE_TX_ENERGY 0.00086779
28 #d e f i n e POST_TX_ENERGY 0.00152
#d e f i n e PRE_TX_DUR 0.011
30 #d e f i n e POST_TX_DUR 0.00796
32 #d e f i n e FAN_ON_DUR 10
34 #d e f i n e OP_1 0
#d e f i n e OP_2 1
36 #d e f i n e OP_3 2
#d e f i n e OP_4 3
38
105
106 C. MDOT PARTICLE SENSING ENERGY-AWARE APPLICATION
// P a r t i c a l S e n s o r
40 f l o a t getVsWithOutFAN ( v o i d ) ;
float getParticalDensity ( float ) ;
42 f l o a t getDustVoltageSample ( void ) ;
void generate_event ( ) ;
44
s t a t i c uint8_t network_address [ ] = { 0 x01 , 0 x02 , 0 x03 , 0 x04 } ;
46 s t a t i c uint8_t n e t w o r k _ s e s s i o n _ k e y [ ] = { 0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x01 ,
0 x02 , 0 x03 , 0 x04 , 0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x01 , 0 x02 , 0 x03 , 0 x04 } ;
s t a t i c uint8_t d a t a _ s e s s i o n _ k e y [ ] = { 0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x01 ,
0 x02 , 0 x03 , 0 x04 , 0 x01 , 0 x02 , 0 x03 , 0 x04 , 0 x01 , 0 x02 , 0 x03 , 0 x04 } ;
48
mDot∗ dot = NULL;
50
S e r i a l pc (USBTX, USBRX) ;
52
D i g i t a l O u t f a n C t r l (FAN_PIN) ;
54 D i g i t a l O u t l e d p o w e r (LED_PIN) ;
AnalogIn measure (MEASUREV_PIN) ;
56
58 i n t main ( ) {
60 // Custom e v e n t h a n d l e r f o r a u t o m a t i c a l l y d i s p l a y i n g RX data
RadioEvent e v e n t s ;
62 uint32_t tx_frequency ;
uint8_t tx_datarate ;
64 u i n t 8 _ t tx_power ;
u i n t 8 _ t frequency_band ;
66
// P a r t i c a l S e n s o r
68 f l o a t vS = 0 ; // s t o r e s r e f e r e n c e v o l t a g e
70 pc . baud ( 1 1 5 2 0 0 ) ;
mts : : MTSLog : : s e t L o g L e v e l ( mts : : MTSLog : : TRACE_LEVEL) ;
72
dot = mDot : : g e t I n s t a n c e ( ) ;
74
l o g I n f o ( " mbed−o s l i b r a r y v e r s i o n : %d " , MBED_LIBRARY_VERSION) ;
76
// s t a r t from a w e l l −known s t a t e
78 l o g I n f o ( " d e f a u l t i n g Dot c o n f i g u r a t i o n " ) ;
dot−>r e s e t C o n f i g ( ) ;
80
// make s u r e l i b r a r y l o g g i n g i s t u r n e d on
82 dot−>s e t L o g L e v e l ( mts : : MTSLog : : INFO_LEVEL) ;
84 // a t t a c h t h e custom e v e n t s h a n d l e r
dot−>s e t E v e n t s (& e v e n t s ) ;
86
// update c o n f i g u r a t i o n i f n e c e s s a r y
88 i f ( dot−>getJoinMode ( ) != mDot : : PEER_TO_PEER) {
107
126 // s a v e c h a n g e s t o c o n f i g u r a t i o n
logInfo ( " saving configuration " ) ;
128 i f ( ! dot−>s a v e C o n f i g ( ) ) {
logError ( " f a i l e d to save c o n f i g u r a t i o n " ) ;
130 }
132 // d i s p l a y c o n f i g u r a t i o n
display_config () ;
134
108 C. MDOT PARTICLE SENSING ENERGY-AWARE APPLICATION
l o g I n f o ( " g e t t i n g Vs " ) ;
136 vS = getVsWithOutFAN ( ) ;
152 f l o a t pDensity = 0 . 0 ;
f l o a t pDensity_sum = 0 . 0 ;
154 f l o a t pDensity_sum2 = 0 . 0 ;
f l o a t stdErrorPDensity = 0 . 0 ;
156 s t d : : v e c t o r <uint8_t> tx_data ;
i n t i =0;
158
// E n t e r i n g s e n s i n g phase
160 t_op . s t a r t ( ) ;
f o r ( i =0; i <SENSING_SAMPLE ; i ++){
162 // g e t t h e l a t e s t d u s t sample
p D e n s i t y = g e t P a r t i c a l D e n s i t y ( vS ) ;
164 pDensity_sum += p D e n s i t y ;
pDensity_sum2 += p D e n s i t y ∗ p D e n s i t y ;
166 s t d E r r o r P D e n s i t y = ( pDensity_sum2 − ( ( pDensity_sum ∗
pDensity_sum ) / ( i +1) ) ) / ( i +1) ;
stdErrorPDensity = sqrt ( stdErrorPDensity ) ;
168 }
172 // C a p t u r i n g s e n s i n g d u r a t i o n
t_op . s t o p ( ) ;
174 d u r a t i o n [ OP_1 ] = t_op . r e a d ( ) ;
t_op . r e s e t ( ) ;
176
// s t a r t i n g p r o c e s s i n g phase
178 t_op . s t a r t ( ) ;
// j o i n network i f not j o i n e d
180 i f ( ! dot−>g e t N e t w o r k J o i n S t a t u s ( ) ) {
join_network ( ) ;
182 }
184 // ad di ng a v e r a g e s e n s e d data
109
// t o t h e t r a n s m i s s i o n frame
186 s p r i n t f ( b u f f e r , "%f " , p D e n s i t y ) ;
f o r ( i =0; b u f f e r [ i ] ! = 0 ; i ++)
188 tx_data . push_back ( b u f f e r [ i ] ) ;
190 // ad di ng data s e p a r a t o r
// t o t h e t r a n s m i s s i o n frame
192 tx_data . push_back ( 5 9 ) ;
194 // ad di ng s t d . e r r o r o f s e n s e d data
// t o t h e t r a n s m i s s i o n frame
196 s p r i n t f ( b u f f e r , "%f " , s t d E r r o r P D e n s i t y ) ;
f o r ( i =0; b u f f e r [ i ] ! = 0 ; i ++)
198 tx_data . push_back ( b u f f e r [ i ] ) ;
200 // ad di ng data s e p a r a t o r
// t o t h e t r a n s m i s s i o n frame
202 tx_data . push_back ( 5 9 ) ;
energy = 0 . 0 ;
204 f o r ( i n t i =0; i <4; i ++)
{
206 e n e r g y += ( ( d u r a t i o n [ i ] ∗ powerConsumption [ i ] ) +
staticEnergy [ i ] ) ;
232 // C a p t u r i n g t r a n s m i s s i o n d u r a t i o n
d u r a t i o n [ OP_3 ] = t_op . read_ms ( ) ;
110 C. MDOT PARTICLE SENSING ENERGY-AWARE APPLICATION
246 // S i n g l e t h e O s c i l l o s c o p e t o s t o p s a m p l i n g
generate_event ( ) ;
248
// Wait f o r a d u r a t i o n g r e a t e r than t h e
250 // a c t u a l s e n s i n g c y c l e d u r a t i o n .
// This w a i t was added t o g e t t h e p r e c i s e measurement
252 // from t h e o s c i l l o s c o p e .
// You can comment t h i s w a i t i f you a r e not s a m p l i n g
254 // a u t o m a t i c a l l y from t h e o s c i l l o s c o p e .
w a i t (SLEEP_DUR + (FAN_ON_DUR∗SENSING_SAMPLE) + 5 ) ;
256 }
258 return 0;
}
260
f l o a t getDustVoltageSample ( void )
262 {
f l o a t dustVMeasured = 0 . 0 ;
264
l e d p o w e r = 0 ; // t u r n t h e LED on
266 wait_us (SAMPLING_TIME) ; // Wait samplingTime b e f o r e r e a d i n g V0output
268 // r e a d t h e d u s t v a l u e i n ( 0 − 1 . 0 )<−>(0V−3.3V)
dustVMeasured = measure . r e a d ( ) ;
270
wait_us (DELTA_TIME) ; // Wait d e l t a T i m e b e f o r e s h u t t i g n o f LED
272 l e d p o w e r = 1 ; // t u r n t h e LED o f f
278 f l o a t getVsWithOutFAN ( v o i d )
{
280 f a n C t r l = 0 ; // Turn o f f t h e f a n
f l o a t vsMeasured_sum = 0 ;
282 i n t fanFreeSampleCtr = 0 ;
f o r ( f a n F r e e S a m p l e C t r = 0 ; f a n F r e e S a m p l e C t r < FANFREESAMPLE;
f a n F r e e S a m p l e C t r++)
111
284 vsMeasured_sum += ( g e t D u s t V o l t a g e S a m p l e ( ) ∗ 3 . 3 ) ;
286 r e t u r n vsMeasured_sum ;
}
288
f l o a t g e t P a r t i c a l D e n s i t y ( f l o a t vS )
290 {
f l o a t voMeasured = 0 ; // S t o r e s measured ou tp ut ( 0 − 1 . 0 ) from s e n s o r
292 f l o a t c a l c V o l t a g e = 0 ; // C a l c u l a t e a c t u a l v o l t a g e ou tp ut from
sensor
f l o a t dustDensity = 0;
294
// Turn on t h e FAN t o s t a r t s a m p l i n g
296 fanCtrl = 1;
w a i t (FAN_ON_DUR) ; // Minimum i n t e r m i t t a n t time i s 10 s
298 voMeasured = g e t D u s t V o l t a g e S a m p l e ( ) ;
particleSensingEnergyAware.cpp
mDot Temperature Sensing
Energy-Aware Application
Appendix
D
1 #i n c l u d e " d o t _ u t i l . h "
#i n c l u d e " RadioEvent . h "
3
#d e f i n e P_ACTIVE 0.1536
5 #d e f i n e P_SENSOR 0.1415
#d e f i n e P_TX 0.324745
7 #d e f i n e P_SLEEP 0.0012
9 #d e f i n e SLEEP_DUR 2
#d e f i n e PRE_SLEEP_DUR 0.04399
11 #d e f i n e SENSING_SAMPLE 2
#d e f i n e PRE_SLEEP_ENERGY 0.0027
13 #d e f i n e POST_SLEEP_ENERGY 0.0176
15 #d e f i n e PRE_TX_ENERGY 0.00086779
#d e f i n e POST_TX_ENERGY 0.00152
17 #d e f i n e PRE_TX_DUR 0.011
#d e f i n e POST_TX_DUR 0.00796
19
#d e f i n e OP_1 0
21 #d e f i n e OP_2 1
#d e f i n e OP_3 2
23 #d e f i n e OP_4 3
25 // DS18B20 OneWire p i n
// D13 on Dev Board , p i n 18 on mDot ,
27 // Compatible with Oxford Flood Network PCB t e m p e r a t u r e s e n s o r .
#d e f i n e DATA_PIN PA_5
29
// Temperature s e n s o r o b j e c t
31 DS1820 probe (DATA_PIN) ;
33 void generate_event ( ) ;
113
114 D. MDOT TEMPERATURE SENSING ENERGY-AWARE APPLICATION
65 // a t t a c h t h e custom e v e n t s h a n d l e r
dot−>s e t E v e n t s (& e v e n t s ) ;
67
// update c o n f i g u r a t i o n i f n e c e s s a r y
69 i f ( dot−>getJoinMode ( ) != mDot : : PEER_TO_PEER) {
l o g I n f o ( " c h a n g i n g network j o i n mode t o PEER_TO_PEER" ) ;
71 i f ( dot−>setJoinMode (mDot : : PEER_TO_PEER) != mDot : :MDOT_OK) {
l o g E r r o r ( " f a i l e d t o s e t network j o i n mode t o
PEER_TO_PEER" ) ;
73 }
}
75 frequency_band = dot−>getFrequencyBand ( ) ;
s w i t c h ( frequency_band ) {
77 c a s e mDot : : FB_EU868 :
// 250 kHz c h a n n e l s a c h i e v e h i g h e r t h r o u g h p u t
79 // DR6 : SF7 @ 250 kHz
// DR0 − DR5 ( 1 2 5 kHz c h a n n e l s ) a v a i l a b l e but much s l o w e r
81 tx_frequency = 869850000;
t x _ d a t a r a t e = mDot : : DR6 ;
83 // t h e 869850000 f r e q u e n c y i s 100% duty c y c l e i f t h e t o t a l
power i s under 7 dBm − t x power 4 + antenna g a i n 3 = 7
tx_power = 4 ;
85 break ;
115
c a s e mDot : : FB_US915 :
87 c a s e mDot : : FB_AU915 :
default :
89 // 500 kHz c h a n n e l s a c h i e v e h i g h e s t t h r o u g h p u t
// DR8 : SF12 @ 500 kHz
91 // DR9 : SF11 @ 500 kHz
// DR10 : SF10 @ 500 kHz
93 // DR11 : SF9 @ 500 kHz
// DR12 : SF8 @ 500 kHz
95 // DR13 : SF7 @ 500 kHz
// DR0 − DR3 ( 1 2 5 kHz c h a n n e l s ) a v a i l a b l e but much s l o w e r
97 tx_frequency = 915500000;
t x _ d a t a r a t e = mDot : : DR13 ;
99 // 915 bands have no duty c y c l e r e s t r i c t i o n s , s e t t x power
t o max
tx_power = 2 0 ;
101 break ;
}
103 // i n PEER_TO_PEER mode t h e r e i s no j o i n r e q u e s t / r e s p o n s e
transaction
// a s l o n g a s both Dots a r e c o n f i g u r e d c o r r e c t l y , t h e y s h o u l d be
a b l e t o communicate
105 update_peer_to_peer_config ( network_address , network_session_key ,
d a t a _ s e s s i o n _ k e y , t x _ f r e q u e n c y , t x _ d a t a r a t e , tx_power ) ;
107 // s a v e c h a n g e s t o c o n f i g u r a t i o n
logInfo ( " saving configuration " ) ;
109 i f ( ! dot−>s a v e C o n f i g ( ) ) {
logError ( " f a i l e d to save c o n f i g u r a t i o n " ) ;
111 }
113 // d i s p l a y c o n f i g u r a t i o n
display_config () ;
115
// S e t t h e Temperature s e s n o r r e s o l u t i o n , 9 b i t s i s enough and
makes i t f a s t e r t o p r o v i d e a r e a d i n g .
117 probe . s e t R e s o l u t i o n ( 9 ) ;
f l o a t temperature_sum2 = 0 . 0 ;
133 f l o a t stdErrorTemperature = 0 . 0 ;
s t d : : v e c t o r <uint8_t> tx_data ;
135 i n t i =0;
f l o a t tempdur = 0 . 0 ;
137
// E n t e r i n g s e n s i n g phase
139 t_op . s t a r t ( ) ;
f o r ( i =0; i <SENSING_SAMPLE ; i ++){
141 // S t a r t t e m p e r a t u r e c o n v e r s i o n , w a i t u n t i l r e a d y
probe . c o n v e r t T e m p e r a t u r e ( t r u e , DS1820 : : a l l _ d e v i c e s ) ;
143 t e m p e r a t u r e = probe . t e m p e r a t u r e ( ) ;
145 temperature_sum += t e m p e r a t u r e ;
temperature_sum2 += t e m p e r a t u r e ∗ t e m p e r a t u r e ;
147 s t d E r r o r T e m p e r a t u r e = ( temperature_sum2 −
( ( temperature_sum ∗ temperature_sum ) / ( i +1) ) ) / ( i +1) ;
stdErrorTemperature = s q r t ( stdErrorTemperature ) ;
149 }
153 // C a p t u r i n g s e n s i n g d u r a t i o n
t_op . s t o p ( ) ;
155 d u r a t i o n [ OP_1 ] = t_op . r e a d ( ) ;
t_op . r e s e t ( ) ;
157
// s t a r t i n g p r o c e s s i n g phase
159 t_op . s t a r t ( ) ;
// j o i n network i f not j o i n e d
161 i f ( ! dot−>g e t N e t w o r k J o i n S t a t u s ( ) ) {
join_network ( ) ;
163 }
165 // ad di ng a v e r a g e s e n s e d data
// t o t h e t r a n s m i s s i o n frame
167 s p r i n t f ( b u f f e r , "%f " , t e m p e r a t u r e ) ;
f o r ( i =0; b u f f e r [ i ] ! = 0 ; i ++)
169 tx_data . push_back ( b u f f e r [ i ] ) ;
171 // ad di ng data s e p a r a t o r
// t o t h e t r a n s m i s s i o n frame
173 tx_data . push_back ( 5 9 ) ;
175 // ad di ng s t d . e r r o r o f s e n s e d data
// t o t h e t r a n s m i s s i o n frame
177 s p r i n t f ( b u f f e r , "%f " , s t d E r r o r T e m p e r a t u r e ) ;
f o r ( i =0; b u f f e r [ i ] ! = 0 ; i ++)
179 tx_data . push_back ( b u f f e r [ i ] ) ;
181 // ad di ng data s e p a r a t o r
// t o t h e t r a n s m i s s i o n frame
117
213 // C a p t u r i n g t r a n s m i s s i o n d u r a t i o n
d u r a t i o n [ OP_3 ] = t_op . read_ms ( ) ;
215 d u r a t i o n [ OP_3 ] = d u r a t i o n [ OP_3] / 1 0 0 0 − (PRE_TX_DUR +
POST_TX_DUR) ;
t_op . r e s e t ( ) ;
217
// E n t e r i n g s l e e p mode f o r SLEEP_DUR s e c o n d s
219 dot−>s l e e p (SLEEP_DUR, mDot : : RTC_ALARM, f a l s e ) ;
// S i n c e t h e t i m e r r o u t i n e d o e s not work i n t h e s l e e p mode
221 // T h e r e f o r e , I have f i x e d i t s d u r a t i o n .
// Moreover , I d i d not s u b t r a c t t h e POST_SLEEP_DUR
223 // b e c a u s e a f t e r a n a l y s i s I found t h a t t h e POST_SLEEP_DUR
// i s added t o t h e a c t u a l s l e e p d u r a t i o n .
225 d u r a t i o n [ OP_4 ] = SLEEP_DUR − PRE_SLEEP_DUR;
227 // S i n g l e t h e O s c i l l o s c o p e t o s t o p s a m p l i n g
generate_event ( ) ;
229
// Wait f o r a d u r a t i o n g r e a t e r than t h e
231 // a c t u a l s e n s i n g c y c l e d u r a t i o n .
118 D. MDOT TEMPERATURE SENSING ENERGY-AWARE APPLICATION
239 return 0;
}
241
void generate_event ( )
243 {
D i g i t a l O u t l e d 1 (PA_2) ;
245 led1 = 1;
wait_ms ( 1 0 0 ) ;
247 led1 = 0;
}
tempSensingEnergyAware.cpp
Appendix
waspMote CO2 Sensing
Energy-Aware Application E
E.1 Header File
1 #d e f i n e DEVICE_ID "wmt−v12−v3−1"
2 #d e f i n e DEVICE_EUI " 0041549CB158AB46 "
3 #d e f i n e DEVICE_ADDR " 260116E2 "
4 #d e f i n e NWK_SESSION_KEY " 131CF400BBC2D7C0CB35E86CA9FA7022 "
5 #d e f i n e APP_SESSION_KEY " 184F79B3706D6DA8F46AE4AFEEF721C4 "
6 #d e f i n e APP_KEY " 184F79B3706D6DA8F46AE4AFEEF721C4 "
7 #d e f i n e TRANSMISSION_POWER 1 // 14 dBm
8
9 #d e f i n e LW_CH 8
10 uint32_t lwFreqs [ ] = {868100000 , 868300000 , 868500000 , 867100000 ,
867300000 , 867500000 , 867700000 , 867900000};
11
12 //#d e f i n e _DEBUG
13 #d e f i n e SHOW_BATT_LEVEL
configParams.h
1 #i n c l u d e <WaspSensorGas_Pro . h>
2 #i n c l u d e <WaspFrame . h>
3 #i n c l u d e <WaspLoRaWAN . h>
4 #i n c l u d e " configParams . h "
5
6 #d e f i n e VERSION 3
7
8 #d e f i n e PORT 3 // Port t o u s e i n Back−End : from 1 t o 223
9 #d e f i n e SOCKET SOCKET0
10
11 #d e f i n e MAX_SENSE_COUNT 1
119
120 E. WASPMOTE CO2 SENSING ENERGY-AWARE APPLICATION
12 #d e f i n e PC_SENSE 0.3572
13 #d e f i n e PC_TRANSMIT 0.2891
14 #d e f i n e PC_SLEEP 0.1890
15
16 f l o a t itmTemperature , t e m p e r a t u r e ; // S t o r e s t h e t e m p e r a t u r e i n
celsius
17 f l o a t itmHumidity , humidity ; // S t o r e s t h e r e a l i t v e humidity i n %RH
18 f l o a t itmPressure , pressure ; // S t o r e s t h e p r e s s u r e i n Pa
19 f l o a t itmCO2 , itmNO2 , c o 2 C o n c e n t r a t i o n , n o 2 C o n c e n t r a t i o n ;
20
21 u n s i g n e d l o n g timestamp ;
22 int i ;
23
24 Gas co2 (SOCKET_A) ;
25
26 u i n t 8 _ t errorLW ;
27 v o l a t i l e i n t senseCount ;
28
29 f l o a t PowerConsumption [ 3 ] = {PC_SENSE, PC_TRANSMIT, PC_SLEEP} ;
30 unsigned long Duration [ 3 ] = { 0 , 0 , 2 0 } ;
31
32 v o i d configureLoRaWAN ( ) ;
33 void frequencyConfiguration ( ) ;
34 u i n t 8 _ t hexCharsToByte ( c h a r l e f t H ex C , c h a r rightHexC ) ;
35
36 void setup ( )
37 {
38 configureLoRaWAN ( ) ;
39 frame . s e t I D (DEVICE_ID) ;
40
41 // Making t h e d i g i t a l o ut pu t
42 // f o r o s c i l l o s c o p e a u t o m a t i c
43 // s a m p l i n g t r i g g e r .
44 pinMode ( DIGITAL3 ,OUTPUT) ;
45 d i g i t a l W r i t e ( DIGITAL3 , 0 ) ;
46 }
47
48 void loop ( )
49 {
50 // s t a r t O s c i l l o s c o p e Sampling
51 generate_event ( ) ;
52
53 // S t a r t i n g s e n s i n g p r o c e s s
54 RTC.ON( ) ;
55 timestamp = RTC. getEpochTime ( ) ;
56
57 co2 .ON( ) ;
58 delay (10000) ;
59 c o 2 C o n c e n t r a t i o n = t e m p e r a t u r e = humidity = p r e s s u r e = 0 ;
60 senseCount = 0 ;
61
62 w h i l e ( s e n s e C o u n t < MAX_SENSE_COUNT)
E.2. SOURCE FILE 121
63 {
64 delay (1000) ;
65 // S e n s e t h e v a l u e s and s t a r t i t a l l o v e r a g a i n i f t h e r e i s a v a l u e
out o f r a n g e .
66 itmCO2 = co2 . getConc ( ) ;
67 itmTemperature = co2 . getTemp ( ) ;
68 itmHumidity = co2 . getHumidity ( ) ;
69 i t m P r e s s u r e = co2 . g e t P r e s s u r e ( ) ;
70
71 c o 2 C o n c e n t r a t i o n += itmCO2 ;
72 t e m p e r a t u r e += itmTemperature ;
73 humidity += itmHumidity ;
74 p r e s s u r e += i t m P r e s s u r e ;
75 s e n s e C o u n t++;
76 }
77 co2 .OFF( ) ;
78 // S t o r i n g t h e s e n s i n g d u r a t i o n
79 D u r a t i o n [ 0 ] = RTC. getEpochTime ( ) − timestamp ;
80
81 #i f d e f _DEBUG
82 USB . p r i n t (F( " S e n s e D u r a t i o n S t a r t : " ) ) ;
83 USB . p r i n t l n ( timestamp ) ;
84 USB . p r i n t (F( " S e n s e D u r a t i o n End : " ) ) ;
85 USB . p r i n t l n (RTC. getEpochTime ( ) ) ;
86 USB . p r i n t (F( " S e n s e D u r a t i o n : " ) ) ;
87 USB . p r i n t l n ( D u r a t i o n [ 0 ] ) ;
88 #e n d i f _DEBUG
89 RTC.OFF( ) ;
90
91 c o 2 C o n c e n t r a t i o n /= MAX_SENSE_COUNT;
92 t e m p e r a t u r e /= MAX_SENSE_COUNT;
93 humidity /= MAX_SENSE_COUNT;
94 p r e s s u r e /= MAX_SENSE_COUNT;
95
96 // C r e a t e a new tx−frame
97 frame . c r e a t e F r a m e (BINARY) ;
98 frame . a d d S e n s o r (SENSOR_GP_CO2, ( d o u b l e ) c o 2 C o n c e n t r a t i o n ) ;
99 // adds t h e e n e r g y consumption t o tx−frame
100 addEnergyConsumptiontoFrame ( ) ;
101
102 #i f d e f _DEBUG
103 frame . showFrame ( ) ;
104 #e n d i f
105
106 // E n t r i n g t r a n s m i s s i o n phase
107 RTC.ON( ) ;
108 timestamp = RTC. getEpochTime ( ) ;
109 // S wi tc h on LoRaWAN
110 errorLW = LoRaWAN.ON(SOCKET) ;
111
112 frequencyConfiguration () ;
113
122 E. WASPMOTE CO2 SENSING ENERGY-AWARE APPLICATION
114 #i f d e f _DEBUG
115 // Check s t a t u s
116 i f ( errorLW == 0 )
117 {
118 USB . p r i n t l n (F( " 1 . S wi tc h ON OK OK" ) ) ;
119 }
120 else
121 {
122 USB . p r i n t (F( " 1 . Sw it ch ON e r r o r = " ) ) ;
123 USB . p r i n t l n ( errorLW , DEC) ;
124 }
125 #e n d i f
126
127 errorLW = LoRaWAN. joinABP ( ) ;
128
129 i f ( errorLW == 0 )
130 {
131 // Send u n c o n f i r m e d p a c k e t
132 errorLW = LoRaWAN. sendUnconfirmed (PORT, frame . b u f f e r ,
frame . l e n g t h ) ;
133
134 // E r r o r m e s s a g e s :
135 /∗
136 ∗ ’ 6 ’ : Module hasn ’ t j o i n e d a network
137 ∗ ’ 5 ’ : Sending e r r o r
138 ∗ ’ 4 ’ : E r r o r with data l e n g t h
139 ∗ ’ 2 ’ : Module didn ’ t r e s p o n s e
140 ∗ ’ 1 ’ : Module communication e r r o r
141 ∗/
142 // Check s t a t u s
143 i f ( errorLW == 0 )
144 {
145 #i f d e f _DEBUG
146 USB . p r i n t l n (F( " 3 . Send Unconfirmed p a c k e t OK" ) ) ;
147 i f (LoRaWAN. _dataReceived )
148 {
149 USB . p r i n t (F( " There ’ s data on p o r t number " ) ) ;
150 USB . p r i n t (LoRaWAN. _port ,DEC) ;
151 USB . p r i n t (F( " . \ r \n Data : " ) ) ;
152 f o r ( i =0; i < 1 0 1 ; i ++){
153 USB . p r i n t ( i ) ;
154 USB . p r i n t ( " : " ) ;
155 USB . p r i n t (LoRaWAN. _data [ i ] ) ;
156 USB . p r i n t ( " , " ) ;
157 }
158 USB . p r i n t l n ( " " ) ;
159 t e s t C o u n t = ( u i n t 8 _ t ) hexCharsToByte (LoRaWAN. _data [ 0 ] ,
LoRaWAN. _data [ 1 ] ) ; // Test o n l y t h e f i r s t c h a r a c t e r
160 }
161 USB . p r i n t ( " t e s t C o u n t : " ) ;
162 USB . p r i n t l n ( ( i n t ) t e s t C o u n t ) ;
163 #e n d i f
E.2. SOURCE FILE 123
164 }
165 else
166 {
167 #i f d e f _DEBUG
168 USB . p r i n t (F( " 3 . Send Unconfirmed p a c k e t e r r o r = " ) ) ;
169 USB . p r i n t l n ( errorLW , DEC) ;
170 #e n d i f
171 }
172 }
173 else
174 {
175 #i f d e f _DEBUG
176 USB . p r i n t (F( " 2 . J o i n network e r r o r = " ) ) ;
177 USB . p r i n t l n ( errorLW , DEC) ;
178 #e n d i f
179 }
180
181 #i f d e f _DEBUG
182 errorLW = LoRaWAN. g e t R a d i o F r e q ( ) ;
183 i f ( errorLW == 0 )
184 {
185 USB . p r i n t (F( " O p e r a t i n g r a d i o f r e q u e n c y : " ) ) ;
186 USB . p r i n t l n (LoRaWAN. _radioFreq ) ;
187 }
188 else
189 USB . p r i n t (F( " Could not g e t t h e r a d i o f r e q u e n c y . " ) ) ;
190 errorLW = LoRaWAN. g e t R a d i o F r e q D e v i a t i o n ( ) ;
191 i f ( errorLW == 0 )
192 {
193 USB . p r i n t (F( " O p e r a t i n g r a d i o f r e q u e n c y d e v i a t i o n : " ) ) ;
194 USB . p r i n t l n (LoRaWAN. _radioFreqDev ) ;
195 }
196 else
197 USB . p r i n t (F( " Could not g e t t h e r a d i o f r e q u e n c y d e v i a t i o n . " ) ) ;
198
199 errorLW = LoRaWAN. getRadioMode ( ) ;
200 errorLW = LoRaWAN. getRadioPower ( ) ;
201 i f ( errorLW == 0 )
202 {
203 USB . p r i n t (F( " O p e r a t i n g r a d i o power : " ) ) ;
204 USB . p r i n t l n (LoRaWAN. _radioPower ) ;
205 }
206 else
207 USB . p r i n t (F( " Could not g e t t h e r a d i o power . " ) ) ;
208 i f ( errorLW == 0 )
209 {
210 USB . p r i n t (F( " O p e r a t i n g r a d i o mode : " ) ) ;
211 USB . p r i n t l n (LoRaWAN. _radioMode ) ;
212 }
213 else
214 USB . p r i n t (F( " Could not g e t t h e r a d i o mode . " ) ) ;
215
124 E. WASPMOTE CO2 SENSING ENERGY-AWARE APPLICATION
320 c a s e ’E ’ : c a s e ’ e ’ : r e t u r n 1 4 ;
321 c a s e ’F ’ : c a s e ’ f ’ : r e t u r n 1 5 ;
322 }
323 }
324
325 u i n t 8 _ t hexCharsToByte ( c h a r l e f t H ex C , c h a r rightHexC ) {
326 u i n t 8 _ t l e f t H e x = hexCharToInt ( l e f t H e x C ) ;
327 u i n t 8 _ t r i g h t H e x = hexCharToInt ( rightHexC ) ;
328 u i n t 8 _ t num = ( l e f t H e x << 4 ) | r i g h t H e x ;
329 r e t u r n num ;
330 }
331
332 void frequencyConfiguration ( )
333 {
334 //LoRaWAN must be t u r n e d on b e f o r e t h i s f u n c t i o n i s c a l l e d .
335 // This f u n c t i o n depends on t h e c o n s t a n t ’LW_CH’ and t h e a r r a y
’ lwFreqs ’ in configParams . h .
336 i n t ch ;
337 f o r ( ch =1; ch <= LW_CH; ch++)
338 {
339 errorLW = LoRaWAN. s e t C h a n n e l F r e q ( ch , l w F r e q s [ ch −1]) ;
340 #i f d e f _DEBUG
341 i f ( errorLW == 0 ) {
342 //USB . p r i n t (F ( " The c h a n n e l " ) ) ;
343 //USB . p r i n t ( ch ) ;
344 //USB . p r i n t (F ( " i s s e t t o " ) ) ;
345 //USB . p r i n t ( l w F r e q s [ ch − 1 ] / 1 0 0 0 0 0 0 . 0 ) ;
346 //USB . p r i n t l n (F ( " MHz . " ) ) ;
347 } else {
348 //USB . p r i n t (F ( " E r r o r when s e t t i n g t h e f r e q u e n c y c h a n n e l " ) ) ;
349 //USB . p r i n t ( ch ) ;
350 //USB . p r i n t (F ( " . E r r o r code : " ) ) ;
351 //USB . p r i n t l n ( errorLW , DEC) ;
352 }
353 #e n d i f
354 }
355 }
356
357 v o i d configureLoRaWAN ( )
358 {
359 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
360 // 1 . s w i t c h on
361 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
362
363 u i n t 8 _ t e r r o r = LoRaWAN.ON(SOCKET) ;
364 #i f d e f _DEBUG
365 // Check s t a t u s
366 i f ( e r r o r == 0 )
367 {
368 USB . p r i n t l n (F( " 1 . S wi tc h ON OK OK OK" ) ) ;
369 }
370 else
E.2. SOURCE FILE 127
371 {
372 USB . p r i n t (F( " 1 . Sw it ch ON e r r o r = " ) ) ;
373 USB . p r i n t l n ( e r r o r , DEC) ;
374 }
375 #e n d i f
376
377 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
378 // 2 . R e s e t t o f a c t o r y d e f a u l t v a l u e s
379 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
380
381 e r r o r = LoRaWAN. f a c t o r y R e s e t ( ) ;
382
383 #i f d e f _DEBUG
384 // Check s t a t u s
385 i f ( e r r o r == 0 )
386 {
387 USB . p r i n t l n (F( " 2 . R e s e t t o f a c t o r y d e f a u l t v a l u e s OK" ) ) ;
388 }
389 else
390 {
391 USB . p r i n t (F( " 2 . R e s e t t o f a c t o r y e r r o r = " ) ) ;
392 USB . p r i n t l n ( e r r o r , DEC) ;
393 }
394 #e n d i f
395
396 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
397 // 3 . S e t / Get D e v i c e EUI
398 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
399
400 // S e t D e v i c e EUI
401 e r r o r = LoRaWAN. s e t D e v i c e E U I (DEVICE_EUI) ;
402
403 #i f d e f _DEBUG
404 // Check s t a t u s
405 i f ( e r r o r == 0 )
406 {
407 USB . p r i n t l n (F( " 3 . 1 . S e t D e v i c e EUI OK" ) ) ;
408 }
409 else
410 {
411 USB . p r i n t (F( " 3 . 1 . S e t D e v i c e EUI e r r o r = " ) ) ;
412 USB . p r i n t l n ( e r r o r , DEC) ;
413 }
414 #e n d i f
415
416 // Get D e v i c e EUI
417 e r r o r = LoRaWAN. getDeviceEUI ( ) ;
418
419 #i f d e f _DEBUG
420 // Check s t a t u s
421 i f ( e r r o r == 0 )
422 {
128 E. WASPMOTE CO2 SENSING ENERGY-AWARE APPLICATION
475
476 e r r o r = LoRaWAN. setNwkSessionKey (NWK_SESSION_KEY) ;
477
478 #i f d e f _DEBUG
479 // Check s t a t u s
480 i f ( e r r o r == 0 )
481 {
482 USB . p r i n t l n (F( " 5 . S e t Network S e s s i o n Key OK" ) ) ;
483 }
484 else
485 {
486 USB . p r i n t (F( " 5 . S e t Network S e s s i o n Key e r r o r = " ) ) ;
487 USB . p r i n t l n ( e r r o r , DEC) ;
488 }
489 #e n d i f
490
491 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
492 // 6 . S e t A p p l i c a t i o n S e s s i o n Key
493 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
494
495 e r r o r = LoRaWAN. s e t A p p S e s s i o n K e y (APP_SESSION_KEY) ;
496
497 #i f d e f _DEBUG
498 // Check s t a t u s
499 i f ( e r r o r == 0 )
500 {
501 USB . p r i n t l n (F( " 6 . S e t A p p l i c a t i o n S e s s i o n Key OK" ) ) ;
502 }
503 else
504 {
505 USB . p r i n t (F( " 6 . S e t A p p l i c a t i o n S e s s i o n Key e r r o r = " ) ) ;
506 USB . p r i n t l n ( e r r o r , DEC) ;
507 }
508 #e n d i f
509
510 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
511 // 7 . S e t r e t r a n s m i s s i o n s f o r u p l i n k c o n f i r m e d p a c k e t
512 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
513
514 // s e t r e t r i e s
515 e r r o r = LoRaWAN. s e t R e t r i e s ( 7 ) ;
516
517 #i f d e f _DEBUG
518 // Check s t a t u s
519 i f ( e r r o r == 0 )
520 {
521 USB . p r i n t l n (F( " 7 . 1 . S e t R e t r a n s m i s s i o n s f o r u p l i n k c o n f i r m e d
p a c k e t OK" ) ) ;
522 }
523 else
524 {
130 E. WASPMOTE CO2 SENSING ENERGY-AWARE APPLICATION
574 #i f d e f _DEBUG
575 // Check s t a t u s
576 i f ( e r r o r == 0 )
577 {
578 USB . p r i n t l n (F( " 1 3 . 1 . S e t Adaptive data r a t e s t a t u s t o on OK" ) ) ;
579 }
580 else
581 {
582 USB . p r i n t (F( " 1 3 . 1 . S e t Adaptive data r a t e s t a t u s t o on e r r o r = " ) ) ;
583 USB . p r i n t l n ( e r r o r , DEC) ;
584 }
585 #e n d i f
586
587 // Get ADR
588 e r r o r = LoRaWAN. getADR ( ) ;
589
590 #i f d e f _DEBUG
591 // Check s t a t u s
592 i f ( e r r o r == 0 )
593 {
594 USB . p r i n t (F( " 1 3 . 2 . Get Adaptive data r a t e s t a t u s OK. " ) ) ;
595 USB . p r i n t (F( " Adaptive data r a t e s t a t u s : " ) ) ;
596 i f (LoRaWAN. _adr == t r u e )
597 {
598 USB . p r i n t l n ( " on " ) ;
599 }
600 else
601 {
602 USB . p r i n t l n ( " o f f " ) ;
603 }
604 }
605 else
606 {
607 USB . p r i n t (F( " 1 3 . 2 . Get Adaptive data r a t e s t a t u s e r r o r = " ) ) ;
608 USB . p r i n t l n ( e r r o r , DEC) ;
609 }
610 #e n d i f
611
612 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
613 // 1 4 . S e t Automatic Reply
614 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
615
616 // s e t AR
617 e r r o r = LoRaWAN. setAR ( " on " ) ;
618
619 #i f d e f _DEBUG
620 // Check s t a t u s
621 i f ( e r r o r == 0 )
622 {
623 USB . p r i n t l n (F( " 1 4 . 1 . S e t a u t o m a t i c r e p l y s t a t u s t o on OK" ) ) ;
624 }
625 else
132 E. WASPMOTE CO2 SENSING ENERGY-AWARE APPLICATION
626 {
627 USB . p r i n t (F( " 1 4 . 1 . S e t a u t o m a t i c r e p l y s t a t u s t o on e r r o r = " ) ) ;
628 USB . p r i n t l n ( e r r o r , DEC) ;
629 }
630 #e n d i f
631 // Get AR
632 e r r o r = LoRaWAN. getAR ( ) ;
633
634 #i f d e f _DEBUG
635 // Check s t a t u s
636 i f ( e r r o r == 0 )
637 {
638 USB . p r i n t (F( " 1 4 . 2 . Get a u t o m a t i c r e p l y s t a t u s OK. " ) ) ;
639 USB . p r i n t (F( " Automatic r e p l y s t a t u s : " ) ) ;
640 i f (LoRaWAN. _ar == t r u e )
641 {
642 USB . p r i n t l n ( " on " ) ;
643 }
644 else
645 {
646 USB . p r i n t l n ( " o f f " ) ;
647 }
648 }
649 else
650 {
651 USB . p r i n t (F( " 1 4 . 2 . Get a u t o m a t i c r e p l y s t a t u s e r r o r = " ) ) ;
652 USB . p r i n t l n ( e r r o r , DEC) ;
653 }
654 #e n d i f
655
656 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
657 // 1 5 . Save c o n f i g u r a t i o n
658 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
659
660 e r r o r = LoRaWAN. s a v e C o n f i g ( ) ;
661
662 #i f d e f _DEBUG
663 // Check s t a t u s
664 i f ( e r r o r == 0 )
665 {
666 USB . p r i n t l n (F( " 1 5 . Save c o n f i g u r a t i o n OK" ) ) ;
667 }
668 else
669 {
670 USB . p r i n t (F( " 1 5 . Save c o n f i g u r a t i o n e r r o r = " ) ) ;
671 USB . p r i n t l n ( e r r o r , DEC) ;
672 }
673
674 USB . p r i n t l n (F( "−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−" ) ) ;
675 USB . p r i n t l n (F( "Now t h e LoRaWAN module i s r e a d y f o r " ) ) ;
676 USB . p r i n t l n (F( " j o i n i n g n e t w o r k s and send m e s s a g e s . " ) ) ;
677 USB . p r i n t l n (F( " P l e a s e c h e c k t h e n e x t examples . . . " ) ) ;
E.2. SOURCE FILE 133
CO2SensingEnergyAware.pde