Когда Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ скСтч для Arduino Π² ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ срСдС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ (Arduino IDE), Π²Ρ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²ΠΈΠ΄ΠΈΡ‚Π΅ явного объявлСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main() β€” Ρ‚ΠΎΠΉ самой Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ…ΠΎΠ΄Π°, с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ начинаСтся Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ любой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π° C/C++. Π­Ρ‚ΠΎ Π½Π΅ ΡΠ»ΡƒΡ‡Π°ΠΉΠ½ΠΎΡΡ‚ΡŒ, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ скрытой инфраструктуры, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ создатСли ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ спрятали ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ для упрощСния взаимодСйствия с ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°ΠΌΠΈ. Однако ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ устроСна main() Π² Arduino CC (ядро Arduino, написанноС Π½Π° C++), ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π½ΠΎΠ²Ρ‹Π΅ возмоТности для ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ΄Π°, ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ слоТных ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ Π΄Π°ΠΆΠ΅ портирования скСтчСй Π½Π° Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹.

Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Ρ€Π°Π·Π±Π΅Ρ€Ρ‘ΠΌ:

  • πŸ” Π“Π΄Π΅ скрыта функция main() Π² ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌ ПО Arduino ΠΈ ΠΊΠ°ΠΊ ΠΎΠ½Π° связана с вашими скСтчами.
  • πŸ› οΈ Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρƒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° Π΄ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° setup() ΠΈ loop().
  • ⚑ Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ошибки, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ ΠΈΠ·-Π·Π° нСпонимания Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ Arduino CC.
  • πŸ“‘ Как ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ main() для ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с FreeRTOS ΠΈΠ»ΠΈ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΌΠΈ bootloaders).

Если Π²Ρ‹ ΠΊΠΎΠ³Π΄Π°-Π»ΠΈΠ±ΠΎ задавались вопросом, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ваш скСтч Π²Π΅Π΄Ρ‘Ρ‚ сСбя Π½Π΅ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ оТидалось, ΠΈΠ»ΠΈ ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΡƒΡŽΡ‚ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ β€” ΠΎΡ‚Π²Π΅Ρ‚ часто кроСтся ΠΈΠΌΠ΅Π½Π½ΠΎ Π² Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Arduino IDE ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈ связываСт ΠΊΠΎΠ΄ Π·Π° кулисами. Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΊΠΎΠΏΠ°Ρ‚ΡŒ Π³Π»ΡƒΠ±ΠΆΠ΅.

1. Π“Π΄Π΅ находится функция main() Π² Arduino IDE?

ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ любой скСтч Π² Arduino IDE β€” Π²Ρ‹ Π½Π΅ Π½Π°ΠΉΠ΄Ρ‘Ρ‚Π΅ Ρ‚Π°ΠΌ main(). Но это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ Π΅Ρ‘ Π½Π΅Ρ‚. На самом Π΄Π΅Π»Π΅, ΠΎΠ½Π° автоматичСски гСнСрируСтся компилятором Π½Π° этапС сборки ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ этой "ΠΌΠ°Π³ΠΈΠΈ" β€” Ρ„Π°ΠΉΠ» main.cpp, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π»Π΅ΠΆΠΈΡ‚ Π² ядрС Arduino (Arduino Core) ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΊ Π²Π°ΡˆΠ΅ΠΌΡƒ ΠΊΠΎΠ΄Ρƒ нСявно.

Для ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ AVR (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Arduino Uno ΠΈΠ»ΠΈ Nano) этот Ρ„Π°ΠΉΠ» находится ΠΏΠΎ ΠΏΡƒΡ‚ΠΈ:

hardware/arduino/avr/cores/arduino/main.cpp

А для ARM-ΠΏΠ»Π°Ρ‚ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Arduino Due ΠΈΠ»ΠΈ Teensy) β€” Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ°ΠΏΠΊΠ°Ρ… ядра. Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ PlatformIO, ΠΏΡƒΡ‚ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ, Π½ΠΎ ΡΡƒΡ‚ΡŒ остаётся Ρ‚ΠΎΠΉ ΠΆΠ΅: main() ΡƒΠΆΠ΅ написана Π·Π° вас.

