Помогите найти пропущенную или лишнюю "}"

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Друзья, полночи ищу причину появления сообщения "'BUTTON' was not declared in this scope". Моск завял. Скорее всего где-то лишняя или недостающая фигурная скобка. Возможно, есть еще какая-то причина. Помогите ее найти: глаз замылился, голова кругом.

Заранее спасибо!

//Arduino UNO 
//Блок индикатора
#include "LedControl.h" 
  /* Расцветка шлейфа UNO-max7219
  pin Мсс - оранжевый
  pin Gnd - желтый
  pin 10 DataIn - зеленый
  pin 8 CLK - синий
  pin 9 LOAD (CS) - фиолетовый
  */
LedControl lc=LedControl(10,8,9,1);
int digit;  //номер 7-сегментника на индикаторе
int sot;  //сотни 
int des;  //десятки 
int edi;  //единицы

//Блок кнопки
volatile int button_pin=2; //Пин кнопки
volatile int button_state; //Состояние кнопки

//Блок энкодера
volatile int enca_pin=3; //Пин энкодера А
volatile int encb_pin=4; //Пин энкодера B

//Блок температуры
#include <OneWire.h>
OneWire ds_1820(12); // Датчик на пине 12 (Белый)
//Подвязывание переменных к библиотеке датчика
byte i;
byte present = 0;
byte data[12];
byte addr_ds_1820[8];
long reading_time;
int ds_1820_5v (11); //пин +5v для датчика температуры (Серый)
volatile int temperature_stop=20; //Температура отсечки
volatile int temperature_current; //Текущая температура 
unsigned long temperature_time; //Переменная задержки времени для считывания датчика температуры
unsigned long temperature_loop_time; //Переменная задержки времени для считывания датчика температуры предыдущая

//Блок насоса
int pump_pin=6; //Пин насоса
volatile long pump_on=3000;              //Время включенного (мсек)
volatile long pump_off=1000;             //Время выключенного (мсек)
volatile unsigned long pump_switch=1;   //Время переключения (мсек)
volatile unsigned long pump_switch_prev=0;  //Время последнего переключения (мсек)
volatile int pump_state;                      // Состояние пина насоса

//Блок нагревателя
volatile int heating_pin=7; //Пин нагревателя
volatile long heating_on=30;           //Время включенного (мсек) 
volatile long heating_off=570;             //Время выключенного (мсек)
volatile unsigned long heating_switch=1;   //Время переключения (мсек)
volatile unsigned long heating_switch_prev=0;  //Время последнего переключения (мсек)
volatile int heating_state;                      // Состояние пина нагревателя

void setup() 
{
  Serial.begin (115200);
  //Проверка индикатора
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
  delay (1000);
  for (digit=0;digit<8;digit++)
  {
    lc.setDigit(0,7-digit,digit,false);
    delay (200);
  }
  delay (333);
  lc.clearDisplay(0);
  //Пишем " HELLO! "
    lc.setRow (0,7,B00000000);
    lc.setRow (0,6,B00110111);
    lc.setRow (0,5,B01001111);
    lc.setRow (0,4,B00001110);
    lc.setRow (0,3,B00001110);
    lc.setRow (0,2,B01111110);
    lc.setRow (0,1,B10100000);
    lc.setRow (0,0,B00000000);
  
  //Активация прерываний
  pinMode (button_pin, INPUT); //Кнопка на прерывании 0
  attachInterrupt(0, BUTTON, RISING);
  pinMode (enca_pin, INPUT); //ЭнкодерА на прерывании 1
  attachInterrupt(1, ENCODER, RISING);
  pinMode (encb_pin, INPUT); //ЭнкодерB на пине № 4

  //Блок нагревателя
  pinMode (heating_pin,OUTPUT); //Пин нагревателя - на ВЫХОД
  heating_state=LOW;
  digitalWrite (heating_pin,heating_state);
  //heating_on=1000;
  //heating_off=2000;
  //heating_on=heating_on*heating_multi; //Определение времени включения/выключения для наладки (для работы heating_multi=1)
  //heating_off=heating_off*heating_multi;
     
  //Блок насоса
  pinMode (pump_pin,OUTPUT); //Пин насоса на выход
  digitalWrite (pump_pin,pump_state); 
    
  //Первая инициация датчика температуры
  pinMode (ds_1820_5v,OUTPUT);
  digitalWrite (ds_1820_5v,HIGH);
  
  //Запрос датчику на измерение температуры
  if ( !ds_1820.search(addr_ds_1820)) {}
  //Инициируем датчик температуры
  ds_1820.reset();
  ds_1820.select(addr_ds_1820);
  ds_1820.write(0x44);
}

