Analog pontentiometer connected to an Arduino. simplest possible setup.
The goal is to send a message over Serial
whenever the value changes.
I do not want to spam the Serial connection to much, so the value has to change by at least 20
(sensitivty threshold) before a message Packet is sent.
However, in reality a message Packet is sent even if the value changed only by 1
. Why is sensitivity parameter ignored?
edit: After debugging I can see that it enters the first IF-statement in read()
. The IF statement evaluates to 0
which is super weird. It shouldn't have entered that IF statement!
MagicPot.h:
#define MAGIC_POT_MAX_RAW_VALUE_10B 1023
#define MAGIC_POT_MAX_RAW_VALUE_12B 4095
#define MAX_RAW_VALUE_DEFAULT (MAGIC_POT_MAX_RAW_VALUE_10B)
class MagicPot
{
public:
typedef void (*callback_fn)();
MagicPot(uint8_t pin, uint16_t minRead = 0, uint16_t maxRead = MAX_RAW_VALUE_DEFAULT, uint16_t maxRawRead = MAX_RAW_VALUE_DEFAULT): pin(pin), minRead(minRead), maxRead(maxRead), maxRawRead(maxRawRead) {};
void begin();
bool read(uint8_t sensitivity = 5);
uint16_t getValue();
uint16_t getRawValue();
uint8_t pin;
private:
uint16_t minRead;
uint16_t maxRead;
uint16_t maxRawRead;
callback_fn onChangeCallback;
uint16_t value;
uint16_t rawValue;
};
MagicPot.cpp:
void MagicPot::begin()
{
this->onChangeCallback = nullptr;
this->value = 0;
this->rawValue = 0;
pinMode(this->pin, INPUT);
this->read(0);
}
bool MagicPot::read(uint8_t sensitivity)
{
this->rawValue = analogRead(this->pin);
uint16_t value = map(this->rawValue, 0, this->maxRawRead, this->minRead, this->maxRead);
if (abs(value - this->value) > sensitivity)
{
this->value = value;
return true;
}
else if (value < sensitivity && this->value != this->minRead)
{
this->value = minRead;
return true;
}
else if (value + sensitivity > maxRead && this->value != this->maxRead)
{
this->value = this->maxRead;
return true;
}
return false;
}
Arduino code:
MagicPot analogPots[] =
{
MagicPot(A0),
}
void setup() {
for (MagicPot& x : analogPots) //arr only contains 1 element
x.begin();
}
void loop() {
for (MagicPot& pot : analogPots) //arr only contains 1 element
{
if(true == pot.read(20))
{
CPPacket* analogPotChangedPacket = new CPPacket(HWEvent::Switch, pot.pin, pot.getValue());
SendPacket( &myPacketSerial, analogPotChangedPacket);
delete analogPotChangedPacket;
}
}
}
Actual Output: (read from computer(conn via Serial))
Type | Error | Target | Value |
---|---|---|---|
Switch | NONE | 54 | 516 |
Switch | NONE | 54 | 515 |
Switch | NONE | 54 | 514 |
Switch | NONE | 54 | 513 |
Expected Output:
Type | Error | Target | Value |
---|---|---|---|
Switch | NONE | 54 | 516 |
Switch | NONE | 54 | 496 |
Switch | NONE | 54 | 456 |
Switch | NONE | 54 | 436 |
abs((int16_t) value - this->value)
abs((int16_t) (value - this->value))
orabs((int16_t) value - (int16_t) this->value)
. Or, better yet, make everything signed. Otherwise, if only one term of the subtraction is signed, the unsigned type wins the “usual arithmetic conversions” game.