Programowanie Arduino Pro Mini zdalnie przez Bluetooth

W kolejnym wpisie chciałem się podzielić moją drogą do umożliwienia programowania Arduino Pro Mini (choć sposób będzie działał z każdą płytką) bez podłączania kabla USB do PC. Zamiast kabla postanowiłem użyć moduł Bluetooth XM-15B SPP. Pomysł powstał w czasie, gdy poznawałem możliwości tego modułu, które zresztą opisałem we wpisie tutaj: Arduino Uno oraz Bluetooth XM-15B.

Dla łatwiejszego zrozumienia problemu przypomnę jedynie, że wykorzystany moduł Bluetooth działa zgodnie z profilem SPP (Serial Port Profile), który jest niczym innym jak portem szeregowym UART poprzez połączenie Bluetooth. Czyli jest dokładnie tym samym co tradycyjny programator/konwerter USB->UART, jaki jest wbudowany w płytkę Arduino UNO. Natomiast płytka Arduino Pro Mini, jest w ogóle pozbawiona tego konwertera. Zatem jedyną możliwością programowania jej jest podłączenie poprzez dodatkowy konwerter USB/UART, np. FT232RL.

Wybrałem płytkę Arduino Pro Mini, gdyż to właśnie do niej docelowo zakupiłem moduł Bluetooth, aby zdalnie sterować mikrokontrolerem poprzez telefon. Ale sposób powinien działać z dowolną płytką, która wystawia połączenie szeregowe.

Zacznijmy od poprawnego podłączenia układu. Mój schemat wygląda następująco:

Podłączenie jest dość trywialne. Pin nadawania TXD z modułu Bluetooth musi zostać połączony z pinem odbiorczym RX Arduino. Tak samo pin odbiorczy RXD trafia do TX w Arduino. Zasilanie to sprawa oczywista, moduł czerpie je z Arduino, a Arduino zostało zasilone zewnętrznym źródłem 5V podanym na wejście RAW, aby było przepuszczone przez układ stabilizujący. Nadmienię jedynie, że Arduino Pro Mini wykorzystane w tym schemacie to wersja z 5V logiką. Choć pewnie wersja 3,3V będzie działać identycznie, bo moduł XM-15B pracuje w obu logikach bez problemu.

Z punktu widzenia hardware’u to wszystko, jesteśmy gotowi do programowania. Musimy jedynie sparować urządzenie z komputerem. W każdym systemie operacyjnym wykonuje się to troszkę inaczej, więc nie będę wdawał się tu w szczegóły. Należy sparować się z urządzeniem o nazwie:

A następnie w systemie Windows przejść do Device Managera, celem odnalezienia numeru portu COM jaki został nadany dla naszego Bluetooth.

Przypominam, że w systemie zostaną zarejestrowane dwa porty, z czego tylko jeden będzie ten właściwy. Który wybrać? To niestety musimy określić eksperymentalnie. W moim przypadku był to port: Standard Serial over Bluetooth link (COM11).

Wydaje się, że jesteśmy już gotowi do skompilowania i wgrania programu zdalnie na płytkę. W związku z tym otworzyłem Arduino IDE oraz załadowałem najprostszy Sketch z Blink diodą LED. Nie jest ważne co wgramy, a raczej czy wgramy. Przed skompilowaniem upewniam się, że w menu: Tools->Board wybrana jest płytka Arduino Pro Mini, oraz Tools->Processor ustawiony na Atmega328P (5V, 16 MHz). Wybieram port COM11 w Tools->Port i…

Zaraz, zaraz. Zanim wgramy nasz kod, musimy się jeszcze zastanowić nad sygnałem DTR, który resetuje naszą płytkę przed wgraniem programu. Jak to działa?

