เมนู

วันอังคารที่ 12 กรกฎาคม พ.ศ. 2559

Pinguino กับ LCD Adaptor Plate I2C


               บทความครั้งนี้ผมจะเขียนถึงการใช้งาน LCD Adaptor Plate I2C หรือบางทีก็เรียกว่า I2C Convertor Module for LCD1602/2004 ซึ่งรูปร่างหน้าตาของมันก็จะอยู่ในรูปที่ 1 เจ้าตัวนี้นั้นถูกออกแบบมาเพื่อให้สามารถใช้สายสัญญานเพียงสองเส้นก็สามารถสื่อสารและแสดงข้อความบนจอ LCD ขนาด 16x2 หรือ 20x4 ได้แล้ว จากเดิมที่ต้องใช้อย่างน้อย 6 เส้นถึงจะสื่อสารกันได้  อีกทั้งราคาที่ถูกมากจึงได้รับความนิยมสูง โดยตัว I2C converter นี้จะมีอยู่หลายเวอร์ชัน ซึ่งแต่ละเวอร์ชันก็จะมี I2C address ไม่เหมือนกัน ข้อมูลเพิ่มเติมสามารถหาอ่านได้จากที่นี่ครับ ค่อนข้างละเอียดดีทีเดียว
รูปที่ 1 LCD Adaptor Plate I2C

               จากการดูและเปรียบเทียบแล้วตัวที่ผมมีอยู่นั้นมี หมายเลข I2C address เป็น 0x27 เมื่อรู้ดังนี้แล้วก็เริ่ม wiring สายจาก I2C convertor ไปที่ตัวบอร์ด Pinguino 8 ซึ่งก็จะมีเพียงแค่ 4 เส้นเท่านั้น คือ Vdd, Gnd, SCL, SDA
ซึ่งก็จะมี label พิมพ์ติดไว้อยู่แล้วทั้งบน I2C convertor และ Pinguino 8 โดยเมื่อต่อเสร็จแล้วก็จะได้ตามรูปที่ 2 ครับ
รูปที่ 2 เชื่อมต่อกับ Pinguino 8
และในส่วนของโค้ดที่จะเขียนนั้นง่ายและสั้นมากครับโดยเราเพียงต้อง initialize เจ้า I2C convertor ว่าต่ออยู่กับจอ LCD ขนาดเท่าไหร่ 16x2 หรือ 20x4 และกำหนดหมายเลข address ให้ตรงกับของ I2C convertor เท่านั้นเองซึ่งตัวที่ผมใช้คือ 0x27 โดยโค้ดจะเป็นดังนี้ครับ

1:  lcdi2c.init(16,2,0x27);  
2:  lcdi2c.backlight();  
3:  lcdi2c.printf("Hello Thailand");  

               ในบรรทัดแรกเป็นการ initialize อย่างที่ได้อธิบายด้านบน ส่วนบรรทัดถัดมาเป็นการสั่งให้ไฟ back light สว่างขึ้นมา และบรรทัดสุดท้ายก็ให้ส่งข้อความ Hello Thailand ออกมาแสดงครับ เมื่อเราสั่งคอมไพล์และโปรแกรมลงตัวไมโครคอนโทรลเลอร์แล้วก็จะจะจะ……..อ้าว! ทำไมไม่มีอะไรเกิดขึ้นเลย ต่อสาย SCL กับ SCA  สลับกันหรือเปล่า ? ก็ถูกนี่ งั้นโค้ดต้องผิดแน่นอนเลย!!!!!


               นั่นคือประสบการณ์ครั้งแรกของผมกับ Pinguino กับ I2C converter for LCD ครับ ผมใช้เวลาอยู่หลายวันหาข้อมูลจากอินเตอร์เน็ทก็หาไม่ค่อยได้ สุดท้ายผมหาเจอ schematic หรือ ใน Arduino forum นี่แหละจำไม่ค่อยได้แล้วครับ ประกอบกับนั่งอ่าน library ของ Pinguino เองจนพบว่าในไฟล์ที่ชื่อ lcdi2c.h ที่อยู่ในโฟล์เดอร์ ‘C:\pinguino-11\p8\include\pinguino\libraries’ นั้น define ขาที่ต่อกับ PCF8574 ไม่ตรงกันโดยของเดิมจะเป็น

1:  #define LCD_BL     PCF8574_data.bits.bit0     // P0  
2:  #define LCD_RS     PCF8574_data.bits.bit1     // P1  
3:  #define LCD_RW     PCF8574_data.bits.bit2     // P2  
4:  #define LCD_EN     PCF8574_data.bits.bit3     // P3  

ผมจึงแก้ไขใหม่ให้ตรงกับตัว I2C convertor for LCD ที่ผมมีอยู่โดยแก้เป็นของใหม่ดังนี้ครับ

1:  #define LCD_BL     PCF8574_data.bits.bit3     // P0  
2:  #define LCD_RS     PCF8574_data.bits.bit0     // P1  
3:  #define LCD_RW     PCF8574_data.bits.bit1     // P2  
4:  #define LCD_EN     PCF8574_data.bits.bit2     // P3  

หลังจาก save file แล้ว ทำการคอมไพล์ใหม่และโปรแกรมลงไมโครคอนโทรลเลอร์อีกครั้ง คราวนี้…..ทำงานได้แล้วครับ เย้ๆ ลองดูจากวิดีโอดูนะครับ ส่วนข้างล่างนี้เป็นโค้ดทั้งหมดนะครับ


1:  /*-----------------------------------------------------  
2:  Author: --<Ekkachai Muangrodpai>  
3:  Board:  Pinguino8 + I2C LCD board.  
4:  Date: 2016-03-20  
5:  Description:  
6:  - display message on LCD through I2C adaptor.  
7:  -----------------------------------------------------*/  
8:  /*  
9:    Note: must change the definition in 'lcdi2c.h' to match the hardware. Like following:    
10:  #define LCD_BL     PCF8574_data.bits.bit3     // P0  
11:  #define LCD_RS     PCF8574_data.bits.bit0     // P1  
12:  #define LCD_RW     PCF8574_data.bits.bit1     // P2  
13:  #define LCD_EN     PCF8574_data.bits.bit2     // P3  
14:   */  
15:  void setup() {  
16:    // put your setup code here, to run once:  
17:    lcdi2c.init(16,2,0x27);  
18:    lcdi2c.backlight();  
19:    lcdi2c.printf("Hello Thailand");    
20:  }  
21:  void loop() {  
22:    // put your main code here, to run repeatedly:  
23:  }  



