Skip to content
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Multiple I2C sensors sketch
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

Multiple I2C sensors sketch

Scheduled Pinned Locked Moved Development
6 Posts 3 Posters 4.3k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • macieiksM Offline
    macieiksM Offline
    macieiks
    wrote on last edited by
    #1

    Hello Guys,

    I am happy user of Mysensors project :)

    I have many nodes up and running around my house. My new project is to build node with RFID functionality. I would like to use Lux sensor (BH1750) running on I2C bus with RFID sensor (red PN532) which is also running on I2C bus. How I can connect two I2C sensors together and make correct Mysensors sketch for it? Do you know maybe already explained tutorial so I could dig into it ? :D I know that each of I2C sensor will have its own bus address but I do not know how it is looks like from MySensors library perspective.

    Looking forward for your reply.

    Regards,
    Maciek

    P.S. I also have around 5x (blue) RFID RC522 I only know sketches for PN532, but maybe you know how to use them with Arduino MySensors also ? :D

    RPI2 + RFLink + PiFace D2 + Aeon Z-Wave Gen5 + Foscams FI9821P&R2 + MySensors + UPS APC Back-UPS 950VA
    RPI2 + RFXtrx433e + Foscams FI9821P + MySensors + UPS APC Back-UPS 950VA
    RPIB+ + TP-Link MR3420 + Huawei E173 GarageDomoticz :)

    TheoLT 1 Reply Last reply
    0
    • macieiksM macieiks

      Hello Guys,

      I am happy user of Mysensors project :)

      I have many nodes up and running around my house. My new project is to build node with RFID functionality. I would like to use Lux sensor (BH1750) running on I2C bus with RFID sensor (red PN532) which is also running on I2C bus. How I can connect two I2C sensors together and make correct Mysensors sketch for it? Do you know maybe already explained tutorial so I could dig into it ? :D I know that each of I2C sensor will have its own bus address but I do not know how it is looks like from MySensors library perspective.

      Looking forward for your reply.

      Regards,
      Maciek

      P.S. I also have around 5x (blue) RFID RC522 I only know sketches for PN532, but maybe you know how to use them with Arduino MySensors also ? :D

      TheoLT Offline
      TheoLT Offline
      TheoL
      Contest Winner
      wrote on last edited by
      #2

      @macieiks You need to know the i2c addresses of each individual device. You can use the i2c scanner for that. Hooking up is real easy. See this:

      alt text

      You need pullup resistors (10K if I'm not mistaken).

      1 Reply Last reply
      0
      • macieiksM Offline
        macieiksM Offline
        macieiks
        wrote on last edited by
        #3

        Hey,

        Thanks for the reply. In overall I know concept of I2C, however I am looking for the guide which describes "How to" and also example ofMysensors sketch with support of min 2 I2C sensors together :)

        Regards,
        Maciek

        RPI2 + RFLink + PiFace D2 + Aeon Z-Wave Gen5 + Foscams FI9821P&R2 + MySensors + UPS APC Back-UPS 950VA
        RPI2 + RFXtrx433e + Foscams FI9821P + MySensors + UPS APC Back-UPS 950VA
        RPIB+ + TP-Link MR3420 + Huawei E173 GarageDomoticz :)

        TheoLT 1 Reply Last reply
        0
        • scalzS Offline
          scalzS Offline
          scalz
          Hardware Contributor
          wrote on last edited by
          #4

          @macieiks
          Hi.
          not sure if it's the right section ;)
          In fact it's not really complicated. i2c or others sensors are almost the same when you want to mix sketch.
          Add includes for your desired sensors libs, declarations for your sensors id, present sensors like it's done for one sensor sketch, and use send function to send infos in sketch.
          The best is to start with your rfid sketch. Check it works ok. Then add to it, the bh1750 sketch parts. if you're not sure, add things step by step.
          If you have some problems, post your sketch and we will help you :)

          1 Reply Last reply
          0
          • macieiksM Offline
            macieiksM Offline
            macieiks
            wrote on last edited by
            #5

            Thank you guys for your input.

            Yes, I will start step by step as I do with mixing Mysensors sketches. The thing was about theses multiple I2C how they will be discovered. I will try to start with example RFID sketch, make it 100% work and then I will start with example lux sensor :) We will see what will happend. For sure I will provide my output here hehe :D

            Regards,
            Maciek

            RPI2 + RFLink + PiFace D2 + Aeon Z-Wave Gen5 + Foscams FI9821P&R2 + MySensors + UPS APC Back-UPS 950VA
            RPI2 + RFXtrx433e + Foscams FI9821P + MySensors + UPS APC Back-UPS 950VA
            RPIB+ + TP-Link MR3420 + Huawei E173 GarageDomoticz :)

            1 Reply Last reply
            1
            • macieiksM macieiks

              Hey,

              Thanks for the reply. In overall I know concept of I2C, however I am looking for the guide which describes "How to" and also example ofMysensors sketch with support of min 2 I2C sensors together :)

              Regards,
              Maciek

              TheoLT Offline
              TheoLT Offline
              TheoL
              Contest Winner
              wrote on last edited by
              #6

              @macieiks I don't think you're question is really related to MySensors, it's more an Arduino related question. The problem you might have is the memory capacity of the Arduino. Here's the sketch for the first mySensor node I made. It uses an I2C lux and i2c barometric pressure sensor and an HDT11 humidity sensor.

              /**
               * The MySensors Arduino library handles the wireless radio link and protocol
               * between your home built sensors/actuators and HA controller of choice.
               * The sensors forms a self healing radio network with optional repeaters. Each
               * repeater and gateway builds a routing tables in EEPROM which keeps track of the
               * network topology allowing messages to be routed to nodes.
               *
               * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
               * Copyright (C) 2013-2015 Sensnology AB
               * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
               *
               * Documentation: http://www.mysensors.org
               * Support Forum: http://forum.mysensors.org
               *
               * This program is free software; you can redistribute it and/or
               * modify it under the terms of the GNU General Public License
               * version 2 as published by the Free Software Foundation.
               *
               *******************************
               *
               * REVISION HISTORY
               * Version 1.0 - Henrik EKblad
               * 
               * DESCRIPTION
               * This sketch provides an example how to implement a humidity/temperature
               * sensor using DHT11/DHT-22 
               * http://www.mysensors.org/build/humidity
               */
               
              // #define DEBUG 
               
              #include <SPI.h>
              #include <MySensor.h>  
              #include <DHT.h>
              #include <Wire.h>
              #include <Adafruit_BMP085.h>
              #include <Adafruit_TSL2561_U.h>
              #include <Adafruit_Sensor.h>
              
              #define CHILD_ID_HUM 0
              #define CHILD_ID_TEMP 1
              #define CHILD_ID_BARO 2
              #define CHILD_ID_LIGHT 3
              
              #define HUMIDITY_SENSOR_DIGITAL_PIN 3
              
              const float ALTITUDE = 28; // <-- adapt this value to your own location's altitude. Lijkt dus in meters te zijn
              unsigned long SLEEP_TIME = 60000; // Sleep time between reads (in milliseconds)
              
              const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
              enum FORECAST
              {
              	STABLE = 0,			// "Stable Weather Pattern"
              	SUNNY = 1,			// "Slowly rising Good Weather", "Clear/Sunny "
              	CLOUDY = 2,			// "Slowly falling L-Pressure ", "Cloudy/Rain "
              	UNSTABLE = 3,		// "Quickly rising H-Press",     "Not Stable"
              	THUNDERSTORM = 4,	// "Quickly falling L-Press",    "Thunderstorm"
              	UNKNOWN = 5			// "Unknown (More Time needed)
              };
              
              Adafruit_BMP085 bmp = Adafruit_BMP085();
              MySensor gw;
              Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
              
              DHT dht;
              float lastTemp = -1000;
              float lastHum = -1;
              float lastPressure = -1;
              int lastForecast = -1;
              int lastLightLevel = -1;
              
              const int LAST_SAMPLES_COUNT = 5;
              float lastPressureSamples[LAST_SAMPLES_COUNT];
              
              // this CONVERSION_FACTOR is used to convert from Pa to kPa in forecast algorithm
              // get kPa/h be dividing hPa by 10 
              #define CONVERSION_FACTOR (1.0/10.0)
              
              int minuteCount = 0;
              bool firstRound = true;
              // average value is used in forecast algorithm.
              float pressureAvg;
              // average after 2 hours is used as reference value for the next iteration.
              float pressureAvg2;
              
              float dP_dt;
              
              MyMessage msgHum(CHILD_ID_HUM, V_HUM);
              MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
              MyMessage pressureMsg(CHILD_ID_BARO, V_PRESSURE);
              MyMessage forecastMsg(CHILD_ID_BARO, V_FORECAST);
              MyMessage lightMsg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
              
              
              /**************************************************************************/
              /*
                  Displays some basic information on this sensor from the unified
                  sensor API sensor_t type (see Adafruit_Sensor for more information)
              */
              /**************************************************************************/
              #ifdef DEBUG
              void displaySensorDetails(void)
              {
                sensor_t sensor;
                tsl.getSensor(&sensor);
                Serial.println("------------------------------------");
                Serial.print  ("Sensor:       "); Serial.println(sensor.name);
                Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
                Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
                Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" lux");
                Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" lux");
                Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" lux");  
                Serial.println("------------------------------------");
                Serial.println("");
                delay(500);
              }
              #endif
              
              /**************************************************************************/
              /*
                  Configures the gain and integration time for the TSL2561
              */
              /**************************************************************************/
              void configureSensor(void)
              {
                /* You can also manually set the gain or enable auto-gain support */
                // tsl.setGain(TSL2561_GAIN_1X);      /* No gain ... use in bright light to avoid sensor saturation */
                // tsl.setGain(TSL2561_GAIN_16X);     /* 16x gain ... use in low light to boost sensitivity */
                tsl.enableAutoRange(true);            /* Auto-gain ... switches automatically between 1x and 16x */
                
                /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */
                tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS);      /* fast but low resolution */
                // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);  /* medium resolution and speed   */
                // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);  /* 16-bit data but slowest conversions */
              
                /* Update these values depending on what you've set above! */
              #ifdef DEBUG
                  Serial.println("------------------------------------");
                Serial.print  ("Gain:         "); Serial.println("Auto");
                Serial.print  ("Timing:       "); Serial.println("13 ms");
                Serial.println("------------------------------------");
              #endif
              }
              
              void setup()  
              { 
                gw.begin();
              
              #ifdef DEBUG
                Serial.begin(115200);
                Serial.println("Light Sensor Test"); Serial.println("115200");
              #endif
              
                dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
              
                // Send the Sketch Version Information to the Gateway
                gw.sendSketchInfo("Inside weather conditions", "1.0");
              
                /* Only presenting the sensors if they're available */  
                if (bmp.begin()) {
                  gw.present(CHILD_ID_BARO, S_BARO);
                }
              #ifdef DEBUG
                else {
                  Serial.println( 'Barometer not found' );
                }
              #endif
              
                if(!tsl.begin())
                {
              #ifdef DEBUG
                  /* There was a problem detecting the ADXL345 ... check your connections */
                  Serial.print( "Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!" );
              #endif
               //    while(1);
                } 
                else {
              #ifdef DEBUG
                  /* Display some basic information on this sensor */
                  displaySensorDetails();
              #endif  
                  /* Setup the sensor gain and integration time */
                  configureSensor();
                  gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL); 
                }
              
                // Register all sensors to gw (they will be created as child devices)
                gw.present(CHILD_ID_HUM, S_HUM);
                gw.present(CHILD_ID_TEMP, S_TEMP);
                gw.sendBatteryLevel( 100 );
              }
              
              void loop()      
              {  
                delay(dht.getMinimumSamplingPeriod());
              
                float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
                float temperature = bmp.readTemperature();
                
                int forecast = sample(pressure);
                
              #ifdef DEBUG
                float dhtTemperature = dht.getTemperature();
                Serial.print("Temperature = ");
                Serial.print(temperature);
                Serial.println( " *C" );
                Serial.print("Pressure = ");
                Serial.print(pressure);
                Serial.println(" hPa");
                Serial.print("Forecast = ");
                Serial.println(weather[forecast]);
              
                Serial.print( "Dht Temp: " );
                Serial.print(dhtTemperature);
                Serial.println( " *C" );
              #endif
              
                if (isnan(temperature)) {
              #ifdef DEBUG    
                    Serial.println("Failed reading temperature from DHT");
              #endif
                }
                else if (temperature != lastTemp) {
                  lastTemp = temperature;
                  gw.send(msgTemp.set(temperature, 1));
              #ifdef DEBUG    
                  Serial.print("T: ");
                  Serial.println(temperature);
              #endif    
                }
                
                float humidity = dht.getHumidity();
                if (isnan(humidity)) {
              #ifdef DEBUG
                Serial.println("Failed reading humidity from DHT");
              #endif  
                } 
                else if (humidity != lastHum) {
                    lastHum = humidity;
                    gw.send(msgHum.set(humidity, 1));
              #ifdef DEBUG      
                    Serial.print("H: ");
                    Serial.println(humidity);
              #endif      
                }
                
                 sensors_event_t event;
              
               // maybe a delay between the sensor readings
                tsl.getEvent(&event);
               
                /* Display the results (light is measured in lux) */
                // if (event.light) { // removed test to see if we get a 0 meeting during the evening and night.
              #ifdef DEBUG
                  Serial.print(event.light); 
                  Serial.println(" lux");
              #endif
                  if ( event.light != lastLightLevel ) {
                    gw.send(lightMsg.set((uint16_t)event.light));
                    lastLightLevel = event.light;
                  }
              /*  } // removed test to see if we get a 0 meeting during the evening and night.
                else
                {
                  // If event.light = 0 lux the sensor is probably saturated and no reliable data could be generated! 
               #ifdef DEBUG
                 Serial.println("Sensor overload");
               #endif  
                }
                */
                
                if (pressure != lastPressure) 
                {
                  gw.send(pressureMsg.set(pressure, 0));
                  lastPressure = pressure;
                }
              
                if (forecast != lastForecast)
                {
                  gw.send(forecastMsg.set(weather[forecast]));
                  lastForecast = forecast;
                }
              
               gw.sleep(SLEEP_TIME); //sleep a bit
              }
              
              
              float getLastPressureSamplesAverage()
              {
              	float lastPressureSamplesAverage = 0;
              	for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
              	{
              		lastPressureSamplesAverage += lastPressureSamples[i];
              	}
              	lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
              
              	return lastPressureSamplesAverage;
              }
              
              
              
              // Algorithm found here
              // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
              // Pressure in hPa -->  forecast done by calculating kPa/h
              int sample(float pressure)
              {
              	// Calculate the average of the last n minutes.
              	int index = minuteCount % LAST_SAMPLES_COUNT;
              	lastPressureSamples[index] = pressure;
              
              	minuteCount++;
              	if (minuteCount > 185)
              	{
              		minuteCount = 6;
              	}
              
              	if (minuteCount == 5)
              	{
              		pressureAvg = getLastPressureSamplesAverage();
              	}
              	else if (minuteCount == 35)
              	{
              		float lastPressureAvg = getLastPressureSamplesAverage();
              		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
              		if (firstRound) // first time initial 3 hour
              		{
              			dP_dt = change * 2; // note this is for t = 0.5hour
              		}
              		else
              		{
              			dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
              		}
              	}
              	else if (minuteCount == 65)
              	{
              		float lastPressureAvg = getLastPressureSamplesAverage();
              		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
              		if (firstRound) //first time initial 3 hour
              		{
              			dP_dt = change; //note this is for t = 1 hour
              		}
              		else
              		{
              			dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
              		}
              	}
              	else if (minuteCount == 95)
              	{
              		float lastPressureAvg = getLastPressureSamplesAverage();
              		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
              		if (firstRound) // first time initial 3 hour
              		{
              			dP_dt = change / 1.5; // note this is for t = 1.5 hour
              		}
              		else
              		{
              			dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
              		}
              	}
              	else if (minuteCount == 125)
              	{
              		float lastPressureAvg = getLastPressureSamplesAverage();
              		pressureAvg2 = lastPressureAvg; // store for later use.
              		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
              		if (firstRound) // first time initial 3 hour
              		{
              			dP_dt = change / 2; // note this is for t = 2 hour
              		}
              		else
              		{
              			dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
              		}
              	}
              	else if (minuteCount == 155)
              	{
              		float lastPressureAvg = getLastPressureSamplesAverage();
              		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
              		if (firstRound) // first time initial 3 hour
              		{
              			dP_dt = change / 2.5; // note this is for t = 2.5 hour
              		}
              		else
              		{
              			dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
              		}
              	}
              	else if (minuteCount == 185)
              	{
              		float lastPressureAvg = getLastPressureSamplesAverage();
              		float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
              		if (firstRound) // first time initial 3 hour
              		{
              			dP_dt = change / 3; // note this is for t = 3 hour
              		}
              		else
              		{
              			dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
              		}
              		pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
              		firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
              	}
              
              	int forecast = UNKNOWN;
              	if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
              	{
              		forecast = UNKNOWN;
              	}
              	else if (dP_dt < (-0.25))
              	{
              		forecast = THUNDERSTORM;
              	}
              	else if (dP_dt > 0.25)
              	{
              		forecast = UNSTABLE;
              	}
              	else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
              	{
              		forecast = CLOUDY;
              	}
              	else if ((dP_dt > 0.05) && (dP_dt < 0.25))
              	{
              		forecast = SUNNY;
              	}
              	else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
              	{
              		forecast = STABLE;
              	}
              	else
              	{
              		forecast = UNKNOWN;
              	}
              
              	// uncomment when debugging
              #ifdef DEBUG
              	Serial.print(F("Forecast at minute "));
              	Serial.print(minuteCount);
              	Serial.print(F(" dP/dt = "));
              	Serial.print(dP_dt);
              	Serial.print(F("kPa/h --> "));
              	Serial.println(weather[forecast]);
              #endif
              	return forecast;
              }
              
              1 Reply Last reply
              1
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              16

              Online

              11.7k

              Users

              11.2k

              Topics

              113.0k

              Posts


              Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • OpenHardware.io
              • Categories
              • Recent
              • Tags
              • Popular