Π’ΠΎΡ‚ упрощённая вСрсия Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ выглядит стандартная main() Π² Arduino CC:

int main(void) {

init(); // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠΉ части (Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹, прСрывания, UART ΠΈ Ρ‚.Π΄.)

initVariant(); // Настройка спСцифичных для ΠΏΠ»Π°Ρ‚Ρ‹ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²

setup(); // Π’Ρ‹Π·ΠΎΠ² вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ setup()

while (1) {

loop(); // БСсконСчный Π²Ρ‹Π·ΠΎΠ² вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ loop()

if (serialEventRun) serialEventRun(); // ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° событий Serial (Ссли Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΎ)

}

return 0; // Π­Ρ‚Π° строка Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ выполняСтся

}

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: Если Π²Ρ‹ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ main.cpp Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для добавлСния кастомного bootloader), ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ваша вСрсия совмСстима с ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΠΎΠΉ. НСсоотвСтствиС ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ зависанию ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° Π½Π° этапС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π°ΠΌ с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌΠΈ.

2. Π§Ρ‚ΠΎ происходит Π΄ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° setup()?

Ѐункция init(), которая вызываСтся ΠΏΠ΅Ρ€Π²ΠΎΠΉ Π² main(), ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΡƒΡŽ настройку ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°. Π’ Π½Π΅Ρ‘ Π²Ρ…ΠΎΠ΄ΠΈΡ‚:

  • πŸ•’ Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Ρ‚Π°ΠΊΡ‚ΠΎΠ²ΠΎΠ³ΠΎ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€Π° (настройка частоты CPU).
  • πŸ”Œ ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ ΠΏΠΎΡ€Ρ‚ΠΎΠ² Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, сброс состояния GPIO).
  • ⏱️ Настройка Ρ‚Π°ΠΉΠΌΠ΅Ρ€ΠΎΠ² для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π²Ρ€ΠΎΠ΄Π΅ millis() ΠΈ delay().
  • πŸ“‘ Активация UART (Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Serial).

НапримСр, для ATmega328P (Ρ‡ΠΈΠΏ Π½Π° Arduino Uno) init() выполняСт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ дСйствия:

Π”Π΅ΠΉΡΡ‚Π²ΠΈΠ΅ΠžΠΏΠΈΡΠ°Π½ΠΈΠ΅Π Π΅Π³ΠΈΡΡ‚Ρ€Ρ‹/Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ
Настройка Ρ‚Π°ΠΊΡ‚ΠΎΠ²ΠΎΠΉ частотыУстанавливаСт CPU Π½Π° 16 ΠœΠ“Ρ† (Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ внСшний ΠΊΠ²Π°Ρ€Ρ†)CLKPR, OSCCAL
Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ стСкаУказываСт Π²Π΅Ρ€ΡˆΠΈΠ½Ρƒ стСка Π² RAMSPH, SPL
Бброс GPIOВсС ΠΏΠΎΡ€Ρ‚Ρ‹ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π² состояниС INPUT Π±Π΅Π· подтяТкиDDRx, PORTx
Настройка Watchdog TimerΠžΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ стороТСвой Ρ‚Π°ΠΉΠΌΠ΅Ρ€ (Ссли Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½)MCUSR, WDTCR

Если Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ это ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для экономии энСргии Π² Π±Π°Ρ‚Π°Ρ€Π΅ΠΉΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…), ΠΌΠΎΠΆΠ½ΠΎ:

  1. Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ кастомный main.cpp ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ‡Π΅Ρ€Π΅Π· PlatformIO.
  2. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ weak-Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ Π² C++ для пСрСопрСдСлСния стандартных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.
  3. ΠžΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Ρ‡Π΅Ρ€Π΅Π· Ρ„Π»Π°Π³ΠΈ компилятора (Π½Π΅ рСкомСндуСтся для Π½ΠΎΠ²ΠΈΡ‡ΠΊΠΎΠ²).
πŸ“Š Как Π²Ρ‹ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚Π΅ с Arduino?
  • ΠŸΠΈΡˆΡƒ скСтчи Π² Arduino IDE
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ PlatformIO
  • Π Π°Π±ΠΎΡ‚Π°ΡŽ с AVR Studio + GCC
  • Π‘ΠΎΠ±ΠΈΡ€Π°ΡŽ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΡƒ Ρ‡Π΅Ρ€Π΅Π· Makefile
  • Π”Ρ€ΡƒΠ³ΠΎΠ΅

