How To: Prevent duplicate coding
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:
#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
What about using arrays? An array of CCS811, an array of int for SDApin, an array of ClosedCube_HDC1080 etc? Then use a loop to deal with each device. Just needs one set if code for however many devices there are.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
2kaud
What about using arrays? An array of CCS811, an array of int for SDApin, an array of ClosedCube_HDC1080 etc? Then use a loop to deal with each device. Just needs one set if code for however many devices there are.
Thank you for the thought. I tried that, but it did not work out while the CCS does not read accurate values over 2 sensors when using only 1 alias. Apparently you need 1 per sensor.
In the mean time somebody suggested to use a vector. This I checked and indeed it did.
Code:
std::vector<CCS811> vec_of_CCS811(2);
int SDApin[]={D2,D6};
and
Code:
for (int i = 0; i < vec_of_CCS811.size(); ++i){
Wire.begin(SDApin[i], SCLpin);
vec_of_CCS811[i].set_i2cdelay(50);
vec_of_CCS811[i].begin();
.......}
Re: How To: Prevent duplicate coding
I suggested using arrays as I wasn't sure Arduino supported vectors - and you know in advance how many elements are needed. Your SDApin is an array, and CCS811 could be as well:
Code:
#define NO_SENSE 2
#define C_DELAY 50
CCS811 ccs[NO_SENSE];
const int SDApin[NO_SENSE]={D2, D6};
...
for (int i = 0; i < NO_SENSE; ++i){
Wire.begin(SDApin[i], SCLpin);
ccs[i].set_i2cdelay(C_DELAY);
ccs[i].begin();
.......}
Using a vector really only makes sense in these cases where the number of elements isn't known at compile time - or you need some specific 'feature' of a vector.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
2kaud
I suggested using arrays as I wasn't sure Arduino supported vectors - and you know in advance how many elements are needed. Your SDApin is an array, and CCS811 could be as well:
Code:
#define NO_SENSE 2
#define C_DELAY 50
CCS811 ccs[NO_SENSE];
const int SDApin[NO_SENSE]={D2, D6};
...
for (int i = 0; i < NO_SENSE; ++i){
Wire.begin(SDApin[i], SCLpin);
ccs[i].set_i2cdelay(C_DELAY);
ccs[i].begin();
.......}
Using a vector really only makes sense in these cases where the number of elements isn't known at compile time - or you need some specific 'feature' of a vector.
Thanks. I will retry, because I also do understand using vectors also may have an impact on the limited available memory in NodeMCU.
Re: How To: Prevent duplicate coding
Unless you need them, IMO I'd avoid using C++ containers and C++ STL (algorithms etc). When I did some Arduino programming a few years ago I basically just used C with some specific Arduino extensions.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
KapakoProf
Thanks. I will retry, because I also do understand using vectors also may have an impact on the limited available memory in NodeMCU.
Also works and is even better fitting in the rest of the project coding.
Learned a lot for you both. Thanks
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
KapakoProf
how to compact the code
Why not simply use functions and structs?
One function for example could be called setup. It would expect a struct as input. The struct contains all data that is necessary to setup a channel. The function operates on the struct only. It means that by passing different structs to setup, different channels are being setup.
The algorithm part of the "code" is now present once in the setup function, and the data part of the "code" is present in the structs and there are as many structs as there are channels. It means duplication is minimal.
The structs must be stored somewhere. There are several standard data structures available for that: arrays, vectors, list, sets, maps etcetera. All will "work", the question is which is most suitable.
There are more advanced ways of introducing abstractions in programs but using functions is the most fundamental. It belongs to a programming paradigm called procedural programming.
Re: How To: Prevent duplicate coding
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
salem_c
If must be rather tedious not to respond constructively but only scour the internet seeking out duplicate posts. Well done, sir.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
Arjay
If must be rather tedious not to respond constructively but only scour the internet seeking out duplicate posts. Well done, sir.
He responded on the other site.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
2kaud
He responded on the other site.
Fantastic, why post here that it's a dupe, then?
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
Arjay
Fantastic, why post here that it's a dupe, then?
So that people here become aware of the double post and can avoid wasting time on something that has already been sorted elsewhere. It's very annoying to find out that your effort was for nothing.
The problem is that the perspective of the double posting OP is different. It makes sense to start several independent solution processes. It increases the chance of coming closer to an optimal solution. This strategy is used commercially at competitive programming sites like Topcoder,
https://en.wikipedia.org/wiki/Topcoder
The difference is that if you post at Topcoder you are aware of the setup and you get paid if you "win" but at an ordinary forum you don't. You do it voluntarily just to help (and maybe get some gratitude for it). So in an ordinary forum situation you tend to dislike double posting because you feel you are being used by a cunning OP.
This is a dilemma but I would recommend OPs to be open about double posting in order not to piss people off because then they may get no solution at all. In this case the OP indicated double posting but without actually saying so in #3,
"In the mean time somebody suggested"
It could have been made clear already at the outset with a link to the other site. I think openness is the best strategy. The OP gets a wider audience for the question and no one feels offended.
Re: How To: Prevent duplicate coding
Just because someone has double posted doesn't mean it has been answered elsewhere. At any rate, it amazes that folks have the bandwidth to visit other sites enough to discover when something has been double posted.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
Arjay
Just because someone has double posted doesn't mean it has been answered elsewhere.
No but if you know about the double post you can better decide if and how you want to reply. I cannot think of any situation where awareness of the existence of a double post would be in the way.
Quote:
At any rate, it amazes that folks have the bandwidth to visit other sites enough to discover when something has been double posted.
You don't need much bandwidth today. There aren't that many programming forums and the overall activity is much slower than it used to be. I used to post at the Sun Java forum in its heyday and there was hundreds of questions each day and hundreds of replies to each from a large community of regular posters. Those were the days...
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
wolle
No but if you know about the double post you can better decide if and how you want to reply. I cannot think of any situation where awareness of the existence of a double post would be in the way.
You don't need much bandwidth today. There aren't that many programming forums and the overall activity is much slower than it used to be. I used to post at the Sun Java forum in its heyday and there was hundreds of questions each day and hundreds of replies to each from a large community of regular posters. Those were the days...
My bandwidth is limited to this site. If I see a question I know the answer to I generally will respond. It makes no difference if the question has been posted to other sites that I don't visit. To me, posting that something has been cross posted is just noise.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
Arjay
To me, posting that something has been cross posted is just noise.
To me it's relevant information. It's because I adapt my replies to the existing contributions. If there's an identical discussion going on elsewhere I like to know. Ideally the OP should volunteer this information already at the outset.
Is there a Codeguru policy on this? Is it considered bad/wrong to double post or to post information about double posting? If not then it's probably your post #10 that makes the largest noise in this thread. It's an ad hominem attack on a fellow forum member.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
wolle
To me it's relevant information. It's because I adapt my replies to the existing contributions. If there's an identical discussion going on elsewhere I like to know. Ideally the OP should volunteer this information already at the outset.
Is there a Codeguru policy on this? Is it considered bad/wrong to double post or to post information about double posting? If not then it's probably your post #10 that makes the largest noise in this thread.
Perhaps but then you don't have to deal with reported posts from the one person that complains about duplicate posts.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
Arjay
Perhaps but then you don't have to deal with reported posts from the one person that complains about duplicate posts.
I don't understand the meaning of this reply.
You made an ad hominem attack on a forum member in #10 for having reported a double post. That's quite serious coming from a moderator and especially if reporting double posts is not wrong according to the rules of the forum.
That's my view but I drop this now.
Re: How To: Prevent duplicate coding
Quote:
Originally Posted by
wolle
I don't understand the meaning of this reply.
You made an ad hominem attack on a forum member in #10 for having reported a double post. That's quite serious coming from a moderator and especially if reporting double posts is not wrong according to the rules of the forum.
That's my view but I drop this now.
In your eyes that maybe is what it appears, but there is more to the story that you don't know about. I could explain, but...
Re: How To: Prevent duplicate coding
Hello guys!
I think the discussion i this thread runs out of the goal stated by OP.
So let's stop such kind of talking.
You could however continue the off-topic discussions using private messaging.