Запуск двух циклов одновременно на Arduino
Я не могу объединить два приведенных ниже скетча. Что мне нужно, так это либо запустить оба цикла вместе, либо найти способ запустить обе функции внутри одного цикла.
Скетч 1
#include <SevSeg.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <TimeLib.h>
#include <Wire.h>
// Создаем экземпляр объекта
SevSeg sevseg;
bool militaryTime = false; // верно для 24-часового формата
void setup() {
byte numDigits = 4;
byte digitPins[] = {2, 3, 4, 5};
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
bool resistorsOnSegments = false; // 'false' означает, что резисторы находятся на цифровых выводах
byte hardwareConfig = COMMON_ANODE; // См. README.md для опций
bool updateWithDelays = false; // По умолчанию. рекомендуемые
bool leadingZeros = true; // Используйте 'true', если хотите сохранить ведущие нули
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
sevseg.setBrightness(90);
}
void loop() {
tmElements_t tm;
int time;
int dot;
if (RTC.read(tm)) {
time = tm.Hour * 100;
if (time > 1200 && militaryTime == false) {
time = time - 1200;
}
if (time == 0 && militaryTime == false) {
time = 1200;
}
time += tm.Minute;
}
if ((tm.Second % 2) == 0) {
dot = 4;
} else {
dot = 2;
}
//Производим вывод на дисплей
sevseg.refreshDisplay();
sevseg.setNumber(time, dot);
}
Скетч 2
// Измените это на выходной контакт, который вы используете
#define TICK_PIN A0
void setup()
{
pinMode(TICK_PIN,OUTPUT);
while (1) {
tone(TICK_PIN,1000,2);
delay(1000);
}
}
void loop()
{
}
@Ameer, 👍0
Обсуждение4 ответа
Лучший ответ:
В основном вам нужно избавиться от задержки и любых других циклов блокировки. Вот как это сделать.
Определите эту переменную глобально.
unsigned long lastTime = 0;
Затем в первом цикле добавьте следующий код либо в начало, либо в конец:
if (millis() - lastTime >= 1000 || !lastTime) {
lastTime = millis();
tone(TICK_PIN,1000,2);
}
Для чего нужен !lastTime
?, @Jot
Это сработало очень хорошо, @Ameer
Это выглядит знакомо .... точно так же, как мой ответ, который был опубликован за 3 часа до вашего., @Johnny Mopp
@JohnnyMopp Ну, это обычный трюк для эмуляции многозадачности на Arduino. Посмотрев на ваш, он не решает первую проблему выполнения, описанную выше. Вы можете найти этот ответ почти везде, это не ракетостроение., @Ikbel
Это нормально, хотя я не читал ваш ответ заранее, но я могу удалить свой ответ, если это сделает вас счастливым;), @Ikbel
Отпусти ситуацию. Я пошел дальше ... и правильно было бы удалить ваш необоснованный DV в моем ответе., @Johnny Mopp
Не проблема. Ожидание одобрения редактирования, прежде чем я смогу снова проголосовать за вас. Кроме того, я не мог удалить этот ответ, потому что он был принят., @Ikbel
@LookAlterno, я никогда не использовал !lastTime
. Возможно, мне никогда не нужно было что-то запускать при первом выполнении цикла. Через 50 дней это может вызвать сбой., @Jot
Один из способов — использовать обратный вызов таймера.
// Включить библиотеку timer1
#include "TimerOne.h"
// Здесь другой код...
void setup()
{
// Другой код установки здесь....
// Настройка таймера
Timer1.initialize(1000000); // 1 секунда
Timer1.attachInterrupt(callback); // Установить обратный вызов
}
void callback()
{
tone(TICK_PIN, 1000, 2);
}
void loop()
{
// Код из 1-го цикла здесь...
}
Если это не сработает (если что-то еще использует timer1), вы можете просто отслеживать время между звуковыми сигналами:
uint32_t last_beep = 0;
const int beep_timeout = 1000;
void loop() {
// Здесь код из первого цикла
uint32_t now = millis();
if (now - last_beep >= beep_timeout) {
tone(TICK_PIN, 1000, 2);
last_beep = now;
}
}
Не могли бы отрицатели объяснить?, @Johnny Mopp
Вы действительно прочитали и поняли мой вопрос лучше, чем принятый ответчик. Причина, по которой я не принял это, была просто из-за сложности. Я проголосовал за ваш ответ., @Ameer
Одновременный запуск двух циклов на Arduino
в общем случае ответ зависит от вашего определения слова "одновременно".
Но в данном случае ответ "определенно да", так как другой цикл пуст.
общий подход к такого рода вопросам:
void setup(void) {
setup1(); // запускаем настройку 1
setup2(); // запускаем настройку 2
...
}
void loop(void) {
loop1(); // запускаем цикл1
loop2(); // запускаем цикл2
...
}
этот подход потерпит неудачу только в том случае, если исходные функции setup() и loop() написаны плохо.
Это может работать в некоторых случаях, но даже близко не для моего случая., @Ameer
Я считаю, что самый простой способ справиться с этой задачей, когда вам приходится иметь дело с большой задержкой и думать, что вам нужен второй цикл, — это создать счетчик в основном цикле, используя сантисекунды (10 миллисекунд), а затем запустить ваш требуемый ответ, когда счетчик достигает вашего времени, например недействительный цикл (пустой) { счетчик=счетчик +1; если (счетчик==100){ тон (TICK_PIN, 1000, 2); счетчик =0; } ....остальная часть кода
- 74HC595 к 4 значному 7 сегменту с использованием библиотеки SevSegShift
- Как записать и прочитать из файла SPIFFS как данные объекта на ESP8266
- Почему у меня 7 сегмент не обновляется каждую секунду как в программе?
- 7-сегментный дисплей с потенциометром
- Как прочитать выходные данные с разъема SPI с помощью Arduino Uno?
- отображение 3-значного времени часов на 4-значном 7-сегментном дисплее
- 4-значный 7-сегментный дисплей неправильно отображает значение
- Преобразование из 3 вольт в 5В
@LookAlterno На самом деле второй «цикл» никогда не выполняется из-за «пока» в «настройке»., @Johnny Mopp
Второй цикл также может быть в функции цикла. В любом случае, я не могу объединить их, чтобы заставить это работать., @Ameer