ของแถมครับ จาก link ข้างบนผมเห็นมีตัวอย่างของ Arduino ที่ใช้ Serial รับค่า string จากคอมพิวเตอร์แล้วเอามาแสดงผลบนจอ LCD ที่ต่อผ่าน I2C adaptor for LCD ซึ่งน่าสนุกดีผมจึงลองเขียนด้วย Pinguino ดูบ้างโดยใช้ฟังก์ชันจากบทความนี้และจากบทความที่ผ่านมาเรื่อง Pinguino สื่อสารผ่าน Com Port ก็ได้มาเป็นโค้ดที่แสดงข้างล่างต่อไปนี้ครับลองทดลองกันดูนะครับ
1:  /*-----------------------------------------------------  
2:  Author: --<Ekkachai Muangrodpai>  
3:  Board:  Pinguino8 + I2C convertor for LCD board + USB-to-Serial.  
4:  Date: 2016-07-11  
5:  Description:  
6:  - Get string from computor through terminal program, then display on LCD.  
7:  -----------------------------------------------------*/  
8:  int i;  
9:  void setup() {  
10:   Serial.begin(9600);    
11:   lcdi2c.init(16, 2, 0x27);         
12:   // ------- Quick 3 blinks of backlight -------------  
13:   for(i = 0; i< 3; i++)  
14:   {  
15:    lcdi2c.backlight();  
16:    delay(250);  
17:    lcdi2c.noBacklight();  
18:    delay(250);  
19:   }  
20:   lcdi2c.backlight(); // finish with backlight on   
21:   //-------- Write characters on the display ------------------  
22:   lcdi2c.setCursor(0,0);   
23:   lcdi2c.printf("Hello, World!....");  
24:   delay(1000);  
25:   lcdi2c.setCursor(0,1);  
26:   lcdi2c.printf("Hi Your Pinguino");  
27:   delay(1000);   
28:  // Wait and then tell user they can start the Serial Monitor and type in characters to  
29:  // Display. (Set Serial Monitor option to "No Line Ending")  
30:   lcdi2c.clear();  
31:   lcdi2c.setCursor(0,0); //Start at character 0 on line 1  
32:   lcdi2c.printf("Use Serial Mon");  
33:   lcdi2c.setCursor(0,1);  
34:   lcdi2c.printf("Type to display");    
35:  }  
36:  void loop() {  
37:    // when characters arrive over the serial port...  
38:    if (Serial.available()) {     
39:     delay(100);          // wait a bit for the entire message to arrive      
40:     lcdi2c.clear();  
41:     // read all the available characters  
42:     while (Serial.available() > 0) {      
43:      lcdi2c.write(Serial.read());          // display each character to the LCD  
44:     }  
45:    }  
46:  }  

วันเสาร์ที่ 9 กรกฎาคม พ.ศ. 2559

Pinguino กับ LCD Keys pad shield part 2


               จากบทความที่แล้วเราสามารถติดต่อกับ LCD shield และแสดงข้อความออกที่หน้าจอได้แล้ว ในบทความต่อเนื่องชิ้นนี้เราจะมาเขียนโค้ดเพื่อให้ LCD Keys pad shield ทำงานได้เหมือนอย่างเดโมของ Arduino ที่แสดงใน link ของ shield ในบทความที่ผ่านมา ซึ่งนั่นรวมถึงการอ่านค่าจาก keys ผ่านทาง ADC โมดูล และการอัพเดทเวลาทุกๆ 1 วินาทีแล้วแสดงผล ซึ่งเดี๋ยวเราจะมาดูกันทีละส่วนครับ

               จาก schematic ของ LCD Keys pad shield เราจะเห็นว่ามีสวิตซ์กด(keys) อยู่ทั้งหมด 6 สวิตซ์ โดย 5 ใน 6 สวิตซ์ต่อเข้ากับวงจรแบ่งแรงดันและแรงดันเอ้าต์พุตต่อเข้ากับ analog input(A0) เพราะจำนวน I/O ของ Arduino มีจำกัดหากต่อแต่ละสวิตซ์เข้า I/O จะต้องใช้ถึง 5 I/O แต่หากใช้ตัวต้านทานต่อเป็นวงจรแบ่งแรงดันร่วมกับ ADC ก็จะลดจำนวน I/O ลงได้มาก ส่วนอีกสวิตซ์จะเป็น RESET ครับ


               สำหรับ Pinguino นั้นมี library สำหรับอ่านค่าจาก ADC โมดูลที่เหมือนกับของ Arduino เป๊ะแถมความละเอียดยังเป็น 10 บิตเท่ากันอีกด้วย นั่นหมายความว่าเราสามารถ copy โค้ดเดโมของ Arduino มาใช้ใน Pinguino ได้เลย ง่ายดีไหมละครับ โดยโค้ดในส่วนการอ่านค่าสวิตซ์จะเป็นดังนี้ครับ

1:  int adc_key_in = 0;  
2:  #define btnRIGHT 0  
3:  #define btnUP   1  
4:  #define btnDOWN  2  
5:  #define btnLEFT  3  
6:  #define btnSELECT 4  
7:  #define btnNONE  5  

8:  int read_LCD_buttons()  
9:  {  
10:   adc_key_in = analogRead(A0);   // read the value from the sensor  
11:   if (adc_key_in < 50)  return btnRIGHT;   
12:   if (adc_key_in < 195) return btnUP;   
13:   if (adc_key_in < 380) return btnDOWN;   
14:   if (adc_key_in < 555) return btnLEFT;   
15:   if (adc_key_in < 790) return btnSELECT;    
16:   return btnNONE; // when all others fail, return this...  
17:  }  


              เริ่มต้นจากการประกาศตัวแปรชื่อ adc_key_in ไว้สำหรับรับค่าจากการอ่านผลลัพธ์ของการแปลง A/D โดยในฟังก์ชัน read_LCD_buttons() จะมีการเรียกใช้ analogRead(A0) ซึ่งจะส่งค่าผลลัพธ์ของการแปลง A/D ของช่อง A0  มาเก็บไว้ในตัวแปรที่กล่าวข้างต้น จากนั้นจึงเปรียบเทียบค่า แล้วส่งผลลัพธ์ที่ถูกต้องกลับไปให้ฟังก์ชัน main ต่อไป โดยผลลัพธ์ที่จะส่งกลับไปก็คือตัวเลขที่ถูก define เอาไว้ก่อนแล้วเพื่อให้ง่ายในการเขียน หรืออ่านโค้ด ส่วนค่าตัวเลขที่นำมาเปรียบเทียบกับค่าที่อ่านจาก ADC นั้นเคยอ่านเจอว่าเจ้าของได้คำนวณ และวัดแรงดันตกคร่อมจริงเพื่อทดสอบ จากนั้นก็มีบวกค่าความคลาดเคลื่อนเข้าไปอีกค่าละประมาณ 50 จึงได้เป็นตัวเลขเหล่านี้ออกมา

             เมื่อมีฟังก์ชันอ่านค่าจากสวิตซ์แล้ว เราก็มาเขียนโค้ดในส่วนของ main(หรือ loop())กัน ซึ่งก็จะเป็นเพียงการเรียกใช้ฟังก์ชัน read_LCD_buttons() แล้วเขียนข้อความออกไปที่จอ LCD ให้ตรงกับสวิตซ์ที่กด( หรือตรงกับค่าที่ได้รับกลับมาหลังจากเรียกใช้ฟังก์ชัน read_LCD_buttons())เท่านั้นเอง โดยโค้ดในส่วนนี้จะเป็นดังนี้นะครับ