void loop() 
{ 
  if (button_state==1) // Настройка температуры отсечки
  {
    //Пишем "Adj   °c"
    lc.setRow (0,7,B01110111);
    lc.setRow (0,6,B00111101);
    lc.setRow (0,5,B00011000);
    lc.setRow (0,4,B00000000);
    lc.setRow (0,1,B01100011);
    lc.setRow (0,0,B00001101);
    //Расчленяем температуру отсечки
    des=temperature_stop%100/10;
    edi=temperature_stop%10;
    lc.setDigit (0,3,des,false);
    lc.setDigit (0,2,edi,false);
  }
  if (button_state==2) // Работа системы
  {
    //Пишем температуру отсечки и текущую температуру
    //Расчленяем температуру отсечки
    des=temperature_stop%100/10;
    edi=temperature_stop%10;
    lc.setDigit(0,7,des,false);
    lc.setDigit (0,6,edi,false);
    lc.setRow (0,5,B01100011);
    lc.setRow (0,4,B00000001);
    //Расчленяем текущую температуру
    des=temperature_current%100/10;
    edi=temperature_current%10;
    lc.setRow (0,3,B00000001);
    lc.setDigit (0,2,des,false);
    lc.setDigit (0,1,edi,false);
    lc.setRow (0,0,B01100011);
    
    //Опрос показаний датчика температуры 1 раз в 850 мсек
    if (millis()-reading_time>850)
    {
      //Опрашиваем датчик колонны
      present = ds_1820.reset();
      ds_1820.select(addr_ds_1820);
      ds_1820.write(0xBE);
      for ( i = 0; i < 9; i++)
      {
      data[i] = ds_1820.read();
      }
      int16_t raw = (data[1] << 8) | data[0];
      temperature_current=raw / 16;
      //Заново инициируем датчик
      ds_1820.reset();
      ds_1820.select(addr_ds_1820);
      ds_1820.write(0x44);
    } 
    //Работа нагрева
    if (temperature_current>temperature_stop) //Запрещаем нагрев, если температура выше отсечки
    {
      heating_state=LOW;
      digitalWrite(heating_pin, heating_state);
    } 
    else //Разрешаем нагрев, если температура ниже отсечки
    {
      if(millis() - heating_switch_prev > heating_switch-1) //проверяем не прошел ли нужный интервал, если прошел то: 
      { 
        heating_switch_prev = millis();                          // сохраняем время последнего переключения
        // если нагрев отключен, то подключаем, и наоборот
        if (heating_state == LOW)
        {  
          heating_state = HIGH;
          heating_switch=heating_on;
        }
        else
        { 
          heating_state = LOW;
          heating_switch=heating_off;
        }
        digitalWrite(heating_pin, heating_state); // Управляем нагревом
      }
    }

    //Работа насоса
    if(millis() - pump_switch_prev > pump_switch-1) //проверяем не прошел ли нужный интервал, если прошел то: 
    { 
      pump_switch_prev = millis();                          // сохраняем время последнего переключения
      // если насос отключен, то подключаем, и наоборот
      if (pump_state == LOW)
      {  
        pump_state = HIGH;
        pump_switch=pump_on;
      }
      else
      { 
        pump_state = LOW;
        pump_switch=pump_off;
      }
        digitalWrite(pump_pin, pump_state); // Управляем насосом
    }
  }  
}



