Reading serial from a laser mic

so now apply the formula...looks good to me.

and you have lost me again. how would I apply "the formula". pretend you are speaking to an 8 year old. given the code that I posted, where and what formula would I apply.

The formula...in the pdf...mentioned earlier in reply 8

Someone can fix my mistakes as I’m prone to make a few.
I’ve left in your original arguments, remarked out for comparison.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 3, 1); // RX, TX

//const byte numChars = 32;
//char receivedChars[numChars];   // an array to store the received data
unsigned int digitalValue = 0; // unsigned int store value from laser micrometer 0-65535
float measuredValue; // the calculated measured value
boolean newData = false;

void setup() {
  // Open serial communications 
  Serial.begin(9600);

  Serial.println("Hello, LaserMic!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  
  
}



void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 4;
    char endMarker = '13';
    char rc;
    
    if (mySerial.available() > 0 && newData == false) {
        rc = mySerial.read();

        if (rc != endMarker) {
            //receivedChars[ndx] = rc;
            if (isDigit(rc) && ndx >= 0 && ndx <=4) {
              digitalValue += (rc - '0') * (1^ndx)
              ndx--;
            }
            else {
              digitalValue = 0;
              ndx = 4;
            }
            //ndx++;
            //if (ndx >= numChars) {
            //    ndx = numChars - 1;
            //}
        }
        else if (rc = endMarker && digitalValue > 0) {
            //receivedChars[ndx] = '\0'; // terminate the string
            //ndx = 0;
            measuredValue = digitalValue * 40.824 / 65519 - 0.4204872
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(measuredValue, 4);
        newData = false;
    }
}

This might work also...

float receivedDigitalValuetoMeasuredValue(char *receivedCharArray) {
  unsigned int digitalValue = atoi(receivedCharArray);
  float measuredValue = digitalValue * 40.824 / 65519 - 0.4204872;
  return measuredValue;
}

...but it might not, depending upon whether or not receivedCharArray is a C-style string.

sspence65:

    char endMarker = '13';

I won't comment on the rest of your code, but the above line is certainly wrong (a char variable can, as its name suggests, hold a character; '13' is two characters). Perhaps you want something like this:

    char endMarker = '\r';

or

    char endMarker = 13;

That will give you a carriage return character, which has an ASCII code of 13. (The first is usually the preferred way to go because the intention is clearer.)

TolpuddleSartre:
...but it might not, depending upon whether or not receivedCharArray is a C-style string.

I was intending it to be dropped in to the existing code, which looked like a c-string to me...

the following code prints -0.4012 when the mic display reads -0.0058
and -0.4143 when the mic display reads +0.1954

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 3, 1); // RX, TX

//const byte numChars = 32;
//char receivedChars[numChars];   // an array to store the received data
unsigned int digitalValue = 0; // unsigned int store value from laser micrometer 0-65535
float measuredValue; // the calculated measured value
boolean newData = false;

