Combining 2 working sketches together

I have a sketch which carries out a PID routine. It uses an LDR to vary the output to the led. It works great. However I have another sketch which measures lux using the veml 7700. My intention is to remove the LDR and replace it with the Lux sensor.
Not much experience with the arduino but was hoping to join the two sketches together.
the two sketches are shown below. My thinking is to add the PID sketch to the adafruit sketch, remove the photocellPin variable and pin since that is no longer required and then use the 'veml.readLux()' to return the sensors light reading.

#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();

void setup() {

  while (!Serial) {
    delay(10);
  }
  Serial.begin(115200);
  Serial.println("Adafruit VEML7700 Test");

  if (!veml.begin()) {
    Serial.println("Sensor not found");
    while (1);
  }
  Serial.println("Sensor found");

  veml.setGain(VEML7700_GAIN_1);// set gain = 1
  veml.setIntegrationTime(VEML7700_IT_100MS);// set 100ms exposure time

  Serial.print(F("Gain: "));
  switch (veml.getGain()) {
    case VEML7700_GAIN_1: Serial.println("1"); break;
    case VEML7700_GAIN_2: Serial.println("2"); break;
    case VEML7700_GAIN_1_4: Serial.println("1/4"); break;
    case VEML7700_GAIN_1_8: Serial.println("1/8"); break;
  }

  Serial.print(F("Integration Time (ms): "));
  switch (veml.getIntegrationTime()) {
    case VEML7700_IT_25MS: Serial.println("25"); break;
    case VEML7700_IT_50MS: Serial.println("50"); break;
    case VEML7700_IT_100MS: Serial.println("100"); break;
    case VEML7700_IT_200MS: Serial.println("200"); break;
    case VEML7700_IT_400MS: Serial.println("400"); break;
    case VEML7700_IT_800MS: Serial.println("800"); break;
  }

  //veml.powerSaveEnable(true);
  //veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4);

  veml.setLowThreshold(10000);
  veml.setHighThreshold(20000);
  veml.interruptEnable(true);
}

void loop() {
  Serial.print("Lux: "); Serial.println(veml.readLux());
  Serial.print("White: "); Serial.println(veml.readWhite());
  Serial.print("Raw ALS: "); Serial.println(veml.readALS());

  uint16_t irq = veml.interruptStatus();
  if (irq & VEML7700_INTERRUPT_LOW) {
    Serial.println("** Low threshold");
  }
  if (irq & VEML7700_INTERRUPT_HIGH) {
    Serial.println("** High threshold");
  }
  delay(500);
}
#include <PID_v1.h>

double Setpoint; // pidsetpoint.desired level of brightness
double photocellReading; //input
double ledBrightness; // output

double kp = 0.1, ki = 2, kd = 0; // tuning values

const int photocellPin = 0; // the analog pin A0
const int ledPin = 9; // the digital pin output is pin number 9

//setup the PID

PID myPID(&photocellReading, &ledBrightness, &Setpoint, kp, ki, kd, DIRECT);


void setup() {
  Serial.begin(115200);

  Setpoint = 800;
  myPID.SetSampleTime(4);// sample time 4ms
  myPID.SetMode(AUTOMATIC);
  myPID.SetTunings(kp, ki, kd);
  delay(1000);

}

void loop() {
  photocellReading = analogRead(photocellPin);
  myPID.Compute();
  analogWrite(ledPin, ledBrightness);

  Serial.print(ledBrightness);
  Serial.print(",");

  Serial.println(photocellReading);

}

I'm thinking of changing line
photocellReading= analogRead(photocellpin);
to
photocellReading= veml.readlux();
from the pid code.
Any help and advice before I screw things up would be much appreciated thanks

The trick in ‘merging’ two programs… is to understand it’s not usually the right way to go.

Your first step is to UNDERSTAND every line of the programs you want to combine, then decide which most closely resembles what you want to do…

Then, with your newfound understanding, you can hopefully weave the second program functionality into the first.

If the gap is too wide, you may need to start from scratch, but you will already know how the individual parts work, and can bring your progressive combined efforts here, and we can help push you over the line.

1 Like

I’d agree with that - trying to merge two programs, I presume, written by someone else, is not a great way forward .
If you manage it and it works , you don’t really learn so much and it will be difficult to modify later on. ( as you don’t understand it ).
Better to use them for inspiration for your own code

1 Like

The above is very good advice.

But if you want to know a specific way of merging two codes I show you how to do it here:-
http://www.thebox.myzen.co.uk/Tutorial/Merging_Code.html

Note that this might not always work like you might want, as in the end it does one code and then the other. So if one code contains a big delay that will run before the other code can be run.

1 Like

the sketch that reads the lux sensor, I have managed to shorten it and still able to get a lux reading via the serial monitor. that code is shown below

#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();// assign one variable the value of another

