для измерения времени между сигналом ВКЛ и сигналом ВЫКЛ
int pin_state = LOW;
struct Channel {
byte pin;
byte state;
byte count;
unsigned long fell, rose;
};
const int CHANNEL_COUNT = 3;
Channel channels[CHANNEL_COUNT] = {
{ 2, LOW, 0, 0 },
{ 3, LOW, 0, 0 },
//{ 4, LOW, 0, 0 },
//{ 5, LOW, 0, 0 },
//{ 6, LOW, 0, 0 }
};
void setup()
{
for (int i = 2; i <= CHANNEL_COUNT; ++i) {
pinMode(channels[i].pin, INPUT);
}
Serial.begin(9600);
//Serial.println("pin,fell,rose,low time");
Serial.println("Minutes, Seconds, Count");
}
void loop()
{
for (int i = 0; i < CHANNEL_COUNT; ++i)
{
Channel &c = channels[i];
byte new_state = digitalRead(c.pin);
if (c.state == LOW && new_state == HIGH)
{
c.rose = millis();
c.count = c.count + 1;
}
else if (c.state == HIGH && new_state == LOW)
{
c.fell = millis();
display_channel(c);
}
c.state = new_state;
}
}
void display_channel(const Channel &c)
{
int minutes, seconds;
unsigned long difference;
difference = c.fell - c.rose;
seconds = int(difference/1000);
if (seconds >= 60)
{
minutes = seconds / 60;
seconds = seconds % 60;
}
//Serial.print(difference/1000);
//Serial.print(",");
Serial.print(minutes);
Serial.print(",");
Serial.print(seconds/1000);
Serial.print(",");
Serial.println(c.count-1);
//Serial.print(",");
}
Когда я пытаюсь запустить программу, я не получаю никаких результатов. Есть ли что-то не так с кодом, которое необходимо устранить, прежде чем можно будет отобразить какой-либо вывод?
@Rajesh Anand10, 👍0
Обсуждение1 ответ
Вот каталог ошибок, которые я вижу на первый взгляд:
const int CHANNEL_COUNT = 3;
Channel channels[CHANNEL_COUNT] = {
{ 2, LOW, 0, 0 },
{ 3, LOW, 0, 0 },
//{ 4, LOW, 0, 0 },
//{ 5, LOW, 0, 0 },
//{ 6, LOW, 0, 0 }
};
Вы устанавливаете место для 3 записей, но заполняете только 2. Кроме того, структура канала имеет 5 записей, а не 4. Вы не инициализируете 5-ю запись (rose
) (хотя она будет для вас инициализировано значением 0 - хотя лучше быть явным).
for (int i = 2; i <= CHANNEL_COUNT; ++i) {
pinMode(channels[i].pin, INPUT);
}
Вы начинаете с записи номер 2 (третьей записи) и переходите к четвертой (несуществующей) записи, чтобы установить режим вывода для неопределенных или недопустимых выводов.
for (int i = 0; i < CHANNEL_COUNT; ++i)
Вы заполнили только 2 из трех записей. Однако вы используете третий, как если бы он был заполнен.
Serial.print(minutes);
Если секунд
меньше 60, то минуты
здесь не определены.
Я бы предложил изменить ваш код так, чтобы Channel
был классом, и встроить в него код для управления этим классом.
- Бонусное время
Вот ваша программа, переписанная с использованием класса. В качестве дополнительного бонуса я добавил автоматическое присвоение номера канала каждому объекту при его создании. Чтобы добавить больше каналов, просто добавьте номер контакта в список инициализации.
class Channel {
private:
uint8_t _pin;
uint8_t _state;
uint32_t _rise;
uint32_t _fall;
uint8_t _count;
uint8_t _channel;
static uint8_t channelCount;
void display() {
uint32_t diff = (_fall - _rise) / 1000;
uint32_t secs = diff % 60;
uint32_t mins = diff / 60;
Serial.print(_channel);
Serial.print(",");
Serial.print(mins);
Serial.print(",");
Serial.print(secs);
Serial.print(",");
Serial.println(_count);
}
public:
Channel(int pin) : _pin(pin), _count(0) {
_pin = pin;
_count = 0;
_channel = channelCount;
channelCount++;
}
void process() {
int s = digitalRead(_pin);
if (s != _state) {
_state = s;
if (s == LOW) { // Fell
_fall = millis();
_count++;
display();
} else {
_rise = millis();
}
}
}
void begin() {
pinMode(_pin, INPUT);
}
};
uint8_t Channel::channelCount = 0;
Channel channels[] = { 2, 3 };
#define NUM_CHANNELS (sizeof(channels) / sizeof(channels[0]))
void setup() {
Serial.begin(115200);
Serial.println("Channel,Minutes,Seconds,Count");
for (unsigned int i = 0; i < NUM_CHANNELS; i++) {
channels[i].begin();
}
}
void loop() {
for (unsigned int i = 0; i < NUM_CHANNELS; i++) {
channels[i].process();
}
}
Класс в Arduino такой же, как и в Python, так как я только начинаю с Arduino. В этом случае будет полезен модифицированный код :), @Rajesh Anand10
Да, концепция класса та же самая (это стандартный термин объектно-ориентированного программирования), но способ работы с ними и синтаксис разные. Вам следует проверить некоторые из множества библиотек — почти все они используют классы., @Majenko
@ RajeshAnand10 Я переписал твою программу, используя класс. Там нет комментариев. Вам предстоит разобрать его и понять, что он делает и как он это делает., @Majenko
Но не похоже, что два контакта могут обрабатывать один и тот же «voidprocess()», когда два входа поступают одновременно, верно?, @Rajesh Anand10
У каждого вывода есть свой собственный voidprocess()
, и одновременного выполнения не существует., @Majenko
Здесь счетчик продолжает увеличиваться, когда на выводе низкий уровень, но мне нужен счетчик только тогда, когда на выводе низкий уровень. Я имею в виду, что подсчетом фактически является количество раз, когда булавка становится низкой, а не то, как долго она остается низкой. Как мне соответствующим образом перейти к этому состоянию, поскольку я даже не могу использовать команду Break, поскольку ее нет в структуре цикла?, @Rajesh Anand10
- Использовать timer0, не влияя на millis() и micros().
- Торговый автомат Arduino для мониторинга ввода монет в слот во время ожидания ввода пользователя
- Arduino Мигает двумя светодиодами без задержки (количество повторений)
- Сброс Arduino с помощью ПО (каждый день)
- Та же кнопка одним кликом и двойным кликом
- Как сбросить millis()?
- Реструктурировать код для многозадачности Neopixel + ИК-пульт + ардуино
- Кнопка переключения переключает между операторами обращения с разблокированием кнопки
Подсказка: возможно, вам захочется проверить, как вы обрабатываете индекс вектора канала, инициализацию выводов и т. д. В эскизе много тривиальных ошибок., @Mikael Patel
Не могли бы вы предоставить лучший код решения ошибок, поскольку я не могу их найти., @Rajesh Anand10
Проверьте ответ Маженко ниже. Намеки он понял :)., @Mikael Patel