สไลด์ประกอบกิจกรรม one (language) for all (platforms)

50
One (language) for All (platforms) development note ผศ.ดร.ศภช ย วรพจนพศทธ ภาควชาวศวกรรมไฟฟ้าและคอมพวเตอร มหาวทยาลยธรรมศาสตร

Upload: supachai-vorapojpisut

Post on 15-Jul-2015

293 views

Category:

Devices & Hardware


0 download

TRANSCRIPT

Page 1: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

One (language) for All (platforms)development note

ผศ.ดร.ศ�ภช�ย วรพจน�พ�ศ�ทธ��

ภาคว�ชาว�ศวกรรมไฟฟ้าและคอมพ�วเตอร�

มหาว�ทยาล�ยธรรมศาสตร�

Page 2: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

บ�นทกึ

● 13 ม%ค. 58การต�ดต�ง้ Python และเครือ่งมอืการต�ดตอ่เว็บบร�การ Google Mapsการต�ดต�ง้ Raspberry Pi

● 19 ม%ค. 58การต�ดต�ง้ OpenCV สำาหร�บ Windows + Raspberry Piการเข%ยนโคด้ computer vision

● 26 ม%ค. 58การต�ดต�ง้ Python SDK สำาหร�บ Google App Engineการพ�ฒนา web app และ web service

Page 3: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เตร%ยม Python และ IDE● ดาวน�โหลดและต�ดต�ง้ Python 2.7.8

http://www.python.org● ดาวน�โหลดและต�ดต�ง้ PyCharm IDE

https://www.jetbrains.com/pycharm/

Page 4: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ทดสอบ Python environment● เป�ด PyCharm แลว้เลอืกสรา้ง Pure Python project

ตรวจสอบวา่ Interpreter ตรงก�บร�น่ท%ต่ �ดต�ง้

● คล�กท% ่Python console แลว้พ�มพ� print('hello') เพือ่ยนืย�นการทำางาน

Page 5: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ทดสอบ Python IDE● คล�กขวาท%ช่ ือ่ project แลว้เลอืก New → Python file● พ�มพ�โคด้เพือ่ทดสอบ

if __name__ == '__main__': print('hello, world')

● เลอืกเมนู Run เพือ่ส�ง่ทำางาน เชค็ผลจากหนา้ตา่ง Run

Page 6: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

อา่นเข%ยนไฟล�

● เตร%ยมไฟล� test.txt ท%เ่ป็นขอ้ความสำาหร�บใชท้ดสอบ ● พ�มพ�โคด้สำาหร�บน�บคำาจากไฟล� แลว้ส�ง่ Run

if __name__ == '__main__': f = open('test.txt', 'r') counts = {} content = f.read() for word in content.split(): if word not in counts: counts[word] = 1 else: counts[word] += 1 for k,v in counts.items(): print k,v

Page 7: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เขา้ถงึเนือ้หาบนอ�นเตอร�เน็ต

● ขอ้มลูอส�งหาร�มทร�พย�ท% ่Sacramento เป็น CSVhttp://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv

● พ�มพ�โคด้สำาหร�บการอา่นไฟล�จากเว็บ แลว้ส�ง่ Run

Page 8: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

import urllibif __name__ == '__main__': url = 'http://…csv' conn = urllib.urlopen(url) content = conn.read() conn.close() lines = content.split('\r') table = [] for line in lines: fields = line.split(',') if not table: for field in fields: table.append({'name':field, 'column':[]}) else: idx = 0 for field in fields: table[idx]['column'].append(field) idx += 1 for item in table: print(item['name'])

ดงึไฟล�จากเว็บไซต�

แยกเนือ้หาตามบรรท�ด

แยกขอ้มลูดว้ย ,

ประกอบขอ้มลูใหม่

Page 9: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ทดสอบใชด้%บ�๊กเกอร�

● คล�กต�ง้ breakpoint ท%ด่า้นหนา้โคด้

lines = content.split('\r')

● เลอืกเมนู Run → Debug● ตรวจสอบต�วแปรในหนา้ตา่งยอ่ย Variables● ใชป้�่ มบน toolbar เพือ่ส�ง่ทำางาน

Page 10: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ใชง้านบร�การ Google Maps● API สำาหร�บเขา้ใชเ้ว็บบร�การของ Google Maps

