Ini adalah terjemahan. Artikel diterbitkan 27 Mei 2018
Pelacak kebugaran sebelum dan sesudah pembongkaranKetika saya datang ke perusahaan saat ini, pada hari pertama saya dengan ramah diberikan satu set hadiah. Di antara mereka ada gelang dengan pelacak kebugaran. Terlepas dari kesukaan Anda berolahraga, ini adalah gadget yang sangat keren dari sudut pandang teknis:
- faktor bentuk sangat kecil (sekitar 15 × 40 mm);
- Bluetooth low energy (BLE);
- Tampilan OLED (96 × 32 piksel);
- baterai
- Biaya USB
- akselerometer;
- motor getaran;
- harganya sekitar $ 10 (!).
Di luar, satu-satunya pengidentifikasi di panel belakang adalah stiker "FCC ID: 2AHFTID115". Jika Anda google itu, tampaknya sesuai dengan perangkat
ID115 dan Anda bahkan dapat menemukan
beberapa foto bagian dalamnya. Melihat kembali
salah satu dari foto-foto ini , jika Anda berusaha keras, Anda dapat melihat nama sirkuit terpadu terbesar (IC): N51822. Ini menunjukkan bahwa mungkin ada mikrokontroler
Nordic (MCU)
nRF51822 ,
prosesor 32-bit ARM M0 dengan dukungan BLE bawaan, yang secara teoritis mudah diprogram untuk hal-hal lain yang harus dilakukan gelang.
Sebelum membongkar gadget, saya sedikit Google dan menemukan bahwa di
beberapa gelang serupa chip yang sama diinstal, dan orang-orang berhasil memprogramnya.
Membuka kasing itu tidak mudah. Penutup plastik hitam terpaku pada latar belakang abu-abu. Saya mencoba pengering rambut untuk melembutkan lem, dan dengan sabar memotongnya dengan pisau kecil, berusaha untuk tidak merusak plastik terlalu banyak. Setelah dibuka, saya memastikan benar-benar ada nRF51822. Kemudian saya membeli gelang MCU yang hampir identik dari Texas Instrument. Perlu diingat bahwa ada opsi.
nRF51822 dan pulpen untuk skalaMenemukan cara untuk berkomunikasi
Dokumentasi mengatakan bahwa chip dapat diprogram / didebug menggunakan antarmuka dua pin ARM
Serial Wire Debug (SWD). Jika kita ingin membuat saluran komunikasi dengan sebuah chip, ini berarti dua hal:
- Kami memerlukan programmer SWD (misalnya, Segger J-Link ).
- Kita akan membutuhkan akses ke dua pin SWD pada mikrokontroler, yaitu SWDIO (data) dan SWDCLK (pulsa clock).
Untungnya, ada beberapa bantalan yang tersedia di papan tulis. Meskipun keberadaan mereka jelas dijelaskan oleh kebutuhan untuk debugging, pengujian dan verifikasi, saya lebih suka berpikir bahwa beberapa insinyur keren meninggalkan mereka di sana sebagai hadiah kecil untuk orang-orang seperti kita. Tidak semuanya diberi label dengan benar, jadi saya sarankan kode berikut:

Sisi depan dan belakang papan sirkuit. Ballpoint pen untuk skala dan nama semi-arbitrer untuk bantalan terbukaDengan menggunakan
mikroskop USB murah yang sama
, saya mengambil beberapa gambar dari sisi depan dan belakang papan dan mencoba melacak jejak dari mikrokontroler ke bantalan.

Melacak ke pin SWDIO dan SWDCLK di bagian depan dan belakang papanHarap dicatat bahwa ini adalah papan sirkuit cetak multi-layer dengan lubang berlubang, jadi Anda harus memeriksa trek di kedua sisi papan. Dari foto-foto ini, Anda dapat melacak trek dari kontak SWDIO dan SWDCLK pada chip ke bantalan IO dan CLK. Jadi kami akan memastikan bahwa tanda CLK di papan sesuai dengan SWDCLK pada MCU, dan kontak yang tidak berlabel adalah pin SWDIO. Sekarang Anda dapat menyiapkan tabel pemetaan pertama kami:
Pin NRF51822 | Taman bermain | Deskripsi |
---|
SWDIO | IO | Output data untuk pemrograman SWD |
SWDCLK | CLK | Output clock untuk pemrograman SWD |
Operasi post-mortem
Setelah mendapatkan akses ke dua bantalan SWD, saya menyolder kabel yang sangat tipis ke mereka dan ke semua kontak lain yang tersedia.

