Can I wire multiple SCL & SDA pins?

I have a Boron and I’d like to wire up multiple sensors that use SCL & SDA. The issue it, I only see 1 set pinouts for each. Is there a way I can wire more than 1 set of SCL & SDA pins to my Boron?

I2C is a bus interface, so you can have multiple devices on the same bus and each of them will be addressed via its I2C address.

You just need to take care of the shared pull-up resistance on the SCL/SDA lines.
If you have multiple interface clients their combined pull-up resistances should fall in the range between 2k2 and 10k.

1 Like

I just have 2 INA260 from adafruit. Just a multiplex would work? How would that be addressed in the code?

When you look closely (and read the datasheet) you will notice two cut/solder jumpers on the sensor I2C Addr A0 and A1 this tells me that you can have up to four such sensors on the same I2C bus :wink:

I found this project where he does it but doesn’t give all of the connection details.

So 1 board is left as is, board 2 is soldered across the A0 pads, (board 3 would be soldered across A1 pads) then all of the sensors use the same SCL & SDA terminals TO the boron? Am I interpreting that correctly?

That is correct, and the fourth sensor would have both A0 and A1 soldered.
The respective address is then to be used whenever you want to talk to a specific sensor.

For some better info about the usage of that sensor you may want to look at Adafruit’s tutorials
e.g. this one

Awesome !! I got it to work.

image

but I’m having issues with the outputs. Its seems like it’s outputing x40 for both values even when only connect x41

image

#include <adafruit-ina219.h> 
Adafruit_INA219 ina219_0x40 = Adafruit_INA219();
Adafruit_INA219 ina219_0x41 = Adafruit_INA219();

char voltageStr40[30];        /// New String for x40voltage
char voltageStr41[30];        /// New String for x41voltage

////
bool ina219_0x40_active = false;
bool ina219_0x41_active = false;
////
void setup(void) {
    uint32_t currentFrequency;
    Adafruit_INA219 ina219_0x40 = Adafruit_INA219();
    Adafruit_INA219 ina219_0x41 = Adafruit_INA219();
    Serial.begin(115200);
      
    Particle.function("switch", pinSwitch);        
    Particle.variable("voltageStr40", voltageStr40);
    Particle.variable("voltageStr41", voltageStr41);

    ina219_0x40.begin();
    ina219_0x41.begin();
}

void loop(void) 
{
  float shuntvoltage40 = 0;
  float busvoltage40 = 0;
  float loadvoltage40 = 0;
  char voltageStr40[30];  
  
  float shuntvoltage41 = 0;
  float busvoltage41 = 0;
  float loadvoltage41 = 0;
  char voltageStr41[30];  

  shuntvoltage40 = ina219_0x40.getShuntVoltage_mV();
  busvoltage40 = ina219_0x40.getBusVoltage_V();
  loadvoltage40 =(busvoltage40 + shuntvoltage40);
  
  shuntvoltage41 = ina219_0x41.getShuntVoltage_mV();
  busvoltage41 = ina219_0x41.getBusVoltage_V();
  loadvoltage41 =(busvoltage41 + shuntvoltage41);
  
    sprintf(voltageStr40, "%f", loadvoltage40);         
    sprintf(voltageStr41, "%f", loadvoltage41);       

//Particle.publish("loadMe",voltageStr40);          /// Publish voltageStr with publish event name "loadMe"
Serial.println("D40-Voltage: ");Serial.print(voltageStr40);
   delay(1000);
   Serial.println("D41-Voltage: ");Serial.print(voltageStr41);
   delay(1000);
}
 

No stacking pins so I had to improvise. Tested the connection and nothing is shorted. The only pins that are connected are VCC,GND,SCL,SDA

You need to pass 0x41 to the Adafruit_INA219 constructor.

Are you using the INA219 library with an INA260? I’m not sure if the libraries are compatible.


I've taken some time to restructure your application to make use of pointers to increase clarity:

#include "Particle.h"
#include <adafruit-ina219.h>

// Particle: Semi-automatic mode with system thread
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

// Settings
const int VOLTAGE_LEN = 30;
const size_t SENSOR_COUNT = 2;

// Addresses of sensors
const size_t SENSOR_ADDRS[SENSOR_COUNT] = {0x40, 0x41};

// Sensor array
Adafruit_INA219* sensors[SENSOR_COUNT];

// Data gathered from sensors
struct INA219Data {
  float shuntVoltage;
  float busVoltage;
  float loadVoltage;
  char voltageStr[VOLTAGE_LEN];
} readings[SENSOR_COUNT];

// Forward declarations
const char* voltageStr40();
const char* voltageStr41();
void takeReadings();

// SETUP
void setup() {
  // Initialize serial
  Serial.begin(115200);

  // Register Particle variables
  Particle.variable("voltageStr40", voltageStr40);
  Particle.variable("voltageStr41", voltageStr41);

  // Initialize sensor array
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    sensors[i] = new Adafruit_INA219(SENSOR_ADDRS[i]);
    sensors[i]->begin();
  }

  // Connect to Particle cloud
  Particle.connect();
}

// LOOP
void loop() {
  // Update readings
  takeReadings();

  // Print readings to serial
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    Serial.printlnf("D%X-Voltage: %s", SENSOR_ADDRS[i], readings[i].voltageStr);
  }
  delay(1000);
}

// Use calculated particle variables
// https://docs.particle.io/reference/device-os/firmware/boron/#particle-variable-calculated

// Voltage of first sensor
const char* voltageStr40() {
  return readings[0].voltageStr;
}

// Voltage of second sensor
const char* voltageStr41() {
  return readings[1].voltageStr;
}

