diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..1174bc05 --- /dev/null +++ b/404.html @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + Ping Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 00000000..1cf13b9f Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.51d95adb.min.js b/assets/javascripts/bundle.51d95adb.min.js new file mode 100644 index 00000000..b20ec683 --- /dev/null +++ b/assets/javascripts/bundle.51d95adb.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Hi=Object.create;var xr=Object.defineProperty;var Pi=Object.getOwnPropertyDescriptor;var $i=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,Ii=Object.getPrototypeOf,Er=Object.prototype.hasOwnProperty,an=Object.prototype.propertyIsEnumerable;var on=(e,t,r)=>t in e?xr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))Er.call(t,r)&&on(e,r,t[r]);if(kt)for(var r of kt(t))an.call(t,r)&&on(e,r,t[r]);return e};var sn=(e,t)=>{var r={};for(var n in e)Er.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&an.call(e,n)&&(r[n]=e[n]);return r};var Ht=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Fi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $i(t))!Er.call(e,o)&&o!==r&&xr(e,o,{get:()=>t[o],enumerable:!(n=Pi(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Hi(Ii(e)):{},Fi(t||!e||!e.__esModule?xr(r,"default",{value:e,enumerable:!0}):r,e));var fn=Ht((wr,cn)=>{(function(e,t){typeof wr=="object"&&typeof cn!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(wr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(T){return!!(T&&T!==document&&T.nodeName!=="HTML"&&T.nodeName!=="BODY"&&"classList"in T&&"contains"in T.classList)}function f(T){var Ke=T.type,We=T.tagName;return!!(We==="INPUT"&&a[Ke]&&!T.readOnly||We==="TEXTAREA"&&!T.readOnly||T.isContentEditable)}function c(T){T.classList.contains("focus-visible")||(T.classList.add("focus-visible"),T.setAttribute("data-focus-visible-added",""))}function u(T){T.hasAttribute("data-focus-visible-added")&&(T.classList.remove("focus-visible"),T.removeAttribute("data-focus-visible-added"))}function p(T){T.metaKey||T.altKey||T.ctrlKey||(s(r.activeElement)&&c(r.activeElement),n=!0)}function m(T){n=!1}function d(T){s(T.target)&&(n||f(T.target))&&c(T.target)}function h(T){s(T.target)&&(T.target.classList.contains("focus-visible")||T.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(T.target))}function v(T){document.visibilityState==="hidden"&&(o&&(n=!0),B())}function B(){document.addEventListener("mousemove",z),document.addEventListener("mousedown",z),document.addEventListener("mouseup",z),document.addEventListener("pointermove",z),document.addEventListener("pointerdown",z),document.addEventListener("pointerup",z),document.addEventListener("touchmove",z),document.addEventListener("touchstart",z),document.addEventListener("touchend",z)}function re(){document.removeEventListener("mousemove",z),document.removeEventListener("mousedown",z),document.removeEventListener("mouseup",z),document.removeEventListener("pointermove",z),document.removeEventListener("pointerdown",z),document.removeEventListener("pointerup",z),document.removeEventListener("touchmove",z),document.removeEventListener("touchstart",z),document.removeEventListener("touchend",z)}function z(T){T.target.nodeName&&T.target.nodeName.toLowerCase()==="html"||(n=!1,re())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),B(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var un=Ht(Sr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},a=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(re,z){d.append(z,re)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(T){throw new Error("URL unable to set base "+c+" due to "+T)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,B=!0,re=this;["append","delete","set"].forEach(function(T){var Ke=h[T];h[T]=function(){Ke.apply(h,arguments),v&&(B=!1,re.search=h.toString(),B=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var z=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==z&&(z=this.search,B&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},a=i.prototype,s=function(f){Object.defineProperty(a,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){s(f)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr)});var Qr=Ht((Lt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Lt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Lt=="object"?Lt.ClipboardJS=r():t.ClipboardJS=r()})(Lt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return ki}});var a=i(279),s=i.n(a),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(O){return!1}}var d=function(O){var w=p()(O);return m("cut"),w},h=d;function v(j){var O=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[O?"right":"left"]="-9999px";var k=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(k,"px"),w.setAttribute("readonly",""),w.value=j,w}var B=function(O,w){var k=v(O);w.container.appendChild(k);var F=p()(k);return m("copy"),k.remove(),F},re=function(O){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},k="";return typeof O=="string"?k=B(O,w):O instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(O==null?void 0:O.type)?k=B(O.value,w):(k=p()(O),m("copy")),k},z=re;function T(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?T=function(w){return typeof w}:T=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},T(j)}var Ke=function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=O.action,k=w===void 0?"copy":w,F=O.container,q=O.target,Le=O.text;if(k!=="copy"&&k!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&T(q)==="object"&&q.nodeType===1){if(k==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(k==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Le)return z(Le,{container:F});if(q)return k==="cut"?h(q):z(q,{container:F})},We=Ke;function Ie(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ie=function(w){return typeof w}:Ie=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},Ie(j)}function Ti(j,O){if(!(j instanceof O))throw new TypeError("Cannot call a class as a function")}function nn(j,O){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof F.action=="function"?F.action:this.defaultAction,this.target=typeof F.target=="function"?F.target:this.defaultTarget,this.text=typeof F.text=="function"?F.text:this.defaultText,this.container=Ie(F.container)==="object"?F.container:document.body}},{key:"listenClick",value:function(F){var q=this;this.listener=c()(F,"click",function(Le){return q.onClick(Le)})}},{key:"onClick",value:function(F){var q=F.delegateTarget||F.currentTarget,Le=this.action(q)||"copy",Rt=We({action:Le,container:this.container,target:this.target(q),text:this.text(q)});this.emit(Rt?"success":"error",{action:Le,text:Rt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(F){return yr("action",F)}},{key:"defaultTarget",value:function(F){var q=yr("target",F);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(F){return yr("text",F)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(F){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return z(F,q)}},{key:"cut",value:function(F){return h(F)}},{key:"isSupported",value:function(){var F=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof F=="string"?[F]:F,Le=!!document.queryCommandSupported;return q.forEach(function(Rt){Le=Le&&!!document.queryCommandSupported(Rt)}),Le}}]),w}(s()),ki=Ri},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,f){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(f))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?s.apply(null,arguments):typeof m=="function"?s.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return s(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(m))return c(m,d,h);if(a.nodeList(m))return u(m,d,h);if(a.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return s(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),a=f.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var f=this;function c(){f.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=s.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var is=/["'&<>]/;Jo.exports=as;function as(e){var t=""+e,r=is.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],a;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(a)throw a.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||s(m,d)})})}function s(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof Xe?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){s("next",m)}function u(m){s("throw",m)}function p(m,d){m(d),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof xe=="function"?xe(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(a){return new Promise(function(s,f){a=e[i](a),o(s,f,a.done,a.value)})}}function o(i,a,s,f){Promise.resolve(f).then(function(c){i({value:c,done:s})},a)}}function A(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var $t=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function De(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Fe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=xe(a),f=s.next();!f.done;f=s.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var u=this.initialTeardown;if(A(u))try{u()}catch(v){i=v instanceof $t?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=xe(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{dn(h)}catch(v){i=i!=null?i:[],v instanceof $t?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new $t(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)dn(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&De(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&De(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Or=Fe.EMPTY;function It(e){return e instanceof Fe||e&&"closed"in e&&A(e.remove)&&A(e.add)&&A(e.unsubscribe)}function dn(e){A(e)?e():e.unsubscribe()}var Ae={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?Or:(this.currentObservers=null,s.push(r),new Fe(function(){n.currentObservers=null,De(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new U;return r.source=this,r},t.create=function(r,n){return new wn(r,n)},t}(U);var wn=function(e){ne(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Or},t}(E);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ne(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,f=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var a=r.actions;n!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Ut);var On=function(e){ne(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Wt);var we=new On(Tn);var R=new U(function(e){return e.complete()});function Dt(e){return e&&A(e.schedule)}function kr(e){return e[e.length-1]}function Qe(e){return A(kr(e))?e.pop():void 0}function Se(e){return Dt(kr(e))?e.pop():void 0}function Vt(e,t){return typeof kr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return A(e==null?void 0:e.then)}function Nt(e){return A(e[ft])}function qt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ki(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Qt=Ki();function Yt(e){return A(e==null?void 0:e[Qt])}function Gt(e){return ln(this,arguments,function(){var r,n,o,i;return Pt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,Xe(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,Xe(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,Xe(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Bt(e){return A(e==null?void 0:e.getReader)}function $(e){if(e instanceof U)return e;if(e!=null){if(Nt(e))return Qi(e);if(pt(e))return Yi(e);if(zt(e))return Gi(e);if(qt(e))return _n(e);if(Yt(e))return Bi(e);if(Bt(e))return Ji(e)}throw Kt(e)}function Qi(e){return new U(function(t){var r=e[ft]();if(A(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Yi(e){return new U(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?_(function(o,i){return e(o,i,n)}):me,Oe(1),r?He(t):zn(function(){return new Xt}))}}function Nn(){for(var e=[],t=0;t=2,!0))}function fe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,f=s===void 0?!0:s;return function(c){var u,p,m,d=0,h=!1,v=!1,B=function(){p==null||p.unsubscribe(),p=void 0},re=function(){B(),u=m=void 0,h=v=!1},z=function(){var T=u;re(),T==null||T.unsubscribe()};return g(function(T,Ke){d++,!v&&!h&&B();var We=m=m!=null?m:r();Ke.add(function(){d--,d===0&&!v&&!h&&(p=jr(z,f))}),We.subscribe(Ke),!u&&d>0&&(u=new et({next:function(Ie){return We.next(Ie)},error:function(Ie){v=!0,B(),p=jr(re,o,Ie),We.error(Ie)},complete:function(){h=!0,B(),p=jr(re,a),We.complete()}}),$(T).subscribe(u))})(c)}}function jr(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function V(e,t=document){let r=se(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function se(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),N(e===_e()),Y())}function Be(e){return{x:e.offsetLeft,y:e.offsetTop}}function Yn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,we),l(()=>Be(e)),N(Be(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,we),l(()=>rr(e)),N(rr(e)))}var Bn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!zr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),xa?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!zr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ya.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Jn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Zn=typeof WeakMap!="undefined"?new WeakMap:new Bn,eo=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Ea.getInstance(),n=new Ra(t,r,this);Zn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){eo.prototype[e]=function(){var t;return(t=Zn.get(this))[e].apply(t,arguments)}});var ka=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:eo}(),to=ka;var ro=new E,Ha=I(()=>H(new to(e=>{for(let t of e)ro.next(t)}))).pipe(x(e=>L(Te,H(e)).pipe(C(()=>e.disconnect()))),J(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){return Ha.pipe(S(t=>t.observe(e)),x(t=>ro.pipe(_(({target:r})=>r===e),C(()=>t.unobserve(e)),l(()=>de(e)))),N(de(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var no=new E,Pa=I(()=>H(new IntersectionObserver(e=>{for(let t of e)no.next(t)},{threshold:0}))).pipe(x(e=>L(Te,H(e)).pipe(C(()=>e.disconnect()))),J(1));function sr(e){return Pa.pipe(S(t=>t.observe(e)),x(t=>no.pipe(_(({target:r})=>r===e),C(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function oo(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=de(e),o=bt(e);return r>=o.height-n.height-t}),Y())}var cr={drawer:V("[data-md-toggle=drawer]"),search:V("[data-md-toggle=search]")};function io(e){return cr[e].checked}function qe(e,t){cr[e].checked!==t&&cr[e].click()}function je(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),N(t.checked))}function $a(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ia(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(N(!1))}function ao(){let e=b(window,"keydown").pipe(_(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:io("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),_(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!$a(n,r)}return!0}),fe());return Ia().pipe(x(t=>t?R:e))}function Me(){return new URL(location.href)}function ot(e){location.href=e.href}function so(){return new E}function co(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)co(e,r)}function M(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)co(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function fo(){return location.hash.substring(1)}function uo(e){let t=M("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Fa(){return b(window,"hashchange").pipe(l(fo),N(fo()),_(e=>e.length>0),J(1))}function po(){return Fa().pipe(l(e=>se(`[id="${e}"]`)),_(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(N(t.matches))}function lo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(N(e.matches))}function qr(e,t){return e.pipe(x(r=>r?t():R))}function ur(e,t={credentials:"same-origin"}){return ve(fetch(`${e}`,t)).pipe(ce(()=>R),x(r=>r.status!==200?Tt(()=>new Error(r.statusText)):H(r)))}function Ue(e,t){return ur(e,t).pipe(x(r=>r.json()),J(1))}function mo(e,t){let r=new DOMParser;return ur(e,t).pipe(x(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),J(1))}function pr(e){let t=M("script",{src:e});return I(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(x(()=>Tt(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),C(()=>document.head.removeChild(t)),Oe(1))))}function ho(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function bo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(ho),N(ho()))}function vo(){return{width:innerWidth,height:innerHeight}}function go(){return b(window,"resize",{passive:!0}).pipe(l(vo),N(vo()))}function yo(){return Q([bo(),go()]).pipe(l(([e,t])=>({offset:e,size:t})),J(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(X("size")),o=Q([n,r]).pipe(l(()=>Be(e)));return Q([r,t,o]).pipe(l(([{height:i},{offset:a,size:s},{x:f,y:c}])=>({offset:{x:a.x-f,y:a.y-c+i},size:s})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(a=>{let s=document.createElement("script");s.src=i,s.onload=a,document.body.appendChild(s)})),Promise.resolve())}var r=class{constructor(n){this.url=n,this.onerror=null,this.onmessage=null,this.onmessageerror=null,this.m=a=>{a.source===this.w&&(a.stopImmediatePropagation(),this.dispatchEvent(new MessageEvent("message",{data:a.data})),this.onmessage&&this.onmessage(a))},this.e=(a,s,f,c,u)=>{if(s===this.url.toString()){let p=new ErrorEvent("error",{message:a,filename:s,lineno:f,colno:c,error:u});this.dispatchEvent(p),this.onerror&&this.onerror(p)}};let o=new EventTarget;this.addEventListener=o.addEventListener.bind(o),this.removeEventListener=o.removeEventListener.bind(o),this.dispatchEvent=o.dispatchEvent.bind(o);let i=document.createElement("iframe");i.width=i.height=i.frameBorder="0",document.body.appendChild(this.iframe=i),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + +

The protocol

+

The protocol is designed for synchronous communications in a master->slave network. The slave will only send data when requested by the master. This allows the protocol to be used on a half-duplex bus like RS485. Some devices may also provide facilities to allow asynchronous communication.

+

Message Format

+

Each message consists of a header, optional payload, and checksum. The binary format is specified as follows:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ByteTypeNameDescription
0u8start1Start frame identifier, ASCII 'B'
1u8start2Start frame identifier, ASCII 'R'
2-3u16payload_lengthNumber of bytes in payload.
4-5u16message_idThe message id.
6u8src_device_idThe device ID of the device sending the message.
7u8dst_device_idThe device ID of the intended recipient of the message.
8-nu8[]payloadThe message payload.
(n+1)-(n+2)u16checksumThe message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message.
+

Scheme

+

Messages are divided into 4 categories:

+
    +
  • general: messages that are used for general purpose signalling and communication.
  • +
  • read/get: messages that are sent from the device in response to a general_request from the host. These messages are designed to read data from the device.
  • +
  • write/set: messages that are sent from the host to configure some parameters on the device. These messages are designed to write data to the device.
  • +
  • control: messages that are sent from the host to command the device to perform some action. These messages are designed to perform more complex device interactions than atomic read/write.
  • +
+

There are a some messages that are implemented by all devices, referred to as the 'common' message set. Message ids # 0~999 are reserved for the common messages. The request message is a special message in the common set that is used to request the device to respond with a message from the get category. Each device must also define it's own message set specific to the operation of the particular device.

+

Message Definitions

+ +

Device Discovery

+

If necessary, Ping Protocol enabled devices may be discovered and identified by the host as follows:

+
    +
  1. The host first requests the protocol version from the device
  2. +
  3. After receiving a protocol version reply, the host switches to the matching protocol version and requests the device type and firmware version
  4. +
  5. The host then loads the appropriate message set matching the device
  6. +
  7. Communication may then continue using the device-specific messages
  8. +
+

Negotiation example

+

Here we demonstrate a byte-by-byte breakdown of some messages sent between the host application (master) and the device (slave). This example illustrates a few points: + - how to pack and unpack some message data (the byte-order of a message) + - how the request/response mechanism of the protcol works with the general_request message + - how to identify the protocol version that the device is using

+

Establishing communication with a sensor using the ping-protocol should begin with negotiating the protocol version. This negotiation process consists of two steps: + - the host application requests a protocol_version message from the device + - the device responds with a protocol_version message

+
+

Before reading these examples, you should be familiar with the message format specification.

+
+

Request protocol version

+

In order to receive a protocol_version message from the device, we will first send a general_request message to the device to ask for the message. The general_request message has a single payload field, requested_id. We populate this field with a value of 5 to indicate that we want the sensor to respond with a protocol_version message:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ByteValue (hex)Value (decimal)TypeNameDescription
00x42 ('B')66u8start1This is a message start identifier, an ascii letter 'B'
10x52 ('R')82u8start2This is a message start identifier, an ascii letter 'R'
2-30x00022u16payload_lengthThe number of bytes in the general_request payload
4-50x00066u16message_idThis message is a general_request (id pingmessage-common#6) message
60x000u8src_device_idThe device ID of the device sending the message. This field is not currently implemented and should be populated with a value of zero
70x000u8dst_device_idThe device ID of the intended recipient of the message. This portion is not currently implemented and should be populated with a value of zero
8-90x00055u16requested_idThis is the message id that we would like the device to transmit to us. Valid ids are those in the get category of messages
10-110x00a1161u16checksumThe message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message: 66 + 82 + 2 + 6 + 0 + 0 + 5 = 161
+

The bytes should be transmitted in this order: +0x42, 0x52, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa1, 0x00

+
+

Note that the messages are transmitted in little-endian format (observe the byte-order of the 16 bit fields)

+
+

Receive protocol version

+

If everything is right, the sensor will respond to our request with a protocol_version message. The protocol_version message has 4 bytes in the payload: version_major, version_minor, version_patch, and reserved.

+

In this example, the device is using (a hypothetical) protocol version 1.2.3: + - version_major = 1 + - version_minor = 2 + - version_patch = 3

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ByteValue (hex)Value (decimal)TypeNameDescription
00x42 ('B')66u8start1This is a message start identifier, an ascii letter 'B'
10x52 ('R')82u8start2This is a message start identifier, an ascii letter 'R'
2-30x00044u16payload_lengthThe number of bytes in the protocol_version payload
4-50x00055u16message_idThis message is a protocol_version (id #5) message
60x000u8src_device_idThe device ID of the device sending the message. This field is not currently implemented and should be populated with a value of zero
70x000u8dst_device_idThe device ID of the intended recipient of the message. This field is not currently implemented and should be populated with a value of zero
80x011u8version_majorThis is the protocol major version, the first digit in our example: v1.2.3
90x022u8version_minorThis is the protocol minor version, the second digit in our example: v1.2.3
100x033u8version_patchThis is the protocol patch version, the third digit in our example: v1.2.3
110x000u8reservedThis byte is unused and will normally be zero (but it might be any value)
12-130x00a3163u16checksumThe message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message: 66 + 82 + 4 + 5 + 0 + 0 + 1 + 2 + 3 + 0 = 163
+

The bytes will be received in this order: +0x42, 0x52, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0xa3, 0x00

+
+

Note that the messages are transmitted in little-endian format (observe the byte-order of the 16 bit fields)

+
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/pingmessage-common/index.html b/pingmessage-common/index.html new file mode 100644 index 00000000..db5ad708 --- /dev/null +++ b/pingmessage-common/index.html @@ -0,0 +1,769 @@ + + + + + + + + + + + + + + + + + + + + + + common - Ping Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + +

Common messages

+

general

+

1 ack

+

Acknowledged.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16acked_idThe message ID that is ACKnowledged.
+

2 nack

+

Not acknowledged.

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16nacked_idThe message ID that is Not ACKnowledged.
char[]nack_messageASCII text message indicating NACK condition. (not necessarily NULL terminated) Length is derived from payload_length in the header.
+

3 ascii_text

+

A message for transmitting text data.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
char[]ascii_messageASCII text message. (not necessarily NULL terminated) Length is derived from payload_length in the header.
+

6 general_request

+

Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16requested_idMessage ID to be requested.
+

get

+

4 device_information

+

Device information

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8device_typeDevice type. 0: Unknown; 1: Ping Echosounder; 2: Ping360
u8device_revisiondevice-specific hardware revision
u8firmware_version_majorFirmware version major number.
u8firmware_version_minorFirmware version minor number.
u8firmware_version_patchFirmware version patch number.
u8reservedreserved
+

5 protocol_version

+

The protocol version

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8version_majorProtocol version major number.
u8version_minorProtocol version minor number.
u8version_patchProtocol version patch number.
u8reservedreserved
+

set

+

100 set_device_id

+

Set the device ID.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8device_idDevice ID (1-254). 0 is unknown and 255 is reserved for broadcast messages.
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/pingmessage-omniscan450/index.html b/pingmessage-omniscan450/index.html new file mode 100644 index 00000000..ebf9c1d5 --- /dev/null +++ b/pingmessage-omniscan450/index.html @@ -0,0 +1,620 @@ + + + + + + + + + + + + + + + + + + Omniscan450 messages - Ping Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + +

Omniscan450 messages

+

control

+

1002 set_speed_of_sound

+

Set the speed of sound.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32speed_of_soundThe speed of sound in the measurement medium. ~1,500,000 mm/s for water.mm/s
+

2197 os_ping_params

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32start_mm
u32length_mm
u32msec_per_ping
floatreserved
floatreserved
floatpulse_len_percent
floatfilter_duration_percent
i16gain_index
u16num_results
u8enable
u8reserved
+

get

+

2198 os_mono_profile

+

A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between and millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32ping_numbersequentially assigned from 0 at power up
u32start_mmThe beginning of the scan region in mm from the transducer.mm
u32length_mmThe length of the scan region.mm
u32timestamp_msmsec since power up at time of pingms
u32ping_hzFrequency of acoustic signalhz
u16gain_index0-7
u16num_resultslength of pwr_results array
u16sos_dmpsspeed of sound, decimeters/sec
u8channel_number
u8reserved
floatpulse_duration_sec
floatanalog_gain
floatmax_pwr_db
floatmin_pwr_db
floattransducer_heading_deg
floatvehicle_heading_deg
u16[]pwr_resultsAn array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db Length is derived from payload_length in the header.
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/pingmessage-ping1d/index.html b/pingmessage-ping1d/index.html new file mode 100644 index 00000000..c3a03138 --- /dev/null +++ b/pingmessage-ping1d/index.html @@ -0,0 +1,1494 @@ + + + + + + + + + + + + + + + + + + + + + + ping1d - Ping Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + +

Ping1d messages

+

set

+

1000 set_device_id

+

Set the device ID.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8device_idDevice ID (0-254). 255 is reserved for broadcast messages.
+

1001 set_range

+

Set the scan range for acoustic measurements.

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32scan_startmm
u32scan_lengthThe length of the scan range. Minimum 1000.mm
+

1002 set_speed_of_sound

+

Set the speed of sound used for distance calculations.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32speed_of_soundThe speed of sound in the measurement medium. ~1,500,000 mm/s for water.mm/s
+

1003 set_mode_auto

+

Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8mode_auto0: manual mode. 1: auto mode.
+

1004 set_ping_interval

+

The interval between acoustic measurements.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16ping_intervalThe interval between acoustic measurements.ms
+

1005 set_gain_setting

+

Set the current gain setting.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8gain_settingThe current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144
+

1006 set_ping_enable

+

Enable or disable acoustic measurements.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8ping_enabled0: Disable, 1: Enable.
+

get

+

1200 firmware_version

+

Device information

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8device_typeDevice type. 0: Unknown; 1: Echosounder
u8device_modelDevice model. 0: Unknown; 1: Ping1D
u16firmware_version_majorFirmware version major number.
u16firmware_version_minorFirmware version minor number.
+

1201 device_id

+

The device ID.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8device_idThe device ID (0-254). 255 is reserved for broadcast messages.
+

1202 voltage_5

+

The 5V rail voltage.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16voltage_5The 5V rail voltage.mV
+

1203 speed_of_sound

+

The speed of sound used for distance calculations.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32speed_of_soundThe speed of sound in the measurement medium. ~1,500,000 mm/s for water.mm/s
+

1204 range

+

The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length).

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32scan_startThe beginning of the scan range in mm from the transducer.mm
u32scan_lengthThe length of the scan range.mm
+

1205 mode_auto

+

The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8mode_auto0: manual mode, 1: auto mode
+

1206 ping_interval

+

The interval between acoustic measurements.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16ping_intervalThe minimum interval between acoustic measurements. The actual interval may be longer.ms
+

1207 gain_setting

+

The current gain setting.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32gain_settingThe current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144
+

1208 transmit_duration

+

The duration of the acoustic activation/transmission.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16transmit_durationAcoustic pulse duration.microseconds
+

1210 general_info

+

General information.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16firmware_version_majorFirmware major version.
u16firmware_version_minorFirmware minor version.
u16voltage_5Device supply voltage.mV
u16ping_intervalThe interval between acoustic measurements.ms
u8gain_settingThe current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144
u8mode_autoThe current operating mode of the device. 0: manual mode, 1: auto mode
+

1211 distance_simple

+

The distance to target with confidence estimate.

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32distanceDistance to the target.mm
u8confidenceConfidence in the distance measurement.%
+

1212 distance

+

The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32distanceThe current return distance determined for the most recent acoustic measurement.mm
u16confidenceConfidence in the most recent range measurement.%
u16transmit_durationThe acoustic pulse length during acoustic transmission/activation.us
u32ping_numberThe pulse/measurement count since boot.
u32scan_startThe beginning of the scan region in mm from the transducer.mm
u32scan_lengthThe length of the scan region.mm
u32gain_settingThe current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144
+

1213 processor_temperature

+

Temperature of the device cpu.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16processor_temperatureThe temperature in centi-degrees Centigrade (100 * degrees C).cC
+

1214 pcb_temperature

+

Temperature of the on-board thermistor.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16pcb_temperatureThe temperature in centi-degrees Centigrade (100 * degrees C).cC
+

1215 ping_enable

+

Acoustic output enabled state.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8ping_enabledThe state of the acoustic output. 0: disabled, 1:enabled
+

1300 profile

+

A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between and millimeters away from the transducer. A distance measurement to the target is also provided.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u32distanceThe current return distance determined for the most recent acoustic measurement.mm
u16confidenceConfidence in the most recent range measurement.%
u16transmit_durationThe acoustic pulse length during acoustic transmission/activation.us
u32ping_numberThe pulse/measurement count since boot.
u32scan_startThe beginning of the scan region in mm from the transducer.mm
u32scan_lengthThe length of the scan region.mm
u32gain_settingThe current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144
u16profile_data_lengthThe length of the proceeding vector field
u8[]profile_dataAn array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range.
+

control

+

1100 goto_bootloader

+

Send the device into the bootloader. This is useful for firmware updates.

+

No payload.

+

1400 continuous_start

+

Command to initiate continuous data stream of profile messages.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16idThe message id to stream. 1300: profile
+

1401 continuous_stop

+

Command to stop the continuous data stream of profile messages.

+ + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u16idThe message id to stop streaming. 1300: profile
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/pingmessage-ping360/index.html b/pingmessage-ping360/index.html new file mode 100644 index 00000000..ca6ec7c8 --- /dev/null +++ b/pingmessage-ping360/index.html @@ -0,0 +1,930 @@ + + + + + + + + + + + + + + + + + + + + ping360 - Ping Protocol + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + +

Ping360 messages

+

set

+

2000 set_device_id

+

Change the device id

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8idDevice ID (1-254). 0 and 255 are reserved.
u8reservedreserved
+

get

+

2300 device_data

+

This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8modeOperating mode (1 for Ping360)
u8gain_settingAnalog gain setting (0 = low, 1 = normal, 2 = high)
u16angleHead anglegradians
u16transmit_durationAcoustic transmission duration (1~1000 us)microseconds
u16sample_periodTime interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)eicosapenta-nanoseconds
u16transmit_frequencyAcoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver.kilohertz
u16number_of_samplesNumber of samples per reflected signal (supported values: 200~1200)samples
u16data_lengthThe length of the proceeding vector field
u8[]dataAn array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range.
+

2301 auto_device_data

+

NEW (v1.1.0) Extended version of device_data with auto_transmit information. The sensor emits this message when in auto_transmit mode.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8modeOperating mode (1 for Ping360)
u8gain_settingAnalog gain setting (0 = low, 1 = normal, 2 = high)
u16angleHead anglegradians
u16transmit_durationAcoustic transmission duration (1~1000 us)microseconds
u16sample_periodTime interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)eicosapenta-nanoseconds
u16transmit_frequencyAcoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver.kilohertz
u16start_angleHead angle to begin scan sector for autoscan (0~399 = 0~360 degrees).gradians
u16stop_angleHead angle to end scan sector for autoscan (0~399 = 0~360 degrees).gradians
u8num_stepsNumber of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)gradians
u8delayAn additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT.milliseconds
u16number_of_samplesNumber of samples per reflected signal (supported values: 200~1200)samples
u16data_lengthThe length of the proceeding vector field
u8[]dataAn array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range.
+

control

+

2600 reset

+

Reset the sonar. The bootloader may run depending on the selection according to the bootloader payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again.

+ + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8bootloader0 = skip bootloader; 1 = run bootloader
u8reservedreserved
+

2601 transducer

+

The transducer will apply the commanded settings. The sonar will reply with a device_data message. If the transmit field is 0, the sonar will not transmit after locating the transducer, and the data field in the device_data message reply will be empty. If the transmit field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the data field of the device_data message reply. To allow for the worst case response time the command timeout should be set to 4000 msec.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8modeOperating mode (1 for Ping360)
u8gain_settingAnalog gain setting (0 = low, 1 = normal, 2 = high)
u16angleHead anglegradians
u16transmit_durationAcoustic transmission duration (1~1000 us)microseconds
u16sample_periodTime interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)eicosapenta-nanoseconds
u16transmit_frequencyAcoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver.kilohertz
u16number_of_samplesNumber of samples per reflected signal (supported values: 200~1200)samples
u8transmit0 = do not transmit; 1 = transmit after the transducer has reached the specified angle
u8reservedreserved
+

2602 auto_transmit

+

NEW (v1.1.0) Extended transducer message with auto-scan function. The sonar will automatically scan the region between start_angle and end_angle and send auto_device_data messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a motor_off message may be sent (but retries might be necessary on the half-duplex RS485 interface).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescriptionUnits
u8modeOperating mode (1 for Ping360)
u8gain_settingAnalog gain setting (0 = low, 1 = normal, 2 = high)
u16transmit_durationAcoustic transmission duration (1~1000 us)microseconds
u16sample_periodTime interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)eicosapenta-nanoseconds
u16transmit_frequencyAcoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver.kilohertz
u16number_of_samplesNumber of samples per reflected signal (supported values: 200~1200)samples
u16start_angleHead angle to begin scan sector for autoscan (0~399 = 0~360 degrees).gradians
u16stop_angleHead angle to end scan sector for autoscan (0~399 = 0~360 degrees).gradians
u8num_stepsNumber of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)gradians
u8delayAn additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT.milliseconds
+

2903 motor_off

+

The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled.

+

No payload.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000..6cdd0c7c --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"The protocol","text":"

The protocol is designed for synchronous communications in a master->slave network. The slave will only send data when requested by the master. This allows the protocol to be used on a half-duplex bus like RS485. Some devices may also provide facilities to allow asynchronous communication.

"},{"location":"#message-format","title":"Message Format","text":"

Each message consists of a header, optional payload, and checksum. The binary format is specified as follows:

Byte Type Name Description 0 u8 start1 Start frame identifier, ASCII 'B' 1 u8 start2 Start frame identifier, ASCII 'R' 2-3 u16 payload_length Number of bytes in payload. 4-5 u16 message_id The message id. 6 u8 src_device_id The device ID of the device sending the message. 7 u8 dst_device_id The device ID of the intended recipient of the message. 8-n u8[] payload The message payload. (n+1)-(n+2) u16 checksum The message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message."},{"location":"#scheme","title":"Scheme","text":"

Messages are divided into 4 categories:

  • general: messages that are used for general purpose signalling and communication.
  • read/get: messages that are sent from the device in response to a general_request from the host. These messages are designed to read data from the device.
  • write/set: messages that are sent from the host to configure some parameters on the device. These messages are designed to write data to the device.
  • control: messages that are sent from the host to command the device to perform some action. These messages are designed to perform more complex device interactions than atomic read/write.

There are a some messages that are implemented by all devices, referred to as the 'common' message set. Message ids # 0~999 are reserved for the common messages. The request message is a special message in the common set that is used to request the device to respond with a message from the get category. Each device must also define it's own message set specific to the operation of the particular device.

"},{"location":"#message-definitions","title":"Message Definitions","text":"
  • common
  • ping1d
  • ping360
"},{"location":"#device-discovery","title":"Device Discovery","text":"

If necessary, Ping Protocol enabled devices may be discovered and identified by the host as follows:

  1. The host first requests the protocol version from the device
  2. After receiving a protocol version reply, the host switches to the matching protocol version and requests the device type and firmware version
  3. The host then loads the appropriate message set matching the device
  4. Communication may then continue using the device-specific messages
"},{"location":"#negotiation-example","title":"Negotiation example","text":"

Here we demonstrate a byte-by-byte breakdown of some messages sent between the host application (master) and the device (slave). This example illustrates a few points: - how to pack and unpack some message data (the byte-order of a message) - how the request/response mechanism of the protcol works with the general_request message - how to identify the protocol version that the device is using

Establishing communication with a sensor using the ping-protocol should begin with negotiating the protocol version. This negotiation process consists of two steps: - the host application requests a protocol_version message from the device - the device responds with a protocol_version message

Before reading these examples, you should be familiar with the message format specification.

"},{"location":"#request-protocol-version","title":"Request protocol version","text":"

In order to receive a protocol_version message from the device, we will first send a general_request message to the device to ask for the message. The general_request message has a single payload field, requested_id. We populate this field with a value of 5 to indicate that we want the sensor to respond with a protocol_version message:

Byte Value (hex) Value (decimal) Type Name Description 0 0x42 ('B') 66 u8 start1 This is a message start identifier, an ascii letter 'B' 1 0x52 ('R') 82 u8 start2 This is a message start identifier, an ascii letter 'R' 2-3 0x0002 2 u16 payload_length The number of bytes in the general_request payload 4-5 0x0006 6 u16 message_id This message is a general_request (id pingmessage-common#6) message 6 0x00 0 u8 src_device_id The device ID of the device sending the message. This field is not currently implemented and should be populated with a value of zero 7 0x00 0 u8 dst_device_id The device ID of the intended recipient of the message. This portion is not currently implemented and should be populated with a value of zero 8-9 0x0005 5 u16 requested_id This is the message id that we would like the device to transmit to us. Valid ids are those in the get category of messages 10-11 0x00a1 161 u16 checksum The message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message: 66 + 82 + 2 + 6 + 0 + 0 + 5 = 161

The bytes should be transmitted in this order: 0x42, 0x52, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa1, 0x00

Note that the messages are transmitted in little-endian format (observe the byte-order of the 16 bit fields)

"},{"location":"#receive-protocol-version","title":"Receive protocol version","text":"

If everything is right, the sensor will respond to our request with a protocol_version message. The protocol_version message has 4 bytes in the payload: version_major, version_minor, version_patch, and reserved.

In this example, the device is using (a hypothetical) protocol version 1.2.3: - version_major = 1 - version_minor = 2 - version_patch = 3

Byte Value (hex) Value (decimal) Type Name Description 0 0x42 ('B') 66 u8 start1 This is a message start identifier, an ascii letter 'B' 1 0x52 ('R') 82 u8 start2 This is a message start identifier, an ascii letter 'R' 2-3 0x0004 4 u16 payload_length The number of bytes in the protocol_version payload 4-5 0x0005 5 u16 message_id This message is a protocol_version (id #5) message 6 0x00 0 u8 src_device_id The device ID of the device sending the message. This field is not currently implemented and should be populated with a value of zero 7 0x00 0 u8 dst_device_id The device ID of the intended recipient of the message. This field is not currently implemented and should be populated with a value of zero 8 0x01 1 u8 version_major This is the protocol major version, the first digit in our example: v1.2.3 9 0x02 2 u8 version_minor This is the protocol minor version, the second digit in our example: v1.2.3 10 0x03 3 u8 version_patch This is the protocol patch version, the third digit in our example: v1.2.3 11 0x00 0 u8 reserved This byte is unused and will normally be zero (but it might be any value) 12-13 0x00a3 163 u16 checksum The message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message: 66 + 82 + 4 + 5 + 0 + 0 + 1 + 2 + 3 + 0 = 163

The bytes will be received in this order: 0x42, 0x52, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0xa3, 0x00

Note that the messages are transmitted in little-endian format (observe the byte-order of the 16 bit fields)

"},{"location":"pingmessage-common/","title":"Common messages","text":""},{"location":"pingmessage-common/#general","title":"general","text":""},{"location":"pingmessage-common/#1-ack","title":"1 ack","text":"

Acknowledged.

Type Name Description Units u16 acked_id The message ID that is ACKnowledged."},{"location":"pingmessage-common/#2-nack","title":"2 nack","text":"

Not acknowledged.

Type Name Description Units u16 nacked_id The message ID that is Not ACKnowledged. char[] nack_message ASCII text message indicating NACK condition. (not necessarily NULL terminated) Length is derived from payload_length in the header."},{"location":"pingmessage-common/#3-ascii_text","title":"3 ascii_text","text":"

A message for transmitting text data.

Type Name Description Units char[] ascii_message ASCII text message. (not necessarily NULL terminated) Length is derived from payload_length in the header."},{"location":"pingmessage-common/#6-general_request","title":"6 general_request","text":"

Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec.

Type Name Description Units u16 requested_id Message ID to be requested."},{"location":"pingmessage-common/#get","title":"get","text":""},{"location":"pingmessage-common/#4-device_information","title":"4 device_information","text":"

Device information

Type Name Description Units u8 device_type Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360 u8 device_revision device-specific hardware revision u8 firmware_version_major Firmware version major number. u8 firmware_version_minor Firmware version minor number. u8 firmware_version_patch Firmware version patch number. u8 reserved reserved"},{"location":"pingmessage-common/#5-protocol_version","title":"5 protocol_version","text":"

The protocol version

Type Name Description Units u8 version_major Protocol version major number. u8 version_minor Protocol version minor number. u8 version_patch Protocol version patch number. u8 reserved reserved"},{"location":"pingmessage-common/#set","title":"set","text":""},{"location":"pingmessage-common/#100-set_device_id","title":"100 set_device_id","text":"

Set the device ID.

Type Name Description Units u8 device_id Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."},{"location":"pingmessage-omniscan450/","title":"Omniscan450 messages","text":""},{"location":"pingmessage-omniscan450/#control","title":"control","text":""},{"location":"pingmessage-omniscan450/#1002-set_speed_of_sound","title":"1002 set_speed_of_sound","text":"

Set the speed of sound.

Type Name Description Units u32 speed_of_sound The speed of sound in the measurement medium. ~1,500,000 mm/s for water. mm/s"},{"location":"pingmessage-omniscan450/#2197-os_ping_params","title":"2197 os_ping_params","text":"Type Name Description Units u32 start_mm u32 length_mm u32 msec_per_ping float reserved float reserved float pulse_len_percent float filter_duration_percent i16 gain_index u16 num_results u8 enable u8 reserved"},{"location":"pingmessage-omniscan450/#get","title":"get","text":""},{"location":"pingmessage-omniscan450/#2198-os_mono_profile","title":"2198 os_mono_profile","text":"

A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between and millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels. Type Name Description Units u32 ping_number sequentially assigned from 0 at power up u32 start_mm The beginning of the scan region in mm from the transducer. mm u32 length_mm The length of the scan region. mm u32 timestamp_ms msec since power up at time of ping ms u32 ping_hz Frequency of acoustic signal hz u16 gain_index 0-7 u16 num_results length of pwr_results array u16 sos_dmps speed of sound, decimeters/sec u8 channel_number u8 reserved float pulse_duration_sec float analog_gain float max_pwr_db float min_pwr_db float transducer_heading_deg float vehicle_heading_deg u16[] pwr_results An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db Length is derived from payload_length in the header."},{"location":"pingmessage-ping1d/","title":"Ping1d messages","text":""},{"location":"pingmessage-ping1d/#set","title":"set","text":""},{"location":"pingmessage-ping1d/#1000-set_device_id","title":"1000 set_device_id","text":"

Set the device ID.

Type Name Description Units u8 device_id Device ID (0-254). 255 is reserved for broadcast messages."},{"location":"pingmessage-ping1d/#1001-set_range","title":"1001 set_range","text":"

Set the scan range for acoustic measurements.

Type Name Description Units u32 scan_start mm u32 scan_length The length of the scan range. Minimum 1000. mm"},{"location":"pingmessage-ping1d/#1002-set_speed_of_sound","title":"1002 set_speed_of_sound","text":"

Set the speed of sound used for distance calculations.

Type Name Description Units u32 speed_of_sound The speed of sound in the measurement medium. ~1,500,000 mm/s for water. mm/s"},{"location":"pingmessage-ping1d/#1003-set_mode_auto","title":"1003 set_mode_auto","text":"

Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range.

Type Name Description Units u8 mode_auto 0: manual mode. 1: auto mode."},{"location":"pingmessage-ping1d/#1004-set_ping_interval","title":"1004 set_ping_interval","text":"

The interval between acoustic measurements.

Type Name Description Units u16 ping_interval The interval between acoustic measurements. ms"},{"location":"pingmessage-ping1d/#1005-set_gain_setting","title":"1005 set_gain_setting","text":"

Set the current gain setting.

Type Name Description Units u8 gain_setting The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"},{"location":"pingmessage-ping1d/#1006-set_ping_enable","title":"1006 set_ping_enable","text":"

Enable or disable acoustic measurements.

Type Name Description Units u8 ping_enabled 0: Disable, 1: Enable."},{"location":"pingmessage-ping1d/#get","title":"get","text":""},{"location":"pingmessage-ping1d/#1200-firmware_version","title":"1200 firmware_version","text":"

Device information

Type Name Description Units u8 device_type Device type. 0: Unknown; 1: Echosounder u8 device_model Device model. 0: Unknown; 1: Ping1D u16 firmware_version_major Firmware version major number. u16 firmware_version_minor Firmware version minor number."},{"location":"pingmessage-ping1d/#1201-device_id","title":"1201 device_id","text":"

The device ID.

Type Name Description Units u8 device_id The device ID (0-254). 255 is reserved for broadcast messages."},{"location":"pingmessage-ping1d/#1202-voltage_5","title":"1202 voltage_5","text":"

The 5V rail voltage.

Type Name Description Units u16 voltage_5 The 5V rail voltage. mV"},{"location":"pingmessage-ping1d/#1203-speed_of_sound","title":"1203 speed_of_sound","text":"

The speed of sound used for distance calculations.

Type Name Description Units u32 speed_of_sound The speed of sound in the measurement medium. ~1,500,000 mm/s for water. mm/s"},{"location":"pingmessage-ping1d/#1204-range","title":"1204 range","text":"

The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length).

Type Name Description Units u32 scan_start The beginning of the scan range in mm from the transducer. mm u32 scan_length The length of the scan range. mm"},{"location":"pingmessage-ping1d/#1205-mode_auto","title":"1205 mode_auto","text":"

The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range.

Type Name Description Units u8 mode_auto 0: manual mode, 1: auto mode"},{"location":"pingmessage-ping1d/#1206-ping_interval","title":"1206 ping_interval","text":"

The interval between acoustic measurements.

Type Name Description Units u16 ping_interval The minimum interval between acoustic measurements. The actual interval may be longer. ms"},{"location":"pingmessage-ping1d/#1207-gain_setting","title":"1207 gain_setting","text":"

The current gain setting.

Type Name Description Units u32 gain_setting The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"},{"location":"pingmessage-ping1d/#1208-transmit_duration","title":"1208 transmit_duration","text":"

The duration of the acoustic activation/transmission.

Type Name Description Units u16 transmit_duration Acoustic pulse duration. microseconds"},{"location":"pingmessage-ping1d/#1210-general_info","title":"1210 general_info","text":"

General information.

Type Name Description Units u16 firmware_version_major Firmware major version. u16 firmware_version_minor Firmware minor version. u16 voltage_5 Device supply voltage. mV u16 ping_interval The interval between acoustic measurements. ms u8 gain_setting The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144 u8 mode_auto The current operating mode of the device. 0: manual mode, 1: auto mode"},{"location":"pingmessage-ping1d/#1211-distance_simple","title":"1211 distance_simple","text":"

The distance to target with confidence estimate.

Type Name Description Units u32 distance Distance to the target. mm u8 confidence Confidence in the distance measurement. %"},{"location":"pingmessage-ping1d/#1212-distance","title":"1212 distance","text":"

The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided.

Type Name Description Units u32 distance The current return distance determined for the most recent acoustic measurement. mm u16 confidence Confidence in the most recent range measurement. % u16 transmit_duration The acoustic pulse length during acoustic transmission/activation. us u32 ping_number The pulse/measurement count since boot. u32 scan_start The beginning of the scan region in mm from the transducer. mm u32 scan_length The length of the scan region. mm u32 gain_setting The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"},{"location":"pingmessage-ping1d/#1213-processor_temperature","title":"1213 processor_temperature","text":"

Temperature of the device cpu.

Type Name Description Units u16 processor_temperature The temperature in centi-degrees Centigrade (100 * degrees C). cC"},{"location":"pingmessage-ping1d/#1214-pcb_temperature","title":"1214 pcb_temperature","text":"

Temperature of the on-board thermistor.

Type Name Description Units u16 pcb_temperature The temperature in centi-degrees Centigrade (100 * degrees C). cC"},{"location":"pingmessage-ping1d/#1215-ping_enable","title":"1215 ping_enable","text":"

Acoustic output enabled state.

Type Name Description Units u8 ping_enabled The state of the acoustic output. 0: disabled, 1:enabled"},{"location":"pingmessage-ping1d/#1300-profile","title":"1300 profile","text":"

A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between and millimeters away from the transducer. A distance measurement to the target is also provided. Type Name Description Units u32 distance The current return distance determined for the most recent acoustic measurement. mm u16 confidence Confidence in the most recent range measurement. % u16 transmit_duration The acoustic pulse length during acoustic transmission/activation. us u32 ping_number The pulse/measurement count since boot. u32 scan_start The beginning of the scan region in mm from the transducer. mm u32 scan_length The length of the scan region. mm u32 gain_setting The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144 u16 profile_data_length The length of the proceeding vector field u8[] profile_data An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."},{"location":"pingmessage-ping1d/#control","title":"control","text":""},{"location":"pingmessage-ping1d/#1100-goto_bootloader","title":"1100 goto_bootloader","text":"

Send the device into the bootloader. This is useful for firmware updates.

No payload.

"},{"location":"pingmessage-ping1d/#1400-continuous_start","title":"1400 continuous_start","text":"

Command to initiate continuous data stream of profile messages.

Type Name Description Units u16 id The message id to stream. 1300: profile"},{"location":"pingmessage-ping1d/#1401-continuous_stop","title":"1401 continuous_stop","text":"

Command to stop the continuous data stream of profile messages.

Type Name Description Units u16 id The message id to stop streaming. 1300: profile"},{"location":"pingmessage-ping360/","title":"Ping360 messages","text":""},{"location":"pingmessage-ping360/#set","title":"set","text":""},{"location":"pingmessage-ping360/#2000-set_device_id","title":"2000 set_device_id","text":"

Change the device id

Type Name Description Units u8 id Device ID (1-254). 0 and 255 are reserved. u8 reserved reserved"},{"location":"pingmessage-ping360/#get","title":"get","text":""},{"location":"pingmessage-ping360/#2300-device_data","title":"2300 device_data","text":"

This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec.

Type Name Description Units u8 mode Operating mode (1 for Ping360) u8 gain_setting Analog gain setting (0 = low, 1 = normal, 2 = high) u16 angle Head angle gradians u16 transmit_duration Acoustic transmission duration (1~1000 us) microseconds u16 sample_period Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us) eicosapenta-nanoseconds u16 transmit_frequency Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver. kilohertz u16 number_of_samples Number of samples per reflected signal (supported values: 200~1200) samples u16 data_length The length of the proceeding vector field u8[] data An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."},{"location":"pingmessage-ping360/#2301-auto_device_data","title":"2301 auto_device_data","text":"

NEW (v1.1.0) Extended version of device_data with auto_transmit information. The sensor emits this message when in auto_transmit mode.

Type Name Description Units u8 mode Operating mode (1 for Ping360) u8 gain_setting Analog gain setting (0 = low, 1 = normal, 2 = high) u16 angle Head angle gradians u16 transmit_duration Acoustic transmission duration (1~1000 us) microseconds u16 sample_period Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us) eicosapenta-nanoseconds u16 transmit_frequency Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver. kilohertz u16 start_angle Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees). gradians u16 stop_angle Head angle to end scan sector for autoscan (0~399 = 0~360 degrees). gradians u8 num_steps Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees) gradians u8 delay An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT. milliseconds u16 number_of_samples Number of samples per reflected signal (supported values: 200~1200) samples u16 data_length The length of the proceeding vector field u8[] data An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."},{"location":"pingmessage-ping360/#control","title":"control","text":""},{"location":"pingmessage-ping360/#2600-reset","title":"2600 reset","text":"

