0% found this document useful (0 votes)
28 views

Energy Consumption of Wireless IoT Nodes (PDFDrive)

Uploaded by

ERMIAS Amanuel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Energy Consumption of Wireless IoT Nodes (PDFDrive)

Uploaded by

ERMIAS Amanuel
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 151

Energy Consumption of Wireless IoT

Nodes

Amen Hussain

Master of Telematics - Communication Networks and Networked Services


Submission date: June 2017
Supervisor: Frank Alexander Krämer, IIK

Norwegian University of Science and Technology


Department of Information Security and Communication Technology
Energy Consumption of Wireless IoT Nodes

Amen Hussain

Submission date: June 2017


Responsible professor: Frank Alexander Kraemer, ITEM
Supervisor: Nattachart Tamkittikhun, ITEM

Norwegian University of Science and Technology


Department of Telematics
Abstract

The Internet of Things (IoT) is an emerging technology, encompassing


a wide spectrum of applications related to industrial control, smart
metering, home automation, agriculture, eHealth and so on. For these
applications to run autonomously, the IoT devices are required to survive
for months and years under strict energy constraints. When developing
such applications, it is important for the application to know about its
own energy consumption.

In this work, we propose and evaluate an energy consumption esti-


mation approach for periodic sensing applications running on the IoT
devices. Our approach is based on three phases. In the first phase, we
identify the distinct activities such as sleep, transmit, sense and process
in a sensing cycle. In the second phase, we measure the power consump-
tion of these activities before the IoT device has been deployed in the
network. The third phase takes place at run-time once the IoT device has
been deployed, with the purpose of delivering the energy consumption
of a sensing cycle. The energy consumption is calculated by using the
activities’ power consumption and their durations obtained at run-time.

The proposed approach is simple and generic because it doesn’t involve


any complex hardware for runtime power measurement. Moreover, this
approach also incorporates the dynamic nature of sensing applications by
run-time estimation of energy consumption. Our results show that the
error of energy estimation for the chosen applications is between 0,04%
and 2,928%.
Preface

This dissertation is part of the Telematics, Master’s Thesis taken


in the 4th semester (spring 2017) of my 2-year MSc in Telematics-
Communication Networks and Networked Services at the Norwegian
University of Science and Technology (NTNU), awarding 30 ECTS cred-
its.

This work is focused on the development of a precise and efficient


energy consumption estimation model designed specifically for periodic
sensing applications running on IoT sensing devices. It involves experi-
mental work to understand the energy consumption by the sensing nodes.
The development of energy consumption estimation model has given me
an insight into various topics related to the power measurement pro-
cess, LoRaWAN communication protocol and hardware and software
platforms used by different IoT devices. In this work, I also developed
a skill to design relevant experiments and analyze the gathered data
efficiently. I would like to thank my supervisor, Nattachart Tamkittikhun
and my responsible professor, Frank Alexander Kraemer for providing
their insightful guidelines throughout this work.

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

List of Tables xiii

List of Algorithms xvi

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

3 Power Measurement Setup 13


3.1 Measurement Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2 Measurement Procedure . . . . . . . . . . . . . . . . . . . . . . . . . 15

4 Power and Energy Consumption Analysis 17


4.1 LED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.2 Energy Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.3 Peer-to-Peer Radio Transmission . . . . . . . . . . . . . . . . . . . . 33
4.4 Peer-to-Peer Radio Receive . . . . . . . . . . . . . . . . . . . . . . . 39
4.5 Cryptography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.6 Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

vii
5 Energy Modeling 53
5.1 Energy Consumption Estimation Model . . . . . . . . . . . . . . . . 53
5.2 Run-time Logic for Energy Estimation . . . . . . . . . . . . . . . . . 55

6 Energy-Aware Application: Increasing Sensing Phase 57


6.1 Particle Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6.1.1 Energy Aware Application . . . . . . . . . . . . . . . . . . . . 58
6.1.2 Oscilloscope Measurement . . . . . . . . . . . . . . . . . . . . 61
6.1.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.2 Temperature Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.2.1 Energy Aware Application . . . . . . . . . . . . . . . . . . . . 63
6.2.2 Oscilloscope Measurement . . . . . . . . . . . . . . . . . . . . 65
6.2.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

7 Energy-Aware Application: Different Sensing Modes 67


7.1 Particle Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
7.1.1 Energy-Aware Application . . . . . . . . . . . . . . . . . . . . 68
7.1.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
7.2 Temperature Sensor . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
7.2.1 Energy-Aware Application . . . . . . . . . . . . . . . . . . . . 73
7.2.2 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

8 Energy-Aware Application: Waspmote 75


8.1 Application Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
8.2 Design-time and Run-time Energy Estimation Logic . . . . . . . . . 78
8.3 Energy Aware Application . . . . . . . . . . . . . . . . . . . . . . . . 80

9 Discussion and Conclusion 83

References 85

Appendices
A Picoscope Python Script 89

B mDot P2P Communication Header Files 95


B.1 dot_util.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
B.2 mDotEvent.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
B.3 RadioEvent.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

C mDot Particle Sensing Energy-Aware Application 105

D mDot Temperature Sensing Energy-Aware Application 113

E waspMote CO2 Sensing Energy-Aware Application 119


E.1 Header File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
E.2 Source File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
List of Figures

1.1 Sensing System Overview [THK17] . . . . . . . . . . . . . . . . . . . . . 2

3.1 Power Measurement Setup . . . . . . . . . . . . . . . . . . . . . . . . . . 14


3.2 mDot Current Consumption measurement using Python Script . . . . . 16

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

5.1 Power consumption of one cycle of a sensing application. Some phases


are shortened on the x-axis, to save space. The labels reveal the actual
duration [THK17]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

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

6.1 Energy Profiles of Particle Sensing Energy-aware Application with In-


creasing Sensor Sampling Count . . . . . . . . . . . . . . . . . . . . . . 60
6.2 Energy Profiles of Temperature Sensing Energy-aware Application with
Increasing Sensor Sampling Count . . . . . . . . . . . . . . . . . . . . . 64

7.1 Energy Profiles of Particle Sensing Energy-aware Application with Differ-


ent Sensing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
7.2 Energy Profiles of Temperature Sensing Energy-aware Application with
Different Sensing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

8.1 Current Consumption of a CO2 Sensing Application using Moderate


Sensing Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
8.2 CO2 Sensing: Energy Consumption Comparison under Different Sensing
Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

9.1 Percentage Error in Estimated Energy under Different Sensing Modes


Running on Different Sensing Devices . . . . . . . . . . . . . . . . . . . 83
List of Tables

4.1 LED: Energy Consumption . . . . . . . . . . . . . . . . . . . . . . . . . 22


