UCON-UART in Application (Thai)

Page 1

Proto Knowledge

PC Interface โดย : กฤษดา ใจเย็น

ต�ดตออุปกรณภายนอกผาน พอรต USB ดวยบอรด UCON-UART ก่อนหน้านี้การอินเตอร์เฟสระหว่างคอมพิวเตอร์กับอุปกรณ์ภายนอกท�าได้ง่ายๆ ผ่าน พอร์ตอนุกรมหรือพอร์ตขนาน แต่เมื่อพอร์ตอนุกรมและพอร์ตขนานถูกตัดสิทธิ์ ไม่มีให้ใช้ งานเหลือเพียงพอร์ต USB ซึ่งเข้าถึงได้ยาก บอร์ด UCON-UART จึงถือก�าเนิดขึ้นเพื่อแก้ ปัญหานี้ โดยแปลงกายตัวเองให้เปนพอร์ตอนุกรม มาดูกันว่าการเขียนโปรแกรมควบคุม จะง่ายเหมือนกับพอร์ตอนุกรมหรือไม่

บอร์ด UCON-UART บอร์ด UCON-UART เปนบอร์ดแปลงพอร์ต USB ให้เปน พอร์ตอนุกรมหรือ COM PORT โดยหัวใจหลักคือชิปเบอร์ FT232RL ของบริษัท FTDI สามารถเขียนโปรแกรมติดต่อได้ 2 รูปแบบคือ VCP (Visual Com Port) ที่จ�าลองการท�างานของพอร์ตอนุกรมสมบูรณ์ แบบมีขาสัญญาณออกมาให้ใช้งานครบทั้ง 9 เส้น และแบบ D2xx ที่ก�าหนดขาพอร์ตให้เปนอินพุตเอาต์พุตได้อย่างอิสระ ในบทความ ตอนนี้จะใช้งานในรูปแบบของ VCP ก่อน โดยรูปร่างของบอร์ด UCON-UART และขาต่อใช้งานต่างๆ ในโหมด VCP แสดงในรูปที่ 1

รูปที่ 1 บอร์ด UCON-UART และข�สำ�หรับต่อใช้ง�น

RTS DTR TxD

VUSB

3.3V

VUSB

Tx

USB

รูปที่ 2 วงจรแสดงก�รเชื่อมต่อบอร์ด UCON-UART เข้�กับ LED เพื่อทดสอบก�รส่งค่�เอ�ต์พุต

The Prototype Electronics

USB to UART Converter

Rx

Rx

52

UCON-UART

SLEEP TXDEN PWREN TXLED RXLED RESET GND

R3 510

GND VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS

SLEEP TXDEN PWREN TXLED RXLED RESET GND

LED3

R2 510

USB to UART Converter

FTDI

LED2

R1 510

UCON-UART

FTDI

LED1

VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS

3.3V

GND

รูปที่ 3 แสดงก�รเชื่อมต่อวงจรจริงบนเบรดบอร์ด

Tx

USB


Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Port_Name As String() Dim Name_ As String

รูปที่ 4 หน้าต่างเริ่มต้นขั้นตอนการสร้างโปรเจ็กต์ ของ Visual Basic Express

รูปที่ 5 การวางคอนโทรลต่างๆ สำ�หรับโปรแกรม ที่ 1

‘=========================================== ‘ กำ�หนดชื่อให้กับคอนโทรลต่างๆ ‘===========================================

Me.Text = “Simple Digital Output” GroupBox1.Text = “Serial Port” Button1.Text = “Connect” Button2.Text = “E&xit” GroupBox2.Text = “Digital Ouput” Button3.Text = “TxD “ Button4.Text = “DTR “ Button5.Text = “RTS “

