Dealing dengan RAM Microcontroller

, , 2 Comments

To read in english, choose any language in the translator then once this page gets translated, you’ll find English as the first language in the list.


Halo selamat datang kembali di andidinata.com. Posting saya terakhir mungkin 4 atau 5 bulan yang lalu. Maaf jika lama tidak menulis artikel karena waktu yang dibagi-bagi. Karena selain pekerjaan kantor yang makin banyak, saya juga menyelesaikan buku ke-2 untuk naik editing ke publisher, menyiapkan materi untuk workshop, ngadain workshop ardubuino dan coding dan mengerjakan project-project yang berhubungan dengan coding, bukan tinkering. Mohon dukungannya melalui komentar, share blog ini untuk memotivasi saya dalam membagikan pengalaman.

Tentang judul di atas benar adanya. Selama saya coding dengan Raspberry Pi, hal itu tidak begitu ribet karena Pi sebenarnya komputer dengan resource yang lebih besar dibandingkan dengan microcontroller atau MCU (untuk mempersingkat sebutan). MCU memang sebuah sistem komputasi yang terbatas. Dalam urusan untuk menjalankan aplikasi, memory (RAM) adalah ibarat ruangan yang memungkinkan aplikasi kita dapat berjalan. Kita ingin MCU mampu mengerjakan banyak hal secara simultan, namun semua aplikasi yang berjalan tersebut sedang memperebutkan RAM yang premium. Apabila memori habis, program tidak akan berjalan dan sistem akan reboot. Inilah yang saya alami dalam project pada penutup tahun 2018 ini. Nantikan tutorialnya sebelum akhir tahun.

Project saya sederhana, yaitu ingin membuat multi information display dengan layar LCD 16×2. Dalam layar berbasis teks ini ada 3 macam informasi yang ditampilkan:

  • Waktu: hari, tanggal, jam dan menit
  • Kondisi temperatur & kelembaban ruangan
  • Custom Message

Ketiga fungsi tersebut ingin ditampilkan secara bersama. Saat dijalankan maka ketahuanlah bahwa memori yang ada tidak cukup. Akibatnya fungsi terakhir yaitu custom message tidak bisa dijalankan karena RAM yang tersisa tidak mendukung proses HTTP request. Akibatnya, MCU langsung soft boot alias reset begitu perintah request dijalankan. MCU yang saya gunakan adalah ESP-E12 dalam body Wemos D1 Mini dengan firmware Micropython versi 1.9.3.

Masalah reset ini membuat saya mencari tahu penyebab tekornya memori sehingga sebuah fungsi tidak bisa dijalankan. Jika kita melihat kebelakang saat Micropython di ESP8266 masih dalam tahap awal pengembangan. Masalah RAM memang sudah menjadi issue untuk dapat menjalankan python pada microcontroller ESP8266. Jika tertarik untuk mengetahui aspek teknis tetang RAM di ESP8266, ikuti pembahasannya di laman kickstarter (klik disini).

Sebagai langkah pertama terhadap permasalahan tersebut, saya mencoba memetakan penggunaan memori (RAM) dari project saya tersebut seperti terlihat pada gambar dibawah ini dengan tujuan untuk mengetahui konsumsi mana yang terbesar.

Pola konsumsi memori pada ESP8266 dengan MIcropython saya tampilkan dalam waterfall chart berikut ini.

Pola konsumsi RAM

Dari kiri ke kanan kita bisa melihat pergerakan konsumsi RAM oleh fungsi-fungsi yang dijalankan. Informasi tersebut mudah untuk di dapatkan seperti contoh di bawah ini yang diambil dari unit ESP8266 latihan anak saya yang saya jejali dengan autorun script untuk memudahkan belajar sehingga untuk unit latihan tersebut memori yang tersisa 21 Kb.

>> import micropython
>>> micropython.mem_info()
stack: 2112 out of 8192
GC: total: 35968, used: 13904, free: 22064
No. of 1-blocks: 106, 2-blocks: 32, max blk sz: 264, max free sz: 1004

Dari perintah tersebut saya coba jalankan fungsi satu per satu untuk mengukur besaran konsumsi RAM. Selain itu, saya juga mencoba untuk gunakan garbage collector (GC) untuk mengetahui besaran memory yang bisa direclaim.