void setup() {

  while (!Serial) {
    delay(10);  //wait for serial port to connect
  }
  Serial.begin(115200);
  Serial.println("Adafruit VEML7700 Test");

  if (!veml.begin()) {
    Serial.println("Sensor not found");
    while (1);
  }
  Serial.println("Sensor found");

  veml.setGain(VEML7700_GAIN_1);// set gain = 1
  veml.setIntegrationTime(VEML7700_IT_100MS);// set 100ms exposure time



  //veml.powerSaveEnable(true);
  //veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4);

  veml.setLowThreshold(10000);
  veml.setHighThreshold(20000);
  veml.interruptEnable(true);
}

void loop() {
  Serial.print("Lux: "); Serial.println(veml.readLux());
  uint16_t irq = veml.interruptStatus();
  if (irq & VEML7700_INTERRUPT_LOW) {
    Serial.println("** Low threshold");
  }
  if (irq & VEML7700_INTERRUPT_HIGH) {
    Serial.println("** High threshold");
  }
  delay(500);
}

I then merged the two together as what made sense to me as shown below

#include <PID_v1.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();// assign one variable the value of another

double Setpoint; // pidsetpoint. desired level of brightness
double photocellReading; // light sensor reading
double ledBrightness; // output to led
double kp = 0.1, ki = 2, kd = 0; // pid tuning values
float photocellPin = veml.readLux(); // assign variable photocell value of variable veml.readLux(). i can only assume this variable is in the adafruit library
int ledPin = 9; // led is pin 9 output pwm

// setup the pid
PID myPID(&photocellReading, &ledBrightness, &Setpoint, kp, ki, kd, DIRECT);



void setup() {

  Serial.begin(115200);
  Serial.println("Adafruit VEML7700 Test");

  if (!veml.begin()) {
    Serial.println("Sensor not found");
    while (1);
  }
  Serial.println("Sensor found");

  veml.setGain(VEML7700_GAIN_1);// set gain = 1
  veml.setIntegrationTime(VEML7700_IT_100MS);// set 100ms exposure time
  //veml.powerSaveEnable(true);
  //veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4);

  veml.setLowThreshold(10000);
  veml.setHighThreshold(20000);
  veml.interruptEnable(true);

  Setpoint = 300; // desired level of lux
  myPID.SetSampleTime(4); // this setting fine tuned the pid loop
  myPID.SetMode(AUTOMATIC);// part of pid
  myPID.SetTunings(kp, ki, kd); //part of pid
  delay(1000);
}

void loop() {

  photocellReading = veml.readLux(); // assign the variable photocellReading the value of veml.readLux() which is a measurement from the lux sensor
  myPID.Compute();
  analogWrite(ledPin, ledBrightness);//dims led according to pid algorithm
  Serial.print("Lux: "); Serial.println(veml.readLux());
  uint16_t irq = veml.interruptStatus();
  if (irq & VEML7700_INTERRUPT_LOW) {
    Serial.println("** Low threshold");
  }
  if (irq & VEML7700_INTERRUPT_HIGH) {
    Serial.println("** High threshold");
  }
  delay(500);
}

now i'm not getting any data going to the serial monitor, not even the first print command. I tried using the printfunction in the void loop for debugging purposes but that never printed anything to serial monitor as well.
Hoping somebody can help
thanks

The trick with merging programs (and indeed any development work) is to do it gradually. Pick one of the sketches and test it. Then add the smallest possible piece of the other one (probably the #include) and test again. Rinse and repeat until it breaks and you'll have a pretty good clue that the last thing you added is a problem.

As you have it now, all combined, you lack any information at all about where things went wrong.

Why is this missing from the "combined code"?

my understanding is that that piece of code sets up the serial port. But I already have a piece of code that does that the serialbegin function
The code below works. I have just added the PID library to the lux sensor sketch

#include <PID_v1.h>
#include "Adafruit_VEML7700.h"

Adafruit_VEML7700 veml = Adafruit_VEML7700();// assign one variable the value of another

void setup() {

  Serial.begin(115200);
  Serial.println("Adafruit VEML7700 Test");

  if (!veml.begin()) {
    Serial.println("Sensor not found");
    while (1);
  }
  Serial.println("Sensor found");

  veml.setGain(VEML7700_GAIN_1);// set gain = 1
  veml.setIntegrationTime(VEML7700_IT_100MS);// set 100ms exposure time



  //veml.powerSaveEnable(true);
  //veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4);

  veml.setLowThreshold(10000);
  veml.setHighThreshold(20000);
  veml.interruptEnable(true);
}

void loop() {
  Serial.print("Lux: "); Serial.println(veml.readLux());
  uint16_t irq = veml.interruptStatus();
  if (irq & VEML7700_INTERRUPT_LOW) {
    Serial.println("** Low threshold");
  }
  if (irq & VEML7700_INTERRUPT_HIGH) {
    Serial.println("** High threshold");
  }
  delay(500);
}

Now it seems I have to slowly put the PID code into the lux sensor sketch and test until it breaks
thanks for helping

On some Arduinos e.g. Leonardo, you need to wait for the Serial port object to be initialized before you use it which is what the loop that Grumpy Mike highlighted is doing.

Which one do you have?

the uno