Receive data from ph-controller

Hey everyone,

i’m working on a university project for which we need to work with serial output from a ph-controller for fish-tanks.

The serial output from the “black box” is supposed to have this format:

Data rate: 9600 bits per second (fix)
Data bits: 8
Parity: none
Stop bits: 1
Signal lines: TxD, RxD, GND
Flow control: none

So this would be the SERIAL_8N1 config, which to my knowledge is the default.

We are using a RS232 <-> TTL converter and receiving data blocks like this:

93
98
51
5
10
144
67
144
49
49
4
2
53
5
2
8
106

there are four slightly different ones, every two seconds.

We don’t really know what to make of this, since converting it with an ascii table only gives us more gibberish…
The output is supposed to be Date, Time, Temp, Ph-Value but we don’t know how exactly.

This is the code we used so far:

byte incomingByte = 0; // for incoming serial data

void setup() {
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}

void loop() {
  // send data only when you receive data:
  if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
    Serial.println(incomingByte);
  }
}

We’ve been trying to find a solution via this forum we couldn’t really find a similar problem so yeah, please help :slight_smile:

Thanks a lot in advance!

Do you have a manual or data sheet for the sensor that describes the data format?

Having the sensor and the serial monitor connected to the serial port at the same time can cause problems. I would suggest using a second serial port for the sensor and use the (hardware) Serial port for program upload, output and debug prints. The second port can be an extra hardware serial port like on a Mega or a software serial port.

Here is an example to read the sensor using software serial. Connect the sensor TX to pin 5 and the sensor RX to pin 7. What is the output with this code?

#include <SoftwareSerial.h>

SoftwareSerial ss(5, 7);

void setup()
{
   Serial.begin(115200);  // *********** set serial monitor baud to 115200 *********
   Serial.println("\n software serial ph reader /n");
   ss.begin(9600);
}

void loop()
{
   if (ss.available() > 0)
   {
      Serial.print(char(ss.read()));
   }
}

the first 4 bytes

93	0x5D
98	0x62
51	0x33
5	0x05

in big endian format give 0x5D623305hex which is 1 566 716 677(dec)

if you look at this as a unix timestamp that would be a possible date not too far back: 25/08/2019 @ 07:04:37 UTC

is that possible ? when did you acquire the frame ?

Hey thanks a lot for the quick answers!

So i tried your code @groundFungus but all i got was “software serial ph reader /n” in the serial monitor once.

@J-M-L: The time and date werent set right, but i dont know what date they were set to (I had to recalibrate because i turned it off by accident). Now I changed the time and date so now these values came at about: 10:06:30, Fr. 01.01.10

I tried converting it to a unix timestamp like you did, but i get 07/06/2019 @ 4:26am (UTC) for the first 4 bytes which isn’t correct.

Heres the Serial i receive:
93
32
35
9
2
19
34
9
2
32
32
4
0
41
13
2
18
9
10

pause 1 second, then:

93
98
51
1
2
76
83
144
80
19
41
0
49
1
32
10
32
3
83
0

then:

93
33
35
9
0
1
35
9
10
35
33
8
2
41
13
2
16
9
10

and so on…

In the manual it says the output looks like this (but it’s for the industrial device, much more features like Rx, Ox and so on. But the pattern could be similar):
"Result:

E11:36 Fr, 20.01.
E1 (Lv ) Air
E2 (pH-)07.01 pH
E3(Rx)+507 mV
E4 (Te+ ) 21.4 °C
E5 (Ox )110.4 %
E6(Co) 958 uS
E7 (AP) 1014 mB
E8 (Co)
E11:37 Fr, 20.01.

"

well

93
32
35
9

would be 0x5D202309 which is 1562387209 in decimal at in UNIX time is 06/07/2019 @ 04:26:49 so not that great....

what's the PH reader brand and model ?? will be easier to try to find the doc :slight_smile:

can you also print in HEXA rather than decimal ? makes it easier :slight_smile:

oh there I was too slow with my edit haha.
It's a german company: "IKS aquastar midi ph" but theres nothing to find. I only got the few info i have from emailing them, but thats all they could tell me.

This is the manual I'm quoting:

I also noticed that the length of the blocks varies from 18 to 21 lines...

I tracked the measures at the same time of the output:

Time: 10:43:00 (dont know the exact seconds)
Date: Fr. 01.01.10
Ph: 6.83
Temp: 20.5C

Output:

5D
0
44
80
0
D0
2
14
4
D
0
8
10
D
A
30
0
0

Looking quickly at the the doc it seems you are supposed to receive ASCII
So something is wrong in the setup.

Can you describe your exact wiring ?

You likely need to use groundFungus’ code as you can’t have both your PC and the pH meter on the same serial line , here is a slightly modified version

#include <SoftwareSerial.h>

