开源改变世界

解析来自 GRBL 的传入消息 #558

推推 grbl 2年前 (2023-01-22) 78次浏览

关闭
MeJasonT 打开了这个问题 2018 年 11 月 13 日 · 7条评论
关闭

解析来自 GRBL 的传入消息#558

MeJasonT 打开了这个问题 2018 年 11 月 13 日 · 7条评论

注释

解析来自 GRBL 的传入消息 #558

我想知道是否有人可以为我编写一个基本的解析例程,让我在另一个 Arduino 上运行,它会嗅探来自 PC/Grbl 通信链路的数据,通过使用第二个 arduino,我可以从 grbl TX pin 接收返回消息 -这不影响 pc/grbl 控件的操作。
我目前能够读取返回字符串并通过 arduino IDE 串行监视器输出它。

我希望能够将数据解析为一个数组(块),这样我就可以操纵为主轴速度返回的值以及肥皂水/冷却剂泵的操作和主轴方向。我正在尝试在 grbl 和我的铣床电机变频驱动器之间建立一个接口。长话短说——来自 VFD 的高频噪声扰乱了 grbl 操作,我想通过 RS485 在嗅探信号的电路板和 VFD 之间传输命令。返回消息的美妙之处在于它告诉我功能何时执行,而不是何时排队,这是我从通信链接的另一端获得的信息。
能够做到这一点也将使那些希望为等离子台或任何其他项目构建火炬高度控制器的人受益,因为报告将是一个优势,因为它不可能从 grbl 提供任何进一步的资源以从第二个串行端口传输最大化内存,尤其是在 UNO 变体上。

除了解析消息字符串之外,我可以看到它的可能性并且能够做所有事情,我们将不胜感激。

解析来自 GRBL 的传入消息 #558
贡献者

@MeJasonT:由于这不是直接的 Grbl 问题,我将关闭此线程,但人们仍然可以响应您的请求。

解析来自 GRBL 的传入消息 #558
作者

谢谢桑尼

解析来自 GRBL 的传入消息 #558
作者

附带一提——我们什么时候才能得到一个指向和点击版本的 GRBL for M0,它仍然是编程兄弟会中的斗篷和匕首。

解析来自 GRBL 的传入消息 #558
作者

对于任何感兴趣的人。
使用 Nick Gammon 的 RS485 草图和库

