exit status 1 redefinition of void setup

Функции void loop () и void setup () – именно с них начинается знакомство с программированием под arduino у большинства начинающих. В этой статье мы узнаем, для чего нужны эти функции, что можно, а что нельзя в них писать, а также попробуем найти решение таких проблем как ‘redefinision of void setup’, часто возникающих у новичков в проектах arduino.

Как запускается программа на Arduino

Когда мы подключаем плату Arduino к питанию, то внутри него начинается весьма бурная деятельность встроенных микропрограмм. Микроконтроллер сконфигурирован так, что при запуске системы управление получает программа-загрузчик. Первое, что делает загрузчик – проверяет в течение 1-2 секунд, не начнется ли от пользователя отправка новой программы. Если процесс перепрограммирования начат, то скетч загружается в память и управление отдается ему. Если новых программ нет, то загрузчик выполняет ранее сохраненную программу.

Начав выполнение программы, Arduino выполняет ряд рутинных операций по инициализации и настройке среды окружения и только затем приступает к выполнению того самого кода, который содержится в наших с вами скетчах. Таким образом, ардуино избавляет нас от необходимости помнить все детали архитектуры микропроцессора и сконцентрироваться на стоящей перед нами задаче (это не значит, что мы не должны понимать, что же происходит за кадром, но об этом поговорим в отдельной статье).

Для иллюстрации сказанного приведем фрагмент исходников Arduino, в которых и производится вызов наших функций (файл main.cpp):

Функция main() – это настоящая точка входа в программу, именно она вызывается первой. Как мы видим, в ней вызываются методы инициализации параметров и среды окружения, а затем и наши void setup() и, уже в цикле – void loop();

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

Для чего нужна функция void setup()

Загрузив программу, Arduino дает нашему коду возможность поучаствовать в инициализации системы. Для этого мы должны указать микроконтроллеру команды, которые он выполнит в момент загрузки и потом забудет про них (т.е. эти команды выполнятся только один раз при старте системы). И именно с этой целью в нашей с вами программе мы должны выделить блок, в котором будут храниться эти команды. void setup(), а верней пространство внутри фигурных скобок этой функции, и является таким местом внутри Arduino скетча.

Синтаксис void setup()

Синтаксис функции setup очень прост:

// тут располагаются команды подпрограммы

В этом примере слово setup – это название функции. Нужно писать именно так, именно в таком регистре. Слово перед названием описывает тип возвращаемых данных. В данном случае никаких данных подпрограмма не возвращает, поэтому мы должны указать слово void. Все команды должны размещаться внутри фигурных скобок <>.

Не забывайте ставить фигурные скобки! Потеря хотя бы одной скобки сразу сделает всю программу непонятной для ардуино. Но и лишние скобки тоже не ставьте – это так же приведет к ошибке.

Примеры void setup()

Чаще всего внутри void setup указываются следующие инструкции:

  • pinMode с указанием номера и типа пина. Это инструкция определяет режим работы пинов ардуино.
  • Serial.begin с указанием скорости (чаще всего, 9600). Эта инструкция инициализирует работы с последовательным портом на указанной скорости.
  • Инструкции подключения и инициализации различных объектов библиотек ардуино. Например, servo.atach(6) укажет библиотеке, что сервопривод мы подключили к 9 пину, и все последующие действия код библиотеки будет совершать именно с этим портом.
  • Инициализацию глобальных переменных, если мы по каким-то причинам не можем сделать это при определении переменных в глобальной области видимости.
  • Выполнение других настроек и начальных значений для переменных и объектов.

Если говорить об ошибке redefinision of void setup’, то она возникает в том случае, если мы подключаем модуль или скетч, в котором уже есть данная функция. Это и вызывает ошибку

Функция void loop()

Функция loop это то место, куда мы должны поместить команды, которые будут выполняться все время, пока включена плата Arduino. Начав выполнение с первой команды, микроконтроллер дойдет до конца и сразу же перепрыгнет в начало, чтобы повторить ту же последовательность. И так бесконечное число раз (до тех пор, пока на плату будет подан электричество). Наиболее уместный перевод английского слова loop в даном случае – это цикл (петля).

По своей сути, void loop – это главная функция, точка входа в нашу программу. Arduino повторяет вызов этой функции миллионы раз в секунду, таким образом, вы можете быть уверены, что

Пример void loop()

Так хорошо знакомый пример скетча проекта Blink (маячок). Если бы не функция delay(), мы бы никогда не заметили выключение светодиода, т.к. дойдя до конца, скетч начнет выполняться с первой строчки, в которой он сразу же включится.

Резюме

С помощью функций arduino void loop и void setup мы передаем микроконтроллеру инструкции нашего скетча. Все то, что содержится внутри блока setup выполнится один раз. Содержимое блока loop будет выполняться в цикле до тех пор, пока останется включенным Arduino-контроллер.

«Getting the error message:

«error: ‘int ButtonStateNext’ previously declared here» (line 7 is where the issue lies)

«redefinition of ‘int ButtonStateNext’

Whenever I try to compile my arduino program..Could someone shed some light on what exactly is going wrong? I understand that the error message is telling me that i’ve declared ButtonNextState previously, but I see nowhere that i’ve done so (atleast, intentionally?). The below is the entirety of the code (posted it all since its minimal) Thanks.