void setup() {
  // Open serial communications 
  Serial.begin(9600);

  Serial.println("Hello, LaserMic!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  
  
}



void loop() {
    recvWithEndMarker();
    showNewData();
}

void recvWithEndMarker() {
    static byte ndx = 4;
    char endMarker = '13';
    char rc;
    
    if (mySerial.available() > 0 && newData == false) {
        rc = mySerial.read();

        if (rc != endMarker) {
            //receivedChars[ndx] = rc;
            if (isDigit(rc) && ndx >= 0 && ndx <=4) {
              digitalValue += (rc - '0') * (1^ndx);
              ndx--;
            }
            else {
              digitalValue = 0;
              ndx = 4;
            }
            //ndx++;
            //if (ndx >= numChars) {
            //    ndx = numChars - 1;
            //}
        }
        else if (rc = endMarker && digitalValue > 0) {
            //receivedChars[ndx] = '\0'; // terminate the string
            //ndx = 0;
            measuredValue = digitalValue * 40.824 / 65519 - 0.4204872;
            newData = true;
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(measuredValue, 4);
        newData = false;
    }
}

christop:
I won't comment on the rest of your code, but the above line is certainly wrong (a char variable can, as its name suggests, hold a character; '13' is two characters). Perhaps you want something like this:

    char endMarker = '\r';

or

    char endMarker = 13;

That will give you a carriage return character, which has an ASCII code of 13. (The first is usually the preferred way to go because the intention is clearer.)

When I change '13' to 13 or '\r' I get no readings in the serial monitor.

sspence65:
the following code prints -0.4012 when the mic display reads -0.0058
and -0.4143 when the mic display reads +0.1954

After I posted that, I recalled c-string functions that make this easier… I slapped myself for trying to reinvent the wheel…
Does this get you closer to actual?

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 3, 1); // RX, TX

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
//unsigned int digitalValue = 0; // unsigned int store value from laser micrometer 0-65535
float measuredValue; // the calculated measured value
boolean newData = false;

void setup() {
  // Open serial communications
  Serial.begin(9600);

  Serial.println("Hello, LaserMic!");

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


}



void loop() {
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '13';
  char rc;

  if (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else if (rc = endMarker && digitalValue > 0) {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      unsigned long digitalValue = strtoul (receivedChars, NULL, 0);
      measuredValue = digitalValue * 40.824 / 65519 - 0.4204872;
      newData = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(measuredValue, 4);
    newData = false;
  }
}

That change has no output in the serial monitor.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(4, 3, 1); // RX, TX

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
//unsigned int digitalValue = 0; // unsigned int store value from laser micrometer 0-65535
float measuredValue; // the calculated measured value
boolean newData = false;
unsigned long digitalValue;

void setup() {
  // Open serial communications
  Serial.begin(9600);

  Serial.println("Hello, LaserMic!");

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


}



void loop() {
  recvWithEndMarker();
  showNewData();
}

void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '13';
  char rc;

  if (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else if (rc = endMarker && digitalValue > 0) {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      digitalValue = strtoul (receivedChars, NULL, 0);
      measuredValue = digitalValue * 40.824 / 65519 - 0.4204872;
      newData = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(measuredValue, 4);
    newData = false;
  }
}

SoftwareSerial mySerial(4, 3, 1); // RX, TX

What is this? ? ?

ieee488:
SoftwareSerial mySerial(4, 3, 1); // RX, TX

What is this? ? ?

sets up pins 4 and 3 as serial ports connected to the ttl / rs422 converter with the inverse logic option set.

https://www.arduino.cc/en/Reference/SoftwareSerialConstructor

Think about now I’d slap a scope on those serial lines and try to figure out what data is actually coming across.

sspence65:
When I change '13' to 13 or '\r' I get no readings in the serial monitor.

'13' is still incorrect. Fixing only that line may not be sufficient to make your program work, but it's necessary.

If anyone wishes to see the full manual for the optoCONTROL 2600 we are working with, see https://www.micro-epsilon.com/download/manuals/man--optoCONTROL-2600--en.pdf

sspence65:
If anyone wishes to see the full manual for the optoCONTROL 2600 we are working with, see https://www.micro-epsilon.com/download/manuals/man--optoCONTROL-2600--en.pdf

56 replies in :o

gfvalvo:
Think about now I’d slap a scope on those serial lines and try to figure out what data is actually coming across.

Another option would be to connect one of these to the serial output from the RS422 / TTL Serial converter:

You could then use a terminal emulator on the PC to monitor the serial output. It will be easiest if ASCII is actually being sent.

In the terminal program you could play with baud and other settings. It won’t be able to handle inverted data. But, you can do that by switching the polarity on the differential input to the converter as I already suggested (and you apparently haven’t tried).

Only issue is that the device I linked above is for 3.3V logic and your converter is 5V. A simple resistive voltage divider would probably fix that as you're only interested in listening on the Serial bus, not talking on it.

gfvalvo:
Another option would be to connect one of these to the serial output from the RS422 / TTL Serial converter:
USB to TTL Serial Cable - Debug / Console Cable for Raspberry Pi : ID 954 : $9.95 : Adafruit Industries, Unique & fun DIY electronics and kits
You could then use a terminal emulator on the PC to monitor the serial output. It will be easiest if ASCII is actually being sent.

In the terminal program you could play with baud and other settings. It won’t be able to handle inverted data. But, you can do that by switching the polarity on the differential input to the converter as I already suggested (and you apparently haven’t tried).

Only issue is that the device I linked above is for 3.3V logic and your converter is 5V. A simple resistive voltage divider would probably fix that as you're only interested in listening on the Serial bus, not talking on it.

ASCII is being sent, and I did try your advice on switching the polarity even though it didn't make any sense. As I suspected, I got no output. You can't connect rx to rx ....