SoftwareSerial phReader(2, 3); 
// SoftwareSerial(rxPin, txPin)
// rxPin: the pin on which to receive serial data
// txPin: the pin on which to transmit serial data
// ==> connect pin 2 (Rx) to pH meter Tx
// ==> connect pin 3 (Tx) to pH meter Rx
// ==> connect GND together 

void setup()
{
  Serial.begin(115200);  // *********** set serial monitor baud to 115200 *********
  Serial.println("\n software serial ph reader\n");
  phReader.begin(9600);
}

void loop()
{
  static unsigned long lastChrono =0;
  static bool waitingForFrame = true;
  if (!waitingForFrame && (millis() - lastChrono > 750)) {
    // probably got the full frame, go to next line
    Serial.println();
    waitingForFrame = true;
  }
  
  if (phReader.available() > 0)
  {
    uint8_t b = phReader.read();
    lastChrono = millis();
    Serial.print(char(b));  Serial.write(' '); // let's try ASCII printing first
  }
}

connect Arduino pin 2 (Rx) to pH meter Tx
connect Arduino pin 3 (Tx) to pH meter Rx
connect GND of Arduino to GND of pH meter
open the Serial monitor at 115200 bauds

First of all thanks a lot again for your help!

I’m using a MAX3232 on a breakout-board, on the ph-Controller theres just a MiniDin6-Cable coming out, on which i measured the currents to find out which wires are GND and which ones have voltage (about 9V).
This is my wiring:

I tried your code and now i got this (the first three “blocks”, always start with a “]” :

 software serial ph reader /n
] ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ s e ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮  ] g { ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ^ y = ] ⸮ { ⸮ o ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮ ⸮  o ⸮ ⸮

Do you have any idea what that could be?

Could it be that the other three wires, on which i don’t measure any voltage, are needed for something?

Cheers

Here is your image a bit bigger :slight_smile:


You did not put any labels. Can you confirm the pins are connected the right way (confirm the orange labels / path)

how did you find out Tx and Rx on the pH meter side ?

it seems you are powering your MAX3232 with 3.3 V. --> the Arduino logic level is 5V so you should likely power it with 5V. What's your exact MAX3232 board model ?

in the code change the line

    Serial.print(char(b));  Serial.write(' '); // let's try ASCII printing first

to this to print the Hex data received

    Serial.print(b, HEX);  Serial.write(' '); // let's try HEX printing

On the board there are just the arrows, but i'm pretty sure the labels are correct like you placed them. On the ph-controller-side is just tried this way and the other way around. But with the first code I had, the other way around didn't give me any output so i assumed this was the right way, since i received at least something.

Powering it with 5V didn't change the output. In some tutorial on the MAX3232 i read that it could get very hot when powered with 5V instead of 3.3V so i just did that.

This is the board I'm using:

I already outputting it as Hex, but didn't really know what to do with this output either ;D
This is the output:

software serial ph reader /n
5D F6 B6 95 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 5D 67 7B BB D5 BF AD BF 9B 9D A3 8F BF BF 9F 5E 79 3D 5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0

With your code i actually get an output when switching rx and tx on the ph-controller side:

software serial ph reader /n
FF FF FF FF BF FD FF 0 FF FF FD E5 FF 0 FF FD F9 FD FF FD FF 0

How is it possible to receive some kind of input on the arduino with the rx and tx switched (on ph-controller)?

it’s weird indeed may be random noise as there are lots of FF

Did you wire to 5V ? 3.3V will be seen as a HIGH on the Arduino side, so that’s why it’s probably working but if the signal is a bit weak you would have issues.

(by the way change the ‘/n’ into ‘\n’ in the welcome message, it was meant to have an extra line break)

have you installed the “firmware updates” they mention in the doc ?

also I had a small bug in my “going to next line” code, use this

#include <SoftwareSerial.h>

SoftwareSerial phReader(2, 3);
// SoftwareSerial(rxPin, txPin)
// rxPin: the pin on which to receive serial data
// txPin: the pin on which to transmit serial data
// ==> connect pin 2 (Rx) to pH meter Tx
// ==> connect pin 3 (Tx) to pH meter Rx
// ==> connect GND together

void setup()
{
  Serial.begin(115200);  // *********** set serial monitor baud to 115200 *********
  Serial.println("\n software serial ph reader\n");
  phReader.begin(9600);
}

void loop()
{
  static unsigned long lastChrono = 0;
  static bool frameStarted = false;

  if (frameStarted && (millis() - lastChrono > 500)) {
    // probably got the full frame, go to next line
    Serial.println();
    frameStarted = false;
  }

  if (phReader.available() > 0)
  {
    uint8_t b = phReader.read();
    lastChrono = millis();
    frameStarted = true;
    Serial.print(b, HEX);  Serial.write(' ');
  }
}

and could you grab many sequences like 30 seconds worth of recording

This is the output now, with 5V:

5D B3 7B FB 6F BF AD 9F 91 A3 9D 97 BF BF 1F 6F E5 EB 0 
5D D6 B6 9B 8F BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 9B BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 97 BF BF 1F 6F E5 EB 0 
5D D6 B6 9B 8F BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 9B BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 97 BF BF 1F 6F E5 EB 0 
5D D6 B6 9B 8F BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 9B BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 97 BF BF 1F 6F E5 EB 0 
5D D6 B6 9B 8D BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 9B BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 97 BF BF 1F 6F E5 EB 0

The controller has the newest firmware, when it starts it show the number, and its the one of the latest update you can download.

well at least now there is a pattern emerging

but it's not ASCII

the same 3 frames are repeating, seems there is a common start ']' symbol (0x5D) and first part has similar length.

There is also a 0xBF repeating in column 5 and 0xBF appears many times, may be it's a field separator

What values were you seing at the time ?

I don't know the exact values so I tracked them again:

Time: 02:47:02
Sa, 02.01.2010
Temp: 22.4 C (or 22.5 C)
Ph: 7.15

5D 67 7B BB D5 BF AD BF 9B 9B A3 95 BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0 
5D B6 B6 97 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 95 BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0 
5D B6 B6 97 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 97 BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0 
5D B6 B6 97 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 97 BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0 
5D B6 B6 97 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 97 BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0 
5D B6 B6 97 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0 
5D 67 7B BB D5 BF AD BF 9B 9B A3 97 BF BF 9F 5E 79 3D 
5D B3 7B FB 6F BF AD 9F 91 A3 9D 95 BF BF 1F 6F E5 EB 0 
5D B6 B6 97 91 BF BF BF BF 59 3D A7 BF 9F 9B A3 9F 9D A3 E5 EB 0

I warmed up the thermometer to see which values change and i noticed that only in the blocks that end with “3D” changes happen, and only between column 7 (BF) and 12(BF).

And i just noticed that in the longest block in column (or byte) 4 the value changes from changes from 9F to 9D, thats probably because the ph-value changed by 0.01 (because of false temp change)

challenge is that nothing really clicks

if I look at UNIX time:
Time: 02:47:02 Sa, 02.01.2010 --> 0x4B3EA596 (paris) or 0x4B3EB3A6 (UTC) and I see no 4B in the data

(when you said 02:47:02 is that 2am or 2pm ? (2pm would be 0x4B3F4E56 but still start with 0x4B anyway)
Temp: 22.4 C (or 22.5 C) => 0x41B33333 or 0x41B40000 in IEEE float on 4 bytes again nothing very similar

Ph: 7.15 => 0x40E4CCCD in IEEE float on 4 bytes again nothing very similar

and the data is not in ASCII either....

it might be windows time, which is handled differently, (your date if UTC would be 40180.61599537 or 01CA8BBA:71A07700 in microsoft format) but I don't see anything that looks like being increased over time anyway ...

Could you record for 1 minute and not change anything in the measure... this way we shall see what part could represent the date/time if any

the last point I could see is that SoftwareSerial it's not exact enough in timings to communicate with devices that might be super picky. In that case you would need to go to hardware Serial and need an Arduino with two hardware Serial ports. Do you have a MEGA by any chance ?

I didn't have much time today, but i checked again what the output is like without software.serial! It's exactly the same output when using the hardware serial, so i don't think that's the problem.

So I took the values for more than a minute and these are the blocks that changed (the long blocks):

67 66 B1 16 F6 FB FB FB CB 85 A7 BF 9F 99 A3 9F 9D A3 E5 EB 0
67 66 B1 F6 BF BF BF BF 59 21 A7 BF 9F 99 A3 9F 9D A3 E5 EB 0
67 66 B1 D9 F6 FB FB FB CB 85 A7 BF 9F 99 A3 9F 9D A3 E5 EB 0

The other blocks stayed the same, but in my last post I only changed temperature and the block that ends with 3D changed. So we know which block contains what info, but not how its hidden in the numbers :smiley:

I'm pretty sure this is what the blocks translate to (took these values now and copied the output):

5D 67 D9 EC D6 F6 FB FB FB CB 85 A7 BF 9F 99 A3 9F 9D A3 E5 EB 0 --> E14:01 So, 03.01.
5D 67 7B BB D5 BF AD BF 9B 9F A3 93 BF BF 9F 5E 79 3D --> E1 (Te) 20.5 °C
5D B3 7B FB 6F BF AD 9F 91 A3 99 99 BF BF 1F 6F E5 EB 0 --> E2 (pH)07.33 pH

I took the supposed output pattern from the pdf they sent me.