‘=========================================== ‘ ค้นหาพอร์ตอนุกรมที่ติดตั้งภายในคอมพิวเตอร์ ‘===========================================

ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList ComboBox1.Sorted = True Port_Name = IO.Ports.SerialPort.GetPortNames() For Each Name_ In Port_Name ComboBox1.Items.Add(Name_) Next ComboBox1.SelectedIndex = 0 SerialPort1.PortName = ComboBox1.Text End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If SerialPort1.IsOpen Then ‘ ปิดการสื่อสารของพอร์ตอนุกรม ถ้าพอร์ตนั้นเปิดอยู่ SerialPort1.Close() Button1.Text = “Connect” ComboBox1.Enabled = True Else SerialPort1.Open() ‘ เปิดการสื่อสารของพอร์ตอนุกรม Button1.Text = “Disconnect” ComboBox1.Enabled = False SerialPort1.DtrEnable = True ‘ ส่งลอจิก “0” ให้ขา DTR SerialPort1.RtsEnable = True ‘ ส่งลอจิก “0” ให้ขา RTS SerialPort1.BreakState = True ‘ ส่งลอจิก “0” ให้ขา TxD End If End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If SerialPort1.IsOpen Then ‘ ปิดการสื่อสารของพอร์ตอนุกรมและออกจากโปรแกรม SerialPort1.Close() End If End End Sub Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged SerialPort1.PortName = ComboBox1.Text ‘ เลือกของตำ�แหน่งของพอร์ตอนุกรมที่ต้องการ End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click SerialPort1.BreakState = Not SerialPort1.BreakState ‘สลับบิตที่ส่งไปยังขา TxD End Sub Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click SerialPort1.DtrEnable = Not SerialPort1.DtrEnable ‘สลับบิตที่ส่งไปยังขา DTR End Sub Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click SerialPort1.RtsEnable = Not SerialPort1.RtsEnable ‘สลับบิตที่ส่งไปยังขา RTS End Sub End Class

รูปที่ 6 หน้าต่างโปรแกรม Simple Digital Output เมื่อสั่งรันให้ทำ�งาน

ขา 1 2 3 4 5 6 7 8 9

ชื่อ DCD RxD TxD DTR GND DSR RTS CTS RI

หนาที่ Data Carrier Detect Receive Data Transmit Data Data Terminal Ready Signal Ground Data Set Ready Request to Send Clear to Send Ring Indicator

ทิศทาง อินพุต อินพุต เอาตพุต เอาตพุต กราวด อินพุต เอาตพุต อินพุต อินพุต

ตารางที่ 1 ตำ�แหน่งขามาตรฐานของพอร์ต อนุกรมและทิศทางของขาพอร์ต

โปรแกรมที่ 1 โปรแกรมสำ�หรับทดสอบส่งค่าลอจิกไปยังขา TxD,DTR และ RTS ของบอร์ด UCON-UART ขาสัญญาณของพอร์ตอนุกรม

การเขียนโปรแกรมควบคุม

กอน​จะ​ใชงาน​บอรด UCON-UART จะ​ตอ ง​ รูจ กั ​หนาที​ข่ อง​ขา​ตา งๆ ของ​พอรต​อนุกรม​กนั ​กอ น โดย​ขา​สญ ั ญาณ​ของ​พอรต​อนุกรม 9 ขา​แบง​เปน​ขา​ อินพุต 5 ขา ขา​เอาตพตุ 3 ขา อีก 1 ขา​เปน​กราวด ดัง​แสดง​รายละเอียด​ใน​ตาราง​ที่ 1 ซึง่ ​ขา​เหลานี​ใ้ น อดีต​ถูก​ออกแบบ​มา​เพื่อ​เชื่อม​ตอ​กับ​โมเด็ม การ​ ใชงาน​ปกติ​จะ​ใช​ขา TxD ใน​การ​สง ​ขอ มูล และ​ขา RxD ใน​การ​รบั ​ขอ มูล สวน​ขา​อนื่ ๆ ท�ำหนาที​เ่ ปน​ ขา​ตรวจสอบ​การ​สอื่ สาร​ขอ มูล​หรือ​ท​เี่ รียกวา​แฮนด​ เซ็ก และ​เมื่อ​จ�ำแนก​ขา​สัญญาณ​ออก​เปน​สอง​ ประเภท​คอื ขา​อนิ พุต​และ​ขา​เอาตพตุ เรา​สามารถ​ เขียน​โปรแกรม​เพือ่ ​ควบคุม​ขา​เหลานี​ไ้ ด​อยาง​อสิ ระ โดย​โปรแกรม​ท​ใี่ ช​เขียน​ทดสอบ​ก​ค็ อื Visual Basic Express 2008 ซึง่ ​เคย​แนะน�ำ​การ​ใช​งาน​ไป​แลว​ใน​ TPE ฉบับ​ที่ 2

ทดสอบการขับอุปกรณ์เอาต์พุต ทดสอบโปรแกรมรูปแบบแรกด้วยการส่ง ค่าลอจิก “0” และลอจิก “1” ออกไปยังอุปกรณ์ ภายนอกกันก่อน วงจรในรูปที่ 2 เป็นวงจรน�ำเอา ขา DTR, RTS และขา TxD มาต่อเข้ากับ LED เพือ่ ให้เห็นสถานะลอจิก “0” (LED ดับ) และลอจิก “1” (LED ติดสว่าง) รูปที่ 3 จะแสดงการเชือ่ มต่อจริง โดย ใช้เบรดบอร์ดแผ่นจิว๋ มาต่อวงจร (1) เปด​โปรแกรม Visual Basic Express 2008 (2) สรางโปร​เจ็กต​ใหม โดย​เรียก​จาก​เมนู File > New Project เลือก​สรางโปร​เจ็กต​เปน​แบบ Windows Forms Application ดังร​ ูปท​ ี่ 4 (3) ตั้งชื่อโปร​เจ็กต​ในที่นี้​ตั้ง​ชื่อวา Simple Digital Output The Prototype Electronics

53


PC Interface : UCON-UART UCON-UART

GND

SW2 RI

SW3 DSR

R4 10k

SW4 DCD

R5 10k

3.3V

VUSB

Rx

Tx

VUSB

Tx

USB

USB

SW5 CTS

(4) ลาก คอนโทรล ต่างๆ มา วางลง บน ฟอร์ม ใน ต�าแหน่ง ดัง รูป ที่ 5 โดย ส่วน ส�าคัญที่สุด คือ คอนโทรล SerialPort1 ซึ่ง ใช้ ใน การ สื่อสาร กับ บอร์ด UCON-UART (5) เขียน โปรแกรม ให้ กับ คอนโทรล ต่างๆ ตามที่ แสดง ใน โปรแกรม ที่ 1

รูปที่ 8 แสดงก�รเชื่อมต่อ วงจรจริงบนเบรดบอร์ด

โปรแกรมยอย Button3_Click() Button4_ Click() Button5_Click() จะใชเพื่อสลับลอจิกที่

การเขียนโปรแกรมรับค่าจากสวิตช์ 5 ช่อง

รันโปรแกรม

(2) สร้างโปรเจ็กต์ใหม่ โดยเรียกจากเมนู File > New Project เลือกสร้างโปรเจ็กต์เปนแบบ Windows Forms Application

ขา TxD DTR และ RTS ตามลําดับ

