หน้าเว็บ

วันศุกร์ที่ 22 กุมภาพันธ์ พ.ศ. 2556

เฉลยโจทย์การแข่งขันทักษะอาชีวะศึกษา ไมโครคอนโทรลเลอร์ระดับประเทศ ปวส.อิเล็กทรอนิกส์ ปีการศึกษา 2555 
การติดต่อและใช้งานโมดูล RFID (15 คะแนน)




4. ทำการเชื่อมต่อบอร์ดอ่าน RFID เข้ากับบอร์ด UNICON รวมทั้งต่อสวิตช์ SW1 และ LED1 จากนั้นเขียนโปรแกรมเพื่ออ่านค่า RFID โดยให้ผลลัพธ์รูปแบบดังนี้
4.1 อ่านค่าจาก RFID นำค่ามาแสดงผลที่หน้าจอ GLCD เป็นตัวอักษร 10 หลักได้ (5 คะแนน)
สามารถตรวจสอบ RFID อันที่ต้องการได้
4.2 เมื่อนำ RFID อันที่ 1 มาอ่านหน้าจอ GLCD แสดงข้อความ “CORRECT!”  LED 1 ติดสว่าง นำการ์ดอันที่ 2 หรืออันอื่นๆ จากกรรมการหน้าจอ GLCD แสดงข้อความ “WRONG!” และ LED1 ดับ (5 คะแนน )
การเก็บค่ารหัสใน EEPROM
4.3 เมื่อทำการกดสวิตช์ SW1 จะต้องมีการบันทึกรหัสของ RFID อันที่อ่านล่าสุดเก็บในหน่วยความจำ EEPROM ซึ่งจะไม่ศูนย์หายไปเมื่อไม่มีไฟเลี้ยง ดังนั้นเมื่อทดลองถอดไฟเลี้ยงออกจากบอร์ด UNICON และจ่ายไฟเข้าไปใหม่อีกครั้ง  RFID อันที่อ่านล่าสุด เมื่อนำมาอ่านอีกครั้งจะต้องแสดงข้อความ “CORRECT” ส่วนใบอื่นๆ จะต้องแสดงข้อความ “WRONG” (5 คะแนน)


โปรแกรมนี้จะต้องอ่านค่าข้อมูลจากการ์ดจำนวน 10 ไบต์แล้วนำมาใช้เปรียบเทียบเพื่อหาการ์ดที่ถูกต้อง ซ้ำยังต้องบันทึกค่าที่อ่านได้ไว้ในหน่วยความจำอีอีพรอมด้วย โดยโปรแกรมมีดังนี้ครับ



Exported from Notepad++
#include <unicon.h> #include <EEPROM.h> int j,val=0; int address=0; char code[10]; char ref[10]; int bytesread = 0; void setup(){ Serial1.begin(2400); out(6,LOW); glcdMode(1); setTextSize(2); /* setTextColor(GLCD_GREEN);glcd(0,1,"Read EEPROM"); for(int i=0;i<10;i++){ ref[i]=EEPROM.read(i); }*/ setTextColor(GLCD_GREEN);glcd(0,1,"Ready "); } void loop(){ if(in(21)==0){ setTextColor(GLCD_SKY);glcd(0,1,"Write EEPROM"); for(int i=0;i<10;i++){ EEPROM.write(i,code[i]); } sleep(1000); setTextColor(GLCD_GREEN);glcd(0,1,"Read EEPROM"); for(int i=0;i<10;i++){ ref[i]=EEPROM.read(i); } } if(in(23)==0){ setTextColor(GLCD_GREEN);glcd(0,1,"Read EEPROM"); for(int i=0;i<10;i++){ ref[i]=EEPROM.read(i); } } if(Serial1.available()>0){ if((val=Serial1.read())==10){ bytesread=0; while(bytesread<10){ if( Serial1.available()>0){ val=Serial1.read(); if((val==10)||(val==13)){ break; } code[bytesread] = val; bytesread++; } } if(bytesread==10){ j=0; for(int i=0;i<10;i++){ if(code[i]==ref[i]){j++;} } if(j>9) {out(22,1);setTextColor(GLCD_BLUE);glcd(2,1,"CORRECT!"); } else {out(22,0);setTextColor(GLCD_RED);glcd(2,1,"WRONG!!!");} } out(6,HIGH);code[10]='$';setTextColor(GLCD_BLUE);glcd(5,1,code); bytesread= 0; setTextColor(GLCD_YELLOW);glcd(0,1,"Ready "); sleep(500); out(6,LOW);setTextColor(GLCD_GREEN);glcd(0,1,"Ready "); } } }

