Я привык к наброскам Arduino с void setup()
частью, которая выполняется один раз, и void loop()
частью, которая продолжает цикл. Что происходит, когда у вас есть пустые функции вне основного void loop()
? Все ли они будут продолжать работать параллельно, или они будут работать один за другим? Или определенные пустые функции запускаются только после того, как определенные критерии были выполнены (например, цикл while)?
Например , в коде ниже, когда будет void receiveData(int byteCount)
и void sendData()
функция запуска?
//I2C_test
//This code demonstrates communication via an I2C bus between a raspberry pi and an arduino.
//When the Raspberry pi (master) sends data to the Arduino (slave), the Arduino uses this
//data to control a motor. After the Arduino has recieved data from the master, it then collects
//data from the external environment via a sensor and sends this data back to the Raspberry pi.
#include <Wire.h>
int number = 0; //Declare variables
int val = 0;
void setup() {
//Anything between the curly brackets runs once when the arduino is turned on or reset
pinMode(0, INPUT);
//Set pin 0 as input and 3 as output
pinMode(3, OUTPUT);
Serial.begin(9600);
//Set the data rate for serial transmission at 9600bps
Wire.begin(0x04);
//Initiate the Wire library, join the Arduino as a slave, and specify its 7 bit slave address
Wire.onReceive(receiveData);
//Define callbacks for i2c communication
Wire.onRequest(sendData);
}
void loop() {
//The code between the curly brackets keeps repeating
delay(100);
}
void receiveData(int byteCount) {
while(Wire.available()) {
number = Wire.read();
//Set the variable "number" to the data sent by the master
analogWrite(3, number);
//Write this number to pin 3 (PWM). This controls the motor speed
}
val = analogRead(0);
//Read the voltage on pin 0 (connected to the sensor). Map input voltages between 0 and 5 volts into integer values between 0 and 1023
}
void sendData() {
Wire.write(val);
//Send the data read from the sensor to the master.
}
arduino-uno
i2c
Blue7
источник
источник
Ответы:
Функции
setup()
иloop()
необычны, потому что они автоматически вызываются для вас кодом Arduino. Никакие другие функции не ведут себя таким образом.Вообще говоря, функция никогда не запустится, если вы сами не вызовете ее (например, из
setup()
илиloop()
) или не проинструктируете другую часть программы вызывать ее. (Существуют и другие способы выполнения функций, но обычно они включают в себя некоторые очень сложные операции, которых лучше избегать.)Например,
pinMode()
это функция, как и любая другая. Он запускается только тогда, когда вы действительно добавляете что-то подобноеpinMode(3, INPUT)
в свой код. В этот момент он запускается один раз, завершается, а затем вызывающая функция продолжается с того места, где она остановилась (они никогда не запускаются параллельно).Пример кода, который вы опубликовали, довольно интересный. Посмотрите на эти строки в
setup()
:Эти строки сообщают
Wire
объекту о вызовеreceiveData()
иsendData()
в ответ на события I2C. Это делается путем передачи указателей на функции, которые хранятся и используютсяWire
.Я бы порекомендовал поискать информацию об указателях функций C / C ++ онлайн, если вы хотите узнать больше об этом. Вам также может быть интересно изучить
attachInterrupt()
функцию Arduino .источник
receiveData()
иsendData()
функция не работает , если они не называют, то почему они называются внутриvoid setup()
функции и не является основнойvoid loop()
функцией? Конечно, эти функции никогда не будут вызваны, если только редкий шанс, что есть событие i2c, пока указатель инструкции все еще находится внутриvoid setup
функции? Не лучше ли вызывать эти функции изнутриvoid loop
функции, чтобы при возникновении события i2c функция вызывалась?void setup()
, они передаются в качестве параметраonReceive
иonRequest
, они обратные вызовы в качестве комментария состояний. Вкратце: это говорит (код из) библиотеки Wire вызывать эти функции, когда происходят определенные вещи ( arduino.cc/en/Reference/WireOnReceive , arduino.cc/en/Reference/WireOnRequest ...)twi_init()
при вызовеWire.begin
. Когда есть активность I2C, микроконтроллер перестает выполнять свою текущую задачу (если ... на данный момент не имеет значения :-) и входит в код библиотеки Wire, которая затем вызывает (соответствующую, в зависимости от происходящего) функцию, которую вы зарегистрировали как обратный вызов (receiveData
например). Обратный вызов это общее название для функций , таких какreceiveData
илиsendData
, как они называются с помощью обработчика прерываний внутри провода.Разве это не тот случай, который
setup()
вызывается один раз иloop()
вызывается неоднократно? то есть, что есть невидимое,main()
которое может выглядеть так:Извиняюсь за то, что я просто изучаю Arduino и почти не имею опыта работы с C / C ++; Я пытаюсь разобраться в этой
loop()
ситуации сам.источник
init()
который запускает таймерыmillis
иdelay
т. Д. Такinit()
же для общей инициализации,setup()
для вашей инициализации иloop
для, ну, в общем , зацикливания. Вы можете написать свой собственный,main
если вы хотите получить полный контроль.;
не требуется после предпоследнего}
:-)Я не могу комментировать ответ Ди. Фактический код, который выполняется в основном цикле, находится здесь :
И да, вызывается
setup()
один раз иloop()
вызывается неоднократно (вместе с некоторыми последовательными вещами).источник
Работает как обычная функция, ее нужно вызывать, чтобы иметь смысл. loop () / setup () вызываются из функции main (), которая скомпилирована из каталога Arduino и связана с ней. receiveData / sendData должны вызываться из вашей программы, корень которой находится в функциях loop / setup.
источник