Arduino'da pastadir () qanchalik tez ishlaydi

Salom, Arduino Nano ni foydalanib, Unity3D-dagi tajribamni qo'llab-quvvatlayman. Unity3D-da Update() kodi har soniya ichida har bir freymni ishga tushirganini bilaman, lekin men men elektron kod emas, balki loop() funktsiyasini Arduino .

Bu CPU tsikllari soniga (yoki Arduino uchun mikro protsessor chipiga) yoki nimaga bog'liq? Iltimos, izohlang. Mening o'yinimdagi ba'zi kechikishlar bilan qarayman. Men Arduino-dagi() funktsiyasi qanday ishlashini bilsangiz, ularni tuzatib beraman

There ain't a lot of information about loop() in arduino documentation

4
Qisqa javoblar "imkon qadar tez".
qo'shib qo'ydi muallif Jirka Hanika, manba
"soniya ichida har bir freymni boshqaradi". lekin Unity3D da har bir freymni iloji boricha tezroq ishlaydi, ular maqsadga muvofiq emas, balki bu freymda kechikish
qo'shib qo'ydi muallif Udo G, manba
qo'ying ramkada kechikish (tahrir qila olmayapsizmi?)
qo'shib qo'ydi muallif Udo G, manba

5 javoblar

Loop ishlashi kerak bo'lgan davrda ishlaydi.

CPUdagi ko'rsatmalar ketma-ketlikda ishlaydi. Qanday yo'l-yo'riqlar ko'proq ishlaydi?

Ichki loopga joylashtirilgan kodning uzunligi pastroq bo'ladi.

Har bir iteratsiya qancha davom etishi haqida bilishning ikki yo'li bor:

  1. Foydalanuvchining profili: Har bir iteratsiya davrida faol ogohlantirilsa-da, vaqt belgilari olingan vaqt miqdoriga ta'sir qiladi.
  2. Ko'chadan hisoblash. Resursni yig'ishga qo'shing va barcha yo'riqnomalar (funktsiyalarga qo'ng'iroq qilish) uchun zarur bo'lgan soat sikllarining sonini yig'ing.

Shuni ham ta'kidlash kerakki, ko'plab tashqi omillar (masalan, ketma-ket aloqa tezligi va h.k.

8
qo'shib qo'ydi
@FilipFranik: 1. millis() qiymatini yangilaydigan intervalli har 1024 mil, yoki 16 MGts da 16384 protsessor tsikli ishlaydi. 2. O'chirishlar dasturiy ta'minotning PWM chiqishi sifatiga ta'sir qiladi (masalan, Servo kutubxonasi). Ular apparat ishlab chiqarilgan PWM-ga (masalan, analogWrite() ) ta'sir qilmaydi).
qo'shib qo'ydi muallif Sprogz, manba
Misol uchun, har bir 16000 soat periyodunda milliis qiymatini yangilashni unutmang (16Mhz oscilator uchun). Ular muntazam ravishda dasturni to'xtatadilar va arduinolarni yaxshi PWM manbai bo'lishiga to'sqinlik qiladilar. (Ha, siz ularni o'chirib qo'yishingiz mumkin)
qo'shib qo'ydi muallif Robert Sibek, manba

loopning oxiri() va uning keyingi ishlashi o'rtasidagi ko'rsatmalar ret, jmp va chaqiruv.

Asosiy funktsiyani samarali deb hisoblashingiz mumkin:

void main(){

    init();
    while(1) loop();

}

Aslida millis() va shunga o'xshash ishlarni bajarish uchun init() dan oldin ba'zi bir sozlamalar mavjud.

3
qo'shib qo'ydi
@Majenko bu uzilishlar bilan emasmi?
qo'shib qo'ydi muallif CTKeane, manba
Arduinolarning standart ish vaqtiga qaraganda ko'proq men dissapointed bo'laman ...
qo'shib qo'ydi muallif CTKeane, manba
@ next-hack: Arduino IDE ning yangi versiyalari ulanish vaqtini optimallashtirish imkonini beruvchi va loop() ning inline qilinishiga olib keladigan -flto parametri bilan gcc ni chaqiradi. Eski versiyalarda ushbu parametrdan foydalanilmaydi, shuning uchun loop() qayta-qayta main() tomonidan chaqiriladigan haqiqiy funksiyaga kiritiladi.
qo'shib qo'ydi muallif Sprogz, manba
Bundan tashqari, loopdan keyin ketma-ket voqelik kodi ham mavjud.
qo'shib qo'ydi muallif Majenko, manba
Yo'q bu emas. Bu faqat pastki oxirida chaqiriladi. Bu juda xomashyo va ko'p odamlar aslida qanchalik beg'ubor ekanligini tushunishmaydi.
qo'shib qo'ydi muallif Majenko, manba
Menimcha loop() derleyici tomonidan optimallashtirilgan, shuning uchun hech qanday haqiqiy jmp yoki raddiya paydo bo'lmaydi. Kod quyidagi ma'noni anglatadi: while (1) yourLoopCode; funktsiya chaqirmasdan turib. Lekin GCC bilan dahshatli soxta narsalarni ko'rdim ...
qo'shib qo'ydi muallif next-hack, manba

