logo

Notification

Icon
Error

Options
Go to last post Go to first unread
Offline Wilfried Buck  
#1 Posted : Monday, June 8, 2015 1:01:59 AM(UTC)
Wilfried Buck

Rank: Newbie

Joined: 6/8/2015(UTC)
Posts: 4

I got the OPC UA Embedded Server SDK Evaluation V2 for the QuickBoard and I want to do my first steps for teaching OPC UA.
I want to change the code for my own applications and now I have some problems:
1. I created a variable (UA_Type_String). I am able to read the string from a Demo-Client but i
am not able to write a string back to the server. I get the correct number of bytes of the written string, but not the
string itself.
The SDK User Manual is not very helpfull.
2. I want to create a method with input- and output-arguments. I do not find any helpfull documentation to do that.
Please can you help a teacher, who is not an developer-expert.

Thanks
Wilfried
Offline Liam  
#2 Posted : Thursday, June 11, 2015 12:52:29 AM(UTC)
Liam

Rank: Newbie

Joined: 12/1/2014(UTC)
Posts: 7

Was thanked: 2 time(s) in 2 post(s)
Hi Wilfried,

Apologies for the delay in responding to your query.

Regarding 1. Please post your code showing where you create the variable and how you handle the write. This will allow us to identify the issue.

Regarding 2. The SDK supports Methods that are defined internally, for example as part of the UA File Transfer spec. but does not currently support creating arbitrary methods via the API.

Best regards,

Liam.

Offline Wilfried Buck  
#3 Posted : Friday, June 12, 2015 7:50:20 AM(UTC)
Wilfried Buck

Rank: Newbie

Joined: 6/8/2015(UTC)
Posts: 4

Hi Liam,
Here my code:

void UAServer_Callback_write( uint32_t handle,
UA_Value_type_t value_type,
uint32_t status_code,
uint32_t max_array_length,
uintptr_t write_context)
{
UA_Value_t data_value;
uint32_t new_array_length = 0;
int64_t* source_timestamp = 0;
uint32_t op_status_code = OpcUa_BadWriteNotSupported;

bool_t vBool = FALSE;
int vInt = 0;
float vFloat = 0;
uint32_t vUint = 0;
UA_Var_string_t vString;
vString.length = 0;
vString.data = NULL;
vString.max_length = 128;

data_value.value_Any = 0;

switch(value_type)
{
case UA_TYPE_Boolean: data_value.value_Boolean = & vBool; break;
case UA_TYPE_Float: data_value.value_Float = & vFloat; break;
case UA_TYPE_Int32: data_value.value_Int32 = & vInt; break;
case UA_TYPE_UInt32: data_value.value_UInt32 = & vUint; break;
case UA_TYPE_String: data_value.value_String = & vString; break;
default: data_value.value_Any = NULL; op_status_code = OpcUa_BadTypeMismatch;
}

if(data_value.value_Any != NULL)
{
source_timestamp = &my_variables[handle - 1].source_timestamp;
my_variables[handle - 1].status_code = status_code;
op_status_code = OpcUa_Good;
}


/* UAServer_Perform_write() must always be called */
UAServer_Perform_write(write_context, data_value, source_timestamp, FALSE, &new_array_length);

if(data_value.value_Any != NULL)
{

if(handle == HANDLE_STRING_TEST && value_type == UA_TYPE_String)
{
my_variables[handle - 1].source_timestamp = UAServer_Get_datetime();
int n = vString.length;
uint8_t* text;
text = vString.data;
UA_SERVER_PRINTF("\nreceived: %d - %d\n",n,strlen((char*)text));
//n shows the correct number of received bytes
//strlen(text) = 0 !? why?
}

}
UAServer_Set_write_operation_level_result_code(write_context, op_status_code);
}

Wilfried
Offline Wilfried Buck  
#4 Posted : Saturday, June 13, 2015 12:01:41 AM(UTC)
Wilfried Buck

Rank: Newbie

Joined: 6/8/2015(UTC)
Posts: 4

Hi Liam,

I found the answer! I have to do this:

uint8_t text[128];
UA_Var_string_t vString;
vString.length = 0;
vString.data = text;
vString.max_length = sizeof(text);

Best regards
Wilfried
Offline Basavaraju B V  
#5 Posted : Monday, June 15, 2015 8:14:28 PM(UTC)
Basavaraju B V

Rank: Advanced Member

Joined: 6/10/2015(UTC)
Posts: 34
Location: Bengaluru

Was thanked: 1 time(s) in 1 post(s)
Hi Wilfried,

Good to hear that problem is solved without the assistance.

Yes. For String type variables <stringVariable>.data should be pointing to the memory which is either allocated with some BUFFER_SIZE, or should be pointing to an array (just like it is done above). This will apply for ByteString and XMLElement variables as well.