https://developers.google.com/maps/documentation/webservices/

● ทดสอบบร�การ Geocoding ดว้ยเบราเซอร�

https://maps.googleapis.com/maps/api/geocode/json?address=Bangkok+Thailand

Page 11: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

● พ�มพ�คำาส�ง่ลงใน Python console เพือ่ทดลองการแยกขอ้มลูในรปูแบบ jsonimport urllibimport json

url = 'https://maps.googleapis.com/maps/api/geocode/json?'args = {'address':'Bangkok,Thailand','language':'th'}url += urllib.urlencode(args)conn = urllib.urlopen(url)resp = json.load(conn)

● ทดลองดงึคา่ออกจากผลล�พธ�ของเว็บบร�การresp.keys()print resp['status']type(resp['results'])

ทดสอบการแยกขอ้มลู

ไดผ้ลล�พธ� [u'status', u'results']

Page 12: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ลำาด�บการดงึขอ้มลูพ�ก�ด

● ลำาด�บในการแยกขอ้มลูพ�ก�ด lat/lng ของสถานท%่type(resp['results'][0])<type 'dict'>resp['results'][0].keys()[u'geometry', u'address_components', u'place_id', …type(resp['results'][0]['geometry'])<type 'dict'>resp['results'][0]['geometry'].keys()[u'location', u'bounds', u'viewport', …type(resp['results'][0]['geometry']['location'])<type 'dict'>resp['results'][0]['geometry']['location'].keys()[u'lat', u'lng']resp['results'][0]['geometry']['location']{u'lat': 13.7563309, u'lng': 100.5017651}

ขอ้มลูแบบ list

ผลล�พธ�

Page 13: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ดงึขอ้มลูพ�ก�ดจากสถานท%่

● พ�มพ�โคด้ดงึขอ้มลู แลว้ส�ง่ Runimport urllibimport json

if __name__ == '__main__': url = 'https://.../maps/api/geocode/json?' args = {'address':'Bangkok,Thailand','language':'th'} url += urllib.urlencode(args) conn = urllib.urlopen(url) resp = json.load(conn) latlng = resp['results'][0]['geometry']['location'] print latlng['lat'],latlng['lng'] for place in resp['results']: print place['formatted_address']

Page 14: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เตร%ยม Raspberry Pi

ดาวน�โหลดและต�ดต�ง้ Raspbian ลงใน SD card โดยใช ้โปรแกรม Win32 Disk Imager

● http://downloads.raspberrypi.org/raspbian_latest● http://sourceforge.net/projects/win32diskimager/

Page 15: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เตร%ยมคอมพ�วเตอร� (Windows 7)● ต�ง้คา่ Network and Connection Sharing โดยเลอืก

รายการ change adapter settings● เลอืกแชร� WiFi → LAN (Ethernet)

Page 16: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เชือ่มตอ่ PC ↔ Raspberry Pi● เส%ยบ SD card เขา้ Raspberry Pi● เส%ยบสาย LAN และ USB เขา้คอมพ�วเตอร�

เชค็สถานะบตู/เครอืขา่ยจาก LED ส%เข%ยว

● พ�มพ�คำาส�ง่ cmd ใน Start menu ของ Windows● พ�มพ�คำาส�ง่ arp -a เพือ่ด ูIP address ของบอร�ด

Page 17: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ล็อกอ�นผา่น Ethernet● ดาวน�โหลดโปรแกรม PuTTY

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

● ล็อกอ�นผา่น ssh โดยป้อน IP address ของบอร�ด● รห�สผูใ้ช ้pi และรห�สผา่น raspberry

Page 18: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

สง่ไฟล�จาก PC● ดาวน�โหลดและต�ดต�ง้โปรแกรม WinSCP (secure copy)

http://sourceforge.net/projects/winscp/● โอนยา้ยไฟล� ???.py ไป แลว้ทดสอบเร%ยกใช ้เชน่

python test.py

Page 19: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ง้คา่เร�ม่ตน้ใหบ้อร�ด

● พ�มพ�คำาส�ง่ sudo raspi-config● เลอืกรายการ Expand Filesystem เพือ่ขยายระบบไฟล�

ใหใ้ชเ้ต็มพืน้ท% ่SD card● กดป�่ มลกูศรหรอื Tab เพือ่เลอืก <Finish>

Page 20: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้ซอฟต�แวร�พืน้ฐาน

● พ�มพ�คำาส�ง่เพือ่ต�ดต�ง้แพคเกจ

sudo apt-get install tightvncserver

● เป�ดใชง้าน vncserver แลว้ป้อนรห�สผา่น

vncserver :0 -geometry 800x600 -depth 16

● ไปท%เ่ว็บ chrome เพือ่ต�ดต�ง้แอพ VNC viewerhttps://chrome.google.com/webstore/category/apps

Page 21: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้ VNC client บน PC● เชือ่มตอ่บร�การ VNC โดยป้อน IP address:0● เลอืก LXTerminal เพือ่เป�ด console ร�บคำาส�ง่

Page 22: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้เครือ่งมอืท%จ่ำาเป็น

● การต�ง้ vncserver ใหท้ำางานชว่งบตูระบบ

http://www.raspberrypi.org/documentation/remote-access/vnc/

● แกไ้ขการทำางานของสคร�ปต� vncboot ใหเ้ป็นผูใ้ช ้pisudo -u pi vncserver :0 -geometry 800x600 -depth 16 -pixelformat 565

Page 23: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้เครือ่งมอืสำาหร�บ Python● พ�มพ�คำาส�ง่เพือ่ต�ดต�ง้ wxPythonsudo apt-get install python-wxgtk2.8 wx2.8-i18n python-wxtools

● เลอืกแอพ PyCrust จากเมนู

ป�่ ม Ctrl + ] หรอื [ เพือ่ขยาย/ลดขนาด font

● พ�มพ�คำาส�ง่ pyalamode หรอื pyalacarte เพือ่เป�ดใช ้editor

Page 24: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้ OpenCV ใน PC● ดาวน�โหลดและต�ดต�ง้ numpy สำาหร�บ Python 2.7

http://sourceforge.net/projects/numpy/files/NumPy/● ดาวน�โหลดและขยายไฟล� OpenCV

http://sourceforge.net/projects/opencvlibrary/files/ opencv-win/

● สำาเนาไฟล� cv2.pyd จากโฟลเดอร� opencv\build\ python\2.7\x86 ไปท% ่C:\Python27\Lib

● ทดสอบการต�ดต�ง้จาก Python Consoleimport cv2

Page 25: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

สรา้งโครงของ computer vision● พ�มพ�โคด้เพือ่อา่นภาพจากเว็บแคม กล�บดา้น และแสดง

ผลทางหนา้ตา่งimport cv2if __name__ == '__main__': cap = cv2.VideoCapture(0) cv2.namedWindow('mirror') while True: res,frame = cap.read() cv2.flip(frame, 1, frame) cv2.imshow('mirror', frame) if cv2.waitKey(100) == 27: break cap.release() cv2.destroyAllWindows()

รอ 100 msecป�่ ม Esc เพือ่หย�ด

อา่นภาพประมวลผลนำาไปใช ้

Page 26: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้ OpenCV ใน RPi● พ�มพ�คำาส�ง่เพือ่ต�ดต�ง้ OpenCV

sudo apt-get install python-opencv● เร%ยกใช ้pyalamode เพือ่พ�มพ�โคด้ mirror.py● พ�มพ�คำาส�ง่เพือ่เร%ยกใช ้

python mirror.py

การจ�บภาพจากเว็บแคมดว้ย OpenCVใน Raspberry Pi จะหน่วง และม%ความซำ้าของภาพ

Page 27: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ใช ้filter เพือ่แปลงรปู

● เข%ยนโคด้แทรกใน mirror.py● สรา้งฟ�งก�ช�นกอ่น if __name__ == '__main__':

def onChange(pos): print 'Current position is ' + str(pos)

● สรา้ง trackbar หล�งบรรท�ด cv2.namedWindow()

cv2.createTrackbar('filter', 'mirror', 0, 2, onChange)● เข%ยนโคด้เพือ่ทำาเงือ่นไขประมวลผลภาพ

0 ไมป่ระมวลผล1 แปลงเป็นภาพเฉดเทา2 แปลงเป็นเสน้ขอบ (อ�ลกอร�ธมึ Canny)

Page 28: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ใช ้filter เพือ่แปลงรปู

● เข%ยนโคด้แทรกหล�งบรรท�ด cv2.flip()if cv2.getTrackbarPos('filter', 'mirror') == 1: frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2GRAY)

if cv2.getTrackbarPos('filter', 'mirror') == 2: frame = cv2.cvtColor(frame, cv2.cv.CV_BGR2GRAY) frame = cv2.Canny(frame, 50, 200)

Page 29: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

สรา้ง time lapse camera● เข%ยนโคด้เพือ่สรา้งต�วบ�นทกึ video โดยกำาหนด format

ก�บ frame ratew = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))h = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))format = cv2.cv.CV_FOURCC('M','J','P','G')out = cv2.VideoWriter('test.avi', format, 10, (w,h))

