Здравствуйте, есть задача управлять напряжением с помощью твердотельного реле согласно показаниям датчика температуры. Мне помогли с кодом, однако при тестах void(loop) прерывается и прекращает работу. Проблема судя по всему в timer_setup но не могу понять что именно не так. Arduino Uno Код (C++): #include <OneWire.h> #include "timer-api.h" #define IN 11 #define OUT 2 #define LVLOFF 30 #define LVLON 80 OneWire ds(IN); boolean flag = 0; void setup () { Serial.begin(9600); pinMode(OUT, OUTPUT); digitalWrite(OUT, 0); timer_setup(0); } void loop () { float temperature = getTemp(); // читаем температуру if (temperature <= LVLOFF) { flag = 0; } if (temperature >= LVLON) { flag = 1; } if (flag) { for(int i = 100; i >= 0; i--) { timer_setup(i); delay(500); } } else { for(int i = 0; i <= 100; i++) { timer_setup(i); delay(500); } } } void timer_handle_interrupts(int timer) { digitalWrite(OUT, 1); delayMicroseconds(10); digitalWrite(OUT, 0); } void timer_setup (float freq) { if (freq) { float HZ = 16000000.0 / 8.0; HZ = HZ / freq; if (HZ <= 65535.0) { timer_init_ISR(TIMER_DEFAULT, TIMER_PRESCALER_1_8, HZ-1); } else if (HZ > 65535.0) { HZ = 16000000.0 / 256.0; HZ = HZ / freq; if (HZ <= 65535.0) { timer_init_ISR(TIMER_DEFAULT, TIMER_PRESCALER_1_256, HZ-1); } else { HZ = 16000000.0 / 1024.0; HZ = HZ / freq; timer_init_ISR(TIMER_DEFAULT, TIMER_PRESCALER_1_1024, HZ-1); } } } } float getTemp(){ // возвращает температуру с датчика byte data[12]; // и останавливает программу на секунду byte addr[8]; if (!ds.search(addr)); ds.reset_search(); if (OneWire::crc8(addr, 7) != addr[7]); ds.reset(); ds.select(addr); ds.write(0x44); delay(1000); ds.reset(); ds.select(addr); ds.write(0xBE); for (int i = 0; i < 9; i++) data[i] = ds.read(); int raw = (data[1] << 8) | data[0]; // Переводим в температуру if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6]; return raw / 16.0; }
Честно говоря не могу сказать, сам нуб, только начал разбираться, код чужой. Задача была линейное изменение напряжения от 0 до 220 через твердотельное реле в рамках температурного коридора который задан в LVLON/LVLOFF
ни твердотельное реле, ни тиристор не способны менять частоту тока, и соответвенно, если вентилятор у вас на асинхронном двигателе - регулировать частоту вращения вы таким образом не сможете. Какой-то очень знакомый заказ - это вы не на ардуино.ру заказывали?
скетч в целом написан на троечку с минусом. Процедура timer_setup довольно-таки кривая, совершенно непонятно почему автор при настройке таймера считает параметры в типе float. Но эта процедура лишь интерфейс, основная настройка таймера делается в файле timer-api.h
Сможет, если речь о однофазном асинхроннике с короткозамкнутым витком. Там меняется коэффициент скольжения при понижении напряжения. А т.к. такие двигатели очень маломощные, то вреда им не нанасоит такой способ регулировки. Ну и двигатель должен сам себя обдувать.
Когда что-то не получается - вставляете обильно команды выводить сообщения в терминал. Вставьте такое - Код (C++): void loop () { float temperature = getTemp(); // читаем температуру if (temperature <= LVLOFF) { flag = 0; //***** } if (temperature >= LVLON) { flag = 1; } Serial.print(" flag= "); Serial.println(flag); if (flag) { for(int i = 100; i >= 0; i--) { Serial.print("Action_A = "); Serial.println(i); timer_setup(i); delay(500); } } else { for(int i = 0; i <= 100; i++) { Serial.print("Action_B = "); Serial.print(i); timer_setup(i); delay(500); } } } И смотрите : Код без конца "крутит ручку" минимум-максимум-минимум- Код дает 10мкС-ные импульсы с интервалом 100мС и постепенно уменьшает интервал до 10мС, при сохранении ширины самого импульса. И потом снова 100мС и тд. 10мкС-екундный импульс - мало. Надо бы 100-1000мкС. ПС. Твердотельное реле- тот же симистор со схемой управления.
прошу прощения, посмотрел внимательнее - код просто бредятина. Такое впечатление, что кто-то просто набросал несвязанные строчки, лишь бы денег срубить. Проследим основную "логику" кода в процедуре loop(). Если температура больше установленной, у вас вентилятор включается 100 раз со скоростью от 100 до 0 оборотов, а если температура меньше установленной - вентилятор включается те же сто раз, только скорость меняется от 0 до 100. То есть реально и на уменьшение и на увеличение температуры код реагирует одинаково - раскручивая вентилятор. Будет при это температура как-то регулироваться - я очень сомневаюсь. Добавлю, что в течении времени работы вентилятора ( примерно минута) температура не измеряется и не регулируется совсем. То есть проблема тут вовсе не в таймере - код просто фейковый, его надо переписывать полностью. Это не счяитая таких замечательных ошибок, когда в функции timer_setup происходит деление на ноль... В общем, как не печально - но вас просто обманули, код абсолютно нерабочий.