tag:blogger.com,1999:blog-5822192345925131242024-03-06T14:59:35.951-05:00Electronics projects and tutorialsThis blog is maintained by Frederick Blais, a recent Electrical Engineering graduate. My goal is to write several tutorials on electronics and programming aimed at beginner to intermediate hobbyists. I also show off some projects I'm working on.Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.comBlogger27125tag:blogger.com,1999:blog-582219234592513124.post-1239183747589611922015-01-13T09:19:00.000-05:002015-01-13T09:19:23.644-05:00Pebble communication with FlaskI travel often for work so I have to spend some time in airports all around Canada. Recently, I came across a Best Buy Express machine while waiting for my plane and decided to finally <a href="https://www.youtube.com/watch?v=qg35XPQDQ8M&feature=youtu.be">buy a Pebble</a> :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFMBFP35gw372Zt7K_X7X3EWg-3Kr-GuC7jOeGYOXAx9PKw1H4P1lr6wzbDjPcTrWvfi6oPVDUaw4EylWFoeMrsERlwa6NviBISwePLMQ2S7c0Lp8kObD9BDl8Mui6cPE3lZGr53csHNym/s1600/BestBuy200Left.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFMBFP35gw372Zt7K_X7X3EWg-3Kr-GuC7jOeGYOXAx9PKw1H4P1lr6wzbDjPcTrWvfi6oPVDUaw4EylWFoeMrsERlwa6NviBISwePLMQ2S7c0Lp8kObD9BDl8Mui6cPE3lZGr53csHNym/s1600/BestBuy200Left.png" height="200" width="195" /></a></div>
<br />
The Pebble is a nice watch for its price (100$) and what I really like about it is the <a href="https://cloudpebble.net/ide/">CloudPebble</a>, an online development environment. The documentation is great and there is some <a href="http://developer.getpebble.com/getting-started/">nice tutorials to get started</a>.<br />
<br />
I wanted to make a quick project to learn a little bit about apps development. What I done is simple app that send an HTTP POST request to turn on/off an LED on my <a href="https://www.sparkfun.com/products/13097">Intel Edison Arduino Breakout Board</a>. There is two ways you can code for the Pebble on CloudPebble, you can use C or Javascript (with Pebble.js). The C way offers more flexibility at the expense of bigger code. The Javascript way is really simple, the API is a bit more limited but you can create great apps in less time. You also have easily access to the "ajax" function, which is the killer feature in my humble opinion.<br />
<br />
The next 2 pictures show how simple the app is. This one is a picture of the app launcher in the Pebble menu :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwrKhCVKwqLIZ9UppAtKHEL6oITnpfSzu9LO_McRCIUL3EcFCTT9vTLmv347UqZenEY-F63vhLoUfPLmE15TUwrINwtfWjPd5kTJ7WO8t4mjBYNcpAdbZHj4neo2RoYWALKROi9F-zdZvF/s1600/settings.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwrKhCVKwqLIZ9UppAtKHEL6oITnpfSzu9LO_McRCIUL3EcFCTT9vTLmv347UqZenEY-F63vhLoUfPLmE15TUwrINwtfWjPd5kTJ7WO8t4mjBYNcpAdbZHj4neo2RoYWALKROi9F-zdZvF/s1600/settings.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
And this is the actual app, it cannot be more simple than that :</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip0-w1NTFQ_v8dgo3MramxEex4se6zkzKjE6wiVjX6rptOU_5lqHALzb5f8-SSHvQhYlQtUfkoy5n3z3o3fgVjPnUpn2TqipcIHf8xHnDuUjnHXvTvyBHBhO13UBXYzeWRNTznJKZkNvgf/s1600/menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip0-w1NTFQ_v8dgo3MramxEex4se6zkzKjE6wiVjX6rptOU_5lqHALzb5f8-SSHvQhYlQtUfkoy5n3z3o3fgVjPnUpn2TqipcIHf8xHnDuUjnHXvTvyBHBhO13UBXYzeWRNTznJKZkNvgf/s1600/menu.png" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The structure of the programming is the following :</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ol>
<li>Create a menu that displays 2 item (LED ON/ LED OFF)</li>
<li>Generate an event when the user "select" the menu item</li>
<li>When the event is generated, send a POST request to the embedded Linux board running Flask </li>
</ol>
<br />
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="color: #fb660a; font-weight: bold;">var</span> <span style="color: white;">UI</span> <span style="color: white;">=</span> <span style="color: white;">require(</span><span style="color: #0086d2;">'ui'</span><span style="color: white;">);</span>
<span style="color: #fb660a; font-weight: bold;">var</span> <span style="color: white;">ajax</span> <span style="color: white;">=</span> <span style="color: white;">require(</span><span style="color: #0086d2;">'ajax'</span><span style="color: white;">);</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// Connect to Edison and send POST data (state=ON | state=OFF)</span>
<span style="color: #fb660a; font-weight: bold;">function</span> <span style="color: white;">request(state)</span> <span style="color: white;">{</span>
<span style="color: white;">ajax(</span>
<span style="color: white;">{</span>
<span style="color: white;">url:</span> <span style="color: #0086d2;">'http://192.168.0.80:5000'</span><span style="color: white;">,</span>
<span style="color: white;">method:</span> <span style="color: #0086d2;">'post'</span><span style="color: white;">,</span>
<span style="color: white;">data:</span> <span style="color: white;">{state:state}</span>
<span style="color: white;">},</span>
<span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">(data)</span> <span style="color: white;">{</span>
<span style="color: white;">console.log(data);</span>
<span style="color: white;">},</span>
<span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">(error)</span> <span style="color: white;">{</span>
<span style="color: white;">console.log(</span><span style="color: #0086d2;">'The ajax request failed: '</span> <span style="color: white;">+</span> <span style="color: white;">error);</span>
<span style="color: white;">}</span>
<span style="color: white;">);</span>
<span style="color: white;">}</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// Make a list of menu items (ON/OFF)</span>
<span style="color: #fb660a; font-weight: bold;">var</span> <span style="color: white;">states</span> <span style="color: white;">=</span> <span style="color: white;">[</span>
<span style="color: white;">{</span>
<span style="color: white;">title:</span> <span style="color: #0086d2;">"ON"</span><span style="color: white;">,</span>
<span style="color: white;">icon:</span> <span style="color: #0086d2;">"images/LEDon.png"</span>
<span style="color: white;">},</span>
<span style="color: white;">{</span>
<span style="color: white;">title:</span> <span style="color: #0086d2;">"OFF"</span><span style="color: white;">,</span>
<span style="color: white;">icon:</span> <span style="color: #0086d2;">"images/LEDoff.png"</span>
<span style="color: white;">}</span>
<span style="color: white;">];</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// Create the Menu</span>
<span style="color: #fb660a; font-weight: bold;">var</span> <span style="color: white;">menu</span> <span style="color: white;">=</span> <span style="color: #fb660a; font-weight: bold;">new</span> <span style="color: white;">UI.Menu({</span>
<span style="color: white;">sections:</span> <span style="color: white;">[{</span>
<span style="color: white;">title:</span> <span style="color: #0086d2;">'LED State'</span><span style="color: white;">,</span>
<span style="color: white;">items:</span> <span style="color: white;">states</span>
<span style="color: white;">}]</span>
<span style="color: white;">});</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// Send command when menu item is selected</span>
<span style="color: white;">menu.on(</span><span style="color: #0086d2;">'select'</span><span style="color: white;">,</span> <span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">(e)</span> <span style="color: white;">{</span>
<span style="color: white;">request(e.item.title);</span>
<span style="color: white;">});</span>
<span style="color: white;">menu.show();</span>
</pre>
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
On the other side, the Python script running Flask capture that POST request and turn an LED on or off depending of the value of the "state" data included in the request :<br />
<br />
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">flask</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">request</span>
<span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">flask</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">Flask</span>
<span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">mraa</span>
<span style="color: white;">app</span> <span style="color: white;">=</span> <span style="color: white;">Flask(__name__)</span>
<span style="color: white;">pin</span> <span style="color: white;">=</span> <span style="color: white;">mraa.Gpio(</span><span style="color: #0086f7; font-weight: bold;">13</span><span style="color: white;">)</span>
<span style="color: white;">pin.dir(mraa.DIR_OUT)</span>
<span style="color: white;">@app.route(</span><span style="color: #0086d2;">"/"</span><span style="color: white;">,</span> <span style="color: white;">methods=[</span><span style="color: #0086d2;">'POST'</span><span style="color: white;">,])</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">toggle</span><span style="color: white;">():</span>
<span style="color: white;">state</span> <span style="color: white;">=</span> <span style="color: white;">request.form[</span><span style="color: #0086d2;">'state'</span><span style="color: white;">]</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: white;">state</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">state==</span><span style="color: #0086d2;">"ON"</span><span style="color: white;">:</span>
<span style="color: white;">pin.write(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">state==</span><span style="color: #0086d2;">"OFF"</span><span style="color: white;">:</span>
<span style="color: white;">pin.write(</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: #0086d2;">"done!"</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">__name__</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"__main__"</span><span style="color: white;">:</span>
<span style="color: white;">app.run(host=</span><span style="color: #0086d2;">"0.0.0.0"</span><span style="color: white;">,port=</span><span style="color: #0086f7; font-weight: bold;">5000</span><span style="color: white;">)</span>
</pre>
</div>
<br />
When the script is running, I print the value of "state" each time a request is received. We can see that the request is successful because the HTTP response is 200 (OK).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDrW19-HLKiDqUNTZhdsZyX00johEaLZVLA2YWFCp_gcTaWRYPkZQRfhOtuzb099vs0-1sPWVish71jqRU0w3RteleWRF3t3HumnrLiEjUR939dGSv6oTsDdvaXhMDmFAjNAFWueZIDxfE/s1600/term.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDrW19-HLKiDqUNTZhdsZyX00johEaLZVLA2YWFCp_gcTaWRYPkZQRfhOtuzb099vs0-1sPWVish71jqRU0w3RteleWRF3t3HumnrLiEjUR939dGSv6oTsDdvaXhMDmFAjNAFWueZIDxfE/s1600/term.png" height="176" width="640" /></a></div>
<br />
A great way to test the Python script in your Linux terminal is to use "curl" to simulate the Pebble POST request<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">curl --data "state=ON" 192.168.0.80:5000</span><br />
<span style="font-family: Courier New, Courier, monospace;">curl --data "state=OFF" 192.168.0.80:5000</span><br />
<br />
As usual, my code does nothing more than turning an LED on or off. This is intended to be used as a template for real projects. Remember that if you can toggle an output pin you can dominate the world :)<br />
<br />Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com1tag:blogger.com,1999:blog-582219234592513124.post-45501850115028952302014-06-14T17:22:00.002-04:002014-06-14T17:30:55.726-04:00IO Expander PCF8574 with Raspberry PiWith the Raspberry Pi, you can easily run out of IO pins. A good way to solve that problem is to use an IO expander to give your Pi a couple more IO. On Tayda Electronics website, you have two different chips, the 8-bits PCF8574 and the 16-bits MCP23017 from Microchip. These two devices can communicate with the PI using the I2C protocol, it only uses two pins : SDA (data) and SCL (clock). The MCP23017 is a bit more complicated than the other one because you have access to a lot of registers on the device. The PCF8574 does not use register address : you simply read or write from it.<br>
<div>
<br></div>
<div>
First, you will need to activate the I2C port on your Raspberry Pi. There are several tutorials showing how to do this and I covered a couple links in my article about Adafruit's I2C LED matrix. You also have to find the address of your device. If it's a PCF8574A the address will be different.</div>
<div>
<br></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmxu8VZV98dUX2xVr5m2ex3yPb1kjoAyOEaRS2Oy3jMID8sn8hTQ_lo2bss7LHx6AbEczexhjkmaNCVnpmq-692R_YQHnYsANVGejtSfYrxPsYEil0i7w8PG8-Ek6J9FnoxTL7lAiz4NvW/s1600/pcf8574.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmxu8VZV98dUX2xVr5m2ex3yPb1kjoAyOEaRS2Oy3jMID8sn8hTQ_lo2bss7LHx6AbEczexhjkmaNCVnpmq-692R_YQHnYsANVGejtSfYrxPsYEil0i7w8PG8-Ek6J9FnoxTL7lAiz4NvW/s1600/pcf8574.png" height="251" width="640"></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
The three least significant bits of the 7-bits address are A2, A1, and A0. These three bits are set on the pins of the chip that have the same name. That means that you could have a maximum of 8 PCF8574 connected to your Pi without having address conflict. This means you can have up to 64 more IO. If you use 8 PCF8574 and 8 PCF8574A you can double this number :)</div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
On my breadboard, I wired 8 orange leds to the PCF8574 using 220 Ohms resistors. I plugged to chip on the 5V line to have a little bit more current on the LEDs than on the 3.3V line. A2, A1, and A0 are shorted to ground. The address of the device is then 0x38 (<a href="tel:0111000" x-apple-data-detectors="true" x-apple-data-detectors-type="telephone" x-apple-data-detectors-result="0">0111000</a>). At first I did not understand it was this address because of the picture above, where we see a 0 next to A0. But A0 is really the least significant bit. An I2C address is always 7-bit.</div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
On the rev2 Raspberry Pi, the I2C port is #1 and on rev1 it is #0. This little detail is important to know when we initialize the I2C device. Once everything is wired up and I2C is enabled, we can issue a detect command :</div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguDMMcvDlHgprdeOVv7gYE3Lz5wEvcqB1a5nDkZnUmjoYnRKxVHFNz9UpRg9VHowCwNU0rXmeCIrXZF1k7XRVQoJ1fvlmp0BKW7wbS8kQvZuNJ04Y4ZJ3zDdTEIfQ7-n-hfQYu5ylWr6yA/s1600/detect.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguDMMcvDlHgprdeOVv7gYE3Lz5wEvcqB1a5nDkZnUmjoYnRKxVHFNz9UpRg9VHowCwNU0rXmeCIrXZF1k7XRVQoJ1fvlmp0BKW7wbS8kQvZuNJ04Y4ZJ3zDdTEIfQ7-n-hfQYu5ylWr6yA/s1600/detect.png"></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
In the command <span style="font-family: Courier New, Courier, monospace;"><b>i2cdetect -y 1</b> </span><span style="font-family: inherit;">we specify that we are using port #1 for the rev2 Pi. There is also a really useful command we can use :</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Courier New, Courier, monospace;"><b>i2cset -y 1 0x<i>ADDRESS</i> 0x<i>DATA</i></b></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: Courier New, Courier, monospace;"><b><i><br></i></b></span></div>
<div class="separator" style="clear: both; text-align: left;">
For example, if I want to turn on all the LEDs directly on the command line, I can issue this command :</div>
<div class="separator" style="clear: both; text-align: left;">
<b style="font-family: 'Courier New', Courier, monospace;">i2cset -y 1 0x38 0xFF</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="separator" style="clear: both; text-align: left;">
It's easy as that!!!</div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<h2 style="clear: both; text-align: left;">
Python example</h2>
<div>
This demo would not be complete without some LED chasing and a demo Python program. In the sample below, LED1 through LED8 are the bit position of each LED in hexadecimal. I used the <i>cycle</i> function from the <i>itertools</i> library to create an infinite array that cycle from LED1 to LED8, and back to LED1, etc... Without pausing between each iteration, the Raspberry Pi would do that sequence really fast, so I'm adding a 100ms delay so we can see what is happening.</div>
<div class="separator" style="clear: both; text-align: left;">
<br></div>
<div class="highlight" style="background: #111112;">
<pre style="line-height: 125%;"><span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">smbus</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">SMBus</span>
<span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">itertools</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">cycle</span>
<span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">time</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">sleep</span>
<span style="color: white;">LED1</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x01</span>
<span style="color: white;">LED2</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x02</span>
<span style="color: white;">LED3</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x04</span>
<span style="color: white;">LED4</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x08</span>
<span style="color: white;">LED5</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x10</span>
<span style="color: white;">LED6</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x20</span>
<span style="color: white;">LED7</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x40</span>
<span style="color: white;">LED8</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x80</span>
<span style="color: white;">PATTERN</span> <span style="color: white;">=</span> <span style="color: white;">(LED1,</span> <span style="color: white;">LED2,</span> <span style="color: white;">LED3,</span> <span style="color: white;">LED4,</span>
<span style="color: white;">LED5,</span> <span style="color: white;">LED6,</span> <span style="color: white;">LED7,</span> <span style="color: white;">LED8,</span>
<span style="color: white;">LED7,</span> <span style="color: white;">LED6,</span> <span style="color: white;">LED5,</span> <span style="color: white;">LED4,</span>
<span style="color: white;">LED3,</span> <span style="color: white;">LED2)</span>
<span style="color: white;">bus</span> <span style="color: white;">=</span> <span style="color: white;">SMBus(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># Port 1 used on REV2 </span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">LED</span> <span style="color: white;">in</span> <span style="color: white;">cycle(PATTERN):</span>
<span style="color: white;">bus.write_byte(</span><span style="color: #0086f7; font-weight: bold;">0x38</span><span style="color: white;">,</span> <span style="color: white;">LED)</span>
<span style="color: white;">sleep(</span><span style="color: #0086f7; font-weight: bold;">0.1</span><span style="color: white;">)</span>
</pre>
</div>
<div>
<br>
<h2>
Demo video</h2>
</div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/qpc7IaVqkC8" width="560"></iframe>Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com7tag:blogger.com,1999:blog-582219234592513124.post-61316071750211825922014-06-01T19:59:00.003-04:002014-06-07T12:47:04.064-04:00Blasting wire tester projectI have been working on a new project for the last weeks. One of my friend is an electrical technician in a gold mine and regularly test blasting wire used to detonate dynamite. Sometimes, the wire is damaged, either open or short-circuited and he have to find where the problem is. He asked me if it was possible to create a simple portable device that continuously make a electrical contact for 1 second and release it for 1 second.<br />
<br />
The challenge is quite easy: configure a 555 timer in the astable mode and wire the ouput to a relay coil and power all that with a 9V battery. However, I wanted to have something that looks nice and is robust so it needed a little effort on my part as my project are mostly programming and electronics.<br />
<br />
<h2>
The circuit</h2>
<div>
This time again I used Diptrace to design the schematic and PCB of my project. Before doing the PCB I tested the functionality of my circuit on a breadboard. The 555 timer is good to work from 5V to 16V and can source 200mA with its output pin, which is more than enough to drive my small relay. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIMeIudcy4Yc71GhJG7mnFOmKzWlBDQFAeFGbyW2gZO3_sOqrTrpOhPd5Upw89cGFXNEFyF_Q3ZHA21HmquvOxxou470cnXky82CbugXgDpOhQujzS4R2XbuPFCj8QY3-OKGbTN9OULo5h/s1600/TesterSchematics.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIMeIudcy4Yc71GhJG7mnFOmKzWlBDQFAeFGbyW2gZO3_sOqrTrpOhPd5Upw89cGFXNEFyF_Q3ZHA21HmquvOxxou470cnXky82CbugXgDpOhQujzS4R2XbuPFCj8QY3-OKGbTN9OULo5h/s1600/TesterSchematics.png" height="309" width="640" /></a></div>
<div>
<br /></div>
<div>
The circuit is pretty straightforward, I have a switch to connect the 9V battery to the circuit and I use a green "Power Good" LED and a red LED that flashes as the contact relay closes and open. The timing of the 555 is done with the 10uF capacitor (C2) and the 1k and 100k resistors (R4, R3). Below are pictures of the Printed Circuit Board.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnqSI3qDSU6wL1xRVvOctr7JCv1-kg1ECb0Yv3mQFKQinPUCXubfYMU4N9iyo8jPHxwnUtchiYGT4Bz8oqF10EQwJq1r712IuXzl_rwtgp_B7sgs5vzM1j6fVlmnHRQ3nBOrrMrHqecdNb/s1600/20140522_221555563_iOS.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnqSI3qDSU6wL1xRVvOctr7JCv1-kg1ECb0Yv3mQFKQinPUCXubfYMU4N9iyo8jPHxwnUtchiYGT4Bz8oqF10EQwJq1r712IuXzl_rwtgp_B7sgs5vzM1j6fVlmnHRQ3nBOrrMrHqecdNb/s1600/20140522_221555563_iOS.jpg" height="400" width="300" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<h2>
The hardware</h2>
<div>
<br /></div>
<div>
All the components used in the circuit have been bought on <a href="http://www.taydaelectronics.com/">Tayda Electronics</a> website, my favorite part supplier. I bought an <a href="http://www.taydaelectronics.com/catalogsearch/result/?q=diecast+enclosure">aluminum case</a> on Tayda to put the circuit in it and I wanted to have the top of the case look great, so I made a drawing on Inkscape and asked a local store to print a sticker out of it. Below is the original artwork:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHI3jDmxGWN8XuH3pvopami3wjo95EpZwGBCMrriWnGDtLJbzzkWAfIoX-8JYJSZUy9pUWSqup7hpnDB-GtDp2m7SnnOdbBMUileD5TF8fLYbdXyPaf1ht6ks11HA0cEbqSu48zlgcei8S/s1600/blast.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHI3jDmxGWN8XuH3pvopami3wjo95EpZwGBCMrriWnGDtLJbzzkWAfIoX-8JYJSZUy9pUWSqup7hpnDB-GtDp2m7SnnOdbBMUileD5TF8fLYbdXyPaf1ht6ks11HA0cEbqSu48zlgcei8S/s1600/blast.png" height="200" width="106" /></a></div>
<div>
<br /></div>
<div>
I adjusted the DPI and size of the frame in Inkscape so I have a printed drawing the right size (2.4"x4.5"). The two following pictures are the sticker and the aluminum case with the sticker on it.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-lAaiQOR9yZghgvWtQNxGuC_2gwWLPsQ7K1gia22oiW6XdBR3NEC8JYx12By7-Kip6DA3-Yy4LFOpk1HGGsNfJ-7W6uKL3Z0H8UoxMTeLHmKHBRBA4oNCVaIA-gu26Rl3KHZxgOXZEzPt/s1600/Photo+2014-06-01+17+25+43.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-lAaiQOR9yZghgvWtQNxGuC_2gwWLPsQ7K1gia22oiW6XdBR3NEC8JYx12By7-Kip6DA3-Yy4LFOpk1HGGsNfJ-7W6uKL3Z0H8UoxMTeLHmKHBRBA4oNCVaIA-gu26Rl3KHZxgOXZEzPt/s1600/Photo+2014-06-01+17+25+43.jpg" height="200" width="150" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieYAwxUliDsl_xZIL_U0UNZZTm1O0v0D9WhapdpvFGqLhOCTGsNnUqX0Sijr62Je6gOqcheQgTmVQc5jUEls22PIcwamsOr2s8fk_h0mRfYE_MXaa8luAit8Y6Zjdny33DPbLQzaC2f82X/s1600/20140527_220712494_iOS.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieYAwxUliDsl_xZIL_U0UNZZTm1O0v0D9WhapdpvFGqLhOCTGsNnUqX0Sijr62Je6gOqcheQgTmVQc5jUEls22PIcwamsOr2s8fk_h0mRfYE_MXaa8luAit8Y6Zjdny33DPbLQzaC2f82X/s1600/20140527_220712494_iOS.jpg" height="200" width="150" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Once the sticker in place, I used a step drill bit (see picture below) to make holes the right size to put my LED holders and switch. The LED are held in place with a bezel panel mounting clip.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2VLZjFv-Wa3_3XcRxoRxHSCMGpgCWmOElDDllZgK88oENApsYs_ucsKlzAyVxk5xt3wD6f6tRCFzaOfRZp85BDJlcXzmMQuKxDt6sNbRQOXAGdtUTfO4M_HxYEXi0GO9ajYOh_p-0Pzas/s1600/image_11761.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2VLZjFv-Wa3_3XcRxoRxHSCMGpgCWmOElDDllZgK88oENApsYs_ucsKlzAyVxk5xt3wD6f6tRCFzaOfRZp85BDJlcXzmMQuKxDt6sNbRQOXAGdtUTfO4M_HxYEXi0GO9ajYOh_p-0Pzas/s1600/image_11761.jpg" height="200" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvAPnIjU1Sypp8DtC_1yyjPTWkiRJljLUIfqaTCojX13cSzbA3ggwZXMDkV4TH_KFQcU2iIVO2rOALuvc_CFtIgrTLx67Du6kqrsocydl6GfmouNqDyZ6OBUmV_xXMmd5APLlY5LamwOSQ/s1600/20140527_224120811_iOS.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvAPnIjU1Sypp8DtC_1yyjPTWkiRJljLUIfqaTCojX13cSzbA3ggwZXMDkV4TH_KFQcU2iIVO2rOALuvc_CFtIgrTLx67Du6kqrsocydl6GfmouNqDyZ6OBUmV_xXMmd5APLlY5LamwOSQ/s1600/20140527_224120811_iOS.jpg" height="320" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0PilGbutK78L2lI86bQbtyHL-ekTyaPFKEncwu17WXweYkA_u7w5Ip84U1Rbti2Nk7IWbfNi_xgV5dQqek55r-4nryJeDaPf876uwDqwztb3dOqyVztCYKmeJwFU01LTc0zqRIfkoNkPv/s1600/20140529_003222354_iOS.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0PilGbutK78L2lI86bQbtyHL-ekTyaPFKEncwu17WXweYkA_u7w5Ip84U1Rbti2Nk7IWbfNi_xgV5dQqek55r-4nryJeDaPf876uwDqwztb3dOqyVztCYKmeJwFU01LTc0zqRIfkoNkPv/s1600/20140529_003222354_iOS.jpg" height="320" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2>
Video demonstration</h2>
<div>
If you want to hear the relay click and the red LED flash, just take a look at this YouTube video<br />
<br /></div>
<div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/pjhONd45UlQ" width="560"></iframe>
<br />
<br />
That's it! I really like the outcome of this little project, this make me wants to do a lot more of good looking prototype put into cases :)<br />
<br />
See you soon,<br />
Fred</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com5tag:blogger.com,1999:blog-582219234592513124.post-52593249850819531722014-02-15T19:38:00.002-05:002014-05-22T08:21:45.078-04:00Raspberry Pi control from mobile device or desktop web browserIn my disco ball hack project, I have been using my mobile phone browser to send commands to my Raspberry Pi. In this post, I will give you a quick overview on how to do the same thing and we will take a look at the code involved. I hooked up a LED and a button to my RPi so we can read the state of the button and toggle the LED. I'm using a self flashing RGB LED that I bought on Ebay, it looks cool :)<br />
<br />
There are multiple ways to connect to the Raspberry Pi from another device. It could have been a usb-serial link, bluetooth or even raw socket programming. Also, you could have used other methods to create the user interface by using native programming on the device : Android or iPhone app, Visual Studio on the PC... The biggest advantage of using HTTP with a web server on the Pi is that it will work with all devices that have a browser. Also, you only need to know a bit of HTML and JavaScript, you don't need to learn all the other SDK and languages. I think that it's much easier to design a user interface using HTML and adding a bit of CSS for improving the look of the page than learning all the GUI toolkits out there. Using HTML5 and JavaScript is trending right now with all the web development. In Windows 8, apps can be created natively in HTML5 and JavaScript. Some of the new operating systems like Firefox OS and Tizen use HTML for everything. Anyway, let's get started with our application.<br />
<br />
For the server side software part, I'm using Python and the <a href="http://flask.pocoo.org/" target="_blank">web framework Flask</a>. There is a ton of these Python web frameworks (Django is the most well known) but Flask is great because it is really simple and does not need any configuration. For the HTML part, I'm using a bit of <a href="http://www.w3schools.com/jquerymobile/" target="_blank">JQuery Mobile</a> because it helps making a great looking page in a few line of HTML. There is also another reason to use JQuery: <a href="http://en.wikipedia.org/wiki/Ajax_(programming)" target="_blank">Ajax</a>. (Asynchronous JavaScript and XML)<br />
<br />
In a typical webpage without Ajax in which you want to send data to the server, you have to make an HTML form with a submit button. Once you press submit, a POST or GET request is done, your data is transmitted to the server and the page is completely reloaded with new data or you are redirected. With Ajax, you can easily send data to the web server without disrupting the page displayed. It is also possible to request JSON data from the server and modify the DOM (update only certain element of the page).<br />
<br />
<h3>
The simple circuit used</h3>
<div>
My circuit is an LED connected on P1 (WiringPi pin numbers) in series with a 470 ohm resistor. I also have a button between P0 and GND. I don't need a pull-up on the button because I'm using the internal pull-up of the Raspberry Pi GPIO. The circuit is even simpler like that.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuqfEllaplPqZGAonHGHpNezkSMfKge31j4WlAdcHNiusTfpooCx9AKorZKoxZNnzN_qC17JYjyr5I9ojHkKqDvZ4OiXiW6zwV-Petn-Jizhq_saVDRBVC5Mlv2-23C1s-6tefDXd2-2P4/s1600/Photo+2014-02-15+17+48+00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuqfEllaplPqZGAonHGHpNezkSMfKge31j4WlAdcHNiusTfpooCx9AKorZKoxZNnzN_qC17JYjyr5I9ojHkKqDvZ4OiXiW6zwV-Petn-Jizhq_saVDRBVC5Mlv2-23C1s-6tefDXd2-2P4/s1600/Photo+2014-02-15+17+48+00.jpg" height="200" width="150" /></a></div>
<h3>
</h3>
<h4>
</h4>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
Python code to access the button and LED</h3>
<div>
This code is fairly simple, I used the standard Raspberry Pi Python module to read/write to the GPIO. I made small utility functions so that later it is easier to read the code in the server Python file. The file name is Pins.py and I will use this as a module in the web server code.</div>
<div>
<br /></div>
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">RPi.GPIO</span> <span style="color: #fb660a; font-weight: bold;">as</span> <span style="color: white;">GPIO</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># BCM to WiringPi pin numbers</span>
<span style="color: white;">P0</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">17</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># LED pin</span>
<span style="color: white;">P1</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">18</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># Button pin</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">Init</span><span style="color: white;">():</span>
<span style="color: white;">GPIO.setwarnings(False)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># suppress GPIO used message</span>
<span style="color: white;">GPIO.setmode(GPIO.BCM)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># use BCM pin numbers</span>
<span style="color: white;">GPIO.setup(P0,</span> <span style="color: white;">GPIO.OUT)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># set LED pin as output</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># set button pin as input</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># also use internal pull-up so we don't need external resistor</span>
<span style="color: white;">GPIO.setup(P1,</span> <span style="color: white;">GPIO.IN,</span> <span style="color: white;">pull_up_down=GPIO.PUD_UP)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">LEDon</span><span style="color: white;">():</span>
<span style="color: white;">GPIO.output(P0,</span> <span style="color: white;">GPIO.HIGH)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">LEDoff</span><span style="color: white;">():</span>
<span style="color: white;">GPIO.output(P0,</span> <span style="color: white;">GPIO.LOW)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">SetLED</span><span style="color: white;">(state):</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">state:</span>
<span style="color: white;">LEDon()</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">LEDoff()</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># the "not" is used to reverse the state of the input</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># when pull-up is used, 1 is returned when the button is not pressed</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">ReadButton</span><span style="color: white;">():</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">not</span> <span style="color: white;">GPIO.input(P1):</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">True</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">False</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># if not used as a module (standalone), run this test program </span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">__name__</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"__main__"</span><span style="color: white;">:</span>
<span style="color: white;">Init()</span>
<span style="color: #fb660a; font-weight: bold;">try</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">while</span><span style="color: white;">(True):</span>
<span style="color: white;">SetLED(ReadButton())</span>
<span style="color: #fb660a; font-weight: bold;">except</span><span style="color: white;">:</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#clean exit on CTRL-C</span>
<span style="color: white;">GPIO.cleanup()</span>
<span style="color: white;">quit()</span>
</pre>
</div>
<div>
<br />
<h3>
Web server code</h3>
<div>
With Flask you can create a working web server in half a page of code. The Index function send the page to the web browser. Notice that the page is rendered only once, the rest is handled with Ajax. The function names that starts with the underscore are the Ajax request. They are called with the GetJSON function with JQuery (see the web page JavaScript in the next section). The _led function does not return JSON, but extract the state parameter from the GET url from the Ajax request to set the state of the LED. The _button function does not have parameter but instead return a JSONified text string corresponding to the button state. As a bonus, when the page is rendered first, I send the uptime of the Raspberry Pi. You can try to type "uptime" in a Unix terminal, you will see a status string displayed. It gives you the time, uptime, # of connected users and load average. I only wanted the uptime so I parsed it.<br />
<br />
By the way, to get the Flask module on your Raspbian Python folder, enter the following commands:<br />
<span style="font-family: Courier New, Courier, monospace;">sudo apt-get install python-pip</span><br />
<span style="font-family: Courier New, Courier, monospace;">sudo pip install flask</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">The first command is to install pip (a tool for installing and managing Python packages).</span><br />
<br /></div>
</div>
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">flask</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">Flask,</span> <span style="color: white;">render_template,</span> <span style="color: white;">request,</span> <span style="color: white;">jsonify</span>
<span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">Pins</span>
<span style="color: white;">app</span> <span style="color: white;">=</span> <span style="color: white;">Flask(__name__)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># return index page when IP address of RPi is typed in the browser</span>
<span style="color: white;">@app.route(</span><span style="color: #0086d2;">"/"</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">Index</span><span style="color: white;">():</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">render_template(</span><span style="color: #0086d2;">"index.html"</span><span style="color: white;">,</span> <span style="color: white;">uptime=GetUptime())</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># ajax GET call this function to set led state</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># depeding on the GET parameter sent</span>
<span style="color: white;">@app.route(</span><span style="color: #0086d2;">"/_led"</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">_led</span><span style="color: white;">():</span>
<span style="color: white;">state</span> <span style="color: white;">=</span> <span style="color: white;">request.args.get(</span><span style="color: #0086d2;">'state'</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">state==</span><span style="color: #0086d2;">"on"</span><span style="color: white;">:</span>
<span style="color: white;">Pins.LEDon()</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">Pins.LEDoff()</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: #0086d2;">""</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># ajax GET call this function periodically to read button state</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># the state is sent back as json data</span>
<span style="color: white;">@app.route(</span><span style="color: #0086d2;">"/_button"</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">_button</span><span style="color: white;">():</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">Pins.ReadButton():</span>
<span style="color: white;">state</span> <span style="color: white;">=</span> <span style="color: #0086d2;">"pressed"</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">state</span> <span style="color: white;">=</span> <span style="color: #0086d2;">"not pressed"</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">jsonify(buttonState=state)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">GetUptime</span><span style="color: white;">():</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># get uptime from the linux terminal command</span>
<span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">subprocess</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">check_output</span>
<span style="color: white;">output</span> <span style="color: white;">=</span> <span style="color: white;">check_output([</span><span style="color: #0086d2;">"uptime"</span><span style="color: white;">])</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># return only uptime info</span>
<span style="color: white;">uptime</span> <span style="color: white;">=</span> <span style="color: white;">output[output.find(</span><span style="color: #0086d2;">"up"</span><span style="color: white;">):output.find(</span><span style="color: #0086d2;">"user"</span><span style="color: white;">)-</span><span style="color: #0086f7; font-weight: bold;">5</span><span style="color: white;">]</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">uptime</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># run the webserver on standard port 80, requires sudo</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">__name__</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"__main__"</span><span style="color: white;">:</span>
<span style="color: white;">Pins.Init()</span>
<span style="color: white;">app.run(host=</span><span style="color: #0086d2;">'0.0.0.0'</span><span style="color: white;">,</span> <span style="color: white;">port=</span><span style="color: #0086f7; font-weight: bold;">80</span><span style="color: white;">,</span> <span style="color: white;">debug=True)</span>
</pre>
</div>
<div>
<br />
<h3>
Web page HTML code</h3>
</div>
<div>
In the web page, I import everything needed to get JQuery Mobile working. In the script section, I have two JavaScript functions : the first one detect a change on the slider-switch and send the state of this switch with an Ajax GET to the webserver, the second one is called once each 500 ms to get the button state. The rest of the HTML is the minimal structure of the page.<br />
<br /></div>
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="background-color: #0f140f; color: #ff0007; font-style: italic; font-weight: bold;"><!doctype html></span>
<span style="color: #fb660a; font-weight: bold;"><head></span>
<span style="color: #fb660a; font-weight: bold;"><meta</span> <span style="color: #ff0086; font-weight: bold;">name=</span><span style="color: #0086d2;">"viewport"</span> <span style="color: #ff0086; font-weight: bold;">content=</span><span style="color: #0086d2;">"initial-scale=1, maximum-scale=1"</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: #fb660a; font-weight: bold;"><link</span> <span style="color: #ff0086; font-weight: bold;">rel=</span><span style="color: #0086d2;">"stylesheet"</span> <span style="color: #ff0086; font-weight: bold;">href=</span><span style="color: #0086d2;">"http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.css"</span> <span style="color: #fb660a; font-weight: bold;">/></span>
<span style="color: #fb660a; font-weight: bold;"><script </span><span style="color: #ff0086; font-weight: bold;">src=</span><span style="color: #0086d2;">"http://code.jquery.com/jquery-1.9.1.min.js"</span><span style="color: #fb660a; font-weight: bold;">></script></span>
<span style="color: #fb660a; font-weight: bold;"><script </span><span style="color: #ff0086; font-weight: bold;">src=</span><span style="color: #0086d2;">"http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"</span><span style="color: #fb660a; font-weight: bold;">></script></span>
<span style="color: #fb660a; font-weight: bold;"></head></span>
<span style="color: #fb660a; font-weight: bold;"><style></span>
<span style="color: #fb660a; font-weight: bold;">h3</span><span style="color: white;">,</span> <span style="color: #fb660a; font-weight: bold;">h4</span> <span style="color: white;">{</span><span style="color: #fb660a; font-weight: bold;">text-align</span><span style="color: white;">:</span> <span style="color: #fb660a; font-weight: bold;">center</span><span style="color: white;">;}</span>
<span style="color: #fb660a; font-weight: bold;">span</span> <span style="color: white;">{</span><span style="color: #fb660a; font-weight: bold;">font-weight</span><span style="color: white;">:</span> <span style="color: #fb660a; font-weight: bold;">bold</span><span style="color: white;">;}</span>
<span style="color: #fb660a; font-weight: bold;"></style></span>
<span style="color: #fb660a; font-weight: bold;"><script </span><span style="color: #ff0086; font-weight: bold;">type=</span><span style="color: #0086d2;">text/javascript</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: white;">$(</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// When the LED button is pressed (change)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// do an ajax request to server to change LED state</span>
<span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">()</span>
<span style="color: white;">{</span>
<span style="color: white;">$(</span><span style="color: #0086d2;">'#flip-1'</span><span style="color: white;">).change(</span><span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">()</span>
<span style="color: white;">{</span>
<span style="color: white;">$.getJSON(</span><span style="color: #0086d2;">'/_led'</span><span style="color: white;">,</span> <span style="color: white;">{state:</span> <span style="color: white;">$(</span><span style="color: #0086d2;">'#flip-1'</span><span style="color: white;">).val()});</span>
<span style="color: white;">});</span>
<span style="color: white;">}</span>
<span style="color: white;">);</span>
<span style="color: white;">$(</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// periodically (500ms) do an ajax request to get the button state</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// modify the span tag to reflect the state (pressed or not)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">// the state text comes from the JSON string returned by the server</span>
<span style="color: #fb660a; font-weight: bold;">function</span> <span style="color: white;">button()</span>
<span style="color: white;">{</span>
<span style="color: white;">$.getJSON(</span><span style="color: #0086d2;">'/_button'</span><span style="color: white;">,</span> <span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">(data)</span>
<span style="color: white;">{</span>
<span style="color: white;">$(</span><span style="color: #0086d2;">"#buttonState"</span><span style="color: white;">).text(data.buttonState);</span>
<span style="color: white;">setTimeout(</span><span style="color: #fb660a; font-weight: bold;">function</span><span style="color: white;">(){button();},</span><span style="color: #0086f7; font-weight: bold;">500</span><span style="color: white;">);</span>
<span style="color: white;">});</span>
<span style="color: white;">}</span>
<span style="color: white;">);</span>
<span style="color: #fb660a; font-weight: bold;"></script></span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"><!-- Simple JQuery Mobile page that display the button state on the breadoard --></span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"><!-- You can also change the LED state with the slider switch --></span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"><!-- The Raspberry Pi uptime is displayed in the footer (Jinja2 expands the template tag) --></span>
<span style="color: #fb660a; font-weight: bold;"><div</span> <span style="color: #ff0086; font-weight: bold;">data-role=</span><span style="color: #0086d2;">"page"</span> <span style="color: #ff0086; font-weight: bold;">data-theme=</span><span style="color: #0086d2;">"b"</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: #fb660a; font-weight: bold;"><div</span> <span style="color: #ff0086; font-weight: bold;">data-role=</span><span style="color: #0086d2;">"header"</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: #fb660a; font-weight: bold;"><div><h3></span>Raspberry Pi Web Control<span style="color: #fb660a; font-weight: bold;"></h3></div></span>
<span style="color: #fb660a; font-weight: bold;"></div></span>
<span style="color: #fb660a; font-weight: bold;"><div</span> <span style="color: #ff0086; font-weight: bold;">data-role=</span><span style="color: #0086d2;">"content"</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: #fb660a; font-weight: bold;"><form></span>
<span style="color: #fb660a; font-weight: bold;"><p></span>The button is <span style="color: #fb660a; font-weight: bold;"><span</span> <span style="color: #ff0086; font-weight: bold;">id=</span><span style="color: #0086d2;">"buttonState"</span><span style="color: #fb660a; font-weight: bold;">></span></p></span>
<span style="color: #fb660a; font-weight: bold;"><br></span>
<span style="color: #fb660a; font-weight: bold;"><select</span> <span style="color: #ff0086; font-weight: bold;">name=</span><span style="color: #0086d2;">"flip-1"</span> <span style="color: #ff0086; font-weight: bold;">id=</span><span style="color: #0086d2;">"flip-1"</span> <span style="color: #ff0086; font-weight: bold;">data-role=</span><span style="color: #0086d2;">"slider"</span> <span style="color: #ff0086; font-weight: bold;">style=</span><span style="color: #0086d2;">"float: left;"</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: #fb660a; font-weight: bold;"><option</span> <span style="color: #ff0086; font-weight: bold;">value=</span><span style="color: #0086d2;">"off"</span><span style="color: #fb660a; font-weight: bold;">></span>LED off<span style="color: #fb660a; font-weight: bold;"></option></span>
<span style="color: #fb660a; font-weight: bold;"><option</span> <span style="color: #ff0086; font-weight: bold;">value=</span><span style="color: #0086d2;">"on"</span><span style="color: #fb660a; font-weight: bold;">></span>LED on<span style="color: #fb660a; font-weight: bold;"></option></span>
<span style="color: #fb660a; font-weight: bold;"></select></span>
<span style="color: #fb660a; font-weight: bold;"></form></span>
<span style="color: #fb660a; font-weight: bold;"></div></span>
<span style="color: #fb660a; font-weight: bold;"><div</span> <span style="color: #ff0086; font-weight: bold;">data-role=</span><span style="color: #0086d2;">"footer"</span><span style="color: #fb660a; font-weight: bold;">></span>
<span style="color: #fb660a; font-weight: bold;"><div><h4></span>This Raspberry Pi has been {{uptime}}<span style="color: #fb660a; font-weight: bold;"></h4></div></span>
<span style="color: #fb660a; font-weight: bold;"></div></span>
<span style="color: #fb660a; font-weight: bold;"></div></span>
</pre>
</div>
<div>
<br />
<h3>
In action : demo video on Youtube</h3>
</div>
<div>
<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJwYsa9P9mpHYbC3II6k-D7BItjXDmNiygRGmhyphenhyphen96bNHhFM9V7KiwfLdf4iwNPAlDnzXQD4MatZcrh1WmSHgv0WFo_PuzZBKal72jPo6NcflKkzd0qTr1CVPDzRHX328KIis8eKUxjDbqV/s1600/web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJwYsa9P9mpHYbC3II6k-D7BItjXDmNiygRGmhyphenhyphen96bNHhFM9V7KiwfLdf4iwNPAlDnzXQD4MatZcrh1WmSHgv0WFo_PuzZBKal72jPo6NcflKkzd0qTr1CVPDzRHX328KIis8eKUxjDbqV/s1600/web.png" height="236" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
Here is a demo of the server running and being controlled by my mobile phone. On my main computer, I connect to the Raspberry Pi with SSH. I then start the python application. If you look closely on the computer screen around 0:15, you will see a lot of requests being made to the server. This is due to the 500ms timer sending the Ajax request to read the status of the button.<br />
<br /></div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/QEF3cOkeL2w?list=UU0n9rIda1jNIz4TLJs4844Q" width="560"></iframe>
<br />
<br />
I really hope that this code can help you in your projects. When I started doing electronics stuff in 2007, I was dreaming about doing something like this. At that time, we did not have smart phones and low cost Linux single board computer. Things changed a lot since!<br />
<div>
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com56tag:blogger.com,1999:blog-582219234592513124.post-89231541318897949072014-02-11T21:34:00.001-05:002014-06-11T21:16:31.111-04:00Hacking a Disco Ball - Part 2In my<a href="http://electronicsbyexamples.blogspot.ca/2013/12/hacking-disco-ball-part-1.html" target="_blank"> last blog post</a>, I gave you an overview of the Disco Ball project. A couple weeks ago I received the printed circuit boards from OSH Park. So here are a couple of pictures of the boards and assembly :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEzFd9QOpmwJoMGpnfAEIghLmqfMFiUDQ5ODNq5jbQSgvpx7-Nqcq9O5dl7UCIgnnHlO7nkjE_iHmSeYv2RLcIim28H9O2ieT2xtz_FSORO81i75Sy50y9_WeljjhNVEDGzf7egp1QZAuA/s1600/pcb.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEzFd9QOpmwJoMGpnfAEIghLmqfMFiUDQ5ODNq5jbQSgvpx7-Nqcq9O5dl7UCIgnnHlO7nkjE_iHmSeYv2RLcIim28H9O2ieT2xtz_FSORO81i75Sy50y9_WeljjhNVEDGzf7egp1QZAuA/s1600/pcb.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh14RSr4u59Bu7g1Nb7N0FsSaTm4s7qvNrpxAradTQEnNYzJT13NXD9eeSaTu4_dO9d4oEFaJcua3aCv4ePuO4HP-93CHpH3gMeeXpXcvxCVJtQeUeGYl7lIF2nR5QIZQPQwF-ntOnbckL5/s1600/soldering.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh14RSr4u59Bu7g1Nb7N0FsSaTm4s7qvNrpxAradTQEnNYzJT13NXD9eeSaTu4_dO9d4oEFaJcua3aCv4ePuO4HP-93CHpH3gMeeXpXcvxCVJtQeUeGYl7lIF2nR5QIZQPQwF-ntOnbckL5/s1600/soldering.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0b60y5xRtrUokG4-uv9NoDwmjAxiJtafqKUBQzzqE7Z7F9PbrYJNQc2vYR1322sUkQuQQH0CA_g-GAwa6Arxj0CA1AtShZnnJ__WToeQ13nYjY8PwNQVihvgcjAbmZTuJ8HcRn5qCpISk/s1600/soldered.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0b60y5xRtrUokG4-uv9NoDwmjAxiJtafqKUBQzzqE7Z7F9PbrYJNQc2vYR1322sUkQuQQH0CA_g-GAwa6Arxj0CA1AtShZnnJ__WToeQ13nYjY8PwNQVihvgcjAbmZTuJ8HcRn5qCpISk/s1600/soldered.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5MmyBFogCWHt0kgRrN1aGWh48b70D_Oec_Nm7jYY8xEW994ftEaNfJ42DQx-x__-GNLuWZ-PnbK1HB2RYX07e64VEezFCivfdnt5nnrUoPPs7CkgkZ_FdZwbrglzzD30yBXUiWbhtTfHe/s1600/inside.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5MmyBFogCWHt0kgRrN1aGWh48b70D_Oec_Nm7jYY8xEW994ftEaNfJ42DQx-x__-GNLuWZ-PnbK1HB2RYX07e64VEezFCivfdnt5nnrUoPPs7CkgkZ_FdZwbrglzzD30yBXUiWbhtTfHe/s1600/inside.jpg" height="180" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
After soldering the circuit, I was really relieved that everything worked perfectly. The first thing I did was to test if I was able to identify the Propeller chip with the programming software and load a program in the EEPROM memory. Once done, I soldered the 3 MOSFET LED drivers and fired a 3.3V signal on their gates. The LEDs of the disco ball turned on as normal. I was a bit stressed with the last part, driving the 120V motor with the Triac. I tested the connections on the breadboard before doing the PCB, but there is always a chance that something is not correct. I closed my eyes when I plugged the 120V in... no explosion or blue fume, phew :)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
Software</h3>
<div>
Originally, I wrote a command interpreter in Python that compile a sequence file and send the compiled sequence to the microcontroller on the PCB. The compiled sequence was stored in the unused part of the boot EEPROM and the main program purpose was to run the loaded sequence. The Python code is shown below :<br />
<br /></div>
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="background-color: #0f140f; color: #008800; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #0086d2;">"""</span>
<span style="color: #0086d2;"> This program is free software: you can redistribute it and/or modify</span>
<span style="color: #0086d2;"> it under the terms of the GNU General Public License as published by</span>
<span style="color: #0086d2;"> the Free Software Foundation, either version 3 of the License, or</span>
<span style="color: #0086d2;"> (at your option) any later version.</span>
<span style="color: #0086d2;"> This program is distributed in the hope that it will be useful,</span>
<span style="color: #0086d2;"> but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span style="color: #0086d2;"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
<span style="color: #0086d2;"> GNU General Public License for more details.</span>
<span style="color: #0086d2;"> You should have received a copy of the GNU General Public License</span>
<span style="color: #0086d2;"> along with this program. If not, see <http://www.gnu.org/licenses/>.</span>
<span style="color: #0086d2;">"""</span>
<span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">sys,</span> <span style="color: white;">re</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Pyserial needed to connect to the printed circuit board</span>
<span style="color: #fb660a; font-weight: bold;">try</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">serial</span>
<span style="color: #fb660a; font-weight: bold;">except</span><span style="color: white;">:</span>
<span style="color: white;">sys.exit(COM_LIBRARY_UNDEFINED)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#This constant value needs to fit with the one in the microcontroller, it won't work otherwise </span>
<span style="color: white;">MAX_COMMANDS</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">1024</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Error codes, ease the debugging process and script interpreting troubleshooting</span>
<span style="color: white;">OK</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Everything is OK</span>
<span style="color: white;">COM_UNDEFINED</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">1</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#COM Port undefined on the first line</span>
<span style="color: white;">COM_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">2</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Unable to connect to the board</span>
<span style="color: white;">SYNTAX_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">3</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Incorrect command syntax</span>
<span style="color: white;">COLOR_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">4</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#bad color range (0-100)</span>
<span style="color: white;">DELAY_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">5</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#bad delay range</span>
<span style="color: white;">LABEL_NOT_FOUND_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">6</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#unable to find loop label</span>
<span style="color: white;">LABEL_DUPLICATE_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">10</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#loop lable duplicate</span>
<span style="color: white;">SCRIPT_NOT_FOUND</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">7</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#wrong script path</span>
<span style="color: white;">COM_LIBRARY_UNDEFINED</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">8</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#pyserial not installed on the machine</span>
<span style="color: white;">ARGS_ERROR</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">9</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#need path as command line argument</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#we need the disco light sequence script path as first argument</span>
<span style="color: #fb660a; font-weight: bold;">try</span><span style="color: white;">:</span>
<span style="color: white;">script_path</span> <span style="color: white;">=</span> <span style="color: white;">sys.argv[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">]</span>
<span style="color: #fb660a; font-weight: bold;">except</span><span style="color: white;">:</span>
<span style="color: white;">sys.exit(ARGS_ERROR)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#read the script and put it in a list </span>
<span style="color: #fb660a; font-weight: bold;">try</span><span style="color: white;">:</span>
<span style="color: white;">script_file</span> <span style="color: white;">=</span> <span style="color: white;">open(script_path)</span>
<span style="color: white;">raw_script</span> <span style="color: white;">=</span> <span style="color: white;">script_file.readlines()</span>
<span style="color: white;">script_file.close()</span>
<span style="color: #fb660a; font-weight: bold;">except</span><span style="color: white;">:</span>
<span style="color: white;">sys.exit(SCRIPT_NOT_FOUND)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#only keep the important stuff (remove comments) </span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">strip</span><span style="color: white;">(line):</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">line[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">'['</span><span style="color: white;">:</span>
<span style="color: white;">index</span> <span style="color: white;">=</span> <span style="color: white;">line.find(</span><span style="color: #0086d2;">']'</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">index==-</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">return</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">line[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">:index].lower()</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#list comprehension to execute the above function on all the lines</span>
<span style="color: white;">cleaned_script</span> <span style="color: white;">=</span> <span style="color: white;">[strip(line)</span> <span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">line</span> <span style="color: white;">in</span> <span style="color: white;">raw_script</span> <span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">strip(line)]</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"Clean script:\n"</span><span style="color: white;">+str(cleaned_script)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#find all the labels</span>
<span style="color: white;">labels</span> <span style="color: white;">=</span> <span style="color: white;">{}</span>
<span style="color: white;">index</span> <span style="color: white;">=</span> <span style="color: white;">-</span><span style="color: #0086f7; font-weight: bold;">1</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Strip the COM Port line</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">command</span> <span style="color: white;">in</span> <span style="color: white;">cleaned_script:</span>
<span style="color: white;">index</span> <span style="color: white;">+=</span> <span style="color: #0086f7; font-weight: bold;">1</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">'.'</span><span style="color: white;">:</span>
<span style="color: white;">labels[command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">:]]</span> <span style="color: white;">=</span> <span style="color: white;">index</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#look for duplicates </span>
<span style="color: white;">unique_labels</span> <span style="color: white;">=</span> <span style="color: white;">tuple(set(labels))</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">tuple(labels)</span> <span style="color: white;">!=</span> <span style="color: white;">unique_labels:</span>
<span style="color: white;">sys.exit(LABEL_DUPLICATE_ERROR)</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"Labels:\n"</span><span style="color: white;">+str(labels)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#regex patterns to parse commands</span>
<span style="color: white;">pat_com</span> <span style="color: white;">=</span> <span style="color: white;">re.compile(</span><span style="color: #0086d2;">"(com\d+)"</span><span style="color: white;">)</span>
<span style="color: white;">pat_col</span> <span style="color: white;">=</span> <span style="color: white;">re.compile(</span><span style="color: #0086d2;">"([rgb]):(\d+)"</span><span style="color: white;">)</span>
<span style="color: white;">pat_del</span> <span style="color: white;">=</span> <span style="color: white;">re.compile(</span><span style="color: #0086d2;">"\$(\d+)"</span><span style="color: white;">)</span>
<span style="color: white;">pat_jmp</span> <span style="color: white;">=</span> <span style="color: white;">re.compile(</span><span style="color: #0086d2;">"jmp\.(.+)?(\d+)"</span><span style="color: white;">)</span>
<span style="color: white;">pat_jmpINF</span> <span style="color: white;">=</span> <span style="color: white;">re.compile(</span><span style="color: #0086d2;">"jmp\.(.+)"</span><span style="color: white;">)</span>
<span style="color: white;">pat_lbl</span> <span style="color: white;">=</span> <span style="color: white;">re.compile(</span><span style="color: #0086d2;">"\.(.+)"</span><span style="color: white;">)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#get the serial COM Port and set the link speed</span>
<span style="color: white;">m</span> <span style="color: white;">=</span> <span style="color: white;">pat_com.match(cleaned_script[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">])</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">not</span> <span style="color: white;">m:</span>
<span style="color: white;">sys.exit(COM_UNDEFINED)</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">com_port</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"Port: "</span><span style="color: white;">+str(com_port)</span>
<span style="color: #fb660a; font-weight: bold;">try</span><span style="color: white;">:</span>
<span style="color: white;">BAUDRATE</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">115200</span>
<span style="color: white;">ser</span> <span style="color: white;">=</span> <span style="color: white;">serial.Serial(com_port,BAUDRATE)</span>
<span style="color: #fb660a; font-weight: bold;">except</span><span style="color: white;">:</span>
<span style="color: white;">sys.exit(COM_ERROR)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#The next lines parse all the commands and generate</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># a list of parsed command in an easy to use way</span>
<span style="color: white;">commands</span> <span style="color: white;">=</span> <span style="color: white;">[]</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">command</span> <span style="color: white;">in</span> <span style="color: white;">cleaned_script[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">:]:</span>
<span style="color: white;">m</span> <span style="color: white;">=</span> <span style="color: white;">pat_col.match(command)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">m:</span>
<span style="color: white;">color</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: white;">brightness</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">int(brightness)</span> <span style="color: white;">></span> <span style="color: #0086f7; font-weight: bold;">100</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: white;">brightness</span>
<span style="color: white;">sys.exit(COLOR_ERROR)</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"COLOR"</span><span style="color: white;">,color,brightness))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: white;">m</span> <span style="color: white;">=</span> <span style="color: white;">pat_del.match(command)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">m:</span>
<span style="color: white;">delay</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">int(delay)</span> <span style="color: white;">></span> <span style="color: #0086f7; font-weight: bold;">100000</span><span style="color: white;">:</span>
<span style="color: white;">sys.exit(DELAY_ERROR)</span>
<span style="color: white;">delay</span> <span style="color: white;">=</span> <span style="color: white;">int(delay)</span>
<span style="color: white;">b0</span> <span style="color: white;">=</span> <span style="color: white;">delay</span> <span style="color: white;">>></span> <span style="color: #0086f7; font-weight: bold;">0</span> <span style="color: white;">&</span> <span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">b11111111</span>
<span style="color: white;">b1</span> <span style="color: white;">=</span> <span style="color: white;">delay</span> <span style="color: white;">>></span> <span style="color: #0086f7; font-weight: bold;">8</span> <span style="color: white;">&</span> <span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">b11111111</span>
<span style="color: white;">b2</span> <span style="color: white;">=</span> <span style="color: white;">delay</span> <span style="color: white;">>></span> <span style="color: #0086f7; font-weight: bold;">16</span> <span style="color: white;">&</span> <span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">b11111111</span>
<span style="color: white;">b3</span> <span style="color: white;">=</span> <span style="color: white;">delay</span> <span style="color: white;">>></span> <span style="color: #0086f7; font-weight: bold;">24</span> <span style="color: white;">&</span> <span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">b11111111</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"DELAY"</span><span style="color: white;">,b0,b1,b2,b3))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: white;">m</span> <span style="color: white;">=</span> <span style="color: white;">pat_jmp.match(command)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">m:</span>
<span style="color: white;">label</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: white;">label</span> <span style="color: white;">=</span> <span style="color: white;">label[:-</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">]</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;"># Strip the question mark</span>
<span style="color: white;">times</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">not</span> <span style="color: white;">label</span> <span style="color: white;">in</span> <span style="color: white;">labels:</span>
<span style="color: white;">sys.exit(LABEL_NOT_FOUND_ERROR)</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"REPEAT"</span><span style="color: white;">,labels[label],times))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: white;">m</span> <span style="color: white;">=</span> <span style="color: white;">pat_jmpINF.match(command)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">m:</span>
<span style="color: white;">label</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">not</span> <span style="color: white;">label</span> <span style="color: white;">in</span> <span style="color: white;">labels:</span>
<span style="color: white;">sys.exit(LABEL_NOT_FOUND_ERROR)</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"LOOP FOREVER"</span><span style="color: white;">,labels[label]))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: white;">m</span> <span style="color: white;">=</span> <span style="color: white;">pat_lbl.match(command)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">m:</span>
<span style="color: white;">label</span> <span style="color: white;">=</span> <span style="color: white;">m.group(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"LABEL"</span><span style="color: white;">,labels[label]))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">command</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"stop"</span><span style="color: white;">:</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"MOTOR"</span><span style="color: white;">,False))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">command</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"start"</span><span style="color: white;">:</span>
<span style="color: white;">commands.append((</span><span style="color: #0086d2;">"MOTOR"</span><span style="color: white;">,True))</span>
<span style="color: #fb660a; font-weight: bold;">continue</span>
<span style="color: white;">sys.exit(SYNTAX_ERROR)</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"Commands:\n"</span><span style="color: white;">+str(commands)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Patch for the ser.write : we want to send </span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># the decimal number as a byte</span>
<span style="color: white;">commands_sent</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">write</span><span style="color: white;">(num):</span>
<span style="color: #fb660a; font-weight: bold;">global</span> <span style="color: white;">commands_sent</span>
<span style="color: white;">commands_sent</span> <span style="color: white;">+=</span> <span style="color: #0086f7; font-weight: bold;">1</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">num</span> <span style="color: white;">!=</span> <span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">pass</span><span style="background-color: #0f140f; color: #008800; font-style: italic;">#print num</span>
<span style="color: white;">ser.write(chr(int(num)))</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Special read : read the bytes as string and when there is a newline, it marks the end of string</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Return all the strings in a array (tuple) stop reading when null character received chr(0)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">readLineFeed</span><span style="color: white;">():</span>
<span style="color: white;">data</span> <span style="color: white;">=</span> <span style="color: white;">[]</span>
<span style="color: white;">buffer</span> <span style="color: white;">=</span> <span style="color: white;">[]</span>
<span style="color: #fb660a; font-weight: bold;">while</span><span style="color: white;">(True):</span>
<span style="color: white;">value</span> <span style="color: white;">=</span> <span style="color: white;">ser.read()</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">value</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"\n"</span><span style="color: white;">:</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#LineFeed</span>
<span style="color: white;">data.append(</span><span style="color: #0086d2;">""</span><span style="color: white;">.join(buffer))</span>
<span style="color: white;">buffer</span> <span style="color: white;">=</span> <span style="color: white;">[]</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Flush the buffer</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">value</span> <span style="color: white;">==</span> <span style="color: white;">chr(</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">):</span>
<span style="color: #fb660a; font-weight: bold;">break</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">buffer.append(value)</span>
<span style="color: #fb660a; font-weight: bold;">return</span> <span style="color: white;">tuple(data)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">readINF</span><span style="color: white;">():</span>
<span style="color: #fb660a; font-weight: bold;">while</span><span style="color: white;">(True):</span>
<span style="color: white;">value</span> <span style="color: white;">=</span> <span style="color: white;">ser.read()</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: white;">value</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#After the commands are parsed, we send </span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;"># serial commands to the controller PCB</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">command</span> <span style="color: white;">in</span> <span style="color: white;">commands:</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"COLOR"</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">'r'</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#brightness</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">'g'</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#brightness</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">'b'</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">3</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#brightness</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"MOTOR"</span><span style="color: white;">:</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">]:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">4</span><span style="color: white;">)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Start</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">5</span><span style="color: white;">)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#Stop</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"DELAY"</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">6</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#delay b0</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#delay b1</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">3</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#delay b2</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">4</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#delay b3</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"LABEL"</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">7</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">])</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"REPEAT"</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#label</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#times</span>
<span style="color: #fb660a; font-weight: bold;">elif</span> <span style="color: white;">command[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]</span> <span style="color: white;">==</span> <span style="color: #0086d2;">"LOOP FOREVER"</span><span style="color: white;">:</span>
<span style="color: white;">write(</span><span style="color: #0086f7; font-weight: bold;">9</span><span style="color: white;">)</span>
<span style="color: white;">write(command[</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">])</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#label</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">commands_sent</span> <span style="color: white;">!=</span> <span style="color: white;">MAX_COMMANDS:</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"Before looping: "</span><span style="color: white;">+str(commands_sent)</span>
<span style="color: white;">to_max</span> <span style="color: white;">=</span> <span style="color: white;">MAX_COMMANDS-commands_sent</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">index</span> <span style="color: white;">in</span> <span style="color: white;">range(to_max):</span>
<span style="color: white;">write(</span><span style="color: #0086d2;">'0'</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"After looping: "</span><span style="color: white;">+str(commands_sent)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Print the data echoed (debug)</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">data</span> <span style="color: white;">in</span> <span style="color: white;">readLineFeed():</span>
<span style="color: #fb660a; font-weight: bold;">print</span><span style="color: white;">(data)</span>
<span style="background-color: #0f140f; color: #008800; font-style: italic;">#Everything should be fine if we get there </span>
<span style="color: white;">ser.close()</span>
<span style="color: #fb660a; font-weight: bold;">print</span> <span style="color: #0086d2;">"Script OK!\n"</span>
<span style="color: white;">sys.exit(OK)</span>
</pre>
</div>
<br />
In the end, my friend and I decided to control the board with a Raspberry Pi, by using a serial port on each side. The interface is really simple : you have commands to dim the 3 LEDs from 0 to 100% and a command to turn the motor on and off. The reason for the Raspberry Pi is that with an internet connected device, we can easily make a simple webpage to control the board with our mobile phones.<br />
<br />
I love Python, so for the web framework on the Pi I decided to use <a href="http://flask.pocoo.org/" target="_blank">F<span id="goog_253614176"></span><span id="goog_253614177"></span>lask</a>. For the HTML code, I used jQuery Mobile for a good page rendering on mobile devices. There is an <a href="http://www.w3schools.com/jquerymobile/" target="_blank">excellent jQuery Mobile tutorial</a> on the w3schools website. To make the page interactive, I used a bit of AJAX with jQuery. I really should do a little tutorial about all that in another article. It is really cool to be able to control the IO of the Pi with a webpage! Pictures of the webpage:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNMe5WLgPhRzZgSpiayUgfyOxCuDgIZeeidRrRyxmrNWPvgLEVYq_fpgizvyeVf6ZazsiAf_Gpq4fbJhnstFh3x4WroW38Db9-t6Ph3iauYaUjFmVQGaDJjCNRWfwcbsRIab4PswlogZej/s1600/Screenshot_2014-02-11-21-22-49.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNMe5WLgPhRzZgSpiayUgfyOxCuDgIZeeidRrRyxmrNWPvgLEVYq_fpgizvyeVf6ZazsiAf_Gpq4fbJhnstFh3x4WroW38Db9-t6Ph3iauYaUjFmVQGaDJjCNRWfwcbsRIab4PswlogZej/s1600/Screenshot_2014-02-11-21-22-49.png" height="640" width="360" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYnGDa43PAjvHiWHEsVfpQSUkBpc1vgFKP2VBGp3SFhlqNH6-GaL9fzwd43jCmrE3AcRHVxxy80gm8_KtmoqVZoiHr0O1DfOQ6Yva5ijqGkmeMndrhzuDebTjOaNrwoWusIjN1dgJ5FaFx/s1600/Screenshot_2014-02-11-21-23-22.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYnGDa43PAjvHiWHEsVfpQSUkBpc1vgFKP2VBGp3SFhlqNH6-GaL9fzwd43jCmrE3AcRHVxxy80gm8_KtmoqVZoiHr0O1DfOQ6Yva5ijqGkmeMndrhzuDebTjOaNrwoWusIjN1dgJ5FaFx/s1600/Screenshot_2014-02-11-21-23-22.png" height="640" width="360" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3 style="clear: both; text-align: left;">
Here is a YouTube video showing the Disco Ball in action</h3>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/BQGjrDPf3nU" width="560"></iframe>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Finally, I did not gave too much explanation about the software side of the project (webpage source and microcontroller programs)... I might just be a little bit lazy :) If someone is interested, I can send my source code. Thanks for reading!</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com3tag:blogger.com,1999:blog-582219234592513124.post-38840922573248353032013-12-14T21:22:00.000-05:002014-12-30T14:56:28.571-05:00Hacking a Disco Ball - Part 1Several months ago, one of my friends bought a cheap disco ball on ebay like <a href="http://www.ebay.ca/itm/Sound-Control-Disco-DJ-Stage-Lighting-Digital-LED-RGB-Crystal-Ball-Effect-Light-/360814424157?pt=US_Stage_Lighting_Single_Units&hash=item540237305d&_uhb=1" target="_blank">this one</a>. When plugged in the wall outlet, the disco ball turns and produce automatic lights pattern. After using it a couple times, he found the built-in pattern to be pretty boring so he asked me if it was possible to hack the electronics inside to create his own patterns.<br />
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCx-nKfTGpkJlD2ShecTHQtfBexH3xM6cvCS5VN0h__RRnY48-1-fX9pSoDcV5zWXR0GhE9RpTkAioVjYoOHbnlh4AigpFV-ijpgcpb1xpmyXak1LFSCYjICAmdWHIAUUGQGXt1J5HptWt/s1600/$_35.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCx-nKfTGpkJlD2ShecTHQtfBexH3xM6cvCS5VN0h__RRnY48-1-fX9pSoDcV5zWXR0GhE9RpTkAioVjYoOHbnlh4AigpFV-ijpgcpb1xpmyXak1LFSCYjICAmdWHIAUUGQGXt1J5HptWt/s1600/$_35.jpeg" /></a></div>
<div>
<br /></div>
<div>
We then opened the disco ball to see how it worked, the design was pretty simple. Inside the ball, there is 2 printed circuit board and a 120V motor. One of the PCB only contains 3 big LEDs for the red, green and blue color. On the side of the PCB you have a six pin connection that gives access to the 3 cathodes and 3 anodes of the LEDs.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh88qN8f1Yt9jVW3Slgz1Q5VSKjeT8HowrKM24aY-um_IaHN8_B7-JReV7rzDtjF_nLVWzhcs027EmoxH6rnLPtYjfwo9G8ZiAbhl3pvBKjyrYQemT_GcQXnkK-sZ1DYoV0badgSMsjyFfo/s1600/photo+1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh88qN8f1Yt9jVW3Slgz1Q5VSKjeT8HowrKM24aY-um_IaHN8_B7-JReV7rzDtjF_nLVWzhcs027EmoxH6rnLPtYjfwo9G8ZiAbhl3pvBKjyrYQemT_GcQXnkK-sZ1DYoV0badgSMsjyFfo/s320/photo+1.JPG" height="320" width="320" /></a></div>
<br />
<br />
On the other PCB, you have a transformer and 7805 regulator to provide low voltage for the LEDs and a couple chips for animating the hardware of the ball. Like most Chinese stuff I've seen, the controller PCB is very cheaply made and by looking at the quality of the soldering, I wonder how it can work properly.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi098DWX-15-qoXYCzjnf7MASJHzOCDx5Y0R55N7UPv4u25Z0JZESgtxtXhkQIFEeWI9Td7WYmH-ZB7wzr2AFJuqLB0MeTzDwGYMx4sXWmkxgzLhT6KslvOJ9gXYApFUBBlMUUEG0zaYZuo/s1600/photo+3.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi098DWX-15-qoXYCzjnf7MASJHzOCDx5Y0R55N7UPv4u25Z0JZESgtxtXhkQIFEeWI9Td7WYmH-ZB7wzr2AFJuqLB0MeTzDwGYMx4sXWmkxgzLhT6KslvOJ9gXYApFUBBlMUUEG0zaYZuo/s400/photo+3.JPG" height="400" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<br /></div>
<div>
To hack the disco ball, I suggested to my friend that we get rid of the controller board and make our own so we can control each LEDs and the motor. The content of the PCB is quite simple :</div>
<div>
<br /></div>
<div>
<ul>
<li>5V input connector</li>
<li>120V input connector</li>
<li>Microcontroller (I chose the Propeller from Parallax)</li>
<li>3.3V voltage regulator</li>
<li>3 MOSFET transistors to drive the LEDs</li>
<li>Triac to turn ON and OFF the 120V motor</li>
<li>Couples of connectors for LEDs, motor and programming</li>
</ul>
<div>
For the software part, I scratched my head a little bit... I wanted to make something simple so we could create several lighting patterns easily, without messing too much with the code. I ended up with designing a simple scripting language to control the LEDs and motors. The language also features looping construct for the animations. Here is what is needed for the software :</div>
</div>
<div>
<br /></div>
<div>
<ul>
<li>Specification for the disco scripting language</li>
<li>Computer program to send the script to the disco ball</li>
<ul>
<li>Functions to read the script file and translate it to a binary form</li>
<li>Functions to send the binary file serially to the microcontroller</li>
</ul>
<li>Microcontroller program to receive and interpret the binary program</li>
<li>Software routines for controlling the motor and switching/dimming the LEDs</li>
</ul>
<div>
Even if this project is simple, completing each task took me quite some time and the project is almost finished. At the moment, all the software part is working and I'm waiting for the PCB that I ordered from OSH Park to arrive. Take a look at the preview of the PCB I got :</div>
</div>
<div>
<br /></div>
<div style="text-align: center;">
Front side</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://uploads.oshpark.com/uploads/project/top_image/FGK7AXJ8/thumb_i.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://uploads.oshpark.com/uploads/project/top_image/FGK7AXJ8/thumb_i.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Back side</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://uploads.oshpark.com/uploads/project/bottom_image/FGK7AXJ8/thumb_i.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://uploads.oshpark.com/uploads/project/bottom_image/FGK7AXJ8/thumb_i.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<a href="http://electronicsbyexamples.blogspot.ca/2014/02/hacking-disco-ball-part-2.html">In the next part of this article</a>, I'll give you an overview of the software involved in this project.</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-42654630867867529972013-11-13T20:54:00.003-05:002013-11-13T20:54:38.040-05:00Led matrix graphical user interface on the RaspberryPiYesterday, I plugged into my Raspberry Pi a little i2c <a href="http://www.adafruit.com/products/870" target="_blank">LED Matrix</a>. I wrote Python class to interact with it but I tought it would be really interesting to toggle the matrix's LED with a graphical user interface on the Pi itself. This is exactly what I done and you can take a look at the result in the following Youtube video:<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/cNHwP9B2BQc" width="560"></iframe>
<br />
<br />
To connections between the matrix and the Pi are really simple, you just need to connect 4 signals directly together : <b>GND, 3V3, DATA </b>and<b> CLK</b>. There is no need for pull-up resistor on the i2c clock and data lines, I presume the Pi already have them. The display is designed for 5V but it works really well at 3.3V.<br />
<br />
For using i2c on the Raspberry Pi, you need to make some little configurations and install the Python libraries. These steps are outlined on <a href="http://www.instructables.com/id/Raspberry-Pi-I2C-Python/" target="_blank">this Instructable tutorial</a>.<br />
<br />
You will also need the PyQt4 package, install it with:<br />
<b><span style="font-family: Courier New, Courier, monospace;">sudo apt-get install python-qt4</span></b><br />
<b><span style="font-family: Courier New, Courier, monospace;"><br /></span></b>
<span style="font-family: inherit;">The final Python script is listed below. The <i>LedMatrix</i> class is the i2c communication part of my program and <i>MatrixWidget</i> is the graphical user interface. The Qt windows part does essentially two things, it reacts to mouse press and draw an array of ellipse (the virtual LEDs).</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">If you have any questions with the code, just ask in the comments and I will be glad to help. Happy coding!</span><br />
<br />
<div class="highlight" style="background: #111111;">
<pre style="line-height: 125%;"><span style="background-color: #0f140f; color: #008800; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">sys</span>
<span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">smbus</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">SMBus</span>
<span style="color: #fb660a; font-weight: bold;">from</span> <span style="color: white;">PyQt4</span> <span style="color: #fb660a; font-weight: bold;">import</span> <span style="color: white;">QtGui,</span> <span style="color: white;">QtCore</span>
<span style="color: #fb660a; font-weight: bold;">class</span> <span style="color: white;">LedMatrix():</span>
<span style="color: white;">ADDRESS</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x70</span>
<span style="color: white;">OSCILLATOR_ON</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x21</span>
<span style="color: white;">BLINK_CMD</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x80</span>
<span style="color: white;">DISPLAY_ON</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x01</span>
<span style="color: white;">BLINK_2HZ</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x01</span>
<span style="color: white;">BLINK_1HZ</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x02</span>
<span style="color: white;">BLINK_HALFHZ</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0x03</span>
<span style="color: white;">BRIGHTNESS_CMD</span> <span style="color: white;">=</span> <span style="color: #0086f7; font-weight: bold;">0xE0</span>
<span style="color: white;">POS_X</span> <span style="color: white;">=</span> <span style="color: white;">(</span><span style="color: #0086f7; font-weight: bold;">128</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">4</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">16</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">32</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">64</span><span style="color: white;">)</span>
<span style="color: white;">POSn_X</span> <span style="color: white;">=</span> <span style="color: white;">(</span><span style="color: #0086f7; font-weight: bold;">127</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">254</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">253</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">251</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">247</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">239</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">223</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">191</span><span style="color: white;">)</span>
<span style="color: white;">POS_Y</span> <span style="color: white;">=</span> <span style="color: white;">(</span><span style="color: #0086f7; font-weight: bold;">7</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">2</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">3</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">4</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">5</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">6</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">__init__</span><span style="color: white;">(self,</span> <span style="color: white;">blink=</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">,</span> <span style="color: white;">brightness=</span><span style="color: #0086f7; font-weight: bold;">15</span><span style="color: white;">):</span>
<span style="color: white;">self.bus</span> <span style="color: white;">=</span> <span style="color: white;">SMBus(</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#device on i2c channel 1</span>
<span style="color: white;">self.bus.write_byte(self.ADDRESS,</span> <span style="color: white;">self.OSCILLATOR_ON)</span>
<span style="color: white;">self.bus.write_byte(self.ADDRESS,</span> <span style="color: white;">self.BLINK_CMD|self.DISPLAY_ON|(blink<<</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">))</span>
<span style="color: white;">self.bus.write_byte(self.ADDRESS,</span> <span style="color: white;">self.BRIGHTNESS_CMD|brightness)</span>
<span style="color: white;">self.clearBuffer()</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">setBrightness</span><span style="color: white;">(self,</span> <span style="color: white;">brightness):</span>
<span style="color: white;">self.bus.write_byte(self.ADDRESS,</span> <span style="color: white;">self.BRIGHTNESS_CMD|brightness)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">setBlinkRate</span><span style="color: white;">(self,</span> <span style="color: white;">blink):</span>
<span style="color: white;">self.bus.write_byte(self.ADDRESS,</span> <span style="color: white;">self.BLINK_CMD|self.DISPLAY_ON|(blink<<</span><span style="color: #0086f7; font-weight: bold;">1</span><span style="color: white;">))</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">setPixel</span><span style="color: white;">(self,</span> <span style="color: white;">x,</span> <span style="color: white;">y,</span> <span style="color: white;">state):</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">state:</span>
<span style="color: white;">self.buffer[self.POS_Y[y]]|=self.POS_X[x]</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">self.buffer[self.POS_Y[y]]&=self.POSn_X[x]</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">clearBuffer</span><span style="color: white;">(self):</span>
<span style="color: white;">self.buffer</span> <span style="color: white;">=</span> <span style="color: white;">[</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">]*</span><span style="color: #0086f7; font-weight: bold;">8</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">writeBuffer</span><span style="color: white;">(self):</span>
<span style="color: white;">data</span> <span style="color: white;">=</span> <span style="color: white;">[]</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">row</span> <span style="color: white;">in</span> <span style="color: white;">self.buffer:</span>
<span style="color: white;">data.append(</span><span style="color: #0086f7; font-weight: bold;">0</span><span style="color: white;">)</span>
<span style="color: white;">data.append(row)</span>
<span style="color: white;">self.bus.write_block_data(self.ADDRESS,</span> <span style="color: #0086f7; font-weight: bold;">0x00</span><span style="color: white;">,</span> <span style="color: white;">data)</span>
<span style="color: #fb660a; font-weight: bold;">class</span> <span style="color: white;">MatrixWidget(QtGui.QWidget):</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">__init__</span><span style="color: white;">(self):</span>
<span style="color: white;">super(MatrixWidget,</span> <span style="color: white;">self).__init__()</span>
<span style="color: white;">self.w=</span><span style="color: #0086f7; font-weight: bold;">20</span>
<span style="color: white;">self.setGeometry(</span><span style="color: #0086f7; font-weight: bold;">300</span><span style="color: white;">,</span> <span style="color: #0086f7; font-weight: bold;">300</span><span style="color: white;">,</span> <span style="color: white;">self.w*</span><span style="color: #0086f7; font-weight: bold;">10</span><span style="color: white;">,</span> <span style="color: white;">self.w*</span><span style="color: #0086f7; font-weight: bold;">10</span><span style="color: white;">)</span>
<span style="color: white;">self.setWindowTitle(</span><span style="color: #0086d2;">'Led Matrix'</span><span style="color: white;">)</span>
<span style="color: white;">self.clearPixelBuffer()</span>
<span style="color: white;">self.setFixedSize(self.width(),self.height())</span>
<span style="color: white;">self.leds</span> <span style="color: white;">=</span> <span style="color: white;">LedMatrix()</span>
<span style="color: white;">self.show()</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">clearPixelBuffer</span><span style="color: white;">(self):</span>
<span style="color: white;">self.buffer</span> <span style="color: white;">=</span> <span style="color: white;">[[</span><span style="color: #0086f7; font-weight: bold;">0</span> <span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">_</span> <span style="color: white;">in</span> <span style="color: white;">range(</span><span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">)]</span> <span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">_</span> <span style="color: white;">in</span> <span style="color: white;">range(</span><span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">)]</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">mousePressEvent</span><span style="color: white;">(self,</span> <span style="color: white;">QMouseEvent):</span>
<span style="color: white;">x</span> <span style="color: white;">=</span> <span style="color: white;">QMouseEvent.pos().x()</span>
<span style="color: white;">y</span> <span style="color: white;">=</span> <span style="color: white;">QMouseEvent.pos().y()</span>
<span style="color: white;">x</span> <span style="color: white;">=</span> <span style="color: white;">x/self.w-</span><span style="color: #0086f7; font-weight: bold;">1</span>
<span style="color: white;">y</span> <span style="color: white;">=</span> <span style="color: white;">y/self.w-</span><span style="color: #0086f7; font-weight: bold;">1</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">x==-</span><span style="color: #0086f7; font-weight: bold;">1</span> <span style="color: white;">or</span> <span style="color: white;">y==-</span><span style="color: #0086f7; font-weight: bold;">1</span> <span style="color: white;">or</span> <span style="color: white;">x==</span><span style="color: #0086f7; font-weight: bold;">8</span> <span style="color: white;">or</span> <span style="color: white;">y==</span><span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">:</span>
<span style="color: white;">self.clearPixelBuffer()</span>
<span style="color: white;">self.update()</span>
<span style="color: white;">self.leds.clearBuffer()</span>
<span style="color: white;">self.leds.writeBuffer()</span>
<span style="color: #fb660a; font-weight: bold;">return</span>
<span style="color: white;">pixel</span> <span style="color: white;">=</span> <span style="color: white;">self.buffer[x][y]</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">pixel:</span>
<span style="color: white;">self.leds.setPixel(x,</span> <span style="color: white;">y,</span> <span style="color: white;">False)</span>
<span style="color: white;">self.buffer[x][y]=</span><span style="color: #0086f7; font-weight: bold;">0</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">self.leds.setPixel(x,</span> <span style="color: white;">y,</span> <span style="color: white;">True)</span>
<span style="color: white;">self.buffer[x][y]=</span><span style="color: #0086f7; font-weight: bold;">1</span>
<span style="color: white;">self.update()</span>
<span style="color: white;">self.leds.writeBuffer()</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">paintEvent</span><span style="color: white;">(self,</span> <span style="color: white;">e):</span>
<span style="color: white;">qp</span> <span style="color: white;">=</span> <span style="color: white;">QtGui.QPainter()</span>
<span style="color: white;">qp.begin(self)</span>
<span style="color: white;">self.refresh(qp,</span> <span style="color: white;">e)</span>
<span style="color: white;">qp.end()</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">drawLed</span><span style="color: white;">(self,</span> <span style="color: white;">qp,</span> <span style="color: white;">x,</span> <span style="color: white;">y):</span>
<span style="color: white;">state</span> <span style="color: white;">=</span> <span style="color: white;">self.buffer[x][y]</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">state:</span>
<span style="color: white;">col</span> <span style="color: white;">=</span> <span style="color: white;">QtGui.QColor(</span><span style="color: #0086d2;">"#FFF71C"</span><span style="color: white;">)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#bright yellow</span>
<span style="color: #fb660a; font-weight: bold;">else</span><span style="color: white;">:</span>
<span style="color: white;">col</span> <span style="color: white;">=</span> <span style="color: white;">QtGui.QColor(</span><span style="color: #0086d2;">"#373511"</span><span style="color: white;">)</span> <span style="background-color: #0f140f; color: #008800; font-style: italic;">#dark yellow</span>
<span style="color: white;">qp.setPen(col)</span>
<span style="color: white;">qp.setBrush(col)</span>
<span style="color: white;">qp.drawEllipse(self.w+self.w*x,self.w+self.w*y,self.w-</span><span style="color: #0086f7; font-weight: bold;">3</span><span style="color: white;">,self.w-</span><span style="color: #0086f7; font-weight: bold;">3</span><span style="color: white;">)</span>
<span style="color: #fb660a; font-weight: bold;">def</span> <span style="color: #ff0086; font-weight: bold;">refresh</span><span style="color: white;">(self,</span> <span style="color: white;">qp,</span> <span style="color: white;">event):</span>
<span style="color: white;">qp.setBrush(QtCore.Qt.black)</span>
<span style="color: white;">qp.drawRect(event.rect())</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">y</span> <span style="color: white;">in</span> <span style="color: white;">range(</span><span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">):</span>
<span style="color: #fb660a; font-weight: bold;">for</span> <span style="color: white;">x</span> <span style="color: white;">in</span> <span style="color: white;">range(</span><span style="color: #0086f7; font-weight: bold;">8</span><span style="color: white;">):</span>
<span style="color: white;">self.drawLed(qp,</span> <span style="color: white;">x,</span> <span style="color: white;">y)</span>
<span style="color: #fb660a; font-weight: bold;">if</span> <span style="color: white;">__name__==</span><span style="color: #0086d2;">"__main__"</span><span style="color: white;">:</span>
<span style="color: white;">app</span> <span style="color: white;">=</span> <span style="color: white;">QtGui.QApplication(sys.argv)</span>
<span style="color: white;">ex</span> <span style="color: white;">=</span> <span style="color: white;">MatrixWidget()</span>
<span style="color: white;">sys.exit(app.exec_())</span>
</pre>
</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-29681363133590118012013-11-03T23:30:00.002-05:002013-11-03T23:30:35.320-05:00I'm back for the winterHi everyone, I suppose some of you noticed that I have been silent for a couple months now. I have been pretty this summer with work and sport. At the beginning of October, I also moved into my new house so I had to move my workbench and all my electronic stuff. That was a lot of work!<br />
<br />
Even if I have not posted any blog post, I have been working on a side project with a friend from Spain, Arrizen. The project is about domotics and you can learn more about it on our project website : <a href="http://arrizen.com/koollaborate/">Koollaborate</a>.<br />
<br />
Here is an excerpt from the website describing the project :<br />
<br />
<div style="text-align: center;">
<i>This project is about creating a home network of autonomous little sensor/actuator node called ‘Motes’. The Mote is a generic pluggable module comprising a brain (µController) and a communication module. The Motes are slaves to a central controller. Motes with different µC will be designed; they will share code librairies and projects should compile and work on the different architectures.</i></div>
<div style="text-align: center;">
<i><br /></i></div>
<div style="text-align: center;">
<i>The goal of this project is to provide a cheap module for home automation that you can program to your will and make it communicate information. It will help someone focus on the project he wants to do and not designing controllers board over and over.</i></div>
<br />
<br />
Domotics is a subject that interests me a lot because it involves electricity, electronics, programming, human machine interface, communication protocols, internet, servers...<br />
<br />
For an house to be intelligent, it needs to be able communicate information to you, even if you are not home. In the next article, I will show you how to use the Python programming language to send emails and text messages on your cellphone.Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-48965316866493735962013-06-18T22:19:00.000-04:002013-06-22T08:30:22.280-04:00Switching AC loads with the TRIAC<div style="text-align: justify;">
Often in electronics, you need to switch loads (motors, lights, solenoids...) ON and OFF from a microcontroller's pin or the output of a low-voltage electronic circuit. When you are working with DC sources, a transistor gets the job done : you supply a voltage at the base/gate pin and current will flow from a higher voltage source at the collector/drain pin to the emitter/source pin (for NPN/N-Channel depending if the transistor is Bipolar/MOSFET). The problem with the transistor solution is that its current flow cannot be reversed. It's alright in most situation, but that won't let you work with AC loads.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The two most common way to switch an AC load is to use a mechanical relay or a TRIAC. The relay is easy to use, but has the disadvantages of being slow and consuming a lot of current (to keep the coil energized). Due to the fact that the relay contacts are mechanical, they will also wear out over time and make switching noise. On the other hand, the TRIAC is a small solid-state device that can switch really fast, hence you can use it to dim lights, control motors speed and heating elements. In fact, the TRIAC is used in recent digital electronics thermostats to regulate the power of a heater.</div>
<div style="text-align: justify;">
<br /></div>
<h2>
TRIAC overview</h2>
<div>
The TRIAC is a 3-pin semiconductor device that can let current flow from his main terminals in either direction. Some people describe its behaviour similar to 2 thyristors in antiparallel configuration.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Q_bhicaxpB4kgzhLJkhcU-cER6GJT80bpU3W31RzOlYFRbijl04Yn5b6wVqNAxF7wNjwqUXfywlzSl0hD9-E3lkPzD4lKLedfm3AViEvcUGF4NxxkRV9dmrx19t0mkewrMSA1cpOgam9/s1600/TRIAC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Q_bhicaxpB4kgzhLJkhcU-cER6GJT80bpU3W31RzOlYFRbijl04Yn5b6wVqNAxF7wNjwqUXfywlzSl0hD9-E3lkPzD4lKLedfm3AViEvcUGF4NxxkRV9dmrx19t0mkewrMSA1cpOgam9/s200/TRIAC.png" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
When choosing a TRIAC for your application, take a look at its absolute maximum electrical ratings. The peak voltage (not RMS) of your AC source must be lower than the allowed peak maximum off-state voltage of the TRIAC datasheet. For a 120VAC source, this datasheet value should be higher than 170 volts (Vrms * sqrt(2)). There is also the RMS on-state current and the non-repetitive peak on-state current. Usually, just ensure that the average current of your load is below the RMS on-state current written in the datasheet.</div>
<br /></div>
<h2>
Triggering the TRIAC</h2>
<div>
To trigger a TRIAC (let current flow between T1 and T2) you need to send a pulse on the gate with respect to the T1 terminal. When you read about TRIAC theory, you can see there is 4 different triggering modes (the four quadrants). All this means is that you can send a positive/negative pulse on the gate while T2 is positive/negative with T1 as the reference. Anyway, you don't really have to care about that to try the following circuits.</div>
<div>
<br /></div>
<div>
Keep in mind that once triggered, a TRIAC will continue to conduct until the current between its terminal drop below its holding current that can be found in its datasheet (a couple of milliamps for small TRIACs). This means that it will stop conducting at the end of the AC cycle, when there is no more voltage difference between hot and neutral (zero crossing). However, if you put DC voltage across the TRIAC terminals, it will conduct indefinitely; or until you cut the wire/shut the power off :)<br />
<br /></div>
<h3>
#1 - With a single AC source</h3>
<div>
If you want to test if a TRIAC works and mess around with it, this is a simple way to wire it as it only requires a single AC source. I don't really think this circuit is useful unless you want to turn on an AC load by pressing or flipping a switch. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdU1e5fkKuWnJ8m0qczA4BtB6NSwYoOd-9qDWibzgASTX6PoOQRI4UCYO-UclHUbshD5QDaGryjOtrFE6Xjh-Uh55tk1NYHfwN5NfMWdhmF66bzkDxFnSrAz6glrgOeLbkIuAARONuTkC2/s1600/ss.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdU1e5fkKuWnJ8m0qczA4BtB6NSwYoOd-9qDWibzgASTX6PoOQRI4UCYO-UclHUbshD5QDaGryjOtrFE6Xjh-Uh55tk1NYHfwN5NfMWdhmF66bzkDxFnSrAz6glrgOeLbkIuAARONuTkC2/s1600/ss.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
<h3>
#2 - With a DC signal</h3>
</div>
<div>
Here's a more interesting way to trigger a TRIAC. With this configuration, you can use an external low voltage DC signal to control an AC load. You have to watch out with this circuit because you have to tie the neutral of your AC source with the ground of your DC subsystem. I would not recommend this configuration with costly development board to control the TRIAC. It is also possible that noise could be injected in analogs part of your circuits, resulting in poor performances (e.g. ADC, op-amps...).</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS_5OxU8n3yPXnehIglI299JFyXVrdrgK92eLdtMPXvPHPCqGiwYSoRiiK_1YtKH8OdYfqQdU87vaGWCklwdraLbL8KMQ3jZ4jZXBMOKqE8ks-P40bxmsnvUh2ef7pzI-1EiiblaQqczc-/s1600/dual.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS_5OxU8n3yPXnehIglI299JFyXVrdrgK92eLdtMPXvPHPCqGiwYSoRiiK_1YtKH8OdYfqQdU87vaGWCklwdraLbL8KMQ3jZ4jZXBMOKqE8ks-P40bxmsnvUh2ef7pzI-1EiiblaQqczc-/s320/dual.jpg" width="320" /></a></div>
<br /></div>
<div>
<h3>
#3 - With a phototriac (opto-isolator)</h3>
</div>
<div>
In my humble opinion, the best and safest way to trigger a TRIAC would be to use a phototriac. It consist of using a chip that isolate the DC part of your circuit from the AC part. If you look closely to the right part of the circuit, it is almost the same as the first configuration we saw instead that the switch has been replaced by another TRIAC. The other TRIAC (phototriac) is triggered by the photodiode that is coupled with it in the chip package. In short, you only have to turn on the photodiode and the main TRIAC will be conducting, thus providing current to your AC load.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR_x9_dPlol6BRJNYdfYVl4hhKiJu5S5Ea8pF38bkFNHLr_QwuaFmXz2G8smykX7TH5RkbY4HFXFQ1n0F_2vo0gyU-rXRIebOQekOJGR68jmw8A7V4cT4FzT5R6jmgrBDTE3yynPjlK45J/s1600/triac_circuit2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR_x9_dPlol6BRJNYdfYVl4hhKiJu5S5Ea8pF38bkFNHLr_QwuaFmXz2G8smykX7TH5RkbY4HFXFQ1n0F_2vo0gyU-rXRIebOQekOJGR68jmw8A7V4cT4FzT5R6jmgrBDTE3yynPjlK45J/s400/triac_circuit2.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
There is two kind of phototriacs : the ones with zero crossing circuit and the ones who don't. Phototriacs like the MOC3041 and the MOC3062 have an internal protection circuit that will not let you switch the main TRIAC on until the AC voltage is at the beginning of its cycle. This will prevent you to put a high voltage (middle of cycle) directly on the load as it could create a high in-rush current or excessive electrical noise. Phototriacs like the MOC3023 does not have this kind of protection. In a lot of applications, you won't really care about that.</div>
<div>
<br /></div>
<h2>
Conclusion</h2>
<div>
If you want to try the different configurations above, ensure your load current is okay with the maximum current through your TRIAC. For the triggering resistor, choose it so the current through the gate is above the gate trigger current in the datasheet, just use Ohm's law. <span style="color: #ffe599;">Please experiment with caution if you use mains electricity. When I tested the circuits above, I used a small 1.5W 120VAC to 12VAC open frame transformer like the one below so I could put my finger in the circuit without fearing an electrical shock or burning down the house.</span></div>
<div>
<span style="color: #660000;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRMKeDB7aIOY3UNKoMKw8kAh2O6ZUc4UfvXRh3Ri3FXmxiQAj8IOjoleTSLG8zP7HTdt8TN3YR2p9tW9FtLAUqaw_WK9gT7JhJw2RF5yKVPm1guap2K-gPKtMrOJFfSLTMnsbNYPLwBpd0/s1600/$(KGrHqR,!h4FDiuI0)K6BR!D3IFY6w~~60_12.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRMKeDB7aIOY3UNKoMKw8kAh2O6ZUc4UfvXRh3Ri3FXmxiQAj8IOjoleTSLG8zP7HTdt8TN3YR2p9tW9FtLAUqaw_WK9gT7JhJw2RF5yKVPm1guap2K-gPKtMrOJFfSLTMnsbNYPLwBpd0/s200/$(KGrHqR,!h4FDiuI0)K6BR!D3IFY6w~~60_12.JPG" width="200" /></a></div>
<div>
<span style="color: #660000;"><br /></span></div>
<div>
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com6tag:blogger.com,1999:blog-582219234592513124.post-37316906021356026452013-05-12T11:55:00.001-04:002013-05-13T16:48:39.716-04:00Adjustable constant current source (1A@12V)The goal with a voltage source is to supply a load with a constant voltage. However, if the impedance of the load varies, the load current will vary too. For some reasons, if you need a constant current through a load, you will need a current source. A current source will sense the current through a load and adjust the voltage across it to keep that current constant. Take a look at the standard sources symbol:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRqXIrIQjotQypshf3IZ348F2EPjIO-8CdhpWBEAvUa5xvgw5icp1kRqyGZAC373shs_F4VIMzS-wz1zJ1hPHFjjtA0y3MZM3V3_2lWX3DP0P6Q54L_3BfU5GqlrpSdH2KUG0cFnLLw_B6/s1600/sources.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRqXIrIQjotQypshf3IZ348F2EPjIO-8CdhpWBEAvUa5xvgw5icp1kRqyGZAC373shs_F4VIMzS-wz1zJ1hPHFjjtA0y3MZM3V3_2lWX3DP0P6Q54L_3BfU5GqlrpSdH2KUG0cFnLLw_B6/s320/sources.png" width="320" /></a></div>
<br />
Constant current sources can be useful in different situations, like DC motor control. For a DC motor, the torque is proportional to its current; this means that we can effectively achieve constant torque control with a current source. Another example is battery charging, some of them require to be charged at a constant current rate. They are also convenient to supply a constant current to a load that is highly dependent to temperature.<br />
<br />
I have been searching for a while for an adjustable current source circuit and I think the following one is quite simple and reliable. It works with a single operational amplifier in negative feedback configuration. I added a second op-amp to make a voltage comparator with the potentiometer. It's used to light up the orange LED to indicate when the potentiometer is over 80% turned on (that is, >0.8A when the current source is shorted); this helps me remind that the components may be hot! I also placed a green LED in series with the 12V voltage supply to indicate when the circuit is working.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikhAAkZZaxMbPC8D4rnQp-w3Jnts78a-CcW8l-DhQ2Z-9aCkN7LKnl0F1zJ4hbEzTHv62-5Gs4YzJ8oTJNK6_ZmULwmPdhEBctXRcHKLsbMciXaXoHsShlGoloMCOxF-_9SFtj_WhQZgjY/s1600/current_source_schem.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="293" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikhAAkZZaxMbPC8D4rnQp-w3Jnts78a-CcW8l-DhQ2Z-9aCkN7LKnl0F1zJ4hbEzTHv62-5Gs4YzJ8oTJNK6_ZmULwmPdhEBctXRcHKLsbMciXaXoHsShlGoloMCOxF-_9SFtj_WhQZgjY/s640/current_source_schem.jpg" width="640" /></a></div>
<br />
Here is the principle of operation of the op-amp current source (only the upper op-amp is used for the source):<br />
<br />
<br />
<ul>
<li>The 5k potentiometer (R4) let you feed the non-inverting input terminal (+) with a voltage from 0-12V</li>
<li>The op-amp in negative feedback tries to keep (by adjusting its output voltage) the voltage at the inverting (-) and non-inverting (+) terminal the same</li>
<li>The output terminal of the op-amp will automatically drive the base pin of the PNP transistor so that the voltage at its emitter pin will stay the same as the potentiometer voltage</li>
<li>The current sense resistor (R5) will see 12V minus the potentiometer voltage across it (V<span style="font-size: xx-small;">R5</span> = 12 - V<span style="font-size: xx-small;">pot</span>)</li>
<li>With ohm's law, you can easily find the current supplied (V<span style="font-size: xx-small;">R5</span> / 10)</li>
</ul>
<div>
<br /></div>
<div>
The maximum current that will be supplied by the current source will be about 1.2A (12V / 10Ω). If we consider the voltage loss in the Darlington TIP107, it will be more around 1A. </div>
<div>
<br /></div>
<div>
<i><b>With a 10Ω current sense resistor, this circuit is rather inefficient (lot of power dissipated). The reason why I did it like that is because I wanted the circuit to be safe when shorted. Normally, the current sense resistor is much lower (about 10 times and up).</b></i></div>
<div>
<i><b><br /></b></i></div>
<div style="text-align: center;">
<div style="text-align: left;">
For fun, I soldered the circuit on a perforated board. The red and black binding post are the load terminals. The 12V is supplied to the little blue terminal block. The TIP107 is supposed to be able to carry 8A but I realized that even at 1A, it was getting awfully hot; i then decided to put an heatsink on its back. If you make a similar circuit, beware of the current sense resistor too! I burned one of my finger on it <span style="font-size: large;">☻
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYjNvyxFpzWQzKlVaJU5DlC1GsruHhPYHgPTwm8jbKhXtTxEfsr3HioEKN1BbJxleNo50nUPbK6QTdqln4IqK00-1VBO7dXjOFUA5mTdI0FbWA_5UJJAVTBLYt5P84wrodLYw8G9a1EXxE/s1600/img1.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYjNvyxFpzWQzKlVaJU5DlC1GsruHhPYHgPTwm8jbKhXtTxEfsr3HioEKN1BbJxleNo50nUPbK6QTdqln4IqK00-1VBO7dXjOFUA5mTdI0FbWA_5UJJAVTBLYt5P84wrodLYw8G9a1EXxE/s400/img1.bmp" width="400" /></a></div>
<br />
<div style="text-align: center;">
On the picture above, the load terminals are shorted with an hidden wire. The IC in the center is the dual op-amp (OPA2241). The strange looking component is the power resistor (brown devil from Ohmite), it's in ceramic with a flame resistant coating. There is a lot of soldering under the perf board!</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyiU2D4ngt1s9RKqOPidffdWHJC1pYl3JLpk1t6lXL9w5w9eMIc0mC9wBsieb1fCTKYAWeo5xKmXi4XvNmmu0ZVuFBMLMCENf8Ojxr7ieiSqv6USglFVV13jOY3IoTHGAYyKbTobOH4I9-/s1600/img2.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyiU2D4ngt1s9RKqOPidffdWHJC1pYl3JLpk1t6lXL9w5w9eMIc0mC9wBsieb1fCTKYAWeo5xKmXi4XvNmmu0ZVuFBMLMCENf8Ojxr7ieiSqv6USglFVV13jOY3IoTHGAYyKbTobOH4I9-/s400/img2.bmp" width="400" /></a></div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="background-color: white; font-family: sans-serif; font-size: 26px; line-height: 19.1875px; text-align: center;"><br /></span></div>
<div>
<span style="background-color: white; font-family: sans-serif; font-size: 26px; line-height: 19.1875px; text-align: center;"><br /></span></div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com2tag:blogger.com,1999:blog-582219234592513124.post-23502980056161732392013-05-04T15:20:00.002-04:002013-05-09T14:10:42.450-04:00Microprocessors part 2 - Instruction set and programmingThe PicoBlaze is one of the simplest processor to program in assembly language. Thanks to its RISC (<a href="http://en.wikipedia.org/wiki/Reduced_instruction_set_computing" target="_blank">Reduced Instruction Set Computing</a>) architecture. A RISC processor only have a few instructions (about 20 of them), compared to a CISC (<a href="http://en.wikipedia.org/wiki/Complex_instruction_set_computing" target="_blank">Complex Instruction Set Computing</a>) processor. Having less instructions means that they can be packed at a higher density (because of the <a href="https://en.wikipedia.org/wiki/Opcode" target="_blank">opcode</a> length), thus requiring a smaller program memory. Moreover, it's easier to learn!<br />
<br />
<i>The PicoBlaze has been created by Ken Chapman from Xilinx and you can find an excellent and comprehensive documentation on the processor from <a href="https://www.google.ca/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&ved=0CC0QFjAA&url=http%3A%2F%2Fwww.xilinx.com%2Fsupport%2Fdocumentation%2Fip_documentation%2Fug129.pdf&ei=pSOFUb7ZJMep0AGpp4HYBQ&usg=AFQjCNExPNTfQAXhd79LBXna8xed2rm5Og&sig2=1pCxg0BaDfPKTu8paXCiCw&bvm=bv.45960087,d.dmQ" target="_blank">Xilinx's User Guide 129 (UG129)</a>. I suggest you get it now.</i><br />
<br />
<h2>
Instructions groups</h2>
<div>
Before doing some programming, let's talk a little bit about the purposes of the PicoBlaze instructions and group them by category.</div>
<div>
<br /></div>
<h3>
Arithmetic</h3>
<div>
These instructions are used to make simple calculations. It is possible to use them in a loop to perform more complex operation like multiplication, division, square root, power... The carry (added C) variant is used to make calculations on numbers larger than a byte (255). These operations modify the processor flags, more on that in a moment.</div>
<div>
<ul>
<li>ADD</li>
<li>ADDC</li>
<li>SUB</li>
<li>SUBC</li>
</ul>
</div>
<br />
<h3>
Logic</h3>
<div>
These logic instructions are used to perform <a href="https://en.wikipedia.org/wiki/Bitwise_operation" target="_blank">bitwise operations</a> on two bytes. They are often used to set, clear or toggle bits. This is done with a technique called <a href="http://en.wikipedia.org/wiki/Mask_(computing)" target="_blank">masking</a>; I'll give you some example in a next article on microprocessors programming.</div>
<div>
<ul>
<li>AND</li>
<li>OR</li>
<li>XOR</li>
</ul>
<div>
<br /></div>
</div>
<h3>
Bit manipulation</h3>
<div>
To perform operation at a bit level, it is often useful to<a href="https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts" target="_blank"> shift (or rotate)</a> the bits in a byte. Shifting to the left or right can be useful for multiplication or division by a multiple of 2 (see binary number mathematical property). Often, when doing IO or mathematical operations, the bits you want to manipulate are located at the wrong position in the byte; you can solve the problem with these instructions. There is a subtle difference between shifting and rotating. When rotating, the bit that is pushed out of the byte (either 1 or 0) is fed back at the empty position. While shifting, that pushed bit is lost and the empty position is replaced either by a 1 or 0, depending if you use S?1 or S?0, respectively. </div>
<div>
<ul>
<li>RL / SL0 / SL1</li>
<li>RR / SR0 / SR1</li>
</ul>
<div>
<br /></div>
</div>
<h3>
Testing</h3>
<div>
These two operation (especially COMP) are essential to create conditionals. But before, you need to understand the <a href="http://en.wikipedia.org/wiki/Flag_word" target="_blank">processor flags</a>. In the PicoBlaze, there is 2 status flag bits, ZERO (Z) and CARRY (C). The ZERO flag bit is set when the result of the last operation is zero. The CARRY flag bit is used to indicate various conditions, often used to signal a overflow/underflow condition while adding or subtracting. Back to our instructions... COMPare is used like a dummy SUB operation. The two bytes are subtracted (result not written back): if the Z flag is set, the numbers were equal; if the C flag is set, we know which number was greater than the other. The TEST instruction is a bit less used. It works like a dummy AND, the two numbers are "ANDed" together. If the result is zero, the Z flag is set. If there is a odd number of 1 bit in the resulting byte, the C flag is set (this is used to <a href="http://en.wikipedia.org/wiki/Parity_bit" target="_blank">check the parity</a>).<br />
<br /></div>
<div>
<ul>
<li>COMP</li>
<li>TEST</li>
</ul>
<div>
<br /></div>
</div>
<h3>
Memory manipulation</h3>
<div>
The LOAD instruction is used to move a register/constant value in another register. The FETCH and STORE instruction are used respectively to get data from scratchpad RAM into a register and put a register value into the scratchpad RAM. These operations are useful because you can reserve RAM or register address for a certain purpose and often, you need to move data to/from them.</div>
<div>
<ul>
<li>FETCH</li>
<li>STORE</li>
<li>LOAD</li>
</ul>
<div>
<br /></div>
</div>
<h3>
Program redirection</h3>
<div>
The last piece of the puzzle, program <a href="http://en.wikipedia.org/wiki/Control_flow" target="_blank">flow control</a>. The CALL/RETurn statements are used to describe functions that are called multiple times during the program lifetime (examples: doing a complex mathematical operation or getting a scaled value from a sensor). The inner working if these two instruction is simple: when CALL is executed, the address of the next instruction is <b><u>push</u>ed</b> on a special memory space called <a href="http://en.wikipedia.org/wiki/Stack_(abstract_data_type)" target="_blank">the stack</a>. The program flow then branch to the function and execute it until the RET instruction is encountered; the return address is then <b><u>pop</u>ped</b> from the stack into the program counter (remember? the register that hold the value of the address of the current instruction). <a href="http://en.wikipedia.org/wiki/Stack_(abstract_data_type)" target="_blank">The stack</a> allow multiple CALL to be nested. The JUMP instruction is often used with conditionals, where some instructions can be skipped depending of the current Z and C flags value.</div>
<div>
<ul>
<li>CALL</li>
<li>RET</li>
<li>JUMP</li>
</ul>
<div>
<br /></div>
</div>
<h2>
Hello, PicoBlaze!</h2>
<div>
Enough theory, let's run the IDE and write some code (very small executable file, <a href="https://www.dropbox.com/s/r1offq82v12uotc/pBlazIDE.exe" target="_blank">download it here</a>). If you are using Linux, it works well under <a href="https://en.wikipedia.org/wiki/Wine_(software)" target="_blank">Wine</a>. More info is available on <a href="http://www.mediatronix.org/pages/pBlazIDE" target="_blank">Mediatronix's website</a>, the maker of the IDE.</div>
<div>
<br /></div>
<div>
Our first PicoBlaze program will be simple and not really useful. Though it's great for learning purpose. We are going to write the number 0 to 63 in the 6-bit scratchpad RAM, backward! The picture below is the simulation result of the program (you can see the hexadecimal numbers in the ScratchPad0 debug area):</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjonGSlStSOfjj0ZtZ1JrnvbCzEtsJA8wu1rpgusgRP7EFiJarH5EeJxRPVZD9Z-vd9Q9gjfT1cQQckDk0JmlevEJMDrHanpkx9HKqr8AxKWbPRnIpFvJNMc1wxFdHgz2etCb5j0R-irn0W/s1600/pico.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjonGSlStSOfjj0ZtZ1JrnvbCzEtsJA8wu1rpgusgRP7EFiJarH5EeJxRPVZD9Z-vd9Q9gjfT1cQQckDk0JmlevEJMDrHanpkx9HKqr8AxKWbPRnIpFvJNMc1wxFdHgz2etCb5j0R-irn0W/s1600/pico.png" /></a></div>
<div>
<br /></div>
<div>
<span style="color: red;">Before using the program, choose Picoblaze 3 in Settings (shortcut Ctrl+3). This is important! If you don't select this option, my sample code will not compile. Take a look in the bottom left corner of the window above, you should see Mode: Picoblaze-3.</span><br />
<br />
The pBlazIDE is used to write the PicoBlaze program and simulate it in a convenient environment. When you open the IDE, you can either create a new project (Ctrl+N) and write the above program or just <a href="https://www.dropbox.com/s/g2htis8pnzbgb9a/hello.psm" target="_blank">download mine</a> and open it (Ctrl+O). When it's done, click the Assemble & Simulate (F12) button. The simulation mode is really cool because you can view the flags status, content of the registers, scratchpad memory, IO, etc... When you are in simulation, run (F9) the program, then pause it with the red button at the right (the one at the left is used to reset the simulation). You should be able to see the content of the ScratchPad0 area filled up.</div>
<div>
<br /></div>
<div>
Let's review the code line by line:</div>
<div>
<ol>
<li>The EQU keyword is used to assign a name to a register/constant value (this is optional). The TOTAL_RAM label will be used to represent the decimal value 64 (the total number of RAM register address).</li>
<li>The register s0 will be used to store the count from 64 to 0. Let's name it that way.</li>
<li>The ORG keyword is used to select the starting address of the following instructions. We put our program at the beginning of the program memory (address 0).</li>
<li>The keywords followed by a colon are called label. It is conventional to name the address of our first instruction (Main:).</li>
<li>The LOAD instruction is used to move a value into a register. In this case, we move 64 in the s0 register. Instead of using the EQU directive, we could have explicitly written LOAD s0, 64.</li>
<li>The Loop: label is used to reference the address of the SUB and following instructions that we will repeat 64 times in a loop.</li>
<li>Each time we go through the loop, we subtract 1 from the count register (s0). When the result of the subtraction will be 0, the Z flag will be set.</li>
<li>We want to fill the RAM so we store the count value at the count address with the STORE instruction. The first time 63 (3F) will be written at address 63 (3F). At the end, 0 will be written at address 0. This is why it counts backward :)</li>
<li>While the Z flag is not set, the JUMP NZ, will go back to the Loop label address. When the SUB instruction result will update the Z flag, this JUMP instruction won't be executed. Read the instruction like it were JUMP (if) NotZero.</li>
<li>The two following lines are used to create an infinite loop that JUMP on itself. In a real life situation it is important to stop the execution of the program in a certain way because it will continue to execute the bits in memory in a unpredictable way.</li>
</ol>
<div>
Please note that I changed the color setting of the IDE syntax. In the picture above, there is 5 orange instructions (LOAD, SUB, STORE, JUMP, JUMP). These instructions are what is written in the program memory. Everything else is directives and labels. Once assembled with the pBlazASM.exe utility (you can find it on the website mentioned above), the binary that goes into the program memory is reduced to (in hexadecimal):</div>
</div>
<div>
<br /></div>
<div>
<div>
<i>00040</i></div>
<div>
<i>1C001</i></div>
<div>
<i>2F000</i></div>
<div>
<i>35401</i></div>
<div>
<i>34004</i></div>
</div>
<div>
<br /></div>
<h2>
Conclusion</h2>
<div>
I hope that you found this article interesting and you learned new stuff. I would like that you guys try to create a simple program or modify mine (using information in UG129) and play around with the IDE. Send me your experiments on my email address: fred_blais5(at)hotmail.com and I would be glad to showcase some of your programs in a next article. Also, don't hesitate to write programming ideas in the comment section, I'm all ears!</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com1tag:blogger.com,1999:blog-582219234592513124.post-55680850472185270112013-04-20T21:52:00.000-04:002014-12-30T14:58:29.284-05:00Microprocessors part 1 - IntroductionThe microprocessor has evolved a lot in the past 40 years since its debut in November 1971, with the Intel 4004 chip. Nowadays, we have a huge amount of different processing units to do electronics, control systems, robotics, etc...<br />
<br />
The microprocessor can be seen has a large electrical circuit that can be serve a lot of different purposes and that needs to be supplied with a "binary file" of instructions to execute. The piece of silicon that doesn't change (microprocessor) is called <b>hardware</b>. The supplied binary code is called the <b>software</b>. By definition, <b>hardware is fixed</b> and <b>software can be modified </b>(with programming). I want to emphasize that point because I'll come back to that when discussing soft-core and hard-core in a FPGA. Throughout this article, I'll give practical examples with the PicoBlaze processor, which is a very simple soft processor core.<br />
<br />
<h2>
Computer bus</h2>
A bus in computing can be seen as a kind of highway for data. This highway can have several lanes (<b>parallel bus</b>) or the cars can line up one after the other (<b>serial bus</b>). This highway connects the different sub-systems of the computer. To show you the importance of device interconnect/communication here are some examples of common wired interface:<br />
<br />
<h4>
Peripheral</h4>
<div>
<ul>
<li>USB (Universal Serial Bus)</li>
<li>RS-232</li>
<li>FireWire</li>
<li>Thunderbolt</li>
</ul>
<h4>
Printed circuit board</h4>
</div>
<div>
<ul>
<li>I²C (Inter-Integrated Circuit)</li>
<li>SPI (Serial Peripheral Interface)</li>
<li>1-Wire</li>
<li>PCI (Peripheral Component Interconnect)</li>
<li>AGP (Accelerated Graphics Port)</li>
</ul>
<h4>
Network</h4>
</div>
<div>
<ul>
<li>Ethernet</li>
<li>CAN (Controller Area Network)</li>
<li>RS-485</li>
</ul>
<h4>
Video</h4>
</div>
<div>
<ul>
<li>VGA (Video Graphics Array)</li>
<li>HDMI (High-Definition Multimedia Interface)</li>
<li>DVI (Digital Visual Interface)</li>
</ul>
</div>
<h4>
Hard drive</h4>
<div>
<ul>
<li>SATA (Serial Advanced Technology Attachment) </li>
<li>IDE (Integrated Drive Electronics)</li>
</ul>
</div>
<h4>
Internal IC buses</h4>
<div>
Even more important for today discussion, there is a lot of different buses inside integrated circuits to connect the different memories/caches to the processing unit and the inputs/outputs.</div>
<div>
<br /></div>
<h2>
Program memory</h2>
<div>
The program memory is where the microprocessor program instructions are stored. This memory has a fixed width that matches the computer instruction width. It is sometimes considered as a ROM (Read-only Memory) because the program storage don't change while the processor is running. Here is an excerpt of the 18-bit PicoBlaze instruction set; that is, available instructions opcode understood by the processing unit.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlGWusi63JonOs-eDK5LP64xb9S3ecBzI6oTfeiHsQUspxbko1OuQtznDFwrR1pXTWMzBamsRA0rySUlIsbs2wNMeyyF4dfkSqnq2HT8jjr8GmdS82E4-mNZNgHo2Cs1FjCEv0Xu0q4ybU/s1600/opcode.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlGWusi63JonOs-eDK5LP64xb9S3ecBzI6oTfeiHsQUspxbko1OuQtznDFwrR1pXTWMzBamsRA0rySUlIsbs2wNMeyyF4dfkSqnq2HT8jjr8GmdS82E4-mNZNgHo2Cs1FjCEv0Xu0q4ybU/s400/opcode.jpg" height="372" width="400" /></a></div>
<div>
<br /></div>
<h2>
Data memory</h2>
<div>
The data memory is used to store temporary data/variables. This kind of memory is also called the RAM (Random-Access Memory). You can see it like a kind of scratchpad area, where you can make some calculations on it and retrieve it later for other uses. Some CPU can process RAM directly, some others using the Load/Store Architecture have to switch this data back and forth in their internal registers to process it.<br />
<br /></div>
<h2>
Harvard versus Von Neumann architecture</h2>
<div>
There is basically two kind of architecture to access memories. The Harvard architecture can access the program and data memory independently because it has two distinct buses to access them. In the Von Neumann architecture, the program and data memories share a single datapath. With a single memory bus, the processor will be less complex, but will also be slower than with separate buses. The Harvard architecture is mainstream now because of the <a href="http://en.wikipedia.org/wiki/Von_Neumann_architecture#Von_Neumann_bottleneck" target="_blank">Von Neumann Bottleneck</a>.</div>
<br />
<h2>
CPU</h2>
<div>
The CPU (Central Processing Unit) is where everything is processed in a computer. Let's take a look at the internals schematics of the 8-bit PicoBlaze core:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5Tjvw1GLHRr1OiZ44M9HF16Lk1Oi4dAIxRmyr-7HKJwF3zq-HbDOjs6xeUEHdIBZQp6PIZjolKzoGKJMU3lu-W4ULCf5uEPh6S4fYqUx2dRkl1Xhx-0UqwDp3zQNSkh4nu8a9LdkZRLFz/s1600/core.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5Tjvw1GLHRr1OiZ44M9HF16Lk1Oi4dAIxRmyr-7HKJwF3zq-HbDOjs6xeUEHdIBZQp6PIZjolKzoGKJMU3lu-W4ULCf5uEPh6S4fYqUx2dRkl1Xhx-0UqwDp3zQNSkh4nu8a9LdkZRLFz/s640/core.jpg" height="305" width="640" /></a></div>
<br />
At the top-left corner, there is the program memory. In this case, it's limited to 1024 18-bit instructions. The next block at the right is a small 10-bit pointer register called the PC (Program Counter). It is used to store the address of the next instruction to be executed. It can address all the 1024 instruction because it is 10 bits wide (2^10=1024). In the PicoBlaze, there's a quite small amount of RAM, only 64 bytes. There is however 16 registers that you can use for general purposes.<br />
<br />
The CPU specific components in this schematics are the registers, PC, instruction decoder, buses and the ALU (Arithmetic Logic Unit). The ALU is the heart of the CPU, it's used to process the data that are brought to it by the different buses. You can see that it has 2 input buses and one output bus that work in conjunction with the registers. Everything that has to be processed has to be in the registers and is stored back in the registers. That it why it's a Load/Store Architecture core, there is no direct access between the ALU and the RAM. By the way, that PicoBlaze has a separate bus for instructions and data (as you can see above), so it's an Harvard processor.<br />
<br />
The big arrows at the far left and right of the schematic is the interrupt line and the IO. It is what allow the PicoBlaze to talk and interact with the external world, like sensors and actuators.<br />
<br />
<h2>
MCU (µC)</h2>
</div>
<div>
A last thing I would like to discuss about is MCUs (Microcontroller Unit). A microcontroller contains all we've talked about previously on a single chip. They are mostly used in embedded systems, where they do repetitive tasks in a reliable way.</div>
<div>
<br /></div>
<div>
In contrast, personal computers have a motherboard with separate components : CPU, GPU, RAM, hard drives, etc. They have much larger memories and faster clock frequencies.</div>
<div>
<br /></div>
<div>
The advantages of µC are their low cost and small power consumption. They're all around and you don't even see them; watches, Bluetooth headset, keyboard/mouse, microwave oven, remote control, digital photo frame, radio...</div>
<div>
<br /></div>
<h2>
Conclusion</h2>
<div>
<a href="http://electronicsbyexamples.blogspot.ca/2013/05/microprocessors-part-2-instruction-set.html">In the next part of this article</a>, I'll write a little tutorial on PicoBlaze ASM programming and you will be able to simulate it on your computer!</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-87695359889156075282013-04-14T18:53:00.000-04:002013-04-14T18:53:11.653-04:00Digital Systems Part 4 - Decoder for 7-segment displayIn one of my latest post about digital systems, I talked about the different types of combinational circuits. Let's take some time to discuss about the decoder and one of it's most widely known utilization: driving a seven segment display.<br />
<div>
<br /></div>
<h2>
The seven-segment display</h2>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyapVTqv2Jhyphenhyphen-B0cl0w0hH66eODob-ubJkheyDGR5MPNqcxo0F3_Eus7uAEhF39engqTv0E_AEFTcCgrOYy7_KtRjjJlienUZxaI6RRZ1x_LRAiixTyfKn3X9eS4jyqrMwyR6XTkIyJWJi/s1600/7-segments_Indicator.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyapVTqv2Jhyphenhyphen-B0cl0w0hH66eODob-ubJkheyDGR5MPNqcxo0F3_Eus7uAEhF39engqTv0E_AEFTcCgrOYy7_KtRjjJlienUZxaI6RRZ1x_LRAiixTyfKn3X9eS4jyqrMwyR6XTkIyJWJi/s1600/7-segments_Indicator.gif" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
It is likely that you've already seen a 7-segment in a numeric watch or clock. This device contain 7 LEDs (hence 7-segment) enclosed in a small plastic case. It is generally used to display decimal digits from 0 to 9 (and display hexadecimal digit A to F). There are also some version of the 7-segment that contain a decimal point LED.</div>
<div>
<br /></div>
<div>
Being a 7-bit device, the 7-segment can display 128 (2^7) different "symbols". Take a look at this chart that shows all the possible combinations :</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMYnA1TZOJmkMmFtg521F1bRCP4iJGrvj_IYR5aretTSJAl0AHV-Q9iFie4gPc28npXyRnA53y-cYSv9YD0hZfCQV1I_RHuODxwGF2A0aVWgzPrGxam7_rc-hpb9I2EEHosNA6-Hl1gR9x/s1600/720px-7-segment.svg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="332" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMYnA1TZOJmkMmFtg521F1bRCP4iJGrvj_IYR5aretTSJAl0AHV-Q9iFie4gPc28npXyRnA53y-cYSv9YD0hZfCQV1I_RHuODxwGF2A0aVWgzPrGxam7_rc-hpb9I2EEHosNA6-Hl1gR9x/s400/720px-7-segment.svg.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2>
Driving the display with a decoder</h2>
<div class="separator" style="clear: both; text-align: left;">
The fact is that we don't really need all these combinations. We can then cut down 3 bits and have 16 (2^4) possible patterns, enough to hold the numbers 0 to 9. This is the goal of the 4 bit in, 7 bin out decoder as shown below :</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA5bkq2h78knvwC9nPGbZLGV3IUpUgXL8Tew313nJvrWSj4AdfUHSlIw_fuCTjATeiBTFNGR_uyST_flxsMNe1fZTsUbM0gBqh5oW65sMmnq9vJKne9sH_Hv4pr-zspA7JqS9_3aBw9fSN/s1600/decoder.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="181" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA5bkq2h78knvwC9nPGbZLGV3IUpUgXL8Tew313nJvrWSj4AdfUHSlIw_fuCTjATeiBTFNGR_uyST_flxsMNe1fZTsUbM0gBqh5oW65sMmnq9vJKne9sH_Hv4pr-zspA7JqS9_3aBw9fSN/s320/decoder.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In the picture, you can read the term BCD (Binary Coded Decimal) that means a 4-bit code representing the decimal digit coded in binary (as the name imply). The BCD to seven-segment decoder can be implemented with simple logic gates (see picture below).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6fpNRGzpjKvDbo7abpAqZFfNNMXP8lS6ISAm4HgLO2jJCWs5BgrhGv8wB-LyLw083-xFOhZSNcYTu-txHemUuOy9ciJuUZSWAeFuutL3b8iIFEE-0agVlcBrv86sAWzlBaEzJGbISi5IA/s1600/bcd-to-seven-segment-decoder-driver.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6fpNRGzpjKvDbo7abpAqZFfNNMXP8lS6ISAm4HgLO2jJCWs5BgrhGv8wB-LyLw083-xFOhZSNcYTu-txHemUuOy9ciJuUZSWAeFuutL3b8iIFEE-0agVlcBrv86sAWzlBaEzJGbISi5IA/s640/bcd-to-seven-segment-decoder-driver.jpg" width="472" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
<br /></div>
<div>
<h2>
The CD4511 to the rescue</h2>
<div>
I already implemented a 7-segment display decoder with 74 series logic gates when I was in college and it was quite a challenge to get it working (without doing any wiring mistakes)! Integrated circuits like the CD4511 does the same thing, but in a tiny DIP package. Here is the basic schematic of a circuit using the decoder :</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX0XxwiWJ2J9D-iDMeODFGsJQDo-1-s5qllRt6Ip_LK3QNOEh8eBXfegr3gW5-henK2EbRvKSfY1kdib_VbVwtA3GIkYEfg7bg2Ub_OBkUcNL-BRiA6ZTy7lgam6DmQ2F13Y5Zd5H24903/s1600/4511-to-Display.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiX0XxwiWJ2J9D-iDMeODFGsJQDo-1-s5qllRt6Ip_LK3QNOEh8eBXfegr3gW5-henK2EbRvKSfY1kdib_VbVwtA3GIkYEfg7bg2Ub_OBkUcNL-BRiA6ZTy7lgam6DmQ2F13Y5Zd5H24903/s320/4511-to-Display.gif" width="320" /></a></div>
<div>
<br /></div>
<br />
The "Lamp test" pin is used to light all the LED on the seven-segment to check if it's working properly. The "Blanking" pin does the opposite, it blanks the display. These two pins can be tied to the positive power rail as they are rarely used. The "Latch enable" pin, when pulled down to the ground, refresh the display with the current input (A0 to A3). The wiring is pretty straightforward, below is two pictures of what it looks like on a breadboard :<br />
<br /></div>
<div>
<br /></div>
<table style="margin: auto;"> <tbody>
<tr><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhairTbsK-7_4VpNBAGzHWOmsYyswi_lxSWJ7r-iKUc_ZPI5pHTvw-zg3OCD2TVc_Z3CHRyxUCiZfQmWXl4CTv5kFjqepy41DEzeWIjDXjWc_nVOSg_EB4Wur7T6EkeBBoLcsNL57wOVQEY/s1600/2013-03-11+22.10.48.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhairTbsK-7_4VpNBAGzHWOmsYyswi_lxSWJ7r-iKUc_ZPI5pHTvw-zg3OCD2TVc_Z3CHRyxUCiZfQmWXl4CTv5kFjqepy41DEzeWIjDXjWc_nVOSg_EB4Wur7T6EkeBBoLcsNL57wOVQEY/s320/2013-03-11+22.10.48.jpg" width="180" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-2Ai7BDn4MAEuORtJTGqaZWUjX5umlUxUqTBMr3re-fE7eDMRSqt5nSCzLqw3vqwZwT57YXXWGf3aaTLkNcvmRX3SpzbOSGfHl_eRELY5-07z45OBl6rVG8S5LWfYzARaK_YRi6LLs_zK/s1600/2013-03-11+22.11.56.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-2Ai7BDn4MAEuORtJTGqaZWUjX5umlUxUqTBMr3re-fE7eDMRSqt5nSCzLqw3vqwZwT57YXXWGf3aaTLkNcvmRX3SpzbOSGfHl_eRELY5-07z45OBl6rVG8S5LWfYzARaK_YRi6LLs_zK/s320/2013-03-11+22.11.56.jpg" width="180" /></a></div>
</td></tr>
</tbody></table>
<br />
<br />
<h2>
The CD4511 in action</h2>
<div>
There is multiple way to drive a decoder. It can be with simple DIP switches, or driven by a microcontroller. In the second video, I use 4 outputs of the Parallax Propeller to drive the chip. In the program I made, the delay between the counts is randomized between 150-1000 ms so the result is a bit more interesting...</div>
<div>
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/-wG9LIjpHZQ?rel=0" width="560"></iframe></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/tkR-nT3-On8?rel=0" width="560"></iframe></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com2tag:blogger.com,1999:blog-582219234592513124.post-10688706328424533712013-04-13T16:33:00.003-04:002014-02-17T19:04:08.831-05:00The op-amp as a comparator : temperature change detection circuitIn this post, we're going to take a brief look at one way of using an operational amplifier. To test the op-amp as a comparator, we will build a small and simple working circuit. Before diving in, let's take a moment to discuss about the operational amplifier.<br />
<div>
<br /></div>
<h2>
Operational amplifier theory</h2>
<div>
The operational amplifier is a type of amplifier that can be use in a lot of different arrangements to create filters, comparators, integrators, inverting/non-inverting amplifiers etc... In the picture below, you can see the schematic representation of an op-amp and it's different terminals.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDS5NXxRem98S6tr53q7ZPIgIZESQuZ4K7pPoBMNebzMA8QR6NR6I-6qHABj8WmqVfWfHHc9HscLWVcxhEOB6iy-z01uGBGkVxreA9CNcXjLtpB87aJpNM55ZCihuQr_yTf1Oa_e3AZ0Ep/s1600/opamp_block.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDS5NXxRem98S6tr53q7ZPIgIZESQuZ4K7pPoBMNebzMA8QR6NR6I-6qHABj8WmqVfWfHHc9HscLWVcxhEOB6iy-z01uGBGkVxreA9CNcXjLtpB87aJpNM55ZCihuQr_yTf1Oa_e3AZ0Ep/s320/opamp_block.jpg" height="246" width="320" /></a></div>
<br />
As you can see, it needs a positive and negative power supply. The op-amp has an electrical caracteristic called the open-loop gain. This gain is really high and usually range from 100,000@1,000,000. In open-loop, the relation between the output and inputs is dictated by this formula :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJocD4sgaQ7giLQFFgRyBm28UYtWWqxZ0nB740Gg8qiLP29SAbHLmYXddIVSR1qKoRX8AQ537WRGOV7t_paNYA1ICt1W2c22farh84HHkFjlK74696r51GlLiVXDSRrztU2xaPrph7k4BO/s1600/eq.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJocD4sgaQ7giLQFFgRyBm28UYtWWqxZ0nB740Gg8qiLP29SAbHLmYXddIVSR1qKoRX8AQ537WRGOV7t_paNYA1ICt1W2c22farh84HHkFjlK74696r51GlLiVXDSRrztU2xaPrph7k4BO/s1600/eq.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
It is important to remember that the voltage on the output pin can only swing between the positive and negative supply voltage.<br />
<br />
Op-amps are packaged into chips. It's possible that there are multiple op-amps in the same chip. Here is the pinout of the CA3140 IC :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw3GESZ9wLQj48OGyP3FcfzoAGtYA_HeeW6NHee2RUsGyHJhlhxiNxcUGprlMZ1jvTMHaaSKTGcioKT3FMXDUgiV0LdqfhP3cx23rk5PmGYKQZ4DQQdvTPXPgkmL8quEzIwR6ZK33mBtrY/s1600/pinout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw3GESZ9wLQj48OGyP3FcfzoAGtYA_HeeW6NHee2RUsGyHJhlhxiNxcUGprlMZ1jvTMHaaSKTGcioKT3FMXDUgiV0LdqfhP3cx23rk5PmGYKQZ4DQQdvTPXPgkmL8quEzIwR6ZK33mBtrY/s320/pinout.png" height="194" width="320" /></a></div>
<br />
<br />
<h3>
Comparator mode</h3>
The principle of operation of the comparator mode is quite simple. In the equation, if the result of the substraction in the parenthesis is positive, the output will equal the positive supply (because of the high open-loop gain). If it's negative, the output will be limited to the negative supply, ground in most of applications. Briefly said (with a LED connected at the output) if V+ is at an higher voltage than V- the LED will be on.<br />
<br />
<h3>
</h3>
<h3>
Single supply (rail-to-rail) vs. dual supply</h3>
Most op-amp cannot drive it's output signal to their supply, only close to. If you want the output to go completely from a supply to the other, you need to order a rail-to-rail op-amp. These ones can be a little bit pricier. Let's take a look at the internal of a cheap dual supply op-amp that I <a href="http://www.taydaelectronics.com/ca3140ez-ca3140-4-5mhz-bimos-op-amp-ic.html" target="_blank">purchased from Tayda Electronics</a>.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9CK8X_siWPsrZuD3j9dvUS0kD9DU6fVj1SHWBYEuX54Gg4toaNstAswmy6NfshuQKb9KzVGgJjqW9FuH6mAUPSoffmUid4Tr4quOl6FgWImXLXvdo1LV1bfImhvqio9pqWD6IAN5Mek5/s1600/internal.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9CK8X_siWPsrZuD3j9dvUS0kD9DU6fVj1SHWBYEuX54Gg4toaNstAswmy6NfshuQKb9KzVGgJjqW9FuH6mAUPSoffmUid4Tr4quOl6FgWImXLXvdo1LV1bfImhvqio9pqWD6IAN5Mek5/s640/internal.jpg" height="544" width="640" /></a></div>
<br />
I highlighted in red the components that limit the output pin from going all the way to the supply pins voltage. In the upper part, you have a diode (D7) with a forward drop of 0.7 volt and a transistor (Q18) that will saturate at 0.2-0.3 volt. This means that we cannot go higher than about 1 volt below the positive supply rail. For the negative supply, the transistors (Q15&Q16) will limit the voltage from going lower than 0.2-0.3 volt if the negative pin is tied to ground. By example, if we connect an op-amp to a 12 volt supply source, it's outuput will swing from 0.3 to 11 volts.<br />
<br /></div>
<h2>
The temperature detect circuit</h2>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBoS7U6Mq1i_E37zKhySf4pS105vR2g0xmdCptTa-LmYW-m7QGx7tWC0IHN3C0WLx9XI7i96az1sweefFLb7jhjiHldt0k_VpegefUGWmvQ9WY-HB2FA9-1kTld9RwX7WKAP5PQ_xIpxrb/s1600/2013-04-10+23.09.53.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBoS7U6Mq1i_E37zKhySf4pS105vR2g0xmdCptTa-LmYW-m7QGx7tWC0IHN3C0WLx9XI7i96az1sweefFLb7jhjiHldt0k_VpegefUGWmvQ9WY-HB2FA9-1kTld9RwX7WKAP5PQ_xIpxrb/s400/2013-04-10+23.09.53.jpg" height="225" width="400" /></a></div>
<br />
<br />
To demonstrate the comparator mode of an operational amplifier, I made a little circuit that use a thermistor. It detects a change of temperature above the ambient room temperature. Take a look at the schematic :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyxUEa85LSoH7Nnl1NCHreyWcComQsTjVzFcEsRq8GWulG7ry_uvJzbe3S0hyphenhyphen2eY-nTakCLQAeBE9h0pOOUUhXx9s4ihQYBmEgPSBrwZbAYaC5nnWLNSnY7n28B9t5i3qTaZ58w04JMxL5/s1600/comparator_temperature_schem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyxUEa85LSoH7Nnl1NCHreyWcComQsTjVzFcEsRq8GWulG7ry_uvJzbe3S0hyphenhyphen2eY-nTakCLQAeBE9h0pOOUUhXx9s4ihQYBmEgPSBrwZbAYaC5nnWLNSnY7n28B9t5i3qTaZ58w04JMxL5/s640/comparator_temperature_schem.png" height="304" width="640" /></a></div>
<br />
The thermistor is a resistance that is varying with the temperature. At the room temperature, the measured resistance is about 10kΩ, but when I touch it with my finger, it rapidly drop to 7kΩ. The 10kΩ fixed resistor in series with the thermistor make a voltage divider.<br />
<br />
At ambient temperature, there is 6 volts at the voltage divider but when I touch the thermistor, the voltage goes a little bit below 5 volts. The output of the voltage divider is brought to the inverting input (-) of the op-amp. I want to compare this to 5 volts, so I used a 5V voltage regulator at the non-inverting input (+) (I was too lazy to make a 5V voltage divider from resistors). When I touch the thermistor with my finger, the (+) pin voltage is above the (-) pin voltage so the output goes almost to the positive supply. This cause the LED to light. (I changed the LED for a green one because the other one was too bright for the camera)<br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/ieW72XQqedw?rel=0" width="560"></iframe>
</div>
<br />
<br />
<h3>
Conclusion</h3>
The principle of operation of this circuit can be transposed to a lot of different sensors or output device. It could have been a photoresistor (light detector) in place of the thermistor. We also could have replaced the LED by a fan so it could cool a hot device. Except for using an operational amplifier as a comparator, we rarely use it in open-loop (without any feedback). In a few articles, we'll take a look at other useful examples of circuits that uses an op-amp. </div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com2tag:blogger.com,1999:blog-582219234592513124.post-62356604602711977602013-03-24T18:39:00.002-04:002013-03-24T18:49:20.782-04:00Milestones in digital electronics evolutionAsk someone about what electronics is, the answer will probably be related to all the modern devices we're using everyday : mp3 players, televisions, computers, cell phones... All of these are made of many integrated circuits containing millions of transistors (sized in nanometer). In numeric circuits, you always need a switching device that can be used to create logic gates and registers. However, these switches have not always been as small as they are today. Here are some milestones in the advances of modern electronics.<br />
<div>
<br /></div>
<h2>
The mechanical relay (1835)</h2>
<div>
The relay is one of the oldest device used to make computers (primitive ones) and is still used a lot nowadays in all sort of different applications. The basic relay consist of a coil, spring, armature and contacts. When the coil is energized the armature close the normally open contact, otherwise the spring maintains the normally closed contact.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV-k0c5PmhJPGrmo4jGAbAKwl_maJpXBK7RqC91w-0YNwUj_cW5dogMJ2utnUWJLRaPYujXLFjQj_burVfjTc986l7TBFn_KLXNyFqBTxoK9goYIfEkZeLmP4AR7Unb_7qtbv2J-UDX7JJ/s1600/relay.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV-k0c5PmhJPGrmo4jGAbAKwl_maJpXBK7RqC91w-0YNwUj_cW5dogMJ2utnUWJLRaPYujXLFjQj_burVfjTc986l7TBFn_KLXNyFqBTxoK9goYIfEkZeLmP4AR7Unb_7qtbv2J-UDX7JJ/s200/relay.jpg" width="200" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Computer with limited programming capabilities could be made using relays, like the Z1 in germany around 1938. It is considered as the first freely programmable computer, but it's operation was unreliable.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiz8wlFpmQjVk_My4NZhoS5qOo_PeF46eE5ExR2lzOEWbIqKHFwrrGVBgemobvZD3LWpRoBCRXR-07d9NaLiqtr3P3BzV4jicOCo4cN3qTEvwwnD6ZJGCaR_Jll4uAmSxB0MNgMDYXuSHJ/s1600/Zuse_Z1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiz8wlFpmQjVk_My4NZhoS5qOo_PeF46eE5ExR2lzOEWbIqKHFwrrGVBgemobvZD3LWpRoBCRXR-07d9NaLiqtr3P3BzV4jicOCo4cN3qTEvwwnD6ZJGCaR_Jll4uAmSxB0MNgMDYXuSHJ/s400/Zuse_Z1.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2>
The vacuum tube (1907)</h2>
<div>
The vacuum tube is a great improvement over the mechanical relay because it contains no moving parts, that means it's a lot more reliable. Like the transistor, the vacuum tube can be used as an amplification device or as a switch. Hi-fidelity audio equipment still use vacuum tubes, for the clarity of the sound it provides. However, it is no more used as a switching device.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimOHm24RBvLZ0tTu-w5RM1esqv6pWG5cJ747573IZLvdBbRQDwG-7_2yzxwaMhm1MfK1zbzu-9y_WXdEojyt7LYWx-sM12Pj1YBi9olTt2PMTUVuOeMax4MHKWH-nNDH6JF6UBc31_Xalx/s1600/vacuum+tube.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="141" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimOHm24RBvLZ0tTu-w5RM1esqv6pWG5cJ747573IZLvdBbRQDwG-7_2yzxwaMhm1MfK1zbzu-9y_WXdEojyt7LYWx-sM12Pj1YBi9olTt2PMTUVuOeMax4MHKWH-nNDH6JF6UBc31_Xalx/s200/vacuum+tube.jpg" width="200" /></a></div>
<div>
<br /></div>
<div>
The first computers using vacuum tubes appeared around 1945 : the Colossus and the ENIAC. They were quite power hungry and heavy machines. The ENIAC contained around 17500 vacuum tubes as well as 1500 relays.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNXJwE87TeCKztpCL8JI_NbNjotg31lQdvAPGgjjsPuxnFm7yCa2sJj5RwAKuAILbZG9lgG9eAjMi_XkYZVk3NMkV75VKrk9sIwBNrS3aaC8-2tdH83IK2yBkKSiVK1-wFWFWNe9gIofU/s1600/eniac.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="317" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwNXJwE87TeCKztpCL8JI_NbNjotg31lQdvAPGgjjsPuxnFm7yCa2sJj5RwAKuAILbZG9lgG9eAjMi_XkYZVk3NMkV75VKrk9sIwBNrS3aaC8-2tdH83IK2yBkKSiVK1-wFWFWNe9gIofU/s320/eniac.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2>
The transistor (1954)</h2>
<div>
The transistor is the device of choice to create digital electronics circuit and has evolved considerably since it's beginnings. The biggest advantages of the transistor over the vacuum tube is it's small size and small power consumption. That marks the debut of lightweight and portable electronics. In the picture below, you can see a replica of the first bipolar junction germanium transistor.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ2F9v85O0UGiuJ_4UPnDx2QOFzFil37mPwc0iZ7EabMpzUosl3_YvQ62Sep1PSKngAPf19OqjEHJ0R_x1kXrcBYDxqV5CkGhuRyrQxYjJEsLyn2vxGSA5-2Xp0VE6X8sOQLdad8_IVwNr/s1600/Replica-of-first-transistor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ2F9v85O0UGiuJ_4UPnDx2QOFzFil37mPwc0iZ7EabMpzUosl3_YvQ62Sep1PSKngAPf19OqjEHJ0R_x1kXrcBYDxqV5CkGhuRyrQxYjJEsLyn2vxGSA5-2Xp0VE6X8sOQLdad8_IVwNr/s320/Replica-of-first-transistor.jpg" width="320" /></a></div>
<div>
<br /></div>
<div>
With the invent of the transistor, computers got a lot smaller and were ready to be manufactured for the commercial market. The IBM 608 is one of these fully transistorised computers. Below, a picture of Harwell CADET computer.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgApIFdt3PKvq6LU1USHS05y5pX8oXiCKFC3LK7Qh_4T4SxQtSZDREKzQjEnM8yUGaMv44KRvqFRoiHNJTySdoW4ne6ei-dyil2Iqi8mueOgqm1Uamtqe_mIhhUFyM9-Enruv1ZhD1IsZEO/s1600/harwell.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgApIFdt3PKvq6LU1USHS05y5pX8oXiCKFC3LK7Qh_4T4SxQtSZDREKzQjEnM8yUGaMv44KRvqFRoiHNJTySdoW4ne6ei-dyil2Iqi8mueOgqm1Uamtqe_mIhhUFyM9-Enruv1ZhD1IsZEO/s320/harwell.jpg" width="320" /></a></div>
<div>
<br /></div>
<h2>
The integrated circuit (1962)</h2>
<div>
Transistors really began to get small when packaged into chips. That way, a lot of transistors could be packed on the same "die". I bet you have ever heard about Moore's law, stating in 1965 that the transistors count in integrated circuits will double every year for at least ten years. Here is a picture (a little bit outdated) representing the advances in the number of transistor in IC.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixREaVRkFr-QXQ-JEATa66PIe2QcOPCaxvLVxidpihm5qBqiWFqA2_Kua3_bAXztGthVRe5DmQxgiX1pIJq_FuNR8uASCTlWosayOPyGBlxEZMbnZZGYaBgVUi21NmsFFUuSn9z-5nV_fA/s1600/moores.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixREaVRkFr-QXQ-JEATa66PIe2QcOPCaxvLVxidpihm5qBqiWFqA2_Kua3_bAXztGthVRe5DmQxgiX1pIJq_FuNR8uASCTlWosayOPyGBlxEZMbnZZGYaBgVUi21NmsFFUuSn9z-5nV_fA/s640/moores.png" width="640" /></a></div>
<div>
</div>
<div>
As you can see, the first generation of integrated circuits were used to make logic gates. Lots of things could be done with simple TTL gates, take a look at this circuit schematic of an <a href="http://en.wikipedia.org/wiki/Pong" target="_blank">arcade machine Pong game</a> made by Atari in 1974.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqDXsPPgCjtg1USY8ih1Gyu37hTNtG9IXwWW_IHil_6_RDQMTfpJs8yvSOKCq6_QvtipvnkFjpiAkfCPNXXsYkKHa5jFHM11lR8X-2qtuueLzbPw6_9txe3NfMQOcF4MuOs6ZGCZPp6-42/s1600/pong.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="411" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqDXsPPgCjtg1USY8ih1Gyu37hTNtG9IXwWW_IHil_6_RDQMTfpJs8yvSOKCq6_QvtipvnkFjpiAkfCPNXXsYkKHa5jFHM11lR8X-2qtuueLzbPw6_9txe3NfMQOcF4MuOs6ZGCZPp6-42/s640/pong.jpg" width="640" /></a></div>
<div>
<br /></div>
<h2>
Generations of computers</h2>
<div>
I found an interesting article about <a href="http://www.webopedia.com/DidYouKnow/Hardware_Software/2002/FiveGenerations.asp" target="_blank">computer generations</a> here's the summary (mechanical relay computers not included) :</div>
<div>
<div>
<ol>
<li>First Generation (1940-1956) Vacuum Tubes</li>
<li>Second Generation (1956-1963) Transistors</li>
<li>Third Generation (1964-1971) Integrated Circuits</li>
<li>Fourth Generation (1971-Present) Microprocessors</li>
</ol>
</div>
</div>
I bet you learned something new about computers... That's all for today folks!Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com2tag:blogger.com,1999:blog-582219234592513124.post-36178889525859056702013-03-23T19:04:00.000-04:002013-03-23T19:04:28.602-04:00Serial and parallel I/O : shift registers<h2>
Sequential logic</h2>
When I discussed about digital logic, I mostly focused on combinational logic (decoders, adders...) but there is another really important type of digital circuits : sequential logic circuits. Sequential logic circuits are circuits that the outputs not only depend on the inputs, but also of the order in time that these inputs are read. Some new terms are introduced in this circuit type.<br />
<br />
First of all, the concept of the memory bit : if the sequential circuit is time dependent, it means that there is some way to memorize the internal state of the circuit at a given time period. This is done with bistable circuits called latches or flip-flop (more on this in another article) that can be used as storage elements. If we combine more than one of these memory bits together, we can create registers.<br />
<br />
Most of the time, sequential circuits work with a clock signal. A clock signal is a stream of square wave pulses that is used to synchronize the circuits. With the clock signal, data can be serialized on a single wire. This is the basis of high-speed computer buses. Here is examples waveform of a I2C bus transaction. The SDA signal is serial data and the SCL signal means serial clock and is square wave signal. The data being transferred is something like 011011001...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFqu12jvtnsrqQAhI9Tp63lSXWihSEdFQ0odCUVY2M2j3-yPUqavcXL_QPYdhrcixl7D22Sjo4fuEKXBYKcB78cVpGWNl6e5Mf9vXCt8MMXSLbJW0xCySU0UFUj6n0X0yYNbv_I84-z667/s1600/i2c.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFqu12jvtnsrqQAhI9Tp63lSXWihSEdFQ0odCUVY2M2j3-yPUqavcXL_QPYdhrcixl7D22Sjo4fuEKXBYKcB78cVpGWNl6e5Mf9vXCt8MMXSLbJW0xCySU0UFUj6n0X0yYNbv_I84-z667/s320/i2c.png" width="320" /></a></div>
<br />
<br />
<h2>
Shift registers</h2>
<div>
An interesting sequential logic device is the shift register. The shift register is a clocked device and can work in many modes. In the picture below, the blue cubes are memory bits and red arrows represent data being shifted right each clock cycle. Data can be shifted at the rising or falling edge of the clock pulses (depending on the IC). As you can see, inputs can be serial or parallel and outputs can also be serial or parallel. We're going to see two example of chips using a shift register.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglgQ2Ud4pW_DvVk3STqtI1RrYzrIBnpYyO8aFZphKauSpMvkBMrzgAgVOQ5oMYFZXE0McMzh_6vugNw9nijPuSoPgmL_HZbe2cPnm7VgVBefgKACVq9NICcc5k5AyeDINCn2u1uSw2s-WM/s1600/shift+reg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglgQ2Ud4pW_DvVk3STqtI1RrYzrIBnpYyO8aFZphKauSpMvkBMrzgAgVOQ5oMYFZXE0McMzh_6vugNw9nijPuSoPgmL_HZbe2cPnm7VgVBefgKACVq9NICcc5k5AyeDINCn2u1uSw2s-WM/s400/shift+reg.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
Serial to parallel with the 74HC595 IC</h3>
<div>
The 74HC595 chip is often called an outputs expander. This is due to the fact that a µC (microcontroller) or other devices that can talk serially to this chip have the possibility to add a few output lines to their I/O. Has you may have already guessed, this IC is a serial input, parallel output shift register. With a single 595, you can add 8 output lines with as few as 3 wires. What's interesting is that you can daisy chain multiple 595 to add 16, 24, 32 and more outputs with only 3 control wires.</div>
<div>
<br /></div>
<div>
To be able to understand the inner working of that chip, I used it's datasheet. Below are some information that I found concerning the pin-out of the chip and the pins functionality.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7xv8QiLym12HokqG8SHCJuTu62W4iNqAeNVGgdkXwLkjAtyHHzohjpdLm9g7AlbsU_IjJ1qhMMKmHBDYNfHSEkBFiI7YJ5tPVkATZffSB_XA5iuycuUhGyBGik9ZFoslaoDzJtli0GqNL/s1600/pins74hc595.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7xv8QiLym12HokqG8SHCJuTu62W4iNqAeNVGgdkXwLkjAtyHHzohjpdLm9g7AlbsU_IjJ1qhMMKmHBDYNfHSEkBFiI7YJ5tPVkATZffSB_XA5iuycuUhGyBGik9ZFoslaoDzJtli0GqNL/s320/pins74hc595.png" width="240" /></a></div>
<div>
<br />
The interesting pins are the 8 parallel outputs (Q0-Q7) and the 3 control pins : STCP (latch), SHCP (clock), DS (serial input). The OE pin is the output enable and must be tied to the ground to activate the outputs. MR is the master reset, tie it to Vcc (positive supply voltage) to get the chip out of the reset state.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbi-tbhfPHp1Hx-P5R8bMnuULeOUNJLkuGY3ei8gJsrFMD_DRDoPJ5eQPnqtHH9pLGyztrR74J33LFvrCbdkRhLgE7wUwvYIcU0nPisFWh9NVlsYd-QK3T5bNcL7ItPyLjqgobfYjgNhM7/s1600/pindesc74hc595.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="314" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbi-tbhfPHp1Hx-P5R8bMnuULeOUNJLkuGY3ei8gJsrFMD_DRDoPJ5eQPnqtHH9pLGyztrR74J33LFvrCbdkRhLgE7wUwvYIcU0nPisFWh9NVlsYd-QK3T5bNcL7ItPyLjqgobfYjgNhM7/s320/pindesc74hc595.png" width="320" /></a></div>
<div>
<br />
In the table below, you can easily see what is going to happen with a given set of inputs. To make that short, a rising edge on the clock pin (SHCP) will store the serial input bit (DS) in the least significant bit (Q0S) of the shift register. All the previous bits in the shift register will move one bit toward the most significant bit (Q7S) one clock at a time. When the latch input is pulsed (STCP) the actual content of the shift register will be saved in the storage register. The storage register is directly tied to the parallel output (Q0-Q7). Remember that you must activate OE to make the outputs visible.<br />
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOG-szGpedotH23vGX_FcP99P_EJZdopxqXqVrV4FJLv2pLhwIppkIJJzWbXZ2hejzTa_NhE3wV3zp78zN8P-OJvalTF5L1iktLMRHdTvX9BOFnWfdCgLJbrq4J-I3uJjn62kd3MZvdUQU/s1600/table74hc595.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="386" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOG-szGpedotH23vGX_FcP99P_EJZdopxqXqVrV4FJLv2pLhwIppkIJJzWbXZ2hejzTa_NhE3wV3zp78zN8P-OJvalTF5L1iktLMRHdTvX9BOFnWfdCgLJbrq4J-I3uJjn62kd3MZvdUQU/s640/table74hc595.png" width="640" /></a></div>
<div>
<br />
I wrote a driver in SPIN (the language used by my favorite µC, the P8X32A) to drive the 74HC595. I hope that in a couple of article I can write some tutorials about microcontroller programming. If you are a bit familiar with programming languages and algorithm, you should easily understand the code below.<br />
<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivb99UkOaDWGsXnXzDbJrOlO2W0okG5GmI5klgcM9mcEgAhYaAbIJg5e807j87Td2SY_noGDTICyTj0205oqd_tl4iMPtWEkxnVXuopOJPl6vl4S780MC7tM06HU6D51WpSYD_FfitQmVC/s1600/74hc595.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivb99UkOaDWGsXnXzDbJrOlO2W0okG5GmI5klgcM9mcEgAhYaAbIJg5e807j87Td2SY_noGDTICyTj0205oqd_tl4iMPtWEkxnVXuopOJPl6vl4S780MC7tM06HU6D51WpSYD_FfitQmVC/s1600/74hc595.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You can see the result of the code on a LED bar-graph. On the first picture, $FF (1111_1111) was sent to the 595. On the second one, $55 was sent (0101_0101), can you see it? Please note that the 595 only has 8 output, so I only use 8 of the ten available LED on the bar-graph. Besides, I burned these two LEDs by doing some experiments on the bar-graph without current limiting resistors, duh!</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6pF_2tc143fhyphenhyphen1bpnlZwlNiZYmmNnZHUihb-ko3l_mPNKwId_jbBCx49VCksnj7MR9WdnxVwv8GSDCpwz5XLPH8MMBZMTbAKhQSEhjXa3mu9l_cIn9zbyMi-2mr0-GuMe6JjVargv8m_y/s1600/2013-03-22+21.45.43.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6pF_2tc143fhyphenhyphen1bpnlZwlNiZYmmNnZHUihb-ko3l_mPNKwId_jbBCx49VCksnj7MR9WdnxVwv8GSDCpwz5XLPH8MMBZMTbAKhQSEhjXa3mu9l_cIn9zbyMi-2mr0-GuMe6JjVargv8m_y/s320/2013-03-22+21.45.43.jpg" width="180" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2wUp5Tnf3ET_uF1JsSKi4Oocsb80r_3BCu5Jtul6amrTC485ep2D4sda7cQazkcd_QRG6l7r8wzEVPBPAJyrrPo46jd2Euq1_5sCU6HXrq3fe8G0WlfYQWBg4CzYKzvMRSsjRJOGzEllt/s1600/2013-03-22+21.50.58.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2wUp5Tnf3ET_uF1JsSKi4Oocsb80r_3BCu5Jtul6amrTC485ep2D4sda7cQazkcd_QRG6l7r8wzEVPBPAJyrrPo46jd2Euq1_5sCU6HXrq3fe8G0WlfYQWBg4CzYKzvMRSsjRJOGzEllt/s320/2013-03-22+21.50.58.jpg" width="180" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
<h3>
Parallel to serial with the 74HC165 IC</h3>
</div>
The 165 IC is a parallel input, serial output shift register. Almost everyone has already used a device containing a 8 bit parallel to serial static shift register, if you ever played with an old Nintendo Entertainment System :)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFYLd8LTP1BwV44zJoh2FBJMvZ6iMRWKCKCiIxSDgVABVNkoSG8jGkP4GPbtXITj5oQiaTMJvjnpGAdzEnICmDL9CejWEXjKgdKLEx7cF_PzldxoF6rmj3PRXZj3MN3UtmYB5S-8smObhG/s1600/inside_controller.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFYLd8LTP1BwV44zJoh2FBJMvZ6iMRWKCKCiIxSDgVABVNkoSG8jGkP4GPbtXITj5oQiaTMJvjnpGAdzEnICmDL9CejWEXjKgdKLEx7cF_PzldxoF6rmj3PRXZj3MN3UtmYB5S-8smObhG/s320/inside_controller.jpg" width="320" /></a></div>
<br />
In fact, this is the kind of chip used to store the 8 NES controller buttons (start, select, A, B, up, down, left, right) state and send it serially to the console. This operation is performed several times in a second. This can be seen as the inverse operation of the 595, as an input pins expander.<br />
<br />
The working principle is quite simple : when PL (parallel load) is asserted, data from (D0-D7) are loaded in the shift register. After that, the bits are sent serially to Q7 (serial output from last stage) on each rising CP pin (clock) pulses.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggR-U4VB1mP4ax_FN5OywgrIkIRH3mCAIZP_wVpCQMpWrS7z6opaDlroWTB8DN-oYPsYA7ezKQOHqyRb4fExr1FlWjzY3d9DCl8s6TT6LRsWqHEvi-dboVweVCxUmuIwjvqhniFK68edXZ/s1600/165.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggR-U4VB1mP4ax_FN5OywgrIkIRH3mCAIZP_wVpCQMpWrS7z6opaDlroWTB8DN-oYPsYA7ezKQOHqyRb4fExr1FlWjzY3d9DCl8s6TT6LRsWqHEvi-dboVweVCxUmuIwjvqhniFK68edXZ/s320/165.png" width="281" /></a></div>
<br />
I think that this IC is a little less interesting to demonstrate, as the data end up in the microcontroller and cannot really be seen... Though, it could be interesting to make some kind of gamepad with this IC as a demonstration. Moreover, the development board that I use has 2 NES gamepad port on it. Here is the source code for dealing with two gamepads (thanks to XGameStation, the developers of the board) :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw9qPpkz0C4ONMRkUBjQL6yNp9GhGDr3IXjjT0XF0jUWUsLw9VBaESsNfByi6nSxuMhL0ZFWt6Ycj4k7l5x24uiQUj82yhVBp_SBqwBLr0hQMFnByYak79A9w-v0SrWzsmdYbvAjyW9Jun/s1600/gamepadread.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw9qPpkz0C4ONMRkUBjQL6yNp9GhGDr3IXjjT0XF0jUWUsLw9VBaESsNfByi6nSxuMhL0ZFWt6Ycj4k7l5x24uiQUj82yhVBp_SBqwBLr0hQMFnByYak79A9w-v0SrWzsmdYbvAjyW9Jun/s1600/gamepadread.png" /></a></div>
<br />
<br />
Still here? :)<br />
<br />
There was a lot of new information in this post, I did my best to make it the clearer and easier to understand as possible. For the lines of code shown, as I said, I will blog about programming later but there is a lot of interesting things to see before delving into that. Do not hesitate to write suggestions in the comment box!<br />
<h3>
</h3>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-57576921993808491032013-03-19T16:44:00.000-04:002013-03-19T20:10:25.104-04:00The 555 timer ICIn my previous post on diodes, we saw how to light up an LED. This was exciting, for the ones who made their first step in electronics! What would be even more exciting is blinking that LED at a chosen rate. With what we're going to see today, you'll be able to do that easily.<br />
<br />
<h3>
The venerable 555 timer</h3>
<div>
The 555 has been introduced in 1972, and is still used a lot nowadays, with an estimated production of 1 billion device every year. There is multiple ways for generating pulses of different duration, but learning how to do it with the 555 timer is essential, and no programming is required. By setting a capacitor and resistors values, you can choose the timing you need. The 555 timer can be used in three different modes. Here is a picture of a breadboard with a 555 chip in monostable mode (notice the push-button used for triggering and only one resistor used on the chip pins).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRhW4bjVERlt1KDRp7oGokSGKY-YJn2yH8hiHJPgOpXdN6cGq1-gwV_2PKs-2bXXUR1qZFxOa1aw6G49jiwYgV5dghWl_2jA-nbZu1jph4BgXLsIKh96sy0NCW5k631Q6U4vCPQY5Zjm2w/s1600/2013-03-15+17.32.42.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRhW4bjVERlt1KDRp7oGokSGKY-YJn2yH8hiHJPgOpXdN6cGq1-gwV_2PKs-2bXXUR1qZFxOa1aw6G49jiwYgV5dghWl_2jA-nbZu1jph4BgXLsIKh96sy0NCW5k631Q6U4vCPQY5Zjm2w/s320/2013-03-15+17.32.42.jpg" width="320" /></a></div>
<br /></div>
<div>
<br /></div>
<h4>
Monostable (one-shot mode)</h4>
<div>
In this mode, the 555 is configured to generate a single pulse when a signal is sent to the trigger (TRIG) pin of the device. As you can see, there is a bar over the "Trigger" net name. This means that the pin works with inverse logic signals. You have to connect it to the Vcc supply through a pull-up resistor (let's say 10k) and bring it down to the ground net to trigger the one-shot pulse. This is useful if you want to turn on a device only for a certain duration e.g. motors, LEDs, lasers, relays, transistors...</div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7ZhUCB2uPTH02kacn4sE9B-LPDA6sN1t-YhAbP_2fJh4Gs9G_tq6BOiMGkn_1NQS-dggnYD8ycsqN95eSKznfEKEIPTQLeTUGVxj3NEM_quaXg6S7Se6-WsrlhNPcYRk3J6hYZ6wh5q71/s1600/555_Monostable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7ZhUCB2uPTH02kacn4sE9B-LPDA6sN1t-YhAbP_2fJh4Gs9G_tq6BOiMGkn_1NQS-dggnYD8ycsqN95eSKznfEKEIPTQLeTUGVxj3NEM_quaXg6S7Se6-WsrlhNPcYRk3J6hYZ6wh5q71/s1600/555_Monostable.png" /></a></div>
<div>
<br />
Here is a screenshot with my oscilloscope of the one-shot pulse in the monostable mode, triggered with a push button. I used a 10µF aluminum capacitor with a 100k resistor. The width of the pulse should be 1.1 seconds, but capacitors values varies a lot. In this case, a smaller resistor value could have been used to reduce the duration of the signal.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtb4SuqBd58Gfyhrp0bar7hoVLspjenpcA9QP_w75Xy5J6dlvVP_1GR4R7M4fAeJ6-o0ci0ZGCjtPy9q6L2z_w_bS1Qk6z3Bz0y4stRJ-3aJm1iZFAecKH0XINOguUEmT7whx_pLBsLp0n/s1600/MONOSTABLE.BMP" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtb4SuqBd58Gfyhrp0bar7hoVLspjenpcA9QP_w75Xy5J6dlvVP_1GR4R7M4fAeJ6-o0ci0ZGCjtPy9q6L2z_w_bS1Qk6z3Bz0y4stRJ-3aJm1iZFAecKH0XINOguUEmT7whx_pLBsLp0n/s1600/MONOSTABLE.BMP" /></a></div>
<br />
<br /></div>
<script language="JavaScript">
function printMono (form) {
r = form.r.value
c = form.c.value
on = 1.1*r*c/1000
on = on.toFixed(1)
alert("On time duration = "+on+" milliseconds")
}
function printMono2 (form) {
r = form.r.value
c = form.c.value
on = 1.1*r*c/1000000
on = on.toFixed(1)
alert("On time duration = "+on+" seconds")
}
</script>
<br />
<form>
<fieldset style="width: 200px;">
<legend>Monostable Mode</legend>
R:<input name="r" size="5" type="text" value="" />Ohms<br />
C:<input name="c" size="5" type="text" value="" />uF (microfarads)<br />
<br />
<input onclick="printMono(this.form)" type="button" value="Calculate ms" />
<input onclick="printMono2(this.form)" type="button" value="Calculate s" />
</fieldset>
</form>
<div>
<br /></div>
<div>
<br /></div>
<h4>
Bistable (latching mode)</h4>
<div>
In this mode, the 555 is not used as a timer, it is more like a memory bit that can be set or reset. This is similar to a SR latch that is found in digital circuits. When set, the OUT pin of the 555 will go high and will stay at this level until the reset pin receive a signal. This mode is used when you want to permanently turn on a device with the set (TRIG pin) button, until the reset (RESET pin) button is pressed. Electricians will recognize this behavior from a start-stop relay wiring. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmq80GHqoboW6fR9TcSC0nXQ0EWwauxJtFZ7a_ffrghKe-vQAa5ft0RoEsZJapGr1hubrdFW47N2A_CL0473XJUEIwb0icx3bhY5iiEjc8qdXNyLdWy50NRj8vyqMDeDW9I-DRBNIfsA5N/s1600/555_Bistable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmq80GHqoboW6fR9TcSC0nXQ0EWwauxJtFZ7a_ffrghKe-vQAa5ft0RoEsZJapGr1hubrdFW47N2A_CL0473XJUEIwb0icx3bhY5iiEjc8qdXNyLdWy50NRj8vyqMDeDW9I-DRBNIfsA5N/s1600/555_Bistable.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<h4>
Astable (pulses stream mode)</h4>
<div>
In this mode, the 555 will output rectangular waves that you can configure the on and off time with two resistors and one capacitor. This is the mode that you use to blink LEDs. The outputted frequency will depend on the high and low time of the repetitive waves. Something interesting to note is that if you change the value on the capacitor without changing the resistors value, the duty cycle will stay the same. So set your duty cycle first with the resistors and adjust the frequency with the capacitor.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm-XBSPHTwFr-iq96kaU9vOGpKS3wDzg9FAvCMI5LnR49XO833hbSbVmk2cvtXCE4sB4qjyTF8tzuYvsqoF5rmX6k4MNiorZ0q2T0fQsYy6XuPOhzp0Qe7g3JGLr-PCIcLmyGxKR7_GnNQ/s1600/555_Astable_Diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhm-XBSPHTwFr-iq96kaU9vOGpKS3wDzg9FAvCMI5LnR49XO833hbSbVmk2cvtXCE4sB4qjyTF8tzuYvsqoF5rmX6k4MNiorZ0q2T0fQsYy6XuPOhzp0Qe7g3JGLr-PCIcLmyGxKR7_GnNQ/s1600/555_Astable_Diagram.png" /></a></div>
<div>
<br />
Here is a screenshot with my oscilloscope of the stream of pulses in the astable mode. I used a 10µF aluminum capacitor with 10k/100k resistors. Here again the capacitor tolerance has an effect on the timing.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5sAy5O17Un1-tWKXl5EOJNhaSmQNq9UBTvfXpTpyaqC-UtOTr-5jgslOWH0ix8dXSEekG-VZbKjVhGF4a57zYnmZ73ovCAEzVBhu7OHK2E6cF_1p2wrU9UH91Xg4B_zbx2-5kI2XMKBdk/s1600/ASTABLE.BMP" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5sAy5O17Un1-tWKXl5EOJNhaSmQNq9UBTvfXpTpyaqC-UtOTr-5jgslOWH0ix8dXSEekG-VZbKjVhGF4a57zYnmZ73ovCAEzVBhu7OHK2E6cF_1p2wrU9UH91Xg4B_zbx2-5kI2XMKBdk/s1600/ASTABLE.BMP" /></a></div>
<br />
<br /></div>
<script language="JavaScript">
function printAs (form) {
r1 = form.r1.value
r2 = form.r2.value
c = 1*form.c.value/1000000
on = 0.693*(1*r1+1*r2)*c
off = 0.693*r2*c
duty = 100*on/(1*on+1*off)
duty = duty.toFixed(1)
freq = 1/(1*on+1*off)
freq = freq.toFixed(3)
on = on.toFixed(3)
off = off.toFixed(3)
alert("High duration = "+on+" s\nLow duration = "+off+" s\nDuty cycle = "+duty+"%\nFrequency = "+freq+" Hz")
}
function printAs2 (form) {
r1 = form.r1.value
r2 = form.r2.value
c = 1*form.c.value/1000
on = 0.693*(1*r1+1*r2)*c
off = 0.693*r2*c
duty = 100*on/(1*on+1*off)
duty = duty.toFixed(1)
freq = 1/(on/1000+off/1000)
freq = freq.toFixed(3)
on = on.toFixed(1)
off = off.toFixed(1)
alert("High duration = "+on+" ms\nLow duration = "+off+" ms\nDuty cycle = "+duty+"%\nFrequency = "+freq+" Hz")
}
</script>
<br />
<form>
<fieldset style="width: 200px;">
<legend>Astable Mode</legend>
R1:<input name="r1" size="5" type="text" value="" />Ohms<br />
R2:<input name="r2" size="5" type="text" value="" />Ohms<br />
C:<input name="c" size="5" type="text" value="" />uF (microfarads)<br />
<br />
<input onclick="printAs2(this.form)" type="button" value="Calculate ms" />
<input onclick="printAs(this.form)" type="button" value="Calculate s" />
</fieldset>
</form>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-54317886807832397422013-02-07T00:11:00.001-05:002013-04-14T16:08:43.051-04:00Digital Systems Part 3 - Combinational Logic<div class="separator" style="clear: both; text-align: left;">
In the first two parts of this installment, we learned about the different logic gates and how some of these are implemented with transistors. It is now the time to go a bit further i.e. working with these gates to form complex circuits. Electronics circuits made with logic gates are called digital circuits. There are two main type of digital circuits : combinational and sequential.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h4>
Combinational circuits</h4>
<div>
These circuits are easier to understand than sequential circuits. Combinational logic means that the outputs of the circuit are going to be the same for a given set of input values. The sequence of how the inputs have been setted has no effect on the circuit outputs. There are multiple different type of combinational circuits :</div>
<div>
<br /></div>
<div>
<ul>
<li>encoder/decoders</li>
<li>multiplexer/demultiplexer</li>
<li>comparator</li>
<li>adder/substracter/multiplier/divider</li>
</ul>
<div>
...and I do probably miss some types. </div>
<div>
<br /></div>
<div>
A decoder is a type of circuit that will take a given number of input bits (a code) and will produce a set of signal for each code. The output will have a larger number of bits than the input. The encoder is the inverse, it will take a set of signals and generate fewer code bits. </div>
<div>
<br /></div>
<div>
The multiplexer can be seen like a train rail that encounter an Y path. The train will take a selected path. The same thing happens with the multiplexer, the input bit (either one or zero) will propagate to one of the outputs, depending of the control signals (that set the path). The demultiplexer will take one bit from multiple input bits and propagate it to the single output depending of the control signals.</div>
<div>
<br /></div>
<div>
The comparator is used to determine which of two binary number is the highest. The mathematical operations (+ - x /) will also work on binary numbers.</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
A special type of encoder is the one-hot encoder. It will take a certain number of input bits, and generate a single high bit among the output bits (all other are zeroed). In the example animated GIF below, you can see how this encoder works. When the wire turns green, it means that the input is high. There is only one high output (lit LED) at a time. The gates used are 3-pins AND gates; observe that there are little bubbles at various inputs, this is a shortcut to indicate that the corresponding input is inverted. (ps. I used Logisim circuit simulator on Linux and took screenshots of the possible combinations to finally animate the cropped screenshots with GIMP)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKDn0yOBew5jxghp0zMFH6tKvlKxRwGqSD29LiELR1U9ZqCRVoVkTjOPrxpbjJSjt8b7XqNDo8yMDTSlhYKoSUn8QztTIlB97rYFew_cCoiB-FXU0gD_LsFhSuAYIpGUAqioPRb-kxP3d3/s1600/anim.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKDn0yOBew5jxghp0zMFH6tKvlKxRwGqSD29LiELR1U9ZqCRVoVkTjOPrxpbjJSjt8b7XqNDo8yMDTSlhYKoSUn8QztTIlB97rYFew_cCoiB-FXU0gD_LsFhSuAYIpGUAqioPRb-kxP3d3/s320/anim.gif" width="166" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The one-hot encoder circuit is used to create a decade counter. A popular decade counter chip is the CD4017 in the CD4000 series of IC. This integrated circuit is really old and we can see the chip layout (transistors) in the datasheet. In the picture below, you can see the mask of the real chip.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNaFGtCZiOGhyphenhyphenvCruryZ_9gh4eDHW7O5kE8-FQddPHwJdc6V98dvSg1jd8dwEojWnyvYuWwzSj9WnWFsNTp1d6ra8FI4zVvLaWDOKpFgenqVJXO9Yejel7inmsQlyC4KhL9LgnPYjg-ETl/s1600/cd4017.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNaFGtCZiOGhyphenhyphenvCruryZ_9gh4eDHW7O5kE8-FQddPHwJdc6V98dvSg1jd8dwEojWnyvYuWwzSj9WnWFsNTp1d6ra8FI4zVvLaWDOKpFgenqVJXO9Yejel7inmsQlyC4KhL9LgnPYjg-ETl/s640/cd4017.jpg" width="616" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h4>
Sequential circuits</h4>
<div>
I won't go in the details of sequential circuits, I will keep that subject for later. A sequential circuits is a combination (no pun intended) of registers and combinational circuits. What's special with them is that their outputs will depend on when the inputs change (time factor). These circuits need a clock signal as a time base. Also, sequential circuits have internal states (memory effect) that are kept in different registers. The most complex digital structure like processors and state-machines use sequential circuits to work. An example circuit is a pass code locked door. The door will unlock only if a certain pattern of button is pressed sequentially. That would not be possible with combinational circuits.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-77317481774730324222013-02-06T02:08:00.002-05:002013-02-06T02:08:45.628-05:00Digital Systems Part 2 - Transistors implementationIn the last post about digital systems, you learned the differences between the different logic gates. Now, we're going to look at how to make AND/OR gates with NPN transistors. But first, we need to talk a little bit about the purpose of the transistors.<br />
<br />
<h4>
The Bipolar Junction Transistor (BJT)</h4>
<div>
The theory behind the transistors is quite complicated (quantum theory, semiconductors and electronic doping). Fortunately, you don't have to know about all these things to understand the operation of the transistor. Keep in mind, transistors can operate in different modes but in this post we are only going to learn about the <b>saturation mode</b>. First, take a look at the schematic diagram of the BJT and it's TO-92 (Transistor Outline) casing :</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN1SxSlTsT2ivQEZ7mRrzvUItq7l-Sp2l8rf5rOdKytzDQXaSoKA1Vjtg-ndoj0Z7vcQUIT4vF6ipPTy-Tl-PQvfdf6myh6Nnf7-xhyIAuLNBxC29uC5n4v6I_-2AeFhL2AZraP_2Nj8zH/s1600/bjt.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN1SxSlTsT2ivQEZ7mRrzvUItq7l-Sp2l8rf5rOdKytzDQXaSoKA1Vjtg-ndoj0Z7vcQUIT4vF6ipPTy-Tl-PQvfdf6myh6Nnf7-xhyIAuLNBxC29uC5n4v6I_-2AeFhL2AZraP_2Nj8zH/s1600/bjt.jpg" /></a></div>
<div>
<br /></div>
<div>
In the saturation mode, the transistor is behaving like a simple switch. The transistor is a 3-pin device : emitter, base and collector (<b>EBC</b>). This switch will let the current flow in only one direction, <b>from the</b> <b>collector to the emitter</b>. The condition required to let current flow in the switch is that there is a small current flow <b>between the base and the emitter</b>. In other words, the base is a control pin and applying a voltage to it will close the switch (thus resulting in a current flow from <b>C to E</b>).</div>
<div>
<br /></div>
<div style="text-align: center;">
<u>A small current flow from the base to the emitter will produce a large current flow between the collector and the emitter</u><br />
<div style="text-align: left;">
<u><br /></u></div>
<h4 style="text-align: left;">
Making gates with BJTs</h4>
<div style="text-align: left;">
With only two NPN transistors, we're able to build a AND/OR gate. The transistors used in the circuit will be the <a href="http://en.wikipedia.org/wiki/2N3904">2N3904</a>. The circuit is simple : we have 4 switches (labelled 1 to 4) in a DIP package connected to a AND gate and a OR gate. The output of the AND gate is connected to a yellow LED; The output of the OR gate is connected to a red LED. In the table below, you see all the possible switch combinations. Without any doubts, S1 and S2 are wired to the OR gate (red), S3 and S4 to the AND gate (yellow).</div>
</div>
<div style="text-align: center;">
<h4 style="text-align: center;">
Truth Table</h4>
<div style="text-align: justify;">
<br /></div>
</div>
<table border="3" style="background-color: #343434; border-color: rgb(2, 221, 8); color: white; margin: auto; text-align: justify;">
<tbody>
<tr>
<td>S1</td>
<td>S2</td>
<td>S3</td>
<td>S4</td>
<td>Red LED</td>
<td>Yellow LED</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>OFF</td>
<td>OFF</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>OFF</td>
<td>OFF</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>OFF</td>
<td>OFF</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>OFF</td>
<td>ON</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>ON</td>
<td>ON</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>ON</td>
<td>ON</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>ON</td>
<td>OFF</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>ON</td>
<td>ON</td>
</tr>
</tbody></table>
<div style="text-align: justify;">
<br />
<br /></div>
<h4 style="text-align: center;">
The Circuit On A Breadboard</h4>
<div style="text-align: center;">
The upper part is the OR gate, the lower part is the AND gate. The small components in black are the 2N3904 NPN transistors. On the left, all switches are off, on the right : 1 on - 2 off - 3 on - 4 on.</div>
<div>
<br /></div>
<table style="margin: auto;"> <tbody>
<tr><td><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_n2YPh2byR7a2wBwvdFgHywBTIm_uP008wMgu5a4liDm-CXb3R3Y1zz8JlN2oxT2nyGAql7wONgrelFCHr2xgIHWG3iflW2E3oT9ZOekASXaZPkqV4njouECVNt-GCzj70MspS5VIdQw/s1600/2013-02-05+23.15.30.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ_n2YPh2byR7a2wBwvdFgHywBTIm_uP008wMgu5a4liDm-CXb3R3Y1zz8JlN2oxT2nyGAql7wONgrelFCHr2xgIHWG3iflW2E3oT9ZOekASXaZPkqV4njouECVNt-GCzj70MspS5VIdQw/s320/2013-02-05+23.15.30.jpg" width="180" /></a> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_6mk8zwInJ2XGX_1Y__oLLDl7GMfzpkP7nt3BWUjJvM8DEUOinw8izQIOlLwZql3_nKzwxKDnD9UDkUIVg5Glq7N4ad5nAHKBPx_CTuBn8mMpJSHm0HIerJev-B_Zgng3h_GfSenS0XCm/s1600/2013-02-05+23.15.12.jpg" imageanchor="1"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_6mk8zwInJ2XGX_1Y__oLLDl7GMfzpkP7nt3BWUjJvM8DEUOinw8izQIOlLwZql3_nKzwxKDnD9UDkUIVg5Glq7N4ad5nAHKBPx_CTuBn8mMpJSHm0HIerJev-B_Zgng3h_GfSenS0XCm/s320/2013-02-05+23.15.12.jpg" width="179" /></a></div>
</td></tr>
</tbody></table>
<br /><h4 style="text-align: center;">
The circuit Schematic</h4>
<div style="text-align: center;">
I think the diagram below speaks for himself. With the OR part, the two switches are in parallel, so if one of the switch is closed, the red LED will light. For the AND part, the two switches need to be closed for the yellow LED to light. I chose 10 kiloohms for the base resistors (R1-R2-R3-R4) to produce 1mA of current from base to emitter. For the LED resistors, I chose the value of 680 ohms so 12mA is flowing in the LED. Please take a look at my post about diodes if you do not remember how to calculate the current through the LEDs.</div>
<div style="text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_0bkq-5M9lC7K1e1N5n5iQawVoJZsdldCClVoi4sgGQQA4T4P-ue7qtPWRYH4DXBg6hrUsef480n5xUe2sS52dxn_2D74EPDaGOoOvFo7MAJq7clO7ktTm21MFdqbAih8lCoyp2MrRjeE/s1600/ANDOR_schem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_0bkq-5M9lC7K1e1N5n5iQawVoJZsdldCClVoi4sgGQQA4T4P-ue7qtPWRYH4DXBg6hrUsef480n5xUe2sS52dxn_2D74EPDaGOoOvFo7MAJq7clO7ktTm21MFdqbAih8lCoyp2MrRjeE/s640/ANDOR_schem.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
That's it for today! In the next part, we will look at integrated circuits that contains four to six logic gates of the same kind (74 series); this will help us to make digital circuits faster. The goal will be to create complex structures with logic gates. See ya!</div>
<div style="text-align: center;">
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-44190479620887954622013-02-03T16:05:00.000-05:002013-02-05T13:12:48.860-05:00Digital Systems Part 1 - Logic GatesIn electronics, there is the analog world and digital world. The analog circuits operate on continuous valued signals. Digital circuits operate on discrete signals values i.e. 1/0, on/off, high/low, true/false. In the digital world, we're interested in bits, that is binary numbers. You can learn more about the <a href="http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary">binary number base here</a>. In numeric circuits, each signal (wire) is seen as either being high or low (two-valued logic). Depending on the voltage at which the circuit operate, the high value will be the power supply voltage : 3.3V, 5V, 12V, 24V... The low value will be equal to the ground reference.<br />
<br />
<h2>
Logic gates</h2>
<div>
The logic gates are the basic building blocks of digital systems. They provide the most simple operations on binary signals. With a combination of multiple logic gates, you can build complex circuits e.g. adders, comparators, encoders/decoders, timers, multiplexers, etc. Here are the logic gates that we are going to work with (you can see the schematic diagrams of the gates and their truth table) :</div>
<div>
<br /></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/AVvXsEgijmkkKkHmFiJ_AXY4jIvis-lGi_I5hmxAifuzhyCUfgW2EdSSfMgH0air_jEt-JbysnyDXspMIQYbbQu9CpaAHuzpLFdPG80RNgvIvmly2YkjrWKXBvSQ330D6i7Eh8wrMtQqgwPpKz_7/s1600/gates.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgijmkkKkHmFiJ_AXY4jIvis-lGi_I5hmxAifuzhyCUfgW2EdSSfMgH0air_jEt-JbysnyDXspMIQYbbQu9CpaAHuzpLFdPG80RNgvIvmly2YkjrWKXBvSQ330D6i7Eh8wrMtQqgwPpKz_7/s1600/gates.png" /></a></div>
<div>
<br /></div>
<h4>
The NOT gate</h4>
<div>
The most simple logic gate, the inverter will flip the value of the bit at the input pin (left pin on the picture above). Imagine you have a light connected to a N.O. (Normally Open) push button, when you press the button, the light will turn on. If you connect the light to a N.C. (Normally Closed) push button, the light will always be on unless you press the button. With an inverting gate, you could easily change the behavior of an N.O. contact into a N.C contact and vice versa.<br />
<br />
<h4>
The AND - OR gate</h4>
</div>
These gates are used to make logical equations. For the AND gate, <b>all</b> the inputs have to be on for the output to come on. Example : if button A is pressed AND button B is pressed, the LED will light up. For the OR gate, <b>one</b> of the inputs have to be on for the output to come on. Example : if button A is pressed OR button B is pressed, the LED will light up.<br />
<br />
<h4>
The XOR gate</h4>
<div>
The XOR logic gate serve a special purpose : when you look at it's truth table you realize that the output is on only when the inputs bits are not the same. This gate is then used to detect if there is an inequality of the input bits. The XOR gate is also used to compute the sum (S) of a one-bit adder. S being the sum, C being the carry bit : </div>
<div>
<br /></div>
<div>
0 + 0 : S = 0, C = 0</div>
<div>
0 + 1 : S = 1, C = 0</div>
<div>
1 + 0 : S = 1, C = 0</div>
<div>
1 + 1 : S = 0, C = 1</div>
<div>
<br /></div>
<div>
From the following equations can you see that <u>S = A <b>XOR</b> B</u> and <u>C = A <b>AND</b> B</u>? Here is the schematic of the one-bit adder.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWsQBR01PcmWCdixfzvLVIxljfdklPqtBPtKwARG5tvSV9yigL4Yru9PeGk0bqUTQHUmNHXw9SvdTXBN-mzpYc3O4oyKF_kqa0C7AOnWQ8ErD-7GWsybx7kQ6zhyRVB84VpyKq3Fquk_xL/s1600/Half_Adder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWsQBR01PcmWCdixfzvLVIxljfdklPqtBPtKwARG5tvSV9yigL4Yru9PeGk0bqUTQHUmNHXw9SvdTXBN-mzpYc3O4oyKF_kqa0C7AOnWQ8ErD-7GWsybx7kQ6zhyRVB84VpyKq3Fquk_xL/s1600/Half_Adder.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In the second part of this tutorial, we're going too see how simple logic gates can be made with Bipolar Junction Transistors (BJTs).</div>
<div>
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-87602060597368316392013-01-31T10:57:00.003-05:002013-01-31T13:07:33.133-05:00Getting componentsAfter you bought the multimeter, breadboard, pliers, wire stripper, soldering iron (...) there is still something missing, the components! But from where should you get them?<br />
<br />
You have a few options:
<br />
<br />
<ul>
<li>From a local store (in my case, they are too far from my place)</li>
<li>By salvaging old equipment (TVs, radio, etc...)</li>
<li>From Ebay</li>
<li>From small online stores</li>
<ul>
<li><a href="http://www.sparkfun.com/" target="_blank">Sparkfun</a></li>
<li><a href="http://www.parallax.com/Store/tabid/60/Default.aspx" target="_blank">Parallax</a></li>
<li><a href="http://www.robotshop.com/store" target="_blank">Robotshop</a></li>
</ul>
<li>From a large online electronic component distributor</li>
<ul>
<li><a href="http://www.digikey.com/" target="_blank">Digikey</a></li>
<li><a href="http://www.newark.com/" target="_blank">Newark</a></li>
<li><a href="http://www.mouser.com/" target="_blank">Mouser</a></li>
</ul>
</ul>
<h3>
</h3>
<h3>
</h3>
<h3>
Local store</h3>
<div>
There are a lot of specialized shops to buy components. Usually, the prices are a lot higher than the other places, and the choice of component is limited. They are useful when you need a component right away and do not want to wait several days for the parts to arrive.</div>
<div>
<br /></div>
<h3>
Salvaging and scavenging</h3>
<div>
Sometimes, you can find some little gems in broken and old electronic equipment. It may be hard to remove the component without breaking it though. You might want to search for power supplies, toroids, LCD screen, resistors/capacitors, connectors, switches etc...</div>
<div>
<br /></div>
<h3>
Ebay</h3>
<div>
This one is my favorite! Components on Ebay are cheap... really cheap. Most of the time, you can get bulk parts for 1$, free shipping. I recommend <a href="http://stores.ebay.ca/Tayda2009" target="_blank">Tayda2009</a>, he got a lot of stuff at a bargain price. The only problem with Chinese and Thai sellers is that the shipping time is 2-3 weeks. For even better prices, you can visit his <a href="http://www.taydaelectronics.com/" target="_blank">online store</a> and use the voucher EB99922 for a 10% discount. ;)</div>
<div>
<br /></div>
<h3>
Small online stores</h3>
<div>
These stores are handy for specialized parts like sensors, motors and various purposes boards. Shipping prices can sometimes be a problem; maybe not in the US but in Canada it can often be something like 30$. On Cyber Monday, shipping was free at Sparkfun so I bought some interesting stuff. Take a look at this <a href="https://www.sparkfun.com/products/10969" target="_blank">resistor kit</a>. I suggest you try them by yourself and pick your favorites.</div>
<div>
<br /></div>
<h3>
Large online distributors</h3>
<div>
For a professional service, try some of the large electronic retailers. Their parts selection is HUGE and shipping time are blazing fast (2-3 days). They are often the only choice when looking for a particular component. One nice tip : try <a href="http://www.findchips.com/" target="_blank">findchips website</a>, you can enter a part number and you will get a list of all the distributors that stock the component you are looking for.</div>
<div>
<br /></div>
<div>
If you do buy some parts, leave a comment and tell me which method worked for you :)</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com2tag:blogger.com,1999:blog-582219234592513124.post-19731771327078365032013-01-29T19:21:00.000-05:002013-08-26T09:49:05.357-04:00Diodes fundamentals and LEDs<br />
The diode is an non-linear (current vs. voltage not proportional) electronic component of the semiconductor class. It is a two leaded device that is primarily used to block the flow of current in one direction. The terminals of the diode are called the anode (positive) and the cathode (negative).<br />
<br />
In the reverse mode, the diode will block current until the breakdown voltage is reached, then the device is destroyed. In the forward mode (conducting mode), the diode let the current flow and will drop some volts, this is called the forward voltage drop. In datasheets, this value is abbreviated Vf.<br />
<br />
There are multiple diodes types;<br />
<br />
<h2>
Signal/Switching diode</h2>
<div>
This diode is the simplest of all. Some of them can carry only small current values (usually signal diodes). Some others like the rectifier diodes can carry larger amounts of current. Some of the most popular diodes are part of the 1N4000 series (1N4148; 1N4007; etc...). For this type of diode, you often see forward drop of 0.7 Volts.</div>
<div>
<br /></div>
<h2>
Schottky and Zener</h2>
<div>
The Schottky diode is usually used where you need a small power dissipation. This is due to their low forward drop (often 0.2 Volts). The Zener is a special type, where the reverse mode will conduct at low voltage values : 24V, 12V, 5V, 3.3V etc... This is useful to create voltage references and small current capacity regulators.</div>
<div>
<br /></div>
<h2>
The ubiquitous LED</h2>
I think everyone is familiar with the LED (Light Emitting Diode). This type of diode is available in a lot of different colours, shape and brightness. The most common is the discrete 5mm red LED. Here is what it looks like :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMxEGWiq9BDnisBIF1qj6kxufnQKffNF5zRHOO38SSyOpmDok1pnvuuTYJUeuG-PsG9lEOS13aiDmLE7cJ5vnJF6XYpIFTC8pXa3PLIzlmrBUh6KEaC0hp-UqNtl5O-T7lbiKYIMgSFFdF/s1600/electronics_led_diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMxEGWiq9BDnisBIF1qj6kxufnQKffNF5zRHOO38SSyOpmDok1pnvuuTYJUeuG-PsG9lEOS13aiDmLE7cJ5vnJF6XYpIFTC8pXa3PLIzlmrBUh6KEaC0hp-UqNtl5O-T7lbiKYIMgSFFdF/s320/electronics_led_diagram.png" width="320" /></a></div>
<br />
On this image, you can also see the schematic symbol of the LED and how to identify the terminals. For through hole parts, the longer lead is the anode. The forward voltage drop of the red LED is about 2 Volts. Other colours have different forward drop. To light the LED, current has to flow from it's anode to cathode. Here is the basic connection schematic :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0KvZNy9gcoIZ3yafvHHjhKW7tbnox6b5MhQ7-2D7lHT-gvY1qkpSNG3mUgycvQjqpqkyNeb5HoFiB_mRH2fZ5G531kRyGHmNm59vfcokHXbquqGZBiiWyvc2eLpcUjW8B3fVyQP4FQYk1/s1600/led.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="252" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0KvZNy9gcoIZ3yafvHHjhKW7tbnox6b5MhQ7-2D7lHT-gvY1qkpSNG3mUgycvQjqpqkyNeb5HoFiB_mRH2fZ5G531kRyGHmNm59vfcokHXbquqGZBiiWyvc2eLpcUjW8B3fVyQP4FQYk1/s400/led.png" width="400" /></a></div>
<br />
<br />
The current through a LED usually has to bet set between 5mA and 15mA. Too much current will damage the LED. The formula to calculate the current is the following : (<b>Vsource-Vforward)/R</b>. I made a little html form (powered by javascript) so you can try different voltage source and resistor combination. You can choose the colour to change the forward drop. Results are approximative, consult the LED datasheet for more accurate values.<br />
<br />
<script language="JavaScript">
function print3 (form) {
v = form.voltage.value
r = form.resistance.value
sel = form.led_color.value
switch(sel)
{
case "R": vf = 2; break;
case "Y": vf = 2.6; break;
case "G": vf = 2.2; break;
case "B": vf = 3.5; break;
case "W": vf = 3.6; break;
default: vf = 2;
}
current = ((v-vf)/r)*1000
current = current.toFixed(2)
alert("LED Current = "+current+"mA ")
}
</script>
<br />
<form>
<fieldset style="width: 200px;">
<legend>LED Current Calculator</legend>
Voltage:<input name="voltage" size="3" type="text" value="" />V<br />
Resistance:<input name="resistance" size="3" type="text" value="" />Ohm<br />
LED Color:<select name="led_color">
<option value="R">Red</option>
<option value="G">Green</option>
<option value="B">Blue</option>
<option value="Y">Yellow</option>
<option value="W">White</option>
</select>
<br />
<input onclick="print3(this.form)" type="button" value="Calculate" /></fieldset>
</form>
<div>
<br />
I hope that diodes have no longer secrets for you!</div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-48763984044380654412013-01-28T23:20:00.000-05:002013-01-30T09:07:27.675-05:00Resistive circuits calculationsIn my last post, I introduced the basic quantities used in electronics. These notions are necessary to move further with electrical circuits calculation. It is easier to learn the Ohm's law with examples so here we go :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkRex3y2tNEcHlzCU7Byv_D9lNH1z2ohhWU_sWCaGHVeAAK5V-DwbVn5ipMfoLRPGuyvVOZVb5SeIgiEAO1NWUx6YB5_Gq3-k8G5HEivhKLFMKI9AFsPpbkq-sGpv0xavdwUIsYpDceaBr/s1600/series.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkRex3y2tNEcHlzCU7Byv_D9lNH1z2ohhWU_sWCaGHVeAAK5V-DwbVn5ipMfoLRPGuyvVOZVb5SeIgiEAO1NWUx6YB5_Gq3-k8G5HEivhKLFMKI9AFsPpbkq-sGpv0xavdwUIsYpDceaBr/s400/series.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
The picture above is what we call a circuit schematic. At the left of the schematic we have the DC source (batteries in this example). At the right you see the resistor schematic symbol. Keep in mind that the wire at the bottom is the ground net. We have a voltage source of <b>10</b> Volts and a resistance of <b>5</b> Ohms. We want to find the current that the supply will source through the resistor. If we recall that <b>E = R x I </b>we can solve for the current <b>I = E/R </b>then <b>10/5 = 2 </b>Amps. But what if we've got multiple resistors?<br />
<br />
<h3>
Resistors in series</h3>
<div>
<span style="font-weight: normal;">If you have multiple resistors in series, you just have to sum their values and replace all the resistors by one resistor that is the total of the others. See this circuit :</span><br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOk8V13nuMY8y-84nXQCl3coL3Mc6zO6C9zJLgIPUKG1as2j2K7L9udCrNYZix6rPJmmt2lsVRuNVgMuXhZueJx3tClex6I8IE8TY7EPtFxLk6QDOT5S6SytOyPwG9al2C0u53hKwh2Inx/s1600/series.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="345" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOk8V13nuMY8y-84nXQCl3coL3Mc6zO6C9zJLgIPUKG1as2j2K7L9udCrNYZix6rPJmmt2lsVRuNVgMuXhZueJx3tClex6I8IE8TY7EPtFxLk6QDOT5S6SytOyPwG9al2C0u53hKwh2Inx/s400/series.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
</div>
<div>
<span style="font-weight: normal;">The 2 and 3 Ohms resistors can be replaced by a resistor of 5 Ohms. You then are </span><b>I = E/R</b>, <b>5/5 = 1 </b> Amps.</div>
<div>
<br /></div>
<div>
Remember : what we are doing here is circuit reduction. In the above example, we reduced the circuit to find the total current the goes through the resistors. In a series circuit, <b>the current is the same through the series component.</b> This means that above, you have <b>1</b> Amps through <b>R1</b> <b>and R2</b>. To completely solve the circuit, you would want to know the voltage accross the two resistors. Easy! Remember <b>E = R x I </b>? For <b>R1</b>, <b>E = 2 x 1 = 2 </b>Volts. I hope you guess that we have <b>3 </b>Volts across <b>R2</b>.</div>
<div>
<br /></div>
<h3>
Resistors in parallel</h3>
<div>
For parallel resistors, the formula is a little bit more complicated. When we have two resistors <b>R1 </b>and <b>R2</b>, the parallel resistance <b>R3 </b>is calculated with <b>1/R3 = 1/R1 + 1/R2</b>. You can reduce the formula to <b>R3 = (R1 x R2) / (R1 + R2)</b>. After a while, you will realize that if two resistors of the same value are in parallel, the result will be the half of the resisor value. Proof : <b>(R0 * R0) / (R0 + R0) = (R0^2) / (2*R0) = R0/2</b>, half of <b>R0</b>.<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghLJ9-FvvqQ2V2AJOmVuLsiTxKCYF4WFGnGpRK1l9HN0CeoGfVLg6woLjYIn2J-d7D1Krmt0KznD3JVSNuM9-gJM397_Qv-RmFNjWXo4XRx5PnR4Sp7fs0fWQrkmip_mRZ4BaaofuJf95r/s1600/parr.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghLJ9-FvvqQ2V2AJOmVuLsiTxKCYF4WFGnGpRK1l9HN0CeoGfVLg6woLjYIn2J-d7D1Krmt0KznD3JVSNuM9-gJM397_Qv-RmFNjWXo4XRx5PnR4Sp7fs0fWQrkmip_mRZ4BaaofuJf95r/s640/parr.jpg" width="640" /></a></div>
<br /></div>
<div>
In the above circuit, the resistors are the same, <b>20</b> Ohms. <b>R3 = (R1 * R2) / (R1 + R2) = ( 20 * 20) / (20 + 20) = 400 / 40 = 10</b> Ohms. The current sourced by the batteries : <b>I = E/R</b>, <b>24/10 = 2.4 </b>Amps. </div>
<div>
<br /></div>
<script language="JavaScript">
function print2 (form) {
r1 = form.r1.value
r2 = form.r2.value
sum = 1*r1+1*r2
mul = r1*r2
par = mul/sum
par = par.toFixed(1)
alert("Equivalent resistor = "+par+" Ohms")
}
</script>
<br />
<form>
<fieldset style="width: 200px;">
<legend>Parallel Resistors Calculator</legend>
R1:<input name="r1" size="3" type="text" value="" />Ohms<br />
R2:<input name="r2" size="3" type="text" value="" />Ohms<br />
<br />
<input onclick="print2(this.form)" type="button" value="Calculate" /></fieldset>
</form><br>
Observe that the resulting resistor is always at a lower value than the smaller of the two resistors value.
<br>
<br>
<h3>
Units in electronics</h3>
<div>
In the circuits above, we have several amps through the resistors. This means a lot of heat and big resistors (physically). Most of the time, in electronics circuits, we have currents about 1000 times smaller. The resistors used are several thousands times bigger than the ones used in the examples.</div>
<div>
<br /></div>
<div>
The most common SI (International System) units are : milli (1/1000) and kilo (1000x). Generally, we have milliamps, kiloohms, and volts stay the same. If you multiply kiloohms and milliamps, you end up with volts. The fun part is that you can calculate everything without caring too much about the units, just remember that you have milliamps and kiloohms. Example (from above) : <b>R = 5 </b>kiloohms, <b>E = 10 </b>Volts : <b>I = E/R </b>; <b>10/5 = 2 </b>milliamps. See? The units are not the same but the numbers are. Don't worry, it will eventually sink into your brain...<br />
<br /></div>
<h3>
Shortcut : voltage dividers</h3>
<div>
When you have 2 resistors in series (see example above) you can easily find the voltage across each resistors. This is needed to completely solve the circuit. <b>V2 </b>is going to be the voltage across <b>R2</b>. If <b>R2 (3</b>Ω<b>)</b> is next to <b>GND</b> (ground) and <b>R1 </b><b>(2</b>Ω<b>)</b><b> </b>is<b> </b>next to the positive supply : <b>V2 = E * (R2 / (R1 + R2))</b>. In the example of the series resistors : <b>V2 = 5 * (3 / (2 + 3)) = 5 * (3 / 5) = 15 / 5 = 3</b>. We then have <b>3 </b>Volts across <b>R2</b>, exactly what we found earlier. Here is a little form to test voltage dividers :<br />
<script language="JavaScript">
function print (form) {
v = form.voltage.value
r1 = form.r1.value
r2 = form.r2.value
sum = 1*r1+1*r2
v2 = v*(r2/sum)
v2 = v2.toFixed(2)
alert("Voltage across R2 = "+v2+"V")
}
</script>
<br />
<form>
<fieldset style="width: 200px;">
<legend>Voltage Divider Calculator</legend>
V+:<input name="voltage" size="3" type="text" value="" />V<br />
R1:<input name="r1" size="3" type="text" value="" />Ohm<br />
R2:<input name="r2" size="3" type="text" value="" />Ohm<br />
<br />
<input onclick="print(this.form)" type="button" value="Calculate" /></fieldset>
</form>
<br /></div>
<div>
<br /></div>
<h3>
Conclusion</h3>
<div>
Okay, I have to admit that a lot of boring calculations were done in this post, but they are needed for the most simple circuits and this is the basis to understand all the later examples. This will help us to get lower voltages from a higher voltage source with the right combination of resistors. We will also be able the verify the current flowing through our components and be sure that the current ratings are respected.<br />
<br />
The next post will quickly cover the operation of the diode, and we will see how to light some LEDs (Light Emitting Diodes). This will be a lot of fun =D</div>Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0tag:blogger.com,1999:blog-582219234592513124.post-8358727095465991112013-01-25T21:35:00.002-05:002013-01-30T09:54:40.545-05:00Basic electrical quantities : the Ohm's law<h2>
Quantities</h2>
<div>
Everybody has heard about voltage, current and resistance electrical quantities. Here is what you have to know about them to get started.<br />
<br /></div>
<h4>
Voltage - E</h4>
<div>
Voltage, also known as potential difference, is the initiator of current flow. The unit of the voltage is the Volt (V). In the nature, every systems seeks the equilibrium. Think about the temperature : you have some rooms at different temperature, if you open the doors, the temperature will settle at a value sitting in between the maximum and minimum temperature of the rooms. The same happens for electricity, pressure (i.e. water level in pots) and even odours. Voltage consist of an unbalance of electrical charges (electrons). So the electrical potential difference will create a flow (current) when a path exist between the positive and negative electrodes.</div>
<div>
<br /></div>
<div>
Voltage can be stable over time (DC) or varies over a period (AC). There are also transient voltages, that exists for a short amount of time. In electronics, we mostly use direct current. This is because of the transistors, which works only in DC (every digital integrated circuits are made of a lot of transistors).<br />
<br /></div>
<h4>
Current - I</h4>
<div>
We already said that the current is the results of the electrical potential difference. The unit of the current is the Ampere (A) and correspond to a flow of a predefined quantity of electrons per second. For the curious, this predefined quantity is one coulomb and it contains 6.24x10^18 electrons. The electrical current is responsible of heat elevation in the different conductors. This is the principle of the electric heater. Current in a wire will also generate something invisible called a magnetic field. The same kinds of magnetics field are generated by magnets.<br />
<br /></div>
<h4>
Resistance - R</h4>
<div>
The quantity that links voltage and current is known as the electrical resistance in Ohm (Ω). For a lower value of resistance, a higher value of current will flow for a certain voltage level. Materials with low resistance are called conductors (i.e. metals, plasmas); the ones with high resistance are called insulator (i.e. ceramics, glass, plastics...). In other words, the resistance limits the flow of current.<br />
<br />
<h4>
</h4>
<h4>
Power - P</h4>
</div>
<div>
The power is expressed in Watts (W) and is used to calculate the amount of energy consumed by a circuit. In fact, energy is the result of power over a certain amount of time. For example, you have one 100W light bulb, on for a period of 10 hours. This result of an electrical energy consumption of 1000W for one hour : 1kWh. The kilowatt hour is the unit of energy used by electrical distributors to bill their clients.</div>
<div>
<br /></div>
<h2>
Ohm's law</h2>
The Ohm's law is the most basic and most used formula in the electrical domain. It was named after the German physicist Georg Ohm, in 1827. This law links the three principal electrical quantities.<br />
<br />
<b>E = R </b>x <b>I </b><br />
<b><br /></b>
This is all you have to remember. By manipulating this formula with simple algebra, you can compute each quantity by knowing the other two. Here is an interesting picture that shows the possible equations we can generate with the Ohm's law (and by knowing that <b>P = E </b>x<b> I</b>).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_ViXtO3pKJMgrb9bseM9c157V9oC8ix0-VyiL70BojwVDnUomDImkQUq3SDoYhthNjIKC6UrCV2-tqbzS1zCaHG-ErFjOPMUniUG7lybTnEQSWg8D3_hLk0vRC9K08mJFto67HP9_focu/s1600/watt.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_ViXtO3pKJMgrb9bseM9c157V9oC8ix0-VyiL70BojwVDnUomDImkQUq3SDoYhthNjIKC6UrCV2-tqbzS1zCaHG-ErFjOPMUniUG7lybTnEQSWg8D3_hLk0vRC9K08mJFto67HP9_focu/s1600/watt.jpg" /></a></div>
<br />
I'm going to give various calculation examples, can you guess which equation is being used?<br />
<br />
<ul>
<li>8A flowing in a 3Ω resistor generates a 24V potential difference</li>
<li>12V across a 4Ω resistor generates a current flow of 3A</li>
<li>To get 4A flowing with a 8V DC supply, you need to connect a 2Ω resistor across the supply contact </li>
<li>There are 2A flowing in the filament of a 240W light bulb from the 120V AC main (wall outlet)</li>
</ul>
<div>
<br />
Take a look at this Ohm's law calculator, just let one blank field for the unknown value.</div>
<div>
<br /></div>
<script language="JavaScript">
function print0 (form) {
v = form.v.value
c = form.c.value
r = form.r.value
if (v && c)
{
ans = v/c
alert("The resistance is = "+ans.toFixed(2)+" Ohms")
}
if (v && r)
{
ans = v/r;
alert("The current is = "+ans.toFixed(2)+" Amps")
}
if (r && c)
{
ans = r*c;
alert("The voltage is = "+ans.toFixed(2)+" Volts")
}
}
</script>
<br />
<form>
<fieldset style="width: 200px;">
<legend>Ohm's Law Calculator</legend>
Voltage:<input name="v" size="3" type="text" value="" />Volts<br />
Current:<input name="c" size="3" type="text" value="" />Amps<br />
Resistance:<input name="r" size="3" type="text" value="" />Ohms<br />
<br />
<input onclick="print0(this.form)" type="button" value="Calculate" /></fieldset>
</form><br>
<div>
</div>
<div>
<br /></div>
<div>
I hope you learned something new by reading this post. The next step will be to fiddle with a power supply and resistors to get the grips with the Ohm's law. You will also learn about voltage dividers.</div>
<div>
<br /></div>
<div>
See you later friends and have fun!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3REL2B3S0KLC7Zdsmv_pIwOpHIf_sTsudSKBdnvCXVnasRBOWuqCVJKl582Q3BQPT3Z7gm95sZVFh4ZFhQepeu6EjMxdSRjV7IshtxDGe6QkaFc8e97v99Izn4p44TU9nRNgLzH0K-0J5/s1600/equation+cartoon.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3REL2B3S0KLC7Zdsmv_pIwOpHIf_sTsudSKBdnvCXVnasRBOWuqCVJKl582Q3BQPT3Z7gm95sZVFh4ZFhQepeu6EjMxdSRjV7IshtxDGe6QkaFc8e97v99Izn4p44TU9nRNgLzH0K-0J5/s320/equation+cartoon.jpg" width="293" /></a></div>
<br /></div>Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com1tag:blogger.com,1999:blog-582219234592513124.post-19043478524585389792013-01-25T09:44:00.001-05:002013-01-25T19:42:14.699-05:00Checklist for beginner electronics kitSome of the Parallax "forumistas" told me that I should post a list of cheaper tools and instrument to get started with electronics. By the way, <a href="http://www.parallax.com/" target="_blank">Parallax Inc.</a> is a great place to buy sensors, robot parts, microcontroller development kit, etc... They also developped their own microcontroller, the Propeller, that I will cover extensively in the next weeks. Don't forget to take a look at <a href="http://forums.parallax.com/" target="_blank">their forum</a>, the people there are really nice and can answer the most of your questions.<br />
<br />
So here is what I came with for a budget beginner electronics kit (parts found on Newark) :<br />
<br />
<br />
<ul>
<li>DURATOOL 22-8850 - WIRE STRIPPER - 4$</li>
<li>DURATOOL D00120 - WIRE CUTTER - 2.70$</li>
<li>DURATOOL TL10328 - LONG NOSE PLIERS - 2.60$</li>
<li>AMPROBE AM-500 - DIGITAL MULTIMETER - 30$</li>
<li>NTE WHS22-00-25 - HOOK-UP WIRE 25FT BLACK - 3.70$</li>
<li>NTE WHS22-02-25 - HOOK-UP WIRE 25FT RED - 3.70$</li>
<li>GLOBAL SPECIALTIES GS-830T - BREADBOARD - 9.30$</li>
</ul>
<div>
The good thing with the Amprobe multimeter is the auto-ranging feature, it automatically detects the value range of the voltage/current/resistance you are measuring. When buying wire for breadboarding, you have to get solid core wire, not stranded. I did this error with my last order. The part number looks the same for the 25 feet NTE 22 gauge; solid wire: whs22, stranded wire: wh22.</div>
<div>
<br /></div>
<div>
If you plan to do some soldering, you can take a look at :</div>
<div>
<br /></div>
<div>
<ul>
<li>WELLER WES51 - ANALOG SOLDERING STATION - 125$</li>
<li>KESTER 83-4000-0000 - POCKET PACK SOLDER - 3.70$</li>
</ul>
<div>
An benchtop oscilloscope is a more exotic beast. For low cost alternative, you can take a look at USB oscilloscope like <a href="http://www.parallax.com/StoreSearchResults/tabid/768/txtSearch/propscope/List/0/SortField/4/ProductID/586/Default.aspx" target="_blank">this one</a>. You can even find ones that you can directly embed in a breadboard :<br />
<br /></div>
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/Q22tB7C-bMg" width="560"></iframe>
<br />
<div>
<br />
Finally, here is an example BOM (Bill of Materials) of the beginner kit.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVg_pDxpaLtiS1FwXTOJNGWh2DWUMNJsjGGSnAYsWimyOls_qZ25XcWFiqLNDEqlYdpH7KnCxLtb0s0dI1FcmmKNKKdlGFWKSTumRYL4Z7hUmmfTzQucdS1WN80GDV6LFX_63deZ9Hdf8l/s1600/order.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVg_pDxpaLtiS1FwXTOJNGWh2DWUMNJsjGGSnAYsWimyOls_qZ25XcWFiqLNDEqlYdpH7KnCxLtb0s0dI1FcmmKNKKdlGFWKSTumRYL4Z7hUmmfTzQucdS1WN80GDV6LFX_63deZ9Hdf8l/s1600/order.png" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
In the next tutorials, I will cover basic components needs along with circuit schematics.<br />
<br />
<br /></div>
</div>
<div>
<br /></div>
Testhttp://www.blogger.com/profile/10476755884474865744noreply@blogger.com0