I welcome you to this part of my review about Arduino Nano 33 BLE Sense. My review is split into multiple blog posts. You can find all my thoughts about this Arduino and related parts in chapters with name beginning with "Review" like this one. There are also articles describing test projects which I have done for gathering experiences with board and some tutorials. Main page of review contains summary and final score. Following Table of Contents contains links to other parts of my roadtest review.
Table of Contents
- Review of Development Board
- Review of Onboard Sensors (this article)
- Review of Microcontroller and BLE Module
- Review of Software
- Review of Documentation
- Tutorial 01: Accessing Sensor Values
- Tutorial 02: nRF52840 Application without Arduino IDE
Review of Onboard Sensors
This chapter of my review targets all sensors which are present on tested board. Except PDM microphone all sensors are connected to MCU using I2C bus and all of them follows standard protocol for writing and reading internal sensor registers. This chapter describes details about sensors. Most information presented there you will probably never need because basic usage of sensors is implemented in libraries and you do not need to worry about implementation details. But article may contain some interesting details about sensors and their features which you can utilize with some amount of work. In this article I won’t describe libraries much. Details about libraries you can find in chapter Review of Software.
Temperature and Humidity Sensor
It is very small sensor for measuring temperature and humidity with very low power consumption. Temperature tolerance is +- 0.5°C between 15 to 40 °C and +- 1°C between 0 to 60°C. Tolerance is not the best one on the market. Humidity tolerance is +- 3.5% between 20 to 80% and +-5% between 0 to 100%. Both temperature and humidity have 16-bit signed output. You can get up to 12.5 samples per second (80ms sampling period). Device supports averaging measured samples on background. Device supports power down mode for lower power consumption when you do not need to use them. There is integrated heater which can enable and disable by firmware. Sensor outputs signal about availability of measured sample but roadtested Arduino has not connected this signal to MCU.
Sensor has user friendly interface with standard I2C protocol for reading and writing registers. Protocol supports burst reads and writes. You can choose if you want to read single register multiple times or increment address after every reading by setting most significant bit in register address. There are also implemented auto overflow in one bank of registers. When you read status and data registers, then you read status register again. Finally there are support for preventing update of data registers when you are reading them, so when you enable this, you are sure that MSB and LSB comes from the same sample and you do not need worry about state that you read LSB from previous sample and MSB from next. Remember to enable this feature when you are using continuous mode of sensor.
Sensor also supports SPI with standard protocol used. As expected, this cannot be utilized on Arduino because bus is shared with other I2C sensors and CS signal is not exposed to MCU. Features that apply to I2C mentioned above also apply to SPI.
Sensor has no unique ID which many competitors have. In comparison with other sensors on board this sensor has no alarm feature which triggers interrupt when value goes below or above configured threshold.
Sensor do not apply calibration values itself, but you must do calculation yourself. Calibration coefficients are stored in registers. Converting measured data to final value is easy. You need to know only basics of secondary school math to calculate final temperature and humidity. Calibration data are provided as two reference temperatures (and humidities) and value which is outputted by sensor at this reference temperature and humidity. You can resolve step and offset by solving linear equation and then you get linear functions for getting temperature and humidity from measured data. Sensor on my board came with calibration done at 19.625 °C and 33.375 °C. Humidity was measured at 19.625 °C and two measurements were done. One with humidity 32.5 % and second reading at humidity level 69.5 %.
While sensor should have calibrated temperature, measurements were very inaccurate in my case. In my room with temperature about 22 °C I got results between 28 – 34 °C. I tried to investigate it furthermore and I noticed that calibration data contains value 0xFFFF as reference value measured at 19.625 °C. 0xFFFF is -1 in 2nd complement, so it can be valid value. I am not sure if it really is valid calibration value -1 or it means that correct value was not programmed because 0xFFFF is default value of unprogrammed flash cell. As experiment I tried to measure temperature below 19.625 °C. Due to liner function behaviour, at lower temperatures than this reference point I must get lower value from sensor. This beans that below 19.625 °C I must get raw value from sensor lower than -1 which should be returned by sensor at 19.625 °C. For test I used other three temperature sensors. One of them was and two were Dallas (now Maxim) DS18B20. I also tried read temperature from integrated temperature sensor present in LPS22 and LSM9DS1 sensors which are also available on this Arduino Nano 33 BLE Sense. These integrated temperature sensors in humidity and IMU are normally used for internal compensation and has low accuracy. I used all of them for reference, has accuracy about 0.3 °C between 10 – 25 °C and DS18B20 has accuracy 0.5 °C between 10 – 25 °C. Integrated temperature sensor in pressure sensor has mentioned accuracy 1.5 °C. Integrated temperature sensor in LSM9DS1 has no mentioned accuracy in datasheet but expect accuracy similar to other embedded temperature sensors used for compensations. Please note that my and one DS18B20 were bought in China stores so there is no guaranty about genuine of devices. Second DS18B20 come from local Czech shop and I have no idea about their supplier.
I placed device outside and printed temperatures from all sensors. On the following picture first two columns are values from DS18B20 sensors, third column shows values from sensor, forth and fifth columns show values from integrated temperature sensors in pressure sensor and IMU which are pretty inaccurate and sixth column show value from reviewed sensor. Value is calculated based on calibration data from sensor (I think they are invalid) and in brackets there are RAW value retrieved from sensor.
After first look, we can see that values from LPS22 are completely wrong. Sensor was placed in environment with temperature about 5 – 10 °C. Sensor still reports temperature about 20 °C which is nonsense, but temperature went down over time and it may be caused by long inertia. So just ignore this column. In picture I marked red line a point when temperature from HTS21 sensor went below -1 which should happen at 19.625 °C according to calibration data. But you can see that real temperature were about 7.47 °C (accurate value from ) – 13.44 °C (inaccurate value from LSM9DS1 IMU). From this experiment I think that my sensor was really improperly calibrated at factory and calibration value 0xFFFF means non-programmed calibration value rather than -1 because sensor returns -1 at temperature about 10 °C and not a 19.625 °C. I expect that this is issue only with my sensor and you receive sensor (or Arduino with this sensor) which will be properly calibrated.
To summary: you can find many other more accurate sensors with even lower consumption and more features. My onboard sensor also came with invalid calibration data.
LSP22 Pressure sensor
LPS22 sensors is very similar to mentioned above. Sensor is packed in similar small package. Interface and mode of operation is also very similar. In opposition to sensor applies all calibration coefficients itself and you can read just final absolute value (because it is float, you must integer divide by 4096). Accuracy is +- 1 hPa with no further calibration after soldering. I did not find any information about advanced calibration in Arduino factory. With calibration after soldering you can get accuracy +- 0.1 hPa. Sensor can provide samples at maximum rate of 75 Hz. Similarly, to it can generate interrupt on data ready, but this signal is not connected on Arduino 33 Nano BLE Sense. Except data ready, it can trigger interrupt when measured values differs from configured refence more or less than specified tolerance and finally, it can generate interrupt when specified number of samples are available in FIFO. Sensor has integrated FIFO so you do not need process samples quickly and you can process them in batches.
Communication protocol based on I2C is simple and like but there are small differences. Burst mode is not configured by highest bit in register address but it is configurable in register. There are also support for SPI with combined MISO/MOSI wire which is not present in .
FIFO supports multiple modes. Modes mainly differs in behaviour happening after overrun occur. Some mode stop sampling, some mode overwrites oldest data. They are also modes which changes behaviour depending on interrupt status. They probably target interrupt that some configurable number of samples is available in FIFO. FIFO can generate interrupt when configured number of samples are available and it can also notify overrun. I have limited ideas how to use some advanced FIFO modes, but I think they are sufficient for almost any application.
Sensor supports configuring reference pressure and compares it to captured samples and configured tolerance. If real pressure goes above or below threshold it can generate interrupt. You can specify reference value manually or it can be loaded to register from next sample.
As part of sensor there are also temperature sensor. Temperature sensing is probably internally used for compensation, but you can read temperature from this sensor. Specified accuracy is +-1.5 °C and there no possibility for further calibration of this temperature sensor.
I have limited opportunity to test this sensor. It reports pressure like expected pressure in my area and it looks correct. Temperature returned by internal temperature sensor is very inaccurate, so use this sensor only for pressure measurements.
Proximity, Ambient Light, RGB Colour and Gesture Sensor
is optical sensor which can sense multiple ambient lights and proximity. Ambient light sensors (ALS) for multiple colours can be used for determining RGB colour of object paced in front of sensor. Sensor has a unit which can detect gestures based on data from ambient light sensors. Gesture detection works in a way that sensor monitors drop or growth of ambient lights on sensors and from offsets determine direction of gesture. If you move hand from left to right, ambient light on left sensor drops just before it drops on right sensor. Charts how does it works are specified in datasheet, but you do not worry about it much in case of this sensor.
Sensor has 4 photodiodes to sense ambient light. Except RGB ambient light channels there is C channel for any colour. Channels can be disabled, and gain can be configured to fill gap caused by less light received due to disabling one (or more) channels.
Sensor does not detect values at once, but it internally switches between modes. You can set sensor to sleep mode for lowering power consumption. You can also configure sensor to going sleep automatically after next conversion.
You can configure thresholds for proximity and sensor can trigger interrupt when proximity goes below or above configured thresholds (this sensor has connected interrupt signal to MCU on Arduino Nano 33 BLE Sense, so you can utilize this feature). You can configure duration of signal that is connected to IR led for modifying behaviour of proximity detection.
Ambient light sensing also supports generating interrupt on value below or above configured thresholds. You can tweak sensing by configuring gain, wait time and integration time.
Gesture engine is also configurable. You can configure some gains, wait times, and some proximity detection parameters. Gesture engine supports FIFO. Gestures need to be processed in MCU based on data from FIFO.
I tried sensor and all sensing works. There are also one project present as part of this review which utilize this sensor. Proximity detection is very non-liner but for normal detection of near or far object it is sufficient. Gesture sensing works very reliable. 3 years ago, I tried to implement gesture sensing using two VL6180x sensors from ST manually and performance was much worse, mainly due to low output rate and need for advanced manual processing of sensor data. So, I am very satisfied with .
LSM9DS1 Accelerometer, Gyroscope and Magnetometer
This sensor contains digital gyroscope and accelerometer. This unit also has magnetometer. On the market there are usually sensor with gyroscope, accelerometer, and no magnetometer. This sensor has magnetometer. Internally magnetometer is additional sensor and has own logic and I2C address. There are also two CS signals for SPI bus. Sensor has also integrated temperature sensor which is probably used for compensations.
Accelerometer and gyroscope can provide data at maximum rate 952 Hz and 119 Hz in low power mode. You can disable gyroscope. While it is not properly documented, it looks that there are feature for detecting inactivity using accelerometer and automatically disable gyroscope when there are no movement detected for lowering consumption. Sensors supports multiple FIFO related interrupts, data availability related interrupts and threshold checks interrupts. You can configure automatic negating of measured values in case when you placed your sensor rotated or on other side of board to get user-friendly values.
Magnetometer can provide samples at maximum rate 80 Hz, has no FIFO, has own interrupt signal, supports low power mode, support configurable endianness of data, supports threshold checking for all three directions, and supports checking for value overflow.
I2C interface for both part of sensor is similar and follows commonly used concepts. Burst reads are supported and there auto overflow when reading samples from FIFO. Enabling or disabling bursts is done by configuring most significant bit of address similarly to sensor. FIFO is like FIFO described in LSP22 part of this article.
To summarize: Sensor contains all what you need and expects from this kind of sensors.
It is standard Microphone with PDM output. PDM is basic interface which requires only clock (clock frequency is significantly higher than audio frequency, it is about 3 MHz) and then microphone outputs sound signal encoded using PDM coding. PDM microphone supports Left/Right signal similarly to any other PDM microphone. If L/R is connected to high, valid data can be read when clock is high and vice versa. This concept enable outputs stereo audio on single data wire and single clock. Arduino contains only one microphone (placing two microphones does not makes sense due to board size).
I tested microphone and it provides valid sound signal. Volume is very low but MCU supports some configurable gain, so it can be easily tweaked and then sound received from sensor is quite good. You can consider quality of microphone like standard notebook microphone. Microphone quality is good enough to do voice recognition apps.
Arduino Nano 33 BLE Sense has 5 very interesting sensors. They can be classified as low-end (HTS221), mid-end (LSP22, MP34DT06J) and high-end (APDS-9960, LSM9DS1). All of them are good. Except issue with temperature sensor calibration data they work correctly and can be used as expected. You can write lot of interesting applications with these sensors.