mike-matera/ArduinoSTL

class object does not populate well outside scope

Opened this issue · 0 comments

Hi Everyone,

To begin with, this library is excellent for people who are sandwiched between C++ and Arduino. :) Nevermind, I have started to use this library and it works with most of my cases except the situation my single global class object is giving different address at two places.

Consider this scenario:

driver.h file I have placed this header file at the Arduino.h level so that I can access driver.h file from anywhere.

#pragma once
#ifndef MOTOR_DRIVER_INCLUDED_
#define MOTOR_DRIVER_INCLUDED_

#include<ArduinoSTL.h>
#include<Arduino.h>

class Element {
public:
bool isTLE;

Element() {
isTLE = false;
}
};

class Motor {
public:
Motor() {
Serial.println("Calling the motor constructor");
}
~Motor() {
}
void stopAllBoard();
std::vector<Element*> commandsQueue;
};

static Motor* motor = new Motor;

#endif

driver.cpp file

#include <SPI1.h>

void Motor::stopSomething() {
SPI1.transfer16(0x801);
}

SPI1.h file It is placed at its own standard path.

This is a standard SPI1 library with only minor modifcation in transfer16 function. I am just pushing the command in transfer16 to an queue and printing the address of the object there. Snapshot of SPI1.h file:

....
#include<driver.h>
....
inline static uint16_t transfer16(uint16_t data) {
// My code starts
Element* elem = new Element();
elem->isTLE = true;
motor->commandsQueue.push_back(elem);
Serial.print("Pushed the SPI1 object into the queue with 16bit data. Size queue = ");
Serial.println(motor->commandsQueue.size());
Serial.printf("Motor address at transfer : %x", motor);
Serial.println("");
Serial.print("Size of motor object at transfer: ");
Serial.println(sizeof(motor));
// My code ends

union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;

if (!(SPCR1 & _BV(DORD))) {
  SPDR1 = in.msb;
  asm volatile("nop"); // See transfer(uint8_t) function
  while (!(SPSR1 & _BV(SPIF)));// {Serial.println(data,HEX);}
  out.msb = SPDR1;
  SPDR1 = in.lsb;
  //Serial.println(in.msb,HEX);
  asm volatile("nop");
  while (!(SPSR1 & _BV(SPIF))) ;
  out.lsb = SPDR1;
} else {
  SPDR1 = in.lsb;
  asm volatile("nop");
  while (!(SPSR1 & _BV(SPIF))) ;
  out.lsb = SPDR1;
  SPDR1 = in.msb;
  asm volatile("nop");
  while (!(SPSR1 & _BV(SPIF))) ;
  out.msb = SPDR1;
}
return out.val;

}
....
....

main.cpp

#include<motor_driver.h>

void setup() {
Serial.begin(9600);
Serial.println("");
Serial.printf("Motor address at setup : %x", motor);
Serial.println("");
motor->stopAllBoard();
motor->stopAllBoard();
Serial.print("Commands queue size at the operation start = ");
Serial.println(motor->commandsQueue.size());
Serial.printf("Motor address at setup : %x", motor);
Serial.println("");
}

Output of main.cpp comes out like this in Arduino serial monitor.

18:54:31.008 -> Motor address at setup : 2df
18:54:31.008 -> Pushed the SPI1 object into the queue with 16bit data. Size queue = 1
18:54:31.066 -> Motor address at transfer : 2c4
18:54:31.148 -> Size of motor object at transfer: 2
18:54:31.148 -> ,
18:54:31.148 -> Pushed the SPI1 object into the queue with 16bit data. Size queue = 2
18:54:31.288 -> Motor address at transfer : 2c4
18:54:31.288 -> Size of motor object at transfer: 2
18:54:31.335 -> , ,
18:54:31.335 -> Commands queue size at the operation start = 0
18:54:31.335 ->

If you notice the output, motor address at main.cpp is different than the motor object address in SPI1.h. This means that my vector, considering it as queue. :), does not have right elements in main.cpp.

Out of ideas for this since I do not see any programming issue here. Can anyone suggest a way to move forward. Thank you.