tag:blogger.com,1999:blog-68808215913706974842024-03-05T08:49:02.587+01:00 R6500Blog about Electronics and Microcontrollers. English companion to the AIM65 spanish blog (http://aim65.blogspot.com.es/)Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-6880821591370697484.post-3784070939086214682018-04-09T14:31:00.000+02:002018-04-09T15:21:33.024+02:00Solving circuits with Python<a href="https://www.python.org/" target="_blank">Python</a> is a scripting languaje that is now quite popular.<br />
<br />
It is used in a broad range of applications including performing scientific calculations thanks to the <a href="https://www.scipy.org/" target="_blank">SciPy</a> libraries.<br />
<br />
This blog entry links to a pair of Google <a href="https://colab.research.google.com/notebooks/welcome.ipynb" target="_blank">Colaboratory documents</a>. Colaboratory documents are Python <a href="http://jupyter.org/" target="_blank">Jupyter</a> Notebooks hosted in a Google Drive account that run the code in virtual machines owned by Google.<br />
<br />
That way you don't need to have <b>Python</b> installed to try or modify the proposed code.<br />
<br />
<h3>
Solving circuits with SymPy</h3>
<a href="http://www.sympy.org/es/" target="_blank">SymPy</a> is one of the <b>SciPy </b>libraries. It enables you to perform symbolic calculations. This can come handy to solve electrical circuits like the one below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjItA5NkNv7quAZ7y1Dtd3lDJQuESbmS45qFUlufpfH7ZDYtoNTPE5OEYdvlG106LdPiWU_qK566gbrLMr2EGdXbeFj2PycmYr-kvIfLCMc2fLa0xn93eDc_PhV-xtQxoGNbDys4X77jqNs/s1600/Circuit01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="245" data-original-width="365" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjItA5NkNv7quAZ7y1Dtd3lDJQuESbmS45qFUlufpfH7ZDYtoNTPE5OEYdvlG106LdPiWU_qK566gbrLMr2EGdXbeFj2PycmYr-kvIfLCMc2fLa0xn93eDc_PhV-xtQxoGNbDys4X77jqNs/s320/Circuit01.jpg" width="320" /></a></div>
In order to solve a circuit, you need to obtain a set of equations whose solution is the magnitude you want to know. In the above circuit, let's say that we want to know the value of <b>Vo</b> as function of <b>Vs</b>, <b>R1</b>, <b>R2</b> and <b>Is</b>.<br />
<br />
You start defining <b>symbols </b>for the circuit. We need symbols for the component values <b>Vs</b>, <b>R1</b>, <b>R2</b> and <b>Is</b> and for the solution <b>Vo</b>.<br />
As we will solve the circuit using the nodal method that applies current equations in all nodes except the <b>ground </b>one, we also need symbols for the nodal voltages <b>V1</b> and <b>V2</b>.<br />
Also, using the full nodal method requires as to add a symbol, like <b>iVs</b> for the current in the source voltages.<br />
<b></b><br />
<br />
<span style="font-size: small;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Create the circuit symbols</span><br /><span style="color: blue;">Vs,iVs,R1,R2,Is,Vo, V1, V2 = sympy.symbols('Vs,iVs,R1,R2,Is,Vo,V1,V2')</span></span></span><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
Now we define the equations of nodes 1 and 2. To do that, we initizalize an empty list of equations and add the two equations to this list. Using the nodal method, we apply the <a href="https://en.wikipedia.org/wiki/Kirchhoff%27s_circuit_laws" target="_blank">Kirchhoff KCL law</a> on each node:</div>
<br />
<span style="color: #674ea7;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Create an empty list of equations</span><br /><span style="color: blue;">equations = []</span><br /><br /><span style="color: #a64d79;"><span style="color: #674ea7;"># Nodal equations</span></span><br /><span style="color: blue;">equations.append(iVs-(V1-V2)/R1) <span style="color: #a64d79;"># Node 1</span><br />equations.append(Is-(V2-V1)/R1-V2/R2) <span style="color: #a64d79;"># Node 2</span></span></span><br />
<br />
In <b>SymPy </b>it is assumed that all equations are equal to zero.<br />
<br />
In the nodal method we also need to add an equation for each <b>voltage source</b> that relates it to the node voltages. In SymPy, <b>Eq </b>means equal, so, Eq(Vs,V1) means Vs = V1.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Voltage source equations</span><br /><span style="color: blue;">equations.append(sympy.Eq(Vs,V1))</span></span><br />
<br />
The final equation is the one that contains the result we want to obtain for the circuit:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Measurement equations</span><br /><span style="color: blue;">equations.append(sympy.Eq(Vo,V2))</span></span><br />
<br />
<br />
Now we have a full set of equations:<br />
<br />
<pre><span style="color: blue;"><span style="font-family: "courier new" , "courier" , monospace;">iVs - (V1 - V2)/R1
Is - V2/R2 - (-V1 + V2)/R1
Eq(Vs, V1)
Eq(Vo, V2)</span></span></pre>
<br />
Those equations enables us to obtain <b>Vo </b>but a smaller set of equation will also work. In particular, as the first equation contains an unknown <b>iVs</b> that is not found in any other equation, we can eliminate this equation if the only unknown we care for is <b>Vo</b>. We don't need, however, to know that to solve the circuit.<br />
<br />
In these equations, some variables are unknowns, we make a list of them:<br />
<br />
<span style="color: blue;"><span style="font-family: "courier new" , "courier" , monospace;">unknowns = [V1,V2,iVs,Vo] </span></span><br />
<br />
Then we can solve the circuit using the <b>solve </b>function of the <b>SymPy </b>library:<br />
<br />
<span style="color: blue;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Solve the circuit</span><br />solution = sympy.solve(equations,unknowns)</span></span> <br />
<br />
That will yield the <b>solutions </b>for the <b>unknowns</b>:<br />
<br />
<pre><span style="color: blue;"><span style="font-family: "courier new" , "courier" , monospace;">V1 = Vs
V2 = R2*(Is*R1 + Vs)/(R1 + R2)
iVs = (-Is*R2 + Vs)/(R1 + R2)
Vo = R2*(Is*R1 + Vs)/(R1 + R2)</span></span></pre>
<br />
If you want to see more details, more circuit solutions or you want to test te code yourself, <a href="https://colab.research.google.com/drive/1hWYPdNfYP0Pwf3YlKWjV_P-d0-krTcAU?authuser=1#scrollTo=XKJXe4be50PC" target="_blank">open this colaboratory document</a>.<br />
<br />
<br />
<h3>
Automating the solution</h3>
As you can see we have followed a recipe for solving the circuit. That means that it can be automated. The <b>circuit </b>Python module, just does that: Solves a circuit using the nodal method recipe.<br />
<br />
As we remember the circuit is:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbfJSo3YDog2PVxa7QxOcVMAWw03gq7RTy8q6pwx4FewftgFLZnG1oI2blzl-JLMHwAu4gQDdG6QvneooTmTB5ihac6se0SiltONkQ_ckUMuuBwM9NMREDcsBb_wRVzDt-bnzTkj44PbOC/s1600/Circuit01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="245" data-original-width="365" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbfJSo3YDog2PVxa7QxOcVMAWw03gq7RTy8q6pwx4FewftgFLZnG1oI2blzl-JLMHwAu4gQDdG6QvneooTmTB5ihac6se0SiltONkQ_ckUMuuBwM9NMREDcsBb_wRVzDt-bnzTkj44PbOC/s320/Circuit01.jpg" width="320" /></a></div>
We can describe it just with a list of <b>components </b>and <b>measurements</b>:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Circuit 1 definiton</span><br /><span style="color: blue;">c1 = circuit.circuit() <span style="color: #a64d79;"># New circuit</span><br />c1.addV('Vs',1,0,5) <span style="color: #a64d79;"># Vs between 1 and GND with 5 V value</span><br />c1.addR('R1',1,2,1000) <span style="color: #a64d79;"># R1 between 1 and 2 with 1000 Ohm value</span><br />c1.addR('R2',2,0,1000) <span style="color: #a64d79;"># R2 between 2 and GND with 1000 Ohm value</span><br />c1.addI('Is',2,0,0.01) <span style="color: #a64d79;"># Is going from GND to 2 with 10 mA value</span><br />c1.addVM('Vo',2,0) <span style="color: #a64d79;"># Measurement Vo between 2 and GND</span></span></span><br />
<br />
Then we can obtain the symbolic solution for <b>Vo</b>:<br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Symbolic solution</span><br /><span style="color: blue;">print('Vo =',c1.solution['Vo'],' (Symbolic)')</span></span><br />
<br />
That yields:<br />
<br />
<pre><span style="color: blue;"><span style="font-family: "courier new" , "courier" , monospace;">Vo = R2*(Is*R1 + Vs)/(R1 + R2) (Symbolic)</span></span></pre>
<br />
Note that this is the very same solution we obtained previously without using the <b>SymPy </b>module. <br />
<br />
Also, as we have indicated the component values, we can also obtain the numerical solution:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #a64d79;"># Numeric solution</span><br /><span style="color: blue;">print('Vo =',c1.particular['Vo'],'V (Particular)')</span></span><br />
<br />
That yields:<br />
<br />
<pre><span style="color: blue;"><span style="font-family: "courier new" , "courier" , monospace;">Vo = 7.5 V (Particular)</span></span></pre>
<br />
If you want to see more about the <b>circuit </b>module, see other solutions or use your own code, <a href="https://colab.research.google.com/drive/1dMRvwgzQGN1sGfrEGmtYxV3xP7TACWeF?authuser=1#scrollTo=lvBmqlL-ltP4" target="_blank">open this colaboratory document</a>.Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com5tag:blogger.com,1999:blog-6880821591370697484.post-923542844743777082018-03-07T12:39:00.003+01:002018-03-28T12:39:10.421+02:00Google colaboratory<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<span class="" id="result_box" lang="en" tabindex="-1"><span class="">This is an entry about my <a href="https://colab.research.google.com/" target="_blank">Google Colaboratory</a> documents.</span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27artF4xVbwhDeCPnxt2-W7UJcJou9mqHLllJwmkW_s3GA2LXzEs6p4A0BsjhDmlMITZ9VUmxNsUKo_6WnN9OBgJQkxllJ7sSw1-mo7rOaJlyvO22rwsv7aTbsQCy3eSXezzac_OJsHyh/s1600/Colaboratory.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="200" data-original-width="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27artF4xVbwhDeCPnxt2-W7UJcJou9mqHLllJwmkW_s3GA2LXzEs6p4A0BsjhDmlMITZ9VUmxNsUKo_6WnN9OBgJQkxllJ7sSw1-mo7rOaJlyvO22rwsv7aTbsQCy3eSXezzac_OJsHyh/s1600/Colaboratory.png" /></a></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1">Google
colaboratory allows you to execute Python code in virtual machines so
that it is possible to execute and share code without having owning a Python execution environment. You just need to have a browser.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"></span><span class="" id="result_box" lang="en" tabindex="-1">Colaboratory documents are <a href="http://jupyter.org/" target="_blank">Python Jupyter</a> notebooks that allow you to include not only code but also text, formulas and images.</span><br />
<br />
<span class="" id="result_box" lang="en" tabindex="-1">The colaboratory documents can be downloaded on your computer as Jupyter <b>.ipynb</b> documents and executed offline in a localPython evironment.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1">To access colaboratory you need to have a Google account. This
is enough to see the documents, but if you want to execute your
content, you must save a copy in your own <a href="https://www.google.com/intl/es_ALL/drive/" target="_blank">Google Drive</a> account.</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1">Below yoy can find links to some documents created in Colabortory. <span class="">They
all import a Python <b>calc </b>module that includes support functions such
as, for example, <b>plot11</b>, <b>plot1n </b>and <b>plotnn </b>that assist in curve drawing.</span> <span class="">The module is accessible thanks to<a href="https://github.com/R6500/Python-bits/blob/master/Modules/calc.py" target="_blank"> GitHub</a>.</span></span></span></span></div>
<div style="text-align: justify;">
<br />
The colaboratory document list is constantly updated. The <b>current </b>list of documents is accessible my <a href="https://colab.research.google.com/drive/1-p9U6eK5CdJxYof2AZHV2IHO0lv_gzhM#scrollTo=TBSFHEfej6Dm" target="_blank">Master Colaboratory Document</a>.<br />
<br />
What follows is a list of currently available documents. See the previous list for an updated list.<br />
<br /></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1">The documents organized by categories. </span></span></span></span></span></div>
<div style="text-align: justify;">
</div>
<h3 style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1">Control</span></span></span></span></span></h3>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1">Documents related to mechanical and control subjects</span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><a href="https://colab.research.google.com/drive/1GAjq-R4cTyVu90KjOd9P0_r4L1dNJNx9" target="_blank">Pendulum</a><br /><span class="">Document that explains the physical behavior of a pendulum and that allows to simulate it.</span><br /><a href="https://colab.research.google.com/drive/1GAjq-R4cTyVu90KjOd9P0_r4L1dNJNx9"><span class="">https://colab.research.google.com/drive/1GAjq-R4cTyVu90KjOd9P0_r4L1dNJNx9</span></a></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik9cJD1-3l9I-mmZEv9qzHBmQ8nyRVylvB0GL6Mr-eg6UQGOQDbRC2wIisvl0vqq57JqhTf-md9TylJTVFIbr-6BEO84ZvO2iqV_oJFxieR7t4URPJuv21JSyy7ldb7TJpbIUiEK9TZyKh/s1600/Pendulum.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="468" data-original-width="503" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik9cJD1-3l9I-mmZEv9qzHBmQ8nyRVylvB0GL6Mr-eg6UQGOQDbRC2wIisvl0vqq57JqhTf-md9TylJTVFIbr-6BEO84ZvO2iqV_oJFxieR7t4URPJuv21JSyy7ldb7TJpbIUiEK9TZyKh/s200/Pendulum.png" width="200" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><a href="https://colab.research.google.com/drive/1uOeXitZxeUZZdZlmT8d5pZNUr0QXrb5E#scrollTo=t6-DFI-JwoZr" target="_blank">DC Motor</a><br /><span class="">A document that explains how a DC motor works and also allows you to simulate its dynamic behavior.</span><br /><a href="https://colab.research.google.com/drive/1uOeXitZxeUZZdZlmT8d5pZNUr0QXrb5E#scrollTo=t6-DFI-JwoZr"><span class="">https://colab.research.google.com/drive/1uOeXitZxeUZZdZlmT8d5pZNUr0QXrb5E#scrollTo=t6-DFI-JwoZr</span></a></span></span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGuaczKXTt_F9Gz9u84rIfw-JQHiiy6e5Eq4ECw5opmsT1VWPDuU6KzEvRjQuIN9lqBrJowy-qVq_RjzZuJOpPWFJPaBg3YLJTG_IrPkE8oBC6QbHiCNscjJ5Es3-X60MKSrLVcO9D8vpM/s1600/Motor+Blocks.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="618" data-original-width="1162" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGuaczKXTt_F9Gz9u84rIfw-JQHiiy6e5Eq4ECw5opmsT1VWPDuU6KzEvRjQuIN9lqBrJowy-qVq_RjzZuJOpPWFJPaBg3YLJTG_IrPkE8oBC6QbHiCNscjJ5Es3-X60MKSrLVcO9D8vpM/s320/Motor+Blocks.png" width="320" /></a></div>
<br />
<span class="" id="result_box" lang="en" tabindex="-1"><a href="https://colab.research.google.com/drive/1Jpje3UWRr-ZvVKR1SlcwoM-KI1OGBNYA#scrollTo=fmPgBsrTlnvd" target="_blank">Inverted pendulum</a><br /><span class="">A
document that deals with the control of an inverted pendulum, which is
intrinsically unstable, and which explains how it can be stabilized
using a PID controller and an electric motor.</span><br /><a href="https://colab.research.google.com/drive/1Jpje3UWRr-ZvVKR1SlcwoM-KI1OGBNYA#scrollTo=fmPgBsrTlnvd"><span class="">https://colab.research.google.com/drive/1Jpje3UWRr-ZvVKR1SlcwoM-KI1OGBNYA#scrollTo=fmPgBsrTlnvd</span></a></span><br />
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR2FRjDXdCl6Mz9-ZT4h8tqQGhfGTg0i111XPxj3uDWopl-u3OYYGy4GXMc1PkJl33tJ586CpjEV33ZbHFmyDkUThy3ZRppLKuFnx3WKjCmqlsvRPssth_BCU3rBglC_bLOjmfjlR5Emob/s1600/Inverted+Pendulum.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="353" data-original-width="381" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR2FRjDXdCl6Mz9-ZT4h8tqQGhfGTg0i111XPxj3uDWopl-u3OYYGy4GXMc1PkJl33tJ586CpjEV33ZbHFmyDkUThy3ZRppLKuFnx3WKjCmqlsvRPssth_BCU3rBglC_bLOjmfjlR5Emob/s200/Inverted+Pendulum.png" width="200" /></a></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class=""> </span></span> </span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1">Analog electronics</span></span></span></span></span></span></span></span></span></h3>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1">Documents related to analog electronics</span></span></span></span></span></span></span></span></span><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"> </span> </span></span></span></span></span></span></span></span></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""></span></span></span></span><br />
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><a href="https://colab.research.google.com/drive/1o57vd-1jAhsuXuMI_HxixXEJiKh7cqGU" target="_blank"><span class="">Common Emitter</span></a><br /><span class="">Document on the operation of a simple amplifier based on a BJT in common emitter configuration.</span><br /><a href="https://colab.research.google.com/drive/1o57vd-1jAhsuXuMI_HxixXEJiKh7cqGU"><span class="">https://colab.research.google.com/drive/1o57vd-1jAhsuXuMI_HxixXEJiKh7cqGU</span></a></span></span></span></span></span></span></span></span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""> </span></span></span></span></span></span></span></span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieYF3uO02sMjuhggM7Xfj3a0aB6eEzKfIUdGaZO3BEfojp3otGErWqQwpd8MKbqnqW9DuGpK6Q-QnhXMnSa1kzmlSvBWHKcqRSnGaTr6XOEn4aGI7K-PV0h9xMUvSChUU4qRC87GFBhvPg/s1600/Common_Emitter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="434" data-original-width="556" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieYF3uO02sMjuhggM7Xfj3a0aB6eEzKfIUdGaZO3BEfojp3otGErWqQwpd8MKbqnqW9DuGpK6Q-QnhXMnSa1kzmlSvBWHKcqRSnGaTr6XOEn4aGI7K-PV0h9xMUvSChUU4qRC87GFBhvPg/s320/Common_Emitter.png" width="320" /></a></div>
<div style="text-align: justify;">
<span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class="" id="result_box" lang="en" tabindex="-1"><span class=""> </span></span> </span> </span></span></span></span></span></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-41112997642562720612018-03-01T17:51:00.001+01:002018-03-01T17:51:35.885+01:00SLab updated to v1.3I have just updated the SLab project in <a href="https://github.com/R6500/SLab" target="_blank">Github</a>.<br />
<br />
The new version afects three of the python source files:<br />
slab.py, slab_meas.py, slab_fft.py<br />
<br />
With those changes SLab should work both in Python 2.7 and 3.x branchs.<br />
<br />
<div style="text-align: justify;">
I have also added a new script <a href="https://github.com/R6500/SLab/blob/master/Code/slabTest.py" target="_blank">slabTest.py i</a>n the main code folder. This scripts lets you check the basic SLab functionality so you can verify that you have a working SLab environment.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Current SLab version has been checked on Windows under Anaconda with Python 2.7.10 and 3.5.1.</div>
<div style="text-align: justify;">
Basic functionality has also been verified on Linux with Python 2.7.</div>
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-43597896121640156082018-02-19T11:12:00.001+01:002018-02-19T11:15:44.832+01:00About SLab DAC calibrations<div style="text-align: justify;">
This is a brief article about when you can rely on the DAC calibrations on the SLab system.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you see the CurveVV command in the DC module that is used to obtain a DC voltage transfer curve of a Circuit Under Test (CUT), you will notice that you can use the basic configuration that uses DAC1 and ADC1:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFibu28eIcm2CEnBS4ZGgrmSImYG4e9ZKAo6Pym7U6XqC7dwGFVYWGRSKtjyyUKT32akSeLztMZU6srn-r4Eyn0B1UWHlqWKvdQ0u7z_Icd8ZPcnNA-NFcQbwrJJ7k5vuCW9UEjrp0l1Fn/s1600/curveVV+configuration+A.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="181" data-original-width="380" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFibu28eIcm2CEnBS4ZGgrmSImYG4e9ZKAo6Pym7U6XqC7dwGFVYWGRSKtjyyUKT32akSeLztMZU6srn-r4Eyn0B1UWHlqWKvdQ0u7z_Icd8ZPcnNA-NFcQbwrJJ7k5vuCW9UEjrp0l1Fn/s400/curveVV+configuration+A.jpg" width="400" /></a></div>
<br />
Or a configuration that uses DAC1, ADC1 and ADC2:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjzRddSpcsrRbWqD2paKIFy6hH2mYLypBViU0cHyMT6hKL5n8iXCGlsx8elhdZpiX659pvfifsxK4cdXAmPbI18FhUwn45pcLR2DEOwKqIQunIKuyJ4A3sOzVaczmLfgZ_zhfajrdGiXZ2/s1600/curveVV+configuration+B.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="182" data-original-width="390" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjzRddSpcsrRbWqD2paKIFy6hH2mYLypBViU0cHyMT6hKL5n8iXCGlsx8elhdZpiX659pvfifsxK4cdXAmPbI18FhUwn45pcLR2DEOwKqIQunIKuyJ4A3sOzVaczmLfgZ_zhfajrdGiXZ2/s400/curveVV+configuration+B.jpg" width="400" /></a></div>
<div style="text-align: justify;">
If the DAC1 operation has ben properly calibrated, you may ask why do you need to take measurements on Vi using ADC2.</div>
<br />
Well, the truth is that you cannot always rely on the DAC calibrations because they can depend on the load applied to their nodes. If you recall the DAC driver circuits, they are based on follower opamps or non inverting amplifiers.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikTEhfsKpFhyU5MzRl6XXmDV1oRGmNvAwkNfnH22TsrZRwWOblTnUt6TSLpAM87apAyAyZmtEhzoyQCPvb5zUmBODaWEcoHzCS9ru64YwuxLY6odiTkL9unRlZb7SeV5GJkWg99HIgaUam/s1600/SLab+buffering.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="603" data-original-width="986" height="390" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikTEhfsKpFhyU5MzRl6XXmDV1oRGmNvAwkNfnH22TsrZRwWOblTnUt6TSLpAM87apAyAyZmtEhzoyQCPvb5zUmBODaWEcoHzCS9ru64YwuxLY6odiTkL9unRlZb7SeV5GJkWg99HIgaUam/s640/SLab+buffering.jpg" width="640" /></a></div>
<br />
<div style="text-align: justify;">
Opamps have limited current capabilities. This doesn't affect to the ADCs because no current is drawn on the ADC nodes, but you can put any load on the DAC nodes and the opamps won't alway be able to cope with it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The following figure shows a test circuit for the DAC output load capabilities. DAC 1 is connected to ADC1 and a grounded resistor R.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheiACmKz0o1vv_VWjHWH96LwrZs1dxM7lteS0JWPy-_p4m4yts6Dn1Y3R5iUsStiRrVXpzsdrISz2fLmfl6QZx13BTEN7fD1gCeZJSLn2RX_aHo87IcjLf3SNDbQRxAhV4Clrir6wqHW7E/s1600/Grounded.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="180" data-original-width="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheiACmKz0o1vv_VWjHWH96LwrZs1dxM7lteS0JWPy-_p4m4yts6Dn1Y3R5iUsStiRrVXpzsdrISz2fLmfl6QZx13BTEN7fD1gCeZJSLn2RX_aHo87IcjLf3SNDbQRxAhV4Clrir6wqHW7E/s1600/Grounded.jpg" /></a></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The following figure shows the ADC readings as function of the DAC values set for different values of the resistor R. You can see that the programmed DAC value gives the proper voltage to the node for resistances of 10k or more. For lower loads there is a degradation that increases at higher voltages. For a 100 Ohm load, the voltage is only good up to about 1.5 Volt with some degradation before reaching this point.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBToxSg-K79yrvbtPhJrB42BceaJnGVbibItVgzeWCKCOsRMcrb-jf0uxtst-ZMyX1O4wesnSBgClJQ2rpigrlR-eK5IJLUpq-Lqt9B-6-NAFmWvpPbYADfPLEuNNIcweR-UaokiDoiycg/s1600/DAC1+with+grounded+load.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="615" data-original-width="815" height="482" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBToxSg-K79yrvbtPhJrB42BceaJnGVbibItVgzeWCKCOsRMcrb-jf0uxtst-ZMyX1O4wesnSBgClJQ2rpigrlR-eK5IJLUpq-Lqt9B-6-NAFmWvpPbYADfPLEuNNIcweR-UaokiDoiycg/s640/DAC1+with+grounded+load.png" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Is this behavior expected? Well, the <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/21733j.pdf" target="_blank">MCP6002 opamp datasheet</a> shows the following maximum short circuit currents:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpX9RtuYRM9paIA74evb_Ny2MtmaW6uzxYplVDLaUrGI_YZeeAwK6bCM9V5jw0d3QqikIXO8lmccQmobaShiuGwkNm9qktYTWNVHi8tZGPnAsjmDT3z1A8rezNAFDRuAJhpqTuCgd8j549/s1600/Opamp+Isc.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="310" data-original-width="473" height="261" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpX9RtuYRM9paIA74evb_Ny2MtmaW6uzxYplVDLaUrGI_YZeeAwK6bCM9V5jw0d3QqikIXO8lmccQmobaShiuGwkNm9qktYTWNVHi8tZGPnAsjmDT3z1A8rezNAFDRuAJhpqTuCgd8j549/s400/Opamp+Isc.jpg" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At 3.3V and 25ºC the short circuit current is about 15 mA. For a 100 Ohm load that meas that the maximum voltage will be 1.5 V. This is the result shown on the measurement curves.<br />
For a 1k resistor, the voltage limit should be 15 V, but we see some degradation before reaching the 3.3V limit. Why is that?<br />
<br />
The limit in this case is the voltage headroom. The MCP6002 is a full rail opamp. That means that it should de capable to reach both supply rails. In practice, however, no opamp can be really full rail. You need some voltage difference between the output and the rails to maintain the output current. This minimum voltage difference to the rails is the Headroom voltage. The following figure, taken from the opamp datasheet shows the needed voltage to the rails as function of the current. </div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5NbUeogamjGhh7QWnQ8MtDYOiMH2ro8vFztdj2q4XwKHCToLhyZ6721qkhyphenhyphen_2GMpixCvNDsclxj4y-gSOTsM_mBORYSs_eeEKmroNXHEcT4q6r2PkSmpJKLrgLyVRWfQzUye1a3Zj8eo-/s1600/Headroom.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="301" data-original-width="458" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5NbUeogamjGhh7QWnQ8MtDYOiMH2ro8vFztdj2q4XwKHCToLhyZ6721qkhyphenhyphen_2GMpixCvNDsclxj4y-gSOTsM_mBORYSs_eeEKmroNXHEcT4q6r2PkSmpJKLrgLyVRWfQzUye1a3Zj8eo-/s400/Headroom.jpg" width="400" /></a></div>
<br />
In our case, to reach 3.3V using a 1k resistor, we need to provide 3.3mA. From the above curve we can see that we need a headroom of about 100 mV to maintain this current. So we cannot get above 3.2V and that's about what we are seeing in our measurements.<br />
<br /></div>
<div style="text-align: justify;">
The same experiment can be performed for loads connected to Vdd.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIWCRScb3PM3GacK9J1ISgaKNKnUj_sRsCh3pUAuIx_5JrIfZPqjZzmcpQa0ea7W_2Il-QMq84hnlH2YhqHDdJb4C4xby7k0DXOG1C_M9FOWbTZGGWKD5XEzJcmBJphEBTX2hpuNQlyF59/s1600/To+Vdd.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="197" data-original-width="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIWCRScb3PM3GacK9J1ISgaKNKnUj_sRsCh3pUAuIx_5JrIfZPqjZzmcpQa0ea7W_2Il-QMq84hnlH2YhqHDdJb4C4xby7k0DXOG1C_M9FOWbTZGGWKD5XEzJcmBJphEBTX2hpuNQlyF59/s1600/To+Vdd.jpg" /></a></div>
As you can imagine, the degradation will be, in this case, at the lower voltages, when the opamp needs to sink more current.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO00Et7JshGMe2-muEaLYBSYE7i-bycRmeU10uxWnUfAiJQ798ChXxCPcAWs9j8HJKcPMLTtfJ0qBRx_kOvzB0czaf6br5Qb6qSle2WTIjFcyr_spKFQe84_SvKFFExr2MJifzZzy9kv9m/s1600/DAC1+with+load+at+Vdd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="615" data-original-width="815" height="482" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO00Et7JshGMe2-muEaLYBSYE7i-bycRmeU10uxWnUfAiJQ798ChXxCPcAWs9j8HJKcPMLTtfJ0qBRx_kOvzB0czaf6br5Qb6qSle2WTIjFcyr_spKFQe84_SvKFFExr2MJifzZzy9kv9m/s640/DAC1+with+load+at+Vdd.png" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For a specified 15 mA short circuit current the maximum voltage drop to Vcc will be 1.5 V on a 100 Ohm load. As Vdd is 3.3 V, that gives a voltage of 1.8 V minimum voltage respect to ground. Just about the limit we are measuring.<br />
The headroom voltage also explains why we cannot reach the 0V limit with a 1k load. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
That's all for this article. When you driving voltages using SLab or any other instrument like a power supply or a function generator, there are always limits to the load you can put on the driven node.</div>
<div style="text-align: justify;">
If you are not sure that the node can be properly driven, it is a good idea to measure the REAL voltage value on the node instead of relying on the voltage selected on the instrument.<br />
<br />
In the particular case of the CurveVV command, using ADC 2 on the node driven by DAC 1 guarantees that the final curves you obtain relate the REAL voltage input to the output voltage on the circuit.<br />
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-52254550061445369742018-02-12T10:34:00.000+01:002018-02-19T19:27:28.815+01:00SLab First ReleaseThis article is also available, in spanish, in the companion <a href="http://aim65.blogspot.com.es/2018/02/primera-version-de-slab.html" target="_blank">AIM65 blog</a>. <br />
<br />
This is the first release of Small Lab (SLab), a project I have been working on for a long time. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFAjuwIXKmBGohJ8EPBj9fQbX5faYqvQP8b6AmlQOWsGgQim6ppkF6atLDdr57l-3fAgn6Vcfspa4Bs58l6ds68xmf4vCfPZHohIWjDeSpe_lDEaa_57K2RW7YcxctkY_KNdMH6JJn2_2I/s1600/Logo+Powered+Color.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="476" data-original-width="1128" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFAjuwIXKmBGohJ8EPBj9fQbX5faYqvQP8b6AmlQOWsGgQim6ppkF6atLDdr57l-3fAgn6Vcfspa4Bs58l6ds68xmf4vCfPZHohIWjDeSpe_lDEaa_57K2RW7YcxctkY_KNdMH6JJn2_2I/s200/Logo+Powered+Color.png" width="200" /></a></div>
<br />
<div style="text-align: justify;">
SLab is a project to develop a tool for hands-on electronics learning on a minimum budget. The idea is to provide, to anyone who wants it, a system capable to inject excitations on a circuit and obtain measurements so that the circuit operation can be understand by practice.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Low cost means really low cost, below 40€ in my rough calculations for a full system with instrumentation and components to build the circuits.</div>
<div style="text-align: justify;">
<br />
<h3>
SLab System (and disclaimer) </h3>
The SLab system is composed of a chain of components as shown in the figure below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbAFwK0cR-IEE5ogZbvrKxLiuyaesWppIbQsBGC3whVp1nn-T275NP-d0mu6cgO0DuTWBhlZ1AeUz6w8utWsZA8Kqyr_VXOeZlIvJnJ2UJRhxQV94Fdf32v8ga5lk7Zd5LuBqs4UqaVAs2/s1600/Slab+System.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="349" data-original-width="1156" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbAFwK0cR-IEE5ogZbvrKxLiuyaesWppIbQsBGC3whVp1nn-T275NP-d0mu6cgO0DuTWBhlZ1AeUz6w8utWsZA8Kqyr_VXOeZlIvJnJ2UJRhxQV94Fdf32v8ga5lk7Zd5LuBqs4UqaVAs2/s640/Slab+System.png" width="640" /></a></div>
First we have our Circuit Under Test (CUT). This is a circuit that enables us to learn somethig about electronics. Then we have a hardware board that is able to inject signals on the circuit and measure the voltage on some of its nodes. The board connects to a PC where some Python modules interact with the board by sending command throug a serial over USB COM link. You are at the right end of the chain sending high level commands for the SLab system to execute. Those commands, if needed, can be written on Python scripts to ease repetitive tasks. You can also create your own libraries that connect with the SLab ones and extend the system capabilities.<br />
<br />
Note the red isolation zone in the previous drawing. You are only supposed to connect the Circuit Under Test (CUT) to the hardware board. No electrical connection, except the USB cable, shall go outside of the protection zone. The CUT shall also be powered only by the hardware board.<br />
<br />
If you want an additional layer of protection, or you are not sure of your own actions, you can use an isolated USB cable together with a powered HUB to run the harware board like in the figure below. That way you could damage the hardware board or the HUB but the PC will be more secure.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYBnNvtTRkjVdM7LftOKeKrpTOBfaY-X4Gqy_o0AyK9jYU2yxiUHvjLwjsdh86sYfgCJjyCh_EWn-Z_u97y8lTydYSKh7g8Dyc4rpA2G31RhjSamflWK1MMGM_IjtvtGOuO4qdX2GuE_6g/s1600/Isolation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="487" data-original-width="1187" height="262" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYBnNvtTRkjVdM7LftOKeKrpTOBfaY-X4Gqy_o0AyK9jYU2yxiUHvjLwjsdh86sYfgCJjyCh_EWn-Z_u97y8lTydYSKh7g8Dyc4rpA2G31RhjSamflWK1MMGM_IjtvtGOuO4qdX2GuE_6g/s640/Isolation.png" width="640" /></a></div>
Either way the following disclaimer apply:<br />
<br />
<b><span style="color: red;">The author of this document takes no responsibility for any damage to you, your properties or equipment due to the use of the SLab system. This is true either if you are following the proper procedures or not.</span></b><br />
<br /></div>
<div style="text-align: justify;">
</div>
<h3 style="text-align: justify;">
The hardware</h3>
<div style="text-align: justify;">
In order to keep costs as low as possible, the main hardware element of the system is a microcontroller demonstration board. The chosen board for this first release is the <a href="http://www.st.com/en/evaluation-tools/nucleo-f303re.html" target="_blank">STM32 Nucleo64 F303RE board</a>.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpTjKjm0DAy-E324zcFaNZnS-s2cucq5LLUbBz0PeM8aumfyQCVSSt-FtZsgJ9GNpSSeJtDiAaDMudNO4ZTJacZT09SxMnRHVIZ37PtiYddSOcFktUBOAbzBvbnzteAWtbnzfAWT5U0n5t/s1600/Nucleo+F303RE.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="468" data-original-width="600" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpTjKjm0DAy-E324zcFaNZnS-s2cucq5LLUbBz0PeM8aumfyQCVSSt-FtZsgJ9GNpSSeJtDiAaDMudNO4ZTJacZT09SxMnRHVIZ37PtiYddSOcFktUBOAbzBvbnzteAWtbnzfAWT5U0n5t/s320/Nucleo+F303RE.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Nucleo F303RE Board</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Why this board?. Well, it is cheap, currently only 9€ at <a href="http://es.farnell.com/stmicroelectronics/nucleo-f303re/placa-desarrollo-st-link-nucleo/dp/2467271?ost=f303re&ddkey=http%3Aes-ES%2FElement14_Spain%2Fsearch" target="_blank">farnell</a> and it is quite capable. It includes the <a href="http://www.st.com/content/ccc/resource/technical/document/datasheet/2c/6f/d7/64/1f/a3/4f/c9/DM00118585.pdf/files/DM00118585.pdf/jcr:content/translations/en.DM00118585.pdf" target="_blank">STM32F303RE</a> microcontroller that features two 12 bit <a href="https://en.wikipedia.org/wiki/Digital-to-analog_converter" target="_blank">DACs</a>, four 12 bit <a href="https://en.wikipedia.org/wiki/Analog-to-digital_converter" target="_blank">ADCs</a>, 512KB of flash and 80KB of SRAM. It also is <a href="https://os.mbed.com/platforms/ST-Nucleo-F303RE/" target="_blank">MBED</a> enabled. That means that installing a binary firmware is just drag&drop. Moreover, the USB communication includes a serial over USB Com link that installs the driver as soon as you connect the board to a computer. Finally, as MBED is so easy to use, and the board is much more powerful than most Arduinos, having this board also enables you to play with firmware developement in your spare time if you want to.<br />
<br />
Using the proper software on the board, you can instruct it to send signals out of the DACs and read signals with the ADC inputs. The problem is that you usually need some buffering to prevent loading effects when you connect the ADCs and DACs to a Circuit Under Test (CUT).<br />
The following figure shows a suitable solution based on opamp <a href="https://en.wikipedia.org/wiki/Buffer_amplifier" target="_blank">voltage followers</a> for all DAC outputs and ADC inputs. See that it also adds a LED and a resistor so that we can see that the CUT is properly powered.</div>
<div style="text-align: justify;">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE2jswifIYK3WJ5l69YOmk8kCTAVeMvetEEyUfqkElvQINkWXIIggCrVX3i1BG_dFBh-PmiE8Dnx0XhPyvEgMSJdiq_harqPq5d5QCIyacu9SAL1w3eDhJj9AxF6YJfX1hdg4xXMMipVY5/s1600/Drivers.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="486" data-original-width="790" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE2jswifIYK3WJ5l69YOmk8kCTAVeMvetEEyUfqkElvQINkWXIIggCrVX3i1BG_dFBh-PmiE8Dnx0XhPyvEgMSJdiq_harqPq5d5QCIyacu9SAL1w3eDhJj9AxF6YJfX1hdg4xXMMipVY5/s640/Drivers.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Drivers to interface the circuit</td></tr>
</tbody></table>
<br />
Note that DAC2, associated to pin D13, has a non inverter amplifier instead of a follower. This is needed because, in the F303RE board, the D13 pin is also connected to a LED, that prevents us to use the full range of the DAC and we are limited only to le lower half of the full range. This is no problem, however, as we will see later.<br />
<br />
You can implement the driver circuit in a solderless breadboard and you have plenty of space left to put a circuit to be measured. The following figure shows the F303RE board, the driver circuit and a test circuit composed of a resistor and a diode.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAkRVbdXrzW8AWph0yIA3_IPJv_yWwKav8w2mrtR6au_NcHkToljGboN4YQTxshVKXBVPl_9lJCqoAEmZs95MSD4tWWyW-g3qC_XBrju8V3-XS6M7p8G2t4UqrZrcgzNneIbKq0hZuIa_x/s1600/BB+Circuit+2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="453" data-original-width="789" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAkRVbdXrzW8AWph0yIA3_IPJv_yWwKav8w2mrtR6au_NcHkToljGboN4YQTxshVKXBVPl_9lJCqoAEmZs95MSD4tWWyW-g3qC_XBrju8V3-XS6M7p8G2t4UqrZrcgzNneIbKq0hZuIa_x/s400/BB+Circuit+2.jpg" width="400" /></a></div>
<br /></div>
<div style="text-align: justify;">
<br />
If you have the capabilities to solder you can implement the driver circuit in a shield. The following figure shows the drivers on a shield board designed for Arduino. This is ok because F303RE board features Arduino compatible connectors.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaqciEVTMmYnN3Hf-4PsXLCHAOc7zu_hAs6B45gk4z9lHjoo4HnqAYr8eSFnaDJ9MeG7dMxffAGlFON4UF4zHL5-36AIj4jXd_Fs__I8RVdN-6PSDb0QISoOYsgtZAUgCTs66vjBgNYqDh/s1600/Shield+1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="666" data-original-width="800" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaqciEVTMmYnN3Hf-4PsXLCHAOc7zu_hAs6B45gk4z9lHjoo4HnqAYr8eSFnaDJ9MeG7dMxffAGlFON4UF4zHL5-36AIj4jXd_Fs__I8RVdN-6PSDb0QISoOYsgtZAUgCTs66vjBgNYqDh/s320/Shield+1.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Driver Shield</td></tr>
</tbody></table>
<br />
If you have option to build your own PCBs, you can create a better shield. The following figure shows the <i>"Long Board"</i>. It includes the F303RE board, a milled PCB shield with the drivers, a solderless breadboard for the test circuit and an aluminium clad to join it all. A small electronics lab in a 28 x 8 cm form factor. The details are in the <a href="https://github.com/R6500/SLab/tree/master/Docs" target="_blank">SLab documentation</a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFXrDMzEkt_Ad5F6GbKlQqnrkClStEzBAeEov0c7Ik-xZKGO4ispHLqImyKeetP5VKKoLiAAduktThtdl2VyawtWiO9h4pJ8CNko9_mNU88UG2RrQ_jo3eUc2U68DwTMRZfRdF1ews8r65/s1600/Long+Board.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="329" data-original-width="1100" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFXrDMzEkt_Ad5F6GbKlQqnrkClStEzBAeEov0c7Ik-xZKGO4ispHLqImyKeetP5VKKoLiAAduktThtdl2VyawtWiO9h4pJ8CNko9_mNU88UG2RrQ_jo3eUc2U68DwTMRZfRdF1ews8r65/s640/Long+Board.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Long Board</td></tr>
</tbody></table>
The following image shows the shield diagram wit its 17 male pins. In includes two GND pins, a 3.3V Vdd pin, the two buffered DAC outputs, the four buffered ADC inputs and eight digital I/O lines. All of that can be controlled from Python code.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA8tQDiGpyFN7NCfc7xKtJoEcwBfuQ28LiGzgi94qeMSzbg-_i_LlJLTAp1grw15CWEOod_olLhpOCfZmKP_5fbKXYl8dCOgDgrBIHFcnaoC2tvjkdS2KqOomWuO81VCsbNbDNotT52VvP/s1600/Shield+Diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="482" data-original-width="699" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA8tQDiGpyFN7NCfc7xKtJoEcwBfuQ28LiGzgi94qeMSzbg-_i_LlJLTAp1grw15CWEOod_olLhpOCfZmKP_5fbKXYl8dCOgDgrBIHFcnaoC2tvjkdS2KqOomWuO81VCsbNbDNotT52VvP/s320/Shield+Diagram.png" width="320" /></a></div>
Depending on your resources and capabilities you can use the any of the hardware options to mix together the demonstration MCU board, the drivers, and space to mount a circit to test. Either way, in the end, you will have the elements shown in the following figure: A Vdd supply, two DAC outputs and four ADC inputs. You can also add the digital I/O but this is not needed for most analog circuits.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc3_UwOCpr5sK1vNg3NhX2RnVEeRX-XlnuJpHSAwEDcLa8ZnKTA1MO4oeVDT6DxAh0YufA3c8Sv39Dazs_HRK7N9cpuLJ5fVwUzeNmWbWD2IOshBQm7PNTPWPWSME0un0NPdLN1uMy8XIY/s1600/SLab+Elements.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="240" data-original-width="817" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc3_UwOCpr5sK1vNg3NhX2RnVEeRX-XlnuJpHSAwEDcLa8ZnKTA1MO4oeVDT6DxAh0YufA3c8Sv39Dazs_HRK7N9cpuLJ5fVwUzeNmWbWD2IOshBQm7PNTPWPWSME0un0NPdLN1uMy8XIY/s640/SLab+Elements.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">SLab elements</td></tr>
</tbody></table>
<br />
<br />
By using the proposed <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/21733j.pdf" target="_blank">MCP6002 and MCP6004</a> operational amplifier chips, you get very high input impedance on the ADCs, and nearly full rail operation inside the 3.3V range of the board. The current capabilities of the opamps are not so great, but, as we are powering the system from the USB port, we are quite limited in the currents anyway.<br />
<br />
It would be possible to design a driver interface circuit with more voltage and current range. And it will be done in the future, but, for now, the idea is to keep the system as cheap and simple as possible. Making a better interface circuit is not difficult at all, the problem is making it available, at low cost, for everyone.<br />
<br /></div>
<div style="text-align: justify;">
<h3>
The software</h3>
</div>
<div style="text-align: justify;">
Bad software can make a low budget instrumentation device a nightmare to operate, and developing good software is difficult and time consuming. For this project, I have taken profit of the huge <a href="https://www.python.org/" target="_blank">Python</a> library and, in particular, of some <a href="https://www.scipy.org/" target="_blank">SciPy </a>libraries (NumPy and Matplotlib).<br />
<br />
But Python is not easy to use on the F303RE board, and also, it would be very inefficient for performing timed measurement. So,the full system needs an additional element: the board firmware that is the middle element between the board ADCs and DACs and the Python code in the PC. It acts as a server for commands from a client PC.<br />
<br />
The software structure somewhat resembles the <a href="https://github.com/firmata/protocol" target="_blank">firmata</a> protocol with a server on the hardware board and a client on the PC. But it is not firmata. The main difference, apart from the fact that the communication is not MIDI, is that commands can include waveform generation and the reading of sequences of voltage values at constant rates (up to about 80kHz with the current firmware). Some functionalities, like the DC ones, could be performed adding a Python layer to firmata, but not all of them, specially for the AC ones. In general, the SLab system, it is more oriented towards analog signals than digital ones.<br />
<br />
<br /></div>
<div style="text-align: justify;">
<b><u>The board firmware </u></b><br />
<br />
As the F303RE board is MBED enabled, the first version of the firmware has been developed in the MBED cloud compiler. I plan on designing a future version of the firmware, probably without MBED, to optimize the code as close as the board limits as possible. On the following table you can see that, when using only one channel, sampling time in transient measurements can be as low as 13 microseconds. This is not too bad for a microcontroller board, but far from the F303RE capabilities that can get sample rates in the MHz range. Most of the problems when using more than one channel are due to the fact that MBED uses only one ADC for all analog inputs son all four channels cannot be read at the same time. There is always room for improvement, and the firmware will be sure improved. When I have time, that's it. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWUKvY_S_u5f2Hry-TxjXL7szlbo_BfokoOrY7vZNUYunI7uY65VwcLv-_LJ_eXvZOFe5ujfbemFi2stTdZKo6A-HzenjlExCgxkPiQdTb8qhgWC9Ku-lmyv9rjqpyglKa5eKG66GDmMDs/s1600/Capabilities.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="420" data-original-width="690" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWUKvY_S_u5f2Hry-TxjXL7szlbo_BfokoOrY7vZNUYunI7uY65VwcLv-_LJ_eXvZOFe5ujfbemFi2stTdZKo6A-HzenjlExCgxkPiQdTb8qhgWC9Ku-lmyv9rjqpyglKa5eKG66GDmMDs/s400/Capabilities.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Current firmware sample time transient capabilities</td></tr>
</tbody></table>
The board firmware communicates with the PC and basically receives commands, interfaces with the circuit through the DACs and ADCs, and reply a response to the PC. Some examples of commands are:<br />
<ul>
<li>Set a DAC voltage value</li>
<li>Read the voltage on an ADC input</li>
<li>Read a sequence of ADC values with at a constant sample rate</li>
<li>Store on the board SRAM waveforms to be generated later on the DACs</li>
<li>Generate waveforms and read the circuit response using at a constant sample rate</li>
</ul>
</div>
<div style="text-align: justify;">
The most complex thing the board firmware can do is to generate two different arbitrary waveforms on the two DAC outputs and simultaneously read the four ADC inputs. After generatings the waves and collecting data for some time, the data is sent to the PC for processing.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The communication protocol between the board and the PC is fully documented so, if you have a board with at least two DACs and four ADC inputs and you know about firmware developement, you can create your own firmware to interface with the SLab system. The communication link implements CRC checking, but, as USB communication is quite reliable at short distances, the main purpose of the CRC is to detect software bugs.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The board capabilities are read from the board uppon connection, so no modifications need to be performed at the PC side if you develop a firmware for a new board.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Current board firmware is about 2500 lines of "C" code. You can find it in the <a href="https://github.com/R6500/SLab/tree/master/Firmware" target="_blank">SLab Github project</a>. But, if you only want to use it, just download the binnary file and drag&drop it on the board to program it.<br />
<br />
The firmware code is also <a href="https://os.mbed.com/users/vic20/code/SLab_Python/" target="_blank">available on MBED</a>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<u><b>The SLab Python code</b></u></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The board firmware interfaces with the circuit and needs to be as optimized as possible because it is what set the limits of the full system. But one important part of the software is Python code. Currently the SLab project has next to 6000 lines of Python code. It really is not that much because of comments and blank lines. Although comments are also important because they generate the SLab help subsystem. No exactly <a href="http://www.stack.nl/~dimitri/doxygen/" target="_blank">doxygen</a> but is the same idea.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In order to work with a circuit, you open a Python interpreter, import the SLab module, then call SLab functions that communicate with the board, perform excitations and/or measurements and return the results. Thanks to <a href="https://matplotlib.org/" target="_blank">Matplotlib</a> the results can be shown on the screen, and, thanks to <a href="http://www.numpy.org/" target="_blank">NumPy</a>, the results can be manipulated to your heart's content.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
All the SLab Python code is included in the same <a href="https://github.com/R6500/SLab/tree/master/Code" target="_blank">Github project</a> as the firmware code. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first layer of the Python code is the calibration code. How do you obtain good measuments from instruments? By proper calibration, off course. Before using the board you should calibrate it. From the calibration procedure you obtain a set of curves, one for each DAC and ADC that describe how the real values relate to the inputs or outputs of those devices. As an example, the following figure shows the DAC ratiometric calibration curves that include the drivers indicated on the previous schematic. Note how DAC2 has a slope of two due to the non inverting amplifier operation. But you don't need to bother as calibration takes care of that. Once the calibration is completed, you can forget about it, SLab takes care of the details internally on each measurement.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhjLrKFGejkvdLE4v4W9zMxNoLymodWJwd0BemotMAFVElcqKCfxHwSNAzqMPqg9Bn7_40Oxpy6Cnc1N29Tkfas1zTWAJqT0TWCGkelpOfGpBqm-nME-8rKEa26k4R6uBa6pGhdMclYhMB/s1600/DAC+calibration.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="366" data-original-width="466" height="313" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhjLrKFGejkvdLE4v4W9zMxNoLymodWJwd0BemotMAFVElcqKCfxHwSNAzqMPqg9Bn7_40Oxpy6Cnc1N29Tkfas1zTWAJqT0TWCGkelpOfGpBqm-nME-8rKEa26k4R6uBa6pGhdMclYhMB/s400/DAC+calibration.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">DAC Calibration Curves</td></tr>
</tbody></table>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The last layer of the SLab code are the functions that the user can call. Those functions indicate the board to do something and return a result, if available. It can be as simple as setting one DAC to a given voltage value or as complex as measuring the distortion that a circuit induces on a sinewave or obtaining a bode plot by obtaining the response to several sinewaves. The simple commands are just directly sent to the board after calibration. The more complex commands require more Python code work do do their magic from the basic board firmware commands.<br />
<br />
<br />
<h3>
Some examples </h3>
</div>
<div style="text-align: justify;">
Now, some examples of what can be done in SLab. Refer to the <a href="https://github.com/R6500/SLab/tree/master/Docs/SLab%20References" target="_blank">reference documentation</a> for much more examples. Let's start playing with a simple low pass filter:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqRNeQKphUHz3LvBg0hFYm2bOq5VQY3eRveVRKuhzHqufIEIWzPg5SHLRl4UAv8jZNo6Tlug65b3ax2zq2CafA_w92vdHLklybOjqbB-35n616xJpVE8nXOWmrzmAE547SJDuz4-nUD-Zb/s1600/Low+Pass.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="221" data-original-width="493" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqRNeQKphUHz3LvBg0hFYm2bOq5VQY3eRveVRKuhzHqufIEIWzPg5SHLRl4UAv8jZNo6Tlug65b3ax2zq2CafA_w92vdHLklybOjqbB-35n616xJpVE8nXOWmrzmAE547SJDuz4-nUD-Zb/s320/Low+Pass.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Low Pass Filter</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You connect the buffered DAC1 output to the input of the filter and the buffered ADC1 input to the output of the filter. Then, you input the following Python code. You don't need to use interactive mode, but this is always an option.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgacj-tvbcbgalrD0N2MG-CT5JlhaDjY91gYETkXzhIrkPbEVG6bAlDNanhhGen94OFEr-V-Sx8wkXU9MrEEVjmbjkHqcwhDXtE52xbYOvkmZlJzm5X3-NUgGu-6dc8Ib9dzexSzkPFV8vW/s1600/Filter+code+3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="244" data-original-width="453" height="215" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgacj-tvbcbgalrD0N2MG-CT5JlhaDjY91gYETkXzhIrkPbEVG6bAlDNanhhGen94OFEr-V-Sx8wkXU9MrEEVjmbjkHqcwhDXtE52xbYOvkmZlJzm5X3-NUgGu-6dc8Ib9dzexSzkPFV8vW/s400/Filter+code+3.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: justify;">
The first six lines calculate the ideal response of a low pass filter using the NumPy library. The sixth line measures the real frequency response of the circuit connected between DAC1 and ADC1 for the same set of frequencies used on the previous calculations. You will obtain the following graph that compares the idel and real responses right after the last command.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBmkkeTwVa5N03z9lTd5zcSI6VYRFU6ITkGEx2BNhzyMeP2KgRjBjrEHE7GGROWxIUuGLfiRV2qeYBAlcJR5oqUfhn300cJXjsv4REsHLFyeR40MJfo8gPNhoPdBCoiAYxoc5ntdmOyZRZ/s1600/Bode+Plot.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="444" data-original-width="614" height="462" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBmkkeTwVa5N03z9lTd5zcSI6VYRFU6ITkGEx2BNhzyMeP2KgRjBjrEHE7GGROWxIUuGLfiRV2qeYBAlcJR5oqUfhn300cJXjsv4REsHLFyeR40MJfo8gPNhoPdBCoiAYxoc5ntdmOyZRZ/s640/Bode+Plot.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bode Plot</td></tr>
</tbody></table>
<div style="text-align: justify;">
As the SLab system, to keep costs down, features no amplification stages , the dynamic range is not so great and bode plots start to get ugly, specially in the phase graph, after 30 dB atenuation levels.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The circuits can be much more complicated. The following circuit uses DAC1 to generate a sinewave and DAC2 to generate a random noise signal. From those signals, two differential signals with injected common noise are generated on V1 and V2. Then, a differential amplifier is used to reject the noise and recover the signal. On the image, unity gain amplifier are opamp followers and the inverting amplifier is an opamp inverting amplifier.</div>
<div style="text-align: justify;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_8_cL54nbqxQcvBd6qcBGz_2o_Dxb_KrtVVgSooaJtn4UfCycMb9v2cZ4WnC8IzJIImh2dyOGVFEaWSJq8eYEpvZNdH8E4cC0TjZkIO7N_ATRAsT7gQvBUZkxVmqSYOGrOc9zfXTu9A2i/s1600/Noise+Circuit.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="463" data-original-width="960" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_8_cL54nbqxQcvBd6qcBGz_2o_Dxb_KrtVVgSooaJtn4UfCycMb9v2cZ4WnC8IzJIImh2dyOGVFEaWSJq8eYEpvZNdH8E4cC0TjZkIO7N_ATRAsT7gQvBUZkxVmqSYOGrOc9zfXTu9A2i/s640/Noise+Circuit.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Common Noise Reject Circuit</td></tr>
</tbody></table>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The circuit has been mounted on a breadboard and tested using the following code that generates the signals, performs the measurement and plots the results. In this case, althoug SLab includes gaussian and uniform noise generation, we use numpy calls to generate the noise.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8rKunOKxqB7IAo2TqYYp4G_YuJQfvRvQivRH-Ckesy5csSs6660R087MLJ4NP2kZQxCiPYbPZFIOY67fcOhh9Ns7QRVFn4Ykzad4SsrLg0P0sxkVkRnp0wG7CyhOn927DNcovFaDhlUpu/s1600/Noise+code.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="364" data-original-width="728" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8rKunOKxqB7IAo2TqYYp4G_YuJQfvRvQivRH-Ckesy5csSs6660R087MLJ4NP2kZQxCiPYbPZFIOY67fcOhh9Ns7QRVFn4Ykzad4SsrLg0P0sxkVkRnp0wG7CyhOn927DNcovFaDhlUpu/s400/Noise+code.png" width="400" /></a></div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The following graph shows the differential signal, with common noise, at ADC1 and ADC2. It also shows the noise at ADC4 and how the signal is recovered without noise at ADC3. It looks like a simulation but they are real measurements.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfINwVMimmR7BVva1DekIq2-KKGcKAmRMWHZR60dJqiUXsfbF6w5wBExF7hAv6qpRkwDwHa-1ryphVN1wxdmGmXx3SGeLiQ3WHiMPc2dItOJzWcQTZQgYIql-4q5hQwY7pLO03BXt0gcvF/s1600/Noise.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="532" data-original-width="695" height="488" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfINwVMimmR7BVva1DekIq2-KKGcKAmRMWHZR60dJqiUXsfbF6w5wBExF7hAv6qpRkwDwHa-1ryphVN1wxdmGmXx3SGeLiQ3WHiMPc2dItOJzWcQTZQgYIql-4q5hQwY7pLO03BXt0gcvF/s640/Noise.png" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You don't need to provide inputs to the circuit. The following example is an astable circuit, based on a <a href="https://en.wikipedia.org/wiki/Hysteresis" target="_blank">hysteresis</a> comparator that generates a square wave.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeCNW1_Wzp9C9yw2VRx8LdDJWiDu7i8uPWcwEokKAX4c6flH8ZdZusFTisTWMKbYYP89uSxVrllFaLwGNXK01dIu9M-KqnKZkDCWA8gcxtRK_8XWKuONRPrDgdTZN0Nnvv_mWS4T3rN-0H/s1600/Astable.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="374" data-original-width="642" height="371" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeCNW1_Wzp9C9yw2VRx8LdDJWiDu7i8uPWcwEokKAX4c6flH8ZdZusFTisTWMKbYYP89uSxVrllFaLwGNXK01dIu9M-KqnKZkDCWA8gcxtRK_8XWKuONRPrDgdTZN0Nnvv_mWS4T3rN-0H/s640/Astable.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Astable Circuit</td></tr>
</tbody></table>
The measurements of some circuit nodes are shown below. The code is <a href="https://github.com/R6500/SLab/blob/master/Code/Examples/Example_25.py" target="_blank">here</a>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYeiNC5Zgvf_Tm6mG9Hj_ADSvdbVeU__h9VtsqHqmsKyEsNjcvAtSPnQH3GkCMfB3eaUJu395dw1vr04vRdhMdbvfGoNjTmFzuv9tZHMOvRwPWCtfCiEpnQsxJI6gz0ZMJev0Zj7Coq5cP/s1600/Astable+Curves.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="359" data-original-width="451" height="317" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYeiNC5Zgvf_Tm6mG9Hj_ADSvdbVeU__h9VtsqHqmsKyEsNjcvAtSPnQH3GkCMfB3eaUJu395dw1vr04vRdhMdbvfGoNjTmFzuv9tZHMOvRwPWCtfCiEpnQsxJI6gz0ZMJev0Zj7Coq5cP/s400/Astable+Curves.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Astable transient operation</td></tr>
</tbody></table>
<br />
You don't always need to operate with time varying signals. You can also perform DC calculations. The following figure shows the collector current for various base currents on a bipolar transistor. Each point on the curve is an independent DC reading with some time given between the setting the input and reading the output. You can find the associated <a href="https://github.com/R6500/SLab/blob/master/Code/Examples/Example_12.py" target="_blank">code here</a>.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4QbQohi6YRpu88eoHHqsggWbYXoQDdAVc_Xf0IzjSw7FS7YSK7C01vItqsKMOjptaKw61n2UwxOi4_3fyzchLWuSJNgC3tuJ6RslrbpA5wbCEllSKT-0r8KzVElj7mBxeMbLaOO4Gj1de/s1600/BJT.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="375" data-original-width="493" height="303" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4QbQohi6YRpu88eoHHqsggWbYXoQDdAVc_Xf0IzjSw7FS7YSK7C01vItqsKMOjptaKw61n2UwxOi4_3fyzchLWuSJNgC3tuJ6RslrbpA5wbCEllSKT-0r8KzVElj7mBxeMbLaOO4Gj1de/s400/BJT.png" width="400" /></a></div>
<div style="text-align: justify;">
<br />
In the stock SLab system you are limited to the 3.3V range of the Nucleo board. But using the two DACs in bridge configuration can give a -3.3V to +3.3V range in some circuits. This is the case of the full bridge rectifier:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEyeatFylZW0cDBpwMsPwSAG8mcqaKBzBznaaX1-PkQyc48mn5mzVoXOaW0NQXVtiAvcGMyObAhyphenhyphenvqmgP8oCothMd6xp03tKwkSD0Amz8A1ArfcPGuSYz8ebKKJ6qqw3wB_PuoGTAg6iSi/s1600/Full+Bridge.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="403" data-original-width="627" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEyeatFylZW0cDBpwMsPwSAG8mcqaKBzBznaaX1-PkQyc48mn5mzVoXOaW0NQXVtiAvcGMyObAhyphenhyphenvqmgP8oCothMd6xp03tKwkSD0Amz8A1ArfcPGuSYz8ebKKJ6qqw3wB_PuoGTAg6iSi/s400/Full+Bridge.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Full Bridge Circuit</td></tr>
</tbody></table>
The 100k R2 resistor provides some bias on the outputs when no diode is conducting. You can neglect it to ease the understanding of the circuit. The measured input to output voltage response is shown in the following figure:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs0H3I1knDcl8TeK6GAQD0bqisgyQfyUF7DW5hI0tON_-Meq2pgexLz3P4zsQJfDGbJXamjQRSx-lFHsXiQgqlbeTTXx7H5YSyszu55WlRRY_t327SXwjbFCcYHpk2Y-lslMUhy4cqcY4N/s1600/Bridge+Curve.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="373" data-original-width="467" height="318" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs0H3I1knDcl8TeK6GAQD0bqisgyQfyUF7DW5hI0tON_-Meq2pgexLz3P4zsQJfDGbJXamjQRSx-lFHsXiQgqlbeTTXx7H5YSyszu55WlRRY_t327SXwjbFCcYHpk2Y-lslMUhy4cqcY4N/s400/Bridge+Curve.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bridge Voltage Curve</td></tr>
</tbody></table>
You can find the code <a href="https://github.com/R6500/SLab/blob/master/Code/Examples/Example_26.py" target="_blank">here</a>.<br />
<br />
<br />
<br /></div>
<div style="text-align: justify;">
<h3>
The documentation</h3>
</div>
<div style="text-align: justify;">
We have a hardware board. We have the firmware on the board and the Python code on the PC. If you know enough about electronics and want to use the SLab system, you only need to add in the SLab reference documentation and you are on the track for messing with circuits.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The current documentation to setup the hardware and the software and to reference all the SLab functions (there are a lot of them) is 239 pages in several PDF files. The Python code folder, also includes a folder with 31 examples in self contained Python code files. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But one of the SLab project objectives was about learning electronics. That's why the SLab project also contains 222 pages of tutorials about several devices and circuits. Currenty the subjets are:</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<ul>
<li>Linear Operational Amplifier circuits (7 files)</li>
<li>Diode circuits (4 files)</li>
<li>BJT circuits (2 files)</li>
</ul>
</div>
<div style="text-align: justify;">
I will keep adding files when I have time. Perhaps I will also add some experiments on the blog.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<h3>
Last words (for now)</h3>
</div>
<div style="text-align: justify;">
SLab is an ongoing project. The board firware will be improved in the future and more tutorials about circuits will be added. Now we are on the first release version 1.2. All the files can be obtained in <a href="https://github.com/R6500/SLab" target="_blank">Github</a> or in a <a href="https://github.com/R6500/SLab/blob/master/SLab%20v1.2%20(11-02-2018).zip" target="_blank">Zip file</a>, also on Github.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I want to end this blog entry just showing a dual wave arbitrary waveform generated with the SLab system just for fun.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDv2-eb84mIh32PQ5tdu-SBSgVi88ItVtGqRb9qsB6zhpZROvqhKKFh_6FCxQtGwcFrQwJxsUhyphenhyphenjmaoCdPfuHBXVil4X60iH4s3tTy3-efa29uMFOh9IADmXswFLETQjaLD1Iv4GUAo_u1/s1600/Arbitrary+Waves.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="358" data-original-width="568" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDv2-eb84mIh32PQ5tdu-SBSgVi88ItVtGqRb9qsB6zhpZROvqhKKFh_6FCxQtGwcFrQwJxsUhyphenhyphenjmaoCdPfuHBXVil4X60iH4s3tTy3-efa29uMFOh9IADmXswFLETQjaLD1Iv4GUAo_u1/s400/Arbitrary+Waves.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Isn't it pretty? Wanna see <a href="https://github.com/R6500/SLab/blob/master/Code/Examples/Example_31.py" target="_blank">the code</a>?<br />
<br />
<h3>
Article updates</h3>
<br />
19/2/2018<br />
Updated the RC filter code. AC functions now are inside the <b>slab_ac</b> module and not in the main <b>slab</b> Python module.<br />
Added a new system description together with security recommendations and a disclaimer. </div>
<div style="text-align: justify;">
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com4tag:blogger.com,1999:blog-6880821591370697484.post-72161794198209451742016-03-22T19:37:00.000+01:002016-03-22T19:37:51.275+01:00Building a simple circuit probe<br />
<h3>
The Goals</h3>
<div style="text-align: justify;">
Sometimes you need to check one circuit and test some of its nodes. Usually a tester in voltage mode is a good solution, but it has a pair of problems. First, it measures about zero both when the node is driven at zero volts and when the node is floating (not driven at all). Second, it gives the information on the tester display, so you need to take the view from the circuit to the tester to check the voltage.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The proposed circuit somewhat qualifies as a <a href="https://en.wikipedia.org/wiki/Logic_probe" target="_blank">logic probe</a>. It should give no indication when the node is not being driven and it should give a different indication when the node is driven at high or a low voltage.</div>
<br />
<div style="text-align: justify;">
A lot of logic probes are not self powered. They rely on the circuit supply to operate. In my case I would like the probe to be usable also a as a <a href="https://en.wikipedia.org/wiki/Continuity_tester" target="_blank">continuity tester</a>. If we set ground in one point of the circuit and we probe another point, the continuity can be detected between both points because a low level will be driven even if the circuit is not powered at all.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
The Circuit</h3>
<div style="text-align: justify;">
The following figure shows the schematic of the circuit.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiSEHkI9tsFVAOupIQlJDcIGz-Tm4o2B6TBvMqgPtpki_e415xhA5wkwf8tgGxKorVDdvh0HK34tzQaEhMcjFcTJV7TetvKhXIlzMksZ5tU064zcjZughrU-eHBmxaHv1cUOoILIKJwFJq/s1600/Schematic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="491" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiSEHkI9tsFVAOupIQlJDcIGz-Tm4o2B6TBvMqgPtpki_e415xhA5wkwf8tgGxKorVDdvh0HK34tzQaEhMcjFcTJV7TetvKhXIlzMksZ5tU064zcjZughrU-eHBmxaHv1cUOoILIKJwFJq/s640/Schematic.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="color: #0000ee;"><u>Probe Schematic</u></span></td></tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
The circuit is powered with a 3V CR2032 battery. When the probe is not connected to anything, the probe voltage, as set with R1 and R2 will be 1.5V. As both Operational Amplifiers (<a href="http://www.microchip.com/wwwproducts/en/MCP6002" target="_blank">MCP6002</a>) have very low bias current (1pA), no voltage drops on R3 and 1.5V is also seen on the non inverting input of U2 and on the inverting input of U1.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Resistors R4, R5 and R6 define a voltage divider that sets 1V on the inverting input of U2 and 2V on the non inverting input of U1. With 1.5V on the probe, both operationals saturate at high level (3V) so both LEDs are OFF.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If we set the probe tip to a voltage below 1V (The trip point of U2), U2 will saturate at low level and the Blue LED will turn ON. In a similar way, if the probe tip voltage is set above 2V (The trip point of U1), U1 will saturate at low level and the White LED will turn ON. I know white is a strange color for high level. A red color will be better buy I had no red LEDs similar to the blue one at hand.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Operational Amplifiers are not the best suited components for this project. As they are used as comparators, a dual comparator could be better in this case. The choice of the MCP6002 dual opamp was only because I had them available.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Circuit operation</h3>
<div style="text-align: justify;">
In the end, the circuit puts a 1.5V voltage on the probe tip, provided by the two 100k resistors, so it behaves like a 1.5V source with a 50k series resistance. If the probe voltage is kept between 1V and 2V, no LED is lit. If the probe voltage is below 1V, the blue LED turns ON. And if the probe voltage is above 2V, the white LED will turn ON.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
When you probe a node in the circuit, you can sense its voltage using a high impedance voltmeter. That will give you the open circuit voltage (Voc). This voltage can be driven with different strengths. The drive strength is related to the equivalent resistance at the node. For a linear non reactive circuit it will be the equivalent <a href="https://en.wikipedia.org/wiki/Th%C3%A9venin's_theorem" target="_blank">Thevenin</a> resistance. In the end, the equivalent circuit will be something like that:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUdzLCwD8PVZS1ViVo0Uyn2ppwqECjfAdXMXSwNWokYlJGDObFByCPEpdVOah_hqYme3a_MbnvzhIROlXnuOhyaIx27ApKiiOqAZKcDDs2YaREOBKt5qFa_LvzKjEz1XwwT2P2V09YS3cl/s1600/Equivalent+Circuit.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUdzLCwD8PVZS1ViVo0Uyn2ppwqECjfAdXMXSwNWokYlJGDObFByCPEpdVOah_hqYme3a_MbnvzhIROlXnuOhyaIx27ApKiiOqAZKcDDs2YaREOBKt5qFa_LvzKjEz1XwwT2P2V09YS3cl/s400/Equivalent+Circuit.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="color: #0000ee;"><u>Simplified equivalent circ<span style="color: #0000ee;"><u>uit</u></span></u></span></td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
</div>
<br />
<br />
<div style="text-align: justify;">
Here we have the 1.5V and 50k resistance provided by the probe and the Voc and Rth associated with the probed node. As we know, the LEDs will lit when the probe voltage Vp is above 2V or below 1V. The following graph shows the LED status as function of Voc and Rth.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-_2M4Gx8j5FubUTy6Zs6EeOqaehkKc-fLWArzCjtO9lH7Y8hjeMc25R_veC7Rr2vzeSUxeiyZTeM2FrSqBEb5UwTRh7oLo2kGg5CvgTHQZFz-BatVmTIKPzwR2T-f3SxpWADDRUJdiJDl/s1600/LED+Graph.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="348" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-_2M4Gx8j5FubUTy6Zs6EeOqaehkKc-fLWArzCjtO9lH7Y8hjeMc25R_veC7Rr2vzeSUxeiyZTeM2FrSqBEb5UwTRh7oLo2kGg5CvgTHQZFz-BatVmTIKPzwR2T-f3SxpWADDRUJdiJDl/s400/LED+Graph.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="color: #0000ee;"><u>LED status as function on Voc and Rth</u></span></td></tr>
</tbody></table>
<div style="text-align: justify;">
For low Thevenin equivalent resistances (below 1k) only the Voc voltage determines if each LED is lit of not. For higher node resistances the threshold Voc voltage shifts due to the resistor interaction in the circuit.</div>
<div style="text-align: justify;">
We can see that at 100k Thevenin resistance we need 0V to lit the Blue led. For higher resistances we will need a negative voltage to lit the LED. Same for the white led: at 100k or more Thevenin resistance you need more than 3V to turn ON the LED. So, the circuit, not only senses the node voltage but also its drive strength.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
From the curve we can see that, when used as continuity tester, it can detect continuity (or lack of isolation) for resistances up to 100k. To lower the resistance detection threshold, the R1 and R2 resistors could be changed for lower values.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Effects of the probe on the circuit under test</h3>
<div style="text-align: justify;">
Measuring any magnitude always modifies the device under test (DUT). Sometimes this error is negligible. For instance, using a good quality voltmeter to measure the voltage between two nodes usually introduces a 10 megaohm resistance between the measured nodes.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Measuring the drive strength always affects the DUT. In our case we are applying a 1.5V voltage with a drive strength of 50k. If the node has a Thevenin resistance similar or higher than 50k, we are actively modifying the node voltage and potentially inducing a modification in the behaviour of the DUT.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<br />
<div style="text-align: justify;">
</div>
<h3 style="text-align: justify;">
Give it some protection</h3>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
As explained before, resistor R3 should not have any current in normal operation. IC inputs, like the ones on the MCP6002 device, don't like to be driven above Vcc (3V in our case) or below GND. Trying to go outside of this limits will trigger the internal protections on the device. The R3 resistor guarantees that it will not cause a high input current.</div>
<div style="text-align: justify;">
The circuit has been used to probe a low impedance 20V node and it operated correclty, detecting a higher than 2V level, without any harm done to the probe. This would not be the case if R3 wasn't present.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Frequency limits</h3>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
If the tip voltage changes with time alternating between voltages over 2V and below 1V, both LEDs will lit during some time. At low frequencies the blinking is apparent. At higher frequencies, over the <a href="https://en.wikipedia.org/wiki/Flicker_fusion_threshold" target="_blank">Flicker fusion</a> frequency, both LEDs seem to be lit at the same time. The circuit, however, due to some technical limits like the use of opamps instead of comparators has a maximum frequency of operation at about 50kHz. A square signal over this frequency doesn't lit any LED.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is no problem as the main purpose of the probe was to test static nodes but it should be taken into account for dynamic nodes. It is usual for logic probes to have an special detection mode for pulsed signals with frequencies up to several MHz. This is not the case in this circuit.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Building the probe</h3>
<div style="text-align: justify;">
The probe has been fabricated in a prototyping <a href="https://en.wikipedia.org/wiki/Perfboard" target="_blank">perfboard</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0zjedloYbUIRPzEvfYd4jxRT8X_68uj_BbHiRFYIk3W_wnqGmwaFkqHFkKVNwF3_kqi4jbyCGk6NLghykRU6T8lHy6vKbPoGZFmeMfH7s3ZAw_7gnNQxqUoZh3KlFCZt17kKodhBTGyO/s1600/Probe+1.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0zjedloYbUIRPzEvfYd4jxRT8X_68uj_BbHiRFYIk3W_wnqGmwaFkqHFkKVNwF3_kqi4jbyCGk6NLghykRU6T8lHy6vKbPoGZFmeMfH7s3ZAw_7gnNQxqUoZh3KlFCZt17kKodhBTGyO/s640/Probe+1.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Built Probe</td></tr>
</tbody></table>
<div style="text-align: justify;">
From left to right you have the probe tip, the three R1, R2 and R3 resistors, both LEDs and their R7 and R8 resistors, the MCP6002 dual opamp and the three R4, R5 and R6 resistors.</div>
<div style="text-align: justify;">
Ending the board we have the ground connection and the three pin power connector.</div>
<div style="text-align: justify;">
The LEDs are close to the tip so that we don't need to move the eyes from the circuit to check if they are lit. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The back side of the probe board is shown in the following figure. All the wiring has been done using thin, isolated, solid wire.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIhl28xxqoSCugOpYR1GPaDyraFV9N_dr0KbqOZrsdPUNdQGC79XoyOONpckprENhl_9kXZEUVggNxA2TpeaZifAdd0xTi7BPtydbbJNPby8PIbAKdEgTt7CGvCg5tirT5FJG2sHEq_3UQ/s1600/Probe+back.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIhl28xxqoSCugOpYR1GPaDyraFV9N_dr0KbqOZrsdPUNdQGC79XoyOONpckprENhl_9kXZEUVggNxA2TpeaZifAdd0xTi7BPtydbbJNPby8PIbAKdEgTt7CGvCg5tirT5FJG2sHEq_3UQ/s640/Probe+back.jpg" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Probe, solder side</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The three pin power connector uses the center pin for Vdd (+3V) and the other two pins for ground. A CR2032 socket is connected to a three pin female socket to provide the supply to the circuit.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
As the connector is symmetric, it can be connected with the battery facing the top of the bottom of the board. As the supply is detachable from the probe, we don't need a power switch.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNQPztgNEQz0H9vJnibI3jah7mlCqnWBe_KpRGPdw9N3dK1ctJieekUzMOyu9F7m0l5rbI9n6G0QEj9Nyxr_vHrI55E1C1nH1cskCFo1cACJw-0FXYVsaJTb-lRUQS7b9EyDMjRCtp8WAl/s1600/Battery.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNQPztgNEQz0H9vJnibI3jah7mlCqnWBe_KpRGPdw9N3dK1ctJieekUzMOyu9F7m0l5rbI9n6G0QEj9Nyxr_vHrI55E1C1nH1cskCFo1cACJw-0FXYVsaJTb-lRUQS7b9EyDMjRCtp8WAl/s200/Battery.jpg" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Power Supply</td></tr>
</tbody></table>
<div style="text-align: justify;">
The ground connection is provided by an aligator clip connected to a short stranded wire.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIDrjFEhATxwFDYBtHUIVZ1t2iQoXLIbMP_YSWNxgXppl8xIAqPJK-UL0ABzK3e61kPjtooXay8Hn4qLKXilhjw84TfJw7IMC_dpA6kMzplPT6x6bH87yQWhOvRpiYLHbN-ULWdEe1jnqa/s1600/Aligator.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIDrjFEhATxwFDYBtHUIVZ1t2iQoXLIbMP_YSWNxgXppl8xIAqPJK-UL0ABzK3e61kPjtooXay8Hn4qLKXilhjw84TfJw7IMC_dpA6kMzplPT6x6bH87yQWhOvRpiYLHbN-ULWdEe1jnqa/s320/Aligator.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="color: #0000ee;"><u>Ground connect<span style="color: #0000ee;"><u>ion</u></span></u></span></td></tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
The final probe with the supply and ground terminal is shown in the following figure.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRdIvGgyAbXhr0GBwhpg9X6KoqMfmzfmb5GT2Jm979giWs4DuoNtB16oH83CC8OwcSNtFYNZ9I9NNZLiK2Poe6Y1xF3R6f9w-_3JN2taGRqOEPo2i_PLtb7yS5Z9BYC2W3OPKKBpKzFxpl/s1600/Probe+2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRdIvGgyAbXhr0GBwhpg9X6KoqMfmzfmb5GT2Jm979giWs4DuoNtB16oH83CC8OwcSNtFYNZ9I9NNZLiK2Poe6Y1xF3R6f9w-_3JN2taGRqOEPo2i_PLtb7yS5Z9BYC2W3OPKKBpKzFxpl/s320/Probe+2.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="color: #0000ee;"><u>Probe with batter<span style="color: #0000ee;"><u>y and ground connection</u></span></u></span></td></tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
In order to check for continuity or to check diferential voltages, a second ground probe has been built using a thin piece of coper board and some <a href="https://en.wikipedia.org/wiki/Heat-shrink_tubing" target="_blank">heat-shrink tubing</a>. As you can see, touching both probe tips makes the system behave as a continuity tester.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPnUIm5GYyHMaQsHG5nxmzPa6r1M1KVvi20QnjoLpVtmbJMD_cUaEPUSZWcG4Sv_dJJVmETBV9LxFp-xL2B5EuIxCYky3lhJz6bDS3Qx3ogzjVBT_OxtKWUF8LwM7ZM-mM9fcyZV5b7i-S/s1600/Probe+4.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="277" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPnUIm5GYyHMaQsHG5nxmzPa6r1M1KVvi20QnjoLpVtmbJMD_cUaEPUSZWcG4Sv_dJJVmETBV9LxFp-xL2B5EuIxCYky3lhJz6bDS3Qx3ogzjVBT_OxtKWUF8LwM7ZM-mM9fcyZV5b7i-S/s400/Probe+4.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="color: #0000ee;"><u><span style="color: #0000ee;"><u>M<span style="color: #0000ee;"><u>ain probe and gr<span style="color: #0000ee;"><u>ound probe</u></span></u></span></u></span></u></span></td></tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<br />
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-72193685263451140782015-11-10T11:52:00.000+01:002015-11-10T11:52:09.002+01:00Atollic returns to no code limit<div style="text-align: justify;">
In the year 2011 I was in the search for free programming solutions for the STM32 Discovery boards when I found the <a href="http://timor.atollic.com/truestudio/" target="_blank">Atollic</a> True Studio Lite. It was a very interesting product. Based on Eclipse, it provided all the necessary tools to develop on ARM MCUs. It had some functionality limitations in the free version but It was very good for learning and teaching MCU programming.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
That ended at the start of 2012 when Atollic decided to set at 32KB code limit in True Studio Lite. When programming a STM32F4 Discovery board that features 1MB of flash, a code limit of 32KB is a joke. Moreover, it made impossible to integrate an RTOS and some middleware in the code. As I was using <a href="http://www.chibios.org/dokuwiki/doku.php" target="_blank">ChibiOS</a> at this time, this limitation was very important to me. I complained to Atollic, but, in the end, I found that I was out of the user group that Atollic was targetting. So, I moved on, leaved Atollic alone, and developed my own Eclipse based environment and used it for learning and teaching. That was dificult because the debug was quite difficult to setup at that time and ChibiOS didn't had come with <a href="http://www.chibios.org/dokuwiki/doku.php?id=chibios:product:chibistudio:start" target="_blank">ChibiStudio</a> yet.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now, at the end of 2015, almost four years after Atollic introduced the code limit in True Studio Lite, Atollic has decided to remove it. That is good news because ST provides examples for True Studio for its evaluation boards so it eases a lot the developement. Perhaps it is time to check again what Atollic has to offer but now there are quite more free options to develop in ARM MCUs that there were at the start of 2012. And now I have my own toolchain.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But for anyone willing to program the cheap evaluation boards that ST and others like Freescale provide, Atollic True Studio Lite is a free solution that should be taken into account now that the code limit is removed.</div>
<div style="text-align: justify;">
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-74017421457967192472015-05-29T23:53:00.002+02:002015-05-29T23:55:59.548+02:00LED lights deadbug style<div style="text-align: justify;">
This will be a brief article about building some LED lights to illuminate small things. The objective is to create some lights that can be oriented as needed to iluminate small objets to work on.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVhhTwPvRLQRmKTjo4p5i-rmDr_gieMu7YRw27u8GYPJsmE8sRU19R4cOSxkiPYGUHjLwqqIr9lZE0waFKCvkF1Jt7W_NShaBJhGqxniiQCBOyGEz4Z3CwTiJfsaxOis8VJojrHQZulHrC/s1600/Schematic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVhhTwPvRLQRmKTjo4p5i-rmDr_gieMu7YRw27u8GYPJsmE8sRU19R4cOSxkiPYGUHjLwqqIr9lZE0waFKCvkF1Jt7W_NShaBJhGqxniiQCBOyGEz4Z3CwTiJfsaxOis8VJojrHQZulHrC/s640/Schematic.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Schematic of the circuit</td></tr>
</tbody></table>
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<div style="text-align: justify;">
The basic circuit is a constant current driver using a NPN transistor. The 6k8 resistor, the 1N4148 diode and the adjustable resistor set the base voltage at the transistor between about 0.6V and 1.2V. That sets the votage at Re between 0 and 0.6V. The current at the transistor collecto will be between 0 and 0.6V/Re. </div>
<div style="text-align: justify;">
For instance, selecting a 15Ohm resistor we can get currents on the LED up to 27mA.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To power the circuit we will use a 2x6 100 mill spaced connector (J1). This connector works in a pseudocoaxial way with ground at the outer pins and +5V at the center. Having two rows enables us to chain several independent LED drive circuits.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The LED is also connected to the circuit using a 3 pin pseudocoaxial connector (J2) with +5V on the outer pin and the drive current on the center.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The circuit is mounted on a scrap piece of two sided copper PCB. The connections are done directly on the copper using deadbug style. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWUH8rMs0HZANiRz8MTEwJrEL8xr2ZhV3Tsc-YKUNE1iFb5fbttIhs88k5Jp05fl-8qSsQzFVQ_DQYqewwwfSSRzBuQ85rWzZePm0xyhR0IlyoIXSHPReEgoYAwLn4i14pwud8_zUoyhAJ/s1600/Circuit.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWUH8rMs0HZANiRz8MTEwJrEL8xr2ZhV3Tsc-YKUNE1iFb5fbttIhs88k5Jp05fl-8qSsQzFVQ_DQYqewwwfSSRzBuQ85rWzZePm0xyhR0IlyoIXSHPReEgoYAwLn4i14pwud8_zUoyhAJ/s320/Circuit.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Deadbug circuit</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
</div>
<br />
<br />
<div style="text-align: justify;">
We want the LEDs to be able to be positioned in the position we want. To do that a SMD LED is mounted on a rigid wire soldered to the current pin at the center of a 3 pin male connector. A second thin wire provides the +5V supply on one of the outer connector pins.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp5I5dWOvs0Vj7VVjz5VW_Fd8kw0T8dwfqXw_MfFtKXTN9vMCJCWAM70yKYPT2jOF5lHqFbYIYY69G-aU-hAczmCwO5Netnqibm0PBKNflsVRKZAUIawmbeE2zBR5zj3I7KsXUUypaWSRV/s1600/LED+wire.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp5I5dWOvs0Vj7VVjz5VW_Fd8kw0T8dwfqXw_MfFtKXTN9vMCJCWAM70yKYPT2jOF5lHqFbYIYY69G-aU-hAczmCwO5Netnqibm0PBKNflsVRKZAUIawmbeE2zBR5zj3I7KsXUUypaWSRV/s320/LED+wire.jpg" width="307" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LED connected to a rigid wire</td></tr>
</tbody></table>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
In order to have two independent LED lights I have build two twin circuits.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsqzYQ3VQCXOl3rGxe0brfNhK3XdDlKbKWno_iMrxhTwGibscZXL1dFwMfBfsm5f2Sq2C6-ivxKZQZQCc03oj7XCkWoGoesQ4ymPLol2_nn2Ou_HVnCLiFBXicnK7m_t3OB4gX2dTfX4EX/s1600/2+Circuits.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsqzYQ3VQCXOl3rGxe0brfNhK3XdDlKbKWno_iMrxhTwGibscZXL1dFwMfBfsm5f2Sq2C6-ivxKZQZQCc03oj7XCkWoGoesQ4ymPLol2_nn2Ou_HVnCLiFBXicnK7m_t3OB4gX2dTfX4EX/s320/2+Circuits.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Twin LED drivers</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next figure shows the detail of the supply J1 connector.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2yB7dKlUZ-2W3BnGJUl9-YVnxn2k_gqVNxHRR1mXWHV47r-j6xxlgISrgfYGjpdUI8bz8u_LeSg6fjD92y5TJwC0F6IWEwI068H0uWgPan8qs6C0iF9K9e1W6IMaJDRwbwHB-ll0gBIpn/s1600/Vdd+detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2yB7dKlUZ-2W3BnGJUl9-YVnxn2k_gqVNxHRR1mXWHV47r-j6xxlgISrgfYGjpdUI8bz8u_LeSg6fjD92y5TJwC0F6IWEwI068H0uWgPan8qs6C0iF9K9e1W6IMaJDRwbwHB-ll0gBIpn/s320/Vdd+detail.jpg" width="299" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Supply connector</td></tr>
</tbody></table>
<div style="text-align: justify;">
This connector enables us to chain both boards</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8KPc2Ud8hmq4MpJWT7KoLRwWdI4hwbcd_57YkbRRz-w-XwKB0r8KFDcB-RbBq-5cyMnb8ctMYgIN_5VWEvsRkh3XL26CtbKngY9tffCyTpBWc4o9flrd1uSs18rsOMDMCOHXi_FQ_jdE_/s1600/Chain.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8KPc2Ud8hmq4MpJWT7KoLRwWdI4hwbcd_57YkbRRz-w-XwKB0r8KFDcB-RbBq-5cyMnb8ctMYgIN_5VWEvsRkh3XL26CtbKngY9tffCyTpBWc4o9flrd1uSs18rsOMDMCOHXi_FQ_jdE_/s320/Chain.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Chain power to the twin drivers</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br />
Now we can put the LEDs on the driver boards</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUtwgLTZPIicEYMseCEnQ13LOvjGddXJQJ85Io98QzWRgabWuMxP7ayVSCMJuy4JkVWafgudLAAzjQ_6L58KZpFAz3MnVml00SGTteqG_m-M5S-qQj3RwtTGsdlv8lbLWNZSz8MuvhEYZt/s1600/Twin+lights.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUtwgLTZPIicEYMseCEnQ13LOvjGddXJQJ85Io98QzWRgabWuMxP7ayVSCMJuy4JkVWafgudLAAzjQ_6L58KZpFAz3MnVml00SGTteqG_m-M5S-qQj3RwtTGsdlv8lbLWNZSz8MuvhEYZt/s320/Twin+lights.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Twin lights</td></tr>
</tbody></table>
We can also use different LED colors, although this is less usefull.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8vksoP1hCbvjsvfnhYviHromnFrnPtpasgcOhzX4w9dCdqFXKTszdyWC99-ltIILGaFHcjC-qwE-Wx4pzDrjkKTCDU9dxLTMiVLu13dEgCWbL3FOQhCZLEh3nN-hP7uQrBBoXtwHbVP7E/s1600/Green+and+White.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8vksoP1hCbvjsvfnhYviHromnFrnPtpasgcOhzX4w9dCdqFXKTszdyWC99-ltIILGaFHcjC-qwE-Wx4pzDrjkKTCDU9dxLTMiVLu13dEgCWbL3FOQhCZLEh3nN-hP7uQrBBoXtwHbVP7E/s320/Green+and+White.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Green and White lights</td></tr>
</tbody></table>
<br />
That's all for now. This was only a little project to iluminate small spaces. In fact, with the size of the SMD LEDs, we can practically illuminate anything regardless of the space we have to route the lights.<br />
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-63578111589406770762015-01-17T21:49:00.000+01:002018-02-11T17:38:54.763+01:00Fast ADC on Arduino Leonardo<div style="text-align: justify;">
Last December I wrote about generating fast PWM on the Arduino Leonardo board.</div>
<div style="text-align: justify;">
This time I will follow my ideas of going beyond stock vanilla Arduino talking about the ADC.</div>
<br />
<br />
<h3>
The problem</h3>
<div style="text-align: justify;">
You can use the Arduino <a href="http://arduino.cc/en/Reference/AnalogRead" target="_blank">analogRead</a> function to read an analog value on one of the analog enabled pins. On the Arduino Leonardo there are 12 analog inputs. The typical A0 to A5 six standard Arduino inputs and the additional six lines A6 to A11 that correspond to D4, D6, D8, D9, D10 and D12. </div>
<div style="text-align: justify;">
The ADCs contained in the Atmega MCUs used in Arduino boards are 10 bit converters. To do one conversion the analogRead function takes 100us. It is supposed that the MCU needs that much time to give a 10 bit precision conversion. But 100us, for some applications, can be too much time. It limits, in fact, the maximum analog sample frequency to 10kHz and this doesn't take into account the time needed to process the read data.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can do better. You can do faster. But, as is normal in life, there must be some trade offs. So, if you want to do faster conversions you need to know what are you trading for them.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
The ATmega 32u4 ADC</h3>
<div style="text-align: justify;">
I suspect that other ATmega based Arduinos include a similar ADC, but I don't know for sure. The ADC uses an internal clock that is obtained from the system clock (16MHz on Arduino Leonardo) which is divided by factor between 2 and 128 using an special register setting. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On the Arduino Leonardo, the divider is set to the maximum 128 value so, at 16MHz master clock frequency we get a 125kHz ADC clock frequency.</div>
<div style="text-align: justify;">
To obtain the time needed to do a conversion from the ADC clock frequency we can refer to one table in the <a href="http://www.atmel.com/Images/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf" target="_blank">ATmega 42u4 datasheet</a>.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg6As5fUrpuFAyQtopQa6FtYROoI8YBtv1VCsv_SkC7vU3m12fTshtzuh2w70mytmakXNbajU1CO5x_UraDIn0wmyerHJ_SZm_bB0hKUy7qCXUoJDf4HRrdNtRmvKI9wnBaUmfFV5ljn0c/s1600/ADC+Conversion+Time.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg6As5fUrpuFAyQtopQa6FtYROoI8YBtv1VCsv_SkC7vU3m12fTshtzuh2w70mytmakXNbajU1CO5x_UraDIn0wmyerHJ_SZm_bB0hKUy7qCXUoJDf4HRrdNtRmvKI9wnBaUmfFV5ljn0c/s1600/ADC+Conversion+Time.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Number of cycles to do a conversion</td></tr>
</tbody></table>
<div style="text-align: justify;">
There are three kinds of conversion: First Conversion, Normal Conversions and Auto Triggered Conversion. The ones that apply to <span style="color: blue;">analogRead </span>are the two first ones, but the first only applies to the first conversion so we can use the central column (Normal Conversion) as the typical case.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The ADC needs to do two things to provide a conversion: Sample and Hold and SAR Conversion. In the table we find that those needs 1.5 and 13 cycles for a total of 14.4 cycles. As the ADC frequency is 125kHz, the total ADC time is 14.5/125kHz = 116 us. That's where the about 100us <span style="color: blue;">analogRead </span>time comes from.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The MCU datasheet states that we need an ADC frequency between 50kHz and 200kHz to get the maximum 10 bit resolution. With a 200kHz frequency we could shorten the total ADC time to 72,5us. Unfortunately the clock divider option next to 128 is 64 so, we cannot select 200kHz. We can only select 125kHz, 250kHz... Any option beyond 125kHz, using a 16MHz master clock, goes beyond the Atmel recommendations for the MCU.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Separating the two things the ADC does we get 12us Sample and Hold time and 104us SAR Conversion time. If we increase the ADC frequency we could shorten those times but. We know that we won't get maximum resolution but, ¿What are exactly the side effecs?</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Sample and Hold</h3>
<div style="text-align: justify;">
To understand the Sample and Hold we can use one of the figures in the ATmega 32u4 datasheet:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicUsS70Vf8dq_W4aVBkZuqTF3ggQJU6ph2iZw4BTlEXXj9SXkY2RN5ImOvZSNXuIFmKjHcVQ5mAVsmLvkd76U58ch7JJFVXsTujJp82kA-xjxo9hZYv6DKaQmJpmUccaETup3AFkB1WqpC/s1600/Sample+and+Hold.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicUsS70Vf8dq_W4aVBkZuqTF3ggQJU6ph2iZw4BTlEXXj9SXkY2RN5ImOvZSNXuIFmKjHcVQ5mAVsmLvkd76U58ch7JJFVXsTujJp82kA-xjxo9hZYv6DKaQmJpmUccaETup3AFkB1WqpC/s1600/Sample+and+Hold.png" width="320" /></a></div>
<div style="text-align: justify;">
The Sample and Hold (S&H) circuit is composed on a switch, a resistor and a capacitor. At the start of the conversion the switch is closed during the sample time (1.5 ADC clock cycles). After that, the switch is open and the ADC SAR circuit does the real conversion. The S&H circuit is important because the signal should not change during the SAR conversion. That is guaranteed by the fact that the switch is open during the conversion.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One fundamental point about S&H circuits is that the capacitor need to be charged to the input voltage, during the sample time, before the conversion starts. As this is an RC circuit, in theory, the capacitor voltage will never reach the input one. In practice we only need to get as close to the input voltage as is needed for the converter resolution. For a 10 bit ADC, in order to get a negligible error we need to get to 1/2^11 of the ADC reference value that is normally 5V for Arduino boards. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The RC charging, assuming the worst case of capacitor at zero will be modelled by:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS23D_dYb7btkxlOqMXftdOTb_bkUhdZCPF8pI8tySe3Wf-E4EQZRHD-65BQnNYBglWcTQ2eZuEPcC27oapSUvJC_L4ZtlKCmCgYuSpwKvEYJ_3cwhD-i1hCRk17nwsCXVX85w5LncU6Ou/s1600/Formula+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS23D_dYb7btkxlOqMXftdOTb_bkUhdZCPF8pI8tySe3Wf-E4EQZRHD-65BQnNYBglWcTQ2eZuEPcC27oapSUvJC_L4ZtlKCmCgYuSpwKvEYJ_3cwhD-i1hCRk17nwsCXVX85w5LncU6Ou/s1600/Formula+1.png" width="320" /> </a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
In the worst case, the input voltage will be 5V and to meet the required 10 bit precision the input value capacitor value should get to 1/2^11 of the input value.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhktaCxjdu6XfKJx42DYKiUpNcqwezxZC16_fLxe67-2GIZ55J7NE_3QsSV1wQhwuM8gENPAs6321sLSlJQ38rxJCFccIltEM-ByIk1XUlHRq9u4xC0XPb1vbxU2hjO2R6GYDjkrxw6Z0ob/s1600/Formula+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhktaCxjdu6XfKJx42DYKiUpNcqwezxZC16_fLxe67-2GIZ55J7NE_3QsSV1wQhwuM8gENPAs6321sLSlJQ38rxJCFccIltEM-ByIk1XUlHRq9u4xC0XPb1vbxU2hjO2R6GYDjkrxw6Z0ob/s1600/Formula+2.png" width="200" /></a></div>
<div style="text-align: justify;">
That will get:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXLFE5aAb1S50wZwYha2G_677V9NuwhtAOkW5r9N8RKqToVOD94vSl7bOyQc0vL1MaBOxe1kywqnu-N_hZuYrJ67Dcoc9KrGsfUYiv973iJpGCSTEYK7CdHeMKLT3iw1ee73e_09ocNola/s1600/Formula+3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXLFE5aAb1S50wZwYha2G_677V9NuwhtAOkW5r9N8RKqToVOD94vSl7bOyQc0vL1MaBOxe1kywqnu-N_hZuYrJ67Dcoc9KrGsfUYiv973iJpGCSTEYK7CdHeMKLT3iw1ee73e_09ocNola/s1600/Formula+3.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At 125kHz ADC clock operation we know that the sample time is 12us, so the time constant should be 1,57us or less. As the capacitance is 14pF, the total resistance should be below 112 kOhm. As the ADC internal resistance can go up to 100k, that limits the external resistance to about 12kOhm. That is consistent with the fact that the MCU datasheet recommends external resistances to the ADC of 10 kOhm or less.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The above formula is quite important. When using the ADC. At a 16MHz master frequency the sample time cannot be bigger than 12us so you should not use a total external resistance to the ADC greater than 12 kOhm. Using a greater resistance could limit the ADC resolution lowering the effective number of bits you get from the ADC.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If, for instance, you only need 8 bits because you are discarding the 4 lower bits resulting from the conversion, you only need to have a 5,4 us time constant (sampling time divided by ln(9) ) so, with the same 14pF ADC capacitance you will only need a total resistance below 386k Ohm. Considering the maximum 100k internal ADC resistance you only need to guarantee a maximum of 286k Ohm external resistance.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
SAR Conversion</h3>
<div style="text-align: justify;">
The ATmega 32u4 MCU uses a <b>S</b>uccesive <b>A</b>pproximation <b>R</b>egister (SAR) to do the conversion. This is the most usual kind of converter that can be found on MCUs. These converters get one bit at a time at each clock cycle. So, in order to get a 10bit value, we need 10 clock cycles. From the table found on the datasheet we know that the actual conversion takes 13 cycles. The extra 3 cycles are probably for synchronization tasks.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Increasing the clock frequency during the conversion operation will affect the ADC resolution but the effect is not easy to model although it can be measured. Fortunately someone has done this measurements.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
On the <a href="http://www.openmusiclabs.com/" target="_blank">Open Music Labs website</a> you can find this two articles:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="http://www.openmusiclabs.com/learning/digital/atmega-adc/">http://www.openmusiclabs.com/learning/digital/atmega-adc/</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="http://www.openmusiclabs.com/learning/digital/atmega-adc/in-depth/">http://www.openmusiclabs.com/learning/digital/atmega-adc/in-depth/</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
They are a quite interesting read and they explain more details on the Sample and Hold operation. The links apply to the ATmega 328p but I don't think that the ATmega 32u4 ADC should be much different.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The result is that increasing the ADC frequency reduces the equivalent number of bits (ENOB) of the conversion. Observe that at the minimum stock 125 kHz frequency the ENOB is not 10 bits but something above 9. Also, at 250 and 500 kHz the ENOB is also over 9 but decaying. At 1MHz the ENOB is over 8. For frequencies greater than that the ENOB falls below 8 bits.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Finally we can find the trade offs of using a bigger ADC frequency:</div>
<div style="text-align: justify;">
</div>
<ul>
<li>The resolution (number of bits) could be limited by the S&H</li>
<li>The resolution (number of bits) will be limited during the conversion </li>
</ul>
<div style="text-align: justify;">
The number of bits of an ADC is an integer number, but the Equivalent Number of Bits (ENOB) is not. At 125kHz, if the S&H is not the limiting factor, you will get about 9,5 bits worth of data. That is, the ratio between the maximum value you can convert and the conversion noise will be limited to a 2^9,5 ratio. If you don't need more than 9 bits of <b>real resolution</b>, you can increase the ADC clock frequency up to 500kHz but you must verify that the S&H is also capable to keep with that speed for your ADC external resistance values. For 8 bit operation you could go to 1MHz. That is eight times the original conversion speed.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Example Program</h3>
<div style="text-align: justify;">
In order to change the ADC speed clock you need to change the ADC Control and Status Register A (ADCSRA).</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP4QZ36EWVFlcxMZozJSF58rM0kQL5ZnvGJB9rWxNcSWSrBopK_J8wvzcIXH0cYTD_sFJwV5FmMnANQHjrFXWSNYKkHuEt9aVaHkzT2bci7g-d-1_uruI4BFJtvsdHyEs3JuF4d51dC7eo/s1600/ADCSRA.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP4QZ36EWVFlcxMZozJSF58rM0kQL5ZnvGJB9rWxNcSWSrBopK_J8wvzcIXH0cYTD_sFJwV5FmMnANQHjrFXWSNYKkHuEt9aVaHkzT2bci7g-d-1_uruI4BFJtvsdHyEs3JuF4d51dC7eo/s1600/ADCSRA.png" width="640" /></a></div>
<div style="text-align: justify;">
The 3 lower bits of this register determine the divider used to obtain the ADC clock from the MCU master frequency.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYNGbZTOAW1QhCMdT_TgYu0AM1reUG8E29FKOhpqD1zavew4LrkwDUM25hBdZf1H3kvxz6WPXI83eQoEu4oKQfnpGA5iCj7Da00_8Ap_UogxoWIvCdQdWwbTUhG6_5aEQci2aQ_p1q66Wa/s1600/Prescaler+table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="162" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYNGbZTOAW1QhCMdT_TgYu0AM1reUG8E29FKOhpqD1zavew4LrkwDUM25hBdZf1H3kvxz6WPXI83eQoEu4oKQfnpGA5iCj7Da00_8Ap_UogxoWIvCdQdWwbTUhG6_5aEQci2aQ_p1q66Wa/s1600/Prescaler+table.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For 111 we get a 128 prescaler that corresponds to the 125 kHz stock Arduino frequency.</div>
<div style="text-align: justify;">
For 110 we get a 64 divider that gets a 250kHz clock. For 101 we get 500kHz and for 100 we get 1MHz.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The following example program just does 4 conversions in a row. The first at the stock 125kHz, the second at 250kHz, the third at 500kHz and the last one at 1MHz.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<script src="https://gist.github.com/anonymous/40f13541ca0fa3ec77ef.js"></script><br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The program also toggles the Arduino pin 3 before and after each call to <span style="color: blue;">analogRead </span>so that the total time associated to this function can be measured.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqm2Bv2TWhyphenhyphenTec8TE0FB8j4hG4rRBfrtOeGEhksRUuy1TjVRG_tKywQIB_2KIzZpIGCu69AHDGahkALTn2aE68QMeJ1OFfhYaWgJ3WyclNd3hjdariuy3ppGWa_gQ2zgWJG1oZ9kYujpeo/s1600/FastAdcTest.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqm2Bv2TWhyphenhyphenTec8TE0FB8j4hG4rRBfrtOeGEhksRUuy1TjVRG_tKywQIB_2KIzZpIGCu69AHDGahkALTn2aE68QMeJ1OFfhYaWgJ3WyclNd3hjdariuy3ppGWa_gQ2zgWJG1oZ9kYujpeo/s1600/FastAdcTest.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Output at pin 3</td></tr>
</tbody></table>
<div style="text-align: justify;">
From the mesurement we can see how the <span style="color: blue;">analogRead </span>function time halves on each call as the ADCSRA register is changed to obtain greater ADC frequencies.</div>
<div style="text-align: justify;">
<br />
Fortunately the <span style="color: blue;">analogRead </span>function itself doesn't modify the ADCSRA register. If that was the case we could not hack the ADC speed without creating a new <span style="color: blue;">analogRead </span>function.<br />
<br />
<br />
<h3>
Code on Github (11/02/2018) </h3>
The code is now on Github:<br />
<br />
<a href="https://github.com/R6500/Leonardo/blob/master/FastAdcTest.ino">https://github.com/R6500/Leonardo/blob/master/FastAdcTest.ino</a><br />
<br /></div>
<div style="text-align: justify;">
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com2tag:blogger.com,1999:blog-6880821591370697484.post-85097370604888145412014-12-22T23:26:00.000+01:002018-02-11T17:37:35.860+01:00Fast PWM on Arduino Leonardo<div style="text-align: justify;">
Today I will talk about PWM generation.</div>
<div style="text-align: justify;">
The Arduino boards provide pseudo analog outputs using the <a href="http://arduino.cc/en/Reference/AnalogWrite" target="_blank">analogWrite( )</a> function. This function is not available on all pins, only the ones marked with the ~ symbol. The Analog Write function doesn't provide a real analog output but a <a href="http://en.wikipedia.org/wiki/Pulse-width_modulation" target="_blank">PWM </a>signal instead. </div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii2Wa14M-y5AUIum-35PezNjsd-Q1NpUGVqLFs0MVkEyGQ9zSrvulniGPd_PzLEFyaZw7nKnEEj1P8EBOsX6H1RlnxYdWuTcNiG8aK6MkDqseHIbLncyWTeSG3xxO26qexvwmdusjEQ19a/s1600/Leonardo.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii2Wa14M-y5AUIum-35PezNjsd-Q1NpUGVqLFs0MVkEyGQ9zSrvulniGPd_PzLEFyaZw7nKnEEj1P8EBOsX6H1RlnxYdWuTcNiG8aK6MkDqseHIbLncyWTeSG3xxO26qexvwmdusjEQ19a/s1600/Leonardo.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arduino Leonardo Board</td></tr>
</tbody></table>
<div style="text-align: justify;">
A PWM (Pulse Width Modulation) signal is a pulsed binary signal. As it is binary it can only have two output states "HIGH" and "LOW". The analog information is not on the signal levels but on the width of the generated pulses.We define <span style="color: blue;">Pulse Width</span> as the width of the HIGH pulses and <span style="color: blue;">Duty Cycle</span>, represented with a lower case delta letter, as the fraction of the Pulse Width to the total period T of the signal. The frequency of the PWM signal is defined as the inverse of the period.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gNqhJjmglPwroXQnpbqzu39nYe3H0sQam0As3KMTLVbLHOH0qxD6iH_by7NVxHrP-goiUCs-oU5j2752_EHa9ht8MEhY7bkiyXxrCYnng_cR9Fg3ffgdPWBsFI9aUrONMk6FAeFwdQXs/s1600/PWM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3gNqhJjmglPwroXQnpbqzu39nYe3H0sQam0As3KMTLVbLHOH0qxD6iH_by7NVxHrP-goiUCs-oU5j2752_EHa9ht8MEhY7bkiyXxrCYnng_cR9Fg3ffgdPWBsFI9aUrONMk6FAeFwdQXs/s1600/PWM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PWM Signal</td></tr>
</tbody></table>
<br />
The mean value of the PWM signal depends on the Duty Cycle and the voltage values associated to the HIGH and LOW levels:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcDJmeoysKrmHXdC-rqQBUMNeozsnuisA-_Zx6UCZ_OpqijrFfyETUsgCgJHg8XMy5uSY0sCa7e5orIHFgYbRoRe3eu0R5IEBl9t6w3C6pLd8XuUf1YK6SvlImQvsLCTvM1j9dOGBYX3s9/s1600/PWM+formula+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcDJmeoysKrmHXdC-rqQBUMNeozsnuisA-_Zx6UCZ_OpqijrFfyETUsgCgJHg8XMy5uSY0sCa7e5orIHFgYbRoRe3eu0R5IEBl9t6w3C6pLd8XuUf1YK6SvlImQvsLCTvM1j9dOGBYX3s9/s1600/PWM+formula+1.png" width="320" /></a></div>
If the LOW level is zero, the the mean value of the PWM signal is:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFJln2WjzXjRIxOxpWQzrne9etBufn4j_MfKz3zKhSPCMxejSk-wSr9spwWEom8jdO_AQW5pv0J8GJRfF0mkRY2XF6Snt9D_4lO3KtqGOQZKXUobc-skeMm0nkvHFQrqOinvmEhmzsyZIL/s1600/PWM+formula+2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFJln2WjzXjRIxOxpWQzrne9etBufn4j_MfKz3zKhSPCMxejSk-wSr9spwWEom8jdO_AQW5pv0J8GJRfF0mkRY2XF6Snt9D_4lO3KtqGOQZKXUobc-skeMm0nkvHFQrqOinvmEhmzsyZIL/s1600/PWM+formula+2.png" /></a></div>
That way, the mean value of the signal is proportional to the Duty Cycle. <br />
<br />
<br />
<br />
<div style="text-align: justify;">
Arduino <span style="color: blue;">analogWrite( )</span> function maps a 0 to 255 input value to a 0% to 100% Duty Cycle. As the HIGH level is about 5V and the LOW level is near to zero, the mean value of the signal generated using <span style="color: blue;">analogWrite(pin,x)</span> is:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwylqg5UgV5bZGURFnlvnnmGAOabSvMKYfUqgpj0Dpq-oBDhNec5aTQGJmCkQ0723f9_q5UKfSligfjZqqtOQhPrmBHGbC5WLU_E2m6MQlmv8u7Z91IQxpLBLDly3PVWhx9TXVXHpZ2orC/s1600/PWM+formula+3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwylqg5UgV5bZGURFnlvnnmGAOabSvMKYfUqgpj0Dpq-oBDhNec5aTQGJmCkQ0723f9_q5UKfSligfjZqqtOQhPrmBHGbC5WLU_E2m6MQlmv8u7Z91IQxpLBLDly3PVWhx9TXVXHpZ2orC/s1600/PWM+formula+3.png" /></a></div>
<div style="text-align: justify;">
If the device connected to the pin has lower bandwidth than the frequency of the PWM signal, it will work as low pass to the signal an only will see the mean value. Arduino Leonardo PWM pins use frequencies of 488Hz or 976Hz. When you use <span style="color: blue;">analogWrite</span> on a LED, as LEDS have usually higher than 1kHz bandwidth, the LED will turn full ON and OFF as indicated on the PWM signal. Our eye, however, has a bandwidth (<a href="http://en.wikipedia.org/wiki/Flicker_fusion_threshold" target="_blank">fusion frequency</a>) up to about 100 Hz depending on the ambient ligh levels. As the LED pulses at a higher frequency than the eye bandwidth, we only see the mean value and seems that the LED lights at intermediate levels between ON and OFF. </div>
<div style="text-align: justify;">
The same applies if we use a PWM signal to drive a motor. Normal DC motors, due to their inertia, have bandwidths near or below the Arduino PWM frequency, so the motor works as if a constant variable voltage where applied. In fact, PWM operation at low frequency can make the motor work better at low speeds.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
All in all, the 500Hz to 1kHz PWM frequency in stock Arduino is adequate to drive motors. If we want, however, to generate an audio signal, the <span style="color: blue;">analogWrite</span> function does not work.The hearing bandwidth in humans is arround 20kHz, much higher than the Arduino PWM frequency. Typical speakers are usually designed inside the human hearing bandwith so applying a PWM signal to them will produce an audible tone at the PWM frequency.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One of the utilities to generate a high frequency PWM signal is going beyond the speaker and hearing bandwidths so that we can use an PWM signal to generate an audio signal.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Stock PWM on Arduino Leonardo</h3>
<div style="text-align: justify;">
First we start explaining how the PWM is implementated on the Arduino Leonardo board. In most Arduino boards the PWM signals are generated using timers. Timer peripheras provide hardware PWM generation so that the CPU don't need to use any of it's execution resources to generate the signals. Each timer has a limited number of PWM signals than can be generated by hardware. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The Arduino Leonardo, as the <a href="http://arduino.cc/en/Main/ArduinoBoardMicro" target="_blank">Micro</a> and <a href="http://arduino.cc/en/Main/ArduinoBoardEsplora" target="_blank">Esplora</a> use the <a href="http://www.atmel.com/devices/ATMEGA32U4.aspx" target="_blank">ATmega42u4</a> MCU. It includes four timers: Timer 0, Timer 1, Timer 3 and Timer 4. Timers 1 and 3 are equal, but the rest of timers are quite different. Other Arduino Boards make use of other timers provided by the MCUs they use.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The following table shows the timers usage to generate PWM on the Arduino Leonardo board. You can see it and more information on my <a href="https://docs.google.com/spreadsheets/d/1zFkrNUWS6-ow6kGBxUObfnzK1ZsuW7VK3vRO1FoV8fc/edit?usp=sharing" target="_blank">Arduino Leonardo spreadsheet</a>.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxcfbBYOiJomh-pO9ZO6ztRfVSy7RHFuQKExogxeMH5NhYT325HgNs9vFZztIyNljAG_xc1CHc8kwoCrQiCix510xhK28sfJTwcskDj2N71f8jXHfBGOQyEvUrDV0uERKQTU_2wGc70ZQG/s1600/Leonardo+Timers.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxcfbBYOiJomh-pO9ZO6ztRfVSy7RHFuQKExogxeMH5NhYT325HgNs9vFZztIyNljAG_xc1CHc8kwoCrQiCix510xhK28sfJTwcskDj2N71f8jXHfBGOQyEvUrDV0uERKQTU_2wGc70ZQG/s1600/Leonardo+Timers.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PWM Timers in Arduino Leonardo</td></tr>
</tbody></table>
<div style="text-align: justify;">
Arduino uses the timers for other functionalities. For instance, Timer 0 is also used to record the pass of time as is needed for the functions <a href="http://arduino.cc/en/Reference/Millis" target="_blank">millis( )</a>, <a href="http://arduino.cc/en/Reference/Micros" target="_blank">micros( )</a>, <a href="http://arduino.cc/en/Reference/Delay" target="_blank">delay( )</a> and <a href="http://arduino.cc/en/Reference/DelayMicroseconds" target="_blank">delayMicroseconds( )</a>. You don't wanna mess with Timer 0 operation as it will disturb all timing functions. </div>
<div style="text-align: justify;">
Some Arduino libraries make also use of timers. The <a href="http://arduino.cc/en/Reference/Servo" target="_blank">Servo</a> library uses Timer 1 on the Leonardo while the <a href="http://www.pjrc.com/teensy/td_libs_MsTimer2.html" target="_blank">MsTimer2</a> library uses Timer 4. You should know that using any library that needs a timer will affect any PWM pin associated to that timer.</div>
<div style="text-align: justify;">
<br />
There are several two basic ways to create a PWM signal using a timer.<br />
<br />
<h3>
Single Slope PWM</h3>
The timers are typically based on a Counter. The counter uses a clock input and, at each active clock edge, the counter changes state. One typical mode of operation for a timer involves increasing the counter at clock each clock edge until it reaches a maximum value. Once this value is reached, the counter returns to zero and the process repeats.That gives a sawtooth waveform on the counter values as is depicted in the figure below. One full cycle of the sawtooth will need Count Max + 1 clock cycles.<br />
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOGNX5NEvM7KREG6yLDwcJL9s74vQqrRjxNFMcDfTjNKkudU_UGm_H_rjdb6vsN_BihIvd_5C76tatf5dYP0x8D1ALqCBAgAKhVpKXEAWWuoaBXEPRVB0qyPMocXE9GbrSIl3NQ2Xnv1t-/s1600/FastPWM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="271" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOGNX5NEvM7KREG6yLDwcJL9s74vQqrRjxNFMcDfTjNKkudU_UGm_H_rjdb6vsN_BihIvd_5C76tatf5dYP0x8D1ALqCBAgAKhVpKXEAWWuoaBXEPRVB0qyPMocXE9GbrSIl3NQ2Xnv1t-/s1600/FastPWM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Single slope PWM</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
Timer peripherals usually include several capture/compare registers. In order to create a PWM signal, a compare register is linked to a hardware output of the MCU in a way that makes this output high if the counter is below or equal to the compare register value. That will give, for each compare register, a PWM signal whose duty cycle depends on the compare value. </div>
<div style="text-align: justify;">
All PWM signals generated by the same timer, will have the same frequency as the start of the generated pulses will allways be at the falling edge of the sawtooth signal. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHw8T82CqdAo4Uq9oRyGsZhw_hElrIfXwftd9hTlu3BPhel8CxMQkv6Tce4gfe-rSZ7Zs0vQU7XmtnKrKdfNBLKUNH0yFcFo1VslL556gt1EeosQUJpQ0S0lr7rxyNDqMuCsWreQjgHfZL/s1600/PWM+formula+4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHw8T82CqdAo4Uq9oRyGsZhw_hElrIfXwftd9hTlu3BPhel8CxMQkv6Tce4gfe-rSZ7Zs0vQU7XmtnKrKdfNBLKUNH0yFcFo1VslL556gt1EeosQUJpQ0S0lr7rxyNDqMuCsWreQjgHfZL/s1600/PWM+formula+4.png" width="320" /></a></div>
<div style="text-align: justify;">
If we have several PWM signals regenerated with different compare
registers at the same timer, all of them will have the rising edge at
the same times. </div>
<div style="text-align: justify;">
<br />
<div style="text-align: justify;">
The Arduino <span style="color: blue;">analogWrite( )</span>
functions operate the ATmega 32u4 Timer 0 at single slope. The 250kHz
clock used is obtained dividing by 64 the 16MHz system clock. The final
PWM frequency will the be 976Hz. </div>
<div style="text-align: justify;">
Timer 0 has two compare channels A and B associated to two compare registers <span style="color: blue;">OCR0A</span> and <span style="color: blue;">OCR0B</span>. The two channels are linked to two hardware outputs <span style="color: blue;">OC0A</span> and <span style="color: blue;">OC0B</span> that are used as Arduino pins numbers 11 and 3.</div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<h3 style="text-align: justify;">
Dual Slope PWM</h3>
<div style="text-align: justify;">
Another way to generate a PWM signal configures the counter to increase at each clock edge, and when it reaches the maximum value, start decreasing one number each clock cycle until it reaches zero and the patter repeats again. That will give a triangle waveform instead of the sawtooth one.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEmH3IWm5BuoJAxNNQbuzhlyhdiLWHVwML-d937PJBt-46OGeRxHVcEBmkA1Cn4JVduo9xcjQ0jT9SfkFQPAwJHjL9WZiJSM-4pKvVwVlCiqNasODEmL9EnUFHKjEL5ikVVMRYjUSv5pWk/s1600/CenteredPWM.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEmH3IWm5BuoJAxNNQbuzhlyhdiLWHVwML-d937PJBt-46OGeRxHVcEBmkA1Cn4JVduo9xcjQ0jT9SfkFQPAwJHjL9WZiJSM-4pKvVwVlCiqNasODEmL9EnUFHKjEL5ikVVMRYjUSv5pWk/s1600/CenteredPWM.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Dual Slope PWM</td></tr>
</tbody></table>
<div style="text-align: justify;">
We can also configure a capture register so that a generated output signal is high when the counter is below this register. This will generate a PWM signal as in the single slope case. The difference is that, if we have several compare registers, the PWM signal generated with each one will be synchronized at the center of the generated pulses.</div>
<div style="text-align: justify;">
This is handy in some kinds of motor control but the details are beyond this article.</div>
<div style="text-align: justify;">
In any case, the PWM frequency will be the same for all compare channels and will also be half of the value we would obtain if we used a Single Slope counter.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrmDiORv-2OrcoQ3jw_8pjKdmtUdyU1QQkyiWLVIPgbhkYgo74OHM-08kO0DDZlmhkmR4Hibe_Uj7oMyTQCC6UwXL-ciqOZi_5QjQ1-TC01z3WF8pzKluAVd7vm7_iXfS97F7eSOOTpxjr/s1600/PWM+formula+5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="49" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrmDiORv-2OrcoQ3jw_8pjKdmtUdyU1QQkyiWLVIPgbhkYgo74OHM-08kO0DDZlmhkmR4Hibe_Uj7oMyTQCC6UwXL-ciqOZi_5QjQ1-TC01z3WF8pzKluAVd7vm7_iXfS97F7eSOOTpxjr/s1600/PWM+formula+5.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The Arduino <span style="color: blue;">analogWrite( )</span> functions operate the ATmega 32u4 MCU Timers 1, 3 and 4 in Dual Slope mode. A possible reason why Timer 0 is not operated also in Dual Slope can probably be due to the fact that Timer 0 is used to record the pass of time and, this use, is difficult to be implemented on a dual slope timer. Working on dual slope, all PWM pins associated to those pins use half the Timer 0 frequency working at 488Hz.</div>
<div style="text-align: justify;">
Timer 1 includes three compare channels A, B and C associated to compare registers <span style="color: blue;">OCR1A</span>, <span style="color: blue;">OCR1B</span>, <span style="color: blue;">OCR1C</span> linked to hardware outputs <span style="color: blue;">OC1A</span>, <span style="color: blue;">OC1B</span> and <span style="color: blue;">OC1C</span>. The Arduino software only uses the channels A and B that are related to Arduino pins 9 and 10. Channel C output <span style="color: blue;">OC1C</span> is associated to the same 11 Arduino Pin driven by Timer 0. For whatever reason Arduino designers preferred to drive pin 11 using Timer 0 at single slope than use Timer 1 at dual slope. </div>
<div style="text-align: justify;">
Timer 3 only includes one hardware output <span style="color: blue;">OC3A</span> at Arduino pin 5, associated to the compare register <span style="color: blue;">OCR3A</span>.</div>
<div style="text-align: justify;">
Timer 4 is a special timer, but respect to PWM, it operates as Timers 1 and 3 in dual slope mode. It includes three hardware outputs <span style="color: blue;">OC4A</span>, <span style="color: blue;">OC4B </span>and <span style="color: blue;">OC4D </span>associated to registers <span style="color: blue;">OCR4A</span>, <span style="color: blue;">OCR4B </span>and <span style="color: blue;">OCR4D</span>. Only channels A and D are used in stock Arduino for pins 13 and 6. Channel B is associated to the same pin driven by <span style="color: blue;">OC1B </span>so Timer 1, instead of Timer 4, is used for this pin.</div>
<div style="text-align: justify;">
All of that gives the table of the 7 PWM enabled Arduino Pins. </div>
<div style="text-align: justify;">
<br />
<br />
<h3>
Fast PWM on Timer 1</h3>
If the maximum 976 Hz that stock Arduino <span style="color: blue;">analogWrite</span> is not enough, we need to develop our own PWM functionality. Timer 1 is a good candidate as it has three available compare channels and don't mess with Arduino delay functions. You should take care if you use the Servo library because it also uses Timer 1.<br />
<br />
Timer 1 is based arround a 16 bit counter. That means that it can count from 0 up to 65535 before overflowing. The timer has several modes of operations that include 12 PWM modes. The fastest PWM mode available is single slope 8 bits counting between 0 and 255. As single slope is faster that dual slope, it is also called <span style="color: blue;"><b>Fast</b></span> PWM mode.<br />
You can also have 9 bits and 10 bits PWM modes with 511 and 1023 terminal counts that can operate on single and dual slope modes. Three bit modes 8, 9 and 10 for single and dual slope PWM gives a total of 6 PWM modes. The other 6 additional PWM modes use programmable terminal counts that can be any 16 bit value and is not restricted to 255, 511 or 1023.<br />
<br />
The timer gets its clock from the global MCU prescaler that provides five frequencies from the system clock. The divide ratios are 1, 8, 64, 256 and 1024. That gives, using the 16MHz Arduino Leonardo system clock, the fiveclock and single slope frequencies shown below for standard 8, 9 and 19 bit modes:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbBxhV76Qo_ZiWBDydtjmbAAD0LTAKIBPzivdrOtcVWk3mLQ2mbOrftNnsQnaiW-8ovedDYqkYR1nN4rdlj8jBu5dwb_l1f6vqE5e3HLBX3K0gxtO7A1scTxpY3d17maeoncXqkFkuv_0R/s1600/PWM+Prescaler.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbBxhV76Qo_ZiWBDydtjmbAAD0LTAKIBPzivdrOtcVWk3mLQ2mbOrftNnsQnaiW-8ovedDYqkYR1nN4rdlj8jBu5dwb_l1f6vqE5e3HLBX3K0gxtO7A1scTxpY3d17maeoncXqkFkuv_0R/s1600/PWM+Prescaler.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Prescaler and PWM options</td></tr>
</tbody></table>
</div>
<div style="text-align: justify;">
Using dual slope the maximum frequency will be half. We see that the maximum available PWM frequency on Timer 1 is 62.5kHz. That's enough to generate some sort of audio signal as it is beyond the audible range of frequencies.<br />
<br />
In order to configure the timer we must program the Timer 1 registers TCCR1A and TCCR1B.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-U9DmM-flrZwgj5gvAX0YgWfws2Rifs4kVNk-VU0M_PuCvvi83nGdYWel9qQyaDN2cJZkEk-oaIgzKLJowFZNoFtXCdQM8_HDlwxvZLt8fknIJ4CI5tRTrgYcS9dEekXOsRdl7lW_NsMw/s1600/TCCR1A.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-U9DmM-flrZwgj5gvAX0YgWfws2Rifs4kVNk-VU0M_PuCvvi83nGdYWel9qQyaDN2cJZkEk-oaIgzKLJowFZNoFtXCdQM8_HDlwxvZLt8fknIJ4CI5tRTrgYcS9dEekXOsRdl7lW_NsMw/s1600/TCCR1A.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
</div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMyjy_tGjqZEzt4b1oQgWmpeYdBVt44mLMCx0LYquxtZcaUGhSVP2bjwm1wwkbOIEXV3YbVrVo_CKf_0euHsIgApirF9dn1RP_wVu408wmCjggl5Gj5SfoR7VlGthL9pGpvkqV88x5d1v5/s1600/TCCR1B.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMyjy_tGjqZEzt4b1oQgWmpeYdBVt44mLMCx0LYquxtZcaUGhSVP2bjwm1wwkbOIEXV3YbVrVo_CKf_0euHsIgApirF9dn1RP_wVu408wmCjggl5Gj5SfoR7VlGthL9pGpvkqV88x5d1v5/s1600/TCCR1B.png" width="640" /></a></div>
Bits 0, 1 and 2 of <span style="color: blue;">TCCR1B</span> (CS10, CS11 and CS12) configure the clock options acording to the following table. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNZ1NFKifEb9aGQUWM2cXg0hH7z6D84zP0S_aPjra2DIhMf2jbU-T8_GicSbPwqMuMmY9a1O9DzKSSk1U4lebk-9csAtPMT3z1j-3OtQI84ntPp5vL6NCJ_ovDyIngrPXgJuPIqRTgvJc9/s1600/Clock+options+Timer+1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNZ1NFKifEb9aGQUWM2cXg0hH7z6D84zP0S_aPjra2DIhMf2jbU-T8_GicSbPwqMuMmY9a1O9DzKSSk1U4lebk-9csAtPMT3z1j-3OtQI84ntPp5vL6NCJ_ovDyIngrPXgJuPIqRTgvJc9/s1600/Clock+options+Timer+1.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
Bit 1 of <span style="color: blue;">TCCR1A</span> (WGM11) and bits 3 and 4 of <span style="color: blue;">TCCR1B</span> configure the waveform for the timer acording to the table:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-wz9_65txYhTdDDFvT4OarbRqBmFjK4pJ5E-a8Gwuq4g5JZZlAf67QUTyEnDoC_P4mH-ZjFIbCqo_w0me7ba1Cie22NDwQXZN8zR1DDvSXj_hBwWHymo5P1q5yhggRSuCEmdhpHYCpYez/s1600/Waveforms+Timer++1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="366" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-wz9_65txYhTdDDFvT4OarbRqBmFjK4pJ5E-a8Gwuq4g5JZZlAf67QUTyEnDoC_P4mH-ZjFIbCqo_w0me7ba1Cie22NDwQXZN8zR1DDvSXj_hBwWHymo5P1q5yhggRSuCEmdhpHYCpYez/s1600/Waveforms+Timer++1.png" width="640" /></a></div>
<br />
Modes 1, 2, 3, 5, 6 and 7 correspond to the 6 standard PWM modes.<br />
<br />
Once the timer is configured on one PWM mode, each of the three compare channels A, B and C can be enabled to generate a PWM signal. To do that, the <span style="color: blue;">COM1x0 </span>an <span style="color: blue;">COM1x1 </span>bits on register <span style="color: blue;">TCCR1A</span> associated to a particular x channel (A, B, C) need to be configured according to the table:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijstCVPpm-7DgoQCu9riL7qoLylQAznEeHCzcBAvsMLPjDzpfAIzWx7okaYRe3TqZLX0FzFasHMpoCwUY_ES29d2s-grVqnertXPcOTjYpsheQlV3PluiHkFNMjQmLpK3bCf4PZbYCwxsH/s1600/Fast+PWM+compare+modes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijstCVPpm-7DgoQCu9riL7qoLylQAznEeHCzcBAvsMLPjDzpfAIzWx7okaYRe3TqZLX0FzFasHMpoCwUY_ES29d2s-grVqnertXPcOTjYpsheQlV3PluiHkFNMjQmLpK3bCf4PZbYCwxsH/s1600/Fast+PWM+compare+modes.png" width="640" /></a></div>
<br />
The PWM value for each channel should be programmed in each channel compare register <span style="color: blue;">OCR1A</span>, <span style="color: blue;">OCR1B </span>and <span style="color: blue;">OCR1C</span>.<br />
<br />
All the above tables habe been taken from the <a href="http://www.atmel.com/Images/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf" target="_blank">ATmega32u4 datasheet</a>. <br />
<br />
Configuring the <span style="color: blue;">TCCR1A </span>bits is not enough to generate the PWM signal at the output pins. We also need to configure them in output mode. From the ATmega32u4 we can see that the timer 1 outputs <span style="color: blue;">OC1A</span>, <span style="color: blue;">OC1B </span>and <span style="color: blue;">OC1C </span>are associated to port lines <span style="color: blue;">PB5</span>, <span style="color: blue;">PB6 </span>and <span style="color: blue;">PB7</span> (Arduino Pins 9, 10 and 11). We need to set those pins in output mode using the Port B Data Direction Register <span style="color: blue;">DDRB</span>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5RgIlAp1d7_4cZU_IAm6z23cuxQA3dimMbo9FZ_6dhIxWHp8rz954jaGzOIk-JUkwPbElPZCV9JZTooHqfAAHeU7dMgTf-AgDBiIHp5GNmHoSJnanOK-cgQ3OnfrLJw1tRDzSaOkCOrHa/s1600/atmega16u_32u.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="596" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5RgIlAp1d7_4cZU_IAm6z23cuxQA3dimMbo9FZ_6dhIxWHp8rz954jaGzOIk-JUkwPbElPZCV9JZTooHqfAAHeU7dMgTf-AgDBiIHp5GNmHoSJnanOK-cgQ3OnfrLJw1tRDzSaOkCOrHa/s1600/atmega16u_32u.png" width="640" /></a></div>
<br />
<h3>
Fast PWM on Timer 4</h3>
Using Timers 0, 1 or 3 we can have up to 62,5kHz PWM signals, but the maximum possible PWM frequency is only available on Timer 4.<br />
Timer 4 is a 10 bit timer that can operate at very fast speed due to its clock source options.<br />
The ATmega32u4 MCU includes an USB peripheral. This peripheral needs a 48MHz clock frequency that goes beyond the maximum 16MHz system clock. In order to generate the USB frequency the MCU incorporates an internal <a href="http://en.wikipedia.org/wiki/Phase-locked_loop" target="_blank">PLL</a>. In the Arduino Leonardo the PLL takes as input the 16MHz system clock and multiplies it by 6 to generate a 96MHz output frequency. <br />
You don't want to mess with the PLL configuration on the Arduino Leonarda as it will break the USB communications. The only need you need to know about the PLL is that its output can source the Timer 4 peripheral.<br />
<br />
The PLL register PLLFRQ includes among other things, two bits <span style="color: blue;">PLLTM0 </span>and <span style="color: blue;">PLLTM1 </span>that determine the input clock to Timer 4.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAFglaRuvrX3JJpQfUBWJ1RUrcnGUmXpu6tc-mIafWm9VOVP0FLOpw4d0kgSWxmNF4vDU8TOeDjwoYBtoWhEjL_nyycDE77yqjGmG4d-Zd_Kq6qgz5sBP48nRW1zElZ7hpMhzljGKrG3cX/s1600/PLLFRQ.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAFglaRuvrX3JJpQfUBWJ1RUrcnGUmXpu6tc-mIafWm9VOVP0FLOpw4d0kgSWxmNF4vDU8TOeDjwoYBtoWhEjL_nyycDE77yqjGmG4d-Zd_Kq6qgz5sBP48nRW1zElZ7hpMhzljGKrG3cX/s1600/PLLFRQ.png" width="640" /></a></div>
<br />
There are four options, don't use the PLL to source the timer (it will be sourced by system clock) or to use the PLL output divided by 1, 1.5 or 2. That will give 96MHz, 64MHz or 48MHz clock frequencies. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju0n52Q4TVKChzaTAu6Of4-w79i6eAttnenmTjcVk6DCy0-WH2GDY5rx3icjOebYsMSqr6S3k_37lXNfKwFCnql42_jPWDMBwJDYdvi-ZbV4SWfTmLSSgTSHxaqrhqbDiOUytMeKcyNKgb/s1600/PLL+Timer+Options.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEju0n52Q4TVKChzaTAu6Of4-w79i6eAttnenmTjcVk6DCy0-WH2GDY5rx3icjOebYsMSqr6S3k_37lXNfKwFCnql42_jPWDMBwJDYdvi-ZbV4SWfTmLSSgTSHxaqrhqbDiOUytMeKcyNKgb/s1600/PLL+Timer+Options.png" width="400" /></a></div>
<br />
<i><span style="color: #444444;">At the time of this writting the above table was missing from the official ATmega32u4 current datasheet. I needed to find an older datasheet to obtain the full PLL configuration register contents.</span></i><br />
<br />
Timer 4 has an additional divider configured with bits <span style="color: blue;">CS40 </span>to <span style="color: blue;">CS43 </span>of the <span style="color: blue;">TCCR4B</span> configuration register.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIsyqdqw9GlHDcSNu2j15syVnVV4YgLBUAzpPWJLx0IrBrv-TYHytKG64IdjVE6Z3pYfw0vmSSTCZfNrKCgxJpZrnNkt0CgbETYki9JdcZnvkUP34qmxTV7ZPolCFIRGGOt28hAPAWibAp/s1600/TCCR4B.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIsyqdqw9GlHDcSNu2j15syVnVV4YgLBUAzpPWJLx0IrBrv-TYHytKG64IdjVE6Z3pYfw0vmSSTCZfNrKCgxJpZrnNkt0CgbETYki9JdcZnvkUP34qmxTV7ZPolCFIRGGOt28hAPAWibAp/s1600/TCCR4B.png" width="640" /></a></div>
The available options are:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR1CB3yi7QtunYnrtdx6GFY_ep8AOQ4O6vLKxRoE1MFWeaIyZNU44JzpHTkpfwjbleTUVvlyVrctiUI9yZLVY8spPxYFGqaBKt-RC46cQZbs263RO7zCT8Z35mXbDKWYRXtEs_8TxA_koE/s1600/Timer4+Prescaler+(New).png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="273" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR1CB3yi7QtunYnrtdx6GFY_ep8AOQ4O6vLKxRoE1MFWeaIyZNU44JzpHTkpfwjbleTUVvlyVrctiUI9yZLVY8spPxYFGqaBKt-RC46cQZbs263RO7zCT8Z35mXbDKWYRXtEs_8TxA_koE/s1600/Timer4+Prescaler+(New).png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7XVt9RBpaNdqxtwAteTI07VzyZI9W3IH78Tg-TZ8FgWldUh-N9mkdgrgBn4ylAO4f6wqMYhy81pypncs-vAtbP1iTzhD-eYEf5lrmJkGVhf51By3a1hULmBAF6Rp5Ebll4bo5ipyv3M6q/s1600/Timer4+Prescaler.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
That way, using the PLL and Timer 4 dividers you can have input frequencies betwen 96MHz and 5859Hz.<br />
<br />
In a similar way than Timer 1, Timer 4 must select a waveform operation mode using bits <span style="color: blue;">WGM40</span> and <span style="color: blue;">WGM41 </span>of the <span style="color: blue;">TCCR4D </span>register.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_37DEOF1cwmEc8rk3vy1827AhNMc6cK1b6qRPdSFKdYeHSWe7lRVorvjlKXdHVuNXq2oxEs8KpdxnTCrpsLQL5CNrOAouruocZ7MyZ9090pT-PrShEniFmIz7c3VNKB9dTzOXURAPF18h/s1600/TCCR4D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_37DEOF1cwmEc8rk3vy1827AhNMc6cK1b6qRPdSFKdYeHSWe7lRVorvjlKXdHVuNXq2oxEs8KpdxnTCrpsLQL5CNrOAouruocZ7MyZ9090pT-PrShEniFmIz7c3VNKB9dTzOXURAPF18h/s1600/TCCR4D.png" width="640" /></a></div>
The available options are:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqVgljiv0MAMhcD9lbFWzAnuYyAhJZDYuV9pw_KXxS35JwmQKdh-pfmRYrvPrHVxkIx7UERmjjEJU-EEmlrZMQfnr-0Ov_lGfEw9Nl_55bUYjuXrtzc1krpOgTMpRHlDuj0aGn0QjqjiAP/s1600/Timer4+waveforms.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqVgljiv0MAMhcD9lbFWzAnuYyAhJZDYuV9pw_KXxS35JwmQKdh-pfmRYrvPrHVxkIx7UERmjjEJU-EEmlrZMQfnr-0Ov_lGfEw9Nl_55bUYjuXrtzc1krpOgTMpRHlDuj0aGn0QjqjiAP/s1600/Timer4+waveforms.png" width="640" /></a></div>
<br />
Mode 00 is Single Slope while mode 01 is Dual Slope. <br />
<br />
Observe that the PWM signal has a maximum count value defined in <span style="color: blue;">OCR4C </span>register. As compare channel C register is used for the terminal count, there is no independent channel C PWM output.<br />
<br />
PWM6 is an special PWM operation mode that uses all three available channels A, B and D to drive a motor. The details, that are beyond the scope of this document, can be found on the MCU datasheet.<br />
<br />
After configuring the clock input, each channel x = A, B and D of Timer 4, can be configured with its own bits <span style="color: blue;">COM4x0</span>, <span style="color: blue;">COM4x1 </span>and <span style="color: blue;">PWM4x</span> at registers <span style="color: blue;">TCCR4A </span>and <span style="color: blue;">TCCR4C</span>.<br />
As we have explained channel C, used as terminal count, has no output unit so it cannot be used to generate PWM.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzcq4esJPp0cJVEqthwwSWFXeNeG1T6ZBC8qAlSxBhENFZe_4BpPO8THzC04cW5H2zw_la8TrDO_NVr7HKnVMGTzIhxTkCYI7L04m81_Az2jvR5KthzLN2E7P2IybVSwt9lWMtBoTcyfDn/s1600/TCCR4A.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzcq4esJPp0cJVEqthwwSWFXeNeG1T6ZBC8qAlSxBhENFZe_4BpPO8THzC04cW5H2zw_la8TrDO_NVr7HKnVMGTzIhxTkCYI7L04m81_Az2jvR5KthzLN2E7P2IybVSwt9lWMtBoTcyfDn/s1600/TCCR4A.png" width="640" /></a></div>
</div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy-YvOxktlLR6aIO7DFTSB_0RQYY0Q2RMrfhg_Z5h4VYJli69Q8CYzxOi4jLh7q5GJhgelCYyVp8YfxsxNYX2uRB8LmZ-KbkcT3kv_PrikSjCZgA5UsYnNpdojzOLk3WpTmUVCNFNhbHry/s1600/TCCR4C.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy-YvOxktlLR6aIO7DFTSB_0RQYY0Q2RMrfhg_Z5h4VYJli69Q8CYzxOi4jLh7q5GJhgelCYyVp8YfxsxNYX2uRB8LmZ-KbkcT3kv_PrikSjCZgA5UsYnNpdojzOLk3WpTmUVCNFNhbHry/s1600/TCCR4C.png" width="640" /></a></div>
To operate one x channel in PWM mode you need to set to "1" the corresponding <span style="color: blue;">PWM4x </span>bit. After that, the <span style="color: blue;">COM4x0 </span>and <span style="color: blue;">COM4x1 </span>determine the mode of PWM operation. In the case of channel A in fast PWM mode we can choose:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEfW61M8A5AMvG8bsp5mwv4lJGJV9JNwsfyafSuQpRj-DX-A3DnvDwkkvTE-bfwppQZlEv5CXIGR6ZRqFBs4dOQCjHvQ-i156Nb_-0K8_4lComFi9Te7hHw3LKPlf1Xh7tNzi8VomYKKRl/s1600/COM4Ax.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEfW61M8A5AMvG8bsp5mwv4lJGJV9JNwsfyafSuQpRj-DX-A3DnvDwkkvTE-bfwppQZlEv5CXIGR6ZRqFBs4dOQCjHvQ-i156Nb_-0K8_4lComFi9Te7hHw3LKPlf1Xh7tNzi8VomYKKRl/s1600/COM4Ax.png" width="640" /></a></div>
<br />
Normal PWM operation corresponds to mode 10. Mode 11 will give a complementary output whereas mode 01 gives two complementary PWM outputs at different pins. The complementary signals can have some deadband between them so that one signal, and its complement are never active at the same time.<br />
Similar tables can be found for channels B and D.<br />
<br />
<h3>
Fast PWM Test Code</h3>
I have put together all the above methods to generate PWM in a FastPWM Arduino sketch.<br />
<br />
<script src="https://gist.github.com/anonymous/f5dc94881438846cf684.js"></script><br />
<br />
The sketch includes the needed code to operate 5 pins associated to Timers 1 and 4 in fast PWM modes.<br />
<br />
<u>Timer 1 Code</u><br />
<br />
The code associated to timer 1 includes 4 functions and several defines. It can uses all three Timer 1 compare channels to generate PWM signals at Arduino pins 9, 10 and 11.<br />
<br />
The <span style="color: blue;">pwm91011configure </span>function must be called previously to the call of any other function associated to this timer. It configures the timer to operate in single slope fast PWM mode and sets the prescaler to the mode indicated on the function argument.<br />
The five possible modes are PWM62k, PWM8k, PWM1k, PWM244 and PWM61 and are associated to the four available frequencies in single slope 8 bit PWM modes.<br />
<br />
Functions <span style="color: blue;">pwmSet9</span>, <span style="color: blue;">pwmSet10 </span>and <span style="color: blue;">pwmSet11 </span>configure the Timer 1 channels associated to pins 9, 10 and 11 to work in PWM mode and set the given PWM value (0 to 255).<br />
<br />
After one of the three above functions is called, the PWM value can be fast changed using a direct access to the corresponding compare register. To ease the access, three definitions <span style="color: blue;">PWM9</span>, <span style="color: blue;">PWM10</span> and <span style="color: blue;">PWM11 </span>are associated to compare registers <span style="color: blue;">OCR1A</span>, <span style="color: blue;">OCR1B </span>and <span style="color: blue;">OCR1C</span>.<br />
<br />
<br />
<u>Timer 4 Code</u></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The code associated to timer 4 includes 3 functions and several defines also. It uses two of the three available compare channels A and D associted to Arduino pins 13 and 6. It doesn't use channel B because its Arduino pin 10 conflicts with the Timer 1 channel B previously used.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The <span style="color: blue;">pwm613configure </span>function is similar to the one defined for Timer 1. It sets the PLL and PWM modes to properly configure Timer 4 in high speed mode from the 48MHz PLL tap and sets the terminal count in <span style="color: blue;">OCR4C </span>to 8 bits (255). </div>
<div style="text-align: justify;">
The input argument sets one of seven available prescaler frequencies for a 48MHz timer 4 clock input: PWM187k (187500 Hz), PWM94k (93750 Hz), PWM47k (46875 Hz), PWM23k (23437 Hz), PWM12k (11719 Hz), PWM6k (5859 Hz) and PWM3k (2930 Hz). If you remenber the Timer4 options there where 15 clock prescaler options. The lower frequency ones are not implemented in the defines as they provide no advantage over stock <span style="color: blue;">analogWrite </span>functionality.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Functions <span style="color: blue;">pwmSet13 </span>and <span style="color: blue;">pwmSet6 </span>configure the Timer 4 channels associated to pins 13, 6 to work in PWM mode and set the given PWM value (0 to 255).</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
In a similar way than timer 1, after one of the two above functions is called, the PWM value can be
fast changed using a direct access to the corresponding compare
register. Two definitions <span style="color: blue;">PWM13</span>, <span style="color: blue;"></span>and <span style="color: blue;">PWM6 </span>are associated to compare registers <span style="color: blue;">OCR4A</span> <span style="color: blue;"></span>and <span style="color: blue;">OCR4D</span>. An aditional <span style="color: blue;">PWM6_13_MAX</span> definition has been added to access the <span style="color: blue;">OCR4C </span>register that sets the PWM terminal count that is, by default, set to 255 (8 bits).<br />
<br />
<br />
<u>Setup and Loop Code</u><br />
<br />
To check all the above functions Timer 1 is configured in <span style="color: blue;">setup </span>to generate 62,5kHz PWM signals. Timer 4 is configured for 187kHz. 4 signals are generated. At pins 11 and 13 11% and 75% fixed PWM values are set. For pins 6 and 9, a variable 0% to 100% PWM value is programmed inside the <span style="color: blue;">loop </span>function.<br />
<br />
<h3>
Generated Waveforms</h3>
The following figure shows the generated waveforms captured with the Logic Analizer of the <a href="http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY&CFID=7055375&CFTOKEN=c1e47546bd88378d-7D056868-5056-0201-02F3C686BED59350" target="_blank">Analog Discovery</a> scope.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgikOxPEoSikEF4hMAzii05IJPXUbuYrAfIGf3zoZfIg2dUbb-XlfxuKehRPghZPOnsGZj4kAQyuOfywaQgE-KuiMfR3MfzaBYLpSo3538x_cPoscILo024cNn92c-QePkxzjVi_YxFqtIL/s1600/FastPwmTest-01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgikOxPEoSikEF4hMAzii05IJPXUbuYrAfIGf3zoZfIg2dUbb-XlfxuKehRPghZPOnsGZj4kAQyuOfywaQgE-KuiMfR3MfzaBYLpSo3538x_cPoscILo024cNn92c-QePkxzjVi_YxFqtIL/s1600/FastPwmTest-01.png" width="640" /></a></div>
<br />
Timer 1 signals at pins 9 and 11 have the same risign edge as they are in single ramp PWM mode. The same applies to signals at pins 6 and 13 that depend on Timer 4. Signals at different timers are at different frequency so the rising edges don't usually coincide for both timer signals.<br />
<br />
That's all for now. Timers are very usefull peripherals. PWM is only one of the timer applications. In the future I plan to talk also about generation of periodic events.<br />
<br />
<br />
<h3>
Code on Github (11/02/2018) </h3>
The code is now on Github:<br />
<br />
<a href="https://github.com/R6500/Leonardo/blob/master/FastPWM.ino">https://github.com/R6500/Leonardo/blob/master/FastPWM.ino</a><br />
<br /></div>
<div style="text-align: justify;">
</div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com21tag:blogger.com,1999:blog-6880821591370697484.post-42021207619354959712014-12-10T00:05:00.000+01:002018-02-11T17:36:15.972+01:00Low level GPIO on Arduino Leonardo<div style="text-align: justify;">
The <a href="http://www.arduino.cc/" target="_blank">Arduino</a> boards provide an easy entry in the microcontroller (MCU) world. With practically no knowledge on electronics and in no time yo can have a little project up and running.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The Arduino way to do coding builds over an extensive set of pre-coded libraries that hides the complexities of interfacing a MCU. That's all OK if don't need to go to the limits of what the MCU can do or if you don't mind to know about how the MCU does its things. But it you need to cut corners or if you want to learn about MCUs, you should try to depart a little from the Arduino way.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One good and bad thing about Arduinos is their uniformity. All arduinos use the same <span style="color: blue;"><span style="background-color: white;">digitalWrite</span></span>, <span style="color: blue;">digitalRead</span>, <span style="color: blue;">analogRead</span> and <span style="color: blue;">analogWrite </span>functions. And they work the same, more or less, if you are using an Arduino <a href="http://arduino.cc/en/Main/ArduinoBoardUno" target="_blank">UNO</a> with an <span class="wikiword">ATmega328 or an Arduino <a href="http://arduino.cc/en/ArduinoCertified/IntelGalileo" target="_blank">Galileo</a> with an </span>Intel Quark <span class="wikiword">SoC</span> X1000. But, as the MCUs used are different, they really don't work exactly the same.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you want to go beyond the Arduino way, the uniformity falls off as the methods change depending on the MCU the board uses. If two boards use the same kind of MCU, the internal procedures will be similar, although not always equal. If two boards use a different MCU, the internal procedures can be quite different.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In this article I will target the Arduino <a href="http://arduino.cc/en/Main/ArduinoBoardLeonardo" target="_blank">Leonardo</a>. This is a quite capable board that comes to substitute the old Arduino UNO. It includes an <a href="http://www.atmel.com/devices/ATMEGA32U4.aspx" target="_blank">ATmega 32u4</a> MCU. This is part of the megaAVR familly of MCUs. Most classic arduino boards like the UNO (<span class="wikiword">ATmega328</span>), <a href="http://arduino.cc/en/Main/ArduinoBoardMega2560" target="_blank">Mega 2560</a> (<span class="wikiword">ATmega2560), <a href="http://arduino.cc/en/Main/ArduinoBoardMini" target="_blank">Mini</a> (</span><span class="wikiword"><span class="wikiword">ATmega168)</span> </span>are in this family. In fact, the Arduinos <a href="http://arduino.cc/en/Main/ArduinoBoardMicro" target="_blank">Micro</a> and <a href="http://arduino.cc/en/Main/ArduinoBoardEsplora" target="_blank">Esplora </a>use the very same 32u4 MCU that uses the Leonardo.</div>
<div style="text-align: justify;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrHc0OcJcHeodDNcpa6z2fbfs2V9eJca2q4D3lYP4VsU702UrzbtpxMkapoAlIfpIDn9drZLY_h3sZZo8LVkI99YSxOfnUpmuNHHBa1lsu4Txt671u9grZxfa3EkgEc08ozNcZl1tu__rc/s1600/Leonardo.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="249" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrHc0OcJcHeodDNcpa6z2fbfs2V9eJca2q4D3lYP4VsU702UrzbtpxMkapoAlIfpIDn9drZLY_h3sZZo8LVkI99YSxOfnUpmuNHHBa1lsu4Txt671u9grZxfa3EkgEc08ozNcZl1tu__rc/s1600/Leonardo.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arduino Leonardo</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
The Arduino Leonardo don't need to use an additional chip to provide the USB communication because the MCU that includes can manage that itself. For the same reason, the board can emulate an USB peripheral like a mouse or a keyboard.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Using an Arduino to learn the insides of the ATmega 32u4 MCU has advantages and inconvenients. On one hand, the Arduino IDE provides all kinds of functions and libraries to do complex operations so you can do low level coding of only one part of the system. For instance you can leave the serial over USB communication to the Arduino libraries and do manual control of GPIO lines. On the other hand, the Arduino IDE tries to hide the low level sintax of the MCU and the bootloader method used to load the program don't provide any hardware debugging of your code.</div>
<div style="text-align: justify;">
To make things a little worse, the Arduino libraries make some use of the MCU internal resources and it's not always easy to know what libraries will you break if you take a step out of the Arduino way.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
In this first article about the insides of the Arduino Leonardo I will talk about how the digital GPIO works. That is, I will talk about how to do low level operations equivalent, but faster, to the use of the <span style="color: blue;">pinMode</span>, <span style="color: blue;">digitalRead </span>and <span style="color: blue;">digitalWrite</span> functions.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Arduino pins and Leonardo ports</h3>
<div style="text-align: justify;">
The ATmega 32u4 MCU that powers the Arduino Leonardo features 5 digital GPIO (General Purpose Input/Output) ports. Each one is labeled with a leter, so we have ports B, C, D, E and F. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Each port can have up to 8 digital lines (numbered from 0 to 7) associated with pins of the MCU package.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjocYabzdYJ2UeVUp1yq6jh2Z8-nmLh1t5Lev9KxAa2RRGLnGOFMUGWlDO8M_aMGLNQD4RIb6Op0r1VomxQOlSdG_dBKnGCx6DYR1uWis2vnhgoOrJAvf0CpgYBGutPiWrWo5mJiWEd0ZOK/s1600/atmega16u_32u.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="373" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjocYabzdYJ2UeVUp1yq6jh2Z8-nmLh1t5Lev9KxAa2RRGLnGOFMUGWlDO8M_aMGLNQD4RIb6Op0r1VomxQOlSdG_dBKnGCx6DYR1uWis2vnhgoOrJAvf0CpgYBGutPiWrWo5mJiWEd0ZOK/s1600/atmega16u_32u.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ATmega 32u4 pinout</td></tr>
</tbody></table>
<div style="text-align: justify;">
As you can see in the above pinout, most package pins include references like PE6 (Line 6 of port E) and PB0 (Line 0 of port B). As the MCU package has 44 pins and as each of the 5 ports could have up to 8 lines, you can see that you could get out of pins if you include power supplies, Xtal and USB connections. I you obseve the pinout you will see, for instance, that there is no PD5 and that the port E includes only two lines. In fact, only ports B and D are complete (8 lines each).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The line distribution is:</div>
<ul>
<li>Port B : 8 lines PB0 to PB7</li>
<li>Port C : 2 lines PC6 and PC7</li>
<li>Port D : 8 lines PD0 to PD7</li>
<li>Port E : 2 lines PE2 and PE6</li>
<li>Port F : 6 lines PF0, PF1 and PF4 to PF7</li>
</ul>
<div style="text-align: justify;">
So you have 26 GPIO lines in total. You can also see this line distribution in the MCU internal block diagram description.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrWdWUBbOLSMEDQB9RkLlmHGbNxmHjCK3G1zvOynHHPK5rOG7dZrqggwxdRjx0XClvaFVsBuDqU97cJWuSArQCTuuzbpFHnG86WeVtpytSQ5SCWvhiDBD6DRgKfiSNJOSPbCgiYF-jKe03/s1600/ATmega32u4+Blocks.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="350" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrWdWUBbOLSMEDQB9RkLlmHGbNxmHjCK3G1zvOynHHPK5rOG7dZrqggwxdRjx0XClvaFVsBuDqU97cJWuSArQCTuuzbpFHnG86WeVtpytSQ5SCWvhiDBD6DRgKfiSNJOSPbCgiYF-jKe03/s1600/ATmega32u4+Blocks.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Internal ATmega 32u4 structure</td></tr>
</tbody></table>
<div style="text-align: justify;">
The 26 GPIO lines are relabeled, in the Arduino functions, as lines 0 to 23. You can see that there are two lines missing. That's because PD5 and PE2 are not available as digital or analog lines in the Leonardo board. If you look at the board you will only see the numbers of 14 of the lines (0 to 13). The lines 14 to 17 are located on the male 6 pin ISP/SPI header and the lines 18 to 23 are alias names for the analog A0 to A5 lines that can also be used as digital I/O.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcCR_pPseLhkplvkCNWoeCSq8lihjn_ozaIDY12L6oRQ1A99Qi9eKR9Mg_8c1xVRU2SnPXVd3_akw2gsNTK0pKaD5152YhAADWZVpIrKMGVmonoynUp04Jn08VbZYZLYg9HdNofhQ4LmGo/s1600/Leonardo+2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcCR_pPseLhkplvkCNWoeCSq8lihjn_ozaIDY12L6oRQ1A99Qi9eKR9Mg_8c1xVRU2SnPXVd3_akw2gsNTK0pKaD5152YhAADWZVpIrKMGVmonoynUp04Jn08VbZYZLYg9HdNofhQ4LmGo/s1600/Leonardo+2.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Top view of the Leonardo Board</td></tr>
</tbody></table>
<div style="text-align: justify;">
The ATmega 32u4 features 12 analog inputs. That's more that the 6 A0 to A5 marked on the board. Those inputs are avalilable as the lines 4, 6, 8, 9, 10 and 12 and you can use the alias names A6, A7, A8, A9, A10 and A11 for those lines.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Why aren't all the extra analog lines marked as A6 to A11?</div>
<div style="text-align: justify;">
Well, because the original Arduino, with PDIP package, only had 6 lines and keeping the pin form factor of the board is important to provide board to board compatibility.</div>
<div style="text-align: justify;">
In other words, the Leonardo, with its 32u4 MCU is different from the UNO with its 328 MCU but the board is marked to use the same pin names.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9y5yYQx5JeZfd0vaMI1vsZ_QE0NnnHKnoIxGieYc2yal0ZuUGpY4FVrzsPlbfITiOX-1bF2P9EGva9RyRsOKzj0-XKrz5egBvAAecwuNbWo0VcQR8haR1TzFWBvhj56ZlitE1JGgM_Uu4/s1600/Uno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9y5yYQx5JeZfd0vaMI1vsZ_QE0NnnHKnoIxGieYc2yal0ZuUGpY4FVrzsPlbfITiOX-1bF2P9EGva9RyRsOKzj0-XKrz5egBvAAecwuNbWo0VcQR8haR1TzFWBvhj56ZlitE1JGgM_Uu4/s1600/Uno.jpg" width="244" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arduino UNO top view</td></tr>
</tbody></table>
<div style="text-align: justify;">
The different port lines are not related to the standard Arduino pin names. That's because, to keep the board pinout compatibility, the lines that can give PWM signals using the <span style="color: blue;">analogWrite</span> function need to be associated to lines 3, 5, 6, 9, 10, 11 and 13. </div>
<div style="text-align: justify;">
In the UNO board the pin numbering is easy, digital pins 0 to 7 go to lines 0 to 7 of port D, lines 8 to 13 go to lines 0 to 5 of port B and analog lines 0 to 5 go to lines 0 to 5 of port C.</div>
<div style="text-align: justify;">
In the Leonardo, to keep things compatible, there is a mess of lines. Digital lines 0 and up are connected to PD2, PD3, PD1, PD0, PD4, PC6, PD7, PE6.... All messed up.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The only way to know with Arduino line relates to which port line on the Leonardo is using a written list as there is no logical distribution as it was on the Arduino UNO.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I you want to see which line goes with what, you can use the Arduino Leonardo Spreadsheet I wrote on Google Drive from the link below.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<a href="https://docs.google.com/spreadsheets/d/1zFkrNUWS6-ow6kGBxUObfnzK1ZsuW7VK3vRO1FoV8fc/edit?usp=sharing" target="_blank">Arduino Leonardo Spreadsheet Link</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Bitwise variables and registers</h3>
<div style="text-align: justify;">
Every digital port B, C, D, E and F has three related 8 bit registers. You can access those registers in a similar way that accessing <a href="http://arduino.cc/en/Reference/Byte" target="_blank">byte</a> variables. You only have to know their names. Every register has one pin associated to each port line. So, for instance, bit 3 (with weight 2^3 = 8), is related to the line 3 of the port. You can think of port registers as sets of 8 boolean values.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you want to set bits 0, 4 and 6 of a 8 bit variable you can add its weights:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;">VARIABLE = 2^0 + 2^4 + 2^6;</span></span></b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
That is: </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;"><b><span style="color: #38761d;">VARIABLE = 1 + 16 + 64; </span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Or, in a more "C" style:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;"><b><span style="color: #38761d;">VARIABLE = 1 | (1 << 4) | (1 << 6);<!--4--></span></b></span> </div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;"><br /></span></b></span>
To ease the naming of bits you can use the <span style="color: blue;">bit( )</span> macro that is defined in Arduino.h.<br />
Using this macro you can use an easier bit assignment:<br />
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;"></span></b></span><br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">VARIABLE = bit(0) + bit(4) + bit(6);</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To set one bit of a variable you can use the bitwise OR operator:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">VARIABLE = VARIABLE | bit(3); // Sets bit 3 of VARIABLE</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To clear one bit of a variable you can use the bitwise AND and complement ~ operators.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">VARIABLE = VARIABLE & (~bit(3)); // Clears bit 3 of VARIABLE</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To ease clear and set of variable you can define two macros:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">#define SET_FLAG(REGISTER,FLAG) REGISTER|=(FLAG)</span></b></span></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">#define CLEAR_FLAG(REGISTER,FLAG) REGISTER&=~(FLAG)</span></b></span> </span></b></span></div>
<div class="line" id="file-io430masks-h-LC58">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
So, you can use:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">SET_FLAG(VARIABLE,bit(3)); // Sets bit 3 of VARIABLE</span></b></span></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">CLEAR_FLAG(VARIABLE,bit(3); // Clears bit 3 of VARIABLE </span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can also set several bits at the same time:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">SET_FLAG(VARIABLE,bit(2)|bit(3)); // Sets bits 2 and 3 of VARIABLE</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">CLEAR_FLAG(VARIABLE,bit(2)|bit(3)); // Clears bits 2 and 3 of VARIABLE</span></b></span></div>
<div style="text-align: justify;">
<br />
<br />
If you want, you can use the stock <span style="color: blue;">bitRead</span>, <span style="color: blue;">bitSet</span>, <span style="color: blue;">bitClear </span>and <span style="color: blue;">bitWrite </span>macros defined in Arduino.h:<br />
<br />
<script src="https://gist.github.com/anonymous/51d3c5760c70fd0d4e4f.js"></script><br />
<br />
It is important to know which are the Arduino macros as they are
compliled in place and, because of that, they don't have the overhead
associated to a function call. <br />
<br />
Observe that, using the stock Arduino macros, you should not use the bit( ) macro in the calls:<br />
<br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>if (bitRead(VARIABLE,3) </b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b> {</b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b> // Do something if bit 3 of VARIABLE is set </b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b> }</b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>bitSet(VARIABLE,3); // Sets bit 3 of VARIABLE</b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>bitClear(VARIABLE,3); // Clears bit 3 of VARIABLE</b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>bitWrite(VARIABLE,3,value); // Sets or Clears bit 3 of </b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b> // VARIABLE depending on value </b></span></span><br />
<br /></div>
<div style="text-align: justify;">
Beware that you cannot use the bitSet and bitClear macros to set or clear several bits at the same time.<br />
<br />
<br /></div>
<h3 style="text-align: justify;">
Low level digital I/O</h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The three registers associated to each port controls the port direction (similar to <span style="color: blue;">pinMode</span>) the port output (similar to <span style="color: blue;">digitalWrite</span>) and the port input (similar to <span style="color: blue;">digitalRead</span>). Let's see the one by one.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: blue;"><u>Port Data Direction Registers (DDRB, DDRC, DDRD, DDRE, DDRF)</u></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Those registers indicate, for each line, if it is an input or an output. Each bit on the register can only have two values:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li>"0" Indicates that the line is an input</li>
<li>"1" Indicates that the line is an output </li>
</ul>
<div style="text-align: justify;">
So, for instance, to set Arduino pins 10 and 11, associated to PB6 and PB7 in output mode you can write:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b><span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;">SET_FLAG(DDRB,bit(6)|bit(7));</span></span></b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This way, the above line is equivalent to:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">pinMode(10,OUTPUT);</span></b></span></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">pinMode(11,OUTPUT);</span></b></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But ocupies less program space and requires less time to execute.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: blue;"><u>Port Output Registers (PORTB, PORTC, PORTD, PORTE, PORTF)</u></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
When a port line is in <b>output mode</b>, as set with a DDRx register, this register holds the value that will be seen at the output line.</div>
<div style="text-align: justify;">
</div>
<ul>
<li>"0" Indicates a low value (next to 0 Volts)</li>
<li>"1" Indicates a high value (next to 5 Volts)</li>
</ul>
For instance:<br />
<br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>SET_FLAG(PORTB,bit(6));</b></span></span><br />
<br />
Is equivalent to:<br />
<br />
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">digitalWrite(10,HIGH); </span></b></span><br />
<br />
The low and high output values can be obtained from the datasheet of the ATmega 42u4. <br />
<ul>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkfv17UIQM4OxIzQb9U4PahsV4qMn0yAYVgSnCztapenkKVDTUbjHCgPwAGKKIjhRFUjAQpMN8awZZpxoHZwGo3c0ZauX9x8LxIblLlcaT-40V1ikM0aWD_uQ_1VJopgtzXuW8uP0nOgx2/s1600/DC+Data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="337" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkfv17UIQM4OxIzQb9U4PahsV4qMn0yAYVgSnCztapenkKVDTUbjHCgPwAGKKIjhRFUjAQpMN8awZZpxoHZwGo3c0ZauX9x8LxIblLlcaT-40V1ikM0aWD_uQ_1VJopgtzXuW8uP0nOgx2/s1600/DC+Data.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">DC Voltage Data</td></tr>
</tbody></table>
You can see that the low level output voltage Vol is guaranteed to be below 0.7V up to 10mA of sink current when the supply is 5V. In a similar way, you can see that the high level voltage is guaranteed to be over 4.2V up to 10mA of source current. <br />
<br />
<br />
When a port line is in <b>input mode</b>, however, the PORTx register indicates if the port will feature or not a pull-up resistor.<br />
<br />
<ul>
<li>"0" Indicates that no Pull-Up will be used</li>
<li>"1" Indicates that a Pull-Up will be used</li>
</ul>
It is important to note that when you configure one port from output to input mode, the previous value on the Port Output Register determine if it will feature or not a Pull-Up.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixuX7wVDwMRZnHNkG9DiEVcAuv5qkDfTlIvfqtD5B5ubLj3tzKuRP0qe3bugwWXptKhRLTRS8OBsmHNhVTJfZ-NLfVMWuy_CJaflHYQgXsNeRFqJ8CvQAVt3FN4vA5vZRM_V7vx_mXqGKi/s1600/Pullup+data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="44" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixuX7wVDwMRZnHNkG9DiEVcAuv5qkDfTlIvfqtD5B5ubLj3tzKuRP0qe3bugwWXptKhRLTRS8OBsmHNhVTJfZ-NLfVMWuy_CJaflHYQgXsNeRFqJ8CvQAVt3FN4vA5vZRM_V7vx_mXqGKi/s1600/Pullup+data.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pull-Up resistor data</td></tr>
</tbody></table>
As you can see from the data obtained from the MCU datasheet the Pull-Up resistors on the I/O ports are guaranteed to be between 20kOhm and 50kOhm.<br />
<br />
<br />
That way:<br />
<br />
<b><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #38761d;">CLEAR_FLAG(DDRB,bit(6));</span></span></b><br />
<b><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #38761d;">CLEAR_FLAG(PORTB,bit(6));</span></span></b><br />
<br />
Configures the Arduino pin 10, associated to PB6, in input mode.<br />
And is equivalent to:<br />
<br />
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">pinMode(10,INPUT); </span></b></span><br />
<br />
and<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #38761d;"><b>CLEAR_FLAG(DDRB,bit(6));</b></span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: #38761d;"><b>SET_FLAG(PORTB,bit(6));</b></span></span><br />
<br />
Configures the Arduino pin 10, in input mode with a Pull-Up resistor to Vdd.<br />
And is equivalent to:<br />
<br />
<span style="color: #38761d;"><b><span style="font-family: "courier new" , "courier" , monospace;">pinMode(10,INPUT_PULLUP); </span></b></span><br />
<br />
<br />
<span style="color: blue;"><u>Port Input Registers (</u><u>PINB, PINC, PIND, PINE, PINF)</u></span><br />
<br />
<div style="text-align: justify;">
This register always returns, when read, the logic state at the related port pin. This is independendent on the Input or Output configuration of the port.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This register is normally read for input pins to determine the state of the related lines, but it can also be read for output pins to verify that no external element is forcing a different logic state that the one we set.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Each bit reads:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li>"0" If the related line is at low level (Voltage below Vil_max)</li>
<li>"1" If the related line is at high level (Voltage above Vih_min) </li>
</ul>
<div style="text-align: justify;">
For instance: <br />
<br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>if (PINB&bit(6)) { // Do something </b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b> };</b></span></span><br />
<br />
Is equivalent to:<br />
<br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>if (digitalRead(10)) { // Do something </b></span></span><br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b> };</b></span></span><br />
<br />
<br />
You can find the Vil_max and Vih_min thresholds in the table shown before from the ATmega 32u4 datasheet. As you can see they are:<br />
<br />
<ul>
<li>Vil max = 0,2Vcc - 0,1V = 0.9V at Vcc = 5V</li>
<li>Voh min = 0,2Vcc + 0,9V = 1.9V at Vcc = 5V</li>
</ul>
</div>
<div style="text-align: justify;">
Writing to the PINx registers have not relation with reading them. In fact, writing to a PINx register bit to "1" affects the corresponding Output Register PORTx bit toggling its value. Writting a bit to "0" doesn't make any effect. <br />
<br />
For instance, the line:<br />
<br />
<span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;"><b>PINB=BIT(6); // Toggles PORTB bit 6</b></span></span><br />
<br />
Is much faster than the equivalent line:<br />
<br />
<b><span style="color: #38761d;"><span style="font-family: "courier new" , "courier" , monospace;">digitalWrite(10,!digitalRead(10)); // Toggles Arduino pin 10</span></span></b><br />
<br />
<br />
The following code implements two functions: <span style="color: blue;">highLevelToggle</span> and <span style="color: blue;">lowLevelTogge</span>. The first one uses standard Arduino calls and the second uses low level port accesses.<br />
<br />
<script src="https://gist.github.com/anonymous/bbf26cf239c32a65bb60.js"></script><br />
<br />
Testing the functions you can see that the high level one gives an
output frequency of about 43kHz whereas the low level one gives a
frequency of about 2.5MHz. The low level function is 58 times faster
than the high level one so, when you need to get all the available speed
from the MCU, nothing beats low level programming. The next step will
be using assembler, but the gain wont be so big in this case.<br />
<br />
<br />
<h3>
Code on Github (11/02/2018)</h3>
<br />
The code is now on Github:<br />
<br />
<a href="https://github.com/R6500/Leonardo/blob/master/fastToggleTest.ino">https://github.com/R6500/Leonardo/blob/master/fastToggleTest.ino</a> <br />
<br />
<br />
<br />
</div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-80128400279551802822014-12-01T22:38:00.000+01:002018-02-11T17:34:39.816+01:00Interfacing a MC122032B6W Graphic LCDSometime ago I bought a graphic LCD.I leaved it in corner until I had time to test it. Now it is the time and I will post the low level interface details. In this case I have used an <a href="http://arduino.cc/en/Main/ArduinoBoardLeonardo" target="_blank">Arduino Leonardo</a> because nothing beats the Arduino platform to get a program up and running in no time.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjacnCA0yKstdQPuoQlrLCiTeBd-N2lqP0B05lAk7Q9v_g6bBbRLalHfGyK_PbmmQvtuTdq3Jg1HNzUgNUYppXwd4TKBRXCD5VI7uOGkFmUGVmZCrUNNcX_ImNXpSlZzmLgtuFui0cH8Spa/s1600/01-MC122032B6W.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjacnCA0yKstdQPuoQlrLCiTeBd-N2lqP0B05lAk7Q9v_g6bBbRLalHfGyK_PbmmQvtuTdq3Jg1HNzUgNUYppXwd4TKBRXCD5VI7uOGkFmUGVmZCrUNNcX_ImNXpSlZzmLgtuFui0cH8Spa/s1600/01-MC122032B6W.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Advertisement image of the LCD</td></tr>
</tbody></table>
<br />
<h3>
LCD Information Details</h3>
<div style="text-align: justify;">
The LCD features 122 (horizontal) x 32 (vertical) dots. The interface uses 20 connections for data and power. So it is not a low pin count serial SPI LCD. We would need a lot of lines to make it work.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In the following figure I show with a red dot the origin position on the LCD below the pin #1.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCP8grGRaBVADL9Ml_aUHXKUyKJHIk7mXGSi5uj-n-ekIGDwUVxQCW0Dg5U5u8SPPd7tC9V9QnPyFCqTykpR1VDKJa__hohO4a-UJfUCvZOwbXGN3fIDEHDE1qU99Zf6BPNRrmBh7DtCuc/s1600/02-Origin.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCP8grGRaBVADL9Ml_aUHXKUyKJHIk7mXGSi5uj-n-ekIGDwUVxQCW0Dg5U5u8SPPd7tC9V9QnPyFCqTykpR1VDKJa__hohO4a-UJfUCvZOwbXGN3fIDEHDE1qU99Zf6BPNRrmBh7DtCuc/s1600/02-Origin.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">0,0 coordinate on the LCD</td></tr>
</tbody></table>
<br />
<br />
To start working with the LCD we need its <a href="https://drive.google.com/file/d/0B0PzZrEvAdjVd1VPM0FkMUVVT1k/view?usp=sharing" target="_blank">datasheet</a>. It should include all the required information although, in this case it is not the case.<br />
The following figure shows the LCD pinout on the datasheet. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4ipAfwrcBAs3KnrK7b0gwt8dQ6wWpOJyghUE_Fnydb_UGirt8qPAyvMSwFCnnaJLiviiPviHHC2SwtJPQwzDRjauP5BQ1Z2xScA9Z2CojN63ctCi6dp1EfqTk73B5vjAjc3lGkCKcIWWf/s1600/03-Pinout.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4ipAfwrcBAs3KnrK7b0gwt8dQ6wWpOJyghUE_Fnydb_UGirt8qPAyvMSwFCnnaJLiviiPviHHC2SwtJPQwzDRjauP5BQ1Z2xScA9Z2CojN63ctCi6dp1EfqTk73B5vjAjc3lGkCKcIWWf/s1600/03-Pinout.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LCD Pinout</td></tr>
</tbody></table>
Pins 1, 2 and 3 correspond to Vss, Vdd (5V) and the contrast adjustment V0. These pins follow the usual connections in Character LCDs:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYqmmsao-ggboyBZVR1nV4MywlkUIkqeDpHrkdZkzITpnU4hDMEnIfd5cWE6lg1c8tiFh4uezZlzWkqznamCh6St22a8TJx9exDgB3QWhPudY-NLHurPO-cZBZf2hP1Rl7i84hUeIWkyaP/s1600/04-Contrast.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYqmmsao-ggboyBZVR1nV4MywlkUIkqeDpHrkdZkzITpnU4hDMEnIfd5cWE6lg1c8tiFh4uezZlzWkqznamCh6St22a8TJx9exDgB3QWhPudY-NLHurPO-cZBZf2hP1Rl7i84hUeIWkyaP/s1600/04-Contrast.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Supply and Contrast</td></tr>
</tbody></table>
<div style="text-align: justify;">
The backlight LED is associated to pins 19R and 20. Although the LCD board includes the LED current limiting resistor, I had found it to be too bright for indoor use, so I added a 150 Ohm resistor in series with the LED+ line before connecting to the 5V line.</div>
<br />
<div style="text-align: justify;">
A0 is used to select if the data sent goes to configuration "A0=Low" or data "A0=High". CS1 and CS2 are two chip enable signals. We need two because one driver chip alone is not able to drive all the screen points. It is important to note that the datasheet makes no indication that these lines are <b>active LOW</b>.</div>
<br />
<div style="text-align: justify;">
On pin 7 there is a Clock Input (CL) line were we must feed a 2kHz signal. I its a hassle needing to provide an external clock signal but that's how this LCD works.</div>
<br />
<div style="text-align: justify;">
The R/W signal determines if the data goes to the LCD (Write) or from the LCD (Read). This signal should be called R/W*, R/W# or something like that to indicate that "0" means Write and "1" means "Read". As with character LCDs, we don't need to use the read feature if we don't want to so we can connect this line to GND. That also prevents the potential destructive problems that we could have if we incorrectly try to write on the LCD when it is configured in read mode.</div>
<br />
There are 8 data bits DB0 to DB7 because this is a parallel device where we write a Byte at a time.<br />
<br />
<div style="text-align: justify;">
Finally there is a RST ti reset the LCD. It is important to know that the use of this signal is very important to the operation of the LCD, something that the datasheet doesn't explain. To obtain the information associated to this signal we need to obtain the SED1520DAA driver chip <a href="https://drive.google.com/file/d/0B0PzZrEvAdjVLXloQm8tY2M5X1k/view?usp=sharing" target="_blank">datasheet</a>.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Cawde9JBjrBj6lfT7PNNXgnXnuO4wcwJqCNBsdSKhHWmoteskOWksrdr67cyRjXIEolea5GnJcW3JiS3lX1xbWbwnyz4-StcUf6QwYpHP6yjE5k8UPRcUGBZQ5VzUldQE7Q6jBYJe6iX/s1600/05-Signal+Data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="464" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_Cawde9JBjrBj6lfT7PNNXgnXnuO4wcwJqCNBsdSKhHWmoteskOWksrdr67cyRjXIEolea5GnJcW3JiS3lX1xbWbwnyz4-StcUf6QwYpHP6yjE5k8UPRcUGBZQ5VzUldQE7Q6jBYJe6iX/s1600/05-Signal+Data.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Signal data on the SED1520DAA datasheet</td></tr>
</tbody></table>
<div style="text-align: justify;">
We can see that the LCD can interface two kinds of MCUs, 68-series or 80-series. The kind of MCU that interfaces is determined bye the RES* signal. If it is a LOW pulse the 68-series communication is selected, if it is a HIGH pulse, a 80-series is selected. </div>
<div style="text-align: justify;">
Observe that the R/W only has separates Read from Write in 68 mode. In 80 mode the R/W signal acts as a WR* write enable strobe whereas the E signal acts as a RD* read enable strobe.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In our case we will use the 68-series mode so we must provide a proper reset signal (High level idle state with a low level reset pulse).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To send a Byte to the LCD we must:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li>Set A0 to "0" Command or "1" Data mode</li>
<li>Activate CS1 or CS2 at "0" to select te chip that we are adressing</li>
<li>Set R/W to "0" to set write mode</li>
<li>Send a positive pulse to E to send the data</li>
</ul>
<div style="text-align: justify;">
In order to know the needed timings we can check the LCD datasheet:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDU7ikRv5aBwn6ie2FvkdzbrHymII0uITKpwawaPb3CzZg9zdnCgdjvbjheAZBIHwJL8Wg0xyfUKRDRAXsi77QyPlTlHmtAcWSHT2KAjfX0KMSb7370N81BaZ0qBBlaCxxMy9om0v2mcZj/s1600/06-AC+Data.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDU7ikRv5aBwn6ie2FvkdzbrHymII0uITKpwawaPb3CzZg9zdnCgdjvbjheAZBIHwJL8Wg0xyfUKRDRAXsi77QyPlTlHmtAcWSHT2KAjfX0KMSb7370N81BaZ0qBBlaCxxMy9om0v2mcZj/s1600/06-AC+Data.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LCD AC Data</td></tr>
</tbody></table>
<div style="text-align: justify;">
We can see that is enough to have the E signal high during 80 ns to write the data to the LCD. As the data set up time is equal to the E pulse width and, as the data is captured when E falls, we could send the data at the same time that E goes high.</div>
<div style="text-align: justify;">
All in all we could operate with up to a 5MHz (200ns) cycle time so, using an Arduino Leonardo and stock <b>digitalWrite</b> functions, it is difficult not to meet the correct timings.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Screen Layout</h3>
<div style="text-align: justify;">
The screen layout is badly explained in the datasheet. This is bad beacuse in order to write graphical data on the LCD we need proper information about the correspondence between the framebuffer memory and the screen. After some experiments I can confirm the following layout:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnO1X5cp9n5k8LFBX6nBbUhXkUSQVqvsrarenCIuDZCpyKYslHG1uQjQR1IO_sP0fhrks6OrzW0IA59iZ7rENcQ4OKukoOERVBAmeHNIPWjLJv1f3WCo9D43VWm_iJlogYrzXm1-p6gpPO/s1600/07-Screen+Layout.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnO1X5cp9n5k8LFBX6nBbUhXkUSQVqvsrarenCIuDZCpyKYslHG1uQjQR1IO_sP0fhrks6OrzW0IA59iZ7rENcQ4OKukoOERVBAmeHNIPWjLJv1f3WCo9D43VWm_iJlogYrzXm1-p6gpPO/s1600/07-Screen+Layout.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Screen Layout</td></tr>
</tbody></table>
<div style="text-align: justify;">
There are two driver chips on the LCD board U1 and U2. U1, selected with a low CS1 signal, controls the left half of the screen (columns 0 to 60) and U2, selected with a low CS2 signal, controls the right half of the screen (columns 61 to 121).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Each chip features 240 Bytes of memory distributed in 4 pages of 80 Bytes. Each page is associated to 8 display rows. Page 0 goes from row 0 to row 7, page 2 goes from row 8 to row 15 and so on...</div>
<div style="text-align: justify;">
As there are only 61 columns associated to each chip, we only use 61 bytes in each page. We could use the 19 extra Bytes on each page as a temporal storage as those bytes are not shown on screen.</div>
<div style="text-align: justify;">
The LSB of the Bytes correspond to the lower row associated to the page, so, for instance, bit 0 of page 0 Bytes are associated to the first 0 row. A bit set will light white showing the backlight.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Writes feature an auto-increment, so to fill one page, we can select it and write all bytes from the first to the last column in order.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<h3 style="text-align: justify;">
Test program</h3>
<div style="text-align: justify;">
I have developed an <b>TestGLCD</b> sketch to test the LCD.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<script src="https://gist.github.com/anonymous/d906596368defa7cc8f1.js"></script><br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The <b>setup </b>function configures all pins and provides the 2kHz signal to the clock line using the <b>tone </b>function.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The <b>loop </b>function initializes and rewrites the LCD 20 times. In each iteration, the image is changed so we get some sort of diagonal lines animation.After the animation, there is a pause and the process repeats.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are several commands associated to the possible Bytes we can write with the A0 signal at "0". I have included in the code some <b>defines </b>to give an easier access to those commands.</div>
<div style="text-align: justify;">
Any Byte sent while A0 is "1" will go to the current position on the frame buffer. After each write, the frame buffer position autoincrements.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Putting all together</h3>
<div style="text-align: justify;">
To test the program I have connected an Arduino Leonardo to the LCD. As the interface is parallel there are a lot of wires to connect.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDkZhZfJmoKnegOo_ghFt7Vn28ub63QnPqFpEW14f5KUZCzQAtU73gjjSs_IvbBUmM4W5SfQ_md3c_3h7v3zgS0S5Pgrm0t31ZoaXDhIfL0_tI2WcLnI2nFO6sgCFXaW6q0et6BkZSHWuI/s1600/08-All+Together.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDkZhZfJmoKnegOo_ghFt7Vn28ub63QnPqFpEW14f5KUZCzQAtU73gjjSs_IvbBUmM4W5SfQ_md3c_3h7v3zgS0S5Pgrm0t31ZoaXDhIfL0_tI2WcLnI2nFO6sgCFXaW6q0et6BkZSHWuI/s1600/08-All+Together.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">All the LCD connections</td></tr>
</tbody></table>
<div style="text-align: justify;">
During the program loading the LCD shows some random lines but, after that, the program runs as it should.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLMNaAclT8FWkueUTYez1VpcZFtA2Pxssev-g1HAOlSG2ZsN2zglRHUHsiZFyPVNhek4aOt0H9SDodBw1XuxBkkMxn0u4p1AJ0b3BUx_u975PCGgKcQp1w0bRUDn_hSPlY7mkWrkWxeXDF/s1600/09-Test+Running.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLMNaAclT8FWkueUTYez1VpcZFtA2Pxssev-g1HAOlSG2ZsN2zglRHUHsiZFyPVNhek4aOt0H9SDodBw1XuxBkkMxn0u4p1AJ0b3BUx_u975PCGgKcQp1w0bRUDn_hSPlY7mkWrkWxeXDF/s1600/09-Test+Running.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Program Running</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
<br />
That's all for now. I'm not sure what will I make in the future with this LCD but I will probably write a C library file from the foundations of the test sketch.</div>
<br />
<div style="text-align: justify;">
<br />
<h3>
Firmware on Github (11/02/2018)</h3>
<br />
This code is now on Github<br />
<br />
<a href="https://github.com/R6500/Leonardo/blob/master/TestGLCD.ino">https://github.com/R6500/Leonardo/blob/master/TestGLCD.ino</a><br />
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com9tag:blogger.com,1999:blog-6880821591370697484.post-13869334072162326762014-11-26T10:21:00.000+01:002018-02-11T17:32:50.890+01:00New Firmware for the IR Trigger<div style="text-align: justify;">
Some days ago I posted an article about a RC-1 clone infrared remote trigger for Canon SLR cameras. You can find it in <a href="http://r6500.blogspot.com.es/2014/11/canon-ir-trigger.html" target="_blank">this link</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The design included a quick and dirty firmware developed using <a href="http://energia.nu/" target="_blank">Energia</a>, an Arduino like environment for the MPS430 MCUs. This firmware was enough for testing most of the hardware but it could be improved. Mainly:</div>
<br />
<ul>
<li>It didn't used the 32768 Hz watch crystal</li>
<li>It didn't used the resistors included to measure the battery voltage </li>
<li>It consumed 3.2mA in idle state so it was not efficient at all</li>
</ul>
<div style="text-align: justify;">
Before talking about the code I should comment that there were a pair of errors in the schematic of the previous article. There are two changes that are indicated<span style="color: blue;"> in blue</span> in the following figure: The 22k resistors to measure the battery voltage were at incorrect pins. When soldering the components I changed the pins on the fly to ease the connections and I forget to update the schematic. In the same way the resistor and IR LED diode are swapped to ease, also, the connections. </div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlJNdmRqHRPwJT_0KSoW7lqi6boYdKrmy4F0rsUDq-vNZgDTTtaEZ_Y7Ithu7pBXcYZ6tm7jNytQ2wmWd6l8ej-WJ0VKc4gzrqgW087BP77fjiUEGboRpSq0U9EmIwgQgf5AntoKHSsTeA/s1600/01-New+Schematic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="459" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlJNdmRqHRPwJT_0KSoW7lqi6boYdKrmy4F0rsUDq-vNZgDTTtaEZ_Y7Ithu7pBXcYZ6tm7jNytQ2wmWd6l8ej-WJ0VKc4gzrqgW087BP77fjiUEGboRpSq0U9EmIwgQgf5AntoKHSsTeA/s1600/01-New+Schematic.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">IR Trigger Schematic v1.4</td></tr>
</tbody></table>
<br />
<h3>
GCC Firmware</h3>
<div style="text-align: justify;">
The new firmware was developed on the <a href="http://r6500.blogspot.com.es/2014/11/portable-environment-for-msp430.html" target="_blank">Portable MSP320 Environment</a> I set up some days ago. The Texas Instruments sponsored Red Hat MSP430 GCC I used is a mixed bag. On one hand it provides an easy setup and an up to date selection of MCUs but on the other hand is not fully compatible with previous MSP430 code I developed for the <a href="http://sourceforge.net/projects/mspgcc/" target="_blank">MSP430 GCC at Sourceforge</a>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The firmware code is distributed in three files:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="https://docs.google.com/document/d/1CLfExWOVLxlfoc17N6W-g8K8kGSVHddUCUJ3AR43s6M/edit?usp=sharing">io430masks.h</a></div>
<div style="text-align: justify;">
This file includes some macros to ease the acces to bit fields on the MCU hardware registers.</div>
<div style="text-align: justify;">
I developed this file long time ago but I needed to do some modifications for this project due to the change of toolchain. Due to that, it is not guaranteed that all this file works in a particular toolchain.</div>
<div style="text-align: justify;">
<br />
<script src="https://gist.github.com/anonymous/3e96f492f26586125ce3.js"></script><br />
<br /></div>
<div style="text-align: justify;">
<a href="https://docs.google.com/document/d/1RrUZPhzd8ZN9k6VRDaQTVUq45Rcb_19slPtbXB8Fqek/edit?usp=sharing">main.c</a></div>
<div style="text-align: justify;">
This is the main file for the firmware. It practically contains all the code. It also includes some test code not used in the final firmware but that was left behind.</div>
<div style="text-align: justify;">
<br />
<script src="https://gist.github.com/anonymous/b74a48ad015f91629cfa.js"></script><br />
<br /></div>
<div style="text-align: justify;">
<a href="https://docs.google.com/document/d/10LUGedF83q8qaPyQE-Bk2jOk3PA2pilpL6yH1hJrKuk/edit?usp=sharing">Makefile</a></div>
<div style="text-align: justify;">
This is the makefile that coordinates the build of all the firmware.</div>
<div style="text-align: justify;">
<br />
<script src="https://gist.github.com/anonymous/44a8571979079401c97a.js"></script><br />
<br /></div>
<div style="text-align: justify;">
The code starts stopping the Watchdog and configuring the I/O ports. In particular it is very important to leave guarantee than there is no I/O floating as they will ruin the low power figures. In order to tie the unused lines to GND, the pull-downs are enabled on these lines.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next, the 32768 Hz ACLK clock is configured and set as SMCLK. Then the main DCO clock is configured to operate at 16MHz using the Flash stored factory calibrated values.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After that, the push buttons SW1 and SW2 are configured to generate an interrupt when pressed. The configuration ends with the Timer0A that is connected to the 32768 Hz ACLK as input and associated with a capture interrupt RSI.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At the end of the initialization the red LED gives two blinks to indicate that the system is ready to operate.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After the initialization there is an infinite event loop. There are two possible events, each one associated to a function. If there is no event to process, the system enters in deep sleep LPM4 mode.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The Port 1 RSI associated to the pushbuttons generates the two possible events and gets out of LPM4 mode if needed so that the main event loop can process them.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As it was indicated there are two kinds of events. The SW1 button generates Normal Trigger Events that sends through the IR LED the signal that makes the camera shoot immediately. The SW2 button generates the Delayed Trigger Event that sends a similar signal that makes the camera shoot with a 2 seconds delay.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The signals associated to each event are composed on two 32768 Hz 16 cycles square wave bursts separated with some delay. That delay is used by the camera to identify both signals. The Normal Trigger signal has both bursts starts separated 7.82ms whereas the Delayed Trigger signal uses a 5.86ms separation.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The signals associated to those events are generated with an state machine associated to the Timer. An ISR execution associated to the Capture channel 0 of the Timer 0 provides the change from one state to the following one. The entry point to the state machine for the Normal Trigger Event is the Normal First Burst (NFB) state that connects the ACLK to the P1.4 pin during 16 cycles. After the state times out, the following Normal Delay (ND) state waits during 240 clock cycles. Then the Second Burst (SB) state outputs the second burst of 16 clock cycles to the IR LED. That ends the state machine for the Normal Trigger.</div>
<div style="text-align: justify;">
There is a sencod path in the state machine for the Delayed Trigger signal that starts with the Delayed First Burst (DFB) state. The only difference is this path is the second Delayed Delay (DD) state that is 176 cycles long instead of the 240 cycles associated to the ND state.</div>
<div style="text-align: justify;">
To provide some security against random errors, any undefined state goes to the NONE estate that stops the machine and also the associated timer. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAsgfRbFcMDRkqviNS__bBfK7gDIPmjG0kXm2jEfhNNPnMxDHu3k4TRdrRRsDSvScksDiOQsZ-5HUoYzwxwfq9pK4XoUAXnyDHYAUwEKZOXjKiSqZCuanBtuLGpjCMbq6_dyQghd3ZCIPd/s1600/01b-State+Machine.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAsgfRbFcMDRkqviNS__bBfK7gDIPmjG0kXm2jEfhNNPnMxDHu3k4TRdrRRsDSvScksDiOQsZ-5HUoYzwxwfq9pK4XoUAXnyDHYAUwEKZOXjKiSqZCuanBtuLGpjCMbq6_dyQghd3ZCIPd/s1600/01b-State+Machine.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Timer State Machine</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br />
The use of an state machine is an efficient way to sequence the operations associated to the generation of the IR signal. At the start of the first state NFB, the SMCLK clock is sent to the P1.4 pin, the Compare register TACCR0 is set to 16 cycles in the future and the timer counter TAR is started in countinuous up mode.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjehF5i7g_FgARnxT_11urJGqrj4bAq9KpoU5kHO76Ou-cPjQ2eYnho09aWwovhhj6FvINSbauzKYfa4tNn3t-zpqXima4iKisyoEDNPm_K9fSwsPYCelx6i-v1k6kHfOO1C8HjQHUOawBW/s1600/01c-Timer+TAR.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="398" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjehF5i7g_FgARnxT_11urJGqrj4bAq9KpoU5kHO76Ou-cPjQ2eYnho09aWwovhhj6FvINSbauzKYfa4tNn3t-zpqXima4iKisyoEDNPm_K9fSwsPYCelx6i-v1k6kHfOO1C8HjQHUOawBW/s1600/01c-Timer+TAR.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Timer 0 TAR evolution and States</td></tr>
</tbody></table>
<div style="text-align: justify;">
When the TAR counter reaches the TACCR0 value, an interrupt is generated. That changes the state from NFB to ND. The P1.4 pin is disconnected from the SMCLK clock and the TACCR0 Compare register is set 176 cycles in the future. When TAR reaches the 256 cycle mark a new interrupt is generated giving start to the SB state. A new burst is generated and TACCR0 is set 16 cycles in the future. Finally, at the 272 cycle mark, we enter in the NONE state where the burst ends and the TAR timer counter is stopped. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Measurements</h3>
<div style="text-align: justify;">
I have made some measurements to test the operation of the system. The following image shows the voltage at the IR LED diode during the first burst. We can see that there are 16 pulses. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyiFnJtDDV3_b_wuVCgVKT4VIqgJykxH0ukvfsj15BE9sIo61cRgqwbyRUyn5DqrTFyvpnpkDbx_9LI88vwM8uA4aVMtx18u_x82wIl8W4YnuhoIeEOAOz-hqOJ5A7NmXFk6sZT2EynxY3/s1600/02-Va-k+Burst.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="187" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyiFnJtDDV3_b_wuVCgVKT4VIqgJykxH0ukvfsj15BE9sIo61cRgqwbyRUyn5DqrTFyvpnpkDbx_9LI88vwM8uA4aVMtx18u_x82wIl8W4YnuhoIeEOAOz-hqOJ5A7NmXFk6sZT2EynxY3/s1600/02-Va-k+Burst.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Burst signal at the IR LED</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To measure the clock frequency we can zoom in the burst pulses at the LED. We can see from it that the period is 30.6us so that the frequency is about 32680 Hz. As the start of the signal is not synchronized with the clock, the first pulse is not equal to the rest. In practice this is not a problem but, if it were, we could add another state in the machine to synchronize the burst start.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_RR7p5yuOMpR3RajdyiWhe6b0Vk0IWymtfNgCVQW747SiVox8CX_4CoGqGz_f9lIkJ1qBW55MhjCijrFbvvp3nlxhGu5vYc-FA_RJe5k_uza1T_skus_UnoORuiKBau4VeD3yKFoXhDlx/s1600/03-Va-k+Burst+Detail.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_RR7p5yuOMpR3RajdyiWhe6b0Vk0IWymtfNgCVQW747SiVox8CX_4CoGqGz_f9lIkJ1qBW55MhjCijrFbvvp3nlxhGu5vYc-FA_RJe5k_uza1T_skus_UnoORuiKBau4VeD3yKFoXhDlx/s1600/03-Va-k+Burst+Detail.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Burst pulse detail</td></tr>
</tbody></table>
<div style="text-align: justify;">
The following figure shows the IR LED voltage for the full signal in normal non delayed camera trigger mode. We can measure a 7.81ms delay time between the start of both bursts. This is just the desired value.</div>
<div style="text-align: justify;">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6wk49QaoXaHZU6_qMEA5HfkzUlF72Tl0yv3717CGpj6_kHP60jSjadsEsF9EYyCbwNHLhrNdvYajZ2HnqeyGOtOiYM8znU5u3uzOy0IPKQAhnZ8b4otIWU3rtxJeHd5E4jUJ-sQhSlbZ/s1600/05-Va-k+Immediate.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="103" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip6wk49QaoXaHZU6_qMEA5HfkzUlF72Tl0yv3717CGpj6_kHP60jSjadsEsF9EYyCbwNHLhrNdvYajZ2HnqeyGOtOiYM8znU5u3uzOy0IPKQAhnZ8b4otIWU3rtxJeHd5E4jUJ-sQhSlbZ/s1600/05-Va-k+Immediate.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Normal Trigger Full signal</td></tr>
</tbody></table>
In the same way we can see that the delayed mode trigger features a 5.86 ms time between the start of the two bursts. So everything is ok.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil9OHbBjKU63PEomoxyk-WGScYycNb6jm9hBWYloRfT3l3DfYFDqNdDogmhYLG060OZdQUBULz1rVGSsbBiDjolpxTRssaC5b7E2ofQb8Ok4ijuUZOs3HhfGt4DzixpTws7tR1Il08BQzp/s1600/04-Va-k+Delayed.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil9OHbBjKU63PEomoxyk-WGScYycNb6jm9hBWYloRfT3l3DfYFDqNdDogmhYLG060OZdQUBULz1rVGSsbBiDjolpxTRssaC5b7E2ofQb8Ok4ijuUZOs3HhfGt4DzixpTws7tR1Il08BQzp/s1600/04-Va-k+Delayed.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Delayed Trigger Full signal</td></tr>
</tbody></table>
The above signals indicate that the IR LED has a non zero offset voltage. This is true but it doesn't affect its current. As the IR LED is a diode, it features an exponential relationship between its voltage and its current so by the time its voltage falls below 1V the current is practically zero.<br />
<br />
To test the real current on the diode we can measure the voltage on the current limiting 6.8Ohm resistor that is in series with the LED. We can see that the peak pulse voltage goes from 560mV at the start of the burst to about 470mV at its end. That means that the peak current goes from 82mA to 69mA. We planned for 100mA current and we could lower the current limiting resistor to increase the current, but in the end the CR2032 battery that powers the system could produce system resets due to the fall in the supply during the bursts.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2-a0UbNkLWNEtfChPeOoqyPo-cDW7r3bZ1uTnpZy4Bq1MvyLpcOjTCPmFuMXF7n8el4a1pbzHq1aaSElMvBkCQQgv2cFe3gK8DnTd5sXKmCZMzsGNezgBZXMRqGjMyyBiEEucWMfLpoeB/s1600/06-Vr+Burst.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="250" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2-a0UbNkLWNEtfChPeOoqyPo-cDW7r3bZ1uTnpZy4Bq1MvyLpcOjTCPmFuMXF7n8el4a1pbzHq1aaSElMvBkCQQgv2cFe3gK8DnTd5sXKmCZMzsGNezgBZXMRqGjMyyBiEEucWMfLpoeB/s1600/06-Vr+Burst.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Voltage at 6.8 Ohm resistor</td></tr>
</tbody></table>
<br />
<br />
<h3>
Idle current</h3>
One of the most important drawbacks in the Energia firmware was the 3.2mA idle current. Using the GCC firmware we can use the low power LPM4 mode to significantly reduce this current.<br />
From the information provided on the MSP430G2553 we know that the LPM4 current can be as low as 0.1uA. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnBVESVKAf8E_P8bQn3FrcMmH4eN1k8Z8VF54oVajSb0BAw3ge7czX17WzBjQpHZA-DuhGdIU7NZey8ISN9OzNaXopULUefjtk-Yx1kh3KuU6lOUqHyQi16qxP_qKxMwjK5RUXzZypuR7Z/s1600/07-MSP430G2553+LPM+Table.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnBVESVKAf8E_P8bQn3FrcMmH4eN1k8Z8VF54oVajSb0BAw3ge7czX17WzBjQpHZA-DuhGdIU7NZey8ISN9OzNaXopULUefjtk-Yx1kh3KuU6lOUqHyQi16qxP_qKxMwjK5RUXzZypuR7Z/s1600/07-MSP430G2553+LPM+Table.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Low Power figures in the MSP430G2553</td></tr>
</tbody></table>
Going to currents as low as that is not easy. 0.1uA at 3V means an equivalent resitance of 30 MOhm. Just touching the battery terminals will give a much greater current. That means that we must take care that no current in wasted during the sleep time. As we have commented, all unused pins are tied down to GND using the integrated pull-down resistors. That includes the port 3 lines that are not used in the DIP20 package.<br />
Using this method I obtained in practice the datasheet indicated value of 0.1uA for the typical scenario at 25ºC as you can see in the image below. 0.1uA is so low that we don't need to power down the circuit at all as the battery will live ages with that current.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY6RgxKiewUMREm4rIpMgvTr2a7jauPhvtVqcKaRtJgonQA-2NteCbyNnFNG7kkarB5ouiHIwJuQj_0bG3bu98VMdqCjooo0-trXXzmRzc8FYCrXO08GzMoVtPHL7mlw6bB5aDVWA6JGjI/s1600/08-Low+Current.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY6RgxKiewUMREm4rIpMgvTr2a7jauPhvtVqcKaRtJgonQA-2NteCbyNnFNG7kkarB5ouiHIwJuQj_0bG3bu98VMdqCjooo0-trXXzmRzc8FYCrXO08GzMoVtPHL7mlw6bB5aDVWA6JGjI/s1600/08-Low+Current.png" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">0.1uA current at LPM4 mode</td></tr>
</tbody></table>
</div>
<div style="text-align: justify;">
<br />
<h3>
Power supply measurement</h3>
The firmware also includes a measurement of the power supply after each signal sent. The ADC uses the 1.5V internal reference because the 2.5V one cannot be used below 2.8V. That means that our resistor divider used to measure the supply will get just the maximum 1023 10 bit count at 3V. The system detects the low voltage condition when the voltage falls below 2.6V, that means that the voltage at the divider is 1.3V so that the ADC gives about 890 counts.<br />
<br />
The firmware lights the red LED during 400ms after each transmited signal. When it detects a low battery voltage condition the LED is not turned on so that the user can see that the battery is nearly depleted.<br />
<br />
<br />
<h3>
Last words</h3>
<br />
That's all for now. The code currently ocupies about 2500 bytes with no optimization and with debug enabled. Disabling the debug and turning on the compiler optimizations its size falles to about 2000 bytes. That leaves a lot of room for future firmwares improvements as the MSP430G2553 features 16KB of flash memory. <br />
In fact, the project could be developed in a smaller MCU but given the price differences in the MSP3250G budget line at low volumes there is little to gain in costs selecting another MCU.<br />
<br />
<br />
<h3>
Gist Update (30/11/2014)</h3>
Thanks to <a href="https://gist.github.com/" target="_blank">Gist</a>, now the code, with syntax highlighting, is now included inside the blog entry.<br />
<br />
<h3>
Code on Github (11/02/2018)</h3>
This new firmware and the old energia one are now on Github:<br />
<br />
<a href="https://github.com/R6500/Canon-IR-trigger">https://github.com/R6500/Canon-IR-trigger</a><br />
<br />
<br />
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-78444889124058992992014-11-23T20:21:00.002+01:002014-11-23T21:14:18.808+01:00LED Light Teardown<div style="text-align: justify;">
Today I have made a tear down and reverse engineering of a cheap 12V LED light that is designed to substitute a 12V halogen lamp. Let's see what it is inside.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcT0YqYkK9JV4zR9GtdeiUwQmrLvX27EnetoZggpkSf6aySFbCXh8HuSIuui5oqPx6SyfCpJwVgkGE-SVTpXXwTRLLL0fNgtKFWHN5neiYiW89y6VvMA8r4thYU-6K2pGL8tJ4nIKkyoI-/s1600/01-Blister.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcT0YqYkK9JV4zR9GtdeiUwQmrLvX27EnetoZggpkSf6aySFbCXh8HuSIuui5oqPx6SyfCpJwVgkGE-SVTpXXwTRLLL0fNgtKFWHN5neiYiW89y6VvMA8r4thYU-6K2pGL8tJ4nIKkyoI-/s1600/01-Blister.jpg" height="211" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">12V LED Light</td></tr>
</tbody></table>
<div style="text-align: justify;">
The LED light is composed of 21 small white LEDs. The package says it's 1W. Applying 12V we I get 87mA so it is trully 1W. But what efficiency we get on the circuit?</div>
<br />
<br />
<h3>
The insides</h3>
After breaking the enclosure we get the lamp internals.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuRjP5so0aP8RpozlmsbZgHecYO4dNhLrrWRvylfXz3egka2ohSZ3CNSImhxNavR86C7sllj2RpDSkGb6gSXnd-FlK17aDLdtgdMAiY86iwLmlBSbrAnLvKGIpWme6M6cS5kwel4HI6D6H/s1600/02-Internals.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuRjP5so0aP8RpozlmsbZgHecYO4dNhLrrWRvylfXz3egka2ohSZ3CNSImhxNavR86C7sllj2RpDSkGb6gSXnd-FlK17aDLdtgdMAiY86iwLmlBSbrAnLvKGIpWme6M6cS5kwel4HI6D6H/s1600/02-Internals.jpg" height="320" width="313" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Lamp internals</td></tr>
</tbody></table>
<div style="text-align: justify;">
The lamp is internally composed on two boards. One round board holds the 21 LEDs and a smaller octagonal board holds the control circuit.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6xmTWGv6AJfCDD_D5usjmCYJ7SB0kN_Coq8MfxF6zJlwhcXKdBxLIy0KzXg557UMCHW1crfGFz-gzReE0gD_OmensOhlYAXAcAdbL4FkVPOpFDynHnfab6FYzrYALM9pBdOnZoq37CvHB/s1600/03-21+LEDs.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6xmTWGv6AJfCDD_D5usjmCYJ7SB0kN_Coq8MfxF6zJlwhcXKdBxLIy0KzXg557UMCHW1crfGFz-gzReE0gD_OmensOhlYAXAcAdbL4FkVPOpFDynHnfab6FYzrYALM9pBdOnZoq37CvHB/s1600/03-21+LEDs.jpg" height="315" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LED Board</td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<div style="text-align: justify;">
The LED board is painted white at the LED side to give a better reflectance of stray light.</div>
<div style="text-align: justify;">
Before continuing the tear down, I liked to check the curren on one of the LEDs. To do that, I disordered a LED and re soldered only one terminal to put a multimeter in series.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE8Iqvi-pgQQi6nQZ-upg2t5kOTbTqz8iLDNTgGoPbIMmBdp7O7CXAN50CBqxSNGZVf3-VhJjiNDm7DgTdAF928612ptY_Z9wqVU2HE2InO2lAKnWc-nsmLDjx3dGghprvSpc_T1BM09PQ/s1600/04-Current+meas.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE8Iqvi-pgQQi6nQZ-upg2t5kOTbTqz8iLDNTgGoPbIMmBdp7O7CXAN50CBqxSNGZVf3-VhJjiNDm7DgTdAF928612ptY_Z9wqVU2HE2InO2lAKnWc-nsmLDjx3dGghprvSpc_T1BM09PQ/s1600/04-Current+meas.jpg" height="261" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Current meas setup</td></tr>
</tbody></table>
<div style="text-align: justify;">
Measuring the LED current when operating it gives 10.5mA. Those are quite simple LEDs. More modern LED lamps use high current devices. That's why it needs 21 LEDs to get 1W of power.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Continuing the tear down, I have separated the two boards and removed all LEDs from the led board. The front side has markings so we can see where should be the anode and cathode of each led.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoGLiAuqfz34qy0_4Ai3FtovQJ_HMFu5RsfMU4gKkUmmx7in24lcDHp-hG_-jMLvZdL8eCiLy589Lwday7oxL28t3okgv-nsub6ipFTctgzwKSFmtc0Bb9Y-9qkpCY1BF_ogV-f0Gc8ryO/s1600/05-LEDs+Board+Front.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoGLiAuqfz34qy0_4Ai3FtovQJ_HMFu5RsfMU4gKkUmmx7in24lcDHp-hG_-jMLvZdL8eCiLy589Lwday7oxL28t3okgv-nsub6ipFTctgzwKSFmtc0Bb9Y-9qkpCY1BF_ogV-f0Gc8ryO/s1600/05-LEDs+Board+Front.jpg" height="294" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LED board: Front</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
The back of the led board holds all the connections. From them we can see that the 21 LEDs are arranged in seven parallel groups of 3 LEDs in series. As one white LED can have a forward current of up to 3.5V, we cannot use more than three LEDs in series if we use a linear control circuit. We also don't want to put less than three LEDs because that will give less efficiency.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglYZsq38KT3XTNqx8_odysJjLt5LPYkWJ776NFXmkA5zw3EGvoowXnh-c74FzAB163HyuyUBhrmqr7jkcy8YbtevByzcisrNG0BASSNj2BCcznZiXXJKdNFSXOG4gbUojqCpIdA05V3diz/s1600/06-LEDs+Board+Back.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglYZsq38KT3XTNqx8_odysJjLt5LPYkWJ776NFXmkA5zw3EGvoowXnh-c74FzAB163HyuyUBhrmqr7jkcy8YbtevByzcisrNG0BASSNj2BCcznZiXXJKdNFSXOG4gbUojqCpIdA05V3diz/s1600/06-LEDs+Board+Back.jpg" height="292" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LED board: Back</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: justify;">
As a result of the tear down we get also a bunch of leds.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Ch9ghzr5o2mdYpFr7Av8iWwEquokoaxPB-xOFOn5jWZ_6658Wst-qM5JmvepUqyKK1unPTzIY7nbnwpp-DfX0EG0at0PxgoYvwy3YWl3qNfG_LPrCmdzovqbr3_AWm_HW2aTwSthayQZ/s1600/07-Bunch+of+LEDs.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-Ch9ghzr5o2mdYpFr7Av8iWwEquokoaxPB-xOFOn5jWZ_6658Wst-qM5JmvepUqyKK1unPTzIY7nbnwpp-DfX0EG0at0PxgoYvwy3YWl3qNfG_LPrCmdzovqbr3_AWm_HW2aTwSthayQZ/s1600/07-Bunch+of+LEDs.jpg" height="271" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bunch of LEDs</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Reverse engineering of the circuit</h3>
<div style="text-align: justify;">
The circuit used to power the LEDs is shown in the next figure.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifLd1y6hchp9cahkesQvMlPWAWTadytz4WvecKDIYDsytsQDyIHjl-aKL1MnsA97-K0PFGpSktzu7AEq3q0H7tmhe44ujSVTAq7oHso2JG4A-wKMOgAVhXMHXIHoW-1eQBj_j7_E9_GNMS/s1600/08-Circuit.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifLd1y6hchp9cahkesQvMlPWAWTadytz4WvecKDIYDsytsQDyIHjl-aKL1MnsA97-K0PFGpSktzu7AEq3q0H7tmhe44ujSVTAq7oHso2JG4A-wKMOgAVhXMHXIHoW-1eQBj_j7_E9_GNMS/s1600/08-Circuit.jpg" height="320" width="298" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Control Circuit</td></tr>
</tbody></table>
<div style="text-align: justify;">
There are two input cables for the AC 12V input source and two output nodes (+) and (-) to connect the seven stripes of three LEDs.</div>
<div style="text-align: justify;">
To get the circuit schematic I have taken a photo of the back of the board. I have mirrored it to have the same positions as the component side and I have written down all the components present on the board.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5EiHEL9tnMgGTwouDqrFJ4DYSDTBeiRPLAnJeVfxdvkk7Ey6FRWjflCjzXMWNw7AucYUeVZ1_5aUd_-vYcGFaeeDy11XCYrZkBPlIQ9dEpbs3TPg-_uNkoAy5s-ovhFHHqFOjuhqAj56R/s1600/09-Distribution.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5EiHEL9tnMgGTwouDqrFJ4DYSDTBeiRPLAnJeVfxdvkk7Ey6FRWjflCjzXMWNw7AucYUeVZ1_5aUd_-vYcGFaeeDy11XCYrZkBPlIQ9dEpbs3TPg-_uNkoAy5s-ovhFHHqFOjuhqAj56R/s1600/09-Distribution.jpg" height="298" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Component distribution on the board</td></tr>
</tbody></table>
<div style="text-align: justify;">
</div>
<br />
<br />
<div style="text-align: justify;">
The equivalent schematic of the board follows:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG3ULLmN4n6hUzhh1ijfslY__Whya1lZFZgZgLBnfkuxQYDClCD_Tgpqur3WwubdAGcTBbVay3XMqaQjWPGayxkzAa_Z9WLPQJgD77fqG_7ILZFbYr6jtPcPmts6ujAqWsgB_QScjtRGY1/s1600/10-Schematic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG3ULLmN4n6hUzhh1ijfslY__Whya1lZFZgZgLBnfkuxQYDClCD_Tgpqur3WwubdAGcTBbVay3XMqaQjWPGayxkzAa_Z9WLPQJgD77fqG_7ILZFbYr6jtPcPmts6ujAqWsgB_QScjtRGY1/s1600/10-Schematic.png" height="260" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Circuit schematic</td></tr>
</tbody></table>
<div style="text-align: justify;">
Nothing fancy. Just a linear current control regulator.</div>
<div style="text-align: justify;">
The four diodes take the 12V AC input source and rectify it to get, with the help of the capacitor E1, a constant voltage between Vdd and GND. </div>
<div style="text-align: justify;">
The diodes have a marking RS1M. Those seems to be standard 1A silicon diodes. The voltage at 87mA should be around 0.7V. As we have two voltage drops, that gives a Vdd-Vss voltage of about 10.6V. </div>
<div style="text-align: justify;">
The LEDs are connected to the collector of the big transistor Q1 (D882). The base current of Q1 is fed by the resistor R2. </div>
<div style="text-align: justify;">
The base of Q1 is at two Vbe drops over Vss, so, about 1.2V. That gives a maximum base current of 3.1mA. That means that we can drive the 87mA current of the 21 LEDs with a minimum forward beta (current gain) of 28.</div>
<div style="text-align: justify;">
We need, of course a way to limit the current at the LEDs. That's the mission of Q2.</div>
<div style="text-align: justify;">
The collector current in Q1 is similar to the emitter current that goes to R1. As the base-emitter junction of Q2 is connected to this resistor, when it reaches about 0.6V, Q2 will turn on and drain the base current of Q1. The equilibrium point of the circuit is where Q2 is just starting to turn on and the current at Q1 will be at about 0.6V/R1 that gives 80mA. This theoretical result is quite similar to the measured current of 87mA.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I have measured one of the LEDs and it gives about 3V at 10mA. For a series of three LEDs we get 9V. The voltage at R1 is 0.6V. That gives a voltage drop of about 10.6V - 9V - 0.6V = 1V between the collector and emitter of Q1. Enough room for voltage drop changes on the diodes as function of the temperature.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If we consider that we get a total voltage of 9V on the LED strips from a source voltage of 12V, that means that the circuit efficiency cannot be better than 75%. It could be better using a DC/DC voltage to current converter instead of using linear circuit but what can you expect from a 3€ LED lamp?</div>
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com3tag:blogger.com,1999:blog-6880821591370697484.post-26826225233500845392014-11-18T23:18:00.001+01:002014-11-30T16:29:23.674+01:00Portable environment for the MSP430 Launchpad<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; float: right; margin-bottom: 1em; text-align: center;"><tbody>
<tr></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; float: right; margin-bottom: 1em; text-align: center;"><tbody>
<tr><td style="text-align: center;"></td></tr>
<tr align="left"><td class="tr-caption"><br /></td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><br /></td></tr>
<tr align="left"><td class="tr-caption"><br /></td></tr>
</tbody></table>
I love portable environments. I like programming using an external hard drive, moving the HDD from one PC to another, and continue programming using the same tools and data.<br />
<br />
Here I explain the method I use to create a Windows portable Eclipse based development environment for the MSP340 family using the Launchpad as the programming/debugging link.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgePOQUwS74xE9JFwu6UvFbAC7d6VxApqoCryGXDgbwmtYI-q5KIeMSVfqi8towPcOCWfGTWZejH2sI5NjH7qrWPmClk-ss9ptGTNZPbhYUX45257XfQsWeGtNm2OX0kdkoHDuYr-yOsEBk/s1600/Launchpad.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgePOQUwS74xE9JFwu6UvFbAC7d6VxApqoCryGXDgbwmtYI-q5KIeMSVfqi8towPcOCWfGTWZejH2sI5NjH7qrWPmClk-ss9ptGTNZPbhYUX45257XfQsWeGtNm2OX0kdkoHDuYr-yOsEBk/s1600/Launchpad.jpg" height="320" width="312" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MSP430 Launchpad</td></tr>
</tbody></table>
<br />
As a compiler I will use MSP430 GCC. For every element in the toolchain I try to use as much open software tools as possible but I will also try to keep things simple so sometimes it will be a compromise.<br />
<br />
This is a deep rewrite of the portable development environment for the MSP430 Launchpad board I set up in 2012. I then wrote <a href="http://aim65.blogspot.com.es/2012/03/desarrollo-portable-con-launchpad.html" target="_blank">an article</a> in my spanish blog <a href="http://aim65.blogspot.com.es/" target="_blank">AIM 65</a> and, since then, some things have changed. So, here I am repeating all the steps I made before. Some things are the same but most are quite different.<br />
<br />
This procedure works in Windows 7 and it should work also in Windows XP. Don't know about other operating systems.<br />
<br />
<h3>
Basics</h3>
<br />
<div style="text-align: justify;">
Unfortunately Eclipse is not fully portable between machines. Some paths in the projects are absolute, not relative. That means that if you want to move your Eclipse development environment from one machine to another you have to guarantee that the files have the same location in both places. The easiest way to do that is changing the drive letter in windows so that it is the same in any machine. In my case, my moving HDD uses the letter M, so its M: on all systems.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Check your operating system for the method to assign the external drive letters. It usually involves using the Disk Manager, selecting the drive and selecting one option with the right mouse button contextual menu.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Eclipse is a java application. That means that you need to have java installed in any computer where you want to use the development environment.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are several free toolchains available for the MSP430 devices. Texas Instruments provide a free version of the Code Composer Studio. As they state:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: blue;"><span style="background-color: white;">"A free license will be generated that supports a 16KB code size limit for the optimized TI compiler or no code size limit with GCC."</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You are limited to 16KB but as no MSP4340 value line MCU has more memory that that it's no big deal. Moreover, you can always USE GCC and not be constrained at all.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you want to have an easy install of the tools needed to develop on the MSP430 value line of MCUs, nothing is easier that downloading and installing CCS.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This application is not, however, the target of this article.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One of the complex elements in the development environment is the debug chain. To successfully debug successfully a MSP430 device you usually need:</div>
<br />
<ul>
<li> USB drivers for the board of FET used</li>
<li> DLLs needed to communicate with the USB drivers</li>
<li> GDB Proxy to communicate with a GDB program</li>
<li> GDB program</li>
</ul>
<br />
<div style="text-align: justify;">
The GDB program is usually included with the compiler but the rest of the elements sometimes have to be found in different places.</div>
<br />
Fortunately nowadays the USB drivers are detected and installed automatically and Texas Instruments provides a file that provides the rest of elements together with the GCC compiler.<br />
<br />
<br />
<h3>
Downloading the files</h3>
<br />
First, we will start downloading the required files.<br />
<br />
Go to the Eclipse donwload web page <a href="http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a> and download the required installer. At the time of writing this article it was Eclipse Luna.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMDR4jJCclDE_9wRBCdqwBe9qmshBL4lmRVqfJJF-KNiBgjO5nQF9Pv2Ch5ZjRVSyjunjNwIh3q0kZ6YQWtJ0SmnHouK1tToS4184MVfVB_qYIOOvXoOloEbEmZsrIL1cFnzf_yd4Yc_R4/s1600/01-Eclipse+Download.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMDR4jJCclDE_9wRBCdqwBe9qmshBL4lmRVqfJJF-KNiBgjO5nQF9Pv2Ch5ZjRVSyjunjNwIh3q0kZ6YQWtJ0SmnHouK1tToS4184MVfVB_qYIOOvXoOloEbEmZsrIL1cFnzf_yd4Yc_R4/s1600/01-Eclipse+Download.jpg" height="248" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Eclipse Luna Download</td></tr>
</tbody></table>
As I'm using Win7 32 bit I selected the 32 bit installer.<br />
<br />
Then we need to download the make and other Unix-like companion commands from this link:<br />
<br />
<div style="text-align: center;">
<a href="http://sourceforge.net/projects/unxutils/files/latest/download?">http://sourceforge.net/projects/unxutils/files/latest/download?</a></div>
<br />
You should get a UnxUtils.zip file.<br />
<br />
Finally you should get the Red Hat msp430 gcc compiler from Texas Instruments using this link:<br />
<br />
<div style="text-align: center;">
<a href="http://www.ti.com/tool/msp430-gcc-opensource">http://www.ti.com/tool/msp430-gcc-opensource</a></div>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsoclVL5WitZYNgdV6bdjJMadb48SpmTymihIGwis6LtESvMQLiKGM4AmSuvWiInkqQNaS_rZodNssx7VhJSbEvDJEt_SdOn1rDwoxq3ileamos_f3qOVq4oS2frfBSJsfttUOsRD7gAk2/s1600/02-TI+MSP430+GCC.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsoclVL5WitZYNgdV6bdjJMadb48SpmTymihIGwis6LtESvMQLiKGM4AmSuvWiInkqQNaS_rZodNssx7VhJSbEvDJEt_SdOn1rDwoxq3ileamos_f3qOVq4oS2frfBSJsfttUOsRD7gAk2/s1600/02-TI+MSP430+GCC.png" height="187" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MSP430 GCC at Texas Instruments</td></tr>
</tbody></table>
<br />
You could use the MSPGCC from the sourceforge location. The problem is that it doesn't include all the needed debug elements.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93H_zt-NCej8ETbPLRxRH8tN_iwiL0ob4VBsIifWL6P6TM0TsEtOT6QcnrWg9U2mNJyUwiw5O5IGcQYaX99vtostLCXmidS14NP3VNElUxPNWBvTIOenAYbkH8PD6XBONtC7nqoL273rz/s1600/03-Red+Hat+GCC+2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj93H_zt-NCej8ETbPLRxRH8tN_iwiL0ob4VBsIifWL6P6TM0TsEtOT6QcnrWg9U2mNJyUwiw5O5IGcQYaX99vtostLCXmidS14NP3VNElUxPNWBvTIOenAYbkH8PD6XBONtC7nqoL273rz/s1600/03-Red+Hat+GCC+2.png" height="168" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Second Step downloading MSP430 GCC</td></tr>
</tbody></table>
<br />
That will lead to a page were you need to use a TI account to download the software. It's free, but it could not suit everyone.<br />
At the end you should get a file with a name like msp430-gcc-full-windows-installer-2.1.1.0.exe.<br />
<br />
That are all the files needed to download. You should have something like this list:<br />
<br />
<ul>
<li>eclipse-cpp-luna-SR1-win32.zip</li>
<li>UnxUtils.zip</li>
<li>msp430-gcc-full-windows-installer-2.1.1.0.exe</li>
</ul>
<br />
<h3>
Creating and filling the directories</h3>
<div style="text-align: justify;">
I locate all the microcontroller files inside a MCU folder insider M:. You can do as you please but you'll need to change the directories.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Create the main directory, in my case, as I use Eclipse Luna it will be:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
M:\MCU\msp430_Luna</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Open the eclipse zip file and copy the eclise folder it contains over the newly created directory.</div>
<div style="text-align: justify;">
The main executable of all the environment will be M:\MCU\msp430_Luna\eclipse\eclipse.exe. Feel free to put a link to this file somewhere that is easy to reach like your desktop or your main folder in the external drive.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Create te following four directories inside M:\MCU\msp430_Luna:</div>
<div style="text-align: justify;">
<br /></div>
<ul>
<li>UnxUtils</li>
<li>msp430-gcc</li>
<li>workspace</li>
<li>projects</li>
</ul>
<div style="text-align: justify;">
Copy the contents of UnxUtils.zip inside the UnxItils directory.</div>
<div style="text-align: justify;">
Finally execute the msp430-gcc-full-windows-installer-2.1.1.0.exe GCC installer, accept the license and instruct it to put all the files inside the msp430-gcc folder.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiruwECYuyHB_dO_7ZdzM-3lnphLOLIRztyTaoDV5rdfzky85RZrThnXKzP5hh1vWJowNXGHi3U6gCX3TnlRzbTZa5HjjHtp51mcOAUHQnyMX56XPv4aTJvzBg4sjuZJ0DHnOErZFJtABT7/s1600/04-GCC+Install+02.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiruwECYuyHB_dO_7ZdzM-3lnphLOLIRztyTaoDV5rdfzky85RZrThnXKzP5hh1vWJowNXGHi3U6gCX3TnlRzbTZa5HjjHtp51mcOAUHQnyMX56XPv4aTJvzBg4sjuZJ0DHnOErZFJtABT7/s1600/04-GCC+Install+02.png" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MSP430 GCC Install</td></tr>
</tbody></table>
<div style="text-align: justify;">
So far we have filled the eclipse, UnxUtils and msp430-gcc folders and we have empty the workspace and projects folders.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Configuring Eclipse</h3>
<div style="text-align: justify;">
<br />
Now it's time to run and configure eclipse. Run the eclipse.exe program located inside M:\MCU\msp430_Luna\eclipse (directly or using a previously created link).</div>
<div style="text-align: justify;">
You will see a window like the one shown that prompts for a workspace folder.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwJK8wzqhy0uRxAQ-FnUhS1-D1EoD4XCjXPpcihGg38zhXhfSVtSLezpSO5jgokiT8iAwZx-9pC8jbAIoX8Jjvy2ghYEZJzTLpyF6qa99S171Q4ELAmf0EWY6xx3GGW0n-_jo03PRgGrZs/s1600/05-Workspace.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwJK8wzqhy0uRxAQ-FnUhS1-D1EoD4XCjXPpcihGg38zhXhfSVtSLezpSO5jgokiT8iAwZx-9pC8jbAIoX8Jjvy2ghYEZJzTLpyF6qa99S171Q4ELAmf0EWY6xx3GGW0n-_jo03PRgGrZs/s1600/05-Workspace.jpg" height="183" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Eclipse workspace selection</td></tr>
</tbody></table>
<div style="text-align: justify;">
Select M:\MCU\msp430_Luna\workspace and hit OK.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After some initialization you will see a window like that:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlDGAhyphenhyphenGQIAecM4o5spIqY1CvhWB6T7Tim2zYy-kIQwDEvkjuWY3wCtHKQQr1cloR69Qa7kslJymxmnaXWq4FSJI4QB2LOA5szh1kyL-J9hgZt2cTGATUD_zb811w1l9HQm5-hnpayZ4_u/s1600/12-Eclipse+start.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlDGAhyphenhyphenGQIAecM4o5spIqY1CvhWB6T7Tim2zYy-kIQwDEvkjuWY3wCtHKQQr1cloR69Qa7kslJymxmnaXWq4FSJI4QB2LOA5szh1kyL-J9hgZt2cTGATUD_zb811w1l9HQm5-hnpayZ4_u/s1600/12-Eclipse+start.jpg" height="225" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Eclipse Start Window</td></tr>
</tbody></table>
<div style="text-align: justify;">
Before continuing we must install the needed debug elements inside eclipse. To do that, select "Install New Software" from the Help menu.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcrhROCLGovKQGIBwsbU6HyXB9Jt9lSktMhuuqtYL093V2Lr3vGnb-jJyktN0jFkWgckEcxUjBDtD-ylO2SucZjXwsoY1hHT3HPSvTgYmNnCpAdy-upUgikqadVMZegs4k2ZfZcWizGaTT/s1600/12B-Eclipse+selection.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcrhROCLGovKQGIBwsbU6HyXB9Jt9lSktMhuuqtYL093V2Lr3vGnb-jJyktN0jFkWgckEcxUjBDtD-ylO2SucZjXwsoY1hHT3HPSvTgYmNnCpAdy-upUgikqadVMZegs4k2ZfZcWizGaTT/s1600/12B-Eclipse+selection.png" height="220" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Install new software</td></tr>
</tbody></table>
<div style="text-align: justify;">
Select "All Available Sites" as "Work with" option and write down "GDB Hardware Debugging" as is shown in the next window. It can take a while to do the search.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmHrVV2oZQXAIKc4kcRJz1oBnGgI3eibu1NJQ-WjzVq2PeV6fRz8hJAW0j5InlmhK0rtrE-gCL0S8GgJ6HrpMgCSo3MzCQvTg9FKG58ibLRkSaNznTlElW8FF0Wv-W0BIsZ6exUY9Ye9g7/s1600/13-GDB+Install.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmHrVV2oZQXAIKc4kcRJz1oBnGgI3eibu1NJQ-WjzVq2PeV6fRz8hJAW0j5InlmhK0rtrE-gCL0S8GgJ6HrpMgCSo3MzCQvTg9FKG58ibLRkSaNznTlElW8FF0Wv-W0BIsZ6exUY9Ye9g7/s1600/13-GDB+Install.jpg" height="336" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">GDB Support Installation</td></tr>
</tbody></table>
<div style="text-align: justify;">
Select the C/C++ GDB Hardware Debugging item and click Next.</div>
<div style="text-align: justify;">
Hit Next in the following window, accept the License in the next one and click Finish.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After the install it will prompt to restart, let it do it and use the same workspace when it restarts.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifRR4tsCsx8mS-RHW_3nwD_czkgwNanQWUsehIBsl-wsbU9y1Erw680bBaTwgHOFPfyUsRxacs2-85AhPLM-G1H08HKAbtQIbBBN6K-AH0HD1XqqrURFxhFfDTHo4uxSNgm1pvzw7wtST2/s1600/15-Restart.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifRR4tsCsx8mS-RHW_3nwD_czkgwNanQWUsehIBsl-wsbU9y1Erw680bBaTwgHOFPfyUsRxacs2-85AhPLM-G1H08HKAbtQIbBBN6K-AH0HD1XqqrURFxhFfDTHo4uxSNgm1pvzw7wtST2/s1600/15-Restart.jpg" height="91" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Restarting Eclipse</td></tr>
</tbody></table>
<div style="text-align: justify;">
You will get the same start screen. Here click over the workbench icon to continue.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuC2p8qOTb-6K1UX92heJXLqDSgK2d1M_g_FyD7sNpm9V_OqXVeLgl0E0YksdmJAgsPWBw-irs_p_liOA7MuQZ988-rvSerAMlFznacD6xFVR1zi1nLhNM_0p1XnqMtwQUBCWvy5Yk7mE1/s1600/16-To+Workbench.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuC2p8qOTb-6K1UX92heJXLqDSgK2d1M_g_FyD7sNpm9V_OqXVeLgl0E0YksdmJAgsPWBw-irs_p_liOA7MuQZ988-rvSerAMlFznacD6xFVR1zi1nLhNM_0p1XnqMtwQUBCWvy5Yk7mE1/s1600/16-To+Workbench.jpg" height="228" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Workbench ICON</td></tr>
</tbody></table>
<div style="text-align: justify;">
That will give the standard Eclipse C/C++ view:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXde6B-bGNW3OwhzCu1i3qb5doSsYrrZtj2RusgI5QXHq8hb_aUtYUAv7uvCbSeFuY4YfcMWRO7hK13s-TQhjuEWJ5WLFe9F7PRIh-_q49ymnpB04wjTcMbz91tLsKTzkMGOCb64q3AkW6/s1600/17-C+view.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXde6B-bGNW3OwhzCu1i3qb5doSsYrrZtj2RusgI5QXHq8hb_aUtYUAv7uvCbSeFuY4YfcMWRO7hK13s-TQhjuEWJ5WLFe9F7PRIh-_q49ymnpB04wjTcMbz91tLsKTzkMGOCb64q3AkW6/s1600/17-C+view.jpg" height="228" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Eclipse C/C++ view</td></tr>
</tbody></table>
<br />
<br />
<h3 style="text-align: justify;">
Compiling a Blink example</h3>
Next step is to compile a simple example. In embedded systems a LED blink program is the equivalent of a hello world program in a normal console C program.<br />
The msp430 GCC distribution comes with an example.<br />
I don't like to compile the program in its provided location, so I suggest to copy it to the projects folder, that means copying the folder:<br />
<br />
M:\MCU\msp430_Luna\msp430-gcc\examples\windows\msp430g2553<br />
<br />
To the projects folder location:<br />
<br />
M:\MCU\msp430_Luna\projects<br />
<br />
And rename it from msp430g2553 to blink<br />
<br />
That way you should have the following folder contents:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbWs0TrlsKuQkF7jlku9MIWiQY5MoL-Jfo-oPAkOfUp8xlMRJU6Inxu1PVFYfE0oNRhGc4zlw0ZRf18akd0CoJEUEgpeXCZZgJdJgPVN1eMq3nlaLLcYB2Yc8h3UpIQyhF4yKRd-Pqili8/s1600/18-Blink+project.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbWs0TrlsKuQkF7jlku9MIWiQY5MoL-Jfo-oPAkOfUp8xlMRJU6Inxu1PVFYfE0oNRhGc4zlw0ZRf18akd0CoJEUEgpeXCZZgJdJgPVN1eMq3nlaLLcYB2Yc8h3UpIQyhF4yKRd-Pqili8/s1600/18-Blink+project.png" height="218" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Blink project contents</td></tr>
</tbody></table>
Then we will include this project in Eclipse using the <b>New </b>"<b>Makefile Project with Existing Code</b>" option inside the File menu.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV1KfFOu-SerWgkHWsqlccOpk_dL_zeO8PR2nSUu1l3GTlFMh8EACmQvJsIJct2UaxhRWOpaAs3Tjns5vsWGcxpKGAUgj2g5O-kcwwflZz1cQ5vA9jglfBKafyRR4ioUFsDk9TXHbxIdlW/s1600/19-New+makefile+project.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV1KfFOu-SerWgkHWsqlccOpk_dL_zeO8PR2nSUu1l3GTlFMh8EACmQvJsIJct2UaxhRWOpaAs3Tjns5vsWGcxpKGAUgj2g5O-kcwwflZz1cQ5vA9jglfBKafyRR4ioUFsDk9TXHbxIdlW/s1600/19-New+makefile+project.png" height="96" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Creation of a Makefile Project</td></tr>
</tbody></table>
<br />
That will give a dialog window were you can use the browse button to locate the project directory. Eclipse will give it the "blink" name. You can leave as is or change it.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9c4-85a0V0hoBWIz3pbW1dnON-fnEVgtgZUWxPaZA6w1J8mk4mgHUEjpzyDnwCXb4HqVfeSKNwsyzmJ8oY1WWaKM29OUSZ3w8b9iQwaqBP11H15RhBiCsMOxo4HFTH_fi44PbUakIqaGW/s1600/20-Browse+to+folder.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9c4-85a0V0hoBWIz3pbW1dnON-fnEVgtgZUWxPaZA6w1J8mk4mgHUEjpzyDnwCXb4HqVfeSKNwsyzmJ8oY1WWaKM29OUSZ3w8b9iQwaqBP11H15RhBiCsMOxo4HFTH_fi44PbUakIqaGW/s1600/20-Browse+to+folder.png" height="346" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Creation of new project dialog</td></tr>
</tbody></table>
After clicking on "<b>Finish</b>" the project will be created and you return to the C/C++ view.<br />
Then, you can use the project explorer to view the contents of the Makefile.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWC7LcBm2jzlOqhshktPZpktrLsq4aPGrcgAP4Ai9ZhoENVqUkKBdhU4qRnytfKPP8dfzky_zHEd6xzOACOgeaiWGSu15E1pAS0rvbcb19jO0dw2zLOprq9qsAq3ZEkUNgnQDnWZohKj5r/s1600/21-Project+Makefile.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWC7LcBm2jzlOqhshktPZpktrLsq4aPGrcgAP4Ai9ZhoENVqUkKBdhU4qRnytfKPP8dfzky_zHEd6xzOACOgeaiWGSu15E1pAS0rvbcb19jO0dw2zLOprq9qsAq3ZEkUNgnQDnWZohKj5r/s1600/21-Project+Makefile.png" height="252" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Original project Makefile</td></tr>
</tbody></table>
As we have moved the make file from its original location we need to change the paths.<br />
You can use relative or absolute paths, using relative paths you can set:<br />
<br />
GCC_DIR = ../../msp430-gcc/bin<br />
SUPPORT_FILE_DIRECTORY = $(GCC_DIR)/../include<br />
<br />
Then we can change the -O2 optimization option to -O0 so that the compiler doesn't optimize the code. This is needed if we want to do step by step debugging as the compiler optimizations break the relation between written and executed code. After all debugging is done its best to replace -O0 with -O2 to optimize the program so that the memory is reduced and the program speed is increased.<br />
<br />
Finally, we can change the name of the output file to do that, we will create a new variable called "EXECUTABLE" and use it in the GCC reference.<br />
As we won't use the GDC target in the makefile and we could era its last two lines.<br />
That will give the following Makefile.</div>
<div style="text-align: justify;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip8Lh6CkqsUebes98MiSLFxkKv3B-2ouWkMAzYUOJ5KIBOZkGMPrzs716nF_AMquK86SB38_hcHQAuOYgI1YQ-skfbS01rn_xik5AELY4wptKGaBG_5p9Dty1MXMMoW-RNgMv_QzccZdMv/s1600/22C-New+Makefile.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip8Lh6CkqsUebes98MiSLFxkKv3B-2ouWkMAzYUOJ5KIBOZkGMPrzs716nF_AMquK86SB38_hcHQAuOYgI1YQ-skfbS01rn_xik5AELY4wptKGaBG_5p9Dty1MXMMoW-RNgMv_QzccZdMv/s1600/22C-New+Makefile.png" height="270" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Makefile modifications</td></tr>
</tbody></table>
<div style="text-align: justify;">
This is the final Makefile after all modifications:<br />
<br />
<script src="https://gist.github.com/anonymous/01613bae827cedf0b572.js"></script><br />
<br />
Observe that the makefile is designed to use a <b>MSP430G2553</b> MCU, this is the MCU mounted on the MSP430 Launchpad version 1.5 board. If you want to compile for another MCU you should change this line.</div>
<div style="text-align: justify;">
<br />
After all modifications are made you can save them using the save button.<br />
You can also examine the main<b> blink.c</b> source file:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAkR13WCFVJ4VBK9rfchjkNWXXg5QfTYcTA6z5qWhOicKUSPwgCqzL-OrV9CHNRmu2mhA0erX9cQp8rXcn8UPKNGcym2nLGdPW131RnAVS32ZG516rDQa__nFl1XpNT92l8rLHLYg4-ur7/s1600/34-blink+C+file.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAkR13WCFVJ4VBK9rfchjkNWXXg5QfTYcTA6z5qWhOicKUSPwgCqzL-OrV9CHNRmu2mhA0erX9cQp8rXcn8UPKNGcym2nLGdPW131RnAVS32ZG516rDQa__nFl1XpNT92l8rLHLYg4-ur7/s1600/34-blink+C+file.png" height="236" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">blink.c source file</td></tr>
</tbody></table>
You will see that there are plenty of errors. As this is not an eclipse managed project, the error checker don't know how to process the includes needed to provide several literal definitions. As those errors are quite ugly we can remove them. To do that, select the <b>Project properties</b> on the contextual menu on the <b>blink folder</b> of the <b>Project Explorer</b>. And then select <b>Code Analysis</b> and unselect the 5 elements than end in <b>"..resolved"</b>. Then hit <b>OK</b>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL7tiqfBdWAtAJukHktCGlOCO7Y6DSE8sQyUosY8NvnR1rbOT_QMfiJSq1UwucK6bZZcX8f4A7N1GtnLTncPP8tzojnZIpswMOQg5pflhoQ3Fu3RCHyiu7WSpN9TGMA4K87V2IHD7KwZbo/s1600/35-Code+Analysis.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL7tiqfBdWAtAJukHktCGlOCO7Y6DSE8sQyUosY8NvnR1rbOT_QMfiJSq1UwucK6bZZcX8f4A7N1GtnLTncPP8tzojnZIpswMOQg5pflhoQ3Fu3RCHyiu7WSpN9TGMA4K87V2IHD7KwZbo/s1600/35-Code+Analysis.png" height="321" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Code Analysis</td></tr>
</tbody></table>
That will get us rid of those nasty error messages.<br />
<br />
The last step to obtain an executable is to compile the project. Just select <b>Build Project</b> in the Project menu. </div>
<div style="text-align: justify;">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvNX3xcB5MofC3ybzRf1DY-Z8Pm_kJHSCd2eEzeKIMfoDDDFk1DpXY-XiFTLwI3jme_IRuHqD6yLXYnUxQ5kKMgghj8N2YrigLjYlGHSOq8jeWLOwSltWuG733V8TZ2tulonCZKUcv1HT0/s1600/23-Project+Build.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvNX3xcB5MofC3ybzRf1DY-Z8Pm_kJHSCd2eEzeKIMfoDDDFk1DpXY-XiFTLwI3jme_IRuHqD6yLXYnUxQ5kKMgghj8N2YrigLjYlGHSOq8jeWLOwSltWuG733V8TZ2tulonCZKUcv1HT0/s1600/23-Project+Build.png" height="183" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Building the project</td></tr>
</tbody></table>
If all goes well you will see something like that in the console:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7uI2tOiAqL0ksK-X2JjphikR9uy_x7XTZ8DxqQsCT8N64o6jt9yJ8P141gkDAzzDakhrB7_gxH8Dn40DFOJNEB_ZsbNvuQKg7gy2614mW1eApY7Gb5RvixiO2Z-qs75nrBrvcH_C1Vhft/s1600/24-After+compilation.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7uI2tOiAqL0ksK-X2JjphikR9uy_x7XTZ8DxqQsCT8N64o6jt9yJ8P141gkDAzzDakhrB7_gxH8Dn40DFOJNEB_ZsbNvuQKg7gy2614mW1eApY7Gb5RvixiO2Z-qs75nrBrvcH_C1Vhft/s1600/24-After+compilation.png" height="140" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Console after compilation</td></tr>
</tbody></table>
You can now see in the project explorer that you have two new files in the blink directory . The <b>blink.o </b>object file obtained from the compilation of blink.c and the <b>blink </b>(with no extension) executable file.<br />
<br />
Optionally we can create a command to see the memory usage of the program.<br />
To do that, select <b>External tools configuration</b> in the contextual menu in the tools icon.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOk5tozGfvU88WiOa-770LG3stx7WvXUsv_KOUrlWz21Kbr49MulEFlW45Cn1J2GKLgK5Ko9nYjEI02z1mbGbqWQOtxuRlgQIB0VhGMKNC7kMKjvup69DOTmAbe3L_ixK45Qi2POl5KEuS/s1600/25-External+tools.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOk5tozGfvU88WiOa-770LG3stx7WvXUsv_KOUrlWz21Kbr49MulEFlW45Cn1J2GKLgK5Ko9nYjEI02z1mbGbqWQOtxuRlgQIB0VhGMKNC7kMKjvup69DOTmAbe3L_ixK45Qi2POl5KEuS/s1600/25-External+tools.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">External tools</td></tr>
</tbody></table>
Select program and click the <b>New Launch Configuration</b> button. And fill the data indicated below:<br />
<br />
Name: Resource Size<br />
Location: M:/MCU/msp430_Luna/msp430-gcc/bin/msp430-elf-size.exe<br />
Working Directory: ${container_loc}<br />
Arguments: ${resource_loc}<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbwHyhEjQXj-vbnJmQ1-TFub_N7cLVdmLcSBcze2jsGflHY2ilD3JK-LV8hgVAJEp6wGwyLfpvDePZLmgTsofRrfEGqd-9pw6igUG8HfOgpWlneMIfMQGrW7dCB4vh430PaJtPrtsGjgIY/s1600/26-Resource+Size+main+tab.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbwHyhEjQXj-vbnJmQ1-TFub_N7cLVdmLcSBcze2jsGflHY2ilD3JK-LV8hgVAJEp6wGwyLfpvDePZLmgTsofRrfEGqd-9pw6igUG8HfOgpWlneMIfMQGrW7dCB4vh430PaJtPrtsGjgIY/s1600/26-Resource+Size+main+tab.png" height="387" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Resource size main tab</td></tr>
</tbody></table>
In the build tab unselect <b>Build before launch</b>.<br />
<br />
In the Common tab select <b>External Tools</b> in the <b>Display in favorites menu</b> section.<br />
<br />
After that, just hit <b>Apply </b>and then <b>Close</b>.<br />
<br />
To see, for instance, the size of the executable binary file we can select it in the <b>Project explorer</b> and select the <b>Resource Size</b> element in the <b>External tools</b> menu.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF-m7MmTStiBn5qMMx_MICYlA_odVQrVAMcCQOQijxVi5eYprZao0sU3NUEV_vEQLoPe1mA0wLzBx3DpvnN2ONk6AMY6uT9MzEanC5SVxWOYH7lYUtELKwrzy-2SosfvQ14LLsdcJrYr2C/s1600/27-Resource+size.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF-m7MmTStiBn5qMMx_MICYlA_odVQrVAMcCQOQijxVi5eYprZao0sU3NUEV_vEQLoPe1mA0wLzBx3DpvnN2ONk6AMY6uT9MzEanC5SVxWOYH7lYUtELKwrzy-2SosfvQ14LLsdcJrYr2C/s1600/27-Resource+size.png" height="258" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Resource size of the main binary file</td></tr>
</tbody></table>
Here we can see that the binary file includes 708 bytes of code for a total size of 746 bytes. As the MSP430G2553 features 16KB of flash memory we have plenty of space left.<br />
<br />
<br />
<h3>
Program Run and Debug</h3>
To program and run the program on the MSP430G2553 MCU included in the Launchpad board we need o use several software elements.<br />
<br />
First we need the USB drivers for the launchpad board. They will normally be installed automatically when you connect the board to the computer, but if you need to manually locate them, there are some drivers in this location inside the GCC folder:<br />
<br />
<div style="text-align: center;">
M:\MCU\msp430_Luna\msp430-gcc\emulation\drivers\msp430</div>
<br />
Alternatively you can download the energia drivers from:<br />
<br />
<div style="text-align: center;">
<a href="https://github.com/energia/Energia/raw/gh-pages/files/EZ430-UART.zip" target="_blank">https://github.com/energia/Energia/raw/gh-pages/files/EZ430-UART.zip </a></div>
<br />
Then we need to start the <b>GDB Agent</b> that will communicate the <b>gdb </b>program with the USB drivers. I was not able to properly use the command line program <b>gdb_agent_console.exe</b> without debugging errors so I used the GUI version <b>gdb_agent_gui.exe</b> file instead.<br />
You can run this program directly but I prefer to run it from eclipse. To do that you can create a new external tool configuration:<br />
<br />
Name: GDB Agent GUI<br />
Main TAB:<br />
Location: M:\MCU\msp430_Luna\msp430-gcc\bin\gdb_agent_gui.exe<br />
Working Directory: M:\MCU\msp430_Luna\msp430-gcc<br />
Common TAB:<br />
Select tick in External Tools<br />
<br />
Then click Apply and then close. You have now the <b>GDB Agent GUI</b> program next to the <b>Resource Size </b>one. Launch the <b>GDB Agent GUI</b> and then click on <b>Configure </b>and select <b>msp430.dat</b>. After that click on the <b>Start </b>button.<br />
If all goes well you will see a "Waiting for client" message like in the following window:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwXhOZrqcamjJF61VRIDmCwWge8R49k8fyQvl4QdVl29gdtyrQhLhZkCbiaKoIZmAypqRvQFz4rLP5OmX3AertN9qGKAS8XuR8cakE3RCvu2QHMmFKQo9xKoy0jrDiHV7kjhrzDCfcQrQZ/s1600/28-GDB+Agent.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwXhOZrqcamjJF61VRIDmCwWge8R49k8fyQvl4QdVl29gdtyrQhLhZkCbiaKoIZmAypqRvQFz4rLP5OmX3AertN9qGKAS8XuR8cakE3RCvu2QHMmFKQo9xKoy0jrDiHV7kjhrzDCfcQrQZ/s1600/28-GDB+Agent.png" height="400" width="290" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">GDB Agent</td></tr>
</tbody></table>
After the GDB agent is successfully running we need to create a debug configuration. Use the contextual menu on the <b>debug </b>icon to select <b>Debug Configurations...</b><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtioeJEX1Lp4jh2CPxbMaei2TZ2A3Sqca7N4aIBJQxbDISyk_UO3EdQbo5gG5Q5j66EfC5Y2mH7TjsDd78yJnnVjuPuYKN0mZ50J_ILqwlA6nqjUiZJr4FuQB-p7PYAFiObnIsBDC6z_M_/s1600/29-Debug+configuration+1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtioeJEX1Lp4jh2CPxbMaei2TZ2A3Sqca7N4aIBJQxbDISyk_UO3EdQbo5gG5Q5j66EfC5Y2mH7TjsDd78yJnnVjuPuYKN0mZ50J_ILqwlA6nqjUiZJr4FuQB-p7PYAFiObnIsBDC6z_M_/s1600/29-Debug+configuration+1.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Select Debug Configurations</td></tr>
</tbody></table>
Selecting <b>GDB Hardware Debugging</b>, click on the <b>New Launch Configuration</b> button and fill the following data:<br />
<br />
Name: Blink<br />
Main TAB:<br />
C/C++ Application: blink<br />
Project: blink (Select it from the browse button)<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6kw7d2_GFMr80M-i3z2gdR5EDBuJW2oepoEQO13JnynllscnJyQwx2mc4s8GORmypY6HrtVcHmR4OoPjvMx3yw2GeBQu_etSPSvMCXRtwsaSq8Z8RQ6duEpnuULD3GiYpBOi_jWvcsX_5/s1600/30-Debug+configuration+2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6kw7d2_GFMr80M-i3z2gdR5EDBuJW2oepoEQO13JnynllscnJyQwx2mc4s8GORmypY6HrtVcHmR4OoPjvMx3yw2GeBQu_etSPSvMCXRtwsaSq8Z8RQ6duEpnuULD3GiYpBOi_jWvcsX_5/s1600/30-Debug+configuration+2.png" height="300" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Debug configuration Main tab</td></tr>
</tbody></table>
Then click on <b>Select other...</b> at the bottom of the window and select in the new window <b>Use configuration specific settings</b> and <b>Legacy GDB Hardware Debugging Launcher</b>. Then click <b>OK</b>.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUizIFr7cOwKmeVOmAyjiTRVVQJOiqqnecoZ_LbVvHErqPARGiYlAzNgtvZvlR-m2HrIxlFl0z47Z90cpyyVyBmHeoiyXyU0-IovH8_X-ZLygEKBfeKF705gezYKKkKmmtSVDa3k_bOgFz/s1600/31-Debug+configuration+3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUizIFr7cOwKmeVOmAyjiTRVVQJOiqqnecoZ_LbVvHErqPARGiYlAzNgtvZvlR-m2HrIxlFl0z47Z90cpyyVyBmHeoiyXyU0-IovH8_X-ZLygEKBfeKF705gezYKKkKmmtSVDa3k_bOgFz/s1600/31-Debug+configuration+3.png" height="390" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Selecting the debugger launcher</td></tr>
</tbody></table>
<br />
Next continue with the other tabs:<br />
<br />
Debugger TAB:<br />
GDB Command: M:\MCU\msp430_Luna\msp430-gcc\bin\msp430-elf-gdb.exe<br />
Port number: 55000<br />
<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP_B-7lewRpFiAltP1VwVEjsZ3y_AXIgUe6NCp2u1UjY8npySai-BwnDZs8ZUvPdpK_dxQQCjferSmy1Wo4gBj-hXewvRg0v44fGSIMIZ4geki7tVwyCbs-dlIKyolnzYJ9FROrqO159Eb/s1600/32-Debug+configuration+4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP_B-7lewRpFiAltP1VwVEjsZ3y_AXIgUe6NCp2u1UjY8npySai-BwnDZs8ZUvPdpK_dxQQCjferSmy1Wo4gBj-hXewvRg0v44fGSIMIZ4geki7tVwyCbs-dlIKyolnzYJ9FROrqO159Eb/s1600/32-Debug+configuration+4.png" height="333" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Debugger tab</td></tr>
</tbody></table>
<br />
Startup TAB:<br />
Set breakpoint at: main<br />
Resume <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTbw0xiQVYkdKYkrUNxD1gi9IUtNz3V8LC2fcPAfy62llhLBsPu_9YvEjlB1gePK1v2CVVHp8lmAHYqlntG-yK2lXtAKWUN5ZVuWgvCu-mPN6zUwRe3Cjj2Q5KAZYGJEDz-cszskg76RV1/s1600/32-Debug+configuration+5.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTbw0xiQVYkdKYkrUNxD1gi9IUtNz3V8LC2fcPAfy62llhLBsPu_9YvEjlB1gePK1v2CVVHp8lmAHYqlntG-yK2lXtAKWUN5ZVuWgvCu-mPN6zUwRe3Cjj2Q5KAZYGJEDz-cszskg76RV1/s1600/32-Debug+configuration+5.png" height="250" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Startup tab</td></tr>
</tbody></table>
<br />
Common TAB:<br />
Set tick in Display in favorites menu "Debug"<br />
<br />
After that, <b>Apply </b>all changes and then <b>Close</b>.<br />
<br />
Now you have a new element in the debug icon contextual menu. Check that the<b> GDB Agent</b> is still running and select the <b>Blink </b>option in the debug icon contextual menu.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzQq9ZUUa0iANUtYSkq_x7yRBn9HANoOUD0V0kzPO9EOGVhPmzrvYZBc-LiUnd8FiogTL0w7-V985bNT03jVSLHCQ97ws4zpufa7I8gcicvBv0ZskDwENddX3u1t0rSI7n2M2pY3YQn9A_/s1600/33-Debug+configuration+6.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzQq9ZUUa0iANUtYSkq_x7yRBn9HANoOUD0V0kzPO9EOGVhPmzrvYZBc-LiUnd8FiogTL0w7-V985bNT03jVSLHCQ97ws4zpufa7I8gcicvBv0ZskDwENddX3u1t0rSI7n2M2pY3YQn9A_/s1600/33-Debug+configuration+6.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Launch the debugger</td></tr>
</tbody></table>
You will see message recommending to change the perspective to the debug one. Just say <b>yes</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTTMIZgwbMFkhIbbSriWHhxbaspY2zUOqfB9Fyv2nAhNbLdNMggg8aGFx7eEo72MFl1SvMxiC4IJgpi_g-Af4c3mjtnHe3dEXmiUPnG-xd97iuyfDIlDCvkFWTPl_qb3JpW9fYUTt8fFBp/s1600/34-Change+perspective.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTTMIZgwbMFkhIbbSriWHhxbaspY2zUOqfB9Fyv2nAhNbLdNMggg8aGFx7eEo72MFl1SvMxiC4IJgpi_g-Af4c3mjtnHe3dEXmiUPnG-xd97iuyfDIlDCvkFWTPl_qb3JpW9fYUTt8fFBp/s1600/34-Change+perspective.jpg" height="147" width="320" /></a></div>
<br />
The Debug View will open and you will see something like the following window.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2z2XX9E_7FLVjPlTYbd82mApnAZVCvEZIXhdC2KKeui48rbInFV6ArqMo87yGRtTOsWUfta-GvSwkpa0wHkJ9a6EjxXGzyP9nGvV_22T5N_5_4Pe8PwJz5O4KBl3HxBahxAXnUgcfQpn2/s1600/36-Debug+View.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2z2XX9E_7FLVjPlTYbd82mApnAZVCvEZIXhdC2KKeui48rbInFV6ArqMo87yGRtTOsWUfta-GvSwkpa0wHkJ9a6EjxXGzyP9nGvV_22T5N_5_4Pe8PwJz5O4KBl3HxBahxAXnUgcfQpn2/s1600/36-Debug+View.png" height="315" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Debug View</td></tr>
</tbody></table>
We see that the program is stopped at the start of the main program. To continue running the program just push the <b>play </b>button.<br />
<br />
You should see the red LED blinking on the Launchpad board. Congratulations!!!<br />
<br />
You can now use the <b>pause </b>button to pause program execution. To continue, just push the <b>play </b>button another time. You can also see the variables contents and use breakpoints but all that goes out of the scope of this long article.<br />
<br />
To end the debugging you can hit the Terminate red square icon and remove the terminate debugin session selecting it and hitting the DEL key. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzrLzKWSqEnr4qhFPP3RrmN5jlhzMsNo1R2YU3QqqdbWUpHXdSqZjU0X4ZPaUCNwOe0mjq9SpxIgOlzkk1KwR1SOmVn8aMO-IlpN8WAeyl62IVRF4KWP2c3xDpWZxpiItwLnswSYur-1tD/s1600/37-Terminate.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzrLzKWSqEnr4qhFPP3RrmN5jlhzMsNo1R2YU3QqqdbWUpHXdSqZjU0X4ZPaUCNwOe0mjq9SpxIgOlzkk1KwR1SOmVn8aMO-IlpN8WAeyl62IVRF4KWP2c3xDpWZxpiItwLnswSYur-1tD/s1600/37-Terminate.png" height="218" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Terminate the debugging session</td></tr>
</tbody></table>
After all debug is done, the GDB Agent can also be terminated selecting it and pushing the red square terminate button. After that, the DEL key will eliminate it from the debug view.<br />
<br />
<h3>
Closing Words</h3>
After all this work we have a blink project and a MSP430 portable development environment to be used with it. To create a new project you can duplicate the <b>blink </b>entry on the <b>projects </b>folder and repeat the needed steps to incorporate the project in eclipse.<br />
<br />
You don't need to repeat the creation of the items in the run <b>programs menu</b>, but you must replicate the <b>debug entry</b> for each new project. To do that, the easiest way is have the blink and the new projects open at the same time and duplicate the debug entry in the debug configurations window.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiocfSesTxT6sTqSDZVr7zCbC73WyDA2WI4dgYrMtoN7BNpT_TEl7tC06AtGQdXt2zPhc_KQgE5R-sJVz7b7KdROeBAP397YwPO56sZE8KCcupzS08IiH3RbHDZwKKX3wD9XsidumekaMYy/s1600/36-Debug+Duplication.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiocfSesTxT6sTqSDZVr7zCbC73WyDA2WI4dgYrMtoN7BNpT_TEl7tC06AtGQdXt2zPhc_KQgE5R-sJVz7b7KdROeBAP397YwPO56sZE8KCcupzS08IiH3RbHDZwKKX3wD9XsidumekaMYy/s1600/36-Debug+Duplication.png" height="320" width="222" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Duplicating a debug configuration</td></tr>
</tbody></table>
That's all for now. The eclipse environment is so complex that there is no more space in this article to talk about it. I will probably write more on the subject in future articles.<br />
<br />
<br />
<h3>
Compiler woes (update at November, 25 2014)</h3>
It seems that the TI sponsored msp430 gcc compiler is not able to determine how to do multiplications on the MSP430G2553. I got strange results in multiplications and I suspect that the compiler is trying to use a hardware multiplier that this MCU lacks.<br />
<br />
I needed to do some guesswork to find the needed <span style="color: blue;">-mhwmult</span> compiler option as I could not find where it is documented. Finally I know, by asking the gcc compiler, that there are 5 available options: <span style="color: blue;">16bit</span>, <span style="color: blue;">32bit</span>, <span style="color: blue;">auto</span>, <span style="background-color: white;"><span style="color: blue;">f5series</span> </span>and <span style="color: blue;"><span style="background-color: white;">none</span></span>.<br />
<br />
In order to correctly compile the code I had to include the compiler option:<br />
<br />
<div style="text-align: center;">
<span style="color: blue;">-mhwmult=none</span></div>
<br />
That way multiplications go as they should.<br />
<br />
The interrup macro at<span style="color: blue;"> iomacros.h</span> is also broken. It is defined:<br />
<br />
<div style="text-align: center;">
<span style="color: #38761d;">#define __interrupt(vec) __attribute__((__interrupt__(vec)))</span></div>
<div style="text-align: center;">
<br /></div>
but msp430-gcc don't like this format. I have developed a new definition:<br />
<br />
<div style="text-align: center;">
<span style="color: #38761d;">#define interruptNew(vec) __attribute__((interrupt(vec)))</span></div>
<br />
That way I can properly compile, for instance, the port 1 RSI:<br />
<br />
<span style="color: #38761d;">void interruptNew(PORT1_VECTOR) PORT1_ISR (void)<br /> {</span><br />
<span style="color: #38761d;"> // Do RSI things </span><br />
<span style="color: #38761d;"> }</span><br />
<br />
<br />
<h3>
Gist Embedded Makefile (Update at 30/11/2014)</h3>
Now the Makefile code is embedded in the blog using <a href="https://gist.github.com/" target="_blank">Gist </a><br />
<br />
<br />
<br />
<br />
<br />
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"><tbody>
<tr><td style="text-align: center;"></td><td style="text-align: center;"></td><td style="text-align: center;"></td></tr>
<tr align="left"><td class="tr-caption"><br /></td><td class="tr-caption"><br /></td><td class="tr-caption"><br /></td><td class="tr-caption"><br /></td><td class="tr-caption"><br /></td></tr>
</tbody></table>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com5tag:blogger.com,1999:blog-6880821591370697484.post-78417842245080162272014-11-09T17:42:00.000+01:002018-02-08T14:42:08.185+01:00Canon IR Trigger<div style="text-align: justify;">
This article explains the development of an IR trigger to be used on Canon EOS digital SLR cameras. It should mimic the operation of the Canon RC-1 remote trigger and will be built around an MSP430G2553 microcontroller. The article showed up on the <a href="https://hackaday.com/2014/11/09/an-msp430-clone-of-the-canon-rc-1-remote/" target="_blank">hackaday</a> blog.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA_kp5PUcA4YO7un_fwCmFUkeOC956kJXy2vymSm6lC2i8_pay9_1y4b9KHGywsn7k5kbKDssv0XLYGcUXr5K_9QZV4VplyHurTe7jbasEC4M8QMInFj97bQto2tECgc6pPUd_xILNaNrt/s1600/Canon+RC-1+(Small).png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgA_kp5PUcA4YO7un_fwCmFUkeOC956kJXy2vymSm6lC2i8_pay9_1y4b9KHGywsn7k5kbKDssv0XLYGcUXr5K_9QZV4VplyHurTe7jbasEC4M8QMInFj97bQto2tECgc6pPUd_xILNaNrt/s1600/Canon+RC-1+(Small).png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Canon RC-1 remote trigger</td></tr>
</tbody></table>
<div style="text-align: justify;">
The Canon RC-1 device features two options to remote trigger a camera. Instant shot, just as it receives the signal and two seconds delayed shot after the signal is received. That way, if you are in the photo, you have time to hide the remote out of view when the photo is taken.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A clone of the RC-1 trigger can be bough at about 20€ in local photo stores so the point of this development is not for economic purposes but to exercise in miniaturization and power restrictions.</div>
<div style="text-align: justify;">
I will also use it to add some new features in the future as the system will be reprogrammable.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's start with the basics.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Precedents and signal specs</h3>
<div style="text-align: justify;">
Developing a DIY RC-1 clone is not anything new. I have used as a reference the <a href="http://www.doc-diy.net/photo/eos_ir_remote/" target="_blank">EOS IR REMOTE</a> work at doc-diy.net. This work is quite interesting for anyone trying to develop a RC-1 clone as it includes a <a href="http://www.doc-diy.net/photo/rc-1_hacked/index.php" target="_blank">reverse engineering</a> of the original RC-1 remote. I don't quite like the proposed direct connection of a IR LED to the output pins of a MCU but worse things I have seen.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
From this reference I have obtained the needed signal specifications.</div>
<div style="text-align: justify;">
To send the trigger signal, the Canon RC-1 remote sends two 16 pulses bursts. The bursts are at about 32700 Hz and are obtained from a watch crystal (They should be probably 32768 Hz).</div>
<div style="text-align: justify;">
The two burst separation determines the operation of the trigger.</div>
<div style="text-align: justify;">
If the start of both bursts are separated about 8ms (7.82ms) the shot is taken just as the signal is received.</div>
<div style="text-align: justify;">
If the burst separation is about 6ms (5.86ms) the shot is delayed two seconds after the signal is received.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The signal protocol is quite easy to reproduce and that simplifies the developing of a RC-1 clone.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The reference also indicates that the RC-1 remote uses an infrared signal with a 950nm wavelength.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
IR LED Selection</h3>
<div style="text-align: justify;">
The main element in the remote trigger is the Infrared LED that should send the pulse bursts to the camera. To select an optimal component we would need the characteristics of the IR receiver on the Canon EOS cameras. Unfortunately I don't have that information but a reasonable guess can be made from other IR receivers we can find in the market. I have considered a <a href="http://www.farnell.com/datasheets/1699774.pdf" target="_blank">TSOP11</a> as and example of a typical IR receiver (normally used in IR remote receivers).</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyzyoEmQeULcyGR0r53YopwAPauyGtMPIkeKr_xr76uaCAsFQSklvrWAffUkkAQ8e3hOEuI6eqwNDpgos4nd2s5rbq5Xre_zwLviYMQx5ble3t1S52aZPBe_cLvV3eU0DwX4LRX4B-jakG/s1600/TSOP11+View.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyzyoEmQeULcyGR0r53YopwAPauyGtMPIkeKr_xr76uaCAsFQSklvrWAffUkkAQ8e3hOEuI6eqwNDpgos4nd2s5rbq5Xre_zwLviYMQx5ble3t1S52aZPBe_cLvV3eU0DwX4LRX4B-jakG/s1600/TSOP11+View.png" width="200" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">TSOP11 IR Receiver</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Silicon is sensitive to wavelengths from near infrared to the end of the visible spectrum. IR receivers usually incorporate an IR filter that reduces tha sensitivity to visible wavelengths. That way, the visible light that shines over the receiver don't interfere with the revived IR signal. In the following figure I show the typical silicon wavelength sensitivity (from a silicon photodiode BPW33) together with the sensitivity of a TSOP11 receiver and the visible wavelength range. As can be seen, the IR filter on the receiver removes all sensitivity to short wave light, including all the visible range. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtD3wIEUQqLa56khtYKbZEEA0sKnBqpBFY9HTB7myFmBQdyyZlGjY0DGfjMDbaCOArR1lsZKZ9wrQh8gOGwuXvmM8D6SSws4sWkHu2oY4jfbtOxyMcUKOD1yFdOeZ4yDqu7tT9DlCEYqI9/s1600/IR+Receptor+sensitivity.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtD3wIEUQqLa56khtYKbZEEA0sKnBqpBFY9HTB7myFmBQdyyZlGjY0DGfjMDbaCOArR1lsZKZ9wrQh8gOGwuXvmM8D6SSws4sWkHu2oY4jfbtOxyMcUKOD1yFdOeZ4yDqu7tT9DlCEYqI9/s1600/IR+Receptor+sensitivity.png" width="248" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">TSOP11 IR Receiver Vavelength Range</td></tr>
</tbody></table>
<div style="text-align: justify;">
We cannot be sure that the EOS Cameras have the same sensitivity as the TSOP11, but its a quite reasonable guess. The fact that the RC-1 uses a wavelength of 950nm, just at the center of the TSOP11 curve, gives us some additional confidence.</div>
<br />
Knowing the receiver sensitivity is important to select the IR emitter LED for the project as not all IR LEDs are created equal.<br />
<br />
For instance, we can check a TSUS5400 LED whose characteristics are shown below:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4upTNvnVTWqvaA0kEhOOrI1fRuBMdJBA6yBVPqMzix4Si3zymfA3MQeo3qJUUm3m_45hl9G0B2w-zyvJq4BZMs7AoV2Ji_4G4nQQhMvX92x2vsh5xSIja5D3Jfo79lGepOTrTvd33Y5Lc/s1600/TSUS+Power.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="83" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4upTNvnVTWqvaA0kEhOOrI1fRuBMdJBA6yBVPqMzix4Si3zymfA3MQeo3qJUUm3m_45hl9G0B2w-zyvJq4BZMs7AoV2Ji_4G4nQQhMvX92x2vsh5xSIja5D3Jfo79lGepOTrTvd33Y5Lc/s1600/TSUS+Power.png" width="640" /></a></div>
<br />
<div style="text-align: justify;">
The peak wavelength is at 950nm, just at the center of the TSOP11 receiver. So it will be ideal for the project. But peak wavelength is not all that we need. We also need power. The TSUS LEDs feature powers between 14 and 20 mW/sr. That is, 20mW for each stereoradian of solid angle.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In every radiant emitter there is a compromise between angle and power density. The radiant angle of the TSUS diodes is +/- 22 degrees. As can be show in the following curve:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh3DjuZr9NK8fWUoZuKeoHIAvtSeCv5aXWQOo_SE1YUaB9mozJSIsC3hsIBqVGMZNBo2Kd5TFTpuiLyaxBfQvr0-PsiNRXFSywrC6BWYpGupR-s4KTsmjF0hC2zRp_IpqVqfVVojYYczZs/s1600/TSUS+Angle.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh3DjuZr9NK8fWUoZuKeoHIAvtSeCv5aXWQOo_SE1YUaB9mozJSIsC3hsIBqVGMZNBo2Kd5TFTpuiLyaxBfQvr0-PsiNRXFSywrC6BWYpGupR-s4KTsmjF0hC2zRp_IpqVqfVVojYYczZs/s1600/TSUS+Angle.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Angle spread of TSUS LEDs</td></tr>
</tbody></table>
<div style="text-align: justify;">
Having a big spread angle is good because that way we don't need to point exactly in the Camera direction, but is also bad because the total energy is spread in a bigger angle so less power incides in the receptor. As always there is no win-win solution and we should compromise. We can have a good range and a need to a better aiming or a bad range and loose aim needs. In this project I considered that 20mW/sr was quite low so I checked for other IR emiter options.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I finally narrowed the selection to two LEDs: TSHF5210 and TSAL6100. Both LEDs have the same angle spread of +/-10 degrees. As you can see from the following figure, that means that we will need a good aiming to us those devices.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMEfFlpkP9AneOCgaIhsonDozC3moB4oPXBdK1sbqOOCvFAiflffGStT1J6Cvj96T-YtfXZRh-kRtRDTLXchIS-Sf5Yzd_nBq8Wu1_Hv3ENouNOpzXpqXcmIuilCAZFQ_N6gk6xwTp4E_c/s1600/IR+LED+Angle+2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMEfFlpkP9AneOCgaIhsonDozC3moB4oPXBdK1sbqOOCvFAiflffGStT1J6Cvj96T-YtfXZRh-kRtRDTLXchIS-Sf5Yzd_nBq8Wu1_Hv3ENouNOpzXpqXcmIuilCAZFQ_N6gk6xwTp4E_c/s1600/IR+LED+Angle+2.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Selected LEDs angle spread</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br />
The range is much better because those LEDs feature a quite bigger radiant power:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibe8kv014Qo8T-ZKv74pbwqfcOehajNyVSGT6MFaAxjOfiO1B825aXTIWPw_2ok6cBrPXpP9VqBWRQuulRzlq52tbOYNcHdbwGx0hvcwoPpVXnHyVC8kRQhNarPTw1XMeXo3ydaFtqA65J/s1600/IR+LED+Angle.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibe8kv014Qo8T-ZKv74pbwqfcOehajNyVSGT6MFaAxjOfiO1B825aXTIWPw_2ok6cBrPXpP9VqBWRQuulRzlq52tbOYNcHdbwGx0hvcwoPpVXnHyVC8kRQhNarPTw1XMeXo3ydaFtqA65J/s1600/IR+LED+Angle.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYVmmrg2uDYJ9SbSwbmQtq-dLZNntPU9-2xe5DTcqVV211rp6FqmbnelBZlAGbVpT8z0Vz-cUgSIdnuWcJS26u1DbSX5HCJmRDgytY4Hm8B_fq9mtYE_a04N0KwTwQf57G1kbZrSIS-kDf/s1600/TSAL6100+Angle.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYVmmrg2uDYJ9SbSwbmQtq-dLZNntPU9-2xe5DTcqVV211rp6FqmbnelBZlAGbVpT8z0Vz-cUgSIdnuWcJS26u1DbSX5HCJmRDgytY4Hm8B_fq9mtYE_a04N0KwTwQf57G1kbZrSIS-kDf/s1600/TSAL6100+Angle.png" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Both feature radiant powers over 100mW/sr (much better than the TSUS LEDs) but they are different in peak wavelengths and response time.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are IR LEDs in the market with better radiant power. The SFH4550, for instance, features 400mW/sr at 100mA. But its radiant spread angle is only +/3 degrees so you will need a very good aim to use it. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Respect to the response time we would like to send 32768Hz signal bursts. That means a period of about 30us. A response time of about 1us in the TSAL6100 seems to be ok, but the TSHF5210 is better.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Respect to the wavelength, the TSAL6100 at 940nm is very near to the 950nm peak value of the RC-1 and the expected sweet point of the IR receiver. The project were I got the RC-1 specs used a SFH484 LED that has a peak wavelength of 880nm so I think that the 890nm of the TSHF5210 could not be too bad.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To further analyze the wavelength question we can put the LED responses, obtained from their datasheets, in the expected receiver sensitivity curve. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-jwPKF4PxAsVRXNimLU9fI1Obh30SiD97eyjNVcxbDAWFKiPWZWxHpiXBknSgM3OiF6K8gz8l9kEPjQXcyT_3h5u134GE1Vne2K_ohwQRkarltG1wLm2F6JRpQsxxzb7geNVapmtfGiuT/s1600/Sensitivity+Compare+3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="283" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-jwPKF4PxAsVRXNimLU9fI1Obh30SiD97eyjNVcxbDAWFKiPWZWxHpiXBknSgM3OiF6K8gz8l9kEPjQXcyT_3h5u134GE1Vne2K_ohwQRkarltG1wLm2F6JRpQsxxzb7geNVapmtfGiuT/s1600/Sensitivity+Compare+3.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LED Wavelength comparison</td></tr>
</tbody></table>
As can be seen, the TSAL6100 diode is better positioned in the center of the receiver range. But the TSHF5210 has a bigger output (180mW/sr versus 130mW/sr). The bigger radiant power somewhat compensates for the wavelength offset. As the TSHF5210 also is faster I selected in the end this diode. In fact I can change it in the future so its not a big deal.<br />
<br />
<br />
<h3>
Circuit Design</h3>
<div style="text-align: justify;">
The circuit to drive the IR LED is constructed around a <a href="http://www.ti.com/product/msp430g2553" target="_blank">MSP430G2553</a> microcontroller in a DIP20 package. This MCU, as the following figure shows, features 16KB Flash, 512B RAM, Two 8 bit ports (The third one is not available in a DIP package) and several peripherals. It can be overkill for this project but, for the added cost respect to less complex MCUs in the MSP430G family I don't need to optimize program size and several features can be added in the future without needing to change the MCU.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBtuuiSN5kVFmq0hRPkUbxRNGt4zDDuOgRba55MfQvDF7RUf4o1ZDuXsgBJl9DLSSiYGWauEx5z9eq-U0alEviTPfNI0JliAMRnX8DXGOrKZDjZDbU4yYfd2eU4Twa34VbkX0-NPoxhtaW/s1600/MSP430G2553.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBtuuiSN5kVFmq0hRPkUbxRNGt4zDDuOgRba55MfQvDF7RUf4o1ZDuXsgBJl9DLSSiYGWauEx5z9eq-U0alEviTPfNI0JliAMRnX8DXGOrKZDjZDbU4yYfd2eU4Twa34VbkX0-NPoxhtaW/s1600/MSP430G2553.gif" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MSP430G2553 Features</td></tr>
</tbody></table>
<br />
Around the MCU there are several components, as we can see from the schematic below. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8Fv6wfNQ6hOGFRu-kJYzUwgbV8UN6vk1WMwLwaNUfsUy4apWDsyUxM1pHcvw4P0lxM6kGUBd1jZQqcuMUfveVY1EcKssn0KojARYf0MseU9z_Nu0zFmmGTUIlThD47CwZ0Rc_jMDcMmdR/s1600/Schematic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="465" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8Fv6wfNQ6hOGFRu-kJYzUwgbV8UN6vk1WMwLwaNUfsUy4apWDsyUxM1pHcvw4P0lxM6kGUBd1jZQqcuMUfveVY1EcKssn0KojARYf0MseU9z_Nu0zFmmGTUIlThD47CwZ0Rc_jMDcMmdR/s1600/Schematic.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Canon IR Trigger Schematic</td></tr>
</tbody></table>
<div style="text-align: justify;">
The IR LED is driven by a BC547 bipolar transistor in emitter follower configuration (common collector). This configuration don't require a base resistor as the common emitter configuration and is faster because the transistor never gets into the saturation region. This comes at a price, though, as the output voltage is reduced about 0,5V respect of the common emitter configuration. In this application this is no problem because we only need a maximum of 1.6V to drive the LED at 100mA as we can see from its datasheet:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQWkpbyFJNsvV-OIb3RNFTrzsd2fOibO5nhr-QOQVXfj-JQYaD1aDpNrLKPvVt0ofhLQsaAiqxDOh56fztXSA5Ni4Gw9MUGs7r6nMd5-JVD1sBvCkA3iqJsMA5rvVE_zzDzFg2KdnhMcim/s1600/IR+LED+Vf.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="70" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQWkpbyFJNsvV-OIb3RNFTrzsd2fOibO5nhr-QOQVXfj-JQYaD1aDpNrLKPvVt0ofhLQsaAiqxDOh56fztXSA5Ni4Gw9MUGs7r6nMd5-JVD1sBvCkA3iqJsMA5rvVE_zzDzFg2KdnhMcim/s1600/IR+LED+Vf.png" width="640" /></a></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDtwu8uw81hWPZb1nu-Ssx5apfVvKHW-it7HP5gca3XE-TtFeGDeXTrXykh9rp4cfUML7tlsyn16F7mfAsnj8aVzfcm2H_iXTRcn60F9TvZsgpqEzFTp4mPHYoLFreIuDy5fPP_GfayFjS/s1600/IR+LED+If.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDtwu8uw81hWPZb1nu-Ssx5apfVvKHW-it7HP5gca3XE-TtFeGDeXTrXykh9rp4cfUML7tlsyn16F7mfAsnj8aVzfcm2H_iXTRcn60F9TvZsgpqEzFTp4mPHYoLFreIuDy5fPP_GfayFjS/s1600/IR+LED+If.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">TSHF5210 data</td></tr>
</tbody></table>
<div style="text-align: justify;">
We can see that the maximum continuous forward current is 100mA. In our application we send a 16 pulse burst at 32768Hz. That gives a total duration of 488us that is more that the allowed peak forward current time of 100us in the datasheet. So we will keep the current at about 100mA.</div>
<br />
The emitter follower configuration needs series resistor with the LED that can be calculated:<br />
<br />
Rseries = ( Vport - Vled - Vbe ) / Iled<br />
<br />
Where:<br />
Vport: Is the output voltage in a microcontroller port (3V)<br />
Vled: Is the maximum LED forward voltage Vf (1,6V)<br />
Vbe: Is the base emitter voltage of the transistor (0,7V) <br />
Iled: Is the desired LED current<br />
<br />
That gives a 7 Ohm value. We will select a 6,8 Ohm value as it is a similar normalized resistor value.<br />
In practice the battery output resistance, specially when it ages, can also limit the current so its easy that the current falls below 100mA in practical operation.<br />
<br />
In the circuit, the transistor can be controlled with two port outputs: P1.4 and P2.1. We have selected both outputs because that way we can select three different ways to drive the LED:<br />
<ul>
<li>Using normal GPIO operation with P1.4 or P2.1</li>
<li>Using the SMCLK output with P1.4</li>
<li>Using the line TA1.0 of the Timer 1 </li>
</ul>
In the first test firmware of the system I have used normal GPIO operations, but in the future I plan to test the other options and connecting the base to both P1.4 and P2.1 leaves the options only on the software side.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhr-FNx8Cuis7F38GKUmRW0Oy6APUhwUiXMN7xMlGgKLp0nU1nLx6V-IZmBDYjTJokjy0aeE4tpURA8-Od_ImDilwlhDaaZVUiWjYtC7MzyZtY5wrOVi40YalgDrA2M60g_NI4Yrr-tXiX/s1600/DIP20+Package.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhr-FNx8Cuis7F38GKUmRW0Oy6APUhwUiXMN7xMlGgKLp0nU1nLx6V-IZmBDYjTJokjy0aeE4tpURA8-Od_ImDilwlhDaaZVUiWjYtC7MzyZtY5wrOVi40YalgDrA2M60g_NI4Yrr-tXiX/s1600/DIP20+Package.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">MSP430G2553 20 pin package</td></tr>
</tbody></table>
<div style="text-align: justify;">
The circuit includes a normal 3mm red LED diode connected to P1.0. That LED will light when the trigger signal is sent and will also be used to any other user interaction.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are two push buttons connected to P1.3 and P1.5. One button will give an instant trigger of the camera and the other will give the two second delayed operation.</div>
<br />
Two capacitors of 10uF and 100nF provide the needed supply filtering.<br />
<br />
<div style="text-align: justify;">
The circuit includes also a 32768 Hz 12pF watch crystal and two 22k resistors connected to P1.6 and P1.7. Both elements are optional as the system can work without them. In fact, the first developed firmware makes no use of them. The watch crystal is included to provide a better frequency stability than the internal DCO oscillator if it is needed and the two resistors are included to use the MCU ADC to measure the supply voltage and give indication of a low battery situation. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Finally there is a 6 pin ISP connector. This connect, together with the 47k resistor and 1nF capacitor enables the system to be programmed using a custom cable using the TDIO and TCK signals. Pin 1 is eliminated from the connector to indicate its proper orientation. Pin 6 is connected to the CR2032 battery that supplies the system. That way we can power the system shorting pins 5 and 6 using a jumper. The circuit don't include a power switch because it can be powered off removing a jumper and because I plan to use the very low power modes of the MCU in the final firmware to make powering off the system unnecessary.</div>
<br />
<br />
<h3>
Breadboard Prototype</h3>
<div style="text-align: justify;">
To test the system the main circuit elements were put on a solderless breadboard. To program the MCU a <a href="http://www.ti.com/tool/msp-exp430g2" target="_blank">MSP430 Launchpad</a> was used. I could use my previously constructed <a href="http://r6500.blogspot.com.es/2014/10/msp340-launchpad-fet.html" target="_blank">Launchpad FET</a> but it was in use in another more important project. An <a href="http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY&CFID=6648245&CFTOKEN=188f4783d48c0dd9-D1C6FA75-5056-0201-020DD5EEAE5EB505" target="_blank">Analog Discovery</a> was used to test the timings.</div>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQnFcLlwshemGTl7Bk4c26-4SuPZze5LcrcER-RjkEYaVaZXB3YLAofRund-dBcnnbtJzZVd0pFxGl4R4yg7piWaVSNQVYXlxHPuVn_Zud42Jj-9Aqsat7lLCMOnp9FAH4TqigkUFX1iBA/s1600/01-Measurement+setup.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQnFcLlwshemGTl7Bk4c26-4SuPZze5LcrcER-RjkEYaVaZXB3YLAofRund-dBcnnbtJzZVd0pFxGl4R4yg7piWaVSNQVYXlxHPuVn_Zud42Jj-9Aqsat7lLCMOnp9FAH4TqigkUFX1iBA/s1600/01-Measurement+setup.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Breadboard Setup</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
The first firmware for the project was developed on <a href="http://energia.nu/" target="_blank">Energia</a>, an Arduino like development environment for the MSP430 family. The timings for the IR signal were manually fine tuned using the Analog Discovery oscilloscope. You can find the code at <a href="https://docs.google.com/document/d/1rqWkRUU4eEmcjEnAVqccBHkRR-vANMMnUwILBC5ER6o/edit?usp=sharing" target="_blank">this google drive reference</a>. Energia provides a quick and dirty way to develop the firmware. The future firmware of the system will be developed under MSP GCC, but in order to check the operation of the system, Energia is ok.</div>
<br />
<div style="text-align: justify;">
<span style="color: #0b5394;">UPDATE: There is a new firmware developed with GCC. See more information at the end of this article.</span></div>
<br />
<script src="https://gist.github.com/anonymous/3034ae7a2d5bd579c378.js"></script><br />
<br />
<h3>
Circuit implementation</h3>
The final circuit is implemented in a solder 100 mil pitch breadboard. First step was to lay down all the components to check for needed space.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6gU8GekUZE0T6o1YWK_WD7_Prd9UTpAcwLDZZ6_O1cnmvdD04H_nKF58hFz563cw5iW3qaYeiTYNFSdMXf3On4qpNtCHG4-G_8A78dpaj3XulJVFkqNEl_YbljBKLDOP5-UuW3VfmOW6E/s1600/03-Components.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6gU8GekUZE0T6o1YWK_WD7_Prd9UTpAcwLDZZ6_O1cnmvdD04H_nKF58hFz563cw5iW3qaYeiTYNFSdMXf3On4qpNtCHG4-G_8A78dpaj3XulJVFkqNEl_YbljBKLDOP5-UuW3VfmOW6E/s1600/03-Components.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Project components (1nF cap is missing)</td></tr>
</tbody></table>
The following figure shows the layout of the components over the board that way the needed space is checked so that I can cut the board to the needed size.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU0dgzwh-fjsX_3FDLloEF9r53VZv620GT89ZRaDtZ-cF7Ji3OUCob3na6Lf_6pVhyscY7ecnANDZgWptsYWXykcZdWDKP6xMf_xOrULLtQ8HofPzIWOTLiDnW-jStVg9laoccyGT4Qft9/s1600/04-Distribution.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU0dgzwh-fjsX_3FDLloEF9r53VZv620GT89ZRaDtZ-cF7Ji3OUCob3na6Lf_6pVhyscY7ecnANDZgWptsYWXykcZdWDKP6xMf_xOrULLtQ8HofPzIWOTLiDnW-jStVg9laoccyGT4Qft9/s1600/04-Distribution.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Layout of the components</td></tr>
</tbody></table>
<div style="text-align: justify;">
After the board was cut to size, the components were soldered and all the connections were done one by one. The routing was made on the fly with no previous planning, so I wrote down all connections as they were made on the board to check what was missing to route.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwcz6ckSLr1NFFNF78PO_M6Tl5l0qkdLNO5lHGmcH-7c1bqGc9T5L0LEOUuKKFxrOR4qI1VwpaoIOPzTsZzYUd-LtGL6gFIj-3mvwdkWDsWPVw307dIl48ub7JqVp6OPekQsnxPKY-OtOq/s1600/Routing.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwcz6ckSLr1NFFNF78PO_M6Tl5l0qkdLNO5lHGmcH-7c1bqGc9T5L0LEOUuKKFxrOR4qI1VwpaoIOPzTsZzYUd-LtGL6gFIj-3mvwdkWDsWPVw307dIl48ub7JqVp6OPekQsnxPKY-OtOq/s1600/Routing.png" width="238" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Board Routing Drawing</td></tr>
</tbody></table>
<br />
<br />
<br />
<div style="text-align: justify;">
</div>
The following figure shows the upper side of the final soldered circuit. The 100uF capacitor, the IR LED and the watch crystal were locked in place with soldered metal wires.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_x8d_-LaS_tQjSgtA8-F_9iY85jEF6z0AocmslC0OhHH48oUitl6F_cS9FXDqyBA0kcqfC2lm-WXnk4kh3A2jzSEGSpS-ngbvOuaMCNTilSH5iZvdBUQj_Ix_VeyhtwIsQmR2F5YeC3t/s1600/05-Upper+side.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH_x8d_-LaS_tQjSgtA8-F_9iY85jEF6z0AocmslC0OhHH48oUitl6F_cS9FXDqyBA0kcqfC2lm-WXnk4kh3A2jzSEGSpS-ngbvOuaMCNTilSH5iZvdBUQj_Ix_VeyhtwIsQmR2F5YeC3t/s1600/05-Upper+side.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Board. Upper side</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: justify;">
To minimize the used space, the battery holder was soldered on the lower side of the board after all the other component were routed<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgngGKKJmZ0WTuKotU0vHZOHjvwWkUhn2RUC6qpvYb2a13LZlpCFHn7QI2NgsSkxVnBt6M3QFpqzaeCYNfaFpmPAH2DRBx72NWw7abDUKRdIS1KEphqf_U2b15NRLXzjopBDlWUPIn_0FWr/s1600/06-Lower+Side.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgngGKKJmZ0WTuKotU0vHZOHjvwWkUhn2RUC6qpvYb2a13LZlpCFHn7QI2NgsSkxVnBt6M3QFpqzaeCYNfaFpmPAH2DRBx72NWw7abDUKRdIS1KEphqf_U2b15NRLXzjopBDlWUPIn_0FWr/s1600/06-Lower+Side.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYC5zHrPHTq-vSdWqOAdrC4LINarCyXyiD37hca1x3l7DiLKQ_25FEyyVc1iZTqu6XN2r9GdwjCgIbbkK1m2pHj_w_AqfA3X04U2xkq3ctEeFE2W5i6Kj_tnpVJfO9zylN1mHIOSiiUfB1/s1600/06-Lower+Side.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYC5zHrPHTq-vSdWqOAdrC4LINarCyXyiD37hca1x3l7DiLKQ_25FEyyVc1iZTqu6XN2r9GdwjCgIbbkK1m2pHj_w_AqfA3X04U2xkq3ctEeFE2W5i6Kj_tnpVJfO9zylN1mHIOSiiUfB1/s1600/06-Lower+Side.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Board. Lower side</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: justify;">
</div>
<br />
<br />
The IR LED needed some foam to guarantee that it was properly aligned to the board. As the radiant angle is only +/- 10 degrees it is important to get it right.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6FeztX0CAs9P6OvzbHJs4nE9RGjEpMPZYJnY-Vl7AE7QqjB8hWiXUMrP8gku4CgMRd-X0qPfkvpDLBhuGTZjmY6mlUG3Hvu4W5KT-ycmzr3SIl92egbWfn5SRvdoJI1d67xIdTzHSiF8/s1600/09-Jumper.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg30qJHB-Scg7yrrNaopJjznw87weWCl-DvlNUZ02LZ7H6HiM7oar1eadZD9H-8G4s33wiMigufW5Fl-xRAsvkCcmqt8XdlFXBt0wF1am5CO66wjTAbvkdjHx6IY5ZSB0UZie6I9fDdQuFX/s1600/07-LED+Detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg30qJHB-Scg7yrrNaopJjznw87weWCl-DvlNUZ02LZ7H6HiM7oar1eadZD9H-8G4s33wiMigufW5Fl-xRAsvkCcmqt8XdlFXBt0wF1am5CO66wjTAbvkdjHx6IY5ZSB0UZie6I9fDdQuFX/s1600/07-LED+Detail.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">IR LED alignment</td></tr>
</tbody></table>
<div style="text-align: justify;">
As was explained before, the ISP connector doubles as the power switch. As the first firmware, developed in Energia, was not efficient enough, the board needs to be put in off position when its not in use. Next firmware, to be developed with MSP GCC will use the low power modes of the MCU son the jumper won't need to be put in OFF position after each use. </div>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6FeztX0CAs9P6OvzbHJs4nE9RGjEpMPZYJnY-Vl7AE7QqjB8hWiXUMrP8gku4CgMRd-X0qPfkvpDLBhuGTZjmY6mlUG3Hvu4W5KT-ycmzr3SIl92egbWfn5SRvdoJI1d67xIdTzHSiF8/s1600/09-Jumper.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgn6FeztX0CAs9P6OvzbHJs4nE9RGjEpMPZYJnY-Vl7AE7QqjB8hWiXUMrP8gku4CgMRd-X0qPfkvpDLBhuGTZjmY6mlUG3Hvu4W5KT-ycmzr3SIl92egbWfn5SRvdoJI1d67xIdTzHSiF8/s1600/09-Jumper.jpg" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">ISP-Power connector</td></tr>
</tbody></table>
For now, the system works OK for distances up to 5m. Enough for my needs for a camera IR trigger.<br />
<br />
<br />
<h3>
Next Steps</h3>
The system, as it is now if fully functional. However I plan to do some improvements in the future:<br />
<ul>
<li>Develop the firmware using my Eclipse MSP GCC toolchain</li>
<li>Implement the MSP430 low power mode so that the jumper can always be in ON mode</li>
<li>Use the 32768Hz crystal to provide a more robust timing</li>
<li>Implement the low battery indication using the resistors connected to P1.6 and P1.7</li>
</ul>
<br />
<h3>
New Firware released (Update at 26/11/2014)</h3>
I have written a new firmware for the IR Trigger. You can find it in the following link:<br />
<br />
<div style="text-align: center;">
<a href="http://r6500.blogspot.com.es/2014/11/new-firmware-for-ir-trigger.html">http://r6500.blogspot.com.es/2014/11/new-firmware-for-ir-trigger.html</a></div>
<br />
It is developed using a portable MSP430GCC environment I describe in this other reference:<br />
<br />
<div style="text-align: center;">
<a href="http://r6500.blogspot.com.es/2014/11/portable-environment-for-msp430.html">http://r6500.blogspot.com.es/2014/11/portable-environment-for-msp430.html</a></div>
<br />
The new firmware uses the 32768 Hz crystal so it gives a more stable timing on the generated signal. It also greatly improves the idle current that goes from 3.2mA to 0.1uA.<br />
<br />
<br />
<h3>
Code is now embedded (30/11/2014)</h3>
<br />
Thanks to <a href="https://gist.github.com/" target="_blank">Gist</a>, now the code is embedded inside the blog entry.<br />
<br />
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com3tag:blogger.com,1999:blog-6880821591370697484.post-76638870474257745172014-10-13T15:16:00.000+02:002014-10-13T15:18:22.807+02:00PSoC4 debug with the Pioneer kit<div style="text-align: justify;">
In this article I will talk a little about the Cypress PSOC4 family of devices. Then I will explain the method I use to debug a cheap CY8CKIT-049-42XX board using a not so cheap CY8CKIT-042 Pioneer kit.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Cypress PSOC 4 </h3>
<div style="text-align: justify;">
<a href="http://www.cypress.com/psoc4/?source=CY-ENG-HEADER" target="_blank">Cypress PSOoC 4</a> is an interesting blend of MCU and programmable logic. It includes an ARM Cortex M0 CPU together with some programmable logic all in one chip. That way you can develop a system not only a MCU brain but also some custom digital peripherals. The Cypress web site has more information about it so I will not explain any further.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One interesting point about those devices is that the developement software <a href="http://www.cypress.com/psoccreator/" target="_blank">PSoC Creator</a> is freely available from Cypress alhough it is a Windows only application.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi5riFKqX2yStdFir4CURMeX0QP-x-3WXHruk_E_7aADjxkBf6noJiiCfZUxUg0Fs0B78Oa5ppjPNY96hLIj-G5IdyHKDE3lGYkbgh-cVTjqI3i9YKER_nbw7rDkGrscRvPp3CAyk-7FRC/s1600/LUT+Example.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgi5riFKqX2yStdFir4CURMeX0QP-x-3WXHruk_E_7aADjxkBf6noJiiCfZUxUg0Fs0B78Oa5ppjPNY96hLIj-G5IdyHKDE3lGYkbgh-cVTjqI3i9YKER_nbw7rDkGrscRvPp3CAyk-7FRC/s1600/LUT+Example.png" height="270" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PSOC Creator 3</td></tr>
</tbody></table>
<div style="text-align: justify;">
The application enables to develop both the programmable logic and the MCU programs. The glue code to link the program to the digital devices is created on the fly. It should be easy to develop an application in no time alhough I have not dedicated much time to explore the IDE features.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
CY8CKIT-049-42XX Board</h3>
<div style="text-align: justify;">
Texas Instruments broke the low level MCU development hardware with it's <a href="http://www.ti.com/ww/en/launchpad/launchpads-msp430-msp-exp430g2.html#tabs" target="_blank">Launchpad</a> when they sold it an only 5€ (now it is about 10€). Now Cypress is following the same path with its <a href="http://www.cypress.com/?rID=92146" target="_blank">CY8CKIT-049-42XX board</a>. This board sells for about 4€ and for it's price it's good deal. I bought mine at <a href="http://es.farnell.com/cypress-semiconductor/cy8ckit-049-42xx/prototype-board-cy8c4245axi-483/dp/2420489" target="_blank">Farnell</a>.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOagt-HmtXJ7U1WSQXe0VqH9kcBM8_LP6QEzLG7tIq4jr_Uy85Mdda9ByA3nWitKPjnMv1Sp8QTECUDj3n2L-i7W4x_K7cSNVin0h-IjmHbhVoxpcOwfFzIy6A5a2Ac9KYB2BNXu5SXish/s1600/42xx.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOagt-HmtXJ7U1WSQXe0VqH9kcBM8_LP6QEzLG7tIq4jr_Uy85Mdda9ByA3nWitKPjnMv1Sp8QTECUDj3n2L-i7W4x_K7cSNVin0h-IjmHbhVoxpcOwfFzIy6A5a2Ac9KYB2BNXu5SXish/s1600/42xx.jpg" height="132" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">CY8CKIT-049-42XX</td></tr>
</tbody></table>
<div style="text-align: justify;">
Cypress also sells another board, the CY8CKIT-049-41xx at the same price. But as it is a less featured board at the same price so I don't recommend it.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The board is a two part construction that can be directly connected to a free USB port. The left part of the board, that includes the USB connector, include a <a href="http://www.cypress.com/?mpn=CY7C65211-24LTXI" target="_blank">CY7C65211-24LTXI</a> devide that implements an USB to serial bridge. The right part of the board includes the main chip of the board, a PSoC4<a href="http://www.cypress.com/?mpn=CY8C4245AXI-483" target="_blank"> CY8C4245AXI-483</a> in a TQFP 44 pin package. A little pushbutton and a blue LED act as a minimalist peripheral set and complete this side of the board.<br />
<br />
The CY8C4245AXI-483 main chip features a 48MHz ARM Cortex M0 MCU with 32kB flash and 4kB SRAM memories. It also includes a 12 bit SAR ADC, a pair of operational amplifiers, a pair of comparators, 4 timers, 2 serial peripherals and the hardware to interface to cap sense inputs. Next to the MCU it includes digital programmable logic in the form of 4 Universal Digital Blocks. Each of them includes 8 macrocells, one 8 bit datapath and two 12 input PLDs. Quite a lot to play with at only 4€.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can use the PSoC Creator software to program the main chip in the board, but as it doesn't feature any JTAG or equivalent connection you are limited to programming using a bootloader that is preprogrammed in the chip. That means that you also need to include the bootloader in any user program as it is needed to do any future reprograming of the board. The bootloader, of course, takes a little space on the program memory. This not a big deal, Arduino has been using bootloaders for ages but it is sure a worse solution that the TI Launchpad that include both a two wire Debug link AND a Serial bridge.</div>
<br />
<div style="text-align: justify;">
I ordered two CY8CKIT-049-42xx boards. The first thing I do when I receive a development board is to try to program it to check the software. I downloaded the PSoC Creator software and I tried to program a boatloadable PSoC 4 example that is provided for this board.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To program the boad, you need to enter in <b>bootloader mode</b>. To do that you need to press the user button at the same time you insert the board in an available USB socket. One of my boards worked fine and I could program it with no problem. The other, however, wasn't able to enter in <b>bootloader mode</b> so it could not be programmed. I suspected that the problem was the push button so I re soldered its connections. After that, it worked ok. Perhaps there are some quality issues in the manufacture of those boards.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The board is designed to be cut at the serial link between the two chips, just after the serial bridge. It also includes some pins to do proper debugging of the main MCU. To do that, you are suggested to buy a <a href="http://www.cypress.com/?rID=38154" target="_blank">MiniProg3 </a>kit. At 74€ at <a href="http://es.farnell.com/cypress-semiconductor/cy8ckit-002/miniprog3-psoc-prog-debug-kit/dp/1753960?ost=miniprog3&categoryId=700000005132" target="_blank">Farnell </a>it's not a bad option to debug the board.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSgkHc45tOSz8qdR73Vg1jPiuaSHs2d5NDxZ4lxs8pLemlkixf-JBQZeZ62LLx6ynBKM_DAw8tVliXfh8BTFh0fXfn9VzCgN2CnFIlX_SeEQUdWeBwvvi3reMjfumSzMtfWz_bYPY0mjsj/s1600/Debug.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<div style="text-align: justify;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2hSmHTyadPmyhGTJ6AHP-kFeRUDJN8XuM3i7YH-2D4cxui1RJVNYbIUItEihPH_no25pUQqplPtdtIP0Opl_g9h6YjDB0ob124wS-e2YHR7dXKiNyfM8xRpcAVdLVjXzRNcO4j9rF-nU/s1600/42xx+Conns.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr2hSmHTyadPmyhGTJ6AHP-kFeRUDJN8XuM3i7YH-2D4cxui1RJVNYbIUItEihPH_no25pUQqplPtdtIP0Opl_g9h6YjDB0ob124wS-e2YHR7dXKiNyfM8xRpcAVdLVjXzRNcO4j9rF-nU/s1600/42xx+Conns.png" height="132" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Board connections</td></tr>
</tbody></table>
I decided to separate both board sections and to include some connectors to the serial bridge and debug port. That way I can use the board pieces independently of each other. Off course, as I have no MiniProg3 kit, for now I can only program the board using the bootloader.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCxPAFVBxcB3wh4KgKnS5eznXbtvfv-ROmW1dT6widPSYS1kXtXfPV6QOIRiV2-1rlb2OVgs4MzyBC2c73FtMUne3Cbb00VXDMrx8ywSRA55NODVNhas_r-rIvPKjMhUlITKIXzU9zHgW0/s1600/42xx-Separated.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCxPAFVBxcB3wh4KgKnS5eznXbtvfv-ROmW1dT6widPSYS1kXtXfPV6QOIRiV2-1rlb2OVgs4MzyBC2c73FtMUne3Cbb00VXDMrx8ywSRA55NODVNhas_r-rIvPKjMhUlITKIXzU9zHgW0/s1600/42xx-Separated.jpg" height="271" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Soldered Connectors</td></tr>
</tbody></table>
You need four pins for the serial bridge: Vdd, GND, TX and RX. And you need five for the debug port: Vdd, GND, SWDIO, SWDCLK and RESET. I used one five pin connector and one six pin connector. The unused pin is removed in the male side and blocked in the female side to prevent an incorrect alignment of the pins.<br />
<br />
So far so good, I have a cheap development board to play with, but I don't like bootloaders to do developing so my goal is to use the debug port to program the board.<br />
<br />
<br />
<h3>
CY8CKIT-042 Pioneer kit</h3>
The <a href="http://www.cypress.com/?rid=77780" target="_blank">CY8CKIT-42</a> is a more featured board that previously described CY8CKIT-049-42XX one. Both feature the very same main chip, a CY8C4245AXI-483, but the rest of the board is quite different. The price is also different as this board cost about 20€.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimVAdBaxOgYBS_gYi_rHx8Ux2fDdCcCWBL68O0Mf-QXQbto1yBcR-lSgakVg332Y1YPBq580qsYTt3tLO09H5Eb5RKwHR0BNPU2AhvrWiIIXGEK1iSfD_jBl6weudtmVAVAH8nOUqAG0D4/s1600/01-CY8CKIT.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimVAdBaxOgYBS_gYi_rHx8Ux2fDdCcCWBL68O0Mf-QXQbto1yBcR-lSgakVg332Y1YPBq580qsYTt3tLO09H5Eb5RKwHR0BNPU2AhvrWiIIXGEK1iSfD_jBl6weudtmVAVAH8nOUqAG0D4/s1600/01-CY8CKIT.jpg" height="194" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">CY8CKIT-042 Board</td></tr>
</tbody></table>
A part from more peripherals, like one RGB LED, a cap sense slider and some Arduino connectors, one main difference in this board is that it features full hardware debug. A PSoC 5 programmed as USB debug bridge enables hardware debug on the PSoC 4 CY8C4245AXI-483 chip.<br />
<br />
I tested to program this board and do some step by step debugging without any problem. As the cheaper CY8CKIT-049-42XX features the same main chip, I thought about programming it using the debugger in the pioneer kit. Unfortunatelly this is not as easy as in other boards.<br />
<br />
Both in the Texas Instruments Launchpad boards and in the ST Discovery boards the flash emulator and the main MCU are connected through jumpers so that you can separate the emulator from the main chip enabling you to use the emulator to develop another board. This is not the case in the pioneer board.<br />
<br />
In this board, the PSoC 5 emulator chip is connected to the emulator lines using several zero ohm resistors. Zero ohm resistors R11, R16 and R15 connect the RESET, SWDIO and SWDCLK lines.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyYaUkgUmVGTqhJOK_JCmHpCbWxSmxjXkdPOhIcJRsEQLkm1ZZIoRIHOo1pa_O0j-tr7uSzBNRy1lKmacD9zm-NvPrrKQrtQqiPhuQVLX9fLwwcOXtgFN9rF7MLPolHPJwKEKCjOQl4wNU/s1600/SCH-Resistors+2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyYaUkgUmVGTqhJOK_JCmHpCbWxSmxjXkdPOhIcJRsEQLkm1ZZIoRIHOo1pa_O0j-tr7uSzBNRy1lKmacD9zm-NvPrrKQrtQqiPhuQVLX9fLwwcOXtgFN9rF7MLPolHPJwKEKCjOQl4wNU/s1600/SCH-Resistors+2.png" height="195" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PSoC 5 Emulator Zero Ohm link resistors</td></tr>
</tbody></table>
Those lines connect to a small pitch J6 debug connector and, from that connector, they connect to the PSoC 4 main chip using another set of zero ohm resistors (R34, R32 and R33).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUilc6oBuLhKypbaFJTRJ7AKxb3jb6MoTnVwgEZyXwmeoDStEXc_CiOBVfzbDcXQ-t_HKB8BikBiAx-GF2oNo1jIocPbEDJC_9djbHlH_AI2V4A2nw0YsR6JG2UYp1G9UP_v835eE8CsUa/s1600/SCH-Resistors+1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUilc6oBuLhKypbaFJTRJ7AKxb3jb6MoTnVwgEZyXwmeoDStEXc_CiOBVfzbDcXQ-t_HKB8BikBiAx-GF2oNo1jIocPbEDJC_9djbHlH_AI2V4A2nw0YsR6JG2UYp1G9UP_v835eE8CsUa/s1600/SCH-Resistors+1.png" height="146" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Debug Connector</td></tr>
</tbody></table>
So we have the three debug lines with the J6 connector in the middle and zero ohm resistors both in the emulator PSoC 5 chip and the emulated PSoC 4 chip.<br />
<br />
The solution proposed by Cypress to do debugging in another board using the pioneer PSoC 5 emulator is to desolder the R34, R32 and R33 resistors and use the J6 connector to stablish the debug link.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja2BAvxkh6b9ec2i-wHnmUZMeRZiIx7Tv8fdV_JGzdgSMcw-QLU7-piWpUB78g7hYwM6haGxr5O4AfBwrBI3w0Iy4LUxuS3hhIdyyaKVML_dztYZd54Y7QkmigbiEM55fxOa7sRoeEn3W5/s1600/Debug+elements.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja2BAvxkh6b9ec2i-wHnmUZMeRZiIx7Tv8fdV_JGzdgSMcw-QLU7-piWpUB78g7hYwM6haGxr5O4AfBwrBI3w0Iy4LUxuS3hhIdyyaKVML_dztYZd54Y7QkmigbiEM55fxOa7sRoeEn3W5/s1600/Debug+elements.png" height="206" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pioneer board debug elements</td></tr>
</tbody></table>
There are two problems associated with the Cypress solution:<br />
<br />
<ul>
<li>Removing R34, R32 and R33 disables the programming of the PSoC 4 chip included in the board.</li>
</ul>
<ul>
<li>I have no connector that match the 50 mill fine pitch debug connector J6. </li>
</ul>
<br />
<br />
<h3>
Changes in the board</h3>
I carried a modification to enable the board to be used as an external debug programmer fro the CY8CKIT-049-42XX board without losing the optin to program the pioneer board PSoC 4 chip.<br />
The idea is to remove all six resistors R11, R16, R15, R34, R32 and R33 and substitute them with a 100 mill standard male connector.<br />
<br />
First thing is to locate those resistors, they are between the small PSoC 5 chip and the larger PSoC 4 chip. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGpRAwhZz9j76kLPwPjzifEbP_n_b2HzTRya1PY2Yle3uz6sGyTHkwbIqC5bsBf2BarHjTarggzyxtTiCDM-pwpQSn8EqhSNXWbT0y6gdjy8WcPYH-fXU4sUs7PAIu_7T1o1aJmW6zfIyK/s1600/03-Detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGpRAwhZz9j76kLPwPjzifEbP_n_b2HzTRya1PY2Yle3uz6sGyTHkwbIqC5bsBf2BarHjTarggzyxtTiCDM-pwpQSn8EqhSNXWbT0y6gdjy8WcPYH-fXU4sUs7PAIu_7T1o1aJmW6zfIyK/s1600/03-Detail.jpg" height="175" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Resistors to remove</td></tr>
</tbody></table>
Then I removed the resistors:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpdUp1LTF6GXKUFCcLz3LxFf_oed3Tft8skvR0Gxg9gpKrvVFgZRMR71RWBMuZaMQCHgN0Z9eueiz68AH8jHztZKK9HgevyqCpPkZH10hHzD4ZidtqRyjjJb_TqLBUHHcpRZSkX3R8Vs_X/s1600/04-Desolder.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpdUp1LTF6GXKUFCcLz3LxFf_oed3Tft8skvR0Gxg9gpKrvVFgZRMR71RWBMuZaMQCHgN0Z9eueiz68AH8jHztZKK9HgevyqCpPkZH10hHzD4ZidtqRyjjJb_TqLBUHHcpRZSkX3R8Vs_X/s1600/04-Desolder.jpg" height="169" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Resistors removed</td></tr>
</tbody></table>
Then I got a 2x4 100 mill male pin connector and removed the pin in one of the corners:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiryBgdyUUhidC1vGXRZwNaYJ1UavovLOpYz1RJk6hNH6oLGURf8-Rq68APxXkAQ7H-mD9vM9eDngC9jZMT86Tlc5trkLIKUIV-LuSGDetLh7IDajwIBC1Ke0flUmt43WyRHgWZUEcZb0gv/s1600/02-Pines.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiryBgdyUUhidC1vGXRZwNaYJ1UavovLOpYz1RJk6hNH6oLGURf8-Rq68APxXkAQ7H-mD9vM9eDngC9jZMT86Tlc5trkLIKUIV-LuSGDetLh7IDajwIBC1Ke0flUmt43WyRHgWZUEcZb0gv/s1600/02-Pines.jpg" height="185" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Standard 100 mil male pin strip</td></tr>
</tbody></table>
Then I aligned the full three pairs of pins with the landings of the resistors and soldered them in the board leaving the last half-pair pin unconnected.<br />
<br />
In the first pair I connect the left side of R11 with the left pin and the right side of R34 with the right pin. For the two other pairs I do the same with R16-R32 and R15-R33. There is no problem if the pads of one resistor are shorted as long as only one resistor is shorted in each pair.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2W64MbTzN9fK2L05OlvtxDP7jbJQTVf6tkObb1-6XiLbPN88hI6pO9psVk8N0q5TSmsNWzyw3CAKLy4YcHukFPsstXAEHYnNk1hWzS57qo_ZO5zxES9FzK3FVZNzR-2Y17nyzKQTaTf0E/s1600/06-Pin+Detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2W64MbTzN9fK2L05OlvtxDP7jbJQTVf6tkObb1-6XiLbPN88hI6pO9psVk8N0q5TSmsNWzyw3CAKLy4YcHukFPsstXAEHYnNk1hWzS57qo_ZO5zxES9FzK3FVZNzR-2Y17nyzKQTaTf0E/s1600/06-Pin+Detail.jpg" height="196" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Connector soldered in the board</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjecsR_AL_V1WBohFqd45I1RATlOi4PzwyQMII6MZaByV01bN58Oi4RVUYHQlw3Sk1U_Sv_s6YFfzVK5z3HMl5HJOgGTrj4JzWBeimbgCbLi3YiIQfOb0RVtRP9Cy-jwMKB2EqplNFq3QJo/s1600/07-Pin+Detail+2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjecsR_AL_V1WBohFqd45I1RATlOi4PzwyQMII6MZaByV01bN58Oi4RVUYHQlw3Sk1U_Sv_s6YFfzVK5z3HMl5HJOgGTrj4JzWBeimbgCbLi3YiIQfOb0RVtRP9Cy-jwMKB2EqplNFq3QJo/s1600/07-Pin+Detail+2.jpg" height="221" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Side view</td></tr>
</tbody></table>
<br />
If all goes ok, the connector separates the three debug signals SWDIO, SWDCLK and RESET from the emulator to the PSoC 4 main chip. To reenable the connections a jumper can be fitted in each pin pair as is shown on the next figure.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOzLWRyvGsOxltZiwHVgehzPT2B7Qa1rdfoXkmSVB6wrGbyS7mHYIF3TSQGk9759J531zn32o0Nkc5PQ0u-SgSisPaZwgoShKW5xCk-lX42hlqpkhQxIPehNWuQS-X9LiaoiTf-I0Ox2NK/s1600/08-Jumpers.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOzLWRyvGsOxltZiwHVgehzPT2B7Qa1rdfoXkmSVB6wrGbyS7mHYIF3TSQGk9759J531zn32o0Nkc5PQ0u-SgSisPaZwgoShKW5xCk-lX42hlqpkhQxIPehNWuQS-X9LiaoiTf-I0Ox2NK/s1600/08-Jumpers.jpg" height="191" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Connector with jumpers</td></tr>
</tbody></table>
<br />
That way I can check that the board can be programmed ok as before.<br />
<br />
The pin that was not used in the connector forms half a pair of pins and is designed to provide alignement to the connector so that it cannot be fitted in the wrong orientation. I soldered one wire from this pin to a GND node in the board to provide the needed common reference in the debug link.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB3ZhFDbDNhVt5mj4rMYEu_INfNjzGErXIDlH_pvX7cw_u7cXSFrpQBh7xzp4ZK1P3kgLBUaD_mPvbUYgmlKABIkjpYyrrFlWH3y8q7GRsD_-EYT_hwqYV3TUED1hO6CeVkcckG15m0Geg/s1600/09-Ground.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB3ZhFDbDNhVt5mj4rMYEu_INfNjzGErXIDlH_pvX7cw_u7cXSFrpQBh7xzp4ZK1P3kgLBUaD_mPvbUYgmlKABIkjpYyrrFlWH3y8q7GRsD_-EYT_hwqYV3TUED1hO6CeVkcckG15m0Geg/s1600/09-Ground.jpg" height="320" width="266" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ground connection</td></tr>
</tbody></table>
<br />
<br />
<br />
<h3>
Debugging the CY8CKIT-049-42XX board</h3>
To debug a CY8CKIT-049-42XX we only need to remove the jumpers route the three debug signals and the common ground between the two boards. That means using the left four pins of the male connector.<br />
If we want to power the debugged board at the same time, we can use the Vdd connection at J5 in the pioneer board. After thinking about it I could have fitted a bigger two row male connector and include the Vdd signal.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidthENV2e49zJTOkqquyBexpwLTQ2pI1J57-Dd9Gel9nxw0aulQ4uPLpva0NrhyioOMqJl-jEdlB9ZaXx9gAdnvaJGyWGgZDR0KYSWHh1JQXg1P6xTsOWG0bmndj8bvQMqJZ9F-i5SQRaP/s1600/Debug.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidthENV2e49zJTOkqquyBexpwLTQ2pI1J57-Dd9Gel9nxw0aulQ4uPLpva0NrhyioOMqJl-jEdlB9ZaXx9gAdnvaJGyWGgZDR0KYSWHh1JQXg1P6xTsOWG0bmndj8bvQMqJZ9F-i5SQRaP/s1600/Debug.jpg" height="306" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Connected boards</td></tr>
</tbody></table>
<br />
You know that the connection is ok if you can enable the debugger in PSoC Creator and detect the chip in the CY8CKIT-049-42XX board.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmjL-H5yv2dfLHOeR5cptMIMOEE9uc5zqcWWPPm22IFQ53xTDIzU6gGyK_mH9y4cC2DoseKCG0wlFjAkMXu2MwUWrV5_lTPvjyFjpYtnfzy00qFivG7fKi6LjILtNwAs1SpFBMG-tIuVI1/s1600/Debug+Connected.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmjL-H5yv2dfLHOeR5cptMIMOEE9uc5zqcWWPPm22IFQ53xTDIzU6gGyK_mH9y4cC2DoseKCG0wlFjAkMXu2MwUWrV5_lTPvjyFjpYtnfzy00qFivG7fKi6LjILtNwAs1SpFBMG-tIuVI1/s1600/Debug+Connected.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Chip detected in the debug link</td></tr>
</tbody></table>
<br />
After that I modified a Cypress example program to test the debug functionality and it worked like a charm. Now I can properly debug the dirt cheap CY8CKIT-049-42XX board.<br />
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-54104237797631144392014-10-08T23:09:00.001+02:002018-02-11T17:30:39.405+01:00Calibrating the MSP430 DCO<div style="text-align: justify;">
In this article I will give a brief explanation of the MSP340 DCO oscillator and I will provide a program to calibrate it to several frequencies.<br />
This article is a rewrite from a previous <a href="http://aim65.blogspot.com.es/2012/05/calibrando-el-dco.html">article </a>in spanish of my twin spanish blog <a href="http://aim65.blogspot.com.es/">AIM65</a>. </div>
<h3>
DCO Description</h3>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
The MSP340 familly of MCUs feature an internal digitally controlled RC oscillator (DCO). This oscillator generates a frequency that is controlled by three digital values:</div>
<ul>
<li>RSELx (0..15) Select a coarse frequency range</li>
<li>DCOx (0..7) Fine frequency selection for each range</li>
<li>MODx (0..31) Frequency modulation between the selected fine value and the next one</li>
</ul>
<div style="text-align: justify;">
The RSELx and DCOx values determine the oscillator frequency as is indicated in the following figure obtained from the <a href="http://www.ti.com/lit/ug/slau144j/slau144j.pdf?keyMatch=slau144i&tisearch=Search-EN">MSP430x2xx family guide</a>.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguMOKQKSId2qjSTPOLYsmEvOIvGaa6bybU6pA4Y9MbcmGS-sxMWbe5DVi0Y8A3-0iiwnMRpG9QANeaMb5_Ip9IrZfGZZPP3lK1-FQ7J3jv-mb1TWiTD237TiBkvFWVfwJg87EK1TDTl8BB/s1600/DCO+Fig+1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguMOKQKSId2qjSTPOLYsmEvOIvGaa6bybU6pA4Y9MbcmGS-sxMWbe5DVi0Y8A3-0iiwnMRpG9QANeaMb5_Ip9IrZfGZZPP3lK1-FQ7J3jv-mb1TWiTD237TiBkvFWVfwJg87EK1TDTl8BB/s1600/DCO+Fig+1.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Frequency as function of RSELx and DCOx</td></tr>
</tbody></table>
<div style="text-align: justify;">
The different frequencies you can select for each RSEL value have some overlap. For instance the RSEL=7 DCO=7 frequency could be higher that the one selected with RSEL=8 DCO=0.</div>
<div style="text-align: justify;">
<div style="text-align: justify;">
<br />
The MODx value enables us a finer control of the average frequency. For each 32 clock cycles, (32-MOD) cycles will run at the frequency associated with the selected RSEL and DCO values and the other MOD cycles will run at the frequency associated with the same RSEL but with DCO+1 value.<br />
As DCOx could only be between 0 and 7, the DCO value could not be 7 if we want to use the modulation.</div>
<div style="text-align: justify;">
<br />
The following figure shows the modulation pattern for different MOD values:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUCPEh98HFN7SCQK9QK4O828Uhn2XSM_rR0SWJ_gFUfJxpm4VBdPYblSku2z5WzLuAWDste8QLQqSy_WD-8j8CPegt9WarNZ3enUisU2MteaUfbSfFkkhZcRPwvOnsuHQMg0T8I6wZzntG/s1600/DCO+Fig+2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUCPEh98HFN7SCQK9QK4O828Uhn2XSM_rR0SWJ_gFUfJxpm4VBdPYblSku2z5WzLuAWDste8QLQqSy_WD-8j8CPegt9WarNZ3enUisU2MteaUfbSfFkkhZcRPwvOnsuHQMg0T8I6wZzntG/s1600/DCO+Fig+2.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">DCO modulation</td></tr>
</tbody></table>
It is important that the use of modulation introduces some Jitter in the clock signal. This is not important on some applications, but it could be a problem if, for instance, you need a low jitter periodic sampling.</div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<h3>
Factory DCO calibration</h3>
</div>
<div style="text-align: justify;">
<div style="text-align: justify;">
The frequency associated to each RSEL and DCO value has a high tolerance. If you need an exact operation frequency you need to calibrate the oscillatror. As an example taken from the MSP430G2x21 datasheet, a setting of RSELx = 7, DCOx = 3 and MODx = 0 could yield frequency values between 0,8 MHz and 1,5 MHz. That is, you can have a 0,35 MHz error (23%) respect to the central value of 1,15MHz. </div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<div style="text-align: justify;">
To calibrate the DCO you must determine the RSEL, DCO and MOD values needed to generate a target frequency. A calibrated DCO gives a more exact frequency than an uncalibrated one, however it can also show some frequency drift in the +/- 6% range due to changes in Vdd and temperature. To minimize drifts, the best way is to calibrate the DCO at the same Vdd and operating temperature that will be used when the circuit is active.<br />
<br />
All MSP430 MCUs are factory calibrated at least at 1MHz frequency. The three RSEL, DCO and MOD calibration values are stored on the internal flash memory. To set the calibrated frequency those values must be written to the DCOCTL (DCO and MOD) and BCSCTL1 (RSEL) registers.</div>
<div style="text-align: justify;">
<br />
There are some problems with the factory calibration values:<br />
<br />
<ul>
<li>They can only be used at the calibration points availables for the selected MCU. The G2211 has only one calibration value for 1MHz. The G2553 is calibrated for 1, 8 and 16 MHz. If you want to operate at 4MHz in this MCU you need to do the calibration yourself.</li>
</ul>
<ul>
<li>Texas Instruments calibrates at 30ºC and 3V supply. If you want to operate out of this conditions, a custom calibration could be better than the factory one. </li>
</ul>
</div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<h3>
Custom DCO calibration</h3>
</div>
<div style="text-align: justify;">
The calibration procedure needs to check the DCO against a good reference. As the Launchpad board comes with a 32768 Hz quartz, we can use its as reference. You can se an article about this Xtal on another <a href="http://r6500.blogspot.com.es/2014/10/soldering-launchpad-xtal.html">entry </a>of this blog.<br />
<br />
You can find on the Internet several references about the calibration procedure like <a href="http://mspsci.blogspot.com.es/2011/10/tutorial-16c-accurate-clocks.html">this one</a> or <a href="http://justinstech.org/2011/05/msp430-custom-calibration-for-dco/">this another</a>. There is also Texas Instruments <a href="http://www.ti.com/lit/an/slaa336a/slaa336a.pdf">library </a>to do that.<br />
<br />
Most solutions rewrite <b>Section A</b> of the Flash <b>Information Area</b> inside the MCU. That area is used by Texas Instruments to store some calibration data of their MCUs. This area is protected by a special security flag (LOCKA) to prevent an accidental erase of calibration data.<br />
<br />
The rewrite of Information Area Section A is dangerous as we could erase not only the DCO calibration data but also the ADC calibration data. Moreover, this area includes a checksum that some applications could try to check. You could recalculate the checksum but you cannot recover the ADC data if it was not saved before erasing it.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
Section A is only one of the four information areas included on the MSP430 MCUs. All four areas A, B, C and D have a 64 byte size. Section A is filled at the TI factory but areas B, C and D are empty and free for the user programs. I think that storing the user DCO calibration data could be done on Section B and leave Section A with factory data.<br />
<br />
I selected 9 frequency values for calibration: 500Hz, 1MHz, 2MHz, 4MHZ, 6MHz, 8 MHz, 10MHz, 12MHz and 16 MHz. In the next section I describe the program used for calibration.<br />
<br />
<br />
<h3>
DCO Calibration program</h3>
<h4>
main.c </h4>
The DCO Calibration program <a href="https://docs.google.com/document/pub?id=1J9OvQTGObowVQzrErTYJQiQRdaXcZexfBB7ilollPOs">main.c</a> file contains most of the code. It compiles under MSP GCC and should fit in any MSP430 MCU with at least 2kB Flash. Once the program runs and the calibration data is stored in the flash, it can be erased. Any future program could use the stored calibration values.<br />
<br />
<script src="https://gist.github.com/anonymous/1d67d8702ca019103822.js"></script><br />
<br />
Two source files are linked to main.c, <a href="https://docs.google.com/document/pub?id=17QD0mRxXWZs0PsDH5yn__HlEb4QBPxp_Xceurq-TfyE">io430masks.h</a> gives some register mask values and <a href="https://docs.google.com/document/pub?id=1CZz-vlGyUREEqNX96rmhbaMzvmokViORngletaM_7ik">NewDCOCal.h</a> set the flash memory addressed of the calibration data generated by the program.<br />
<br />
<h4>
io430masks.h</h4>
<script src="https://gist.github.com/anonymous/c05460b7062bea8a1e78.js"></script><br />
<br />
<h4>
NewDCOCal.h</h4>
<script src="https://gist.github.com/anonymous/0f9f76ac5eb14aa1df59.js"></script><br />
<br />
The program is designed to be run on the <a href="http://www.ti.com/ww/en/launchpad/launchpads-msp430-msp-exp430g2.html">Launchpad G2 board</a> and needs the 32768 Hz Xtal to be populated. It also uses the green LED at P1.0, the red LED at P1.6 and the user button at P1.3.<br />
<br />
Two MCU pins are also used to check the calibration frequencies:<br />
<br />
P1.4: Square wave at DCO frequency<br />
P1.5: 256 Hz square wave generated from the 32768 Hz Xtal<br />
<div class="c1">
<br />
<span class="c0">When the program starts it checks if there is data in Information Area Section B. If there is any information it goes to the generation frequency mode that I will explain later. If it is empty, the calibration is carried out and the obtained data is stored in Section B jumping next to generating frequency mode.</span><br />
<span class="c0">During calibration, P1.4 shows the generated frequency. Every time a new frequency is selected for calibration the green LED makes a blink. If the calibration for one frequency must be repeated because it is outside the desired tolerance it is indicated with a blink of both green and red LEDs.</span><br />
<span class="c0"> </span></div>
In frequency generation mode, entered after calibration or upon start if Section B is not empty, the system programs the first calibration frequency (500Hz). Each time the user button at P1.3 is pushed the next frequency is generated. After the last one (16MHz) the system restarts at the first one.</div>
<div style="text-align: justify;">
In this mode P1.4 shows the generated frequency and the green LED blinks at a frequency associated to 20 overflows of Timer A0 (20 times the count to 65536 from the DCO frequency).<br />
<div class="c1">
<span class="c0"><br /></span>
<span class="c0">In case of error the program locks itself with an error code indicated with a number of red LED blinks:</span><br />
<span class="c0"><br /></span>
<span class="c0"> (1) 32768 Hz clock fails</span><br />
<span class="c0"> (2) Cannot calibrate one frequency</span></div>
<div class="c1">
(4) There is no factory calibration data for 1MHz (It is needed to program the flash)<br />
(5) Cannot calibrate inside the selected tolerance (5% by default)</div>
<div class="c1">
<span class="c0"><br /></span>
<span class="c0">If the 32768 Hz clock cannot start at all, the system blocks with the red LED fixed in ON state.</span><br />
<span class="c0"><br /></span>
<span class="c0"></span><br />
<h3>
<span class="c0">Program operation</span></h3>
In order to do the calibration the Watchdog timer is programmed in timmer mode with about 1,9ms timeout (64 cycles at 32768 Hz) using the Xtal oscillator. Timer A0 is configured in continuous mode using the DCO as input. A capture is generated in A0 each time the Watchdog timer timeouts. We can calculate the DCO frequency from the number of DCO clock cycles between two captures:<br />
<br />
<div style="text-align: center;">
DCO Frequency = 512 * Ncycles</div>
</div>
<div class="c1">
</div>
<div class="c1">
<br />
To increase the precission the calculation is made averaging 50 captures.</div>
<div class="c1">
</div>
<div class="c1">
</div>
<div class="c1">
</div>
<div class="c1">
<br />
<div class="c1">
<span class="c0">The program starts choosing the RSEL value, then the DCO value just below the target frequency is selected. Finally the frequency is fine tuned using the MOD value.</span></div>
</div>
<div class="c1">
<span class="c0"><br /></span>
<br />
<h3>
<span class="c0">Conditional compilation</span></h3>
The program uses three defines to configure its compilation.<br />
<br />
If the <b>DEBUG </b>define is activated, the program stores the RSEL, DCO and MOD values next to the calibration error at each frequency. That data can be extacted using the debugger.<br />
<br />
If the <b>FLASH_OVERRIDE</b> flag is active, the program will rewrite Information Area Section B even if it is not empty upon startup.<br />
<br />
If the <b>TEST_MODE</b> is active, all the calibration data will be stored in RAM instead of flash. That way the program operation can be checked without touching the flash memory information areas.<br />
<br />
<br />
<h3>
Calibration video</h3>
The following video shows the system working in a v1.5 Launchpad board that has the default MSP430G2553 MCU installed. Next to the board you can see the frequency generated both in an oscilloscope and a multimeter in frequency mode.<br />
<br /></div>
<div class="c1">
</div>
<div class="c1">
<br />
<div class="separator" style="clear: both; text-align: center;">
<object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="https://i.ytimg.com/vi/D6HWVOVNV_k/0.jpg" height="266" width="320"><param name="movie" value="https://www.youtube.com/v/D6HWVOVNV_k?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="https://www.youtube.com/v/D6HWVOVNV_k?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div>
<span class="c0"><br /></span>
<span class="c0"><br /></span></div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br />
<h3>
Source code is now ebedded (Update at 30/11/2014)</h3>
Thanks to <a href="https://gist.github.com/" target="_blank">Gist </a>the source code is now embedded inside the blog entry.<br />
<br />
<h3>
Source code now in Github (Update at 11/02/2018) </h3>
<br />
You can find it in this link:<br />
<br />
<a href="https://github.com/R6500/MSP430-DCO-Calibration">https://github.com/R6500/MSP430-DCO-Calibration</a><br />
<br />
<br />
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-76505238439464544072014-10-08T21:27:00.001+02:002014-11-30T16:34:35.479+01:00Soldering the Launchpad Xtal<div style="text-align: justify;">
In this article I will talk about soldering the 32768 Hz quartz Xtal that is provided with the G2 <a href="http://www.ti.com/ww/en/launchpad/launchpads-msp430-msp-exp430g2.html" target="_blank">Launchpad</a>.</div>
<div style="text-align: justify;">
This article is a rewrite in english of one <a href="http://aim65.blogspot.com.es/2012/05/instalacion-del-cristal-en-el-launchpad.html" target="_blank">article </a>in my spanish twin blog <a href="http://aim65.blogspot.com.es/" target="_blank">Aim65</a>. </div>
<div style="text-align: justify;">
The 32768 Hz Xtal is the basis of a real time clock. In fact 2^15 clock
cycles of that device correspond to one second. In the MSP340 familly we
can use the Watchdog in timer mode associated to it to generate one
interrupt each second. </div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoNTulvuXooB8F8f8-YrIDoBhoRnZn2l9LLJkyfKCeYXw23lnLZdWi8646yiZWnIUyBFvWBmbdQ0TvRLc-x_cYcnvwNxCkwcakxI0NYPpQL7MIxKhP_SaG4iZcPFwkq89FIEBDxffSGrbM/s1600/Figure+01.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoNTulvuXooB8F8f8-YrIDoBhoRnZn2l9LLJkyfKCeYXw23lnLZdWi8646yiZWnIUyBFvWBmbdQ0TvRLc-x_cYcnvwNxCkwcakxI0NYPpQL7MIxKhP_SaG4iZcPFwkq89FIEBDxffSGrbM/s1600/Figure+01.jpg" height="197" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Launchpad and Xtal bag</td></tr>
</tbody></table>
<br />
This Xtal is included with the Launchpad package but it is not soldered on the board. As this device uses two MCU pins, you lose two I/O lines when you solder it on the board. It's up to you to decide what is better: a 32768 Xtal or two I/O lines.<br />
<br />
The following figure show the position where the Xtal should be soldered.<br />
<div style="text-align: justify;">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLaosIeJRq4hn_TEviZQ7gGy58A-lWO92ydmnNASXfG-ExNrGvaqn5WP-nsHpGhB1vNceSqS8AIOO4U-rDxA_V9KUNrxdSzJxmTVW3qg6T6E8VfkowsM_r45qsHYynzMnKhyphenhyphenj18pCx4aDj/s1600/Figure+02.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLaosIeJRq4hn_TEviZQ7gGy58A-lWO92ydmnNASXfG-ExNrGvaqn5WP-nsHpGhB1vNceSqS8AIOO4U-rDxA_V9KUNrxdSzJxmTVW3qg6T6E8VfkowsM_r45qsHYynzMnKhyphenhyphenj18pCx4aDj/s1600/Figure+02.jpg" height="281" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xtal Location</td></tr>
</tbody></table>
<br />
This Xtal is tiny and somewhat difficult to solder. The easiest way to proceed is to fix it in place by means of adhesive tape. Beware that the Xtal is not symmetrical. When correctly laid on the board the contacts should touch the soldering pads.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDgFDyRJhlbqF6NzhkizS7kZl4SRtPlzJS499KdGnPzpyoBsp7RN6gDw_IYDkAjzg8NLL8QGctkJPd1UBAFpLIal9T1HAc7z2f_hdkA9i27P0EoqZ0Mqj0fR80fyq4GHRhi_YFavdWvIEZ/s1600/Figure+03.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDgFDyRJhlbqF6NzhkizS7kZl4SRtPlzJS499KdGnPzpyoBsp7RN6gDw_IYDkAjzg8NLL8QGctkJPd1UBAFpLIal9T1HAc7z2f_hdkA9i27P0EoqZ0Mqj0fR80fyq4GHRhi_YFavdWvIEZ/s1600/Figure+03.jpg" height="304" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xtal fixed with adhesive tape</td></tr>
</tbody></table>
A good soldering iron and a magnifier helps soldering the Xtal.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHoxbx7192L0QzxGVMqj7VmsXSynblFQ1kg2dOfdfd4YhuMSr0OLvmRFuwyVMDckNYXMiSNxy3dxm464EbyMZyoiE4wLrkpg-8Xdv6KIjC3PS_7wtgn_Jn0xs4PcBi-n64kol9oDm5I-Te/s1600/Figure+04.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHoxbx7192L0QzxGVMqj7VmsXSynblFQ1kg2dOfdfd4YhuMSr0OLvmRFuwyVMDckNYXMiSNxy3dxm464EbyMZyoiE4wLrkpg-8Xdv6KIjC3PS_7wtgn_Jn0xs4PcBi-n64kol9oDm5I-Te/s1600/Figure+04.jpg" height="284" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xtal soldered on the board</td></tr>
</tbody></table>
When the Xtal terminals are soldered we can take out the adhesive tape and then we can solder the Xtal body to the pad located below it. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfJXBN0MVWkQ2SJkDmLxOvls5qU0MHD2sAhNWNo7H8X4Iofrd_ZTRLduSUoktfmiMAz9X4fdRoAM9vBQJfziYsCsvp69HVYnPlcdB0d9j4H1IQwn461vVsqVep1qRLOmwdAnO99o3F1Rlq/s1600/Figure+05.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfJXBN0MVWkQ2SJkDmLxOvls5qU0MHD2sAhNWNo7H8X4Iofrd_ZTRLduSUoktfmiMAz9X4fdRoAM9vBQJfziYsCsvp69HVYnPlcdB0d9j4H1IQwn461vVsqVep1qRLOmwdAnO99o3F1Rlq/s1600/Figure+05.jpg" height="260" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xtal soldered at the three points</td></tr>
</tbody></table>
<div style="text-align: justify;">
After the Xtal is soldered we should check its correct operation. I have developed a little program to do that. It compiles under MSP-GCC and contain two main files: <a href="https://docs.google.com/document/pub?id=1unYNToGky6u6tZRRn33BITmeg_crMPuUqeQWmClNv_U">main.c</a> and <a href="https://docs.google.com/document/pub?id=17QD0mRxXWZs0PsDH5yn__HlEb4QBPxp_Xceurq-TfyE">io430masks.h</a>.<br />
<br />
<h4>
main.c </h4>
<script src="https://gist.github.com/anonymous/e0cba07726621add6dda.js"></script> <br />
<br />
<h4>
io430masks.h </h4>
<script src="https://gist.github.com/anonymous/f918bed1b3c69b0d4b73.js"></script><br />
<br />
<br />
The program tries to start the oscillator associated to the Xtal. If it works ok, the green LED blinks every second. If the oscillator could not start, it lights the red LED. <br />
<br /></div>
If the oscillator cannot start we must first check the soldering.<br />
<div style="text-align: justify;">
<br />
The oscillator is quite sensible to any interference. The oscillator pins are connected to the J2 header as they can also be used for I/O. This connection includes two zero Ohm resistors in the path. To minimize any interference those lines can be disconnected desoldering those resistors.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1cFjO8Pbbd448sKMtmpHFHJyRqaSoDXCP-l5E02B1jDCfdq9k3B34_JjYIjJsponYcMg7BrnYR7We8uTNiNPNCLV-Mnfnga_IsVJtNweSKfF3n1mIqqPsdW2vztdYBnL-yzdUfNfcqzpz/s1600/Figure+06.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1cFjO8Pbbd448sKMtmpHFHJyRqaSoDXCP-l5E02B1jDCfdq9k3B34_JjYIjJsponYcMg7BrnYR7We8uTNiNPNCLV-Mnfnga_IsVJtNweSKfF3n1mIqqPsdW2vztdYBnL-yzdUfNfcqzpz/s1600/Figure+06.jpg" height="259" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Resistors removed</td></tr>
</tbody></table>
<br />
<h3>
Alternative to soldering the Xtal</h3>
If you don't want to mess with the board or you don't want to permanently eliminate two I/O lines you can connect a Xtla to the J2 lines associated to the oscillator.<br />
That can be done using the Xtal provided with the Launchpad but its size makes it a little complex. Moreover 32768 Xtals are cheap and easy to obtain. It is important, however, to buy ones designed to operate with 12,5pF or 6pF capacitors. As the MCU includes those capacitor options inside you don't need to add them using discrete components.<br />
This is the Xtal I have bought at <a href="http://es.farnell.com/raltron/r26-32-768-12-5/crystal-frequency-32-768khz/dp/1652573?Ntt=1652573">Farnell</a>, for instance:<br />
<br /></div>
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<div style="text-align: justify;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHo5MbntAnRwSOPRxeWeOeBIRLfJhow_2_Sn9Bm737EuvoJiRG9APi4yTYKRtkkaXtLtMxceuZM-Hazu8KfBMrt83ZaU2J3-E1b24lYtvbaiu1ZpDaI7iDziKY0pZ_Nub2jL99tP6hNuZr/s1600/Figure+07.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHo5MbntAnRwSOPRxeWeOeBIRLfJhow_2_Sn9Bm737EuvoJiRG9APi4yTYKRtkkaXtLtMxceuZM-Hazu8KfBMrt83ZaU2J3-E1b24lYtvbaiu1ZpDaI7iDziKY0pZ_Nub2jL99tP6hNuZr/s1600/Figure+07.jpg" height="191" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xtal soldered to a female header</td></tr>
</tbody></table>
I have soldered it to a two pin female header to be easily connected to the oscillator J2 pins.</div>
<div style="text-align: justify;">
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCyk39WCA7HsIsdoEl22xlUzidLm1WQmibGeUzBBQOMrnDUXYbcoVqIOgPaAyN8hPFUlza3L65OIbLmFo-81_9rx7lMU8ue1BCyqJDxDXUIe8w2dApMl7GeC5onzrxR6NhfWAD2qyC40No/s1600/Figure+08.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCyk39WCA7HsIsdoEl22xlUzidLm1WQmibGeUzBBQOMrnDUXYbcoVqIOgPaAyN8hPFUlza3L65OIbLmFo-81_9rx7lMU8ue1BCyqJDxDXUIe8w2dApMl7GeC5onzrxR6NhfWAD2qyC40No/s1600/Figure+08.jpg" height="235" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xtal at J2</td></tr>
</tbody></table>
Connecting the Xtal at J2 increase its wire lenght and could give some interferences. The proper solution is to solder it on board if possible.<br />
<br />
With the Xtal mounted on the board its easy to develop any application that should keep a real time clock.</div>
</div>
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-18043992293522948882014-10-06T14:35:00.000+02:002014-11-30T16:39:27.300+01:00MSP340 Launchpad Fet<div style="text-align: justify;">
In order to do In System Programming (ISP) you usually need a Flash Emulator Tool (FET). For the Texas instruments MSP340 family you can buy the <a href="http://www.ti.com/tool/msp-fet?keyMatch=msp430%20fet&tisearch=Search-EN" target="_blank">one</a> that TI sells for their MCUs:</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOEjqBEs-RJvwNkv1qGM2imJBFgrM8c-AGbLZkRcqB23eC0mB5ZdrL0SUzL7fJfsSCianTX2W5i6d3299BdeuLJaEKkgbCf7OknAqKnDWGlcdJ9DI9Ls6hLgfnOLsK83vtJUjk6po4LE1I/s1600/flash-emulation-tool.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOEjqBEs-RJvwNkv1qGM2imJBFgrM8c-AGbLZkRcqB23eC0mB5ZdrL0SUzL7fJfsSCianTX2W5i6d3299BdeuLJaEKkgbCf7OknAqKnDWGlcdJ9DI9Ls6hLgfnOLsK83vtJUjk6po4LE1I/s1600/flash-emulation-tool.jpg" height="205" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Official TI MSP340 FET</td></tr>
</tbody></table>
<div style="text-align: justify;">
That costs about 100$ and it isn't too much if you program MCUs for a living. It can work with supplies from 1.8V to 3.6V and do program/debug using JTAG or Spy-By-Wire (2 Wire) interfaces.</div>
<br />
<div style="text-align: justify;">
For the hacker that buys their own tools there are cheaper solutions. You can find several references on Internet about people that have used the <a href="http://www.ti.com/tool/msp-exp430g2?keyMatch=msp430%20launchpad&tisearch=Search-EN" target="_blank">MSP430 Launchpad</a> to do ISP programming. This Launchpad board is designed to program MSP430 MCUs of the "G" value line in dip packages using an included 20 pin socket. As all the signals needed to do Spy-By-Wire are available so you can use this board to program MCUs located in another board as long as you route the needed signals: TDIO, TCK and the reference GND to the proper pins of the MCU to program.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This article explains a FET implementation using the TI Launchpad. As this board provides also a serial TX/RX communication using the PC USB connection. It will also be implemented in the FET.</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Features</h3>
<br />
<ul>
<li>Two Wire Spy-By-Wire for the MSP430 family</li>
<li>Serial TX and RX communication at 3.6V level</li>
</ul>
<br />
<h3 style="text-align: justify;">
Limitations and Disclaimer </h3>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The FET will inherit all the limitations related to the use of the TI Launchpad as a FET device.</div>
<div style="text-align: justify;">
</div>
<ul>
<li>Can only use Spy-By-Wire, no full JTAG is available</li>
<li>It can only work with and provide 3.6V</li>
</ul>
<div style="text-align: justify;">
The second limitation could be important. As the Launchpad works at a fixed 3.6V supply, the provided Vcc and the signaling is at 3.6V. As long as the board you communicate with is at about 3.6V all will be ok. </div>
<div style="text-align: justify;">
As 3.6V is the maximum operating voltage in the MSP430 you cannot connect the FET to a board that operates the MCU at a greater voltage. In the case of connecting to a board that uses a lower voltage, let's say 2.5V, you could power the board without using the FET, but the signaling from the FET to the board will be at 3.6V and that could be above the Absolute Maximum Ratings from the MCU. Adding level shifters is out of the goals of this project so I recommend using this FET only when the board is powered between 3.3V and 3.6V in order to guarantee that the Maximum Ratings are not exceeded.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If the connected board should work at less than 3.3V I recommend to power it at 3.6V from the FET during the programming and debugging and powering it at it's own lower voltage when it is disconnected from the FET.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Off course this document is only a documentation of something I have done for myself and there are no provided guarantees that it will suit your own needs or that it won't blow-up your home. Yoy have been warned.<br />
<br />
<br />
<h3>
Launchpad Signals and project schematic</h3>
The signals needed to program a MSP430 chip and provide Serial communication are mainly at the J3 connector that links the emulator upper side of the board with the target MCU lower side. As we won't use the lower part, we will take out all the five jumpers in J3.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Jfc6Z6JBgk3HmR9V-BqZ-cJEKMb3kVQVee96TEd4igfqlavE6dZFF0OJxx5RxNVk6RqT3d9K37pgS-yg9Ikg99k6Z03kxkod95aOMplFv4HxItk1TTfyX9R2ftHhDrUvLgzHQGkn1UgI/s1600/Launchpad+Conn.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Jfc6Z6JBgk3HmR9V-BqZ-cJEKMb3kVQVee96TEd4igfqlavE6dZFF0OJxx5RxNVk6RqT3d9K37pgS-yg9Ikg99k6Z03kxkod95aOMplFv4HxItk1TTfyX9R2ftHhDrUvLgzHQGkn1UgI/s1600/Launchpad+Conn.jpg" height="320" width="302" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Launchpad connectors used</td></tr>
</tbody></table>
<br />
The signals used will be:<br />
<br />
<ul>
<li>SBWTDIO: Two wire data / nRESET</li>
<li>SBWTCK: Two wire clock</li>
<li>VCC: 3.6V supply generated from the USB line using a regulator</li>
<li>RXD: Serial from MCU to the PC</li>
<li>TXD: Serial from the PC to the MCU</li>
</ul>
We will also need a common GND node. This one is not available at J3, so we will take it from pin 20 at J2.<br />
<br />
The connector J1 is not needed, but as the Launchpad has no mounting holes, it will be used to provide physical support.<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvbiv8rfK94xhUeoC2uTzwQbsLtajXAsoYjOkrHoD7UqTsd61JOvln7faH_9nPS46Kb22GzDydUELV1Uk0yiPO5D05If8-cQs7K6A_uU_CivVhsJvCIcqabOT7Gww-9MeReaEPO6DWx6GH/s1600/Schematic.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvbiv8rfK94xhUeoC2uTzwQbsLtajXAsoYjOkrHoD7UqTsd61JOvln7faH_9nPS46Kb22GzDydUELV1Uk0yiPO5D05If8-cQs7K6A_uU_CivVhsJvCIcqabOT7Gww-9MeReaEPO6DWx6GH/s1600/Schematic.png" height="383" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Project Schematic</td></tr>
</tbody></table>
<br />
The above schematic shows all the needed connections. In the Launchpad we will use J2 and J3 to provide the needed signals. Those signals will be routed to a 2x4 male connector that will be used to do ISP on the target MCU. I have removed one pin in the connector (marked with X) to be able to develop cables that can only be connected in the right way and not in the 180 degree rotation position.<br />
A LED to check that the Launchpad is operating and a push button to force a RESET on the target MCU complete the schematic.<br />
<br />
<br />
<h3>
Construction</h3>
To build the project I have selected a box that is just over the Launchad board size. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjltk4jy7IwyfDCJAjjHxh4WO8VzEko7rdxVBHupI4TOwJ78IKGhb6q2ikzv7IuMZWQeTKTNk4cUG-Ci3Hw95GHIrmiVBNPaC4AiHWPjLMLRZdjsageXz3qUX-lyDcwRiPfj8aNQ_MVj0vJ/s1600/01-Box.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjltk4jy7IwyfDCJAjjHxh4WO8VzEko7rdxVBHupI4TOwJ78IKGhb6q2ikzv7IuMZWQeTKTNk4cUG-Ci3Hw95GHIrmiVBNPaC4AiHWPjLMLRZdjsageXz3qUX-lyDcwRiPfj8aNQ_MVj0vJ/s1600/01-Box.jpg" height="228" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Project Box</td></tr>
</tbody></table>
All the connections will be done on a perf board. In order to mount it on the box four M3 thread 10mm spacers are fitted inside the box.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQT6tqxjSArYSUKa1q2kMzgbp17qdSDcAAslqSr5j4GF0JB3PZcnWLuigAGG7LHD68lDSNFbhRsyS6jfv1bOBjI8AIt_vPmGX3VyhRwGPLztXZh03uXNPt70nwAmcuHBFybZYdwo_PxBQj/s1600/03-Box-Spacers.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQT6tqxjSArYSUKa1q2kMzgbp17qdSDcAAslqSr5j4GF0JB3PZcnWLuigAGG7LHD68lDSNFbhRsyS6jfv1bOBjI8AIt_vPmGX3VyhRwGPLztXZh03uXNPt70nwAmcuHBFybZYdwo_PxBQj/s1600/03-Box-Spacers.jpg" height="222" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Box with fittex M3 spacers</td></tr>
</tbody></table>
The board is cut to the box size and it has been milled to leave space to the thread posts that are in each corner of the box. Four holes match the four spacers in the box.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWYJ7Gdee-_nWRGKPXiOjlKtQULQnX-VeUhp1t0DDKE4C9hgUHp5Ypy-gB3qcmSwjbG5nOl9GcmLJRf_EU8Xtt4AF6KWQOMsKiGqo-kdjHswSWE7o11G2J62ikuFOUqxR85v8ejRTVP-Yl/s1600/04-Perf-Board.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWYJ7Gdee-_nWRGKPXiOjlKtQULQnX-VeUhp1t0DDKE4C9hgUHp5Ypy-gB3qcmSwjbG5nOl9GcmLJRf_EU8Xtt4AF6KWQOMsKiGqo-kdjHswSWE7o11G2J62ikuFOUqxR85v8ejRTVP-Yl/s1600/04-Perf-Board.jpg" height="214" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Perf Board</td></tr>
</tbody></table>
As I have commented, the Launchpad board has no mounting holes, so I will put it over the perf board upsidedown. That means that the connections on the board will be mirrored respect to the Launchpad ones as seen from above.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_3xNNVL_gcdDfuanMLYa90RbLsW9I3CV_gL0cLzwKkVEuXFiNbse4YDRHccDmaPyx3krahLpcmmTE9Q0iVxOkx7nmMpGMw6tLNzeGQL524VF6Q8FF4XiKHL0PMLl9vFpCX2s4x8ngWnl1/s1600/Board+Distribution.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_3xNNVL_gcdDfuanMLYa90RbLsW9I3CV_gL0cLzwKkVEuXFiNbse4YDRHccDmaPyx3krahLpcmmTE9Q0iVxOkx7nmMpGMw6tLNzeGQL524VF6Q8FF4XiKHL0PMLl9vFpCX2s4x8ngWnl1/s1600/Board+Distribution.png" height="400" width="283" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Board Distribution</td></tr>
</tbody></table>
<br />
I have used three connectors, one female 2x5 to match J3 and two females 2x7 that connect to J1 and J2. I know that J1 and J2 are 1x10 male, but I had those 2x7 connector lying arround and as I only need to connect one pin at J2 that's ok for this project.<br />
The LED will be connected to the board with a pair of wires. To make things cleaner I have added a 2 pin male connector in the board to connect it.<br />
<br />
The following figure shows the populated perf board with all components. The LED that will connect to the two pin male connector is also shown .<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvnzLIr8d-pSM5rZp2R7NojPV_iS6zq8Ribt8dC8ak_ziRkW8gcU9cPtA7cvigO-GBxkZV3w-Go50yweOtC4DEEF56BS94ckuuskdalUFB5vt_lNqHqVTk8eo5MRQVWj_4Y5iffVHCjXM1/s1600/05-Board-Component.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvnzLIr8d-pSM5rZp2R7NojPV_iS6zq8Ribt8dC8ak_ziRkW8gcU9cPtA7cvigO-GBxkZV3w-Go50yweOtC4DEEF56BS94ckuuskdalUFB5vt_lNqHqVTk8eo5MRQVWj_4Y5iffVHCjXM1/s1600/05-Board-Component.jpg" height="270" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Populated perf board</td></tr>
</tbody></table>
<br />
To make the necessary connection I have used WMS (Wire Mess Routing). As the connections are easy this is ok for this project.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzTzwvk5CJPYebd8JAMMGsOx660SW63KX6AkcXzJzR0O0tH52iam5FkbVIgCVEFhz-Sb6aY3d2Or8I-HbhaVghjgNe08Q6k7MpBLBvh59BtIIsN-PVhyphenhyphenjzI-3xCeV5oB6ray4yJc5JOXTi/s1600/06-Board-Routing.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzTzwvk5CJPYebd8JAMMGsOx660SW63KX6AkcXzJzR0O0tH52iam5FkbVIgCVEFhz-Sb6aY3d2Or8I-HbhaVghjgNe08Q6k7MpBLBvh59BtIIsN-PVhyphenhyphenjzI-3xCeV5oB6ray4yJc5JOXTi/s1600/06-Board-Routing.jpg" height="256" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Wire mess under the board</td></tr>
</tbody></table>
The board is mounted inside the box and it is secured with four M3 screws.<br />
To connect the Launchpad board all five J3 jumpers and the DIP MCU must be removed.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd68WapF8QsREA1YMSyCEEBHS-03v8iOZ9PdYvcjrlKr7i1phLV5U4o2HX_WHetS1Zg0E-gE470amB1-nbztVp2LTTpNyPDNQ3ZEquhIe_e7wi_o4zFKynAMjvRd_be_Hst46yIVndzjF5/s1600/02-Launchpad.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd68WapF8QsREA1YMSyCEEBHS-03v8iOZ9PdYvcjrlKr7i1phLV5U4o2HX_WHetS1Zg0E-gE470amB1-nbztVp2LTTpNyPDNQ3ZEquhIe_e7wi_o4zFKynAMjvRd_be_Hst46yIVndzjF5/s1600/02-Launchpad.jpg" height="202" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Launchpad Board without MCU or J3 jumpers</td></tr>
</tbody></table>
The Launchpad board is mounted upsidedown over the perf board and the LED is fitted in a 5mm hole and connected to the board.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYuEbwKkeVlqa_B4pLyPcq_EEJPkr4WIK04IJcCKWTzL_6Fuk3J-7hYkTKB6jlho-36kMW29TCmJdsDBWm_91f7i3sqLguXhn2Qm6EfZQ4gAqn1bUNjFx9dVYbX9mxOiIijbGtEt0J9v1E/s1600/07-Launchpad-Installed.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYuEbwKkeVlqa_B4pLyPcq_EEJPkr4WIK04IJcCKWTzL_6Fuk3J-7hYkTKB6jlho-36kMW29TCmJdsDBWm_91f7i3sqLguXhn2Qm6EfZQ4gAqn1bUNjFx9dVYbX9mxOiIijbGtEt0J9v1E/s1600/07-Launchpad-Installed.jpg" height="240" width="320" /></a></div>
<br />
Four holes are made on the box. One for the Launchpad USB connector,<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO_-6l_pxvUa-s8MLlGuiKC4SuB8RLeST2hl3drWhtGywzmIkcvoQ9d_2voXvRtlg0ts30rc4bDS5I_Hj9yk9tniCVniXmQE5vS0Ombgi0jM0EG2-aEQvVrePUUzNCoN3XANkSa2Bb5pdw/s1600/11-USB-Detail.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjO_-6l_pxvUa-s8MLlGuiKC4SuB8RLeST2hl3drWhtGywzmIkcvoQ9d_2voXvRtlg0ts30rc4bDS5I_Hj9yk9tniCVniXmQE5vS0Ombgi0jM0EG2-aEQvVrePUUzNCoN3XANkSa2Bb5pdw/s1600/11-USB-Detail.jpg" height="200" width="320" /></a></div>
<br />
<br />
two for the ISP connector and the LED,<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijF74ZyNkhO44G23CFdVIfBEnXnbX7uw02x4xPp1eNXE0xGNBkHjnLft4GDWKxiPQ_9iiL2tWuVvRuZ7BlnNPaQ0xvb6Y7mtSEUCfFGzdFekc0j2cfTftXWrdzjQdQi77wqPpYdvf_PUOM/s1600/09-Conn-Detail.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijF74ZyNkhO44G23CFdVIfBEnXnbX7uw02x4xPp1eNXE0xGNBkHjnLft4GDWKxiPQ_9iiL2tWuVvRuZ7BlnNPaQ0xvb6Y7mtSEUCfFGzdFekc0j2cfTftXWrdzjQdQi77wqPpYdvf_PUOM/s1600/09-Conn-Detail.jpg" height="249" width="320" /></a></div>
<br />
<br />
and the last one for the RESET button. This one is missaligned, I know.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyhEtzqflsSB1j1hcZZ9Rshr5L742uoneXXFl35cURwLlnCzgLE3kA6ypQde_v7DPNgkQXd69llP98W9mXRzoe04Nc2FuyltYV9Fbr0qT6K1dxs4_KaI8MXuNtzY172onIKXDSpVc41kiG/s1600/10-Reset-Detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyhEtzqflsSB1j1hcZZ9Rshr5L742uoneXXFl35cURwLlnCzgLE3kA6ypQde_v7DPNgkQXd69llP98W9mXRzoe04Nc2FuyltYV9Fbr0qT6K1dxs4_KaI8MXuNtzY172onIKXDSpVc41kiG/s1600/10-Reset-Detail.jpg" height="185" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
Four feet bumps, one on each corner complete the box and makes it stable over a table.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj66LuMcGaAzg3o1j-QDjufVIS9YxG8aTqSo62xWqH6NOpOnmECz956Cr4YX8I8QId0C2ccmUNBCPSTAy-40NYIyNE_NNtAHsSZ-WRFuY20yaqfyOq56RxTJhwb9s1wxISOeqWpajiPbC5b/s1600/08-Bumps.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj66LuMcGaAzg3o1j-QDjufVIS9YxG8aTqSo62xWqH6NOpOnmECz956Cr4YX8I8QId0C2ccmUNBCPSTAy-40NYIyNE_NNtAHsSZ-WRFuY20yaqfyOq56RxTJhwb9s1wxISOeqWpajiPbC5b/s1600/08-Bumps.jpg" height="258" width="320" /></a></div>
<br />
To end the build I have added a picture over the box with the ISP connector pinout.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoCB-AtO7FIr8GLirqeywsXgOoVm5B7JqreiNIkUu1tqoxpDX0f6XlC7WQgtPkQCvO0D1FGc6EGrLtB6U2wDPBkTFm7RVID0pGaLyWu9ZushtqwoQDx9E0YTU-GmWse1Fkz0Mx-oNsMN0o/s1600/14-Final.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoCB-AtO7FIr8GLirqeywsXgOoVm5B7JqreiNIkUu1tqoxpDX0f6XlC7WQgtPkQCvO0D1FGc6EGrLtB6U2wDPBkTFm7RVID0pGaLyWu9ZushtqwoQDx9E0YTU-GmWse1Fkz0Mx-oNsMN0o/s1600/14-Final.jpg" height="259" width="320" /></a></div>
<br />
<br />
<h3>
Echo Blink Test Program</h3>
To test the FET we need a program to load in a MCU using ISP. The developed program blinks a LED so we can see that the program has been corretly transfered to the MCU.<br />
The program also provides an echo functionality using the serial port. Each character received from RX is converted to uppercase (if it was between 'a' and 'z') and then it is echoed to TX. That way we can also test the serial communication using the same program. <br />
<br />
I have three toolchains to work with the MSP340 familly:<br />
<br />
<ul>
<li>MSPGCC eclipse based IDE that I configured myself</li>
<li><a href="http://www.ti.com/tool/CCSTUDIO" target="_blank">Code Composer Studio</a> that is free for the Launchpad Use or below 16kB</li>
<li><a href="http://energia.nu/" target="_blank">Energia</a></li>
</ul>
The last one, <a href="http://energia.nu/" target="_blank">Energia</a>, is interesting because it provides an Arduino like IDE for the MSP430 familly. If you don't know Energia and like Arduino, chek it out. One important difference with Arduino is that Arduino boards are programmed using a bootloader, so you need a resident program in the MCU. Energia, uses Spy-By-Wire, not serial, to do the programming so it doesn't need a bootloader. This makes easy to program any compatible MSP430 chip you have bought.<br />
<br />
Energia, in the same way that the Arduino IDE don't provide hardware debug functionalities. As the FET can be used to do hardware debugging on the target MCU, using Energia is not the most featured solution, but sure it is the easier to get working. So, I developed the <b>Echo Blink</b> program as an Energia sketch.<br />
<br />
The <a href="https://docs.google.com/document/d/1SXy5Yiwau1b32AEuZDrbZolGa2sBQoGtCBtY3XHCfKg/edit?usp=sharing" target="_blank">Echo Blink</a> sketch is provided in this <a href="https://docs.google.com/document/d/1SXy5Yiwau1b32AEuZDrbZolGa2sBQoGtCBtY3XHCfKg/edit?usp=sharing" target="_blank">link</a>. But you can also see it here:<br />
<br />
<script src="https://gist.github.com/anonymous/049cf3ffd494be9728ec.js"></script><br />
<br />
The program just blinks a led on P1.0 (pin 2 on MSP430G2553) changing its state each 200ms. During the 200ms wait between changes, the RX line (FET TX) is tested for incoming chars each millisecond and the characters are changed to uppercase if they were in lowercase and echoed to TX (FET RX). If no character is echoed during each 200ms wait, a '.' char is sent to TX. That way TX can be tested alone.<br />
<br />
<h3>
Simple ISP schematic</h3>
You can program a system outside of the Launchpad board using the FET. At a minimum, it needs to have the needed connections between the FET and the MCU: GND, TCK and TDIO. The Reset line that is shared with TDIO must not be connected directly to Vdd. A 47k resistor to Vdd and a 1nF or 2.2nF to ground works ok. You can also add a reset button if needed in this line.<br />
The following figure shows a simple system to be ISP programmed.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc4c1RWTezQNMVhH6yMujCeHMCv3wiqCj3MP4VKB1kzFrC16Z3cSNjlypyXJ17JbSLKPch2JrApz9gS9MAJUvRcEegWSSEdc8vdLvycvTpOpYWMIP48226uwkrr5tVmOb1hk-eQZxKvUdO/s1600/MSP430G2553+Sch.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc4c1RWTezQNMVhH6yMujCeHMCv3wiqCj3MP4VKB1kzFrC16Z3cSNjlypyXJ17JbSLKPch2JrApz9gS9MAJUvRcEegWSSEdc8vdLvycvTpOpYWMIP48226uwkrr5tVmOb1hk-eQZxKvUdO/s1600/MSP430G2553+Sch.png" height="213" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Basic ISP system based on MSP430G2553</td></tr>
</tbody></table>
Aside from the described ISP and RESET connections there is a 100nF decoupling cap. The serial TX and RX are also included but they are not needed to programming.<br />
<br />
<h3>
System Test </h3>
To test the system I have connected it to and a PC and a MSP430 G 2553 and loaded the Echo Blink program.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4jjTpvGHh4e-HqJBdn4mZs2pe8jycl0oUyZhuumDLYaecjd07yUwOr3IY-F9qMLbk8TjCBky-2_LnJOYB7NZQgCaYFYULfbVvK4IsRXBMMpofYEh7ioRmI3XVBUB1pCi3lHGnVrzNa7yT/s1600/13-PC-Conn.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4jjTpvGHh4e-HqJBdn4mZs2pe8jycl0oUyZhuumDLYaecjd07yUwOr3IY-F9qMLbk8TjCBky-2_LnJOYB7NZQgCaYFYULfbVvK4IsRXBMMpofYEh7ioRmI3XVBUB1pCi3lHGnVrzNa7yT/s1600/13-PC-Conn.jpg" height="285" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">System running, only tested programming on this test</td></tr>
</tbody></table>
I have also connected the system to a 28 pin TSSOP MCU, using a SMD to DIL adaptation board, and it also works ok.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTnEuC3dKreC_b_phg3mMDMQy8kVhxBvKpBcr-RckC_Oe0N4LpmW0icmT8uYJ28-Q2b_vXz0m5iVgJv513r_PrrUVGZbOD0LmvrIBUNUv9ywAHZ0DS5tT36JEeXCPfgF5sEZT6alhjQYsq/s1600/15-SMD28.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTnEuC3dKreC_b_phg3mMDMQy8kVhxBvKpBcr-RckC_Oe0N4LpmW0icmT8uYJ28-Q2b_vXz0m5iVgJv513r_PrrUVGZbOD0LmvrIBUNUv9ywAHZ0DS5tT36JEeXCPfgF5sEZT6alhjQYsq/s1600/15-SMD28.jpg" height="249" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Test of a MSP430 G 2553 in TSSOP 28 package</td></tr>
</tbody></table>
<br />
All in all I'm quite satisfied with this build. It eases programming a MSP430 MCU using a launchpad board.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkv1XLq5Dmof0DjSDNJGgPc_e8dSqli-Sze6Oz8Z7xJEecvTgD-efYXj1vbX8qEfl4aol5lHgHCUPnDo5gtZYdCjgqr45MWoXW-6fxSNEhje7M2QD5ab1jhWy3F4R8lUc1rkCMFnykISpW/s1600/Echo+Blink.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkv1XLq5Dmof0DjSDNJGgPc_e8dSqli-Sze6Oz8Z7xJEecvTgD-efYXj1vbX8qEfl4aol5lHgHCUPnDo5gtZYdCjgqr45MWoXW-6fxSNEhje7M2QD5ab1jhWy3F4R8lUc1rkCMFnykISpW/s1600/Echo+Blink.png" height="314" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Echo Link Program Running</td></tr>
</tbody></table>
<br />
<br />
<br />
Addition at 7/10/2014: It seems that someone has made the same upsidedown FET configuration before. It don't surprise me. You can find it at this <a href="http://it-pro-hu.blogspot.hu/2013/03/mi-keszult-hetvegen.html" target="_blank">link</a>. (It's in Hungarian)<br />
<br />
Update at 30/11/2014: Now the EchoBlink.ino sketch is embedded in the blog using <a href="https://gist.github.com/" target="_blank">Gist </a></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com3tag:blogger.com,1999:blog-6880821591370697484.post-43240548903209256002014-05-14T00:04:00.000+02:002014-05-14T00:04:59.896+02:00STM32 Nucleo BoardsI have just received two nucleo boards: the L152RE and the F401RE. This is my first impression.<br />
<br />
The <a href="http://www.st.com/web/en/press/p3526" target="_blank">Nucleo boards</a> are the last entry level boards in the STM32 family. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyDLa1GbeTyzSESvvWX_Z-ysP0eA4ZbKjDP5ssYE4FX4c4Yj3qEz3F0rBB9ZOU5ugmwZKNsQJ3Iiqm7LZ5u2sVtb6P99wME6r7aAppuJfArJwXiwhVF6FSsDL2AR4ZimgL8GfsHCLiroIs/s1600/STM32_Nucleo_p3526big.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyDLa1GbeTyzSESvvWX_Z-ysP0eA4ZbKjDP5ssYE4FX4c4Yj3qEz3F0rBB9ZOU5ugmwZKNsQJ3Iiqm7LZ5u2sVtb6P99wME6r7aAppuJfArJwXiwhVF6FSsDL2AR4ZimgL8GfsHCLiroIs/s1600/STM32_Nucleo_p3526big.jpg" height="224" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">STM32 Nucleo advertising</td></tr>
</tbody></table>
<div style="text-align: justify;">
In the last years ST has provided the fantastic <a href="http://In the last years ST has provided the fantastic Discovery boards" target="_blank">Discovery boards</a>. Those boards, specially the <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF254044" target="_blank">STM32F3</a>, <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF252419" target="_blank">STM32F4</a>, <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF259098" target="_blank">STM32F401</a> and <a href="http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF259090" target="_blank">STM32F429</a> pack a lot of power for their price. Unfortunately they are not easy on the beginners. Of course there are projects like <a href="http://sourceforge.net/projects/chibios/files/ChibiStudio/" target="_blank">ChibiStudio</a> or <a href="http://www.coocox.org/CooCox_CoIDE.htm" target="_blank">CoIDE</a> that ease the programming of these boards but they are not as easy as Arduinos, for instance.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
But that changes with the Nucleo boards. Those boards are <a href="https://mbed.org/" target="_blank">mbed</a> enabled. Mbed is a development platform for ARM microcontrollers. It started with the ARM Embed board based on NXP LPC microcontrollers. What is special about this platform is that it is web based. You don't need to install any toolchain in the computer and the source files are available everywhere. And, as in the Arduino case, you get libraries for all the board peripherals. Off course, a web based compiler is not the solution for everyone. For instance you cannot work offline.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpSrlcSIM-GTlckwweDET7ja8ya3CAdyxDoLft2pgtNwNBxq2FtWlmla0bagCgzykG4YfhLWyGpeVEnHkawnmfk-MItjwOssHnAmhZi-bUmihYJhMYNM_7vnOyWGpT7bq3rOvc7Rb6625H/s1600/Mbed.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpSrlcSIM-GTlckwweDET7ja8ya3CAdyxDoLft2pgtNwNBxq2FtWlmla0bagCgzykG4YfhLWyGpeVEnHkawnmfk-MItjwOssHnAmhZi-bUmihYJhMYNM_7vnOyWGpT7bq3rOvc7Rb6625H/s1600/Mbed.png" height="222" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">mbed web compiler</td></tr>
</tbody></table>
You write the code from scratch or from one of the examples available. Hit the compile button and a binary file is generated that you can directly drop on the mbed board that shows on the PC as a mass storage drive. Quite easy.<br />
<br />
<h3>
The Nucleo F401RE Board</h3>
<div style="text-align: justify;">
The nucleo boards are not the only mbed boards. They are only the last ones in the mbed world but are well positioned next to several cheap boards from Frescale that are mbed enabled too and range from the basic 32KB Flash <a href="https://mbed.org/platforms/FRDM-KL05Z/" target="_blank">FRDM-KL05Z</a> to the 1MB Flash Ethernet enabled <a href="https://mbed.org/platforms/FRDM-K64F/" target="_blank">FRDM-K64F</a>. </div>
The original LPC mbed boards are not so well positioned in price or specs. <br />
<br />
<div style="text-align: justify;">
In this article I will talk about the F401RE Board that is the best specified nucleo board available. I don't have first hand experience on the Freescale mbed enabled boards buy they seem to be very interesting boards too.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6QNxEmp9F9Qiag67XIJRuhmmjQn1vNgp1NfCFijTnO27jT8PR6SK2gFYoBpHcaJpk9HpMOejQgd0_tWvIuu6COBfiLIb6vR9agHyyZR7H4bwP3oOPm0wu4XNIMJgVAw4YgQvtWuLd5WYX/s1600/Detail.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6QNxEmp9F9Qiag67XIJRuhmmjQn1vNgp1NfCFijTnO27jT8PR6SK2gFYoBpHcaJpk9HpMOejQgd0_tWvIuu6COBfiLIb6vR9agHyyZR7H4bwP3oOPm0wu4XNIMJgVAw4YgQvtWuLd5WYX/s1600/Detail.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Nucleo F401RE board</td></tr>
</tbody></table>
<div style="text-align: justify;">
The Nucleo F401RE board includes an ARM Cortex M4 STM32F401RET6 microcontroller with 512KB of flash memory. As all nucleo boards are equally priced I see little point in buying any other nucleo board unless you have very special requirements.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In the above figure I have encircled the two clock crystal empty slots. Some figures show them populated but you must be aware that the they are not in the board. You will normally get the clock from the upper side of the board that includes the USB connector but if you separate both board pieces you will have no crystal clock for the board. And, of course, if you need a 32kHz clock for the real time clock you would need to solder it yourself.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The nucleo boards are compatible with the now "standard" Arduino headers.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguQCQUEkXYsFKSWAYXxDKL9yDu-5ShkCDUL3XGpOsh7gDEYpGbLhWT0R9ckLmPlYgwcjQbnRbZP5dtwccMar5deMriEiRQZXDXEUb2dmZritz56ePs6CUJucIy8VhaxQ1XseCiB87ZInGO/s1600/Arduino+Headers.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguQCQUEkXYsFKSWAYXxDKL9yDu-5ShkCDUL3XGpOsh7gDEYpGbLhWT0R9ckLmPlYgwcjQbnRbZP5dtwccMar5deMriEiRQZXDXEUb2dmZritz56ePs6CUJucIy8VhaxQ1XseCiB87ZInGO/s1600/Arduino+Headers.png" height="300" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">F401RE Arduino headers</td></tr>
</tbody></table>
<div style="text-align: justify;">
If, as in my case, you don't mind about Arduino compatibility you can use the dual row Morpho headers that include more signals that the Arduino headers and don't include the damm non 100 mil pitch space of the right arduino headers.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvY4TfAHJBnVS_NGRlmHcuHsnX-ncaKGa8TnkLfxmlnXNO0Tis8thAJSKRHA7PD6IXFKORCpvr2cvFJT6RJn5EAN8gLDQNDqhDcLICggfavhhjKmambg4xJSM8c62qDVfJHHILAzgCyJVF/s1600/Morpho+Headers.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvY4TfAHJBnVS_NGRlmHcuHsnX-ncaKGa8TnkLfxmlnXNO0Tis8thAJSKRHA7PD6IXFKORCpvr2cvFJT6RJn5EAN8gLDQNDqhDcLICggfavhhjKmambg4xJSM8c62qDVfJHHILAzgCyJVF/s1600/Morpho+Headers.png" height="300" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">F401RE Morpho headers</td></tr>
</tbody></table>
<div style="text-align: justify;">
This is a very capable board. The ARM Cortex M4 processor includes a FPU that speeds any 32bit floating point operation. As an example I have tested that the board can calculate 40000 times the square root of a float quotient in only 25ms. Its not as fast as a STM32F4 Discovery board but is a quite good spec for a board so cheap and easy to program.</div>
<br />
All in all I'm quite pleased with this board. Packs a lot of power for its price and its very easy to program.<br />
In the future I plan to try to program it using more traditional development tools under eclipse but for now mbed is working quite well. In fact I like this environment more that the Arduino one.<br />
<div style="text-align: justify;">
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com1tag:blogger.com,1999:blog-6880821591370697484.post-22512417541875456912014-05-09T12:17:00.002+02:002014-05-09T12:17:46.984+02:00Intel Galileo. What will I make?<div style="text-align: justify;">
Some time ago I applied for the Intel Galileo university program and I was given ten <a href="http://www.intel.com/content/www/us/en/do-it-yourself/galileo-maker-quark-board.html" target="_blank">Intel Galileo</a> boards to be used on education projects. I supposed that the first I should do is learn to use the board before giving it to my students. This is the first blog entry about this board. </div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw4HI5uOqJWLJWosKw7YEqpheG_4wEQrmrntNgkeUXMlWn3S8RzHPJMH2s6vMe3K_U4j02Ch59Nx4TYuRj34PMuyt-7XPl2VroNm9TPZVoWkwPu1fMGSsj5KubtqWPbjS5VEzJ0_exm2Pj/s1600/Galileo+Box2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw4HI5uOqJWLJWosKw7YEqpheG_4wEQrmrntNgkeUXMlWn3S8RzHPJMH2s6vMe3K_U4j02Ch59Nx4TYuRj34PMuyt-7XPl2VroNm9TPZVoWkwPu1fMGSsj5KubtqWPbjS5VEzJ0_exm2Pj/s1600/Galileo+Box2.jpg" height="114" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Intel Galileo Board Box</td></tr>
</tbody></table>
<h3>
The Expectation</h3>
The Intel Galileo board promises a lot. It is an <a href="http://arduino.cc/en/ArduinoCertified/IntelGalileo" target="_blank">Arduino</a> compatible board that uses a 400MHz 32 bit Intel® Quark <span class="wikiword">System on a Chip (SoC)</span> X1000 Processor. That makes it the fastest Arduino Board in the market while we wait for the <a href="http://arduino.cc/en/Main/ArduinoBoardTre" target="_blank">Arduino Tre</a> upcoming board.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMrxY3LgPmSRH5UrUjg6p9_YrsmtAN7eQmHM85vd-tPlTsPAKGuvBdUv6rfl-ccE3hAV2kMJMjBzTjOx89pkj61DL9w3BOexAufEoqhMA-yYxDvvnNbPLnQxQ3ncnKRWeGa47Xg0Wg8dab/s1600/Board3.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMrxY3LgPmSRH5UrUjg6p9_YrsmtAN7eQmHM85vd-tPlTsPAKGuvBdUv6rfl-ccE3hAV2kMJMjBzTjOx89pkj61DL9w3BOexAufEoqhMA-yYxDvvnNbPLnQxQ3ncnKRWeGa47Xg0Wg8dab/s1600/Board3.jpg" height="253" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Intel Galileo Board</td></tr>
</tbody></table>
<br />
The Galileo board includes a lot of functionality:<br />
<br />
<ul>
<li>Ethernet LAN RJ45 socket</li>
<li>RS-232 COM 3.5mm Jack</li>
<li>USB Client Socket</li>
<li>USB Host Socket</li>
<li>SD Slot</li>
<li>Mini PCIe connector for WLAN Card</li>
<li>One SPI port</li>
<li>One I2C port </li>
</ul>
And, of course, the full Arduino UNO headers with 14 Digital lines (6 with PWM functionality) and 6 analog lines. The full board specification can be found in this <a href="https://communities.intel.com/docs/DOC-21835" target="_blank">link</a>.<br />
<br />
<br />
The board can be programmed using a special <a href="https://communities.intel.com/docs/DOC-22226" target="_blank">Arduino IDE with version 1.5.3</a>. The IDE makes easy to program the board as any other Arduino board.<br />
<br />
That all sounds good , ok?<br />
Well not everything is so good in this board.<br />
<br />
<br />
<br />
<h3>
The Reality </h3>
The main problem about this board is in the GPIO implementation.<br />
Intel decided to use a <a href="http://www.cypress.com/?mpn=CY8C9520A-24PVXI" target="_blank">Cypress CY8C9540A</a> I/O expander to implement most of the I/O functionality. <br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmk7j0VyhgdPhsZ8RlHq9T0Y6d5ny3egzTvchMV3-6h1HTKsmfV-eCToOJ5tpPrp3QQDz1bAo7FesmnLzufb2pHrmBw-9sar3Pbo7u-qn0zejmkJrgy-y-Q-ie8JIQmnSJ2hC6oFgeEWVM/s1600/Expander2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmk7j0VyhgdPhsZ8RlHq9T0Y6d5ny3egzTvchMV3-6h1HTKsmfV-eCToOJ5tpPrp3QQDz1bAo7FesmnLzufb2pHrmBw-9sar3Pbo7u-qn0zejmkJrgy-y-Q-ie8JIQmnSJ2hC6oFgeEWVM/s1600/Expander2.jpg" height="207" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The Cypress CY8C9520A Expander Chip</td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
The selected I/O expander is quite powerful. It gives 40 GPIO lines and 8 of them can generate PWM. I suspect that Intel selected this chip in order to mimic the standard Arduino I/O functionality. The problem is the I2C link that communicates this I/O expander with the Quark CPU. It operates at a only 100kHz. That means that the in practical terms the maximum GPIO frequency is 230Hz for most of the I/O pins.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Two lines (IO2 and IO3) that are normally routed through the I/O expander can be alternatively routed directly to the SoC chip and thus can operate at a much higher frequency. But only those two pins can benefit from high speed operation.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The analog readings are provided by an external <a href="http://www.analog.com/en/analog-to-digital-converters/ad-converters/ad7298/products/product.html" target="_blank">AD7298</a> ADC but at least this device connects at 4MHz with the SoC chip using a SPI interface.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrSQ5m0UQaN60zkJqIs2sMYVGnzpBi840oD0JSD7OXvPx0RA8g0bO0A4trjeA0z4eN-Xrr0MbEYMX_ckmwAzYwKUL0uZurdASfKrjiEdsZv1ud8XXwKLqSySQZ2iOrZPiXAaPX8Xptomz7/s1600/ADC.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrSQ5m0UQaN60zkJqIs2sMYVGnzpBi840oD0JSD7OXvPx0RA8g0bO0A4trjeA0z4eN-Xrr0MbEYMX_ckmwAzYwKUL0uZurdASfKrjiEdsZv1ud8XXwKLqSySQZ2iOrZPiXAaPX8Xptomz7/s1600/ADC.jpg" height="177" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AD7298 ADC (to the right)</td></tr>
</tbody></table>
The catch is that most Arduino compatible I/O lines, analog included, are routed trough <a href="http://www.ti.com/product/ts5a23159" target="_blank">TS5A23159</a> multiplexers that are controlled by the outputs of the I/O expander controlled by the slow 100kHz I2C interface. So changing from digital to analog mode on a pin is quite slow.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The final problem is that the SoC chip don't run directly the Arduino sketches. The SoC runs under Linux and the running sketch is one process in the myriad of processes of the Linux operating system. As Linux is not real time you cannot guarantee a deterministic timing on the sketches. If the operating system happens to be under high load you can expect a lot of jitter on the sketches.</div>
<br />
All in all, the Galileo Board includes a power hungry (it cannot run on USB only) 400MHz Quark SoC but a lousy <span class="wikiword">ATmega328 at 16MHz on an Arduino UNO runs circles around it in raw GPIO bandwidth.</span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2eY6BOZjWRiNCUaQUr0CIeJTJe_tcjQi20UVLbhYlgSkfuo6uvfLRDmQkaXJMLIDLuAkyFNukJV4WXwMeb1vpJLA8PHQkbHQuA1e_V02HZZF_sl-h305kIJ7vp2wK9194zsjm1Cq9_Yae/s1600/ArduinoUno.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2eY6BOZjWRiNCUaQUr0CIeJTJe_tcjQi20UVLbhYlgSkfuo6uvfLRDmQkaXJMLIDLuAkyFNukJV4WXwMeb1vpJLA8PHQkbHQuA1e_V02HZZF_sl-h305kIJ7vp2wK9194zsjm1Cq9_Yae/s1600/ArduinoUno.jpg" height="210" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arduino UNO</td></tr>
</tbody></table>
<br />
<h3>
So, what will I make?</h3>
<div style="text-align: justify;">
In the end the Galileo Board delivers less than I expected due to the small I/O bandwidth that the 100kHz I2C port expander provides. The Linux operating system also don't help to obtain a deterministic reaction time. As a conclusion the Galileo Board is not a good board for fast real time operation. Better use a normal Arduino board or, better yet, a STM32 Discovery board for fast I/O operation.<br />
<br />
<h4>
Following the Arduino path</h4>
If you want, however, an Arduino compatible board that includes support for Ethernet, SD card storage and a real time clock and provides a lot of RAM and ROM memory, this is a very capable board if you don't mind the the slow GPIO bandwidth.<br />
<br />
I use the <a href="http://arduino.cc/en/Main/ArduinoBoardLeonardo" target="_blank">Arduino Leonardo</a> board in a mixed analog-digital lab course for students without the proper programming foundations to use a more capable board.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge4fkdSxqL_0PQh__maqfDDyELnCp4ptpAymnuRYeuG3eKG-2RRokvUpkEtmFEci6nIT0HQt2E_LapPAWUZQwQo_pqkhFePcajU-6Fq1MEgc1wrSrBhKFlCymvoEN8OveeRBVtsRf2Hgxt/s1600/Leonardo.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEge4fkdSxqL_0PQh__maqfDDyELnCp4ptpAymnuRYeuG3eKG-2RRokvUpkEtmFEci6nIT0HQt2E_LapPAWUZQwQo_pqkhFePcajU-6Fq1MEgc1wrSrBhKFlCymvoEN8OveeRBVtsRf2Hgxt/s1600/Leonardo.jpg" height="253" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Arduino Leonardo Board</td></tr>
</tbody></table>
For applications that need more memory and speed I use the PIC32 Pinguino board. For the price of a Leonardo you get a board that features much more memory and speed and includes several goodies as a SD card slot and a 32kHz clock. I don't use this board as the main one because the Leonardo is better supported by the Arduino community.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0F2yvED8HjVx8bDdJppgR_g1wdX6MhqiuSsE8QHmUXnfQdzl_EW8KH0ZzqjjqnVneKhunUWu3PYUenj9EFBqPxGRXNt-P1mDi3Drrm074rcbY7bWN0kLO-_fkqB9Icw-L4eR847cFXD7x/s1600/PIC32-PINGUINO.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0F2yvED8HjVx8bDdJppgR_g1wdX6MhqiuSsE8QHmUXnfQdzl_EW8KH0ZzqjjqnVneKhunUWu3PYUenj9EFBqPxGRXNt-P1mDi3Drrm074rcbY7bWN0kLO-_fkqB9Icw-L4eR847cFXD7x/s1600/PIC32-PINGUINO.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PIC32 Pinguino Board</td></tr>
</tbody></table>
Now I have also the Galileo. I plan to use the Galileo in Arduino projects that need a lot of memory or network connectivity and don't need fast GPIO operation.<br />
<br />
<h4>
Following the Linux path</h4>
</div>
<div style="text-align: justify;">
I am more interested, however, in the Galileo as a Linux board, not as an Arduino one. For some kind of projects I'm interested in controlling the board from Linux eliminating any Arduino IDE operation. That puts this board next to the <a href="http://www.raspberrypi.org/" target="_blank">Raspberry Pi</a> and the <a href="http://beagleboard.org/Products/BeagleBone" target="_blank">BeagleBone</a> / <a href="http://beagleboard.org/Products/BeagleBone+Black" target="_blank">BeagleBone Black</a> boards. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKOlnHbuQOLaumlIs1rEB-Vsb2ckxesER2Uu_jNzcVwX8C_wr5O6XariArh3QPW9pj-Ewv7JvEgf9lZEFJYtKqdjv3GZz9Yf-8w5BECgW1fXYG-LY4ytlkHMzG8HoX_hiFZ6KH-lderF5X/s1600/BeagleBone.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKOlnHbuQOLaumlIs1rEB-Vsb2ckxesER2Uu_jNzcVwX8C_wr5O6XariArh3QPW9pj-Ewv7JvEgf9lZEFJYtKqdjv3GZz9Yf-8w5BECgW1fXYG-LY4ytlkHMzG8HoX_hiFZ6KH-lderF5X/s1600/BeagleBone.jpg" height="188" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">BeagleBone Board</td></tr>
</tbody></table>
<br />
<br />
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1CaM4bgEcIg_bOVRHlo8AcDYrxm3MrJniPu6bnqiEmD9zf6QFZgWx7lITl8PCnhJxi9QNpqxb6bPF9S9yL93Wprd7M0gkImjBJc6lUFnNppt3Xlwru8lHXZB9mHMWQQCxoVwb1W4lUQts/s1600/RaspberryPi.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1CaM4bgEcIg_bOVRHlo8AcDYrxm3MrJniPu6bnqiEmD9zf6QFZgWx7lITl8PCnhJxi9QNpqxb6bPF9S9yL93Wprd7M0gkImjBJc6lUFnNppt3Xlwru8lHXZB9mHMWQQCxoVwb1W4lUQts/s1600/RaspberryPi.jpg" height="218" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Raspberry Pi Model B</td></tr>
</tbody></table>
<div style="text-align: justify;">
Both of the Raspberry Pi and BeagleBone boards are faster. Also both the Raspberry Pi and the BeagleBone Black provide a video output that the Galileo lacks. So the Galileo will only be useful for embedded operation not as a desktop computer substitute.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Compared with the Raspberry Pi the Galileo has some strong points:</div>
<br />
<ul>
<li>One USB client that can work as a serial over USB terminal</li>
<li>14 Digital lines and 6 Analog lines with both 3.3V and 5V functionality</li>
<li>A RS-232 level Serial</li>
<li>A battery backed RTC clock </li>
<li>Arduino Shield Compatibility </li>
<li>Four mounting holes that make it easier to use without a case. </li>
</ul>
Off course the Raspberry Pi has also some strong points:<br />
<br />
<ul>
<li>Faster operation</li>
<li>Much more capable Linux distribution</li>
<li>Video and audio output</li>
<li>Camera and LCD connectors</li>
<li>Cheaper price</li>
</ul>
<div style="text-align: justify;">
It's a pity that the Raspberry Pi don't provide a USB client to enable a serial over USB console. For headless operation that could be very handy. The lack of proper mounting holes is also a problem.</div>
<div style="text-align: justify;">
For desktop Linux use nothing beats the Raspberry Pi in its price range but it shows that embedded operation was not a priority in its design.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For embedded Linux operation the BeagleBone is my first option. Both the BeagleBone and the Galileo feature digital and analog I/O although the BeagleBone with its GPMC bus features several orders of magnitude higher bandwidth. Both boards feature Ethernet and a serial over USB console. Both boards feature also a USB host socket. In general, however, the BeagleBone is more powerful. It uses a better Linux distribution, has higher clock frequency, consumes less power, and has more I/O lines and bandwidth. The only thing that the Galileo has and the BeagleBone lacks is the battery backed real time clock and Arduino Shield compatibility.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
I plan to use the Galileo boards for Linux projects that don't need all the BeagleBone power. As this board includes in the SD card image a Python interpreter and no C compiler I will start using it in Python. </div>
<div style="text-align: justify;">
<br /></div>
<h3>
Closing Comments</h3>
That's all for now. In the end the Galileo is a quite capable Linux board but it could have been much better if the designers had opted for a higher bandwidth I/O solution. That's a pity because that positions this board in a very bad place against the BeagleBone Black. It's only strong point is the Arduino shield compatibility but I don't really care about that.<br />
<br />
I know that it is difficult for Inter to fight against ARM but those kinds of design decisions don't help at all. <br />
Off course I will use for teaching projects the ten Galileo boards I have been given but I'm not sure I would opt for these boards if I needed to buy them myself.<br />
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-17626262091894944742014-05-01T11:37:00.000+02:002014-05-01T12:03:14.269+02:00Testing the AD5697R DAC<div style="text-align: justify;">
Yesterday I tested an interesting DAC: the <a href="http://www.analog.com/en/digital-to-analog-converters/da-converters/ad5697r/products/product.html" target="_blank">AD5697R</a>. This an interesting 12 bit dual channel Digital to Analog Converter (DAC). I plan to use it on a project where it will susbstitute some operational fixed voltages. </div>
<div style="text-align: justify;">
Using a DAC instead of a potentiometers make those voltages adjustables by the microcontroller that manages all the system. Moreover, as the DAC features an internal reference the voltage values are independent on power supply variations. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Unfortunately, as is more and more habitual this days the DAC only comes in SMD packages and they are not board friendly at all. This 16 pin device comes in the 3mm x 3mm Lead Frame Chip Scale Package (LFCSP) package and in the 5mm x 4.4mm Thin Shrink Small Outline Package
(TSSOP) package. That's tinny!</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Adpating the chip to protoboard use</h3>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
I selected the 16 TSSOP package as it's easier to solder although it features a 0.65 pin pitch that is about 1/4of the standard 2.50 (100 mil) DIP pitch. To test it on a protoboard I used an SMD adapter. The following figure shows the adapter I used before soldering the chip. The image also serves to show the pitch difference between TSSOP and 100 mil DIP. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0zDNz2OhIaXIImEyXB5lw5a5HMfhb8-oReRAXheWILj3SdOWFJrZyYLfoVmsC3crwrjaUOfilQdQTqftq0QGdXYQSv9Zv1WGcmV5CCqyw96lhv3Xus5QmtHjcct1MhRawCLRO0AhsBYzK/s1600/Adaptador+Vacio.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0zDNz2OhIaXIImEyXB5lw5a5HMfhb8-oReRAXheWILj3SdOWFJrZyYLfoVmsC3crwrjaUOfilQdQTqftq0QGdXYQSv9Zv1WGcmV5CCqyw96lhv3Xus5QmtHjcct1MhRawCLRO0AhsBYzK/s1600/Adaptador+Vacio.jpg" height="198" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">TSSOP16 Adapter</td></tr>
</tbody></table>
<div style="text-align: justify;">
As is normally the case, the adapter costs more than the DAC chip itself. </div>
<div style="text-align: justify;">
This adapter, however, has one problem: It uses dual rows of pins at either side of the chip. That's bad for a protoboard as you will short odd and even pins.</div>
<div style="text-align: justify;">
The solution was to extend the adapter after I soldered the chip:</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL-vx7kAKh80u7PtzD9P6wosfUf7jjeI6rZ106GlVOz5xmXXi-1SHYq9pu_c6VCK6SDa5wzvyd4A_OyDGs0KPp6J3_Api-4TZ_Ymzs6dfnAkoZ4XH-w53QsNd9MFIQKssxyWVCoqjtiyUm/s1600/Adaptador.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL-vx7kAKh80u7PtzD9P6wosfUf7jjeI6rZ106GlVOz5xmXXi-1SHYq9pu_c6VCK6SDa5wzvyd4A_OyDGs0KPp6J3_Api-4TZ_Ymzs6dfnAkoZ4XH-w53QsNd9MFIQKssxyWVCoqjtiyUm/s1600/Adaptador.jpg" height="209" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adapter extension</td><td class="tr-caption" style="text-align: center;"><br /></td></tr>
</tbody></table>
<br />
<div style="text-align: justify;">
</div>
<br />
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Using the extension half of the 100mil pitch pins are soldered to the original adapter and the other half to the extension. </div>
<br />
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<h3 style="text-align: justify;">
Test circuit</h3>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
So far so good. Time to test the chip.</div>
<div style="text-align: justify;">
In order to test the chip I used the <a href="http://r6500.blogspot.com.es/2014/04/presenting-f3-gizmo.html" target="_blank">F3 Gizmo</a> to send the I2C commands the chip needs to operate. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFZQoEr0I7eZJLGCtvqbyy5GQmzrw0rVeoRs1g9D7iW4hbmURKFy3HCCaO9ksOE1ULxmuwaNcFZgfZ9WfY83vi6TxdBQj4Lww9zinIzah_hoEaPPBPmlLM5ma_sa0BJ8QpVyT__-Pb5zgc/s1600/Esquema.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFZQoEr0I7eZJLGCtvqbyy5GQmzrw0rVeoRs1g9D7iW4hbmURKFy3HCCaO9ksOE1ULxmuwaNcFZgfZ9WfY83vi6TxdBQj4Lww9zinIzah_hoEaPPBPmlLM5ma_sa0BJ8QpVyT__-Pb5zgc/s1600/Esquema.png" height="250" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Test circuit for the DAC</td></tr>
</tbody></table>
<div style="text-align: justify;">
The circuit only needs four main wires: 3V supply, ground and the I2C SDA and SCL lines. A0 and A1 are connected to ground although this is not shown in the above schematic.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF6QrAAoZl77AAvAaeSfnkVIYbbXt_yprcWw7SqmNyTmn5vY4arniZSi1yS-wVD-kjoSl06PKki04ga5-eoszuUeBesiUg-iCBnjFHJTuSNCpjJEZKfNt3Q3wFXYvBST2AOJiAgC_uMBOO/s1600/Conexiones.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiF6QrAAoZl77AAvAaeSfnkVIYbbXt_yprcWw7SqmNyTmn5vY4arniZSi1yS-wVD-kjoSl06PKki04ga5-eoszuUeBesiUg-iCBnjFHJTuSNCpjJEZKfNt3Q3wFXYvBST2AOJiAgC_uMBOO/s1600/Conexiones.jpg" height="247" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Test circuit on the protoboard</td></tr>
</tbody></table>
<div style="text-align: justify;">
</div>
<h3 style="text-align: justify;">
Test of the DAC</h3>
<div style="text-align: justify;">
Once the test circuit is mounted it's time to test the DAC by sending some I2C commands.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The 7 bit I2C address for the DAC is</div>
<div style="text-align: justify;">
<br />
<b>0 0 0</b><span style="color: red;"> |</span> <b>1 1 A1 A0</b><br />
<br />
As A1=A0=0 the address will be:<br />
<br />
000 1100 = 0xC</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Using the F3 Gizmo ISCAN word whe can check that the I2C channel is operational:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;"> ISCAN</span></span></div>
<div style="text-align: justify;">
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;"> 0xC</span></span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To send data to the DAC we must send 3 Bytes to it's I2C address.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first Byte indicates the command and the channel.</div>
<div style="text-align: justify;">
The 4 MSBs are the command. The command I tried is:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: center;">
<span style="color: #660000;">0011 (3h) Write to and update DAC channel n</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This command directly writes a binnary data to one or both DAC channels.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The 4 LSBs of the first Byte selects the channel to adress:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #660000;"> 0001 (1h) DAC A<br /> 1000 (8h) DAC B<br /> 1001 (9h) DAC A and DAC B</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The two following Bytes to send are the data to send to the DAC. As two bytes are 16 bits and the DAC channels are 12 bits only, the last 4 LSBs bits are discarded.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The DAC uses an internal 2.5V bandgap reference. The full scale (FFFh code) should be 1 LSB below the reference for the selected GAIN=1. If the GAIN pin was at VDD the selected GAIN would be 2 and the full scale value would be one LSB below 5V.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In order to set the A channel to the maximum value we can must send the following data:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Command: 3h</div>
<div style="text-align: justify;">
DAC addressed: 1h</div>
<div style="text-align: justify;">
Code to send: FFFh<br />
Last dummy nibble: 0h </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
We can use the following F3 Gizmo command in order to send the data:</div>
<div style="text-align: justify;">
<br />
<span style="color: #38761d;"> 0xC 0x31 0xFF 0xF0 3 0 I2CT</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As a result the output goes to 2.5V as expected.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
To set any other value we must compute the 12 bit value. For instance, to set the output to 1V we must use the code:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b> code =4096 * 1 / 2.5 = 1638 = 666h</b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Using the F3 Gizmo that means sending the following command:</div>
<div style="text-align: justify;">
<b> </b></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<span style="color: #38761d;"> 0xC 0x31 0x66 0x60 3 0 I2CT</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As you can see from the multimeter reading the response is quite good. </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8fRsU8VvcYMSaQpfBqH-OFFtzPUyr9cCwkCel4dZGlnxGuuXIKCC45gROvJUZY5IMZnfTyk5Xf9iVA_krMVptm-btSWK3fBGYcewrOVXfVlzH4bwerCa-M6lv7U-4rK9hRtWvlGl6OnCr/s1600/Lectura+1V.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8fRsU8VvcYMSaQpfBqH-OFFtzPUyr9cCwkCel4dZGlnxGuuXIKCC45gROvJUZY5IMZnfTyk5Xf9iVA_krMVptm-btSWK3fBGYcewrOVXfVlzH4bwerCa-M6lv7U-4rK9hRtWvlGl6OnCr/s1600/Lectura+1V.jpg" height="202" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Measuring the response to code 0x666</td></tr>
</tbody></table>
<div style="text-align: justify;">
Having the DAC an internal reference makes very easy to generate exact absolute output values. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The test was a success. Now I can test the rest of the I2C functionality before deploying the DAC in the project.</div>
<div style="text-align: justify;">
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-21420263368707485512014-04-27T18:34:00.000+02:002014-05-13T13:34:39.848+02:00Bare bones CForth<div style="text-align: justify;">
The <a href="http://r6500.blogspot.com.es/2014/04/presenting-f3-gizmo.html" target="_blank">F3 Gizmo</a> includes a Forth line engine that I call <b>CForth</b>. Its name is related to the fact that is a Forth like engine developed in <b>C</b>. CForth is machine independent. That way I could develop the engine without needing to use the ARM cross compiler nor needing to flash the STM32 F3 Discovery board.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The bare bones CForth is a simple CForth port that can be compiled in most 32 bit systems that provide a GCC compiler and the basic I/O LIBC functions. Currently I have tested it under MinGW on Windows XP and 7 and under Linux Ubuntu.</div>
<div style="text-align: justify;">
It should also compile in 64 bit operating systems but you could run into problems using CForth pointer operations. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As current win command windows don't support the ANSI escape sequences, I use <a href="https://github.com/adoxa/ansicon/releases" target="_blank">Ansicon</a> to create the console that runs CForth.</div>
<br />
<h3>
MinGW executable</h3>
<br />
<div style="text-align: justify;">
The link below points to the executable MinGW CForth port. Just run the contained <b>cforth.exe</b> file.</div>
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVQnR4UDlJeF9NOTg/edit?usp=sharing" target="_blank">MinGW cforth executable v1.0(2014-04-27).zip</a><br />
<br />
Upon start you should get into the CForth console:<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzSI7CuFKSrTcuxrlftxBuBm-Vnf6mo9gquIpa0exp18-8NwXokwap67uQ284B38zAdgYQ78JDS1Xpol59HKqTnzw2_YMLV6NeEumxmae5tnN2t1sD1XkrsZzeL0xrqxSMYcNI3PTzguto/s1600/Console.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzSI7CuFKSrTcuxrlftxBuBm-Vnf6mo9gquIpa0exp18-8NwXokwap67uQ284B38zAdgYQ78JDS1Xpol59HKqTnzw2_YMLV6NeEumxmae5tnN2t1sD1XkrsZzeL0xrqxSMYcNI3PTzguto/s1600/Console.png" height="258" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">CForth start on Ansicon</td></tr>
</tbody></table>
The CForth manual can be obtained from the reference below:<br />
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVM24xc2NkeFMwa3c/edit?usp=sharing" target="_blank">CForth Manual v1.0 (2014-04-20).pdf</a><br />
<br />
<br />
<br />
<h3>
CForth Sources</h3>
<div style="text-align: justify;">
If you want to run CForth in other system different from windows you would need to compile from its sources. The link below points to the bare bones CForth sources:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="https://drive.google.com/folderview?id=0B0PzZrEvAdjVUU9SdC1GbWVuZU0&usp=sharing" target="_blank">MinGW CForth Sources v1.0(2014-04-27).zip</a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can also use the sources to expand the CForth built-in word dictionary using your own C functions. </div>
<div style="text-align: justify;">
CForth is different from normal Forth implementatios because all its built-in words are created in C, not in Forth. </div>
<div style="text-align: justify;">
The information about how can it be done is on the included <b>_CForth API.txt</b> file.</div>
<br />
<br />
<h3>
CForth Limitations</h3>
<div style="text-align: justify;">
CForth was never developed to run on a PC. It tragets medium size microcontrollers. The PC bare bones port was develop to ease the CFoth engine development as it doesn't neeed to access a real microcontroller. That's the reason why you don't get any file operation words. The only file operations that this port implements are the ones needed to create and read the <b>userDict.bin</b> file that is used to implement the <b>SAVE </b>and <b>LOAD </b>words.</div>
<div style="text-align: justify;">
<br />
<h3>
13/5/2014 Update</h3>
The project is nowat Github:<br />
<br />
<a href="https://github.com/R6500/MinGW_CForth">https://github.com/R6500/MinGW_CForth</a><span id="goog_1849991014"></span><a href="https://www.blogger.com/"></a><span id="goog_1849991015"></span><br />
<br /></div>
Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0tag:blogger.com,1999:blog-6880821591370697484.post-89018244929668065152014-04-26T00:41:00.000+02:002014-05-13T12:56:36.313+02:00Presenting the F3 Gizmo<div style="text-align: justify;">
Today I present the F3 Gizmo. A firmware solution for the <a href="http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF254044" target="_blank">STM32F3 Discovery board</a>.</div>
<div style="text-align: justify;">
<br />
<h3>
Motivation</h3>
</div>
<div style="text-align: justify;">
The STM32F3 Discovery board is a fantastic board full of features that ST sells at a very low cost. In includes a <a href="http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1576/LN1531/PF252054" target="_blank">STM32F303</a> ARM Cortex M4 32bit microcontroller running at 72 MHz, 8 LEDs, one Gyroscope and one combined Accelerometer/Magnetometer. The microcontroller itself includes several communication ports: Serial, SPI, I2C, CAN, USB... as well as a lot of other peripherals like GPIOs, timers, Operational Amplifiers and Comparators.</div>
<div style="text-align: justify;">
The problem is that it is not easy to program. At least not as easy as an Arduino for instance.</div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqzXp2AwIz9_TCrjsPXhtm3DEMLZ_gFCGh-CxGEoxppkGvXZWRJTt-W61SbjYknyeuTs2t3P4uDupeNiIKSnX50GV3aJzN7n5dMuIgRDbYnO5v_qa4RkaCvKEYT5pgK7S_JI5zPj0j1jNI/s1600/stm32f3discovery.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqzXp2AwIz9_TCrjsPXhtm3DEMLZ_gFCGh-CxGEoxppkGvXZWRJTt-W61SbjYknyeuTs2t3P4uDupeNiIKSnX50GV3aJzN7n5dMuIgRDbYnO5v_qa4RkaCvKEYT5pgK7S_JI5zPj0j1jNI/s1600/stm32f3discovery.jpg" height="320" width="210" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">STM32F3 Discovery Board</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are software solutions that ease the use of this board. One case is the <a href="http://www.chibios.org/dokuwiki/doku.php" target="_blank">ChibiOS/RT</a> Real Time Operating System (RTOS) that provides all the board initialization code, a Hardware Abstraction Layer (HAL) and and a mutithreaded operating system.<br />
There are other solutions aside from ChibiOS/RT but this is the one I use. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Building a software solution for the STM32F3 Discovery board using ChiBiOS/RT as its foundation is much easier that trying to build from scratch or from the verbose libraries that ST provides but it is still complex. Not only that, but you have to piece together a development environment with compiler, editor, debugger, and so on although <a href="http://sourceforge.net/projects/chibios/files/ChibiStudio/" target="_blank">ChibiStudio </a>eases this process.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Sometimes you have an idea to test quick and dirty and you don't need a fully featured development environment. Or you have a new SPI or I2C chip to check. In those cases you need to develop a small test program, compile it, flash it on the microcontroller and run it.<br />
<br />
<br />
<h3>
What is the F3 Gizmo </h3>
</div>
<div style="text-align: justify;">
The F3 Gizmo tries to ease quick tests of ideas by providing a <a href="http://en.wikipedia.org/wiki/Forth_%28programming_language%29" target="_blank">Forth</a> like development environment in the STM32F3 board.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You only need to burn the F3 Gizmo firmware on a STM32F3 Discovery board, connect it to a PC using one USB cable and stablish a serial over USB connection using an emulator terminal . </div>
<div style="text-align: justify;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNjI0H8n_OANq5gefDMvVNhn8KAG7XPh66zGIgP9iZsGKm6-5yIYSCrl2q7kfgbszRucD82QP-W45tR_c2SiPh7rpV7wnF1cyti5kMA-Fo7RMscWTAisp7lnKR4rwHJQ__QmqctylBn9tL/s1600/Terminal+01.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNjI0H8n_OANq5gefDMvVNhn8KAG7XPh66zGIgP9iZsGKm6-5yIYSCrl2q7kfgbszRucD82QP-W45tR_c2SiPh7rpV7wnF1cyti5kMA-Fo7RMscWTAisp7lnKR4rwHJQ__QmqctylBn9tL/s1600/Terminal+01.png" height="260" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">F3 Gizmo Console</td></tr>
</tbody></table>
<div style="text-align: justify;">
In the above figure we see the start of the F3 Gizmo as shown in the <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/" target="_blank">PuTTY</a> terminal emulator. </div>
<div style="text-align: justify;">
Just writing <span style="color: #38761d;"><span style="font-family: "Courier New",Courier,monospace;"><b>0 LedSet</b></span></span> in the console one LED (Number 0) in the board is lit. </div>
<div style="text-align: justify;">
Just writing <span style="color: #38761d;"><span style="font-family: "Courier New",Courier,monospace;"><b>AccelRead</b></span></span> we get the X, Y and Z readings on the acceleromenter.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Do you want to blink the led? Write:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<span style="color: #38761d;"><span style="font-family: "Courier New",Courier,monospace;"><b>: blink begin 0 ls 300 ms 0 lc 300 ms again ;<br />blink</b></span></span></div>
<div style="text-align: justify;">
<br />
The new <span style="color: #38761d;"><span style="font-family: "Courier New",Courier,monospace;"><b>blink </b></span></span>user word definition can be used just like the built-in <span style="font-family: "Courier New",Courier,monospace;"><span style="color: #38761d;"><b>LedSet</b></span></span> word and it can be used in any new user word definition making the system perfect for incremental development.<br />
<br /></div>
<div style="text-align: justify;">
What to check the addresses of an I2C device? </div>
<div style="text-align: justify;">
Connect it and call <b><span style="color: #38761d;">ISCAN</span> </b></div>
<div style="text-align: justify;">
<br />
Do you want to access the internal microcontroller registers?<br />
You also can:<br />
<br />
<span style="color: #38761d;"><span style="font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">0x48001000 CONSTANT gpioe \Start of GPIOE <br />0x14 CONSTANT odr \Offset of ODR register <br />gpioe odr + \ODR register of port E <br />DUP @ \Get current ODR value <br />1 9 LSHIFT OR \OR with bit 9 <br />SWAP ! \Store new ODR</span></span></span><br />
<br /></div>
<div style="text-align: justify;">
It is fast and it is interactive. You don't need anything on the host PC aside from the terminal emulator.<br />
And it's Forth like.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
And all operates in RAM. You can create new <b>words </b>(something like functions), erase them, rewrite them and you don't need to touch the flash memory of the microcontroller.</div>
<div style="text-align: justify;">
If any time you want to store the current RAM status you can use save it on the flash to recover it on the next reboot.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
If you want to test a system that don't use the console, you can set a function to start when the board boots, save the RAM in flash and make it work standalone.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The F3 Gizmo don't pretend to be the next great development environment. It just tries to be a quick and easy access to the STM32F3 Board features.</div>
<div style="text-align: justify;">
<br />
<h3>
Features</h3>
</div>
<div style="text-align: justify;">
The F3 Gizmo makes a fixed assignment of several board pins. The following figure shows each allocated pin.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Qsme0Rwb0wh4AA6F4viX5H8vMA6Vt6uwCjLlF9lqG60Cn8TAD-fDyIcqKY0cXscG3ebXh0tI2XMdbb3FYNJo6rKyGs9fqIy30Oozo6FOpMZTpB_2WbPNE8-HgeXMbN2FAP3BXMbKjP8_/s1600/F3+Gizmo+Pins.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-Qsme0Rwb0wh4AA6F4viX5H8vMA6Vt6uwCjLlF9lqG60Cn8TAD-fDyIcqKY0cXscG3ebXh0tI2XMdbb3FYNJo6rKyGs9fqIy30Oozo6FOpMZTpB_2WbPNE8-HgeXMbN2FAP3BXMbKjP8_/s1600/F3+Gizmo+Pins.png" height="400" width="351" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">F3 Gizmo Pins </td></tr>
</tbody></table>
Currently the F3 Gizmo manages the following Board /MCU elements:<br />
<ul>
<li>8 User LEDs</li>
<li>10 Digital I/O pins</li>
<li>3 PWM digital outputs</li>
<li>6 Analog input channels</li>
<li>1 Analog DAC output channel </li>
<li>2 General use Timers</li>
<li>1 SPI Bus</li>
<li>1 I2C Bus</li>
<li>1 Giroscope</li>
<li>1 Combined Accelerometer/Magnetometer</li>
</ul>
It also provides some features provided by the underlying ChibiOS/RT operating system:<br />
<ul>
<li>Mutithreaded execution</li>
<li>Binary Semaphores</li>
<li>Mutexes</li>
</ul>
In the future I plan to include at least:<br />
<ul>
<li>Two asyncronous serial lines </li>
<li>2 Operational Amplifiers</li>
<li>2 Comparators</li>
<li>1 CAN bus</li>
</ul>
<br />
<ul>
</ul>
<h3>
Components</h3>
The F3 Gizmo is composed by three elements:<br />
<ul>
<li>ChibiOS/RT : Provides the Board and MCU Start routines, the HAL for several of the microcontroller peripherals and all OS services.</li>
<li>CForth engine: Provides the basic machine independent programing and interpreter language.</li>
<li>F3 Gizmo port for the CForth engine. Provides the link between CForth and all MCU or board specific features. It also includes the low level code for the features that don't use the ChibiOS/RT HAL.</li>
</ul>
<br />
<h3>
Installing the F3 Gizmo </h3>
To install the F3 Gizmo you just need its firmare file that is available in bin and hex formats and the <a href="http://www.st.com/web/en/catalog/tools/PF258168" target="_blank">STLink</a> utility that ST provides.<br />
You only need the <b>bin </b>file. The <b>hex </b>is not necesary for the STLink utility.<br />
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVV1M4QTFvM0Q0aVE/edit?usp=sharing" target="_blank">F3Gizmo_V1.0(2014-04-25).bin</a><br />
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVcHpWOXJvYkxieGM/edit?usp=sharing" target="_blank">F3Gizmo_V1.0(2014-04-25).hex.zip</a><br />
<br />
Of course you can also build it from its sources but you'll need an ARM toolchain:<br />
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVQk5kUHJrRnpTY00/edit?usp=sharing" target="_blank">F3Gizmo_V1.0(2014-04-25) Source.zip</a><br />
<br />
<br />
<h3>
Manuals </h3>
To learn how to use the F3 Gizmo you have two manuals:<br />
<br />
<div style="text-align: justify;">
The F3 Gizmo Manual explains how to install the firmware and use all STM32F3 Discovery Board Functionalities.</div>
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVYVVCMHc4WndUTzg/edit?usp=sharing" target="_blank">F3 Gizmo Manual v1.0 (2014-04-25).pdf</a><br />
<br />
As the F3 Gizmo implements a Forth like language called CForth, you will also need the CForth manual as the F3 Gizmo manual don't explain the operations of the CForth engine.<br />
<br />
<a href="https://drive.google.com/file/d/0B0PzZrEvAdjVM24xc2NkeFMwa3c/edit?usp=sharing" target="_blank">CForth Manual v1.0 (2014-04-20).pdf</a><br />
<br />
That's all for now. Just try it if you like.<br />
In the future I will post more entries about the F3 Gizmo use.<br />
<br />
<br />
<h3>
13/5/2014 Update</h3>
The project is now on Github:<br />
<br />
<a href="https://github.com/R6500/STM32F3_Gizmo">https://github.com/R6500/STM32F3_Gizmo</a><br />
<br />
<br />Vicente Jiménezhttp://www.blogger.com/profile/12517267788005036790noreply@blogger.com0