управление твердотельным реле

Тема в разделе "Arduino & Shields", создана пользователем Nick_davis, 8 дек 2019.

  1. Nick_davis

    Nick_davis Нуб

    Здравствуйте, есть задача управлять напряжением с помощью твердотельного реле согласно показаниям датчика температуры. Мне помогли с кодом, однако при тестах 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;
    }
     
     
  2. parovoZZ

    parovoZZ Гуру

    А зачем влезать в таймер таким методом? И для чего?
     
  3. Nick_davis

    Nick_davis Нуб

    Честно говоря не могу сказать, сам нуб, только начал разбираться, код чужой. Задача была линейное изменение напряжения от 0 до 220 через твердотельное реле в рамках температурного коридора который задан в LVLON/LVLOFF
     
  4. parovoZZ

    parovoZZ Гуру

    твердотельное реле на такое не способно
     
  5. Nick_davis

    Nick_davis Нуб

    Странно, мне на вот такую постановку задачи посоветовали именно его
     
  6. Asper Daffy

    Asper Daffy Иксперд

    Обратись к автору кода.
     
  7. parovoZZ

    parovoZZ Гуру

    бери обычный симистор
     
  8. DetSimen

    DetSimen Guest

    Который, опять жэ, ты сможешь выковырять молотком и отверткой из твердотельного реле.
     
    ИгорьК нравится это.
  9. parovoZZ

    parovoZZ Гуру

    зачем платить за твёрдотёлку, люто трахаца, если можно купить сразу симистор за меньшие деньги?
     
  10. Asper Daffy

    Asper Daffy Иксперд

     
  11. b707

    b707 Гуру

    ни твердотельное реле, ни тиристор не способны менять частоту тока, и соответвенно, если вентилятор у вас на асинхронном двигателе - регулировать частоту вращения вы таким образом не сможете.
    Какой-то очень знакомый заказ - это вы не на ардуино.ру заказывали?
     
  12. Nick_davis

    Nick_davis Нуб

    Проверяли на ЛАТРе, изменение напряжения позволяет управлять оборотами. Нет, заказывал не там.
     
  13. b707

    b707 Гуру

    скетч в целом написан на троечку с минусом. Процедура timer_setup довольно-таки кривая, совершенно непонятно почему автор при настройке таймера считает параметры в типе float. Но эта процедура лишь интерфейс, основная настройка таймера делается в файле timer-api.h
     
  14. parovoZZ

    parovoZZ Гуру

    Сможет, если речь о однофазном асинхроннике с короткозамкнутым витком. Там меняется коэффициент скольжения при понижении напряжения. А т.к. такие двигатели очень маломощные, то вреда им не нанасоит такой способ регулировки. Ну и двигатель должен сам себя обдувать.
     
  15. Nick_davis

    Nick_davis Нуб

    В целом с вентилятором все именно так и обстоит.
     
  16. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Когда что-то не получается - вставляете обильно команды выводить сообщения в терминал. Вставьте такое -
    Код (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мкС.
    ПС. Твердотельное реле- тот же симистор со схемой управления.
     
    Последнее редактирование: 9 дек 2019
    b707 нравится это.
  17. b707

    b707 Гуру

    прошу прощения, посмотрел внимательнее - код просто бредятина. Такое впечатление, что кто-то просто набросал несвязанные строчки, лишь бы денег срубить.
    Проследим основную "логику" кода в процедуре loop(). Если температура больше установленной, у вас вентилятор включается 100 раз со скоростью от 100 до 0 оборотов, а если температура меньше установленной - вентилятор включается те же сто раз, только скорость меняется от 0 до 100. То есть реально и на уменьшение и на увеличение температуры код реагирует одинаково - раскручивая вентилятор. Будет при это температура как-то регулироваться - я очень сомневаюсь. Добавлю, что в течении времени работы вентилятора ( примерно минута) температура не измеряется и не регулируется совсем. То есть проблема тут вовсе не в таймере - код просто фейковый, его надо переписывать полностью.
    Это не счяитая таких замечательных ошибок, когда в функции timer_setup происходит деление на ноль...

    В общем, как не печально - но вас просто обманули, код абсолютно нерабочий.
     
    Последнее редактирование: 9 дек 2019
  18. Nick_davis

    Nick_davis Нуб

    Спасибо, за информацию. Печальные новости, придется курить самому.
     
  19. Asper Daffy

    Asper Daffy Иксперд

    Только не ту гадость, что курил автор кода.
     
    Daniil и DetSimen нравится это.