Adding a delay to I2C sensor run thru multiplexer

Is it possible to place a delay between each of the sensor so that the MKR1010 is sending data a slower rate?

jim


#define BLYNK_PRINT Serial
#include <Wire.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>


//#include <BlynkSimpleWiFiShield101.h>
#include <Adafruit_MCP9808.h>
#include <Adafruit_Si7021.h>
#include "HX711.h"


// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "cShY4GW_GMJCO0Q8BGYqviAHJt09I5_D";

// Set password to "" for open networks.
char ssid[] = "Bxxxxxx";
char pass[] = "Fxxxxxxxxxxxxx";

#define calibration_factor -4800.0 

#define DOUT  2  //#define scale DT (2)
#define CLK  3   //#define scale CL (3)

HX711 scale;

#define TCAADDR 0x70

#define TCAADDR       0x70
#define TEMP1_ADDR    0x18
#define TEMP2_ADDR    0x18
#define TEMP3_ADDR    0x18
#define HUM1_ADDR     0x40
#define HUM2_ADDR     0x40


// Assign unique ID to each sensor
Adafruit_MCP9808 temp1 = Adafruit_MCP9808();
Adafruit_MCP9808 temp2 = Adafruit_MCP9808();
Adafruit_MCP9808 temp3 = Adafruit_MCP9808();
Adafruit_Si7021 hum1 = Adafruit_Si7021();
Adafruit_Si7021 hum2 = Adafruit_Si7021();
//HS711 scale1 = HS711(6)

float temperature1;
float temperature2;
float temperature3;

float humidity1;
float humidity2;

long int loadcell;
long int tare;

void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

// standard Arduino setup()
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);

  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0

  Serial.println("Readings:");

//setup temp sensors:
tcaselect(7);
  if (!temp1.begin(0x18)) {
    Serial.println("Couldn't find Temp1! Check your connections and verify the address is correct.");
    while (1);
  }

   Serial.println("Found MCP9808, Sensor 1!");

  temp1.setResolution(0); // sets the resolution mode of reading, the modes are defined in the table bellow:
  // Mode Resolution SampleTime
  //  0    0.5°C       30 ms
  //  1    0.25°C      65 ms
  //  2    0.125°C     130 ms
  //  3    0.0625°C    250 ms

tcaselect(6);
  if (!temp2.begin(0x18)) {
    Serial.println("Couldn't find Temp2! Check your connections and verify the address is correct.");
    while (1);
  }

   Serial.println("Found MCP9808, Sensor 2!");

  temp2.setResolution(0); 


tcaselect(5);
  if (!temp3.begin(0x18)) {
    Serial.println("Couldn't find Temp3! Check your connections and verify the address is correct.");
    while (1);
  }

     Serial.println("Found MCP9808, Sensor 2!");

  temp3.setResolution(0); 


}

void loop(void) 
{
  
  tcaselect(7);
  //temp1.getEvent(&event);
  temperature1=temp1.readTempF();
  //Display the results
  Blynk.virtualWrite(V7,temperature1); 

  tcaselect(6);
  //temp2.getEvent(&event);
  temperature2=temp2.readTempF();
  Blynk.virtualWrite(V6,temperature2); 

  tcaselect(5);
  //temp3.getEvent(&event);
  temperature3=temp3.readTempF();
  Blynk.virtualWrite(V5,temperature3);

  tcaselect(4);
  //hum4.getEvent(&event);
  humidity1=hum1.readHumidity();
  Blynk.virtualWrite(V4,humidity1);

  tcaselect(3);
  //hum5.getEvent(&event);
  humidity2=hum2.readHumidity();
  Blynk.virtualWrite(V3,humidity2);

  Serial.print("Reading: ");
  Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
  Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();
  Blynk.virtualWrite(V2, scale.get_units());
    }

You might want to take a look at this:

I will take a look thank you, once done will this help in someway or is this just a general statement on the script?

Jim

When you read the “keep your void loop clean” document you’ll see that you’ll be moving everything except Blynk.run out of your void loop and calling it with a timer. If you want sensor readings every 30 seconds then set that timer frequency to 30 seconds (30,000 milliseconds) and that will solve your problem.

Pete.

it is thank you. I read the information from the link that was sent to me. It made sense, working out how to apply the timer to multiple sensors. can multiple BlynkWrite commands live within one BlynkTimer or do they each need their own?

Jim

Yes, provided you don’t do more than one virtualWrite per 100ms.

Pete.

Pete,

