Arduino RS232 Serial Communication to Laser Control Board

Yes, I can get the Arduino Mega. I am now testing with SerialSoftware, following @wildbill and @lastchancename advice, I think I am getting a hang of things now, at least a little bit :sweat_smile:

You could also look at my Arduino Software Solutions which has a variety of alternative sketches for reading / parsing from Serial with the pros/cons of each.

1 Like

looks like the command language is pretty simple and straightforward, so should not be a massive issue to get or send commands as long as you Serial line is robust.

1 Like

When you get this working I would like to see video of it in action.

1 Like

just reading this again, the reason it was not working is that commands need to be be terminated by '\r' so

Serial.print("Command");
Serial.write('\r'); // end of command

is basically what it takes (if the laser is connected to the Serial port)

1 Like

I was just learning about that in Serial input basics (Serial Input Basics - updated - #3 by Robin2).
in the basics they use '\n' or '>' as end markers ('<' as a starter marker, or LF). I was reading through google and ASCII uses the number 13 as Carriage return.

with the terminal emulation software I was only able to send and read commands once I selected a check box with "+CR". I assume the terminal emulation program could now read and send the carriage return characters automaticaly, with me just needing to type "INSTRUCTION".

My question now is, what is the CR character I should use, are they all the same?
It will probably work if I just type 13 as the end marker character right? Since it is the ASCII value for carriage return.
Will '\n' or '\r' work the same?

No, the laser controller is expecting '\r'.

1 Like

So is '\n' for new line?

\r is carriage return ascii 13. \n is linefeed, ascii 10.

1 Like

thank you very much!
I just had an enlightenment moment :sweat_smile: everything just seems to be making so much sense now regarding the laser communication and what the laser control board expects to recieve ahahaha

CR is the ASCII code for Carriage Return, it's a byte with value 13(dec) or 0x0D(hex)

so if your terminal emulator was able to send the character for you, that's why it was working

in C++ some well known ASCII characters have an escape sequence and '\r' is the one for Carriage return, so doing Serial.write('\r'); is the same as doing Serial.write(13);

In Robin's tutorial you would define the end marker as '\r' to get a line

1 Like

So I have made a new code.

The laser always sends a set of initial chars that should be ignored, regardless of that I still want to read that initial communication to make sure everything is working properly.

in main.cpp setup I have this:

void setup()
{
  Serial_1.begin(baudRate_1);
  Serial_2.begin(baudRate_2);

  //setup here
  sys.initPyrometer(); //initialize Pyrometer
  sys.initLaser();     //initialize Laser
  ~
  //PID Setup
  Setpoint = 750;           //Target value (Temperature)
  myPID.SetMode(AUTOMATIC); //Turn PID ON
  myPID.SetTunings(Kp, Ki, Kd);
  myPID.SetSampleTime(10);        //Sample time = 10 [ms]
  myPID.SetOutputLimits(10, 100); //Output limits = Diode Current (10-100% of Max Laser Power)

  //Serial Communication Setup
  sys.laser_COM(); //Establish init communications to laser. check system.cpp
}

sys.laser_COM() function:

SoftwareSerial Serial_1(0, 1); //RX and TX ports
const byte numChars = 32;      //number of readable characters
char receivedChars[numChars];  //chars to print

boolean newData = false;

void System::laser_COM()
{
    //laser initial communications (to run once)
    //Check Laser YLR-200-AC User Manual for laser instructions descriprion
    Serial_1.begin(baudRate_1); //Set the data rate for the software serial port
    while (!Serial_1)
    {
        ; //wait for the serial port to connect. needed for native usb port only
    }
    recieving_data();
    show_data();
    Serial_1.println('\n');

    //Send Laser instructions now:
    Serial_1.println("DMOD"); // Disable Modulation
    Serial_1.write('\r');
    recieving_data();
    show_data();
    Serial_1.println('\n');

    Serial_1.println("DEC"); // Disable External Control
    Serial_1.write('\r');
    recieving_data();
    show_data();
    Serial_1.println('\n');

    Serial_1.println("ELE"); // Enable Hardware Emission Control
    Serial_1.write('\r');
    recieving_data();
    show_data();
    Serial_1.println('\n');
}

Serial communication functions taken from example 3 in: Serial Input Basics - updated - #2 by Robin2


void System::recieving_data() //Recieve data from laser control board
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char rc;

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

        if (recvInProgress == true)
        {
            if (rc != '\r')
            {
                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 == '\n')
        {
            recvInProgress = true;
        }
    }
}

void System::show_data() //print recieved data from laser control board
{
    if (newData == true)
    {
        Serial_1.print("LASER COMMUNICATING: ");
        Serial_1.println(receivedChars);
        newData = false;
    }
}

Then everytime I send an instruction to the laser, if the laser control board understands the instruction it replies back that instruction, otherwise it gives back ERROR.
This is the code to send and recieve those instructions.
in main.cpp loop I have this:

void loop()
{
sys.tempReading(); //temperature reading
  Input = sys.tempReading();
  //PID calculation
  myPID.Compute();
  sys.laser_output(Output); //laser output intructions (Serial communication, RS232)
}

laser_output() function:

void System::laser_output(float input)
{

    //     //Check Laser YLR-200-AC User Manual for laser instructions descriprion

    Serial_1.print("SDC ");  // Set Diode Current.

    Serial_1.println(input); //PID_value = Diode Current (10-100% of Max Laser Power)

    Serial_1.write('\r');

    recieving_data();

    show_data();

    Serial_1.println('\n');

    Serial_1.println("EMON"); // Emission ON

    Serial_1.write('\r');

    recieving_data();

    show_data();

    Serial_1.println('\n');

}

I have baudRate_1 set for 57600
and baudRate_2 set for 9600
I will probably change the baudRate_1 to 38400 as advised.
I am now using an arduino mega.
I am also using SoftwareSerial to have the temperature readings in monitor 2 and laser control instructions in monitor 1.

Do you think this can work?
Sorry for the amount of code I am posting, I can only test this code tomorrow morning but would like some feedback.

if you are on a MEGA use the other Hardware Serial ports !

yes, I am using ports 16 and 17 for temp readings and, at the moment, ports 0 and 1 for laser communication, but I will change that for ports 18 and 19.

OK - but don't declare SoftwareSerial on those pins, use Serial, Serial1, Serial2 and Serial3

1 Like

Thanks!!! Now I know what you mean
I was not understanding what the issue was

So I have been testing the new code just now, and I cannot receive or send any data through the arduino mega. I do not know what the issue could be.
There is no communication whatsoever. Program starts running but nothing happens

What can I do?

Arduino has very little in the way of debugging tools. Serial.print is about as good as it gets. You can add some to your code and see what it's doing.

Personally though, I'd write another sketch that just tests communication with the laser and echoes the results to the serial monitor. When that's working you'll have a better idea what's wrong with your bigger program, or at least have some clues about whereto start looking.

1 Like

OK, thanks, will do that!

Post that code