در قسمت قبل از سری آموزش LinuxCNC به بررسی فایل های HAL و INI پرداختیم . در این قسمت میخوایم کار با این فایل ها رو به صورت عملی بررسی کنیم و یک درایور برای آردوینو بنویسیم و خروجی های آردوینو رو توسط نرم افزار تغییر بدیم و یکسری مقدار هم از آردوینو بخونیم. با آردوینو از این جلوتر نمیریم چراکه صرفا برای یه تست ساده هست و نرم افزاری با این پتانسیل بالا رو نمیاند با یه آردوینو چی محدود کنند.
لینک اصلی آموزشی که این پروژه رو کد نویسی کرده این هست که میتونید بررسیش کنید، البته مال خیلی سال پیشه و من یکم ادیتش کردم.
قسمت اول یک فایل HAL هست که باید فراخوانی اون رو به فایل INI در بخش HAL به این صورت اضافه کنیم.
1 | HALFILE = arduino-vcp.hal |
فایل HAL به این صورت هست.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | loadusr -W ~/linuxcnc/configs/sim.axis/arduino /dev/ttyACM0 3 loadusr -Wn arduino-vcp pyvcp arduino-vcp.xml show pin arduino-vcp net ain0 arduino.analog-in-00 => arduino-vcp.analog-in-00 arduino-vcp.analog-in-00b net ain1 arduino.analog-in-01 => arduino-vcp.analog-in-01 arduino-vcp.analog-in-01b net ain2 arduino.analog-in-02 => arduino-vcp.analog-in-02 arduino-vcp.analog-in-02b net ain3 arduino.analog-in-03 => arduino-vcp.analog-in-03 arduino-vcp.analog-in-03b net ain4 arduino.analog-in-04 => arduino-vcp.analog-in-04 arduino-vcp.analog-in-04b net ain5 arduino.analog-in-05 => arduino-vcp.analog-in-05 arduino-vcp.analog-in-05b net din0 arduino.digital-in-08 => arduino-vcp.digital-in-08 net din1 arduino.digital-in-12 => arduino-vcp.digital-in-12 net din2 arduino.digital-in-13 => arduino-vcp.digital-in-13 net aout0 arduino.analog-out-03 => arduino-vcp.analog-out-03-f net aout1 arduino.analog-out-05 => arduino-vcp.analog-out-05-f net aout2 arduino.analog-out-06 => arduino-vcp.analog-out-06-f net aout3 arduino.analog-out-09 => arduino-vcp.analog-out-09-f net aout4 arduino.analog-out-10 => arduino-vcp.analog-out-10-f net aout5 arduino.analog-out-11 => arduino-vcp.analog-out-11-f net dout0 arduino.digital-out-02 <= arduino-vcp.digital-out-02 net dout1 arduino.digital-out-04 <= arduino-vcp.digital-out-04 net dout2 arduino.digital-out-07 <= arduino-vcp.digital-out-07 setp arduino.digital-in-08-pullup 1 setp arduino.digital-in-12-pullup 1 setp arduino.digital-in-13-pullup 1 |
فایل بالا رو در کنار فایل ini قرار بدید و خط اول اون رو در صورت نیاز بر اساس سیستم خودتون تغییر بدید.
خط اول فایل بالا یک فایل دیگه با نام arduino رو اجرا میکنه که این محتویاتش هست.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #!/usr/bin/python # HAL userspace component to interface with Arduino board # Copyright (C) 2007 Jeff Epler <jepler@unpythonic.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import serial import hal import sys import time def encode(addr, data): if data < 0 or data > 2048: raise ValueError, "data %02d out of range" % data if addr < 0 or addr > 8: raise ValueError, "address %02d out of range" % addr b1 = 0x80 | (addr << 4) | (data >> 7) b2 = data & 0x7f return chr(b1) + chr(b2) PORT = "/dev/ttyUSB0" if len(sys.argv) > 1: PORT = sys.argv[1] if len(sys.argv) > 2: nout = int(sys.argv[2]) else: nout = 6 if nout > 6 or nout < 0: raise SystemExit, "Number of digital outputs must be from 0 to 6" pinmap = [2,4,7,8,12,13] dacpinmap = [3,5,6,9,10,11] ser = serial.Serial(PORT, 9600, timeout=2) c = hal.component("arduino") for port in range(6): c.newpin("analog-in-%02d" % port, hal.HAL_FLOAT, hal.HAL_OUT) c.newparam("analog-in-%02d-offset" % port, hal.HAL_FLOAT, hal.HAL_RW) c.newparam("analog-in-%02d-gain" % port, hal.HAL_FLOAT, hal.HAL_RW) c.newpin("analog-out-%02d" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_IN) c.newparam("analog-out-%02d-offset" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_RW) c.newparam("analog-out-%02d-scale" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_RW) c['analog-in-%02d-gain' % port] = 1.0 c['analog-out-%02d-scale' % dacpinmap[port]] = 1.0 for port in range(nout): c.newpin("digital-out-%02d" % pinmap[port], hal.HAL_BIT, hal.HAL_IN) c.newparam("digital-out-%02d-invert" % pinmap[port], hal.HAL_BIT, hal.HAL_RW) for port in range(nout, 6): c.newpin("digital-in-%02d" % pinmap[port], hal.HAL_BIT, hal.HAL_OUT) c.newpin("digital-in-%02d-not" % pinmap[port], hal.HAL_BIT, hal.HAL_OUT) c.newparam("digital-in-%02d-pullup" % pinmap[port], hal.HAL_BIT, hal.HAL_RW) c.ready() firstbyte = 0 state = 0 try: while 1: while ser.inWaiting(): byte = ord(ser.read()) if firstbyte & 0x80 == 0x80 and byte & 0x80 == 0: v = (firstbyte << 7) | byte port = (v >> 11) & 7 if port < 6: if port >= nout: b = v & 1024 c['digital-in-%02d' % pinmap[port]] = b != 0 c['digital-in-%02d-not' % pinmap[port]] = b == 0 gain = c['analog-in-%02d-gain' % port] or 1. offset = c['analog-in-%02d-offset' % port] value = (v & 1023) / 1023. * 5.0 * gain + offset c['analog-in-%02d' % port] = value firstbyte = byte scale = c['analog-out-%02d-scale' % dacpinmap[state]] or 1. offset = c['analog-out-%02d-offset' % dacpinmap[state]] data = (c['analog-out-%02d' % dacpinmap[state]] - offset) / scale / 5 data = int(data * 255 + 0.5) if data < 0: data = 0 if data > 255: data = 255 if state < nout: out = not c['digital-out-%02d' % pinmap[state]] invert = not c['digital-out-%02d-invert' % pinmap[state]] if out != invert: data |= 0x200 data = data | 0x100 else: pullup = c['digital-in-%02d-pullup' % pinmap[state]] if pullup: data |= 0x200 data = data | (state << 11) ser.write(chr(0x80 | (data >> 7))) ser.write(chr(data & 0x7f)) state = (state+1) % 6 time.sleep(.001) except (KeyboardInterrupt,): raise SystemExit, 0 |
این فایل رو هم باید در همون پوشه ای که بقیه فایل ها هستند قرار بدید، همونطور که در خط اول فایل HAL آدرس دهی شده، همچنین در صورت نیاز باید با کمک این دستور بهش دسترسی اجرا بدید.
1 | chmod +x arduino |
فایل پایتون بالا از کتابخونه های hal استفاده میکنه و یک کامپوننت با نام arduino میسازه و پین های لازم رو به اون اضافه میکنه، بعد از اون با کمک پورت سریال با خود سخت افزار آردوینو ارتباط میگیره و دیتا تبادل میکنه در ادامه میتونید فرمت دیتایی که تبادل میشه رو مشاهده کنید.
دیتا هر بار به صورت دو بایتی ارسال میشه از هر سمت، بیت اول مشخص میکنه که بایت اول دیتا هست یا بایت دوم، بعد از اون 3 بیت آدرس که مشخص میکنه کدوم مقدار میخواد ارسال بشه و بعد از اون هم 11 بیت دیتا
این هم کدی که باید روی آردوینو ریخته بشه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | void setup() { Serial.begin(9600); } uint8_t adc=0; uint8_t firstbyte=0; uint8_t pinmap[6] = {2,4,7,8,12,13}; uint8_t dacpinmap[6] = {3,5,6,9,10,11}; void loop() { while(Serial.available()) { uint8_t byte = Serial.read(); if(((firstbyte & 0x80) == 0x80) && ((byte & 0x80) == 0)) { // got a packet uint16_t payload = (firstbyte << 7) | byte; uint8_t address = (firstbyte >> 4) & 7; uint8_t dac = payload & 0xff; uint8_t dir = (payload & 0x100) == 0x100; uint8_t out = (payload & 0x200) == 0x200; if(address < 6) { analogWrite(dacpinmap[address], dac); digitalWrite(pinmap[address], out); pinMode(pinmap[address], dir); } } firstbyte = byte; } uint16_t v = analogRead(adc) | (adc << 11); if(digitalRead(pinmap[adc])) v |= (1<<10); Serial.write((v >> 7) | 0x80); Serial.write(v & 0x7f); adc = (adc + 1) % 6; } |
قسمت آخر هم یک فایل با نام arduino-vcp.xml هست که این هم کنار بقیه فایل ها باید باشه، این در حقیقت یک پنل گرافیکی هست که مقدار های دریافتی از آردوینو رو نمایش میده و مقدار های ارسالی رو توسط اون تنظیم میکنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?xml version='1.0' encoding='UTF-8'?> <pyvcp> <table> <tablesticky sticky="n"/> <tablerow/> <label text="digital-in-08" font="helvetica -12 bold"/> <label text="digital-in-12" font="helvetica -12 bold"/> <label text="digital-in-13" font="helvetica -12 bold"/> <label text="digital-out-02" font="helvetica -12 bold"/> <label text="digital-out-04" font="helvetica -12 bold"/> <label text="digital-out-07" font="helvetica -12 bold"/> <tablerow/> <led halpin="digital-in-08"/> <led halpin="digital-in-12"/> <led halpin="digital-in-13"/> <checkbutton halpin="digital-out-02"/> <checkbutton halpin="digital-out-04"/> <checkbutton halpin="digital-out-07"/> <tablerow/> <label text="analog-in-00" font="helvetica -12 bold"/> <label text="analog-in-01" font="helvetica -12 bold"/> <label text="analog-in-02" font="helvetica -12 bold"/> <label text="analog-in-03" font="helvetica -12 bold"/> <label text="analog-in-04" font="helvetica -12 bold"/> <label text="analog-in-05" font="helvetica -12 bold"/> <tablerow/> <number halpin="analog-in-00" format="-2.4f"/> <number halpin="analog-in-01" format="-2.4f"/> <number halpin="analog-in-02" format="-2.4f"/> <number halpin="analog-in-03" format="-2.4f"/> <number halpin="analog-in-04" format="-2.4f"/> <number halpin="analog-in-05" format="-2.4f"/> <tablerow/> <bar halpin="analog-in-00b" min_="0" max_="5"/> <bar halpin="analog-in-01b" min_="0" max_="5"/> <bar halpin="analog-in-02b" min_="0" max_="5"/> <bar halpin="analog-in-03b" min_="0" max_="5"/> <bar halpin="analog-in-04b" min_="0" max_="5"/> <bar halpin="analog-in-05b" min_="0" max_="5"/> <tablerow/> <label text="analog-out-03" font="helvetica -12 bold"/> <label text="analog-out-05" font="helvetica -12 bold"/> <label text="analog-out-06" font="helvetica -12 bold"/> <label text="analog-out-09" font="helvetica -12 bold"/> <label text="analog-out-10" font="helvetica -12 bold"/> <label text="analog-out-11" font="helvetica -12 bold"/> <tablerow/> <scale resolution="0.1" halpin="analog-out-03" min_="0" max_="5" orient="h"/> <scale resolution="0.1" halpin="analog-out-05" min_="0" max_="5" orient="h"/> <scale resolution="0.1" halpin="analog-out-06" min_="0" max_="5" orient="h"/> <scale resolution="0.1" halpin="analog-out-09" min_="0" max_="5" orient="h"/> <scale resolution="0.1" halpin="analog-out-10" min_="0" max_="5" orient="h"/> <scale resolution="0.1" halpin="analog-out-11" min_="0" max_="5" orient="h"/> </table> </pyvcp> |
این هم پیشنمایشش
حالا همه فایل ها رو ذخیره کنید و LinuxCNC رو اجرا کنید و عملکرد رو بررسی کنید، بهتره که شما یه قدم جلوتر برید و مثلا دکمه ای روی آردوینو رو اگر فشار دادید، به جای اینکه یک نشانگر در پنل بالا روشن بشه، مثلا دکمه شروع برنامه فشار داده بشه یا برنامه متوقف بشه.
این هم ویدیویی از عملکرد پروژه
لینک های مفید
سلام و احترام؛
چرا این سری آموزش ادامه پیدا نکرد؟ خیلی عالی بود 🙁
مرجع مناسبی میشناسین برای مطالعه ؟
سلام. فرصتش پیش نیومد دیگه
میخوام ادامش بدم ولی کی رو نمیدونم 🙁
بهترین منبع داکیومنت های خود linuxcnc هست:
http://linuxcnc.org/docs/stable/html/
سلام
تشکر بابت زحمتی که کشیدین
بیزحمت ادامه بدین
خواهش میکنم
ایشالا به زودی
سلام قسمت جدید کی منتشر میشه ؟
سلام وخسته نباشید ادامه داره مهندس جان
در تلاشم ادامش رو بنویسم
هنوز فرصت نشده
سلام و احترام
چرا قسمت های جدید منتشر نمیشه؟ منتظر باشیم ؟
سلام
منتظر باشید اما صبر زیاد هم داشته باشید :))
سلام و عرض خسته نباشید
خیلی وقته سایت رو دنبال میکنم میبینم قسمت جدیدی منتشر نشده 🙂 شدیدا منتظر قسمت بدی این عنوانم
سلام
ممنون از شما 🙂
درگیر بحث سخت افزار هستیم برای ادامه آموزش ها
ایشالا تا یکماه دیگه منتشر میشه
با سلام
ممنون بابات اموزش خوبتون … به نظرم به جای پیاده سازی سطحی ، تا همین جا اگر کد های برناه اردوینو و کد های رابط گرافیکی به صورت عمیق تر بررسی بشه بهتره مخصوصا این که سخت افزار های مورد نیاز توی ایران کم یابه و چاره ای نیست جز راه اندازی با میکرو
سلام. تا چند وقت دیگه یک سخت افزار با قیمت مناسب و به کمک FPGA که کپی از کارت های mesa هست رو معرفی میکنیم
این کد آردویتو هم چیز قابل توضیحی نداشت و گرنه حتما این کار رو میکردم
اگر سوالی بابتش دارید بفرمایید
سلام … بسیار بسیار عالی …. خسته نباشید … یه سوال ….. اینکه تست با آردوینو همین کافیه …. دیگه با چی قراره تست کنید؟
ممنون از شما
با چیز دیگه ای قرار نیست تست کنیم
دیگه میریم سراغ پیاده سازی با برد اورنج پای 4 LTS
عالی بود خیلی ممنونم ✅✅✅
خواهش میکنم 🙂