3. Как loop() взаимодСйствуСт с main()?

Ѐункция loop() β€” это Π½Π΅ просто бСсконСчный Ρ†ΠΈΠΊΠ» Π² вашСм скСтчС. Она ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π° Π² main() Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ Π΅Ρ‘ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΎ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²Ρ‹ Π΄Π°ΠΆΠ΅ Π½Π΅ ΠΏΠΎΠ΄ΠΎΠ·Ρ€Π΅Π²Π°Π΅Ρ‚Π΅. НапримСр:

  • πŸ”„ ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΉ (Ссли ΠΎΠ½ΠΈ настроСны).
  • πŸ“₯ ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π±ΡƒΡ„Π΅Ρ€Π° Serial (Ссли ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ serialEventRun()).
  • ⚑ Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ„ΠΎΠ½ΠΎΠ²Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, WiFi ΠΈΠ»ΠΈ BLE).

Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ Π² loop() (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Π΅Ρ€Π΅Π· delay()) ΠΌΠΎΠ³ΡƒΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ваш ΠΊΠΎΠ΄, Π½ΠΎ ΠΈ систСмныС процСссы. ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π° β€” ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ millis() для Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ:

unsigned long previousMillis = 0;

const long interval = 1000; // Π˜Π½Ρ‚Π΅Ρ€Π²Π°Π» Π² 1 сСкунду

void loop() {

unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval) {

previousMillis = currentMillis;

// Π’Π°Ρˆ ΠΊΠΎΠ΄ здСсь

}

// ΠžΡΡ‚Π°Π»ΡŒΠ½ΠΎΠΉ ΠΊΠΎΠ΄ выполняСтся Π±Π΅Π· Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ

}

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: Если ваш скСтч зависаСт Π±Π΅Π· Π²ΠΈΠ΄ΠΈΠΌΡ‹Ρ… ΠΏΡ€ΠΈΡ‡ΠΈΠ½, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ Π»ΠΈ loop() Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ систСмных Π·Π°Π΄Π°Ρ‡. НапримСр, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° SoftwareSerial Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ рСгулярного опроса Π±ΡƒΡ„Π΅Ρ€Π°, ΠΈ Π΄ΠΎΠ»Π³ΠΈΠ΅ delay() ΠΌΠΎΠ³ΡƒΡ‚ Π½Π°Ρ€ΡƒΡˆΠΈΡ‚ΡŒ Π΅Ρ‘ Ρ€Π°Π±ΠΎΡ‚Ρƒ.
πŸ’‘

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π½Π° loop(), выноситС Ρ€Π΅Π΄ΠΊΠΎ выполняСмыС Π·Π°Π΄Π°Ρ‡ΠΈ Π² прСрывания ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ RTOS-ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Arduino-FreeRTOS-Library.

4. ΠœΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ main() для ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡

Иногда стандартной main() нСдостаточно. НапримСр, Ссли Π²Ρ‹:

  • πŸ€– Π Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚Π΅ ΠΌΠ½ΠΎΠ³ΠΎΠ·Π°Π΄Π°Ρ‡Π½ΡƒΡŽ систСму с FreeRTOS.
  • πŸ”Œ ΠŸΠΈΡˆΠ΅Ρ‚Π΅ кастомный bootloader.
  • ⚑ ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΊΠΎΠ΄ для критичСски Π²Π°ΠΆΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, управлСния Π΄Ρ€ΠΎΠ½ΠΎΠΌ).

Π’ Ρ‚Π°ΠΊΠΈΡ… случаях ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ main(). Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ для Arduino Uno с Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΈ FreeRTOS:

#include 

void setup() {

// Π’Π°Ρˆ ΠΊΠΎΠ΄ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ

}

void loop() {

// Π­Ρ‚Π° функция станСт Π·Π°Π΄Π°Ρ‡Π΅ΠΉ FreeRTOS

}

