หน้าเว็บ

วันจันทร์ที่ 3 มิถุนายน พ.ศ. 2556

UNICON & POP-BOT XT: คู่มือ POP-BOT XT

UNICON & POP-BOT XT: คู่มือ POP-BOT XT

คู่มือ POP-BOT XT

สำหรับหนังสือ สร้างและพัฒนาโปรแกรมควบคุมหุ่นยนต์อัตโนมัติด้วยโปรแกรมภาษา C/C++ กับ Arduino และ POP-BOT XT นั้นเป็นหนังสือที่อยู่ในชุดหุ่นยนต์ POP-BOT XT ครับ สามารถดาวน์โหลดไปศึกษาการเขียนโปรแกรมต่าง ๆ ได้ด้วยตนเองเลยครับ
ส่วนลิงก์นี้ก็เป็นตัวอย่างการทำงานของหุ่นยนต์ ก็ตามนี้ครับ

   

จากวีดิโอเป็นกิจกรรมที่ 20-3 หุ่นยนต์ Object Hitter BOT


สำหรับโค้ดตัวอย่างก็มีดังนี้


#include // Include the main library int L,R,x=0,y=0; /* Move forward funtion */ void FF() { fd(60); sleep(300); } /* 90-Degree Turn right function */ void R90() { fd(60); // Move forward pass the crossing line sound(1500,100); // Drive the sound signal while(analog(1)>500) // Check the Right line sensor to detect the white area { sr(60); // Spin right } while(analog(1)<500) // Spin right until detect the black line { sr(60); // Spin right again to pass the black line } } /* 90-Degree Turn left function */ void L90() { fd(60); // Move forward pass the crossing line sound(1500,100); // Drive the sound signal while(analog(0)>500) // Check the Right line sensor to detect the white area { sl(60); // Spin right } while(analog(0)<500) // Spin right until detect the black line { sl(60); // Spin right again to pass the black line } } /* Hit object function */ void hit() { bk(100); // Move backward short time sleep(50); ao(); // Stop motor servo(1,180); // Drive servo motor to 180-degree position sleep(1000); servo(1,0); // Drive servo motor back to 0-degree position bk(60); // Move backward sleep(200); R90(); // 90-degree turn right } void setup() { setTextSize(2); // Set text size 2x glcd(1,1,"Press OK"); // Show the start message glcd(2,1,"to Start"); sw_ok_press(); // Wait for OK switch pressed glcdClear(); glcd(1,1,"Let's go!"); // Show operation message } void loop() { L=analog(0); // Read the Left line sensor value R=analog(1); // Read the Right line sensor value if (L<500&&R<500) // Detect the crossing line { if(x==5) // The crossing line counting was complete { x=0; // Restart counting y++; // Increase branch counter if (y==4) // The branch counting was complete { ao(); // Stop the robot servo (1,-1); // Stop servo motor while(1); } } x++; // Increase the line crossing counter if (x==1) // 1st crossing { L90(); // Turn left } else if(x==2||x==4) // 2nd and 4th crossing { hit(); // Hit the object } else if (x==3) // 3rd crossing { FF(); // Move forward } else if (x==5) // 5th crossing { R90(); // 90-degree turn right } } else if(L>500&&R>500) // Both sensors detect the white area. It means robot move bestride the line { fd(60); // Move forward with 60% power } else if(L<500) // The left line sensor detects the black line // The robot will move out the line in right { sl(60); // Spin left a little bit to adjust the robot over the line sleep(20); } else if(R<500) // The right line sensor detects the black line // The robot will move out the line in left { sr(60); // Spin right a little bit to adjust the robot over the line sleep(20); } }

วันศุกร์ที่ 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(); }