[Solved] Trouble Utilizing Null Character

I am using Automation Direct's P1AM Arduino PLC to try and send commands to a TCP/IP stepper motor driver. Using Wireshark I was able to see the data that needed to be in the packet to control the motor.
image

I wrote the following program to try and send this same packet to the stepper driver but from the Arduino instead of my computer:

#include <SPI.h>
#include <Ethernet.h>

String Control, Command;

byte mac[] = { //Mac address on side of P1AM Eth module
  0x60, 0x52, 0xD0, 0x07, 0x41, 0x95
};

IPAddress ip(192, 168, 1, 2);//IP Address of the P1AM-ETH module.
IPAddress stepperDriver(192, 168, 1, 1); //IP Address for stepper motor driver

EthernetClient client;

char Null = 0;  //Ascii value of null character
char Bell = 7;  //Ascii value of bell character

char Ret = 13; //Ascii value of carriage return
char Lf = 10;  //Ascii value of line feed

void setup() {
  Control = String("FL10000");  //step motor 10000 steps
  Command = String(Null + Bell + Control + Ret + Lf); //append header and footer to command string

  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  delay(2000); //sanity delay

  Serial.println("Connecting...");

  if (client.connect(stepperDriver, 49153)) { //Connect to device
    Serial.println("Connected");
  } else {
    Serial.println("Connection Failed");  
  }
}

void loop() {
  delay(3000);
  client.print(Command);  //send packet
  Serial.print(Command);  //print packet in serial monitor
}

Running this and using Wireshark again gives me this:
PacketBad

However if I change the line:

Command = String(Null + Bell + Control + Ret + Lf);

To:

Command = String(Bell + Control + Ret + Lf);

I get closer to my expected result but still do not have the null character at the start:
PacketBetter

Any help would be greatly appreciated,

Thank you!

Welcome to the forum

Command = String(Null + Bell + Control + Ret + Lf);

You possible meant

Command = String(Null) + String(Bell) + String(Control) + String(Ret) + String(Lf);

Thank you for the help. I tried that and got the same result as when I simply removed Null from the Command string.
image

maybe try..

#include <SPI.h>
#include <Ethernet.h>

String Control, Command;

byte mac[] = { //Mac address on side of P1AM Eth module
  0x60, 0x52, 0xD0, 0x07, 0x41, 0x95
};


byte command[] = {0x00, 0x07, 0x46, 0x4c, 0x31, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a};

IPAddress ip(192, 168, 1, 2);//IP Address of the P1AM-ETH module.
IPAddress stepperDriver(192, 168, 1, 1); //IP Address for stepper motor driver

EthernetClient client;

char Null = 0;  //Ascii value of null character
char Bell = 7;  //Ascii value of bell character

char Ret = 13; //Ascii value of carriage return
char Lf = 10;  //Ascii value of line feed

void setup() {
  Control = String("FL10000");  //step motor 10000 steps
  Command = String(Null + Bell + Control + Ret + Lf); //append header and footer to command string

  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  delay(2000); //sanity delay

  Serial.println("Connecting...");

  if (client.connect(stepperDriver, 49153)) { //Connect to device
    Serial.println("Connected");
  } else {
    Serial.println("Connection Failed");
  }
}

void loop() {
  delay(3000);
  client.print(Command);  //send packet
  client.write(command, sizeof(command));
  Serial.print(Command);  //print packet in serial monitor
}

good luck.. ~q

Do you understand the difference between your code and mine ?

What do you see when you print the Command variable after building it ?

As an experiment why not just set the String to the required value ?

if the motor is expecting a command line terminated with a return and linefeed, why not just create such a string and send it

output

FL1234
 46 4C 31 32 33 34 D A 0

char buf [90];
char s   [90];

// -----------------------------------------------------------------------------
void
loop (void)
{
    if (Serial.available ()) {
        int n = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
        buf [n] = '\0';

        int val;
        sscanf (buf, "%d", &val);

        sprintf (s, "FL%d\r\n", val);
        Serial.print (s);
        for (unsigned n = 0; n < 1+strlen (s); n++)  {
            Serial.print (" ");
            Serial.print (s [n], HEX);
        }
        Serial.println ();
    }
}

void
setup (void)
{
    Serial.begin (9600);
}

I see a problem…
You can’t ‘print’ a null within a string…
You need to ‘write’ it.

Serial.print('\0');

(N'est-ce pas?)

maybe: char command[] = "\000\007FL100000\r\n";
(be careful - the \0nn syntax expects an octal number. Doesn't matter for null and bell, but...)

it seems strange to me that an ASCII command expecting a \r and \n termination would require a NUL prefix.

Hi all,

Thank you all very much for the help, I ended up solving the issue by using memcpy and .c_str() to copy the contents of the header, command, and footer into a byte array and sending that to the server using the client.write function rather than client.print.

For those interested here is my code:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0x60, 0x52, 0xD0, 0x07, 0x41, 0x95 };
int port = 49153;

int time = 5000;

IPAddress ip(192, 168, 1, 2);//IP Address of the P1AM-ETH module.
IPAddress stepperDriver(192, 168, 1, 1); //IP Address for stepper motor driver

EthernetClient client;

byte header[2] = {0x00, 0x07};
byte footer[2] = {0x0d, 0x0a};

String Control = "FL10000";

void setup() {
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  delay(2000); //sanity delay

  Serial.println("Connecting...");

  if (client.connect(stepperDriver, port)) { //Connect to device
    Serial.println("Connected");
  } else {
    Serial.println("Connection Failed");
  }
}

void loop() {
  if(client.connected()){
    int commandSize = sizeof(header) + sizeof(footer) + Control.length();
    byte Command[commandSize];
    
    memcpy(Command, header, sizeof(header));
    memcpy(Command + sizeof(header), Control.c_str(), Control.length());
    memcpy(Command + sizeof(header) + Control.length(), footer, sizeof(footer));


    client.write(Command, commandSize); //send command
    
  }
  else{
    Serial.println("Connection lost, attempting to reconnect.");
    client.connect(stepperDriver, port);  //attempt to reconnect
  }
  delay(time);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.