int main(void) {

init();

initVariant();

setup();

// Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Π·Π°Π΄Π°Ρ‡Ρƒ для loop()

xTaskCreate(

loopTask, // Ѐункция-Π·Π°Π΄Π°Ρ‡Π°

"Loop", // Имя Π·Π°Π΄Π°Ρ‡ΠΈ

128, // Π Π°Π·ΠΌΠ΅Ρ€ стСка

NULL, // ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹

1, // ΠŸΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚

NULL // Π₯Π΅Π½Π΄Π» Π·Π°Π΄Π°Ρ‡ΠΈ

);

// ЗапускаСм ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Ρ‰ΠΈΠΊ FreeRTOS

vTaskStartScheduler();

return 0;

}

// ΠžΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° для loop()

void loopTask(void *pvParameters) {

while (1) {

loop();

vTaskDelay(1); // Π”Π°Ρ‘ΠΌ врСмя Π΄Ρ€ΡƒΠ³ΠΈΠΌ Π·Π°Π΄Π°Ρ‡Π°ΠΌ

}

}

Однако Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚:

  1. Π“Π»ΡƒΠ±ΠΎΠΊΠΎΠ³ΠΎ понимания Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°.
  2. Π£Ρ‡Π΅Ρ‚Π° ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ² с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ main().
  3. ВСстирования Π½Π° Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹Ρ… прСрываниях (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Timer1 ΠΌΠΎΠΆΠ΅Ρ‚ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒ с FreeRTOS).

β˜‘οΈ ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠ° ΠΊ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ main()

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ: 0 / 5

5. Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ошибки ΠΈ ΠΊΠ°ΠΊ ΠΈΡ… ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ

НСпониманиС Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ структуры main() Π² Arduino CC ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ряду распространённых ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ:

ΠžΡˆΠΈΠ±ΠΊΠ°ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°Π Π΅ΡˆΠ΅Π½ΠΈΠ΅
Π‘ΠΊΠ΅Ρ‚Ρ‡ Π½Π΅ запускаСтся послС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈΠšΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ с кастомной main() ΠΈΠ»ΠΈ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Π°Ρ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ init() ΠΈ initVariant() Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ
Serial Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ послС ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ main()НС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ UART ΠΈΠ»ΠΈ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½ Π²Π΅ΠΊΡ‚ΠΎΡ€ прСрыванияВызовитС serialEventRun() Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ UCSR0B
Зависания ΠΏΡ€ΠΈ использовании delay()loop() Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅Ρ‚ систСмныС Π·Π°Π΄Π°Ρ‡ΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, WiFi)Π—Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ delay() Π½Π° millis() ΠΈΠ»ΠΈ RTOS-Π·Π°Π΄Π°Ρ‡ΠΈ
Ошибки Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠΈ ΠΏΡ€ΠΈ компиляцииДублированиС main() (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ сторонних Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ)Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ #ifndef ΠΈΠ»ΠΈ слабыС символы (__attribute__((weak)))

Одна ΠΈΠ· самых ΠΊΠΎΠ²Π°Ρ€Π½Ρ‹Ρ… ошибок β€” нСявноС ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ систСмных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. НапримСр, Ссли Π²Ρ‹ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚Π΅ Π² скСтчС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ с ΠΈΠΌΠ΅Π½Π΅ΠΌ init(), ΠΎΠ½Π° Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ init() ΠΈΠ· ядра Arduino, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ нСпрСдсказуСмому повСдСнию ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°. ВсСгда провСряйтС ΠΈΠΌΠ΅Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π½Π° ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Ρ‹!

Π§Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚, Ссли ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ² setup() ΠΈΠ· main()?

Π‘Π΅Π· Π²Ρ‹Π·ΠΎΠ²Π° setup() Π½Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ пСрифСрия (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Serial.begin(9600) Π½Π΅ выполнится). ΠœΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ запустится, Π½ΠΎ ваш ΠΊΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΠ»ΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ стартуСт.

6. ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ ΠΊΠΎΠ΄Π° с ΡƒΡ‡Ρ‘Ρ‚ΠΎΠΌ структуры main()