1:  lcd_key = read_LCD_buttons(); // read the buttons  
2:   switch (lcd_key)        // depending on which button was pushed, we perform an action  
3:   {  
4:    case btnRIGHT:  
5:     {  
6:     lcd.printf("RIGHT ");  
7:     break;  
8:     }  
9:    case btnLEFT:  
10:     {  
11:     lcd.printf("LEFT  ");  
12:     break;  
13:     }  
14:    case btnUP:  
15:     {  
16:     lcd.printf("UP  ");  
17:     break;  
18:     }  
19:    case btnDOWN:  
20:     {  
21:     lcd.printf("DOWN ");  
22:     break;  
23:     }  
24:    case btnSELECT:  
25:     {  
26:     lcd.printf("SELECT");  
27:     break;  
28:     }  
29:     case btnNONE:  
30:     {  
31:     lcd.printf("NONE ");  
32:     break;  
33:     }  
34:   }  


               อันสุดท้าย  ในตัวอย่างของ Arduino จะเห็นว่ามีตัวเลขที่เพิ่มค่าทุกๆวินาทีแสดงอยู่ด้วย ซึ่งในโค้ดเดโมจะมีการเรียกใช้ฟังก์ชัน millis() ซึ่งจะเป็นฟังก์ชันที่คืนค่าที่เพิ่มขึ้นทุกๆ 1 วินาที( millisecond ) กลับมาให้ เมื่อเราหารค่าทีได้คืนกลับมาด้วย 1000 เราก็จะได้ตัวเลขที่จะแสดงผลทุกๆ 1 วินาที ซึ่งโค้ดก็จะเป็นดังตัวอย่างข้างล่างนี้


1:  lcd.setCursor(9,1);      // move cursor to second line "1" and 9 spaces over  
2:  lcd.printf("%u", millis()/1000);   // display seconds elapsed since power-up  

               เมื่อเราเข้าใจทุกส่วนแล้วเราก็เอามารวมกันก็จะได้เป็นโค้ดเดโมที่ทำงานกับ LCD Keys pad shield ได้เหมือนกับ Arduino ทุกอย่างเลยครับ โค้ดตัวเต็มจะอยู่ข้างล่างนี้นะครับ แล้วลองดูวิดีโอผลลัพธ์การทำงานได้เลยครับ


1:  /*-----------------------------------------------------  
2:  Author: --<Ekkachai Muangrodpai>  
3:  www.picgetstart.blogspot.com  
4:  Date: 2016-07-09  
5:  Board:  Pinguino 8 by Jimmy + LCD Keypads Shield V.1  
6:  Description:  
7:  -Display a message on LCD Keypads Shield, and also read a keys through analog AN0.  
8:  -At the same time, display the second time too.  
9:   * LCD RS pin to digital pin 5  
10:   * LCD E pin to digital pin 4  
11:   * LCD D4 pin to digital pin 24  
12:   * LCD D5 pin to digital pin 18  
13:   * LCD D6 pin to digital pin 17  
14:   * LCD D7 pin to digital pin 16  
15:   * LCD R/W pin to ground  
16:   note:  
17:   - don't use lcd.print() and lcd.printf() in the same program.  
18:  -----------------------------------------------------*/  
19:  #define BACK_LIGHT  2    //LCD back light control by pin2  
20:  // define some values used by the panel and buttons  
21:  int lcd_key   = 0;  
22:  int adc_key_in = 0;  
23:  #define btnRIGHT 0  
24:  #define btnUP   1  
25:  #define btnDOWN  2  
26:  #define btnLEFT  3  
27:  #define btnSELECT 4  
28:  #define btnNONE  5  
29:  // read the buttons  
30:  int read_LCD_buttons()  
31:  {  
32:   adc_key_in = analogRead(A0);   // read the value from the sensor   
33:   if (adc_key_in < 50)  return btnRIGHT;   
34:   if (adc_key_in < 195) return btnUP;   
35:   if (adc_key_in < 380) return btnDOWN;   
36:   if (adc_key_in < 555) return btnLEFT;   
37:   if (adc_key_in < 790) return btnSELECT;    
38:   return btnNONE; // when all others fail, return this...  
39:  }  
40:  void setup( void) {  
41:    // put your setup code here, to run once:  
42:    pinMode(BACK_LIGHT, OUTPUT);  
43:    digitalWrite(BACK_LIGHT, HIGH);  
44:    // initialize the library with the numbers of the interface pins    
45:    lcd.pins(5, 4, 24, 18, 17, 16, 0, 0, 0, 0); // RS, E, D4 ~ D8    
46:    // set up the LCD's number of columns and rows:   
47:    lcd.begin(16, 2);  
48:    // Print a message to the LCD.  
49:    lcd.clear();  
50:    lcd.setCursor(0,0);  
51:    lcd.printf("Push the buttons"); // print a simple message  
52:  }  
53:  void loop( void ) {  
54:   lcd.setCursor(9,1);      // move cursor to second line "1" and 9 spaces over  
55:   lcd.printf("%u", millis()/1000);   // display seconds elapsed since power-up  
56:   lcd.setCursor(0,1);      // move to the begining of the second line  
57:   lcd_key = read_LCD_buttons(); // read the buttons  
58:   switch (lcd_key)        // depending on which button was pushed, we perform an action  
59:   {  
60:    case btnRIGHT:  
61:     {  
62:     lcd.printf("RIGHT ");  
63:     break;  
64:     }  
65:    case btnLEFT:  
66:     {  
67:     lcd.printf("LEFT  ");  
68:     break;  
69:     }  
70:    case btnUP:  
71:     {  
72:     lcd.printf("UP  ");  
73:     break;  
74:     }  
75:    case btnDOWN:  
76:     {  
77:     lcd.printf("DOWN ");  
78:     break;  
79:     }  
80:    case btnSELECT:  
81:     {  
82:     lcd.printf("SELECT");  
83:     break;  
84:     }  
85:     case btnNONE:  
86:     {  
87:     lcd.printf("NONE ");  
88:     break;  
89:     }  
90:   }    
91:  }  