วันอังคารที่ 19 กุมภาพันธ์ พ.ศ. 2556

เฉลยโจทย์การแข่งขันทักษะอาชีวะศึกษา ไมโครคอนโทรลเลอร์ระดับภาค ปวส.อิเล็กทรอนิกส์ ปีการศึกษา 2555 ตอนจบ

4. ระบบควบคุมวิทยุ FM อย่างง่าย (35 คะแนน)




สร้างระบบเครื่องรับวิทยุ FM แบบดิจิตอล โดยใช้การควบคุมจากสวิตช์และรีโมตคอนโทรล โดยมีขั้นตอนการสร้างดังนี้
4.1 บัดกรีคอนเน็กเตอร์ IDC ตัวเมียที่บอร์ด UNICON เพื่อเตรียมสำหรับเชื่อมต่อขาพอร์ตด้วยสายกับบอร์ดตัวอื่นๆ
4.2 บัดกรีคอนเน็กเตอร์ IDC ตัวเมียและ RPACK ที่บอร์ดสวิตช์เมตริก 16 ช่อง
4.3 เชื่อมต่อสายจากสวิตช์เมตริกซ์เข้าที่บอร์ด UNICON โดยตำแหน่งขาจะเป็นขาใดๆ ก็ได้
4.4 เชื่อมต่อสายสัญญาณจากโมดูลรับ FM เข้ากับบอร์ด UNICON โดยตำแหน่งขาจะเป็นขาใดๆ ก็ได้
4.5 เชื่อมต่อโมดูลรับรีโมตคอนโทรลอินฟราเรดเข้ากับบอร์ด UNICON โดยตำแหน่งขาจะเป็นขาใดๆ ก็ได้
4.6 เชื่อมต่อจุด MUTE ของเครื่องขยายเสียงและต่อสายสัญญาณจากโมดูลรับ FM เข้ากับเครื่องขยายเสียง

4.7 เขียนโปรแกรมเพื่อรับค่าจากสวิตช์เมตริกและรีโมตคอนโทรลเพื่อนำไปควบคุมการทำงานของโมดูล FM สั่งให้โมดูล FM ทำงานตามรูปแบบต่าง ๆ โดยมีเกณฑ์การให้คะแนนดังนี้
4.7.1 เมื่อกดสวิตช์เมตริกที่ตำแหน่งทั้ง 16 ปุ่มมีค่าตัวเลขแสดงที่หน้าจอ GLCD ในตำแหน่งดังรูป (หน้าจอบรรทัดที่ 5 ขวาสุด) โดยแสดงเป็นค่าตัวเลข 0 ถึง 15 ถ้าไม่กดให้แสดงเป็นตัวเลข 16 (2 คะแนน)
4.7.2 โปรแกรมที่เขียนสามารถสั่งการแล้วรับสถานี FM สถานีใดสถานีหนึ่งได้ มีเสียงดังออกลำโพง (3 คะแนน)
4.7.3 หน้าจอในบรรทัดที่ 3 แสดงค่าสถานีที่รับได้ถูกต้อง ในรูปแบบ XX.XX MHz ความละเอียด .05 MHz เป็นอย่างน้อย
(2 คะแนน)
4.7.4 หน้าจอบรรทัดที่ 4 แสดงข้อความ RSSI:XX โดย XX คือค่าความแรงของสัญญาณตามจริง (ทดสอบโดยการต่อเสาอากาศ )
(2 คะแนน)
4.7.5 หน้าจอบรรทัดที่ 5 แสดงข้อความ Volume:XX โดย XX คือค่าความดังของเสียงตามจริง 0-15 (2 คะแนน )
4.7.6 เมื่อกดปุ่มต่อไปนี้ที่สวิตช์เมตริกซ์ ให้ผลลัพธ์ที่เกิดขึ้นที่โมดูล FM และหน้าจอ GLCD ตามตาราง (รวม 11 คะแนน)




















4.7.7 เมื่อกดสวิตช์ปุ่มใด ๆ ที่รีโมตคอนโทรล หน้าจอ GLCD จะต้องแสดงค่าที่อ่านได้จากรีโมตคอนโทรล ในตำแหน่งดังรูป (หน้าจอบรรทัดที่ 4 ขวาสุด ) ( 2 คะแนน)
4.7.8 เมื่อกดปุ่มต่อไปนี้ที่ รีโมตคอนโทรลให้ผลลัพธ์ที่เกิดขึ้นที่โมดูล FM และหน้าจอ GLCD ตามตาราง (รวม 11 คะแนน)


