Π—Π½Π°Π½ΠΈΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ устроСна main(), позволяСт ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ скСтчи Π½Π° Π½ΠΈΠ·ΠΊΠΎΠΌ ΡƒΡ€ΠΎΠ²Π½Π΅. Π’ΠΎΡ‚ нСсколько практичСских совСтов:

  • ⚑ ΠŸΠ΅Ρ€Π΅Π½ΠΎΡΠΈΡ‚Π΅ Ρ€Π΅Π΄ΠΊΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΊΠΎΠ΄ Π² setup():
  • Если ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½ΡƒΠΆΠ½Ρ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠ°Π»ΠΈΠ±Ρ€ΠΎΠ²ΠΊΠ° Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°), выполняйтС ΠΈΡ… Π² setup(), Π° Π½Π΅ Π² loop().

  • πŸ”„ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ прСрывания для ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡:
  • Если Π·Π°Π΄Π°Ρ‡Π° Π΄ΠΎΠ»ΠΆΠ½Π° Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ строго ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ШИМ-сигнал для сСрвопривода), вынСситС Π΅Ρ‘ Π² ISR (Interrupt Service Routine).

  • πŸ—‘οΈ ΠžΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΠΉΡ‚Π΅ RAM послС setup():
  • ΠžΠ±ΡŠΡΠ²Π»ΡΠΉΡ‚Π΅ большиС массивы ΠΊΠ°ΠΊ static ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ PROGMEM для хранСния констант Π²ΠΎ Flash.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с NeoPixel (Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Adafruit_NeoPixel):

#include 

#define LED_PIN 6

#define LED_COUNT 60

// ΠŸΠ΅Ρ€Π΅Π½ΠΎΡΠΈΠΌ Π² PROGMEM, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ RAM

const uint32_t colors[] PROGMEM = {0xFF0000, 0x00FF00, 0x0000FF};

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {

strip.begin();

strip.show(); // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·

}

void loop() {

static uint8_t colorIndex = 0;

for (int i = 0; i < LED_COUNT; i++) {

// Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· PROGMEM

strip.setPixelColor(i, pgm_read_dword(&colors[colorIndex % 3]));

}

strip.show();

delay(500);

colorIndex++;

}

⚠️ Π’Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ динамичСскоС Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, malloc()) Π² loop(), ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ освобоТдаСтС Π΅Ρ‘ Ρ‡Π΅Ρ€Π΅Π· free(). Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС ΡƒΡ‚Π΅Ρ‡ΠΊΠ° памяти ΠΏΡ€ΠΈΠ²Π΅Π΄Ρ‘Ρ‚ ΠΊ ΠΊΡ€Π°Ρ…Ρƒ ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° Ρ‡Π΅Ρ€Π΅Π· нСсколько часов Ρ€Π°Π±ΠΎΡ‚Ρ‹.
πŸ’‘

Ѐункция main() Π² Arduino β€” это Π½Π΅ просто ΠΎΠ±Ρ‘Ρ€Ρ‚ΠΊΠ° для setup() ΠΈ loop(). Она управляСт ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠΉ части, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΉ ΠΈ Ρ„ΠΎΠ½ΠΎΠ²Ρ‹ΠΌΠΈ Π·Π°Π΄Π°Ρ‡Π°ΠΌΠΈ. ПониманиС Π΅Ρ‘ структуры позволяСт ΠΏΠΈΡΠ°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ эффСктивный ΠΈ Π½Π°Π΄Ρ‘ΠΆΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄.

7. ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Ρ‹: обходимся Π±Π΅Π· Arduino IDE

Если Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Π½Π°Π΄ main(), рассмотритС Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Ρ‹ Arduino IDE:

  • πŸ› οΈ PlatformIO:
  • ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ Π³ΠΈΠ±ΠΊΠΎ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ процСсс сборки, ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ кастомныС main.cpp ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚Ρ‹Π΅ ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, GDB).

  • πŸ”§ AVR-GCC + Makefile:
  • ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒ Π½Π°Π΄ компиляциСй, Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Ρ€ΡƒΡ‡Π½ΠΎΠΉ настройки Π»ΠΈΠ½ΠΊΠΎΠ²Ρ‰ΠΈΠΊΠ° ΠΈ Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠ°.

  • πŸ€– Arduino-CLI:
  • ΠžΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ инструмСнт ΠΎΡ‚ Arduino для сборки скСтчСй ΠΈΠ· ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ кастомных ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Makefile для компиляции скСтча Π±Π΅Π· Arduino IDE:

