REXYGEN Community Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Login

    ASCII Commands Over RS485

    Communication (RS232, RS485, I2C, SPI, UDP, TCP, ...)
    2
    19
    1.7k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      GeorgeDumitru @Jan Reitinger
      last edited by

      @jan-reitinger Hi Jan, here is the code of the entire block:

      
      
      #define COM_BAUDRATE 9600 //baudrate, e.g. 9600, 19200, 57600, 115200
      #define COM_PARITY_NONE 0 //no parity
      #define COM_PARITY_ODD  1  //odd parity
      #define COM_PARITY_EVEN 2  //even parity
      
      #define BUFFER_SIZE 20 // MAXIMUM NUMBER OF BYTES TO SEND
      #define COMMAND_LENGTH_MAX 20 //maximum length of command
      
      //Assigning parameters to variables, these variables are read-only;
      string parameter(0) serialdevice;//serial device is defined by parameter p0 of the REXLANG Block (e.g. /dev/ttyS0 in Linux or COM1 in Windows)
      
      //Assigning inputs to variables
      bool input(0) IsGreenButtonSignalOn;
      bool input(1) IsRedButtonSignalOn;
      bool input(2) IsYellowButtonSignalOn;
      bool input(3) IsProcedureStandardSignal;
      
      //Assigning Variables to Outputs, these variables are WRITE-Only
      bool output(0) IsDeviceReady;
      bool output(1) IsDeviceInError;
      bool output(2) IsDeviceRunning;
      string output(3) ResponseFromDMX;
      long output(14) DebugMessage;
      long output(15) ConnectionStatus;
      
      //Variables Declaration
      const long cr = 13; 	  // (cr) is the termination character, carrige return (0Dh);
      long hCom, s, receive;	  // Communication Handle
      long buffer[BUFFER_SIZE]; // buffer for incoming data
      long dataCount; 		  // Number of bytes sent
      bool read = true;
      string data[BUFFER_SIZE+1];
      int status=0;
      long a;
      
      void HomeMotor(void){
      	long readData[6];
      	readData[0]='L';
      	readData[1]='H';
      	readData[2]='O';
      	readData[3]='M';
      	readData[4]='E';
      	readData[5]='-';
      	s=Send(hCom,readData,6);
      	return;
      }
      
      
      void ClearError(void){
      	a=Write(hCom,"@DMK01EO=1[CR]");
      	if(a>0){
      		DebugMessage=a;
      	}
      	else{
      		DebugMessage=-1;
      	}
      }
      void MoveTo1000(void){
      	a=Write(hCom,"@01J+");
      	if(a>0){
      		DebugMessage=a;
      		status=0;
      	}
      	else{
      		DebugMessage=-1;
      	}
      }
      
      //the init procedure is executed once when the REXLANG function block initializes
      long init(void)
      {
      	/* PUT YOUR CODE HERE */
      	hCom=-1;
      	
      
      	
      	return 0;
      }
      
      //the main procedure is executed repeatedly (once in each sampling period)
      long main(void)
      {
      	/* PUT YOUR CODE HERE */
      	if(hCom<0)
      	{
      		hCom = OpenCom(serialdevice,COM_BAUDRATE,COM_PARITY_NONE); //Opening Serial Device
      		ConnectionStatus=hCom;
      	}	
      	switch(status)
      	{
      		case 0:
      			a=Write(hCom,"@00EO[CR]");
      			if(a>0){
      				status=1;
      			}
      			break;
      		case 1:
      			dataCount = Read(hCom, data,BUFFER_SIZE);
      			if(dataCount>0){
      				if(data=="1"){
      					ResponseFromDMX="ON";
      				}
      				else{
      					ResponseFromDMX="OFF";
      				}
      				status = 0;
      			}
      		default:
      			break;
      
      	}
      
      	return 0;
      }
      
      //the exit procedure is executed once when the task is correctly terminated
      // (system shutdown, downloading new control algorithm, etc.)
      long exit(void)
      {
      	/* PUT YOUR CODE HERE */
      	if(hCom>=0){
      		Close(hCom);
      	}
      	return 0;
      }
      
      
      
      
      
      
      
      
      J 1 Reply Last reply Reply Quote 0
      • J
        Jan Reitinger @GeorgeDumitru
        last edited by Jan Reitinger

        @georgedumitru, I believe there's a mistake in the Write command. Instead of using the [CR], it should be the ASCII symbol "\r". My apologies for not thoroughly reading the controller manual. Furthermore, I'm considering putting the switch into an else statement:

        long main(void)
        {
        	/* PUT YOUR CODE HERE */
        	if(hCom<0)
        	{
        		hCom = OpenCom(serialdevice,COM_BAUDRATE,COM_PARITY_NONE); //Opening Serial Device
        		ConnectionStatus=hCom;
        	}
        	else
        	{	
        		switch(status)
        		{
        			case 0:
        				a=Write(hCom,"@00EO\r");
        				if(a>0){
        					status=1;
        				}
        				break;
        			case 1:
        				dataCount = Read(hCom, data,BUFFER_SIZE);
        				if(dataCount>0){
        					if(data=="1"){
        						ResponseFromDMX="ON";
        					}
        					else{
        						ResponseFromDMX="OFF";
        					}
        					status = 0;
        				}
        			default:
        				break;
        
        		}
        	}
        
        	return 0;
        }
        
        G 1 Reply Last reply Reply Quote 0
        • G
          GeorgeDumitru @Jan Reitinger
          last edited by

          @jan-reitinger Hi Jan, sorry if I'm being difficult here, but I am just curious, I am receiving a string in the return message. How can i process that to have the string in the output of the block? I managed to get a response from the device, and as long as the response is a single byte, that works just fine, but I am struggling to get a string out of the buffer. Do you have any suggestions?

          J 1 Reply Last reply Reply Quote 0
          • J
            Jan Reitinger @GeorgeDumitru
            last edited by

            @georgedumitru Hi George,
            if you only need a control statement in the log, use Trace(1,data). If you want the string to output directly, this should work:

            ...
            string output(3) outputstring;
            ...
            outputstring = data;
            

            Cheers,
            Jan

            G 1 Reply Last reply Reply Quote 0
            • G
              GeorgeDumitru @Jan Reitinger
              last edited by

              @jan-reitinger said in ASCII Commands Over RS485:

              trol statement in the log, use Trace(1,data). If you want the string to output directly, this should work:

              That's what I thought, but every time I try to do that I get this as an error:

              a3c625d1-eb27-44d0-bad6-45a86a04262f-image.png

              J 1 Reply Last reply Reply Quote 0
              • J
                Jan Reitinger @GeorgeDumitru
                last edited by Jan Reitinger

                @georgedumitru Could you post line 111 here or ideally the whole code again?

                This minimal example works for me:

                #define BUFFER_SIZE 20
                
                string output(1) outputstring;
                
                string data[BUFFER_SIZE+1];
                
                long init(void)
                {
                	data = "hello there";
                	return 0;
                }
                
                long main(void)
                {
                	Trace(1,data);
                	outputstring = data;
                	return 0;
                }
                
                long exit(void)
                {
                	return 0;
                }
                
                
                1 Reply Last reply Reply Quote 0
                • G
                  GeorgeDumitru
                  last edited by

                  Can you please help me with a conversion? I need to interrogate the position of the stepper motor, they have an ascii command I can send to do that, but the response is a 28-bit number. Can you tell me what I can use to get that number from the buffer?

                  J 1 Reply Last reply Reply Quote 0
                  • J
                    Jan Reitinger @GeorgeDumitru
                    last edited by

                    @georgedumitru Hi,
                    When we refer to a 28-bit number, does this imply that the number is transmitted within 4 bytes? If that's the case, and the number is in floating-point format, you should use double buf2double(buf[,endian]) REXLANG function.

                    G 1 Reply Last reply Reply Quote 0
                    • G
                      GeorgeDumitru @Jan Reitinger
                      last edited by

                      @jan-reitinger said in ASCII Commands Over RS485:

                      buf2double

                      Hi, the number is not in floating-point format, is actually an int. But what I don't understand is how to use your function What exactly does it take in the argument. I never seen a function taking anything like yours and if I call just double myDouble = buf2double(myBuffer) I expect 100.000 and I get -7.403 669 410 330E-171 . So, how exacttly do i solve this?

                      J 1 Reply Last reply Reply Quote 0
                      • J
                        Jan Reitinger @GeorgeDumitru
                        last edited by

                        @georgedumitru
                        Hello George,

                        It's challenging to give advice remotely when I can't see what's happening. The data might be in a different format than expected. Could you use Trace() to print the contents of the buffer and share it here?

                        G 1 Reply Last reply Reply Quote 0
                        • G
                          GeorgeDumitru @Jan Reitinger
                          last edited by

                          @jan-reitinger can you direct me to some documentation that shows how to actually use Trace() as I could definitely use that for myself too.

                          J 1 Reply Last reply Reply Quote 0
                          • J
                            Jan Reitinger @GeorgeDumitru
                            last edited by Jan Reitinger

                            @georgedumitru I think the best documentation is this thread here on the forum. Byte array reading from communication is also discussed there.

                            Another helpful tool is definitely the example located at C:\Program Files\REX Controls\REXYGEN 2.50.12.14711\Examples\0203_Function_Blocks_REXLANG.

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post

                            This is a community forum for REXYGEN users and fans. Detailed information can be found at REXYGEN homepage.

                            There is also an outdated REXYGEN community forum.

                            Powered by NodeBB.