หลังจาก ตอ่ วงจร เรียบร้อย ให้รนั โปรแกรม จะ พบ หน้าต่าง โปรแกรม ดงั รปู ท ี่ 6 เรา จะ ตอ้ ง เลือก ต�าแหน่ง พอร์ ตอน กรุ ม ท เี่ ปน ตา� แหน่ง ของ UCONการท�างานของโปรแกรม UART จากนัน้ กดปุม Connect เพือ่ เปด พอร์ต โปรแกรมยอย Form_Load() อนุกรม ข้อความ ท ปี่ มุ จะ แสดง Disconnect จะ จะเริ่ ม ต้ น จากก� า หนดค่ า คุ ณ สมบั ติ ข อง เห็นว่า LED ทีต่ อ่ อยู ท่ งั้ 3 ดวง ดบั ทงั้ หมด ทดสอบ คอนโทรลต่างๆ ที่ใช้บนฟอร์มเมื่อโหลดขึ้นมาใช้ กดปุม TxD DTR และ RTS จะ เห็น LED ติด และ งานครั้งแรก จากนั้นจะค้นหาพอร์ตอนุกรมที่ติด ดับ ตาม การ กด คยี ์ จากนัน้ กดปุม Disconnect ตั้งอยู่ภายในเครื่องคอมพิวเตอร์ โดยแสดงรายชื่อ เพือ่ ปด พอร์ต อนุกรม และ กด Exit เพือ่ ออกจาก COMPORT ที่ตรวจพบใน ComboBox โดยจะรอ โปรแกรม ให้ผู้ใช้กดเลือกเพื่อเลือแล้วกดปุม Button1 เพื่อ ทดสอบการรับค่าอินพุต ใช้เชื่อมต่อ โปรแกรมยอย ComboBox1_SelectedInde- ขา รับสัญญาณ อินพุต ของ พอร์ต อนุกรม Changed() จะเกิดเหตุการณ (Event) เมือ่ มีการ มี มาก ถงึ 5 ขา การ ทดลอง น จี้ ะ เชือ่ ม ตอ่ สวิตช์ เปลีย่ นแปลงการเลือกตําแหนงพอรตอนุกรมภายใน ทัง้ หมด 5 ตัว เพือ่ อา่ น คา่ จาก ขา อนิ พุต ทงั้ 5 ขา ComboBox โดยจะกําหนดใหตําแหนงพอรตอนุกรม โดย แสดง วงจร การ เชือ่ ม ตอ่ ดงั รปู ท ี่ 7 ส่วนใน รปู ที่ 8 เปนการ ตอ่ ใช้งาน จริง บน เบรด บอร์ด จวิ๋ สวิตช์ ทงั้ เปนตําแหนงทีถู่ กเลือก 5 ตัว เปน สวิตช์ กด ตดิ ปล่อย ดบั ต่อตัว ตา้ นทาน พลู โปรแกรมยอย Button1_Click() จะตรวจสอบ อัพ คา่ 10kΩ เพือ่ ให้ สถานะ ท ไี่ ม่ กด สวิตช์ ม ลี อจิก พอรตอนุกรมตําแหนงปจจุบนั วาถูกเปดใชอยูห รือไม เปน “1” ถาไมจะทําเปดพอรตอนุกรม ในตําแหนงทีร่ ะบุผา น การ อ่าน ค่า อินพุต ส�าหรับ พอร์ต อนุกรม นี้ มี ComboBox และสงลอจิก “0” ใหกบั ขาเอาตพตุ ข้อจ�ากัด ด้วย อปุ นิสยั ดงั้ เดิม ของ ขา พอร์ต เหล่านี้ ทัง้ 3 ขาโดย กล่าว คอื มนั จะ ม วี รรณะ ท ไี่ ม่ เท่ากัน โดย ถา้ ม กี าร ขา TxD ควบคุมดวยคําสั่ง BreakState กด สวิตช์ ท ขี่ า CTS (Clear To Send) ค้าง เอา ไว้ ขา DTR ควบคุมดวยคําสั่ง DTREnable สถานะ ท ขี่ า DCD และ DSR จะ ไม่ สามารถ คง คา้ ง ค่า เอา ไว้ ได้ เนือ่ งจาก เมือ่ CTS ท�างาน ขา เหล่านี จ้ ะ ขา RTS ควบคุมดวยคําสั่ง RTSEnable ถูก เคลียร์ สถานะ ไป ดว้ ย แต่ อย่างไร กต็ าม เมือ่ ไม่ม ี ถาขาเหลานี้เปน TRUE จะใหเอาตพุตเปน การ ใช้งาน ทบั ซอ้ นกัน ขา พอร์ต เหล่านี ก้ ท็ า� หน้าที ่ ลอจิก “0” เปน ขา อนิ พุต ได้ อย่าง ดี โปรแกรมยอย Button2_Click() ใชเพื่อออกจาก โปรแกรม

The Prototype Electronics

3.3V

Rx

รูปที่ 7 วงจรเชื่อมต่อสวิตช์เข้�กับบอร์ด UCON-UART เพื่อทดสอบรับค่�อินพุต

54

SLEEP TXDEN PWREN TXLED RXLED RESET GND

R3 10k

FTDI

SW1 RxD

R2 10k

USB to UART Converter

SLEEP TXDEN PWREN TXLED RXLED RESET GND

R1 10k

VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS

UCON-UART

USB to UART Converter

FTDI

GND

VUSB 3.3V TxD DTR RTS RxD RI DSR DCD CTS

(1) เปดโปรแกรม Visual Basic Express 2008

(3) ตั้งชื่อโปรเจ็กต์ในที่นี้ตั้งชื่อว่า Simple Digital Input (4) ลากคอนโทรลต่างๆ มาวางลงบนฟอร์ม ในต�าแหน่งดังรูปที่ 9 (5) เขี ย นโปรแกรมให้ กั บ คอนโทรลต่ า งๆ ตามที่แสดงในโปรแกรมที่ 2

การท�างานของโปรแกรม ในโปรแกรมที่ 2 มีหลายโปรแกรมย่อยที่ ท�างานเช่นเดียวกับโปรแกรมที่ 1 ดังนั้นจะอธิบาย เฉพาะโปรแกรมย่อยที่เพิ่มเติมขึ้นมา ประกอบ ด้วย

โปรแกรมยอย SerialPort1_PinChanged() โปรแกรมย่ อ ยนี้ จ ะถู ก เรี ย กขึ้ น มาท� า งาน เมื่อเกิดเหตุการณ์ การเปลี่ยนแปลงที่ขาอินพุต โดยจะให้ค่า Eventype ออกมา เพื่อแจ้งสถานะ ของขาต่าง ๆ โดยค่า Eventype เปนค่าตัวเลข ค่าที่เกี่ยวข้องกับขาทั้ง 5 ขามีดังนี้ Eventype = 8 ขา CTS มีลอจิก “0” Eventype = 16 ขา DSR มีลอจิก “0” Eventype = 32 ขา DCD มีลอจิก “0” Eventype = 64 ขา RxD มีลอจิก “0” Eventype = 256 ขา RI มีลอจิก “0” โดยค่ า เหล่ า นี้ ส ามารถใช้ ตั ว แปรเหล่ า นี้ แทนได้ IO.Ports.SerialPinChange.Brake = ขา RxD IO.Ports.SerialPinChange.Ring = ขา RI


Public Class Form1 Dim Even_ As Integer Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim Port_Name As String() Dim Name_ As String

‘=========================================== ‘ กำ�หนดชื่อให้กับคอนโทรลต่�งๆ ‘===========================================

รูปที่ 9 ก�รว�งคอนโทรลต่�งๆ สำ�หรับ โปรแกรมที่ 2

Me.Text = “Simple Digital Input” GroupBox1.Text = “Serial Port” Button1.Text = “Connect” Button2.Text = “E&xit” GroupBox2.Text = “Digital Input” RadioButton1.Text = “RxD” RadioButton2.Text = “RI” RadioButton3.Text = “DSR” RadioButton4.Text = “DCD” RadioButton5.Text = “CTS” Timer1.Interval = 200 Timer1.Enabled = False

‘=========================================== ‘ ค้นห�พอร์ตอนุกรมที่ติดตั้งภ�ยในคอมพิวเตอร์ ‘===========================================

ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList ComboBox1.Sorted = True Port_Name = IO.Ports.SerialPort.GetPortNames() For Each Name_ In Port_Name ComboBox1.Items.Add(Name_) Next ComboBox1.SelectedIndex = 0 SerialPort1.PortName = ComboBox1.Text End Sub

รูปที่ 10 หน้�ต่�งโปรแกรม Simple Digital Input เมื่อสั่งรันให้ทำ�ง�น IO.Ports.SerialPinChange.CDChanged = ขา DCD IO.Ports.SerialPinChange.DSRChanged = ขา DSR IO.Ports.SerialPinChange.CTSChanged =ขา CTS

หน้ า ที่ ห ลั ก ของโปรแกรมย่ อ ยจะน� า ค่ า Eventype ที่เกิดขึ้นส่งให้กับตัวแปร Even_ เพื่อ ให้ Timer1 เปนตัวแสดงสถานะที่ RadioButton แทน

โปรแกรมยอย Timer1_Tick()

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If SerialPort1.IsOpen Then ‘ ปิดก�รสื่อส�รของพอร์ตอนุกรม ถ้�พอร์ตนั้นเปิดอยู่ Timer1.Enabled = False SerialPort1.Close() Button1.Text = “Connect” ComboBox1.Enabled = True Else SerialPort1.Open() ‘ เปิดก�รสื่อส�รของพอร์ตอนุกรม Button1.Text = “Disconnect” ComboBox1.Enabled = False Timer1.Enabled = True End If End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If SerialPort1.IsOpen Then ‘ ปิดก�รสื่อส�รของพอร์ตอนุกรมและออกจ�กโปรแกรม SerialPort1.Close() End If End End Sub Private Sub SerialPort1_PinChanged(ByVal sender As Object, ByVal e As System.IO.Ports. SerialPinChangedEventArgs) Handles SerialPort1.PinChanged Even_ = e.EventType End Sub Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick If Even_ = IO.Ports.SerialPinChange.Break Then RadioButton1.Checked = True Else RadioButton1.Checked = False End If If Even_ = IO.Ports.SerialPinChange.Ring Then RadioButton2.Checked = True Else RadioButton2.Checked = False End If RadioButton3.Checked = SerialPort1.DsrHolding RadioButton4.Checked = SerialPort1.CDHolding RadioButton5.Checked = SerialPort1.CtsHolding End Sub End Class

ไทเมอร์เปนคอนโทรลที่ออกแบบมาเพื่อให้ เกิดเหตุการณ์ตามช่วงเวลาที่ก�าหนด (Interval) ซึ่งส�าหรับโปรแกรมนี้ตั้งค่า Interval ไว้เท่ากับ 200 ซึ่งหมายถึงจะมีเหตุการณ์เกิดทุกๆ 0.2 วินาที โดยจะท�าการน�าค่าตัวแปร Even_ ที่อ่าน ค่าได้มาเปรียบเทียบ แล้วไปแสดงสถานะที่ปุม โปรแกรมที่ 2 โปรแกรมทดสอบรับค่�จ�กข�อินพุตของพอร์ตอนุกรม RadioButton แต่ส�าหรับขา CTS DCD และ DSR ไม่จ�าเปนต้องเปรียบเทียบค่าผ่านตัวแปร Even_ ทดสอบการท�างาน ก็ได้ เนื่องจากทั้ง 3 ขา มีค�าสั่งเฉพาะที่เรียกตรวจ เมื่อต่อวงจรเรียบร้อย และเขียนโปรแกรมตามโปรแกรมที่ 2 แล้ว ให้สั่งรันโปรแกรมเพื่อทดสอบ สอบค่าได้โดยตรง ประกอบด้วย การท�างาน หน้าจอของโปรแกรมจะแสดงดังรูปที่ 10 จากนั้นทดลองกดสวิตช์ไล่ล�าดับทีละตัว สังเกตการ SerialPort1.CtsHolding เปลี่ยนแปลงของสถานะที่หน้าจอ SerialPort1.CdHolding จากโปรแกรม 2 โปรแกรมนี้ก็คงพอเปนไอเดีย นําเอาพอรต USB ไปควบคุมอุปกรณภายนอกอยาง

SerialPort1.DsrHolding

งายๆ ไดแลวนะครับ

ดังนั้นเฉพาะ 3 ขานี้ในโปรแกรมจึงใช้การ ตรวจสอบค่าโดยตรงไปยัง RadioButton

The Prototype Electronics

55


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.