зависает прога

haskel
Offline
Зарегистрирован: 03.01.2012

Скажите, почему может зависать программа, все возможные причины.

данный скетч больше по объему, меньший вариант залит в atmega168, после нескольких операций зависает, чем это может быть вызвано, подскажите.

#include <LiquidCrystalRus.h>
#include <EEPROM.h>

// initialize the library with the numbers of the interface pins
LiquidCrystalRus lcd(12, 10, 11, 5, 4, 3, 6);

//переменные, используемые при работе программы
int i;
String s1, buf, sch, zn_sch;
float int_1, int_2, res;
boolean inp=false, clean=false, zn_set=false, synch=false;
//////////////////////////////////////////////////////////
//о программе
void about()
{
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Альтернативный");
  //
  lcd.setCursor(4, 1);
  lcd.print( "калькулятор");
  //
  lcd.setCursor(6, 2);
  lcd.print(   "автор");
  //
  lcd.setCursor(5, 3);
  lcd.print(  "Ver. 1.0");
  //
  delay(3000);
  lcd.clear();
}

//функция очистки последней строки
void clscr_two()
{
  for (int i=0;i<=20;i++)
  {
    lcd.setCursor(i,3);
    lcd.print(' ');
  }
}

//функция очистки первой строки
void clscr_one()
{
  for (int i=0;i<=20;i++)
  {
    lcd.setCursor(i,0);
    lcd.print(' ');
  }
}

//вывод на дисплей главной строки
void write_s1()
{
  lcd.setCursor(0,0);
  lcd.print(s1);
}

//проверка валидности синтаксиса
void error_syntax()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Error syntax");
  delay(500);
  lcd.clear();
  //
  buf='0';
  s1='0';
  zn_set=false;
  zn_sch='0';
  res=0;
  sch=0;
  int_1=0;
  int_2=0;
}

void setup() 
{
  // set up the LCD"s number of rows and columns: 
  lcd.begin(20, 4);
  s1='0';
  // Print a message to the LCD.
  about();
}

void loop() 
{
  //
  i=analogRead(A0);
  //
  if ((i==22)or(i==46)or(i==70)   or
      (i==94)or(i==118)or(i==142) or
      (i==166)or(i==190)or(i==214)or
      (i==238)or(i==262)or(i==286)or
      (i==310)or(i==334)or(i==358)or
      (i==382)or(i==406)or(i==430)or
      (i==454)or(i==478)or(i==502)or
      (i==526)or(i==550)or(i==574)or
      (i==597))
  {
    clscr_two();
  }
  //
  if (digitalRead(13)==LOW)
  {
    inp=false;
  }
  //нажатие кнопки обрабатывает все события с учетом дополнительных условий для уменьшения ветвлений кода срабатывания одного события
  if ((digitalRead(13)==HIGH)&&(inp==false))
  {
    write_s1();
    if (inp==false)
    {
      lcd.clear();
    }
    //событие по вводу символов, ограничение ввода до 40 символов
    if (s1.length()==40)
    {
      //проверка на допустимую длину строки
      clscr_one();
      lcd.setCursor(0, 0);
      lcd.print("max input");
    }
    else
    {
      //непосредственный вывод набранной строки на дисплей
      if (s1=='0')
      {
        s1=buf;
      }
      else
      {
        s1=s1+buf;
      }
      lcd.setCursor(0, 0);
      lcd.print(s1);
      inp=true;
      //определение знака операции
        if ((buf=='+')   or
            (buf=='-')   or
            (buf=='/')   or
            (buf=='*')   or
            (buf=="cos(")or
            (buf=="sin(")or
            (buf=="tg("))
        {
          zn_set=true;
          zn_sch=buf;
          sch='0';
          if ((int_1==0)&&(int_2==0)&&((479<=i)&&(i<=501)))
          {
            error_syntax();
          }
        }
      //получение первого слагаемого
      if (((buf=='1')or
           (buf=='2')or
           (buf=='3')or
           (buf=='4')or
           (buf=='5')or
           (buf=='6')or
           (buf=='7')or
           (buf=='8')or
           (buf=='9')or
           (buf=='0'))&&(zn_set==false))
        {
          sch=sch+buf;
          int_1=sch.toInt();
        }
      //получение второго слагаемого
      if (((buf=='1')or
           (buf=='2')or
           (buf=='3')or
           (buf=='4')or
           (buf=='5')or
           (buf=='6')or
           (buf=='7')or
           (buf=='8')or
           (buf=='9')or
           (buf=='0'))&&(zn_set==true))
        {
          sch=sch+buf;
          int_2=sch.toInt();        
        }
      //получение синхронизирующей скобки
      if (buf==')')
      {
        synch=true;
      }
      //
      }
      //работа с готовыми данными: слагаемые и знак
     int L=analogRead(A0);
     if ((503<=L)&&(L<=525)) 
      {
      //lcd.print("((503<=L)&&(L<=525))");
      //сумма
      if (zn_sch=='+')
      {
        res=int_1+int_2;
      }
      //разность
      if (zn_sch=='-')
      {
        res=int_1-int_2;
      }
      //произведение
      if (zn_sch=='*')
      {
        res=int_1*int_2;
        //for (int g=1;g<=int_1;g++)res=res+int_2;
      }
      //деление
      if (zn_sch=='/')
      {
        res=int_1/int_2;
      }
      //косинус
      if (zn_sch=="cos(")
      {
        if ((int_1>0)or(synch==false))
        {
          error_syntax();
        }
        else
        {
          if ((int_2==0)&&(s1=='0')&&(synch==true))
          {
            res=cos(0);
          }
           else
             {
               res=cos(int_2);
             }
        }
      }
      //синус
      if (zn_sch=="sin(")
      {
        if ((int_1>0)or(synch==false))
        {
          error_syntax();
        }
        else
        {
          if ((int_2==0)&&(s1=='0')&&(synch==true))
          {
            res=sin(0);
          }
           else
             {
               res=sin(int_2);
             }
        }
      }
      //тангенс
      if (zn_sch=="tg(")
      {
        if ((int_1>0)or(synch==false))
        {
          error_syntax();
        }
        else
        {
          if ((int_2==0)&&(s1=='0')&&(synch==true))
          {
            res=tan(0);
          }
           else
             {
               res=tan(int_2); 
             }             
        }
      }
      //модуль числа
      if (zn_sch=="abs(")
      {
        if ((int_1>0)or(synch==false))
        {
          error_syntax();
        }
        else
        {
          if ((int_2==0)&&(s1=='0')&&(synch==true))
          {
            res=abs(0);
          }
           else
             {
               res=abs(int_2); 
             }             
        }
      }
      //квадратный корень
      if (zn_sch=="sqrt(")
      {
        if ((int_1>0)or(synch==false))
        {
          error_syntax();
        }
        else
        {
          if ((int_2==0)&&(s1=='0')&&(synch==true))
          {
            res=sqrt(0);
          }
           else
             {
               res=sqrt(int_2); 
             }             
        }
      }
      //вывод посчитанного значенения
      lcd.clear();
      lcd.setCursor(0,0);
      //
      /*
      if (int_1>0)
      {
        lcd.print(int_1);
      }
      //
      lcd.print(zn_sch);
      //
      if (int_2>0)
      {
        lcd.print(int_2);
      }
      //
      lcd.print('=');
      */
      //lcd.print(int_1);
      //lcd.print(zn_sch);
      //lcd.print(int_2);
      lcd.print('=');
      lcd.print(res);
      buf='0';
      s1="";
      zn_set=false;
      zn_sch='0';
      res=0;
      sch=0;
      int_1=0;
      int_2=0;
      clscr_two();
  }
    }
  //конец обработки события нажатия кнопки  
  //******************************************************************************
  //установка курсора в нижнюю часть дисплея для вывода данных о выбранном символе
  lcd.setCursor(0, 3);
  //
  //вывод информационной строки о возможности выбора цифры "1"
  if ((0<=i)&&(i<=21)) 
  {
    lcd.print("s: 1");
    buf='1';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "2"
  if ((23<=i)&&(i<=45))
  { 
    lcd.print("s: 2");
    buf='2';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "3"
  if ((47<=i)&&(i<=69)) 
  {
    lcd.print("s: 3");
    buf='3';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "4"
  if ((71<=i)&&(i<=93)) 
  {
    lcd.print("s: 4");
    buf='4';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "5"
  if ((95<=i)&&(i<=117)) 
  {
    lcd.print("s: 5");
    buf='5';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "6"
  if ((119<=i)&&(i<=141)) 
  {
    lcd.print("s: 6");
    buf='6';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "7"
  if ((143<=i)&&(i<=165)) 
  {
    lcd.print("s: 7");
    buf='7';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "8"
  if ((167<=i)&&(i<=189)) 
  {
    lcd.print("s: 8");
    buf='8';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "9"
  if ((191<=i)&&(i<=213)) 
  {
    lcd.print("s: 9");
    buf='9';
   //write_s1();
  }
  //вывод информационной строки о возможности выбора цифры "0"
  if ((215<=i)&&(i<=237)) 
  {
    lcd.print("s: 0");
    buf='0';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции модуля числа
  if ((239<=i)&&(i<=261)) 
  {
    lcd.print("s: abs");
    buf="abs(";
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции квадратного корня числа
  if ((263<=i)&&(i<=285)) 
  {
    lcd.print("s: sqrt");
    buf="sqrt(";
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции косинуса числа
  if ((287<=i)&&(i<=309)) 
  {
    lcd.print("s: cos");//
    buf="cos(";
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции синуса числа
  if ((311<=i)&&(i<=333)) 
  {
    lcd.print("s: sin");//
    buf="sin(";
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции тангенса числа
  if ((335<=i)&&(i<=357)) 
  {
    lcd.print("s: tg");//
    buf="tg(";
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции суммы чисел
  if ((359<=i)&&(i<=381)) 
  {
    lcd.print("s: +");
    buf='+';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции разности чисел
  if ((383<=i)&&(i<=405)) 
  {
    lcd.print("s: -");
    buf='-';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции умножения чисел
  if ((407<=i)&&(i<=429)) 
  {
    lcd.print("s: *");
    buf='*';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции деления чисел
  if ((431<=i)&&(i<=453)) 
  {
    lcd.print("s: /");
    buf='/';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции установки открывающей скобки
  if ((455<=i)&&(i<=477)) 
  {
    lcd.print("s: (");
    buf='(';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции установки закрывающей синхронизирующей скобки
  if ((479<=i)&&(i<=501)) 
  {
    lcd.print("s: )");
    buf=')';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции парсинга, при нажатии кнопки она будет вызвана обработкой события нажатия 
  //с учетом дополнительного условия положения переменной i
  if ((503<=i)&&(i<=524)) 
  {
    lcd.print("s: =");
    buf='=';
    //write_s1();
  }
  //вывод информационной строки о возможности выбора функции возведения в степень
  if ((527<=i)&&(i<=549)) 
  {
    lcd.print("s: sqr");
    buf="sqr(";
    //write_s1();
  }
  //вывод информационной строки о возможности использования функции очистки памяти
  if ((551<=i)&&(i<=573)) 
  {
    lcd.print("s: clear all");
    if (digitalRead(13)==HIGH)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Clear memory..");
      //
      s1='0';
      buf='0';
      int_1=0;
      int_2=0;
      res=0;
      sch='0';
      //
      delay(250);
      lcd.clear();
      inp=true;
    }
    //write_s1();
  }
  //вывод информационной строки, при нажатии кнопки выходит информацию о прошивке
  if ((575<=i)&&(i<=597)) 
  {
    lcd.print("s: about");
    if (digitalRead(13)==HIGH)
    {
      about();
      inp=true;
    }
    //write_s1();
  }
  //вывод строки, символизирующей о выходе за пределы используемого диапазона выбираемых функций
  if (i>=598) 
  {
    lcd.print("out of range");
    //write_s1();
  }
}

 

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Комментируйте части кода и ловите после какого кода не "виснет"

step962
Offline
Зарегистрирован: 23.05.2011

 Включите в коды вывод диагностических сообщений по UART-USB в окно терминала (как он там в Arduino IDE  называется - Serial Monitor вроде?.