Saya terbiasa sketsa Arduino dengan void setup()
bagian yang berjalan sekali, dan void loop()
bagian yang terus berulang. Apa yang terjadi ketika Anda memiliki fungsi batal di luar utama void loop()
? Apakah ini semua akan tetap berulang secara paralel atau apakah mereka menjalankan satu demi satu? Atau apakah fungsi void tertentu hanya berjalan setelah kriteria tertentu telah dipenuhi (seperti loop sementara)?
Misalnya dalam kode di bawah ini, kapan akan void receiveData(int byteCount)
dan void sendData()
fungsinya berjalan?
//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
Biru7
sumber
sumber
Jawaban:
Fungsi
setup()
danloop()
tidak biasa karena mereka dipanggil secara otomatis untuk Anda oleh kode Arduino. Tidak ada fungsi lain yang berperilaku seperti ini.Secara umum, suatu fungsi tidak akan pernah berjalan kecuali jika Anda secara eksplisit menyebutnya sendiri (misalnya dari dalam
setup()
atauloop()
), atau memerintahkan bagian lain dari program untuk memanggilnya. (Ada cara lain untuk menjalankan fungsi, tetapi itu biasanya melibatkan beberapa mengutak-atik yang sangat canggih yang sebaiknya dihindari.)Misalnya,
pinMode()
adalah fungsi sama seperti yang lain. Ini hanya berjalan ketika Anda benar-benar memasukkan sesuatu sepertipinMode(3, INPUT)
dalam kode Anda. Pada titik itu, ia berjalan sekali, selesai, dan kemudian fungsi panggilan melanjutkan dari tempat itu ditinggalkan (mereka tidak pernah berjalan secara paralel).Contoh kode yang Anda posting cukup menarik. Lihatlah garis-garis ini di
setup()
:Baris-baris ini memberi tahu
Wire
objek untuk memanggilreceiveData()
dansendData()
menanggapi peristiwa I2C. Ini dilakukan dengan melewati pointer fungsi yang disimpan dan digunakan olehWire
.Saya akan merekomendasikan mencari informasi tentang pointer fungsi C / C ++ online jika Anda ingin mempelajari lebih lanjut tentang ini. Anda mungkin juga tertarik untuk menjelajahi
attachInterrupt()
fungsi Arduino .sumber
receiveData()
dansendData()
tidak dijalankan kecuali jika dipanggil, lalu mengapa mereka dipanggil dalamvoid setup()
fungsi dan bukanvoid loop()
fungsi utama ? Tentunya fungsi-fungsi ini tidak akan pernah dipanggil kecuali kemungkinan langka bahwa ada acara i2c sementara pointer instruksi masih dalamvoid setup
fungsi? Bukankah lebih baik memanggil fungsi-fungsi ini dari dalamvoid loop
fungsi sehingga setiap kali ada acara i2c, fungsi tersebut dipanggil?void setup()
, mereka lulus sebagai parameteronReceive
danonRequest
, mereka callback sebagai negara komentar. Dalam ringkasan yang sangat singkat: ini memberitahu (kode dari) Wire library untuk memanggil fungsi-fungsi ini ketika hal-hal tertentu terjadi ( arduino.cc/en/Reference/WireOnReceive , arduino.cc/en/Reference/WireOnRequest ...)twi_init()
saat Anda meneleponWire.begin
. Ketika ada aktivitas I2C μC berhenti melakukan tugasnya saat ini (kecuali ... tidak ingat untuk saat ini :-) dan masuk dalam kode perpustakaan Wire, yang kemudian memanggil fungsi (sesuai, tergantung pada apa yang terjadi) fungsi Anda terdaftar sebagai panggilan balik (receiveData
misalnya). Sebuah callback adalah nama generik untuk fungsi-fungsi sepertireceiveData
atausendData
, mereka disebut oleh interrupt handler dalam Wire.Bukankah itu kasus yang
setup()
disebut sekali danloop()
disebut berulang kali? yaitu bahwa ada yang tak terlihatmain()
yang mungkin terlihat seperti ini:Maaf karena saya hanya melihat ke dalam Arduino dan hampir tidak memiliki pengalaman C / C ++; Saya mencoba menangani
loop()
situasi ini sendiri.sumber
init()
yang membuat timer berjalanmillis
,delay
dll. Begituinit()
juga untuk inisialisasi umum,setup()
untuk inisialisasi Anda , danloop
untuk, yah, pengulangan. Anda dapat menulis sendirimain
jika Anda ingin mengambil kendali penuh.;
tidak diperlukan setelah kedua dari belakang}
:-)Saya tidak bisa mengomentari tanggapan Dee. Kode aktual yang dieksekusi di loop utama ada di sini :
Dan ya,
setup()
dipanggil sekali danloop()
dipanggil berulang kali (bersama dengan beberapa hal serial).sumber
Ini berfungsi sebagai fungsi normal, itu harus disebut masuk akal. loop () / setup () dipanggil dari fungsi main () yang dikompilasi dari direktori Arduino dan ditautkan. acceptData / sendData dipanggil dari program Anda yang rootnya ada di fungsi loop / setup.
sumber