help with software serial

Good afternoon everyone!

Let me preface by saying I have never used SoftwareSerial before. I looked at a bunch of examples and have tried to adapt the example provided by arduino. I am attempting to communicate with a fiber optic micrometer whose API lists the following:

General command information:
The DMS command line interface uses command strings with “label value” pairs to send and receive configuration and target data. All commands sent to the sensor are prefixed with a forward slash character ‘/’ (ASCII 47) and terminated with a line feed (ASCII 10) or carriage return (ASCII 13). Responses from the sensor are terminated with a line feed. Commands and labels are case sensitive.
Default terminal RS-232 configuration:
Format :8bits, no parity, 1 stop bit
Flow Control :none
Default speed :19.2Kbps
USB Virtual Com port configuration:
Format :8bits, no parity, 1 stop bit
Flow Control :none
Default speed muDMS 250Kbps
microDMS 1Mbps
Note: FTDI USB driver is included in Windows 10. Installer can be downloaded from www.ftdichip.com if needed.
Quick Start using terminal program:

  1. Attach power (+12VDC nominal, 7-24V) and RS-232/USB cable.
  2. Use a terminal program to connect to the com port (see configuration above)
    Note: Any application that can communicate with the com ports should work.
  3. Apply power to sensor. Sensor will send a boot message.
  4. Send “/idn?” + LF (ASCII 10). Sensor will respond with model and serial information.

I purchased : RS232 Serial Port to TTL

and have wired VCC to 3.3 first to try it and then later to 5V (didnt seem to make a difference)
Wired the ground to Ground and rx/tx to pins 10 and 11 (have swapped them to make sure)

here is the latest iteration of the code :

#include <SoftwareSerial.h>
byte idn="/idn?";
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
// Open serial communications and wait for port to open:
Serial.begin(57600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

Serial.println(“Goodnight moon!”);

// set the data rate for the SoftwareSerial port
mySerial.begin(19200);
mySerial.println();

}

void loop() { // run over and over

while (mySerial.available() > 0) {
mySerial.write(idn);

String inByte = mySerial.readStringUntil(’/n’);
//Serial.write();
Serial.println(inByte);
delay(500);
}

any advice would be greatly appreciated

you wait with sending until something is received. but nothing will be received until you send

Typically with hardware like this, as Juraj said, its master/slave. Your the master. Nothing happens unless you initiate it. Your send a command, it sends the reply, end of story. You can set up a time limit for the reply so that you won’t lock if the hardware misses a command and you don’t get a reply for some reason.

Your loop() should monitor your user, she’s your boss. Depending on what your user does, you send commands and give back the hardware’s replies in some form.

-jim lee

jimLee:
Typically with hardware like this, as Juraj said, its master/slave. Your the master. Nothing happens unless you initiate it. Your send a command, it sends the reply, end of story. You can set up a time limit for the reply so that you won't lock if the hardware misses a command and you don't get a reply for some reason.

Your loop() should monitor your user, she's your boss. Depending on what your user does, you send commands and give back the hardware's replies in some form.

-jim lee

Your responses lead me to believe I'm missing something obvious. When I send the command

mySerial.write(idn);

am I sending it incorrectly? I would have thought that first I send the query and then wait for the response from the sensor?

  1. Send “/idn?” + LF (ASCII 10). Sensor will respond with model and serial information.
byte idn="/idn?";

This query message should be

char idn[] = "/idn?";

Then following up on what others have said

#include <SoftwareSerial.h>
char idn[] = "/idn?";
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Goodnight moon!");
  // set the data rate for the SoftwareSerial port
  mySerial.begin(19200);
  mySerial.println();
}

void loop() { // run over and over
  //while (mySerial.available() > 0) {
  mySerial.println(idn);
  delay(500);

  if(mySerial.available() >0)
 {
  String inByte = mySerial.readStringUntil('\n');
  //Serial.write();
  Serial.println(inByte);
  delay(500);
 }
}

It’s possible that idn may want to be written

char idn[] = "/idn?\n";

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

Have a look at the examples in Serial Input Basics - simple reliable, non-blocking ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R

I tried both char array initializations and still nothing. I think the issue may be that the line

if(mySerial.available() >0)

is never true. I threw in a random println in that block to see if it would execute and saw nothing.

I tried both char array initializations and still nothing. I think the issue may be that the line
Quote
if(mySerial.available() >0)
is never true. I threw in a random println in that block to see if it would execute and saw nothing.

So nothing is coming back from the device to the arduino. Can you see any traffic in or out with blinking lights on the adaptor module?

Please provide a hand drawn sketch of your wiring.

SoftwareSerial mySerial(10, 11); // RX, TX

The module TX needs to go to the Arduno RX (pin10) and module RX to Arduino Tx(11).

Can you provide a link to the specification for the fiber optic micrometer?

The R3 LED blinks continuously. I have the Tx on the TTL board wired to pin 10 (RX) on the Arduino. I have also swapped these just to be sure. VCC on TTL is wired to the 3.3V on arduino and GND is wired to GND. I have also Supplied the TTL with 5V it made no difference.

Its a philtec dms-d47 - Their website is trash. In my first post I gave all the pertinent data

The R3 LED blinks continuously.

Is this on the RS232/TTL adaptor? In the Amazon photo and information it talks about TX RX and power leds. Can you see action on them?

Did you receive the RS232 to USB adaptor with the sensor? Can you run the sensor on a computer with the software available from Philtec?

You are correct that the documentation is frustrating. Is there any customer service available from Philtec?

cattledog:
Is this on the RS232/TTL adaptor? In the Amazon photo and information it talks about TX RX and power leds. Can you see action on them?

yes this is on the adapter, given the other LED is labeled T1 I would infer this is the RX power light.

No I had to purchase the adapter separately. The sensor works fine with over serial when connected directly to a computer and using their software interface. Customer service (applications engineer) is the one who provided me with the API I quoted in my first post. Its a pdf that was emailed directly to me. I don't know how to upload it here, but if you provide me with an email i can forward it to you. I've also ordered a different ttl, just in case as the max 3232 on this adapter is getting crazy hot...

Slightly different, sticks and stone approach. Any luck?

#include <SoftwareSerial.h>

#define INTER_MSG_TIME  500ul       //mS between queries
#define RX_BUFF_SIZE    50

const char idn[] = "/idn?";

char
    rxBuff[RX_BUFF_SIZE];
    
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() 
{
    // Open serial communications and wait for port to open:
    Serial.begin(57600);
    while (!Serial);
    Serial.println( "Goodnight moon!" );
    
    // set the data rate for the SoftwareSerial port
    mySerial.begin(19200);
    
}//setup

//state names
#define SEND_REQUEST    0
#define GET_REPLY       1
#define INTER_MSG_DELAY 2
//
void loop() 
{
    static unsigned long
        tDMS;
    char
        ch,
        idx;
    static byte
        stateDMS = SEND_REQUEST;

    switch( stateDMS )
    {
        case    SEND_REQUEST:
            idx = 0;
            while( idn[idx] != 0 )                
                mySerial.write( idn[idx++] );
            mySerial.write( '\n' );
            idx = 0;
            stateDMS = GET_REPLY;
            
        break;

        case    GET_REPLY:
            if( mySerial.available() )
            {
                do
                {
                    ch = mySerial.read();
                    if( ch == '\n' )
                    {
                        rxBuff[idx] = 0;
                        Serial.print( "Received: " );
                        Serial.println( rxBuff );
                        //
                        idx = 0;
                        tDMS = millis();
                        stateDMS = INTER_MSG_DELAY;
                        
                    }//if
                    else
                    {
                        rxBuff[idx++] = ch;
                        if( idx >= RX_BUFF_SIZE )
                            idx--;
                            
                    }//else
                    
                }while( mySerial.available() );
                
            }//if
            
        break;

        case    INTER_MSG_DELAY:
            if( millis() - tDMS >= INTER_MSG_TIME )
                stateDMS = SEND_REQUEST;
                
        break;
        
    }//switch

}//loop

The R3 LED blinks continuously.

I would infer this is the RX

If you increase the delay after the message sending, like this, can you see the light blinking every 5 seconds. If so, you know the outgoing message is received by the module, and I would think the issues are on the device side if nothing is coming back.

mySerial.println(idn);
  delay(5000);

Its a pdf that was emailed directly to me. I don’t know how to upload it here,

Use the attachments and other options pulldown at the bottom of the posting window to attach the file.

Which type arduino are you running? The voltage to the RS-232 adapter should be the same voltage that is powering the arduino itself, typically this will be 5 volts for an Uno, Mega, Nano, etc.

The MAX232 chip should not be getting hot, that is probably a sign that you have damaged the chip. Possibly caused by having the arduino and MAX232 running at different voltages, but could be other things such as a defective chip, incorrectly wiring it at some point, etc.

Have you tried a loopback test? Disconnect the RS-232 cable from the adapter, and connect pins 2 and 3 of the DB9 connector with a jumper wire, then anything you send from the arduino will be sent back to the receive line on the arduino, so you can verify that the connections are connect and the adapter itself is functional. (EDIT - if I recall correctly, software serial is not capable of doing a loopback test, think I tried it in the past and found that software serial has problems sending and receiving simultaneously)

I suspect your main problem is a mis-configured RS-232 cable to the micrometer. The DB9 connector on your adapter typically only has three pins connected, Pins 2, 3, and 5. Pins 2 and 3 will be the RS-232 level serial data lines, one will be RX and the other TX, but without seeing the exact adapter you have I can't say for sure which pin is which. Pin 5 will be ground. The typical problem with RS-232 is that there is not a rigid standard for which pin is RX and which is TX, so there are cables that wire pin 2 on the computer end to pin 2 on the device end, and pin 3 on the computer end to pin 3 on the device, while there are other cables that swap the wires, having pin 2 on the computer end going to pin 3 on the device, and vice-versa. The MAX232, and most other RS-232 drivers, are typically built to withstand a mis-wired cable for at least a short time, because this is such a common problem.

I believe that AltSoftSerial will support a loop back test. The library is available through the library manager.

I jump at the beginning

if (Serial.available()) { <— waits for incoming data
Serial.write(…) <— sends data

so as I wrote you wait with sending until something is received. but nothing will be received until you send

so as I wrote you wait with sending until something is received. but nothing will be received until you send

In reply #4 and #11 There have been two alternative versions of code given to the OP which addressed the issue you pointed out in the OP’s original code.

If he is still running that code, then we all have been wasting our time.

@JohnHamilton can you please post the latest code you are running.

Can you please, post a picture/link of your this device: fiber optic micrometer?

I’m working remotely so i don’t have direct access to the board or chip until the morning (11:45pm here now) i ran both the recent suggested codes/changes and am still not receiving any data back. And to address the reason why the read call was there is that the sensor is supposed to send a boot message. This line has been commented out for several iterations.

#include <SoftwareSerial.h>
char idn[] = "/idn?";
SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Goodnight moon!");
  // set the data rate for the SoftwareSerial port
  mySerial.begin(19200);
  mySerial.println();
}

void loop() { // run over and over
  //while (mySerial.available() > 0) {
  mySerial.println(idn);
  //mySerial.write('\n');
  delay(5000);

  if(mySerial.available() >0)
 {
  String inByte = mySerial.readStringUntil('/n');
  //Serial.write();
  Serial.println(inByte);
  delay(500);
 }
}

From your Post#1, I understand very clearly that --

You execute the following codes:

SUART.print("/idn?");   //SUART stands for software UART port
SUART.print('\n');                 // + LF (ASCII 10).

In response, the micrometer device should send its 'Model and Serial Number'. Do you know the 'Model and Serial Number' of the device?

We need to know the following information:
1. Does your micrometer have a 9-pin DB connector (Fig-1)? Please, show the picture.
2. Are the signals of 9-pin connector of Step-1 RS232 logic levels? If so, you need the following (typical) converter to operate the micrometer with Arduino UNO.
db9x.png
Figure-1:

3. Communication Baud Rate -- 19.2 kbps or 250 kbps
4. Frame structure: 8N1 (8-bit data, no parity, 1 stop bit)
5. What about Pin-7 and Pin-8 of the connector of Step-1? Do they need to be shorted?
6. What about Pin-1, 6, and 4 of the connector of Step-1? Do they need to be shorted together?

db9x.png