Berkedip sedikit
Tugas selanjutnya adalah mencoba memprogram perangkat untuk beberapa tugas. Untuk menjalankan program yang paling sederhana, kita perlu memastikan hal-hal berikut:
- Kami melacak kontak SWDIO / SWDCLK dengan benar.
- Pemrogram SWD sedang berjalan dan komputer dapat mengeluarkan perintah.
- Kita dapat mengkompilasi program Arm dan menggunakan SDK Nordic dengan benar.
- Kita dapat mem-flash program yang dikompilasi ke dalam chip.
- Chip bekerja dengan benar dan memuat program kami.
Dalam hal ini, "halo, dunia" bisa menjadi program yang menyalakan dan mematikan LED. Dan bahkan ini bukan SD, karena tidak ada LED bawaan di papan, dan jika Anda menambahkan yang eksternal, Anda masih perlu mencari tahu apa yang harus dihubungkan. Ini menambah dimensi lain pada model spasial masalah. Menurut kurangnya teorema keju gratis, saya hanya menghubungkan dua LED ke pin
P1
dan
P2
dengan harapan bahwa kita bisa sampai ke pembalut ini dengan MCU.
Hari yang burukProgram driver dan command line untuk programmer J-Link SWD terdapat di
situs web Segger . Jika Anda menggunakan MacOS dan menggunakan Homebrew, cari rumus Cask di
caskroom/drivers/segger-jlink
. Komunikasi dengan programmer SWD dibentuk dari
JLinkExe
baris perintah
JLinkExe
.
Kemudian saya mengunduh
Nordic nRF5 SDK (saya menggunakan
versi 12.3.0 ). Dari contoh SDK, jelas bahwa kita memerlukan kompiler yang mampu mengkompilasi program Arm. Jadi saya menginstal
gcc-arm-embedded
(juga tersedia di Homebrew).
Setelah memeriksa dokumentasi SDK dan forum pengembang Nordik, saya menemukan bahwa SDK mereka paling sering digunakan dengan papan pengembangan
seperti ini . SDK telah dikonfigurasikan sebelumnya untuk beberapa varian papan tersebut. Karena kami berhubungan langsung dengan controller, Anda harus mengkonfigurasi beberapa parameter SDK.
Saya menghabiskan
banyak waktu untuk memahami ekosistem nRF5, tetapi pada akhirnya saya masih dapat menjalankan program pada sebuah chip!
Video menunjukkan dua LED yang berkedip. Pada titik ini, saya membuat
repositori Github dan membuang program dengan
Makefile
berfungsi di
Makefile
. Salah satu rahasia utama adalah bahwa sebenarnya ada beberapa opsi untuk nRF51822, dan di tambang saya hanya ada 16 KB memori. Jadi saya masih harus
memperbaiki skrip linker .
Input / output digital
Seperti yang sudah saya katakan, tugas mem-flash LED memberikan beberapa harapan dan metode poke, yang mana dari kontak MCU mengarah ke
P1
dan
P2
, di mana LED terhubung. Strategi paling sederhana adalah menghubungkan semua output secara bergantian dan menerapkan tegangan tinggi dan rendah secara bergantian. Yang mengejutkan saya, kedua LED menyala! Saya bahkan lebih terkejut ketika vibromotor mulai bekerja!
Jadi, metode poke ditambahkan ke tabel:
Pin NRF51822 | Taman bermain | Deskripsi |
---|
P0.30 | P1 | GPIO digital |
P0.00 | P2 | GPIO digital |
P0.01 | - | Motor getaran |
printf
Kemampuan untuk mentransfer data ke komputer sangat diperlukan untuk debugging. Programmer J-Link mendukung
transmisi waktu nyata (RTT) untuk mengirim dan menerima data dari chip. Untuk menggunakan RTT, Anda harus
#include "SEGGER_RTT.h"
dan memanggil
SEGGER_RTT_WriteString()
. Untuk menerima data di komputer, hubungi
jlinkrttlogger
baris perintah
jlinkrttlogger
, yang disediakan dengan J-Link.
OLED
Tantangan lain adalah membuat OLED bekerja. OLED yang paling umum di pasaran menjalankan driver / controller
ssd1306 , dan biasanya komunikasi dengan MCU adalah melalui antarmuka serial menggunakan
SPI atau
I²C . Ini adalah
contoh dari Adafruit .
Saya tidak menemukan tampilan seperti itu di salah satu toko biasa. Dan ukuran 96 × 32 adalah non-standar. Pencarian dengan pengidentifikasi QT1316P01A pada layar memberikan situs China seperti
Aliexpress , tetapi tidak ada dokumentasi kecuali untuk nama-nama kesimpulan:
Penamaan pin OLED dengan AliexpressJika daftar tidak berbohong, maka kontak
SCL
,
SDA
dan
RES#
memberi tahu kami bahwa ini adalah opsi I²C. Jika ada trek antara tiga pin nRF51822 dan tiga pin OLED ini, maka kita akan mengambil langkah maju. Ayo kembali ke mikroskop.

