Communicating with I2C Slave that has a Sensor connected to the I2C pins

Hi,

I’m trying to create a modular garment that takes Arduino swatches and interfaces them together using the I2C. I’m building a main (Master) swatch that has an Arduino Pro Mini 3.3V, LiPo Battery, and SD Card Reader. From there I have a sensor swatch that uses the Arduino Pro Mini 3.3V and the Adafruit TSL2561 Light Sensor - http://learn.adafruit.com/tsl2561/.

I’m trying to read the data from the swatch with the light sensor, then I would like the Arduino on that swatch to send the data to my main swatch so that it can record it. Problem I’m running into is that the light sensor swatch is using the I2C to integrate the sensor to that Arduino, and when I open the Serial Monitor on my Master Arduino, the data is not right (this is what I get: ÿÿÿÿÿÿÿÿÿÿ…).

Any ideas on how I can send the data to my main Arduino without adding the light sensing code to the Master Arduino?

Here’s what I’m running on the Slave Arduino:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2561.h>

/* This driver uses the Adafruit unified sensor library (Adafruit_Sensor),
 which provides a common 'type' for sensor data and some helper functions.
 
 To use this driver you will also need to download the Adafruit_Sensor
 library and include it in your libraries folder.
 
 You should also assign a unique ID to this sensor for use with
 the Adafruit Sensor API so that you can identify this particular
 sensor in any data logs, etc.  To assign a unique ID, simply
 provide an appropriate value in the constructor below (12345
 is used by default in this example).
 
 Connections
 ===========
 Connect SCL to analog 5
 Connect SDA to analog 4
 Connect VDD to 3.3V DC
 Connect GROUND to common ground
 
 I2C Address
 ===========
 The address will be different depending on whether you leave
 the ADDR pin floating (addr 0x39), or tie it to ground or vcc. 
 The default addess is 0x39, which assumes the ADDR pin is floating
 (not connected to anything).  If you set the ADDR pin high
 or low, use TSL2561_ADDR_HIGH (0x49) or TSL2561_ADDR_LOW
 (0x29) respectively.
 
 History
 =======
 2013/JAN/31  - First version (KTOWN)
 */



Adafruit_TSL2561 myLightSensor = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345);


uint16_t broadband = 0;    //variables for the raw sesor data
uint16_t infrared = 0;



//Constants and Variables for keeping track of time:

// macros from DateTime.h 
/* Useful Constants */
#define SECS_PER_MIN  (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY  (SECS_PER_HOUR * 24L)

/* Useful Macros for getting elapsed time */
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)  
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) 
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)  

int days;
int hours;
int minutes;
int seconds;

int motorPin = 5;

void setup(void) 
{
  Wire.begin(2);                // join i2c bus with address #2
  Serial.begin(9600);
  Serial.println("Light Sensor Test"); 
  Serial.println("");

  /* Initialise the sensor */
  if(!myLightSensor.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.print("Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!");
    while(1);
  }

  /* Display some basic information on this sensor */
  displaySensorDetails();

  /* Setup the sensor gain and integration time */
  configureSensor();

  /* We're ready to go! */
  Serial.println("");

  pinMode(13, OUTPUT);


}




void loop(void) 
{  
  
  
  /* Gets a new reading from the sensor */
  sensors_event_t event;
  myLightSensor.getEvent(&event);

  /* Gets the raw sensor data from each sensor -note this is not neccessary if you are only reading Lux */
  myLightSensor.getLuminosity (&broadband, &infrared);

  /* Display the results (light is measured in lux) */
  if (event.light)
  {
    Serial.print(event.light);                             // 'event.light' is the number of Lux measured in SI
    Serial.print(" lux  |  ");
    Serial.print(infrared);                                // 'infrared' is the raw sensor data coming from the Infrared Sensor
    Serial.print(" infrared  |  ");
    Serial.print(broadband);                               // 'broadband' is the raw sensor data coming from the Full Spectrum Light Sensor
    Serial.print( " full spectrum  |  ");

    int lux = event.light;

    //Send data to Master Arduino with SD card
    Wire.write(lux);                             // 'event.light' is the number of Lux measured in SI
    Wire.write(" lux  |  ");
    Wire.write(infrared);                                // 'infrared' is the raw sensor data coming from the Infrared Sensor
    Wire.write(" infrared  |  ");
    Wire.write(broadband);                               // 'broadband' is the raw sensor data coming from the Full Spectrum Light Sensor
    Wire.write( " full spectrum  |  ");



  }
  else
  {
    /* If event.light = 0 lux the sensor is probably saturated
     and no reliable data could be generated! */
    Serial.println("Sensor overload");
  }

  //function that displays the amount of time the arduino has been on.  Shouldn't need to change this function
  time(millis() / 1000);

  delay(250);
}






/**************************************************************************/
/*
    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;
  myLightSensor.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);
}

/**************************************************************************/
/*
    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 */
  myLightSensor.enableAutoGain(true);          /* Auto-gain ... switches automatically between 1x and 16x */

  /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */
  //myLightSensor.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS);      /* fast but low resolution */
  myLightSensor.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);  /* medium resolution and speed   */
  // myLightSensor.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);  /* 16-bit data but slowest conversions */

  /* Update these values depending on what you've set above! */
  Serial.println("------------------------------------");
  Serial.print  ("Gain:         "); 
  Serial.println("Auto");
  Serial.print  ("Timing:       "); 
  Serial.println("13 ms");
  Serial.println("------------------------------------");
}



void time(long val){  

  days = elapsedDays(val);
  hours = numberOfHours(val);
  minutes = numberOfMinutes(val);
  seconds = numberOfSeconds(val);

  // digital clock display of current time
  Serial.print("time since active = ");
  Serial.print(days,DEC);  
  printDigits(hours);  
  printDigits(minutes);
  printDigits(seconds);
  Serial.println();  

}

void printDigits(byte digits){
  // utility function for digital clock display: prints colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits,DEC);  
}

And the Master:

// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire.requestFrom(2, 12);    // request 6 bytes from slave device #2

  while(Wire.available())    // slave may send less than requested
  { 
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

Thanks for the help, I need this up and running by 9am :slight_smile:

You can use the pins for I2C OR you can use them (or one of them) to read a sensor/ Which would you like to do?

Ideally, I'd like to use the slave arduino to communicate with the sensor (which is set up to use I2C), then have the slave arduino send the sensor data to the master arduino using I2C.

You're designing these swatches, right? Move it to another pin. That's you're only option.

I see. Thanks for the info