I have three files:
main.cpp
RotaryEncoder.h
RotaryEncoder.cpp
Note that the RotaryEncoder
class acts as a wrapper to the Encoder
library. I am getting the following build report and I haven't been able to find the bug for the past couple days:
Build output from PlatformIO on VS Code
Processing uno (platform: atmelavr; board: uno; framework: arduino)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/uno.html
PLATFORM: Atmel AVR 1.15.0 > Arduino Uno
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 31.50KB Flash
PACKAGES: toolchain-atmelavr 1.50400.190710 (5.4.0), framework-arduinoavr 4.1.2
LDF: Library Dependency Finder
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 7 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Encoder>
Building in release mode
Compiling .pio/build/uno/src/main.cpp.o
Linking .pio/build/uno/firmware.elf
/var/folders/t1/fyh283nd1m7dxbrjlkjtf_kc0000gn/T//ccZN56Tq.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x2dc): undefined reference to `RotaryEncoder::getCount()'
collect2: error: ld returned 1 exit status
*** [.pio/build/uno/firmware.elf] Error 1
Explicit Error
In function 'main': :(.text.startup+0x2dc): undefined reference to 'RotaryEncoder::getCount()'.
main.cpp
#include <Arduino.h>
#include "RotaryEncoder.h"
#define cartEncoderPhaseA 3
#define cartEncoderPhaseB 4
#define pendulumEncoderPhaseA 2
#define pendulumEncoderPhaseB 5
// Initialize encoders
const double ENCODER_PPR = 2400.0;
RotaryEncoder cartEncoder(cartEncoderPhaseA, cartEncoderPhaseB, ENCODER_PPR);
RotaryEncoder pendulumEncoder(pendulumEncoderPhaseA, pendulumEncoderPhaseB, ENCODER_PPR);
void setup()
{
Serial.begin(9400);
}
void loop()
{
long cartCount = cartEncoder.getCount();
}
RotaryEncoder.h
#pragma once
#include <Encoder.h>
class RotaryEncoder
{
private:
Encoder encoder;
double encoderPPR;
double angleLowerBound;
double angleUpperBound;
double convertEncoderCountToRadians(long encoderCount);
double normalizeAngle(double angle);
public:
RotaryEncoder(int phaseA, int phaseB, double encoderPPR);
long getCount();
double getRadiansAndOffsetBy(double angleOffset);
void setAngleLowerAndUpperBounds(double lowerBound, double upperBound);
};
RotaryEncoder.cpp
#include "RotaryEncoder.h"
RotaryEncoder::RotaryEncoder(int phaseA, int phaseB, double encoderPPR)
: encoder(phaseA, phaseB), encoderPPR(encoderPPR)
{}
inline long RotaryEncoder::getCount()
{
return encoder.read();
}
inline double RotaryEncoder::getRadiansAndOffsetBy(double angleOffset)
{
long encoderCount = getCount();
double angleInRadians = angleOffset + convertEncoderCountToRadians(encoderCount);
angleInRadians = normalizeAngle(angleInRadians);
return angleInRadians;
}
inline double RotaryEncoder::convertEncoderCountToRadians(long encoderCount)
{
return ((double)encoderCount / (encoderPPR)) * (2.0 * PI);
}
inline double RotaryEncoder::normalizeAngle(double angle)
{
// Constrain an angle between [-pi, pi). Output is in radians
// see: https://stackoverflow.com/questions/11498169/dealing-with-angle-wrap-in-c-code
angle = fmod(angle + PI, 2 * PI);
if (angle < 0)
angle += 2 * PI;
return angle - PI;
}
inline void RotaryEncoder::setAngleLowerAndUpperBounds(double lowerBound, double upperBound)
{
angleLowerBound = lowerBound;
angleUpperBound = upperBound;
}