4.2 Sleep Mode Energy Consumption (E-05 in this table is equivalent to
×10−5 and so on.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.3 Energy Consumption: A Comparison (E-05 in this table is equivalent to
×10−5 and so on.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.4 Power Consumption in Pre-, Post- and Main Transmission Phases (E-05
in this table is equivalent to ×10−5 and so on.) . . . . . . . . . . . . . . 36
4.5 Energy Consumption: Transmission (E-05 in this table is equivalent to
×10−5 and so on.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.6 Rx Energy Conusmption: A Comparison (E-05 in this table is equivalent
to ×10−5 and so on.) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.7 Cryptography: Energy and Power Consumption (E-05 in this table is
equivalent to ×10−5 and so on.) . . . . . . . . . . . . . . . . . . . . . . 44
4.8 Sensor Energy Conusmption: A Comparison . . . . . . . . . . . . . . . . 52

6.1 Energy Consumption Sent by the Energy-Aware Particle Sensing Applica-


tion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.2 Energy Consumption Measurement using Oscilloscope for the Energy-
Aware Particle Sensing Application . . . . . . . . . . . . . . . . . . . . . 62
6.3 Energy Consumption Modling Particle Sensing Application: A comparison 62
6.4 Temperature Sensor Energy and Power Consumption with Transmission 64
6.5 Energy Consumption Sent by the Energy-Aware Temperature Sensing
Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
6.6 Energy Consumption Measurement using Oscilloscope for the Energy-
Aware Temperature Sensing Application . . . . . . . . . . . . . . . . . . 66
6.7 Energy Consumption Modling Temperature Sensing Application: A com-
parison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

7.1 Sensor Modes Parameters in Particle Sensing Energy-Aware Applications 68


7.2 Power and Energy Consumption during Sleep Mode for Particle Sensor 70
7.3 Particle Sensing: Energy Consumption Comparison under Different Sens-
ing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

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

8.1 Power and Energy Consumption of CO2 Sensing Application Running on


WASPMOTE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
8.2 Sensor Modes Parameters in CO2 Sensing Energy-Aware Applications . 80
8.3 CO2 Sensing: Energy Consumption Comparison under Different Sensing
Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
List of Algorithms

4.1 C++ Program: Toggling LED . . . . . . . . . . . . . . . . . . . . . . 19


4.2 C++ Program: Toggling two LEDs . . . . . . . . . . . . . . . . . . . 20
4.3 C++ Program: MTS logger . . . . . . . . . . . . . . . . . . . . . . . 24
4.4 Python Program: Read Serial . . . . . . . . . . . . . . . . . . . . . . 25
4.5 C++ Program: Generate Event for Automatic Energy Measurement 26
4.6 C++ Program: Active Mode Current Consumption . . . . . . . . . . 26
4.7 C++ Program: Entering Sleep Mode . . . . . . . . . . . . . . . . . . 27
4.8 C++ Program: mDot LoRA peer-to-peer . . . . . . . . . . . . . . . 33
4.9 C++ Program: mDot LoRA peer-to-peer Automatic Measurement . 34
4.10 C++ Program: mDot Encryption . . . . . . . . . . . . . . . . . . . . 41
4.11 C++ Program: mDot Dencryption . . . . . . . . . . . . . . . . . . . 42
4.12 C++ Program: Generate input . . . . . . . . . . . . . . . . . . . . . 42
4.13 C++ Program: Temperature Snesor DS18B20 . . . . . . . . . . . . . 46
4.14 C++ Program: Particle Sensor Configuring General-Purpose Input
Output (GPIO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.15 C++ Program: Sensing Value from Particle Sensor . . . . . . . . . 48
4.16 C++ Program: Main Function of Particle Sensor . . . . . . . . . . . 49
4.17 C++ Program: Get Reference Voltage in Particle Sensor . . . . . . . 50
5.1 General Application with Energy Estimation [THK17] . . . . . . . . 56
6.1 C++ Program: Energy Aware Application . . . . . . . . . . . . . . . 59
6.2 C++ Program: Temperature Sensing Modification in Energy Aware
Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
7.1 C++ Program: Energy Aware Application with Static Code Blocks . 69
8.1 waspmote CO2 Sensing Phase . . . . . . . . . . . . . . . . . . . . . . 76
8.2 waspmote Transmission Phase . . . . . . . . . . . . . . . . . . . . . . 77
8.3 waspmote Sleeping Phase . . . . . . . . . . . . . . . . . . . . . . . . 78
8.4 waspmote Generate Event . . . . . . . . . . . . . . . . . . . . . . . . 79
8.5 waspmote RTC to Measure Duration of each Phase . . . . . . . . . . 80
A.1 Python Script: Defining package imports . . . . . . . . . . . . . . . 89
A.2 Defining Energy Measurement Class . . . . . . . . . . . . . . . . . . 90
A.3 Energy Measurement Class: Calculating mean and standard error . . 91
A.4 Energy Measurement Class: Writing to an excel file . . . . . . . . . 92

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:

1. the design of ultra-low hardware platforms

2. the development of intelligent system-level power management techniques

3. the use of environmental energy harvesting to make IoT devices self-powered


[JLL+ 14]

In this thesis, we will work on the development of an energy estimation model


inside an application running on the sensing node. This work comes under the areas
of the development of intelligent system-level power management techniques.

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

Data Analysis Device Management

Upstream:
sensor data
LoRaWAN
energy consumption
Gateway
battery level

Downstream:
sensing mode

Sensor Nodes

Figure 1.1: Sensing System Overview [THK17]

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

In this work, we developed an approach for energy estimation of periodic sensing


applications running on IoT sensing nodes. These applications consist of different
activity phases in a sensing cycle and this cycle repeats itself periodically. The activity
phases in such applications can be sleeping, sensing, transmitting, and processing.
Our proposed energy estimation model consists of three processes; 1) activity phase
identification, 2) design-time and 3) run-time. The activity phase identification can
be done based on each operation such that sensing, transmission, processing etc.
These phases can be clearly identified by the application developer. However, an
activity phase can be further divided into three blocks i.e. pre-, post-, and main
based on their power consumption. The process of further dividing the activity
phase involves rigorous power consumption analysis of these activity phases. In the
design-time process, we measured the power consumption of different activity phases
in a laboratory setting. Whereas, in the run-time process, the application computes
the duration of its activity phases and computes the energy.

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.

1.1 Problem Description

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.

We will conduct various experiments on different hardware platforms to measure


the power consumption under various states and activities. These activities can
be processing data, transmitting packets, reading sensor values, actuating a device.
4 1. INTRODUCTION

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.

To generalize this energy consumption prediction model for various hardware


platforms and communication protocols, we need to parameterize the model. Because
the current consumption, the processing speed, and the transition duration from
one state to the other will be different for different hardware platforms. In addition,
different communication protocols will have a different number of packets sent and
received, as well as packet lengths. To develop such a generic model, we will try to
establish some coarse questions to parameterize this model. These questions will
be related to the power consumed by hardware platforms under different states and
activities with different sensors and actuators attached.

In the beginning, we will use MultiConnect mDot as an experimental hardware


platform and LoRaWAN as the underlying communication protocol to establish the
energy consumption model for the IoT applications.

1.2 Methodology

To solve the above-mentioned problem statement, the methodology of applied research


was used. In the first step, we gathered theoretical knowledge and understanding
of the existing techniques in the literature. Relevant materials were gathered by
different search engines. Our main search engines were; IEEE Xplore, ACM Digital
Library, and Google.

Based on the literature, we adopted an energy consumption measurement tech-


nique that was independent of the underlying IoT hardware platform. Initially, our
motive was to understand the energy profiles of sensing applications running on the
IoT hardware platform. We finalized a target IoT hardware platform and developed
some experiments to deepen our understanding about the energy consumption by
such applications.

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

This thesis is part of an on-going inter-disciplinary research project at the Faculty of


Information Technology and Electrical Engineering in NTNU. The research project is
called Autonomous Resource-Constrained Things 1 . This main goal of this project is
to obtain the optimum data quality from a sensor node, under a constrained energy
budget. The energy budget of a sensor node can be determined by measuring battery
voltages, energy consumption per sensing cycle, and harvested energy from the solar
panel. These parameters along with the weather forecast, to predict the energy
produced the solar panel, can be used in a machine learning algorithm to determine
a sensor node’s energy utilization. This work is vital in the area of measuring per
cycle energy consumption of an application.

Author’s initial motivation was to gain a profound knowledge in the area of


Internet of Things. The author wanted to experiment with different IoT hardware
platforms and understand IoT operating systems i.e. mbed2 and contiki3 . However,
after performing the literature review and some trivial experiments, the author began
to realize the impact of the energy consumption estimation model on the performance
of a sensing node. To develop an energy estimation model that will provide an
application’s energy consumption estimates on a per sensing cycle basis became the
prime 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.

1.5 Report Structure

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

2.1 Energy Monitoring using Shunt Resistor

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.

A. Milenkovic et al. [MMJ+ 05] suggested that run-time energy consumption


measurement is critical for studies that are related to target power optimization.
They proposed two approaches to measure the power consumption of a node in a
wireless sensor network. In the first approach, they sampled power supply and the
output voltage using a current probe. In the second approach, they sampled power
supply and the voltage at the shunt resistor. S. Mijovic et al. [MCB15] presented a
method to perform real-time measurement of the energy consumption by a Wireless
Body Area Network (WBAN). They used a shunt resistor in series with the power
supply to measure the overall current consumption by a wireless node. In this work,
their emphasis was to design a MAC protocol that is both energy efficient and
provides good latency.
2.2. SOFTWARE BASED ENERGY ESTIMATION 9

2.2 Software based Energy Estimation

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

2.3 Specialized Hardware based Approach

Homb [Hom16] proposed a run-time approach to measure system-wide energy


consumption using a specialized hardware. He performed real-time measurements
of the current and voltage of the target device and stored the data on an SD card.
This data was then manually transferred to a computer for further analysis. The
only drawback of this approach is to process a bulk amount of data which adds to
the overall energy consumption of the device.

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.

2.4 CPU Instruction-set based Energy Estimation

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.

Bazzaz et al. [BSE13] suggested an instruction-level energy estimation model for


embedded systems. They used an ARM7TDMI-based microcontroller to determine
the model parameters. In their model, the total energy consisted on the energy
2.5. ENERGY MODELING USING PARAMETRIC APPROACH 11

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%.

2.5 Energy Modeling using Parametric Approach

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

3.1 Measurement Setup

There are three elements in our experimental setup:

1. the IoT device under test

2. high resolution digital oscilloscope

3. a stable power supply

4. current sense resistor

Following figure explains the design:

Figure 3.1: Power Measurement Setup

For the experimental purposes we have used mDot1 by Multiconnect as the


IoT device. We will use a digital oscilloscope to measure the energy consumption
by different network applications. A current sense resistor is connected in series
with power supply and IoT device to measure overall current consumption by the
device. It is a Through Hole Current Sense Resistor; PWR221T-30-10R0J. It has 10Ω
resistance, the power rating is 30 W and resistance tolerance is ± 5% . The output
from the oscilloscope is directly sent to the Desktop PC where all the readings from
the oscilloscope will be logged. PicoScope R6.8.2 software is running on Desktop PC
to capture data from the digital oscilloscope. The oscilloscope attached to Desktop
1 http://www.multitech.com/brands/multiconnect-mdot
3.2. MEASUREMENT PROCEDURE 15

PC is running a Windows-10 operating system. We used PC Oscilloscope PicoScope


6000 series model 6404D. Following is a list of specifications:

– 4 channels

– 500 MHz bandwidth

– 5 GS/s real-time sampling frequency

– 2 GS ultra-deep memory

– 170,000 waveforms per second

– Arbitrary waveform generator (AWG)

– USB 3.0 interface [Pic]

3.2 Measurement Procedure

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:

1. the threshold value for signal channel

2. the capture length

3. number of samples to capture


16 3. POWER MEASUREMENT SETUP

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:

Figure 3.2: mDot Current Consumption measurement using Python Script


Power and Energy Consumption
Analysis
Chapter

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:

P = µ(ImDot ) ∗ VmDot (4.2)


In the following experiments, we have fixed the voltage across the mDot, and µ(ImDot )
is the average current consumption. The current consumption is calculated across
the 10 Ω sense resistor using an oscilloscope as explained in the Chapt. 3. In these
experiments, the calculated energy is the average over 10 samples extracted by the
oscilloscope.

The standard error in energy is calculated by multiplying standard deviation in


∆t and power. The standard error in power is equivalent to the standard error in
current consumption measurement because we are assuming the voltage across mDot
will remain constant. Following is the formula for compound variance:
σ 2 (∆t, ImDot ) = σ 2 (∆t)σ 2 (ImDot ) + (µ(∆t))2 σ 2 (ImDot ) + (µ(ImDot ))2 σ 2 (∆t) (4.3)

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

The experiments are organized as hypothesis, method and results sub-sections.


They are organized as follows:

1. LED: In this section, we will observe how an LED connected to a GPIO


influences the power consumption of mDot.

2. Energy Modes: In this section, we will discuss the impact on the power
consumption of mDot by changing energy modes.

3. peer-to-peer Radio Transmission: Here we will understand the impact of mDot


radio transmission on the power consumption and how the transmission packet
length influences the energy consumption.

4. peer-to-peer Radio Reception: In this section, we will observe the length of


receiving packet to the energy consumption of mDot.

5. Cryptography: The impact of cryptographic operations on the power consump-


tion is observed in this section.

6. Sensor: In this section, we will observe the difference of energy consumption


when different sensors are used. We will currently focus on particle and
temperature sensors.
4.1. LED 19

4.1 LED

Hypothesis: The mDot consumes more energy when it is used to power up an


LED and the energy consumption of mDot increases linearly with respect to the
number of LEDs attached.

Method: In this experiment, we will investigate the energy consumption of the


LED when it is attached to the mDot. In IoT devices, an LED is powered up by
attaching it to a GPIO pin of the embedded device. We used L05R3000F1 Red LED,
whose maximum current rating is 20 mA and requires a voltage of 2,2 V across its
terminals. The LED will be destroyed if more than 20 mA of current follows through
it. To protect the LED, a current limiting resistor is attached in series with the LED
and the GPIO pin. The formula to calculate the resistor value is as follows:

R = (VG − VL )/IL (4.4)

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:

Source code 4.1 C++ Program: Toggling LED


DigitalOut led1(PA_2);
int main(){
while(true){
led1 = !led1;
Thread::wait(200);
}
return 0;
}
20 4. POWER AND ENERGY CONSUMPTION ANALYSIS

Similarly, to investigate the energy consumption when two LEDs light up, follwoing
code snippet was used.

Source code 4.2 C++ Program: Toggling two LEDs

#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

Following figure shows the waveform of current consumption observed on the


digital oscilloscope.

Figure 4.1: mDot Current Consumption when Powering a single LED

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.

Figure 4.2: mDot Current Consumption when Powering two LEDs

TheDC-average of the current consumption of mDot is 39,31 mA when both the


LEDs are at a high state and 14,66 mA when both are at a low state. Using the
Eq. 4.2, the power consumption is calculated to be 196,55 mW when LEDs are at the
high state. It is 73,3 mW when LEDs are in the low state. Similarly, using Eq. 4.1,
the mDot consumes 0,03931 J of energy when the LEDs are at the high state and
0,01466 J when the LEDs are at the low state.
22 4. POWER AND ENERGY CONSUMPTION ANALYSIS

Following table summarises the results obtained:

Table 4.1: LED: Energy Consumption

Parameters 1 LED 2 LEDs Difference


Current_ON(mA) 32,02 39,31 7,29
Current_OFF(mA) 19,88 14,66 5,22
Difference 12,14 24,65 12,51
Power_ON(W) 0,160 0,196 0,36
Power_OFF(W) 0,099 0,0733 0,026
Difference 0,061 0,1227 0,0617
Energy_ON(J) 0,032 0,0392 0,007
Energy_OFF(J) 0,020 0,014 0,006
Difference 0,012 0,0252 0,0132

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

4.2 Energy Modes

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

Source code 4.3 C++ Program: MTS logger

#include "mbed.h"
#include "mDot.h"
#include "MTSLog.h"

//initializing the USB to communicate with PC


Serial pc(USBTX, USBRX);
int main(){

//setting baud rate for communication


pc.baud(115200);

// setting up the logging level


mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);

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

Source code 4.4 Python Program: Read Serial

import time
import datetime
import sys
import serial
import io
import argparse

parser = argparse.ArgumentParser(description=’Read printed serial output.’)


parser.add_argument(’-b’, dest=’baudrate’, type=int, required=True,
help=’The baud rate’)
parser.add_argument(’-p’, dest=’port’, type=str, required=True,
help=’The serial port’)

args = parser.parse_args()

ser = serial.Serial(args.port, args.baudrate)


try:
while True:
msg = ser.readline().decode("ISO-8859-1")
sys.stdout.write(’{1:%Y-%m-%d %H:%M:%S}{0}’.
format(msg,datetime.datetime.now()))
sys.stdout.flush()

except KeyboardInterrupt:
sys.stdout.write(’Interrupted’)
sys.stdout.flush()

To automatically measure energy consumption during active state, we have used


Python script developed in Chapt. 3. To signal the oscilloscope, we have used a
GPIO pin. We generated a pulse of width 100 µs as an indicator to measure the
current consumption from one point to the other as shown in Algo. 4.5. We measure
the current consumption and duration from the oscilloscope and then use formulas
to calculate the power and energy consumption.
26 4. POWER AND ENERGY CONSUMPTION ANALYSIS

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.

Source code 4.6 C++ Program: Active Mode Current Consumption

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();

//sleep for 1 second


dot->sleep(1, mDot::RTC_ALARM, false);
}
return 0;
}

The Python script was run with following values to calculate power and energy
consumption:

Listing 4.1: Python Script Run Command Active Mode


python e n e r g y . py −e Dot−Sleep_MTS_MDOT_F411RE_1s_Active
−t −0.300 −s 10 −F 100 −v 5 . 0 −c 500
4.2. ENERGY MODES 27

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:

Source code 4.7 C++ Program: Entering Sleep Mode

#include "mbed.h"
#include "mDot.h"

int main(){
mDot* dot = NULL;

// reset to default configuration


dot->resetConfig();

while(true){
volatile int32_t j=0;
for (; j<4; j++){
for (volatile int32_t i=0; i<1000000; i++);
}

// sleep mode energy mode


generate_event();
dot->sleep(1, mDot::RTC_ALARM, false)
generate_event();
}
return 0;
}
28 4. POWER AND ENERGY CONSUMPTION ANALYSIS

To calculate power and energy consumption, we used Python script with the
following input values:

Listing 4.2: Python Script Run Command Sleep Mode


python e n e r g y . py −e Dot−Sleep_MTS_MDOT_F411RE_1s_Sleep
−t −0.300 −s 10 −F 5 −v 5 . 0 −c 1500

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:

dot− > sleep(1, mDot :: RT C_ALARM, true)

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.

Results: The mDot is powered on with 5 V and oscilloscope is being used to


measure the current consumption when mDot goes into different states. First, let’s
see the screenshot from the oscilloscope when the mDot is in the active state for
292,5 ms and then goes to the sleep state for one second.
4.2. ENERGY MODES 29

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

Tab. 4.2 summarizes the calculated energy consumption by different phases in


the sleep state.

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:

Figure 4.8: mDot current consumption during deep sleep mode

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 presents a comparison of energy consumption under different modes of


operation. In this table, we have averaged out the current consumption of complete
state. The current consumption of pre- and post- phases has been added to the main
phase to present an overall current consumption comparison among different modes
of operation. We have used Python script to measure average current consumption
during active and sleep modes. However, we couldn’t do the same for deep sleep due
to the problem presented in Fig. 4.9. Hence, the results presented in the deep sleep
mode are the DC-Average values of the complete state.

Table 4.3: Energy Consumption: A Comparison (E-05 in this table is equivalent to


×10−5 and so on.)
States Duration(s) Current(A) Power(W) Energy(J)
Active 0,292±3,17E-06 0,031±5,47E-05 0,154±5,47E-05 0,045±1,60E-05
Sleep 1,162±2,12E-03 3,89E-03±3,18E-05 0,019±3,18E-05 0,022±3,78E-05
Deep-Sleep 1,245±1,92E-03 5,13E-03±2,63E-05 0,026±2,63E-05 0,032±3,42E-05

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.

4.3 Peer-to-Peer Radio Transmission

Hypothesis: The power consumed by the mDot increases linearly by increasing


the number of bytes sent in a packet.

Method: To calculate power consumption during peer-to-peer communication, two


mDots were configured to send and receive LoRaWAN frames after every one second.
The following C++ code snippet explains the mDot transmit and receive process.

Source code 4.8 C++ Program: mDot LoRA peer-to-peer

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

This is an example program provided by MultiTech to transmit and receive data


packets in peer to peer mode using LoRaWAN as the communication protocol [mula].
In the Algo. 4.8, the mDot first resets to the default configuration. Then the network
join mode is set to peer-to-peer. In the next step, the network address, session keys,
data rate, transmission frequency and power are configured. In the final step, mDot
joins the network, creates a dummy data frame and transmits it.

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);
}

The generate_event() function generated a pulse of 100 µs. It is used to signal


the oscilloscope to start capturing data. The execution of Algo. 4.9 gave us the
4.3. PEER-TO-PEER RADIO TRANSMISSION 35

current consumption during the send(tx_data) function. In the result section, we


will first present the results of the manual process and then the data gathered during
automated process.

Results: During these experiments, we observed that the energy consumption of


mDot increases linearly with respect to packet size. Similar to the previous section, we
discovered that the frame transmission operation also consists of three phases. These
three phases have been identified based on the current consumption observed in these
phases. Fig. 4.11 presents the classification of these phases when the transmission
frame length is 25 bytes.

Figure 4.10: mDot Transmit Cycle

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

Figure 4.11: Manual: mDot_senddata Energy Conumsption

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

The author also performed an automated analysis of the current consumption on


mDot. Following command was executed to capture current samples when packet
size was 25 bytes:

Listing 4.3: Run Python Script Transmission


python e n e r g y . py −e Dot−P2P_MTS_MDOT_F411RE_1s_25B
−t −0.300 −s 10 −F 100 −v 5 . 0 −c 280

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.

Figure 4.12: Automatic: mDot_senddata() Energy Consumption


38 4. POWER AND ENERGY CONSUMPTION ANALYSIS

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

Figure 4.13: Automatic: mDot_senddata() Power Consumption

with respect to packet size as shown in Fig. 4.13.

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

Table 4.5: Energy Consumption: Transmission (E-05 in this table is equivalent to


×10−5 and so on.)
PacketSize(B) Duration(s) Current(A) Power(W) Energy(J)
25 0,139±9,92E-08 0,031±7,98E-05 0,157±7,98E-05 0,022±1,11E-05
49 0,150±5,41E-04 0,037±5,09E-05 0,175±5,09E-05 0,026±2,16E-05
73 0,169±9,50E-05 0,038±1,20E-04 0,192±1,20E-04 0,032±2,03E-05
97 0,190±8,61E-04 0,040±5,87E-05 0,201±5,87E-05 0,038±3,64E-05
121 0,210±3,46E-07 0,042±5,41E-05 0,211±5,41E-05 0,044±1,14E-05
145 0,220±6,06E-04 0,044±4,59E-05 0,223±4,59E-05 0,049±2,88E-05
169 0,240±1,06E-07 0,046±5,19E-05 0,229±5,19E-05 0,055±1,25E-05
193 0,260±7,81E-04 0,047±6,38E-05 0,237±6,38E-05 0,062±4,06E-05
217 0,281±4,56E-08 0,048±6,19E-05 0,241±6,19E-05 0,068±1,74E-05
241 0,301±3,89E-07 0,049±4,39E-05 0,245±4,39E-05 0,074±1,32E-05

4.4 Peer-to-Peer Radio Receive

Hypothesis: The energy consumption of mDot does not increase by increasing


the number of bytes received.

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.

In this experiment, we manually measured the current consumption from the


oscilloscope using the DC-Average function. We failed to perform automatic analysis
40 4. POWER AND ENERGY CONSUMPTION ANALYSIS

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.

We conducted two experiments to measure current consumption when the frame


payload length was 120 and 240 bytes respectively. These frame lengths were chosen
to prove the relationship between frame length and the energy consumption. If the
frame length and energy consumption is related then we will observe different energy
consumption values for these two cases.

Results: After conducting the measurements for two different frame lengths we
received following waveforms on the oscilloscope:

Figure 4.14: Current Consump- Figure 4.15: Current Consump-


tion when receiving LoRA frame tion when receiving LoRA frame
of size 240B of size 120B

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.

Table 4.6: Rx Energy Conusmption: A Comparison (E-05 in this table is equivalent


to ×10−5 and so on.)
Size(Bytes) Duration(s) Current(A) Power(W) Energy(J)
120 0,187±3,59E-04 0,02394±6,42E-05 0,120±6,42E-05 0,0225±1,49E-05
240 0,188±1,91E-04 0,02395±5,19E-05 0,120±5,14E-05 0,0226±1,05E-05
Difference 0,001 0,00001 0 0,0001

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

Hypothesis: By increasing the number of bytes to encrypt, the energy consumption


increases linearly.

Method: To measure energy consumption during encryption, we implemented


128-bit AES encryption and decryption using mbed. We used mbedtls library to
implement AES encryption.2 . Following is the code snippet to encrypt 16*n bytes of
data.

Source code 4.10 C++ Program: mDot Encryption

#include "mbedtls/aes.h"
mbedtls_aes_context aes_enc;

// static key
unsigned char key[16] = "itzkbgulrcjmnv";
key[15] = ’x’;

unsigned char iv[16] = {0xb2, 0x4b, 0xf2, 0xf7, 0x7a, 0xc5,


0xec, 0x0c, 0x5e, 0x1f, 0x4d, 0xc1,
0xae, 0x46, 0x5e, 0x75};
mbedtls_aes_setkey_enc( &aes_enc, key, 16*8 );
mbedtls_aes_crypt_cbc( &aes_enc, MBEDTLS_AES_ENCRYPT,
strlen((const char*)input), iv,
input, output );

According to the implementation of mbedtls, the input to the encryption function


should be a multiple of 16. The function mbedtls_aes_crypt_cbc() is called for both
encryption and decryption. The macro MBEDTLS_AES_ENCRYPT instructs the
function to perform encryption. We also implemented the decryption function to
check whether the encryption done in the previous call is correct or not. For the
decryption process, we need to re-initialize the IV (initialization vector) and the macro

2 https://www.mbed.com/en/technologies/security/mbed-tls/
42 4. POWER AND ENERGY CONSUMPTION ANALYSIS

for the mbedtls_aes_crypt_cbc() is set to MBEDTLS_AES_DECRYPT. Following


is the code snippet used for decryption.

Source code 4.11 C++ Program: mDot Dencryption

#include "mbedtls/aes.h"
mbedtls_aes_context aes_dec;

// static key
unsigned char key[16] = "itzkbgulrcjmnv";
key[15] = ’x’;

unsigned char iv[16] = {0xb2, 0x4b, 0xf2, 0xf7, 0x7a, 0xc5,


0xec, 0x0c, 0x5e, 0x1f, 0x4d, 0xc1,
0xae, 0x46, 0x5e, 0x75};
mbedtls_aes_setkey_dec( &aes_dec, key, 16*8 );
mbedtls_aes_crypt_cbc( &aes_dec, MBEDTLS_AES_DECRYPT,
strlen((const char*)output), iv,
output, input );

We generated a variable length input by using a for loop. Following is the code
snippet to generate variable length input used during encryption.

Source code 4.12 C++ Program: Generate input

unsigned char input[300] = {0};


for (int i=0; i<ENCRYPTION_LENGTH; i++)
input[i] = (i % 60) + 33;

We calculated energy consumption by varying input length for encryption. We


gathered data for the current consumption during encryption and decryption for seven
different input data lengths. The number of bytes used for encryption varied from 16
bytes to 112 bytes where there is a difference of 16 bytes between the two samples.
The Python script was used to automatically gather data for current consumption.
We did not perform any manual measurements for these cryptographic operations.

Results: We observed following wavefrom of current drawn by the mDot while


performing encryption and decryption operations. Fig. 4.16 is the waveform of
4.5. CRYPTOGRAPHY 43

crypographic operations; encryption and decryption, when the input data length is
16 bytes.

Figure 4.16: Current Conumsption during Cryptographic Operation

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.

Figure 4.17: mDot Cryptographic Energy Conumsption


4.6. SENSORS 45

Figure 4.18: mDot Cryptographic Power Consumption

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

Source code 4.13 C++ Program: Temperature Snesor DS18B20

#include "mbed.h"
#include "DS1820.h"
#include "mDot.h"

#define DATA_PIN PA_5


// Temperature sensor object
DS1820 probe(DATA_PIN);

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;
}

consumption during temperature sensing by the mDot. Following is the argument to


the Python script to capture data:

Listing 4.4: Run Python Script Temperature Sensor


python e n e r g y . py −e Dot−TTN_DS18B20_MTS_MDOT_F411RE_2s_RT
−t −0.300 −s 10 −F 5 −v 5 . 0 −c 1000

Here the sampling frequency is reduced to 5 MHz and the capture duration to 1000
ms.

To measure energy consumption by the particle sensor, we used DN7C3CA006


particle sensor provided by SHARP corporation[SHA14]. The specification of particle
sensor proposes that we should connect a 220 µF capacitor between GND and pin-6
of the particle sensor. The data sheet also suggests putting a resistor of 150 Ω
4.6. SENSORS 47

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.

Figure 4.19: mDot Interfacing with Particle Sensor Schematic Diagram

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:

Source code 4.14 C++ Program: Particle Sensor Configuring GPIO

#define FAN_PIN PA_3


#define \gls{led}_PIN PA_0
#define MEASUREV_PIN PB_0

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

#define SAMPLING_TIME 280


#define DELTA_TIME 40
#define SLEEP_TIME 9680

float getDustVoltageSample(void)
{
float dustVMeasured = 0.0;
ledpower = 0; // turn the \gls{led} on

//Wait samplingTime before reading V0output


wait_us(SAMPLING_TIME);

// read the dust value in (0-1.0)<->(0V-3.3V)


dustVMeasured = measure.read();
//Wait deltaTime before shutting off \gls{led}
wait_us(DELTA_TIME);

ledpower = 1; // turn the \gls{led} off


wait_us(SLEEP_TIME); // No use in this example
return dustVMeasured;
}

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

Source code 4.16 C++ Program: Main Function of Particle Sensor

#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;

// To calculate dust density


// find reference voltage without fan
vS = getVsWithOutFAN()/FANFREESAMPLE;
while(true) {
generate_event();
// Turn ON FAN to gather particle
fanCtrl = 1;
wait_ms(500);
voMeasured = getDustVoltageSample();
// Calculating output voltage from Raw analog signal to mV
calcVoltage = voMeasured * (3.3) * 1000;

// Calculating dust density


dustDensity += (0.6 * (calcVoltage - vS));
generate_event();
// Turn off the FAN
fanCtrl = 0;
wait(2); // Wait for 2 second
}
}

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:

Listing 4.5: Run Python Script Temperature Sensor


python e n e r g y . py −e Dot−ParticalSensor_MTS_MDOT_F411RE_500ms
−t −0.25 −s 10 −F 5 −v 5 . 0 −c 600

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

Figure 4.20: mDot Temperature Sensor Current Waveform

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

Figure 4.21: mDot Particle Sensor Current Waveform

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

Table 4.8: Sensor Energy Conusmption: A Comparison


Sensor Duration(ms) Current(mA) Power(W) Energy(J)
Temp 763,53±0,359 17,26±5,97E-05 0,086±5,97E-05 0,066±5,90
Particle 510,006±4,16E-04 98,59±3,07E-06 0,493±3,07E-06 0,25±0,894
Difference -253,524 81,330 0,407 0,184

energy as compared to the temperature sensor. The temperature sensor consumes


around 6 times less power than the particle sensor. This section proves that the
power and energy consumption of an application depends on the type of sensor used
in the application. Some sensor might consume less power than the others.
Chapter
Energy Modeling
5
5.1 Energy Consumption Estimation Model

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

Figure 5.1: Power consumption of one cycle of a sensing application. Some


phases are shortened on the x-axis, to save space. The labels reveal the actual
duration [THK17].

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

post-sleep wait pre-send post-send

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.

We proposed a simplified model of energy consumption estimation, where the


model takes Power(P) and duration(∆t) of these distinct phases and computes the
energy consumption.

Equation. 5.1 expresses this model in a mathematical form:

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

phases in a sensing application including the static phases.

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.

5.2 Run-time Logic for Energy Estimation

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]:

Listing 5.1: APIs of timer.h


void s t a r t ( ) \\ s t a r t t h e t i m e r
void s t o p ( ) \\ s t o p t h e t i m e r
float read ( ) \\ g e t time p a s s e d i n s e c o n d s

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

Source code 5.1 General Application with Energy Estimation [THK17]


1: Init the array P of size I − 1 with all pre-measured Pi s.
2: ESsend ← pre-measured energy of pre- and post-send phases
3: Initialize array ES with pre-measured energy of any pre- and post- phases
4: Psend ← The pre-measured power cons. of the send phase
5: En−1 ← 0 . Let n represent cycle n.
6: loop
7: En ← 0
8: i←1
9: while i ≤ I − 1 do
10: tstart ← timestamp()
11: Execute phase i
12: tend ← timestamp()
13: ∆ti ← tend − tstart
14: En ← En + Pi ∆ti + ESi
15: i←i+1
16: end while
17: tstart ← timestamp()
18: Send the data and energy of the previous cycle En−1
19: tend ← timestamp()
20: ∆tI ← tend − tstart
21: En−1 ← En + Psend ∆tI + ESsend
22: end loop

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.

The pseudo code of the application is as follows:


1. Run the particle or temperature sensor and get particle density or temperature
value.
2. Process the sampled sensor data.
3. Repeat step 1 if more sensing samples are required.
4. Transmit the data to a gateway node.
5. Sleep for 2 seconds.
6. Repeat from step 1.

57
58 6. ENERGY-AWARE APPLICATION: INCREASING SENSING PHASE

6.1 Particle Sensor

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

6.1.1 Energy Aware Application

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.

Moreover, in Chapt. 4, we have observed that the receive duration doesn’t


change significantly by changing the number of bytes it receives. Therefore, in these
applications we have fixed its duration to ∼187ms. Similarly, the sleep duration
SLEEP_DUR is fixed to ∼2s. Moreover, the cost of processing has been ignored
since the duration of processing phase is less than a µsecond.

Algo.6.1 gives you an overview of the energy-aware particle sensor application.


6.1. PARTICLE SENSOR 59

Source code 6.1 C++ Program: Energy Aware Application

float powerConsumption[3] ={P_SENSOR, P_TX, P_SLEEP, P_RX};


while(true){
// Sensing Operation
t_op.start();

for (i=0; i<SENSING_SAMPLE; i++){


pDensity = getParticalDensity(vS);
pDensity_sum += pDensity;
pDensity_sum2 += pDensity * pDensity;
stdErrorPDensity = (pDensity_sum2 -
((pDensity_sum * pDensity_sum)/(i+1)))/
(i+1);
stdErrorPDensity = sqrt(stdErrorPDensity);
}
pDensity = pDensity_sum/SENSING_SAMPLE;
t_op.stop();
duration[OP_1] = t_op.read();
t_op.reset();
// Filling mean partical density in the tx buffer
sprintf (buffer, "%f", pDensity);
for (i=0;buffer[i]!=0;i++)
tx_data.push_back(buffer[i]);
// Filling standard error in the tx buffer
sprintf (buffer, "%f", stdErrorPDensity);
for (i=0;buffer[i]!=0;i++)
tx_data.push_back(buffer[i]);
energy = 0.0;
for (int j=0; j<4; j++)
energy += (duration[j] * powerConsumption[j]);
// Filling energy consumption to the tx buffer
sprintf (buffer, "%f", energy);
for (i=0;buffer[i]!=0;i++)
tx_data.push_back(buffer[i]);

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();

dot->sleep(SLEEP_DUR, mDot::RTC_ALARM, false);


duration[OP_3] = SLEEP_DUR;
// Taking care of rx during sleep
duration[OP_4] = DUR_RX/1000;
}
60 6. ENERGY-AWARE APPLICATION: INCREASING SENSING PHASE

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.

Fig. 6.1 presents the energy profiles of these sensing applications.

Figure 6.1: Energy Profiles of Particle Sensing Energy-aware Application with


Increasing Sensor Sampling Count

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

6.1.2 Oscilloscope Measurement

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:

Listing 6.1: Python Script: Energy Aware Sense Application


python e n e r g y . py −e
Dot−EnergyAware_SenseApp_MTS_MDOT_F411RE_20SS −t −0.25
−s 10 −F 0 . 0 0 1 −v 5 . 0 −c 202500

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

Table 6.3: Energy Consumption Modling Particle Sensing Application: A compari-


son
App# Estimated Energy(J) Measure Energy(J) Error(%)
SenseApp..._1SS 5,005±6,27012E-05 5,0748±7,979E-04 1,37%
SenseApp..._2SS 9,933±0,0211 9,9881±5,845E-04 0,55%
SenseApp..._5SS 24,737±0,0211 24,727±1,689E-03 0,04%
SenseApp..._10SS 49,412±0,0211 49,305±1,500E-03 0,22%
SenseApp..._20SS 98,762±0,0211 98,408±3,346E-03 0,36%

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.

6.2 Temperature Sensor

By following the section of particle sensing application we have developed five


different applications for the temperature sensor. In these applications, we will vary
the frequency of sensor sampling to be one, two, five, ten and twenty. Following
names were given to such applications:
– SenseApp_MTS_MDOT_F411RE_1TS
– SenseApp_MTS_MDOT_F411RE_2TS
– SenseApp_MTS_MDOT_F411RE_5TS
– SenseApp_MTS_MDOT_F411RE_10TS
– SenseApp_MTS_MDOT_F411RE_20TS
6.2. TEMPERATURE SENSOR 63

6.2.1 Energy Aware Application

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:

Source code 6.2 C++ Program: Temperature Sensing Modification in Energy


Aware Application

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 power consumption for temperature is ∼86,3 mW as measured and reported


in tab. 4.8 in the Chapt. 4. However, we have used a different value in the current
example. The reason for this is that in those measurements we computed the
temperature sensor’s power consumption when no radio module was enabled. When
we enable the radio module for transmission the power consumption of mDot increases
and therefore, the power consumption of temperature sensor increased. To incorporate
this change we again measured the power consumption by the temperature sensor
using Python script and the setup defined in Chapt. 3. Tab. 6.4 shows the measured
values:

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.

Figure 6.2: Energy Profiles of Temperature Sensing Energy-aware Application with


Increasing Sensor Sampling Count
6.2. TEMPERATURE SENSOR 65

Tab. 6.5 provides the energy consumption sent by the energy-aware temperature
sensing application.

Table 6.5: Energy Consumption Sent by the Energy-Aware Temperature Sensing


Application
Application Sensing Sample Frequency Energy(J)
SenseApp..._1TS 1 0,154±2,77E-17
SenseApp..._2TS 2 0,262±5,55E-17
SenseApp..._5TS 5 0,587±4,24E-04
SenseApp..._10TS 10 1,127±4,71E-04
SenseApp..._20TS 20 2,208±0

6.2.2 Oscilloscope Measurement

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.

Following is the command used to compute energy consumption using Python


script when sensing sample count was 20:

Listing 6.2: Python Script: Energy Aware Sense Application


python e n e r g y . py −e
Dot−EnergyAware_TempSenseApp_MTS_MDOT_F411RE_1TS −t
−0.25 −s 10 −F 1 −v 5 . 0 −c 3100

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

Table 6.7: Energy Consumption Modling Temperature Sensing Application: A


comparison
App# Estimated Energy(J) Measure Energy(J) Error(%)
SenseApp..._1TS 0,154±2,77E-17 0,155±6,10E-04 0,24%
SenseApp..._2TS 0,262±5,55E-17 0,259±4,96E-04 1,49%
SenseApp..._5TS 0,587±4,24E-04 0,588±1,10E-03 0,16%
SenseApp..._10TS 1,127±4,71E-04 1,111±1,12E-03 1,40%
SenseApp..._20TS 2,208±0 2,197±2,09E-03 0,47%

bit balanced and we observed an error in estimation at around 0,24%. Similarly,


the contribution of the sensing phase in the energy estimation of the applications
SenseApp_MTS_MDOT_F411RE_2TS and SenseApp_MTS_MDOT_F411RE_5TS
is 78% and 90% respectively but the error in estimation is still insignificant. These
experimental results gave us more confidence in our energy consumption estimation
approach. Since this approach is performing efficiently when other phases are also
contributing in the energy estimation.

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.

– Moderate: The energy is available at a moderate level. Send sensor data at a


normal pace.

– 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.

7.1 Particle Sensor

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

selection of different parameters in different sensing modes:

Table 7.1: Sensor Modes Parameters in Particle Sensing Energy-Aware Applications


Sensing Mode Duty Cycle(s) Sensing Samples
Extravagant 10 1
Moderate 60 1
Thrifty 300 1

All the values presented in the Tab. 8.2 are with respect to one sensing cycle.

7.1.1 Energy-Aware Application

The technique of developing energy-aware applications is same as explained in the


Chapt. 6, however in the current applications we have added the pre- and post-
static blocks as separate blocks of energy. In the Chapt. 6, we averaged them over
the main phase. There is also another addition in these applications that we are
sending the energy consumption of each phase along with the accumulated energy.
This has increased the transmission packet size along with the transmission phase
energy consumption. In these example applications, we have removed the receive
phase and have added an active phase. However, the contribution of active phase is
again ignorable. Algo. 7.1 presents the modified code snippet of the particle sensing
energy-aware applications.
7.1. PARTICLE SENSOR 69

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

The P_SENSOR and P_ACTIVE are ∼493 mW and ∼153,6 mW respectively,


as calculated in the Chapt. 4. The transmission phase consumes ∼324,74 mW
as defined in the Chapt. 4 without averaging it with pre- and post- phases. The
P_SLEEP measured without the pre- and post- phases is ∼1,2 mW. However, when
the Particle Sensor is attached to the mDot the power consumption is observed to
be increased. We measured the power and energy consumption during Sleep phase
to incorporate the impact of Particle Sensor on the Sleep phase. We measured the
power consumption during Sleep phase using Python script and the measurement
setup described in the Chapt. 3. Following table summarizes the data gathered:

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

Figure 7.1: Energy Profiles of Particle Sensing Energy-aware Application with


Different Sensing Modes

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.

Table 7.3: Particle Sensing: Energy Consumption Comparison under Different


Sensing Modes
Sensing Mode Estimated Energy(J) Measured Energy(J) % Error
Extravagant 5,420±1,33E-03 5,450±1,57E-03 0,582%
Moderate 7,727±8,93E-04 7,672±3,78E-03 0,706%
Thrifty 18,695±1,49E-04 18,681±0,0104 0,071%
72 7. ENERGY-AWARE APPLICATION: DIFFERENT SENSING MODES

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

7.2 Temperature Sensor

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:

Table 7.5: Sensor Modes Parameters in Temperature Sensing Energy-Aware Appli-


cations
Sensing Mode Duty Cycle(s) Sensing Samples
Extravagant 1 1
Moderate 60 5
Thrifty 160 1

All the values presented in the Tab. 7.5 are with respect to one sensing cycle.
7.2. TEMPERATURE SENSOR 73

7.2.1 Energy-Aware Application

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.

Figure 7.2: Energy Profiles of Temperature Sensing Energy-aware Application with


Different Sensing Modes
74 7. ENERGY-AWARE APPLICATION: DIFFERENT SENSING MODES

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.

Table 7.6: Temperature Sensing: Energy Consumption Comparison under Different


Sensing Modes
Sensing Mode Estimated Energy(J) Measured Energy(J) % Error
Extravagant 0,158±1,59E-04 0,157±1,32E-04 0,435%
Moderate 0,658±1,62E-04 0,666±7,64E-03 1,233%
Thrifty 0,349±1,49E-04 0,347±8,68E-03 0,588%

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:

Table 7.7: Temperature 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 2,022 300 47,4
Moderate 64,48 10 7,18
Thrifty 160,99 4 1,396
Energy-Aware Application:
Waspmote
Chapter

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.

The pseudo code of the application is as follows:


1. Run the CO2 sensor and get the CO2 concentration.
2. Process the sampled sensor data.
3. Repeat step 1 if more sensing samples are required.
4. Transmit the data to a gateway node.
5. Sleep for 20 seconds.
6. Repeat from step 1.
We implemented the energy calculation model defined in Eq. 5.1 in these applica-
tions. To prove the accuracy of our energy estimation model using waspmote IoT
hardware platform, we will compare the results from our energy estimation model to
the actual energy consumption. We have used the shunt resistor approach as defined
in the Chapt. 3 to measure actual energy consumption. We have used the Python
script to estimate the energy consumption of a sensing cycle by the application. The
data gathered is an average over 10 energy measurement samples.

8.1 Application Logic

We have used waspmote-pro-ide-v06.02 to write energy-aware sensing applications [was].


In this section, we will describe the source code of the CO2 sensing application. The
complete source code can be found in the Appendix. E.

1 http://www.libelium.com/products/waspmote/

75
76 8. ENERGY-AWARE APPLICATION: WASPMOTE

Following is the code snippet to get CO2 concentration:

Source code 8.1 waspmote CO2 Sensing Phase


Gas co2(SOCKET_A);

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

Algo. 8.2 presents the code for transmission.

Source code 8.2 waspmote Transmission Phase


configureLoRaWAN();

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:

Source code 8.3 waspmote Sleeping Phase

PWR.deepSleep("00:00:00:20", RTC_OFFSET, RTC_ALM1_MODE1, ALL_ON);

8.2 Design-time and Run-time Energy Estimation Logic

Since it was a new hardware platform, therefore, we performed a design-time energy


measurement process for each activity phase as defined in Fig. 5.2. For such type of
applications, we only observed three activity phases; sense, transmit and sleep. We
performed automatic power and energy measurement using the measurement setup
defined in Chapt. 3. We configured a waspmote to signal the oscilloscope to start
sampling the data from the measurement setup. We generated a 100 ms pulse at the
start and end of each phase and computed the power and energy consumption during
these phases. Following is code snippet is used to configure GPIO and generate pulse:
8.2. DESIGN-TIME AND RUN-TIME ENERGY ESTIMATION LOGIC 79

Source code 8.4 waspmote Generate Event


pinMode(DIGITAL3,OUTPUT);
digitalWrite(DIGITAL3,0);

void generate_event(){
// setting event pin for oscillscope measurements
digitalWrite(DIGITAL3,1);
delay(100);
digitalWrite(DIGITAL3,0);
}

We have configured DIGITAL3 in waspmote as the event generator for the


oscilloscope. The function generate_event() is called before the start and the end
of each activity phase as defined in Algo. 8.1, 8.2 and 8.3. The following table
summarizes the measure power and energy consumption is for each activity phase:

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

For the run-time estimation, we implemented the run-time logic as explained in


the Algo. 5.1 in the application. We used the Real-time Counter (RTC) APIs defined
in Waspmote Pro API-v028 to compute the duration of each activity phase [lib]. For
duration calculation, we used a getEpochTime function that returns the number of
seconds passed since Thursday, 1 January 1970.
80 8. ENERGY-AWARE APPLICATION: WASPMOTE

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

Source code 8.5 waspmote RTC to Measure Duration of each Phase


RTC.ON();
timestamp = RTC.getEpochTime();
// Write the code to enter an activity phase
// Write the code to exit an activity phase
Duration[ACTIVITY_PHASE] = RTC.getEpochTime() - timestamp;
RTC.off();

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[].

8.3 Energy Aware Application

We developed three CO2 periodic sensing applications based on different sensing


modes: extravagant, moderate, and thrifty. These three applications have different
duty cycles and CO2 sensing samples in an activity cycle. Following table summarizes
the selection of different parameters in different sensing modes:

Table 8.2: Sensor Modes Parameters in CO2 Sensing Energy-Aware Applications


Sensing Mode Duty Cycle(s) Sensing Samples
Extravagant 5 5
Moderate 20 1
Thrifty 120 1

We modified the SLEEP_DUR and SENSING_SAMPLE in the source defined


in Appendix. E, to generate these three applications.

Fig. 8.1, shows the oscilloscope dump of a sensing cycle of a CO2 energy-aware
sensing application under Moderate sensing mode.

In these applications, we have categorized only three activity phases; sensing,


transmission, and sleeping. The value of P_SENSOR is ∼362,65 mW, P_TX has a
value of ∼293,05 mW, and the value of P_SLEEP is ∼193,6 mW.
8.3. ENERGY AWARE APPLICATION 81

Figure 8.1: Current Consumption of a CO2 Sensing Application using 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.

In the problem description, we proposed to establish a generic energy estimation


model that will give precise energy estimations for a periodic sensing application using
different communication protocols and IoT hardware platforms. Initially, we suggested
that to generalize our energy estimation model we will use parametric approach.
However, during our work, we found that there are two important parameters for
energy estimation; one is the power consumption and the other is the duration.
Similarly, we also figured out that the energy profile of an application consists of
individual activity phases. Therefore, we withdrew the parametric approach and used
the design-time and run-time based approach to compute the power and duration of
each activity phase.

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.

The presented approach is computationally less expensive to implement inside


an application and sends the energy estimation for each sensing cycle along with
the meta-data to the backend cloud. The size of estimated energy is only 8 bytes
that slightly adds to the energy consumption of the transmission which is negligible
and reported to the backend in the next transmission cycle. The design-time power
calculation saves the energy consumed by the co-processor or external hardware
integrated to the IoT device to compute power consumption.
References

[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

[Dal] Dallas Semiconductor. DS18B20 Programmable Resolution 1-Wire Digital Ther-


mometer.

[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.

[GRE+ 01] M. R. Guthaus, J. S. Ringenberg, D. Ernst, T. M. Austin, T. Mudge, and R. B.


Brown. Mibench: A free, commercially representative embedded benchmark suite.
In Proceedings of the Fourth Annual IEEE International Workshop on Workload
Characterization. WWC-4 (Cat. No.01EX538), pages 3–14, Dec 2001.

[Hom16] Gunnar Ranøyen Homb. Adaptive Store and Forward, 2016.

[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.

[lib] libelium. Waspmote RTC Programming Guide. v7.0-02/2017.

[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.

[MCB15] S. Mijovic, R. Cavallari, and C. Buratti. Experimental characterisation of energy


consumption in body area networks. In Internet of Things (WF-IoT), 2015 IEEE
2nd World Forum on, pages 514–519, Dec 2015.
REFERENCES 87

[MMJ+ 05] A. Milenkovic, M. Milenkovic, E. Jovanov, D. Hite, and D. Raskovic. An envi-


ronment for runtime power monitoring of wireless sensor network platforms. In
Proceedings of the Thirty-Seventh Southeastern Symposium on System Theory,
2005. SSST ’05., pages 406–410, March 2005.
[MMVP15] B. Martinez, M. Montón, I. Vilajosana, and J. D. Prades. The power of models:
Modeling power consumption for iot devices. IEEE Sensors Journal, 15(10):5777–
5789, Oct 2015.
[mula] ARMmbed Developer Resources multitech / dot-examples. https://developer.
mbed.org/teams/MultiTech/code/Dot-Examples/. Accessed: 2017-03-30.
[Mulb] Multi-Tech Systems. MTDOT Developer Guide. Rev. 3.1.
[Mul16] Multi-Tech Systems, Inc., 2205 Woodale Drive, Mounds View, MN 55112. Multi-
Connect mDot: MTDOT Developer Guide, 3 edition, 2016.
[PHZ+ 11] Abhinav Pathak, Y. Charlie Hu, Ming Zhang, Paramvir Bahl, and Yi-Min Wang.
Fine-grained power modeling for smartphones using system call tracing. In
Proceedings of the Sixth Conference on Computer Systems, EuroSys ’11, pages
153–168, New York, NY, USA, 2011. ACM.
[Pic] PicoScope 6000 Series deep-memory high-performance usb scopes. https://www.
picotech.com/oscilloscope/6000/picoscope-6000-overview. Accessed: 2016.
[RH10] Andrew Rice and Simon Hay. Measuring mobile phone energy consumption for
802.11 wireless networking. Pervasive Mob. Comput., 6(6):593–606, December
2010.
[SHA14] SHARP Corporation. Device Specification for PM2.5 Sensor module, 9 2014. Rev.
6.1.
[SHC+ 04] Victor Shnayder, Mark Hempstead, Bor-rong Chen, Geoff Werner Allen, and
Matt Welsh. Simulating the power consumption of large-scale sensor network
applications. In Proceedings of the 2Nd International Conference on Embedded
Networked Sensor Systems, SenSys ’04, pages 188–200, New York, NY, USA,
2004. ACM.
[SLE+ 15] N. Sornin, M. Luis, T. Eirich, T Kramp, and O. Hersent. LoRaWAN Specification.
LoRa Alliance, 1 edition, jan 2015.
[SSJ+ 02] Dongkun Shin, Hojun Shim, Yongsoo Joo, Han-Saem Yun, Jihong Kim, and
Naehyuck Chang. Energy-monitoring tool for low-power embedded programs.
IEEE Design Test of Computers, 19(4):7–17, Jul 2002.
[STM16] STMicroelectronics. Datasheet STM32F411xC STM32F411xE, 12 2016. Rev. 6.
[THK17] Nattachart Tamkittikhun, Amen Hussain, and Frank Alexander Kraemer. En-
ergy consumption estimation for energy-aware, adaptive sensing applications.
In International Conference on Mobile, Secure and Programmable Networking
(MSPN’2017), jun 2017.
88 REFERENCES

[was] libelium development. http://www.libelium.com/development/waspmote/sdk_


applications/. Accessed: 2017-05-20.
Appendix
Picoscope Python Script
A
Source code A.1 Python Script: Defining package imports
import math
import time
import inspect
import numpy as np
from picoscope import ps6000

from matplotlib.mlab import find


import pylab as pl
import xlwt
import argparse

89
90 A. PICOSCOPE PYTHON SCRIPT

Source code A.2 Defining Energy Measurement Class


class energyMeasure():

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()

self.ps.setChannel("A", coupling="DC", VRange=0.100,


probeAttenuation=1, BWLimited = 2)
self.ps.setChannel("B", coupling="DC", VRange=1.0,
probeAttenuation=1, BWLimited = 2)
self.ps.setChannel("C", enabled=False)
self.ps.setChannel("D", enabled=False)
res = self.ps.setSamplingFrequency(self.samplingfreq * 1E6,
int(self.capturesampleNo))
self.sampleRate = res[0]
print("Sampling @ %f MHz, %d samples"%(res[0]/1E6, res[1]))

#Use external trigger to mark when we sample


self.ps.setSimpleTrigger(trigSrc="B", threshold_V=self.threshold,
direction="Falling",
timeout_ms=0)

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)

print ("Number of samples: ", fs)


print ("Duration: ", to / fs)
print("MeanCurrent:", np.mean(subChannelA))
print("StandardDeviation:", np.std(subChannelA))

def measure(self, filename):


print("Waiting for trigger")
while(self.ps.isReady() == False): time.sleep(0.01)
print("Sampling Done")
print("captureSampleNo: ",int(self.capturesampleNo))
dataA = self.ps.getDataV("A", int(self.capturesampleNo))
dataB = self.ps.getDataV("B", int(self.capturesampleNo))

indices = []
for index in range(len(dataB)):
if dataB[index] >= THRESHOLD:
break;

print("Index: ", index)


if self.numberOfSamples == 0:
fig = pl.figure()
pl.plot(dataB)
pl.savefig("fig\dataB"+str(self.numberOfSamples)+filename+".png")
fig.clf()
pl.close()

fig = pl.figure()
pl.plot(dataA)
pl.savefig("fig\dataA"+str(self.numberOfSamples)+filename+".png")
fig.clf()
pl.close()

if (index+1) < len(dataB):


self.numberOfSamples = self.numberOfSamples + 1
self.computeMeanAndStdevSubChannel(dataA[1:index], index)
92 A. PICOSCOPE PYTHON SCRIPT

Source code A.4 Energy Measurement Class: Writing to an excel file


def output(self, filename, x, y, z):
book = xlwt.Workbook()
sh = book.add_sheet("Sheet 1")
style = xlwt.XFStyle()
# font
font = xlwt.Font()
font.bold = True
style.font = font
variables = [x, y, z, (self.sampleRate/1E6), self.captureLength * 1E3,
self.capturesampleNo]
desc = [’TextName’, ’Voltage(V)’, "Thresh_Vol", "Sampling Freq"
, "Capture Length(ms)", "Capture Samples/calc"]
for n, (v_desc, v) in enumerate(zip(desc, variables)):
sh.write(n, 0, v_desc, style=style)
sh.write(n, 1, v)
n+=2
sh.write(n, 0, ’SampleDuration(ms)’, style=style)
sh.write(n, 1, ’Duration(ms)’, style=style)
sh.write(n, 2, ’MeanCurrent(A)’, style=style)
sh.write(n, 3, ’StandardError’,ol3, style=style)
index = 1
for m, e1 in enumerate(self.mDur, n+1):
sh.write(m, 0, ’Sample ’ + str(index))
sh.write(m, 1, e1)
index += 1

for m, e2 in enumerate(self.mCurr, n+1):


sh.write(m, 2, (e2))

for m, e3 in enumerate(self.sdCurr, n+1):


sh.write(m, 3, e3)

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)

energy = (np.mean(self.mDur)/1000) * y * np.mean(self.mCurr)


m+=1
sh.write(m,0,"Energy(J)", style=style)
sh.write(m,1, energy)
book.save(filename)
93

Source code A.5 Pyhton Script: Main Function


if __name__ == "__main__":

parser = argparse.ArgumentParser(description=’Get statistics.’)


parser.add_argument(’-e’, dest=’experimentName’, type=str,
required=True, help=’Name of the experiment’)
parser.add_argument(’-t’, dest=’threshold’, type=float,
required=True, help=’Current Threshold’)
parser.add_argument(’-s’, dest=’maxsamples’, type=int, required=True,
help=’Number of data samples for statistical analysis.’)
parser.add_argument(’-F’,dest=’samplingFreq’, type=float,
required=True, help=’Sampling frequency in MS/s.’)
parser.add_argument(’-v’, dest=’voltage’, type=float, required=True,
help=’Voltage to power up the board’)
parser.add_argument(’-c’, dest=’captureLen’, type=float, required=True,
help=’Capture duration in msec’)

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 ) ;

29 void sleep_wake_interrupt_only ( bool deepsleep ) ;

31 void sleep_wake_rtc_or_interrupt ( bool deepsleep ) ;

33 void sleep_save_io ( ) ;

35 void sleep_configure_io ( ) ;

37 void sleep_restore_io ( ) ;

39 v o i d send_data ( s t d : : v e c t o r <uint8_t> data ) ;

41 #e n d i f

Listing B.1: dot_util.h (Used from [mula])

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 ;

177 memcpy ( RxPayload , payload , s i z e ) ;


RxPayloadSize = s i z e ;
179
i f ( c t r l . B i t s . Ack ) {
181 AckReceived = t r u e ;
}
183
i f ( mts : : MTSLog : : g e t L o g L e v e l ( ) ==
mts : : MTSLog : : TRACE_LEVEL) {
185 std : : s t r i n g packet =
mts : : Text : : b i n 2 h e x S t r i n g ( RxPayload , s i z e ) ;
l o g T r a c e ( " Payload : %s " , p a c k e t . c _ s t r ( ) ) ;
187 }

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 }

215 v i r t u a l v o i d NetworkLinkCheck ( i n t 1 6 _ t m_rssi , i n t 8 _ t m_snr ,


i n t 8 _ t s_snr , u i n t 8 _ t s_gateways ) {
logDebug ( " mDotEvent − NetworkLinkCheck " ) ;
B.2. MDOTEVENT.H 101

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 " ) ;

243 memset(& _ f l a g s , 0 , s i z e o f ( LoRaMacEventFlags ) ) ;


memset(& _info , 0 , s i z e o f ( LoRaMacEventInfo ) ) ;
245
_ f l a g s . B i t s . RxSlot = s l o t ;
247 _ i n f o . S t a t u s = LORAMAC_EVENT_INFO_STATUS_RX_ERROR;
Notify () ;
249 }

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 ;

259 bool PacketReceived ;


u i n t 8 _ t RxPort ;
261 u i n t 8 _ t RxPayload [ 2 5 5 ] ;
u i n t 8 _ t RxPayloadSize ;
263
b o o l PongReceived ;
265 i n t 1 6 _ t PongRssi ;
i n t 1 6 _ t PongSnr ;
267
b o o l AckReceived ;
102 B. MDOT P2P COMMUNICATION HEADER FILES

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__

Listing B.2: mDotEvent.h (Used from [mula])

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) {

64 logDebug ( "Rx %d b y t e s " , i n f o −>R x B u f f e r S i z e ) ;


i f ( i n f o −>R x B u f f e r S i z e > 0 ) {
66 // p r i n t RX data a s h e x a d e c i m a l
// p r i n t f ( " Rx data : %s \ r \n " ,
mts : : Text : : b i n 2 h e x S t r i n g ( i n f o −>RxBuffer ,
i n f o −>R x B u f f e r S i z e ) . c _ s t r ( ) ) ;
68
// p r i n t RX data a s s t r i n g
70 s t d : : s t r i n g r x ( ( c o n s t c h a r ∗ ) i n f o −>RxBuffer ,
i n f o −>R x B u f f e r S i z e ) ;
p r i n t f ( "Rx data : %s \ r \n " , r x . c _ s t r ( ) ) ;
72 }
}
74 }
};
76
#e n d i f

Listing B.3: RadioEvent.h (Used from [mula])


Appendix
mDot Particle Sensing
Energy-Aware Application C
#i n c l u d e " d o t _ u t i l . h "
2 #i n c l u d e " RadioEvent . h "

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

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" ) ;


90 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" ) ;
92 }
}
94 frequency_band = dot−>getFrequencyBand ( ) ;
s w i t c h ( frequency_band ) {
96 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
98 // 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
100 tx_frequency = 869850000;
t x _ d a t a r a t e = mDot : : DR6 ;
102 // 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 ;
104 break ;
c a s e mDot : : FB_US915 :
106 c a s e mDot : : FB_AU915 :
default :
108 // 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
110 // DR9 : SF11 @ 500 kHz
// DR10 : SF10 @ 500 kHz
112 // DR11 : SF9 @ 500 kHz
// DR12 : SF8 @ 500 kHz
114 // 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
116 tx_frequency = 915500000;
t x _ d a t a r a t e = mDot : : DR13 ;
118 // 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 ;
120 break ;
}
122 // 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
124 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 ) ;

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 ( ) ;

138 l o g I n f o ( " e n t e r i n g Loop " ) ;

140 f l o a t powerConsumption [ 4 ] ={P_SENSOR, P_ACTIVE, P_TX, P_SLEEP} ;


f l o a t duration [ 4 ] = {0.0};
142 f l o a t s t a t i c E n e r g y [ 4 ] = { 0 , 0 ,PRE_TX_ENERGY+POST_TX_ENERGY,
PRE_SLEEP_ENERGY+POST_SLEEP_ENERGY} ;

144 Timer t_op ;


f l o a t energy = 0 . 0 ;
146 char b u f f e r [50]={0};

148 while ( true ) {


// t r i g g e r i n g o s c i l l o s c o p e t o s t a r t s a m p l i n g
150 generate_event ( ) ;

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 }

170 p D e n s i t y = pDensity_sum /SENSING_SAMPLE ;

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 ] ) ;

208 // ad di ng each a c t i v i t y phase ’ s e n e r g y consumption


// t o t h e t r a n s m i s s i o n frame
210 s p r i n t f ( b u f f e r , "OP%d:% f ; " , i +1 , ( ( d u r a t i o n [ i ] ∗
powerConsumption [ i ] ) + s t a t i c E n e r g y [ i ] ) ) ;
f o r ( i n t i n d =0; b u f f e r [ i n d ] ! = 0 ; i n d++)
212 tx_data . push_back ( b u f f e r [ i n d ] ) ;
}
214
// ad di ng o v e r a l l e n e r g y consumption
216 // t o t h e t r a n s m i s s i o n frame
s p r i n t f ( b u f f e r , "%f " , e n e r g y ) ;
218 f o r ( i =0; b u f f e r [ i ] ! = 0 ; i ++)
tx_data . push_back ( b u f f e r [ i ] ) ;
220
// C a p t u r i n g p r o c e s s i n g d u r a t i o n
222 t_op . s t o p ( ) ;
d u r a t i o n [ OP_2 ] = t_op . read_us ( ) ;
224 d u r a t i o n [ OP_2 ] = d u r a t i o n [ OP_2] / 1 0 0 0 0 0 0 ;
t_op . r e s e t ( ) ;
226
// S e n di n g data
228 t_op . s t a r t ( ) ;
send_data ( tx_data ) ;
230 t_op . s t o p ( ) ;

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

234 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 ( ) ;
236
// 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
238 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
240 // 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
242 // 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 .
244 d u r a t i o n [ OP_4 ] = SLEEP_DUR − PRE_SLEEP_DUR;

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

274 wait_us (SLEEP_TIME) ; // No u s e i n t h i s example


r e t u r n dustVMeasured ;
276 }

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 ( ) ;

300 // C a l c u l a t i n g o ut pu t v o l t a g e from Raw a n a l o g s i g n a l t o mV


c a l c V o l t a g e = voMeasured ∗ 3 . 3 ;
302
// C a l c u l a t i n g d u s t d e n s i t y
304 d u s t D e n s i t y += ( 0 . 6 ∗ ( c a l c V o l t a g e − vS ) ) ;

306 // Turn o f f t h e FAN


fanCtrl = 0;
308 return dustDensity ;
}
310
void generate_event ( )
312 {
D i g i t a l O u t l e d 1 (PA_2) ;
314 led1 = 1;
wait_ms ( 1 0 0 ) ;
316 led1 = 0;
}

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 ( ) ;

35 s t a t i c u i n t 8 _ t network_address [ ] = { 0 x01 , 0 x02 , 0 x03 , 0 x04 } ;


s t a t i c u i n t 8 _ 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 } ;

113
114 D. MDOT TEMPERATURE SENSING ENERGY-AWARE APPLICATION

37 s t a t i c u i n t 8 _ 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 } ;

39 mDot∗ dot = NULL;


S e r i a l pc (USBTX, USBRX) ;
41
i n t main ( ) {
43 // 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 ;
45 uint32_t tx_frequency ;
uint8_t tx_datarate ;
47 u i n t 8 _ t tx_power ;
u i n t 8 _ t frequency_band ;
49
pc . baud ( 1 1 5 2 0 0 ) ;
51
mts : : MTSLog : : s e t L o g L e v e l ( mts : : MTSLog : : TRACE_LEVEL) ;
53
dot = mDot : : g e t I n s t a n c e ( ) ;
55
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) ;
57
// s t a r t from a w e l l −known s t a t e
59 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 ( ) ;
61
// 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
63 dot−>s e t L o g L e v e l ( mts : : MTSLog : : INFO_LEVEL) ;

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 ) ;

119 f l o a t powerConsumption [ 4 ] ={P_SENSOR, P_ACTIVE, P_TX, P_SLEEP} ;


f l o a t duration [ 4 ] = {0.0};
121 f l o a t s t a t i c E n e r g y [ 4 ] = { 0 , 0 ,PRE_TX_ENERGY+POST_TX_ENERGY,
PRE_SLEEP_ENERGY+POST_SLEEP_ENERGY} ;

123 Timer t_op ;


f l o a t energy = 0 . 0 ;
125 char b u f f e r [50]={0};
f l o a t dur ;
127
while ( true ) {
129 generate_event ( ) ;
v o l a t i l e f l o a t temperature = 0 . 0 ;
131 f l o a t temperature_sum = 0 . 0 ;
116 D. MDOT TEMPERATURE SENSING ENERGY-AWARE APPLICATION

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 }

151 t e m p e r a t u r e = temperature_sum /SENSING_SAMPLE ;

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

183 tx_data . push_back ( 5 9 ) ;


energy = 0 . 0 ;
185 f o r ( i n t i =0; i <4; i ++)
{
187 e n e r g y += ( ( d u r a t i o n [ i ] ∗ powerConsumption [ i ] ) +
staticEnergy [ i ] ) ;

189 // ad di ng each a c t i v i t y phase ’ s e n e r g y consumption


// t o t h e t r a n s m i s s i o n frame
191 s p r i n t f ( b u f f e r , "OP%d:% f ; " , i +1 , ( ( d u r a t i o n [ i ] ∗
powerConsumption [ i ] ) + s t a t i c E n e r g y [ i ] ) ) ;
f o r ( i n t i n d =0; b u f f e r [ i n d ] ! = 0 ; i n d++)
193 tx_data . push_back ( b u f f e r [ i n d ] ) ;
}
195
// ad di ng o v e r a l l e n e r g y consumption
197 // t o t h e t r a n s m i s s i o n frame
s p r i n t f ( b u f f e r , "%f " , e n e r g y ) ;
199 f o r ( i =0; b u f f e r [ i ] ! = 0 ; i ++)
tx_data . push_back ( b u f f e r [ i ] ) ;
201
// C a p t u r i n g p r o c e s s i n g d u r a t i o n
203 t_op . s t o p ( ) ;
d u r a t i o n [ OP_2 ] = t_op . read_us ( ) ;
205 d u r a t i o n [ OP_2 ] = d u r a t i o n [ OP_2] / 1 0 0 0 0 0 0 ;
t_op . r e s e t ( ) ;
207
// S e n d i n g data
209 t_op . s t a r t ( ) ;
send_data ( tx_data ) ;
211 t_op . s t o p ( ) ;

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

// This w a i t was added t o g e t t h e p r e c i s e measurement


233 // 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
235 // 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 ) ;
237 }

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

E.2 Source File

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

216 errorLW = LoRaWAN. getRadioBW ( ) ;


217 i f ( errorLW == 0 )
218 {
219 USB . p r i n t (F( " O p e r a t i n g r a d i o bandwidth : " ) ) ;
220 USB . p r i n t l n (LoRaWAN. _radioBW ) ;
221 }
222 else
223 USB . p r i n t (F( " Could not g e t t h e r a d i o bandwidth . " ) ) ;
224 errorLW = LoRaWAN. getRadioSF ( ) ;
225 i f ( errorLW == 0 )
226 {
227 USB . p r i n t (F( " O p e r a t i n g r a d i o s p r e a d i n g f a c t o r : " ) ) ;
228 USB . p r i n t l n (LoRaWAN. _radioSF ) ;
229 }
230 else
231 USB . p r i n t (F( " Could not g e t t h e r a d i o s p r e a d i n g f a c t o r . " ) ) ;
232 #e n d i f
233
234 errorLW = LoRaWAN.OFF(SOCKET) ;
235 // s t o r i n g t r a n s m i s s i o n d u r a t i o n
236 D u r a t i o n [ 1 ] = RTC. getEpochTime ( ) − timestamp ;
237
238 #i f d e f _DEBUG
239 USB . p r i n t (F( " Transmit D u r a t i o n S t a r t : " ) ) ;
240 USB . p r i n t l n ( timestamp ) ;
241 USB . p r i n t (F( " Transmit D u r a t i o n End : " ) ) ;
242 USB . p r i n t l n (RTC. getEpochTime ( ) ) ;
243 USB . p r i n t (F( " Transmit D u r a t i o n : " ) ) ;
244 USB . p r i n t l n ( D u r a t i o n [ 1 ] ) ;
245 #e n d i f _DEBUG
246 RTC.OFF( ) ;
247
248 #i f d e f _DEBUG
249 // Check s t a t u s
250 i f ( errorLW == 0 )
251 {
252 USB . p r i n t l n (F( " 4 . S wi tc h OFF OK" ) ) ;
253 }
254 else
255 {
256 USB . p r i n t (F( " 4 . Sw it ch OFF e r r o r = " ) ) ;
257 USB . p r i n t l n ( errorLW , DEC) ;
258 }
259 #e n d i f
260 // E n t e r i n g s l e e p phase
261 PWR. d e e p S l e e p ( " 0 0 : 0 0 : 0 0 : 5 " , RTC_OFFSET, RTC_ALM1_MODE1, ALL_OFF) ;
262 generate_event ( ) ;
263 // Adding a d e l a y o f 50 s b e f o r e
264 // s t a r t i n g t h e n e x t c y c l e
265 delay (20000) ;
266 }
267
E.2. SOURCE FILE 125

268 void generate_event ( )


269 {
270 // s e t t i n g e v e n t p i n f o r o s c i l l s c o p e measurements
271 d i g i t a l W r i t e ( DIGITAL3 , 1 ) ;
272 delay (100) ;
273 d i g i t a l W r i t e ( DIGITAL3 , 0 ) ;
274 }
275
276 v o i d addEnergyConsumptiontoFrame ( v o i d )
277 {
278 c h a r number [ 2 0 ] ;
279 f l o a t e n e r g y =0;
280
281 f o r ( i n t i =0; i <3; i ++)
282 {
283 // ad di ng t h e e n e r g y consumption o f each a c t i v i t y phase
284 U t i l s . f l o a t 2 S t r i n g ( ( PowerConsumption [ i ] ∗ D u r a t i o n [ i ] ) , number , 3 ) ;
285 frame . a d d S e n s o r (SENSOR_STR, number ) ;
286 #i f d e f _DEBUG
287 USB . p r i n t l n ( number ) ;
288 U t i l s . f l o a t 2 S t r i n g ( PowerConsumption [ i ] , number , 3 ) ;
289 USB . p r i n t l n ( number ) ;
290 U t i l s . f l o a t 2 S t r i n g ( D u r a t i o n [ i ] , number , 3 ) ;
291 USB . p r i n t l n ( number ) ;
292 #e n d i f
293
294 e n e r g y = e n e r g y + ( PowerConsumption [ i ] ∗ D u r a t i o n [ i ] ) ;
295 }
296 // ad di ng accumulated e n e r g y consumption
297 U t i l s . f l o a t 2 S t r i n g ( energy , number , 3 ) ;
298 frame . a d d S e n s o r (SENSOR_STR, number ) ;
299 #i f d e f _DEBUG
300 USB . p r i n t l n ( number ) ;
301 #e n d i f
302 }
303
304 u i n t 8 _ t hexCharToInt ( c h a r c ) {
305 switch ( c ) {
306 case ’0 ’ : return 0;
307 case ’1 ’ : return 1;
308 case ’2 ’ : return 2;
309 case ’3 ’ : return 3;
310 case ’4 ’ : return 4;
311 case ’5 ’ : return 5;
312 case ’6 ’ : return 6;
313 case ’7 ’ : return 7;
314 case ’8 ’ : return 8;
315 case ’9 ’ : return 9;
316 c a s e ’A ’ : c a s e ’ a ’ : r e t u r n 10;
317 c a s e ’B ’ : c a s e ’ b ’ : r e t u r n 11;
318 c a s e ’C ’ : c a s e ’ c ’ : r e t u r n 12;
319 c a s e ’D ’ : c a s e ’ d ’ : r e t u r n 13;
126 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

423 USB . p r i n t (F( " 3 . 2 . Get D e v i c e EUI OK. " ) ) ;


424 USB . p r i n t (F( " D e v i c e EUI : " ) ) ;
425 USB . p r i n t l n (LoRaWAN. _devEUI ) ;
426 }
427 else
428 {
429 USB . p r i n t (F( " 3 . 2 . Get D e v i c e EUI e r r o r = " ) ) ;
430 USB . p r i n t l n ( e r r o r , DEC) ;
431 }
432 #e n d i f
433
434 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
435 // 4 . S e t / Get D e v i c e Address
436 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
437
438 // S e t D e v i c e Address
439 e r r o r = LoRaWAN. s e t D e v i c e A d d r (DEVICE_ADDR) ;
440
441 #i f d e f _DEBUG
442 // Check s t a t u s
443 i f ( e r r o r == 0 )
444 {
445 USB . p r i n t l n (F( " 4 . 1 . S e t D e v i c e a d d r e s s OK" ) ) ;
446 }
447 else
448 {
449 USB . p r i n t (F( " 4 . 1 . S e t D e v i c e a d d r e s s e r r o r = " ) ) ;
450 USB . p r i n t l n ( e r r o r , DEC) ;
451 }
452 #e n d i f
453
454 // Get D e v i c e Address
455 e r r o r = LoRaWAN. g e tD e v i ce A d dr ( ) ;
456
457 #i f d e f _DEBUG
458 // Check s t a t u s
459 i f ( e r r o r == 0 )
460 {
461 USB . p r i n t (F( " 4 . 2 . Get D e v i c e a d d r e s s OK. " ) ) ;
462 USB . p r i n t (F( " D e v i c e a d d r e s s : " ) ) ;
463 USB . p r i n t l n (LoRaWAN. _devAddr ) ;
464 }
465 else
466 {
467 USB . p r i n t (F( " 4 . 2 . Get D e v i c e a d d r e s s e r r o r = " ) ) ;
468 USB . p r i n t l n ( e r r o r , DEC) ;
469 }
470 #e n d i f
471
472 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
473 // 5 . S e t Network S e s s i o n Key
474 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
E.2. SOURCE FILE 129

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

525 USB . p r i n t (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


error = " ) ) ;
526 USB . p r i n t l n ( e r r o r , DEC) ;
527 }
528 #e n d i f
529
530 // Get r e t r i e s
531 e r r o r = LoRaWAN. g e t R e t r i e s ( ) ;
532
533 #i f d e f _DEBUG
534 // Check s t a t u s
535 i f ( e r r o r == 0 )
536 {
537 USB . p r i n t (F( " 7 . 2 . Get 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. " ) ) ;
538 USB . p r i n t (F( "TX r e t r i e s : " ) ) ;
539 USB . p r i n t l n (LoRaWAN. _ r e t r i e s , DEC) ;
540 }
541 else
542 {
543 USB . p r i n t (F( " 7 . 2 . Get 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
error = " ) ) ;
544 USB . p r i n t l n ( e r r o r , DEC) ;
545 }
546 #e n d i f
547
548 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
549 // 8 . S e t a p p l i c a t i o n key
550 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
551
552 e r r o r = LoRaWAN. setAppKey (APP_KEY) ;
553
554 #i f d e f _DEBUG
555 // Check s t a t u s
556 i f ( e r r o r == 0 )
557 {
558 USB . p r i n t l n (F( " 8 . A p p l i c a t i o n key s e t OK" ) ) ;
559 }
560 else
561 {
562 USB . p r i n t (F( " 8 . A p p l i c a t i o n key s e t e r r o r = " ) ) ;
563 USB . p r i n t l n ( e r r o r , DEC) ;
564 }
565 #e n d i f
566
567 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
568 // 1 3 . S e t Adaptive Data Rate ( recommended )
569 // / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
570
571 // s e t ADR
572 e r r o r = LoRaWAN. setADR ( " on " ) ;
573
E.2. SOURCE FILE 131

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

678 USB . p r i n t l n (F( "−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−\n " ) ) ;


679 #e n d i f
680
681 e r r o r = LoRaWAN.OFF(SOCKET) ;
682
683 #i f d e f _DEBUG
684 // Check s t a t u s
685 i f ( e r r o r == 0 )
686 {
687 USB . p r i n t l n (F( " 4 . S wi tc h OFF OK" ) ) ;
688 }
689 else
690 {
691 USB . p r i n t (F( " 4 . Sw it ch OFF e r r o r = " ) ) ;
692 USB . p r i n t l n ( e r r o r , DEC) ;
693 }
694 #e n d i f
695 }

CO2SensingEnergyAware.pde

You might also like