Hi,
I am working on a project to connect a densitometer to a pc app (both made in the 90s).
The newer densitometer doesn’t speak the same serial protocol and the app is fixed, has to be used as is.
I have captured the serial control data from the app and replicated on a Nano v3 with a Max 232 (Code below).
That works just like the app, timing is close enough.
In the code below, the serial_Read(); is where the app would expect a response from the densitometer.
In this case its "R 0.01 0.05 0.09" or whatever other numbers are on the display, they don't matter just the format.
For the other 2 reads its " 0.01 0.05 0.09" (a space instead of R.
I think using the usb serial port to interface with the app and the software serial for the other densitometer should work.
The other densitometer has a completely different protocol but that’s a problem for another day.
Now that I understand what the app is sending and asking for, im not sure how to proceed.
I guess im not really sure of how to get the Nano to read the first 7 lines of serial data transmitted from the PC, respond and wait for the next bunch of lines, respond....then once its done just act as a pass through.
Any ideas?
Thanks so much!!
#include <SoftwareSerial.h>
#define startButton 4
SoftwareSerial mySerial(10, 11); // RX, TX
void setup()
{
pinMode(startButton, INPUT_PULLUP); //Start
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Native USB only
}
// set the data rate for the SoftwareSerial port
mySerial.begin(9600);
digitalWrite(startButton, HIGH);
}
void loop() // run over and over
{ boolean state = false;
if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
if (digitalRead(startButton) == LOW) {
Serial.println("TEST");
delay(1000);
test();
}
}
void test () {
mySerial.println("0");
delay(100);
mySerial.println("K");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("X");
delay(100);
mySerial.println("");
serial_Read();
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("0");
delay(100);
mySerial.println("K");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("X");
delay(100);
mySerial.println("");
serial_Read();
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("0");
delay(100);
mySerial.println("K");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("X");
delay(100);
mySerial.println("");
serial_Read();
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("OFF3");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("0726");
delay(100);
mySerial.println("W");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("ON3");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("ON2");
delay(100);
mySerial.println("");
delay(100);
mySerial.println("G");
delay(100);
mySerial.println("");
delay(100);
}
void serial_Read() {
if (mySerial.available())
Serial.write( mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());
delay(1000);
}
Ianm1:
I guess im not really sure of how to get the Nano to read the first 7 lines of serial data transmitted from the PC, respond and wait for the next bunch of lines, respond....then once its done just act as a pass through.
I'd suggest a state machine using switch/case (examples and tutorials all over). State1, get first set of characters then do something, then set switch variable to State2, get next set.... Lather, rinse, repeat.
I would but turns out I spoke to soon.
Didn’t work at all, the default of the switch/case acted as a passthrough and totally ignored my code.
Im still trying to figure out how to read the incoming serial.
I found Serial.readString almost works but I cant get it to recognize the lines.
i.e. either carriage return or line feed. If I input the LF or CR characters, hex, escape characters, its fails.
The densitometer can accept either CR or LF. Unfortunately the densitometer is the part I already finished.
I cant seem to figure out how to get the Arduino to read in the serial stream and respond.
The attachment is what the PC sends out in Red. In blue is the response. Timing is the first column.
I have to send the blue parts to the pc over serial. Basically just responding but im stuck.
I have tried Serial.readStringUntil and tried to use all of the escape characters one at a time.
Also just Serial.read. Neither seem to be able to interpret because of all of the line breaks.
Any ideas?
Addition: The blank Red lines are Line Feed LF. The blank Blue lines are Carriage Return + Line feed.
On Serial communications characters trickle in one at a time, you can read them one by one and store them in a buffer, optionally parsing chunks of the input as you find the separators (space characters).
When you have that step done, you can do whatever you like with that data: show it on a display, send it on to another PC for further processing - whatever you like.
The PC sends out a command set to setup a specific densitometer.
I am trying to interface another model that doesn’t use the same protocol.
The PC is expecting a specific response after a certain number of controls it sends out.
The later step will be parsing what the new densitometer sends. But I have that pretty much figured out.
It’s spoofing the pc that’s the problem.
Sorry that code was a duplicate of what the PC sends to the densitometer.
Not the translation bit.
I made that so I could verify that the protocol was correct, where the breaks where, where it expected data back...
Running that, I am able to duplicate how the PC interacted with the densitometer.
That code wont be in the finished project.
This is what I came up with to send to the PC so it thinks the densitometer is connected.
But I couldn’t get it to work. Im still tinkering with it.
int Reply2 = 0;
char inByte = Serial.read();
int switch_value = 0;
if (inByte == '0' && inByte == 'K' && inByte == '\r' && inByte == 'G' && inByte == 'X' &&
inByte == '\r') switch_value = 0; //1st Reply
if (inByte == 'G' && inByte == '\r' && inByte == '0' && inByte == 'K' && inByte == '\r' &&
inByte == 'G' && inByte == '\r' && inByte == 'X' && inByte == '\r') switch_value = 1; //2nd Reply
if (Reply2 == 1 && inByte == 'G' && inByte == '\r' && inByte == '0' && inByte == 'K' && inByte == '\r' &&
inByte == 'G' && inByte == '\r' && inByte == 'X' && inByte == '\r') switch_value = 2; //3rd Reply
switch (switch_value) {
case '0':
Serial.println("R 0.01 0.05 0.09"); //First Reply
Serial.println("\r");
break;
case '1':
Serial.write(0x03); //ETX Break/end of text
Serial.println("0.01 0.05 0.09"); //Second and Third Reply
Serial.println("\r");
Reply2 = 1;
break;
case '2':
Serial.write(0x02); //STX Start of text
Serial.println("0.01 0.05 0.09"); //Second and Third Reply
Serial.println("\r");
Reply2 = 0;
break;
default:
Serial.write( mySerial.read()); //default should be a passthrough
}