1 (edited by ttijass 2023-04-14 10:14:34)

Topic: PlatformIO error 'remotexy' not declared in this scope

Hey, I'm trying to compile my project using VSC PlatformIO, but the compiler returns the output below.
I can't figure this one out so thank you in advance for any kind of help.

TTS

platformio.ini file:

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
lib_deps = 
    br3ttb/PID@^1.2.1
    jrowberg/I2Cdevlib-MPU6050@^1.0.0
    https://github.com/RemoteXY/RemoteXY-Arduino-library.git

OUTPUT:

Processing nanoatmega328 (platform: atmelavr; board: nanoatmega328; framework: arduino)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option                                                                                                                                                                                                                    CONFIGURATION: https://docs.platformio.org/page/boards … ga328.html
PLATFORM: Atmel AVR (4.1.0) > Arduino Nano ATmega328
HARDWARE: ATMEGA328P 16MHz, 2KB RAM, 30KB Flash
DEBUG: Current (avr-stub) External (avr-stub, simavr)
PACKAGES:
- framework-arduino-avr @ 5.1.0
- toolchain-atmelavr @ 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 9 compatible libraries
Scanning dependencies...
Dependency Graph
|-- PID @ 1.2.1
|-- I2Cdevlib-MPU6050 @ 1.0.0
|   |-- I2Cdevlib-Core @ 1.0.1
|   |   |-- Wire @ 1.0
|-- RemoteXY @ 3.1.10+sha.743dad0
|   |-- SoftwareSerial @ 1.0
|-- Wire @ 1.0
|-- EEPROM @ 2.0
|-- I2Cdevlib-Core @ 1.0.1
|   |-- Wire @ 1.0
Building in release mode
Compiling .pio\build\nanoatmega328\src\main.cpp.o
Compiling .pio\build\nanoatmega328\lib7bb\PID\PID_v1.cpp.o
Compiling .pio\build\nanoatmega328\lib89d\Wire\Wire.cpp.o
Compiling .pio\build\nanoatmega328\lib89d\Wire\utility\twi.c.o
Compiling .pio\build\nanoatmega328\libafe\I2Cdevlib-Core\I2Cdev.cpp.o
Compiling .pio\build\nanoatmega328\lib311\I2Cdevlib-MPU6050\MPU6050.cpp.o
Compiling .pio\build\nanoatmega328\lib311\I2Cdevlib-MPU6050\MPU6050_6Axis_MotionApps20.cpp.o
Compiling .pio\build\nanoatmega328\lib311\I2Cdevlib-MPU6050\MPU6050_6Axis_MotionApps612.cpp.o
In file included from src\main.cpp:5:0:
src\main.cpp: In function 'void loop()':
.pio\libdeps\nanoatmega328\RemoteXY\src/RemoteXY.h:163:28: error: 'remotexy' was not declared in this scope
#define RemoteXY_Handler() remotexy->handler ()
                            ^
src\main.cpp:280:5: note: in expansion of macro 'RemoteXY_Handler'
     RemoteXY_Handler();
     ^~~~~~~~~~~~~~~~
.pio\libdeps\nanoatmega328\RemoteXY\src/RemoteXY.h:163:28: note: suggested alternative: 'RemoteXY'
#define RemoteXY_Handler() remotexy->handler ()
                            ^
src\main.cpp:280:5: note: in expansion of macro 'RemoteXY_Handler'
     RemoteXY_Handler();
     ^~~~~~~~~~~~~~~~
src\main.cpp: At global scope:
src\main.cpp:50:3: warning: 'RemoteXY' defined but not used [-Wunused-variable]
} RemoteXY;
   ^~~~~~~~
In file included from src\main.cpp:2:0:
C:\Users\TTS\.platformio\packages\framework-arduino-avr\libraries\EEPROM\src/EEPROM.h:145:20: warning: 'EEPROM' defined but not used [-Wunused-variable]
static EEPROMClass EEPROM;
                    ^~~~~~
Archiving .pio\build\nanoatmega328\lib7bb\libPID.a
Archiving .pio\build\nanoatmega328\libafe\libI2Cdevlib-Core.a
*** [.pio\build\nanoatmega328\src\main.cpp.o] Error 1
Indexing .pio\build\nanoatmega328\libafe\libI2Cdevlib-Core.a
Indexing .pio\build\nanoatmega328\lib7bb\libPID.a
========================================================================================================== [FAILED] Took 2.66 seconds ==========================================================================================================

*  The terminal process "C:\Users\TTS\.platformio\penv\Scripts\platformio.exe 'run'" terminated with exit code: 1.

FULL CODE:

#include <Arduino.h>
#include <EEPROM.h>
#include <I2Cdev.h>
#include <PID_v1.h>
#include <RemoteXY.h>

