-->
Page 1 of 1

How To: Prevent duplicate coding

PostPosted: Thu May 14, 2020 7:15 am
by KapakoProf
I am rather new in programming and wonder how to compact the code I wrote for using a flexible number of CJMCU-8110 connected to my NodeMCU. In the attached test code below I have 2 connected, but in the near future I want to expand to 3 or 4 and would like to drive that by a variable (f.i. int SensorNumber = 2) instead of duplicating the code for each sensor like I did in the example.

Who can guide me to a solution?

Code: Select all#include <Arduino.h>
#include <Wire.h>    // I2C library
#include "ccs811.h"  // CCS811 library
#include "ClosedCube_HDC1080.h"

CCS811 ccs811_1;
CCS811 ccs811_2;

ClosedCube_HDC1080 HDC1080_1;
ClosedCube_HDC1080 HDC1080_2;

int SDApin;
int SCLpin = D1;

HDC1080_SerialNumber sernum;
char format[12];
bool vBootphase = true;
uint16_t eco2, etvoc, errstat, raw;

void setup() {Serial.begin(115200); while(!Serial){;}}

void loop()
{
  if (vBootphase == true)
  {
    // Channel 1: Setup
    SDApin = D2;
    Wire.begin(SDApin, SCLpin);
    delay(500);
    // ** CCS811 **
    Serial.println("");
    Serial.println("*** CCS1 ***");
    Serial.print("CCS :");
    ccs811_1.set_i2cdelay(50);
    ccs811_1.begin();
    delay(500);
    ccs811_1.start(CCS811_MODE_1SEC);
    delay(1000);
    Serial.print("setup: hardware    version: "); Serial.println(ccs811_1.hardware_version(),HEX);
    Serial.print("setup: bootloader  version: "); Serial.println(ccs811_1.bootloader_version(),HEX);
    Serial.print("setup: application version: "); Serial.println(ccs811_1.application_version(),HEX);
    // HDC1080
    HDC1080_1.begin(0x40);
    Serial.print("Manufacturer ID=0x");
    Serial.println(HDC1080_1.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
    Serial.print("Device ID=0x");
    Serial.println(HDC1080_1.readDeviceId(), HEX); // 0x1050 ID of the device
    Serial.print("Device Serial Number=");
    sernum = HDC1080_1.readSerialNumber();
    sprintf(format, "%02X-%04X-%04X", sernum.serialFirst, sernum.serialMid, sernum.serialLast);
    Serial.println(format);

    // Channel 2: Setup
    SDApin = D6;
    Wire.begin(SDApin, SCLpin);
    delay(500);
    // ** CCS811 **
    Serial.println("*** CCS2 ***");
    // Print CCS811 versions
    Serial.print("CCS2 :");
    ccs811_2.set_i2cdelay(50);
    ccs811_2.begin();
    delay(500);
    ccs811_2.start(CCS811_MODE_1SEC);
    delay(1000);
    Serial.print("setup: hardware    version: "); Serial.println(ccs811_2.hardware_version(),HEX);
    Serial.print("setup: bootloader  version: "); Serial.println(ccs811_2.bootloader_version(),HEX);
    Serial.print("setup: application version: "); Serial.println(ccs811_2.application_version(),HEX);
    // HDC1080
    HDC1080_2.begin(0x40);
    Serial.print("Manufacturer ID=0x");
    Serial.println(HDC1080_2.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
    Serial.print("Device ID=0x");
    Serial.println(HDC1080_2.readDeviceId(), HEX); // 0x1050 ID of the device
    Serial.print("Device Serial Number=");
    sernum = HDC1080_2.readSerialNumber();
    sprintf(format, "%02X-%04X-%04X", sernum.serialFirst, sernum.serialMid, sernum.serialLast);
    Serial.println(format);

    vBootphase = false;
  }
  else
  {
    // Channel 1
    SDApin = D2;
    Wire.begin(SDApin, SCLpin);
    delay(500);
    // ** CCS811 **
    Serial.print("\nSensor connected on: ");
    Serial.print("SDA - ");Serial.print(SDApin); Serial.print(" | SCL - ");Serial.print(SCLpin);
    Serial.print("\n");
    ccs811_1.read(&eco2,&etvoc,&errstat,&raw);
    delay(500);
    Serial.print("ErrStat: ");Serial.print(errstat);Serial.print(" | ");Serial.println(ccs811_1.errstat_str(errstat));
    if(!errstat==CCS811_ERRSTAT_OK)
    {
      Serial.print("CCS811-1: ");
      Serial.println("Failed to read from sensor");
      ccs811_1.begin();
      delay(500);
      ccs811_1.start(CCS811_MODE_1SEC);
    }
    else
    {
      Serial.print("CCS811-1: ");
      Serial.print("eco2=");    Serial.print(eco2);     Serial.print(" ppm | ");
      Serial.print("etvoc=");   Serial.print(etvoc);    Serial.print(" ppb");
      Serial.print("\n");
    }
    // ** HDC1080 **
    Serial.print("T="); Serial.print(HDC1080_1.readTemperature()); Serial.print("C");
    Serial.print(", RH="); Serial.print(HDC1080_1.readHumidity()); Serial.println("%");

    // Channel 2
    SDApin = D6;
    Wire.begin(SDApin, SCLpin);
    delay(500);
    // ** CCS811 **
    Serial.print("Sensor connected on: ");
    Serial.print("SDA - ");Serial.print(SDApin); Serial.print(" | SCL - ");Serial.print(SCLpin);
    Serial.print("\n");
    ccs811_2.read(&eco2,&etvoc,&errstat,&raw);
    delay(500);
    Serial.print("ErrStat: ");Serial.print(errstat);Serial.print(" | ");Serial.println(ccs811_2.errstat_str(errstat));
    if(errstat!=CCS811_ERRSTAT_OK)
    {
      Serial.print("CCS811-2: ");
      Serial.println("Failed to read from sensor");
      ccs811_1.begin();
      delay(500);
      ccs811_2.start(CCS811_MODE_1SEC);
    }
    else
    {
      Serial.print("CCS811-2: ");
      Serial.print("eco2=");    Serial.print(eco2);     Serial.print(" ppm | ");
      Serial.print("etvoc=");   Serial.print(etvoc);    Serial.print(" ppb");
      Serial.print("\n");
    }
    // ** HDC1080 **
    Serial.print("T="); Serial.print(HDC1080_1.readTemperature()); Serial.print("C");
    Serial.print(", RH="); Serial.print(HDC1080_1.readHumidity()); Serial.println("%");

    delay(10000);
  }
}

Re: How To: Prevent duplicate coding

PostPosted: Thu May 14, 2020 9:20 am
by KapakoProf
In the mean time someone outside this forum suggested to try using a vector. Well it did work out.
Code: Select allstd::vector<CCS811> vec_of_CCS811(2);
int SDApin[]={D2,D6};

and
Code: Select all    for (int i = 0; i < vec_of_CCS811.size(); ++i)
    {
      Wire.begin(SDApin[i], SCLpin);
      delay(500);
      Serial.println("");
      Serial.println("*** CCS1 ***");
      Serial.print("CCS :");
      vec_of_CCS811[i].set_i2cdelay(50);
      vec_of_CCS811[i].begin();
      delay(500);
      vec_of_CCS811[i].start(CCS811_MODE_1SEC);
      ...
    }

Re: How To: Prevent duplicate coding

PostPosted: Thu May 14, 2020 10:05 am
by btidey
You should be able to create arrays of those sensor objects rather than creating them one at a time. Then you can use the index to select the sensor you are dealing with. That allows you to either pass in an index into common code or to iterate over the sensors instead of duplicating code.

e.g declare it something like

Code: Select allint sensorCount = 2;
CCS811 ccs811[sensorCount];

ClosedCube_HDC1080 HDC1080[sensorCount];