โปรแกรมควบคุมการทำงานด้วย Arduino มีดังนี้
(โปรแกรมตัวอย่างทั้งหมดยังไม่สมบูรณ์มากนัก ฝากน้อง ๆ นักศึกษา ไปพัฒนาต่อนะครับ)


Exported from Notepad++
#include #include // config[0] |Output:ON |Mute:OFF|MONO:OFF|BASS:ON|CLK32:EN| // config[1] |ClkMode:32.768kHz|SoftReset:OFF|POWER:ON| // config[2] |CHAN:0001000110=70*50kHz+8700=90.5 MHz| // config[3] |TUNE:DIS|BAND:87-108|SPACE:50kHz| // config[4] |SeekInt:DIS|DE:75uS| // config[5] |I2SEN:DIS|GPIO3:HIZ|GPIO2|HIZ|GPIO1:HIZ| // config[6] |IntMode:untilRead|SEEKTH:RSSI=6| // config[7] |LNA:DualPort|LNA:2.1mA|Vol:3| unsigned char config[10] = { 0xD0,0x01,0x11,0x82,0x04,0x00,0x86,0xd3,0x40,0x00}; unsigned int sw[16] ={ 385,426,461,492,536,560,582,602,629,645,660,673,692,704,714,724}; unsigned char indicator[4]; unsigned char i,freq1,freq2,vol=3,rssi,kp; unsigned int a,b,x,channel; int RECV_PIN = 30; // Coonect the ZX-IRM with pin 6 of Unicon IRrecv irrecv(RECV_PIN); decode_results results; boolean flag_=false,BASS_Flag=false,MONO_Flag=false,MUTE_Flag=false,ampMuteflag=false; int sw16(){ x=16; for(i=0;i<16;i++){ a=sw[i]-4; b=sw[i]+4; if((analog(7)>a)&&(analog(7)<b)){ x=i; } } return x; } void rdStatus(){ Wire.requestFrom(0x20>>1,4); for (i=0;i<4;i++){ indicator[i]=Wire.read(); } channel=indicator[0]<<8|indicator[1]; channel=channel&0x3FF; channel=(channel*5)+8700; rssi=indicator[2]>>2; } void wrConfig(){ Wire.beginTransmission(0x20>>1); for (i=0;i<10;i++){ Wire.write(config[i]); } Wire.endTransmission(); //Show(); } void Show(){ setTextSize(1); setTextColor(GLCD_BLACK); if (BASS_Flag){ setTextBackgroundColor(GLCD_RED); } else { setTextBackgroundColor(GLCD_BLACK); } glcd(0,0,"BASS"); setTextBackgroundColor(GLCD_RED); if (MONO_Flag){ glcd(0,5,"MONO"); } else { glcd(0,5," ST "); } if (MUTE_Flag){ setTextBackgroundColor(GLCD_RED); } else { setTextBackgroundColor(GLCD_BLACK); } glcd(0,10,"MUTE"); if (!ampMuteflag){ setTextBackgroundColor(GLCD_RED); } else { setTextBackgroundColor(GLCD_BLACK); } glcd(0,20,"AMP"); setTextSize(2); setTextColor(GLCD_WHITE); setTextBackgroundColor(GLCD_BLACK); } void SoftReset(){ bitWrite(config[1],1,HIGH); wrConfig(); bitWrite(config[1],1,LOW); } void PowerUp(){ bitWrite(config[3],4,HIGH); bitWrite(config[1],0,HIGH); wrConfig(); bitWrite(config[3],4,LOW); flag_=true; } void PowerOff(){ bitWrite(config[1],0,LOW); wrConfig(); flag_=false; } void Power(){ if (flag_){ PowerOff(); glcd(1,0,"POWER OFF "); } else{ PowerUp(); glcd(1,0,"POWER UP "); } } void ampMute(){ if (ampMuteflag==0){ ampMuteflag=1; glcd(1,0,"AMP MUTE "); } else{ ampMuteflag=0; digitalWrite(9,LOW); glcd(1,0,"AMP ON "); } } void VolUp(){ vol=config[7]&0x0F; if(vol<15){ vol++; } config[7]=(config[7]&0xF0)+vol; wrConfig(); glcd(1,0,"Volume UP "); } void VolDown(){ vol=config[7]&0x0F; if(vol>0){ vol--; } config[7]=(config[7]&0xF0)+vol; wrConfig(); glcd(1,0,"Volume Down "); } void FreqUp(){ bitWrite(config[3],4,HIGH); if (bitRead(config[3],7)&&bitRead(config[3],6)){ config[2]=config[2]++; bitWrite(config[3],7,LOW); bitWrite(config[3],6,LOW); } else{ config[3]=config[3]+64; } wrConfig(); bitWrite(config[3],4,LOW); glcd(1,0,"Freq Up "); } void FreqDown(){ bitWrite(config[3],4,HIGH); if (!bitRead(config[3],7)&&!bitRead(config[3],6)){ config[2]=config[2]--; bitWrite(config[3],7,HIGH); bitWrite(config[3],6,HIGH); } else{ config[3]=config[3]-64; } wrConfig(); bitWrite(config[3],4,LOW); glcd(1,0,"Freq Down "); } void SeekUp(){ bitSet(config[0],1); bitSet(config[0],0); wrConfig(); bitClear(config[0],1); bitClear(config[0],0); glcd(1,0,"Seek Up "); } void SeekDown(){ bitClear(config[0],1); bitSet(config[0],0); wrConfig(); bitClear(config[0],0); glcd(1,0,"Seek Down "); } void BASS_OFF(){ bitClear(config[0],4); wrConfig(); BASS_Flag=0; } void BASS_ON(){ bitSet(config[0],4); wrConfig(); BASS_Flag=1; } void BASS(){ if(BASS_Flag){ BASS_OFF(); glcd(1,0,"BASS OFF "); } else{ BASS_ON(); glcd(1,0,"BASS ON "); } } void MONO_ON(){ bitSet(config[0],5); wrConfig(); MONO_Flag=1; } void MONO_OFF(){ bitClear(config[0],5); wrConfig(); MONO_Flag=0; } void MONO(){ if(MONO_Flag){ MONO_OFF(); glcd(1,0,"STEREO "); } else{ MONO_ON(); glcd(1,0,"MONO "); } } void MUTE_ON(){ bitClear(config[0],6); wrConfig(); MUTE_Flag=1; } void MUTE_OFF(){ bitSet(config[0],6); wrConfig(); MUTE_Flag=0; } void MUTE(){ if(MUTE_Flag){ MUTE_OFF(); glcd(1,0,"MUTE OFF "); } else{ MUTE_ON(); glcd(1,0,"MUTE ON "); } } void setup(){ setTextSize(2); glcdMode(3); Wire.begin(); irrecv.enableIRIn(); // Enable IR module MUTE_OFF(); BASS_OFF(); MONO_OFF(); Show(); VolUp(); PowerUp(); } void loop(){ kp=sw16(); glcd(5,11,"%d ",kp); switch (kp){ case 0: SeekUp(); break; case 1: SeekDown(); break; case 2: FreqUp(); break; case 3: FreqDown(); break; case 4: VolUp(); break; case 5: VolDown(); break; case 6: Power(); break; case 7: MUTE(); break; case 8: MONO(); break; case 9: BASS(); break; case 10: ampMute(); break; } if (irrecv.decode(&results)) // Check the remote control data available { if (results.decode_type == SONY) // Check type of the SONY's remote control protocal { glcd(4,9,"%d ",results.value); irrecv.resume(); switch (results.value){ case 144: SeekUp(); break; case 2192: SeekDown(); break; case 752: FreqUp(); break; case 2800: FreqDown(); break; case 1168: VolUp(); break; case 3216: VolDown(); break; case 2704: Power(); break; case 656: MUTE(); break; case 720: MONO(); break; case 3280: BASS(); break; case 2672: ampMute(); break; } } else { glcd(4, 8, "Err "); // Another is unknown } } rdStatus(); freq1=channel/100; freq2=channel%100; glcd(3,0,"%d.%d%d MHz ",freq1,(freq2/10),(freq2%10)); glcd(4,0,"RSSI:%d ",rssi); glcd(5,0,"Volume:%d ",vol); Show(); }
เฉลยโจทย์การแข่งขันทักษะอาชีวะศึกษา ไมโครคอนโทรลเลอร์ระดับภาค ปวส.อิเล็กทรอนิกส์ ปีการศึกษา 2555 ตอนที่ 2 

