Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regarding IO Mapping like Sycon.net Utility #861

Open
ANANTH5354 opened this issue Sep 27, 2024 · 4 comments
Open

Regarding IO Mapping like Sycon.net Utility #861

ANANTH5354 opened this issue Sep 27, 2024 · 4 comments

Comments

@ANANTH5354
Copy link

Hello all,
I hope you all doing well !

SOEM master code I am here compiled like (slaveinfo fun and simple test ) it working well.

========================================================================
Slaveinfo
Starting slaveinfo
ec_init on \Device\NPF_{F4271784-7547-493D-8A78-8EBAC65E2F75} succeeded.
5 slaves found and configured.
Calculated workcounter 7

Slave:1
Name:EK1100
Output size: 0bits
Input size: 0bits
State: 4
Delay: 0[ns]
Has DC: 1
DCParentport:0

Slave:2
Name:EL3602
Output size: 0bits
Input size: 96bits
State: 4
Delay: 140[ns]
Has DC: 1
DCParentport:1

Slave:3
Name:EL5152
Output size: 96bits
Input size: 160bits
State: 4
Delay: 285[ns]
Has DC: 1
DCParentport:1

IOmap mapped successfully.
End slaveinfo, close socket
End program

Slave info

Here, I want to construct the slave configuration channels (AI, AO, DI, ,DO and Data Address, Data Length) and the code address table (IO mapping) (e.g., Sycon.net utility Address table). Would you please help me, anyone?

final output like that I want here,
Address table PMX.zip

Thank you

@ArthurKetels
Copy link
Contributor

Try : simple_test [network name] -map

@ANANTH5354
Copy link
Author

Okay.. I will check !!!

Could you provide me with some suggestions on how to formulate my questions.

Thank you

@ANANTH5354
Copy link
Author

Hello,

Here is the problem I'm having. I've tried using different logic, but I'm having trouble getting the address table to look like this: input data address, length data address, and output data address. This is a problem for me—the input address appears, but the exit address is hidden. Why?

the this my output:

Screenshot (22)

my code :

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>

// OSAL threading and other necessary declarations
OSAL_THREAD_HANDLE thread1;
int expectedWKC;
bool needlf;
volatile int wkc;
volatile int rtcnt;
bool inOP;
uint8_t currentgroup = 0;
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "ethercat.h" // Include your EtherCAT library header

// Global addresses for input and output
uint32_t global_input_address = 0x0001; // Initialize starting input address
uint32_t global_output_address = 0x1000; // Initialize starting output address
//const char* outputFilePath = "C:/Users/ananth.kumaravel/Desktop/Address_Table_EMaster/Address_Table.csv"; // Specify the output file path

#define MAX_SLAVES 64 // Maximum number of slaves
#define OUTPUT_FILE_PATH "output.csv" // Set your output file path

typedef struct {
int type; // 1: AI, 2: AO, 3: DI, 4: DO
unsigned int address; // Address for both input and output
int length; // Length for input or output
} ChannelInfo;

// Function to identify channel types (AI, AO, DI, DO)
int identify_channel_type(const char* slave_name, int channel_index) {
// Example logic, replace with actual identification logic based on your hardware
if (channel_index < 8) { // Assume first 8 are AI and the next are DI
return (slave_name[0] == 'E') ? 1 : 3; // AI if slave name starts with 'E', else DI
}
else {
return (slave_name[0] == 'E') ? 2 : 4; // AO if slave name starts with 'E', else DO
}
}

void get_channel_data_info(int slave, int channel_index, ChannelInfo* channel_info, const char* slave_name) {
// Identify the channel type
channel_info->type = identify_channel_type(slave_name, channel_index);

// Assign input or output address based on the channel type
if (channel_info->type == 1 || channel_info->type == 3) {  // AI or DI (Input channels)
    channel_info->address = global_input_address;
    global_input_address += (channel_info->type == 1) ? 8 : 2; // 8 bytes for AI, 2 bytes for DI
}
else if (channel_info->type == 2 || channel_info->type == 4) {  // AO or DO (Output channels)
    channel_info->address = global_output_address;
    global_output_address += (channel_info->type == 2) ? 8 : 4; // 8 bytes for AO, 4 bytes for DO
}

// Assign the length based on the channel type
channel_info->length = (channel_info->type == 1) ? 8 :
    (channel_info->type == 2) ? 8 :
    (channel_info->type == 3) ? 2 :
    (channel_info->type == 4) ? 4 : 0;

// Set addresses and lengths for channels that do not support them
if (channel_info->type == 4) { // DO channel
    channel_info->address = 0; // Set address to 0 for DO
    channel_info->length = 0;   // Set length to 0 for DO
}

}

