Skip to content

Combo Sensor TinyShield Tutorial

Looking to add a variety of sensors to your next project? The Combo Sensor TinyShield combines the functionalities of the 9-Axis, Temperature/Humidity, Barometric Pressure, and Ambient Light TinyShields all into one board!

This tutorial teaches the basics of using this TinyShield for various applications.

To learn more about the TinyDuino Platform, click here


Description

This TinyShield features four of our popular TinyShield Sensors on a single board!

9-Axis IMU: This sensor lets you measure 9 degrees of freedom (9DOF) with your TinyDuino and features the ST LSM9DS1 - a system-in-package featuring a 3D digital linear acceleration sensor, a 3D digital angular rate sensor, and a 3D digital magnetic sensor.

Temperature/Humidity: This sensor lets you measure temperature and humidity with the TinyDuino. Based around the Silicon Labs Si7020-A10 sensor, this allows for accurate temperature measurement (±0.4C) and precision relative humidity readings.

Barometric Pressure: This sensor allows you to measure barometric pressure (and determine altitude) and temperature with your TinyDuino using the Bosch BMP280 sensor.

Ambient Light: This sensor features a TAOS TSL2572 Ambient Light Sensor, that approximates human eye response to light intensity under a variety of lighting conditions and through a variety of attenuation materials.

To see what other TinyShields are compatible with this TinyShield, see the TinyShield Compatibility Matrix

Technical Details ST LSM9DS1 9-Axis DOF Specs
  • 3 acceleration channels, 3 angular rate channels, 3 magnetic field channels
  • ±2/±4/±8/±16 g linear acceleration full scale
  • ±4/±8/±12/±16 gauss magnetic full scale
  • ±245/±500/±2000 dps angular rate full scale
  • 6-bit data output
  • “Always-on” eco power mode down to 1.9 mA
  • Embedded temperature sensor
  • Embedded FIFO
  • Position and motion detection functions
  • Click/double-click recognition
Si7020-A10 Specs
  • Precision Relative Humidity Sensor
    • ±4% RH, 0-80% RH
    • 0 - 100% RH operating range
  • High Accuracy Temperature Sensor
    • ±0.4C, -10 to +85C
  • Factory Calibrated
  • Integrated on-chip heater
  • Excellent long term stability
Bosch BMP280 Barometric Pressure Sensor Specs
  • Pressure Range: 300 -> 1100 hPa (equiv to +9000 to -500m above/below sea level)
  • Relative Accuracy: ±0.12 hPa, equiv to ±1m
  • Absolute Accuracy: ±1 hPa
  • Absolute Accuracy Temperature: ±1.0C
TAOS TSL2572 Ambient Light Sensor Specs
  • Approximates Human Eye Response
  • 45,000,000:1 Dynamic Range
  • Operation to 60,000 lux in Sunlight
  • Package UV Rejection Filter
  • Wide Magnetic Field Range (±8 Oe)
  • Low Power – Active: 200uA, Wait: 90uA, Sleep: 2.2uA
TinyDuino Power Requirements
  • Voltage: 3.0V - 5.5V
  • Current: 5.1mA (Normal Mode). Due to the low current, this board can be run using the TinyDuino coin cell option.
Pins Used
  • A5/SCL - I2C Serial Clock line
  • A4/SDA - I2C Serial Data line
Dimensions
  • 20mm x 20mm (.787 inches x .787 inches)
  • Max Height (from lower bottom TinyShield Connector to upper top TinyShield Connector): 5.11mm (0.201 inches)
  • Weight: 1 gram (.04 ounces)

Notes

  • You can also use this shield without the TinyDuino – there are 0.1″ spaced connections for power, ground, and the two I2C signals along the side of the TinyShield to allow you to connect a different system.
  • This TinyShield uses I2C communication and incorporates level shifters and a local power supply to ensure proper and safe operation over the entire TinyDuino operating voltage range up to 5V.
  • Warning: Revision 4 boards have a mistake on the silkscreen, the pin marked VCC is actually SCL, the pin marked SCL is actually SDA, and the pin marked SDA is actually VCC. If you connect this up the way it is marked you will not damage the board.

Materials

TinyZero and Combo Sensor TinyShield

Hardware

Software


Hardware Assembly

On top of your processor board of choice, place the Combo Sensor TinyShield. Plug a MicroUSB cable into the micro USB port (or USB shield) and then plug the cable into an available USB port on your computer. Make sure the processor is switched on.

An assembled stack of a TinyZero and Combo Sensor TinyShield.


Software Setup

First, open the Arduino IDE. If you don't have it installed or are unfamiliar with how to upload the code, check out the TinyDuino Setup Tutorial or TinyZero Setup Tutorial depending on which processor you're using.

Upload Program

9-Axis Code
/*
  TinyCircuits LSM9DS1 9 Axis TinyShield Example Sketch

  This demo is intended for the ASD2511 Sensor Board TinyShield with a LSM9DS1
  9 axis sensor populated. It shows basic use of a modified RTIMULib with the
  sensor.

  This program now includes an EEPROM compatibility file for TinyScreen+.
  Using it will lock the last 16KB of flash for EEPROM emulation and prevent
  the bootloader from erasing or writing that section. This should not affect
  other programs unless they are trying to use the last 16KB of flash.

  Written 11 July 2016
  By Ben Rose
  Modified 07 January 2019
  By Hunter Hykes

  https://TinyCircuits.com
*/

