Go Down

Topic: Decrypting the Vado Identity wired shower controller (Read 4130 times) previous topic - next topic

Monkey3

There's no auto mode that I can find so I had to select everything manually.

I've tried loads of different options and the closest I've come to a match is the one I've got to here which is 9600, 8N1.
I think it's more likely 8N2 as when I add a parity bit (of any type) and set 1 stop bit the length is perfect but the parity bit is often wrong but there's no option to add 2 stop bits in PulseView.

I'm actually monitoring both the A and B but was only showing 1 of them in the images to save space. Both signals are the same, as you'd expect, except being the opposite. The idle high signal shows exactly the same data.

Riva

You will know if the data is correct if you never get UART framing errors.
I mentioned about the A/B high idle as adding a UART protocol decoder to the wrong one may cause wrong data values and framing errors to be returned in the decode data.

This is just the sort thing I like working on and even looks at the Vado unit for playing with but it would be too expensive for just the fun of it.
Don't PM me for help as I will ignore it.

Monkey3

You will know if the data is correct if you never get UART framing errors.
I mentioned about the A/B high idle as adding a UART protocol decoder to the wrong one may cause wrong data values and framing errors to be returned in the decode data.

This is just the sort thing I like working on and even looks at the Vado unit for playing with but it would be too expensive for just the fun of it.
Had to put this down for a bit again as I've been really struggling with it.

When I use the RS485 modules I can't seem to replicate the unit's initial pattern in a sensible way. I set the baud to 9600 but when I send a character it's so much shorter than the pattern from the unit.

The only way I've managed to get close is with the following but it's not using the RS485 module at all so I don't think it'll work with the unit:

Code: [Select]

long unsigned lastCom = 0;
long unsigned curMicros = 0;

const int digPinHigh = 30;
const int digPinLow = 31;
const int byteLen = 7;

bool valArray[] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};

const int bitLen = 104;
const unsigned long comPeriod = 55000;

void setup() {
  pinMode(digPinHigh, OUTPUT);
  pinMode(digPinLow, OUTPUT);
  digitalWrite(digPinHigh, LOW);
  digitalWrite(digPinLow, HIGH);
}

void loop()
{
  curMicros = micros();
  if ((curMicros > (lastCom + comPeriod)) || (curMicros < lastCom)) {
    lastCom = curMicros;

    for (int j = 0; j < byteLen; ++j) {
      for (int i = 0; i < sizeof(valArray); ++i) {
        digitalWrite(digPinHigh, valArray[i]);
        digitalWrite(digPinLow, valArray[i] == HIGH ? LOW : HIGH);
        delayMicroseconds(bitLen);
      }
      digitalWrite(digPinHigh, LOW);
      digitalWrite(digPinLow, HIGH);
      delayMicroseconds(bitLen);
    }
  }
}

Riva

When I use the RS485 modules I can't seem to replicate the unit's initial pattern in a sensible way. I set the baud to 9600 but when I send a character it's so much shorter than the pattern from the unit.
What if you use a lower baud rate, 300, 1200, 2400 and 4800 are standard rates below 9600 but it could also be custom.
Does your logic analyser protocol decoder have an auto baud option where it will try to figure out the baud rate for its self?
Don't PM me for help as I will ignore it.

Monkey3

#19
Nov 10, 2018, 06:45 pm Last Edit: Nov 10, 2018, 06:49 pm by Monkey3
What if you use a lower baud rate, 300, 1200, 2400 and 4800 are standard rates below 9600 but it could also be custom.
Does your logic analyser protocol decoder have an auto baud option where it will try to figure out the baud rate for its self?

Firstly, thank you Riva for your help on this. It's very much appreciated and is really keeping me invested.

ok, another step forwards perhaps...

I changed the arduino code that utlilises the rs485 module to the following:

Code: [Select]

long baudRate = 9600;
byte serialConfig = SERIAL_8N1;

#define TxControlMixer      3   //RS485 Direction control
#define RS485Transmit       HIGH
#define RS485Receive        LOW

long unsigned lastCom = 0;
long unsigned curMicros = 0;
const unsigned long comPeriod = 55000;
const int bitLen = 104;