3. ระบบสื่อสารข้อมูลอย่างง่าย (10 คะแนน)


การสื่อสารอนุกรมระหว่างบอร์ด UNICON 
สร้างระบบการสื่อสารระหว่างไมโครคอนโทรลเลอร์ 2 ตัวให้สามารถรับและส่งข้อมูลกันได้ 
     3.1 เชื่อมต่อสายระหว่างบอร์ด Arduino ทั้งสองบอร์ดเพื่อให้สามารถสื่อสารอนุกรมระหว่างบอร์ดไมโครคอนโทรลเลอร์ทั้งสองบอร์ดได้
     3.2 เชื่อมต่อZX-SWITCH และ ZX-LED ดังแสดงในรูป โดยจะเลือกต่อขาพอร์ตขาใด ๆ ก็ได้
     3.3 เขียนโปรแกรมสื่อสารระหว่างบอร์ด UNICON รับค่าจากสวิตช์แสดงผลที่หน้าจอ GLCD และ ZX-LED โดยมีการให้คะแนนดังนี้
        3.3.1 เมื่อกดสวิตช์ SW1 LED1 ต้องติดค้าง และเมื่อกดสวิตช์ SW1 อีกครั้ง LED1 ต้องดับ สลับกันไปเรื่อยๆ (2 คะแนน)
        3.3.2 เมื่อกดสวิตช์ SW2 LED2 ต้องติดค้าง และเมื่อกดสวิตช์ SW2 อีกครั้ง LED2 ต้องดับ สลับกันไปเรื่อยๆ (2 คะแนน)
        3.3.3 เมื่อกดสวิตช์ SW3 หน้าจอ GLCD จะต้องแสดงข้อความ SW3 PRESS และเมื่อไม่กดข้อความจะต้องหายไป (2 คะแนน)
        3.3.4 เมื่อกดสวิตช์ SW4 หน้าจอ GLCD จะต้องแสดงข้อความ SW4 PRESS และเมื่อไม่กดข้อความจะต้องหายไป (2 คะแนน)
       3.3.5 ทุกครั้งที่มีการกดสวิตช์ทั้ง 4 ตัวมีเสียง BEEP ออกลำโพงเปียโซ ZX-SPEAKER (2 คะแนน)


