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

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

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

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

001//Arduino UNO
002//Блок индикатора
003#include "LedControl.h"
004  /* Расцветка шлейфа UNO-max7219
005  pin Мсс - оранжевый
006  pin Gnd - желтый
007  pin 10 DataIn - зеленый
008  pin 8 CLK - синий
009  pin 9 LOAD (CS) - фиолетовый
010  */
011LedControl lc=LedControl(10,8,9,1);
012int digit;  //номер 7-сегментника на индикаторе
013int sot;  //сотни
014int des;  //десятки
015int edi;  //единицы
016 
017//Блок кнопки
018volatile int button_pin=2; //Пин кнопки
019volatile int button_state; //Состояние кнопки
020 
021//Блок энкодера
022volatile int enca_pin=3; //Пин энкодера А
023volatile int encb_pin=4; //Пин энкодера B
024 
025//Блок температуры
026#include <OneWire.h>
027OneWire ds_1820(12); // Датчик на пине 12 (Белый)
028//Подвязывание переменных к библиотеке датчика
029byte i;
030byte present = 0;
031byte data[12];
032byte addr_ds_1820[8];
033long reading_time;
034int ds_1820_5v (11); //пин +5v для датчика температуры (Серый)
035volatile int temperature_stop=20; //Температура отсечки
036volatile int temperature_current; //Текущая температура
037unsigned long temperature_time; //Переменная задержки времени для считывания датчика температуры
038unsigned long temperature_loop_time; //Переменная задержки времени для считывания датчика температуры предыдущая
039 
040//Блок насоса
041int pump_pin=6; //Пин насоса
042volatile long pump_on=3000;              //Время включенного (мсек)
043volatile long pump_off=1000;             //Время выключенного (мсек)
044volatile unsigned long pump_switch=1;   //Время переключения (мсек)
045volatile unsigned long pump_switch_prev=0;  //Время последнего переключения (мсек)
046volatile int pump_state;                      // Состояние пина насоса
047 
048//Блок нагревателя
049volatile int heating_pin=7; //Пин нагревателя
050volatile long heating_on=30;           //Время включенного (мсек)
051volatile long heating_off=570;             //Время выключенного (мсек)
052volatile unsigned long heating_switch=1;   //Время переключения (мсек)
053volatile unsigned long heating_switch_prev=0;  //Время последнего переключения (мсек)
054volatile int heating_state;                      // Состояние пина нагревателя
055 
056void setup()
057{
058  Serial.begin (115200);
059  //Проверка индикатора
060  lc.shutdown(0,false);
061  lc.setIntensity(0,8);
062  lc.clearDisplay(0);
063  delay (1000);
064  for (digit=0;digit<8;digit++)
065  {
066    lc.setDigit(0,7-digit,digit,false);
067    delay (200);
068  }
069  delay (333);
070  lc.clearDisplay(0);
071  //Пишем " HELLO! "
072    lc.setRow (0,7,B00000000);
073    lc.setRow (0,6,B00110111);
074    lc.setRow (0,5,B01001111);
075    lc.setRow (0,4,B00001110);
076    lc.setRow (0,3,B00001110);
077    lc.setRow (0,2,B01111110);
078    lc.setRow (0,1,B10100000);
079    lc.setRow (0,0,B00000000);
080   
081  //Активация прерываний
082  pinMode (button_pin, INPUT); //Кнопка на прерывании 0
083  attachInterrupt(0, BUTTON, RISING);
084  pinMode (enca_pin, INPUT); //ЭнкодерА на прерывании 1
085  attachInterrupt(1, ENCODER, RISING);
086  pinMode (encb_pin, INPUT); //ЭнкодерB на пине № 4
087 
088  //Блок нагревателя
089  pinMode (heating_pin,OUTPUT); //Пин нагревателя - на ВЫХОД
090  heating_state=LOW;
091  digitalWrite (heating_pin,heating_state);
092  //heating_on=1000;
093  //heating_off=2000;
094  //heating_on=heating_on*heating_multi; //Определение времени включения/выключения для наладки (для работы heating_multi=1)
095  //heating_off=heating_off*heating_multi;
096      
097  //Блок насоса
098  pinMode (pump_pin,OUTPUT); //Пин насоса на выход
099  digitalWrite (pump_pin,pump_state);
100     
101  //Первая инициация датчика температуры
102  pinMode (ds_1820_5v,OUTPUT);
103  digitalWrite (ds_1820_5v,HIGH);
104   
105  //Запрос датчику на измерение температуры
106  if ( !ds_1820.search(addr_ds_1820)) {}
107  //Инициируем датчик температуры
108  ds_1820.reset();
109  ds_1820.select(addr_ds_1820);
110  ds_1820.write(0x44);
111}
112 
113void loop()
114{
115  if (button_state==1) // Настройка температуры отсечки
116  {
117    //Пишем "Adj   °c"
118    lc.setRow (0,7,B01110111);
119    lc.setRow (0,6,B00111101);
120    lc.setRow (0,5,B00011000);
121    lc.setRow (0,4,B00000000);
122    lc.setRow (0,1,B01100011);
123    lc.setRow (0,0,B00001101);
124    //Расчленяем температуру отсечки
125    des=temperature_stop%100/10;
126    edi=temperature_stop%10;
127    lc.setDigit (0,3,des,false);
128    lc.setDigit (0,2,edi,false);
129  }
130  if (button_state==2) // Работа системы
131  {
132    //Пишем температуру отсечки и текущую температуру
133    //Расчленяем температуру отсечки
134    des=temperature_stop%100/10;
135    edi=temperature_stop%10;
136    lc.setDigit(0,7,des,false);
137    lc.setDigit (0,6,edi,false);
138    lc.setRow (0,5,B01100011);
139    lc.setRow (0,4,B00000001);
140    //Расчленяем текущую температуру
141    des=temperature_current%100/10;
142    edi=temperature_current%10;
143    lc.setRow (0,3,B00000001);
144    lc.setDigit (0,2,des,false);
145    lc.setDigit (0,1,edi,false);
146    lc.setRow (0,0,B01100011);
147     
148    //Опрос показаний датчика температуры 1 раз в 850 мсек
149    if (millis()-reading_time>850)
150    {
151      //Опрашиваем датчик колонны
152      present = ds_1820.reset();
153      ds_1820.select(addr_ds_1820);
154      ds_1820.write(0xBE);
155      for ( i = 0; i < 9; i++)
156      {
157      data[i] = ds_1820.read();
158      }
159      int16_t raw = (data[1] << 8) | data[0];
160      temperature_current=raw / 16;
161      //Заново инициируем датчик
162      ds_1820.reset();
163      ds_1820.select(addr_ds_1820);
164      ds_1820.write(0x44);
165    }
166    //Работа нагрева
167    if (temperature_current>temperature_stop) //Запрещаем нагрев, если температура выше отсечки
168    {
169      heating_state=LOW;
170      digitalWrite(heating_pin, heating_state);
171    }
172    else //Разрешаем нагрев, если температура ниже отсечки
173    {
174      if(millis() - heating_switch_prev > heating_switch-1) //проверяем не прошел ли нужный интервал, если прошел то:
175      {
176        heating_switch_prev = millis();                          // сохраняем время последнего переключения
177        // если нагрев отключен, то подключаем, и наоборот
178        if (heating_state == LOW)
179        
180          heating_state = HIGH;
181          heating_switch=heating_on;
182        }
183        else
184        {
185          heating_state = LOW;
186          heating_switch=heating_off;
187        }
188        digitalWrite(heating_pin, heating_state); // Управляем нагревом
189      }
190    }
191 
192    //Работа насоса
193    if(millis() - pump_switch_prev > pump_switch-1) //проверяем не прошел ли нужный интервал, если прошел то:
194    {
195      pump_switch_prev = millis();                          // сохраняем время последнего переключения
196      // если насос отключен, то подключаем, и наоборот
197      if (pump_state == LOW)
198      
199        pump_state = HIGH;
200        pump_switch=pump_on;
201      }
202      else
203      {
204        pump_state = LOW;
205        pump_switch=pump_off;
206      }
207        digitalWrite(pump_pin, pump_state); // Управляем насосом
208    }
209  
210}
211 
212 
213 
214void BUTTON ()
215{
216  button_state++;
217  if (button_state<2) //При настройке нагрев и насос выключаем
218  {
219    heating_state=LOW;
220    digitalWrite(heating_pin, heating_state); // Выключаем нагрев
221    pump_state=LOW;
222    digitalWrite(pump_pin, pump_state); // Выключаем насос
223  if (button_state==2) //При запуске:
224  {
225    //нагрев включаем, перезапускаем таймер
226    heating_switch_prev = millis();
227    //насос включаем, перезапускаем таймер
228    pump_switch_prev = millis();
229  }
230   
231  if (button_state>2)
232  {
233    button_state=1; 
234  }
235   
236}
237void ENCODER ()
238{
239  if (button_state==1) //Настройка температуры отсечки
240  {
241    if (digitalRead (enca_pin)!= digitalRead (encb_pin)){temperature_stop--;}
242    else {temperature_stop++;}
243    if (temperature_stop>45) {temperature_stop=45;}
244    if (temperature_stop<20) {temperature_stop=20;}
245  }
246}

 

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" 

001//Arduino UNO
002//Блок индикатора
003#include "LedControl.h"
004  /* Расцветка шлейфа UNO-max7219
005  pin Мсс - оранжевый
006  pin Gnd - желтый
007  pin 10 DataIn - зеленый
008  pin 8 CLK - синий
009  pin 9 LOAD (CS) - фиолетовый
010  */
011LedControl lc=LedControl(10,8,9,1);
012int digit;  //номер 7-сегментника на индикаторе
013int sot;  //сотни
014int des;  //десятки
015int edi;  //единицы
016 
017//Блок кнопки
018volatile int button_pin=2; //Пин кнопки
019volatile int button_state; //Состояние кнопки
020 
021//Блок энкодера
022volatile int enca_pin=3; //Пин энкодера А
023volatile int encb_pin=4; //Пин энкодера B
024 
025//Блок температуры
026#include <OneWire.h>
027OneWire ds_1820(12); // Датчик на пине 12 (Белый)
028//Подвязывание переменных к библиотеке датчика
029byte i;
030byte present = 0;
031byte data[12];
032byte addr_ds_1820[8];
033long reading_time;
034int ds_1820_5v (11); //пин +5v для датчика температуры (Серый)
035volatile int temperature_stop=20; //Температура отсечки
036volatile int temperature_current; //Текущая температура
037unsigned long temperature_time; //Переменная задержки времени для считывания датчика температуры
038unsigned long temperature_loop_time; //Переменная задержки времени для считывания датчика температуры предыдущая
039 
040//Блок насоса
041int pump_pin=6; //Пин насоса
042volatile long pump_on=3000;              //Время включенного (мсек)
043volatile long pump_off=1000;             //Время выключенного (мсек)
044volatile unsigned long pump_switch=1;   //Время переключения (мсек)
045volatile unsigned long pump_switch_prev=0;  //Время последнего переключения (мсек)
046volatile int pump_state;                      // Состояние пина насоса
047 
048//Блок нагревателя
049volatile int heating_pin=7; //Пин нагревателя
050volatile long heating_on=30;           //Время включенного (мсек)
051volatile long heating_off=570;             //Время выключенного (мсек)
052volatile unsigned long heating_switch=1;   //Время переключения (мсек)
053volatile unsigned long heating_switch_prev=0;  //Время последнего переключения (мсек)
054volatile int heating_state;                      // Состояние пина нагревателя
055 
056void BUTTON ()
057{
058  button_state++;
059  if (button_state<2) //При настройке нагрев и насос выключаем
060  {
061    heating_state=LOW;
062    digitalWrite(heating_pin, heating_state); // Выключаем нагрев
063    pump_state=LOW;
064    digitalWrite(pump_pin, pump_state); // Выключаем насос
065  if (button_state==2) //При запуске:
066  {
067    //нагрев включаем, перезапускаем таймер
068    heating_switch_prev = millis();
069    //насос включаем, перезапускаем таймер
070    pump_switch_prev = millis();
071  }
072   
073  if (button_state>2)
074  {
075    button_state=1; 
076  }
077   
078}
079void ENCODER ()
080{
081  if (button_state==1) //Настройка температуры отсечки
082  {
083    if (digitalRead (enca_pin)!= digitalRead (encb_pin)){temperature_stop--;}
084    else {temperature_stop++;}
085    if (temperature_stop>45) {temperature_stop=45;}
086    if (temperature_stop<20) {temperature_stop=20;}
087  }
088}
089 
090 
091 
092 
093 
094 
095void setup()
096{
097  Serial.begin (115200);
098  //Проверка индикатора
099  lc.shutdown(0,false);
100  lc.setIntensity(0,8);
101  lc.clearDisplay(0);
102  delay (1000);
103  for (digit=0;digit<8;digit++)
104  {
105    lc.setDigit(0,7-digit,digit,false);
106    delay (200);
107  }
108  delay (333);
109  lc.clearDisplay(0);
110  //Пишем " HELLO! "
111    lc.setRow (0,7,B00000000);
112    lc.setRow (0,6,B00110111);
113    lc.setRow (0,5,B01001111);
114    lc.setRow (0,4,B00001110);
115    lc.setRow (0,3,B00001110);
116    lc.setRow (0,2,B01111110);
117    lc.setRow (0,1,B10100000);
118    lc.setRow (0,0,B00000000);
119   
120  //Активация прерываний
121  pinMode (button_pin, INPUT); //Кнопка на прерывании 0
122  attachInterrupt(0, BUTTON, RISING);
123  pinMode (enca_pin, INPUT); //ЭнкодерА на прерывании 1
124  attachInterrupt(1, ENCODER, RISING);
125  pinMode (encb_pin, INPUT); //ЭнкодерB на пине № 4
126 
127  //Блок нагревателя
128  pinMode (heating_pin,OUTPUT); //Пин нагревателя - на ВЫХОД
129  heating_state=LOW;
130  digitalWrite (heating_pin,heating_state);
131  //heating_on=1000;
132  //heating_off=2000;
133  //heating_on=heating_on*heating_multi; //Определение времени включения/выключения для наладки (для работы heating_multi=1)
134  //heating_off=heating_off*heating_multi;
135      
136  //Блок насоса
137  pinMode (pump_pin,OUTPUT); //Пин насоса на выход
138  digitalWrite (pump_pin,pump_state);
139     
140  //Первая инициация датчика температуры
141  pinMode (ds_1820_5v,OUTPUT);
142  digitalWrite (ds_1820_5v,HIGH);
143   
144  //Запрос датчику на измерение температуры
145  if ( !ds_1820.search(addr_ds_1820)) {}
146  //Инициируем датчик температуры
147  ds_1820.reset();
148  ds_1820.select(addr_ds_1820);
149  ds_1820.write(0x44);
150}
151 
152void loop()
153{
154  if (button_state==1) // Настройка температуры отсечки
155  {
156    //Пишем "Adj   °c"
157    lc.setRow (0,7,B01110111);
158    lc.setRow (0,6,B00111101);
159    lc.setRow (0,5,B00011000);
160    lc.setRow (0,4,B00000000);
161    lc.setRow (0,1,B01100011);
162    lc.setRow (0,0,B00001101);
163    //Расчленяем температуру отсечки
164    des=temperature_stop%100/10;
165    edi=temperature_stop%10;
166    lc.setDigit (0,3,des,false);
167    lc.setDigit (0,2,edi,false);
168  }
169  if (button_state==2) // Работа системы
170  {
171    //Пишем температуру отсечки и текущую температуру
172    //Расчленяем температуру отсечки
173    des=temperature_stop%100/10;
174    edi=temperature_stop%10;
175    lc.setDigit(0,7,des,false);
176    lc.setDigit (0,6,edi,false);
177    lc.setRow (0,5,B01100011);
178    lc.setRow (0,4,B00000001);
179    //Расчленяем текущую температуру
180    des=temperature_current%100/10;
181    edi=temperature_current%10;
182    lc.setRow (0,3,B00000001);
183    lc.setDigit (0,2,des,false);
184    lc.setDigit (0,1,edi,false);
185    lc.setRow (0,0,B01100011);
186     
187    //Опрос показаний датчика температуры 1 раз в 850 мсек
188    if (millis()-reading_time>850)
189    {
190      //Опрашиваем датчик колонны
191      present = ds_1820.reset();
192      ds_1820.select(addr_ds_1820);
193      ds_1820.write(0xBE);
194      for ( i = 0; i < 9; i++)
195      {
196      data[i] = ds_1820.read();
197      }
198      int16_t raw = (data[1] << 8) | data[0];
199      temperature_current=raw / 16;
200      //Заново инициируем датчик
201      ds_1820.reset();
202      ds_1820.select(addr_ds_1820);
203      ds_1820.write(0x44);
204    }
205    //Работа нагрева
206    if (temperature_current>temperature_stop) //Запрещаем нагрев, если температура выше отсечки
207    {
208      heating_state=LOW;
209      digitalWrite(heating_pin, heating_state);
210    }
211    else //Разрешаем нагрев, если температура ниже отсечки
212    {
213      if(millis() - heating_switch_prev > heating_switch-1) //проверяем не прошел ли нужный интервал, если прошел то:
214      {
215        heating_switch_prev = millis();                          // сохраняем время последнего переключения
216        // если нагрев отключен, то подключаем, и наоборот
217        if (heating_state == LOW)
218        
219          heating_state = HIGH;
220          heating_switch=heating_on;
221        }
222        else
223        {
224          heating_state = LOW;
225          heating_switch=heating_off;
226        }
227        digitalWrite(heating_pin, heating_state); // Управляем нагревом
228      }
229    }
230 
231    //Работа насоса
232    if(millis() - pump_switch_prev > pump_switch-1) //проверяем не прошел ли нужный интервал, если прошел то:
233    {
234      pump_switch_prev = millis();                          // сохраняем время последнего переключения
235      // если насос отключен, то подключаем, и наоборот
236      if (pump_state == LOW)
237      
238        pump_state = HIGH;
239        pump_switch=pump_on;
240      }
241      else
242      {
243        pump_state = LOW;
244        pump_switch=pump_off;
245      }
246        digitalWrite(pump_pin, pump_state); // Управляем насосом
247    }
248  
249}

 

ЕвгенийП
ЕвгенийП аватар
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++

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