Giter VIP home page Giter VIP logo

Comments (40)

mbuesch avatar mbuesch commented on July 19, 2024

Hi. Thanks for your question.

The initialization phase of your logs actually looks quite good.
It successfully enters Data_Exchange mode.

You configured input_size=0. Is that really intended?
Pyprofibus currently doesn't correctly support unidirectional Data_Exchange. (out or in being zero bytes).
Simply because that operating mode has not been implemented, yet.
You might want to take a look at the Data_Exchange section in dp_master.py.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

; The number of output bytes this slave transmits to the
; master in Data_Exchange.
; This usually depends on the modules plugged into the slave.
output_size=2

; The number of input bytes this slave expects to receive
; in Data_Exchange.
; This usually depends on the modules plugged into the slave.
input_size=0

I guess this doesn't really make any sense, since it should be other way around it seems. But then the output pins are not created in HAL

...
 --> Ignored unknown line
pyprofibus: DP slave 8 output: 0 bytes
pyprofibus: DP slave 8 input:  2 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
./profibus.hal:25: parameter or pin 'profibus.slave.8.output.bit.0.0.active' not found
Shutting down and cleaning up LinuxCNC...
pyprofibus: LinuxCNC HAL module shutdown.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Thanks for your response I'll have a look at it.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

But then the output pins are not created in HAL

Hm, that could actually be a bug. I'm not quite sure right now.
It's quite confusing what's in and what's out for slave, master, hal and so on :)

In pyprofibus-linuxcnc-hal you could try to swap the assignments of inputSize and outputSize. (around line 526 at the createHalPins() call)

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Reading through the code: The HAL pins are named from the slave perspective.
So it possibly is correct as implemented.
You just need to use the slave.8.input... pins. These are HAL_OUT. That seems to be correct, I think.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Thanks again, I'll give it a try.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Cool.
The bigger problem is in the main Data_Exchange code, though.
I'm quite sure that needs some changes for unidirectional transfers. There's even a TODO comment in there. :)

I'm not sure how that change would look like. It could possibly be as simple as don't using the timeout mechanism for input-only slaves.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

So as a first quick try I commented out lines 606...612 in dp_master.py:


			if dataExInData is None:
				if slave.pendingReqTimeout.exceed():
					self.__debugMsg("Data_Exchange timeout with slave %d" % (
							slave.slaveDesc.slaveAddr))
					slave.faultDeb.fault()
					slave.pendingReq = None
			else:

But now I get state_machine timeouts:


PHY-serial: TX   68 05 05 68 08 02 7D 00 00 87 16
PHY-serial: RX   E5
DPM1: State machine timeout! Trying to re-initializing slave 8...
DPM1: Trying to initialize slave 8...

I have also tried to inject a value for 'data'ExInData' but then the master doesn't wait for the slave to respond before sending the next request. I guess the problem is that the master needs to wait for the slave to send the acknowledge (E5) and then continue before the timeout is exceeded. So maybe I would need to parse the response to see if it contains E5.

[edit]
looks like the E5 in the response is correctly parsed as an SC but the telegram is flagged as 'Fdl' instead of 'SD..' :

PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
telegram : FdlTelegram(sd=SC, haveLE=False, da=None, sa=None, fc=None, dae=Empty, sae=Empty, du=None, haveFCS=False, ed=None)
DPM1: Data_Exchange timeout with slave 8

Not sure if it's just the 'du=None' that needs to be addressed or if the 'FdlTelegram' itself causes problems.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Ok, I'm a step further. I think.