Reset the sonar. The bootloader may run depending on the selection according to the bootloader payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again.

Type Name Description Units u8 bootloader 0 = skip bootloader; 1 = run bootloader u8 reserved reserved"},{"location":"pingmessage-ping360/#2601-transducer","title":"2601 transducer","text":"

The transducer will apply the commanded settings. The sonar will reply with a device_data message. If the transmit field is 0, the sonar will not transmit after locating the transducer, and the data field in the device_data message reply will be empty. If the transmit field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the data field of the device_data message reply. To allow for the worst case response time the command timeout should be set to 4000 msec.

Type Name Description Units u8 mode Operating mode (1 for Ping360) u8 gain_setting Analog gain setting (0 = low, 1 = normal, 2 = high) u16 angle Head angle gradians u16 transmit_duration Acoustic transmission duration (1~1000 us) microseconds u16 sample_period Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us) eicosapenta-nanoseconds u16 transmit_frequency Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver. kilohertz u16 number_of_samples Number of samples per reflected signal (supported values: 200~1200) samples u8 transmit 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle u8 reserved reserved"},{"location":"pingmessage-ping360/#2602-auto_transmit","title":"2602 auto_transmit","text":"

NEW (v1.1.0) Extended transducer message with auto-scan function. The sonar will automatically scan the region between start_angle and end_angle and send auto_device_data messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a motor_off message may be sent (but retries might be necessary on the half-duplex RS485 interface).

Type Name Description Units u8 mode Operating mode (1 for Ping360) u8 gain_setting Analog gain setting (0 = low, 1 = normal, 2 = high) u16 transmit_duration Acoustic transmission duration (1~1000 us) microseconds u16 sample_period Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us) eicosapenta-nanoseconds u16 transmit_frequency Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver. kilohertz u16 number_of_samples Number of samples per reflected signal (supported values: 200~1200) samples u16 start_angle Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees). gradians u16 stop_angle Head angle to end scan sector for autoscan (0~399 = 0~360 degrees). gradians u8 num_steps Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees) gradians u8 delay An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT. milliseconds"},{"location":"pingmessage-ping360/#2903-motor_off","title":"2903 motor_off","text":"

The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled.

No payload.

"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000..29cbd3e0 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,28 @@ + + + + None + 2024-05-22 + daily + + + None + 2024-05-22 + daily + + + None + 2024-05-22 + daily + + + None + 2024-05-22 + daily + + + None + 2024-05-22 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 00000000..ab2b1d8f Binary files /dev/null and b/sitemap.xml.gz differ