Обновите атрибут класса с помощью attachInterrupt
Я хочу реорганизовать этот код
/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
volatile int flow_frequency; // Измеряет импульсы датчика расхода
unsigned int l_hour; // Расчетные литры/час
unsigned char flowsensor = 2; // Вход датчика
unsigned long currentTime;
unsigned long cloopTime;
void flow () // Функция прерывания
{
flow_frequency++;
}
void setup()
{
pinMode(flowsensor, INPUT);
digitalWrite(flowsensor, HIGH); // Дополнительное внутреннее подтягивание
Serial.begin(9600);
attachInterrupt(0, flow, RISING); // Настройка прерывания
sei(); // Разрешить прерывания
currentTime = millis();
cloopTime = currentTime;
}
void loop ()
{
currentTime = millis();
// Каждую секунду вычисляем и печатаем литры/час
if(currentTime >= (cloopTime + 1000))
{
cloopTime = currentTime; // Обновляет cloopTime
// Частота импульсов (Гц) = 7,5Q, Q — скорость потока в л/мин.
l_hour = (flow_frequency * 60 / 7.5); // (Частота импульсов x 60 мин) / 7,5Q = расход в л/час
flow_frequency = 0; // Сброс счетчика
Serial.print(l_hour, DEC); // Печать литров в час
Serial.println(" L/hour");
}
}
Первоначально найдено здесь: источник
к решению на основе классов:
/*
YF‐ S201 Water Flow Sensor
Water Flow Sensor output processed to read in litres/hour
Adaptation Courtesy: www.hobbytronics.co.uk
*/
class FlowSensor {
volatile int flow_frequency;
unsigned int l_hour;
unsigned char pin;
unsigned long currentTime;
unsigned long cloopTime;
public:
void flow () {
flow_frequency++;
};
void setup() {
pinMode(pin, INPUT);
digitalWrite(pin, HIGH); // Дополнительное внутреннее подтягивание
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(pin), flow, RISING); // Настройка прерывания
sei(); // Разрешить прерывания
currentTime = millis();
cloopTime = currentTime;
}
void loop() {
currentTime = millis();
// Каждую секунду вычисляем и печатаем литры/час
if(currentTime >= (cloopTime + 1000))
{
cloopTime = currentTime; // Обновляет cloopTime
// Частота импульсов (Гц) = 7,5Q, Q — скорость потока в л/мин.
l_hour = (flow_frequency * 60 / 7.5); // (Частота импульсов x 60 мин) / 7,5Q = расход в л/час
flow_frequency = 0; // Сброс счетчика
Serial.print(l_hour, DEC); // Печать литров в час
Serial.println(" L/hour");
}
}
FlowSensor() {
setup();
};
};
FlowSensor flowsensor_intake;
void setup()
{
flowsensor_intake = FlowSensor();
}
void loop ()
{
flowsensor_intake.loop();
}
Но я получаю следующую ошибку в Arduino IDE:
/tmp/087639235/water_flow/water_flow.ino: в статической функции-члене 'статический недействительный FlowSensor::flow()':
/tmp/087639235/water_flow/water_flow.ino:17:19: ошибка: невозможно позвонить функция-член 'void FlowSensor::update_flow()' без объекта
обновление_потока()
^
статус выхода 1
Я понимаю, что поток не является статической функцией и что я не могу сделать ее статической, поскольку она обрабатывает нестатический элемент.
Но я не могу придумать альтернативного решения этой проблемы. Моя цель — контролировать несколько датчиков потока, создавая объект в функции setup()
и обновляя их при каждом вызове loop()
.
@Valanthor, 👍1
1 ответ
Вы попали в классическую ловушку. Есть пара вещей, о которых стоит подумать. Во-первых, если это одноэлементный класс (так как всегда будет только один экземпляр), то вы можете просто иметь функцию, не являющуюся членом, которую вы используете с attachInterrupt, и эта функция просто вызывает нужную функцию-член. Обычно я бы создал экземпляр в .cpp и поместил объявление extern для него в заголовок, чтобы его можно было просто использовать без его создания. Посмотрите, как работает Serial для примера. Затем поместите все материалы типа конфигурации в метод begin или init для вызова из установки. Таким образом, функция, не являющаяся членом прерывания, может быть частью заголовка, и пользователю никогда не придется видеть ее или возиться с ней, и создается впечатление, что она является частью класса.
Если это не одноэлементный класс, и когда-нибудь у вас может быть несколько экземпляров этого класса в одной программе, вам следует начать спрашивать себя, как прерывание узнает, на какой экземпляр воздействовать.
- Цикл While не прерывается
- как отправить аргумент объектам ESP8266WebServer в функции
- Получена ошибка недопустимого преобразования из 'const char*' в 'const uint8_t*
- Что именно делает препроцессор Arduino?
- GPS автономный робот
- Как изменить переменную/скетч с помощью графического интерфейса
- оператор if не работает с дробью, но работает с десятичным эквивалентом
- Нужна помощь с моими кодами? для моего проекта: Наполнение и укупорка с помощью Arduino uno
Да, я хочу иметь несколько экземпляров. Сейчас думаю о структурном подходе., @Valanthor
Хорошо, тогда у вас есть проблема. Как каждый экземпляр узнает, к какому прерыванию присоединить себя? Как прерывание узнает, какой экземпляр относится к какому прерыванию? Оказывается, это банка с червями, и поэтому это запрещено., @Delta_G
Я согласен. Singlton или статические функции-члены не будут работать. Моя текущая работа — это функция-член, которая вызывается определенной функцией для каждого
attachInterrupt
., @Valanthor