I inserted this at line 589 in dp_master.py ( not sure if all of the four lines at the end are required but I just copied that from the else block with the comment '# We received some data'.:

		if slave.shortAckReceived:
				print(":line590: SHORT_ACK RECIEVED")
				slave.pendingReq = None
				slave.faultDeb.ok()
				slave.restartStateTimeout()
				self._releaseSlave(slave)

So now I don't get the timeouts as before during data_exchange but after a short while I get an RS-fault (SAP not enabled) response from the slave 'Service not active on slave 8'. I'm at a loss as to why this happens since the request from the master doesn't change at all:

pyprofibus: DP slave 8 output: 2 bytes
pyprofibus: DP slave 8 input:  0 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
pyprofibus: Active DP slave (addr=8) pins:
pyprofibus: DP output:  profibus.slave.8.output.bit.0.0
pyprofibus: DP output:  profibus.slave.8.output.bit.0.1
pyprofibus: DP output:  profibus.slave.8.output.bit.0.2
pyprofibus: DP output:  profibus.slave.8.output.bit.0.3
pyprofibus: DP output:  profibus.slave.8.output.bit.0.4
pyprofibus: DP output:  profibus.slave.8.output.bit.0.5
pyprofibus: DP output:  profibus.slave.8.output.bit.0.6
pyprofibus: DP output:  profibus.slave.8.output.bit.0.7
pyprofibus: HAL configuration done
Unexpected realtime delay on task 0 with period 20000
This Message will only display once per session.
Run the Latency Test and resolve before continuing.

DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 6D 3C 3E F1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 13 13 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 7B 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 06 06 68 88 82 7D 3E 3E 21 24 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
note: MAXV     max: 30.000 units/sec 1800.000 units/min
note: LJOG     max: 30.000 units/sec 1800.000 units/min
note: LJOG default: 10.000 units/sec 600.000 units/min
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
note: jog_order='XYZ'
note: jog_invert=set([])
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECIEVED
PHY-serial: TX   68 05 05 68 08 02 7D 05 00 8C 16
PHY-serial: RX   10 02 08 03 0D 16
pyprofibus: PROFIBUS fault:
Service not active on slave 8
DPM1: Data_Exchange timeout with slave 8
PHY-serial: TX   68 05 05 68 08 02 5D 05 00 6C 16
PHY-serial: RX   10 02 08 03 0D 16
pyprofibus: Fatal fault detected
pyprofibus: Fatal PROFIBUS fault:
Service not active on slave 8
pyprofibus: LinuxCNC HAL module shutdown.
Shutting down and cleaning up LinuxCNC.. 

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Very nice.
Does the slave show some life before you get the SAP fault? (e.g. some valve switching, as requested by the TX data).

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Oh I just noticed that right before the fault you receive a different telegram from the slave:
PHY-serial: RX 10 02 08 03 0D 16

Can you try to decode this?
It might be some diagnosis request or something else that has to be serviced.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

The slave correctly switches the valves and after about half a second it goes into error mode as the pyprofibus component shuts down because of the fault. But it did that also before I made the changes to dp_master.py.

According to this : https://www.felser.ch/profibus-manual/funktionscode.html
I interpret the Response Function Code as being hex 03 -> slave , 'RS = SAP not enabled'
Which seems strange since in Data_exchange mode there is no SAP, as I understand it.

Problem is I don't have another profibus device so I can't test if the device itself is faulty. Although the one I have was supposed to come from a working machine.
The only thing I could do is have a look at the data with a scope. But really I don't expect it to send different request telegrams then what it prints to the terminal.

[edit]
Scope shows the same as the terminal, so no indication as to what may be causing the slave to consistently throw that fault.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I don't think the device is broken.
But I can only guess what's going on here. My guess would be: The slave expects some kind of periodic non-Data_Exchange telegram every couple of milliseconds. For example like a diagnosis data fetch or something like that.
The slave has no way to send a diagnostic request with the short-ack. So expecting the master to periodically poll the diagnosis data would make some sense.

Do you have an S7 or something similar? Then you could sniff the Profibus. That way you could check which packets are being sent around.

In any case, I think your changes would be a nice contribution, once resolved this. Feel free to open a Pull Request, as soon as you feel comfortable with the changes.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

One thing I notice it that with half the baud rate (ie 9600) the master does one reinitialization before shutting down:

PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 6D 3C 3E F1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 13 13 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 7B 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 06 06 68 88 82 7D 3E 3E 21 24 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   10 02 08 03 0D 16
pyprofibus: PROFIBUS fault:
Service not active on slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: Many errors in Data_Exchange. Requesting diagnostic information...
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: Slave 8 requests a new parameterization (Set_Prm).
DPM1: slave[08].state --> 'init'
DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 7D 3C 3E 01 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 13 13 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 7B 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 06 06 68 88 82 7D 3E 3E 21 24 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   E5
:line590: SHORT_ACK RECEIVED
PHY-serial: TX   68 05 05 68 08 02 7D 01 00 88 16
PHY-serial: RX   10 02 08 03 0D 16
pyprofibus: Fatal fault detected
pyprofibus: Fatal PROFIBUS fault:
Service not active on slave 8
pyprofibus: LinuxCNC HAL module shutdown.

I also notice that the fault occurs after 15 data requests while with 19200baud it seems to be after 30 requests. So maybe there is indeed a timeout running in the slave. Although one would expect to find a reference in the device documentation.
Unfortunately I don't have any other device.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

The fatal HAL shutdown upon SAP failure probably is not really clever behaviour.
I think the HAL or the dp-master core should try to debounce this fault better and retry a couple of times.
But in your case that probably won't help. It will eventually shutdown anyway.
So it's not the highest priority to fix now.

In the Data_Exchange handler you can see the path where it branches off to the diagnosis request state if the slave requested it.
You might try with a simple counter that does this branch every 10 DX telegrams or so. It that works, we could have a more clever solution with a timer.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Thanks for your suggestion.
I've inserted a counter and got it working (mostly). But the way I'm doing it is not quite right, because i don't really know what I'm doing. Simply doing a diagnosis request from inside the data_exchange loop causes an 'Ignoring telegram in DataExchange with slave 8' and a 'Data_Exchange timeout with slave 8' that is recovered though.
As you suggested, there would have to be a cleverer solution for this but I'm out of my depth really.

...
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 88 82 7D 3C 3E 01 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: Ignoring telegram in DataExchange with slave 8:
DpTelegram_SlaveDiag_Con(da=0x02, sa=0x08, fc=0x08, dsap=0x3E, ssap=0x3C, b0=0x00, b1=0x0C, b2=0x00, masterAddr=0x02, identNumber=0x0A35)
DPM1: Data_Exchange timeout with slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: Many errors in Data_Exchange. Requesting diagnostic information...
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 08 02 7D 14 14 AF 16
...
	def __runSlave_dataExchange(self, slave):
		#TODO: add support for in/out-only slaves
		dataExInData = None

		if slave.stateJustEntered():
			self.__debugMsg("Initialization finished. "
				"Running Data_Exchange with slave %d..." %\
				slave.slaveDesc.slaveAddr)
			slave.flushRxQueue()
			slave.dxStartTime = monotonic_time()


		if slave.shortAckReceived:
			slave.pendingReq = None
			slave.faultDeb.ok()
			slave.restartStateTimeout()
			self._releaseSlave(slave)
 			self.__ScCount += 1
            
			if (self.__ScCount > 10):
				# Send a SlaveDiag request
				self.__send(slave,
				telegram=DpTelegram_SlaveDiag_Req(
				da=slave.slaveDesc.slaveAddr,
				sa=self.masterAddr),
					timeout=0.05)
                                # Reset short confirmation counter
				self.__ScCount = 0
...

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Ok, I understand. But that's not a problem.
Would you like to fork this repo and upload your current changes anyway?
I think that would be a good starting point to implement a more generic and/or correct solution. Even if the real solution would look completely different.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

I created a fork here
https://github.com/Sigma1912/pyprofibus/tree/master/pyprofibus
with the modified dp_master.py.

Thanks for making this profibus stack available.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I'll try to prepare an experimental change for in-only slaves based on your changes.
I'll let you know once that's ready for testing.
Thanks!

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I created a branch for the work on support for input-only slaves:
https://github.com/mbuesch/pyprofibus/tree/in-only-slave

You may want to take a look at it.
This code currently is mostly untested. But you might want to try it and give me some feedback.

Thanks.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Thanks for the update. I think the same confusion about the input_bytes and output_bytes trips me up again:

Because of this in line 625 in dp_master.py:

			if (dataExInData is not None or
			    (slaveOutputSize == 0 and slave.shortAckReceived)):
				# We received some data.
				slave.pendingReq = None
				slave.faultDeb.ok()
				slave.restartStateTimeout()
				self._releaseSlave(slave)

I'm forced to change 'pyprofibus.conf' to output_size=0, input_size=4 (which would be correct if we look at the comments in the file) I get:

--> Ignored unknown line
pyprofibus: DP slave 8 output: 0 bytes
pyprofibus: DP slave 8 input:  4 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
./profibus.hal:25: parameter or pin 'profibus.slave.8.output.bit.0.0.active' not found
Shutting down and cleaning up LinuxCNC...
pyprofibus: LinuxCNC HAL module shutdown.
Note: Using POSIX realtime
LinuxCNC terminated with an error.  You can find more information in the log:
    /home/user/linuxcnc_debug.txt
and
    /home/user/linuxcnc_print.txt
as well as in the output of the shell command 'dmesg' and in the terminal

Because now the component creates the wrong hal-pins (ie. In HAL environment we need hal-pins with direction IN not OUT):

Screenshot from 2021-10-14 10-34-10

If you look at this hal command (which worked fine before because I "wrongly" defined 'output_bytes=4' and 'input_bytes=0'):

net	estop-out	<= halui.estop.is-activated	=> profibus.slave.8.output.bit.0.0

We connect 'halui.estop.is-activated' (which is a hal-pin of direction OUT) to ' profibus.slave.8.output.bit.0.0' (which is, and needs to be, of hal-direction IN)
Screenshot from 2021-10-14 10-44-26

However, now with the "correct" 'output_bytes=0' and 'input_bytes=4', there are only hal-pins created with hal-direction OUT (ie. 'profibus.slave.8.input.bit.x.x') and these are useless because in the hal-environment we cannot connect a pin of hal-direction OUT to another pin of hal-direction OUT.

I'll try and disable all hal related connections and see what the communication looks like.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

So I disabled all Hal-connections to see what I get running your 'in-only-slave' fork.
As far as I can tell, all goes well until we enter 'data_exchange' mode. Then the master sends PHY-serial: TX 10 08 02 7D 87 16
which seems odd to me and shortly after that the slave claims a configuration error.

pyprofibus: DP slave 8 output: 0 bytes
pyprofibus: DP slave 8 input:  4 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
pyprofibus: Active DP slave (addr=8) pins:
pyprofibus: HAL configuration done
DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 6D 3C 3E F1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 17 17 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 5B 00 00 00 D6 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 07 07 68 88 82 7D 3E 3E 21 21 45 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   10 08 02 7D 87 16
PHY-serial: RX   E5
PHY-serial: TX   10 08 02 7D 87 16
PHY-serial: RX   10 02 08 03 0D 16
DPM1: Ignoring telegram in DataExchange with slave 8:
DpTelegram(da=0x02, sa=0x08, fc=0x03, dsap=None, ssap=None, du=Empty)
DPM1: Data_Exchange timeout with slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: Many errors in Data_Exchange. Requesting diagnostic information...
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 06 05 00 FF 0A 35 D5 16
DPM1:  >ERROR<  Slave 8 reports a faulty configuration (Chk_Cfg).
DPM1: Slave 8 requests a new parameterization (Set_Prm).
DPM1: slave[08].state --> 'init'
DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
...

In comparison this is the terminal output from my working modification:
Note, after entering 'data_exchange' mode the master sends PHY-serial: TX 68 07 07 68 08 02 7D 00 00 00 00 87 16
which seems correct.

pyprofibus: DP slave 8 output: 4 bytes
pyprofibus: DP slave 8 input:  0 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
pyprofibus: Active DP slave (addr=8) pins:
pyprofibus: HAL configuration done
DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 6D 3C 3E F1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 17 17 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 5B 00 00 00 D6 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 07 07 68 88 82 7D 3E 3E 21 21 45 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 05 05 68 88 82 7D 3C 3E 01 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: Ignoring telegram in DataExchange with slave 8:
DpTelegram_SlaveDiag_Con(da=0x02, sa=0x08, fc=0x08, dsap=0x3E, ssap=0x3C, b0=0x00, b1=0x0C, b2=0x00, masterAddr=0x02, identNumber=0x0A35)
DPM1: Data_Exchange timeout with slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: Many errors in Data_Exchange. Requesting diagnostic information...
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

It seems that if the 'output_byte' is 0 then no data is sent because if I define 'output_byte=1' the master sends one byte once 'data_exchange' mode is established:

pyprofibus: DP slave 8 output: 1 bytes
pyprofibus: DP slave 8 input:  4 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
pyprofibus: Active DP slave (addr=8) pins:
pyprofibus: HAL configuration done
DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
note: MAXV     max: 1.200 units/sec 72.000 units/min
note: LJOG     max: 1.200 units/sec 72.000 units/min
note: LJOG default: 1.000 units/sec 60.000 units/min
note: AJOG     max: 90.000 units/sec 5400.000 units/min
note: AJOG default: 45.000 units/sec 2700.000 units/min
PHY-serial: TX   10 08 02 49 53 16
note: jog_order='XYZABCUVW'
note: jog_invert=set([])
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 6D 3C 3E F1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 17 17 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 5B 00 00 00 D6 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 07 07 68 88 82 7D 3E 3E 21 21 45 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
DPM1: line 646 outData is not None
line 651: sending data:
PHY-serial: TX   68 04 04 68 08 02 7D 00 87 16
line 658: data sent: 
PHY-serial: RX   E5
DPM1: line 646 outData is not None
line 651: sending data:
PHY-serial: TX   68 04 04 68 08 02 7D 00 87 16
line 658: data sent: 
PHY-serial: RX   10 02 08 03 0D 16
pyprofibus: PROFIBUS fault:
Service not active on slave 8
DPM1: Data_Exchange timeout with slave 8
DPM1: line 646 outData is not None
line 651: sending data:
line 658: data sent: 
DPM1: Data_Exchange timeout with slave 8
DPM1: line 646 outData is not None
line 651: sending data:
line 658: data sent: 
DPM1: Data_Exchange timeout with slave 8
DPM1: Many errors in Data_Exchange. Requesting diagnostic information...
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Ok I made some changes to your dp_master.py and I have it running nicely now:

pyprofibus: DP slave 8 output: 4 bytes
pyprofibus: DP slave 8 input:  0 bytes
Warning in GSD 'cpv_0A35.gse': DPv1 User_Prm_Data override ignored
pyprofibus: Running PROFIBUS-DP master...
pyprofibus: ready.
pyprofibus: Active DP slave (addr=8) pins:
pyprofibus: DP output:  profibus.slave.8.output.bit.0.0
pyprofibus: DP output:  profibus.slave.8.output.bit.0.2
pyprofibus: DP output:  profibus.slave.8.output.bit.0.4
pyprofibus: DP output:  profibus.slave.8.output.bit.0.6
pyprofibus: DP output:  profibus.slave.8.output.bit.1.0
pyprofibus: DP output:  profibus.slave.8.output.bit.1.2
pyprofibus: DP output:  profibus.slave.8.output.bit.1.4
pyprofibus: DP output:  profibus.slave.8.output.bit.1.6
pyprofibus: DP output:  profibus.slave.8.output.bit.2.0
pyprofibus: DP output:  profibus.slave.8.output.bit.2.1
pyprofibus: DP output:  profibus.slave.8.output.bit.2.2
pyprofibus: DP output:  profibus.slave.8.output.bit.2.3
pyprofibus: DP output:  profibus.slave.8.output.bit.2.4
pyprofibus: DP output:  profibus.slave.8.output.bit.2.5
pyprofibus: DP output:  profibus.slave.8.output.bit.2.6
pyprofibus: DP output:  profibus.slave.8.output.bit.2.7
pyprofibus: HAL configuration done
DPM1: Trying to initialize slave 8...
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: TX   10 08 02 49 53 16
PHY-serial: RX   10 02 08 00 0A 16
DPM1: slave[08].state --> 'wait for diag'
DPM1: Requesting Slave_Diag from slave 8...
PHY-serial: TX   68 05 05 68 88 82 6D 3C 3E F1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 02 05 00 FF 0A 35 D1 16
DPM1: slave[08].state --> 'wait for Prm'
DPM1: Sending Set_Prm to slave 8...
PHY-serial: TX   68 17 17 68 88 82 5D 3D 3E B8 1E 01 00 0A 35 01 00 00 00 82 00 00 00 5B 00 00 00 D6 16
note: MAXV     max: 1.200 units/sec 72.000 units/min
note: LJOG     max: 1.200 units/sec 72.000 units/min
note: LJOG default: 1.000 units/sec 60.000 units/min
note: AJOG     max: 90.000 units/sec 5400.000 units/min
note: AJOG default: 45.000 units/sec 2700.000 units/min
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Cfg'
DPM1: Sending Chk_Cfg to slave 8...
PHY-serial: TX   68 07 07 68 88 82 7D 3E 3E 21 21 45 16
note: jog_order='XYZABCUVW'
note: jog_invert=set([])
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 7D 3C 3E 01 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 00 00 00 00 67 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 00 00 00 00 87 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 01 00 8A 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 7D 3C 3E 01 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 5D 3C 3E E1 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
PHY-serial: TX   68 07 07 68 08 02 7D 01 01 11 00 9A 16
PHY-serial: RX   E5
DPM1: slave[08].state --> 'wait for Data_Exchange-ready'
DPM1: Requesting Slave_Diag (WDXRDY) from slave 8...
PHY-serial: TX   68 05 05 68 88 82 7D 3C 3E 01 16
PHY-serial: RX   68 0B 0B 68 82 88 08 3E 3C 00 0C 00 02 0A 35 D9 16
DPM1: slave[08].state --> 'Data_Exchange'
DPM1: Initialization finished. Running Data_Exchange with slave 8...
PHY-serial: TX   68 07 07 68 08 02 5D 01 01 11 00 7A 16
PHY-serial: RX   E5
...

I implemented my previous solution with the counter and with your conditionals I don't get any timeouts anymore.
However I had to swap 'input_byte' and 'output_byte' back to my original "wrong" definition and also swap the conditionals in your modifications, since with 'output_byte=0' the master doesn't send any data during 'data_exchange' mode ( see posts above):
https://github.com/Sigma1912/pyprofibus/blob/master/pyprofibus/dp_master.py

There probably still is a more elegant solution than that counter but the 'input_byte' vs 'output_byte' thing seems to run a bit deeper.
Maybe it would just be easiest to swap the comments in the pyprofibus.conf file?

Thanks for your patience

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Maybe it would just be easiest to swap the comments in the pyprofibus.conf file?

That would be a breaking change, except for LinuxCNC users.
And also it makes sense to have the slave configuration see things from the slave's perspective.

Therefore I'd rather like to swap the meaning of input and output in the LinuxCNC HAL module.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Mind you that will not solve the problem that the master seems to be only sending as many bytes of data as have been declared as 'output_bytes'. See posts above.

So the issue isn't just a question of definition. Setting output_bytes=0 doesn't work for my 'input-only-slave' because the master doesn't send any data during 'data_exchange'. I haven't been able to figure out why though.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Whether any data is sent fully depends on your user code.
If slaveDesc.setOutData() (That's the master's perspective. Should probably be renamed to something like setMasterOutData) is called with some data, then it will be sent.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

Whether any data is sent fully depends on your user code.

Ah ok I just realized that the user code is in LinuxCNC HAL.
And we already found out that the LinuxCNC HAL is buggy (swapped in/out).
So that's the same problem.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I rebased the branch on top of the fix from #21.
I think that should fix the confusion in the HAL.
(The diagnosis part is not yet included).

Disclaimer: Nothing of that has been tested on real hardware by me, yet. :)

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Thanks for all your prompt work.
I've had a bit of a rethink and changed my mind regarding the naming of the hal-pins. I think you had it correct before (ie no-input-slaves like my valve block should create hal-pins 'profibus.slave.n.output.bit.x.y' with the needed hal-direction IN) as this corresponds with other hardware connecting to hal like mesa cards.
My apologies for sending you on a loop there, I got confused.