● บ�นทกึเฟรมลงในคล�ปout.write(frame)

● ควบค�ม frame rate โดยการหน่วงเวลาif cv2.waitKey(100) == 27:

Page 30: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

import cv2

if __name__ == '__main__': cap = cv2.VideoCapture(0) w = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)) h = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)) format = cv2.cv.CV_FOURCC('M','J','P','G') out = cv2.VideoWriter('test.avi', format, 10, (w,h)) cv2.namedWindow('preview') while True: res,frame = cap.read() frame = cv2.flip(frame, 1) cv2.imshow('preview', frame) out.write(frame) if cv2.waitKey(100) == 27: break cap.release() cv2.destroyAllWindows()

ใน Raspberry Pi ใหต้�ดต�ง้ VLC player เพือ่ดไูฟล�ท%บ่�นทกึsudo apt-get install vlc

ต�ง้สือ่บ�นทกึ

Page 31: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

หาตำาแหน่งแลว้แปลงพ�ก�ด

● ประย�กต�ใชใ้นแอพประเภทสแกนเอกสาร

http://www.pyimagesearch.com/2014/09/01/build-kick-ass-mobile-document-scanner-just-5-minutes/

● cv2.cvtColor()● cv2.Canny()● cv2.findContours()● cv2.warpPerspective()