#include "MPU6050_6Axis_MotionApps20.h"
//------------------------------------------------------------------------
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation is used in I2Cdev.h

/////////////////////////////////////////////
//              RemoteXY                  //

#define REMOTEXY_MODE__HARDSERIAL
#define REMOTEXY_SERIAL Serial
#define REMOTEXY_SERIAL_SPEED 115200

#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =  // 113 bytes
    {255, 8, 0, 32, 0, 116, 0, 16, 31, 0, 5, 42, 6, 26, 30, 30, 2, 26, 31, 10,
     48, 1, 9, 15, 15, 4, 26, 31, 79, 78, 0, 31, 79, 70, 70, 0, 66, 193, 1, 1,
     16, 7, 49, 132, 67, 4, 21, 2, 77, 5, 2, 26, 31, 4, 0, 83, 15, 9, 46, 2,
     26, 129, 0, 55, 25, 5, 6, 17, 75, 105, 0, 129, 0, 40, 25, 7, 6, 17, 75, 112,
     0, 129, 0, 69, 25, 7, 6, 17, 75, 100, 0, 4, 0, 40, 6, 7, 18, 2, 26, 4,
     0, 55, 6, 7, 18, 2, 26, 4, 0, 69, 6, 7, 18, 2, 26, 3, 130, 81, 9, 14,
     8, 2, 26};

// this structure defines all the variables and events of your control interface
struct {
    // input variables
    int8_t joystick_1_x;   // from -100 to 100
    int8_t joystick_1_y;   // from -100 to 100
    uint8_t pushSwitch_1;  // =1 if state is ON, else =0
    int8_t slider_1;       // =0..100 slider position
    int8_t slider_2;       // =0..100 slider position
    int8_t slider_3;       // =0..100 slider position
    int8_t slider_4;       // =0..100 slider position
    uint8_t select_1;      // =0 if select position A, =1 if position B, =2 if position C, ...

    // output variables
    int8_t level_1;   // =0..100 level position
    char text_1[21];  // string UTF8 end zero

    // other variable
    uint8_t connect_flag;  // =1 if wire connected, else =0

} RemoteXY;
#pragma pack(pop)

//               END RemoteXY              //
/////////////////////////////////////////////

/////////////////////////////////////////////
//                 DRONE                   //
// Battery
#define ALPHA 0.1
#define MULTIPLIER 6.67
float motorBattery;

// PID
int targetSpeed[4];
#define ADDR_PITCH_OFFSET 0
#define ADDR_ROLL_OFFSET 0
#define FL_MOTOR 3
#define BL_MOTOR 9
#define BR_MOTOR 10
#define FR_MOTOR 11

// Define variables we'll be connecting to
double rollSetpoint, rollInput, rollOutput;
double pitchSetpoint, pitchInput, pitchOutput;
double yawSetpoint, yawInput, YawOutput;

// Define the aggressive and conservative Tuning Parameters
double rpKp = 0.5, rpKi = 0.05, rpKd = 0.05;  // roll, pitch kp, ki, kd
double yKp = 0.5, yKi = 0.05, yKd = 0.05;     // yaw kp ki kd

PID pitchPID(&rollInput, &rollOutput, &rollSetpoint, rpKp, rpKi, rpKd, DIRECT);
PID rollPID(&pitchInput, &pitchOutput, &pitchSetpoint, rpKp, rpKi, rpKd, DIRECT);
// PID yawPID(&yawInput, &YawOutput, &yawSetpoint, yKp, yKi, yKd, DIRECT);
//                  DRONE                  //
/////////////////////////////////////////////

/////////////////////////////////////////////
//                 MPU                    //

//    LED
#define LED_PIN 13
bool blinkState = false;

MPU6050 mpu;
// MPU control/status vars
bool dmpReady = false;   // set true if DMP init was successful
uint8_t mpuIntStatus;    // holds actual interrupt status byte from MPU
uint8_t devStatus;       // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize;     // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount;      // count of all bytes currently in FIFO
uint8_t fifoBuffer[64];  // FIFO storage buffer

// orientation/motion vars
Quaternion q;         // [w, x, y, z]         quaternion container
VectorInt16 aa;       // [x, y, z]            accel sensor measurements
VectorInt16 aaReal;   // [x, y, z]            gravity-free accel sensor measurements
VectorInt16 aaWorld;  // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity;  // [x, y, z]            gravity vector
float euler[3];       // [psi, theta, phi]    Euler angle container
float ypr[3];         // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
float ypr_cal[3];

// ===               INTERRUPT DETECTION ROUTINE                ===
volatile bool mpuInterrupt = false;  // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
    mpuInterrupt = true;
}
//                   MPU                   //
/////////////////////////////////////////////

// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================
void setup() {
    RemoteXY_Init();
    Serial.begin(115200);

    // join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    Wire.begin();
    TWBR = 24;  // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
    Fastwire::setup(400, true);
#endif

    for (int i = 0; i < 3; i++) {
        ypr_cal[i] = 0.0;
    }

    // Enable internal reference of 1.1V
    // initialise battery level array with current battery level value
    pinMode(A0, INPUT);
    analogReference(INTERNAL);
    //  float tmp = analogRead(A0) / 1023.0 * MULTIPLIER;
    motorBattery = 4.2;
    //------------------------------PID----------------------------------
    // initialize the variables we're linked to
    pitchInput = 0.0;
    rollInput = 0.0;
    // yawInput = 0.0;

    pitchSetpoint = 0.0;
    rollSetpoint = 0.0;
    // yawSetpoint = 0.0;

    // turn the PID on
    pitchPID.SetMode(AUTOMATIC);
    rollPID.SetMode(AUTOMATIC);
    // yawPID.SetMode(AUTOMATIC);

    pitchPID.SetOutputLimits(-10, 10);
    rollPID.SetOutputLimits(-10, 10);
    // yawPID.SetOutputLimits(-45, 45);
    //-------------------------------------------------------------------
    for (int i = 0; i < 4; i++) {
        targetSpeed[i] = 0;
    }

    pinMode(FL_MOTOR, OUTPUT);
    pinMode(FR_MOTOR, OUTPUT);
    pinMode(BR_MOTOR, OUTPUT);
    pinMode(BL_MOTOR, OUTPUT);

    mpu.initialize();

    // verify connection
    Serial.println(F("Testing device connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

    // wait for ready
    Serial.println(F("\nSend any character to begin DMP programming and demo: "));
    while (Serial.available() && Serial.read())
        ;  // empty buffer
    while (!Serial.available())
        ;  // wait for data
    while (Serial.available() && Serial.read())
        ;  // empty buffer again

    // load and configure the DMP
    Serial.println(F("Initializing DMP..."));
    devStatus = mpu.dmpInitialize();

    // // supply your own gyro offsets here, scaled for min sensitivity
    // mpu.setXGyroOffset(220);
    // mpu.setYGyroOffset(76);
    // mpu.setZGyroOffset(-85);
    // mpu.setZAccelOffset(1788);  // 1688 factory default for my test chip

    // make sure it worked (returns 0 if so)
    if (devStatus == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP..."));
        mpu.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP ready! Waiting for first interrupt..."));
        dmpReady = true;

        // get expected DMP packet size for later comparison
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP Initialization failed (code "));
        Serial.print(devStatus);
        Serial.println(F(")"));
    }

    // configure LED for output
    pinMode(LED_PIN, OUTPUT);
}

float smoothBattery(float prevEntry, float newEntry, float alpha) {
    return (1 - alpha) * prevEntry + alpha * newEntry;
}

void setSpeed(int val) {
    analogWrite(FL_MOTOR, val);
    analogWrite(FR_MOTOR, val);
    analogWrite(BR_MOTOR, val);
    analogWrite(BL_MOTOR, val);
}

void stabilise(int* currSpeed, int* actSpeed, float rollDiff, float pitchDiff) {
    actSpeed[0] = (int)currSpeed[0] + (rollDiff) - (pitchDiff);  // each motor has actual Speed and speed at which we want them to fly...
    actSpeed[1] = (int)currSpeed[1] + (rollDiff) + (pitchDiff);
    actSpeed[2] = (int)currSpeed[2] - (rollDiff) + (pitchDiff);  // actual Speed is calculated as follows +- half rollDiff +- half pitchDiff
    actSpeed[3] = (int)currSpeed[3] - (rollDiff) - (pitchDiff);

    for (int i = 0; i < 4; i++) {
        if (actSpeed[i] < 0)
            actSpeed[i] = 0;
    }
}

void checkIndividual(int motor, int* actSpeed) {
    analogWrite(FL_MOTOR, 0);
    analogWrite(FR_MOTOR, 0);
    analogWrite(BR_MOTOR, 0);
    analogWrite(BL_MOTOR, 0);

    if (motor == 0)
        analogWrite(FL_MOTOR, actSpeed[0]);
    if (motor == 1)
        analogWrite(FR_MOTOR, actSpeed[1]);
    if (motor == 2)
        analogWrite(BR_MOTOR, actSpeed[2]);
    if (motor == 3)
        analogWrite(BL_MOTOR, actSpeed[3]);
}

void runIndividual(int* actSpeed) {
    analogWrite(FL_MOTOR, actSpeed[0]);
    analogWrite(FR_MOTOR, actSpeed[1]);
    analogWrite(BR_MOTOR, actSpeed[2]);
    analogWrite(BL_MOTOR, actSpeed[3]);
}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================
void loop() {
    RemoteXY_Handler();

    // if programming failed, don't try to do anything
    if (!dmpReady) return;

    // if (Serial.available()) {
    //   myReading = Serial.parseInt();
    // for (int i = 0; i < 4; i++) {
    //   targetSpeed[i] = 0.0;
    // }

    //   runIndividual(targetSpeed);
    //   while (Serial.available())  //flushing anything that wasn't read
    //     Serial.read();
    //      runIndividual(myReading);
    //      checkMotor(myReading);
    //        checkIndividual(myReading);
    //}

    // wait for MPU interrupt or extra packet(s) available
    //      while (!mpuInterrupt && fifoCount < packetSize) {
    // if you are really paranoid you can frequently test in between other
    // stuff to see if mpuInterrupt is true, and if so, "break;" from the
    // while() loop to immediately process the MPU data
    //    }

    // reset interrupt flag and get INT_STATUS byte
    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();

    // get current FIFO count
    fifoCount = mpu.getFIFOCount();

    // check for overflow (this should never happen unless our code is too inefficient)
    if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
        // reset so we can continue cleanly
        mpu.resetFIFO();
        //        Serial.println(F("FIFO overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen frequently)
    } else if (mpuIntStatus & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

        // read a packet from FIFO
        mpu.getFIFOBytes(fifoBuffer, packetSize);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount -= packetSize;

        // get Euler angles in degrees
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
    }

    //----------------------------------------PID-----------------------------------------
    //   if (myReading == 0) {
    //     Serial.println(F("CALIBRATING"));
    //     ypr_cal[0] = ypr[0] * 180 / M_PI;
    //     ypr_cal[1] = ypr[1] * 180 / M_PI;
    //     ypr_cal[2] = ypr[2] * 180 / M_PI;

    //     //              ypr_cal[1] = 1.26;
    //     //              ypr_cal[2] = -0.55;
    //   }

    //   yawInput = ypr[0] * 180 / M_PI - ypr_cal[0];
    //   pitchInput = ypr[1] * 180 / M_PI - ypr_cal[1];
    //   rollInput = ypr[2] * 180 / M_PI - ypr_cal[2];

    //   //            pitchInput /= 2.0;
    //   //            rollInput /= 2.0;

    //   yawPID.Compute();
    //   pitchPID.Compute();
    //   rollPID.Compute();

    //   int actSpeed[4];
    //   stabilise(targetSpeed, actSpeed, rollOutput, pitchOutput);
    //   //    targetSpeed = actSpeed; // should this behere or not?

    //   Serial.print(F("pitchInput="));
    //   Serial.print(pitchInput);
    //   Serial.print(F("   pitchOutput="));
    //   Serial.print(pitchOutput);

    //   Serial.print(F("   rollInput="));
    //   Serial.print(rollInput);
    //   Serial.print(F("   rollOutput="));
    //   Serial.print(rollOutput);

    //   Serial.print(F("   mot[0]="));
    //   Serial.print(actSpeed[0]);
    //   Serial.print(F("   mot[1]="));
    //   Serial.print(actSpeed[1]);
    //   Serial.print(F("   mot[2]="));
    //   Serial.print(actSpeed[2]);
    //   Serial.print(F("   mot[3]="));
    //   Serial.println(actSpeed[3]);

    //   //runIndividual (actSpeed);
    //   //            checkIndividual(myReading, actSpeed);
    //   //------------------------------------------------------------------------------------
    //   motorBattery = smoothBattery(motorBattery, analogRead(A0) / 1023.0 * MULTIPLIER, ALPHA);
    //   if (motorBattery < 2.0) {
    //     Serial.println(F("WARNING! LOW BATTERY!"));
    //   }
    //   Serial.print(motorBattery);
    //   Serial.print(F("   ypr   "));
    //   Serial.print(ypr[0] * 180 / M_PI);
    //   Serial.print("   ");
    //   Serial.print(ypr[1] * 180 / M_PI);
    //   Serial.print("   ");
    //   Serial.println(ypr[2] * 180 / M_PI);

    //   // blink LED to indicate activity
    //   blinkState = !blinkState;
    //   digitalWrite(LED_PIN, blinkState);
    // }
    // delay(100);
}

RemoteXY.h error detected here on line 163 :

#define RemoteXY_Handler() remotexy->handler ()

2

Re: PlatformIO error 'remotexy' not declared in this scope

Now i created a new project and it compiled. I'm very confused.

3 (edited by ttijass 2023-04-14 11:28:45)

Re: PlatformIO error 'remotexy' not declared in this scope

Ok, i figured it out. What a dumb mistake this was.

I had to change the order of the occurance of these two lines from

#include <RemoteXY.h>
#define REMOTEXY_MODE__HARDSERIAL

to

#define REMOTEXY_MODE__HARDSERIAL
#include <RemoteXY.h>