Track Kontak Data OLEDKami memperbarui tabel korespondensi:
Pin NRF51822 | Taman bermain | Deskripsi |
---|
P0.21 | - | Output SDA OLED |
P0.22 | - | Pin OLED SCL |
P0.24 | - | Output OLED RES # |
Protokol I²C jauh lebih maju daripada protokol serial sederhana seperti
UART . Salah satu kelebihannya adalah mendukung beberapa perangkat master dan slave pada bus yang sama. Ini sedikit rumit: paling tidak Anda perlu memberi tahu MCU tentang perintah slave yang dikeluarkan. Jadi pada tingkat tinggi, selain kontak fisik, ada juga alamat "logis" dari layar OLED.
Untungnya, salah satu contoh dalam nRF5 SDK adalah pemindai I²C. Dia menginterogasi dari semua kemungkinan alamat dan laporan logis jika ada sesuatu yang diinstal di sana. Versi modifikasi saya ada di
sini . Ini menghasilkan log berikut:
$ make
# ...
$ make flash
# ...
$ make log
# ...
TWI scanner.
TWI device detected at 0x3c.
Berita bagus! Kami memiliki alasan kuat untuk meyakini bahwa tampilan diidentifikasi dengan benar dan memang merupakan varian I²C. Pencarian
0x3c
mengatakan
0x3c
adalah alamat khas untuk perangkat tersebut.
Sekarang kami siap mengirim beberapa piksel ke layar. Pada tingkat ini, tidak ada abstraksi melalui perpustakaan.
Lihat dokumentasi
ssd1306 untuk cara tingkat rendah untuk mentransfer data. Proses ini terdiri dari urutan perintah konfigurasi yang mengatur orientasi tampilan, mode perekaman, ukuran, dll. Kemudian, urutan byte yang ditampilkan di layar dikirim ke memori tampilan grafik (GDDRAM).
Untuk konfigurasi yang benar, saya mempelajari
perpustakaan ssd1306 dari Adafruit dan mencoba meniru perintah yang sama. Itulah yang menjadi bagian terbesar dari waktu dalam proyek ini. Menemukan semua detail ternyata menjadi tugas yang sangat memakan waktu, dan masih saya tidak bisa menjelaskan beberapa hal. Namun, itu berhasil!
Menampilkan bitmap hard-codedKode untuk contoh ini ada di
sini .
Dengan pengaturan ini, tampilan dibagi menjadi 4 baris (halaman) dan 96 kolom. Jadi halaman tingginya 8 piksel. Byte pertama yang dikirim akan ditempatkan "vertikal" di kolom pertama dari halaman pertama. Byte kedua akan menempati kolom kedua, lalu yang ketiga dan seterusnya, sampai ke kolom ke-96, ketika
kembali dan dimulai dari kolom pertama di halaman kedua.
Inilah perilaku yang
diharapkan . Seperti yang
ditunjukkan dalam video , perilaku yang
diamati berbeda: pertama kolom aneh diisi, lalu yang genap, dan baru kemudian kembali ke halaman kedua.
Saya menghabiskan banyak waktu untuk memahami alasan perilaku tampilan yang bodoh, dan kemudian lebih banyak waktu untuk mengkonfigurasinya untuk memperbaikinya. Pada akhirnya, saya menelan harga diri saya dan masih menerapkan logika rendering yang aneh dalam program untuk menyelesaikannya.
Perjalanan ke Arduino
Menggali perpustakaan Adafruit ssd1306 untuk Arduino, saya selalu berpikir akan menyenangkan untuk memiliki cara untuk "mensimulasikan" bit Arduino tertentu untuk mengujinya di nRF51822. Ternyata orang yang lebih berpengalaman juga memikirkan topik ini - inilah yang dilakukan oleh proyek
sandeepmistry / arduino -
nRF5 yang menakjubkan. Ini mengimplementasikan perpustakaan Arduino utama menggunakan nRF5 SDK.
Dengan proyek ini, kita dapat membuka IDE Arduino, memilih papan nRF5, dan menggunakan ekosistem Arduino yang kaya. Saya
memotong proyek dan menambahkan dukungan untuk papan dari gelang kami. Anda dapat memilihnya dari menu tarik-turun
Tools > Board > ID115 Fitness Bracelet (nRF51822)
.

