1. Уважаемые форумчане! Убедительная просьба, используйте наиболее подходящие темы для своих сообщений. Спасибо за понимание.
    Скрыть объявление

Поиск и устранение ошибок в ArdBir

Тема в разделе "Автоматика", создана пользователем Phantom, 17 июн 2015.

Поделиться этой страницей

  1. Phantom

    Phantom Active Member

    Регистрация:
    11.05.2014
    249
    49
    Имя:
    Олег
    Предлагаю в этой теме выкладывать описание замеченных ошибок ArdBir, по возможности их способов устранения. Я работаю с версией 2.6.70b10 и всё написанное будет применительно к ней.

    Баг №1. Описание: проявляется автоматическом режиме при кипячении, когда уже идет отсчет времени (достигнута температура кипения). Если включить паузу, а затем возобновить процесс, то нижняя строка с подписями кнопок остается пустой.

    Баг №2. Описание: проявляется в автоматическом режиме при кипячении, когда уже идет отсчет времени (достигнута температура кипения). Если включить паузу и выйти из нее, то не отображается уставка температуры и знак SP.

    Метод устранения багов №1 и 2:
    В файле LCD2004_ENG.h найти код:

    Код:
    void Boil(float Heat, float Temp, byte Tipo){
      if (Tipo==1){
      lcd.setCursor(0,0);
      lcd.print(F(" AUTO --> Boil  "));
      }
    заменить его на этот
    Код:
    void Boil(float Heat, float Temp, byte Tipo, float Set){
      if (Tipo==1){
      lcd.setCursor(0,0);
      lcd.print(F(" AUTO --> Boil  "));
    
      lcd.setCursor(1,3);   // устранение бага не отображения нижней строки  при возврате из паузы в режиме Варки с отсчетом времени
      lcd.print(F("UP* *DWN Pause STP"));
    
      lcd.setCursor(8,1);  // устранение бага не отображения темпер SP  при возврате из паузы в режиме Варки с отсчетом времени
      LCDSpace(4);
      if (Set<100)LCDSpace(1);
      lcd.print(Set);
      lcd.write(2);
      }
    В файле ArdBir.ino
    а) Строку
    Код:
    Boil(boil_output,Temp_Now,0);
    заменить на
    Код:
    Boil(boil_output,Temp_Now,0, stageTemp); // исправление бага2
    б) Строку
    Код:
    Boil(boil_output,Temp_Now,1);
    заменить на
    Код:
    Boil(boil_output,Temp_Now,1, stageTemp); // исправление бага2.
    Теоретически достаточно правки лишь второй строки, но я не стал экспериментировать.
    --- сообщения объединены, 17 июн 2015, дата первого сообщения: 17 июн 2015 ---
    Баг №3. Описание: В ручном режиме, когда достигнута уставка температуры выше или равной температуре кипения, ПИД отключается, тэн начинает работать в режиме PWM. Кнопками вверх вниз меняется значение %. Если текущая темература опустится ниже уставки, то PWM отключается и снова запускается ПИД, кнопками уже изменяется уставка температуры. Баг в том, что старая надпись "PWM=xxx%" при этом не стирается, а остается на дисплее.

    Метод устранения бага 3: В файле ArdBir.ino находим процедуру void manual_mode (), а в ней условие ниже. Добавляем в фигурных скобках сразу после else строку с вызовом NoBoil(). Должно получиться следующее:
    Код:
    if (Setpoint >= boilStageTemp && Input >= Setpoint){
          ...
        }else{
          NoBoil();                                                 //исправление бага 3
          ...
        }
    
    --- сообщения объединены, 20 июн 2015 ---
    Неужели никто больше никаких косяков не замечал? Всех всё устраивает? Вот еще один баг.
    Баг №4. Описание: При возврате в меню настроек из подменю Credits в верхней строке не появляется надпись "SETUP MENU", а остается "Open ArdBir 2.6.70bEN"
    Метод устранения: В файле LCD2004_ENG.h найти процедуру Credits() и перед последней фигурной скобкой добавить 2 строки:
    Код:
    void Credits(){
      ...
      lcd.setCursor(0,0);
      lcd.print(F("  SETUP MENU  "));  //исправление бага 4
    }
     
    • Класс Класс x 2
  2. Smk787

    Smk787 Участник

    Регистрация:
    08.01.2015
    36
    3
    Спаибо за выявленные и исправленные ошибки. Не мог бы выложить исправленную версию прошивки?
     
  3. Phantom

    Phantom Active Member

    Регистрация:
    11.05.2014
    249
    49
    Имя:
    Олег
    У меня исправленной версии нет, так как делаю свою модифицированную на базе ардбира.
     
  4. Smk787

    Smk787 Участник

    Регистрация:
    08.01.2015
    36
    3
    Ну так ее выложи!
    --- сообщения объединены, 22 июн 2015, дата первого сообщения: 22 июн 2015 ---
    Ну или если не хочешь на всеобщее выкладывать, может на почту скинешь?
     
  5. Phantom

    Phantom Active Member

    Регистрация:
    11.05.2014
    249
    49
    Имя:
    Олег
    Баг №5. В ручном режиме при включенном насосе если температура превысит температуру остановки насоса, то тот отключается. При снижении температуры (а вдруг это случится) насос обратно не включается. Запустить можно лишь кнопкой выкл/вкл. В автоматическом режиме такого не заметил.
    --- сообщения объединены, 24 июн 2015, дата первого сообщения: 22 июн 2015 ---
    Метод устранения: В файле ArdBir.ino находим процедуру void pump_rest (byte stage).
    В блоке ниже необходимо добавить одну строку
    Код:
    if (Temp_Now >= TempPumpRest){
        if (SensorType==0){
          //Sensore Interno
          pump_off(mpump);
          //pumpRest=true;
          if(stage == 99)pumpRest=true;           //добавить эту строку для устранения бага 5
          return;
    Далее находим и комментируем строку, а следом за ней добавляем кусок кода
    Код:
    // if (stage==99)return; // Non effettua i controlli perchè siamo in MANUAL MODE   // <-- закомментировать эту строку для устранения бага 5
         if (stage==99){              //вместо нее добавить этот кусок кода для устранения бага 5
            if (pumpRest){
              if(Temp_Now <= (TempPumpRest-3)){    //насос включится обратно при опускании темп на 3град ниже темп стопа насоса
                  pump_on();
                  pumpRest = false;
              }
            }
            return;
         }
    
    --- сообщения объединены, 26 июн 2015 ---
    Баг №6. Описание: Сохранение некорректного названия рецепта при использовании ускоренного заполнениями пробелами до конца. Крайний символ замещался пробелом.
    Пример.Название состоит из 10 символов. Вводим имя "abc" =3символа. Чтобы не вводить еще 7 пробелов, нажимаем и удерживаем кнопки вверх+вниз. На дисплее высвечивается "abc ", жмем Ок. Теперь, если попытаться открыть этот рецепт, то имя его будет "ab ". Крайний символ C был заменен пробелом.

    Метод устранения. В файле ArdBir.ino необходимо внести изменения в процедуру void saveRecipe(). Привожу уже отредактированный вариант
    Код:
    void saveRecipe(){
    
      boolean saverecipeLoop;
    
      byte numRicetta = 0;
    
    
    
      for(byte i=90; i<100; i++){//Trova la prima ricetta libera
    
      if (EEPROM.read(i)==0){
    
      numRicetta = (i - 89);
    
      i=99;
    
      }
    
      }
    
    
    
      if (numRicetta == 0) MemoriaPiena();
    
      else {
    
      byte Verso=0;
    
      unsigned long Timer=0;
    
      // Spc 32
    
      // 0-9 da  48 a  57
    
      // A-Z da  65 a  90
    
      // a-z da  97 a 122
    
    
    
      byte NomeRicetta[10];
    
      byte pos = 0;
    
      NomeRicetta[pos] = 97;
    
    
    
      Clear_2_3();
    
    
    
      Ricetta(numRicetta,1);
    
    
      while (pos<10){
    
      LCD_NomeRicetta(pos,NomeRicetta[pos] );
    
      lcd.blink();
    
    
      if ((digitalRead(Button_dn)==0) && (digitalRead(Button_up)==0)){
    
      delay(350);
    
      if ((digitalRead(Button_dn)==0) && (digitalRead(Button_up)==0)){
    
      Buzzer(1,50);
    
      /*for (byte j=(pos+1); j<10; j++){
    
      NomeRicetta[pos]=32;
    
      pos++;
    
      } pos=9;*/
    
      lcd.noBlink();
    
      while(pos<10){  //устранение бага 6
    
      pos++;
    
      NomeRicetta[pos]=32;
    
      LCD_NomeRicetta(pos, NomeRicetta[pos] ); //устранениебага 7
    
       }
    
      pos=9;
    
      lcd.blink();
    
      }
    
      }else{
    
    
    
      LeggiPulsante(Verso, Timer);
    
      Set(NomeRicetta[pos],122,32,1,Timer,Verso);
    
    
    
      if ((NomeRicetta[pos]> 32 && NomeRicetta[pos]< 48) && Verso==1)NomeRicetta[pos]=48;
    
      if ((NomeRicetta[pos]> 57 && NomeRicetta[pos]< 97) && Verso==1)NomeRicetta[pos]=97;
    
    
    
      if ((NomeRicetta[pos]< 97 && NomeRicetta[pos]> 57) && Verso==2)NomeRicetta[pos]=57;
    
      if ( NomeRicetta[pos]< 48 && Verso==2)NomeRicetta[pos]=32;
    
      }
    
    
      if(btn_Press(Button_enter,50)){
    
      pos++;
    
      NomeRicetta[pos]=97;
    
      }
    
    
    
    
    
      if(btn_Press(Button_start,50)){
    
      if(pos>0)pos--;
    
      }
    
    
    
      }
    
    
    
      lcd.noBlink();
    
    
    
      SalvataggioRicetta (numRicetta);
    
    
    
      wait_for_confirm(saverecipeLoop,2,2,2);
    
    
    
      if (saverecipeLoop==false){
    
      Menu_3();
    
      Menu_3_4();
    
      return;
    
      }else{
    
      SalvaRicetta();
    
    
    
      int Da;
    
    
    
      //Parametri Ricetta
    
      Da= 100 + ((numRicetta-1)*52);
    
      for (byte j=30; j<82; j++){
    
      save_set (Da, (byte)EEPROM.read(j));
    
      Da++;
    
      }
    
    
    
    
    
      //Nome Ricetta
    
      for (pos=0; pos<10; pos++){
    
      save_set(620 + pos + ((numRicetta - 1)*10),  NomeRicetta[pos]);
    
      }
    
      //Byte di Controllo
    
      save_set(89+numRicetta,(byte)1);
    
      }
    
      }
    
    }
    
    Баг №7. Описание. Некорректное сохранение названия рецепта при использовании ускоренного ввода пробелов. Пример. Вводим название «abcdef». Кнопкой Назад перемещаем курсор на букву С. Жмем ускоренный ввод пробелов. На дисплее «abcdef ». Но сохранится файл под названием «abc ». Баг в том, что при этом методе все символы после курсора заполняются пробелами, но на дисплее этого не было отображено.
    Метод устранения. Еще раз вносим исправления в процедуру voidsaveRecipe(). Уже готовую процедуру смотри в баге 6.
    Код:
              lcd.noBlink();                                                    //устранение бага 7
              while(pos<10){    //устранение бага 6
                pos++;
                NomeRicetta[pos]=32;
                LCD_NomeRicetta(pos, NomeRicetta[pos] ); //устранение бага 7
              }
              pos=9;
              lcd.blink();                                                         //устранение бага 7
    
    Баг №8. Описание. Изменение в настройках температуры варки не всегда вызывает ее изменение в автоматическом и ручном режиме (продолжает действовать значение, которое было при запуске блока).
    Метод устранения 1. Перезагрузить блок, чтобы новые значения вступили в силу.
    Метод устранения 2. В файле ArdBir.ino необходимо внести изменения в процедуру void set_Unit (). Находим условие
    Код:
    if(i!=2 || i!=3){ 
    и меняем логическое ИЛИ на логическое И. Получаем
    Код:
    if(i!=2 && i!=3){
    . Ошибка в том, что при любых значениях i условие было ИСТИНА, поэтому всё, что после else, никогда не выполнялось. Этого достаточно для корректной работы, но желающие могут заметно оптимизировать код в этом месте. В качестве бонуса теперь в настройках заработает автоматический пересчет температуры варки по другой шкале градусов.

    --- сообщения объединены, 2 июл 2015 ---

    Версия 2.6.70b10 с моими исправлениями багов 1-8
    --- сообщения объединены, 6 июл 2015 ---

    --- сообщения объединены, 15 июл 2015 ---
    Баг №9. В результате исправления бага 8 заработал кусок кода, который раньше был неактивным. Это решило одну проблему, но следом породило другую. При настройке после пункта Температура варки последующие сохранялись в регистры еепром с ошибочными адресами! Причина в еще одной ошибке (даже двух) в том самом бывшем неактивном коде.
    Метод устранения. В файле ArdBir.ino меняем процедуру void set_Unit () на ту, что ниже. Выкладываю полный код переработанной функции. Исправлены баги, оптимизирован код. Также исправлена ошибка неверной адресации памяти при переходе на фарентгейты.
     

    Вложения:

    Последнее редактирование: 15 июл 2015
    • Класс Класс x 2
  6. Phantom

    Phantom Active Member

    Регистрация:
    11.05.2014
    249
    49
    Имя:
    Олег
    Код:
    void set_Unit (){
      byte a;
    
      byte unitSet;
    
      boolean unitLoop = false;
    
      byte Verso=0;
      unsigned long Timer=0;
     
      byte setAddr = 15;
    
      for(byte i=0;i<10;i++){
        a=i*3;
        if ((i==2 && ScaleTemp==1) || (i==3 && ScaleTemp==0))unitLoop=false;
        else unitLoop= true;
      
        if (i==3 && ScaleTemp==1) setAddr = 18;  //исправляем баг 9. корректировка адреса при выборе фарентгейтов.
       
        if(i!=7)r_set(unitSet,setAddr);
        else{
          if (ScaleTemp==0) r_set(unitSet,22);
          else r_set(unitSet,23);
        }
       
        while (unitLoop){
          Menu_3_2_x(i); 
          if (i==0){
            ScaleTemp=unitSet;
            Gradi();
          }
       
          UnitSet(unitSet,i);
     
          LeggiPulsante(Verso, Timer);
         
          if(i!=7){
            Set(unitSet, p_Unit[a], p_Unit[a+1], p_Unit[a+2], Timer, Verso);          
          }else{
            if(ScaleTemp==0){
              Set(unitSet,EEPROM.read(17), 80, 1, Timer, Verso);
            }else{
              Set(unitSet,EEPROM.read(18), 176, 1, Timer, Verso);
            }
          }
         
          quit_mode(unitLoop);
          if (!unitLoop)i=10;
    
        //  B___U___G = setAddr;
          if(btn_Press(Button_enter,50)){
      
            save_set(setAddr,lowByte(unitSet));    
            if(i!=2 && i!=3){                                //условие с ошибкой, вызывающей баг 8. При любых i оно Истина. ИЛИ меняем на И (if(i!=2 || i!=3))
             
              if (i==0){
                ScaleTemp=unitSet;
                Gradi();
              }
              if (i==1)SensorType=unitSet;   
         
              if (i==5 && SensorType==1){ //Il SENSORE E' ESTERNO
                save_set(21,lowByte(1));//La pompa deve essere OBBLIGATORIAMENTE ON
                setPumpBoil = 1;
                //Il Pump Rest viene settato a 0
                unitSet=105; //°F = 221
                save_set(22, lowByte(unitSet));
                save_set(23, lowByte((byte)((unitSet * 1.8) + 32)));
                save_set(24,lowByte(1));
                //unitLoop = false;
                i=8;
                setAddr=23;
              }
         
    
              if(i==6){
                //setPumpBoil = EEPROM.read(21);
                if(EEPROM.read(21)==0){
                  unitSet=80; //°F = 176
                  save_set(22, lowByte(unitSet));
                  save_set(23, lowByte((byte)((unitSet * 1.8) + 32)));
                  i=7;
                  setAddr=22;
                }
              }
             
             
              if(i==7){
                if (ScaleTemp==0){// °C
                  save_set(22,lowByte(unitSet));
                  save_set(23,lowByte((byte)((unitSet*1.8)+32)));     
                }else{// °F
                  save_set(22,lowByte((byte)((unitSet-32)/1.8)));
                  save_set(23,lowByte(unitSet)); 
                } 
                setAddr+=1;
              }
            }else{
              boilStageTemp = unitSet;
              if (i==2) save_set(setAddr+1, lowByte((byte)((unitSet * 1.8) + 32)));
              else      save_set(setAddr-1 ,lowByte((byte)((unitSet - 32) / 1.8)));
              setAddr=18;
            }
           
            unitLoop = false;
            setAddr+=1;  //исправляем баг 9. перенесенная строка
          }        
        }
        //setAddr+=1;
      }Clear_2_3();
    }
    --- сообщения объединены, 17 июл 2015, дата первого сообщения: 15 июл 2015 ---
    Баг №10. Баг это программы или перевода мануала не могу сказать. Дело в том, что работает не так, как написано. Или написано не так, как работает. Взято из перевода мануала относительно ручного режима: «Автоматический таймер запускается, когда измеряемая температура достигает заданной точки. Любое изменение заданной точки сбросит таймер, если температура заданной точки на 2°C больше, чем измеряемая температура.» В итальянской версии также говорится о простом изменении уставки температуры.
    На деле же таймер сбрасывается не при ЛЮБОМ изменении заданной точки, а лишь при увеличении. Например, если температура будет на 50 градусов ниже заданной и мы будем уменьшать ее значение, то таймер продолжит тикать. Но если попытаемся увеличить, то сразу обнулится, т.к. разница больше 2градусов.

    Версия с исправленными багами 1-9
     

    Вложения:

  7. Traector

    Traector Участник

    Регистрация:
    17.11.2014
    68
    4
    пробовал ставить и 1-8фикс, и 1-9 фикс. - ругается при компиляции.
    у меня экран 16х2 не русифицированный, в архивах под 20х4 исправления.
    не знаю, как поставить исправленную версию себе - или построчно править код в файле 16х2_eng? или надо что-то с библиотеками править.
    Ругань компилятора была на что-то типа "передаются не все переменные\недостаточно переменных" "не определены процедуры..."
     
  8. Phantom

    Phantom Active Member

    Регистрация:
    11.05.2014
    249
    49
    Имя:
    Олег
    Делал применительно к 2004 дисплею. Сейчас гляну что там с 1602 и вечером отпишусь
    --- сообщения объединены, 25 авг 2015, дата первого сообщения: 25 авг 2015 ---
    Сделал версию с исправленными багами 5, 8 и 9. В иде 1.5.8 под 1602 дисплей у меня компилируется без ошибок. В эмуляторе работает
     

    Вложения:

    • Полезно Полезно x 2
    • Класс Класс x 1
  9. Traector

    Traector Участник

    Регистрация:
    17.11.2014
    68
    4
    спасибо огромное! субъективно стало лучше. даже менюшки быстрее открываются + появилась заставка "ардбир" и заработал раздел Кредитс!
     
    • Оптимистично Оптимистично x 1
  10. 1exan

    1exan Новенький

    Регистрация:
    20.01.2016
    14
    0
    Имя:
    Алексей
    В 2.8.3. в основном файле в функции setup идет присвоение значения уставки температуры на стадии кипячения, причем уставка читается из епром как float:
    Код:
      if (ScaleTemp == 0) boilStageTemp = r_set_float(12);
      else                boilStageTemp = r_set_float(13);
    
    В результате boilStageTemp при первой загрузке контроллера получает неправильное (большее) значение, и на стадии кипячения устанавливается максимально возможное задание (100 наверно, не помню уже). Исправляется так:
    Код:
      if (ScaleTemp == 0) boilStageTemp = r_set(12);
      else                boilStageTemp = r_set(13);
    
    --- сообщения объединены, 16 сен 2016, дата первого сообщения: 8 сен 2016 ---
    Вообще, тут наверно правильней было бы вставить что-то такое:
    Код:
    void Boil(float Heat, float Temp, byte Tipo, float Set){
      if (Tipo==1) {
        Stage(8, Set, Temp);
      }
    
    Вот только проверить не на чем.
     
    • Поучительно Поучительно x 1
  11. Phantom

    Phantom Active Member

    Регистрация:
    11.05.2014
    249
    49
    Имя:
    Олег
    Проверить можно в эмуляторе Proteus. Я почти все изменения в нем отлаживал и лишь потом на реальном железе.