Sunday 10 April 2016

Hi and thanks grbl team to make grbl opensource again many thanks to grbl team for their hard work and effort .thanks to  universal gcode sender builder guys and thanks to all guys !
now lets talk on why are we here ,this poast is for cnc guys ! people around the world use grbl to drive their cnc instead of mach3 or linuxcnc the problem with mach3 and linuxcnc is that we need parallel port and thats the thing that laptop doesnt have so to drive machine with laptop or pc  we can use grbl , but some time if we have some work that we need to build low cost machine and we dont want even pc or laptop .
here is the main point the pc or laptop only doing is sending g code to arduino some gcode sender have some speciall ferature but after all they send gcode and if want to go for low cost solution we should do the thing like most 3d printer have that they can print without using pc  or laptop using only sd card so we can do the same thing with cnc ,but its a shame that lots  of guys have done grbl without pc or laptop but nobody had uploaded code or given ready made solution and
that want i want to solve here
i have used edward's idea but in  software approch   like universal gcode sender is using
here is a link of grbl arduino setup
http://www.shapeoko.com/wiki/index.php/Headless

what i have used is two arduino  and one sd card shield
one arduino for grbl and second for sending gcode to grbl
thats the same setup on above link
the code is here code is contained with lots of comment ,and may have unsed variable  and thats because of the work in prograss and comment may helpful to understand code also
enough is enough let the code talk !
the code is ready to rock  all you need is just upload

I also welcome to coders to use this and make it more elegant !

code:

/*
//whith this code you can use grbl 
//without using pc 
//we are using two arduino here 
//one for grbl and other for 
//gcode sending from sd crad

Author : magansoma
Note :We dont take any responsibility for any kind of dmaage or anything else its upto you
you can use or modify this code its opensource  
*/
#include <SD.h>
#include <SPI.h>

File myFile;

String x_move, y_move,z_move,gcode_value;
String homing_gcode;
char get_ok;
int ok_word;


const int x_plus = 2;
const int x_minus=3 ;
const int y_plus= 5;
const int y_minus= 6;
const int z_plus= 7;
const int z_minus= 8;
const int home_button=9;
const int send_button=10;

int x_count=0;
int y_count=0;
int z_count=0;
int grbl_rx_buffer;

int rx_buffer_check_rate=500;//rx buffer check rate 500 millisecond

String machine_status="";
int machine_flag=0;
const int rx_buffer_limit =64;//arduino has 128 is 127 byte of buffer 
//so we are here giving less then 127 buffer limit

String get_rx=" ";//this ensures that first gecode doesnt send 
int rx_data=0;//////until Rx buffer is cheked or there is no rx tx connection
////////200 which less then 127 so first time buffer is checked with 200 
/////so after second loop it gets its readed value from rxbuffer

int gecode_send_delay=100;//////
//////////so this will put some delay fofre sending next g code
////this may pervent some problem when we lost rx tx connection 
/////so that time insted of sending g code at full speed this will put some delay

void setup()
{
  pinMode(x_plus, INPUT);
 // Open serial communications and wait for port to open:
  Serial.begin(115200);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
/////////////////sd card initializtion  starts here///

  Serial.print("Initializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
   pinMode(10, OUTPUT);
   
  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);
  
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing is cool");
 // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
  
  ////////// sd card initializtion ends here////////////////////
  
  digitalWrite(x_plus,HIGH);
  digitalWrite(x_minus,HIGH);
  digitalWrite(y_plus,HIGH);
  digitalWrite(y_minus,HIGH);
  digitalWrite(z_plus,HIGH);
  digitalWrite(z_minus,HIGH);
  digitalWrite(home_button,HIGH);
  digitalWrite( send_button,HIGH);
 
  x_move = String("G0X");
  y_move = String("G0Y");
  z_move = String("G0Z");
  homing_gcode= String("G0X0Y0Z0");
  String gcode_value = String("");
  String get_ok= String();
  
}






void loop()
{
  while(1){
    
 //////////////////x movement////////////////////
 ////////////// x++ movement////////////////////
 if(!digitalRead(x_plus)) {
   x_count++;//printing here solves the problem
  gcode_value =x_move+x_count;
  Serial.println(gcode_value);  
   //x_count++; placing it here 
   //creats problem because its already 
   //incremented but not printed 
   //so when we go in rrevese direction 
   //that unprinted variable will comes and 
   //thats we dont want
   //so soultion is increment x_count before prints 
   //so that gives us crrent value of x_count
   delay(100);
 }   
//////////////x-- movement//////////////////////
if(!digitalRead(x_minus)) {
    x_count--;//read comments of x++
  gcode_value =x_move+x_count;
  Serial.println(gcode_value);  
//  x_count--; not here 
   delay(100);
 }   
////////////x  movement ends here///////////////// 
 
////////y movement////////////////////////////////
/////// y++ movement/////////////////////////////
if(!digitalRead(y_plus)) {
  y_count++;// read x+= comment
  gcode_value =y_move+y_count;
  Serial.println(gcode_value);  
  //y_count++; not here
   delay(100);
 }   
///// y-- movement ///////////////////////////////
if(!digitalRead(y_minus)) {
   y_count--;//read x++ comment
  gcode_value =y_move+y_count;
  Serial.println(gcode_value);  
 // y_count--; not here
   delay(100);
 }   
 /////////////y movement ends here//////////////////
 
////z movement ///////////////////////////////////  
/////z++ movement ///////////////////////////////  
  if(!digitalRead(z_plus)) {
    z_count++;//read x++ comments
  gcode_value =z_move+z_count;
  Serial.println(gcode_value);  
  ///z_count++; not here
   delay(100);
 }
///// z-- movement ////////////////////////////////
 
 if(!digitalRead(z_minus)) {
   z_count--;//read x++ comments
  gcode_value =z_move+z_count;
  Serial.println(gcode_value);  
  ///z_count--; not here 
   delay(100);
  }
////// z movement ends here ///////////////////////

///// home movement ///////////////////////////////  
  if(!digitalRead(home_button)) {
  Serial.println(homing_gcode);  
   delay(100);
 }
///// home movement ////////////////////////////////


///// go for next process//////////////////
//ex. sending data from sd card


   if(!digitalRead(send_button)) {
   //----------- need todo some initilize prodedure here --------------
   //------------before sending g code to grbl----------------------------
   //Serial.println("starting g code sending");  
   delay(100);
   break;
 }



///////////////////go for next process ends here




 }////////////////while loop ends here
  
   String l_line = "";
  //opens the file here
   myFile = SD.open("circle.txt");
   ///myFile = SD.open("CROSS.TAP");
   while (myFile.available() != 0) { 
   //A inconsistent line length may lead to heap memory fragmentation    
   l_line = myFile.readStringUntil('\n');    
   if (l_line == "") //no blank lines are anticipated    
   break;   
    // 
    

 ///// G code flow control starts here /////////////   
   //////this checks ok is sent by grbl 
   ////it stays here untill ok is recived 
   ///it checks ok  from ok reading string is
  // not worked here  may be its taking too much times so it may miss some "ok"
  // from grbl
   //////////gcode flow control strats here
   
  /// three method to gcode flow control
   //// MEHOD 1(GOOD MEHOD )  ok method only reading o character
   ///below two method needs rx buffer setting on  by $10=8 in grbl 
   /////we can recheck it by $$ 
   /// MEHOD2 (work slow) desition based on 
   ////reading run idle in string legth measurement
   ///MEHOD 3 (works but some bug) extracting number from string 
   
   
   //////<<<<<<<<<<<<<this line sends g code >>>>>>>>>>>>>>>>>>>
   Serial.println(l_line);
   
 /////////<<<<<<<<<<<above lines sends g code >>>>>>>>>>>>>>>>>>  
   
   ////////////reading one character MEHOD 1 
   //this mehod is first send g code 
   //and check responce after  gcode sent 
  ////with ok massage from grbl 
  while(1){
  
   get_ok = Serial.read();
  
  // get_ok.trim();//clear off white spaces in 
   //strarting end ending of string
   if (get_ok == 'o'){ 
     get_ok=' ';
    //ok_word++;
    break;
    
   }
   //delay(100);
 
   
  }
  
   ////////reading rx buffer METHOD 2//////////
   /*
   while(1){
     ///delay(1);
     //<Idle,RX:0>
    //<Run,RX:110>
    //<Run,RX:55>
    // <Run,RX:0>
   get_rx=" ";//clearing it to reuse
    
   Serial.println('?');//sending this to grbl give us current rx buffer status
   get_rx=Serial.readString();//getting rxbuffer data from grbl
   //Serial.println(get_rx.length());
   get_rx.trim();
  // Serial.println(get_rx.length());
    ///if machine is in idle condition send gcode
    //so  after sending some g coode 
    //this machine will come to run state so we can now check 
    //for run state after this
    if(get_rx.substring(1,5)=="Idle"){
      //in Idle condition should be empty so we are not checking
     // any number from here <Idle,RX:0>
    // Serial.println("this is Idle");
      
      break;
     }
    ///we are check here is RX:100 or less then 100 
    ///so continue sending gcode else dont sent
   /// and wait for RX buffer to be empty  
   if(get_rx.substring(1,4)=="Run"){
    
     //Serial.println("this is Run");
     ////we are making dsition based on sringh 
     ///length here so 
              //<Run,RX:110>=sringhlength =12
              //<Run,RX:55>=Stringlength=11
             // <Run,RX:0>=striglength=10
     ///so if we have srighlengh >12 
     //we dont want to send gcode
    //less <12  wi will send gcode conditon
   // will be like this <= 11
   ////so we can go ahead and send next gcode 
   
    if(get_rx.length() <= 11){
     // Serial.println(" this is less than 100");
        break;
                  
                 }
                 
              
            }
    //  Serial.println(" buffer is full currenty ");
     } 
        
       
 */
  
  //////reading rxbuffer ends here///////////////////////
  
/////<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/// extracting number from string MEHOD 3
//////<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/*  while(1){
  //get_rx=""; //clearing varible to reuse
 // rx_data=0; //
 Serial.flush();
  Serial.println('?');//sending this to grbl
 // give us current rx buffer status which is like this
 // //<Idle,RX:0>
    //<Run,RX:110>
    //<Run,RX:55>
    // <Run,RX:0>
  get_rx=" ";
  while (Serial.available()>0) {
    //delay(3); 
    /////we can not cmpare by R and I 
    //bcause there are R for RX
    char c = Serial.read();
    //before extracting number we check this
    if(c=='d'){/// d in Idle 
      machine_status="Run";
      machine_flag=1;
    }
    if(c=='u'){//////u in Run
       machine_status="Idle";
       machine_flag=0;
    }
    /////this extracts the number from string
    if(isDigit(c)){
    get_rx += c; 
    }
  }
  

 Serial.println(get_rx);
 
 rx_data= get_rx.toInt();
 ////Serial.println(rx_data);
 
 if(rx_data <=rx_buffer_limit){
  break;
 }
 
 
   //delay(100);
   delay(rx_buffer_check_rate);
   //we are here so it means buffer is full
   ////// so give some smoothness to sending  ? to grbl 
   ///so every 100 millisecond we are checking status of rx buffer
 }
*/
////////////////>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
/////MEHOD 3 ends here 
/////////>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
///////////////gcode flow control ends here////////


///////this sends G code ///////////// 
//////<<<<<<<<<<<<<this line sends g code >>>>>>>>>>>>>>>>>>>
  ////Serial.println(l_line);
   
 /////////<<<<<<<<<<<above lines sends g code >>>>>>>>>>>>>>>>>>  
 
  delay(gecode_send_delay);//////smooth opration in gcode sending //this closes file 
myFile.close();
delay(1000);//may need some refresh time
/////to SD CARD after closing file 
/////////////total program completes here 
///put here want you wqant to do after programme compltes  delay(1000); 
}