////////////////////////////////////////////////////////////////////////////
//
//  This file is part of RTIMULib-Arduino
//
//  Copyright (c) 2014-2015, richards-tech
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy of 
//  this software and associated documentation files (the "Software"), to deal in 
//  the Software without restriction, including without limitation the rights to use, 
//  copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the 
//  Software, and to permit persons to whom the Software is furnished to do so, 
//  subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in all 
//  copies or substantial portions of the Software.
//
////////////////////////////////////////////////////////////////////////////


#include <Wire.h>
#include "RTIMUSettings.h"
#include "RTIMU.h"
#include "RTFusionRTQF.h"
#ifndef ARDUINO_ARCH_SAMD
#include <EEPROM.h>
#endif

RTIMU *imu;                                           // the IMU object
RTFusionRTQF fusion;                                  // the fusion object
RTIMUSettings settings;                               // the settings object

//  DISPLAY_INTERVAL sets the rate at which results are displayed

#define DISPLAY_INTERVAL  300                         // interval between pose displays

//  SERIAL_PORT_SPEED defines the speed to use for the debug serial port

#define  SERIAL_PORT_SPEED  115200

#ifdef SERIAL_PORT_MONITOR
  #define SerialMonitor SERIAL_PORT_MONITOR
#else
  #define SerialMonitor Serial
#endif

unsigned long lastDisplay;
unsigned long lastRate;
int sampleCount;

void setup()
{
    int errcode;

    SerialMonitor.begin(SERIAL_PORT_SPEED);
    while(!SerialMonitor);

    Wire.begin();
    imu = RTIMU::createIMU(&settings);                        // create the imu object

    SerialMonitor.print("ArduinoIMU starting using device "); SerialMonitor.println(imu->IMUName());
    if ((errcode = imu->IMUInit()) < 0) {
        SerialMonitor.print("Failed to init IMU: "); SerialMonitor.println(errcode);
    }

    if (imu->getCalibrationValid())
        SerialMonitor.println("Using compass calibration");
    else
        SerialMonitor.println("No valid compass calibration data");

    lastDisplay = lastRate = millis();
    sampleCount = 0;

    // Slerp power controls the fusion and can be between 0 and 1
    // 0 means that only gyros are used, 1 means that only accels/compass are used
    // In-between gives the fusion mix.

    fusion.setSlerpPower(0.02);

    // use of sensors in the fusion algorithm can be controlled here
    // change any of these to false to disable that sensor

    fusion.setGyroEnable(true);
    fusion.setAccelEnable(true);
    fusion.setCompassEnable(true);
}

void loop()
{  
  unsigned long now = millis();
  unsigned long delta;

  if (imu->IMURead()) {                                // get the latest data if ready yet
    fusion.newIMUData(imu->getGyro(), imu->getAccel(), imu->getCompass(), imu->getTimestamp());
    sampleCount++;
    if ((delta = now - lastRate) >= 1000) {
      SerialMonitor.print("Sample rate: "); SerialMonitor.print(sampleCount);
      if (imu->IMUGyroBiasValid())
        SerialMonitor.println(", gyro bias valid");
      else
        SerialMonitor.println(", calculating gyro bias - don't move IMU!!");

      sampleCount = 0;
      lastRate = now;
    }
    if ((now - lastDisplay) >= DISPLAY_INTERVAL) {
      lastDisplay = now;
      RTVector3 accelData=imu->getAccel();
      RTVector3 gyroData=imu->getGyro();
      RTVector3 compassData=imu->getCompass();
      RTVector3 fusionData=fusion.getFusionPose();
      //displayAxis("Accel:", accelData.x(), accelData.y(), accelData.z());        // accel data
      //displayAxis("Gyro:", gyroData.x(), gyroData.y(), gyroData.z());            // gyro data
      //displayAxis("Mag:", compassData.x(), compassData.y(), compassData.z());    // compass data
      displayDegrees("Pose:", fusionData.x(), fusionData.y(), fusionData.z());   // fused output
      SerialMonitor.println();
    }
  }
}

void displayAxis(const char *label, float x, float y, float z)
{
  SerialMonitor.print(label);
  SerialMonitor.print(" x:"); SerialMonitor.print(x);
  SerialMonitor.print(" y:"); SerialMonitor.print(y);
  SerialMonitor.print(" z:"); SerialMonitor.print(z);
}

void displayDegrees(const char *label, float x, float y, float z)
{
  SerialMonitor.print(label);
  SerialMonitor.print(" x:"); SerialMonitor.print(x * RTMATH_RAD_TO_DEGREE);
  SerialMonitor.print(" y:"); SerialMonitor.print(y * RTMATH_RAD_TO_DEGREE);
  SerialMonitor.print(" z:"); SerialMonitor.print(z * RTMATH_RAD_TO_DEGREE);
}
Temperature/Humidity Code
/*
  TinyCircuits Si7020 Temperature and Humidity Sensor TinyShield Example Sketch

  This demo shows the bare minimum to read temperature and humidity data from 
  the Si7020 sensor using the Si7020 library written by Marcus Sorensen.

  This example is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Written 20 March 2016
  By Ben Rose
  Modified 07 January 2019
  By Hunter Hykes

  https://TinyCircuits.com
*/

