0
votes

Hi I am doing my best to get my head around C++ and OOP. I have written some code that works when I put it all in my main loop. I am now trying to tidy it up and make my own simple library and classes.

My project has an 8 LED sensor array conected to an Arduino board. I am trying read the state of the light sensors. I am using the QTRSensors library which has a calibrate method which I would like to call from my class when I instantiate my class.

Currently I have the following code.

HEADER

#ifndef SEDIMENTLOGGER_H
#define SEDIMENTLOGGER_H

#include <QTRSensors.h>
#include <Arduino.h>


#define NUM_SENSORS 8


class sedimentSensor
{
 public:
  QTRSensorsRC sensor1;//(unsigned char [8], int&, int&, int&);
  QTRSensorsRC sensor2;//(unsigned char [8], int&, int&, int&);

  sedimentSensor(); //default constructor
  ~sedimentSensor();
  void  calibrateSensors();
  unsigned int *SensorValues1(){return sensorValues1;};
  unsigned int *SensorValues2(){return sensorValues2;};
  int SampleDelay(){return sampleDelay;};
  int EmitterPin1();
  unsigned int Position1(){return position1;};
  void Position1(unsigned int value){position1 = value;};
  unsigned int Position2(){return position2;};
  void Position2(unsigned int value){position2 = value;};

 private:
  // Map pins to LED numbers
  // first LED array
  int led1;
  int led2;
  int led3;
  int led4;
  int led5;
  int led6;
  int led7;
  int led8;
  int emitterPin1;
  //second Array
  int led9;
  int led10;
  int led11;
  int led12;
  int led13;
  int led14;
  int led15;
  int led16;
  int emitterPin2;

  int  timeout; // waits for 2.5 seconds for sensor outputs to go low
  long sampleDelay; // 1 second
  int numSensors;

  unsigned int sensorValues1[];
  unsigned int sensorValues2[];

  unsigned int position1;
  unsigned int position2;
};
#endif

My attempt at the class implementation

#include "sedimentLogger.h"
#include <Arduino.h>
#include <QTRSensors.h>

sedimentSensor::sedimentSensor() 
{
  //Constructor
  led1 = 24;
  led2 = 26;
  led3 = 28;
  led4 = 30;
  led5 = 32;
  led6 = 34;
  led7 = 36;
  led8 = 38;
  emitterPin1 = 22;
  //second Array
  led9 = 25;
  led10 = 27;
  led11 = 29;
  led12 = 31;
  led13 = 33;
  led14 = 35;
  led15 = 37;
  led16 = 39;
  emitterPin2 = 23;

  timeout = 2500; // waits for 2.5 seconds for sensor outputs to go low
  sampleDelay = 1000; // 1 second

  sensorValues1[NUM_SENSORS];  
  sensorValues2[NUM_SENSORS];
};

sedimentSensor::~sedimentSensor()
{ 
};

int sedimentSensor::EmitterPin1()
{return emitterPin1;};

void sedimentSensor::calibrateSensors()
{
  sensor1((unsigned char[]){led1,led2,led3,led4,led5,led6,led7,led8},numSensors,timeout,emitterPin1);
  sensor2((unsigned char[]) {led9,led10,led11,led12,led13,led14,led15,led16},numSensors,timeout,emitterPin2);


  unsigned int _delay = 500;
  delay(_delay);
  pinMode(13,OUTPUT);
  for(int i = 0; i<400; i++)
    {
      sensor1.calibrate();
      sensor2.calibrate();
    }
  digitalWrite(13,LOW);

  //TODO WRITE MAX AND MIN VALS TO FILE
  Serial.print("Array 1 Min :: ");
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print (sensor1.calibratedMinimumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  Serial.print("Array 2 Min :: ");
  for (int i = 0;i< NUM_SENSORS; i++)
  {
    Serial.print (sensor2.calibratedMinimumOn[i]);
    Serial.print(' ');
  }

  Serial.println();
  Serial.print("array 1 Max :: ");
  // print the calibration maximum values measured when emitters were on
  for (int i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensor1.calibratedMaximumOn[i]);
    Serial.print(' ');
  }
  Serial.println();
  Serial.print("array 2 Max :: ");
  // print the calibration maximum values measured when emitters were on
  for (int 
  i = 0; i < NUM_SENSORS; i++)
  {
    Serial.print(sensor2.calibratedMaximumOn[i]);
    Serial.print(' ');
  }

  Serial.println();
  Serial.println();
  delay(_delay); 
};