Bu loopda nima bog'liq. Bir necha soat burchagidan cheksiz osgancha.

1
qo'shib qo'ydi

Main.cpp fayliga (mening o'rnatishimdagi avr kodi uchun) faylga qarang:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp

Arduino ning ssilkasi() ning cheksiz pastadirida aylana() ga o'tishini ko'rsatadi:

int main(void)
{
    init();
    initVariant();
 #if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

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

    return 0;
}

HardwareSerial.cpp tekshiruvi serialEventRun() serialEvent() ni faqat eskizingizda aniqlagan holda ko'rsatadi.

Buning ma'nosi snooze() kodini yozmasdan va muntazam ravishda ishlashni kutmaguningizcha, o'zingizning cheksiz pastadiringizni loop() ichida mukammal tarzda yozishingiz mumkin.

Bu savolni chaqiradi: agar serialEvent() loop() bilan ketma-ket chaqirilsa, loop() hech qachon qaytarsa ​​serialEvent() deb ataladigan bo'ladimi? Boshqacha aytganda, loop() funktsiyasi qaytarilganda, serialEvent() interrupt-driven va chaqiriladi? Tez test - quyida ko'rsatilgan - bu emas interrupt-driven ekanligini ko'rsatadi, shuning uchun avvalgi xat to'g'ri.

/*
  Serial Event Checker

  A sketch to see if serialEvent() is interrupt-driven.
  Will serialEvent() be called if loop() never returns?

  This code is based on Tom Igoe's SerialEvent example.

  On (at least) Arduino Uno we find that serialEvent() simply runs
  sequentially with loop().  When loop() never returns serialEvent()
  is never called.

  NOTE: The serialEvent() feature is not available on the Leonardo, Micro, or
  other ATmega32U4 based boards.

  R Symonds-Tayler 2018-02-01

  This example code is in the public domain.

*/

String inputString = "";        //a String to hold incoming data

void setup() {
 //initialize serial:
  Serial.begin(115200);
 //reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

// comment out this definition to allow loop() to return
#define INFINITE_LOOP

void loop() { 
#ifdef INFINITE_LOOP
    while(1);
#endif

}

/*
  SerialEvent occurs whenever a new data comes in the hardware serial RX. This
  routine is run between each time loop() runs, so using delay inside loop can
  delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
  while (Serial.available()) {
   //get the new byte:
    char inChar = (char)Serial.read();
   //add it to the inputString:
    inputString += inChar;
   //if the incoming character is a newline, set a flag so the main loop can
   //do something about it:
    if (inChar == '\n') {
      Serial.print("Got: '");
      Serial.print(inputString);
      Serial.println("'");
     //clear the string:
      inputString = "";
    }
  }
}

Buning ma'nosi, serialEvent() kodi o'zingizning asosiy pastadiringizga() quyidagicha kirishi mumkin:

if(serial.available()){
  //your code here...
}

blok.

1
qo'shib qo'ydi

arduino funktsiyalarini qidirib ko'ring micros () va delayMicroseconds () 16000 mikrosaniyadan ko'proq vaqtni kutish uchun loopingiz kerak bo'lsa, u holda milisaniyani bajaradigan boshqa kechikish() funktsiyasini ko'rib chiqing.

Aytgancha, ichki soat juda oz va xona haroratiga qarab o'zgaradi, shuning uchun siz boshqa qurilmangizga qo'l siqimisiz sinxronizatsiya qilinishiga tayanmang.

0
qo'shib qo'ydi
micros() va delayMicroseconds() 32 bitli tamsayılardan ( unsigned long ) foydalaning va 2 darajagacha bo'lgan vaqtni boshqarishingiz mumkin yoki 1,19 soat .
qo'shib qo'ydi muallif Sprogz, manba