Как создать таймер на 1 час с микроконтроллером ATtiny13A?

Я хочу управлять нагрузкой переменного тока так, чтобы она включалась на 1 минуту, затем отключалась на 1 час, затем снова включалась на 1 минуту и так далее в цикле.

Я только что изменил скетч мерцания, чтобы он делал:

  1. Включите A1
  2. Затем задержка на 60 000 мс.
  3. Затем выключите A1
  4. Затем задержка на 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, вроде ничего не работает.

, 👍2

Обсуждение

На чем ты это запускаешь?, @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


3 ответа


2

Поскольку неизмененный скетч мерцания мигает за 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


0

Написанный вами код должен работать должным образом. Если нет, я подозреваю что-то сломано в используемом вами ядре 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 МГц.

,

0

У Attiny13 очень маленькая память. Поэтому, если вы хотите, чтобы он обрабатывал вещи, которые кажутся простыми для других микроконтроллеров, у него может не хватить для этого памяти. Например, он не может последовательно выполнять millis(), как в:

long timeStart = миллис(); . . . if (timeIsUp=0 && millis()-timeStart=>60000) . . .

По моему опыту, максимальное время зацикливания этого кода составляет менее 50 секунд.

В качестве обходного пути мне удалось заставить attiny13 отслеживать время более 10 минут, используя только целые числа и используя счетчик. Счетчик увеличивается через 10 секунд. Итак, пример:

for (int i=0; i>10; i++){ задержка(10000); считать++;

Затем вы можете использовать счетчик, чтобы отслеживать прошедшее время.

Использование millis() очень сложно для attiny13.

,