Coding EXP : ลดขนาด code ( sketch size ) บน Arudino UNO

2 คืนก่อนกดปุ่ม Upload บน Arduino IDE เกิด error ขึ้นมาว่า …

Sketch uses 32142 bytes (104%) of program storage space. Maximum is 30720 bytes
Global variables use 1348 bytes (65%) of dynamic memory, leaving 700 bytes for local variables. Maximum is 2048 bytes.

มันคืออะไรหว่า ? ไม่เคยเจอ error แบบนี้

หาข้อมูลพบว่า Arduino UNO มี flash memory ขนาด 30KB แล้ว code ที่เขียนมีขนาดใหญ่เกิน memory มา 104% แล้วมันไม่ยอมให้ทำงานต่อ

เข้าไปค้นหาดูข้อมูลว่ามี board ไหนที่ใหญ่กว่า 30KB ไหม ได้ข้อมูลดังนี้

สรุปว่า  ถ้าจะ code ได้เยอะกว่านี้   ต้องขยับไปรุ่น Mega หรือ Due ที่มันมีขนาดใหญ่ทั้ง flash memory , ขนาด board , และขนาดค่าตัว

ไม่ใช่เรื่องละที่จะต้องไปหาซื้อ board ใหม่ที่แพงกว่า  ใหญ่กว่า  เทอะทะกว่า  เพื่อได้ขนาดที่รองรับ code ที่มากขึ้นอีกแค่ 4%

จึงหาทาง optimize code ที่มีให้ต่ำกว่า 30720 byte

32142 – 30720 = 1422 byte

2 คืนก่อนก็เลยคิดว่า   ก็นั่งกระชับ code ลงอีกแค่ 1.4 Kbyte เอง

ความคิดนี้เหมือนจะง่าย   คือถ้า 1 Kb บน desktop หน่ะง่าย   แต่บน embedded นี่เป็นเรื่องใหญ่เลย

ตัด function ใดๆออกไม่ได้  ( สำคัญหมด ) ทำได้แค่เพียง optimize code เท่านั้น

นั่ง optimize 1 วันผ่านไปก็ยังไม่สำเร็จ  ลดมาได้แค่ 3%

ยังเกินมาอีก 1%  คือเหลืออีกประมาณ 550 bytes

คืนนี้จะนั่งทำต่อ  คิดว่า 1% น่าจะสำเร็จ

แล้วก็คาดว่าอนาคตน่าจะเจอปัญหานี้อีก  เพราะสิ่งที่ทำนี้ function ยังไม่เยอะเลย flash memory ก็ยังเต็มแล้ว ก็เลยเขียน blog บันทึกการ optimize code นี้เอาไว้ดูในอนาคต

 

บันทึกผลจากการปรับ code ลง 3% มีดังนี้

[ สิ่งที่ช่วยลด size ได้ ]
> เปลี่ยนตัวแปร float เป็น int = ลดได้ถึง 20-100 bytes ต่อ 1 ตัวแปร
> การ drawBitmap บน LCD = ลดได้ถึง 140 bytes ต่อ 1 บรรทัด
> เปลี่ยนจาก int ไปเป็น const int = ลดได้ 6 bytes ต่อ 1 ตัวแปร
> ลบ include ที่ไม่ใช้ออกให้หมด
> ลบ code ที่ไม่ใช้ออกให้หมด
> code ซ้ำๆกัน ให้ทำเป็น function ให้มากที่สุด
> ลบ Serial.Print ที่ไม่จำเป็นออก
> คำที่แสดงใน Serial.Print มีผลต่อ memory ที่ใช้  ดังนั้นถ้าเลี่ยง Serial.Print ไม่ได้ก็ควรใช้คำที่สั้นและกระชับที่สุด
> อะไรที่ยัดใส่ PROGMEM ได้ ให้ใส่เลย ( PROGMEM แยกออกจาก flash memory )

[ สิ่งที่ลองทำแล้วไม่ช่วยอะไร ]
> การลบ comment ออก ไม่ได้ช่วยอะไร ไม่ได้ลดขนาด sketch size ( ควร comment ให้เต็มที่เลย )
> ตั้งชื่อตัวแปรให้สั้นลด ไม่ได้ช่วยลดขนาด sketch size ( ลองแล้ว )
> function ที่ไม่ถูกเรียกใช้ใน code -> arduino ide ก็ฉลาดพอที่จะไม่เพิ่ม ขนาด sketch size  ( ลบ function ออกก็ไม่ช่วยลดขนาด )

 

ปรับแก้ไปเรื่อยๆ  และแล้วก็สำเร็จ ( ต่ำกว่า maximum อยู่ 10 bytes ^_^ )

ประสบการณ์นี้สอนว่า

– Flash memory ขนาด 30,000 bytes   สร้างผลงานได้

– Picture image ขนาด 30,000 bytes    แทบไม่มีคุณค่าเลย ( เล็กและไม่ชัด )

– อย่าคิดว่า code หรือ project หรือ idea ของเรา ว่ามันจะเล็กแค่นั้นตลอดไป อย่ามั่นใจว่ามันจะไม่บวม

– ไป STM32 เลย ( ชัวร์กว่า )