byte message[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

void setup() {
  Serial1.begin(baudRate, serialConfig);

  // Init Transceiver
  pinMode(TxControlMixer, OUTPUT); 
  digitalWrite(TxControlMixer, RS485Receive);
}

void loop()
{
  curMicros = micros();
  if ((curMicros > (lastCom + comPeriod)) || (curMicros < lastCom)){
    lastCom = curMicros;
    digitalWrite(TxControlMixer, RS485Transmit);  // Enable RS485 Transmit
    for (int i = 0; i < sizeof(message); ++i) {
      Serial1.write(message[i]);
      delayMicroseconds(bitLen);
    }
  }
}


The main point being I've removed the line that sets the RS485 module to receive. This means that the arduino is constantly in transmit which could be a problem when I connect the controller up but I'll get to that later.

This gave the right sort of pattern, as shown on the top line in the attached image.

Once I got to there I then changed the baud to 8750 (with some trial and error) which gave me the middle line.

The bottom line is the mixer.

Note:
  • the scale is not the same on each line
  • rather the measure at the top of each line shows the duration


So the overall length of a packet looks right but the individual segments look a little too short.

Monkey3

#20
Nov 10, 2018, 07:04 pm Last Edit: Nov 10, 2018, 07:09 pm by Monkey3
I ran the mixer again and read the data in sigrok and then added a UART decoder at a baud of 8750.

I now get some clean packets but also still some frame errors... (see attachments).

However, if I increase the sample rate in sigrok to 50kHz then the frame errors pretty much go away entirely... :D

Monkey3

#21
Nov 10, 2018, 07:56 pm Last Edit: Nov 10, 2018, 08:48 pm by Monkey3
ok, I've now sampled both the mixer and the controller together and am seeing zero frame errors.

Looks like it's a baud of 8752... :\

Strange, but ok.

And with that I get the following data:

I'm certain the left is the mixer and the right is the controller.

The mixer sends 7 00's until the controller is connected at which point the controller sends a single 02 in response.
Code: [Select]
00 00 00 00 00 00 00   00 00 00 00 00 02 00


The following 6 packets are then exchanged:
Code: [Select]
00 00 00 00 00 00 21   13 72 02 16 07 02 00
00 00 00 00 00 00 53   13 72 02 16 07 02 00
00 00 00 00 00 00 21   13 72 02 16 07 02 00
00 00 00 00 00 00 53   13 72 02 16 07 02 00
00 00 00 00 00 00 21   13 72 02 16 07 02 00
00 00 00 00 00 00 53   13 72 02 16 07 02 00


There are then a whole load of the following packet pairs are exchanged until the mixer has finished its start up (making whirring noises - to reset the proportioning valve I would guess):
Code: [Select]
00 00 00 00 00 00 16   13 72 02 16 07 02 00
00 00 00 00 00 00 53   13 72 02 16 07 02 00


After the mixer's start up completes, the following pairs are exchanged ad infinitum:
Code: [Select]
00 00 00 00 00 00 16   13 72 02 16 07 02 00
00 00 00 00 00 00 51   13 72 02 16 07 02 00


so now to try to replicate the mixer pattern with arduino...

Monkey3

Bit more messing with the controller...

If I press the power button, there's a bit of mess where it looks like the controller stops talking for a few packets while the mixer sends the following:
Code: [Select]
00 00 00 00 00 00 16


The controller then talks over the mixer for a couple of packets until it settles into the following:
Code: [Select]
00 00 00 00 00 00 16   12 72 01 16 07 02 00


After that I pressed the button to switch to a different shower outlet at which point there was some mess again followed by:
Code: [Select]
00 00 00 00 00 00 16   12 72 01 16 07 01 00


They then settled into the following:
Code: [Select]
00 00 00 00 00 00 16   11 72 01 16 07 01 00


I then hit the pause button, there was mess, then:
Code: [Select]
00 00 00 00 00 00 16   12 7A 02 16 07 01 00
00 00 00 00 00 00 53   12 72 02 16 07 01 00

I think the first line above may be a read error and 7A should in fact be 72

Then they settle into the following:
Code: [Select]
00 00 00 00 00 00 16   12 72 02 16 07 01 00
00 00 00 00 00 00 53   12 72 02 16 07 01 00


At some point thereafter they settle into the following:
Code: [Select]
00 00 00 00 00 00 16   12 72 02 16 07 01 00
00 00 00 00 00 00 51   12 72 02 16 07 01 00

Monkey3

New update!

I'm sort of talking to the controller. Certainly it knows I'm talking and is responding.

I rewrote the code to replicate the 3 stage start up sequence (from post 21) and then connected the controller to the arduino and it seems to be responding.
As far as the data being received from the controller in response to the data I'm sending, it looks identical to what's received when it's connected to the arduino.

The only difference in the data, and the main issue I seem to be having, is that on one of the 2 rs485 data pins the idle is HIGH whereas on the mixer it's LOW (see attached).

I'd like to resolve the data issue in order to eliminate it from the investigation (plus I think the arduino's signal is wrong as per the rs485 spec / requirements / guidelines / whatever).

Aside from the data issue I've found that when I connect the controller to the arduino and power everything on, the screen stays on the "00", the backlight stays lit and the buttons are unresponsive.
However, if I start everything up and then move the controller connections to the mixer (which is powered on patiently waiting) the backlight then goes out which is the appropriate standby mode and the buttons are responsive.
Better yet, if I then move the connections back to the arduino, the buttons remain responsive. I can perform all of the usual actions on the buttons until I attempt to put it back into standby at which point the buttons then become unresponsive once more.

Clearly the unresponsive buttons is a blocker for real use but I may continue to work on the code that handles the state, temp, pressure, etc. until I have a breakthrough or somebody points out the glaringly obvious mistake to me...

Riva

What RS485 module are you using and does it have the relevant/correct pullup/pulldown resistors on the A/B lines and maybe the 120 ohm terminator?

Don't PM me for help as I will ignore it.

Monkey3

What RS485 module are you using and does it have the relevant/correct pullup/pulldown resistors on the A/B lines and maybe the 120 ohm terminator?

It's this one: https://www.amazon.co.uk/WINGONEER-MAX485-Module-RS-485-Development/dp/B06XHHWLMW

From the looks of the schematic it's got all the resistors and the board seems to match the schematic (in terms or the number of components).

My first thought was pull up / down resistors so I tried adding a couple of 220's in parallel (so 110 ohm) across the A / B and from each as pull up / down but all I managed to do was change the "incorrect" pin to the other one. So it feels like it's in the right region but I'm not really sure how to work out what's required.

The next thing I'm going to try is to measure the resistance across everything with the controller connected to the mixer and then again with the controller connected to the arduino, both with everything powered on and off.
At least that will tell me what the difference is between the 2 scenarios...

Riva

If you disconnect the mixer and just connect your logic analyser to A, B & Gnd of the MAX485 module while sending data, does it then show idle as low or still as high?
Don't PM me for help as I will ignore it.

Monkey3

If you disconnect the mixer and just connect your logic analyser to A, B & Gnd of the MAX485 module while sending data, does it then show idle as low or still as high?

Exactly the same. Still HIGH.

Riva

#28
Nov 21, 2018, 09:50 am Last Edit: Nov 21, 2018, 10:44 am by Riva Reason: Added extra info and example
Exactly the same. Still HIGH.
Is the MAX485 module in RX or TX mode when you take the readings?

EDIT:
Using the simple test program below on a Mega
Code: [Select]
#define DE 2
#define RE 3
#define TEST 4
#define DELAY 100

void setup()
{
  Serial.begin(115200);
  Serial1.begin(9600);
  pinMode(DE, OUTPUT);
  pinMode(RE, OUTPUT);
  pinMode(TEST, OUTPUT);
  Serial.println("Setup End");
}

void loop()
{
  Serial.println("DE/RE High");
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  digitalWrite(TEST, HIGH);
  delay(10);
  Serial1.print("Hello World");
  delay(DELAY);
  Serial.println("DE/RE Low");
  digitalWrite(DE, LOW);
  digitalWrite(RE, LOW);
  digitalWrite(TEST, LOW);
  delay(DELAY);
}

I get the below image on my LA. You need to put the MAX481 into receive mode to release the lines.

Don't PM me for help as I will ignore it.

Monkey3

Is the MAX485 module in RX or TX mode when you take the readings?

EDIT:
Using the simple test program below on a Mega
Code: [Select]
...
I get the below image on my LA. You need to put the MAX481 into receive mode to release the lines.

...

Using the same code I get the attached.

Go Up