// Populate reading data
void takeReadings() {
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    INA219Data* reading = &readings[i];
    float shunt = sensors[i]->getShuntVoltage_mV();
    float bus = sensors[i]->getBusVoltage_V();
    reading->loadVoltage = (shunt + bus);
    reading->shuntVoltage = shunt;
    reading->busVoltage = bus;
    snprintf(reading->voltageStr, VOLTAGE_LEN, "%f", reading->loadVoltage);
  }
}

Awesome !! Works like a charm. Thanks so much !!! I want it to publish both values so would I just use this format?

 Particle.publish("loadMe",{{{voltageStr40}}} and {{{voltageStr41}}}); 

You could use another buffer to combine the strings together:

char payload[30];

// Modified
snprintf(payload, sizeof(payload), "%s and %s", readings[0].voltageStr, readings[1].voltageStr);

// Original
snprintf(payload, sizeof(payload), "%s and %s", voltageStr40, voltageStr41);
Particle.publish("loadMe", payload);

Here’s the final working code for future reference. I hate when I read a post with all bit and pieces then can’t see how they fit together at the end. Haha

// This #include statement was automatically added by the Particle IDE.
#include "Particle.h"
#include <adafruit-ina219.h>

// Particle: Semi-automatic mode with system thread
SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

// Settings
const int VOLTAGE_LEN = 30;
const size_t SENSOR_COUNT = 2;

// Addresses of sensors
const size_t SENSOR_ADDRS[SENSOR_COUNT] = {0x40, 0x41};

// Sensor array
Adafruit_INA219* sensors[SENSOR_COUNT];

// Data gathered from sensors
struct INA219Data {
  float shuntVoltage;
  float busVoltage;
  float loadVoltage;
  char voltageStr[VOLTAGE_LEN];
} readings[SENSOR_COUNT];

// Forward declarations
const char* voltageStr40();
const char* voltageStr41();
void takeReadings();

// SETUP
void setup() {
  // Initialize serial
  Serial.begin(115200);

  // Register Particle variables
  Particle.variable("voltageStr40", voltageStr40);
  Particle.variable("voltageStr41", voltageStr41);

  // Initialize sensor array
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    sensors[i] = new Adafruit_INA219(SENSOR_ADDRS[i]);
    sensors[i]->begin();
  }

  // Connect to Particle cloud
  Particle.connect();
}

// LOOP
void loop() {
  // Update readings
  takeReadings();

  // Print readings to serial
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    Serial.printlnf("D%X-Voltage: %s", SENSOR_ADDRS[i], readings[i].voltageStr);
               
    char payload[30];
    snprintf(payload, sizeof(payload), "%s and %s", readings[0].voltageStr, readings[1].voltageStr);
    Particle.publish("loadMe", payload);

    delay(5000);
  }
  
}

// Use calculated particle variables
// https://docs.particle.io/reference/device-os/firmware/boron/#particle-variable-calculated

// Voltage of first sensor
const char* voltageStr40() {
  return readings[0].voltageStr;
}

// Voltage of second sensor
const char* voltageStr41() {
  return readings[1].voltageStr;
}

// Populate reading data
void takeReadings() {
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    INA219Data* reading = &readings[i];
    float shunt = sensors[i]->getShuntVoltage_mV();
    float bus = sensors[i]->getBusVoltage_V();
    reading->loadVoltage = ((bus + (shunt / 1000))*(3.3/1.32));
    reading->shuntVoltage = shunt;
    reading->busVoltage = bus;
    snprintf(reading->voltageStr, VOLTAGE_LEN, "%f", reading->loadVoltage);
  }
}

note- I had to move the delay inside the “for” loop because it was giving me a weird double publish

Now… on to getting the info into a google sheet so I can graph it. Right now I’m using IFTTT to post the data but its not very consistent and is delayed by a few hours.

The double publish is because you put the publish inside the for loop. Move the buffer creation and publish directly after the for loop.

Gotcha,

// LOOP
void loop() {
  char payload[30];
  snprintf(payload, sizeof(payload), "%s and %s", readings[0].voltageStr, readings[1].voltageStr);
  
  // Update readings
  takeReadings();

  // Print readings to serial
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    Serial.printlnf("D%X-Voltage: %s", SENSOR_ADDRS[i], readings[i].voltageStr);
    }

  Particle.publish("loadMe", payload);
  delay(5000);
}


I was referring to this. Otherwise you would be publishing old values.

void loop() {
  // Update readings
  takeReadings();

  // Print readings to serial
  for (size_t i = 0; i < SENSOR_COUNT; ++i) {
    Serial.printlnf("D%X-Voltage: %s", SENSOR_ADDRS[i], readings[i].voltageStr);
  }

  char payload[30];
  snprintf(payload, sizeof(payload), "%s and %s", readings[0].voltageStr, readings[1].voltageStr);
  Particle.publish("loadMe", payload);

  delay(5000);
}

I knew that. haha. Thanks so much for the help.
Next step… getting it into google sheets.

I’ve always found the webhooks service on IFTTT to be nearly instantaneous compared to using the Particle service.

Here is a basic Particle webhook template for using IFTTT webhooks:

1 Like

So I’ve built a google form that adds a new line when I submit the form…
my sequence is…
New line created in google sheets…
Triggers particle function (test)…
Publishes values to google sheets.

(Right now in IFTTT its set up) Google Sheets → Particle…Particle-> google sheets

@nrobinson2000 to do Google sheets-> Webhook… Webhook-> Google Sheets? So the process would be?

google sheets webhook (post) → Particle subscribe then…
particle (publish/post)-> ifttt then…
ifttt-> google sheets?

Hi, you can refer to this app notes here for Google integrations:
https://docs.particle.io/datasheets/app-notes/an011-publish-to-google-sheets/

https://wiki.seeedstudio.com/Grove-I2C-Hub-6Port/
I’ve connected several devices on same “bus” with these

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.