MCU = atmega328p

F_CPU = 16000000UL

CC = avr-gcc

OBJCOPY = avr-objcopy

AVRDUDE = avrdude

SRC = main.c

OBJ = $(SRC:.c=.o)

TARGET = firmware.hex

all: $(TARGET)

%.o: %.c

$(CC) -mmcu=$(MCU) -DF_CPU=$(F_CPU) -Os -Wall -c -o $@ $<

$(TARGET): $(OBJ)

$(CC) -mmcu=$(MCU) -Os -Wl,--gc-sections -o firmware.elf $(OBJ)

$(OBJCOPY) -O ihex -R .eeprom firmware.elf $(TARGET)

upload:

$(AVRDUDE) -c arduino -p $(MCU) -P /dev/ttyUSB0 -b 57600 -U flash:w:$(TARGET)

clean:

rm -f $(OBJ) firmware.elf $(TARGET)

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π΄Π°Ρ‘Ρ‚:

  • βœ… МСньший Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΡˆΠΈΠ²ΠΊΠΈ (Π½Π΅Ρ‚ Π»ΠΈΡˆΠ½ΠΈΡ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ ΠΈΠ· Arduino Core).
  • βœ… Π‘Ρ‹ΡΡ‚Ρ€ΡƒΡŽ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡŽ (Π½Π΅Ρ‚ Π½Π°ΠΊΠ»Π°Π΄Π½Ρ‹Ρ… расходов Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ ΠΊΠΎΠ΄Π° Π² IDE).
  • βœ… Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ использования ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠ° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Atmel ICE).

FAQ: ЧастыС вопросы ΠΎ main() Π² Arduino

МоТно Π»ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ setup() ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΈΠ· loop()?

ВСхничСски Π΄Π°, Π½ΠΎ это плохая ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°. Ѐункция setup() ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΈ Π΅Ρ‘ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ:

  • πŸ”Œ ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€ΠΈΡ„Π΅Ρ€ΠΈΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Serial), Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ сбои.
  • πŸ—‘οΈ Π£Ρ‚Π΅Ρ‡ΠΊΠ°ΠΌ памяти, Ссли Π² setup() Π²Ρ‹Π΄Π΅Π»ΡΡŽΡ‚ΡΡ рСсурсы Π±Π΅Π· освобоТдСния.
  • ⚑ НСпрСдсказуСмому повСдСнию Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π½Π° ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½Ρ‹ΠΉ Π²Ρ‹Π·ΠΎΠ².

Если Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ состояниС, Π»ΡƒΡ‡ΡˆΠ΅ вынСситС ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΠ΅ΠΌΡƒΡŽ Π»ΠΎΠ³ΠΈΠΊΡƒ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°ΠΉΡ‚Π΅ Π΅Ρ‘ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ нСобходимости.

ΠŸΠΎΡ‡Π΅ΠΌΡƒ ΠΌΠΎΠΉ ΠΊΠΎΠ΄ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² Arduino IDE, Π½ΠΎ Π½Π΅ компилируСтся Π² AVR Studio?

Π‘ΠΊΠΎΡ€Π΅Π΅ всСго, Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Arduino-спСцифичныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, digitalWrite() ΠΈΠ»ΠΈ millis()), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ Π² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ AVR-GCC. Π§Ρ‚ΠΎΠ±Ρ‹ пСрСнСсти ΠΊΠΎΠ΄:

  1. ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΈΠ· Arduino Core (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, #include "Arduino.h").
  2. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ Π½Π΅Π΄ΠΎΡΡ‚Π°ΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, millis() Ρ‡Π΅Ρ€Π΅Π· Timer1).
  3. НастройтС Π»ΠΈΠ½ΠΊΠΎΠ²Ρ‰ΠΈΠΊ для ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Arduino-Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ.

Или ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ PlatformIO, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ автоматичСски Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ Ρ‚Π°ΠΊΠΈΠ΅ зависимости.

Как ΠΎΡ‚Π»Π°Π΄ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄, Ссли ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ main()?

