1"use strict";(self.webpackChunk_electricui_blog=self.webpackChunk_electricui_blog||[]).push([[1259],{11669:function(s,e){var l="angle-right",a=[8250],n="f105",t="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z";e.DF={prefix:"fas",iconName:l,icon:[320,512,a,n,t]},e.yO=e.DF},22553:function(s,e,l){l.r(e),l.d(e,{default:function(){return E}});var a=l(45392),n=l(2784);function t(s){const e=Object.assign({h2:"h2",p:"p",h3:"h3",code:"code",span:"span",em:"em",blockquote:"blockquote",strong:"strong",a:"a",ol:"ol",li:"li",ul:"ul"},(0,a.ah)(),s.components),{CodeBlock:l}=e;return l||function(s,e){throw new Error("Expected "+(e?"component":"object")+" `"+s+"` to be defined: you likely forgot to import, pass, or provide it.")}("CodeBlock",!0),n.createElement(n.Fragment,null,n.createElement(e.h2,null,"What are callbacks?"),"\n",n.createElement(e.p,null,"Electric UI uses a data-driven model where message payloads contain data representing something like a control input or sensor reading. The general model relies on a publish/sub
1scribe scheme where data is communicated asynchronously to code that consumes the variables."),"\n",n.createElement(e.p,null,"But for something event driven such as saving a series of values to persistent storage, triggering a move to a bookmarked position with a robot, or requesting a system reboot, its not ideal to poll a flag for a change, so we want the ability for Electric UI to call the relevant function directly."),"\n",n.createElement(e.h2,null,"How do I get a UI to call a function?"),"\n",n.createElement(e.h3,null,"Embedded Setup"),"\n",n.createElement(e.p,null,"We use a ",n.createElement(e.code,null,"TYPE_CALLBACK")," packet which contains a function pointer. In C, declare your function in your header ( or private functions in the same scope as eUI ) and then provide a tracked variable with a pointer to it."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #7A3E9D">void</span><span style="color: #333333"> </span><span style="color: #3161AA">motor_reset_callback</span><span style="color: #777777">();</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #A9A9A9">// in your .c file</span></div><div class=\'line\'><span style="color: #7A3E9D">eui_message_t</span><span style="color: #333333"> dev_msg_store</span><span style="color: #4B83CD">[]</span><span style="color: #333333"> </span><span style="color: #777777">=</span></div><div class=\'line\'><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">EUI_FUNC</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">"</span><span style="color: #886338">reset</span><span style="color: #777777">"</span><span style="color: #777777">,</span><span style="color: #333333"> motor_reset_callback </span><span style="color: #777777">),</span></div><div class=\'line\'><span style="color: #777777">};</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #7A3E9D">void</span><span style="color: #333333"> </span><span style="color: #3161AA">motor_reset_callback</span><span style="color: #777777">()</span></div><div class=\'line\'><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">//disable the motor</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">set_servo_enable</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #AB6526">false</span><span style="color: #333333"> </span><span style="color: #777777">);</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">//return to home position</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">request_servo_position</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #9E6D5A">0</span><span style="color: #333333"> </span><span style="color: #777777">);</span></div><div class=\'line\'><span style="color: #777777">}</span></div>'}})),"\n",n.createElement(e.p,null,"When inbound messages arrive for the ",n.createElement(e.code,null,"reset")," message, Electric UI will call your function."),"\n",n.createElement(e.p,null,"If you aren't using the variable helper macros while adding the structure to the tracked array, use ",n.createElement(e.code,null,"TYPE_CALLBACK"),", and the ",n.createElement(e.code,null,"ptr")," union's ",n.createElement(e.code,null,"callback")," member stores the pointer to your function. The size doesn't matter as ",n.createElement(e.em,null,"pointer data is never transmitted"),", but we use a size of ",n.createElement(e.code,null,"1"),"."),"\n",n.createElement(e.h3,null,"User Interface"),"\n",n.createElement(e.p,null,"We'll add a button to our UI which calls the callback once when pressed."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #4B83CD">
1import</span><span style="color: #333333"> </span><span style="color: #777777">{</span><span style="color: #333333"> </span><span style="color: #39927F"><data-lsp lsp=\'<div class='line'><span style="color: #333333">(</span><span style="color: #39927F">alias</span><span style="color: #333333">) </span><span style="color: #7A3E9D">function</span><span style="color: #333333"> </span><span style="color: #3161AA">Button</span><span style="color: #777777">(</span><span style="color: #39927F">props</span><span style="color: #777777">:</span><span style="color: #333333"> </span><span style="color: #248725">ElectricButtonProps</span><span style="color: #777777">):</span><span style="color: #333333"> </span><span style="color: #777777">import</span><span style="color: #333333">(</span><span style="color: #777777">"</span><span style="color: #886338">react/jsx-runtime</span><span style="color: #777777">"</span><span style="color: #333333">).</span><span style="color: #248725">JSX</span><span style="color: #777777">.</span><span style="color: #248725">Element</span></div><div class='line'><span style="color: #4B83CD">import</span><span style="color: #333333"> </span><span style="color: #39927F">Button</span></div>\' >Button</data-lsp></span><span style="color: #333333"> </span><span style="color: #777777">}</span><span style="color: #333333"> </span><span style="color: #4B83CD">from</span><span style="color: #333333"> </span><span style="color: #777777">'</span><span style="color: #886338">@electricui/components-desktop-blueprint</span><span style="color: #777777">'</span></div><div class=\'line\'> </div><div class=\'line\'><span style="color: #A9A9A9">// In the layout somewhere, make a button to invoke the callback on press</span></div><div class=\'line\'><span style="color: #777777"><</span><span style="color: #248725"><data-lsp lsp=\'<div class='line'><span style="color: #333333">(</span><span style="color: #39927F">alias</span><span style="color: #333333">) </span><span style="color: #7A3E9D">function</span><span style="color: #333333"> </span><span style="color: #3161AA">Button</span><span style="color: #777777">(</span><span style="color: #39927F">props</span><span style="color: #777777">:</span><span style="color: #333333"> </span><span style="color: #248725">ElectricButtonProps</span><span style="color: #777777">):</span><span style="color: #333333"> </span><span style="color: #777777">import</span><span style="color: #333333">(</span><span style="color: #777777">"</span><span style="color: #886338">react/jsx-runtime</span><span style="color: #777777">"</span><span style="color: #333333">).</span><span style="color: #248725">JSX</span><span style="color: #777777">.</span><span style="color: #248725">Element</span></div><div class='line'><span style="color: #4B83CD">import</span><span style="color: #333333"> </span><span style="color: #39927F">Button</span></div>\' >Button</data-lsp></span><span style="color: #1C1C1C"> </span><span style="color: #4481B7"><data-lsp lsp=\'<div class='line'><span style="color: #333333">(</span><span style="color: #39927F">property</span><span style="color: #333333">) </span><span style="color: #39927F">ElectricButtonProps</span><span style="color: #777777">.</span><span style="color: #39927F">callback</span><span style="color: #777777">?:</span><span style="color: #333333"> </span><span style="color: #39927F">string</span><span style="color: #333333"> </span><span style="color: #777777">|</span><span style="color: #333333"> </span><span style="color: #AB6526">undefined</span></div>\' >callback</data-lsp></span><span style="color: #777777">=</span><span style="color: #777777">"</span><span style="color: #886338">reset</span><span style="color: #777777">"</span><span style="color: #777777">></span><span style="color: #1C1C1C">Reset Motor Position</span><span style="color: #777777"></</span><span style="color: #248725"><data-lsp lsp=\'<div class='line'><span style="color: #333333">(</span><span style="color: #39927F">alias</span><span style="color: #333333">) </span><span style="color: #7A3E9D">function</span><span style="color: #333333"> </span><span style="color: #3161AA">Button</span><span style="color: #777777">(</span><span style="color: #39927F">props</span><span style="color: #777777">:</span><span style="color: #333333"> </span><span style="color: #248725">ElectricButtonProps</span><span style="color: #777777">):</span><span style="color: #333333"> </span><span style="color: #777777">import</span><span style="color: #333333">(</span><span style="color: #777777">"</span><span style="color: #886338">react/jsx-runtime</span><span style="color: #777777">"</span><span style="color: #333333">).</span><span style="color: #248725">JSX</span><span style="color: #777777">.</span><span style="color: #248725">Element</span></div><div class='line'><span style="color: #4B83CD">import</span><span style="color: #333333"> </span><span style="color: #39927F">Button</span></div>\' >Button</data-lsp></span><span style="color: #777777">></span></div>'}})),"\n",n.createElement(e.h2,null,"Callbacks when any variable is called?"),"\n",n.createElement(e.p,null,"This is done a little indirectly. ",n.createElement(e.code,null,"electricui-embedded")," supports a configurable callback which fires every time a message comes in. Inside this callback, its possible to write logic which calls functions after Electric UI has finished processing the inbound packet."),"\n",n.createElement(e.p,null,"This can be useful if you want to execute logic on the microcontroller after variables are set. This might be used if you have some digitally addressed LEDs and want to immediately handle the data, or the UI just sent some changes to a sensor configuration which need to be written to hardware registers."),"\n",n.createElement(e.blockquote,null,"\n",n.createElement(e.p,null,"We generally caution the ",n.createElement(e.strong,null,"over-use")," of UI callbacks, as in-experienced users may tie embedded logic to the UI operation."),"\n",n.createElement(e.p,null,"Strong coupling to user interface behaviour is a ",n.createElement(e.a,{href:"https://en.wikipedia.org/wiki/Design_smell",target:"_blank",rel:"noopener noreferrer"},"(architectural) design smell"),", as your embedded device might not always have a UI connected, and the interface could change behaviour later down the track."),"\n"),"\n",n.createElement(e.h3,null,"Interface callback setup"),"\n",n.createElement(e.p,null,"Lets start by making a new function which will become our callback."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #7A3E9D">void</span><span style="color: #333333"> </span><span style="color: #3161AA">eui_serial_callback</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #7A3E9D">
1uint8_t</span><span style="color: #333333"> </span><span style="color: #39927F">message</span><span style="color: #333333"> </span><span style="color: #777777">)</span></div><div class=\'line\'><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">switch</span><span style="color: #777777">(</span><span style="color: #333333">message</span><span style="color: #777777">)</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">case</span><span style="color: #333333"> EUI_CB_TRACKED</span><span style="color: #777777">:</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// UI recieved a tracked message ID and has completed processing</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">break</span><span style="color: #777777">;</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">case</span><span style="color: #333333"> EUI_CB_UNTRACKED</span><span style="color: #777777">:</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// UI passed in an untracked message ID</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">break</span><span style="color: #777777">;</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">case</span><span style="color: #333333"> EUI_CB_PARSE_FAIL</span><span style="color: #777777">:</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// Inbound message parsing failed, this callback help while debugging</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">break</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">}</span></div><div class=\'line\'><span style="color: #777777">}</span></div>'}})),"\n",n.createElement(e.p,null,"This callback is provided to the library as part of the ",n.createElement(e.code,null,"eui_interface_t")," which holds the output function and parser state."),"\n",n.createElement(e.p,null,"This can be done where the data output function callback is configured."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #333333"> comm_interface.output_cb </span><span style="color: #777777">=</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">uart_write</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #333333"> comm_interface.interface_cb </span><span style="color: #777777">=</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">eui_serial_callback</span><span style="color: #777777">;</span></div>'}})),"\n",n.createElement(e.p,null,"If you have multiple interfaces, or streamlined for compile-time setup, there is an interface declaration macro ",n.createElement(e.code,null,"EUI_INTERFACE_CB")," which can be used."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #7A3E9D">eui_interface_t</span><span style="color: #333333"> comm_links</span><span style="color: #4B83CD">[]</span><span style="color: #333333"> </span><span style="color: #777777">=</span><span style="color: #333333"> </span><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">EUI_INTERFACE</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">uart_write </span><span style="color: #777777">),</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">EUI_INTERFACE</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">websockets_write </span><span style="color: #777777">),</span></div><div class=\'line\'><span style="color: #777777">};</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #A9A9A9">// becomes</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #7A3E9D">eui_interface_t</span><span style="color: #333333"> comm_links</span><span style="color: #4B83CD">[]</span><span style="color: #333333"> </span><span style="color: #777777">=</span><span style="color: #333333"> </span><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">EUI_INTERFACE_CB</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">uart_write</span><span style="color: #777777">,</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">eui_serial_callback </span><span style="color: #777777">),</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">EUI_INTERFACE_CB</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">websockets_write</span><span style="color: #777777">,</span><span style="color: #333333"> </span><span style="color: #777777">&</span><span style="color: #333333">eui_ws_callback </span><span style="color: #777777">),</span><span style="color: #333333"> </span><span style="color: #A9A9A9">// call the same callback</span></div><div class=\'line\'><span style="color: #777777">};</span></div>'}})),"\n",n.createElement(e.p,null,"In the case where multiple interfaces are used, you can put an interface callback on just one, use the same callback for many, or have unique callbacks per interface. Generally we prefer a unique callback per interface as it allows for custom behaviour with special transports."),"\n",n.createElement(e.p,null,"The general behaviour of the callback during execution is:"),"\n",n.createElement(e.ol,null,"\n",n.createElement(e.li,null,"Electric UI catches a valid inbound packet, and is ready to process the data.","\n",n.createElement(e.ul,null,"\n",n.createElement(e.li,null,"If the packet fails in the parser (CRC error, etc), the callback fires with the ",n.createElement(e.code,null,"EUI_CB_PARSE_FAIL")," flag."),"\n"),"\n"),"\n",n.createElement(e.li,null,"If its a tracked variable, any writes or function callbacks will occur, and ",n.createElement(e.code,null,"ack")," or ",n.createElement(e.code,null,"query")," responses are sent back.","\n",n.createElement(e.ul,null,"\n",n.createElement(e.li,null,"If its an untracked variable, nothing happens here."),"\n"),"\n"),"\n",n.createElement(e.li,null,"The interface callback is fired."),"\n",n.createElement(e.li,null,"The inbound packet buffers are erased, ready for the next packet."),"\n"),"\n",n.createElement(e.h3,null,"Interface callback usage"),"\n",n.createElement(e.p,null,"Now we have our interface callback firing, we'll explore how to call functions or manipulate data based on the inbound packet."),"\n",n.createElement(e.p,null,"We'll consider what happens when we get the callback with ",n.createElement(e.code,null,"EUI_CB_TRACKED")," flag. In this case, lets pretend we are receiving a packet with an identifier of ",n.createElement(e.code,null,"rgb"),", holding the red, green and blue colour values for a multi-coloured LED."),"\n",n.createElement(e.p,null,"In this situation, Electric UI has already copied the inbound data to the tracked variable, but we want to call the LED library with a ",n.createElement(e.code,null,"update_leds()")," to actually send this new value to the hardware."),"\n",n.createElement(e.p,null,"First, lets see how this is written, then we'll breakdown what's happening and what other data can be accessed."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #7A3E9D">void</span><span style="color: #333333"> </span><span style="color: #3161AA">eui_serial_callback</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #7A3E9D">
1uint8_t</span><span style="color: #333333"> </span><span style="color: #39927F">message</span><span style="color: #333333"> </span><span style="color: #777777">)</span></div><div class=\'line\'><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">switch</span><span style="color: #777777">(</span><span style="color: #333333">message</span><span style="color: #777777">)</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">case</span><span style="color: #333333"> EUI_CB_TRACKED</span><span style="color: #777777">:</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// UI recieved a tracked message ID and has completed processing</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #7A3E9D">uint8_t</span><span style="color: #333333"> </span><span style="color: #777777">*</span><span style="color: #333333">msg_id </span><span style="color: #777777">=</span><span style="color: #333333"> </span><span style="color: #39927F">comm_interface</span><span style="color: #777777">.</span><span style="color: #39927F">packet</span><span style="color: #777777">.</span><span style="color: #39927F">id_in</span><span style="color: #777777">;</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// See if the inbound packet name matches our intended variable</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">if</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #3161AA">strcmp</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">(</span><span style="color: #7A3E9D">char</span><span style="color: #333333"> </span><span style="color: #777777">*)</span><span style="color: #333333">msg_id</span><span style="color: #777777">,</span><span style="color: #333333"> </span><span style="color: #777777">"</span><span style="color: #886338">rgb</span><span style="color: #777777">"</span><span style="color: #333333"> </span><span style="color: #777777">)</span><span style="color: #333333"> </span><span style="color: #777777">==</span><span style="color: #333333"> </span><span style="color: #9E6D5A">0</span><span style="color: #333333"> </span><span style="color: #777777">)</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// the packet was for the rgb tracked variable</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">update_leds</span><span style="color: #777777">();</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">}</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">}</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">break</span><span style="color: #777777">;</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">case</span><span style="color: #333333"> EUI_CB_UNTRACKED</span><span style="color: #777777">:</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// UI passed in an untracked message ID</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">break</span><span style="color: #777777">;</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">case</span><span style="color: #333333"> EUI_CB_PARSE_FAIL</span><span style="color: #777777">:</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// Inbound message parsing failed, this callback help while debugging</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #4B83CD">break</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #777777">}</span></div><div class=\'line\'><span style="color: #777777">}</span></div>'}})),"\n",n.createElement(e.ol,null,"\n",n.createElement(e.li,null,"In the callback, we use a switch on the ",n.createElement(e.code,null,"message")," flag, and when the tracked message flag is used we run our code."),"\n",n.createElement(e.li,null,"We create a pointer to the message identifier string in the packet which just came in, letting us check if the message identifier matches ",n.createElement(e.code,null,"rgb")," with ",n.createElement(e.a,{href:"https://www.tutorialspoint.com/c_standard_library/c_function_strcmp.htm",target:"_blank",rel:"noopener noreferrer"},"strcmp"),"."),"\n",n.createElement(e.li,null,"If the message matches, we call our ",n.createElement(e.code,null,"update_leds()")," function, which will update our LED with the data managed by our tracked variable."),"\n"),"\n",n.createElement(e.p,null,"The interesting line here is really the ",n.createElement(e.code,null,"uint8_t *msg_id = comm_interface.packet.id_in;"),", as we are reaching into the inbound packet's buffer and grabbing what we need."),"\n",n.createElement(e.p,null,"For situations where the message isn't tracked, grabbing data might also be useful, and this is also pretty easy, as the packet's header, and inbound buffer of data are also available."),"\n",n.createElement(l,null,n.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class=\'line\'><span style="color: #7A3E9D">eui_header_t</span><span style="color: #333333"> header </span><span style="color: #777777">=</span><span style="color: #333333"> comm_interface.packet.header</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #7A3E9D">
1uint8_t</span><span style="color: #333333"> </span><span style="color: #777777">*</span><span style="color: #333333">name_rx </span><span style="color: #777777">=</span><span style="color: #333333"> comm_interface.packet.id_in</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #7A3E9D">void</span><span style="color: #333333"> </span><span style="color: #777777">*</span><span style="color: #333333">data </span><span style="color: #777777">=</span><span style="color: #333333"> comm_interface.packet.data_in</span><span style="color: #777777">;</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #4B83CD">if</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #3161AA">strcmp</span><span style="color: #777777">(</span><span style="color: #333333"> </span><span style="color: #777777">(</span><span style="color: #7A3E9D">char</span><span style="color: #333333"> </span><span style="color: #777777">*)</span><span style="color: #39927F">msg_id</span><span style="color: #777777">,</span><span style="color: #333333"> </span><span style="color: #777777">"</span><span style="color: #886338">
1sensor_cal</span><span style="color: #777777">"</span><span style="color: #333333"> </span><span style="color: #777777">)</span><span style="color: #333333"> </span><span style="color: #777777">==</span><span style="color: #333333"> </span><span style="color: #9E6D5A">0</span><span style="color: #333333"> </span><span style="color: #777777">&&</span><span style="color: #333333"> header.type </span><span style="color: #777777">==</span><span style="color: #333333"> TYPE_UINT16 </span><span style="color: #777777">)</span></div><div class=\'line\'><span style="color: #777777">{</span></div><div class=\'line\'><span style="color: #777777"> </span><span style="color: #A9A9A9">// Got our calibratiion packet, with a uint16 payload</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #7A3E9D">uint16_t</span><span style="color: #333333"> calibration_value </span><span style="color: #777777">=</span><span style="color: #333333"> </span><span style="color: #777777">*(</span><span style="color: #7A3E9D">uint16_t</span><span style="color: #777777">*)</span><span style="color: #333333">data</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #333333"> </span><span style="color: #3161AA">do_something_fancy</span><span style="color: #777777">(</span><span style="color: #333333"> calibration_value </span><span style="color: #777777">);</span></div><div class=\'line\'><span style="color: #777777">}</span></div><div class=\'line\'></div><div class=\'line\'><span style="color: #A9A9A9">// Other data available in the header includes the</span></div><div class=\'line\'><span style="color: #7A3E9D">bool</span><span style="color: #333333"> packet_was_query </span><span style="color: #777777">=</span><span style="color: #333333"> header.response</span><span style="color: #777777">;</span></div><div class=\'line\'><span style="color: #7A3E9D">uint16_t</span><span style="color: #333333"> packet_size </span><span style="color: #777777">=</span><span style="color: #333333"> header.data_len</span><span style="color: #777777">;</span><span style="color: #333333"> </span><span style="color: #A9A9A9">// how large the header says the payload is</span></div><div class=\'line\'><span style="color: #7A3E9D">uint16_t</span><span style="color: #333333"> buffered_data_size </span><span style="color: #777777">=</span><span style="color: #333333"> comm_interface.data_bytes_in</span><span style="color: #777777">;</span><span style="color: #333333"> </span><span style="color: #A9A9A9">// buffered data - 1kB max</span></div>'}})),"\n",n.createElement(e.p,null,"Have a look at the ",n.createElement(e.a,{href:"/docs/hardware/api/"},n.createElement(e.code,null,"electricui-embedded")," API Reference")," for more details."))}var o=function(s){void 0===s&&(s={});const{wrapper:e}=Object.assign({},(0,a.ah)(),s.components);return e?n.createElement(e,s,n.createElement(t,s)):t(s)};l(63281);var c=l(95303),p=l(94229),r=l(10484),i=l(41170),y=(l(68270),l(9876)),d=l(59111),u=l(8711),m=l(6192),v=l(2598);function h(s){const{pageContext:e,data:l}=s;if(!l)return console.error(s,"no data"),null;const t=e,{data:{mdx:{tableOfContents:o}}}=s,h=o.items&&0!==o.items.length?n.createElement("div",null,n.createElement(d.Z,{items:o.items})):null;return n.createElement(i.Z,{location:s.location},n.createElement(r.A,{title:t.frontmatter.title+" - Electric UI",keywords:t.frontmatter.keywords,description:t.frontmatter.description,type:"guide"===t.frontmatter.category?"article":"website",image:t.image,imageHeight:t.imageHeight,imageWidth:t.imageWidth}),n.createElement(p.Z,{location:s.location,currentTitle:t.frontmatter.title,toc:h},t.breadcrumbs?n.createElement(v.O,{breadcrumbs:t.breadcrumbs}):null,n.createElement("h1",{id:(0,m.Z)(t.frontmatter.title)},t.frontmatter.title),n.createElement("main",{style:{display:"block",marginBottom:(0,c.qZ)(1),marginTop:(0,c.qZ)(1)}},n.createElement(y.Z.Provider,{value:e},n.createElement(a.Zo,{components:u.Z},s.children)))))}function E(s){return n.createElement(h,s,n.createElement(o,s))}},2598:function(s,e,l){l.d(e,{O:function(){return p}});var a=l(2784),n=l(68270),t=l(68251),o=l(11669),c=l(17370);function p(s){return a.createElement("div",{className:"breadcrumbs"},s.breadcrumbs.map(((e,l)=>l===s.breadcrumbs.length-1?a.createElement(a.Fragment,null):a.createElement(a.Fragment,null," ",a.createElement(n.rU,{to:e.slug},e.title)," ",a.createElement(c.G,{icon:o.yO,size:"xs"})))),s.breadcrumbs.length>=2?a.createElement(t.BreadcrumbJsonLd,{itemListElements:s.breadcrumbs.map(((s,e)=>({position:e+1,name:s.title,item:"https://electricui.com"+s.slug})))}):null)}},9876:function(s,e,l){const a=l(2784).createContext(null);e.Z=a},8711:function(s,e,l){l.d(e,{Z:function(){return o}});var a=l(90803),n=l(2784);function t(s){const e=(0,n.useRef)(null),l=(0,n.useRef)(null),a=(0,n.useRef)(null),t=(0,n.useCallback)((s=>{if(!e.current)return;if(!l.current)return;if(!a.current)return;const n=s.target;if("DATA-LSP"!==n.nodeName)return;const t=n.getAttribute("lsp");let o=n.getBoundingClientRect(),c=e.current.getBoundingClientRect(),p=o.left-c.left;l.current.style.display="block",l.current.style.top=o.top+20-c.top+"px",l.current.style.left=p+"px",l.current.style.maxWidth=Math.min(3*c.width/4,c.width-p-2)+"px",t&&(a.current.innerHTML=t)}),[]),o=(0,n.useCallback)((s=>{l.current&&(l.current.style.display="none")}),[]);return n.createElement("div",{className:"code-container"},n.createElement("div",{className:"eui-syntax-highlighting line-numbers"},n.createElement("pre",{className:"shiki twoslash"},n.createElement("code",{className:"code-container",onMouseOver:t,onMouseOut:o,ref:e},s.children)),n.createElement("div",{className:"shiki-twoslash-tooltip",ref:l},n.createElement("pre",{className:"shiki twoslash"},n.createElement("code",{ref:a})))))}var o={h1:s=>
1n.createElement(a.Z,Object.assign({is:"h1"},s)),h2:s=>n.createElement(a.Z,Object.assign({is:"h2"},s)),h3:s=>n.createElement(a.Z,Object.assign({is:"h3"},s)),h4:s=>n.createElement(a.Z,Object.assign({is:"h4"},s)),h5:s=>n.createElement(a.Z,Object.assign({is:"h5"},s)),h6:s=>n.createElement(a.Z,Object.assign({is:"h6"},s)),pre:s=>n.createElement(t,s),code:s=>n.createElement("code",s),table:s=>n.createElement("div",{className:"table-wrapper"},n.createElement("table",s)),CodeBlock:s=>n.createElement(t,s)}},6192:function(s,e){e.Z=function(s){return s.toString().toLowerCase().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\-\-+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}},45392:function(s,e,l){l.d(e,{Zo:function(){return c},ah:function(){return t}});var a=l(2784);const n=a.createContext({});function t(s){const e=a.useContext(n);return a.useMemo((()=>"function"==typeof s?s(e):{...e,...s}),[e,s])}const o={};function c({components:s,children:e,disableParentContext:l}){let c;return c=l?"function"==typeof s?s({}):s||o:t(s),a.createElement(n.Provider,{value:c},e)}}}]); 2//# sourceMappingURL=component---src-templates-template-docs-page-js-content-file-path-src-pages-docs-hardware-callbacks-index-md-b6fb84a6318039cc04ea.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.