Ruuvi Tag - Ready To Go

The Ruuvi Tag is distributed ready to transmit environment data packets periodically in either URL or

depricated as of 2.4.2 2/28/19

The (very) faint blinking of the green LED indicates URL mode while the red LED indicates raw mode.
The mode is changed by pressing the B button on the tag.

Be sure to enable Bluetooth in settings on the phone.
There are android apps that can display the data directly.

See the getting started video.

There are applications which issue a notification whenever a new beacon is detected.
Packets can be processed by a mobile phone with ruuviStation app or open beacon.
Another option is to establish a device, such as a raspberry pi, to receive the packets and run a progran to intrepret the data.

Blue tooth Low Energy Header for advertising packets

Reference:TI.com , Bluetooth.com
byte
offset
0 04 packetType
1 3E LE Meta Event Code plen 43
03 packetLength (?)
ADV_NONCONN_IND - Non connectable undirected advertising(31 bytes) (not ADV_IND(31 bytes) , ADV_DIRECT_IND, 6x ADV_SCAN_IND(31 bytes)) 23 ??
2 02 subEvent
3 01 numberOfReports
4 00 event type
6 01 peerAddressType
7..12 zz:yy:xx:ww:vv:uu 6 byte MAC LSB first
13 17
19  FEAA Complete service classes
21  
23  FEAA Complete service classes
25  10 Frame type
Max length for BLE 4.0 is 31, BLE 5.0 254.

Packet as seen by hcidump

04 3E 2B 02 01 03 01 C2 24 68 3C 10 C7 1F 02 01 06 03 03 AA 
FE 17 16 AA FE 10 F9 03 72 75 75 2E 76 69 2F 23 42 48 67 59 
41 4D 4C 73 47 B8 

High Res formats 3 and 5

It is used by:
See Tomi Tuhkanen's ruuvitag_sensor or Henrik Heikkil's ruuvi Collector .
or custom reader/interpreter and additional hardware for receiving .

The tag will indicate highres (raw) mode by faintly blinking the red LED

The data is decoded from "Manufacturer Specific Data" field, undirected, non-connectable bluetooth advertisement. More details are at Argenox .

Current sensor readings transmitted at 1 second intervals.
ruuvi's manufacturer ID is 0x0499.

Note that there are Bluetooth Generic Attributes (GATT) services specifications for services including ESP Environmental Sensing Profile, which include Humidity but those are NOT followed here.

The payload is:

Offset
intrepreted values Description
0 05 Format type code
1 – 2 -40.000 — 84.995 Temperature (16bit signed in .005 centigrade. ) -32768 aka 0x8000 Invalid / not available
Full accuracy range ±1°C: 0°C(32°F)..60°C(140°F)
operating range -40°C(-40°F)..85°C(185°F)
3 – 4 0 — 100 Humidity: 16bit unsigned; in .0025%, divide by 400 to get percent.
Example 0x9470 = 38000. /400 = 95%
(accuracy tolerance ±3% in the range for 20%-80%,
operating range -40°C(-40°F)..85°C(185°F)
download BME280 datasheet( local copy) description.
5 – 6 300 — 11,000 atmospheric pressure ( 16bit unsigned, value max 50kPa) 65535 (0xFFFF) indicates invalid or unavailable
7 – 8 -16,000 — 16,000 Acceleration-X ( 16bit signed Most Significant Byte first)
9 – 10 -16,000 — 16,000 Acceleration-Y STMicroelectronics LIS2DH12
11 – 12 -16,000 — 16,000 Acceleration-Z ( values over 16000 indicates error (implementation pending 10/04/17)
13 – 14.2
(13.14.)>>5
(13.14.)/32
1.6 — 3.646 Battery voltage above 1.6V, in millivolts, 11 bits unsigned (0-2046 )
2047 (FFEx or FFFx) indicates an invalid reading.
Examples:D4B6=3.3v(new); AC9x=2.98v; 9C4x=2.85v; 960x=2.800v ; 8FCx=2.750
Evaluate using:    echo 'ibase=16; print 640+(   9xxx   /20),"\n"' | /usr/bin/bc
Note: 1600 aka 0x640 and >>5 aka /0x20
14.3 – 14.7
byte 14 & 1F
-40 — +20 TX power above -40dBm, in 2dBm steps. 5 bits unsigned. Value of 31 (0x1F) indicates invalid value.(?)
15 0 — 254 Movement counter (8bit unsigned), incremented by motion detection interrupts from LIS2DH12 Accelerometer
Highest valid value is 254, with 255 is reserved for the "not available".

This seems too small a field since a single movement can cause manny intrrupts causing this to rollover too often.DGG

16 – 17 0 — 65,534 Measurement sequence number (16bit unsigned). 65,535 indicates not available. Each time a measurement is taken, this is incremented by one.
Used for measurement de-duplication (depending on the transmit interval, multiple packets with the same measurements can be sent, and there may be measurements that never were sent). Takes 18 hours to rollover at 1 measurment /
18 – 23 00:00:00:… –
FF:FF:FF:…
MAC aka NRF_FICR->DEVICEADDR | C0 00 00 00 00 00 always leading Cx, Dx, Ex or Fx
 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
05 12 D4 9C 40 C3 40 00 38 00 E4 03 E4 90 76 41 AD EE F7 FA 74 4A 1E 1A            B8 
f  temp  humid atmp  xxxxx yyyyy zzzzz b   t m  -seq- ---- MAC -------- 
m                                      a   X o
t                                      t   p v
                                           r # 

Offset
intrepreted
values
Description
0 03 Format type code
1 0..100 Humidity: in 0.5%, example: 0x70 is 56%. Values > 0x64 indicate error
(accuracy tolerance ±3% in the range for 20%-80%)
2 -40..85 Temperature (MSB is sign, next 7 bits are value (akward?) centigrade.
3 0..99 Temperature (fraction, 1/100.)
Values over 99 indicates error (implementation pending 10/04/17)
cannot initalize, unreadable, excessive variation from previous reading, exceeds reasonable value (see Bosch selfTest
4-5 300..11000 atmospheric pressure (Most Significant Byte first, value max 50hPa)
Values over 11000 indicates error (implementation pending 10/04/17)
cannot initalize, unreadable, excessive variation from previous reading, exceeds reasonable value
6-7 -16000..16000 Acceleration-X (Most Significant Byte first)
8-9 -16000..16000 Acceleration-Y STMicroelectronics
10-11 -16000..16000 Acceleration-Z ( values over 16000 indicates error (implementation pending 10/04/17)
12-13 1700 .. 3300 Battery voltage (millivolts)
Sample:
99 04  03 C8     15 61      C4 4C        01 1D   FF 3D   03 9D    0B A1 00 00 00
mfgr  fmt hum    temp       atmo press     X       Y       Z      battery
          200    21                                                 2.977
          100%     .97


04 3E 25 02 01 03 01 D5 37 52 68 33 F2 19 02 01 04 15 FF 99 04 03 2C 1A 08 C9 79 00 0B FF F5 03 EB 0A ED 00 00 00 00 CD
                     |------MAC------|                   |CIC|fmt|hum|temp|press |  x | y   |  z  |batt              ||RSSI

See discussion.

Temperature: -127.99°C to +127.9 °C (well over boiling!) in .01°C increments.
Value:Measurement; x0000:0°C ; x8145:-1.°C; x0145:1 °C
Atmospheric Pressure
50,000 Pa to 115,536Value Measurement: Pa in 1 Pa increments. (1003-1026 range found by scrin https://graphs.2kgwf.fi/dashboard/db/ruuvi-demo)

Value:Measurement; 0-50000 Pa; 41325:101325 Pa (average sea-level pressure) ; 65534:115534 Pa ; 65535 error to be implemented

Acceleration -32000 to 32000 (mG), 16 G max (2 G in default configuration).
Values are 2-complement int16_t, 3 channels X,Y,X
Value:Measurement; 0xFC18:-1000 mG ; 0x03E8:1000 mG ; 65535 error to be implemented
Battery voltage 1800 mV to 3300 mV in 1 mV increments, accuracy? ; 1000 error to be implemented
ToDo: "special" values to indicate error.


The Ruuvi packets are embedded within an Eddystone URL frame.
Which begin at offset 25 within the packet.

ruuvi Beacon URL Data Formats for sample Application: Environment Station

(doesn't really tell [let alone predict] weather [rain,sunlight…)

The purpose for this (and other URL formats is to provide a means for users familiar with web programming, who are not familiar with C programming and the toolchain, the abliity to process the data from the tag.

When the tag is in URL mode packets can be received by a smart phone which uses an app or widget (for example nRFconnect) or
Phy By BKON Connect to retrieve the web page which intreprets the packet and dislays the data, For example.
Swipe up and click $ . Then swipe left to Add Widgets and select nRFconnect. After a few seconds a link will be presented. Tap it to display the Temperature, Humidity and Atmospheric pressure data.

Frame Specification (summary):

byte
offset
 range of
  values
0   x10   Frame Type
1  -100..+20   TX Power Calibrated Tx power at 0 meters. This allows for estimating the distance to the tag.
 Max for nordic nRF52832 is 4
200..03
¤
Encoded Scheme Prefix
¤ codes:
00 http://www. , 01 https://www., 02 http://, 03 https://
URL (17 bytes)
3..ia-z and - Domain Name (case insensitive, ie translated to lower) (Choose the shortest possible since the total length is restriceted)
i+1..j
or
.c…
Top Level Domain
codes:
00 .com  01.org   02.edu   03 .net  04 .info  05 .biz  06 .gov 
07 .com/ 08 .org/ 09 .edu/ 0a .net/ 0b .info/ 0c .biz/ 0d .gov/

     or
a..zz text characters to specify other (case insensitive) TLD, for example .fi,.us,.edu,.vi,.io,.tv,.news …  
j+1..20c…Beacon Data Characters (Application dependent)

The web server address is nearly minimal ¤ruu.vi/ Where the ¤ is the protocol code x'03' for https://

This allows only 10 characters for the beacon data which must be printable and cannot contain most special characters. (an address of the form XYZ.com/ or XYZ.info/ would allow 12 characters since a code could be used for the TLD and slash).

The beacon data is encoded using a base 64 scheme* This causes 3 bytes to expand to 4 characters; 6 bytes expands to 8 characters. When viewing the packet with a diagnostic tool or the URL in the address bar of a browser it is this string of characters which is visible.

Some URL formats are prefixed with the fragment identifier introducer (#) allowing only 9 actual beacon data characters. The # appears to immediately follow the / from the web page viewpoint. For example: ruu.vi/#BnALAMNQr
This allows the default web page, index.html, to provide the decoding algorithim and page formatting.
The data from the beacon is specified as the fragment identifier. Since the fragment is NOT transmitted, the web site cannot process any information other than the time and IP address. Fomat 8 addresses that.

Format type codes:

#0 unused as of the date of this document
#1 Historical deprecated
#2 Eddystone-URL, URL-safe base64 -encoded, kickstarter edition (no battery voltage)
#3 unused as of the date of this document ( not highres )
#4 Eddystone-URL with tag ID. , URL-safe base64 -encoded,
#5 and greater are unused …

URL Formats that do not include the fragment (#) identifier introducer allow for 11 beacon data characters or 8 binary data bytes.
This means that the web page must be the 404 error handler since the data from the beacon will not specify an existing page.

3 High res (aka raw) format
4 unused
5 x05 raw v2
6-15 06-0Freserved ?
16-239 10-F0reserved bi directional?
240-255 F0-FFcustom appliations
alternate assignments
Allocating as many as 7 bits of FIRST byte for data
format
code
unallocated
possible additional data bits
8-11 08 URL V2
12 0C   possible use as one format
using B[0].67 as data
13 0D  
14 0E  
15 0F  
16-28 10-1C b[0].4567  
32-59 20-3C b[0].34567 
64-123 40-7C b[0].234567 
128-251 80-FC b[0].1234567 
Errors are indicated by "special" values: initialization failure, value xxx exceeds limit

As there are a limited number of format types available without sacrificing bits for data, a change in format type is only necessary when the format is incompatible.
For example using previously unused bits will not be reason to change the format type code. This means that if a field has a range of 0-124, is right justified in a byte and is in a field documented to be 7 bits wide do not assume that the high order bit will be zero.

The decoded, binary array is referred to as b[i] and the bit numbers are shown as .ijk
For example, a reference to the first byte, the low order bit is: b[0].7 aka b'0000 0001'.

URL Format 8 if ( b[0] & 0xF8 == 08 ) uses ruu.vi/404_index.html to intrepret and display

bits usedvalue intrepretation
b[0].0123 0 reserved for future use of format type
b[0].4 1 format type code ( b[0] & 0xF8 == 08 )
b[0].5 0 reserved for future use of format type
b[0].67 0..3Battery status        Renata Battery Designer's Guide
batteryStat=b[0] & 03
0 OK2.50V < vbat
1 notice                                   2.30 <vbat <2.49                Sensor update and transmission frequency reduced
No time known as any counter would over flow.
b[6] hours since notice level crossed (movement data no longer sent)
2 critical            2.25< vbat < 2.29 Frequency of activity reduced further.
b[5] hours since critical level crossed (movement and atmospheric pressure data longer sent)
3 emergency


expect 100 hours from
emergency to power fail at 2.00V

vbat < 2.24 (low or cannot read battery sensor)
Frequency of activity reduced further.
No sensors polled. Attempt to keep transmitting as long as possible.
b[3] Hours since critical level crossed (movement and atmospheric pressure and humidity data longer sent
b[1..2] 0000-FFFF ID of TAG taken from of nRF52832 . DEVICEADDR[0] aka MAC low order 16 bits
b[3].01 0..3 change in temperature since 1 hour ago, 1:= was less then now, 2:= was greater, 0:= no change, 3:= sensor had an error within the last hour
b[3].234567 0..63 Humidity
1 = 2% As environment station humidity with more precision is not meaningful
In addition the bosch sensor accuracy is only ±3% from 20% to 80% and ± otherwise humidity= ( b[1] & 0x3F ) *2
Errors :
59 basic model ruuvi has no humidity sensor
60 sensor could not be read
62 value greater than maximun expected
63 sensor could not be initialized
Users who need humidity more precision undoubtedly use format 3).
b[4].0 0..1 WDOG timer expired within the last 4 hours(?)
b[4].1234567 0..125 Temperature °C
Biased at -30. Range -30..85°C ( span 115 ) aka: ( -22..183 °F )
degc = ( b[4] & 0x7F) -30
Errors:
124 sensor could not be read
125 value less than minimun expected
126 value greater than maximun expected
127 temperature sensor failed to initialize
(Users who need more precise temperature undoubtedly use format 3.
b[5].012345 0..63 atmospheric pressure in pa
biased at 950 (58*2=116) max 1066
pa = ( ( b[5] >> 2 ) * 2) + 950
errors
59 basic model ruuvi has no pressure sensor
60 value greater than maximun expected
61 value less than minimun expected
62 sensor could not be read
63 error sensor failed to initialize
(Users who need larger range undoubtedly eeed … )
understanding Air Pressure
b[5].67 0..3 Change in pressure since 4 hours ago
0  no change
1  pressure was less then it is now
2  pressure was greater
3  pressure sensor had an error then
6 binary bytes encodes to 8 characters
b[6].01 0..3Vibration X:amplitude: 0: < 2mm ; 1: > 2mm ; 3: error
b[6].23 0..3Vibration Y:amplitude
b[6].45 0..3Vibration Z:amplitude
b[6].6 0..1 Tag has been moved within the last 4 hours (?)
b[6].7 0..1
b[6]
alternate
0..255 Encodes to 9th & into 10th characters

firmware version, hardware version(_)
clicks i.e. sample number or
dateTime in xxx format

end of 9thcharacter
b[7].4..7 unusable Would encode into 11th character
which is too big with domain ruu.vi
b[7]4..50..3X frequency: 0 less than 5Hertz ; 1: 6-20Hz ; 2:21-100Hz; 3:error
b[7]6..70..3Y frequency: 0 less than 5Hertz ; 1: 6-20Hz ; 2:21-100Hz; 3:error
b[8]0..10..3Z frequency: 0 less than 5Hertz ; 1: 6-20Hz ; 2:21-100Hz; 3:error
b[8]2..7  
end of 11thcharacter exceeds maximun with ruu.vi/

Example

08iiii 
0000 10.00
C8OZAB4AA.com 

base64 encoding: 0123456789012345678921234567893123456789412345678951234567896123 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_


4/17/17
Format 04
Uses https://ruu.vi/index.html web page to intrepret and display.
Offset
from '#'
Same as format #2 with the addition of the trailing ID byte (x8) taken from the first byte of DEVICEID
6 0 — 255 ID of tag
                                # B  n  A  L  A  M  N  Q  N 
                                 ft x1 x2 x3 x4 x5 x6 x7 x8 
ruu.vi/#BnALAMNQN, ruu.vi/#BGAGAMNQr
Format 02
Uses https://ruu.vi/index.html web page to intrepret and display.
Offset
from '#'
intrepreted
values
Description
02 format: current sensor readings for URL
10 — 100 Humidity (in ½% units, for example: 128 is 64%) (unsigned!)
2-40 — 85 Temperature (MSB is sign, next 7 bits are decimal value) signed
30 Temperature Fraction, 1/100.). Set to ZERO because nearby causes notification on slight changes.
4-5 300 — 1100 Pressure (Most Significant Byte first, Rounded to 1 hPa precision
Example
 
  1  2  3   4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19
 10 EE 03   72 75 75 2E 76 69 2f 23 41 6e 41 4c 41 4d 4e 51     from nRF connect  service data
        |    r  u  u  .  v  i  /  #  A  n  A  L  A  M  N  Q
        ¤---https://                 ft x1 x2 x3 x4 x5 x6 x7
                                    represents  11°C   56%  1000hpa
As seen from
hcidump --raw 
> 04 3E 2B 02 01 03 01 0F EC 72 78 51 D3 1F 02 01 06 03 03 AA 
                       |------MAC------| 

  FE 17 16 AA FE 10 F9 03 72 75 75 2E 76 69 2F 23 42 4A 41 4B 
                       ¤  r  u  u  .  v  i  /  #  B           

  41 4C 79 73 72 B9                                             
URL defined: scheme://[user[:pass]@]host ? #fragment

Hardware B6

Hardware B3 with addition notes

The System On a Chip used in the ruuvi nRF52832

This document adapted from: github.com/ruuvi/ruuvi-sensor-protocols

https://github.com/google/eddystone/blob/master/eddystone-url/docs/config-service-spec.md

Additional links for information:
ruuvi.slack
ruuvi forum

Apps for IOS

From the AppStore For example: NordicSemi

Maximu BLE packet length was revised with version4.2 to be 251

download Bluetooth.org core specs (26MB)

Regarding humidity and dew point

And then there's NFC python lib used to interact with the ruuvi.

Nearby Notification policy

version 09/18/19 DGG