@@ -49,8 +49,22 @@ pwm_output_on_write_request_pwm_period(
4949 const UA_DataValue *data)
5050{
5151 PwmOutput * this_ptr = reinterpret_cast <PwmOutput *>(nodeContext);
52- uint32_t const pwm_period_ms = *(UA_UInt32 *)(data->value .data );
53- this_ptr->onWriteRequestPwmPeriod (server, nodeid, pwm_period_ms);
52+ uint32_t const pwm_period_us = *(UA_UInt32 *)(data->value .data );
53+ this_ptr->onWriteRequestPwmPeriod (server, nodeid, pwm_period_us);
54+ }
55+
56+ static void
57+ pwm_output_on_read_request_pwm_pulse_width (
58+ UA_Server *server,
59+ const UA_NodeId *sessionId,
60+ void *sessionContext,
61+ const UA_NodeId *nodeid,
62+ void *nodeContext,
63+ const UA_NumericRange *range,
64+ const UA_DataValue *data)
65+ {
66+ PwmOutput * this_ptr = reinterpret_cast <PwmOutput *>(nodeContext);
67+ this_ptr->onReadRequestPwmPulseWidth (server, nodeid);
5468}
5569
5670static void
@@ -64,8 +78,8 @@ pwm_output_on_write_request_pwm_pulse_width(
6478 const UA_DataValue *data)
6579{
6680 PwmOutput * this_ptr = reinterpret_cast <PwmOutput *>(nodeContext);
67- uint32_t const pwm_pulse_width_ms = *(UA_UInt32 *)(data->value .data );
68- this_ptr->onWriteRequestPwmPulseWidth (server, nodeid, pwm_pulse_width_ms );
81+ uint32_t const pwm_pulse_width_us = *(UA_UInt32 *)(data->value .data );
82+ this_ptr->onWriteRequestPwmPulseWidth (server, nodeid, pwm_pulse_width_us );
6983}
7084
7185/* *************************************************************************************
@@ -74,13 +88,17 @@ pwm_output_on_write_request_pwm_pulse_width(
7488
7589PwmOutput::PwmOutput (
7690 UA_NodeId const & pwm_period_node_id,
91+ UA_NodeId const & pwm_pulse_width_node_id,
7792 SetPwmFunc const set_pwm_func,
78- GetPwmPeriodFunc const get_pwm_period_func)
93+ GetPwmPeriodFunc const get_pwm_period_func,
94+ GetPwmPulseWidthFunc const get_pwm_pulse_width_func)
7995 : _pwm_period_node_id{pwm_period_node_id}
96+ , _pwm_pulse_width_node_id{pwm_pulse_width_node_id}
8097 , _set_pwm_func{set_pwm_func}
8198 , _get_pwm_period_func{get_pwm_period_func}
82- , _pwm_period_ms{0 }
83- , _pwm_pulse_width_ms{0 }
99+ , _get_pwm_pulse_width_func{get_pwm_pulse_width_func}
100+ , _pwm_period_us{0 }
101+ , _pwm_pulse_width_us{0 }
84102{
85103
86104}
@@ -95,7 +113,8 @@ PwmOutput::create(
95113 UA_NodeId const & parent_node_id,
96114 const char * display_name,
97115 SetPwmFunc const set_pwm_func,
98- GetPwmPeriodFunc const get_pwm_period_func)
116+ GetPwmPeriodFunc const get_pwm_period_func,
117+ GetPwmPulseWidthFunc const get_pwm_pulse_width_func)
99118{
100119 UA_StatusCode rc = UA_STATUSCODE_GOOD;
101120
@@ -123,7 +142,7 @@ PwmOutput::create(
123142 UA_Boolean pwm_output_period_value = get_pwm_period_func ();
124143 UA_Variant_setScalar (&pwm_out_period_value_attr.value , &pwm_output_period_value, &UA_TYPES[UA_TYPES_UINT32]);
125144
126- pwm_out_period_value_attr.displayName = UA_LOCALIZEDTEXT (" en-US" , " PWM Period / ms " );
145+ pwm_out_period_value_attr.displayName = UA_LOCALIZEDTEXT (" en-US" , " PWM Period / us " );
127146 pwm_out_period_value_attr.dataType = UA_TYPES[UA_TYPES_UINT32].typeId ;
128147 pwm_out_period_value_attr.accessLevel =
129148 UA_ACCESSLEVELMASK_READ |
@@ -135,7 +154,7 @@ PwmOutput::create(
135154 UA_NODEID_NULL,
136155 pwm_obj_node_id,
137156 UA_NODEID_NUMERIC (0 , UA_NS0ID_HASCOMPONENT),
138- UA_QUALIFIEDNAME (1 , " PWM Period / ms " ),
157+ UA_QUALIFIEDNAME (1 , " pwm_period_us " ),
139158 UA_NODEID_NUMERIC (0 , UA_NS0ID_BASEDATAVARIABLETYPE),
140159 pwm_out_period_value_attr,
141160 NULL ,
@@ -147,25 +166,72 @@ PwmOutput::create(
147166 return nullptr ;
148167 }
149168
150- /* Create an instance of AnalogOutput here. */
151- auto const instance_ptr = std::make_shared<PwmOutput>(pwm_period_node_id, set_pwm_func, get_pwm_period_func);
169+ UA_ValueCallback pwm_period_callback;
170+ pwm_period_callback.onRead = pwm_output_on_read_request_pwm_period;
171+ pwm_period_callback.onWrite = pwm_output_on_write_request_pwm_period;
172+ rc = UA_Server_setVariableNode_valueCallback (server, pwm_period_node_id, pwm_period_callback);
173+ if (UA_StatusCode_isBad (rc))
174+ {
175+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
176+ " %s: UA_Server_setVariableNode_valueCallback(pwm_period_node_id, ...) failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
177+ return nullptr ;
178+ }
179+
180+ UA_VariableAttributes pwm_out_pulse_width_value_attr = UA_VariableAttributes_default;
181+
182+ UA_Boolean pwm_output_pulse_width_value = get_pwm_pulse_width_func ();
183+ UA_Variant_setScalar (&pwm_out_pulse_width_value_attr.value , &pwm_output_pulse_width_value, &UA_TYPES[UA_TYPES_UINT32]);
184+
185+ pwm_out_pulse_width_value_attr.displayName = UA_LOCALIZEDTEXT (" en-US" , " PWM Pulse Width / us" );
186+ pwm_out_pulse_width_value_attr.dataType = UA_TYPES[UA_TYPES_UINT32].typeId ;
187+ pwm_out_pulse_width_value_attr.accessLevel =
188+ UA_ACCESSLEVELMASK_READ |
189+ UA_ACCESSLEVELMASK_WRITE | UA_ACCESSLEVELMASK_STATUSWRITE |
190+ UA_ACCESSLEVELMASK_TIMESTAMPWRITE; /* Status and timestamp write access necessary for opcua-client. */
191+
192+ UA_NodeId pwm_pulse_width_node_id;
193+ rc = UA_Server_addVariableNode (server,
194+ UA_NODEID_NULL,
195+ pwm_obj_node_id,
196+ UA_NODEID_NUMERIC (0 , UA_NS0ID_HASCOMPONENT),
197+ UA_QUALIFIEDNAME (1 , " pwm_pulse_width_us" ),
198+ UA_NODEID_NUMERIC (0 , UA_NS0ID_BASEDATAVARIABLETYPE),
199+ pwm_out_pulse_width_value_attr,
200+ NULL ,
201+ &pwm_pulse_width_node_id);
202+ if (UA_StatusCode_isBad (rc))
203+ {
204+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
205+ " %s: failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
206+ return nullptr ;
207+ }
208+
209+ UA_ValueCallback pwm_pulse_width_callback;
210+ pwm_pulse_width_callback.onRead = pwm_output_on_read_request_pwm_pulse_width;
211+ pwm_pulse_width_callback.onWrite = pwm_output_on_write_request_pwm_pulse_width;
212+ rc = UA_Server_setVariableNode_valueCallback (server, pwm_pulse_width_node_id, pwm_pulse_width_callback);
213+ if (UA_StatusCode_isBad (rc))
214+ {
215+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
216+ " %s: UA_Server_setVariableNode_valueCallback(pwm_pulse_width_node_id, ...) failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
217+ return nullptr ;
218+ }
219+
220+ auto const instance_ptr = std::make_shared<PwmOutput>(pwm_period_node_id, pwm_pulse_width_node_id, set_pwm_func, get_pwm_period_func, get_pwm_pulse_width_func);
152221
153222 rc = UA_Server_setNodeContext (server, pwm_period_node_id, reinterpret_cast <void *>(instance_ptr.get ()));
154223 if (UA_StatusCode_isBad (rc))
155224 {
156225 UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
157- " %s: UA_Server_setNodeContext(...) failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
226+ " %s: UA_Server_setNodeContext(pwm_period_node_id, ...) failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
158227 return nullptr ;
159228 }
160229
161- UA_ValueCallback pwm_period_callback;
162- pwm_period_callback.onRead = pwm_output_on_read_request_pwm_period;
163- pwm_period_callback.onWrite = pwm_output_on_write_request_pwm_period;
164- rc = UA_Server_setVariableNode_valueCallback (server, pwm_period_node_id, pwm_period_callback);
230+ rc = UA_Server_setNodeContext (server, pwm_pulse_width_node_id, reinterpret_cast <void *>(instance_ptr.get ()));
165231 if (UA_StatusCode_isBad (rc))
166232 {
167233 UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
168- " %s: UA_Server_setVariableNode_valueCallback(pwm_period_node_id , ...) failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
234+ " %s: UA_Server_setNodeContext(pwm_pulse_width_node_id , ...) failed with %s" , __PRETTY_FUNCTION__, UA_StatusCode_name (rc));
169235 return nullptr ;
170236 }
171237
@@ -186,29 +252,46 @@ PwmOutput::onReadRequestPwmPeriod(
186252 UA_Variant_setScalar (&in_x_val_opcua_variant, &in_x_val_opcua_value, &UA_TYPES[UA_TYPES_UINT32]);
187253 UA_Server_writeValue (server, *node_id, in_x_val_opcua_variant);
188254 /* Some debug output. */
189- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm period = %d ms " , __PRETTY_FUNCTION__, in_x_val);
255+ UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm period = %d us " , __PRETTY_FUNCTION__, in_x_val);
190256}
191257
192258void
193259PwmOutput::onWriteRequestPwmPeriod (
194260 UA_Server * server,
195261 UA_NodeId const * pwm_period_node_id,
196- uint32_t const pwm_period_ms)
262+ uint32_t const pwm_period_us)
263+ {
264+ _pwm_period_us = pwm_period_us;
265+ UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm period = %d us, pulse width = %d us" , __PRETTY_FUNCTION__, _pwm_period_us, _pwm_pulse_width_us);
266+ _set_pwm_func (_pwm_period_us, _pwm_pulse_width_us);
267+ }
268+
269+ void
270+ PwmOutput::onReadRequestPwmPulseWidth (
271+ UA_Server * server,
272+ UA_NodeId const * node_id)
197273{
198- _pwm_period_ms = pwm_period_ms;
199- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm period = %d ms, pulse width = %d ms" , __PRETTY_FUNCTION__, _pwm_period_ms, _pwm_pulse_width_ms);
200- _set_pwm_func (_pwm_period_ms, _pwm_pulse_width_ms);
274+ /* Obtain the value of the analog input pin. */
275+ uint32_t const in_x_val = _get_pwm_pulse_width_func ();
276+ /* Update the variable node. */
277+ UA_UInt32 in_x_val_opcua_value = in_x_val;
278+ UA_Variant in_x_val_opcua_variant;
279+ UA_Variant_init (&in_x_val_opcua_variant);
280+ UA_Variant_setScalar (&in_x_val_opcua_variant, &in_x_val_opcua_value, &UA_TYPES[UA_TYPES_UINT32]);
281+ UA_Server_writeValue (server, *node_id, in_x_val_opcua_variant);
282+ /* Some debug output. */
283+ UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm pulse width = %d us" , __PRETTY_FUNCTION__, in_x_val);
201284}
202285
203286void
204287PwmOutput::onWriteRequestPwmPulseWidth (
205288 UA_Server * server,
206289 UA_NodeId const * node_id,
207- uint32_t const pwm_pulse_width_ms )
290+ uint32_t const pwm_pulse_width_us )
208291{
209- _pwm_pulse_width_ms = pwm_pulse_width_ms ;
210- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm period = %d ms , pulse width = %d ms " , __PRETTY_FUNCTION__, _pwm_period_ms, _pwm_pulse_width_ms );
211- _set_pwm_func (_pwm_period_ms, _pwm_pulse_width_ms );
292+ _pwm_pulse_width_us = pwm_pulse_width_us ;
293+ UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_SERVER, " %s: pwm period = %d us , pulse width = %d us " , __PRETTY_FUNCTION__, _pwm_period_us, _pwm_pulse_width_us );
294+ _set_pwm_func (_pwm_period_us, _pwm_pulse_width_us );
212295}
213296
214297/* *************************************************************************************
0 commit comments