void BUTTON ()
{
  button_state++;
  if (button_state<2) //При настройке нагрев и насос выключаем
  {
    heating_state=LOW;
    digitalWrite(heating_pin, heating_state); // Выключаем нагрев
    pump_state=LOW;
    digitalWrite(pump_pin, pump_state); // Выключаем насос
  if (button_state==2) //При запуске: 
  {
    //нагрев включаем, перезапускаем таймер
    heating_switch_prev = millis();
    //насос включаем, перезапускаем таймер
    pump_switch_prev = millis();
  }
  
  if (button_state>2)
  {
    button_state=1;  
  }
  
}
void ENCODER ()
{
  if (button_state==1) //Настройка температуры отсечки
  {
    if (digitalRead (enca_pin)!= digitalRead (encb_pin)){temperature_stop--;}
    else {temperature_stop++;}
    if (temperature_stop>45) {temperature_stop=45;}
    if (temperature_stop<20) {temperature_stop=20;}
  }
}

 

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Понимаю, что стыд и срам, но....

sadman41
Offline
Зарегистрирован: 19.10.2016

Объект (функция) сначала объявляется, потом используется. Такое правило в Си

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Sonologist пишет:

Скорее всего где-то лишняя или недостающая фигурная скобка.nbsp;


Если это было бы так, то компилятор написал бы об этом в ошибке.

v258
v258 аватар
Offline
Зарегистрирован: 25.05.2020

Перенесите функцию void BUTTON () перед сетапом

 
Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Перенес, получил сообщение "a function-definition is not allowed here before '{' token" 

//Arduino UNO 
//Блок индикатора
#include "LedControl.h" 
  /* Расцветка шлейфа UNO-max7219
  pin Мсс - оранжевый
  pin Gnd - желтый
  pin 10 DataIn - зеленый
  pin 8 CLK - синий
  pin 9 LOAD (CS) - фиолетовый
  */
LedControl lc=LedControl(10,8,9,1);
int digit;  //номер 7-сегментника на индикаторе
int sot;  //сотни 
int des;  //десятки 
int edi;  //единицы

//Блок кнопки
volatile int button_pin=2; //Пин кнопки
volatile int button_state; //Состояние кнопки

//Блок энкодера
volatile int enca_pin=3; //Пин энкодера А
volatile int encb_pin=4; //Пин энкодера B

//Блок температуры
#include <OneWire.h>
OneWire ds_1820(12); // Датчик на пине 12 (Белый)
//Подвязывание переменных к библиотеке датчика
byte i;
byte present = 0;
byte data[12];
byte addr_ds_1820[8];
long reading_time;
int ds_1820_5v (11); //пин +5v для датчика температуры (Серый)
volatile int temperature_stop=20; //Температура отсечки
volatile int temperature_current; //Текущая температура 
unsigned long temperature_time; //Переменная задержки времени для считывания датчика температуры
unsigned long temperature_loop_time; //Переменная задержки времени для считывания датчика температуры предыдущая

//Блок насоса
int pump_pin=6; //Пин насоса
volatile long pump_on=3000;              //Время включенного (мсек)
volatile long pump_off=1000;             //Время выключенного (мсек)
volatile unsigned long pump_switch=1;   //Время переключения (мсек)
volatile unsigned long pump_switch_prev=0;  //Время последнего переключения (мсек)
volatile int pump_state;                      // Состояние пина насоса

//Блок нагревателя
volatile int heating_pin=7; //Пин нагревателя
volatile long heating_on=30;           //Время включенного (мсек) 
volatile long heating_off=570;             //Время выключенного (мсек)
volatile unsigned long heating_switch=1;   //Время переключения (мсек)
volatile unsigned long heating_switch_prev=0;  //Время последнего переключения (мсек)
volatile int heating_state;                      // Состояние пина нагревателя

void BUTTON ()
{
  button_state++;
  if (button_state<2) //При настройке нагрев и насос выключаем
  {
    heating_state=LOW;
    digitalWrite(heating_pin, heating_state); // Выключаем нагрев
    pump_state=LOW;
    digitalWrite(pump_pin, pump_state); // Выключаем насос
  if (button_state==2) //При запуске: 
  {
    //нагрев включаем, перезапускаем таймер
    heating_switch_prev = millis();
    //насос включаем, перезапускаем таймер
    pump_switch_prev = millis();
  }
  
  if (button_state>2)
  {
    button_state=1;  
  }
  
}
void ENCODER ()
{
  if (button_state==1) //Настройка температуры отсечки
  {
    if (digitalRead (enca_pin)!= digitalRead (encb_pin)){temperature_stop--;}
    else {temperature_stop++;}
    if (temperature_stop>45) {temperature_stop=45;}
    if (temperature_stop<20) {temperature_stop=20;}
  }
}






void setup() 
{
  Serial.begin (115200);
  //Проверка индикатора
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
  delay (1000);
  for (digit=0;digit<8;digit++)
  {
    lc.setDigit(0,7-digit,digit,false);
    delay (200);
  }
  delay (333);
  lc.clearDisplay(0);
  //Пишем " HELLO! "
    lc.setRow (0,7,B00000000);
    lc.setRow (0,6,B00110111);
    lc.setRow (0,5,B01001111);
    lc.setRow (0,4,B00001110);
    lc.setRow (0,3,B00001110);
    lc.setRow (0,2,B01111110);
    lc.setRow (0,1,B10100000);
    lc.setRow (0,0,B00000000);
  
  //Активация прерываний
  pinMode (button_pin, INPUT); //Кнопка на прерывании 0
  attachInterrupt(0, BUTTON, RISING);
  pinMode (enca_pin, INPUT); //ЭнкодерА на прерывании 1
  attachInterrupt(1, ENCODER, RISING);
  pinMode (encb_pin, INPUT); //ЭнкодерB на пине № 4

  //Блок нагревателя
  pinMode (heating_pin,OUTPUT); //Пин нагревателя - на ВЫХОД
  heating_state=LOW;
  digitalWrite (heating_pin,heating_state);
  //heating_on=1000;
  //heating_off=2000;
  //heating_on=heating_on*heating_multi; //Определение времени включения/выключения для наладки (для работы heating_multi=1)
  //heating_off=heating_off*heating_multi;
     
  //Блок насоса
  pinMode (pump_pin,OUTPUT); //Пин насоса на выход
  digitalWrite (pump_pin,pump_state); 
    
  //Первая инициация датчика температуры
  pinMode (ds_1820_5v,OUTPUT);
  digitalWrite (ds_1820_5v,HIGH);
  
  //Запрос датчику на измерение температуры
  if ( !ds_1820.search(addr_ds_1820)) {}
  //Инициируем датчик температуры
  ds_1820.reset();
  ds_1820.select(addr_ds_1820);
  ds_1820.write(0x44);
}

void loop() 
{ 
  if (button_state==1) // Настройка температуры отсечки
  {
    //Пишем "Adj   °c"
    lc.setRow (0,7,B01110111);
    lc.setRow (0,6,B00111101);
    lc.setRow (0,5,B00011000);
    lc.setRow (0,4,B00000000);
    lc.setRow (0,1,B01100011);
    lc.setRow (0,0,B00001101);
    //Расчленяем температуру отсечки
    des=temperature_stop%100/10;
    edi=temperature_stop%10;
    lc.setDigit (0,3,des,false);
    lc.setDigit (0,2,edi,false);
  }
  if (button_state==2) // Работа системы
  {
    //Пишем температуру отсечки и текущую температуру
    //Расчленяем температуру отсечки
    des=temperature_stop%100/10;
    edi=temperature_stop%10;
    lc.setDigit(0,7,des,false);
    lc.setDigit (0,6,edi,false);
    lc.setRow (0,5,B01100011);
    lc.setRow (0,4,B00000001);
    //Расчленяем текущую температуру
    des=temperature_current%100/10;
    edi=temperature_current%10;
    lc.setRow (0,3,B00000001);
    lc.setDigit (0,2,des,false);
    lc.setDigit (0,1,edi,false);
    lc.setRow (0,0,B01100011);
    
    //Опрос показаний датчика температуры 1 раз в 850 мсек
    if (millis()-reading_time>850)
    {
      //Опрашиваем датчик колонны
      present = ds_1820.reset();
      ds_1820.select(addr_ds_1820);
      ds_1820.write(0xBE);
      for ( i = 0; i < 9; i++)
      {
      data[i] = ds_1820.read();
      }
      int16_t raw = (data[1] << 8) | data[0];
      temperature_current=raw / 16;
      //Заново инициируем датчик
      ds_1820.reset();
      ds_1820.select(addr_ds_1820);
      ds_1820.write(0x44);
    } 
    //Работа нагрева
    if (temperature_current>temperature_stop) //Запрещаем нагрев, если температура выше отсечки
    {
      heating_state=LOW;
      digitalWrite(heating_pin, heating_state);
    } 
    else //Разрешаем нагрев, если температура ниже отсечки
    {
      if(millis() - heating_switch_prev > heating_switch-1) //проверяем не прошел ли нужный интервал, если прошел то: 
      { 
        heating_switch_prev = millis();                          // сохраняем время последнего переключения
        // если нагрев отключен, то подключаем, и наоборот
        if (heating_state == LOW)
        {  
          heating_state = HIGH;
          heating_switch=heating_on;
        }
        else
        { 
          heating_state = LOW;
          heating_switch=heating_off;
        }
        digitalWrite(heating_pin, heating_state); // Управляем нагревом
      }
    }

    //Работа насоса
    if(millis() - pump_switch_prev > pump_switch-1) //проверяем не прошел ли нужный интервал, если прошел то: 
    { 
      pump_switch_prev = millis();                          // сохраняем время последнего переключения
      // если насос отключен, то подключаем, и наоборот
      if (pump_state == LOW)
      {  
        pump_state = HIGH;
        pump_switch=pump_on;
      }
      else
      { 
        pump_state = LOW;
        pump_switch=pump_off;
      }
        digitalWrite(pump_pin, pump_state); // Управляем насосом
    }
  }  
}



 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sonologist пишет:

сообщения "'BUTTON' was not declared in this scope". Моск завял.

....

Перенес, получил сообщение "a function-definition is not allowed here before '{' token" 

Мля, но Вы третий год на форуме и, вроде, раньше всегда были адекватны! Ну, неужели трудно скопипастить сообщение компилятора целиком? Там ведь и номер строки есть, в сообщении-то! А так, нам только вставлять Ваш код и компилировать самим - но у меня вот библиотеки такой нет. Сделайте по-человечески.

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

ЕвгенийП пишет:

Мля, но Вы третий год на форуме и, вроде, раньше всегда были адекватны! 

Прошу простить, Евгений. Действительно, не выспался, потому и неадекватен. Тем не менее, друзья, всем огромное спасибо, напрягся, нашел недостающую скобку в теле функции BUTTON (). Все заработало.

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Но, впредь не забывайте, пожалуйста, целиком сообщения копипастить. А то на троллинг смахивает: "я знаю на какую строку ругается компилятор, но Вам не скажу - пусть квест будет".

flickster
Offline
Зарегистрирован: 09.06.2021

А вообще для таких вещей хорошо использовать Notepad++

Вставляете код, сверху в синтаксисах выбираете нужный ( в нашем случае си) и у вас всё становится красиво подсвечено.