3 Answers 3

You have a typo here

should be at least

I recently had the same problem without having any errors in my code. I thought I would share in case it is of any use to someone looking here later.

I had mistakenly thought that I could have two .ino files in a folder, and the compiler would only look at the file with the same name as the folder. This is not the case, and the compiler looks at all .ino files in a folder. The redefinition error came because both files shared the same variables.

Hope this helps someone else looking for a similar problem in the future!

Try to save the file to a different place and see if the error persists. If the file is located on the cloud I experienced the above problems with the compiler.

Кто может проверить, работает ли эта программа?
// Объявляем переменные для хранения состояния двух моторов.
int motor_L1, motor_L2, input_L;
int motor_R1, motor_R2, input_R;
void setup()
<
// Переменные – номера контактов (пинов) Arduino.
// Для левых и правых моторов машинки.
setup_motor_system(3, 4, 11, 7, 8, 10);
// Двигатели остановлены.
setspeed(0, 0);
>
// Основная программа.
void loop()
<
// Пример движения робота задан жестко в программе.
// и повторяется в цикле.
setspeed(255, 255); // устанавливает макс. скорость колес.
forward(); // едет вперед 1 секунду.
delay(1000);
forward_left(); // поворачивает налево 0,5 секунд.
delay(500);
forward(); // едет вперед 0,5 секунд.
delay(500);
forward_right(); // поворачивает направо 0,5 секунд.
delay(500);
_stop();
delay(500);
backward(); // движется назад 0,8 секунд.
delay(800);
>
// Функция инициализации управления моторами.
void setup_motor_system(int L1, int L2, int iL, int R1, int R2, int iR)
<
// Заносятся в переменные номера контактов (пинов) Arduino.
motor_L1=L1; motor_L2=L2; input_L=iL;
// Для левых и правых моторов робота.
motor_R1=R1; motor_R2=R2; input_R=iR;
// Переводятся указанные порты в состояние вывода данных.
pinMode(motor_L1, OUTPUT);
pinMode(motor_L2, OUTPUT);
pinMode(input_L, OUTPUT);
pinMode(motor_R1, OUTPUT);
pinMode(motor_R2, OUTPUT);
pinMode(input_R, OUTPUT);
>
// Функция задает скорость двигателя.
void setspeed(int LeftSpeed, int RightSpeed)
<
// Задает ширину положительного фронта от 0 до 255.
analogWrite(input_L, LeftSpeed);
analogWrite(input_R, RightSpeed);
// Чем больше, тем интенсивнее работает мотор.
>
// движение вперед.
void forward()
<
// Если двигатель будет работать не в ту сторону,
// поменять на нем контакты местами.
digitalWrite(motor_L1, HIGH);
digitalWrite(motor_L2,LOW);
digitalWrite(motor_R1, HIGH);
digitalWrite(motor_R2,LOW);
>
// Поворот налево с блокировкой левых колес.
void forward_left()
<
// блокировка вращение левых колес.
digitalWrite(motor_L1, LOW);
digitalWrite(motor_L2, LOW);
// правые колеса вращаются.
digitalWrite(motor_R1, HIGH);
digitalWrite(motor_R2, LOW);
>
// Поворот направо с блокировкой правых колес.
void forward_right()
<
// левые колеса вращаются.
digitalWrite(motor_L1, HIGH);
digitalWrite(motor_L2, LOW);
// блокировка вращение правых колес.
digitalWrite(motor_R1, LOW);
digitalWrite(motor_R2, LOW);
>
// Включаем движение назад.
void backward()
<
// Смена направления вращения двигателей.
digitalWrite(motor_L2, HIGH);
digitalWrite(motor_L1,LOW);
digitalWrite(motor_R2, HIGH);
digitalWrite(motor_R1,LOW);
>

void _stop()
<
// Блокировка всех колес.
digitalWrite(motor_L2, LOW);
digitalWrite(motor_L1,LOW);
digitalWrite(motor_R2, LOW);
digitalWrite(motor_R1,LOW);
>

После компилирования даёт такую ошибку
Arduino: 1.8.6 Hourly Build 2018/08/20 05:33 (Windows 7), Плата:» Arduino/Genuino Uno»

C:UsersAdminAppDataLocalTempuntitled1650659760.tmpsketch_aug20blisting_7_1.ino: In function ‘void setup()’:

listing_7_1:4:6: error: redefinition of ‘void setup()’

void setup()
^
C:UsersAdminAppDataLocalTempuntitled1650659760.tmpsketch_aug20bsketch_aug20b.ino:1:6: note: ‘void setup()’ previously defined here

void setup() <
^
C:UsersAdminAppDataLocalTempuntitled1650659760.tmpsketch_aug20blisting_7_1.ino: In function ‘void loop()’:
listing_7_1:13:6: error: redefinition of ‘void loop()’
void loop()
^
C:UsersAdminAppDataLocalTempuntitled1650659760.tmpsketch_aug20bsketch_aug20b.ino:6:6: note: ‘void loop()’ previously defined here

void loop() <
^
exit status 1
redefinition of ‘void setup()’

Оцените статью