So I've changed the files 'pyprofibus-linuxcnc-hal', 'linuxcnc-demo-dummyphy/profibus.hal' and 'linuxcnc-demo-et200s/profibus.hal' accordingly.

I've also modified 'dp_master.py' again to include the required diag request using the counter.

https://github.com/Sigma1912/pyprofibus

This works nicely now with my Festo hardware with the correct definition 'output_byte=0' and 'input_byte=4'.

PS I'm not sure I'm actually doing this right when I change 'master' on my fork.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

ie no-input-slaves like my valve block should create hal-pins 'profibus.slave.n.output.bit.x.y' with the needed hal-direction IN

Your slave is a input-only slave, right? It only receives data. Payload data is only sent from master to slave. (The other way around is just ACKs). That's my definition of input-only.

Therefore the current HAL (after change) implements profibus.slave.n.input.bit.x.y with direction HAL_IN.
And you need to specify output_size=0 and input_size=4 in the config.

That makes perfect sense to me.

PS I'm not sure I'm actually doing this right when I change 'master' on my fork.

It would be more idiomatic, if you would create your own branch derived from the branch that you want to modify. Then just commit your changes. That would make it way easier to review and diff.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Your slave is a input-only slave, right? It only receives data. Payload data is only sent from master to slave. (The other way around is just ACKs). That's my definition of input-only.

