I'm doing a program for a robot and I got stuck at a weird problem:
I have classes defined for my robot's internals, for example for a StepMotor
. I also defined a class for a Controller
, which is going to control the speed of each StepMotor
.
Here's a fragment of my code:
#include <SPI.h>
#include <Tone.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
/SILNIKI KROKOWE:
class StepMotor: public Device
{
public:
int motorPin;
int dirPin;
int sleepPin;
int ForwardState;
volatile double Speed;
volatile int ControlValue; //the value sent to the motor
int MaxControlValue = 4000; //maximum ControlValue
String Name;
void Init ( void )
{
//init
}
void SetSpeed ( int speed )
{
toneObject.play(speed);
}
void SetMode(bool IsOn)
{
if (IsOn)
digitalWrite(sleepPin, HIGH);
else
digitalWrite(sleepPin, LOW);
}
void SetDirection ( Dir direction )
{
//code for setting direction
}
private:
Tone toneObject;
};
StepMotor motor_right;
StepMotor motor_left;
class Controller
{
public:
ControllerType controllerType;
double Kp;
double Ki;
double Kd;
double Tp; //czas próbkowania
volatile double e;
volatile double e_old;
volatile double P_result;
volatile double I_result;
volatile double D_result;
StepMotor Motor;
int Calculate ()
{
int Result;
//Serial.print(Motor.Speed); HERE's THE PROBLEM
/********************************
/********************************
/*******************************
e = MoveOrder::speed - Motor.Speed; //Motor.Speed is always 0.00, although it's not true
//the rest is not important
}
void Reset()
{
//reset procedure
}
};
Controller controller_right;
Controller controller_left;
setup()
{
controller_right.Motor = motor_right;
controller_left.Motor = motor_left;
}
ISR(TIMER5_COMPA_vect)
{
motor_right.ControlValue = controller_right.Calculate();
motor_left.ControlValue = controller_left.Calculate();
motor_right.SetSpeed(motor_right.ControlValue);
motor_left.SetSpeed(motor_left.ControlValue);
}
I have cut the less important parts. The rest works properly, because my robot can drive when I use SetSpeed(somevalue);
The only problem is that place where I need to read current speed of my motor.
In the Controller
class, there's Calculate()
method. In that method I want to calculate e = MoveOrder::speed - Motor.Speed;
Unfortunately it can't be calculated properly, because Motor.Speed ALWAYS is 0.00
(when I display it with Serial.print(Motor.Speed)
I see 0.00
all the time). It's very strange, because when I display speed of each motor (Serial.print(right_motor.Speed)
or Serial.print(left_motor.Speed)
) the value is correct (when the wheels are spinning, value is not 0.00).
The speed calculations are in a different function, which I didn't present here, because it would be too long - I'm sure it works, because, as I said, I can get speed values properly.
As you can see in setup()
, I set each contorller's Motor porperty to the correct object.
I also used volatile keyword for the properties that are used in the interrupt.
What is wrong with my code?
If the code I provided isn't enough, here's the full version: https://1drv.ms/t/s!Atl-jM_xUkz1hc1f-qYYotj-pJIgUw
I'm not sure if anyone would want to dive into it, because it's not so short.