Ralfy1337 wrote: ↑Mon Jan 02, 2023 2:03 pm
Oh, and forgot to mention if no data is send prior to reading from id 0x01 first byte is always 0x40, but when some data is sent, no matter in what ID, 0x01 will give back first byte 0x41.
Sorry - i hadn't noticed the above.
This sounds very similar to something that I saw and used to find the control register (see my earlier link). Essentially this LSB of the 0x41 byte sounds like a transmission error flag, it is complaining that you tried to write to a non valid address, or to a valid address with the wrong number of data bytes. Try sending different packet lengths to all addresses and for each one read the status message and see whether the LSB doesn't get set. If you find one then that is your control register and you can start working out what the data bytes within the message do.
Pete9008 wrote: ↑Mon Jan 02, 2023 2:56 pm
Sorry - i hadn't noticed the above.
This sounds very similar to something that I saw and used to find the control register (see my earlier link). Essentially this LSB of the 0x41 byte sounds like a transmission error flag, it is complaining that you tried to write to a non valid address, or to a valid address with the wrong number of data bytes. Try sending different packet lengths to all addresses and for each one read the status message and see whether the LSB doesn't get set. If you find one then that is your control register and you can start working out what the data bytes within the message do.
My progress with EVX valve - looks like I`m stuck now. My read code was off, today found out that when cycling thru ID`s, ID - 0x00 and 0x01 gave back status byte of 0x41, all other ID`s were 0x40. So looks like ID 0x00 is for motor command, tried to send different data and data sizes - {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80} to all 8 bytes in turn and some more combinations, but no luck with that. Only thing i observed was - when from 1 to 3 bytes and from 5 to 8 bytes of data is sent, status byte is 0x41, but when 4bytes are sent, status changes back to 0x40.
Say the Lsb of the status is a comms error flag and say that it just ignores writes to any non implemented addresses (as these might be in use by other bus slaves). It would then always return an error for writes to the status register (read only register) and only return an error for the command register if the byte count is wrong. That would mean that the command register is on 0x00 and it expecting 4bytes. I'd try a few more value combinations with 4byte writes to that address.
If in ID 0x00 data[4] 0x00, 0x00, 0x00 0x00 are being sent:
ID 0x01 response is: 1st byte 0x40, 2nd byte cycles thru 4 values: 0xE0, 0xE4, 0xE8, 0xEC and rest two bytes are 0x00, 0xFD
If in ID 0x00 data[4] 0xFF, 0b00000000, 0x00000000, 0x00 sent:
response is: 1st byte 0x40, 2nd byte cycles thru 4 values: 0xE0, 0xE4, 0xE8, 0xEC and rest two bytes are 0x00, 0xFD
If in ID 0x00 data[4] 0xFF, 0b00000011, 0x00000000, 0x00 sent:
response is: 1st byte 0x40, 2nd byte cycles thru 4 values: 0xE0, 0xE4, 0xE8, 0xEC and rest two bytes are 0x00, 0xFD
If in ID 0x00 data[4] 0xFF, 0b00000011, 0x00000001, 0x00 sent:
response is: 1st byte 0x40, 2nd byte cycles thru 4 values: 0xE1, 0xE5, 0xE9, 0xED and last two bytes are changing as motor is active from 0x00, 0xFD to 0xFF, 0xFF
Valve will move for like 3000 ms! But only after valve power cycle OR 2nd byte response before was 0xE0, 0xE4, 0xE8, 0xEC(cycles thru 4 values)
If in ID 0x00 data[4] 0xFF, 0b00000011, 0x00001001, 0x00 sent:
response is: 1st byte 0x60, 2nd byte cycles thru 4 values: 0xF1, 0xF5, 0xF9, 0xFD and last two bytes are changing as motor is active from 0x00, 0xFD to 0xFF, 0xFF
Valve will move for like 800 ms! But only after valve power cycle OR 2nd byte response before was 0xE0, 0xE4, 0xE8, 0xEC(cycles thru 4 values)
If in ID 0x00 data[4] 0xFF, 0b00000011, 0x00000001, 0x00 (or any value from 0x00 to 0xFF) motor will move but only after valve power cycle OR 2nd byte response before was 0xE0, 0xE4, 0xE8, 0xEC
So when valve is moving response 1st byte changes from 0x40 to 0x60 and when its done moving changes back to 0x40.
Issue: If valve moved response data byte 2 bit 0 set to 1. And sending any data (all 0x00 for ex.) to it, it doesn`t change back bit 0 to 0 so it can be moved again with loop code. It moves again only when its power cycled (with correct data) OR 2nd byte response before was 0xE0, 0xE4, 0xE8, 0xEC(cycles thru 4 values) - bit 0 is 0.
Just to check, my valves need a status read every few hundred ms. If they don't see a status read then they will go to an inactive low power mode and when you then wake them up with another message you need to repeat the wake-up/calibration process. Could that be contributing to what you are seeing? I made my test program automatically do a status request every 200ms regardless of whether any test messages were being sent to make sure it stayed awake all the time.
Have you a feeling for which 2bytes in the command you think are the valve position and which ones are control flags?
Pete9008 wrote: ↑Wed Jan 18, 2023 2:34 pm
Sounds like you're making progress with it
Somewhat of a progress was made, but now im really stuck
Pete9008 wrote: ↑Wed Jan 18, 2023 2:34 pm
I made my test program automatically do a status request every 200ms regardless of whether any test messages were being sent to make sure it stayed awake all the time.
I`m sending command packet (0x00 with data) and after 40ms sending status request packet(0x01 with no data) all this is done in loop which repeats itself every 400ms. Using ESP mcu and mcp2003 chip. Will try to increase time from 40ms to 200ms. Mby 40ms is too short of a time for it.
Pete9008 wrote: ↑Wed Jan 18, 2023 2:34 pm
Have you a feeling for which 2bytes in the command you think are the valve position and which ones are control flags?
Not sure yet, because i even can`t figure out which is enable and which is calibrate bit. Because 1st byte needs to be "filled out" with 1`ns, 2nd byte needs to have two lsb bits set to 1 and in 3rd byte need to set at least first lsb bit to 1. Mby I`m crashing valves software because it needs some kind on initialization sequence and that's why its acting so weird? Or I`m still missing something small.
The loop time may be part of your problem. I seem to remember needing to let each command complete, and the motor to finish moving (there is a bit in my status register that flags this), before sending another command. My code has a background loop that does a status read every 100ms, that is enough to keep the valve awake. A command is only sent when I manually trigger it.
I'm happy to share my test code if that helps? It's a very hacky command line app writen in Qt that runs on a PC. It uses a usb to ttl rs232 converter to drive a LIN transceiver IC. The code uses key preses to trigger scanning for status registers and command registers. Other keys allow command message contents to be altered and the command sent. As mentioned it is pretty rough code but it does allow different message combinations to be quickly tested. It really needs tidying up and a proper gui adding but that's way down the list at the moment!
Pete9008 wrote: ↑Mon Jan 23, 2023 12:54 pm
I seem to remember needing to let each command complete, and the motor to finish moving (there is a bit in my status register that flags this).
Hmm, ok, need to consider this also, because I`m not waiting for time till it finishes moving.I think on my side it could be 5th bit in response first byte, because while motor is moving it changes to 0x60 (form default 0x40).
Pete9008 wrote: ↑Mon Jan 23, 2023 12:54 pm
My code has a background loop that does a status read every 100ms, that is enough to keep the valve awake.
Yes, will try doing it like you did.
Pete9008 wrote: ↑Mon Jan 23, 2023 12:54 pm
I'm happy to share my test code if that helps?
Now it is very simple/rough and as such various things need modifying in the code to suit your operation, in particular:
In serialclass.cpp change the "FTDI" and "TTL232R-3V3" entries to suit your USB to 232 TTL dongle.
In serialclass.cpp change the "m_serialPort->setBaudRate(QSerialPort::Baud9600);" line to suit your baudrate
In serialclass.cpp change the "QThread::usleep(700); //13bits at 19200baud" line to suit your baudrate (values for 9600 and 19200 in comments)
In serialclass.cpp you may need to chage the csum calculation to include/exclude the header byte (line 79 and 80)
In topclass.cpp change the STATUS and COMMAND ID #defined to match your LIN node.
In topclass.cpp change the write buffer size to match the command size (lines 220-227), currently set at 4 bytes
The functions are:
sends a status message every 200ms (can change on line 115 of topclass)
Hit S to scan for status registers
Hit Q to scan for control registers (need to hit G first to grab/learn the standard status response so that program can tell when it changes)
Hit W to write a walking 1's pattern to the command register
Hit <space> to send a command to the command register
Hit 1 to decrement 1st command byte value, hit ! <shift + 1> to increment 1st command byte
Hit 2 to decrement 2nd command byte value, hit " to increment 2nd command byte
...
Hit 8 to decrement 8th command byte value, hit * to increment 8th command byte
This uses a USB to TTL 232 dongle and assumes that a LIN transceiver is connected to the TTL level RS232 Rx and Tx lines on the dongle. I used a TJA1020 transceiver but a MCP2003 or similar should work just as well.