Ah, yes. I was looking at it from the hardware perspective, since I have a valve block and a digital output module connected but no input modules. 'Input-only' as seen from the profibus perspective because the slave sends no data back to the master.
So in our profibus perspective it is an 'Input-only-device', I'll stick with that.

Therefore the current HAL (after change) implements profibus.slave.n.input.bit.x.y with direction HAL_IN.
And you need to specify output_size=0 and input_size=4 in the config.

I think here is exactly the problem. In HAL we should think 'hardware'. When I look at how the hal-pins are created for the much used interface cards made by MESA it becomes clear that, in HAL, I want my hardware inputs to be represented as 'x.input.y' and my _hardware_outputs as 'x.output.y' because that's what the signal really is in the machine context. That is what the 'hardware abstraction layer' represents.
It's fine to define 'input' and 'output' in context of the communication interface in the configuration file but once that is done and we move to the hardware abstraction layer we want to follow the established convention of calling a hardware input an '.input.x' and a hardware output an '.output.x'
The bug was that the previous version created 'profibus.slave.n.output.bit.x.y' pins according to how many 'output_bytes' were defined. I got confused because I started to see things from the profibus perspective and I think that is wrong in the HAL context.

It would be more idiomatic, if you would create your own branch derived from the branch that you want to modify. Then just commit your changes. That would make it way easier to review and diff.

