I want to write a class for a model bike.
For controlling the steering I use a DC motor with two encoders.
To get the steering angle stAng
of the bike, I attach a interrupt to the pin ST_ENC_A
where one of the encoders is connected to. This interrupt is attached when the bike is initialized with the function bike.begin()
. When the interrupt is triggerd, the increment-steering-angle-function incStAng
is triggerd.
Said function is member of the class Bike
. To make the whole code compile and upload I had to make the increment-steering-angle-function static void incStAng()
and the steering-angle-variable volatile static float stAng
static.
The code is running, there are no errors or warnings.
Now, when I provide pin ST_ENC_A
with 3.3V the interrupt should be triggerd and I should see the printed value of stAng
increse in the Serial Monitor. This is not the case. It stays at 0.00.
This is my first real class I am writing. I only want to create one instance of my bike so the static definition of stAng
and incStAng
should be no problem.
So far I found the following websites helpful for information on 'static' and ISR.
I would be glad if someone could help me and give me a hint why the steering angle is not increasing when I give said pin 3.3V!
Board: Arduino Nano RP2040 Connect
Below you will see the .ino, .h, .cpp files in this order.
// myBike.ino - main file
#include "Bike.h"
Bike bike;
void setup() {
Serial.begin(9600);
bike.begin();
}
void loop() {
float val = bike.getStAng();
Serial.println(val);
}
// Bike.h - header file for the Bike library
#ifndef Bike_h
#define Bike_h
#include "Arduino.h"
class Bike {
public:
Bike();
void begin();
float getStAng();
private:
volatile static float stAng;
static void incStAng();
};
#endif
// Bike.cpp - implementation file for the Bike library
#include "Bike.h"
#define ST_ENC_A 12
#define ST_ENC_B 11
#define DEG_PER_CNT 0.51428571428
Bike::Bike() {
pinMode(ST_ENC_A, INPUT);
pinMode(ST_ENC_B, INPUT);
}
void Bike::begin() {
attachInterrupt(digitalPinToInterrupt(ST_ENC_A),incStAng,RISING);
}
void Bike::incStAng() {
volatile float stAng;
int b = digitalRead(ST_ENC_B);
if(b==HIGH){
stAng = stAng - DEG_PER_CNT;
}else{
stAng = stAng - DEG_PER_CNT;
}
}
float Bike::getStAng() {
volatile float stAng;
return stAng;
}
-
Did you connect that pin to ground previosly before changing to 3.3V? Do you use external pullup or pulldown resistors? The pin might already have been at 3.3V, thus connecting it to 3.3V would not generate a rising edge. Have you tried connecting and rotating the actual encoder?chrisl– chrisl2023年01月23日 19:11:09 +00:00Commented Jan 23, 2023 at 19:11
1 Answer 1
You have three different variables named stAng
here:
- a static member of the
Bike
class, which has been declared but not defined, and is never used - a local variable of the
Bike::incStAng()
method - a local variable of the
Bike::getStAng()
method
There should be only one such variable. For this, you should define the first one: in Bike.cpp
volatile float Bike::stAng;
and get rid of the other two.
Side note: I would recommend avoiding floating point computations within
an ISR, as these can be quite slow. Instead, count the integer number
of encoder steps in the ISR, and convert to an angle within
Bike::getStAng()
.
-
Thank you for this quick help, it works like I want it to! I am still wondering why it has to be like this though. Adding these two local variables you mentioned made the code compile, this is why I did it. So, in the class I only declare
stAng
as a static member but withvolatile float Bike::stAng;
in Bike.cpp I define it, right? I do not get the underlying rule why I have to do it this way. Could you give me a short explanation? If I add a non-static variable to the class and want to access and modify it using a method of Bike I do not have to add such a definition in Bike.cpp.Ole– Ole2023年01月23日 21:32:29 +00:00Commented Jan 23, 2023 at 21:32 -
1@Ole: The class definition in Bike.h defines a type only. No data. The line
Bike bike;
in myBike.ino defines aBike
object, and thus all the data belonging to that object (which in this case just happens to be none). A static data member does not belong to any object, and thus has to de defined elsewhere. It has also to be defined only once, so a .h file, which could potentially be included in multiple other files, would not be appropriate.Edgar Bonet– Edgar Bonet2023年01月23日 22:14:54 +00:00Commented Jan 23, 2023 at 22:14