And my main function and loop

#include <QTRSensors.h>
#include <Arduino.h>

#include "sedimentLogger.h"
#include <Wire.h>
#include "/home/marrabld/Programming/Arduino/arduino-1.0/libraries/RTClib/RTClib.h"

sedimentSensor sedLog;//= sedimentSensor();

void setup()
{
  Serial.begin(9600);
  sedLog.calibrateSensors(); 
}

void loop()
{
  sedLog.Position1(sedLog.sensor1.readLine(sedLog.SensorValues1()));
  sedLog.Position2(sedLog.sensor2.readLine(sedLog.SensorValues2()));

  unsigned char i;
  for (i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(sedLog.SensorValues1()[i] * 10/10001);      
      Serial.print(' ');
    }
  Serial.println(sedLog.Position1());
  for (i=0;i < NUM_SENSORS; i++)
    {
      Serial.print(sedLog.SensorValues2()[i]*10/1001);
      Serial.print(' ');
    }
  Serial.print("  ");
  Serial.println(sedLog.Position2());
  delay(sedLog.SampleDelay());

  Serial.println(sedLog.SampleDelay());
  Serial.println(sedLog.EmitterPin1()); 
}

I get the following errror

sedimentLogger.cpp: In member function ‘void sedimentSensor::calibrateSensors()’: sedimentLogger.cpp:47:102: error: no match for call to ‘(QTRSensorsRC) (unsigned char [8], int&, int&, int&)’ sedimentLogger.cpp:48:108: error: no match for call to ‘(QTRSensorsRC) (unsigned char [8], int&, int&, int&)’

I have tried a few different variations like putting the sensor instantiation in my sedimentSensor constructor and a bunch of other things with no luck.

I would appreciate any help and advice getting this to work. I am clearly missing a concept here as well so any coaching advice would similarly be helpful.

2
which one is line 47 in sedimentLogger.cpp?Naveen
Sorry, the line numbers I get out of the compiler don't actually line up with the lines in the file. But I am pretty sure its the first two lines in the CalibrateSensors() function. namely sensor1((unsigned char[]){led1,led2,led3,led4,led5,led6,led7,led8},numSensors,timeout,emitterPin1); sensor2((unsigned char[]) {led9,led10,led11,led12,led13,led14,led15,led16},numSensors,timeout,emitterPin2)Caustic
Have you try to break out (unsigned char[]){led1,led2,led3,led4,led5,led6,led7,led8} the long way yet using a new operator?jakebird451

2 Answers

3
votes

It seems that you are trying to call the constructors of sensor1 and sensor2, but at that point in the code they have already been constructed. Try using their init function instead:

sensor1.init(
    (unsigned char[]){led1,led2,led3,led4,led5,led6,led7,led8},
    numSensors,
    timeout,
    emitterPin1);

sensor2.init(
    (unsigned char[]){led9,led10,led11,led12,led13,led14,led15,led16},
    numSensors,
    timeout,
    emitterPin2);
1
votes

I assume the lines 47 and 48 are the following two:

sensor1((unsigned char[]){led1,led2,led3,led4,led5,led6,led7,led8},numSensors,timeout,emitterPin1);
sensor2((unsigned char[]) {led9,led10,led11,led12,led13,led14,led15,led16},numSensors,timeout,emitterPin2);

The problem is that you try to call the objects as functions. The objects needs to be initialized in the constructor, like this:

sedimentSensor::sedimentSensor() 
    : led1(24), led2(26), /* other variables needing initialization */
      sensor1(/*arguments*/), sensor2(/*arguments*/)
{
    /* .... */
}

For the above to work you need to change the order of the class member variable declarations, as the order member variables are initialized is the same as the order they are declared. In other words, you should put the declaration of sensor1 and sensor2 to be after the variables used to initialize them.