Ah yes, I recall that you asked me to create a 'branch' and I went ahead and created a 'fork'. Thanks for pointing that out again. That was sloppy reading on my part.

Thanks

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

In HAL we should think 'hardware'.

Well, the HAL pin direction (HAL_IN or HAL_OUT) purely defines the direction of that single pin.
IN-pins are read-from and OUT pins are write-to.
The perspective is the HAL signal here. There's no hardware here, yet.

we want to follow the established convention of calling a hardware input an '.input.x' and a hardware output an '.output.x'

Yeah, well. I think somebody always thinks that stuff is the wrong way around, no matter how we define it. ;)

I'll keep it as-is, because that's consistent with the pyprofibus config.
And I think it makes sense when reading the string profibus.slave.n.output.bit.x.y that it's the profibus slave output. That's literally what's written there. (And it's also very hard to define what a "hardware output" is. We don't know the hardware in pyprofibus. We only care about the Profibus bus data telegrams)

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

I have tested your latest changes to the 'in-only-slave' branch and it works nicely. The settable diag request frequency is very user friendly.
Note: I have tested it with my version of 'pyprofibus-linuxcnc-hal' as I didn't feel like changing all my hal files again. I still think the pin naming is unfortunate and will cause a lot of unnecessary confusion to hal users. It pains me even more because it was me who suggested that ill concieved change.

