Я не совсем уверен, кто я должен это делать, люди arduino из С++ - люди, поэтому я спрашиваю вас обоих.
Я пытаюсь создать небольшую библиотеку для Ардуино. У меня проблема, когда я не могу получить переменную-член структуры, которую нужно изменить. Я просто покажу код и расскажу, что пойдет не так.
ButtonGroup.h:
#ifndef BUTTONGROUP_H
#define BUTTONGROUP_H
#include "Arduino.h"
struct button {
int buttonState;
int lastButtonState;
int pin;
void (*f)(int);
};
class ButtonGroup {
public:
ButtonGroup(int dimension);
~ButtonGroup();
virtual void addButton(int pin, void (*f)(int));
virtual void loopButtons();
private:
button* buttons;
int count;
};
#endif
ButtonGroup.cpp:
#include "ButtonGroup.h"
ButtonGroup::ButtonGroup(int dimension) {
buttons = new button[dimension];
count = 0;
}
ButtonGroup::~ButtonGroup() {
delete [] buttons;
}
void ButtonGroup::addButton(int pin, void (*f)(int)){
button b = {0, 0, pin, f};
buttons[count] = b;
pinMode(pin, INPUT);
count++;
}
void ButtonGroup::loopButtons(){
for(int i=0; i<count; i++) {
button b = buttons[i];
b.buttonState = digitalRead(b.pin);
if (b.buttonState == 0 && b.lastButtonState == 1) {
(b.f(2));
}
b.lastButtonState = b.buttonState;
}
}
Я пытаюсь обнаружить, когда моя кнопка попадает на задний фронт (состояние кнопки prevoius равно 1, а ток - 0), а затем я хочу вызвать функцию-член. Моя проблема в том, что когда я пытаюсь изменить lastButtonState в последней строке, это значение не изменилось при следующем вызове loopButtons(). Кажется, я работаю над локальной копией или чем-то еще, но поскольку я обращаюсь к массиву, я думал, что все должно быть хорошо? Я подозреваю, что у него есть что-то с указателем/ссылкой/значением, но я не могу понять, как его обойти.
Я запускаю и компилирую код через Arduino IDE.
Благодарю!
Так же, как вы делали в addButton
button b = {0, 0, pin, f}; // Local Object
buttons[count] = b; // copied to array via assignment
Так был ваш обработчик, но наоборот:
button b = buttons[i]; // Local object copy-constructed from array element
b.buttonState = digitalRead(b.pin); // remaining code working on local copy.
Используя ссылку, копия не производится, и мы ссылаемся на элемент массива через ссылочную переменную:
button& b = buttons[i]; // using reference to buttons[i]
b.buttonState = digitalRead(b.pin); // remaining code modifying buttons[i] using b
В функции ButtonGroup :: loopButtons() вы объявляете
button b = buttons[i];
На этом этапе вы создаете переменную b, типа кнопки. Когда вы применяете assignemnent (= кнопки [i]), вы берете новую кнопку b и даете ей значение кнопки, хранящейся на кнопках [i] (т.е. вы копируете кнопку).
Вы можете решить это, изменив строку на button& b = buttons[i];
Это создаст ссылку на кнопку, сохраненную на кнопках [i], которая имеет желаемый эффект.
Если вы не возражаете против пары указателей стиля: b - это неправильное имя переменной, и вам следует предпочесть использование массива или вектора c++, а не массива ac.
button b = buttons[i];
к этойbutton& b = buttons[i];
(и да, вы использовали локальную копию, точно так же, как вы были вaddButton
прямо перед тем, как скопировать ее в массив с помощью оператора присваивания, но на этот раз наоборот).