วันพฤหัสบดีที่ 7 กรกฎาคม พ.ศ. 2559

Pinguino กับ LCD Keys pad shield part 1


               วันนี้ผมตั้งใจจะนำเสนอการใช้ Pinguino 8 บอร์ดเชื่อต่อกับจอ LCD โดยผมเลือกที่จะใช้ LCD Keys Pad Shield เพราะความสะดวก สามารถเสียบลงบนตัว Pinguino 8 ได้เลย  หาซื้อได้ง่าย และยังราคาถูกอีกด้วย ผมคิดว่าถูกกว่า และสะดวกกว่า ซื้อแล้วมา wiring สายเองเสียอีกครับ ผู้อ่านหลายๆท่านอาจจะมีอยู่แล้วกับตัวก็ได้ หรือถ้าใครยังไม่มีก็ลอง search หา ลองซื้อมาเล่นดูนะครับ ตัวที่ผมจะใช้จะมีหน้าตาประมาณในรูปข้างล่างนี้เลยครับ


รูปที่ 1 LCD Key pad shield ที่ใช้

คราวนี้เมื่อเราจะใช้งานเจ้า shield ตัวนี้เราก็จำเป็นจะต้องมี schematic รวมถึงตำแหน่งขาที่มันจะเชื่อมต่อกับบอร์ด Pinguino 8 ของเราเสียก่อนจึงจะสามารถเขียนโปรแกรมเพื่อใช้งานมันได้ ซึ่งผมใช้ schematic จากที่นี้ครับ
http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)
และอันนี้ก็ diagram ของมันครับ
ซึ่งใน link ข้างบนนั้นนอกจาก schematic แล้วยังมีโค้ดตัวอย่างที่ใช้กับ Arduino ให้อีกด้วยครับ ซึ่งเราสามารถ copy แล้วเอามา modify เพียงเล็กน้อยก็สามารถใช้งานกับบอร์ด Pinguino 8 ได้แล้วครับ

               หลังจากเราได้ schematic กับ pin diagram ของเจ้า LCD Key pad shield มาแล้ว เราก็ต้องมาดูว่าเจ้า Pinguino 8 นั้นมี pin number อะไรบ้างและมีการจัดเรียงบนบอร์ดอย่างไร  อันดับแรกคือ pin number ของ Pinguino ซึ่งใช้ PIC18F45K50 เราสามารถดูได้จาก link ต่อไปนี้ครับ หรือจะดูที่รูปที่ 2 เลยก็ได้ครับ

รูปที่ 2 Pinguino pin number
               จากรูปที่ 2 จะเห็นว่า Pinguino ได้กำหนดขาต่างๆของ PIC18F45K50 ไว้เป็นหมายเลขเพื่อให้เรียกใช้งานได้สะดวกคล้ายกับ Arduino ตัวอย่างเช่น ขา RB0 ก็จะเป็นขาหมายเลข 0 ขา RB1 ก็จะเป็นขาหมายเลข 1
ไล่เรียงกันไป ซึ่งแต่ละขาก็จะมีความสามารถแตกต่างกันไป คราวนี้พอผมเอามาทำเป็นบอร์ด Pinguino 8 แล้วพยายามจัดเรียงขาให้ได้ใกล้เคียงกับ Arduino ตำแหน่งขามันเลยไม่ได้เรียงกันเป็นลำดับเหมือนกับ Arduino ซึ่งอันนี้เป็นสิ่งที่ทำให้สับสนได้ง่ายโดยเฉพาะผู้เริ่มต้น แม้แต่กับตัวผมเองเมื่อแรกเริ่มก็งงจนเขียนโค้ดผิดแล้วงมหาสาเหตุอยู่หลายวันทีเดียว ดังนั้นที่บอร์ด Pinguino 8 ผมจึงมีเขียนหมายเลขกำกับเอาไว้ที่แต่ละขาเพื่อให้ง่ายเวลาใช้งานและเขียนโปรแกรม รูปที่ 3 และรูปที่ 4 แสดงตัวเลขกำกับแต่ละขาครับ

รูปที่ 3 pin number ฝั่ง digital

รูปที่ 4 pin number ฝั่ง analog

ทีนี้เมื่อเราพิจารณา pin diagram และ schematic ของ LCD Key pad shield กับหมายเลขกำกับบนบอร์ด Pinguino 8 ก็จะสามารถสรุปการเชื่อมต่อได้ดังต่อไปนี้ครับ
LCD Shield         Pinguino 8
D4                          24
D5                          18
D6                          17
D7                          16
RS                          5
E                            4
Back light              2
             Keys                       8 หรือ A0
               เมื่อเรารู้หมายเลขขาที่ใช้ในการเชื่อต่อแล้วเราก็สามารถเริ่มเขียนโค้ดเพื่อแสดงข้อความบนจอ LCD ได้แล้วครับ เริ่มต้นจากการ define ขา back light ก่อนเพื่อให้ง่ายในการเขียนโค้ด และ IDE รู้จักและเพิ่มในส่วนออโต้คอมพลีตให้เราด้วย 


 #define BACK_LIGHT  2    //LCD back light control by pin2  

และเราจะกำหนดขา back light ให้เป็นเอ้าต์พุท และสั่งให้เป็น on โดยส่ง logic high ออกไป ด้วยคำสั่ง


 pinMode(BACK_LIGHT, OUTPUT);  
 digitalWrite(BACK_LIGHT, HIGH);  

ถัดมาเราจึงทำการ initialize LCD ด้วยคำสั่ง

 lcd.pins(5,4,24,18,17,16,0,0,0,0);  //RS,E,D4,D5,D6,D7 in 4 bit mode  

ซึ่งค่าพารามิเตอร์ที่ส่งให้ฟังก์ชันจะเป็นหมายเลข I/O ของ Pinguino ที่เชื่อมต่อกับจอ LCD โดยตัวแรกจะเป็นขา RS, E, และตามมาด้วยขาดาต้า D4-D7 ตามลำดับ นี่เป็นในกรณีที่เชื่อมต่อจอ LCD ในแบบ 4 bit mode นะครับดังนั้นพารามิเตอร์ที่เหลือจึงใส่ค่าเป็น 0 สี่ตัว 