แปลงภาพเป็นเฉดเทา

หาขอบดว้ยCanny

Boundingrectangle

Perspectivewarping

Page 32: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

แปลงภาพเป็น binaryret,frame = cap.read()(h,w,_) = frame.shape; w = w/2; h = h/2img = cv2.resize(frame, (w,h))img = cv2.flip(img, 1)

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray_img = cv2.GaussianBlur(gray_img, (5, 5), 0)edge_img = cv2.Canny(gray_img, 50, 100)

kernel = numpy.ones((5,5), numpy.uint8)edge_img = cv2.morphologyEx(edge_img, cv2.MORPH_CLOSE, kernel)

อา่นและยอ่ภาพ

หาขอบ

Page 33: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

หา 4 จ�ดลอ้มภาพ

(cnts, _) = cv2.findContours(edge_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)cnts = sorted(cnts,key=cv2.contourArea,reverse=True)[:5]

rect = numpy.zeros((4, 2), dtype=numpy.float32)for c in cnts: peri = cv2.arcLength(c, True) pts = cv2.approxPolyDP(c, 0.01 * peri, True) if len(pts) == 4 and cv2.contourArea(c) > 0.15*w*h: cv2.drawContours(img, [pts], -1, (0, 255, 0), 2)

sums = [pt[0].sum() for pt in pts] diffs = [numpy.diff(pt[0]) for pt in pts] rect[0] = pts[numpy.argmin(sums)][0] rect[1] = pts[numpy.argmin(diffs)][0] rect[2] = pts[numpy.argmax(diffs)][0] rect[3] = pts[numpy.argmax(sums)][0]

ลอ้มเสน้

หาจ�ดท% ่4 ม�ม

สรา้งกรอบ

Page 34: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

แปลงพ�ก�ดของภาพ

(tl,tr,bl,br) = recttop = cv2.norm(tr,tl)bottom = cv2.norm(br,bl)width = max(int(top), int(bottom))left = cv2.norm(tl,bl)right = cv2.norm(tr,br)height = max(int(left), int(right))dst = numpy.array([[0, 0],[width - 1, 0], [0, height - 1],[width - 1, height – 1]], dtype=numpy.float32)