Regards,
Basavaraju B V
Offline Wilfried Buck  
#6 Posted : Monday, June 22, 2015 12:07:34 AM(UTC)
Wilfried Buck

Rank: Newbie

Joined: 6/8/2015(UTC)
Posts: 4

Hi,

i hope, you will assist me in solving my next problem.
I want to read the status of a motor (leftrun, stopp, reightrun) from the client.
So i have to create a MultiStateDiscrete-DataItem for the address space. The documentation says, that the
type has to be a enumerated value. This is my problem: I do not know, how to create this type to run the
function UAServer_Create_MultiStateDiscrete without getting an error.

Best regards
Wilfried
Offline Basavaraju B V  
#7 Posted : Monday, June 22, 2015 4:20:57 AM(UTC)
Basavaraju B V

Rank: Advanced Member

Joined: 6/10/2015(UTC)
Posts: 34
Location: Bengaluru

Was thanked: 1 time(s) in 1 post(s)
Hi Wilfried,

Please find the example code below:

+ create a structure which will have value(which will hold the status) time and quality.
ex:
typedef struct
{
uint32_t value; // it could also be of type String. so that to display the text instead of integer value about the status
int64_t timestamp;
uint32_t status;
}struct_multi_state_descrete_info_t;


+ create a variable of that structure.
ex:
struct_multi_state_descrete_info_t multiState;


+ add node of type UA_MultiStateDiscrete_t in address space follow below code snippet.
ex:
UA_MultiStateDiscrete_t variable2;
UAServer_Init_config_structure_MultiStateDiscrete(&variable2);

multiState.value = 0; //Based on the type of value initialization varies!
multiState.status = OpcUa_Good;
multiState.timestamp = 0;

variable2.enum_handle = 1; // This is the position in 2D array ENUM_STRINGS
variable2.no_of_values = 3; // This is the number of states
variable2.data_item_config.data_variable_config.base_config.node_handle = HANDLE_MultiState;
variable2.data_item_config.data_variable_config.base_config.display_name_handle = HANDLE_MultiState;
variable2.data_item_config.data_variable_config.value_type = UA_TYPE_UInt32;
variable2.data_item_config.data_variable_config.user_write_permissions = 0x00;
variable2.data_item_config.use_definition = FALSE;
variable2.data_item_config.value_precision = FALSE;

status = UAServer_Create_MultiStateDiscrete(&variable2);
if (status != 0)
{
printf("UAServer_Create_MultiStateDiscrete returned: %d\n", (uint16_t)status);
return;
}
status = UAServer_Add_to_objects_folder(variable2.data_item_config.data_variable_config.base_config.node_handle);
if (status != 0)
{
printf("UAServer_Add_to_folder returned: %d\n", (uint16_t)status);
return;
}


Note:
HANDLE_MultiState is defined in the header file (with some integer number). It is similar to other node handles which you might already familiar with.
for enum_handle and no_of_values, please check the definition below

const uint8_t EN_DISPLAYNAME_rotateRight[] = "RIGHT_ROTATE";
const uint8_t EN_DISPLAYNAME_rotateLeft[] = "LEFT_ROTATE";
const uint8_t EN_DISPLAYNAME_stopped[] = "STOPPED";

const UA_UTF8_string_t ENUM_STRINGS[1][3] =
{
{
{ sizeof(EN_DISPLAYNAME_rotateRight) - 1, EN_DISPLAYNAME_rotateRight },
{ sizeof(EN_DISPLAYNAME_rotateLeft) - 1, EN_DISPLAYNAME_rotateLeft },
{ sizeof(EN_DISPLAYNAME_stopped) - 1, EN_DISPLAYNAME_stopped }

}

};


+ multiState.value has to be update at server side, based on the motor status. If motor is rotating right then multiState.value = 0 (if it is of type UInt32_t)

+ to read the node at client side, update the UAServer_Callback_read() function as below:
ex:
if((value_type == UA_TYPE_UInt32) && (handle == HANDLE_MultiState))
{
source_timestamp = my_variable.source_timestamp;

/* Set data quality */
status_code = my_variable.status_code;

data_value.value_UInt32 = &multiState.value;
}


+ in UAServer_Callback_translate_enumstrings() function return the enum value like below:
ex:
return &ENUM_STRINGS[enum_handle - 1][enum_index];


I hope this helps you to solve the problem that you are facing.

Please let me know if anything is not clear.

Thank you.
Regards,
Basavaraju B V
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Matrikon Subscribe  |   Matrikon Unsubscribe  |   Global Unsubscribe  |   Privacy Statement  |   Your Privacy Choices   |   Cookie Notice