Estou acostumado a esboços do Arduino com uma void setup()
peça que é executada uma vez e outra void loop()
que fica em loop. O que acontece quando você tem funções nulas fora da principal void loop()
? Todos eles continuarão em loop paralelo ou serão executados um após o outro? Ou certas funções nulas só são executadas quando certos critérios são atendidos (como um loop while)?
Por exemplo, no código abaixo, quando void receiveData(int byteCount)
as void sendData()
funções e serão executadas?
//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
fonte
fonte
Respostas:
As funções
setup()
eloop()
são incomuns porque são chamadas automaticamente para você pelo código do Arduino. Nenhuma outra função se comporta dessa maneira.De um modo geral, uma função nunca será executada, a menos que você a chame explicitamente (por exemplo, de dentro
setup()
ouloop()
), ou instrua outra parte do programa a chamá-la. (Existem outras maneiras de executar funções, mas isso geralmente envolve alguns ajustes muito avançados que devem ser evitados.)Por exemplo,
pinMode()
é uma função como qualquer outra. Só é executado quando você realmente coloca algo comopinMode(3, INPUT)
no seu código. Nesse ponto, ele é executado uma vez, termina e, em seguida, a função de chamada continua de onde parou (eles nunca são executados em paralelo).O código de exemplo que você postou é bastante interessante. Veja estas linhas em
setup()
:Essas linhas estão dizendo ao
Wire
objeto para chamarreceiveData()
esendData()
em resposta aos eventos I2C. Ele faz isso passando ponteiros de função que são armazenados e usados porWire
.Eu recomendo procurar informações sobre ponteiros de função C / C ++ online, se você quiser saber mais sobre isso. Você também pode estar interessado em explorar a
attachInterrupt()
função do Arduino .fonte
receiveData()
esendData()
não são executadas, a menos que sejam chamadas, por que elas são chamadas navoid setup()
função e não navoid loop()
função principal ? Certamente, essas funções nunca serão chamadas, a menos que seja rara a chance de haver um evento i2c enquanto o ponteiro da instrução ainda estiver dentro davoid setup
função? Não seria melhor chamar essas funções de dentro davoid loop
função, portanto, sempre que houver um evento i2c, a função será chamada?void setup()
, eles são passados como parâmetro deonReceive
eonRequest
, eles são chamadas de retorno como o comentário estados. Em um resumo muito curto: isso informa ao (código da) biblioteca Wire para chamar essas funções quando coisas específicas acontecem ( arduino.cc/en/Reference/WireOnReceive , arduino.cc/en/Reference/WireOnRequest ...)twi_init()
durante a ligaçãoWire.begin
. Quando há atividade I2C, o µC para de executar sua tarefa atual (a menos que ... não importa no momento :-) e entra no código da biblioteca Wire, que então chama a função (apropriada, dependendo do que está acontecendo) que você registrou como retorno de chamada (receiveData
por exemplo). Um retorno de chamada é o nome genérico para funções comoreceiveData
orsendData
, elas são chamadas por um manipulador de interrupção dentro do Wire.Não é esse o caso que
setup()
é chamado uma vez eloop()
é chamado repetidamente? ou seja, que há um invisívelmain()
que pode ser assim:Desculpas, pois estou apenas olhando o Arduino e quase não tenho experiência em C / C ++; Estou tentando me controlar com essa
loop()
situação.fonte
init()
qual os temporizadores estão funcionandomillis
,delay
etc. O mesmoinit()
ocorre com a inicialização geral,setup()
é para a sua inicialização eloop
é para, assim, fazer um loop. Você pode escrever o seu própriomain
se quiser assumir o controle total.;
não é necessário após o penúltimo}
:-)Não posso comentar sobre a resposta de Dee. O código real que é executado no loop principal está aqui :
E sim,
setup()
é chamado uma vez eloop()
está sendo chamado repetidamente (junto com algumas coisas em série).fonte
Funciona como função normal, deve ser chamado para fazer sentido. loop () / setup () é chamado a partir de uma função main () compilada no diretório Arduino e vinculada.
fonte