Je suis habitué aux croquis Arduino avec une void setup()
partie qui s'exécute une fois et une void loop()
partie qui continue à boucler. Que se passe-t-il lorsque vous avez des fonctions d'annulation en dehors du principal void loop()
? Est-ce que tous continueront à boucler en parallèle ou fonctionneront-ils l'un après l'autre? Ou certaines fonctions void ne s'exécutent-elles qu'une fois certains critères remplis (comme une boucle while)?
Par exemple, dans le code ci-dessous, quand void receiveData(int byteCount)
les void sendData()
fonctions et s'exécuteront-elles?
//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
la source
la source
Réponses:
Les fonctions
setup()
etloop()
sont inhabituelles car elles sont appelées automatiquement pour vous par le code Arduino. Aucune autre fonction ne se comporte de cette façon.D'une manière générale, une fonction ne s'exécutera jamais à moins que vous ne l'appeliez explicitement vous-même (par exemple depuis
setup()
ouloop()
) ou que vous demandiez à une autre partie du programme de l'appeler. (Il existe d'autres façons d'exécuter des fonctions, mais cela implique généralement un bricolage très avancé qu'il vaut mieux éviter.)Par exemple,
pinMode()
est une fonction comme les autres. Il ne s'exécute que lorsque vous mettez quelque chose commepinMode(3, INPUT)
dans votre code. À ce stade, il s'exécute une fois, se termine, puis la fonction appelante continue là où elle s'était arrêtée (elles ne s'exécutent jamais en parallèle).L'exemple de code que vous avez publié est assez intéressant. Regardez ces lignes dans
setup()
:Ces lignes indiquent à l'
Wire
objet d'appelerreceiveData()
etsendData()
en réponse aux événements I2C. Il le fait en passant des pointeurs de fonction qui sont stockés et utilisés parWire
.Je vous recommande de rechercher des informations sur les pointeurs de fonction C / C ++ en ligne si vous souhaitez en savoir plus. Vous pouvez également être intéressé à explorer la
attachInterrupt()
fonction d'Arduino .la source
receiveData()
etsendData()
ne sont exécutées que si elles sont appelées, pourquoi sont-elles appelées dans lavoid setup()
fonction et non dans lavoid loop()
fonction principale ? Sûrement ces fonctions ne seront jamais appelées à moins que les rares chances qu'il y ait un événement i2c alors que le pointeur d'instruction est toujours dans lavoid setup
fonction? Ne serait-il pas préférable d'appeler ces fonctions à partir de lavoid loop
fonction, donc chaque fois qu'il y a un événement i2c, la fonction est appelée?void setup()
, ils sont passés comme paramètre deonReceive
etonRequest
, ils sont callbacks comme les états de commentaires. En résumé: ceci indique au (code de la) bibliothèque Wire d'appeler ces fonctions lorsque des choses spécifiques se produisent ( arduino.cc/en/Reference/WireOnReceive , arduino.cc/en/Reference/WireOnRequest ...)twi_init()
lorsque vous appelezWire.begin
. Quand il y a une activité I2C, le µC cesse de faire sa tâche actuelle (à moins que ... pour le moment :-) et passe dans le code de la bibliothèque Wire, qui appelle ensuite la fonction (appropriée, selon ce qui se passe) que vous avez enregistrée en tant que rappel (receiveData
par exemple). Un rappel est le nom générique de fonctions commereceiveData
ousendData
, elles sont appelées par un gestionnaire d'interruption à l' intérieur de Wire.N'est-ce pas ce cas qui
setup()
est appelé une fois et quiloop()
est appelé à plusieurs reprises? c'est-à-dire qu'il y a un invisiblemain()
qui pourrait ressembler à ceci:Toutes mes excuses car je ne fais que regarder l'Arduino et je n'ai pratiquement aucune expérience en C / C ++; J'essaie de maîtriser cette
loop()
situation moi-même.la source
init()
qui déclenche les temporisationsmillis
,delay
etc. Il eninit()
va de même pour l'initialisation générale,setup()
pour votre initialisation etloop
pour, eh bien, pour la boucle. Vous pouvez écrire le vôtremain
si vous voulez prendre le contrôle total.;
n'est pas requis après l'avant-dernier}
:-)Je ne peux pas commenter la réponse de Dee. Le code réel qui est exécuté dans la boucle principale est ici :
Et oui,
setup()
est appelé une fois etloop()
est appelé à plusieurs reprises (avec quelques trucs en série).la source
Cela fonctionne comme une fonction normale, il faut l'appeler pour avoir du sens. loop () / setup () sont appelés à partir d'une fonction main () qui est compilée à partir du répertoire Arduino et liée. receiveData / sendData sont appelés à partir de votre programme dont la racine est dans les fonctions loop / setup.
la source