I can't figure out why my C++ version of a script isn't working.

Hi everyone,

I am a complete Arduino novice but I'm not new to programming, so when I found out Sketch was based on C++, I got a bit excited.

I've got a simple vehicle chassis that's running a left and right motor. (With a swivel castor at the front.)

I got the (Freetronics H Bridge Shield and jammed the code it, and it works fine with some very easy tweeks.

const int channel_a_enable  = 6;
const int channel_a_input_1 = 4;
const int channel_a_input_2 = 7;
const int channel_b_enable  = 5;
const int channel_b_input_3 = 3;
const int channel_b_input_4 = 2;

void setup()
{
  pinMode( channel_a_enable, OUTPUT );  // Channel A enable
  pinMode( channel_a_input_1, OUTPUT ); // Channel A input 1
  pinMode( channel_a_input_2, OUTPUT ); // Channel A input 2
  
  pinMode( channel_b_enable, OUTPUT );  // Channel B enable
  pinMode( channel_b_input_3, OUTPUT ); // Channel B input 3
  pinMode( channel_b_input_4, OUTPUT ); // Channel B input 4
  
  Serial.begin( 9600 );
  Serial.println("Starting up");
}

void loop()
{
      Serial.println("Channel A forward");
      analogWrite( channel_a_enable, 255);
      digitalWrite( channel_a_input_1, HIGH);
      digitalWrite( channel_a_input_2, LOW);
      delay(5000);
      allInputsOff();
    
      Serial.println("Channel A reverse");
      analogWrite( channel_a_enable, 255);
      digitalWrite( channel_a_input_1, LOW);
      digitalWrite( channel_a_input_2, HIGH);
      delay(5000);
      allInputsOff();
      
      Serial.println("Channel A forward half speed");
      analogWrite( channel_a_enable, 127);
      digitalWrite( channel_a_input_1, HIGH);
      digitalWrite( channel_a_input_2, LOW);
      delay(5000);
      allInputsOff();
}

void allInputsOff()
{
  digitalWrite( 4, LOW );
  digitalWrite( 7, LOW );
  digitalWrite( 6, LOW );
  digitalWrite( 3, LOW );
  digitalWrite( 2, LOW );
  digitalWrite( 5, LOW );
}

So, knowing C++ like I do, I thought that I'd be a smarty pants and re-write the code as a Class based model and came up with:

//******************************************************************************************************************************************************************************
//Class Definition: MotorControl
//
// Controls and initialises one motor at a time. 
//******************************************************************************************************************************************************************************
class Motor 
{
  public: 
  /*
   * This is the 'constructor', which is automatically called whenever a new object of the class is created, allowing the class to initialise member variables or allocate storage.  
   * This constructor function is declared just like a regular member function, but with a name that matches the class name and without any return type, not even "void".
   */

    Motor(int channelEnable,int inputA, int inputB);

    // these are the public class "members". the actual code for these members is given below...here we just tell the compiler about their existence, and what values aare being reutrned. 
    void setup();
    void Forward (int mSpeed);
    void Reverse (int mSpeed);
    void Stop();
    
  private: 
    //these three control a single motor. 
    int _channelEnable;
    int _input1;
    int _input2;   
};
//this is the end of the class proforma and below is the code for each member functions. 

Motor::Motor (int channelEnable, int inputA, int inputB) // this is the constructor of the class
{
 //printf ("Channel enabler is %s", _channelEnable);
  _channelEnable = channelEnable;
  _input1 = inputA;
  _input2 = inputB;
}


  
void Motor::setup()
{
  pinMode( _channelEnable, OUTPUT );  // Channel enable
  pinMode( _input1, OUTPUT ); // Channel input 1
  pinMode( _input2, OUTPUT ); // Channel input 2
  //Serial.begin( 9600 );
  //Serial.println("Starting up");
}

void Motor::Forward (int mSpeed)
{
  Serial.println("Channel forward");
  analogWrite( _channelEnable, mSpeed);
  digitalWrite( _input1, HIGH);
  digitalWrite( _input2, LOW); 
}

void Motor::Reverse (int mSpeed)
{
  Serial.println("Channel reverse");
  analogWrite(_channelEnable, mSpeed);
  digitalWrite( _input1, LOW);
  digitalWrite( _input2, HIGH);
}

 void Motor::Stop()
{
  digitalWrite( _channelEnable, LOW );
  digitalWrite( _input1, LOW );
  digitalWrite( _input2, LOW );
}

//******************************************************************************************************************************************************************************
// Main Arduino Sketch
//******************************************************************************************************************************************************************************
Motor right (6,4,7);
Motor left (5,3,2);

/*  
 *   right motor
 *   const int channel_a_enable  = 6;
 *   const int channel_a_input_1 = 4;
 *   const int channel_a_input_2 = 7;
 *   
 *   left motor
 *   const int channel_b_enable  = 5;
 *   const int channel_b_input_3 = 3;
 *   const int channel_b_input_4 = 2;
 */

void pause (int seconds)
{
  //this function brings the Arduino into line with the RPi, in that the delay statement is taking the number of seconds and multiplying it by the number of milliseconds, 
  // so that we are still using the delay() inbuit fuinction with milliseconds. 
  // eg: 0.5 seconds * 1000 milliseconds == 500 milliseconds. 
 
  int timeToDelay;

  timeToDelay = seconds * 1000; // multiply the number of seconds by the number of milliseconds in 1 seconds, 1000. 
  delay(timeToDelay);
}

void setup ()
{
  //this code runs once
  
  right.setup();
  left.setup();
    Serial.begin( 9600 );
  Serial.println("Starting up");




  
}
 
void loop()
{
  
  left.Forward(127);
  right.Forward(127);
  pause(0.5);
  left.Stop();
  right.Stop();
  pause(0.5);
  left.Reverse(254);
  right.Forward(254);
  pause(0.5);
  left.Stop();
  right.Stop();
  pause(0.5);
}

(Everything is Python at work at the minute, so I have been heading towards the Raspberry Pi, also. Sorry, folks!)

To me, this looks programmatically equal to the Freetronics sample code but what am I missing?

Is there some nuance with Sketch I am missing?

With so many thanks in advance....

Please explain what "isn't working" means in this case.

One thing that jumps out: Your function pause() takes an int but you are passing a float (0.5).

If you are planning to use analogWrite() in the 'enable' pins, better make sure they are PWM pins on the Arduino model you are using.

By convention your '::setup()' function should be named '::begin()'.

jremington:
Please explain what "isn't working" means in this case.

it's not making the motor run like the non-object version. Only one wheel moves, jittering along very slowly. the left doesn't move at all.

Blackfin:
One thing that jumps out...

...is certainly a catastrophic problem. Well spotted, Blackfin!

Not sure if you're serious. :confused:

I'm also not sure what "it's not making the motor run like the non-object version." means.

Is the motor moving at all? Or is it just that the delays are different?

Blackfin:
Not sure if you're serious. :confused:

I am. There is no way the motors are going to noticeably react with zero delay through loop.

Blackfin:
Not sure if you're serious. :confused:

I'm also not sure what "it's not making the motor run like the non-object version." means.

Is the motor moving at all? Or is it just that the delays are different?

The right wheel is juttering slowly, the left motor isn't running at all.

When the original code runs with the editing required to make both wheels run, they both run fast without any issues. Even with the pause (int speed) as it was.

So, I changed the ::setup() to ::init(). I found ::begin() was shaded in my compiler as a reserved word anyway, so I decided on begin.

I also made the following changes to the following code....

void pause (float seconds)
{
  //this funciton brings the Arduino into line with the RPi, in that the delay statement is taking the number of seconds and multiplying it by the number of milliseconds, 
  // so that we are still using the delay() inbuit fuinction with milliseconds. 
  // eg: 0.5 seconds * 1000 milliseconds == 500 milliseconds. 
  int timeToDelay;

  timeToDelay = int(seconds * 1000); // multiply the number of seconds by the number of milliseconds in 1 seconds, 1000. 
  delay(timeToDelay);
}

and extended the length to 1 full second and something seems to have clicked

It is working fine now.

Thanks everyone for their insights!