element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Sensors Projects
  • Challenges & Projects
  • Project14
  • Sensors Projects
  • More
  • Cancel
Sensors Projects
Blog Wio Terminal Sensor Fusion - Sensor Integration
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Sensors Projects to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: ralphjy
  • Date Created: 2 Nov 2020 9:36 PM Date Created
  • Views 2396 views
  • Likes 5 likes
  • Comments 0 comments
  • sensorsch
  • neopixel
  • ms8607
  • wio terminal
  • tsl2561
Related
Recommended

Wio Terminal Sensor Fusion - Sensor Integration

ralphjy
ralphjy
2 Nov 2020

Software Development Environment

There are a few software development choices supported by Seeed: the Arduino IDE and a couple of MicroPython variants - Adafruit CircuitPython and Seeed ArduPy.  I've been using a different MicroPython variant, Sipeed MaixPy, to program RISC-V K210 boards and CircuitPython to interactively control sensors via the MCP2221, so I considered using MicroPython.  CircuitPython is nice because it has many Adafruit sensor libraries and ArduPy is interesting because it combines MicroPython and the Arduino API.  Using ArduPy is supposed to give you access to all of your current Arduino libraries although you need to write and compile C++ wrappers for any libraries that are not included in the base Arduino build.  In the end I decided to stick with the standard Arduino IDE mainly because it is familiar and because the Seeed Grove Ecosystem has a complete set of Arduino sensor libraries.

 

Sensor Connection and setup

LCD 320x240 Display

The LCD display uses one of the 3 internal SPI interfaces (the other 2 are used for the WiFi and the SD card).  There are touch control lines shown on the schematic but this might be for a future version upgrade as the current display does not have touch capability.  The pin used to drive the backlight control FET is also PWM capable but a third party library is needed to drive it.

 

image

The libraries required to interface the LCD are the Seeed_Arduino_LCD library (TFT_eSPI) and the Adafruit_Zero_DMA library.  These are included in the Seeed SAMD board package.

 

 

TSL2591 Lux Sensor

I am using the I2C1 bus - one of the 2 dedicated I2C interfaces.  I2C1 is available on the bottom left Grove connector of the Wio Terminal and the bottom right connector of the battery chassis in addition to the 40 pin RPi connector.  I am using the bottom left Grove connector for the light sensor.  The Adafruit sensor breakout that I used is an obsolete version that uses a 0.1" header pattern for the pinout.  The new ones have a Stemma QT (QWIC) connector.  I have adapter cables from Stemma QT to Grove but in this case I just cut a Grove cable in half and wired it in directly.  I used the other half of the cable to connect the NeoPixel Stick.  I used the Adafruit Arduino library with the default I2C address of 0x29.

 

MS8607 Temperature, Humidity and Pressure Sensor

I'm using the second I2C1 Grove interface on the bottom right of the battery chassis for this sensor.   Since this is a Grove module the connection was with a standard Grove cable. This sensor breakout is made by TEConnectivity and uses a MEMS sensor that is factory calibrated.  I used the Adafruit Arduino library which is a version of the TEConnectivity library modified for the Arduino IDE. I was somewhat surprised that the sensor uses two I2C addresses - 0x76 for pressure/temperature and 0x40 for humidity.

 

NeoPixel Stick 8 x 5050

I am using Digital Pin D2 on the Grove connector on the upper right side of the battery chassis to drive the NeoPixel Stick.  This stick uses RGB LEDs rather than the 4 color RGBW LEDs.  Each LED is individually addressable and all LEDs are connected sequentially on a single wire interface, so I only needed one of the two signal pins on the Grove interface.  I wired the board using the other half of the Grove cable that I cut for the light sensor interface.  I used the Adafruit NeoPixel library to program it.

 

 

Interactive Sensor Program

So, I started with a program to use the 3 sensors together with the display.

  • Display Temperature, humidity and pressure measurements from the MS8607
  • Display Ambient light readings from the TSL2591
  • Change the number and color of the LEDs on the NeoPixel Stick based on the temperature measurement
  • Change the brightness of the LEDs based on the ambient light measurement

 

 

Wio_Terminal_MS8607_TSL2591_NeoPixel.ino

// Example testing sketch for various sensors on Wio Terminal
// Written by ralphjy, public domain


#include <Wire.h>
#include <Adafruit_MS8607.h>
#include <Adafruit_Sensor.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <Adafruit_NeoPixel.h>
#include "Adafruit_TSL2591.h"