void slaveinfo(char* ifname) {
int cnt, total_slaves = 0;
printf("Starting slaveinfo\n");

if (ec_init(ifname)) {
    printf("ec_init on %s succeeded.\n", ifname);
    if (ec_config(FALSE, &IOmap) > 0) {
        ec_configdc();
        total_slaves = ec_slavecount;  // Count total slaves
        printf("%d slaves found and configured.\n", total_slaves);

        // Open the CSV file for writing
        FILE* file;
        int result = fopen_s(&file, OUTPUT_FILE_PATH, "w");
        if (result != 0) {
            perror("Error opening file");
            return;
        }

        // Write headers in CSV file for both input and output side
        fprintf(file, "Slave Name, Station Address, Channel Name, Channel Type, Input Address, Input Length, Output Address, Output Length\n");

        // Iterate over each slave
        for (cnt = 1; cnt <= total_slaves; cnt++) {
            printf("Slave %d: %s\n", cnt, ec_slave[cnt].name);
            printf("Station Address 0x%04X\n", ec_slave[cnt].configadr);

            int slave_channels = 0; // Reset channel count for this slave

            // Determine the number of channels for the slave based on its type
            if (strstr(ec_slave[cnt].name, "EL2809") != NULL)
                slave_channels = 16; // 16 DO channels
            else if (strstr(ec_slave[cnt].name, "EL5152") != NULL)
                slave_channels = 2;  // 2 DI channels
            else if (strstr(ec_slave[cnt].name, "EL3602") != NULL)
                slave_channels = 2;  // 2 AI channels
            else if (strstr(ec_slave[cnt].name, "EL9512") != NULL)
                slave_channels = 4;  // 4 AO channels
            else if (strstr(ec_slave[cnt].name, "EL3356") != NULL)
                slave_channels = 1;  // 1 AI channel
            else if (strstr(ec_slave[cnt].name, "EK1100") != NULL)
                slave_channels = 0;  // EK1100 has no channels
            else if (strstr(ec_slave[cnt].name, "EL1809") != NULL)
                slave_channels = 16; // 16 DI channels
            else if (strstr(ec_slave[cnt].name, "EL4134") != NULL)
                slave_channels = 4;  // 4 AO channels
            else
                slave_channels = 0;  // Unknown number of channels

            // Iterate over each channel for the slave
            for (int channel_index = 0; channel_index < slave_channels; channel_index++) {
                ChannelInfo channel_info;
                get_channel_data_info(cnt, channel_index, &channel_info, ec_slave[cnt].name);

                // Prepare channel name based on the channel index
                char channel_name[50];
                snprintf(channel_name, sizeof(channel_name), "ch%d.%d", cnt, channel_index + 1);

                // Determine input and output addresses/lengths
                uint32_t input_address = (channel_info.type == 1 || channel_info.type == 3) ? channel_info.address : 0;
                int input_length = (channel_info.type == 1 || channel_info.type == 3) ? channel_info.length : 0;
                uint32_t output_address = (channel_info.type == 2 || channel_info.type == 4) ? channel_info.address : 0;
                int output_length = (channel_info.type == 2 || channel_info.type == 4) ? channel_info.length : 0;

                // Write channel information to the CSV file
                fprintf(file, "%s,0x%04X,%s,%s,0x%04X,%d,0x%04X,%d\n",
                    ec_slave[cnt].name,
                    ec_slave[cnt].configadr,
                    channel_name,
                    channel_info.type == 1 ? "AI" :
                    channel_info.type == 2 ? "AO" :
                    channel_info.type == 3 ? "DI" :
                    channel_info.type == 4 ? "DO" : "Unknown",
                    input_address,
                    input_length,
                    output_address,
                    output_length);

                // Print the channel information to the console
                printf("Channel Name: %s, Channel Type: %s, Input Address: 0x%04X, Input Length: %d bytes, Output Address: 0x%04X, Output Length: %d bytes\n",
                    channel_name,
                    channel_info.type == 1 ? "AI" :
                    channel_info.type == 2 ? "AO" :
                    channel_info.type == 3 ? "DI" :
                    channel_info.type == 4 ? "DO" : "Unknown",
                    input_address,
                    input_length,
                    output_address,
                    output_length);
            }
        }

        fclose(file);
        printf("\nFile created at: %s\n", OUTPUT_FILE_PATH);
    }
    else {
        printf("No slaves found!\n");
    }
    printf("End slaveinfo, close socket\n");
    ec_close();
}

}

===========================================================

thank you

@ANANTH5354
Copy link
Author

And soem.lib visual studio 2022 version Release mode only perform well but Debug mode not performing like linker error shows
how to fix this issue!!!
Screenshot (23)

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants