millis застревает,

Тема в разделе "Arduino & Shields", создана пользователем mutis, 28 сен 2015.

  1. mutis

    mutis Нуб

    Здраствуйте,я переделываю скеч , и на столе пока всё работает.Хочу добавить 2-е условие в таймер turnPeriodMin ,чтоб при выходе outMax и outMin
    Код (C++):
    void thermostat() {
      //long previousMillis = 0;
    unsigned long currentMillis = millis ();
      int fanMax;
      int fanMin;
      float tempPoint;
      float hysteresisTemp ;
      int turnPeriod;              
      int turnPeriodMin;
       int turnCommand;
      int ledState = LOW;

      EEPROM_read(1, tempPoint);
      EEPROM_read(12, hysteresisTemp);
      EEPROM_read(9, fanMax);
      EEPROM_read(16, fanMin);
      EEPROM_read(11, turnPeriod);
      EEPROM_read(20, turnPeriodMin);
      outMax = fanMax;
      outMin = fanMin;
      Setpoint = tempPoint;
      Input = temp1Ink;
      lcd.setCursor(0, 0);                
      lcd.print("T1=");
      lcd.print(temp1Ink, 1);          
      lcd.print((char)223);
      lcd.print(" (");
      lcd.print(Setpoint, 1);
      lcd.print(")");
      lcd.setCursor(9, 1);
      lcd.print("s");
      lcd.print(turnPeriod);
      lcd.setCursor(13, 1);
      lcd.print("s");
      lcd.print(turnPeriodMin);
     
         if (temp1Ink < (Setpoint - hysteresisTemp)) {
           analogWrite(heater_pin, outMax);  
           turnCommand = turnPeriod;
         }
         if (temp1Ink > (Setpoint + hysteresisTemp)){
           analogWrite(heater_pin, outMin);      
           turnCommand = turnPeriodMin;      
         }
     
      if(currentMillis - previousMillis > turnCommand * 1000 && ledState == LOW) {
          ledState = HIGH;//включаем светодиод
          digitalWrite(ledPin, ledState);
         }
        if ( bouncer.update() ) {
       if (currentMillis - previousMillis > ( bouncer.read() == LOW )  && ledState == HIGH) {
        if ( bouncer.read() == LOW ) {
           previousMillis = currentMillis; // сохраняем время последнего выключения
           ledState = LOW;//выключаем светодиод
           digitalWrite(ledPin, ledState);
             }
          }
       }
    }
    отсчитывал разное время.Я переписал команды,и всё заработало .Но ........только без histeresis. Если задаю histeresis ,в том интервале (+- от Setpoint) таймер застревает. И уже незнаю где копать.Поделитесь советами пожалуйста. Чясть кода:
     
  2. DrProg

    DrProg Вечный нерд

    Застревать таймер запросто может при неправильном типе переменной. Тут я вообще не понял как все работает. где ожидание по таймеру и прочее. Часть переменных вообще объявлена за пределами функции и о них ничего не известно.
     
    ИгорьК нравится это.
  3. mutis

    mutis Нуб

    Полный скеч :http://arduino.ru/forum/programmirovanie/taimer-s-2-mya-usloviyami

    Мне самому не понятно, почему только при температуре if < " и " if> в интервале " и" - застой.А если порог температуры фиксированный ,то всё отлично.Такое мнение,что
    millis запутываетса с вычислением разниц темеператур.
     
    Последнее редактирование: 28 сен 2015
  4. mutis

    mutis Нуб

    Господа гуру, моя первая попытка была весьма неудачная. Написал укороченный скеч.Но рабоает криво: когда температуа нарастает-порядок.А вот при падении таймер переключаетса обратно от верхчей температуры.С ШИМом всё ок.Чего то не хватает,но...?
    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM2.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    #include <Bounce.h>
    #define heater_pin 11                 // нагреватель
    #define ledPin 9               // управление поворотом
    #define DS18B20_Pin A1                 //пин термометра
    #define BUTTON 8       //limit switch
    Bounce bouncer = Bounce(BUTTON, 20); //дребезг limit switch
    float tempTank;                  // Температура DS18B20
    unsigned long trhMillis = 0;    // период опроса датчиков
    const unsigned long TRHSTEP   = 3000UL;  // Sensor query period
    byte measActive = false;    
    LiquidCrystal_I2C lcd(0x27, 16, 2);  // инициализация библиотеки дисплея
    OneWire oneWire(DS18B20_Pin);
    DallasTemperature sensors(&oneWire);
    double outMin , outMax ;//PWM
       void setup() {
       TCCR2B = TCCR2B & 0b11111000 | 0x01; // 32 kHz PWM
      Serial.begin(9600);
      lcd.init();          // Старт дисплея
      lcd.backlight();     // Включаем подсветку дисплея
      pinMode(BUTTON, INPUT_PULLUP);// limit switch
      pinMode(heater_pin, OUTPUT);
      pinMode(ledPin, OUTPUT);
      sensors.begin();
      sensors.setResolution(12);    // установить разрешение (точность)
      sensors.setWaitForConversion(false);  // отключить ожидание
    }
    void loop() {
      getSensors();
      Temperature();
    }
    void Temperature(){
      static uint32_t millis_start = 0;
      int val ;
      int turnMin=2;          //timer            
      int turnMax=5;          //timer
      int ledState = LOW;
       val=turnMin,turnMax;
       outMax = 200;         //pwm
       outMin = 20;         //pwm
     
       if (tempTank <=28) {
       analogWrite(heater_pin, outMax);          
        val = turnMin;
       }
       if(tempTank >=30){
       analogWrite(heater_pin, outMin);
        val = turnMax;
      }
        if ( bouncer.update() ) {     //с нажатием запускаетса таймер
        if ( bouncer.read() == LOW ) {
        ledState = LOW;//выключаем limit
        digitalWrite(ledPin,LOW);
        millis_start = millis();
         }
       }
      if(millis_start && millis()-millis_start >= val*1000)
      {  
      digitalWrite(ledPin,HIGH);
       millis_start = 0;
    }
       lcd.setCursor(0, 0);                
       lcd.print("T=");
       lcd.print(tempTank, 1);          
       lcd.print((char)223);
    }
    void getSensors() {//////////////////////////////////////////////////////////////////////
       unsigned long curMillis = millis();          // Получаем текущее время работы
       sensors.requestTemperatures();
       if (curMillis - trhMillis >= TRHSTEP) {      // время для нового измерения?
       measActive = true;
       trhMillis = curMillis;
      }
       tempTank = sensors.getTempCByIndex(0);
    }
     
  5. mutis

    mutis Нуб

    проблема решилась разделив условие.

    Код (C++):
     if (tempTank <=28) {
       analogWrite(heater_pin, outMax);        
        digitalWrite(Led,HIGH);
       }
       if(tempTank >=30) {
       analogWrite(heater_pin, outMin);
        digitalWrite(Led,LOW);
      }
           if(digitalRead(Led)==HIGH) {
        val = turnMin;
      }
      else  {
        val = turnMax;
      }
    я дописал лед как контрольную лампу,и от неё задал таймер.