#define LIGHTPIN A6
#define NEOPIXELPIN D2
#define NUMPIXELS 8


Adafruit_MS8607 ms8607;
Adafruit_TSL2591 tsl = Adafruit_TSL2591(2591); // pass in a number for the sensor identifier (for your use later)


TFT_eSPI tft = TFT_eSPI();       // Invoke custom library


// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS, NEOPIXELPIN, NEO_GRB + NEO_KHZ800);


#if defined(ARDUINO_ARCH_AVR)
    #define debug  Serial


#elif defined(ARDUINO_ARCH_SAMD) ||  defined(ARDUINO_ARCH_SAM)
    #define debug  SerialUSB
#else
    #define debug  Serial
#endif


int ledBrightness = 50;


void setup() {


    debug.begin(115200);
    debug.println("MS8607 test!");


    pinMode(LIGHTPIN, INPUT);


    tft.init();
    tft.setRotation(3);
    tft.fillScreen(TFT_BLACK);
    tft.setTextSize(1);
    tft.setTextColor(TFT_WHITE, TFT_BLACK);  // Adding a background color erases previous text automatically


  // Try to initialize!
    if (!ms8607.begin()) {
      Serial.println("Failed to find MS8607 chip");
      while (1) { delay(10); }
    }
    Serial.println("MS8607 Found!");
    
    if (tsl.begin()) 
    {
      Serial.println(F("Found a TSL2591 sensor"));
    } 
    else 
    {
      Serial.println(F("No sensor found ... check your wiring?"));
      while (1);
    }
      
    /* Display some basic information on this sensor */
    displaySensorDetails();
    
    /* Configure the sensor */
    configureSensor();


    strip.begin();
    strip.setBrightness(ledBrightness);
    strip.show(); // Initialize all pixels to 'off'


    tft.setTextSize(2);
    tft.setTextDatum(TC_DATUM);
    tft.drawString("MS8607 Readings",160, 15, 1);
    tft.setTextDatum(TL_DATUM);
    
}


    int ledNum = 0;
    int ledNumPrevious = 0;


void loop() {
    float tempC, tempF, humid, press;
    sensors_event_t temp, pressure, humidity;
    ms8607.getEvent(&pressure, &temp, &humidity);
    Serial.print("Temperature: ");Serial.print(temp.temperature); Serial.println(" degrees C");
    Serial.print("Pressure: ");Serial.print(pressure.pressure); Serial.println(" hPa");
    Serial.print("Humidity: ");Serial.print(humidity.relative_humidity); Serial.println(" %rH");
    Serial.println("");


    tempC = temp.temperature;
    tempF = tempC * 9 / 5 + 32;
    humid = humidity.relative_humidity;
    press = pressure.pressure;
    uint16_t lightValue = tsl.getLuminosity(TSL2591_VISIBLE);


    int lightValueTrunc;
    if (lightValue > 1024) {
      lightValueTrunc = 1024;
    } else if (lightValue < 256) {
      lightValueTrunc = 256;
    } else {
      lightValueTrunc = (int) lightValue;
    }
    
    ledBrightness = lightValueTrunc / 32;


    if (tempC) {
        debug.print("Humidity: ");
        debug.print(humid);
        debug.print(" %\t");
        debug.print("Temperature: ");
        debug.print(tempC);
        debug.println(" *C");
    } else {
        debug.println("Failed to get temperature and humidity value.");
    }


    tft.setTextSize(2);


    tft.drawString("Temperature: ",20, 55, 1);
    tft.drawString("Humidity: ", 20, 100, 1);
    tft.drawString("Pressure: ", 20, 145, 1);
    tft.drawString("Ambient light: ", 20, 190, 1);


    tft.setTextDatum(TR_DATUM);
    tft.setTextPadding(tft.textWidth("999", 1));
    tft.drawNumber(tempF, 255, 55, 1);
    tft.drawNumber(humid, 255, 100, 1);
    tft.setTextPadding(tft.textWidth("99999", 1));
    tft.drawNumber(press, 255, 145, 1);
    tft.drawNumber(lightValue, 255, 190, 1);
    tft.setTextPadding(0);
    tft.setTextDatum(TL_DATUM);


    tft.drawString("F", 265, 55, 1);
    tft.drawString("%rH", 265, 100, 1);
    tft.drawString("hPa", 265, 145, 1);  


    ledNum = (int) (tempF/10) - 3;


    if (ledNum <= 1){
      ledNum = 1;
    }


    if (ledNum >= 8) {
      ledNum = 8;
    }


    if (ledNum != ledNumPrevious){
      strip.clear();    
    }
    
    switch (ledNum) {
      case 1:
        strip.fill(strip.Color(0, 0, 255), 0, 1);
        break;
      case 2:
        strip.fill(strip.Color(0, 0, 255), 0, 2);
        break;
      case 3:
        strip.fill(strip.Color(0, 0, 255), 0, 3);
        break;
      case 4:
        strip.fill(strip.Color(0, 255, 0), 0, 4);
        break;
      case 5:
        strip.fill(strip.Color(0, 255, 0), 0, 5);
        break;
      case 6:
        strip.fill(strip.Color(255, 0, 0), 0, 6);
        break;
      case 7:
        strip.fill(strip.Color(255, 0, 0), 0, 7);
        break;
      case 8:
        strip.fill(strip.Color(255, 0, 0), 0, 8);
        break;
      default:
        strip.clear();         
    }


    strip.setBrightness(ledBrightness);
    strip.show();
    delay(1500);
}


/**************************************************************************/
/*
    Displays some basic information on this sensor from the unified
    sensor API sensor_t type (see Adafruit_Sensor for more information)
*/
/**************************************************************************/
void displaySensorDetails(void)
{
  sensor_t sensor;
  tsl.getSensor(&sensor);
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Sensor:       ")); Serial.println(sensor.name);
  Serial.print  (F("Driver Ver:   ")); Serial.println(sensor.version);
  Serial.print  (F("Unique ID:    ")); Serial.println(sensor.sensor_id);
  Serial.print  (F("Max Value:    ")); Serial.print(sensor.max_value); Serial.println(F(" lux"));
  Serial.print  (F("Min Value:    ")); Serial.print(sensor.min_value); Serial.println(F(" lux"));
  Serial.print  (F("Resolution:   ")); Serial.print(sensor.resolution, 4); Serial.println(F(" lux"));  
  Serial.println(F("------------------------------------"));
  Serial.println(F(""));
  delay(500);
}


/**************************************************************************/
/*
    Configures the gain and integration time for the TSL2591
*/
/**************************************************************************/
void configureSensor(void)
{
  // You can change the gain on the fly, to adapt to brighter/dimmer light situations
  //tsl.setGain(TSL2591_GAIN_LOW);    // 1x gain (bright light)
  tsl.setGain(TSL2591_GAIN_MED);      // 25x gain
  //tsl.setGain(TSL2591_GAIN_HIGH);   // 428x gain
  
  // Changing the integration time gives you a longer time over which to sense light
  // longer timelines are slower, but are good in very low light situtations!
  //tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);  // shortest integration time (bright light)
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_200MS);
  tsl.setTiming(TSL2591_INTEGRATIONTIME_300MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_400MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_500MS);
  // tsl.setTiming(TSL2591_INTEGRATIONTIME_600MS);  // longest integration time (dim light)


  /* Display the gain and integration time for reference sake */  
  Serial.println(F("------------------------------------"));
  Serial.print  (F("Gain:         "));
  tsl2591Gain_t gain = tsl.getGain();
  switch(gain)
  {
    case TSL2591_GAIN_LOW:
      Serial.println(F("1x (Low)"));
      break;
    case TSL2591_GAIN_MED:
      Serial.println(F("25x (Medium)"));
      break;
    case TSL2591_GAIN_HIGH:
      Serial.println(F("428x (High)"));
      break;
    case TSL2591_GAIN_MAX:
      Serial.println(F("9876x (Max)"));
      break;
  }
  Serial.print  (F("Timing:       "));
  Serial.print((tsl.getTiming() + 1) * 100, DEC); 
  Serial.println(F(" ms"));
  Serial.println(F("------------------------------------"));
  Serial.println(F(""));
}

 

 

Sensor hookup to the Wio Terminal (running on battery in this picture)

image

 

Close-up of the sensor measurements on the LCD Display

image

 

Here is a quick video of the sensor interaction.

 

Color pattern (each LED represents 10 degrees F from 40 to 120 degrees F)

  • Blue - below 70 degrees F
  • Green - greater than or equal to 70 and less than 90
  • Red - above 90 degrees F

 

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

 

 

Next challenge is to get keyword spotting working using TinyML.

  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube