Sending Gcodes read from SD Card

Hello,
I connected the cnc shield and 2 stepper motors to my Arduino uno board and uploaded the "GRBL" library. I have properly connected SDCard to my Arduino nano board and put a text file containing GCode in my SDCard. How can I read the GCodes in the SDCard with Arduino nano and send them to my Uno card via Rx-Tx connection and run them? I would be very happy if you have done a similar work or share the code with me. I'm waiting for your help. Thank you.

Have you looked at the examples for the SD library ?

Hello,
Yes I did it. I also reviewed similar studies. And I found the link below. I write the name of my test file instead of "string filename" but I get "-- error: Bad number format doesn't exist --" on the serial monitor. Why do you think it might?

the code you linked to uses Serial1 which means you need a MEGA (or change the code)
➜ arduino uno run Grbl and Mega run this program

is this your config?

Configuration of the person sharing this code. As he said, I am working on grbl yi uno and this code in mega. The code opens the sd card then loops as in the picture.

This code should open the text file in the Sdcard and continue the process, but it doesn't. Can you help me do this?

Please post your version of the code

This is my code.

/*Here is a basic arduino sketch to show how 
open a gcode file from sd card reader connected to an Arduino Mega
and stream code via Serial to an other Arduino which is running grbl.
The arduino running this program must have several Serial ports.

Here arduino uno run Grbl and Mega run this program

The Arduino Uno has one Serial port:
Serial on pins 0(RX) and 1(TX)
The Arduino Mega has four serial ports: 
Serial on pins 0(RX) and 1(TX), Serial1 on pins 19 (RX) and 18 (TX), 
Serial2 on pins 17 (RX) and 16 (TX),Serial3 on pins 15 (RX) and 14 (TX).

The 2 arduino must be connected between them as this:
RX(uno) to TX(Mega) and TX(Uno) to RX(Mega) and GND to GND.

You need to launch serial monitor to interact with the program.

You can replace the serial monitor interface by any
LCD touchscreen interface and then you almost have a CNC without any computer.

Enjoy!*/

#include <SD.h>

File myFile;
boolean restart = true;		

void setup(){

	Serial.begin(115200);
	Serial1.begin(115200);
}


void loop(){

	checkSD();
	while(restart){
		openFileSD();
		sendGcode();
	}
}



void checkSD(){

	// Check if SD card is OK

	// 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.

	while(!SD.begin(10)){
		Serial.println("Please insert SD card...\n");
		delay(1000);
	}

	Serial.println("SD card OK...\n");
	delay(1000);
}

void openFileSD(){

	String fileName = "test2.txt" ;
	char fileNameChar[100]={0};				// char array for SD functions arguments

	Serial.println("Enter name for a gcode file on SD : \n");
	emptySerialBuf(0);
	fileName=getSerial(0);

	for(int i=0;fileName.charAt(i)!='\n';i++)		//convert String in char array removing '\n'
		fileNameChar[i]=fileName.charAt(i);

	if(!SD.exists(fileNameChar)){				//check if file already exists
		Serial.print("-- ");
		Serial.print(fileNameChar);
		Serial.print(" doesn't exists");
		Serial.println(" --");
		Serial.println("Please select another file\n");
      	delay(200);
      	openFileSD();
    } 
    else{
     	myFile = SD.open(fileNameChar, FILE_READ);		//create a new file
     	Serial.print("-- ");
     	Serial.print("File : ");
		Serial.print(fileNameChar);
		Serial.print(" opened!");
		Serial.println(" --\n");
    }
}

void emptySerialBuf(int serialNum){

	//Empty Serial buffer
	

	if(serialNum==0){
	 	while(Serial.available())                      
			Serial.read();
	}
	else if(serialNum==1){
		while(Serial1.available())                      
    	Serial1.read();
    }
}

void waitSerial(int serialNum){

	// Wait for data on Serial
	//Argument serialNum for Serial number

 	boolean serialAv = false;

 	if(serialNum==0){
 		while(!serialAv){ 
			if(Serial.available())
     		serialAv=true;
 		}
	}
	else if(serialNum==1){
		while(!serialAv){ 
			if(Serial1.available())
			serialAv=true;
		}
	}
}

String getSerial(int serialNum){

	//Return String  from serial line reading
	//Argument serialNum for Serial number

	String inLine = "";
	waitSerial(serialNum);

	if(serialNum==0){
		while(Serial.available()){              
			inLine += (char)Serial.read();
			delay(2);
		}
		return inLine;
	}
	else if(serialNum==1){
		while(Serial1.available()){               
    		inLine += (char)Serial1.read();
    		delay(2);
 		}
		return inLine;
	}
}

void sendGcode(){

	//READING GCODE FILE AND SEND ON SERIAL PORT TO GRBL

	//START GCODE SENDING PROTOCOL ON SERIAL 1

	String line = "";

   Serial1.print("\r\n\r\n");			//Wake up grbl
    delay(2);
    emptySerialBuf(1);
    if(myFile){                                                                      
	    while(myFile.available()){		//until the file's end
	    	line = readLine(myFile);	//read line in gcode file 
	      	Serial.print(line);		//send to serials
	      	Serial1.print(line);
	      	Serial.print(getSerial(1));	//print grbl return on serial
		}
	}
	else
		fileError();

	myFile.close();
	Serial.println("Finish!!\n");
	delay(2000);
}

void fileError(){

	// For file open or read error

	Serial.println("\n");
	Serial.println("File Error !");
}

String readLine(File f){
	
	//return line from file reading
  
	char inChar;
	String line = "";

	do{
		inChar =(char)f.read();
    	line += inChar;
    }while(inChar != '\n');

	return line;
}

Exactly which Nano board do you have ?

(who is 'he'?)

In post #1.

I'm confused. :thinking: is there a MEGA?

I am running the code I have thrown at the moment with MEGA 2560. After running this code on Mega I can convert it to nano. But the code still stays in the loop I threw in Mega.

Is everything okay? :slight_smile:

I have no idea what that means

When I run the code with Mega, it approves to SDCard and the continuation of the code continues as in the picture below.

Hi,
Just thought you might like to have a look at the GRBL for ESP32 as it looks very impressive. I built myself a cnc router a while back using GRBL on an Uno but would have used this instead if it had existed back then

I'm still confused

Why did you start a new topic for the same problem ?

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to [url=https://forum.arduino.cc/index.php?topic=710766.0]Learn How To Use The Forum[/url].

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Hi,
I'm looking for a solution to my problem and I opened a similar topic to reach more people. I would be very happy if someone could help me.

My problem is simple. I'm using a code I found. But although the code recognizes the SDCard, it does not select the file inside. The name of the file is "test2.txt". Where and how should I change in the code so that it chooses the file I want? Below is the output of the serial terminal when I start the code.

#include <SD.h>

File myFile;
boolean restart = true;		

void setup(){

	Serial.begin(115200);
	Serial1.begin(115200);
}


void loop(){

	checkSD();
	while(restart){
		openFileSD();
		sendGcode();
	}
}



void checkSD(){

	// Check if SD card is OK

	// 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.

	while(!SD.begin(10)){
		Serial.println("Please insert SD card...\n");
		delay(1000);
	}

	Serial.println("SD card OK...\n");
	delay(1000);
}

void openFileSD(){

	String fileName = "" ;
	char fileNameChar[100]={0};				// char array for SD functions arguments

	Serial.println("Enter name for a gcode file on SD : \n");
	emptySerialBuf(0);
	fileName=getSerial(0);

	for(int i=0;fileName.charAt(i)!='\n';i++)		//convert String in char array removing '\n'
		fileNameChar[i]=fileName.charAt(i);

	if(!SD.exists(fileNameChar)){				//check if file already exists
		Serial.print("-- ");
		Serial.print(fileNameChar);
		Serial.print(" doesn't exists");
		Serial.println(" --");
		Serial.println("Please select another file\n");
      	delay(200);
      	openFileSD();
    } 
    else{
     	myFile = SD.open(fileNameChar, FILE_READ);		//create a new file
     	Serial.print("-- ");
     	Serial.print("File : ");
		Serial.print(fileNameChar);
		Serial.print(" opened!");
		Serial.println(" --\n");
    }
}

void emptySerialBuf(int serialNum){

	//Empty Serial buffer
	

	if(serialNum==0){
	 	while(Serial.available())                      
			Serial.read();
	}
	else if(serialNum==1){
		while(Serial1.available())                      
    	Serial1.read();
    }
}

void waitSerial(int serialNum){

	// Wait for data on Serial
	//Argument serialNum for Serial number

 	boolean serialAv = false;

 	if(serialNum==0){
 		while(!serialAv){ 
			if(Serial.available())
     		serialAv=true;
 		}
	}
	else if(serialNum==1){
		while(!serialAv){ 
			if(Serial1.available())
			serialAv=true;
		}
	}
}

String getSerial(int serialNum){

	//Return String  from serial line reading
	//Argument serialNum for Serial number

	String inLine = "";
	waitSerial(serialNum);

	if(serialNum==0){
		while(Serial.available()){              
			inLine += (char)Serial.read();
			delay(2);
		}
		return inLine;
	}
	else if(serialNum==1){
		while(Serial1.available()){               
    		inLine += (char)Serial1.read();
    		delay(2);
 		}
		return inLine;
	}
}

void sendGcode(){

	//READING GCODE FILE AND SEND ON SERIAL PORT TO GRBL

	//START GCODE SENDING PROTOCOL ON SERIAL 1

	String line = "";

   Serial1.print("\r\n\r\n");			//Wake up grbl
    delay(2);
    emptySerialBuf(1);
    if(myFile){                                                                      
	    while(myFile.available()){		//until the file's end
	    	line = readLine(myFile);	//read line in gcode file 
	      	Serial.print(line);		//send to serials
	      	Serial1.print(line);
	      	Serial.print(getSerial(1));	//print grbl return on serial
		}
	}
	else
		fileError();

	myFile.close();
	Serial.println("Finish!!\n");
	delay(2000);
}

void fileError(){

	// For file open or read error

	Serial.println("\n");
	Serial.println("File Error !");
}

String readLine(File f){
	
	//return line from file reading
  
	char inChar;
	String line = "";

	do{
		inChar =(char)f.read();
    	line += inChar;
    }while(inChar != '\n');

	return line;
}

As an experiment, try hardcoding the filename rather than prompting the user to enter it. If that works then you know that the problem is in the filename input code which seems much too convoluted to me