Pustaka Adafruit ssd1306 dalam bentuk aslinya (di atas) dan dengan tambalan (di bawah)Ini juga berarti bahwa sekarang kita dapat menggunakan
perpustakaan OLED Adafruit . Yang mengejutkan dan melegakan saya, perilaku aneh yang sama terjadi dengan mengisi kolom aneh dan bahkan OLED terlebih dahulu! Saya senang
bercabang perpustakaan dan menerapkan hack yang sama. Dibandingkan dengan pendekatan tingkat rendah, kami sekarang memiliki akses ke berbagai abstraksi keren, seperti keluaran teks:
"Halo, dunia!" Yang lebih akrab.Input / output analog
Selain sinyal on / off digital, nRF51822 memiliki 10 pin untuk input analog. Ini berguna, misalnya, untuk membaca pengisian daya baterai saat ini. Dilihat oleh dokumentasi, membaca kontak analog menghasilkan nilai 10-bit. Oleh karena itu, jika ada
0V
pada input, maka kita akan membaca
0
, dan jika ada
VCC
, kita akan membaca
1023
dengan nilai antara.
Secara berkala saya membaca nilai input analog dan memplot sinyal yang paling menarik:

Efek papan goyang dan pengisian baterai sesuai dengan data dari input analogSaya yakin bahwa kontak
P0.05
mengacu pada pengisian daya baterai, karena nilainya bertambah dan berkurang saat diisi dan dibuang. Saya menduga pin
P0.26
terhubung ke salah satu output dari accelerometer, karena itu menjadi gila ketika Anda menggoyang papan. Kontak
P0.03
dan
P0.04
juga dapat dihubungkan ke berbagai output akselerometer, tetapi di sini efek orde kedua tertentu kemungkinan besar ditumpangkan pada sinyal dari input. Misalnya, pada grafik pertama, perhatikan bagaimana level baterai (pin 5) berubah ketika accelerometer membutuhkan lebih banyak energi. Ini adalah contoh efek urutan kedua.
Kode dapat ditemukan
dalam sketsa ini . Sumber data dan skrip grafik ada di
sini . Sekarang kita dapat menambahkan beberapa baris ke tabel korespondensi kami:
Pin NRF51822 | Taman bermain | Deskripsi |
---|
P0.05 | - | Input Analog - Terhubung ke Baterai |
P0.26 | - | Input Analog - One Axis Accelerometer |
P0.03 | - | Input analog - satu sumbu accelerometer (kemungkinan) |
P0.04 | - | Input analog - satu sumbu accelerometer (kemungkinan) |
Tombol
Dalam firmware asli, menyentuh gelang pada titik tertentu akan menyalakan layar. Memegang titik ini memulai kronometer, jika saya ingat dengan benar. Ini bukan tombol fisik, tetapi semacam sentuhan kapasitif yang bekerja dengan sangat baik. Menggunakan pendekatan yang sama seperti untuk mencari keluaran digital, saya
menemukan tempat untuk terhubung ke MCU (video) .
Kodenya ada di
sini .
Pin NRF51822 | Taman bermain | Deskripsi |
---|
P0.10 | - | Input Digital - Tombol Bawaan |
Bluetooth low energy (BLE)
Fungsionalitas BLE pada chip nRF5 diimplementasikan melalui sesuatu yang disebut
SoftDevice . Ini adalah biner yang dikompilasi dengan tumpukan BLE. Itu dijahit terlepas dari aplikasi. Ada banyak versi SoftDevice, tergantung pada versi SDK dan versi chip.
Dokumentasi menyediakan matriks dependensi tertentu (sayangnya, Anda tidak dapat menempatkan tautan langsung ke sana). Ini menunjukkan SDK mana versi yang berbeda dari chip datang - dan versi SoftDevice apa itu. Dalam kasus kami, chip ditandai QFAAH0, chip ini memiliki 256 KB memori flash, 16 KB RAM dan kompatibilitas dengan SoftDevice s130 dinyatakan.
SDK versi 12.3 saya sudah berisi beberapa contoh penggunaan SoftDevice s130. Dibandingkan dengan program sebelumnya yang langsung ditransfer ke microchip dari alamat
0x0
, sekarang Anda perlu mem-flash SoftDevice dari alamat
0x0
, dan program itu sendiri dari alamat
0x1b000
. Setelah memuat dan inisialisasi, file biner SoftDevice akan pergi ke alamat ini dan mentransfer kontrol ke program kami. Sebagai ilustrasi, saya mengambil contoh yang sama dengan LED berkedip, tetapi mengubahnya untuk firmware SoftDevice (
kode ). Perilaku yang diamati tidak berubah, kecuali bahwa Anda harus melakukan pra-flash SoftDevice:
$ make
# ...
$ make flash-softdevice
# ...
$ make flash
# ...
$ make log
# ...
Hello, world!
Mungkin aplikasi paling sederhana untuk Bluetooth adalah mengubah perangkat menjadi
suar . Perangkat hanya menyiarkan keberadaannya. Salah satu contohnya adalah di SDK yang disebut
ble_app_beacon
. Diasumsikan bahwa SoftDevice
s130
sudah di-flash.
Di sini juga, komunikasi tingkat rendah dengan chip mempersulit segalanya dibandingkan dengan pemrograman melalui SDK. Selain menyesuaikan ukuran RAM (pengetahuan ini sulit bagi saya dalam contoh dengan LED), masalah sulit lainnya dilacak. Ternyata, tumpukan BLE menggunakan generator jam untuk melakukan tugas yang sensitif terhadap waktu. Dalam contoh SDK, osilator kristal eksternal diasumsikan. Ketika saya menyadari hal ini setelah ribuan upaya untuk
printf
, saya mengubah flag konfigurasi untuk menggunakan generator jam sintetis, dan masalahnya terpecahkan. Kode sumber suar ada di
sini .
BLE + Arduino
Ketika contoh BLE bekerja dengan nRF5 SDK, mengetahui tentang jebakan dengan RAM dan generator, saya melihat kembali pada lingkungan Arduino. Dan lagi, ada proyek
sandeepmistry / arduino-BLE yang mulia (dari orang yang sama dengan arduino-nRF5!), Yang memberikan abstraksi yang sangat baik di atas pengaturan BLE internal.
Yang mengejutkan saya, saya bahkan tidak perlu membayar perpustakaan. Penulis proyek arduino-nrf5 menghabiskan waktu dan menambahkan konfigurasi semua papan dan pengaturan, jadi sekarang memilih generator jam yang tepat untuk SoftDevice diturunkan ke pilihan sederhana dari menu drop-down
Tools > Low Frequency Clock > Synthesized
. Luar biasa. Saya dengan cepat menulis
contoh dengan LED hijau menyala melalui Bluetooth (dengan
aplikasi ini ). Karyanya
ditampilkan dalam video .
Rencana selanjutnya
Setelah sibuk dengan papan ini selama berjam-jam yang tak terhitung jumlahnya, tangan saya gatal selama beberapa minggu untuk menempelkannya lebih jauh ke dalam mesin cuci dan melupakannya sebentar.