Aby było możliwe wgrywanie naszych projektów na płytkę Arduino, jest ona zapisana malutkim programem zwanym Bootloaderem. Program ten ma za zadanie zaraz po uruchomieniu mikrokontrolera sprawdzić czy przypadkiem nie jest podjęta próba wgrania nowego programu. W takim przypadku Bootloader odbiera od Arduino IDE skompilowany kod i wgrywa go do pamięci procesora. Po wgraniu przechodzi do wykonania nowo wgranego źródła i dalej już dzieje się to, co sam napisałeś w swoim programie. A zatem ważne jest, aby uświadomić sobie, że Booltloader po zresetowaniu/uruchomieniu przez krótką chwilę czeka na nowe źródła a następnie przechodzi do wykonania programu głównego. Normalnie programator RS232 UART wykorzystuje sygnał DTR do podania go na wejście RESET układu Atmega. Powoduje to zresetowanie i dalej wgranie programu. Dlatego, jak używamy wbudowanych konwerterów USB/UART (lub np. FT232RL) to nie musimy nic robić. Program po prostu się ładuje, bo resetem steruje oprogramowanie po stronie uploadera (komputera). Niestety w naszym przypadku moduł Bluetooth XM-15B nie wystawia tego sygnału. Albo inaczej – mnie nie udało się go uruchomić. Więc musimy poradzić dobie inaczej. W tej sytuacji musimy wykonać reset manualnie w trakcie wgrywania kodu do procesora. Wykorzystam do tego przycisk reset wbudowany w Pro Mini. Kiedy go musimy nacisnąć? Najlepiej zrobić to w taki sposób, że

  1. Wciskamy i trzymamy przycisk RESET na Arduino Pro Mini
  2. Uruchamiamy kompilację z wgrywaniem w Arduino IDE
  3. Puszczamy przycisk RESET w momencie, gdy Arduino IDE wyświetla komunikat: Uploading…

Tyle teorii. Sprawdźmy co się stanie w rzeczywistości. Wykonałem powyższą procedurę i – niestety wgranie zakończone niepowodzeniem. Program skompilował się poprawnie, ale w trakcie Uploading… wysypał się z poniższym komunikatem:

Sketch uses 15296 bytes (49%) of program storage space. Maximum is 30720 bytes.
Global variables use 1129 bytes (55%) of dynamic memory, leaving 919 bytes for local variables. Maximum is 2048 bytes.
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x55
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.


Co ważne to w trakcie ładowania programu, dioda na module Bluetooth przestała migać. A zatem Arduino otworzyło odpowiedni port COM. Ale i tak nie udało się wgrać programu. Komunikat nie mówi nam za wiele. Zatem postarajmy się zebrać więcej informacji. Aby to zrobić należy włączyć bardziej szczegółowe komunikaty w trakcie kompilowania. Można tego dokonać wchodząc do File->Preferences i zaznaczyć opcję Show verbose output during: według poniższego:

I ponownie przechodzimy do kompilacji, aby zobaczyć bardziej szczegółowe informacje. Z poniższego listingu wykasowałem tę cześć, która odpowiadała za informację o kompilacji – gdyż nie było w niej błędów, a pozostawiłem jedynie tę z momentu wgrywania binariów na płytkę:

Sketch uses 15296 bytes (49%) of program storage space. Maximum is 30720 bytes.
Global variables use 1129 bytes (55%) of dynamic memory, leaving 919 bytes for local variables. Maximum is 2048 bytes.

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM11
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x55
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x55

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

Z powyższych informacji od razu rzuciła mi się w oczy linia:

         Overriding Baud Rate          : 57600

Wynika z tego, że avrdude (program, który wgrywa binarki do procesora) otwiera port COM oczekując prędkości transmisji 57600. Okazuje się, że każda płytka posiada swoją własną konfigurację z jaką port UART nawiązuje komunikację z komputerem. Wszystko jest zapisane w Bootloaderze. A zatem skąd avrdude wie jaką prędkość wybrać? Jest to zapisane w pliku konfiguracyjnym Arduino IDE, który mieści się w ścieżce: C:\Program Files (x86)\Arduino\hardware\arduino\avr\boards.txt. W moim przypadku sekcja opisująca Arduino Pro Mini wygląda następująco:

##############################################################

pro.name=Arduino Pro or Pro Mini

pro.upload.tool=avrdude
pro.upload.protocol=arduino

pro.bootloader.tool=avrdude
pro.bootloader.unlock_bits=0x3F
pro.bootloader.lock_bits=0x0F

pro.build.board=AVR_PRO
pro.build.core=arduino
pro.build.variant=eightanaloginputs

## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328P
## --------------------------------------------------
pro.menu.cpu.16MHzatmega328=ATmega328P (5V, 16 MHz)

pro.menu.cpu.16MHzatmega328.upload.maximum_size=30720
pro.menu.cpu.16MHzatmega328.upload.maximum_data_size=2048
pro.menu.cpu.16MHzatmega328.upload.speed=57600

pro.menu.cpu.16MHzatmega328.bootloader.low_fuses=0xFF
pro.menu.cpu.16MHzatmega328.bootloader.high_fuses=0xDA
pro.menu.cpu.16MHzatmega328.bootloader.extended_fuses=0xFD
pro.menu.cpu.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex

pro.menu.cpu.16MHzatmega328.build.mcu=atmega328p
pro.menu.cpu.16MHzatmega328.build.f_cpu=16000000L

Widać tutaj zapisaną prędkość transmisji bootloadera w opcji pro.menu.cpu.16MHzatmega328.upload.speed.

A co z tego wynika? Pierwsze co przychodzi na myśl, to to, że moduł XM-15B domyślnie działa z prędkością 9600. Więc musimy zmienić jego konfigurację, na 57600. Jak tego dokonać możesz przeczytać w opisie związanym z konfiguracją modułu Bluetooth XM-15B poprzez komendy ATArduino Uno oraz Bluetooth . Aby sprawdzić prędkość wykonaj polecenie:

AT
OK

AT+UART?
+UART:9600,0,0
OK

Moduł zwrócił prędkość 9600. Zatem zmieńmy ją na taką, którą oczekuje Bootloader. Wykonaj poniższe polecenia:

AT
AT+UART=57600,0,0
AT+INIT
AT+RESET

Dla pewności sprawdź jeszcze raz, czy moduł raportuje nową prędkość i jeśli tak – to możemy wrócić do naszego zdalnego programowania poprzez Bluetooth.

Ponownie podłączam moduł Bluetooth i rozpoczynam wgrywanie kodu na mikrokontroler według opisanej powyżej procedury. Tym razem rezultat wygląda następująco:

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM11
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
         Hardware Version: 2
         Firmware Version: 1.16
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "C:\Users\piotr.jozwiak\AppData\Local\Temp\arduino_build_704769/efektownaChmurka.ino.hex"
avrdude: writing flash (15296 bytes):

Writing | ################################################## | 100% 13.34s

avrdude: 15296 bytes of flash written
avrdude: verifying flash memory against C:\Users\piotr.jozwiak\AppData\Local\Temp\arduino_build_704769/efektownaChmurka.ino.hex:
avrdude: load data flash data from input file C:\Users\piotr.jozwiak\AppData\Local\Temp\arduino_build_704769/efektownaChmurka.ino.hex:
avrdude: input file C:\Users\piotr.jozwiak\AppData\Local\Temp\arduino_build_704769/efektownaChmurka.ino.hex contains 15296 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 9.58s

avrdude: verifying ...
avrdude: 15296 bytes of flash verified

avrdude done.  Thank you.

A po chwili miga dioda wbudowana w płytkę Arduino – co oznacza powodzenie. Udało się wgrać kod bez kabla USB.

Jak widać z powyższego przypadku czasem trzeba głębiej pogrzebać, aby dojść do rozwiązania. Opisany sposób nie jest idealny ze względu na potrzebę wciskania przycisku RESET. Idealnie by było, gdyby robił to za nas moduł Bluetooth. Taka możliwość jest przy zastosowaniu modułu HC-05, chociaż nie jest ona łatwo osiągalna, bo wymaga dolutowania dodatkowego kabelka do układu – jak można to zobaczyć tutaj: https://www.instructables.com/id/Program-an-Arduino-Wireless-Over-Bluetooth/ .

Próbowałem się wzorować na powyższym przypadku z HC-05, jednak w układzie XM-15B nie znalazłem żadnego wyjścia, które mogło by służyć za sygnał DTR. Zatem na tę chwilę pozostaję z przymusem ręcznego wciskania Reset – co i tak jest dla mnie wygodniejsze niż podłączenie kabla USB.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.