Go Down

Topic: How to Create Private Instance Variable in Header File (Read 1 time) previous topic - next topic

acapodie

Apr 08, 2013, 01:20 am Last Edit: Apr 08, 2013, 01:29 am by acapodie Reason: 1
Hello all,

I'm trying to create an instance of a library I've written called H_Bridge_Controller in another library called Acrobot (it's the name of the robot).  I've used the H_Bridge_Controller library in multiple projects so I know it's working fine.  The problem is with with declaring an instance of H_Bridge_Controller in Acrobot.  I had to create a dummy constructor in H_Bridge_Controller that takes no arguments because I declare the instance variables _HBridge_vert1, _HBridge_vert2 and _HBridge_horiz3 in Acrobot.h.  I tried to make the delcaration of these instance variables similar to the following form: H_Bridge_Controller _HBridge_vert1(const int VERT1_IN1, const int VERT1_IN2, const int VERT1_EN), but it will not let me use this constructor in the Acrobot.h header file. I get the error "expected ',' or '...' before numeric constant," which also occurs when I try to call H_Bridge_Controller _HBridge_vert1(VERT1_IN1, VERT1_IN2, VERT1_EN) or H_Bridge_Controller _HBridge_vert1(int VERT1_IN1, int VERT1_IN2, int VERT1_EN).  Please note that VERT1_IN1, etc. are #define's in another header file entitled Acrobot_Pin_Definitions.h.  I tried printing out the pin values after calling the Acrobot::Acrobot() constructor, and all the pin values (in1, in2, en) for the H_Bridge_Controller objects inside the instance of the Acrobot class are set to 0, despite calling the following 3 lines of code in the Acrobot::Acrobot() constructor:
Code: [Select]
H_Bridge_Controller _HBridge_vert1(VERT1_IN1, VERT1_IN2, VERT1_EN);
H_Bridge_Controller _HBridge_vert2(VERT2_IN1, VERT2_IN2, VERT2_EN);
// H_Bridge_Controller _HBridge_horiz3(HORIZ_IN1, HORIZ_IN2, HORIZ_EN);


Does anyone know the proper way of defining these instance variables in the Acrobot.h header file so that they take in the correct pin values?  I could probably work around this problem by adding a function to set the pin values, but I'd prefer to do the declaration of these instance values properly.  Thanks in advance for any help, and please let me know if any additional information would be of use.

Here is the code for H_Bridge_Controller:
Code: [Select]
/*
 H_Bridge_Controller_h - Library for controlling a DC motor connected through an H-Bridge to the Arduino.
 Created by Andrew J. Capodieci, April 27th, 2012. Released into the public domain.
*/

#include "H_Bridge_Controller.h"

H_Bridge_Controller::H_Bridge_Controller(int m_in1, int m_in2, int m_en) {
 pinMode(m_in1, OUTPUT);
 pinMode(m_in2, OUTPUT);
 pinMode(m_en, OUTPUT);
 
 _m_in1 = m_in1;
 _m_in2 = m_in2;
 _m_en = m_en;
}

H_Bridge_Controller::H_Bridge_Controller() {
}

// Rotate an H-Bridge controlled motor to the left (counter-clockwise)
void H_Bridge_Controller::left() {
Serial.println(_m_in1);
 digitalWrite(_m_in1, LOW);
 digitalWrite(_m_in2, HIGH);
}

// Rotate an H-Bridge controlled motor to the right (clockwise)
void H_Bridge_Controller::right() {
 digitalWrite(_m_in1, HIGH);
 digitalWrite(_m_in2, LOW);
}

// Stop an H-Bridge controlled motor
void H_Bridge_Controller::stop() {
 digitalWrite(_m_in1, LOW);
 digitalWrite(_m_in2, LOW);
}

// Disable an H-Bridge controlled motor
void H_Bridge_Controller::disable() {
 digitalWrite(_m_en, LOW);
}

// Enable an H-Bridge controlled motor
void H_Bridge_Controller::enable() {
Serial.println(_m_en);
 digitalWrite(_m_en, HIGH);
}

// PWM an H-Bridge controlled motor
void H_Bridge_Controller::pwm(int val) {
 analogWrite(_m_en, val);
}


And here is the code for Acrobot.h:
Code: [Select]
/*
Acrobot_h - Header file for Acrobot library that defines common commands for Acrobot.
Created by Andrew J. Capodieci, April 3rd, 2013.
*/

#ifndef Acrobot_h
#define Acrobot_h

#include <H_Bridge_Controller.h>
#include <Acrobot_Pin_Definitions.h>
#include <Acrobot_Signal_Definitions.h>
#include <Servo.h>
#include <Arduino.h>

class Acrobot {
#define INTEGRAL_RANGE1 10000
#define BIAS1 70
#define MAX_THRESHOLD1 100

#define INTEGRAL_RANGE2 10000
#define BIAS2 70
#define MAX_THRESHOLD2 100

#define INTEGRAL_RANGE3 10000
#define BIAS3 70
#define MAX_THRESHOLD3 100

#define SQUEEGEE_CLEAN_POS 25
#define SQUEEGEE_WIPE_POS 100

#define GROUND_THRESHOLD 100

public:
Acrobot();
void goToLeftProx();
void goToRightProx();
void goToTopProx();
void wipeSqueegee();
void calibrate();
void initialize();
void wash();
void stop();
void cleanColumn();
int getFlowRate();
private:
static void rpm();
H_Bridge_Controller _HBridge_vert1;
H_Bridge_Controller _HBridge_vert2;
H_Bridge_Controller _HBridge_horiz3;
// Servo _squeegee;
volatile int NbTopsFan;
};

#endif



and finally the code for Acrobot.cpp:
Code: [Select]
/*
 Acrobot_cpp - Library for common commands for Acrobot.
 Created by Andrew J. Capodieci, April 27th, 2012. Released into the public domain.
*/

#include <Acrobot.h>

Acrobot::Acrobot() {
H_Bridge_Controller _HBridge_vert1(VERT1_IN1, VERT1_IN2, VERT1_EN);
H_Bridge_Controller _HBridge_vert2(VERT2_IN1, VERT2_IN2, VERT2_EN);
// H_Bridge_Controller _HBridge_horiz3(HORIZ_IN1, HORIZ_IN2, HORIZ_EN);
// H_Bridge_Controller _HBridge_horiz3(8, 7, 3);

_HBridge_horiz3.stop();
_HBridge_vert1.stop();
_HBridge_vert2.stop();

_HBridge_horiz3.disable();
_HBridge_vert1.disable();
_HBridge_vert2.disable();
}

// Rotate an H-Bridge controlled motor to the left (counter-clockwise)
void Acrobot::goToLeftProx() {
// while(analogRead(LEFT_PROX) > 75) {
while(1) {
Serial.println("moving left");
_HBridge_horiz3.left();
_HBridge_horiz3.enable();
// _HBridge_horiz3.pwm(MAX_THRESHOLD3);
}
_HBridge_horiz3.stop();

while(analogRead(LEFT_PROX) <= 75) {
_HBridge_horiz3.right();
_HBridge_horiz3.pwm(MAX_THRESHOLD3/2);
}
_HBridge_horiz3.stop();
}

// Rotate an H-Bridge controlled motor to the right (clockwise)
void Acrobot::goToRightProx() {
while(analogRead(RIGHT_PROX) > 75) {
_HBridge_horiz3.right();
_HBridge_horiz3.pwm(MAX_THRESHOLD3);
}
_HBridge_horiz3.stop();

while(analogRead(RIGHT_PROX) <= 75) {
_HBridge_horiz3.left();
_HBridge_horiz3.pwm(MAX_THRESHOLD3/2);
}
_HBridge_horiz3.stop();
}

// Stop an H-Bridge controlled motor
void Acrobot::goToTopProx() {
while(analogRead(TOP_PROX) > 75) {
_HBridge_vert1.left();
_HBridge_vert2.right();
_HBridge_vert1.pwm(MAX_THRESHOLD1);
_HBridge_vert2.pwm(MAX_THRESHOLD2);
}
_HBridge_vert1.stop();
_HBridge_vert2.stop();

while(analogRead(TOP_PROX) <= 75) {
_HBridge_vert1.right();
_HBridge_vert2.left();
_HBridge_vert1.pwm(MAX_THRESHOLD1/2);
_HBridge_vert2.pwm(MAX_THRESHOLD2/2);
}
_HBridge_vert1.stop();
_HBridge_vert2.stop();
}

// Disable an H-Bridge controlled motor
void Acrobot::wipeSqueegee() {
// _squeegee.write(SQUEEGEE_CLEAN_POS);
delay(300);
// _squeegee.write(SQUEEGEE_WIPE_POS);
}

void Acrobot::calibrate() {
initialize();
}

void Acrobot::initialize() {
goToLeftProx();
goToTopProx();
}

void Acrobot::wash() {

}

void Acrobot::cleanColumn() {
//while(analogRead(GROUND_SENSOR) > GROUND_THRESHOLD) {
//
// }
// _squeegee.write(SQUEEGEE_CLEAN_POS);
_HBridge_vert1.right();
_HBridge_vert2.left();
_HBridge_vert1.pwm(MAX_THRESHOLD1/2);
_HBridge_vert2.pwm(MAX_THRESHOLD2/2);
delay(2000);
_HBridge_vert1.stop();
_HBridge_vert2.stop();
}

void Acrobot::stop() {
_HBridge_vert1.stop();
_HBridge_vert2.stop();
_HBridge_horiz3.stop();
}

acapodie

I should mention that my code works when I hard code the pin values in the dummy constructor H_Bridge_Controller::H_Bridge_Controller() to the following:
Code: [Select]
H_Bridge_Controller::H_Bridge_Controller() {
_m_in1 = 8;
_m_in2 = 7;
_m_en = 3;

pinMode(_m_in1, OUTPUT);
pinMode(_m_in2, OUTPUT);
pinMode(_m_en, OUTPUT);
}


This tells me that the dummy constructor is the one being used in the Acrobot.cpp file, and that the following three lines in the Acrobot::Acrobot() constructor are doing nothing:
Code: [Select]
H_Bridge_Controller _HBridge_vert1(VERT1_IN1, VERT1_IN2, VERT1_EN);
H_Bridge_Controller _HBridge_vert2(VERT2_IN1, VERT2_IN2, VERT2_EN);
// H_Bridge_Controller _HBridge_horiz3(HORIZ_IN1, HORIZ_IN2, HORIZ_EN);


But I don't know how to fix this problem.

PeterH

I haven't quite followed the details of that problem description, but it sounds as if you want to use some constructor args to initialise some of your instance variables which are objects without no-args constructors. If that's right, you can do that within the Acrobot::Acrobot() constructor by putting your instance variable construction between the () and {. (You could use the same approach to construct the integer member variables in the H_Bridge_Controller constructor.)
I only provide help via the forum - please do not contact me for private consultancy.

Nick Gammon

Can you make up a (zip) file which demonstrates your problem and attach it to a reply?

http://arduino.cc/forum/index.php/topic,148850.msg1118324.html#post_attachments

If I can reproduce your error without a lot of mucking around copying and pasting I can advise of a solution.
http://www.gammon.com.au/electronics

acapodie

Peter,

You were exactly right thank you.  The following webpage illustrates the syntax you were talking about: http://msdn.microsoft.com/en-us/library/f1h35k32.aspx.

Basically this problem was an artifact of my unfamiliarity with C++!  The following code shows the solution:

Code: [Select]
Acrobot::Acrobot():
_HBridge_vert1(VERT1_IN1, VERT1_IN2, VERT1_EN),
_HBridge_vert2(VERT1_IN1, VERT1_IN2, VERT1_EN),
_HBridge_horiz3(HORIZ_IN1, HORIZ_IN2, HORIZ_EN)
{...constructor code here...}

Go Up