#include <Wire.h>
#include <SI7021.h>

SI7021 sensor;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  Serial.print("Initializing sensor... ");
  if(!sensor.begin()){
    Serial.println("Sensor not found!");
    while(true);
  }
  Serial.println("Success!");
}

void loop()
{
  int celcius=sensor.getCelsiusHundredths()/100;
  int relativeHumidity=sensor.getHumidityPercent();
  Serial.print(celcius);
  Serial.print(" deg Celsius\t");
  Serial.print(relativeHumidity);
  Serial.println("% relative humidity");

  delay(500);
}
Barometric Pressure Code
/*
  TinyDuino Barometric Pressure Demo

  This example code is in the public domain.

  Written 
  By 
  Modified 07 January 2019
  By Hunter Hykes

  https://TinyCircuits.com
*/

#include "BMP280.h"
#include "Wire.h"
#define P0 1013.25
BMP280 bmp;
void setup()
{
  Serial.begin(9600);
  if(!bmp.begin()){
    Serial.println("BMP init failed!");
    while(1);
  }
  else Serial.println("BMP init success!");

  bmp.setOversampling(4);

}
void loop()
{
  double T,P;
  char result = bmp.startMeasurment();

  if(result!=0){
    delay(result);
    result = bmp.getTemperatureAndPressure(T,P);

      if(result!=0)
      {
        double A = bmp.altitude(P,P0);

        Serial.print("T = \t");Serial.print(T,2); Serial.print(" degC\t");
        Serial.print("P = \t");Serial.print(P,2); Serial.print(" mBar\t");
        Serial.print("A = \t");Serial.print(A,2); Serial.println(" m");

      }
      else {
        Serial.println("Error.");
      }
  }
  else {
    Serial.println("Error.");
  }

  delay(100);
}
Ambient Light Code
/*
  TinyCircuits Ambient Light TinyShield Example Sketch
  Using AMS TAOS TSL2572

  This example code is in the public domain.

  Written 25 October 2015
  By Ken Burns
  Modified 07 January 2019
  By Hunter Hykes

  https://TinyCircuits.com
*/

#include <Wire.h>

#define TSL2572_I2CADDR     0x39

#define GAIN_1X 0
#define GAIN_8X 1
#define GAIN_16X 2
#define GAIN_120X 3

//only use this with 1x and 8x gain settings
#define GAIN_DIVIDE_6 true 

int gain_val = 0;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  TSL2572nit(GAIN_1X);
}


void loop()
{
  float AmbientLightLux = Tsl2572ReadAmbientLight();
  Serial.print("Lux: ");
  Serial.println(AmbientLightLux);

  delay(1000);
}


void TSL2572nit(uint8_t gain)
{
  Tsl2572RegisterWrite( 0x0F, gain );//set gain
  Tsl2572RegisterWrite( 0x01, 0xED );//51.87 ms
  Tsl2572RegisterWrite( 0x00, 0x03 );//turn on
  if(GAIN_DIVIDE_6)
    Tsl2572RegisterWrite( 0x0D, 0x04 );//scale gain by 0.16
  if(gain==GAIN_1X)gain_val=1;
  else if(gain==GAIN_8X)gain_val=8;
  else if(gain==GAIN_16X)gain_val=16;
  else if(gain==GAIN_120X)gain_val=120;
}


void Tsl2572RegisterWrite( byte regAddr, byte regData )
{
  Wire.beginTransmission(TSL2572_I2CADDR);
  Wire.write(0x80 | regAddr); 
  Wire.write(regData);
  Wire.endTransmission(); 
}


float Tsl2572ReadAmbientLight()
{     
  uint8_t data[4]; 
  int c0,c1;
  float lux1,lux2,cpl;

  Wire.beginTransmission(TSL2572_I2CADDR);
  Wire.write(0xA0 | 0x14);
  Wire.endTransmission();
  Wire.requestFrom(TSL2572_I2CADDR,4);
  for(uint8_t i=0;i<4;i++)
    data[i] = Wire.read();

  c0 = data[1]<<8 | data[0];
  c1 = data[3]<<8 | data[2];

  //see TSL2572 datasheet
  cpl = 51.87 * (float)gain_val / 60.0;
  if(GAIN_DIVIDE_6) cpl/=6.0;
  lux1 = ((float)c0 - (1.87 * (float)c1)) / cpl;
  lux2 = ((0.63 * (float)c0) - (float)c1) / cpl;
  cpl = max(lux1, lux2);
  return max(cpl, 0.0);
}

Contact Us

If you have any questions or feedback, feel free to email us at info@tinycircuits.com or make a post on the forum.

Show us what you make by tagging @TinyCircuits on Instagram, Twitter, or Facebook so we can feature it!

Thanks for making with us!


Downloads