You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
9.1 KiB
280 lines
9.1 KiB
= Sensor node/mote
|
|
Apostolos rootApostolos@swarmlab.io
|
|
// Metadata:
|
|
:description: IoT Διαδίκτυο των Αντικειμένων
|
|
:keywords: iot, imu, AHRS
|
|
:data-uri:
|
|
:toc: right
|
|
:toc-title: Πίνακας περιεχομένων
|
|
:toclevels: 4
|
|
:source-highlighter: highlight
|
|
:icons: font
|
|
:sectnums:
|
|
|
|
include::header.adoc[]
|
|
|
|
|
|
{empty} +
|
|
|
|
== Sensor node
|
|
|
|
A **sensor node**, also known as a **mote**, is a node in a sensor network that is capable of performing some processing, gathering sensory information and communicating with other connected nodes in the network.
|
|
|
|
[NOTE]
|
|
====
|
|
A mote is a node but a node is not always a mote
|
|
====
|
|
|
|
.The typical architecture of the sensor node
|
|
image:./sensorNode.jpg[alt="The typical architecture of the sensor node"]
|
|
|
|
The main components of a sensor node are a **microcontroller**, **transceiver/Communication Module**, **memory**, **power source** and one or more **sensors.**
|
|
|
|
== Sensor node example using IMU sensors
|
|
|
|
A basic IMU (Intertial Measurement Unit) generally provides raw sensor data, whereas an AHRS takes this data one step further, converting it into heading or direction in degrees, converting the raw altitude data into standard units like feet or meters, etc.
|
|
|
|
.AHRS (Attitude and Heading Reference System)
|
|
[NOTE]
|
|
====
|
|
An attitude and heading reference system (AHRS) consists of sensors on three axes that provide attitude information for aircraft, including roll, pitch and yaw. These are sometimes referred to as MARG (Magnetic, Angular Rate, and Gravity) sensors and consist of either solid-state or microelectromechanical systems (MEMS) gyroscopes, accelerometers and magnetometers. They are designed to replace traditional mechanical gyroscopic flight instruments.
|
|
[More Info]https://en.wikipedia.org/wiki/Attitude_and_heading_reference_system[^]
|
|
====
|
|
|
|
=== IMU
|
|
|
|
image:./sensors_1604_LRG.jpg[alt="Adafruit 10-DOF IMU Breakout"]
|
|
|
|
Adafruit's 10DOF https://en.wikipedia.org/wiki/Degrees_of_freedom[(10 Degrees of Freedom)] breakout board allows you to capture ten distinct types of motion or orientation related data.
|
|
|
|
|
|
- LSM303DLHC - a 3-axis accelerometer (up to +/-16g) and a 3-axis magnetometer (up to +/-8.1 gauss) on a single die
|
|
- L3GD20 - a 3-axis gyroscope (up to +/-2000 dps)
|
|
- BMP180 - A barometric pressure sensor (300..1100 hPa) that can be used to calculate altitude, with an additional on-board temperature sensor
|
|
|
|
=== Connecting It Up
|
|
|
|
Basic Setup
|
|
|
|
- Connect the **SCL** pin on the breakout to the **SCL** pin on your Arduino. On an UNO & '328 based Arduino, this is also known as **A5**
|
|
- Connect the **SDA** pin on the breakout to the **SDA** pin on your Arduino. On an UNO & '328 based Arduino, this is also known as **A4**
|
|
- Connect the **VIN** pin on the breakout to **3.3V** or **5V** on your Uno (5V is preferred but if you have a 3V logic Arduino 3V is best)
|
|
- Connect the **GND** pin on the breakout to the **GND** pin on your Uno
|
|
|
|
That's it! With those four wires, you should be able to talk to any of the I2C chips on the board and run any of the example sketches.
|
|
|
|
|
|
image:./sensors_10dofwire.jpg[alt="Connecting"]
|
|
|
|
Advanced Setup
|
|
|
|
- **GINT** - The interrupt pin on the L3GD20 gyroscope
|
|
- **GRDY** - The 'ready' pin on the L3GD20 gyroscope
|
|
- **LIN1** - Interrupt pin 1 on the LSM303DLHC
|
|
- **LIN2** - Interrupt pin 2 on the LSM303DLHC
|
|
- **LRDY** - The ready pin on the LSM303DLHC
|
|
|
|
These pins are all outputs from the 10-DOF breakout and are all 3.3V logic
|
|
|
|
|
|
=== Downloading Libraries
|
|
|
|
Place the files in the Arduino Sketch Folder '/libraries' sub-folder. You should end up with a structure like this:
|
|
|
|
- arduinosketches/libraries/Adafruit_10DOF
|
|
- arduinosketches/libraries/Adafruit_BMP085
|
|
- arduinosketches/libraries/Adafruit_L3GD20_U
|
|
- arduinosketches/libraries/Adafruit_LSM303DLHC
|
|
- arduinosketches/libraries/Adafruit_Sensor
|
|
|
|
.Arduino libraries
|
|
[NOTE]
|
|
====
|
|
Arduino libraries are a convenient way to share code such as device drivers or commonly used utility functions.
|
|
https://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use[How to install Arduino libraries]
|
|
====
|
|
|
|
=== Example Sketch
|
|
|
|
==== pitch & roll
|
|
|
|
|
|
.sketch pitchrollheading
|
|
[source,c]
|
|
----
|
|
sensors_event_t accel_event;
|
|
sensors_vec_t orientation;
|
|
|
|
/* Calculate pitch and roll from the raw accelerometer data */
|
|
accel.getEvent(&accel_event);
|
|
if (dof.accelGetOrientation(&accel_event, &orientation))
|
|
{
|
|
/* 'orientation' should have valid .roll and .pitch fields */
|
|
Serial.print(F("Roll: "));
|
|
Serial.print(orientation.roll);
|
|
Serial.print(F("; "));
|
|
Serial.print(F("Pitch: "));
|
|
Serial.print(orientation.pitch);
|
|
Serial.print(F("; "));
|
|
}
|
|
----
|
|
|
|
|
|
image:./800px-Flight_dynamics_with_text.png[alt="pitchroll"]
|
|
|
|
Arguments
|
|
|
|
- event: The **sensors_event_t** variable containing the data from the **accelerometer**
|
|
- orientation: The **sensors_vec_t** object that will have its **.pitch** and **.roll** fields populated
|
|
|
|
Returns
|
|
|
|
- **true** if the operation was successful,
|
|
- **false** if there was an error
|
|
|
|
|
|
image:./piandrroll.png[alt="pitchroll"]
|
|
|
|
|
|
|
|
|
|
== A real AHRS system
|
|
|
|
|
|
=== Loading the AHRS Sketch
|
|
|
|
.AHRS Sketch
|
|
[source,c]
|
|
----
|
|
#include <Wire.h>
|
|
#include <Adafruit_Sensor.h>
|
|
#include <Adafruit_LSM303_U.h>
|
|
#include <Adafruit_BMP085_U.h>
|
|
#include <Adafruit_Simple_AHRS.h>
|
|
|
|
// Create sensor instances.
|
|
Adafruit_LSM303_Accel_Unified accel(30301);
|
|
Adafruit_LSM303_Mag_Unified mag(30302);
|
|
Adafruit_BMP085_Unified bmp(18001);
|
|
|
|
// Create simple AHRS algorithm using the above sensors.
|
|
Adafruit_Simple_AHRS ahrs(&accel, &mag);
|
|
|
|
// Update this with the correct SLP for accurate altitude measurements
|
|
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
|
|
|
|
void setup()
|
|
{
|
|
Serial.begin(115200);
|
|
Serial.println(F("Adafruit 10 DOF Board AHRS Example")); Serial.println("");
|
|
|
|
// Initialize the sensors.
|
|
accel.begin();
|
|
mag.begin();
|
|
bmp.begin();
|
|
}
|
|
|
|
void loop(void)
|
|
{
|
|
sensors_vec_t orientation;
|
|
|
|
// Use the simple AHRS function to get the current orientation.
|
|
if (ahrs.getOrientation(&orientation))
|
|
{
|
|
/* 'orientation' should have valid .roll and .pitch fields */
|
|
Serial.print(F("Orientation: "));
|
|
Serial.print(orientation.roll);
|
|
Serial.print(F(" "));
|
|
Serial.print(orientation.pitch);
|
|
Serial.print(F(" "));
|
|
Serial.print(orientation.heading);
|
|
Serial.println(F(""));
|
|
}
|
|
|
|
// Calculate the altitude using the barometric pressure sensor
|
|
sensors_event_t bmp_event;
|
|
bmp.getEvent(&bmp_event);
|
|
if (bmp_event.pressure)
|
|
{
|
|
/* Get ambient temperature in C */
|
|
float temperature;
|
|
bmp.getTemperature(&temperature);
|
|
/* Convert atmospheric pressure, SLP and temp to altitude */
|
|
Serial.print(F("Alt: "));
|
|
Serial.print(bmp.pressureToAltitude(seaLevelPressure,
|
|
bmp_event.pressure,
|
|
temperature));
|
|
Serial.println(F(""));
|
|
/* Display the temperature */
|
|
Serial.print(F("Temp: "));
|
|
Serial.print(temperature);
|
|
Serial.println(F(""));
|
|
}
|
|
|
|
delay(500);
|
|
}
|
|
----
|
|
|
|
=== compile
|
|
|
|
- Compile the sketch,
|
|
- open up the Serial Monitor (Tools > Serial Monitor),
|
|
- set the baud rate to 115200
|
|
|
|
|
|
.output
|
|
image:./sensors_01_AHRSOutput.png[alt="AHRS raw data"]
|
|
|
|
This raw data shows the main orientation data, consisting of 'roll', 'pitch' and 'heading' (or 'yaw) in degrees, followed by the current altitude and temperature
|
|
|
|
The AHRS sketchs reads raw data from the board's accelerometer/magnetometer and converts the raw data into easy to understand **Euler angles.**
|
|
|
|
In this case, we can see that the **roll is about 18°**, the **pitch is about 78°** and the **heading or yaw is about 32°**, and the sketch will keep updating itself with the latest values at whatever speed we've set in the sketch.
|
|
|
|
[NOTE]
|
|
====
|
|
.Euler angles, one of the possible ways to describe an orientation
|
|
image:./Eulerangles.svg.png[alt="Euler angles"]
|
|
|
|
The first attempt to represent an orientation is attributed to Leonhard Euler. He imagined three reference frames that could rotate one around the other, and realized that by starting with a fixed reference frame and performing three rotations, he could get any other reference frame in the space (using two rotations to fix the vertical axis and other to fix the other two axes). The values of these three rotations are called Euler angles.
|
|
|
|
.Tait–Bryan angles, another way to describe orientation
|
|
image:./Taitbrianzyx.svg.png[alt="Tait–Bryan angles"]
|
|
|
|
These are three angles, also known as yaw, pitch and roll, Navigation angles and Cardan angles. Mathematically they constitute a set of six possibilities inside the twelve possible sets of Euler angles, the ordering being the one best used for describing the orientation of a vehicle such as an airplane. In aerospace engineering they are usually referred to as Euler angles.
|
|
|
|
https://en.wikipedia.org/wiki/Rigid_body_dynamics[More Info: Rigid_body_dynamics]
|
|
|
|
https://en.wikipedia.org/wiki/Euler_angles[More Info: Eulers angles]
|
|
|
|
https://en.wikipedia.org/wiki/Leonhard_Euler[Leonhard Euler]
|
|
====
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:hardbreaks:
|
|
|
|
{empty} +
|
|
{empty} +
|
|
{empty}
|
|
|
|
:!hardbreaks:
|
|
|
|
'''
|
|
|
|
.Reminder
|
|
[NOTE]
|
|
====
|
|
:hardbreaks:
|
|
Caminante, no hay camino,
|
|
se hace camino al andar.
|
|
|
|
Wanderer, there is no path,
|
|
the path is made by walking.
|
|
|
|
*Antonio Machado* Campos de Castilla
|
|
====
|
|
|