Контроллер странно себя ведёт, то работает одно, то другое

Myst
Offline
Зарегистрирован: 19.04.2015

Очень странная проблема. При первом запуске выводится информация на счетчик, но когда жмешь на кнопку для запуска реле, то она зависает(работает вечно). После перезагружаю ардуино, теперь экран застывший, зато реле работает как надо. Может ли кто-нибудь подсказать в чём проблема? Код прилагаю:

 


Myst
Offline
Зарегистрирован: 19.04.2015
// **БИБЛИОТЕКИ**
#include <FastIO.h>
#include <I2CIO.h>
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal_SR.h>
#include <LiquidCrystal_SR2W.h>
#include <LiquidCrystal_SR3W.h>
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Первичная настройка экрана. Связть контактов


// **БЛОК ПЕРЕМЕННЫХ**

#define CLOCK_PIN 6 // Переменыне для счетчика
#define RESET_PIN 7
#define pot A0 //Обращение к потенцометру
const int Trig = 8; //порты для ультравизора
const int Echo = 9; 
const int StartBut = 4; //Кнопка старта 
const int NumButPlus = 10; //Кнопка прибавления числа
const int NumButMinus = 11; //Кнопка убавления числа
const int Relay = 3; // Порт реле
double temp;
int x; //Переменная для счетчика
unsigned int time_us=0; // переменные для работы с ультравизором
unsigned int distance_sm=0;

void setup()
{
  attachInterrupt(0, GetInfo, HIGH); //прерывания
  x=0;
//**Иницилизация всех устройств  
  pinMode(RESET_PIN, OUTPUT); // иницилизация счетчика
  pinMode(CLOCK_PIN, OUTPUT);
  pinMode(pot, INPUT); //иницилизация потенцометра
  pinMode(A3,INPUT); // иницилизация термистора
  pinMode(Trig, OUTPUT); //иницилизация ультравизора 
  pinMode(Echo, INPUT); 
  pinMode(Relay, OUTPUT); //иницилизация реле
  pinMode(13, OUTPUT); // встроенный светодиод
// **Настройка экрана к работе**  
  lcd.begin(16,2);   // установка экрана, как сетку 16/2
  lcd.backlight(); // есть подсветка; lcd.noBacklight(); - нет подсветки
  lcd.clear();   //отчиска экрана
  lcd.setCursor(0,0); // начинаем писать с самого начала
  
  digitalWrite(RESET_PIN, HIGH);
  digitalWrite(RESET_PIN, LOW);
  GetInfo();
}

 // Метод для перевода показаний сенсора в градусы Цельсия. НИЧЕГО НЕ ТРОГАТЬ.
  double Getterm(int RawADC) {
  double temp;
  temp = log(((10240000/RawADC) - 10000));
  temp = 1 / (0.001129148 + (0.000234125 * temp) + (0.0000000876741 * temp * temp * temp));
  temp = temp - 273.15;
  return temp;
}

void GetInfo(){ // Получение информации и её вывод на экран. ФУНКЦИЯ ПРЕРЫВАНИЯ.каждую секунду (delay = 1000?)

 lcd.clear();//убираем прошлое значение
 
//Выводим значение температуры 

    temp = Getterm(analogRead(3));  // считываем показания с сенсора  
    lcd.setCursor(0,0);
    lcd.print("Temp:");
    lcd.print(temp);
    lcd.print(" C");
  
//Выводим зачения дальновизора  

  digitalWrite(Trig, HIGH); // Подаем сигнал на выход микроконтроллера 
  delayMicroseconds(10); // Удерживаем 10 микросекунд 
  digitalWrite(Trig, LOW); // Затем убираем 
  time_us=pulseIn(Echo, HIGH); // Замеряем длину импульса 
  distance_sm=time_us/58*10; // Пересчитываем в сантиметры 
   lcd.setCursor(0,1);
   lcd.print("Volume::");
   lcd.print(distance_sm); //СЮДА ВПИСАТЬ ФОРМУЛУ ЗАВИСИМОСТИ ОТ РАЗМЕРА БУТЫЛКИ
   delay(500); 
 // digitalWrite(13, HIGH);
}

  void showNumber(int n)
  {
      // Обнуляем текущее значение
      digitalWrite(RESET_PIN, HIGH);
      digitalWrite(RESET_PIN, LOW);
   
  // "Помигаем" выводом счётчика до нужного значения
        for (byte i=0; i<x; i++) {
          digitalWrite(CLOCK_PIN, HIGH);
          digitalWrite(CLOCK_PIN, LOW);
        }
  }
void loop()
{
   GetInfo();
   lcd.setCursor(0,14);
   lcd.print("a");
   digitalWrite(13, HIGH);
    if (digitalRead(NumButPlus) == HIGH){
      x++;
      showNumber((millis() / 1000) % 60);
      delay(500);
     }
     
    if (digitalRead(NumButMinus) == HIGH){
      x--;
      showNumber((millis() / 1000) % 60);
      delay(500);
     }
  
  int z = analogRead(pot); // Считываем значения с потенцометра для времнени работы.
  
 if (digitalRead(StartBut) == HIGH){ //Если кнопка старта нажата, то начинается работа.
 
if(x==0){
 delay(0);
 } 
 else
 {
   delay(x*1000);
 } 
 
   digitalWrite(13, LOW);
   digitalWrite(Relay,HIGH);
   delay(z*3);  
   digitalWrite(Relay,LOW);
   GetInfo();
 }
 

 
}

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Я извиняюсь. Плакать хочется видя этот горький абсурд. Мало того, что вы в прерывание пихнули чуть ли не 80 процентов программы, вы еще умудрились туда влепить задержу на ПОЛСЕКУНДЫ !!!! В быдлотернете уже написали бы "убейся оп стену". Я же могу посоветовать вам - "хоть чего нибудь почитать".... грустно :(

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Пальцем в небо.
GetInfo - обработчик прерываний. Вызывается постоянно явно из loop. В обработчике длительные действия и задержка на полсекунды. На мой взгляд это дурдом и желание нарваться на проблемы.
И, да, выкиньте переменную temp из глобальных переменных. Не используйте глобальных переменных, если это не нужно.

Myst
Offline
Зарегистрирован: 19.04.2015

Спасибо за совет