ต่อมาเราจำเป็นต้องกำหนดว่า LCD ที่เรากำลังใช้งานอยู่นั้นเป็นชนิดใด 16x2 หรือ 20x4 โดยใช้คำสั่งต่อไปนี้ครับ

 lcd.begin(16,2);              //collumn, row  

เมื่อมาถึงตรงนี้เราก็สามารถเริ่มใช้งานจอ LCD ได้แล้ว โดยผมจะทำการเคลียร์หน้าจอเสียก่อน จากนั้นจึงกำหนดให้เคอร์เซอร์ไปที่ตำแหน่งเริ่มต้นของแถวแรกซึ่งก็คือตำแหน่ง 0,0 แล้วจึงส่งข้อความออกไปแสดงดังตัวอย่างโค้ดข้างล่างนี้ครับ


 lcd.clear();  
 lcd.setCursor(0,0);              //collumn 0, first row  
 lcd.printf("Hello World!....");  

และนี่คือตัวอย่างโค้ดทั้งหมดครับ


1:  /*-----------------------------------------------------  
2:  Author: --<Ekkachai Muangrodpai>  
3:  Date: 2016-07-07  
4:  Board:  Pinguino 8 + LCD Key pad shield v1  
5:  Description: Display 'Hello World!' on LCD  
6:  LCD Shield           Pinguino 8  
7:  D4                   24  
8:  D5                   18  
9:  D6                   17  
10:  D7                  16  
11:  RS                  5  
12:  E                   4  
13:  Back light          2  
14:  -----------------------------------------------------*/  
15:  #define BACK_LIGHT  2    //LCD back light control by pin2  
16:  void setup() {  
17:    // put your setup code here, to run once:  
18:    pinMode(BACK_LIGHT, OUTPUT);  
19:    digitalWrite(BACK_LIGHT, HIGH);  
20:    lcd.pins(5,4,24,18,17,16,0,0,0,0);  //RS,E,D4,D5,D6,D7 in 4 bit mode  
21:    lcd.begin(16,2);              //collumn, row  
22:    lcd.clear();  
23:    lcd.setCursor(0,0);              //collumn 0, first row  
24:    lcd.printf("Hello World!....");  
25:  }  
26:  void loop() {  
27:    // put your main code here, to run repeatedly:  
28:  }  

เพิ่มเติม

วันอังคารที่ 5 กรกฎาคม พ.ศ. 2559

