Как создать таймер на 1 час с микроконтроллером ATtiny13A?
Я хочу управлять нагрузкой переменного тока так, чтобы она включалась на 1 минуту, затем отключалась на 1 час, затем снова включалась на 1 минуту и так далее в цикле.
Я только что изменил скетч мерцания, чтобы он делал:
- Включите
A1
- Затем задержка на 60 000 мс.
- Затем выключите
A1
- Затем задержка на 3 600 000 мс (3 600 секунд или 1 час).
... но, похоже, это не работает.
Похоже, что светодиод, подключенный к A0
, включается, но вместо того, чтобы выключиться через 1 минуту, он выключается через 8 минут 30 секунд.
Есть предложения?
Я исправил скетч. Теперь это занимает 1 секунду, поскольку фактическая 1 секунда 1 выбирает тактовую частоту 1 МГц в IDE.
int ledPin = A3; // номер вывода светодиода
int ledState = HIGH; // ledState используется для установки светодиода
unsigned long previousMillis = 0; // запомним время последнего обновления светодиода
unsigned long OnTime = 60000; // миллисекунды времени включения
unsigned long OffTime = 10000; // миллисекунды простоя
void setup()
{
// устанавливаем цифровой вывод в качестве выхода:
pinMode(ledPin, OUTPUT);
}
void loop()
{
// проверяем, не пора ли изменить состояние светодиода
unsigned long currentMillis = millis();
if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
{
ledState = LOW; // Выключи это
previousMillis = currentMillis; // Запоминаем время
digitalWrite(ledPin, ledState); // Обновить фактический светодиод
}
else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
{
ledState = HIGH; // включить его
previousMillis = currentMillis; // Запоминаем время
digitalWrite(ledPin, ledState); // Обновить фактический светодиод
}
}
затем включается на 1 сек. и выключается на 1 сек., затем случайное включение через 30 сек или 1 мин 30 сек. Я хочу включать его на 1 минуту каждый час.
Я попытался изменить скетч Blink следующим образом:
void setup() {
pinMode(A3, OUTPUT);
}
void loop() {
digitalWrite(A3, HIGH);
delay(60000);
digitalWrite(A3, LOW);
delay(900000);
}
но он по-прежнему включается на 1 минуту и выключается на 1 минуту.
Я также пробовал это:
void setup() {
pinMode(A3, OUTPUT);
}
void loop() {
digitalWrite(A3, HIGH);
delay(60000);
digitalWrite(A3, LOW);
delay(3.6e+6);
}
Независимо от того, что я делаю во время и в свободное время, всегда остается то же самое.
Я просто хотел узнать одну вещь: могу ли я установить таймер на 1 час выключения и 1 минуту включения с помощью ATtiny13A или нет?
Пробовал 1,2 МГц, 1 МГц, все часы в IDE, вроде ничего не работает.
@VOID seekers, 👍2
Обсуждение3 ответа
Поскольку неизмененный скетч мерцания мигает за 8,4 секунды, я думаю, что мое предположение верно. Часы ATTiny идут в 8 раз медленнее, чем думает код.
После установки ядра Attiny в меню должна появиться запись для тактовой частоты. Скорее всего стандарт 8МГц. Но установка 8 МГц не означает, что Attiny использует 8 МГц. Чтобы выбирать между различными источниками тактовых импульсов и частотами, вы должны изменить фьюзы микроконтроллера (это всего лишь несколько битов специальной энергонезависимой памяти в чипе, которые устанавливают специальную аппаратную конфигурацию; больше информации в этот вопрос). Это делается, когда вы записываете загрузчик на чип. Это легкая версия. В качестве альтернативы вы можете напрямую использовать команду avrdude
для установки фьюзов. Это продвинутый способ.
В настоящее время предохранители вашего Attiny, похоже, установлены на внутреннюю частоту 1 МГц. Но компилятор использует частоту, которую вы выбрали в меню, следовательно, внутренние часы 8 МГц. Таким образом, компилятор считает, что чип работает на частоте 8 МГц, и поэтому генерирует временной код для этой скорости выполнения. Но ваш чип сейчас в 8 раз медленнее, чем думает компилятор.
TL;DR: запишите загрузчик на чип, чтобы среда разработки Arduino IDE установила правильные предохранители для вашей тактовой частоты.
Я сомневаюсь, что ATtiny13a достаточно большой для загрузчика, имея только 1 КБ флэш-памяти / памяти программ. Мой опыт работы с ATtinyCore (который не поддерживает tiny13 AFAIK) заключается в том, что он правильно устанавливает фьюзы при выборе опции «прожечь загрузчик», даже если в настройках платы выбрана опция «ATTiny XX (без загрузчика)»., @StarCat
Написанный вами код должен работать должным образом. Если нет, я подозреваю что-то сломано в используемом вами ядре Arduino. Однако, такая тривиальная задача может быть очень легко запрограммирована на простом C, в уровень avr-libc:
#define F_CPU 1000000 // 1 МГц
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
DDRB |= _BV(PB3); // PB3 в качестве вывода
for (;;) {
PORTB |= _BV(PB3); // высокий уровень PB3
_delay_ms(60e3); // 1 мин
PORTB &= ~_BV(PB3); // низкий уровень PB3
_delay_ms(3.6e6); // 1 час
}
}
Я бы скомпилировал его с помощью:
avr-gcc -mmcu=attiny13a -Os -Wall -Wextra 1h-timer.c -o 1h-timer.elf
См. Регистры портов в руководстве по Arduino, чтобы узнать значение
Здесь используются макросы. Вы можете настроить F_CPU
для точной настройки задержек на случай, если
ваши часы ATtiny не совсем 1 МГц.
У Attiny13 очень маленькая память. Поэтому, если вы хотите, чтобы он обрабатывал вещи, которые кажутся простыми для других микроконтроллеров, у него может не хватить для этого памяти. Например, он не может последовательно выполнять millis(), как в:
long timeStart = millis(); . . . if (timeIsUp=0 && millis()-timeStart=>60000) . . .
По моему опыту, максимальное время зацикливания этого кода составляет менее 50 секунд.
В качестве обходного пути мне удалось заставить attiny13 отслеживать время более 10 минут, используя только целые числа и используя счетчик. Счетчик увеличивается через 10 секунд. Итак, пример:
for (int i=0; i>10; i++){ задержка(10000); считать++;
Затем вы можете использовать счетчик, чтобы отслеживать прошедшее время.
Использование millis() очень сложно для attiny13.
- Arduino Nano 33 BLE получает текущее время с помощью RTC
- C++ против языка Arduino?
- avrdude ser_open() can't set com-state
- Как справиться с rollover millis()?
- Как читать и записывать EEPROM в ESP8266
- Float печатается только 2 десятичных знака после запятой
- устаревшее преобразование из строковой константы в 'char*'
- Как получить текущее время и дату в Arduino без внешнего источника?
На чем ты это запускаешь?, @Majenko
Вы уверены, что Attiny работает на той частоте, на которой вы думаете? Однажды я настроил свой Attiny85 на 1 МГц вместо ожидаемых 8 МГц, поэтому мне стало интересно, почему мой код работает в 8 раз медленнее., @chrisl
Как быстро мигает светодиод, когда вы запускаете исходный и неизмененный скетч мигания?, @ocrdu
Это около 8,4 секунды, @VOID seekers
Похоже, ChrisL прибил это. Ваш attiny13a работает на частоте 1 МГц вместо 8., @Duncan C
Как вы программируете ATtiny? Каким программатором и менеджером плат вы пользуетесь?, @StarCat
Я использую arduino mega в качестве интернет-провайдера на макетной плате., @VOID seekers
Пожалуйста, опубликуйте свой *точный* код. Какие у вас типы переменных?
int
, например, может содержать только32767
мс, НЕ3600000
мс! Это [2 байта на микроконтроллерах AVR] (https://www.arduino.cc/reference/en/language/variables/data-types/int/). Это означает, что «unsigned int» содержит только до «65535» мс., @Gabriel StaplesПожалуйста, переместите все ваши ответы, которые являются дополнениями к вашему вопросу, в свой вопрос, а затем удалите все ваши ответы, которые не являются ответами. Можно написать ответ на свой вопрос, но если вы просто пытаетесь улучшить свой вопрос, отредактируйте свой вопрос и вместо этого добавьте непосредственно к своему вопросу., @Gabriel Staples