I've got a class called Data, whenever I declare a new instance of this class and change something in it, it changes all instances of that class. I'm not sure how to fix this, or why it is even happening.
(Note, I've stripped back a lot of what was in my data class, but this example still produces the error)
Data.h
#include <chrono>
volatile class Data{
public:
volatile struct Ts{
volatile int64_t unixTimestamp;
};
int ReturnTimestamp() volatile;
void SetTimestamp(int) volatile;
};
Data.cpp
#include "data.h"
#include <ctime>
volatile Data::Ts data;
int Data::ReturnTimestamp() volatile{
return data.unixTimestamp;
}
void Data::SetTimestamp(int timestamp) volatile{
data.unixTimestamp = timestamp;
}
In main I run
int main() {
Data d1;
Data d2;
Data d3;
d1.SetTimestamp(1);
d2.SetTimestamp(2);
d3.SetTimestamp(3);
printf("%i %i %i\n", d1.ReturnTimestamp(), d2.ReturnTimestamp(), d3.ReturnTimestamp());
return 0;
}
The output is
3 3 3
I want the output to be
1 2 3
Why is it not "1 2 3" ?
data is not defined in the class, so you create a global variable. Create a member variable.
class Data{
public:
struct Ts{
volatile int64_t unixTimestamp;
} data;
int ReturnTimestamp() volatile;
void SetTimestamp(int) volatile;
};
instead of volatile Data::Ts data;
The Problem is that variables loose their values.
The variables selectable_values_array and searched_array_size contain the correct values while inside the initialisation of the find_number::find_number.
But when the find_closest object is called the variables are containing
values like -28 and 4214247.
As a logical consequence the samplerate_return returns just garbage.
So what am i missing here ?
Is there a method of safely passing a variable/values inside a class ?
Edit: Added the reduced MyClass and main.
#include "MyClass.h"
int main()
{
int32_t samplerate_return = 0;
int32_t samplerate_request = 7;
MyClass ADC_1 ();
while(1) {
samplerate_return = ADC_1.select(samplerate_request);
}
}
The first Class:
#ifndef MyClass_H
#define MyClass_H
#include "find_number.h"
class MyClass
{
public:
MyClass();
int32_t select(int32_t the_searched_number);
int32_t the_selected_number;
private:
int32_t Integer_array[];
int32_t Numbers_in_Integer_array;
bool init();
find_number MyNumber;
};
And the MyClass.cpp
#include "MyClass.h"
MyClass::MyClass()
{
init();
find_number MyNumber;
}
bool MyClass::init()
{
int32_t Integer_array[] = {2,5,10};
Numbers_in_Integer_array = (sizeof(Integer_array)/sizeof(*Integer_array));
find_number MyNumber (Integer_array,Numbers_in_Integer_array);
return 0;
}
int32_t MyClass::select(int32_t the_searched_number)
{
the_selected_number = MyNumber.find_closest(the_searched_number);
return the_selected_number;
}
This is the header file of the "Find_Numbers" class:
#ifndef find_number_h
#define find_number_h
class find_number
{
public:
//Constructor:
find_number(int32_t *selectable_values,int32_t cells_in_array);
find_number(); // = default;
//Class Objects:
int32_t find_closest(int32_t target_value);
private:
int32_t searched_array_size;
int32_t *selectable_values_array;
};
#endif
And the corresponding find_numbers.cpp
#include "find_number.h"
find_number::find_number(int32_t *selectable_values, int32_t cells_in_array)
{
selectable_values_array = selectable_values;
searched_array_size = cells_in_array;
}
find_number::find_number() {};
int32_t find_number::find_closest(int32_t target_value)
{
int32_t difference = abs( target_value - *selectable_values_array);
int32_t closest_integer = selectable_values_array[0];
// calculating stuff
return closest_integer;
}
Can somebody explain why pp1 compiles, but pp2 does not?
I suppose it has something to do with the union and that the compiler will try to fit everything inbetween { } into buffer8 instead of DATA?
#include <iostream>
using namespace std;
union PassFilterValues
{
struct DATA
{
int32_t a;
int32_t b;
int32_t c;
int32_t k;
} data;
uint8_t buffer8[sizeof(DATA)];
};
union PassFilterDynamic
{
struct DATA
{
PassFilterValues lowFilter;
PassFilterValues highFilter;
} data;
uint8_t buffer8[sizeof(DATA)];
};
#define PASSFILTER_OFF {0,1,2,3}
int main() {
PassFilterDynamic pp1 = {((PassFilterValues)PASSFILTER_OFF), ((PassFilterValues)PASSFILTER_OFF)};
PassFilterDynamic pp2 = {PASSFILTER_OFF, PASSFILTER_OFF};
return 0;
}
feel free to try here: http://ideone.com/XYhfIi
I have been working to create an Arduino library to control a touchscreen. My library builds off of pre-existing libraries written to interface with the display & touch controllers.
Here is the constructor that I have been working on:
Display.cpp
Display::Display(int displayCSPin, int displayDCPin, int touchCSPin,
int newBacklightPin, int newRotation, int newBrightness)
: Adafruit_HX8357(displayCSPin, displayDCPin, -1),
Adafruit_STMPE610(touchCSPin)
{
//Initialize display
}
Display.h
#ifndef DISPLAY_H_
#define DISPLAY_H_
#include "arduino.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#include "Adafruit_STMPE610.h"
class Display : public Adafruit_HX8357, Adafruit_STMPE610 {
public:
Display(int displayCSPin, int displayDCPin, int touchCSPin,
int newBacklightPin, int newRotation, int newBrightness);
};
Whenever I try to compile, the compiler ignores the variables in the base class constructors, and tries to call a default constructor with no variables:
error: no matching function for call to 'Adafruit_HX8357::Adafruit_HX8357()'
I have tried my best to solve this problem, but have not had any success.
Any and all help is greatly appreciated!
Here is the raw code:
Display.cpp
#include "Display.h"
Display::Display(int displayCSPin, int displayDCPin, int touchCSPin, int newBacklightPin, int newRotation, int newBrightness) : Adafruit_HX8357(displayCSPin, displayDCPin, -1), Adafruit_STMPE610(touchCSPin)
{
// tft = Adafruit_HX8357(displayCSPin, displayDCPin, -1);
//ts = Adafruit_STMPE610(touchCSPin);
tft.begin(HX8357D);
ts.begin();
tft.setRotation(newRotation);
backlightPin = newBacklightPin;
pinMode(backlightPin, OUTPUT);
rotation = newRotation;
backgroundColor = HX8357_BLACK;
brightness = newBrightness;
}
Display.h
#ifndef DISPLAY_H_
#define DISPLAY_H_
#include "arduino.h"
#include "Adafruit_GFX.h"
#include "Adafruit_HX8357.h"
#include "Adafruit_STMPE610.h"
class Display : public Adafruit_HX8357, public Adafruit_STMPE610 {
public:
Display(int displayCSPin, int displayDCPin, int touchCSPin, int newBacklightPin, int newRotation, int newBrightness);
void wake();
void sleep();
bool isAwake();
void setBackGroundColor(int newColor);
int getBackgroundColor();
void setBrightness(int newBrightness);
int getBrightness();
void setRotation(int newRotation);
int getRotation();
bool isTouched();
Adafruit_HX8357 tft;
Adafruit_STMPE610 ts;
int backgroundColor;
private:
int brightness;
int rotation;
int backlightPin;
bool awake;
bool touched;
TS_Point p;
};
Look at the actual constructors available for Adafruit_HX8357 and Adafruit_STMPE610:
Adafruit_HX8357(int8_t _CS, int8_t _DC, int8_t _MOSI, int8_t _SCLK,
int8_t _RST, int8_t _MISO);
Adafruit_HX8357(int8_t _CS, int8_t _DC, int8_t _RST = -1);
Adafruit_STMPE610(uint8_t cspin, uint8_t mosipin, uint8_t misopin, uint8_t clkpin);
Adafruit_STMPE610(uint8_t cs);
Adafruit_STMPE610(void);
Your Display constructor is trying to call the second constructor of each class. However, Display is passing int values where int8_t and uint8_t values are expected. It sounds like maybe your compiler is not performing implicit conversions from int to (u)int8_t, so try using explicit conversions to force it:
Display::Display(int displayCSPin, int displayDCPin, int touchCSPin, int newBacklightPin, int newRotation, int newBrightness)
: Adafruit_HX8357((int8_t)displayCSPin, (int8_t)displayDCPin, -1),
Adafruit_STMPE610((uint8_t)touchCSPin)
{
//Initialize display
}
Otherwise, change you Display constructor parameters to use int8_t and uint8_t instead of int:
Display::Display(int8_t displayCSPin, int8_t displayDCPin, uint8_t touchCSPin, int newBacklightPin, int newRotation, int newBrightness)
: Adafruit_HX8357(displayCSPin, displayDCPin, -1),
Adafruit_STMPE610(touchCSPin)
{
//Initialize display
}
Below is example code wherein i'm trying to do serialization using boost.
For struct my_type serialize method is implementated but how do i serialize my_time and data_type as bcoz they are in different namespace
// MyData.hpp
namespace X { namespace Y {
struct my_type
{
std::string a;
double b;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & a;
ar & b;
}
public:
my_type();
my_type(const parameter_strings & parms);
virtual ~my_type();
};
namespace Z
{
typedef unsigned int my_time;
typedef std::string data_type;
}
}
}
//MyData.cpp
#include <MyData.hpp>
my_type:: my_type()
{
}
my_type::~ my_type()
{
}
my_type:: my_type(const parameter_strings & parms)
{
// implemetation
}
Since my_time and data_type are not inside any class or struct hence i don't how do serialize it.
what way i should serialize my_time and data_type in MyData.cpp file and if there is an it will be really helpful.
Thanks
There's nothing you have to do.
my_time and data_type are aliases for the types they are declared with.
Boost serialization has built-in support for std::string and int and won't see the difference.
Relevant information:
boost serialization of native type defined with typedef contained within struct
serializing classes using boost serialization without changing the class
See it Live On Coliru:
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/serialization.hpp>
namespace X { namespace Y {
struct my_type {
std::string a;
double b;
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &ar, unsigned) {
ar & a;
ar & b;
}
public:
my_type(){}
virtual ~my_type(){}
};
namespace Z
{
typedef unsigned int my_time;
typedef std::string data_type;
}
} }
#include <iostream>
int main()
{
boost::archive::text_oarchive oa(std::cout);
X::Y::my_type a;
a.a = "in my_type";
a.b = 3.14;
X::Y::Z::my_time b = 42;
X::Y::Z::data_type c = "hello world";
oa << a << b << c;
}
Prints
22 serialization::archive 10 0 0 10 in my_type 3.1400000000000001 42 11 hello world