无效循环之外的功能如何工作?


9

我习惯了Arduino草图,其中void setup()一部分可以运行一次,而void loop()一部分会不断循环。当main之外具有void函数时会发生什么void loop()?这些都将保持并行循环还是一个接一个地运行?还是某些void函数仅在满足某些条件时才运行(例如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和Pi之间的连接细节)。
Milliways

1
@Milliways我使用此*教程在arduino uno和Raspberry pi(B +模型)上编写代码,但是我做了一些小的更改。连接两块板的SDA和SCL引脚以及接地引脚(如果它们连接到不同的电源。然后,我将引脚3连接到以分压器配置配置的传感器,该传感器连接在+ 5V和Gnd引脚之间。引脚0和Gnd连接到电机驱动板。
Blue7

Answers:


11

setup()loop(),因为他们是由Arduino的代码自动为你调用的函数是不寻常的。没有其他函数会以这种方式运行。

一般来说,除非您自己明确地调用它(例如,从内部setup()loop()),或者指示程序的另一部分进行调用,否则该函数永远不会运行。(还有其他执行函数的方法,但这通常涉及一些非常高级的修补程序,最好避免。)

例如,pinMode()是与其他函数一样的函数。它仅在您实际pinMode(3, INPUT)在代码中放入类似内容时运行。到那时,它运行一次,结束,然后调用函数从中断处继续运行(它们从不并行运行)。

您发布的示例代码非常有趣。看一下这些行setup()

Wire.onReceive(receiveData);
Wire.onRequest(sendData);

这些行告诉Wire对象要调用receiveData()sendData()响应I2C事件。它通过传递由存储和使用的函数指针来做到这一点Wire

如果您想了解更多有关C / C ++函数指针的信息,建议您在线搜索。您可能也有兴趣探索Arduino的attachInterrupt()功能。


感谢您的回答。现在这开始变得更有意义了。但是,如果receiveData()and sendData()函数只有在未调用时才运行,那么为什么要在void setup()函数而不是main void loop()函数中调用它们?当然,除非在指令指针仍在void setup函数内的情况下发生i2c事件的罕见机会,否则这些函数将永远不会被调用?从函数内部调用这些函数是否更好,void loop所以每当发生i2c事件时,都会调用该函数?
Blue7

4
@ Blue7公司这些功能都没有所谓void setup(),他们是作为参数传递onReceiveonRequest,他们回调作为注释状态。在很短的总结:这告诉电线库中(从代码),当特定的事情发生(调用这些函数arduino.cc/en/Reference/WireOnReceivearduino.cc/en/Reference/WireOnRequest ...)
FredP

@FredP好的。感谢您提供的链接,当我不在手机上时,我会检查它们。如果您不介意的话,同时我有一个简短的问题。这些回调是否总是准备就绪并正在等待i2c事件?即,无论指令指针在哪里,这些回调都会在i2c事件发生后立即调用该函数?
Blue7

1
@ Blue7大概将使用中断来监视I2C活动。执行中断时,它会暂时使控制权脱离主程序。
彼得·布卢姆菲尔德

3
@ Blue7回调未在等待(Arduino不是多线程的),如@PeterRBloomfield所说,Wire库twi_init()在您调用时启用I2C中断Wire.begin。当有I2C活动时,µC停止执行其当前任务(除非...暂时不要介意:-)并进入Wire库的代码,然后调用您注册为的(适当的,取决于所发生的事情)函数回调(receiveData例如)。一个回调是像功能的通用名称receiveData或者sendData,它们是由一个叫做中断处理程序内部电线。
FredP 2014年

2

难道不是setup()一次被调用又loop()被反复调用的情况?即有一个看不见的 main()可能看起来像这样:

void main(){
  setup();
  while(True){
    loop();
  }
}

抱歉,我只是研究Arduino而几乎没有C / C ++经验;我正在尝试loop()自己解决这种情况。


基本上是。还有一个调用init()它得到定时器去为millisdelay等于是init()对一般的初始化,setup()你的初始化,loop对,很好,循环。main如果要完全控制,可以编写自己的代码。
尼克·加蒙

好贴。;倒数第二个}:-) 之后不需要BTW
-Greenonline 2015年

也有调用serial_event()是吗?
Divisadero

2

我无法评论Dee的回应。在主循环中执行的实际代码在这里

    int main(void) {
    init();
    initVariant();

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }   
    return 0;
}

是的,setup()被调用一次,loop()并被重复调用(以及一些串行的东西)。


0

它作为正常功能工作,必须调用它才有意义。从main()函数调用loop()/ setup(),该函数是从Arduino目录编译并链接进来的。receiveData / sendData是从您的程序中调用的,该程序的根位于loop / setup函数中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.