M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(img, M, (width, height))warped = cv2.flip(warped,1)

คำานวณขนาด

แปลงพ�ก�ด

Page 35: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

แนวค�ด Internet of Things

Cloud computing

gateway

sensor

คา่เซน็เซอร�

serverHTTP - REST

Page 36: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เตร%ยม Google App Engine● เงือ่นไข: ม% google account + ฟร% = จำาก�ดการใช ้● ดาวน�โหลดและต�ดต�ง้ App Engine SDK for Python

https://cloud.google.com/appengine/downloads

Page 37: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ข�น้ตอนสรา้งบร�การบน cloud● กำาหนดชอ่งทาง (URL) ในการเขา้ถงึบร�การ = web API

http://AAA.appspot.com/xxx/yyy/zzz?arg1=?&arg2=?

ต�วอยา่งเชน่ บร�การ Geocoding ของ Google Mapshttps://maps.googleapis.com/maps/api/geocode/ json?address=Bangkok+Thailand

● ออกแบบโมเดลของการแลกเปล%ย่นขอ้มลู● เข%ยนโคด้ประมวลผล HTTP requests: GET,POST,...

จำาแนกขอ้มลู > จ�ดการฐานขอ้มลู > สรา้งผลล�พธ�● ตอบสนอง = return code + HTML (web apps) หรอื

XML/JSON (web services)

Page 38: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

กรณ%ต�วอยา่ง sensor acquisition● ม�มมองอ�ปกรณ� = data entity

คา่ + ค�ณสมบ�ต� (what,which,where,how,...)● ม�มมองเซ�ร�ฟเวอร� = database entity

เวลา + อา้งอ�ง + คา่ + ค�ณสมบ�ต� (what,how,...)● ม�มมองผูใ้ช ้= information

เทรนด�ของคา่ / ต�วแทนของคา่ขอ้มลู / ...

Page 39: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

application: rpi-boxversion: 1runtime: python27api_version: 1threadsafe: yes

handlers:- url: /favicon\.ico static_files: favicon.ico upload: favicon\.ico

- url: /ws script: service.app- url: /ui script: ui.app- url: .* script: main.app

libraries:- name: webapp2 version: latest- name: jinja2 version: latest

ไลบราร%ท%ข่อใช ้

การเชือ่ม URL ก�บโคด้

ชือ่ของแอพพล�เคช�น

ไฟล� app.yaml

Page 40: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

การใชง้าน Google App Engine● กดป�่ ม Run เพือ่ใช ้PC เป็นเซ�ร�ฟเวอร�● ใชเ้บราเซอร�ดกูารทำางานจากพอร�ต

http://localhost:port● กดป�่ ม Logs เพือ่ตรวจสอบสถานะทำางาน● ตรวจสอบฐานขอ้มลู

http://localhost:admin_port● หล�งยนืย�นการทำางาน กดป�่ ม Deploy เพือ่อ�พโหลด● ใชเ้บราเซอร�ไปท%เ่ซ �ร�ฟเวอร�

http://appname.appspot.com

Page 41: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

โครงของเว็บบร�การ (service.py)● HTTP request > ประมวลผล > JSON

#!/usr/bin/env pythonimport webapp2import jsonclass TestHandler(webapp2.RequestHandler): def get(self): resp = {'status':'OK'} self.response.write(json.dumps(resp))app = webapp2.WSGIApplication([ ('/ws/test', TestHandler)], debug=True)

ใชเ้บราเซอร�ดทู% ่http://localhost:xxxx/ws/test

Page 42: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เตร%ยมตน้แบบขอ้มลู (model.py)● น�ยามขอ้มลู

when = เวลา which = แหลง่ขอ้มลูwhat = ขอ้มลู how = ว�ธ%การwhere = ตำาแหน่ง ...from google.appengine.ext import ndb

class MyData(ndb.Model): timestamp = ndb.DateTimeProperty(auto_now_add=True) serial = ndb.IntegerProperty(required=True) value = ndb.FloatProperty(required=True)

Page 43: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เพ�ม่บร�การ (service.py)class UpdateHandler(webapp2.RequestHandler): def get(self): sn = self.request.get('sn') val = self.request.get('value') if sn != '' and val != '': resp = {'status':'OK'} data = MyData(serial=int(sn),value=float(val)) data.put() else: resp = {'status':'ERR'} self.response.write(json.dumps(resp))app = webapp2.WSGIApplication([ ('/ws/test', TestHandler), ('/ws/update', UpdateHandler)], debug=True)

