bnjmnp / pysoem

Cython wrapper for the Simple Open EtherCAT Master Library
MIT License
95 stars 36 forks source link

Failed to write pdo? #122

Open buctwp opened 8 months ago

buctwp commented 8 months ago

i have 6 slaves in my project.

when the salves state is OP, i try to write pdo like this:

master.slaves[0].sdo_write(0x7031, 1, struct.pack('H', 0xAAAA))

it raises an Excpetion: pysoem.pysoem.SdoError:(1, 20721, 1, 100728834, 'Attempt to write to a read only object')

when i call this code:

master.send_processdata()
actual_wkc = master.receive_processdata(2000)

the return actual_wkc is 6, not 18

I'm stuck on it for days now, Help would be very helpful.

bnjmnp commented 8 months ago

Hi @buctwp,

master.slaves[0].sdo_write(0x7031, 1, struct.pack('H', 0xAAAA))

You don't write PDOs there but you do a SDO write. The error message tells you about the issue, are you sure object 0x7031 is writable?

the return actual_wkc is 6, not 18

Why do you expect a value of 18?

buctwp commented 8 months ago

the address 0x7031 is read by this code

` def read_sdo_info(ifname):

master = pysoem.Master()
master.open(ifname)
if master.config_init() > 0:
    for slave in master.slaves:
        try:
            od = slave.od
        except pysoem.SdoInfoError:
            print('no SDO info for {}'.format(slave.name))
        else:
            print(slave.name)
            for obj in od:
                print(' Idx: {}; Code: {}; Type: {}; BitSize: {}; Access: {}; Name: "{}"'.format(
                    hex(obj.index), obj.object_code,  obj.data_type,  obj.bit_length, hex(obj.obj_access), obj.name))
                for i, entry in enumerate(obj.entries):
                    if entry.data_type > 0 and entry.bit_length > 0:
                        print('  Subindex {}; Type: {}; BitSize: {}; Access: {} Name: "{}"'.format(
                            i, entry.data_type, entry.bit_length, hex(entry.obj_access), entry.name))

`

this is a part of console messages: ` Idx: 0x7031; Code: 8; Type: 42; BitSize: 136; Access: 0x0; Name: "b'Module 4 Output Entries'"

Subindex 0; Type: 5; BitSize: 8; Access: 0x7 Name: "b'SubIndex 000'" Subindex 1; Type: 6; BitSize: 16; Access: 0x47 Name: "b'SubIndex 001'" Subindex 2; Type: 6; BitSize: 16; Access: 0x47 Name: "b'SubIndex 002'" Subindex 3; Type: 6; BitSize: 16; Access: 0x47 Name: "b'SubIndex 003'" Subindex 4; Type: 6; BitSize: 16; Access: 0x47 Name: "b'SubIndex 004'" Subindex 5; Type: 6; BitSize: 16; Access: 0x47 Name: "b'SubIndex 005'" Subindex 6; Type: 6; BitSize: 16; Access: 0x47 Name: "b'SubIndex 006'" `

it seems the Index 0x7031 and subIndex 1 maps to the output: Module 4 Channel 1 so i think i can call sdo_write(0x7031, 1, struct.pack('H', 0xAAAA)

about wkc, the code blow here: master.send_processdata() actual_wkc = master.receive_processdata(2000) if not actual_wkc == master.expected_wkc: print('incorrect wkc, actual_wks is {}, expected_wkc is {}'.format(actual_wkc, master.expected_wkc))

the expect wkc is read from the master's property above the codes, i have 6 slaves, when read success, counter+1, when write success, counter+2, so if all slaves RW success, the expect wkc should be 18。

my question is how can i write output to send an Analog signal or Digital signal to the modules? Did I send the wrong address?

GoesWithoutSaying commented 2 months ago

you are doing sdo write which is usually to assign a PDO mapping, not doing PDO communication. to do PDO communication

input_from_slave = slave.input slave.output = bytes([data1, data2]) master.send_processdata() master.receive_processdata()

slave.input represent input data from slave, which is the slave send to master, it is not writeble. these data are only index's value, not include index slave.output represent output data to slave, which is the master send to slave, you should assign a proper data to this, when master.send_processdate(), it will send these data to the slave. the data should only contain index's value.

SDO and PDO are 2 different communication way