การทำงานของโปรแกรม
  การทำงานฝั่ง MASTER จากวงจรการเขียนโปรแกรมสามารถใช้คำสั่ง Serial1 มาใช้งานได้เลย โดยเริ่มต้นกำหนดค่าให้การสื่อสารด้วยบอดเรต 9600 จากคำสั่ง
Serial1.begin(9600);
จากนั้นก็เป็นการตรวจสอบอ่านค่าข้อมูล ถ้ามีข้อมูลถูกส่งเข้ามาก็ให้ตรวจสอบว่าตรงกับค่าใด แล้วให้ทำงานตามค่านั้น ๆ จากนั้นตรวจสอบสวิตช์ว่ามีการกดหรือไม่ ถ้ากดให้ส่งค่าออกไป โดยจะเป็นการส่งค่าสลับกันไป เป็นตัว A และ a สำหรับสวิตช์ SW1 และ B และ b สำหรับ SW2
การทำงานของฝั่ง SLAVE ก็แบบเดียวกัน คือรับค่าแล้วนำค่ามาแสดงที่ LED และรอการกดสวิตช์เพื่อส่งค่าผ่านพอร์ตอนุกรมออกไป
 โดยโปรแกรมทั้งหมดเป็นดังนี้




Exported from Notepad++
//************************************************** :: MASTER UNICON with GLCD //************************************************** #include int x,flag_=0,flag1=0; void setup(){ Serial1.begin(9600); setTextSize(2); glcdMode(3); } void loop(){ if(Serial1.available()){ x=Serial1.read(); if(x==65){ glcd(1,1,"SW3 PRESS"); } else if(x==97){ glcd(1,1," "); } else if(x==66){ glcd(2,1,"SW4 PRESS"); } else if(x==98){ glcd(2,1," "); } } if (in(19)==0){ if(flag_==0){ flag_=1; Serial1.write(65); } else{ flag_=0; Serial1.write(97); } delay(200); } if (in(20)==0){ if(flag1==0){ flag1=1; Serial1.write(66); } else{ flag1=0; Serial1.write(98); } delay(200); } } //************************************************** :: SLAVE UNICON //************************************************** #include int x,flag19_0,flag19_1,flag20_0,flag20_1=0; void setup(){ Serial1.begin(9600); } void loop(){ if(Serial1.available()){ x=Serial1.read(); if(x==65){ out(21,1); } else if(x==97){ out(21,0); } else if(x==66){ out(22,1); } else if(x==98){ out(22,0); } } if (in(19)==0){ flag19_1=0; if(flag19_0==0){ flag19_0=1; Serial1.write(65); delay(20); } } else{ flag19_0=0; if(flag19_1==0){ flag19_1=1; Serial1.write(97); delay(20); } } if (in(20)==0){ flag20_1=0; if(flag20_0==0){ flag20_0=1; Serial1.write(66); delay(20); } } else{ flag20_0=0; if(flag20_1==0){ flag20_1=1; Serial1.write(98); delay(20); } } }