ΠžΡ‚Π»Π°Π΄ΠΊΠ° кастомной main() слоТнСС, Ρ‡Π΅ΠΌ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ скСтча. Π’ΠΎΡ‚ Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ:

  • πŸ› Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Serial.debug: Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½Ρ‹Π΅ сообщСния Π² ΠΊΠ»ΡŽΡ‡Π΅Π²Ρ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, послС init()).
  • πŸ” ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΉ: Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½Π΅ пСрСзаписали ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Π΅ ISR (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, TIMER0_OVF_vect, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для millis()).
  • πŸ“‘ ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ логичСский Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€: ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ сигналы Π½Π° Π½ΠΎΠΆΠΊΠ°Ρ… ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, SCK ΠΈΠ»ΠΈ TX).
  • πŸ–₯️ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ GDB + AVR Dragon: Для пошаговой ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ассСмблСра.

Если ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ Π½Π΅ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ послС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΡˆΠΈΡ‚ΡŒ bootloader Π·Π°Π½ΠΎΠ²ΠΎ Ρ‡Π΅Ρ€Π΅Π· AVRDUDE:

avrdude -c usbtiny -p atmega328p -U flash:w:optiboot_atmega328.hex
МоТно Π»ΠΈ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Arduino Core своСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ?

Π”Π°, Π½ΠΎ это Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π³Π»ΡƒΠ±ΠΎΠΊΠΈΡ… Π·Π½Π°Π½ΠΈΠΉ AVR/ARM-Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹. Π’Π°ΠΌ придётся:

  1. ΠΠ°ΠΏΠΈΡΠ°Ρ‚ΡŒ собствСнныС Π²Π΅ΠΊΡ‚ΠΎΡ€Π° ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΉ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для USART ΠΈΠ»ΠΈ Timer).
  2. Π Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Ρ€ΠΎΠ΄Π΅ digitalWrite() Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΡΠΌΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ с рСгистрами (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, PORTB |= (1 << PB5)).
  3. ΠΠ°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Π»ΠΈΠ½ΠΊΠΎΠ²Ρ‰ΠΈΠΊ для ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ размСщСния ΠΊΠΎΠ΄Π° Π² памяти.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ минимальной main() для ATmega328P Π±Π΅Π· Arduino Core:

#include 

#include

int main(void) {

DDRB |= (1 << PB5); // Настройка 13 ΠΏΠΈΠ½Π° (LED) Π½Π° Π²Ρ‹Π²ΠΎΠ΄

while (1) {

PORTB ^= (1 << PB5); // ΠŸΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ LED

_delay_ms(500);

}

return 0;

}

Π’Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ Π΄Π°Ρ‘Ρ‚ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Π½ΠΎ Π»ΠΈΡˆΠ°Π΅Ρ‚ вас удобств Arduino-экосистСмы (Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ, кроссплатформСнности ΠΈ Ρ‚.Π΄.).

Как ΡƒΠ·Π½Π°Ρ‚ΡŒ, какая вСрсия Arduino Core ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² ΠΌΠΎΡ‘ΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅?

ВСрсия ядра ΡƒΠΊΠ°Π·Π°Π½Π° Π² Ρ„Π°ΠΉΠ»Π΅:

hardware/arduino/avr/platform.txt

Π˜Ρ‰ΠΈΡ‚Π΅ строки Π²Ρ€ΠΎΠ΄Π΅:

version=1.8.5

runtime.tools.avr-gcc.version=7.3.0-atmel3.6.1-arduino7

Π’Π°ΠΊΠΆΠ΅ Π²Π΅Ρ€ΡΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ Π² Arduino IDE:

  1. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Π€Π°ΠΉΠ» β†’ Настройки.
  2. Π’ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ ΠΎΠΏΡ†ΠΈΡŽ ΠŸΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹ΠΉ Π²Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΈ компиляции.
  3. Π‘ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ скСтч ΠΈ Π½Π°ΠΉΠ΄ΠΈΡ‚Π΅ Π² Π»ΠΎΠ³Π΅ строку с вСрсиСй Arduino Core.

Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ PlatformIO, вСрсия ядра ΡƒΠΊΠ°Π·Π°Π½Π° Π² platformio.ini Π² ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ platform.