แยกขอ้มลูจาก arg

จ�ดเก็บขอ้มลู

http://appname.appspot.com/ws/update?sn=11&val=1.0

Page 44: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

เตร%ยมเชือ่มตอ่ Arduino● Raspberry Pi สามารถเชือ่มตอ่ Arduino ผา่นพอร�ต

USB ท�ง้รปูแบบขอ้มลูและโคด้

sudo apt-get install arduino arduino-mk python-serial

● เส%ยบ Arduino เขา้ก�บ Raspberry Pi● พ�มพ�คำาส�ง่ dmesg ดรูายงานการเชือ่มตอ่● ตรวจสอบพอร�ตอน�กรมท%เ่ป็น Arduino: ttyACMx หรอื

ttyUSBx> ls /dev/tty*

Page 45: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

สรา้งแหลง่ขอ้มลู

● เข%ยนโคด้บน Arduino เพือ่ส�ม่ว�ดและรายงานผลvoid setup() { Serial.begin(9600);}void loop() { int val = analogRead(0); Serial.println(val); delay(1000);}

หากม%หลายขอ้มลู แนะนำาใหใ้ช ้csv หรอื jsonSerial.print(val1); Serial.print(',');Serial.print(val2); Serial.print(',');Serial.println(val3);

Page 46: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

สง่ผา่นขอ้มลู

● สรา้งไฟล� data_feed.py สำาหร�บ Raspberry Piimport jsonimport serialimport urllibif __name__ == '__main__': ser = serial.Serial('/dev/ttyACM0',9600,timeout=10) ser.flush() while True: line = ser.readline() data = line.strip() args = {'sn':11, 'value':data} url = 'http://rpi-box.appspot.com/ws/update?' conn = urllib.urlopen(url + urllib.urlencode(args)) resp = json.load(conn) print resp['status']

เชือ่มตอ่พอร�ตอน�กรม

ร�บและจำาแนกขอ้มลู

Page 47: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

โครงของเว็บแอพ (ui.py)● HTTP request > สบืคน้และจ�ดรปูขอ้มลู > HTML

import webapp2import osimport jinja2

JINJA_ENV = jinja2.Environment(loader= jinja2.FileSystemLoader(os.path.dirname(__file__)),extensions=['jinja2.ext.autoescape'],autoescape=True)class ViewHandler(webapp2.RequestHandler): def get(self): ... self.response.write(template.render(resp))app = webapp2.WSGIApplication([ ('/ui/view', ViewHandler)], debug=True)

Page 48: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

สบืคน้ขอ้มลูจาก datastore● ขอ้มลูถกูจ�ดเกบ็ในรปู object อา้งอ�งไดด้ว้ย key● ใชเ้ทคน�ค templating เพือ่อา่นไฟล� HTML ตน้แบบ

from model import *

sn = self.request.get('sn')if sn != '': resp = {'status':'OK'} query = MyData.query(MyData.serial==int(sn)) data = query.fetch(10) resp['values'] = [entity.value for entity in data]else: resp = {'status':'ERR'}template = JINJA_ENV.get_template('index.html')

กำาหนดเงือ่นไข/สบืคน้

Page 49: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ไฟล� HTML ตน้แบบ

● ใชก้ารทดแทน HTML tag ในระหวา่ง renderingทดแทนต�วแปร<div data-role="footer"> <h2>{{status}}</h2></div>

แบบรายการ list, tuple<ui> {% for value in values %} <li>Value is {{value}}</li> {% endfor %}</ui>

ดงึคา่ต�วแปรมาแสดง

วนสรา้งรายการจาก list

Page 50: สไลด์ประกอบกิจกรรม One (language) for All (platforms)

ต�ดต�ง้เครือ่งมอืสำาหร�บ Python● พ�มพ�คำาส�ง่เพือ่ต�ดต�ง้ต�วต�ดต�ง้แพคเกจเฉพาะ Python

sudo apt-get install python-pip● ต�ดต�ง้ idlex โดยพ�มพ�คำาส�ง่

sudo pip install idlex