<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Notes from the Lab</title>
	<atom:link href="http://blog.notesfromthelab.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.notesfromthelab.com</link>
	<description>An embedded design discussion about human interface applications</description>
	<lastBuildDate>Fri, 04 Jun 2010 16:55:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Sample Rate Jittering</title>
		<link>http://blog.notesfromthelab.com/?p=318</link>
		<comments>http://blog.notesfromthelab.com/?p=318#comments</comments>
		<pubDate>Fri, 04 Jun 2010 16:49:04 +0000</pubDate>
		<dc:creator>Burke</dc:creator>
				<category><![CDATA[Capacitive Touch]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Input]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[Jitter]]></category>
		<category><![CDATA[Noise]]></category>
		<category><![CDATA[Sampling]]></category>
		<category><![CDATA[Sampling Rate]]></category>
		<category><![CDATA[Sensor]]></category>
		<category><![CDATA[Signal]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=318</guid>
		<description><![CDATA[When you are designing a system that has a sensor that must be sampled, eliminating noise from the readings should be one of your concerns. Averages and other low-pass filters do a good job at smoothing the signal which reduces the amount of white noise, but if the sample rate of your system is a [...]]]></description>
			<content:encoded><![CDATA[<p>When you are designing a system that has a sensor that must be sampled, eliminating noise from the readings should be one of your concerns. Averages and other low-pass filters do a good job at smoothing the signal which reduces the amount of white noise, but if the sample rate of your system is a harmonic of the noise’s frequency a different approach is needed.</p>
<p>First, we need to understand what is going on in the system that is causing us to change our sampling behavior. The picture below shows a normal sensor signal that has been injected with a single-frequency noise signal. The sampling rate occurs at a harmonic frequency to the noise and so the samples are not occurring at random locations on the noise &#8211; they are following a harmonic sine wave.</p>
<p><img class="aligncenter size-full wp-image-319" src="http://blog.notesfromthelab.com/wp-content/uploads/2010/06/jitter.PNG" alt="Sampling at a Harmonic of the Noise Frequency" width="452" height="190" /></p>
<p>If each sample is processed individually, the system will have to filter out the sine wave which could slow the response time. If multiple samples are added together or averaged, the resulting stream of samples will look like they have a large increase in the amount of white noise. This will have to be filtered out which will decrease the sensitivity of the sensor.</p>
<p>The solution to this problem is to slightly jitter the sampling rate of your system. Instead of sampling every X ms, sample every X+Y ms, where Y is a random value that is much smaller than X. For example, if your system is sampling once every 10 ms, then the sampling rate may be jittered by +/- 25 &micro;s. (TIP: To create a simple, pseudorandom number, you can take the least significant bits from the previous sample and add them to the sampling rate timer. It’s not perfectly random, but it should be random enough.)</p>
<p>The result of this technique will be that your system will sample with the behavior shown in the picture below. Notice how the samples are still following the sample rate, but now they are more randomly distributed throughout the injected noise signal. Now if the system processes one sample at a time, it will see a small amount of increase white noise which will be solved with a simple averaging filter. If the system takes several samples and combines them before processing them, the white noise should naturally eliminate itself and the samples will hover around the normal sensor signal.</p>
<p><img class="aligncenter size-full wp-image-320" src="http://blog.notesfromthelab.com/wp-content/uploads/2010/06/jitter2.PNG" alt="Jittering the Sample Rate" width="462" height="200" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=318</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Busy Indicator</title>
		<link>http://blog.notesfromthelab.com/?p=312</link>
		<comments>http://blog.notesfromthelab.com/?p=312#comments</comments>
		<pubDate>Wed, 14 Apr 2010 22:18:08 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=312</guid>
		<description><![CDATA[It is an interesting aspect of human nature that we can’t stand to be ignored, particularly by a machine.  I doubt we as a species are particularly sensitive to a snub by our own creations, rather I think we just don’t want to look stupid waiting on a machine that has gone off into the [...]]]></description>
			<content:encoded><![CDATA[<p>It is an interesting aspect of human nature that we can’t stand to be ignored, particularly by a machine.  I doubt we as a species are particularly sensitive to a snub by our own creations, rather I think we just don’t want to look stupid waiting on a machine that has gone off into the weeds.  For what ever reason, our response as designers has been to create a Busy Indicator.  Whether it is an animation of an hour class, a completion bar graphs, or just a blinking cursor, this indicator tells the user to ‘hold on I will be finished in just a moment.’</p>
<p>Of course it also serves the equally important function of telling the user when the system has ‘hung’ as well.  The challenge in simple user interfaces is how to implement the busy indicator using the limited bandwidth at hand.</p>
<p>One option for 7-segment displays is to blink the display, or pulse the intensity.  This is relatively easy to implement in a scanned system, just add in some non-driven scans into the display scanning routine.  Holding non-driven scans for 0.5 to 1 second will blank the display, non-driven scans every other scan will drop the intensity of the display in half.  Then it is just a matter of turning the blank scan function on/off at a 1-2 Hz rate, resulting in a variable intensity display or a flashing one.  Both are relatively simple in that it only requires a few lines of code, but they also effectively demonstrating that the system is still running.</p>
<p>Another option is to use an animation to demonstrate that the system is busy.  One that I implemented recently uses 7 segment displays to indicate that the finish order for cars in a PineWood Derby race.  While the cars are moving, and the display has nothing to display, the displays simulate the wheels on the car by spinning around 1 lit segment.  See below for a visual of the sequence.</p>
<p><a href="http://blog.notesfromthelab.com/wp-content/uploads/2010/04/4-14-2010-2-25-17-PM.png"><img class="aligncenter size-full wp-image-313" title="4-14-2010 2-25-17 PM" src="http://blog.notesfromthelab.com/wp-content/uploads/2010/04/4-14-2010-2-25-17-PM.png" alt="4-14-2010 2-25-17 PM" width="466" height="144" /></a></p>
<p>Another variation on the system uses the same single lit segment, but it drives the pattern in a figure 8.</p>
<p><a href="http://blog.notesfromthelab.com/wp-content/uploads/2010/04/4-14-2010-3-16-27-PM.png"><img class="aligncenter size-full wp-image-315" title="4-14-2010 3-16-27 PM" src="http://blog.notesfromthelab.com/wp-content/uploads/2010/04/4-14-2010-3-16-27-PM.png" alt="4-14-2010 3-16-27 PM" width="611" height="137" /></a></p>
<p>Both are relatively easy to implement, you just create a few extra segment combinations in your 7 segment decoder, and then cycle through the decoder at a 5-6 Hz rate.  In my implementation, I put a counter on the system that increments the display value very 10-15 scans.  The result was actually very easy on the eyes, and tied in well with the race theme of the system.  It also let the spectators know that ‘Yes, the system is running’, and yes it correctly detected the start of the race.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=312</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Non-Linear functions</title>
		<link>http://blog.notesfromthelab.com/?p=304</link>
		<comments>http://blog.notesfromthelab.com/?p=304#comments</comments>
		<pubDate>Wed, 20 Jan 2010 16:19:16 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=304</guid>
		<description><![CDATA[One of the great ironies of engineering is that we try to control a non-linear world with a linear circuitry.  Entire text books have been written just on the subject of linearization of sensors, and until recently, this linearization usually entailed complex op-amp circuits and tedious/expensive calibration techniques in manufacturing.
However, now that we are firmly [...]]]></description>
			<content:encoded><![CDATA[<p>One of the great ironies of engineering is that we try to control a non-linear world with a linear circuitry.  Entire text books have been written just on the subject of linearization of sensors, and until recently, this linearization usually entailed complex op-amp circuits and tedious/expensive calibration techniques in manufacturing.</p>
<p>However, now that we are firmly entrenched in the age of software; this traditionally hardware based problem has become a new headache for programmers.  So, how do we handle non-linearity in software?  Well, there are two common solutions; piecewise linear approximations, and curve fitting.</p>
<p>Piecewise linear approximati ons take the non-linear curve and break it into multiple segments that can be represented by a straight line.  For example, you can approximate a sine function with a set of equations like the following;</p>
<p><a href="http://blog.notesfromthelab.com/wp-content/uploads/2010/01/for-blog.png"><img class="aligncenter size-full wp-image-305" title="for-blog" src="http://blog.notesfromthelab.com/wp-content/uploads/2010/01/for-blog.png" alt="for-blog" width="272" height="83" /></a></p>
<p>Now the approximation is not very good, but it does fit the general outline of a sine wave.    In addition, their can be significant discontinuities where the segments meet, which is all dependant upon the number of segments, or pieces, and how closely the linear segments approximates the function over their range.</p>
<p>Curve fitting is the process of finding a equation that fits the non-linear function over a restricted range of values, for example, an approximation of the same sine wave, for the range 0-180 degrees, is the following function;</p>
<p>Y = -0.00808+(0.0217*X)-(0.000121*X<sup>2</sup>)</p>
<p>The new function is closer, but even with all the floating point math, it still has an error of 3-4% over the range of the function, and the more cyclic the function, the harder it will become to find one function that fits the entire range.</p>
<p>Usually, for periodic functions, the function is approximated over its period, or some segment of its period and the result is applied like the linear segments in piece wise linear approximations.  That is, for 0-180, the function is used as is; for 180-360, we subtract 180 from the input, and multiply the output by -1.</p>
<p>Regardless of the method used, it is important to determine the overall system error, over the range that the system will be used.  Spread sheets are particularly handy for this, just enter a column of reasonable data in the first column, copy your function into the second column, and calculate the error in the third column.  If the error is more than you can live with, then increase the number of pieces in the approximation, or increase the order of the curve fit. </p>
<table border="0" cellspacing="0" cellpadding="0" width="406">
<tbody>
<tr>
<td width="64" valign="bottom">
<p align="center">Input</p>
</td>
<td width="64" valign="bottom">
<p align="center">Ideal</p>
</td>
<td width="77" valign="bottom">
<p align="center">Curve Fit</p>
</td>
<td width="51" valign="bottom">
<p align="center">Error</p>
</td>
<td width="16" valign="bottom">
<p align="center"> </p>
</td>
<td width="70" valign="bottom">
<p align="center">PWL</p>
</td>
<td width="64" valign="bottom">
<p align="center">Error</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">0</p>
</td>
<td width="64" valign="bottom">
<p align="right">0.0000</p>
</td>
<td width="77" valign="bottom">
<p align="right">-0.00808</p>
</td>
<td width="51" valign="bottom">
<p align="right">1%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">0</p>
</td>
<td width="64" valign="bottom">
<p align="right">0%</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">30</p>
</td>
<td width="64" valign="bottom">
<p align="right">0.5000</p>
</td>
<td width="77" valign="bottom">
<p align="right">0.53402</p>
</td>
<td width="51" valign="bottom">
<p align="right">-3%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">0.333333</p>
</td>
<td width="64" valign="bottom">
<p align="right">17%</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">60</p>
</td>
<td width="64" valign="bottom">
<p align="right">0.8660</p>
</td>
<td width="77" valign="bottom">
<p align="right">0.85832</p>
</td>
<td width="51" valign="bottom">
<p align="right">1%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">0.666667</p>
</td>
<td width="64" valign="bottom">
<p align="right">20%</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">90</p>
</td>
<td width="64" valign="bottom">
<p align="right">1.0000</p>
</td>
<td width="77" valign="bottom">
<p align="right">0.96482</p>
</td>
<td width="51" valign="bottom">
<p align="right">4%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">1</p>
</td>
<td width="64" valign="bottom">
<p align="right">0%</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">120</p>
</td>
<td width="64" valign="bottom">
<p align="right">0.8660</p>
</td>
<td width="77" valign="bottom">
<p align="right">0.85352</p>
</td>
<td width="51" valign="bottom">
<p align="right">1%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">0.666667</p>
</td>
<td width="64" valign="bottom">
<p align="right">20%</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">150</p>
</td>
<td width="64" valign="bottom">
<p align="right">0.5000</p>
</td>
<td width="77" valign="bottom">
<p align="right">0.52442</p>
</td>
<td width="51" valign="bottom">
<p align="right">-2%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">0.333333</p>
</td>
<td width="64" valign="bottom">
<p align="right">17%</p>
</td>
</tr>
<tr>
<td width="64" valign="bottom">
<p align="right">180</p>
</td>
<td width="64" valign="bottom">
<p align="right">0.0000</p>
</td>
<td width="77" valign="bottom">
<p align="right">-0.02248</p>
</td>
<td width="51" valign="bottom">
<p align="right">2%</p>
</td>
<td width="16" valign="bottom"> </td>
<td width="70" valign="bottom">
<p align="right">0</p>
</td>
<td width="64" valign="bottom">
<p align="right">0%</p>
</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=304</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inductive Touch Demonstration</title>
		<link>http://blog.notesfromthelab.com/?p=302</link>
		<comments>http://blog.notesfromthelab.com/?p=302#comments</comments>
		<pubDate>Thu, 14 Jan 2010 17:00:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Inductive Touch]]></category>
		<category><![CDATA[Touch Sensing]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=302</guid>
		<description><![CDATA[Check out this new video!
Inductive Touch Demonstration
]]></description>
			<content:encoded><![CDATA[<p>Check out this new video!</p>
<p><a href="http://www.youtube.com/watch?v=02CM9os4r2c">Inductive Touch Demonstration</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=302</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>K.I.S.S.</title>
		<link>http://blog.notesfromthelab.com/?p=301</link>
		<comments>http://blog.notesfromthelab.com/?p=301#comments</comments>
		<pubDate>Tue, 01 Dec 2009 15:02:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=301</guid>
		<description><![CDATA[The other day I was playing with the idea of building an iambic keyer, using the new PIC16F1827 from Microchip.  My dad (W7GP) enjoys making code keys and I have a friend up in Colorado that still uses Morse on the air.  Besides, I had promised myself that I would relearn the code [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I was playing with the idea of building an iambic keyer, using the new PIC16F1827 from Microchip.  My dad (W7GP) enjoys making code keys and I have a friend up in Colorado that still uses Morse on the air.  Besides, I had promised myself that I would relearn the code and actually use it on the air (N7KGC).  In addition, the PIC16F1827 was a perfect choice for the project due to a wealth of CCPs and a new modulation peripheral.  </p>
<p>I was completely caught up in the wild enthusiasm of a new project; I had figured out the timing, allocated the necessary pins and resources for the tone generation, and was considering what kind of user interface when I hit a brick wall over the question of how to handle code speed, dit-to-dah weighting, and tone volume.  </p>
<p>All three functions had typically been handled by a potentiometers, they gave the user a simple interface that was intuitive and simple to handle while actually using the keyer.  In fact, all three functions were typically adjusted while generating dits and dahs until the rate, volume, and weighting “felt right.”</p>
<p>The problem was, in the back of my mind, I was stuck on the misconception that because the keyer was digital, the user interface also had to be digital.  And, try as I might, I couldn’t come up with a simple system that would work as well as the old fashioned pots.</p>
<p>A menu driven user interface with UP and DOWN buttons was going to be too slow, and would require the user to look at the display.  Touch button sliders would work, but if I accidentally touched one, I could mess up their settings and I would need some kind of Braille guide to keep my fingers aligned on the slider.  Encoders would also work, but the cost of both the encoders and the code space required to decode them would not be worth it.</p>
<p>It was about this time, that I suddenly saw the light, and promptly gave my self a swift kick in the cerebellum for being dense.  The answer was the KISS principal, Keep-It-Simple-Stupid.  The potentiometers had the right feel, they retained their setting when the power was removed, and they provided a simple visual feedback and they were simple to interface.  All I needed to do was digitize the wiper voltage with an ADC channel, and I would have my simple, cheep, and intuitive user interface to my digital keyer.  </p>
<p>So, I setup a Timer0 interrupt for 4.096mS, and dropped a simple statemachine into the ISR to periodically sample the three ADC inputs.  The results were stuffed into the appropriate variables, and whiz-bang, I had the perfect interface.  I could even adjust the offset and slope in code to provide convenient values.</p>
<p>No complex commands to decode, no expensive graphics LCD module to show a virtual knob, and I even saved pins.  Keeping It simple not only saved resources, it also saved about 20 pages worth of user’s manual explaining how to set the rate, weighting, and volume of the keyer.</p>
<p>Of course their was one annoying intermittent problem.  Every once in a while I would get a glitch on the pot I was adjusting.  I the value would momentarily jump by ¼ or ½ of full scale.  After several hours of hair pulling and 2 attempts to digitally filter the values, it finally dawned on me, I was using the values out of the variables at exactly the same time that the ISR was updating the values.  The result was a 01FF when the values rolled over from 0FF to 100, or a 000 output when I rolled over 100 to 0FF.  The solution was to simple; turn off the interrupts, copy the values into a separate set of variables, and then turn the interrupts back on.  Basically, I created the software equivalent of double buffering.</p>
<p>While the final result did take some extra storage space and required a small increase in code size, it was still far smaller than any of the other alternatives and a lot more convenient to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=301</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PC productivity tools for embedded programmers</title>
		<link>http://blog.notesfromthelab.com/?p=287</link>
		<comments>http://blog.notesfromthelab.com/?p=287#comments</comments>
		<pubDate>Sun, 22 Nov 2009 16:21:09 +0000</pubDate>
		<dc:creator>Rawin</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[PC]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[progammers]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=287</guid>
		<description><![CDATA[As embedded programmers, we all write firmware. Small projects are not so hard to manage. But as projects get bigger and with more than just one programmer involved, it&#8217;s time to look around for tools to help keep the team&#8217;s productivity high.
To write this blog, I simply dig into my computer and pick out the [...]]]></description>
			<content:encoded><![CDATA[<p>As embedded programmers, we all write firmware. Small projects are not so hard to manage. But as projects get bigger and with more than just one programmer involved, it&#8217;s time to look around for tools to help keep the team&#8217;s productivity high.</p>
<p>To write this blog, I simply dig into my computer and pick out the tools I use often. Here they are, in random order&#8230;</p>
<p>Comparing files, well, the worst way to do is to open up two source files and compare them by eyeballing. Comparing files is often needed when working with other people, you want to see what others have changed. Even by yourself, you may want to compare the file you are using today against the file from 5 days ago. Something was working, now it&#8217;s not, what&#8217;s changed? I personally use Beyond Compare from, <a href="http://www.scootersoftware.com">http://www.scootersoftware.com</a>. This is not free, but very affordable. It can compare files, folders, you name it. It shows result in a very intuitive manner, can&#8217;t live without it. Alternatively, you could use WinMerge, <a href="http://winmerge.org">http://winmerge.org</a>. WinMerge is free. Check them out.</p>
<p>Next is version control. At work, the team I&#8217;m with uses SVN, <a href="http://subversion.tigris.org">http://subversion.tigris.org</a>, and TortoiseSVN, <a href="http://tortoisesvn.tigris.org">http://tortoisesvn.tigris.org</a>. Both are free. First is the server side software, the heart and soul of the version control system.  Second is the client side GUI interface. Nothing too fancy, they just work. Also make sure to backup the SVN repository regularly. Other choices are also available, such as CVS, etc. You can also set TortoiseSVN to use any file comparison tools, in my case, I set it to use Beyond Compare.</p>
<p>Another neat tool we started to use recently is the UniversalIndentGUI, <a href="http://universalindent.sourceforge.net">http://universalindent.sourceforge.net</a>. This tool helps in formatting codes, by processing them per the formatting rules given. If you need to publish your code, whether publicly or just to your customers, this tool helps make everything looks consistent as though the codes were written by just one programmer. UniversalIndentGUI doesn&#8217;t solve all the consistency issues, like variable and function names. For that, your team need to have a coding style policy to follow in the first place. But for indentation, parenthesis, and other formatting related items, this tool takes the meaning of the word quality to another level.</p>
<p>Moving on to text editor. In all likelihood, your computer has the Notepad program that comes with Microsoft Windows, and you also have an IDE (Integrated Development Environment) installed. Your source code files are probably associated with the IDE. But there will be times when you just want to browse folders, and all you want to do is to quickly inspect a source file, both Notepad and IDE may not be a good solution. Notepad doesn&#8217;t highlight syntax, and IDE doesn&#8217;t load quickly. In this case, I use another text editor that can highlight syntax, better than Notepad, but also light-weight when compared to an IDE. The program I use is Notepad++, free and can be found at, <a href="http://notepad-plus.sourceforge.net">http://notepad-plus.sourceforge.net</a>. Many other options are also available, such as EditPlus, TextPad, etc.</p>
<p>Talking about editor, another good tool to have is a hex file viewer/editor. I use XVI32, <a href="http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm">http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm</a>. Not everything you work with is in a text readable form, so something like the XVI32 is a must have.</p>
<p>Another good tool is TreeSize Free, <a href="http://www.jam-software.com/freeware/index.shtml">http://www.jam-software.com/freeware/index.shtml</a>. This tool helps you analyze the disk size allocation of files and folders. I typically use this tool to scan code repository before each public code release. It helps me to understand the file organization from the size perspective. I also tend to use it to look out for any unexpected files that may get introduced to the SVN repository unintentionally. This is helpful when the code distribution is large, and you want to keep the installer package size within a reasonable level.</p>
<p>When it comes to documenting APIs, there was a time when we documented our function APIs by writing them out again manually in a separate document, be it a Microsoft Word or Acrobat PDF. This was an insane way of doing things. Mistakes can happen left and right. Synchronization between the actual code and help file was also very hard to keep up with. When an actual function API changed, we would have to remember to update the documentation too. Typographical errors were also very common, which made the document harder to understand for the end readers. The whole process of tracking and editing was also very time consuming. Fortunately, those were the old days. Now we use Doc-O-Matic, <a href="http://www.doc-o-matic.com">http://www.doc-o-matic.com</a>. The tool scans source codes for comments and function headers and use them to outputs documentation help file in various formats automatically. Doc-O-Matic is not free, but a great investment that helps save countless hours of manual work, which makes it a cheaper choice in the long run. A free alternative is Doxygen, <a href="http://www.stack.nl/~dimitri/doxygen">http://www.stack.nl/~dimitri/doxygen</a>. If you are not using a help authoring tool, you should start, today.</p>
<p>Lastly for packaging an installer, we use Nullsoft Scriptable Install System (NSIS), <a href="http://nsis.sourceforge.net">http://nsis.sourceforge.net</a>, which is free. For a programmer, learning how to use NSIS should be easy, as you will be writing a script. Many functions and templates are provided. We use the Modern UI template. You will see this template once you have installed NSIS. I&#8217;d highly recommend this template and I believe most NSIS users use this template also. To learn the in and out of the Modern UI template, start by reading here: <a href="http://nsis.sourceforge.net/Docs/Modern%20UI/Readme.html">http://nsis.sourceforge.net/Docs/Modern%20UI/Readme.html</a>.</p>
<p>The list above shows just some of the tools we have used within our work environment, some maybe applicable to you, some may not. At some points in the past, we never used to use them either, but we observed where we could improve our productivity and efficiency, and started introducing these tools into our work culture. You could do the same. If the tool doesn&#8217;t exist, consider in building one.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=287</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sensor Degradation</title>
		<link>http://blog.notesfromthelab.com/?p=286</link>
		<comments>http://blog.notesfromthelab.com/?p=286#comments</comments>
		<pubDate>Tue, 03 Nov 2009 22:52:59 +0000</pubDate>
		<dc:creator>Cassie</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Resistive Sensors]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=286</guid>
		<description><![CDATA[It&#8217;s a snowy night, and you&#8217;re about to use the ATM outside your local grocery store that&#8217;s been there for years.  You enter in your access code, and notice only 2 of the 4 entries are reflected on the display.  
You clear the entry, and strike each number on the monitor again.  [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a snowy night, and you&#8217;re about to use the ATM outside your local grocery store that&#8217;s been there for years.  You enter in your access code, and notice only 2 of the 4 entries are reflected on the display.  </p>
<p>You clear the entry, and strike each number on the monitor again.  Again the entry seems off.  </p>
<p>Now your card is eaten up in that darned machine.</p>
<p>The touch screen doesn&#8217;t work.</p>
<p>What is really happening is that the touch screen isn&#8217;t working as well as it used to.  Several factors can lead to sensor degradation.  This sensor degradation, when not accounted for, can push the operating specifications of your touch controller and sensor pair out of functioning range.</p>
<p>Resistive touch panels are made of two sheets of conductive material.  This conductive material needs to be uniformly coated on both sides.  When you press a resistive panel, one side smushes into the other side.  The bending of the flexible layer, referred to as the &#8220;flex&#8221; layer which is often made of polyester, into the glass or plastic layer, the &#8220;stable&#8221; layer, is what makes the resistive touch solution work and move your cursor.  The conductive coating afixed to the flex layer is bent and stretched when the polyester layer comes in contact with a user&#8217;s finger or stylus.  The metallic conductive coating does not have the same flexible properties as this polyester layer, and can stretch and crack with repeated use.</p>
<p>The humidity and the temperature of the environment also affects the wear and tear seen by the resistive panel.  The air trapped inside the resistive panel is maintained by adding a layer, often called spacer dots, between the flex and the stable.  Typically, this is maintained when the environment remains static.  When the temperature rises or falls dramatically, the air within the sensor will expand or contract, stretching the polyester layer again.  Thusly, the uniform coating becomes less uniform, and the sensor&#8217;s electrical properties are again compromised.  The resistance of the panel will increase as the coating cracks, and the capacitance between the two conductive layers will increase as the polyester relaxes.”</p>
<p>While there are coatings and heaters and special manufacturing precautions to add to the longevity of the sensor, the sensor will eventually succumb to wear and tear and stop functioning.  It&#8217;s up to the touch controller to be designed with a wide window of operation so that it will continue to function for as long as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=286</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parsing serial text based commands</title>
		<link>http://blog.notesfromthelab.com/?p=280</link>
		<comments>http://blog.notesfromthelab.com/?p=280#comments</comments>
		<pubDate>Tue, 27 Oct 2009 15:03:18 +0000</pubDate>
		<dc:creator>Carol</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[serial]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=280</guid>
		<description><![CDATA[One of the fun tasks I have at work is creating fun lab projects for teaching classes.  In this case, the class was on basic embedded programming and the object was to show how serial input command strings are parsed into their basic components.  My pseudo project was a coffee maker, and the command set [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">One of the fun tasks I have at work is creating fun lab projects for teaching classes.<span style="mso-spacerun: yes;">  </span>In this case, the class was on basic embedded programming and the object was to show how serial input command strings are parsed into their basic components.<span style="mso-spacerun: yes;">  </span>My pseudo project was a coffee maker, and the command set was relatively simple;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">T 12:00<span style="mso-tab-count: 2;">                        </span>sets the real time clock to 12:00</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">A 1:00<span style="mso-tab-count: 3;">                         </span>sets the start time for the coffee maker to 1:00</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">M<span style="mso-tab-count: 4;">                                             </span>turns on the timer</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">m<span style="mso-tab-count: 4;">                                             </span>turns off the timer</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">?<span style="mso-tab-count: 5;">                                                          </span>returns the time, start time, and current temperature of the coffee</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">Now, while the command set looks relatively simple, I also had to make it reasonably fool proof to use as well.<span style="mso-spacerun: yes;">  </span>So;</span></p>
<p class="MsoNormal" style="text-indent: 0in; margin: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list 0in;"><span style="font-family: Times New Roman;"><span style="mso-list: Ignore;"><span style="font-size: small;">1.</span><span style="font: 7pt &quot;Times New Roman&quot;;">                  </span></span><span style="font-size: small;">I had to be able to accept both upper and lower case for the time and alarm commands.</span></span></p>
<p class="MsoNormal" style="text-indent: 0in; margin: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list 0in;"><span style="font-family: Times New Roman;"><span style="mso-list: Ignore;"><span style="font-size: small;">2.</span><span style="font: 7pt &quot;Times New Roman&quot;;">                  </span></span><span style="font-size: small;">I had to accept both single and double digit input for the hours.</span></span></p>
<p class="MsoNormal" style="text-indent: 0in; margin: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list 0in;"><span style="font-family: Times New Roman;"><span style="mso-list: Ignore;"><span style="font-size: small;">3.</span><span style="font: 7pt &quot;Times New Roman&quot;;">                  </span></span><span style="font-size: small;">I had to accept both a ‘ ‘ or a ‘:’ as a data delimiter.</span></span></p>
<p class="MsoNormal" style="text-indent: 0in; margin: 0in 0in 0pt; mso-list: l0 level1 lfo1; tab-stops: list 0in;"><span style="font-family: Times New Roman;"><span style="mso-list: Ignore;"><span style="font-size: small;">4.</span><span style="font: 7pt &quot;Times New Roman&quot;;">                  </span></span><span style="font-size: small;">And, I had to accept a cr as a delimiter and the termination of the command string.</span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">So, I started out by creating a set a of variables to hold the parsed data;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">A CHAR to hold the command character.<span style="mso-spacerun: yes;">  </span>Note: mt_char is a default character.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 10pt;"><span style="mso-tab-count: 1;">      </span>cmd_char<span style="mso-spacerun: yes;">   </span>= mt_char;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">And a 4 data variables for the individual nibbles of the hours and minutes</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 10pt;"><span style="mso-tab-count: 1;">      </span>data_var1a = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 10pt;"><span style="mso-tab-count: 1;">      </span>data_var2a = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 10pt;"><span style="mso-tab-count: 1;">      </span>data_var1b = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 10pt;"><span style="mso-tab-count: 1;">      </span>data_var2b = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">I then created an init routine to preset the variables to their default values.<span style="mso-spacerun: yes;">  </span>Note, I use this both at startup, and after I decode the commands, to preset the variables for the next command string.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">/******************************************************************************</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Function: void pars_init(void)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Overview: This function configures the parser for operation</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Input:<span style="mso-spacerun: yes;">    </span>none</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Output:<span style="mso-spacerun: yes;">   </span>none</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">******************************************************************************/</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">void pars_init(void)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>cmd_char<span style="mso-spacerun: yes;">   </span>= mt_char;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>data_var1a = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>data_var2a = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>data_var1b = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>data_var2b = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>mode<span style="mso-spacerun: yes;">       </span>= cmd;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>pars_done<span style="mso-spacerun: yes;">  </span>= 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>pars_falt<span style="mso-spacerun: yes;">  </span>= 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">Note: resetting the variables to zero also provides any leading zeros required for single digit entries.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">Next, I created my parser routine in two halves; the first which accepts the individual characters from the serial input and parses the data into blocks, and a second which executes the actual command.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-size: small;"><span style="font-family: Times New Roman;">The first section is implemented as a statemachine with 4 states, CMD for command, VAR1 for the first data variables, VAR2 for the second data variable, and DEFAULT which is a general error handler.<span style="mso-spacerun: yes;">  </span></span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">In the CMD state, any character that is not a number or a delimiter is stored in the cmd_char variable.<span style="mso-spacerun: yes;">  </span>If the character is a ‘ ‘, then the statemachine is advanced to the VAR1 state.<span style="mso-spacerun: yes;">  </span>If the character is a cr, then the parser is done and the command can be decoded by the second half of the routine.<span style="mso-spacerun: yes;">  </span>If any other character is detected than a pars_falt is set indicating an invalid command.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">In the VAR1 state, any number is stored in the data_var1a, after the contents of data_var1a has been shifted into data_var1b.<span style="mso-spacerun: yes;">  </span>This shift register arrangement allows us to either enter 1 or 2 values because both variables were cleared prior to the start of the command, leaving a leading zero for any single value entry.<span style="mso-spacerun: yes;">  </span>If the character is a ‘:’, then the statemachine advances to the state VAR2 for a second value entry.<span style="mso-spacerun: yes;">  </span>If the character is a cr, then the parser is done and the command can be decoded by the second half of the routine.<span style="mso-spacerun: yes;">  </span>If any other character is detected than a pars_falt is set indicating an invalid command.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">The VAR2 state operates nearly identically to VAR1, with the exception that the only delimiter accepted is the cr to terminate the command.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">The only function of the default state is to set the fault flag so the second half of the routine can reset the statemachine to its default condition.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">When the first half of the function is complete, and the <span style="mso-spacerun: yes;"> </span>pars_done variable is set, then the 5 data variables (<span style="mso-tab-count: 1;">            </span>cmd_char, data_var1a, data_var2a, data_var1b, &amp; data_var2b) should have legal values in them, either from data received from the serial port, or default data loaded during the initialization function.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">/******************************************************************************</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Function: void parser(void)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Overview: This function disassembles serial command strings</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Input:<span style="mso-spacerun: yes;">    </span>none</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">* Output:<span style="mso-spacerun: yes;">   </span>values</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">*</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">******************************************************************************/</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">void parser(void)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>switch(mode)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>Case cmd:<span style="mso-tab-count: 1;">     </span>if (((hold &gt;= &#8216;a&#8217;)&amp;(hold &lt;= &#8216;z&#8217;)) | ((hold &gt;= &#8216;A&#8217;)&amp;(hold &lt;= &#8216;Z&#8217;)) | (hold == &#8216;?&#8217;))</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span><span style="mso-tab-count: 2;">              </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span><span style="mso-tab-count: 3;">                     </span>cmd_char = hold;<span style="mso-tab-count: 2;">           </span><span style="mso-tab-count: 2;">              </span>// a-z or A-Z or ? detected store as command</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 2;">              </span><span style="mso-tab-count: 1;">       </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>else if (hold == &#8216; &#8216;)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span>mode = var1;<span style="mso-tab-count: 3;">               </span><span style="mso-tab-count: 2;">              </span>// &#8216; &#8216; delimiter detected goto next field of data</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>else if (hold == CR)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span>pars_done<span style="mso-spacerun: yes;">  </span>= 1;<span style="mso-tab-count: 3;">                   </span><span style="mso-tab-count: 1;">       </span>// CR detected terminate parser and decode command</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>else</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>{<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span>pars_falt<span style="mso-spacerun: yes;">  </span>= 1;<span style="mso-tab-count: 3;">                   </span><span style="mso-tab-count: 1;">       </span>// no clue send a ? and restart</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>case var1:<span style="mso-tab-count: 1;">    </span>if ((hold &gt;= &#8216;0&#8242;) &amp;&amp; (hold &lt;= &#8216;9&#8242;)) </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 5;">                                  </span><span style="mso-tab-count: 1;">       </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>data_var1b = data_var1a;<span style="mso-tab-count: 1;">   </span>// 0-9 detected store as first data</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>data_var1a = hold &#8211; &#8216;0&#8242;;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 4;">                           </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span>else if (hold == &#8216;:&#8217;)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 3;">                     </span>mode = var2;<span style="mso-tab-count: 3;">               </span><span style="mso-tab-count: 2;">              </span>// &#8216;:&#8217; delimiter detected goto next field of data</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>else if (hold == CR)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 5;">                                  </span>pars_done<span style="mso-spacerun: yes;">  </span>= 1;<span style="mso-tab-count: 3;">                   </span><span style="mso-tab-count: 2;">              </span>// CR detected terminate parser and decode command</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 3;">                     </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>else</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span>{<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 5;">                                  </span>pars_falt<span style="mso-spacerun: yes;">  </span>= 1;<span style="mso-tab-count: 3;">                   </span><span style="mso-tab-count: 2;">              </span>// no clue send a ? and restart</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>case var2:<span style="mso-tab-count: 1;">    </span>if ((hold &gt;= &#8216;0&#8242;) &amp;&amp; (hold &lt;= &#8216;9&#8242;)) </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>{<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>data_var2b = data_var2a;<span style="mso-tab-count: 1;">   </span><span style="mso-tab-count: 1;">       </span>// 0-9 detected store as second data</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>data_var2a = hold &#8211; &#8216;0&#8242;;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>else if (hold == CR)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 5;">                                  </span>pars_done<span style="mso-spacerun: yes;">  </span>= 1;<span style="mso-tab-count: 3;">                   </span><span style="mso-tab-count: 2;">              </span>// CR detected terminate parser and decode command</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>}</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 4;">                           </span>else</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 2;">              </span>{<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 5;">                                  </span>pars_falt<span style="mso-spacerun: yes;">  </span>= 1;<span style="mso-tab-count: 3;">                   </span><span style="mso-tab-count: 2;">              </span>// no clue send a ? and restart</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 3;">                     </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span><span style="mso-tab-count: 1;">       </span><span style="mso-tab-count: 3;">                     </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>default:<span style="mso-tab-count: 1;">      </span><span style="mso-tab-count: 1;">       </span>pars_falt = 1;<span style="mso-tab-count: 5;">                                  </span><span style="mso-tab-count: 2;">              </span>// definitely lost, send a ?</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 5;">                                  </span><span style="mso-tab-count: 1;">       </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>}<span style="mso-tab-count: 4;">                          </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">Once the data is parsed into its separate elements, it is a simple matter to decode the command and routine the new data into the appropriate variables.<span style="mso-spacerun: yes;">  </span>In this case; rtc_hours, rtc_mins, alrm_hours, alrm_min, &amp; alrm_on.<span style="mso-spacerun: yes;">  </span>Based on the value in cmd_char, a simple switch statement is all that is needed to routine the incoming data to the appropriate variables.<span style="mso-spacerun: yes;">  </span>Once the command decode is complete, then the routine is reset by calling the initialization routine to clear the variables and set them to their default values.<span style="mso-spacerun: yes;">  </span>In the event that their was a communications fault during the parse or decode operation, then the data is discarded and the system is reset using the initialization routine.</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"> </span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>if (pars_done == 1)<span style="mso-tab-count: 7;">                                           </span><span style="mso-tab-count: 3;">                     </span>// if CR detected, then decode the command</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>switch(cmd_char)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;T&#8217;:<span style="mso-tab-count: 9;">                                                            </span><span style="mso-tab-count: 2;">              </span>// time command uses both data blocks</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;t&#8217;:<span style="mso-tab-count: 1;">     </span>rtc_hours = (data_var1b * 10) + data_var1a;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>rtc_mins<span style="mso-spacerun: yes;">  </span>= (data_var2b * 10) + data_var2a;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;A&#8217;: <span style="mso-tab-count: 9;">                                                           </span><span style="mso-tab-count: 2;">              </span>// alarm set command uses both data blocks</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;a&#8217;:<span style="mso-tab-count: 1;">     </span>alrm_hours = (data_var1b * 10) + data_var1a;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>alrm_mins<span style="mso-spacerun: yes;">  </span>= (data_var2b * 10) + data_var2a;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;M&#8217;:<span style="mso-tab-count: 1;">     </span>alarm_on = 1;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;m&#8217;:<span style="mso-tab-count: 1;">     </span>alarm_on = 0;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 3;">                     </span>case &#8216;?&#8217;:<span style="mso-tab-count: 1;">     </span>send_all_data();<span style="mso-tab-count: 5;">                                </span>// ? sends the time, alarm, and temperature</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 7;">                                                </span>break;</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>pars_init();</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>if (pars_falt == 1)</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>{</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>Tx_send(&#8217;?');<span style="mso-tab-count: 11;">                                                                     </span>// send ‘huh?’ message to user</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>Tx_save(CR);</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>Tx_save(LF);</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 2;">              </span>pars_init();</span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;"><span style="mso-tab-count: 1;">       </span>}<span style="mso-tab-count: 1;">      </span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: &quot;Courier New&quot;; font-size: 8pt;">}</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=280</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting between binary and decimal in assembly</title>
		<link>http://blog.notesfromthelab.com/?p=276</link>
		<comments>http://blog.notesfromthelab.com/?p=276#comments</comments>
		<pubDate>Thu, 22 Oct 2009 17:00:50 +0000</pubDate>
		<dc:creator>Keith</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[data conversion]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=276</guid>
		<description><![CDATA[One of the interesting challenges in working in assembly, versus C, is converting between BCD and binary. We all know that processors work in binary and users work in C, right? The problem is, even thought some processors include BCD math capabilities, things like multiplication, division, and all the system timers, work in binary.
So, one [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">One of the interesting challenges in working in assembly, versus C, is converting between BCD and binary.<span> </span>We all know that processors work in binary and users work in C, right?<span> </span>The problem is, even thought some processors include BCD math capabilities, things like multiplication, division, and all the system timers, work in binary.</p>
<p class="MsoNormal">So, one of the long standing problems, is how do we efficiently convert between base 2 and base 10.<span> </span>Well, a couple of years ago, I was faced with this problem, and I came up with a fairly efficient conversion algorithm that works well in both directions.</p>
<p class="MsoNormal">The routines are based on the same basic principal as a multiply routine.<span> </span>For example, let’s convert an 8-bit binary number to BCD.</p>
<p class="MsoNormal">8-bit binary value<span> </span>10110101</p>
<p class="MsoNormal">First, we build up a constant table for each bit location;</p>
<p class="MsoNormal">
<p class="MsoNormal">0<span> </span>0<span> </span>1</p>
<p class="MsoNormal">0<span> </span>0<span> </span>2</p>
<p class="MsoNormal">0<span> </span>0<span> </span>4</p>
<p class="MsoNormal">0<span> </span>0<span> </span>8</p>
<p class="MsoNormal">0<span> </span>1<span> </span>6</p>
<p class="MsoNormal">0<span> </span>3<span> </span>2</p>
<p class="MsoNormal">0<span> </span>6<span> </span>4</p>
<p class="MsoNormal">1<span> </span>2<span> </span>8</p>
<p class="MsoNormal">
<p class="MsoNormal">Then we create a set of BCD output variables and clear them</p>
<p class="MsoNormal">BCD100<span> </span>BCD10<span> </span>BCD1</p>
<p class="MsoNormal">
<p class="MsoNormal">Next, we shift through the binary value, and for every 1, we add the corresponding value from the table, using BCD addition;</p>
<p class="MsoNormal">8-bit binary value<span> </span>10110101</p>
<p class="MsoNormal">0<span> </span>0<span> </span>1</p>
<p class="MsoNormal">0<span> </span>0<span> </span>4</p>
<p class="MsoNormal">0<span> </span>1<span> </span>6</p>
<p class="MsoNormal">0<span> </span>3<span> </span>2</p>
<p class="MsoNormal">+<span> </span>1<span> </span>2<span> </span>8</p>
<p class="MsoNormal">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p class="MsoNormal"><span> </span>1<span> </span>8<span> </span>1</p>
<p class="MsoNormal">To go in the other direction, we just use a binary array of constants, and add using binary addition</p>
<p class="MsoNormal">BCD value<span> </span>181</p>
<p class="MsoNormal">Binary constants</p>
<p class="MsoNormal">
<p class="MsoNormal">00000001<span> </span><span> </span>1</p>
<p class="MsoNormal">00000010<span> </span><span> </span>2</p>
<p class="MsoNormal">00000100<span> </span><span> </span>4</p>
<p class="MsoNormal">00001000<span> </span><span> </span>8</p>
<p class="MsoNormal">00001010<span> </span><span> </span>10</p>
<p class="MsoNormal">00010100<span> </span><span> </span>20</p>
<p class="MsoNormal">00101000<span> </span><span> </span>40</p>
<p class="MsoNormal">01010000<span> </span><span> </span>80</p>
<p class="MsoNormal">01100100<span> </span>100</p>
<p class="MsoNormal">11001000<span> </span>200</p>
<p class="MsoNormal">
<p class="MsoNormal">And the conversion looks like this;</p>
<p class="MsoNormal">
<p class="MsoNormal">BCD value<span> </span>181</p>
<p class="MsoNormal">
<p class="MsoNormal">01100100<span> </span>100</p>
<p class="MsoNormal">01010000<span> </span><span> </span>80</p>
<p class="MsoNormal">+<span> </span>00000001<span> </span><span> </span>1</p>
<p class="MsoNormal">&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p class="MsoNormal"><span> </span>10110101</p>
<p class="MsoNormal">Of course, this technique can be expanded to any number of bits; all you need to do is expand the constant table to include all the bit values.<span> </span>Attached to the end of this blog are listings for both binary to decimal and decimal to binary for the PIC16FXXX family of parts;</p>
<p class="MsoNormal">;************************************************************************</p>
<p class="MsoNormal"><span>; Converts a 5 digit BCD to 16-bit number in H_byte:L_byte</span></p>
<p class="MsoNormal"><span>; Limitation:<span> </span>5-digit bcd must be less than 2^17 (= 65536) in order</span></p>
<p class="MsoNormal"><span>;<span> </span>to fit into the 16-bit result. Else result is remainder.</span></p>
<p class="MsoNormal"><span>; </span></p>
<p class="MsoNormal"><span>;<span> </span>R2H<span> </span>R2L<span> </span>R1H<span> </span>R1L<span> </span>R0H<span> </span>R0L</span></p>
<p class="MsoNormal"><span>;<span> </span>-<span> </span>dig5<span> </span>dig4<span> </span>dig3<span> </span>dig2<span> </span>dig1</span></p>
<p class="MsoNormal"><span>BCD5BIN16:</span></p>
<p class="MsoNormal"><span><span> </span>clrf<span> </span>H_byte</span></p>
<p class="MsoNormal"><span><span> </span>movf<span> </span>R2, W</span></p>
<p class="MsoNormal"><span><span> </span>andlw<span> </span>0&#215;0F</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>L_byte</span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>mpy10a<span> </span>; result = 10a+b</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>swapf<span> </span>R1, W</span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>mpy10b<span> </span>; result = 10[10a+b]</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>movf<span> </span>R1, W</span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>mpy10b<span> </span>; result = 10[10[10a+b]+c]</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>swapf<span> </span>R0, W</span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>mpy10b<span> </span>; result = 10[10[10[10a+b]+c]+d]</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>movf<span> </span>R0, W</span></p>
<p class="MsoNormal"><span><span> </span>andlw <span> </span>0&#215;0F</span></p>
<p class="MsoNormal"><span><span> </span>addwf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>btfsc<span> </span>STATUS, C</span></p>
<p class="MsoNormal"><span><span> </span>incf<span> </span>H_byte, F<span> </span>; result = 10[10[10[10a+b]+c]+d]+e</span></p>
<p class="MsoNormal"><span><span> </span>return<span> </span>; BCD to binary conversion done</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span>mpy10b:</span></p>
<p class="MsoNormal"><span><span> </span>andlw<span> </span>0&#215;0F</span></p>
<p class="MsoNormal"><span><span> </span>addwf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>btfsc<span> </span>STATUS, C</span></p>
<p class="MsoNormal"><span><span> </span>incf<span> </span>H_byte, F</span></p>
<p class="MsoNormal"><span>mpy10a:</span></p>
<p class="MsoNormal"><span><span> </span>bcf<span> </span>STATUS, C<span> </span>; multiply by 2</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>L_byte, W</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>L_temp</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>H_byte, W<span> </span>; (H_temp,L_H_temp) = 2*N</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>H_temp</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>bcf<span> </span>STATUS, C<span> </span>; multiply by 2</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>H_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>bcf<span> </span>STATUS, C<span> </span>; multiply by 2</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>H_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>bcf<span> </span>STATUS, C<span> </span>; multiply by 2</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>H_byte, F<span> </span>; (H_byte,L_byte) = 8*N</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>movf<span> </span>L_temp, W</span></p>
<p class="MsoNormal"><span><span> </span>addwf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>btfsc<span> </span>STATUS, C</span></p>
<p class="MsoNormal"><span><span> </span>incf<span> </span>H_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>movf<span> </span>H_temp, W</span></p>
<p class="MsoNormal"><span><span> </span>addwf<span> </span>H_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>return<span> </span><span> </span>; (H_byte,L_byte) = 10*N</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span>;*********************************************************************</span></p>
<p class="MsoNormal">
<p class="MsoNormal">
<p class="MsoNormal"><span>;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></p>
<p class="MsoNormal"><span>; Bin16BCD</span></p>
<p class="MsoNormal"><span>;<span> </span>Converts 16-bit binary number (H_byte:L_byte) into a 5 digit </span></p>
<p class="MsoNormal"><span>;<span> </span>BCD number in 5 nibbles of registers R2, R1, R0 as shown.</span></p>
<p class="MsoNormal"><span>;</span></p>
<p class="MsoNormal"><span>;<span> </span>R2H<span> </span>R2L<span> </span>R1H<span> </span>R1L<span> </span>R0H<span> </span>R0L</span></p>
<p class="MsoNormal"><span>;<span> </span>-<span> </span>dig5<span> </span>dig4<span> </span>dig3<span> </span>dig2<span> </span>dig1</span></p>
<p class="MsoNormal"><span>;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</span></p>
<p class="MsoNormal"><span>Bin16BCD:<span> </span></span></p>
<p class="MsoNormal"><span><span> </span>bcf<span> </span>STATUS,C<span> </span><span> </span>; clear the carry bit in STATUS</span></p>
<p class="MsoNormal"><span><span> </span>movlw<span> </span>.16</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>temp+1</span></p>
<p class="MsoNormal"><span><span> </span>clrf<span> </span>R0</span></p>
<p class="MsoNormal"><span><span> </span>clrf<span> </span>R1</span></p>
<p class="MsoNormal"><span><span> </span>clrf<span> </span>R2</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span>b16b_loop16:</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>L_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>H_byte, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>R0, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>R1, F</span></p>
<p class="MsoNormal"><span><span> </span>rlf<span> </span>R2, F</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>decfsz<span> </span>temp+1, F</span></p>
<p class="MsoNormal"><span><span> </span>goto<span> </span>adjDEC</span></p>
<p class="MsoNormal"><span><span> </span>return</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span>adjDEC:</span></p>
<p class="MsoNormal"><span><span> </span>movlw<span> </span>R0</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>FSR<span> </span></span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>adjBCD</span></p>
<p class="MsoNormal"><span><span> </span></span></p>
<p class="MsoNormal"><span><span> </span>movlw<span> </span>R1</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>FSR<span> </span></span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>adjBCD</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span><span> </span>movlw<span> </span>R2</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>FSR<span> </span></span></p>
<p class="MsoNormal"><span><span> </span>call<span> </span>adjBCD</span></p>
<p class="MsoNormal"><span><span> </span>goto<span> </span>b16b_loop16</span></p>
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal"><span>adjBCD:</span></p>
<p class="MsoNormal"><span><span> </span>movlw<span> </span>0&#215;03</span></p>
<p class="MsoNormal"><span><span> </span>addwf<span> </span>INDF,W</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>temp</span></p>
<p class="MsoNormal"><span><span> </span>btfsc<span> </span>temp,3<span> </span><span> </span>; test if result &gt; 7</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>INDF</span></p>
<p class="MsoNormal"><span><span> </span>movlw<span> </span>0&#215;30</span></p>
<p class="MsoNormal"><span><span> </span>addwf<span> </span>INDF,W</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>temp</span></p>
<p class="MsoNormal"><span><span> </span>btfsc<span> </span>temp,7<span> </span><span> </span>; test if result &gt; 7</span></p>
<p class="MsoNormal"><span><span> </span>movwf<span> </span>INDF<span> </span><span> </span>; save as MSD</span></p>
<p class="MsoNormal"><span><span> </span>return</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=276</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capacitive Touch Algorithm Tuning for Thick Overlays</title>
		<link>http://blog.notesfromthelab.com/?p=274</link>
		<comments>http://blog.notesfromthelab.com/?p=274#comments</comments>
		<pubDate>Tue, 20 Oct 2009 17:19:46 +0000</pubDate>
		<dc:creator>Padmaraja</dc:creator>
				<category><![CDATA[Capacitive Touch]]></category>

		<guid isPermaLink="false">http://blog.notesfromthelab.com/?p=274</guid>
		<description><![CDATA[Often the capacitive touch applications need thick overlay to be used over the capacitive touch pads to make the system mechanically robust. In addition to that, for aesthetic reasons, the overlay may be curved. This poses a serious issue of reducing the touch sensitivity. The curvature on the overlay distorts the sample reading from the [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="text-indent: 0.5in; margin: 0in 0in 0pt;"><span style="font-size: small;"><span style="font-family: Times New Roman;">Often the capacitive touch applications need thick overlay to be used over the capacitive touch pads to make the system mechanically robust. In addition to that, for aesthetic reasons, the overlay may be curved. This poses a serious issue of reducing the touch sensitivity. The curvature on the overlay distorts the sample reading from the buttons. Also it gives a variation in reading from button to button. To overcome these issues, the capacitive touch algorithm needs some tuning.<span style="mso-spacerun: yes;">     </span><span style="mso-spacerun: yes;"> </span></span></span></p>
<p class="MsoNormal" style="margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;"> </span></p>
<p class="MsoNormal" style="text-indent: 0.5in; margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">When thick overlay of plastic or glass is used, the sensitivity goes down significantly. As you know, the human touch produces a basic capacitor, with finger and the touch pad being the electrodes and the overlay material is the dielectric material separating the plates. Because the thickness of the dielectric material increased(the overlay), the capacitance shift produced by touch reduces, thus reducing the sensitivity. Because of this, the signal to noise ratio reduces further down. </span></p>
<p class="MsoNormal" style="text-indent: 0.5in; margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">To overcome this, a slow moving average algorithm is used. First, the capacitive sensing module, such as Charge Time Measurement unit(CTMU) or Capacitive Sensing Module(CSM), is sampled 16 to 64 times(N Samples) every fixed interval. These N samples are accumulated and used as the current running sample. The averaging algorithm takes the current sample and takes a fraction of it and adds to the running average. The running average is not updated until 20 or more samples of slow moving average. By doing this the average changes very slow and the slight shift of the current sample allows to detect the touch. </span></p>
<p class="MsoNormal" style="text-indent: 0.5in; margin: 0in 0in 0pt;"><span style="font-family: Times New Roman; font-size: small;">Because of the low sensitivity, the difference between the current sample and the average data could be less than 1%. Each channel needs tuning on the number of samples for slow moving average to suit the touch key size and key characteristics. </span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.notesfromthelab.com/?feed=rss2&amp;p=274</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