Thanks for all your work.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I have tested your latest changes to the 'in-only-slave' branch and it works nicely.

Thanks a lot for testing.

I still think the pin naming is unfortunate

I'll think about changing the naming to something completely different that's less ambiguous than input/output.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I changed the terms from input to mosi and from output to miso.
That completely avoids any assumption about whether we are talking about device out/in or PB out/in. And it also avoids the previously necessary assumption about the perspective.

I think that's a good tradeoff.

And I also merged the input-only-branch into the master branch. Any further development will take place in the master branch.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

Wouldn't it be better to use such terms as 'mosi' and 'miso' inside the communication layer?
Maybe 'output_size' could be 'miso_size' and 'input_size' could be 'mosi_size'?
That would then free up 'input' and 'output' for the hardware layer in HAL. But I guess that would mean that existing configuration files needed to be modified.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

I think that neither input nor output are particular good names, when it comes to the pyprofibus LinuxCNC HAL module.
Calling something that goes into the slave an output, just because it might correspond to a physical output line of the slave, doesn't really make complete sense.
A Profibus slave can be much more complex than simple I/O devices, where every bit maps to a relay, for example.
A bit that's sent to the Profibus slave does not have to be coupled in any way to some kind of physical output.
Same for bits received from the slave.

By using miso/mosi it's more clear that we're talking about the profibus side of the slave and not the physical side of the slave.
Because that's really all pyprofibus and the pyprofibus HAL module care about. There's no knowledge in pyprofibus about what the device does with the data.

The user is free to name the connected HAL signal as input, output or anything else, to give it some hardware related meaning.

And I think it's not such a big deal either. One cannot really get this wrong. If one accidentally swaps miso/mosi, then LinuxCNC will throw an error. It's then just a matter of simply swapping these.

That said, I also don't want to spread the use of the terms miso/mosi throughout the rest of the code. Just because these terms are already allocated to SPI for most people. There I'd rather like to spell the terms out (See recent commits changing some internal names).

And the terms output_size/input_size are explained unambiguously in the corresponding comments. And it is in compliance with all other options in the [SLAVE_x] section. All these options configure what the slave does. Not what the master does.

from pyprofibus.

Sigma1912 avatar Sigma1912 commented on July 19, 2024

The user is free to name the connected HAL signal as input, output or anything else, to give it some hardware related meaning.

And I think it's not such a big deal either. One cannot really get this wrong. If one accidentally swaps miso/mosi, then LinuxCNC will throw an error. It's then just a matter of simply swapping these.

True.

Thanks.

from pyprofibus.

mbuesch avatar mbuesch commented on July 19, 2024

The change has been integrated in the pyprofibus release 1.11.
Thanks for your report and especially for your great help in testing and suggestions!

from pyprofibus.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.