# linuxCNC and arduino

To extend the possibilities i did find it interessting to conect an arduino with linuxCNC.

I will use the parall port to take care of steppers and limitswitch but for all the " just for fun stuff" a arduino give you a world of opputunities.

Here in this link you can find some inspiration  https://emc2arduino.wordpress.com/

But if you want to have a look how i did it then just take a look here :

first you have to install pyserial

sudo apt-get install python-pip

sudo pip install pyserial

then you have to make a new file in you linuxCNC folder where your machine configuration are

i did call it 3axis_hjh_1

when created remember to

sudo chmod +x 3axis_hjh_1

######################################################

#!/usr/bin/python
import serial
import hal
import sys
import time

PORT = "/dev/ttyACM0"
ser = serial.Serial(PORT, 115200, timeout=15)

#Now we create the HAL component and its pins
## HAL_IN arduino can read the from linuxCNC
## HAL_OUT arduino can write to linuxCNC

c = hal.component("arduino")
c.newpin("spindleEnable",hal.HAL_BIT,hal.HAL_IN)
c.newpin("stop",hal.HAL_BIT,hal.HAL_OUT)
c.newpin("axis0-cmd",hal.HAL_FLOAT,hal.HAL_IN)
c.newpin("axis1-cmd",hal.HAL_FLOAT,hal.HAL_IN)
c.newpin("axis2-cmd",hal.HAL_FLOAT,hal.HAL_IN)
c.newpin("x-minus",hal.HAL_BIT,hal.HAL_OUT)
c.newpin("x-plus",hal.HAL_BIT,hal.HAL_OUT)
c.newpin("speed",hal.HAL_FLOAT,hal.HAL_OUT)
c.newpin("y-minus",hal.HAL_BIT,hal.HAL_OUT)
c.newpin("y-plus",hal.HAL_BIT,hal.HAL_OUT)

time.sleep(1)

#We save the machine state (i.e. whether it's off or on) so that we only
#send a message to the Arduino when it changes
axis0cmd = c['axis0-cmd']
axis1cmd = c['axis1-cmd']
axis2cmd = c['axis2-cmd']

axis0cmdOld = 0;
axis1cmdOld = 0;
axis2cmdOld = 0;
spindleEnableOld = 0;

try:
while 1:
time.sleep(.01)

axis0cmd = c['axis0-cmd'];
if axis0cmd != axis0cmdOld:
axis0cmdOld = axis0cmd;
axis0icmd = round(c['axis0-cmd'],2);
ser.write("X");
ser.write(repr(axis0icmd))
ser.write(";");

axis1cmd = c['axis1-cmd'];
if axis1cmd != axis1cmdOld:
axis1cmdOld = axis1cmd;
axis1icmd = round(c['axis1-cmd'],2);
ser.write("Y");
ser.write(repr(axis1icmd))
ser.write(";");

axis2cmd = c['axis2-cmd'];
if axis2cmd != axis2cmdOld:
axis2cmdOld = axis2cmd;
axis2icmd = round(c['axis2-cmd'],2)
ser.write("Z");
ser.write(repr(axis2icmd))
ser.write(";");

spindleEnable = c['spindleEnable'];
if spindleEnable != spindleEnableOld:
spindleEnableOld = spindleEnable;
if spindleEnable == 1:
ser.write("+S;");
else:
ser.write("-S;");

#Check to see if we have a message waiting from the Arduino
while ser.inWaiting():
#This should be set to the length of whatever fixed-length message
#you're sending from the arduino. It does not have to be the same length
#as the outbound messages.
#The Arduino generates two different key events
#One when the key is pressed down (+S) and another when it is released (-S)
#In this case we are going to ignore the release

#eStop
if(key == "e0"):
c['stop'] = 0

if(key == "e1"):
c['stop'] = 1

#jog x minus
if(key == "qq"):
c['x-plus'] = 0
c['speed'] = 0
c['x-minus'] = 0
c['y-minus'] = 0
c['y-plus'] = 0

#jog x minus
if(key == "x-"):
c['speed'] = 500
c['x-minus'] = 1

#jog x plus
if(key == "x+"):
c['speed'] = 500
c['x-plus'] = 1

#jog y minus
if(key == "y-"):
c['speed'] = 500
c['y-minus'] = 1

#jog y plus
if(key == "y+"):
c['speed'] = 500
c['y-plus'] = 1

except KeyboardInterrupt:
ser.write("-P;");
raise SystemExit

######################################################

then you have to edit you custom.hal file

######################################################

# Include your customized HAL commands here
# This file will not be overwritten when you run stepconf again
# Include your customized HAL commands here
# This file will not be overwritten when you run stepconf again

#First load the Python user module

#Second 'unlinkp' our pins to make them available for use.
# Then use 'net' to recreate/hook into them.

net my-jogspeed halui.jog-speed <= arduino.speed
net my-jogxminus halui.jog.0.minus <= arduino.x-minus
net my-jogxplus halui.jog.0.plus <= arduino.x-plus
net my-jogyminus halui.jog.1.minus <= arduino.y-minus
net my-jogyplus halui.jog.1.plus <= arduino.y-plus

# Spindle power
net spindle-On arduino.spindleEnable <= motion.spindle-on

# Stop
net estop-out arduino.stop

net xpos-cmd axis.0.motor-pos-cmd => arduino.axis0-cmd

net ypos-cmd axis.1.motor-pos-cmd => arduino.axis1-cmd

net zpos-cmd axis.2.motor-pos-cmd => arduino.axis2-cmd

#####################################################

remember to make a line in your .ini file

HALUI = halui

and now it is time for the arduino file

###################################################

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int lcd_key     = 0;

#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

#define BAUD    (115200)
char buffer;
int sofar;

void setup()
{
lcd.begin(16, 2);               // start the library
lcd.setCursor(0,0);             // set the LCD cursor   position
lcd.print("on");
Serial.begin(BAUD);
sofar=0;

}

void loop()
{

// listen for serial commands
while(Serial.available() > 0) {
if(buffer[sofar-1]==';') break;  // in case there are multiple instructions
}

// if we hit a semi-colon, assume end of instruction.
if(sofar>0 && buffer[sofar-1]==';') {
lcd.setCursor(0,0);
for(int i =0; i<16;i++){
lcd.print(buffer[i]);
}

buffer[sofar]=0;
sofar=0;
}
lcd.setCursor(0,0);

switch (lcd_key){               // depending on which button was pushed, we perform an action

case btnRIGHT:{             //  push button "RIGHT" and show the word on the screen
lcd.print("RIGHT ");
Serial.print("x+");
delay(20);
Serial.print("qq");
break;
}
case btnLEFT:{
lcd.print("LEFT   "); //  push button "LEFT" and show the word on the screen
Serial.print("x-");
delay(20);
Serial.print("qq");
break;
}
case btnUP:{
lcd.print("UP    ");  //  push button "UP" and show the word on the screen
Serial.print("y+");
delay(20);
Serial.print("qq");
break;
}
case btnDOWN:{
lcd.print("DOWN  ");  //  push button "DOWN" and show the word on the screen
Serial.print("y-");
delay(20);
Serial.print("qq");
break;
}
case btnSELECT:{
lcd.print("SELECT");
Serial.print("e1");
break;
}
case btnNONE:{
//  lcd.print("NONE  ");  //  No action  will show "None" on the screen
//Serial.print("qq");
break;
}
}

}

if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50)   return btnRIGHT;
if (adc_key_in < 195)  return btnUP;
if (adc_key_in < 380)  return btnDOWN;
if (adc_key_in < 555)  return btnLEFT;
if (adc_key_in < 790)  return btnSELECT;
return btnNONE;                // when all others fail, return this.
}

##############################################################

now i do hope that you do have it up and running ;o)
{"ft_lang_label":"__label__en","ft_lang_prob":0.50116414,"math_prob":0.8804261,"size":7129,"snap":"2019-51-2020-05","text_gpt3_token_len":2148,"char_repetition_ratio":0.15578948,"word_repetition_ratio":0.051502146,"special_character_ratio":0.3487165,"punctuation_ratio":0.19887166,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.98398983,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-01-25T18:53:15Z\",\"WARC-Record-ID\":\"<urn:uuid:e559b91d-1e5e-48e5-af96-1f93f2d58274>\",\"Content-Length\":\"23553\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:06f804e0-34e2-4a84-9aa6-a2dc837e6796>\",\"WARC-Concurrent-To\":\"<urn:uuid:c2267f90-502d-4a70-b3eb-9a6588886bc3>\",\"WARC-IP-Address\":\"217.116.232.215\",\"WARC-Target-URI\":\"http://oz1jhm.dk/content/linuxcnc-and-arduino\",\"WARC-Payload-Digest\":\"sha1:S5QGZM4YERCX64O4TUAECT2EDS4LRSUL\",\"WARC-Block-Digest\":\"sha1:O5HM47RX4CFNG5HSIMQCA7XDJBS6J73H\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-05/CC-MAIN-2020-05_segments_1579251678287.60_warc_CC-MAIN-20200125161753-20200125190753-00099.warc.gz\"}"}