Pinguino สื่อสารผ่าน USB และ Com Port

               บทความนี้จะเขียนถึงการสื่อสารระหว่าง Pinguino บอร์ดกับคอมพิวเตอร์ โดยเรามีตัวเลือกว่าจะใช้ USB โมดูลในตัว PIC18F45K50 emulate เป็น com port สื่อสารกับคอมพิวเตอร์ผ่านทางโปรแกรมเทอร์มินอลต่างๆ  หรือจะใช้โมดูล USART ในตัวไมโครคอนโทลเลอร์สื่อสารแทนก็ทำได้ นอกจากนี้หากต้องการ USART มากกว่าหนึ่งโมดูลก็สามารถใช้ Software USART ที่มีเตรียมไว้ให้กับขา I/O อื่นๆได้อีก เดี๋ยวเรามาลองดูกันทีละโมดูลกันนะครับ

                USB CDC (Communication Device Class) คือการให้ USB ทำตัวเป็นตัวเชื่อมต่อสื่อสารแบบต่างๆ(https://en.wikipedia.org/wiki/USB_communications_device_class) แต่ที่ส่วนใหญ่เข้าใจกันก็คือ USB จำลองเป็น com port เมื่อเชื่อมต่อกับคอมพิวเตอร์ โดยใน Pinguino จะมีฟังก์ชันที่ช่วยในการใช้งาน USB CDC อยู่พอสมควร สิ่งที่เราต้องทำคือแค่เรียกใช้งานเท่านั้น ลองดูตัวอย่างโค้ดดังต่อไปนี้นะครับ

1:  void setup() {  
2:    // put your setup code here, to run once:  
3:    pinMode(USERLED,OUTPUT);    
4:  }  

5:  void loop() {  
6:    // put your main code here, to run repeatedly:  
7:     digitalWrite(USERLED, HIGH);  
8:     CDC.printf("On\n\r");  
9:     delay(1000);  

10:    digitalWrite(USERLED,LOW);  
11:    CDC.printf("Off\n\r");  
12:    delay(1000);  
13:  }  

               ตัวอย่างโค้ดนี้จะเหมือนกับในบทความที่ผ่านมาโดยสั่งให้ USER LED ติด และ ดับ ทุกๆ 1 วินาทีแล้วผมทำการเพิ่มให้มีการส่งข้อความว่า “On” เมื่อ USER LED ติดสว่าง และคำว่า “Off” เมื่อ USER LED ดับ จากบอร์ด Pinguino ไปยังคอมพิวเตอร์ผ่านทางสาย USB ที่เชื่อต่อนะแหละครับ โดยทางฝั่งคอมพิวเตอร์ผมก็ใช้โปรแกรมเทอร์มินอลมาอ่านหรือรับค่าแสดงข้อความ โดยสามารถกำหนด baud rate เท่าไหร่ก็ได้เพราะตัว USB จะจัดการให้เอง สังเกตนะครับว่าผมเพียงแต่เรียกใช้ฟังกชัน CDC.printf() เท่านั้นไม่จำเป็นต้องเซ็ทอัพโมดูล USB ใดๆก่อนเลยค่อนข้างสะดวกมากครับ ลองดูวิดีโอประกอบด้านล่างได้ครับ



               USART ( Universal Synchronous Asynchronous Receiver Transmitter ) เป็นโมดูลสื่อสารแบบอนุกรมที่นิยมมากแบบหนึ่งสำหรับไมโครคอนโทรลเลอร์ ใช้ติดต่อสื่อสารกับอุปกรณ์หรือเครื่องมือต่างๆได้มากมาย เช่น Bluetooth, RF, และอื่นๆ รวมถึงใช้สื่อสารกับคอมพิวเตอร์ได้อีกด้วย โดยก่อนเริ่มสื่อสารนั้นจำเป็นต้องกำหนด baud rate หรือความเร็วในการสื่อสารให้ตรงกันทั้งสองฝ่ายเสียก่อน โดยในตัวอย่างต่อไปนี้จะเซ็ทอัพให้ Pinguino สื่อสารกับคอมพิวเตอร์ที่ baud rate เท่ากับ 9600 bits per second ไม่มี hardware flow control ดาต้าบิทเท่ากับ 8 ไม่มี parity และมีเพียง 1 stop bit. โดยสามารถดูได้จากตัวอย่างข้างล่างนี้ครับ


1:  void setup() {  
2:    // put your setup code here, to run once:  
3:    pinMode(USERLED, OUTPUT);  
4:    Serial.begin(9600);  
5:  }  
6:  void loop() {  
7:    // put your main code here, to run repeatedly:  
8:     digitalWrite(USERLED, HIGH);  
9:     Serial.printf("LED On\n\r");  
10:    delay(1000);  

11:    digitalWrite(USERLED, LOW);  
12:    Serial.printf("LED Off\n\r");  
13:    delay(1000);  
14:  }  
              
              จากโค้ดตัวอย่างจะเห็นว่าเราเพียงจำเป็นต้องเซ็ท baud rate ที่เราต้องการในส่วน setup() ก่อนเริ่มใช้งาน USART โดยเรียกใช้ฟังก์ชัน Serial.begin() หลังจากนั้นเราก็สามารถใช้งานฟังก์ชัน Serial.printf() ในการส่งข้อความขึ้นไปยังคอมพิวเตอร์ผ่านทาง USART ได้แล้ว ตัวอย่างนี้จะเหมือนกับตัวอย่างแรกเกือบทั้งหมดเพียงเปลี่ยนมาใช้ USART แทน CDC เท่านั้น  ในการทดสอบเราจำเป็นต้องมี usb-to-serial มาต่อเข้ากับขา Tx และ Rx ของบอร์ด Pinguino ดังแสดงในรูปข้างล่างนี้นะครับ แล้วเราก็ใช้โปรแกรมเทอร์มินอล connect เข้ากับ com port ของ usb-to-serial นั้นๆก็จะสามารถเห็นข้อความ “LED On” และ “LED Off” สลับกันตามจังหวะการติด ดับ ของ USER LED  ลองดูวิดีโอดูครับ


รูป บอร์ด Pinguino เชื่อมต่อกับ USB-to-Serial



               Software Serial เป็นการใช้ขา I/O ของไมโครคอนโทลเลอร์มาทำงานให้เหมือนขา Tx และ Rx ของ USART บางครั้งก็เรียกว่า Bit Bang Serial  โดยทั่วไปในไมโครคอนโทลเลอร์ตัวเล็กๆ หรือไมโครคอนโทลเลอร์รุ่นเก่าๆ จะมี USART เพียงแค่ตัวเดียว แต่บางครั้งงานที่เรากำลังทำอยู่นั้นจำเป็นต้องใช้ USART มากกว่าหนึ่ง จะเปลี่ยนไมโครคอนโทลเลอร์เป็นตัวที่ใหญ่ขึ้นก็เปลืองและไม่ง่ายนัก Software Serial จึงเป็นทางออกที่น่าจะเหมาะสมกว่า แต่มันก็มีข้อจำกัดของมันเช่น ใช้กับการสื่อสารที่ baud rate สูงมากไม่ค่อยได้ ต้องคำนวณคาบเวลาของแต่ละบิต ครึ่งบิต ให้แม่นยำและเขียนโปรแกรมให้ถูกต้องด้วย ซึ่งก็ค่อนข้างยากและเสียเวลามากพอสมควร
                ใน Pinguino นี้ได้จัดเตรียมไลบรารี่ Software Serial ไว้ให้เราเรียกใช้งานได้อย่างง่ายดาย เราเพียงแค่ต้องกำหนดว่าจะใช้ PORT ใด และขาไหนให้เป็นขา Tx และ Rx รวมถึงค่า baud rate ที่ต้องการไว้ที่ส่วนบนของโปรแกรมที่เรากำลังจะเขียนดังตัวอย่างต่อไปนี้ ที่จะใช้ PORTB ขา RB4 เป็น Tx และขา RB5 เป็น Rx โดยกำหนด baud rate ไว้ที่ 9600 bits per second ดังตัวอย่างข้างล่างนี้

 #define SWBAUDRATE 9600// or 57600, 38400, 19200, 9600, 4800  
 // other baudrates 115200 2400 1200 were tried but did not work perfectly   
 #define _SW_PORT _PORTB // Transmit pin port and pin  
 #define TXDpin 4   
 #define RXDpin 5   
 #define SW_PORT_TXDpin PORTBbits.RB4   
 #define SW_TRIS_TXDD TRISBbits.TRISB4   
 #define SW_PORT_RXDpin PORTBbits.RB5   
 #define SW_TRIS_RXDD TRISBbits.TRISB5   
               
              ถัดมาก็จำเป็นต้องกำหนดให้ขา Tx เป็นเอ้าพุตเพื่อให้สามารถ on/off (bit bang) pin เพื่อให้สามารถส่งดาต้าออกไปจากไมโครคอนโทลเลอร์ได้ และกำหนดค่าเริ่มต้นของทั้งขา Tx และ Rx ให้เป็น high( 1 ) ก่อนดังตัวอย่างข้างล่างนี้ครับ ซึ่งเซ็ทอยู่ใน setup() ฟังก์ชัน


 SW_TRIS_TXDD = 0;  
 SW_PORT_TXDpin = 1;  
 SW_TRIS_RXDD = 1;  

หลังจากนั้นเราก็สามารถเรียกใช้งานฟังก์ชันของ Software Serial ได้อย่างง่ายดายเหมือนฟังก์ชัน Serial ในตัวอย่างที่สองที่ผ่านมาได้ ลองดูตัวอย่างโค้ดทั้งหมดได้ครับ


1:  #define SWBAUDRATE 9600// or 57600, 38400, 19200, 9600, 4800  
2:  // other baudrates 115200 2400 1200 were tried but did not work perfectly   
3:  #define _SW_PORT   _PORTB      // Transmit pin port and pin  
4:  #define TXDpin   4  // or 0, 2, 6  
5:  #define RXDpin   5  // or 1, 3, 7  
6:  #define SW_PORT_TXDpin   PORTBbits.RB4  // or 0, 2, 6  
7:  #define SW_TRIS_TXDD    TRISBbits.TRISB4 // or 0, 2, 6  
8:  #define SW_PORT_RXDpin   PORTBbits.RB5  // or 1, 3, 7  
9:  #define SW_TRIS_RXDD    TRISBbits.TRISB5 // or 1, 3, 7  

10:  void setup() {  
11:    SW_TRIS_TXDD = 0;  
12:    SW_PORT_TXDpin = 1;  
13:    SW_TRIS_RXDD = 1;  
14:    pinMode(USERLED, OUTPUT);  
15:  }  

16:  void loop() {   
17:    digitalWrite(USERLED, HIGH);  
18:    SwSerial.printf("USER LED On\n\r");  
19:    delay(1000);  
20:    digitalWrite(USERLED, LOW);  
21:    SwSerial.printf("USER LED Off\n\r");  
22:    delay(1000);  
23:  }  


USB-to-Serial ต่อเข้ากับขา 4,5 (Pinguino) หรือขา 8,9(Arduino)







วันพุธที่ 22 มิถุนายน พ.ศ. 2559

เริ่มต้นกับ Pinguino



วันนี้ผมจะมาแนะนำ platform สำหรับพัฒนาไมโครคอนโทรลเลอร์ของ PIC mcu ที่มีความง่ายเหมือนกับ Arduino นะครับ ซึ่งเจ้า platform ตัวนี้มีชื่อว่า Pinguino ซึ่งใช้ PIC mcu ที่มีโมดูล USB ภายในมาเป็นตัวสื่อสารกับ PC เพื่อโปรแกรม .hex ไฟล์ลงไปในตัว mcu โดยที่ตัว PIC mcu เองจะมี bootloader อยู่ภายในคอยสื่อสารและรับข้อมูลมาเขียนลง Flash เอง ก็เหมือนกับ Arduino นั่นแหละครับเพียงแต่ไม่ต้องมี usb-to-serial อย่างพวก FTDI หรือ CH3404 นั่นเองทำให้ออกแบบง่ายขึ้นเยอะ

โดย Pinguino จะมีทั้ง mcu 8 bit และ 32 bit ทางด้าน 8 bit จะเป็นเบอร์ PIC18F2550, PIC18F4550, PIC18F45K50 และอีกหลายๆเบอร์  ส่วนทางด้าน 32 bit จะมีเบอร์ PIC32MX250F128B, PIC32MX270F128B, PIC32MX795F512L และอีกหลายตัวเลือก ในบทความนี้ผมเลือกใช้ PIC18F45K50 เพราะใช้ไฟ 5 V. , มี internal oscillator ที่มีความแม่นยำสูง ทำให้สามารถทำ application USB โดยไม่ต้องต่อ crystal ข้างนอก ซึ่งก็จะประหยัดไปได้อีก และขา I/O ที่ปกติต้องต่ออยู่กับ crystal ก็จะว่างสามารถนำมาใช้งานเพิ่มได้อีก และสุดท้ายเจ้า PIC18F45K50 นั้นจะใหม่กว่า PIC18F4550 แถมยังราคาถูกกว่าอีกด้วยครับ


            สำหรับ hardware ผมได้ออกแบบให้คล้ายกับ Arduino UNO มากที่สุดเพื่อที่จะได้ใช้กับ shield ต่างๆที่มีขายอยู่มากมาย แต่ด้วยข้อจำกัด และความแตกต่างระหว่าง PIC18F45K50 กับ ATMEGA328P จึงทำได้แค่ใกล้เคียงไม่สามารถแทนกันได้ 100% แล้วเดี๋ยวเราจะค่อยๆมาดูกันครับว่า Pinguino สามารถทำได้ขนาดไหน

รูปที่ 1 schematic
ข้างบนนี้คือ schematic ของ board Pinguino 8 ครับ

รูปที 2 Board Pinguino 8

ทางด้านซ้ายนี้คือหน้าตาของ board ครับ
ใช้ PIC18F45K50 ตัว 40 ขาครับ หลังจากเชื่อมต่อ USB แล้วยังมีขา I/O อีกเหลือเฟือเลยครับ
ราคาก็ใกล้เคียงกับตัว 28 ขาอีกด้วยครับ











รูปที่ 3 อีกมุมนึง
         Crystal ไม่ได้ใช้ครับ ใช้ internal RC แทนครับ แต่สามารถเพิ่ม Crystal ภายหลังได้กรณีต้องการใช้กับ mcu ตัวเก่าเช่น PIC18F4550

         ทางด้าน software พัฒนาเราสามารถใช้ตัว IDE ของ Pinguino เองในการเขียน firmware ส่วนตัว compiler นั้นจะเป็น SDCC สำหรับ 8 bit mcu ซึ่งเราสามารถไปโหลดได้ที่ www.pinguino.cc ครับ แล้วเลือกไปที่แท็บ download จากนั้นก็โหลดตัวติดตั้งสำหรับ windows มา

หมายเหตุ 1: ในขณะที่เขียนบทความนี้ทาง pinguino.cc มี IDE V.11 ที่เป็นตัว stable อยู่ และกำลังทดสอบ IDE V.12 ครับ ตัว installer ที่โหลดมานั้น เมื่อจะติดตั้งต้องต่อ internet ด้วยนะครับ เมื่อคลิ้กติดตั้งไปแล้ว สามารถเลือกได้ว่าจะติดตั้ง IDE V.11 หรือ IDE V.12 หรือทั้งสองตัวก็ได้ โดยตัวติดตั้งจะไปโหลดไฟล์ IDE, Library, compiler, Python 2.7 มาไว้ในคอมพิวเตอร์ของเราแล้วติดตั้งให้ครับ

หมายเหตุ 2: โดยส่วนตัวผมลองติดตั้งตาม หมายเหตุ 1 แล้วแต่ไม่สำเหร็จ ทั้ง IDE V.11 และ IDE V.12 เลย ทดลองเปลี่ยนเครื่องคอมพิวเตอร์ที่มี Windows 7 32 bit ก็ฟลุกติดตั้ง IDE V.11 ได้ครั้งเดียว แต่ตัว IDE V.12 นี่ไม่ได้เลยครับ :<  แล้วตัวติดตั้งเองทุกครั้งที่ลองติดตั้งใหม่ มันก็พยายามไปโหลดไฟล์ต่างๆมาใหม่ ทั้งๆที่ไฟล์ทุกอย่างก็โหลดมาหมดแล้ว ค่อนข้างเสียเวลาครับ

            อีกทางเลือกในการติดตั้ง Pinguino IDE ที่ผมลองแล้วใช้ได้ ง่ายด้วย คือใช้ตัว installer เวอร์ชั่นเก่าที่ตอนนี้ทาง pinguino.cc เอาออกไปไว้ไหนแล้วก็ไม่รู้ แต่ผมมีเซพเก็บไว้แล้วผู้อ่านสามารถโหลดไปติดตั้งได้เลยครับจากลิ้งค์ข้างล่างนี้นะครับ


โดยตัว installer นี้ก็ต้องต่อ internet ในตอนติดตั้งนะครับแล้วมันจะไปโหลดไฟล์ที่จำเป็นมาให้ ผมทดลองติดตั้งกับคอมพิวเตอร์หลายเครื่องแล้วใช้งานได้ทุกครั้งครับ และถ้ามีไฟล์ต่างๆอยู่ในโฟลเดอร์เดียวกันกับตัวติดตั้งอยู่แล้วมันก็รู้และไม่ไปโหลดมาใหม่อีกครับ ง่ายมากเลย
            หลังจากติดตั้งตัว IDE เสร็จแล้ว เมื่อเราเปิดโปรแกรมขึ้นมาก็จะมีหน้าตาสวยงามดังรูปที่ 4 จากนั้นคลิ้กเลือก New ก็จะมีไฟล์ที่มีฟังก์ชั่น setup() และ loop() มาให้เราเสร็จสรรพพร้อมเริ่มต้นเขียน
โปรแกรมกันเลยครับ
รูปที่ 4 หน้าตา IDE


            และโปรแกรมแรกจะเป็นอะไรไปไม่ได้นอกจากไฟกระพริบ ใช่ไม๊ครับ โดยเราเริ่มจากกำหนดขาที่ต่ออยู่กับ LED ให้เป็น output ซึ่งเรากำหนดเพียงครั้งเดียวเราจึงควรกำหนดในฟังก์ชัน setup() จากนั้นเราก็จะสั่งให้ขาเอ้าพุตนั้นเป็น high เพื่อให้ LED ติดสว่างและต้องหน่วงเวลาไว้เพื่อให้เราสามารถมองเห็นการติดดับได้ จากนั้นจึงสั่งขาเอ้าพุตเดิมให้เป็น low เพื่อให้ LED ดับและก็ต้องหน่วงเวลาไว้เช่นกัน แล้วจึงวนกลับไปสั่งให้ LED ติดสว่างอีก วนทำงานอยู่อย่างนี้ไปเรื่อยๆ ดังนั้น code ส่วนนี้จึงควรเขียนในฟังก์ชัน loop() ตัวอย่างโค้ดอยู่ข้างล่างนี้ครับ



 void setup() {  
   // put your setup code here, to run once:  
   pinMode(USERLED,OUTPUT);  
 }  
 void loop() {  
   // put your main code here, to run repeatedly:  
   digitalWrite(USERLED, HIGH);  
   delay(300);  
   digitalWrite(USERLED,LOW);  
   delay(300);  
 }  

         หลังจากเขียนโค้ดเสร็จแล้วควรจะ save เก็บให้เรียบร้อยซะก่อน จากนั้นเราก็มาเลือก mcu ว่าเป็น 8 bit หรือ 32 bit ใช้ bootloader ใช่ไม๊ version ไหน และ mcu เบอร์อะไรแน่ สำหรับ board Pinguino 8 นั้น จะเป็น 8 bit mcu เบอร์ PIC18F45K50 และใช้ bootloader version 4.15  เมื่อเราเลือกถูกต้องแล้วก็สามารถกด compile โค้ดได้ซึ่ง Pinguino จะ compile เร็วกว่า Arduino มาก( อันนี้ชอบมาก ) หลังจาก compile เสร็จแล้วก็จะมี pop-up ขึ้นมาถามว่าจะโปรแกรมลงบอร์ดเลยหรือเปล่า
ถ้าต่อบอร์ดไว้อยู่แล้ว ให้กดปุ่ม Reset บนบอร์ดก่อนครับ RUN LED ก็จะกระพริบถี่ๆเพื่อบอกให้เรารู้ว่า mcu กำลังอยู่ในโหมด bootloader( ตอนเริ่มจ่ายไฟให้กับบอร์ด mcu จะไม่เข้าโหมด bootloader นะครับ จะเริ่มทำงานที่ user program ทันที ถ้าไม่มี user program อยู่ก็จะไม่มีอะไรเกิดขึ้นให้เราเห็น ต้องกดปุ่ม RESET ก่อน mcu ถึงจะเข้าสู่โหมด bootloader ) เราก็สามารถกดโปรแกรมบนคอมพิวเตอร์ได้เลยครับ ( ไม่ต้องรีบร้อนนะครับ mcu จะยังคงอยู่ในโหมด bootloader ตราบเท่าที่เรายังไม่โปรแกรมลงไป ) เมื่อเราโปรแกรมสำเร็จแล้วก็จะเห็น RUN LED( ดวงเดียวกับ USER LED ครับ เมื่อเวอร์ชันก่อนใช้ชื่อ RUN LED ตอนหลังเปลี่ยนมาเป็น USER LED แต่ RUN LED ก็ยังใช้ได้นะ ) กระพริบช้าๆตามที่เราเขียนเอาไว้เลยครับ ลองดูวิดีโอกันก่อนครับ


   
           โค้ดตัวอย่างข้างบนเขียนในแบบ Arduino Style ใน Pinguino สามารถเขียนให้ง่ายกว่านี้อีกครับลองดูโค้ดต่อจากนี้เทียบกันดูครับ


 void setup()  
 {  
   // initialize the digital pin USERLED as an output.  
   pinMode(USERLED, OUTPUT);     
 }  
 void loop()  
 {  
   toggle(USERLED);             // alternate ON and OFF  
   delay(300);                     // wait for 300ms  
 }  

         อีกแบบหนึ่งสำหรับคนที่คุ้นเคยกับการเขียนแบบกำหนดค่าใน register โดยตรงก็สามารถทำได้แบบนี้ครับ

 void setup()  
 {  
   // initialize the digital pin USERLED as an output.  
   TRISAbits.TRISA4 = 0;     
 }  
 void loop()  
 {  
   LATAbits.LATA4 = 1;             // Turn LED on  
   delay(300);                 // wait for 300ms  
      LATAbits.LATA4 = 0;             // Turn LED off  
   delay(300);                 // wait for 300ms  
 }  

          ทั้งสามแบบให้ผลลัพธ์เหมือนกันครับ เพียงแต่แบบที่สามจะมีขนาดโค้ดเล็กกว่าพอสมควร ลองสไตร์ที่ชอบดูครับ นอกจากนี้ยังสามารถดูเพิ่มเติมได้จากลิ้งข้างล่างนี้ได้นะครับ ตอนนี้ขอจบก่อนครับ ขอบคุณครับ

http://wiki.pinguino.cc/index.php/6_ways_to_blink_the_built-in_Led