One more question and I think I’m ready try a new program. I copied this line of code from an example sketch Blynk.virtualWrite(V5, millis() / 1000)

If I am understanding this correctly this line would write to virtual pin 5 every 1000 milliseconds. So if I have 4 virtual pins to write to would i need to do this;
Blynk.virtualWrite(V5, millis() / 1000)
Blynk.virtualWrite(V6, millis() / 1500)
Blynk.virtualWrite(V7, millis() / 2000)
Blynk.virtualWrite(V8, millis() / 2500)

Jim

No, you’re not understanding correctly.
The C++ function millis() returns the number of milliseconds since the device booted.
millis()/1000 will give you the number of seconds since the device booted.
Blynk.virtualWrite(V5, millis() / 1000) will write the number of seconds since the device booted to the widget connected to virtual pin V5.

I guess that you found a bit of code with a function called something like sendUptime that contained the Blynk.virtualWrite(V5, millis() / 1000) command. If you study that code a bit closer you’ll see that the void setup contains a timer which calls the sendUptime function every 5 seconds or so. This timer is what controls the timing frequency, not the /1000 part of the command that you’ve quoted.

Pete.

Pete,

I go the code from the sample that was on the bottom of the Keep your void loop() clean link I was sent Can you suggest sample code or tutorial on the setup for BlynkTImer?

Jim

Hi Jim,
The example of BlynkTimer in the “Keep your void loop clean” document is an excellent starting point.From your previous questions I assume that you are trying to set-up multiple timers, but I don’t think that is necessary, based on your 30ms read time per sensor.

It’s difficult to provide an example for you based on your code, as I can’t understand how it works. I can’t understand why you aren’t putting the majority of code in your void tcaselect(uint8_t i) function and calling that with an incrementing parameter to get your readings.

Pete.

Thanks Pete,

unfortunately I have no clue what an incrementing parameter is. I can take apart just about any mechanical device and put it back together. I even repair my Mac computers when the hardware fail. but unfortunately I have no idea how they work except on a rudimentary level. This is not on a lack wanting to learn, It’s just my head is wired that way.

So, perhaps it’s time to just contract this code out, can you point me in the direction of someone or a site that can help?

Jim

Your problem will be that there is no way to accurately test your code without the hardware that you are using - including the multiplexer and the sensors.
Did parts of this code, in particular the void tcaselect(uint8_t i) function, come from somewhere else?
If so, then seeing the source code may help me to understand how it should work in theory.

Pete.

It came from this link

Okay, I’ll take a look at that, and your code, later and see if I can put something together for you to test.

Pete.

I know nothing about this multiplexor, or your sensors and their associated libraries, but I’ve had a stab at re-writing your code.

To keep it simple, and because you have three different types of sensors that need to be handled in different ways, I’ve gone for the ‘longhand’ approach rather than parameterising the calls to the multiplexor library. This should make it easier for you to follow and debug…

#define BLYNK_PRINT Serial
#include <Wire.h>
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>

#include <Adafruit_MCP9808.h>
#include <Adafruit_Si7021.h>
#include "HX711.h"

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "cShY4GW_GMJCO0Q8BGYqviAHJt09I5_D";

// Set password to "" for open networks.
char ssid[] = "Bxxxxxx";
char pass[] = "Fxxxxxxxxxxxxx";

int reading_frequency = 5000; // How often (in milliseconds) should we take the readings

#define calibration_factor -4800.0 

#define DOUT  2  //#define scale DT (2)
#define CLK  3   //#define scale CL (3)

HX711 scale;

#define TCAADDR       0x70

#define TEMP1_ADDR    0x18
#define TEMP2_ADDR    0x18
#define TEMP3_ADDR    0x18
#define HUM1_ADDR     0x40
#define HUM2_ADDR     0x40


// Assign unique ID to each sensor
Adafruit_MCP9808 temp1 = Adafruit_MCP9808();
Adafruit_MCP9808 temp2 = Adafruit_MCP9808();
Adafruit_MCP9808 temp3 = Adafruit_MCP9808();
Adafruit_Si7021 hum1 = Adafruit_Si7021();
Adafruit_Si7021 hum2 = Adafruit_Si7021();
//HS711 scale1 = HS711(6)

float temperature1;
float temperature2;
float temperature3;

float humidity1;
float humidity2;

float weight;

long int loadcell;
long int tare;

// Initialise the Blynk timer object
BlynkTimer timer;


void tcaselect(uint8_t i)
{
  if (i > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}


void initialise_temp_sensors()
{
  // This function is called from void setup and initialises your temperature and weight sensors
  
  tcaselect(7);
  if (!temp1.begin(0x18))
  {
    Serial.println("Couldn't find Temp1! Check your connections and verify the address is correct.");
    while (1);
  }
  Serial.println("Found MCP9808, Sensor 1!");
  temp1.setResolution(0); // sets the resolution mode of reading, the modes are defined in the table bellow:


  tcaselect(6);
  if (!temp2.begin(0x18))
  {
    Serial.println("Couldn't find Temp2! Check your connections and verify the address is correct.");
    while (1);
  }
  Serial.println("Found MCP9808, Sensor 2!");
  temp2.setResolution(0); 


  tcaselect(5);
  if (!temp3.begin(0x18))
  {
    Serial.println("Couldn't find Temp3! Check your connections and verify the address is correct.");
    while (1);
  }
  Serial.println("Found MCP9808, Sensor 2!");
  temp3.setResolution(0);


  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
  scale.tare(); //Assuming there is no weight on the scale at start up, reset the scale to 0
}


void take_readings()
{
  // This function is called by a timer and takes reading from each sensor nad prints them, as well as sending them to Blynk
  
  // Take temp1 readings...
  tcaselect(7);
  temperature1=temp1.readTempF();
  Serial.print("temperature1 = ");
  Serial.println(temperature1);
  Serial.println();   
  Blynk.virtualWrite(V7,temperature1); 

  Blynk.run();

  // Take temp2 readings...
  tcaselect(6);  
  temperature2=temp2.readTempF();
  Serial.print("temperature2 = ");
  Serial.println(temperature2);
  Serial.println();   
  Blynk.virtualWrite(V6,temperature2); 

  Blynk.run();

  // Take temp3 readings...
  tcaselect(5);
  temperature3=temp3.readTempF();
  Serial.print("temperature3 = ");
  Serial.println(temperature3);
  Serial.println();   
  Blynk.virtualWrite(V5,temperature3);

  Blynk.run();

  // Take hum1 readings...
  tcaselect(4);
  humidity1=hum1.readHumidity();
  Serial.print("humidity1 = ");
  Serial.println(humidity1);
  Serial.println();   
  Blynk.virtualWrite(V4,humidity1);

  Blynk.run();

  // Take hum2 readings...
  tcaselect(3);
  humidity2=hum2.readHumidity();
  Serial.print("humidity2 = ");
  Serial.println(humidity2);
  Serial.println();  
  Blynk.virtualWrite(V3,humidity2);

  // Take weight readings...
  weight = scale.get_units();
  Serial.print("Scale reading: ");
  Serial.print(weight, 1); //scale.get_units() returns a float
  Serial.println(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
  Serial.println();
  Blynk.virtualWrite(V2, weight);
}


// standard Arduino setup()
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  initialise_temp_sensors();
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(reading_frequency, take_readings);
}


void loop() 
{
  Blynk.run();
  timer.run();
}

Change this line near the top of the sketch…

int reading_frequency = 5000; // How often (in milliseconds) should we take the readings

if you want to read the sensors at a different frequency. 5000ms = 5 seconds

Pete.

Pete,

Thank you so much for this redo, I had a chance today to upload it which went great. Unfortunately it still goes offline within 30 seconds of connection. It still feels like way too much data is getting it kicked out. I think I’m going to strip out a few sensors to see if that helps. At least I’ll know its a data overload at Blynk that is getting to booted.

Jim

Five virtualWrites every 5 second is fine.

I suspect that the issue lies with the WiFiNINA library, as it seems you’re not the only one with this issue…

If modifying the library as suggested in that post isn’t something you’re comfortable with then you could try this library instead…

Or maybe go for a more mainstream board such as a NodeMCU or Wemos D1 Mini.

Pete.

1 quick question, the sketch you did is not connecting to wifi. not even getting info on the serial screen. The login code is identical to my last sketch I did and that sketch is connecting just fine. I’m testing the new sketch without the sensors connected, with no data coming from the sensors will that stall the timer and therefore stop the wifi and serial print?

Jim

Do you have the correct baud rate (9600) selected in your serial monitor?

I have no idea I’m afraid, as I said before, I’m not familiar with any of the hardware you’re using.

Pete.

Just an FYI, I’m going to post the sketch you sent see if someone can ID what is keeping the serial print from working and/or why the sketch is not trying to connect to wifi. I sure can’t see what it is.

Jim