Просьба помочь со скетчем.

Тема в разделе "Arduino & Shields", создана пользователем avgustdon, 26 мар 2017.

  1. avgustdon

    avgustdon Нуб

    Прошу помочь настроить работу скетча.

    Задача управлять устройством загрузки твердого топлива (гранулы) в печь. Выглядит это так:

    1. Печь холодная. Растопка осуществляется вручную.

    2. Дальше топливо должно разгореться (температура поднимается) время достижения температуры 500гр порядка 5 мин. Полагаю, этот порог температуры и следует считать минимальным.

    3. По достижении заданной температуры включается загрузочное устройство, работает заданное время (1-5 сек), затем отключается. (первый цикл)

    4. Дальше дожидаемся разгорания топлива. Полагаю это 700 гр. - второй уровень температуры, который необходимо контролировать. (одновременно считаем этот уровень номинальным для режима работы печи)

    5. И только после этого можно разрешать новый цикл подачи топлива, который состоится когда температура снова достигнет 500 гр. Топливо подаем циклами по 1-5 сек.

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

    Заранее благодарен.


    Код (C++):
    [code]
    #define temperature_pin  5
    int relay_pin = 13;
    int relay = HIGH ;
    int podacha = 1000; // время подачи
    int t_min = 500;
    int t_max = 600;
    int t_tek = 0;
    int flag_t_max = 0;
    // ---------------------------------------------
    float  k_temp = 1;
    // ---------------------------------------------
    const int Latch_pin = 4;
    const int CLK_pin  = 7;
    const int Data_pin = 8;

    const byte SEGMENT_MAP[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0X80, 0X90}; // матрица цифр 0 to 9
    const byte SEGMENT_SELECT[] = {0xF1, 0xF2, 0xF4, 0xF8}; // матрица выбора знакоместа 1 to 4
    void WriteNumber(int Number) {// Вывод числа на экран
      WriteNumberToSegment(0 , Number / 1000);
      WriteNumberToSegment(1 , (Number / 100) % 10);
      WriteNumberToSegment(2 , (Number / 10) % 10);
      WriteNumberToSegment(3 , Number % 10);
    }
    void WriteNumberToSegment(byte Segment, byte Value) { // запись нужного числа (0-9) в нужную позицию(1-4)
      digitalWrite(Latch_pin, 0);
      shiftOut(Data_pin, CLK_pin, MSBFIRST, SEGMENT_MAP[Value]);
      shiftOut(Data_pin, CLK_pin, MSBFIRST, SEGMENT_SELECT[Segment] );
      digitalWrite(Latch_pin, 1);
    }
    // -----------------------------------------------------------------------
    void setup() {
      pinMode(relay_pin, OUTPUT);
      digitalWrite(relay_pin, !relay);
      Serial.begin(9600);            // Скорость порта для отладки
      //analogReference(INTERNAL ); //Объявляем диапазон чтения с аналогового порта.
      pinMode(Latch_pin, OUTPUT);
      pinMode(CLK_pin, OUTPUT);
      pinMode(Data_pin, OUTPUT);
    }
    void loop() {
      static uint32_t past = 0;
      if (millis() - past >= 1000) { //опрос раз в заданное время если разгорается
        past = millis();
        t_tek = (analogRead(temperature_pin) / (k_temp));
        if (t_tek >= t_max) {
          flag_t_max = 1; // Топливо разгорелось выходим в автоматический режим
        }
        while (analogRead(temperature_pin) >= t_min && flag_t_max == 1) {
          Serial.println(analogRead(temperature_pin));
         
        } // Ждём понижения температуры до нижнего порога

        if (flag_t_max == 1) {
          digitalWrite(relay_pin, relay);
          delay(podacha);
          digitalWrite(relay_pin, !relay);
          flag_t_max = 0;
        }   // подкинули дровишек
        Serial.println(analogRead(temperature_pin) / (k_temp));
      }
      WriteNumber(t_tek);
    }
     
    [/code]
     
  2. Tomasina

    Tomasina Сушитель лампочек Модератор

    сколько всего режимов?
    Вот тут
    Код (C++):
     while (analogRead(temperature_pin) >= t_min && flag_t_max == 1) {
          Serial.println(analogRead(temperature_pin));
    явно написано, что пока условие выполняется, дальше не двигаемся, а у тебя вывод температуры как раз дальше в скетче.

    Должно быть примерно так:
    Код (C++):
    void loop()
    {
      readTempSensor();
      displayTemperature();
      switch(mode):
      {
        case 1:
        break;

        case 2:
        break;

        case n:
        break;
      }
    }
     
    serg_admin нравится это.
  3. avgustdon

    avgustdon Нуб

    Режим один. Пробовал использовать ваш пример - не получилось. На сколько я понимаю, строка с которой вы не согласны отвечает за превышение над уровнем минимальной температуры, а у меня проблема возникает при превышении максимальной температуры. После снижения температуры ниже максимальной показания восстанавливаются.
     
  4. MDV

    MDV Гик

    Как вариант не успевает пройти опрос датчика температуры, задай в цикле небольшую
    паузу, плюс в цикл введи вывод на дисплей.
    Код (C++):
    while (analogRead(temperature_pin) >= t_min && flag_t_max == 1) {
           Serial.println(analogRead(temperature_pin));
           delay (1000);
    WriteNumber(t_tek);
       
         }
     
  5. serg_admin

    serg_admin Гик

    Правильно Вам выше сказали:
    Код (C++):
    if (t_tek >= t_max) {
          flag_t_max = 1; // Топливо разгорелось выходим в автоматический режим
        }
    Выставляется флаг превышения максимума
    Код (C++):
    while (analogRead(temperature_pin) >= t_min && flag_t_max == 1) {
          Serial.println(analogRead(temperature_pin));
     
        } /
    Если выставлен флаг "превышения максимума" - Висим пока не упадет ниже минимума.
    Добавьте в этот цикл вывод на индикатор.
     
    Последнее редактирование: 27 мар 2017
  6. Tomasina

    Tomasina Сушитель лампочек Модератор

    п. 1 и п. 5 - это уже минимум два режима работы.
     
  7. avgustdon

    avgustdon Нуб

    Да, вы правы, два режима.
     
  8. avgustdon

    avgustdon Нуб

    Добавил. Получилось вот так.
    Код (C++):
        if (t_tek >= t_max) {
          flag_t_max = 1; // Топливо разгорелось выходим в автоматический режим
        }
        while (analogRead(temperature_pin) >= t_min && flag_t_max == 1)
        WriteNumber(t_tek);
        {
          Serial.println(analogRead(temperature_pin));
    теперь после превышения макс. температуры показания не исчезают, а просто замораживаются на последнем значении. В мониторе порта все показания есть во всех режимах.
     
  9. serg_admin

    serg_admin Гик

    Код (C++):
    if (t_tek >= t_max) {
          flag_t_max = 1; // Топливо разгорелось выходим в автоматический режим
        }
        while (analogRead(temperature_pin) >= t_min && flag_t_max == 1)
        {
          t_tek =(analogRead(temperature_pin)/(k_temp));
          WriteNumber(t_tek);
          Serial.println(analogRead(temperature_pin));
        }
     
    Я так понимаю вывод в RS232 вы ни как не используйте?
    Тогда можно по удалять все типа Serial....
     
  10. avgustdon

    avgustdon Нуб

    Задержку ввел. Работает без изменений от начального варианта.
     
  11. avgustdon

    avgustdon Нуб

    Применил ваши изменения. Сейчас после верхнего порога температуры цифры бегут быстро, можно сказать мельтешат. При пересечении верхнего порога вниз, на некоторое время на индикаторе остается последняя цифра, затем восстанавливаются нормальные показания.
    Сериал удалять пока не хочется. По нему есть возможность наблюдать температуру за верхним порогом.
     
  12. MDV

    MDV Гик

    Ну так для этого и нужна задержка, что б не мельчишило
     
  13. serg_admin

    serg_admin Гик

    Ну вот, то медленно теперь быстро :)
    Код (C++):
    while (analogRead(temperature_pin) >= t_min && flag_t_max == 1)
        {
          t_tek =(analogRead(temperature_pin)/(k_temp));
          WriteNumber(t_tek);
          delay(1000);
          Serial.println(analogRead(temperature_pin));
        }
     
  14. MDV

    MDV Гик

    Сделай меньше задержку например delay (500);
     
  15. avgustdon

    avgustdon Нуб

    Задержку меньше уже делал. И в разные места переставлял. :confused: В последнем предложенном варианте уверенно светится последняя цифра. Остальные коротко мигают.
     
  16. serg_admin

    serg_admin Гик

    Не хороший у тебя индикатор какой-то. Мне кажется цифры не должны гаснуть

    Код (C++):
    while (analogRead(temperature_pin) >= t_min && flag_t_max == 1)
    {
       if(millis()- past >=1000) {
          past = millis();
          t_tek =(analogRead(temperature_pin)/(k_temp));
        }
          WriteNumber(t_tek);
          Serial.println(analogRead(temperature_pin));
        }
    }
    По сути увеличиваем частоту моргания до максимума
     
  17. avgustdon

    avgustdon Нуб

    Теперь не гаснут. :rolleyes: Но при достижении максимальной температуры есть некоторое затемнение цифр. Видимо в результате частого моргания. И при переходе от через максимальную температуру вниз на время подачи исчезают все цифры кроме последней. Но это в принципе все терпимо. Огромное спасибо. Конечно если будет вариант в котором указанные особенности отсутствуют, буду еще более рад. :)
     
  18. serg_admin

    serg_admin Гик

    Подозреваю, что у Вас
    Код (C++):
    const int Latch_pin = 4;
    Неконтачит.

    Гаснет здесь

    Код (C++):
    delay(podacha);
     
  19. avgustdon

    avgustdon Нуб

    4 пин проверил. Контачит хорошо.
    гаснет действительно во время подачи.
     
  20. Vitali_2017

    Vitali_2017 Нуб

    Добрый день!
    у меня: Arduino Мега 2560 R3 + 3.2-дюймовый TFT IPS ЖК-дисплей 480 х 320
    +4 сервопривода! Как управлять сервоприводами знаю, подключил.
    Дисплей разбит на 4 "окошка".
    Задача такая. При работе каждого сервоприводов, нужно чтобы на дисплее отображался угол наклона, поворота отклонения каждого сервопривода.
    У меня не получается доработать скетч! Если что, весь проект здесь: https://yadi.sk/d/mdwbKfda3J6kvo... Заранее спасибо!
     

    Вложения: