<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
<channel><generator>http://textpattern.com/?v=4.0.8</generator>
<title>Reynoldson Control Inc.</title>
<link>http://www.reynoldsoncontrol.com/</link>

<description>AMX Programming for A/V</description>
<pubDate>Thu, 30 Jun 2011 18:16:58 GMT</pubDate>

<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ReynoldsonControlInc" /><feedburner:info uri="reynoldsoncontrolinc" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Netlinx Reboot Sequence</title>
<description>
<![CDATA[<p>Here is the reboot sequence for a netlinx system, from the perspective of code execution and domain.</p>]]>
</description>
<content:encoded><![CDATA[
<p>Here is the reboot sequence for a netlinx system, from the perspective of code execution and domain.</p>

	<h4><span class="caps">DEFINE</span>_START</h4>

	<p>Code execution within the <span class="caps">DEFINE</span>_START executes first with the main <span class="caps">AXS</span> program (followed by any <span class="caps">AXI</span> files included in order compiled).  Any modules will execute <span class="caps">DEFINE</span>_START after the main <span class="caps">AXS</span> program (and I assume in order defined by the <span class="caps">AXS</span>).</p>

	<h4><span class="caps">DATA</span>_EVENT (<span class="caps">ONLINE</span>)</h4>

	<p>Modules seem to generate <span class="caps">ONLINE</span> events first, followed by the main <span class="caps">AXS</span> program.</p>

	<p>We can use this to our advantage in that a module can define the default configuration settings.  Then the main <span class="caps">AXS</span> file can overwrite these settings with it&#8217;s own online event that follows.  Of course that means that some of the module initialization may be lost due to a mismatch in configurations (i.e. baud rate).  Therefore it&#8217;s a good idea to wait for a &#8216;<span class="caps">REINIT</span>&#8217; command following an <span class="caps">ONLINE</span> event.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=O0RRkvXPKZg:NDQHEvSfMRI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=O0RRkvXPKZg:NDQHEvSfMRI:6W8y8wAjSf4"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=6W8y8wAjSf4" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=O0RRkvXPKZg:NDQHEvSfMRI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ReynoldsonControlInc/~4/O0RRkvXPKZg" height="1" width="1"/>]]></content:encoded>
<link>http://feedproxy.google.com/~r/ReynoldsonControlInc/~3/O0RRkvXPKZg/netlinx-reboot-sequence</link>
<pubDate>Thu, 30 Jun 2011 18:16:58 GMT</pubDate>
<dc:creator>Chad Reynoldson</dc:creator>
<guid isPermaLink="false">tag:www.reynoldsoncontrol.com,2011-06-30:9baadc79886ae1d7d3b17284099f336f/5489ee2c703b0663b00f92cd2d516d9e</guid>
<feedburner:origLink>http://www.reynoldsoncontrol.com/blog/netlinx-reboot-sequence</feedburner:origLink></item>
<item><title>Inc and Dec Level</title>
<description>
<![CDATA[<p>Here&#8217;s a simple function for level ramping with bounds check:</p>]]>
</description>
<content:encoded><![CDATA[
<p>Here&#8217;s a simple function for level ramping with bounds check:</p>

<pre>//-----------------------------------------------------
// Relative level ramping with bounds check.
//-----------------------------------------------------
DEFINE_FUNCTION levelStep (SINTEGER snValue, SINTEGER snStep, SINTEGER snMin, SINTEGER snMax)
{
  snValue = snValue + snStep

  IF(snStep &gt; 0) {
    IF(snValue &gt; snMax)
      snValue = snMax
  }
  ELSE {
    IF(snValue &lt; snMin)
      snValue = snMin
  }
}
</pre>

	<p>
<br />

It&#8217;s also a good idea to have a function for discrete level setting:</p>

<pre>//-----------------------------------------------------
// Absolute level set.
//-----------------------------------------------------
DEFINE_FUNCTION levelSet (INTEGER nChn, SINTEGER snValue)
{
  uLvl[nChn].snValue = snValue

  SWITCH(nChn) {
    CASE LVL_PGM : SEND_STRING dvMXR,&quot;&#39;LVL_PGM-&#39;,ITOA(snValue)&quot;
    CASE LVL_MIC : SEND_STRING dvMXR,&quot;&#39;LVL_MIC-&#39;,ITOA(snValue)&quot;
  }
}
</pre>

	<p>
<br />

Then it&#8217;s easy to implement with button events:</p>

<pre>//-----------------------------------------------------
// Program volume (0-100).
//-----------------------------------------------------
BUTTON_EVENT[dvPNLs,24]     // Vol Up
BUTTON_EVENT[dvPNLs,25]     // Vol Down
BUTTON_EVENT[dvPNLs,26]     // Vol Mute
{
  PUSH :
  {
    SWITCH(BUTTON.INPUT.CHANNEL) {
      CASE 24  : {
        TO[BUTTON.INPUT]

        levelStep (uLvl[LVL_PGM].snValue, 1, 0, 100)
        levelSet  (LVL_PGM, uLvl[LVL_PGM].snValue)
      }
      CASE 25  : {
        TO[BUTTON.INPUT]

        levelStep (uLvl[LVL_PGM].snValue,-1, 0, 100)
        levelSet  (LVL_PGM, uLvl[LVL_PGM].snValue)
      }
      CASE 26  : {
      }
    }
  }
  HOLD[3,REPEAT] :
  {
    SWITCH(BUTTON.INPUT.CHANNEL) {
      CASE 24  : levelStep (uLvl[LVL_PGM].snValue, 5, 0, 100)
      CASE 25  : levelStep (uLvl[LVL_PGM].snValue,-5, 0, 100)
    }

    IF(BUTTON.INPUT.CHANNEL &lt;&gt; 26)
      levelSet  (LVL_PGM, uLvl[LVL_PGM].snValue)
  }
}
</pre>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=nTIa6yP7ap8:ckz3JbaD1j4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=nTIa6yP7ap8:ckz3JbaD1j4:6W8y8wAjSf4"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=6W8y8wAjSf4" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=nTIa6yP7ap8:ckz3JbaD1j4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ReynoldsonControlInc/~4/nTIa6yP7ap8" height="1" width="1"/>]]></content:encoded>
<link>http://feedproxy.google.com/~r/ReynoldsonControlInc/~3/nTIa6yP7ap8/inc-and-dec-level</link>
<pubDate>Mon, 23 May 2011 13:21:30 GMT</pubDate>
<dc:creator>Chad Reynoldson</dc:creator>
<guid isPermaLink="false">tag:www.reynoldsoncontrol.com,2011-05-23:9baadc79886ae1d7d3b17284099f336f/bd028177ce4fd52a08069031d837b487</guid>
<feedburner:origLink>http://www.reynoldsoncontrol.com/blog/inc-and-dec-level</feedburner:origLink></item>
<item><title>Multi-Edit Keyboards</title>
<description>
<![CDATA[<p><span class="caps">AMX</span> touch panel keyboards and keypads allow editing of a single item.  You can customize a <strong>system page template</strong> to allow editing of multiple items, such as a telephone speed-dial entry for a person&#8217;s name and number.  It works, but with some drawbacks.</p>]]>
</description>
<content:encoded><![CDATA[
<p><strong>Updated (with good news)</strong></p>

	<p>More investigating revealed that multi-edit keyboards with pre-loaded values are possible.  Here&#8217;s the text field properties to use:</p>

	<ul>
		<li>Assign the button a type of &#8220;Text Input&#8221;.  This allows it to be selected (focus) and have the text value editable.</li>
		<li>Assign the button a variable text value.  This is used for pre-loading the value from Netlinx code.</li>
		<li>Assign the &#8220;Name&#8221; property a value to be pre-pended when the edit is done, as in KB_NAME-.</li>
		<li>Parse strings back from the touch panel and look for KB_NAME- to get the values.  Be sure and look for an <span class="caps">ABORT</span> value, in case the person decides to cancel the edit.</li>
		<li>For some reason, this KB_NAME-<value> is not displayed using netlinx diagnostics.  Test code will reveal that it really does work though.</li>
	</ul>

	<p><strong>Original post on 09 April 2010</strong><br />
<hr /></p>

	<p><span class="caps">AMX</span> touch panel keyboards and keypads allow editing of a single item.  You can customize a <strong>system page template</strong> to allow editing of multiple items, such as a telephone speed-dial entry for a person&#8217;s name and number.  It works, but with some drawbacks.</p>

	<p><img src="http://www.reynoldsoncontrol.com/images/16.gif" width="692" height="480" alt="AMX Touch Panel Keyboard" title="A multiple editable field keyboard." /></p>

	<h4><span class="caps">GUI</span> Tweaks</h4>

	<p>First off, open up the system page template and copy the __keyboard popup into your touch panel file.  You will want to rename it (otherwise any @AKB or <span class="caps">AKEYB</span> command will use the new multiple edit keyboard).  I&#8217;ll rename the new popup to &#8216;kbSpdDialEditor&#8217;.</p>

	<p>Open up the new popup and select the prompt at the top.  We&#8217;ll need to change this to a static text label, say &#8216;Enter new name and number&#8217;.  Unfortunately, we won&#8217;t be able to use the @AKB command.</p>

	<p>Open up the new popup and select the text area button.  Resize it, allowing room for a label next to it, like &#8216;Name:&#8217;.   Reselect the text area again.  It will have a variable text assignment as setup:multi-line text area.</p>

	<p>With the button, we will assign the channel number for setup:text entry and modify the ON border color.  This will enable highlighting of the current item being edited.</p>

	<p>Next, we&#8217;ll modify the <span class="caps">OFF</span> text value to &#8216;KB_NAME&#8217;.  The touch panel will use this value as the header with the value once the user presses <span class="caps">DONE</span> (i.e. KB_NAME-Chad Reynoldson).</p>

	<p>Copy the label/button pair and paste it below.  Rename the label and the <span class="caps">OFF</span> text value to &#8216;KB_NUMBER&#8217;.</p>

	<h4>Implementation</h4>

	<p>You can use either a send command (i.e. @PPN) or a pageflip assignment from a touch panel button to bring up the new kbSpdDialEditor popup.  Each time the fields will be reset.</p>

	<p>When the user presses <span class="caps">DONE</span>, you&#8217;ll see a string event with &#8216;KB_NAME-value&#8217; and another with &#8216;KB_NUMBER-value&#8217;.</p>

	<h4><del>Drawbacks</del></h4>

	<p>It works well and moves this functionality into the touch panel file, which is where I prefer to off-load as much work as possible.  <del>Unfortunately it won&#8217;t allow us to pre-load the editable name and number with something we may have stored in netlinx code, something @AKB allows us to do.  This presents a huge problem for the end-user.</del></p>

	<p><del>We could overcome this with netlinx code, but that breaks the simplicity of off-loading the heavy lifting to the touch panel.</del></p>

	<p><del>So this seems like an exercise to prove that it works.  Unfortunately it has some drawbacks that takes us right back to where we started.</del></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=6q3Rl2LXaPE:R1MLVQS3XPY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=6q3Rl2LXaPE:R1MLVQS3XPY:6W8y8wAjSf4"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=6W8y8wAjSf4" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=6q3Rl2LXaPE:R1MLVQS3XPY:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ReynoldsonControlInc/~4/6q3Rl2LXaPE" height="1" width="1"/>]]></content:encoded>
<link>http://feedproxy.google.com/~r/ReynoldsonControlInc/~3/6q3Rl2LXaPE/multi-edit-keyboards</link>
<pubDate>Thu, 24 Mar 2011 11:44:05 GMT</pubDate>
<dc:creator>Chad Reynoldson</dc:creator>
<guid isPermaLink="false">tag:www.reynoldsoncontrol.com,2010-04-09:9baadc79886ae1d7d3b17284099f336f/7a97168cac683f31e46987753ee190eb</guid>
<feedburner:origLink>http://www.reynoldsoncontrol.com/blog/multi-edit-keyboards</feedburner:origLink></item>
<item><title>Blog Articles List</title>
<description>
<![CDATA[<p>Today I spent some time tweaking the website&#8217;s blog navigation when you select a category.  I never really liked the &#8220;excerpts&#8221; view and I am&#8230;</p>]]>
</description>
<content:encoded><![CDATA[
<p>Today I spent some time tweaking the website&#8217;s blog navigation when you select a category.  I never really liked the &#8220;excerpts&#8221; view and I am constantly searching for handy code snippets that I&#8217;ve blogged about in the past.  Now the category will list all articles in a table (without the excerpt) so it is easier to see things.  Hope you can find some use with my website.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=QR69IttQi9Q:qjlYrlHHVCI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=QR69IttQi9Q:qjlYrlHHVCI:6W8y8wAjSf4"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=6W8y8wAjSf4" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=QR69IttQi9Q:qjlYrlHHVCI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ReynoldsonControlInc/~4/QR69IttQi9Q" height="1" width="1"/>]]></content:encoded>
<link>http://feedproxy.google.com/~r/ReynoldsonControlInc/~3/QR69IttQi9Q/blog-articles-list</link>
<pubDate>Sat, 19 Feb 2011 20:38:45 GMT</pubDate>
<dc:creator>Chad Reynoldson</dc:creator>
<guid isPermaLink="false">tag:www.reynoldsoncontrol.com,2011-02-19:9baadc79886ae1d7d3b17284099f336f/53b49b4b846bfc55c3d2c1a58e4dd4f3</guid>
<feedburner:origLink>http://www.reynoldsoncontrol.com/blog/blog-articles-list</feedburner:origLink></item>
<item><title>Inc and Dec Time</title>
<description>
<![CDATA[<p>Here is an easy to implement <strong>NetLinx</strong> function that will increment and decrement a time variable by a +/- seconds offset.  It limits you to 24 hours and is pretty self-explanatory.</p>

	<p>Hope you can find value in it and remember how easy this is in <span class="caps">AMX</span>!</p>]]>
</description>
<content:encoded><![CDATA[
<p>Here is an easy to implement <strong>NetLinx</strong> function that will increment and decrement a time variable by a +/- seconds offset.  It limits you to 24 hours and is pretty self-explanatory.</p>

	<p>Hope you can find value in it and remember how easy this is in <span class="caps">AMX</span>!</p>

<pre>(*---------------------------------------------------------*)
(* Inc/dec cTime by x number of seconds.                 --*)
(*---------------------------------------------------------*)
DEFINE_FUNCTION SLONG getTimeOffset (CHAR cTime[8], SLONG slOffsetSec)
STACK_VAR
  SLONG slHr
  SLONG slMin
  SLONG slSec
  SLONG slTotalSec
  CHAR  cTimeOffset[8]
{
(*-- Offset range limited to 24 hours --*)
  IF((slOffsetSec &gt; 86400) || (slOffsetSec &lt; -86400))
    RETURN(-1)

(*-- Get seconds total --*)
  slHr  = MAX_VALUE(0, TIME_TO_HOUR  (cTime))
  slMin = MAX_VALUE(0, TIME_TO_MINUTE(cTime))
  slSec = MAX_VALUE(0, TIME_TO_SECOND(cTime))

  slTotalSec = (slHr * 3600) + (slMin * 60) + slSec

  slTotalSec = slTotalSec + slOffsetSec

(*-- Need the time --*)
  slHr  = (slTotalSec / 60) / 60
  slMin = (slTotalSec -  (slHr*60*60)) / 60
  slSec =  slTotalSec - ((slHr*60*60) + (slMin*60))

  cTimeOffset = &quot;RIGHT_STRING(&quot;&#39;00&#39;,ITOA(slHr )&quot;,2),&#39;:&#39;,
                 RIGHT_STRING(&quot;&#39;00&#39;,ITOA(slMin)&quot;,2),&#39;:&#39;,
                 RIGHT_STRING(&quot;&#39;00&#39;,ITOA(slSec)&quot;,2)&quot;

(*-- Only passback what they sent in (i.e. HH:MM:SS or HH:MM) --*)
  SET_LENGTH_STRING(cTimeOffset, LENGTH_STRING(cTime))

(*-- Passback --*)
  cTime = cTimeOffset
  RETURN(1)
}
</pre>

	<p>
<br />

Here&#8217;s a simple implementation of it:</p>

<pre>BUTTON_EVENT[dvPnls1a,1] // Up
BUTTON_EVENT[dvPnls1a,2] // Down
{
  PUSH :
  {
    SWITCH(BUTTON.INPUT.CHANNEL)
    {
      CASE 1 : getTimeOffset (cThisTime, 900)   // Inc by 15 minutes
      CASE 2 : getTimeOffset (cThisTime,-900)   // Dec by 15 minutes
    }

    SEND_COMMAND dvPnls1a,&quot;&#39;TEXT1-&#39;,cThisTime&quot;
  }
}
</pre>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=dxouPPpHujU:_ztBLYDq1GI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=dxouPPpHujU:_ztBLYDq1GI:6W8y8wAjSf4"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=6W8y8wAjSf4" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?a=dxouPPpHujU:_ztBLYDq1GI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/ReynoldsonControlInc?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ReynoldsonControlInc/~4/dxouPPpHujU" height="1" width="1"/>]]></content:encoded>
<link>http://feedproxy.google.com/~r/ReynoldsonControlInc/~3/dxouPPpHujU/inc-and-dec-time</link>
<pubDate>Mon, 16 Aug 2010 19:28:49 GMT</pubDate>
<dc:creator>Chad Reynoldson</dc:creator>
<guid isPermaLink="false">tag:www.reynoldsoncontrol.com,2010-08-16:9baadc79886ae1d7d3b17284099f336f/5c441507e1f27d64a4c9baa288f03675</guid>
<feedburner:origLink>http://www.reynoldsoncontrol.com/blog/inc-and-dec-time</feedburner:origLink></item></channel>
</rss>