`//=============================================== =====================
// parseGRBLRS485.ino
// 添加了 RS485 通信的原始 GRBL 解析代码
// GRBL CNC 的解析代码
// 13/11/2018
// 版本 1.0
//============================================ ========================

#include “RS485_protocol.h”
#include <SoftwareSerial.h>

// RS485 通信变量 ///////////////////////////////////

软件序列号 rs485 (2, 3);//接收引脚,发送引脚

常量字节 ENABLE_PIN = 4;
整数通道= 0;
int 设备 ID = 0;
int 函数 = 2;
整数数据 = 0;

常量字节 LED_PIN = 13;

// 解析 GRBL 消息变量 ////////////////////////////////////////

常量字节 numChars =71;
char receivedChars[numChars];
char tempChars[numChars]; // 解析时使用的临时数组

//进给和速度变量
char FSMsgGRBL[12];
int FS_FeedMsg = 0;
int FS_SpeedMsg = 0;

//覆盖变量
bool OvMsg = false; //正在传输的Ov消息
int CmdCoolant = 0;
int CmdSpindleCW = 0;

// 保存消息块的变量

char GRBL_msg1 [numChars] = {0};
char GRBL_msg2 [numChars] = {0};
char GRBL_msg3 [numChars] = {0};
char GRBL_msg4 [numChars] = {0};
char GRBL_msg5 [numChars] = {0};
char GRBL_msg6 [numChars] = {0};

布尔新数据=假;

//================================================ ============================

// 回调例程 RS485 Comms

void fWrite (const byte what)

  {
  rs485.write (what);  
  }
  
int fAvailable ()
  {
  return rs485.available ();  
  }

int fRead ()
  {
  return rs485.read ();  
  }

无效设置(){

Serial.begin(115200);
rs485.begin (28800);
pinMode (ENABLE_PIN, OUTPUT);  // RS485 IC driver output enable
pinMode (LED_PIN, OUTPUT);  // built-in LED - lights on transmission error

} //设置结束

//============

无效循环(){

字节级=(数据);

recvWithStartEndMarkers();
if (newData == true) {
    strcpy(tempChars, receivedChars);
        // this temporary copy is necessary to protect the original data
        //   because strtok() used in parseData() replaces the commas with \0
    parseData();
    outputParsedData();
    newData = false;
    
    
}

} // 循环结束

//============

void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
静态字节 ndx = 0;
字符开始标记 = ‘<‘;
char endMarker = ‘>’;
焦炭;

while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
        if (rc != endMarker) {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars) {
                ndx = numChars - 1;
            }
        }
        else {
            receivedChars[ndx] = '\0'; // terminate the string
            recvInProgress = false;
            ndx = 0;
            newData = true;
        }
    }

    else if (rc == startMarker) {
        recvInProgress = true;
    }
}

}// recvWithStartEndMarkers 结束

//============

void parseData() { // 将数据拆分成多个部分

char * strtokIndx; // this is used by strtok() as an index

//根据“|”解析成块 定界符

    // machine state
        strtokIndx = strtok(tempChars,"|"); // Find first part of string (Machine State Idle, Run, Alarm) 
        strcpy(GRBL_msg1, strtokIndx);      // write characters from string to machine state variable
        
    // machine position   
        strtokIndx = strtok(NULL,"|"); // look for next data block in string  
        strcpy(GRBL_msg2, strtokIndx); // write characters from string to machine position variable 
         
    // BF god knows - alarms ?
        strtokIndx = strtok(NULL,"|"); // look for next data block in string      
        strcpy(GRBL_msg3, strtokIndx); // write characters from string to BF variable  
        
    // feed and spindle speed
        strtokIndx = strtok(NULL,"|"); // look for next data block in string     
        strcpy(GRBL_msg4, strtokIndx); // write characters from string to Feed&Speed variable 
         
    //Ov Overides 1% to 200%
        strtokIndx = strtok(NULL,"|"); // look for next data block in string  
        strcpy(GRBL_msg5, strtokIndx); // write characters from string to Overide variable 
         
    //machine command status
        strtokIndx = strtok(NULL,"|"); // look for next data block in string  
        strcpy(GRBL_msg6, strtokIndx); // write characters from string to machine command status variable 
        
    //anything else

} //解析数据结束

//============

void outputParsedData()
{

      ParseFS (); // Parse feed and speed values from FS Block
      ParseOv_A (); //Reads first character in buffer looking for "O" then knows commands follow "A:" (A:SF Buffer) 


               // comment out on completion - sending serial messages not required, debug only 
               Serial.print("Spindle Speed ");
               Serial.print(FS_SpeedMsg);
               Serial.print(" Spindle ");
               Serial.print(CmdSpindleCW);
               Serial.print("  Coolant ");
               Serial.println(CmdCoolant); 
                 
     DoBusComs ();//Transmit values over RS485 link - Order of presidence goes here as parse has to happen first  

}//end of outputParsedData

//进给和速度 FS Message GRBL /////////////////////////////////////// ///////////////

void ParseFS ()
{

//GRBL_msg4 包含 Feed & Speed 消息字符的数组

char * partOfString; // this is used by strtok_r() as an index

partOfString = strtok (GRBL_msg4,":"); // get the first part - the string
strcpy(FSMsgGRBL, partOfString);     // copy it to inputCsvString

partOfString = strtok (NULL, ","); // this continues where the previous call left off
FS_FeedMsg = atoi(partOfString);     // convert this part to an integer

partOfString = strtok (NULL, ","); // this continues where the previous call left off
FS_SpeedMsg = atoi(partOfString);   // convert this part to a float// actually an int

}//ParseFS结束

// 解析覆盖 Ov 消息 GRBL //////////////////////////////////////// /////////////////

void ParseOv_A ()
{
//GRBL_msg5 包含 Overide 消息字符的数组

  if (GRBL_msg5[0] == 'O')// Ov statement when true check machine command instructions
  
  {
          if (GRBL_msg6[0] == 'A')
           {
            
          Serial.print("Got A ");
          Serial.println(GRBL_msg6);
          
                  
          if (GRBL_msg6[2] == 'S')
                {
                CmdSpindleCW =1;
             
                }
          if(GRBL_msg6[2] == 'C')
                {
                CmdSpindleCW = 0;
                        
                }
                
     
            if (GRBL_msg6[2] == 'F'|(GRBL_msg6[3] == 'F'))
                {
                CmdCoolant = 1;           
                }                                                    
            else
               {
               (CmdCoolant = 0);      
                                      
               }
                                                     
          }//End - seeking "A" in GRBL_msg6
          
          if(strlen(GRBL_msg6) == 0) // makes sure spindle direction and coolant conditions are off woth no signal present
          {
          CmdSpindleCW = 0;  
          CmdCoolant = 0;  
          }                                
  }

} // ParseOv_A 结束

// RS485 通讯命令结构 //////////////////////////////////////////

void DoBusComs ()
{

// assemble message - what to send to Variable Frequency Drive /Spindle Drive
byte msg [] = { 
   deviceID,     // device 1
   function,     // Used to expand future messages fixed at 2 (currently type 2 = master transmit message - future could be type 3 ask for analogue response etc)
   FS_SpeedMsg,  // spindle speed
   CmdSpindleCW, // spindle direction
   CmdCoolant,   // activate suds pump
   data          // Spare data block
};

// send to slave  
digitalWrite (ENABLE_PIN, HIGH);  // enable sending
sendMsg (fWrite, msg, sizeof msg);
//delayMicroseconds (660);
digitalWrite (ENABLE_PIN, LOW);  // disable sending

// 从从设备接收消息 // 不感兴趣 – 只有一种方式通信
// 阻止 grbl 接收,不能使用它
// 导致接收 FS_SpeedMsg 时出现杂散的 128 值

// receive response  
//byte buf2 [20];
//byte received = recvMsg (fAvailable, fRead, buf2, sizeof (buf2) - 1); 


  // only send once per successful change
//if (received)
     //{

// if (buf2 [0] != 0)//0 是 master
// return; // 不是我的设备
//
// //if (buf2 [1] != Cmd)
// //return; // 未知命令
//
// byte msg2 [] = {
// 0, // 设备 0(主设备)
// //RXFunc,
// //RXdata1,
// // RXdata2,
//
// };

          //delay (10);  // give the master a moment to prepare to receive 
          ////Serial.println(buf2[2]);   
          //digitalWrite (LED_PIN, received == 0);  // turn on LED if error
          //
          //        if (buf [1] >= 20){
          //        
          //               InputDevice= buf2 [1];
          //               Inputvalue = buf2 [2];// write coil value to a variable
          //               Serial.print ("A"); Serial.print (InputDevice); Serial.print (","); Serial.print (Inputvalue);Serial.println ("!");
          //        }
          //
          //   // old_level = data;
      
      
     // }  

}// DoBusComs 结束

`

解析来自 GRBL 的传入消息 #558
作者

我不知道为什么它会显示这样的代码,但它就在那里 – 不像我

解析来自 GRBL 的传入消息 #558

我使用了一些现有的工作并将其放入 arduino 库中

它将数据放入一个方便的结构中。您只需要将串行字符串传递给它。

https://github.com/jschoch/grbl_chat

喜欢 (0)