Kembali ke chart di atas, dari 35 Kb RAM, yang tersedia di ESP-12 unit project saya adalah 30 Kb setelah boot. Jadi saya punya quota 30 Kb untuk digunakan untuk menjalankan berbagai macam aplikasi. Dari pemetaan itu saya menemukan pola konsumsi memori dimana LCD membutuhkan konsumsi RAM yang terbesar. Kalau saya jalankan GC, maka jumlah memory yang bisa re-claim memory sejumlah 14 Kb memori yang tersisa. Tanpa GC, RAM akan berakhir di nilai 7Kb yang artinya sudah habis.

Untuk mengatasi ketersediaan RAM maka ada beberapa hal yang saya lakukan:

Optimasi Script untuk menjadi lebih lean

  • Mengganti global variable dengan local variable. Global membutuhan alokasi RAM, sedangkan local tidak.
  • Membuat pre-load variable dari pada membuat variabel baru dari hasil variabel sebelumnya.
  • Mengganti penggunaan list dengan tuple untuk data-data statis
  • Sequencing hardware initiation
  • Menggabungkan beberapa fungsi menjadi satu karena setiap fungsi membutuhkan alokasi memori
  • Memanfaatkan timer untuk menjalankan perintah secara periodic untuk menggantikan while True loop

Mengganti hardware

  • Memasang hardware RTC untuk menggantikan NTPTIME. Hal ini meniadakan fungsi untuk timezone conversion. Sehingga script lebih pendek dan jumlah variable berkurang.
  • Mengurangi import library NTPTIME karena setiap import yang dilakukan membutuhkan alokasi memori.

Cross-Compile Module

  • Untuk terhubung dengan LCD kita membutuhkan modul/library untuk inisiasi hardware dan API untuk menuliskan data ke LCD untuk menggunakan memory lebih sedikit, cross-compile akan merubah file .py ke .mpy. Selain itu, file python program juga dirubah ke .mpy

Skenario cadangan yang saya siapkan adalah dengan membebaskan kembali RAM dengan GC setiap kali LCD difungsikan. Jika masih belum berhasil maka membuat custom micropython firmware dengan modul yang freeze di Flash ROM akan digunakan sebagai cara pamungkas di ESP8266.

Jika masih belum berhasil juga maka saya harus pindah ke ESP32. Namun untungya ketiga pendekatan tersebut berhasil mengurangi konsumsi RAM. Ketiga cara tersebut membuahkan hasil. Semua berfungsi dengan baik dan secara parallel dan tidak ada reset sama sekali meskpi penggunaan non-stop > 48 jam. Itu semua karena saya masih memiliki sisa 12 Kb RAM.

>> import micropython 
>>> micropython.mem_info() 
stack: 2112 out of 8192 GC: total: 35968, used: 23536, free: 12432 
No. of 1-blocks: 410, 2-blocks: 47, max blk sz: 264, max free sz: 415

Berikut ini perubahan script sebelum dan sesudah optimasi. Sebelumnya 141 baris, menjadi 81 baris.

Optimizing Script

Saya akan publish codenya di halaman http://www.github.com/mdinata/micropython jadi silahkan follow atau fork repositorynya.

Kelebihan dari Micropython adalah kecepatan untuk mendevelop dan mencari tahu dimana titik permasalahan lalu mendebug. Cara paling mudah dari semua keterbatasan memory adalah mengganti MCU dengan kapasitas RAM lebih lega. Cara itu dijamin berhasil, namun ada loss opportunity dalam eksplorasi dan eksperimen untuk mengoptimalkan script dan memaksimalkan MCU kita. Saya yakin ketiga cara tersebut masih dapat ditingkatkan lagi karena sisa 12 Kb masih rendah. Target saya adalah mencapai minimum 15 Kb agar tidak hanya melakukan HTTP request, tetapi juga HTTP post atau menjalankan MQTT.

Demikian sharing dari saya, semoga bermanfaat. Mohon komentar, like dan share artikel ini agar bermanfaat bagi lebih banyak orang. Silahkan subscribe untuk mendapatkan pemberitahuan artikel berikutnya. Terima kasih dan sampai bertemu di tulisan berikutnya.

The post Dealing dengan RAM Microcontroller appeared first on Fun with Raspberry Pi and Micropython.

Facebook Comments
 

2 Responses

Leave a Reply