โครงสร้างโปรแกรมภาษา C บน Arduino จะมีลักษณะแบบเดียวกับ C ทั่วๆไป แต่สำหรับท่านที่ยังไม่เคยเรียนรู้การเขียนโปรแกรมภาษาใดๆมาก่อน ท่านต้องทำความเข้าใจในเรื่องต่างๆดังนี้
1. ปรีโปรเซสเซอร์ไดเร็กทีฟ (Preprocessor directives)
2. ส่วนของการกำหนดค่า (Global declarations)
3. ฟังก์ชั่น setup() และ ฟังก์ชั่น loop()
4. การสร้างฟังก์ชั่น และการใช้งานฟังก์ชั่น (Users-defined function)
5. ส่วนอธิบายโปรแกรม (Progarm comments)
1. ปรีโปรเซสเซอร์ไดเร็กทีฟ (Preprocessor directives)
โดยปกติแล้วเกือบทุกโปรแกรมต้องมี โดยส่วนนี้จะเป็นส่วนที่คอมไพลเลอร์จะมีการประมวลผลและทำตามคำสั่งก่อนที่จะมีการคอมไพล์โปรแกรม ซึ่งจะเริ่มต้นด้วยเครื่องหมายไดเร็กทีฟ (directive) หรือเครื่องหมายสี่เหลี่ยม # แล้วจึงตามด้วยชื่อคำสั่งที่ต้องการเรียกใช้ หรือกำหนด โดยปกติแล้วส่วนนี้จะอยู่ในส่วนบนสุด หรือส่วนหัวของโปรแกรม และต้องอยู่นอกฟังก์ชั่นหลักใดๆก็ตาม
#include เป็นคำสั่งที่ใช้อ้างอิงไฟล์ภายนอก เพื่อเรียกใช้ฟังก์ชั่น หรือตัวแปรที่มีการสร้างหรือกำหนดไว้ในไฟล์นั้น รูปแบบการใช้งานคือ
#include <ชื่อไฟล์.h>
ตัวอย่างเช่น
#include <Wire.h>
#include <Time.h>
จากตัวอย่าง จะเห็นว่าได้มีการอ้างอิงไฟล์ Wire.h และไฟล์ Time.h ซึ่งเป็นไลบารี่พื้นฐานที่มีอยู่ใน Arduino ทำให้เราสามารถใช้ฟังก์ชั่นเกี่ยวกับเวลาที่ไลบารี่ Time มีการสร้างไว้ให้ใช้งานได้
การอ้างอิงไฟล์จากภายใน หรือการอ้างอิงไฟล์ไลบารี่ที่มีอยู่แล้วใน Arduino หรือเป็นไลบารี่ที่เราเพิ่มเข้าไปเอง จะใช้เครื่องหมาย <> ในการคร่อมชื่อไฟล์ไว้ เพื่อให้โปรแกรมคอมไพลเลอร์เข้าใจว่าควรไปหาไฟล์เหล่านี้จากในโฟลเดอร์ไลบารี่ แต่หากต้องการอ้างอิงไฟล์ที่อยู่ในโฟลเดอร์โปรเจค จะต้องใช้เครื่อหมาย "" คร่อมแทน ซึ่งคอมไพล์เลอร์จะวิ้งไปหาไฟล์นี้โดยอ้างอิงจากไฟล์โปรแกรมที่คอมไพล์เลอร์อยู่
เช่น
#include "myFunction.h"
จากตัวอย่างด้านบน คอมไพล์เลอร์จะวิ้งไปหาไฟล์ myFunction.h ภายในโฟลเดอร์โปรเจคทันที หากไม่พบก็จะแจ้งเป็นข้อผิดพลาดออกมา
#define เป็นคำสั่งที่ใช้ในการแทนข้อความที่กำหนดไว้ ด้วยข้อความที่กำหนดไว้ ซึ่งการใช้คำสั่งนี้ ข้อดีคือจไม่มีการอ้างอิงกับตัวโปรแกรมเลย
รูปแบบ
#define NAME VALUE
ตัวอย่างเช่น
#define LEDPIN 13
จากตัวอย่าง ไม่ว่าคำว่า LEDPIN จะอยู่ส่วนใดของโค้ดโปรแกรมก็ตาม คอมไพล์เลอร์จะแทนคำว่า LEDPIN ด้วยเลข 13 แทน ซึ่งข้อดีคือเราไม่ต้องสร้างเป็นตัวแปรขึ้นมาเพื่อเปลืองพื้นที่แรม และยังช่วยให้โปรแกรมทำงานเร็วขึ้นอีกด้วยเพราะซีพียูไม่ต้องไปขอข้อมูลมาจากแรมหลายๆทอด
2. ส่วนของการกำหนดค่า (Global declarations)
ส่วนนี้จะเป็นส่วนที่ใช้ในการกำหนดชนิดตัวแปรแบบนอกฟังก์ชั่น หรือประกาศฟังก์ชั่น เพื่อให้ฟังก์ชั่นที่ประกาศสามารถกำหนด หรือเรียกใช้ได้จากทุกส่วนของโปรแกรม
เช่น
int pin = 13;
void blink(void) ;
3. ฟังก์ชั่น setup() และฟังก์ชั่น loop()
ฟังก์ชั่น setup() และฟังก์ชั่น loop() เป็นคำสั่งที่ถูกบังคับให้ต้องมีในทุกโปรแกรม โดยฟังก์ชั่น setup() จะเป็นฟังก์ชั่นแรกที่ถูกเรียกใช้ นิยมใช้กำหนดค่า หรือเริ่มต้นใช้งานไลบารี่ต่างๆ เช่น ในฟังก์ชั่น setup() จะมีคำสั่ง pinMode() เพื่อกำหนดให้ขาใดๆก็ตามเป็นดิจิตอลอินพุต หรือเอาต์พุต ส่วนฟังก์ชั่น loop() จะเป็นฟังก์ชั่นที่ทำงานหลังจากฟังก์ชั่น setup() ได้ทำงานเสร็จสิ้นไปแล้ว และมีการวนรอบแบบไม่รู้จบ เมื่อฟังก์ชั่น loop() งานครบตามคำสั่งแล้ว ฟังก์ชั่น loop() ก็จะถูกเรียกขึ้นมาใช้อีก
ตัวอย่าง
int pin = 13;
void setup() {
pinMode(pin, OUTPUT);
}
void loop() {
digitalWrite(pin, HIGH);
delay(1000);
digitalWrite(pin, LOW);
delay(1000);
}
จากตัวอย่าง จะเห็นว่ามีการประกาศตัวแปรแบบนอกฟังก์ชั่น ทำให้สามารถกำหนด หรือเรียกใช้จากในฟังก์ชั่นใดๆก็ตามได้ ในฟังก์ชั่น setup() ได้มีการกำหนดให้ขาที่ 13 เป็นดิจิตอลเอาต์พุต และในฟังก์ชั่น loop() มีการกำหนดให้พอร์ต 13 มีลอจิกเป็น 1 และใช้ฟังก์ชั่น delay() ในการหน่วงเวลา 1 วินาที แล้วจึงกำหนดให้พอร์ต 13 มีสถานะลอจิกเป็น 0 แล้วจึงหน่วงเวลา 1 วินาที จบฟังก์ชั่น loop() และจะเริ่มทำฟังก์ชั่น loop() ใหม่ ผลที่ได้คือไฟกระพริบบนบอร์ด Arduino Uno ในพอร์ตที่ 13 ทำงานแบบไม่รู้จบ
ในทุกๆการทำงานของฟังก์ชั่น จะต้องเริ่มด้วยการกำหนดค่าที่ส่งกลับ ตามด้วยชื่อฟังก์ชั่น แล้วตามด้วยเครื่องหมายปีกกาเปิด { และจบด้วยเครื่องหมายปีกกาปิด ภายในฟังก์ชั่น หากจะเรียกฟังก์ชั่นใช้งานย่อยใดๆ จะต้องมีเครื่องหมาเซมิโคล่อน ; ต่อท้ายเสมอ
* การกำหนดชนิดค่าที่ส่งกลับเป็น void หมายถึงไม่มีการส่งค่ากลับ แต่สามารถใช้คำสั่ง return; ตรงๆได้ เพื่อให้จบการทำงานของฟังก์ชั่นก่อนจะไปถึงบรรทัดสุดท้ายของฟังก์ชั่น