Arduino + LinuxCNC = Sterowanie po USB

Dyskusje dotyczące działania obsługi programu LinuxCNC
Awatar użytkownika

Autor tematu
syntetyczny
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 6
Posty: 2696
Rejestracja: 08 gru 2009, 22:33
Lokalizacja: Elbląg
Kontakt:

Arduino + LinuxCNC = Sterowanie po USB

#1

Post napisał: syntetyczny » 21 sie 2012, 23:31

Witam,

W poszukiwaniu materiałów do konstrukcji robota delta, natknąłem się na ciekawy wątek:
http://www.linuxcnc.org/index.php/engli ... 16&id=5378 . Wynika z tego, że można wykorzystać dosyć popularne i tanie Arduino jak kontroler USB zastępujący LPT. Pamiętam, że jakiś czas temu były pewne kontrowersje, związane z brakiem takowej możliwości w LinuxCNC, dlatego też zamieszczam linka dla ciekawskich.


Kto pyta, nie błądzi. Eppur si muove
Kreatura CNC
Modernizacja plotera megaplot

Tagi:

Awatar użytkownika

markcomp77
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 21
Posty: 3975
Rejestracja: 18 wrz 2004, 12:51
Lokalizacja: k/w-wy
Kontakt:

#2

Post napisał: markcomp77 » 22 sie 2012, 08:38

syntetyczny pisze:Wynika z tego, że można wykorzystać dosyć popularne i tanie Arduino jak kontroler USB zastępujący LPT.
chyba jeszcze trochę barkuje... :(
andypugh pisze:USB is not realtime, it is not suitable for running stepper motors (it can be used to control remote step-generators, but even that is pushing it).
Jeff's Arduino driver is absolutely not intended for, nor is it suitable for, motion control. It runs as a userspace module apart from all the other issues.

przedstawiony "wsad" do arduino

Kod: Zaznacz cały

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.print((v >> 7) | 0x80, BYTE); 
    Serial.print(v & 0x7f, BYTE); 
    adc = (adc + 1) % 6; 
} 
może być pomocny jako rozszerzenie do zbierania informacji analogowych... + parę pinów we/wy
jednak przy tym sposobie komunikacji -- te piny będą "zbyt powolne" do pracy w szybkich wątkach generacji STEP/DIR

dodatkowo --->> komunikacja po USB nie jest przewidywalna czasowo... no chyba, że ktoś zrobi RealTime USB...
SpotkanieCNC: STOM-TOOL Marzec 2014
http://www.cnc.info.pl/topics79/spotkan ... t55028.htm

Awatar użytkownika

pascalPL
Specjalista poziom 2 (min. 300)
Specjalista poziom 2 (min. 300)
Posty w temacie: 4
Posty: 547
Rejestracja: 10 cze 2011, 14:19
Lokalizacja: Lublin

#3

Post napisał: pascalPL » 22 sie 2012, 12:01

Hmm.. a w EMC2 jako port lpt konfiguruje niby /dev/ttyUSB0 ? Nie czaje troszkę tego "translatora" lpt->usb :).

Awatar użytkownika

markcomp77
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 21
Posty: 3975
Rejestracja: 18 wrz 2004, 12:51
Lokalizacja: k/w-wy
Kontakt:

#4

Post napisał: markcomp77 » 22 sie 2012, 12:20

pascalPL pisze:Hmm.. a w EMC2 jako port lpt konfiguruje niby /dev/ttyUSB0 ? Nie czaje troszkę tego "translatora" lpt->usb .
...tutaj pomyśle z arduino jest nieco inaczej
komunikacja z HALem jest przez aplikację user-space w pytonie

arduino.py

Kod: Zaznacz cały

#!/usr/bin/python
#    HAL userspace component to interface with Arduino board
#    Copyright (C) 2007 Jeff Epler <[email protected]> 
#
#    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
takie przepytywanie portu szeregowego ser.inWaiting(), realizowane przez usb...

a to dalej "wskakuje" do HALa

arduino-vcp.hal

Kod: Zaznacz cały

loadusr -W arduino /dev/ttyUSB0 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

waitusr arduino-vcp
i na koniec można to rzucić na ekran za pomocą arduino-vcp.xml

Obrazek

dokładnie opisane:
Improved Analog & Digital Interface with Arduino
http://emergent.unpythonic.net/01198594294
SpotkanieCNC: STOM-TOOL Marzec 2014
http://www.cnc.info.pl/topics79/spotkan ... t55028.htm

Awatar użytkownika

tuxcnc
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 5
Posty: 7875
Rejestracja: 26 lut 2011, 23:24
Lokalizacja: mazowieckie

#5

Post napisał: tuxcnc » 22 sie 2012, 16:52

Linuxcnc umożliwia podłączenie różnych urządzeń poprzez port szeregowy (więc także przez USB), ale nie umożliwia sterowania silnikami w ten sposób.

Zewnętrzne kontrolery ruchu to domena Windows, który w przeciwieństwie do Linuxcnc nie jest systemem czasu rzeczywistego i nie potrafi sterować w czasie rzeczywistym sterownikami step/dir podłączonymi pod LPT.
Mach/LPT jakoś działa, ale nigdy tak jak powinien, co czasem słychać a czasem nawet widać.
Dlatego wymyślono zewnętrzne kontrolery sterowane prostymi komendami opisującymi jakiś elementarny ruch, które to komendy są tłumaczone na sekwencje impulsów step/dir przez sterownik który jest jak najbardziej maszyną czasu rzeczywistego, zwykle nawet jednozadaniową.

Niektórzy nie bardzo rozumieją o co w tym wszystkim chodzi.
Windows-Mach-sterownik_zewnętrzny to taki kierowca chory na padaczkę, który w przerwach pomiędzy atakami wskazuje drogę, ale kierownicę trzyma ktoś inny.
Ludziom się wydaje że to Mach steruje, ale tak na prawdę to tylko wytycza kierunek.

Niby nic nie stoi na przeszkodzie, żeby zewnętrzny sterownik stworzony dla Mach/Windows współpracował z Linuksem, tylko nie bardzo wiadomo po co.
Linuxcnc nie dostaje czkawki z byle powodu i radzi sobie bez problemu przez port LPT.
Zewnętrzny sterownik to pieniądze wydane bez potrzeby.
Szczególnie bez sensu jest Arduino, które kosztuje kosmiczne pieniądze w porównaniu do mozliwości.

.

Awatar użytkownika

markcomp77
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 21
Posty: 3975
Rejestracja: 18 wrz 2004, 12:51
Lokalizacja: k/w-wy
Kontakt:

#6

Post napisał: markcomp77 » 22 sie 2012, 16:55

tuxcnc pisze:Szczególnie bez sensu jest Arduino, które kosztuje kosmiczne pieniądze w porównaniu do mozliwości.
arduino nie kosztuje tak dużo - jak na kartę zdolną przekazać wartości analogowe do HALa...
SpotkanieCNC: STOM-TOOL Marzec 2014
http://www.cnc.info.pl/topics79/spotkan ... t55028.htm

Awatar użytkownika

Autor tematu
syntetyczny
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 6
Posty: 2696
Rejestracja: 08 gru 2009, 22:33
Lokalizacja: Elbląg
Kontakt:

#7

Post napisał: syntetyczny » 22 sie 2012, 21:34

Pomijając wyższość Linuxa nad całym światem, mam tu kolejną ciekawostkę:
rsteppercontroller
Kto pyta, nie błądzi. Eppur si muove
Kreatura CNC
Modernizacja plotera megaplot

Awatar użytkownika

markcomp77
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 21
Posty: 3975
Rejestracja: 18 wrz 2004, 12:51
Lokalizacja: k/w-wy
Kontakt:

#8

Post napisał: markcomp77 » 22 sie 2012, 21:55

syntetyczny pisze:Pomijając wyższość Linuxa nad całym światem, mam tu kolejną ciekawostkę:
rsteppercontroller
zamierzenia ambitne...
ale -- ostatnia modyfikacja projektu (i pierwsza) to 2010 rok...
czyli projekt jest martwy

arduino ta fajne ustrojstwo - łatwo się programuje.. itd
ale ambitna S-rampa przekracza możliwości avra :(... sprawdzaliśmy to w wątku o oscylatorze:
https://www.cnc.info.pl/topics65/rampa- ... ht=#265578

normalna rampa daje się zrobić... ale z pewnymi ograniczeniami
S-rampa wymaga większej szybkości pracy (ciąg dalszy rozważań na rampie jest w planach na arm-cortex4)

hehe... do arma można wsadzić całe linuxcnc + system...
SpotkanieCNC: STOM-TOOL Marzec 2014
http://www.cnc.info.pl/topics79/spotkan ... t55028.htm

Awatar użytkownika

tuxcnc
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 5
Posty: 7875
Rejestracja: 26 lut 2011, 23:24
Lokalizacja: mazowieckie

#9

Post napisał: tuxcnc » 23 sie 2012, 05:39

syntetyczny pisze:Pomijając wyższość Linuxa nad całym światem
Jak się czegoś nie rozumie to trzeba wyśmiać ?

A takie cuda Kolega widział : http://allegro.pl/listing.php/search?st ... =1&order=p ?
I wcale nie mówimy o systemie operacyjnym, tylko o stosunku możliwości do ceny

A jeśli już mowa o Linuksie, to on w zamierzeniu nie miał być systemem czasu rzeczywistego, ale dlaczego RTAI nie powstał pod Windows nietrudno zrozumieć, wystarczy pomyśleć.

.

Awatar użytkownika

Autor tematu
syntetyczny
Lider FORUM (min. 2000)
Lider FORUM (min. 2000)
Posty w temacie: 6
Posty: 2696
Rejestracja: 08 gru 2009, 22:33
Lokalizacja: Elbląg
Kontakt:

#10

Post napisał: syntetyczny » 23 sie 2012, 08:22

Pomimo daty, projekt już działał.

[youtube][/youtube]
markcomp77 pisze:hehe... do arma można wsadzić całe linuxcnc + system...
Można, nawet myślałem o płytce, która się nazywa BeagleBone, która ma już swój prekompilowany systemik linuxowy. Jednakże, powyżej pewnej kwoty, nie widzę sensu pakowana się w systemy embedded, gdyż za całkiem przyzwoite pieniądze można kupić małego zintegrowanego kompa z lpt.
Kto pyta, nie błądzi. Eppur si muove
Kreatura CNC
Modernizacja plotera megaplot

ODPOWIEDZ Poprzedni tematNastępny temat

Wróć do „LinuxCNC (dawniej EMC2)”