tag:blogger.com,1999:blog-21295873832578768182024-03-28T00:53:15.284+01:00GizmosnackKarl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.comBlogger14125tag:blogger.com,1999:blog-2129587383257876818.post-91708302846801740502015-11-05T08:15:00.001+01:002016-11-04T09:17:57.662+01:00AUX in Volvo HU-XXXX radio This post is a description/tutorial on how I managed to hack the stereo (HU-650) in my Volvo V70 (2007) and successfully added my own AUX input. This hack should work with any HU-xxxx unit, "HU" meaning Head Unit (the stereo)<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWMB9-epEkyu1GiULJhebP23FiLFCRw9RcN4haS1cplrVkBeJyVS10PmIIlyq9tqmQh0gOMVoqhBX-T82npgDrSc9CZzWPU1G9A0sOTganTVFfz1XgJQLQXfOC-ttGtIKSGyaVlWN5RrLT/s1600/2015-11-03+23.33.15.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWMB9-epEkyu1GiULJhebP23FiLFCRw9RcN4haS1cplrVkBeJyVS10PmIIlyq9tqmQh0gOMVoqhBX-T82npgDrSc9CZzWPU1G9A0sOTganTVFfz1XgJQLQXfOC-ttGtIKSGyaVlWN5RrLT/s640/2015-11-03+23.33.15.jpg" width="480" /></a></div>
<br />
<h2>
Background</h2>
Why, why, why isn't there an AUX input on my car stereo from 2007?<br />
Yes 2007 was before the big era of smartphones, but everyone owned a couple of dirt cheap mp3 players and iPod was a big thing.<br />
<br />
The HU that my car is fitted with has two super retro 8-pin DIN-connections on the back. One of which is for connecting a CD-changer "CD-CHGR" that you could have installed in the boot of the car - but who uses CDs these days?<br />
<br />
It didn't take allot of research to find out there is already a <a href="http://www.auxadapter.se/">product out there</a> that lets you add an AUX to you HU-xxxx. The only drawback is that it sets you back $80 and most of all: It doesn't come with the awesome feeling that you get when you have hacked the stereo yourself.<br />
<br />
<h2>
Research</h2>
It wasn't an easy thing finding information on how to hack the HU, but after allot of research I finally found some really good pages that made the hack easy peasy.<br />
<br />
<h4>
This is how it works:</h4>
<ul>
<li>The source knob on the HU lacks the ability to choose the CD-CHGR until you connect the CD-changer. </li>
<li>To trick the HU that you have a connected a CD-CHGR is not as easy as to shorten two of the pins on the DIN-connector, but it has to be done in code via a protocol named MELBUS</li>
<li>MELBUS is a protocol that utilizes a clock pin and a single bi directional data line to transfer the data between the units and the HU.</li>
<li>MELBUS uses three lines: Clock, Data and Busy see blue lines on picture below: ("Run" is just 12V from battery)</li>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK_dAf1rW90L65G0q-tMFMfGeBT_oZDNLbXVNHHfz920kbsgbZq7zRHdyLJsgSa6Q9-3J0OZErC97rbuGcXmTzTQnR8mqGneVK1YFZgoSc1NWgvUG8kWrVKr1gBtH15uw0hMaI3cLZz5MT/s1600/MELBUS.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK_dAf1rW90L65G0q-tMFMfGeBT_oZDNLbXVNHHfz920kbsgbZq7zRHdyLJsgSa6Q9-3J0OZErC97rbuGcXmTzTQnR8mqGneVK1YFZgoSc1NWgvUG8kWrVKr1gBtH15uw0hMaI3cLZz5MT/s640/MELBUS.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://forums.swedespeed.com/showthread.php?50450-VW-Phatbox-to-Volvo-Transplant-(How-To)&highlight=phatbox">Picture source</a></td></tr>
</tbody></table>
<ul>
<li>In the picture above you can also see the Left and Right Audio signals that I tapped into for the AUX-input (Red). </li>
<li>Focus on the left DIN-Socket (female) on the picture, that's the back female socket on the HU. </li>
</ul>
<div>
<br />
<h2>
Hardware</h2>
<br />
<ul>
<li><a href="http://www.ebay.com/sch/i.html?_odkw=arduino+nano+usb+cable&LH_BIN=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.Xarduino+nano+with+cable.TRS0&_nkw=arduino+nano+with+cable&_sacat=0">Arduino Nano (clone) with USB-cable</a> - $2.5</li>
<li><a href="http://www.ebay.com/sch/i.html?_odkw=8-Pin+DIN+plug&LH_BIN=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.X8-Pin+DIN+plug+male.TRS0&_nkw=8-Pin+DIN+plug+male&_sacat=0">8-Pin DIN</a> male plug (pins exactly like the pic above) - $1</li>
<li>0.5m network cable - free</li>
<li>1m 3.5 mm audio cable - free (who doesn't have a drawer full of them?)</li>
</ul>
Total cost: ~$3.5</div>
<div>
<br /></div>
<h2>
Hacking together some code</h2>
<div>
<b><i>Edit 2016-11-04</i></b><br />
A guy named Sebastian has modified my code and his version is more stable, and it also works on Mitsubishi HU and supports displaying track numbers! -<a href="https://gist.github.com/klalle/1ae1bfec5e2506918a3f89492180565e">Here's a link to his code!</a><br />
<br /></div>
<div>
Finally some programming! </div>
<div>
I found <a href="http://volvo.wot.lv/wiki/doku.php?id=melbus">this </a>awesome write-up that contained almost everything I needed to fool the HU that the Arduino is a CD-CHGR. I will talk you through the process:</div>
<div>
<ol>
<li>Set BUSY to low for 1000 ms to make the HU run its initialization routine</li>
<ol>
<li>The HU init routine starts by sending three bytes: 0x07 0x1A 0xEE</li>
<li>Then two bytes per optional connection device (~30 of them), the first byte being the predefined ID of the device (ex. CD-CHGR = 0x8E), followed by either an empty byte 0xFF, if the device is not connected, or the answering ID of the device (CD-CHGR = 0xEE) <br /><br />Example: External CD-CHGR: ID = 0x8E and its return ID is 0xEE<br />Example: Internal CD-player: ID = 0x80 and its return ID is 0x86<br />See list of predefined addresses and returns on bottom of <a href="http://volvo.wot.lv/wiki/doku.php?id=melbus">this site. </a></li>
<li>I.e. to simulate a connected CD-CHGR we have to: </li>
<ol>
<li>Trigger the HU init routine</li>
<li>Wait until HU is sending out our ID (0x8E)</li>
<li>Respond to that by sending back 0xEE </li>
</ol>
</ol>
<li>Now the HU has registered that we have a CD-CHGR and it is now available through the source-knob, and will listen to the Left and Right Audio pins on the DIN-plug. </li>
<li>Every time the car ignition is turned on, the HU will automatically run a secondary initialization routine:</li>
<ol>
<li>Starting by sending four bytes: 0x00 0x00 0x1C 0xED </li>
<li>Then two bytes per already registered connection devices from the first init routine, the two bytes follows the same pattern as in the first init routine, first ID, than expecting the same answering byte as before.</li>
<li>If the HU won't get an answer from the CD-CHGR, the device will be removed, and we have to set BUSY low again to call the first init-routine. </li>
</ol>
</ol>
That's it for fooling the HU that the CD-CHGR is connected, now it's just a matter of connecting a device to the Left and Right Audio pins plus Ground. I soldered a network cable plus an 3.5 mm Audio cable to the pins of a DIN-plug.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsxCPI0KUptFr22yGMgrCHSpF9iSbZwup5S79d46AfzjvXxhBnVpsNfPNyd1e_6eFRl_cl2mt_kj2Nl-vXurymiPzxJXn_mdTst80rOlvUd3F5K2saA5HpzjNfSlits8LPW2V4d3pDzy0W/s1600/2015-11-02+17.35.51.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsxCPI0KUptFr22yGMgrCHSpF9iSbZwup5S79d46AfzjvXxhBnVpsNfPNyd1e_6eFRl_cl2mt_kj2Nl-vXurymiPzxJXn_mdTst80rOlvUd3F5K2saA5HpzjNfSlits8LPW2V4d3pDzy0W/s640/2015-11-02+17.35.51.jpg" width="480" /></a></div>
Take care when reading the schematics above, it is the left socket on the picture you are interested in, that's the socket on the back of the HU-unit (female) and will be equal to the <b>back</b> of the DIN-plug. (as you can see, I put the red cable on the "RUN" to use the 12V to power the arduino, White and yellow are Audio Left and Right)<br />
As a bonus the 12V is only active when the ignition is turned on => no extra load on battery caused by the arduino when car is not used)<br />
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3GtbchXFTxocN1ntzvkDkS8UDoWq-s21KR6p9-X9HDD7UBM63jBJVsxJCx2KYDOP9zyXFcr2RiCCqdEGOnk2crBcc0g_Mjv5-wqLi97t6AH4kUdglBM44KiUSR5JAvVsl1nBCasWSBSKM/s1600/2015-11-02+17.46.56.jpg" imageanchor="1" style="clear: right; display: inline !important; margin-bottom: 1em; margin-left: 1em; text-align: center;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3GtbchXFTxocN1ntzvkDkS8UDoWq-s21KR6p9-X9HDD7UBM63jBJVsxJCx2KYDOP9zyXFcr2RiCCqdEGOnk2crBcc0g_Mjv5-wqLi97t6AH4kUdglBM44KiUSR5JAvVsl1nBCasWSBSKM/s640/2015-11-02+17.46.56.jpg" width="480" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
The code I wrote (below) is well documented and fairly easy to understand...<br />
<br />
I had a hard time getting the function "SendByteToMelbus(uint8_t byteToSend)" to work.<br />
It turned out that the Arduino functions: digitalWrite(MELBUS_DATA, HIGH); and LOW are too slow for this code, (MELBUS runs at 10-12MHz) and CLK had returned to high state before Databit was changed.<br />
<br />
To solve this, I had to go back to the old AVR-GCC technique and use<br />
PORTD |= (1<<MELBUS_DATA); and<br />
PORTD &= ~(1<<MELBUS_DATA);<br />
in place of the Arduino functions.<br />
<br />
I tried this setup without any form of ground-loop isolation and it works like a charm! Even when the engine is running and my smartphone is charging through the cigaret-socket the sound is crisp and no disturbing noise (alternator suppose to cause ground noise)<br />
<br />
I guess one could buy an external <a href="http://www.ebay.com/sch/i.html?_odkw=ground+isolator&LH_BIN=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.Xground+loop+isolator.TRS0&_nkw=ground+loop+isolator&_sacat=0">Ground Loop Isolator</a> ($5) to be on the safe side....</div>
<div>
<br /></div>
<div id="" style="height: 750px; overflow-y: scroll;">
<script src="https://gist.github.com/klalle/ddf22bc67aa7a29e6f15.js"></script></div>
<br />
<br />
<br />
<br />
<br />
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com192Gävle, Sverige60.6748796 17.14127259999997960.5505006 16.818549099999981 60.799258599999995 17.463996099999978tag:blogger.com,1999:blog-2129587383257876818.post-48677863158256172272014-11-23T23:41:00.000+01:002015-02-26T13:28:06.001+01:00Power Plug Energy Meter - Now wireless!This is the second post about my work on the cheap China-style energy meter hack.<br />
My<a href="http://gizmosnack.blogspot.se/2014/10/power-plug-energy-meter-hack.html"> last post</a> covered how I with a logic analyzer successfully (but not in the safest way) sniffed the SPI-transmission on the device and managed to decipher the data. And then how I used an Arduino Nano to do the sniffing for me with an interrupt driven approach. The Arduino translated the bits and bytes to power and voltage values that it continuously printed on the PC's Serial monitor via an USB-cable.<br />
<br />
The next obvious step in this project is to get the energy meter to transmit the data wirelessly. Not only would this mean that I could grab data from several energy meters simultaneously, but it also creates a safe way of debugging the device since my previous setup (which I abandoned after reading some of the comments on <a href="http://hackaday.com/2014/10/21/digital-data-from-a-cheap-power-meter/">Hackaday</a>.com) meant connecting the mains neutral to the computers ground (do not try this at home!!!)<br />
<br />
Today's post will cover how I managed to get an Arduino pro mini (3.3V) to sniff the energy meters SPI and transmit the data wirelessly with a nRF24L01+ to an Arduino Nano connected to a computer. The neat thing with this setup is that the Arduino pro mini and the nRF fits perfectly within the casing of the energy meter, and are both driven by the internal power that charges the rechargeable battery that you'll find in the meter.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO6H3sbB9OzAmqPsnnsi6ytwur1_3e-Jc3QvFVwUbrcCcrdYlVX1Z1GKZbgjCChbGhVnaTFt0ba7S63j9GM_hToZ-_FJoBC4sxPv1jknZySb4y57rFTIOck3OPrdX9Om786GZWv2qZ317W/s1600/2014-11-17+22.05.39.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO6H3sbB9OzAmqPsnnsi6ytwur1_3e-Jc3QvFVwUbrcCcrdYlVX1Z1GKZbgjCChbGhVnaTFt0ba7S63j9GM_hToZ-_FJoBC4sxPv1jknZySb4y57rFTIOck3OPrdX9Om786GZWv2qZ317W/s1600/2014-11-17+22.05.39.jpg" height="360" width="640" /></a></div>
<br />
The total cost of components for each energy meter is:<br />
<a href="http://www.ebay.co.uk/sch/i.html?_odkw=energy+meter&LH_PrefLoc=2&_sc=1&_fcid=192&_sop=15&_jgr=1&_from=R40%7CR40%7CR40%7CR40%7CR40%7CR40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR1.TRC0.A0.H1.Xenergy+meter+plug&_nkw=energy+meter+plug&_sacat=0">Energy meter</a> £7.97<br />
<a href="http://www.ebay.co.uk/sch/i.html?_odkw=Arduino+Mini+3.3+V&LH_PrefLoc=2&_sc=1&_fcid=192&_jgr=1&_sop=15&_from=R40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.XArduino+pro+Mini+3.3+V&_nkw=Arduino+pro+Mini+3.3+V&_sacat=0">Arduino Mini 3.3 V</a> £2.58<br />
<a href="http://www.ebay.co.uk/sch/i.html?_odkw=nrf24l01%2B&LH_PrefLoc=2&_sc=1&_fcid=192&_sop=15&_jgr=1&_from=R40%7CR40%7CR40%7CR40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.Xnrf24l01%2B+-socket&_nkw=nrf24l01%2B+-socket&_sacat=0">nRF24L01+</a> £0.99 (choose the black + version)<br />
A capacitor + cables pretty much free, say £1<br />
<br />
which comes to a total of £12.54 per unit!<br />
<br />
Plus one computer connected node, or a raspberry pi with a nRF24L01 to receive the transmissions from all the energy meters.<br />
<br />
<b><span style="font-size: x-large;">Arduino and RF24.h</span></b><br />
As mentioned in <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-nrf24l01-and-avr.html">previous blog-posts</a> I have worked quite allot with the nRF24L01 and AVR's, writing my own libraries and so on. But since this is my first Arduino-project I wanted to learn how to import and use other peoples libraries. Since I am still a newbie in programming, I always have to learn everything from scratch, and nothing ever works as supposed to when I try to follow a tutorial...<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE3pJ9jfxxNVOl8f_ZiIhRTsraIqseP28ABqr6Gr_OS8bQZXjoH0rcm8Ji9uPJjPg2_WdGVYM10uuBBRLDAebai1YqlFWP-kajID3MJv2lZl4J5LNoYYqavh0U872OEt8a3fNBj8NXdHKf/s1600/aaa.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE3pJ9jfxxNVOl8f_ZiIhRTsraIqseP28ABqr6Gr_OS8bQZXjoH0rcm8Ji9uPJjPg2_WdGVYM10uuBBRLDAebai1YqlFWP-kajID3MJv2lZl4J5LNoYYqavh0U872OEt8a3fNBj8NXdHKf/s1600/aaa.JPG" height="276" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
I started out by setting up two Arduino Nanos according to <a href="http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo">this guide</a> and running the example code at the bottom of that page, and as expected - <i>it didn't work. </i><br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<i><br /></i>
<br />
<span style="font-size: large;">Debugging</span><br />
<b>1. Do I have a working SPI-connection?</b><br />
I had followed the explanation in the guide i linked to above, on how to install the <a href="http://maniacbug.github.io/RF24/">RF24.h</a>-library and it all seamed to work, I definitely had a working SPI-connection between the Arduino and the nRF since I could print out all the registers, and modifying them also worked...<br />
<br />
Took me a while to figure out that I had to download and include the file "printf.h" and call "printf_begin();" to print out data from the nRF to the serial monitor... and why, why, why are they using the "protected" attribute for many of the functions??? For example get_status is a very useful debug-function and should not be protected!<br />
<br />
<b>2. Am I using the correct hardware setup? </b><br />
As always I hadn't used the exact components as the instructions said, in my drawer I could only find one 47 uF 24 V and one 100 uF 16 V capacitors. Well in the guide it sais:<br />
<span style="font-size: x-small;"><span style="background-color: white; color: #006699; font-family: 'Comic Sans MS'; line-height: 30px;">"Connect a .3.3 uF to 10 uF (MicroFarad) capacitor </span><span style="background-color: white; box-sizing: border-box; color: #006699; font-family: 'Comic Sans MS'; line-height: 30px;">directly on the module</span><span style="background-color: white; color: #006699; font-family: 'Comic Sans MS'; line-height: 30px;"> from +3.3V to Gnd (Watch + and - !) <b>[Some users say 10 uF or more..]"</b></span></span><br />
And I read 10 uF or more....<br />
<br />
Anyways, I thought that this should work, since I have used these capacitors before on the nRF, but not with this library and not with Arduino...<br />
<br />
<b>3. I found a working code</b><br />
Yay, suddenly i found a working code, the "pingpair" example that comes with the NRF.h-library worked with my setup!<br />
<br />
<b>4. Why does only Pingpair-code work? </b><br />
I started stripping the Pingpair-code of its components, and found that my setup was only working when it got into receiving mode in between every transmission... strange, but keeping in mind that I was using bigger capacitors I figured it had something to do with the capacitors not have time enough to recharge/discharge.<br />
<br />
I think this is what happened:<br />
When the Arduino calls the "Write" function, the library runs the "startWrite"-function which powers up the nRF and has a predefined delay of 150 us (wait for the nRF to power up) before it starts transmitting the data.<br />
It turned out that this delay was not enough for my setup, so when I changed this to 1000 us (1 ms), the code worked like a charm even without the receiving functions in between! To do this modification, I opened the RF24.cpp-file (in the arduino Sketchbook libraries folder) with notepad, changed the delay, and saved the file.<br />
<br />
<br />
<br />
<span style="font-size: x-large;"><b>Arduino Mini</b></span><br />
Just as I managed to get a working Arduino code for the nRF, two <a href="http://www.ebay.co.uk/sch/i.html?_odkw=Arduino+Mini+3.3+V&LH_PrefLoc=2&_sc=1&_fcid=192&_jgr=1&_sop=15&_from=R40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.XArduino+pro+Mini+3.3+V&_nkw=Arduino+pro+Mini+3.3+V&_sacat=0">Arduino Mini 3.3 V</a> landed in my postbox, awesome timing!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFuaYzLaNWzmtPm3wEWYfJqOUoHc1rK3zyncf6mb0Xi-w3stOfBSXhAkOHvAgzpeZCEbO-K3SvFTq1rczc7og_U2chwBVRlgIT8wjy7D7ZguxdDw9BuLON_hvHLF3xQaaDlVH5iOm5235O/s1600/aaa.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFuaYzLaNWzmtPm3wEWYfJqOUoHc1rK3zyncf6mb0Xi-w3stOfBSXhAkOHvAgzpeZCEbO-K3SvFTq1rczc7og_U2chwBVRlgIT8wjy7D7ZguxdDw9BuLON_hvHLF3xQaaDlVH5iOm5235O/s1600/aaa.JPG" height="320" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
One little problem; the Arduino Mini does not come fitted with an USB to Serial-chip to enable programming over USB.... luckily for me I had an USB to Serial adapter laying around (used for debugging AVR's, as I wrote about in <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-usart-and-avr.html">this tutorial-post</a>) that I could use to program the Arduino.<br />
<br />
Here's a pic of when I have soldered an nRF to the Arduino and uploading code with the USB to COM adapter via a breadboard (out of sight) so the colored cables does not match the pins...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7KiHzDx71ZKIJ_8NvoSiUrKHrHeuI4zQY1mZPxwmc_V17LxZu3j1kDJOI5B4uJQB8G-6HdJ7a3xhQ3myi3OyOFwdZliaFpj8E-W4y8NAvP5v5l4tf45xxgw_f4Rb18_NEdd1KoAYWYh4p/s1600/2014-11-10+19.30.21.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7KiHzDx71ZKIJ_8NvoSiUrKHrHeuI4zQY1mZPxwmc_V17LxZu3j1kDJOI5B4uJQB8G-6HdJ7a3xhQ3myi3OyOFwdZliaFpj8E-W4y8NAvP5v5l4tf45xxgw_f4Rb18_NEdd1KoAYWYh4p/s1600/2014-11-10+19.30.21.jpg" height="640" width="360" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Off course this didn't work straight away either, I found out that when using this kind of FTDI-adapter you have to press the reset-button on the Arduino Mini just when the Arduino-IDE starts to upload the code to get it working! A better buy would be one of <a href="http://www.ebay.co.uk/sch/i.html?_odkw=Arduino+Mini+3.3+V&LH_PrefLoc=2&_sc=1&_fcid=192&_jgr=1&_sop=15&_from=R40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.XArduino+Mini+3.3+V+ftdi&_nkw=Arduino+Mini+3.3+V+ftdi&_sacat=0">these</a> which comes with an automatic reset-pin ("DTR").<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
I soldered the nRF to the Arduino, and glued them together with some hot-glue, which was also used to attach the unit to the power meter. Plenty of unoccupied room in the meter behind the LCD, and perfect position for a wireless transmitter!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihc7kVC1qBZJIbGDwmxnPDhwxKF3YAu-JrTr5EJc2sXHkmHh19Rl_Pv8Gr4lN0dKNGyzSSF9LPex9wn-fKxvF4KMULm0Yq8AkfKRm-IbexjY_NuEjKfp3H6EYkviqGJGehqU-hKCtJ35GE/s1600/2014-11-10+18.56.25.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihc7kVC1qBZJIbGDwmxnPDhwxKF3YAu-JrTr5EJc2sXHkmHh19Rl_Pv8Gr4lN0dKNGyzSSF9LPex9wn-fKxvF4KMULm0Yq8AkfKRm-IbexjY_NuEjKfp3H6EYkviqGJGehqU-hKCtJ35GE/s1600/2014-11-10+18.56.25.jpg" height="400" width="225" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEIMqE6xYlP0isWeit0hEcl5qOmrgYSWvkcLPDo3Y0CkkKXVo8cbEgBRDndcv10xUKNJfzw7JzFtmYKJt41rBmUUN5nhCVXF1vqVUO-NmwFHdmzWRoFt3Ow8a5BjDqtUmCDnYQgja4EN8V/s1600/2014-11-10+18.56.45.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEIMqE6xYlP0isWeit0hEcl5qOmrgYSWvkcLPDo3Y0CkkKXVo8cbEgBRDndcv10xUKNJfzw7JzFtmYKJt41rBmUUN5nhCVXF1vqVUO-NmwFHdmzWRoFt3Ow8a5BjDqtUmCDnYQgja4EN8V/s1600/2014-11-10+18.56.45.jpg" height="400" width="225" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
Here you have the wire diagram: </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/AVvXsEhln_Np8v0xUo4NJ6vsjRSOP5j1sESJPRYJmvm1WGjZv-YRdWIj3cHZK4C0zofuoVHg8GHuqtscW0uCESHmms1ml7CAK_mgL82ozKrqLkLI0k4r7njI794nLtbJe6QuA9C5sUdpPlQ9NugD/s1600/Energy+Meter.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhln_Np8v0xUo4NJ6vsjRSOP5j1sESJPRYJmvm1WGjZv-YRdWIj3cHZK4C0zofuoVHg8GHuqtscW0uCESHmms1ml7CAK_mgL82ozKrqLkLI0k4r7njI794nLtbJe6QuA9C5sUdpPlQ9NugD/s1600/Energy+Meter.jpg" height="640" width="512" /></a></div>
<br />
I started off by just uploading a simple transmission code on the Arduino mini, that would send a dummy byte once a second to confirm a working setup. I soldered everything together, plugged the meter into an outlet and kept my fingers crossed as I watched the Arduino-Serial monitor connected to the receiving unit, and.... noting (of course!)<br />
<br />
After several hours of debugging, (I thought I had burnt the nRF by hooking it up directly to the power-meters VCC-pin) It turned out had I accidentally uploaded a non-working code to the Arduino Mini.... FAIL!!!<br />
<br />
I had cleaned up my working code, and shifted some parts around, it seems like you can't open the writing/reading-pipes on the nRF before you set the datarate/payloadsize/PALevel...<br />
<br />
Anyway, the setup I found working is grabbing the power directly from the battery (3.6 V soldered to the underside of the PCB) rather than the VCC-cable (which i think is a bit flaky, and is connected to the RAW-pin on the Arduino, which has a built in 3,3 V regulator. I'm not sure this modification is necessary, but it ensures that the nRF and the Arduino gets 3.3 V. (The pictures above are not connected to RAW, but the Arduino's 3.3 V)<br />
<br />
Here's whats transmitted to the computer connected Arduino and printed in the Serial monitor:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6iKHtLpVuSNAg_qjMe7b3cGK8ODuw31xRb3pJYGNMEs2wHkvul6IC9uUbqoY1VPmCZZFpO_UMYic8KHEOQz00-IsKMul2vDEzDWBZvC-Ttm-UXR6_fa6-_4UTfLJGx5cVj3Tystjzt_xv/s1600/aaaaaa.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6iKHtLpVuSNAg_qjMe7b3cGK8ODuw31xRb3pJYGNMEs2wHkvul6IC9uUbqoY1VPmCZZFpO_UMYic8KHEOQz00-IsKMul2vDEzDWBZvC-Ttm-UXR6_fa6-_4UTfLJGx5cVj3Tystjzt_xv/s1600/aaaaaa.PNG" height="530" width="640" /></a></div>
<br />
I have spent some time looking at ways to store and plot this data in the cloud. One interesting approach is to send the data to a website like <a href="http://emoncms.org/">http://emoncms.org/</a> and use there ready to use energy-viewing graphs. With the help of a small python-script I wrote, I can easily send the data from my raspberry pi-server to my account on there website where I have the option of making graphs. <br />
<br />
I have also been working in the program called "<a href="https://processing.org/">Processing</a>" which is pretty much the same as Arduino-IDE but for graphing and doing stuff with the data.<br />
I have so far programmed a working graph that shows the data output from up to 6 wireless energy meters, it also logs the data with timestamp to a csv-file. See the processing-code at the bottom.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFUiV9370Yi0Pi15qK0Oiw2xNnXUQttt_dhsvAfMLVwBZ8gpUmkD1VoP7qPRbvya_RSisLuGYELR5ldqNz3WQoUx-Y3JMKa9PMbHFlJs-8AqzPMI-bmfMYxk_bBuRXI9aFfB7x1RZp9MrD/s1600/Graf.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFUiV9370Yi0Pi15qK0Oiw2xNnXUQttt_dhsvAfMLVwBZ8gpUmkD1VoP7qPRbvya_RSisLuGYELR5ldqNz3WQoUx-Y3JMKa9PMbHFlJs-8AqzPMI-bmfMYxk_bBuRXI9aFfB7x1RZp9MrD/s1600/Graf.PNG" height="400" width="385" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Above you see a screenshot of when I have plugged in two energy meters (1 and 2). Nr 1 shows a soldering station which i obviously changed the power on allot during the readings. Nr 2 is a 4-step lamp that i flickered from 3 to 0 to 1 to 2 to 3. as you see i didn't stop at 0 for a very long time, so the graphed mean value stopped at ~10W.<br />
<br />
You might wounder why the red and green line (nr 1) sometimes differ? That's because I have the meter to transmit the average=red and the maximum=green power readings on every third power reading. This interval is easily changed by typing 1:1 or 1:4 to change the interval on meter 1 from to 1 or to 4 readings in between transmissions.<br />
<br />
I had a hard time figuring out how to transmit this new interval from the computer nrf to the meter, because if I in between every transmission changed the nRF to a receiver, the power consumption would cause the whole meter to stop working.<br />
<br />
This time I had to do some serious thinking, and I ended up using the possibility to alter the autoAck-payload. A function that normally sends an "OK" from the receiving nrf back to the transmitting nRF to confirm the transmission. I found out how to alter this value to send something like a "2" instead, or some other integer that would be a new interval. This was exactly what I needed, See the code at the bottom!<br />
<br />
Her's the working Arduino code, first for the Energy Meter then for the computer connected receiver-Arduino. At the very bottom you have the processing code:<br />
<br />
<div id="" style="height: 500px; overflow-y: scroll;">
<script src="https://gist.github.com/klalle/c107c343ff8dc9bd7518.js"></script>
</div>
<br />
Here's the code for the receiving Arduino (connected to computer via USB)
<br />
<div id="" style="height: 500px; overflow-y: scroll;">
<script src="https://gist.github.com/klalle/0084363be41e378d8697.js"></script>
</div>
<br />
And finally the Processing code that can be used to read and write to the computer connected Arduino through its serial connection (over USB)
<br />
<div id="" style="height: 500px; overflow-y: scroll;">
<script src="https://gist.github.com/klalle/4e5ded50cacf6dc7c1bc.js"></script>
</div>
Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com67tag:blogger.com,1999:blog-2129587383257876818.post-9921088601100526962014-10-20T23:59:00.003+02:002015-01-21T18:13:06.429+01:00Power Plug Energy Meter HackIt has been way to long ago since I tested my capability of hacking things.<br />
<div>
<br /></div>
<div>
Since i am an energy engineer, I have been looking for a cheap and easy way of monitoring my power consumption. </div>
<div>
I know there are other hackers out there that have already worked on this problem, and I have seen dozens of hacks on smart and dumb house-power meters, but only a few that covers power plug energy meters. </div>
<div>
<br /></div>
<div>
You have the <a href="http://www.ladyada.net/make/tweetawatt/">Tweetawatt</a> - awesome, but not my cup of tee (i prefer to write my own software for AVR or Arduino) and still ~55$ each...</div>
<div>
And a guy named Connor Wolf has an awesome project where he builds <a href="https://www.youtube.com/watch?v=Zc6N6vNxhZ8&list=UUlUP3SbgT2LGKvHKXkZAOAA">his own</a> and a video where he<a href="https://www.youtube.com/watch?v=MeTVCbjFft4"> tares a few standard power plug meters apart</a>. </div>
<div>
<br /></div>
<div>
I have seen how cheap the <a href="http://www.ebay.co.uk/sch/i.html?_odkw=lg+optimus+one+hard+case&LH_PrefLoc=2&_sc=1&_fcid=192&_sop=15&_jgr=1&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR10.TRC2.A0.H0.Xenergy+meter+eu&_nkw=energy+meter+eu&_sacat=0">China-version</a> of the energy meter is (£7,86), and when i saw the tare-apart video where he takes one apart, I went ahead and ordered two pieces of the EU-type (230V 3,6kW). Of course my intention was to convert them to my own cheaper version of the Tweetawatt.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR8gF10CjDzRuqbootwF2uLIrHtujozPvsCM_bSTDbFpKCwFRIKf2KM0Ykm8ySQSwGqpaACv81nUVowghjSZQLn6R4oQHANbSFj45rjDwgGGZ8m5KwKjTwuJdmNuAqz1INW3646xAbaMvM/s1600/2014-10-15+19.40.03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR8gF10CjDzRuqbootwF2uLIrHtujozPvsCM_bSTDbFpKCwFRIKf2KM0Ykm8ySQSwGqpaACv81nUVowghjSZQLn6R4oQHANbSFj45rjDwgGGZ8m5KwKjTwuJdmNuAqz1INW3646xAbaMvM/s1600/2014-10-15+19.40.03.jpg" height="360" width="640" /></a></div>
<br />
My final goal is to connect them to the internet either via an nRF24L01+ and my <a href="http://gizmosnack.blogspot.se/2013/05/raspberry-pi-nrf24l01-and-tcp.html">rPi-setup</a>, or with an ESP8266 Wifi adapter (if it will ever arrive in the mail box...)<br />
<br />
The future goal is to use an home made Android app to graph the data, i'm not quite there jet, but this tutorial describes how I hacked the power meter and successfully got the voltage, current and power readings to an arduino using interrupts on the CLK. </div>
<div>
<br /></div>
<div>
The meters showed up last week, and the first thing i did was to open the cover of one of them. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGNaVLnbb5Ln4Ih4xW2HsMN206VO9My0JQuFZ8UbDo9igOA9R1DNTpZhTV6BOMjUYZzzQEwAymgCyUSlVgcy2Ub5jWkzi_R9pbtx66NmNeDzhCFl0BrADLR7PF7jv8aZAQO2ntuEKgIK0/s1600/2014-10-15+19.40.16.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGNaVLnbb5Ln4Ih4xW2HsMN206VO9My0JQuFZ8UbDo9igOA9R1DNTpZhTV6BOMjUYZzzQEwAymgCyUSlVgcy2Ub5jWkzi_R9pbtx66NmNeDzhCFl0BrADLR7PF7jv8aZAQO2ntuEKgIK0/s1600/2014-10-15+19.40.16.jpg" height="360" width="640" /></a></div>
<div>
<br /></div>
<div>
The guts looked promising since it is very similar to the one in Connor Wolfs video with the 3,6 V battery and the ribbon cable between the two circuit boards. The differences i can see compared to the 110 V version is the big blue capacitor.<br />
<br />
The reason I started this project from the first place was because I had seen the ribbon cable labels in the video, so I was very satisfied when I confirmed that the 230 V version also came with the labeled ribbon cable between the power meter and the main processor which sits under the brown circuit board.<br />
<br />
The ribbon is labeled: </div>
<div>
VCC, SGND, FREQ, CLK, SDO and SDI as seen here:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOOJ6PVdQqh6shPgwNBwyfx06yZtL3kvevS2R1-aUesKGDd9UkMjpYrURTX89M9MbYy-EKoEZEcCx2XEmD1At0dDiwgENNb3VeWQgcsovxUckuCjHG4lpLx-iZB7tJd3Fl3deXdm9brYsJ/s1600/2014-10-15+19.58.56.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOOJ6PVdQqh6shPgwNBwyfx06yZtL3kvevS2R1-aUesKGDd9UkMjpYrURTX89M9MbYy-EKoEZEcCx2XEmD1At0dDiwgENNb3VeWQgcsovxUckuCjHG4lpLx-iZB7tJd3Fl3deXdm9brYsJ/s1600/2014-10-15+19.58.56.jpg" height="640" width="360" /></a></div>
<div>
<br />
I tapped into all of the 7 wires, (7?) yes there are 7 wires, only 6 labeled. closed the case, and plugged it into the wall.<br />
<br />
Before i hooked it up to my awesome £6, 8-channel, 24 MHz <a href="http://www.ebay.co.uk/sch/i.html?_odkw=saleae+logic+analyzer+-clips&LH_PrefLoc=2&_sc=1&_fcid=192&_jgr=1&_sop=15&_from=R40%7CR40%7CR40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0&_nkw=saleae+logic+analyzer+-clips&_sacat=0">logic analyzer</a> and started testing it in the logic analysing software, I firs checked all the cables with a multimeter to see that none of them was connected to mains (<a href="https://www.youtube.com/watch?v=LiDJp4VBJ_A">this video</a> shows that the Kill-a-Watt meter has 110 V on the ribbon cable strangely enough). But the China version was safe on all 7 wires and the five which weren't VCC or GND got its own channel on the logic analyzer:<br />
<br />
###WARNING!!! I'm not an expert in HVAC and there are lots of knowing people that read this article on <a href="http://hackaday.com/2014/10/21/digital-data-from-a-cheap-power-meter/#comments">Hackaday.com</a> and informed me that hooking up the logical analyser like this is an terrible idea! It seems like the energy meters DC-line is not grounded, but instead use Neutral as ground, which can be very different from your computers USB-ground... DO NOT USE MY SETUP, It can be both dangerous and harmful to the computer!<br />
<br />
If you want to test the SPI on a non-grounded device they have a lot of suggestions on how this should be done, optical isolation sounds pretty smart (maybe there are even optically isolated USB-hubs you could use?!) I guess I was lucky not to blow up my computer, or my self...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHNTQTmSuOy_WRfcsBxVmc30dqUZ1iO12L-K4KGHue5engBzyctX6YtKIVFlzz19pUZTvQY3vXZ9jPStRXMvzGRnd0slIfXF297lTNFtLOQUCjVIiOKTDs9kNMjoAc2F1vy4NArnaHroHd/s1600/2014-10-15+23.21.22.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHNTQTmSuOy_WRfcsBxVmc30dqUZ1iO12L-K4KGHue5engBzyctX6YtKIVFlzz19pUZTvQY3vXZ9jPStRXMvzGRnd0slIfXF297lTNFtLOQUCjVIiOKTDs9kNMjoAc2F1vy4NArnaHroHd/s1600/2014-10-15+23.21.22.jpg" height="360" width="640" /></a></div>
<br />
I must admit that this was the first time I have ever attempted to sniff a data communication before, so I had to do a little research. I recognized the CLK as the clock wire in SPI, and guessed that the <b>S</b>D<b>O</b> and <b>S</b>D<b>I</b> was the same as MI<b>SO</b> and MO<b>SI</b> but where was the SS (chip select) wire?<br />
<br />
My hope was that maybe SPI can work without chip select when there is only one slave that listens, but that would make it heard to know when a transmission starts and end!? how does it sync?<br />
<br />
Well, it turns out that I was right, This is the output on a run with nothing connected but the meter:<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/AVvXsEhSR82lSmYfuA-TdENXpC6e5SrRTfrIFI3JtL1kH43avi6htjb7R6vAJ5E2BSeuqVv4lqc-Ruf2ylDRQwqwz4aRm7kT8gEvdBGf5FAgZLOwmB0ZZHRFSsZJ0erZ2wiwlFraDCem4ls_WkA1/s1600/A11.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSR82lSmYfuA-TdENXpC6e5SrRTfrIFI3JtL1kH43avi6htjb7R6vAJ5E2BSeuqVv4lqc-Ruf2ylDRQwqwz4aRm7kT8gEvdBGf5FAgZLOwmB0ZZHRFSsZJ0erZ2wiwlFraDCem4ls_WkA1/s1600/A11.PNG" height="260" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: center;">
(click picture for larger version)</div>
<br />
Yey, This confirmed my theory and it showed that the FREQ-pin was giving a 50 Hz signal, not at all involved in the SPI communication (nope it's not the SS-line). and that the un-labeled cable was the same as the VCC-labeled pin (high = 3,6V)<br />
<br />
This project has improved my analyzing skills allot, and I had to learn how to set up the analyzer to debug the SPI-signal (great <a href="http://www.gammon.com.au/forum/?id=10892">SPI-info</a>)<br />
<br />
To read this scatter as SPI you need to define the start (where to read the first bit in a byte from)<br />
1. press T1 or hit 1 on keyboard<br />
2. put marker in between SPI-signals (where it's obviously not in the middle of sending a byte)<br />
3-4. Add an Analyzer, choose SPI<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mJjLsgWnrRFjKO3L95XPjU1azf_rANNBLGgjGrV2PUqMX28AK2IoUOZSy4M_igUt_taL737hyphenhyphendOA-ziiNY1hBbyHTp2iVHigGm16AUGwWxVbGPkpZjqFWSmfg9_5FczhtigrZ_pDXgXn/s1600/a22.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mJjLsgWnrRFjKO3L95XPjU1azf_rANNBLGgjGrV2PUqMX28AK2IoUOZSy4M_igUt_taL737hyphenhyphendOA-ziiNY1hBbyHTp2iVHigGm16AUGwWxVbGPkpZjqFWSmfg9_5FczhtigrZ_pDXgXn/s1600/a22.PNG" height="188" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
Next step is setting up the SPI-analyzer:<br />
1. Press settings<br />
2. zoom in on the first byte, and try and figure out what settings that is used. (see pic under this as well)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWcDjwG3EQlIydYnQuDsE1muZLrZmNiZCjxbWMTjn1fk-dR1eHQr4wqWDiMmzuJ_V2vOnrqKGVwEiIMmJo5hdyoRaVjn4ZF1RH70Ho_5s_GSSAlFAzlbQoyfDy1Wbll8kn4k-XCeoSAF3h/s1600/A3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWcDjwG3EQlIydYnQuDsE1muZLrZmNiZCjxbWMTjn1fk-dR1eHQr4wqWDiMmzuJ_V2vOnrqKGVwEiIMmJo5hdyoRaVjn4ZF1RH70Ho_5s_GSSAlFAzlbQoyfDy1Wbll8kn4k-XCeoSAF3h/s1600/A3.PNG" height="584" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Start by "Re-run starting at marker T1" as in picture bellow.</div>
<div class="separator" style="clear: both; text-align: left;">
I found that my data is read when CLK is rising "Trailing Edge" and comes in sets of 8 bits (1 byte). </div>
<div class="separator" style="clear: both; text-align: left;">
Note the last MOSI-byte going low, only catched by the trailing edge of clk=>trailing edge</div>
<div class="separator" style="clear: both; text-align: left;">
This is how the bits in a byte are interpreted on trailing edge: </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/AVvXsEhqKQHQzuWWI0QnZp_pRM6aD2Z6jb6Fl_Wkve2_0zsqn2DLYLkbjfgk9ZvW1ZQ7nkU_VdJy2aFq1CcilweRMpf6vkxDTI4_j5ghlC7mQdHH2LNemr0Sb8ro1HvGZXBPgAyzdv4EnHX0rUJF/s1600/A5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqKQHQzuWWI0QnZp_pRM6aD2Z6jb6Fl_Wkve2_0zsqn2DLYLkbjfgk9ZvW1ZQ7nkU_VdJy2aFq1CcilweRMpf6vkxDTI4_j5ghlC7mQdHH2LNemr0Sb8ro1HvGZXBPgAyzdv4EnHX0rUJF/s1600/A5.PNG" height="128" width="640" /></a></div>
<br />
When the CLK goes high, the status on the MOSI and MISO are converted to either 1 or 0. After 8 bits, you have a byte which can be translated to decimal value, as seen above:<br />
MOSI = 1111 1110 => decimal 254<br />
MISO = 0001 0000 => decimal 16<br />
<br />
At this time, there was one happy geek in the house!<br />
<br />
<h2>
Decipher the data</h2>
Now I had figured out how to sniff the data communication, I still had no idea of what, and in what format the data was sent.<br />
<br />
I figured that my best chance of decoding the data would be to sample lots of data and then compare it. So i started sniffing the setup when connecting my soldering station which was perfect since it has the ability to choose different power settings, and for heavy load i used a 1,8 kW water heater.<br />
<br />
When comparing the data, it was quite clear that there is not much going on here.The data is sent in chunks of 70 packages at a time, followed by a 47 ms delay. Each package contains 8 bytes, and luckily for me, the first 68 package seems to be the same every time, independent of the wattage reading and they all look like this:<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; text-align: center; width: 192px;">
<colgroup><col span="3" style="width: 48pt;" width="64"></col>
</colgroup><tbody>
<tr height="20" style="height: 15.0pt;">
<td class="xl69" height="20" style="height: 15.0pt; width: 48pt;" width="64">Byte</td>
<td class="xl69" style="width: 48pt;" width="64">MOSI</td>
<td class="xl70" style="width: 48pt;" width="64">MISO</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">1</td>
<td class="xl68">255</td>
<td class="xl71">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">2</td>
<td class="xl68">255</td>
<td class="xl71">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">3</td>
<td class="xl68">255</td>
<td class="xl71">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">4</td>
<td class="xl68">254</td>
<td class="xl71">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">5</td>
<td bgcolor="#FFC000" class="xl68">30</td>
<td class="xl71">0</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">6</td>
<td class="xl68">254</td>
<td bgcolor="#FFC000" class="xl71">16</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl68" height="20" style="height: 15.0pt;">7</td>
<td class="xl68">254</td>
<td bgcolor="#FFC000" class="xl71">3</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td class="xl67" height="20" style="height: 15.0pt;">8</td>
<td class="xl67">254</td>
<td bgcolor="#FFC000" class="xl72">193</td>
</tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<div style="text-align: left;">
Sometimes (under high loads) the 16 reads 80, but that's probably because the 7th bit is misread (i haven't found a pattern):<br />
16 = 0001 0000<br />
80 = 0<b>1</b>01 0000<br />
<br />
But then in the 68th package it always sends:<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; text-align: center; width: 192px;"><colgroup><col span="3" style="width: 48pt;" width="64"></col></colgroup><tbody>
<tr height="20" style="height: 15pt;"><td class="xl69" height="20" style="height: 15pt; width: 48pt;" width="64">Byte</td><td class="xl69" style="width: 48pt;" width="64">MOSI</td><td class="xl70" style="width: 48pt;" width="64">MISO</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">1</td><td class="xl68">255</td><td class="xl71">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">2</td><td class="xl68">255</td><td class="xl71">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">3</td><td class="xl68">255</td><td class="xl71">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">4</td><td class="xl68">254</td><td class="xl71">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">5</td><td class="xl68">30</td><td class="xl71">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">6</td><td class="xl68">254</td><td bgcolor="#FFC000" class="xl71">144</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl68" height="20" style="height: 15pt;">7</td><td class="xl68">254</td><td class="xl71">3</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt;">8</td><td class="xl67">254</td><td class="xl72">193</td></tr>
</tbody></table>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Same thing here, 144 sometimes becomes 280</div>
144 = 1101 0000<br />
208 = 1<b>0</b>01 0000<br />
<br /></div>
<div style="text-align: left;">
Which i think prepares the Master that next 8-byte package will contain important stuff.<br />
This is what comes out in package 69 with different loads:<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 522px;"><colgroup><col span="2" style="width: 48pt;" width="64"></col><col style="width: 53pt;" width="71"></col><col style="width: 56pt;" width="74"></col><col style="width: 61pt;" width="81"></col><col span="2" style="width: 63pt;" width="84"></col></colgroup><tbody>
<tr height="20" style="height: 15pt;"><td class="xl70" height="20" style="height: 15pt; text-align: center; width: 48pt;" width="64">Byte</td><td class="xl70" style="text-align: center; width: 48pt;" width="64"><b>SI</b></td><td class="xl71" style="text-align: center; width: 53pt;" width="71">SO 0W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 56pt;" width="74">SO 8,5W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 61pt;" width="81">SO 20W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 63pt;" width="84">SO 44,5W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 63pt;" width="84">SO 1860W</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">1</td><td class="xl67" style="text-align: center;">94</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">2</td><td class="xl67" style="text-align: center;">128</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0 </td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">3</td><td class="xl67" style="text-align: center;">0</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">4</td><td class="xl67" style="text-align: center;">0</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">5</td><td class="xl67" style="text-align: center;">24</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">6</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FFC000" class="xl68" style="text-align: center;">115</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">116</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">115</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">115</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">111</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">7</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FFC000" class="xl68" style="text-align: center;">238</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">10</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">231</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">236</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">191</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl72" height="20" style="height: 15pt; text-align: center;">8</td><td class="xl72" style="text-align: center;">254</td><td class="xl69" style="text-align: center;">249</td><td class="xl69" style="border-left-style: none; text-align: center;">84</td><td class="xl69" style="border-left-style: none; text-align: center;">123</td><td class="xl69" style="border-left-style: none; text-align: center;">215</td><td class="xl69" style="border-left-style: none; text-align: center;">18</td></tr>
</tbody></table>
<br />
Which i figured out to be:<br />
<b>Voltage = 2*(Byte6+Byte7/255) </b><br />
<br />
Which makes sens because when it goes from Byte6=115 and Byte7>238 to Byte6=116 and Byte7=10 It implies a moderate increas in voltage (231,9V=>232,1V), but under high load, one can expect a voltage drop, and when running at 1,86 kW: Byte6=111 and Byte7=191 (223,5V) seems to be correct!<br />
<br />
I guess Byte8 represents a very small fractions of voltage level, so i skip that one.<br />
<br />
And the last 8-byte package hopefully gives me some sort of current measurement value so that I can calculate the power!?<br />
Package 70 looks like this with different power loads:<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 522px;"><colgroup><col span="2" style="width: 48pt;" width="64"></col><col style="width: 53pt;" width="71"></col><col style="width: 56pt;" width="74"></col><col style="width: 61pt;" width="81"></col><col span="2" style="width: 63pt;" width="84"></col></colgroup><tbody>
<tr height="20" style="height: 15pt;"><td class="xl70" height="20" style="height: 15pt; text-align: center; width: 48pt;" width="64">Byte</td><td class="xl70" style="text-align: center; width: 48pt;" width="64"><b>SI</b></td><td class="xl71" style="text-align: center; width: 53pt;" width="71">SO 0W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 56pt;" width="74">SO8,5W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 61pt;" width="81">SO 20W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 63pt;" width="84">SO 44,5W</td><td class="xl71" style="border-left-style: none; text-align: center; width: 63pt;" width="84">SO 1860W</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">1</td><td class="xl67" style="text-align: center;">22</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">2</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FF0000" class="xl68" style="text-align: center;">0</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">0</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">1</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">1</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">68</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">3</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FF0000" class="xl68" style="text-align: center;">2</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">162</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">7</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">156</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">45</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">4</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FF0000" class="xl68" style="text-align: center;">168</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">114</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">31</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">163</td><td bgcolor="#FF0000" class="xl68" style="border-left-style: none; text-align: center;">243</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">5</td><td class="xl67" style="text-align: center;">20</td><td class="xl68" style="text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td><td class="xl68" style="border-left-style: none; text-align: center;">0</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">6</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FFC000" class="xl68" style="text-align: center;">0</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">0</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">0</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">0</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">14</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl67" height="20" style="height: 15pt; text-align: center;">7</td><td class="xl67" style="text-align: center;">254</td><td bgcolor="#FFC000" class="xl68" style="text-align: center;">0</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">17</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">40</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">90</td><td bgcolor="#FFC000" class="xl68" style="border-left-style: none; text-align: center;">137</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl72" height="20" style="height: 15pt; text-align: center;">8</td><td class="xl72" style="text-align: center;">254</td><td bgcolor="#FFC000" class="xl69" style="text-align: center;">2</td><td bgcolor="#FFC000" class="xl69" style="border-left-style: none; text-align: center;">55</td><td bgcolor="#FFC000" class="xl69" style="border-left-style: none; text-align: center;">213</td><td bgcolor="#FFC000" class="xl69" style="border-left-style: none; text-align: center;">248</td><td bgcolor="#FFC000" class="xl69" style="border-left-style: none; text-align: center;">70</td></tr>
</tbody></table>
<br />
Where I have tried hard to find out what bit 2 to 4 means, please help me with that in the comment field!!!! The meter displays power factor, could it be something with that?<br />
<br />
Anyway, I was luckey, it turned out that the last three bits sends the power value like this:<br />
<b>P=(Byte6*255+Byte7+Byte8/255)/2</b><br />
<br />
And to get the current:<br />
P=U*I means <b>I=P/U </b> and I have all i need!!!!!<br />
<br />
And I am one very happy engineer!<br />
<br />
A bonus is that changing the setting to view voltage or current, doesn't change the SPI-data.</div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<h2>
Arduino MISO sniffer</h2>
</div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
I can't have a PC next to every power plug energy meter i have hacked so next step was to program a micro controller to do the SPI-sniffing for me.<br />
<br />
I have been using AVR's for quite some time now, but this is my first Arduino project, and for testing purposes I'll be using an <a href="http://www.ebay.co.uk/sch/i.html?_odkw=arduino+nano+usb&LH_PrefLoc=2&_sc=1&_fcid=192&_sop=15&_jgr=1&_from=R40%7CR40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.Xarduino+nano+usb+cable&_nkw=arduino+nano+usb+cable&_sacat=0">Arduino Nano</a>, but I have decided to use an <a href="http://www.ebay.co.uk/sch/i.html?_odkw=3%2C3+V+Arduino+Mini&LH_PrefLoc=2&_sc=1&_fcid=192&_sop=15&_jgr=1&_from=R40%7CR40%7CR40%7CR40&LH_BIN=1&gbr=1&_osacat=0&_from=R40&_trksid=p2045573.m570.l1313.TR0.TRC0.H0.X3%2C3+V+Arduino+Mini+ATMEGA328&_nkw=3%2C3+V+Arduino+Mini+ATMEGA328&_sacat=0">3,3 V Arduino Mini </a>when it's time to solder everything togeather since I have a 3,3 V battery in the meter, and I am planing on transmitting the read data with either an nRF24L01+ to my <a href="http://gizmosnack.blogspot.se/2013/05/raspberry-pi-nrf24l01-and-tcp.html">rPi-setup</a>, or the ESP8266 Wifi adapter (if it will ever arrive...). I wonder if I need a big fat cap to supply the current when sending data like the Tweetawatt!?<br />
<br />
Anyways, my plan is to send the data to Gdrive so that i can reach it from an android app or something, but that's future work! If you read this, and now how to log data from ESP8226 to G-drive or Dropbox, I'd appreciate if you gave me some tips!<br />
<br />
I first thought of using the built in SPI-function, but learning how to use the "bitbanging" technic on SPI sounded allot more fun! (and I'm not sure the built in SPI would work anyway without SS)<br />
<br />
This is the psudo chode I wrote:<br />
1. Connect GND, CLK (green cable) and SO (blue-white) to Arduino (CLKto INT0 and SO to D5) (Arduino 5V from USB for now)<br />
2. Setup interrupt (ISR) on INT0-pin (D2) and make it trigger on rising edge (se <a href="http://www.gammon.com.au/forum/?id=11488">ISR-info</a>)<br />
3. When trigger occures: loop as long as CLK is high while logging the time<br />
4. When CLK goes low: check if the delay was between 1-2ms, if so then we are in clk-sync and next clk-rise will be the start of a new byte (this is the delay in between every one of the 70 packages in a transmission)<br />
5. Let CLK-interrupt trigger 40 times to skip the first 5 bytes of the current package<br />
6. Save status on pin 5 (MISO) every time CLK-interrupt triggers to two integers (the next 8*2 times, which will be Byte6 and 7) by using <a href="http://arduino.cc/en/Reference/Bitshift">shifting bits</a> method "<<"<br />
7. Let clk trigger 8 more times to finish a complete package and stay in sync<br />
8. check if Byte7!=3, If true: its the 69th package => use byte 6 and 7 to calculate U and proceed with the next step, otherwise (Byte7==3) then: set sync=false and go back to step 3 and wait/look for next package.<br />
9. Let CLK-interrupt trigger 40 more times to skip the first 5 bytes of the 70th package<br />
10. Save byte 6, 7 and 8 in integers by shifting bits each time a new bit is read (8*3 times).<br />
11. Calculate P and then I=P/U<br />
12. Send U,I,P to computer for debug.<br />
<br />
<br />
And believe it or not, after a good couple of hours of debugging it now works like a charm!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjRNSueyjAYg0K-NBAgaZ6txesPe-wHb4kLNX2jCu9b1YTn-QyJZgOB0bNVBW3GzxOZMDoEXW2xA1aAdD6isf5ascwkQ38MDQ4AsMkSkaw5CCdHQTIW-xU43eKQAd-E1ZT6vWhOkaUmpBc/s1600/A9.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjRNSueyjAYg0K-NBAgaZ6txesPe-wHb4kLNX2jCu9b1YTn-QyJZgOB0bNVBW3GzxOZMDoEXW2xA1aAdD6isf5ascwkQ38MDQ4AsMkSkaw5CCdHQTIW-xU43eKQAd-E1ZT6vWhOkaUmpBc/s1600/A9.PNG" height="532" width="640" /></a></div>
<br />
Here is the code that now sends the data to the Arduino-IDE, but is easily changed to an nRF24L01+ and hopefully the ESP8266 as well...<br />
<br />
<br /></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<div id="" style="overflow-y: scroll; height:600px;">
<script src="https://gist.github.com/klalle/0eed7d0ab424f83ae79c.js"></script></div></div>
</div>
<div style="text-align: center;">
<div style="text-align: left;">
<br />
<h2>
Update!</h2>
I now have a working setup where the energy meter is completely wireless with an Arduino mini pro 3,3V and a nRF24L01+ module! =)<br />
Se <a href="http://gizmosnack.blogspot.se/2014/11/power-plug-energy-meter-now-wireless.html">next post</a> for further information.<br />
/Kalle</div>
</div>
</div>Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com72tag:blogger.com,1999:blog-2129587383257876818.post-87871181318204997432014-08-25T21:19:00.000+02:002014-08-25T21:19:12.603+02:00Move program between terminalsFinally I have found an easy way of moving a running program from one terminal to another in Linux.<br />
<br />
1. Install a neat program called "reptyr"<br />
$sudo apt-get install reptyr<br />
2. start a never ending program in one terminal<br />
3. start a second terminal and find the PID of the never ending program by running<br />
$ps -er | grep nRF <br />
-where the "nRF" part is part of the never ending program name<br />
-you might want to make the terminal window broader to see all the text<br />
4. look after the PID that corresponds to the ps-output:<br />
pi <b>2801 </b>2800 1 20:57 pts/1 00:00:01 python3 /home/pi/<span style="color: orange;">nRF</span>24L01p.py<br />
-the PID is the number 2801 in the example above.<br />
5. in the second terminal, run:<br />
$reptyr 2801<br />
and the second terminal will print out 11 rows of text starting with [+] to tell you everything worked, and at the bottom show the out and input of the program.<br />
The first terminal will go on and ask for a new input and act as if nothing has happened.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1aihys4qk-C6juwg2B5q0eGk38vyAZeArURqmzy9X2iYVdlTko0tFd8BR7ITWPQUlxpbwbj6nBvwCj2DiqAsEe4v_j7oH9r4VjF6tBTXspRofE5II5Hjtey3y-jJdvExVLc-_U2rRr6E_/s1600/Capture2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1aihys4qk-C6juwg2B5q0eGk38vyAZeArURqmzy9X2iYVdlTko0tFd8BR7ITWPQUlxpbwbj6nBvwCj2DiqAsEe4v_j7oH9r4VjF6tBTXspRofE5II5Hjtey3y-jJdvExVLc-_U2rRr6E_/s1600/Capture2.PNG" /></a></div>
<br />
Another useful thing with the PID is when you want to kill a process. just type $kill 2801 where 2801 is the PID<br />
<br />Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com2tag:blogger.com,1999:blog-2129587383257876818.post-48569213005203034642013-12-02T23:27:00.000+01:002013-12-04T23:19:55.834+01:00AndroidPlot in AndroidApp<script src="http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js" type="text/javascript"></script>
<script src="http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushRuby.js" type="text/javascript"></script> <script src="http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shLegacy.js" type="text/javascript"></script>
<link href="http://alexgorbatchev.com/pub/sh/2.1.364/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link> <script language="javascript">
window.onload = function () {
dp.SyntaxHighlighter.ClipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
dp.SyntaxHighlighter.BloggerMode();
}
</script>
This will be a simple step by step tutorial in how i managed to get the AndroidPlot up and running in one of my android apps.<br />
<img height="384" src="http://androidplot.com/wp-content/gallery/plot-examples/device-2013-07-04-110827_0.png" width="640" /><br />
The creators of the function has a great <a href="http://androidplot.com/docs/quickstart/">tutorial </a>on there website (allot of code is straight from there tutorial), but as always they assumed i had more knowledge than i do to get it working straight away... Since it wasn't enough to follow there steps, and i had to spend allot of time searching the internet for answers i figured i would post a step by step tutorial on how i managed to get it up and running.<br />
<br />
1. Download the latest version of the "Core Library" .jar-file from there<a href="http://androidplot.com/download/"> download page</a>. (the only file you need to download)<br />
<br />
2. Save the file into your "libs" folder, and it will automatically import the library under "Android Private Libraries" (if not, left click your project foldet/Properties/Java Build Path/ tab "Libraries" / "Add JARs"...)<br />
<br />
3.Create folder res/"xml" which android recognizes as default xml-resources folder.<br />
<br />
4. Create two xml-files, first one named "line_point_formatter_1.xml", and secound one whit "2" instead of "1"....<br />
<br />
5. paste following code in the first xml-file: (you can put a linebreak in between every setting to get a better overview, but my code-viewer wouldn't let me...)<br />
<pre class="brush: ruby" name="code"><?xml version="1.0" encoding="utf-8"?>
<config fillpaint.color="#00000000" linepaint.color="#00AA00" linepaint.strokewidth="3dp" pointlabelformatter.textpaint.color="#FFFFFF" vertexpaint.color="#007700"></config></pre>
<br />
And this in the secound file:
<br />
<pre class="brush: ruby" name="code"><?xml version="1.0" encoding="utf-8"?>
<config fillpaint.color="#00000000" linepaint.color="#0000AA" linepaint.strokewidth="3dp" pointlabelformatter.textpaint.color="#FFFFFF" vertexpaint.color="#000077"></config></pre>
<br />
6. Create a new xml file that you name "dimens.xml" and put in the res/values folder. Paste this in the file:
<pre class="brush: ruby" name="code"><?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="pie_segment_label_font_size">10dp</dimen>
<dimen name="title_font_size">20dp</dimen>
<dimen name="domain_label_font_size">13dp</dimen>
<dimen name="range_label_font_size">13dp</dimen>
<dimen name="range_tick_label_font_size">15dp</dimen>
<dimen name="domain_tick_label_font_size">15dp</dimen>
<dimen name="legend_text_font_size">20dp</dimen>
</resources></pre>
<br />
7. Create a layout file in res/layout and name it something like "plotlayout.xml". Paste this code in the file: <br />
<br />
<br />
<pre class="brush: ruby" name="code"><linearlayout android:background="#fffcef" android:layout_gravity="center|center_vertical" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
<com .androidplot.xy.xyplot="" android:id="@+id/mySimpleXYPlot" android:layout_height="fill_parent" android:layout_width="fill_parent" androidplot.domainlabel="Domain" androidplot.domainlabelwidget.labelpaint.textsize="@dimen/domain_label_font_size" androidplot.graphwidget.domainlabelpaint.textsize="@dimen/domain_tick_label_font_size" androidplot.graphwidget.domainoriginlabelpaint.textsize="@dimen/domain_tick_label_font_size" androidplot.graphwidget.gridlinepaint.color="#000000" androidplot.graphwidget.marginbottom="25dp" androidplot.graphwidget.marginleft="15dp" androidplot.graphwidget.marginright="10dp" androidplot.graphwidget.margintop="20dp" androidplot.graphwidget.rangelabelpaint.textsize="@dimen/range_tick_label_font_size" androidplot.graphwidget.rangeoriginlabelpaint.textsize="@dimen/range_tick_label_font_size" androidplot.legendwidget.heightmetric.value="25dp" androidplot.legendwidget.iconsizemetrics.heightmetric.value="15dp" androidplot.legendwidget.iconsizemetrics.widthmetric.value="15dp" androidplot.legendwidget.positionmetrics.anchor="right_bottom" androidplot.legendwidget.textpaint.textsize="@dimen/legend_text_font_size" androidplot.rangelabel="Range" androidplot.rangelabelwidget.labelpaint.textsize="@dimen/range_label_font_size" androidplot.title="A Simple XY Plot" androidplot.titlewidget.labelpaint.textsize="@dimen/title_font_size">
</com></linearlayout>
</pre>
8. Create a new .java-file in the src/"com.example.NAMEOFYOURPROJECT" (where most of the java-files are stored) and name the file "Plots.java"<br />
<br />
9. Paste this in the file:
<br />
<pre class="brush: ruby" name="code">package com.androidplot.THENAMEOFYOURAPPLICATION; //all in small case letters.
import android.app.Activity;
import android.os.Bundle;
import com.androidplot.xy.*;
import java.util.Arrays;
/**
* A straightforward example of using AndroidPlot to plot some data.
*/
public class Plots extends Activity
{
private XYPlot plot;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.plotlayout); //The name of your plotlayout.xml-file!
// initialize our XYPlot reference:
plot = (XYPlot) findViewById(R.id.mySimpleXYPlot);
// Create a couple arrays of y-values to plot:
Number[] series1Numbers = {1, 8, 5, 2, 7, 4};
Number[] series2Numbers = {4, 6, 3, 8, 2, 10};
// Turn the above arrays into XYSeries':
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers), // SimpleXYSeries takes a List so turn our array into a List
SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, // Y_VALS_ONLY means use the element index as the x value
"Series1"); // Set the display title of the series
// same as above for series 2
XYSeries series2 = new SimpleXYSeries(Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
// Create a formatter to use for drawing a series using LineAndPointRenderer
// and configure it from res/xml/config-files:
LineAndPointFormatter series1Format = new LineAndPointFormatter();
series1Format.setPointLabelFormatter(new PointLabelFormatter());
series1Format.configure(getApplicationContext(),
R.xml.line_point_formatter_1.xml); //Name of the 1'st xml-config file
// add a new series' to the xyplot:
plot.addSeries(series1, series1Format);
// same as above:
LineAndPointFormatter series2Format = new LineAndPointFormatter();
series2Format.setPointLabelFormatter(new PointLabelFormatter());
series2Format.configure(getApplicationContext(),
R.xml.line_point_formatter_2.xml); //Name of the 2'nd xml-config file
plot.addSeries(series2, series2Format);
// reduce the number of range labels
plot.setTicksPerRangeLabel(3);
plot.getGraphWidget().setDomainLabelOrientation(-45);
}
}</pre>
<br />
10. Add these lines to the "Manifest file" (found in the root, and named "YOURAPPNAMEManifest.xml")
<br />
<pre class="brush: ruby" name="code"><activity android:label="TheNameOfTheGraphWindowHere..." android:name="com.example.YOURAPPNAME.Plots" android:theme="@android:style/Theme.Dialog">
</activity></pre>
And put the lines in between these tags:
<br />
<pre class="brush: ruby" name="code"><application> and </application>
</pre>
<br />
11. Now it's time to test the plot. create a button with an onClickListener whit this code in it:
<br />
<pre class="brush: ruby" name="code">Intent i = new Intent(getApplicationContext(), Plots.class);
startActivityForResult(i, 2);
</pre>
which will start a new intent which call the Plots-class which in term opens the plotts-layout showing the graph of the numbers.
<br />
Now when you know how the file-system works, try <a href="http://androidplot.com/docs/dynamically-plotting-sensor-data/">next tutorial</a> they have posted, which is a dynamically updated plot over the phones tilt... =)Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com0tag:blogger.com,1999:blog-2129587383257876818.post-64953406139505906482013-11-23T17:08:00.001+01:002013-11-23T17:34:44.516+01:00Autostart Raspberry pi VNC and server<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="margin-left: 1em; margin-right: 1em;">
</div>
Hi!<br />
Last week i finally configured my Rpi, and had it setup as a server to get 24/7 access to all the gadgets in my apartment. I'm not very familiar with linux, and therefore it is probably a good ide to write down how i managed to do so, for future setups =)<br />
<br />
First of all i wanted to get access to the Rpi from my main computer. I had two options, either just by a terminal (SSH), which is probably best for speed, or configure a remote desktop (VNC) to mirror the pi on my main computers screen. Since i'm not to familiar with the linux terminal, i figured i'd start off with the VNC like this...<br />
<br />
Setting up remote desktop (VNC) on the Rpi using the program TightVNC according to <a href="http://www.howtogeek.com/141157/how-to-configure-your-raspberry-pi-for-remote-shell-desktop-and-file-transfer/">this </a>guide (skipped the SSH-part in the beginning):<br />
<br />
<h2>
Install the TightVNCServer on the Rpi like this:</h2>
<textarea cols="100" rows="3">
$sudo apt-get install tightvncserver #When prompted press 'y'
</textarea><br />
<br />
Then try and start the server by entering: (change the resolution to the screen res where you are going to view the desktop)
<textarea cols="100" rows="3">
$vncserver :1 -geometry 1600×900 -depth 16 -pixelformat rgb565
</textarea><br />
The "1" is an ID, (you can start several different servers)<br />
The program will now prompt for you to enter a password to get access to the remote desktop, set one!<br />
<br />
There might be an permission issue, so to make sure that wont happen, do this: (where "pi" is the username)
<textarea cols="100" rows="3">
$sudo chown pi /home/pi/.Xauthority
</textarea>
<br />
<br />
The VNC-server nr "1" can later be closed by typing:
<textarea cols="100" rows="3">
$vncserver –kill :1
</textarea>
<br />
<br />
<h2>
Install TightVNC on Windows machine</h2>
Now that you have your VNC-server up and running, it is time to install the TightVNC-program on you main computer from there <a href="http://www.tightvnc.com/download.php">website</a>:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://cdn.howtogeek.com/wp-content/uploads/2013/03/2013-03-16_162457.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="2013-03-16_162457" border="0" src="http://cdn.howtogeek.com/wp-content/uploads/2013/03/2013-03-16_162457.jpg" /></a></div>
When done, startup the TightVNC-Viewer (not the server), type in the IP-address and the ID that you specified on the pi and press "Connect". A good ide is to configure your router so that the ip of the Rpi never changes...<br />
<br />
If the server is running, a prompt for the password will show up, enter it and a window with the Rpi-desktop will popup =)<br />
<br />
If you make it full-screen, the way of getting out is by pressing alt+ctrl+shift+F.<br />
<br />
<h2>
Autostart VNC-server when Rpi boots</h2>
Next step is to get the server to start automatically when the Rpi starts up. There is no point of having a remote desktop if I every time the rpi starts have to have a keyboard, mouse and a screen attached to it to startup the server...<br />
<br />
Create a file named tightvnc in the init.d folder, and open it in nano to edit its content:<br />
<textarea cols="100" rows="3">
$sudo nano /etc/init.d/tightvnc
</textarea><br />
<br />
Enter the following:<textarea cols="100" rows="28">
#!/bin/sh
### BEGIN INIT INFO
# Provides: tightvncserver
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start vnc server
# Description:
### END INIT INFO
case "$1" in
start)
su pi -c 'vncserver :1 -geometry 1920x1080 -depth 16 -pixelformat rgb565:'
echo "VNC Started"
;;
stop)
pkill Xtightvnc
echo "VNC Terminated"
;;
*)
echo "Usage: /etc/init.d/tightvnc {start|stop}"
exit 1
;;
esac
</textarea><br />
Press ctrl+x and y to exit and save.<br />
<br />
Now we need to set permissions to the file to make it executable:
<textarea cols="100" rows="3">
$sudo chmod 755 /etc/init.d/tightvnc
</textarea><br />
<br />
And the last thing we’re going to make is to update the rc.d file (which tracks which initilization scripts are in the /init.d/ folder):
<textarea cols="100" rows="3">
$sudo update-rc.d tightvnc defaults
</textarea><br />
<br />
Now it is time to test it: Reboot the Rpi:<br />
<textarea cols="100" rows="3">
$sudo reboot
</textarea><br />
<br />
And try connecting the ThightVNC-program on the main computer.<br />
<br />
<h2>
Autorun other scripts when Rpi boots</h2>
To autorun a script that doesn't need permissions when Rpi starts is a little easier. Take my nRF-server for instance:<br />
Create (if not allready created) the folder<br />
<textarea cols="100" rows="3">
$mkdir ~/.config/autostart
</textarea><br />
<br />
Then add a file with the ending ".desktop" and edit it in nano:<br />
<textarea cols="100" rows="3">
$sudo nano ~/.config/autostart/NRFServer.desktop
</textarea><br />
<br />
Edit the file like this:<textarea cols="100" rows="10">[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
StartupNotify=true
Name=NRF-server
Comment=Starts NRF-server
Exec=lxterminal --command "sh /home/pi/a.sh"
Categories=Application;
</textarea><br />
Where the importent stuff is the terminal=false (we want to start lxterminal), and the "Exec" that executes the script "sh /home/pi/a.sh" in the lxterminal, which is the script that starts the server...<br />
Exit nano with ctrl+x and save (press y)<br />
<br />
Now to make the .desktopfile executable:<br />
<textarea cols="100" rows="3">
$sudo chmod +x ~/.config/autostart/NRFServer.desktop
</textarea><br />
<br />
Reboot the Rpi, and you can see that the lxterminal has started the NRF-server in an open terminal!<br />
<br />Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com2tag:blogger.com,1999:blog-2129587383257876818.post-26180773853964314472013-05-27T16:04:00.000+02:002013-07-29T15:45:58.824+02:00Raspberry pi: nRF24L01 and TCPThis time I will describe how I got a Raspberry pi (Wheezy) to work as a Python server that controls a RF-transmitter (nRF24L01). The server takes commands either from a TCP connection (internet) or via the keyboard, and broadcasts the data through the RF-transmitter to the receivers i have set up in my home automation system. See my other posts covering how to use the <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-nrf24l01-and-avr.html">nRF with an AVR</a>, and the construction of a <a href="http://translate.google.com/translate?sl=auto&tl=en&js=n&prev=_t&hl=en&ie=UTF-8&eotf=1&u=http%3A%2F%2Fgizmosnack.blogspot.se%2F2013%2F03%2Fvarldens-nordigaste-multifjarrkontroll.html&act=url">multi-functional remote control</a>.<br />
<br />
<img height="307" src="http://www.geek.com/wp-content/uploads/2012/12/adafruitcase.jpg" width="400" /> <img src="http://thumbs1.ebaystatic.com/d/l225/m/mxIoCho9RWLt5Kx8Hhdr_RA.jpg" /><br />
<br />
<h2>
Why use a Raspberry pi when i already have a working TCP-server on my PC?</h2>
Easy answered:<br />
<ul>
<li>I do not like to have my PC up and running 24-7 due to the facts that it's noisy (stationed in my bedroom)</li>
<li>The RPi takes much less energy (runs on a 1000mA cellphone charger)</li>
<li>I don't need any other parts other than a RPi, a nRF24L01(+) and cables, since the RPi has a 3,3V power supply!</li>
</ul>
<br />
<h2>
Setting up SPI on RPi</h2>
<div>
First of all, you must have a working copy of raspbian, I use Wheezy (made a <a href="http://gizmosnack.blogspot.se/2013/05/setting-up-raspbian-on-raspberry-pi.html">small tutorial</a> in how to set it up). The RPi has a built in hardware SPI, which we first has to get up and running according to <a href="http://www.brianhensley.net/2012/07/getting-spi-working-on-raspberry-pi.html">this guide</a>, and here is how i did it:<br />
<br />
Start a terminal like the LXTerminal and follow these commands:<br />
<textarea cols="100" rows="20">
$sudo apt-get install git
$sudo wget http://goo.gl/1BOfJ -O /usr/bin/rpi-update #(the O is not zero but the letter)
$sudo chmod +x /usr/bin/rpi-update
$sudo rpi-update
$sudo nano /etc/modprobe.d/raspi-blacklist.conf
#add '#' in front of 'blacklist spi-bcm2708' (to comment it out) ctr+o (save) then ctrl+x (exit)
$ sudo shutdown -h now #(remove power cable and readd it to restart)
$cd /dev
$ls #(check that ”spidev0.0 and 0.1 is in the list as in picture underneath)
</textarea>
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh26ctfgJ8OalsUJ0nn_ikf5GBHkjhUmnf7svrWAuD04r86mW1dvdAp8B1hQ86E9pGDpiuYN7on-yNRJb2SlRUCEtRDqIewvHufSvP-R-q71_jhqxcP_s0NY8aEk21sCGJE5meu6To4yQY/s640/SPIdev.PNG" /><br />
<br />
To check if the SPI is working (optional) you can connect the mosi-pin to the miso-pin (GPIO10 and 9, see picture), and run the commands in a terminal:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img577.imageshack.us/img577/3040/raspberrypirev2pinout.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="444" src="http://img577.imageshack.us/img577/3040/raspberrypirev2pinout.jpg" width="640" /></a></div>
<textarea cols="120" rows="13">
$wget http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/Documentation/spi/spidev_test.c spidev_test.c
$ nano spidev_test.c
#(scroll down and change ”*devic = ”/dev/spidev1.1”; to ”/dev/spidev0.0" , press ctrl+o (save) ctrl+x (exit)
$gcc spidev_test.c #(creates a runnable file)
$sudo ./a.out #(runns the file)
#The output should now look like this:
</textarea>
<br />
<div>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWCTfO-VqqJuptCV1VFi8ZvM06H_eFGFcVwRYBOeUvLM_Oi7ZmHg4d4byzdNCDfxCt_I85HYQQmxjYRzj9-naejqOCCQ3r5KjLzY4AG8fUhLy6pFEyjtAEYRredY43SnjClXEhK9Ki9vA/s1600/spi+working.PNG" /></div>
<div>
<br />
<br />
<h2>
Quick2Wire</h2>
<div>
Quick2Wire is a tool that makes it possible to control the GPIO and the SPI via python. We need to install quick2wire, download the quick2wire python plugin (API) and gain root access to the spi.<br />
Start by <a href="https://github.com/quick2wire/quick2wire-gpio-admin/archive/master.zip">downloading </a>the plugin from there <a href="https://github.com/quick2wire/quick2wire-gpio-admin">website</a>. Extract the zip-file by right clicking and unzip. Now open a terminal window and change directory so that you are in the extracted folder called "quick2wire-gpio-admin-master" then enter the following commands:</div>
<textarea cols="30" rows="7">
$ make
$ sudo make install
$ sudo adduser $USER gpio
</textarea>
<br />
<div>
<br />
Now log out from the RPi and back in again. The power button at the bottom right quorner has the option to log out. Log back in by typing your username "pi"/enter, then your code "raspberry"/enter...<br />
<br />
To gain root access for the SPI so that you dont have to use the "sudo" command in front of every bit of code, I followed<a href="http://quick2wire.com/2012/12/non-root-access-to-spi-on-the-pi/"> this guide</a>, which tells you to do this:<br />
<br /></div>
<textarea cols="45" rows="17">
$ sudo groupadd -f --system spi
$ sudo adduser pi spi
$ cd /etc/udev/rules.d2/
$ sudo nano 90-spi.rules
$ SUBSYSTEM=="spidev", GROUP="spi"
$ #press ctrl+o (save), Enter, ctrl+x (exit)
$ sudo shutdown -h now
</textarea>
<br />
Finnish by remove and reattach the power cable to restart.<br />
<br />
<h2>
Python 3</h2>
Now it's time to install python3 which is needed to run the code. Open a terminal and run these commands:<br />
<textarea cols="30" rows="3">
$ sudo apt-get install python3
</textarea>
<br />
<br />
Now to use quick2wire with python, you need the python API which can be <a href="https://github.com/quick2wire/quick2wire-python-api/archive/master.zip">downloaded </a>from <a href="https://github.com/quick2wire/quick2wire-python-api">this site</a>. Download it, and unpack it to a location on you SD-card (no installation required!)<br />
<br />
<h2>
Setting up the hardware</h2>
</div>
<div>
The setup is very straight forward. Connect the wires like this (see red circles in the picture):<br />
RPi GPIO9 (Pin 21) to RF ( MISO )<br />
RPi GPIO10 (Pin 19) to RF ( MOSI )<br />
RPi GPIO11 (Pin 23) to RF ( SCK )<br />
RPi GPIO8 (Pin 24) to RF ( CSN )<br />
RPi GPIO18 (Pin 12) to RF ( CE )<br />
RPI 3.3V (Pin 17) to RF ( VCC/3.3V )<br />
RPi Gnd (Pin 25) to RF (GND)<br />
(IRQ-pin on nRF is not used in this example)<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEU_tJApwa8xKGGPq7zwGhy36sWP2ynCZycBLGrQeoaXCemmDRnoBGV3-KGyRiOgXGp6efUwekAkYMPs6XVx6sS1G_1HSPszZmVN3O6rMm6yWFxRKCjfzidCVTn0H8Xmfvj07m5GxGfV6W/s1600/RPi.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEU_tJApwa8xKGGPq7zwGhy36sWP2ynCZycBLGrQeoaXCemmDRnoBGV3-KGyRiOgXGp6efUwekAkYMPs6XVx6sS1G_1HSPszZmVN3O6rMm6yWFxRKCjfzidCVTn0H8Xmfvj07m5GxGfV6W/s1600/RPi.JPG" /></a></div>
nRF24L02+ (top view)<br />
<div>
<img src="http://www.electrokit.com/public/upload/productimage/49981-10364-4.jpg" /><br />
<br />
nRF24L01 (only one of each VCC and GND-pin has to be connected!)<br />
<img height="183" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip72hUdLVTrGEa4QVNqesg6PuwW-WiXrYwtsirZhyphenhyphenT5oRWJmA_wFvShLhGhkA3HrRRZaSQBjFdD7yTdg4Yw73fxHt70E7XUvTjAczXbOj4B93cdmKq_t9w_U66jQg1ApGaxOFjsB1ShH8M/s400/nrf.PNG" width="400" /></div>
<br />
<br />
I think the CE-pin should work on a different pin (it would be convenient to put it on GPIO25) since it doesn't have anything to do with the SPI, but I haven't tried that yet...<br />
<br />
<h2>
The python programs</h2>
I got the basic nrf python code from <a href="http://koodi.jussin.net/gitweb/?p=HomeAutomations;a=blob_plain;f=RaspiTempatureReceiver/nRF24L01p.py;hb=HEAD">this program</a> (plus a lot of help with the steps above) from <a href="https://plus.google.com/100198871098258549028/posts">Jussi Kinnunen</a>, all creds to him!<br />
Download <a href="https://gist.github.com/klalle/5658484">my version</a> of the program, as well as my <a href="https://gist.github.com/klalle/5658538">TCP-server</a> program. which is well commented to make it easy to understand. You see the codes below:<br />
<br />
nRF24L01p.py<br />
<textarea cols="150" rows="50">
#!/usr/bin/env python3
from quick2wire.spi import *
from quick2wire.gpio import Pin
from quick2wire.gpio import In,Out,pi_header_1
import time
#import TCP_Server #Uncomment this if you are running a TCP-server!! (this and one more line in the while-loop at the bottom!)
PAYLOAD_SIZE = 3
SMALL_PAUSE = 0.05
LONG_PAUSE=0.5
#Define settings variables for nRF:
SET_ACK = 0x01 #Auto ack on (EN_AA)
SET_ACK_RETR = 0x2F #15 retries, 750us paus in between in auto ack (SETUP_RETR)
SET_DATAPIPE = 0x01 #Datapipe 0 is used (EN_RXADDR)
SET_ADR_WIDTH = 0x03 #5 byte address (SETUP_AW)
SET_FREQ = 0x01 #2,401GHz (RF_CH)
SET_SETUP = 0x07 #1Mbps, -0dB, (250kbps = 0x27) (RF_SETUP)
ADDRESS = 0x12
SET_RX_ADDR_P0 = [ADDRESS,ADDRESS,ADDRESS,ADDRESS,ADDRESS] #Receiver address( RX_ADDR_P0)
SET_TX_ADDR = [ADDRESS,ADDRESS,ADDRESS,ADDRESS,ADDRESS] #Transmitter address (TX_ADDR)
SET_PAYLOAD_S = 0x03 #3byte payload size (32byte = 0x20)(RX_PW_P0)
SET_CONFIG = 0x1E #1=mask_MAX_RT (IRQ-vector), E=transmitter, F= Receiver (CONFIG)
#nRF registers:
CONFIG = 0x00
EN_AA = 0x01
EN_RXADDR = 0x02
SETUP_AW = 0x03
SETUP_RETR = 0x04
RF_CH = 0x05
RF_SETUP = 0x06
STATUS = 0x07
OBSERVE_TX = 0x08
CD = 0x09
RX_ADDR_P0 = 0x0A
RX_ADDR_P1 = 0x0B
RX_ADDR_P2 = 0x0C
RX_ADDR_P3 = 0x0D
RX_ADDR_P4 = 0x0E
RX_ADDR_P5 = 0x0F
TX_ADDR = 0x10
RX_PW_P0 = 0x11
RX_PW_P1 = 0x12
RX_PW_P2 = 0x13
RX_PW_P3 = 0x14
RX_PW_P4 = 0x15
RX_PW_P5 = 0x16
FIFO_STATUS = 0x17
READ_REG = 0x00
WRITE_REG = 0x20
RESET_STATUS = 0x70
WR_TX_PLOAD = 0xA0
RD_RX_PLOAD = 0x61
FLUSH_TX = 0xE1
FLUSH_RX = 0xE2
NOP = 0xFF
class NRF24L01P:
def __init__(self):
"""__init__ function is allways run first, when the class is called!"""
self.nrf24 = SPIDevice(0, 0) #Define SPI-unit (used in doOperation)
self.radio_pin = pi_header_1.pin(12, direction=Out) #"CE" on nRF, output
def doOperation(self,operation):
"""Do one SPI operation"""
time.sleep(SMALL_PAUSE) #Make sure the nrf is ready
toReturn = self.nrf24.transaction(operation) #Sends bytes in "operation" to nRF (first what register, than the bytes)
return toReturn #Return bytes received from nRF
def ReadPrintReg(self, Register, name, numbers):
"""Function that grabs "numbers" of bytes from the registry "Register" in the nRF
and writes them out in terminal as "name....[0xAA,0xBB,0xCC]" """
bytes = [READ_REG|Register] #First byte in "bytes" will tell the nRF what register to read from
for x in range(0, numbers): #Add "numbers" amount of dummy-bytes to "bytes" to send to nRF
bytes.append(NOP) #For each dummy byte sent to nRF later, a return byte will be collected
ret = self.doOperation(duplex(bytes)) #Do the SPI operations (returns a byte-array with the bytes collected)
#print(ret[0]) #debug
#print(hex(ord(ret[0]))) #debug
#print(bin(ord(ret[0]))) #debug
Res = [hex(z)[2:] for z in ret[0]] #convert byte-array to string list
#print(Res) #debug
while len(name)<15: #Fill the name with "." so it allways becomes 15 char long (e.g. "STATUS.........")
name = name + "."
#Print out the register and bytes like this: "STATUS.........[0x0E]"
print("{}".format(name), end='') #First print the name, and stay on same line (end='')
for x in range(1, numbers+1): #Then print out every collected byte
if len(Res[x]) == 1: #if byte started with "0" (ex. "0E") the "0" is gone from previous process => (len == 1)
Res[x]= "0" + Res[x] #Readd the "0" if thats the case
print("[0x{}]".format(Res[x].upper()), end='') #Print next byte after previous without new line
print("") #Finnish with an empty print to contiune on new line and flush the print (no end='')
return Res[1].upper() #Returns the first byte (not the zeroth which is allways STATUS)
def receiveData(self):
"""Receive one or None messages from module"""
#Reset Status registry
bytes = [WRITE_REG|STATUS] #first byte to send tells nRF tat STATUS register is to be Written to
bytes.append(RESET_STATUS) #add the byte that will be written to thr nRF (in this case the Reset command)
self.doOperation(writing(bytes)) #execute the SPI command to send "bytes" to the nRF
try:
self.radio_pin.open() #Open the "CE" GPIO pin for access
self.radio_pin.value=1 #Set the "CE" pin high (3,3V or 5V) to start listening for data
time.sleep(LONG_PAUSE) #Listen 0,5s for incomming data
self.radio_pin.value=0 #Ground the "CE" pin again, to stop listening
self.radio_pin.close() #Close the CE-pin
except(KeyboardInterrupt, SystemExit): #If ctrl+c breaks operation or system shutdown
try:
self.radio_pin.close() #First close the CE-pin, so that it can be opened again without error!
print("\n\ngpio-pin closed!\n")
except:
pass
raise #continue to break or shutdown!
ret = self.doOperation(duplex([STATUS])) #Get the status register as byte-array
Res = [hex(z)[2:] for z in ret[0]] #convert byte-array to string list
Res = Res[0].upper() #Convert the interesting byte to one string, upper case (e.g. "4E")
if len(Res) == 1: #if string started with "0" (ex. "0E") the "0" is gone from previous process => (len == 1)
Res= "0" + Res #Readd the "0" if thats the case
if(Res != "0E"): #If something is flagged in the STATUS-register
self.ReadPrintReg(STATUS,"STATUS",1) #Print out the status-register
if Res == "4E": #If data is received correctly
self.ReadPrintReg(RD_RX_PLOAD,"Received",PAYLOAD_SIZE) #Print out the received bytes
else:
print(".", end='') #Print out dots to show we are still listening!
sys.stdout.flush() #the end='' only puts it in the buffer!
def sendData(self,toSend):
"""Sends x bytes of data"""
#Reset Status registry for next transmission
bytes = [WRITE_REG|STATUS] #first byte to send tells nRF tat STATUS register is to be Written to
bytes.append(RESET_STATUS) #add the byte that will be written to thr nRF (in this case the Reset command)
self.doOperation(writing(bytes)) #execute the SPI command to send "bytes" to the nRF
#Flush RX Buffer
self.doOperation(writing([FLUSH_TX])) #This one is special because it doesn't need any more than one byte SPI-command.
#This is because the FLUSH_TX is located on the top level on the nRF, same as the "WRITE_REG"
#register or the "READ_REG". (See datasheet Tabel 8)
#Print out the STATUS registry before transmission
self.ReadPrintReg(STATUS,"STATUS before",1)
#Print out the transmitting bytes with quotations ("chr(34)"), Payload cannot be read from the nRF!
print("Transmitting...[{}{}{},{}{}{},{}{}{}]".format(chr(34), chr(toSend[0]),chr(34),chr(34), chr(toSend[1]), chr(34), chr(34),chr(toSend[2]),chr(34)))
#This checks if the first byte to send is a "9", and if so, changes the address on the nRF.
a = "".join([chr(x) for x in toSend])
#print(a)
if(a=="009" or a=="019"):
self.changeAddress(0x13) #Calls function located further down
elif(a=="002" or a=="003" or a=="004"):#
self.changeAddress(0x14)
#Print out the address one more time, to make sure it is sent to the right receiver.
self.ReadPrintReg(RX_ADDR_P0,"To",5)
#write bytes to send into tx buffer
bytes = [WR_TX_PLOAD] #This one is simular to FLUSH_TX because it is located on the same top level in the nRF,
#Even though we want to write to it, we cannot add the "WERITE_REG" command to it!
bytes.extend(toSend) #Because we now want to add a byte array to it, we use the "extend(" command instead of "append("
self.doOperation(writing(bytes)) #Write payload to nRF with SPI
try:
self.radio_pin.open() #Open the "CE" GPIO pin for access
self.radio_pin.value=1 #Set the "CE" pin high (3,3V or 5V) to start transmission
time.sleep(0.001) #Send for 0,5s to make sure it has time to send it all
self.radio_pin.value=0 #Ground the CE pin again, to stop transmission
self.radio_pin.close() #Close the CE-pin
except(KeyboardInterrupt, SystemExit): #If ctrl+c breaks operation or system shutdown
try:
self.radio_pin.close() #First close the CE-pin, so that it can be opened again without error!
print("\n\ngpio-pin closed!\n")
except:
pass
raise #continue to break or shutdown!
self.ReadPrintReg(STATUS,"STATUS after",1) #Read STATUS register that hopefully tells you a successful transmission has occured (0x2E)
print("")
if(a=="009" or a=="019" or a=="002" or a=="003" or a=="004"): #If you changed address above, change it back to normal
self.changeAddress(0x12) #Change back address!
def changeAddress(self,Addr):
"""Function to change address on both RX and """
bytes = [WRITE_REG|RX_ADDR_P0]
bytes.extend([Addr,Addr,Addr,Addr,Addr])
self.doOperation(writing(bytes))
bytes = [WRITE_REG|TX_ADDR]
bytes.extend([Addr,Addr,Addr,Addr,Addr])
self.doOperation(writing(bytes))
def setupRadio(self):
"""Function that sets the basic settings in the nRF"""
#Setup EN_AA
bytes = [WRITE_REG|EN_AA]
bytes.append(SET_ACK)
self.doOperation(writing(bytes))
#Setup ACK RETRIES
bytes = [WRITE_REG|SETUP_RETR]
bytes.append(SET_ACK_RETR)
self.doOperation(writing(bytes))
#Setup Datapipe
bytes = [WRITE_REG|EN_RXADDR]
bytes.append(SET_DATAPIPE)
self.doOperation(writing(bytes))
#Setup Address width
bytes = [WRITE_REG|SETUP_AW]
bytes.append(SET_ADR_WIDTH)
self.doOperation(writing(bytes))
#Setup Freq
bytes = [WRITE_REG|RF_CH]
bytes.append(SET_FREQ)
self.doOperation(writing(bytes))
#Setup Data speed and power
bytes = [WRITE_REG|RF_SETUP]
bytes.append(SET_SETUP)
self.doOperation(writing(bytes))
#Setup Receive Address
bytes = [WRITE_REG|RX_ADDR_P0]
bytes.extend(SET_RX_ADDR_P0) #"extend" adds a list to a list, "append" adds one obect to a list
self.doOperation(writing(bytes))
#Setup Transmitter Address
bytes = [WRITE_REG|TX_ADDR]
bytes.extend(SET_TX_ADDR)
self.doOperation(writing(bytes))
#Setup Payload size
bytes = [WRITE_REG|RX_PW_P0]
bytes.append(SET_PAYLOAD_S)
self.doOperation(writing(bytes))
#Setup CONFIG registry
bytes = [WRITE_REG|CONFIG]
bytes.append(SET_CONFIG)
self.doOperation(writing(bytes))
time.sleep(LONG_PAUSE)
#Collect print out the registers from the nRF to to make sure thay are allright
self.ReadPrintReg(STATUS,"STATUS",1)
self.ReadPrintReg(EN_AA,"EN_AA",1)
self.ReadPrintReg(SETUP_RETR,"SETUP_RETR",1)
self.ReadPrintReg(EN_RXADDR,"EN_RXADDR",1)
self.ReadPrintReg(SETUP_AW,"SETUP_AW",1)
self.ReadPrintReg(RF_CH,"RF_CH",1)
self.ReadPrintReg(RF_SETUP,"RF_SETUP",1)
self.ReadPrintReg(RX_ADDR_P0,"RX_ADDR_P0",5)
self.ReadPrintReg(TX_ADDR,"TX_ADDR",5)
self.ReadPrintReg(RX_PW_P0,"RX_PW_P0",1)
self.ReadPrintReg(CONFIG,"CONFIG",1)
#self.radio_pin.close()
def Send(data):
"""Function that can be called from other files that wants to send data"""
SendObj = NRF24L01P()
SendObj.sendData(data)
print("Enter data to send (3 bytes): ") #Retype the input-text (input is still on form main-loop)
if __name__ == "__main__":
"""Gets called upon when running the file"""
rxtx = input("rx or tx? \n") #Receiver or transmitter
SendObj = NRF24L01P() #Start class
if rxtx == "tx": #nRF transmitter
print('\nTransmitter')
SET_CONFIG = 0x1E #Transmitter
SendObj.setupRadio() #Setting up radio
#TCP-Server.Run_func() #Calls the "Run_func()" in a TCP-server (that in termes calls the "Send(data)" function above with the data)
while 1:
package = input("Enter data to send (3 bytes): ") #If not TCP-server is used, calls for input from user to bee sent
print("")
#print(package)
bytesToSend = [ord(str(x)) for x in package] #Convert input to decimal values
#print(bytesToSend)
SendObj.sendData(bytesToSend) #calls the sendData() function with the payload
else: #nRF receiver
print('\nReceiver')
SET_CONFIG = 0x1F #Receiver
SendObj.setupRadio()
print("\nReceiving data")
i=0
while 1:
SendObj.receiveData()
time.sleep(SMALL_PAUSE)
</textarea>
<br />
<br />
TCP_Server.py<br />
<textarea cols="150" rows="53">
import socket
import threading
import socketserver
import time
import nRF24L01p
class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
"""Thread class"""
def handle(self):
while 1:
try:
data = str(self.request.recv(1024), 'ascii') #Receive bytes to from TCP-client to buffer of 1024 bytes
cur_thread = threading.current_thread() #Get thread information
print("Received: {} \n in: {}\n".format(data, cur_thread.name)) #Print out received bytes and thread name
bytesToSend = [ord(str(x)) for x in data] #Convert received bytes to type: Decimal (ord("1")=49)Convert input to decimal values
nRF24L01p.Send(bytesToSend) #Send the bytes to the nRF-program (transmitter) (in decimal form)
self.request.sendall(bytes("{}".format(data), 'ascii')) #Resend the data to TCP-client
except:
break #Break from while-loop
print("{} is now closed".format(cur_thread.name))
print("\nEnter data to send (3 bytes): ") #Retype the input-text (input is still on form main-loop)
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
"""Starts a new thread for each request"""
pass
def Run_func():
"""Gets called on from nRF-script"""
# HOST='' accepts all incoming ip
HOST, PORT = '', 1234
#Setup server on different thread
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
ip, port = server.server_address
# Start a thread with the server -- the function will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True #Run in background thread = true
server_thread.start()
print("\nServer loop running in background thread!\n")
if __name__ == "__main__":
Run_func()
</textarea>
<br />
<br />
<br />
To run the program, create a third file, and name it to something like "a.sh", the ending "sh" means shell file, which is runnable. Fill the file with these commands:<br />
(change the path "/home/pi/" to where you have the quick2wire-folder!)<br />
<textarea cols="75" rows="8">
export QUICK2WIRE_API_HOME=/home/pi/quick2wire-python-api-master
export PYTHONPATH=$PYTHONPAT:$QUICK2WIRE_API_HOME
python3 nRF24L01p.py
</textarea><br />
This will make sure the path is imported every time the script is run! If anyone knows how to permanently add the path, please tell me in the comment field!<br />
<br />
To run the program, all you have to do now is to set the working path in the terminal to where you store the a.sh-file with the cd-command and type<br />
<textarea cols="50" rows="3">
$ sh a.sh
</textarea>
<br />
<br />
This is a screenshot from the code running in the terminal:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL23NRBaMucIlRyO1B_sgiFWiEh9EpEtw7xVz2QiWUOKSj0C9pVlFQnvb8bCyvZaBSUpaV9ugZt844HYv9OaRSXEfp4xL0JaEasZkvOV0tr6uONsF4O9DdCDmreDA1kHs8i84r-2Foe4yZ/s1600/a+kopia.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL23NRBaMucIlRyO1B_sgiFWiEh9EpEtw7xVz2QiWUOKSj0C9pVlFQnvb8bCyvZaBSUpaV9ugZt844HYv9OaRSXEfp4xL0JaEasZkvOV0tr6uONsF4O9DdCDmreDA1kHs8i84r-2Foe4yZ/s1600/a+kopia.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
As you can see, the program starts by asking if you want to run it as "rx" (Receiver) or "tx" (transmitter). I chose transmitter by typing "tx"/enter.<br />
Then it prints out all the registers that the code changes (or sets) and then starts a server loop in a background thread (TCP).<br />
When this is done the program waits for either the user to type in data to send (3 bytes in my example), or for a command from the TCP-server.<br />
In the picture above, you can see that i started by typing "123" on the keyboard, which was sent to the nRF and broadcasted to any nRF-receiver with address 0x12. As you can see the STATUS register after the broadcast tells me that the transmission failed (0x1E), since i don't have a receiver running at the moment... a working transmission would give the result "0x2E" (when the EN_AA is turned on)!<br />
<br />
The second thing I did was to send the command "300" to the TCP-server from my home-made android application (can be sent form any <a href="http://wiki.python.org/moin/TcpCommunication">TCP-client</a> with the right port number). The TCP-server then calls the nRF24L01p.py and transmits the data like it was inputted with the keyboard.<br />
<br />
If a (large) error shows up when you try to run the code, which tells you something about "cannot export the pin number 18 because it is already exported", run the following command in the terminal:<br />
<br />
<textarea cols="50" rows="3">
$ gpio-admin unexport 18
</textarea>
<br />
<br />
If an error shoes up that tells you that the address is occupied, the TCP-server has not closed yet, and you have to sit down and wait for up to 1min before you try again (I know you can change this timing, but haven't come so far)<br />
<br />
<br />
If you have any questions or just want to tell me what you think of the blog, just give me a comment in the comment field underneath...<br />
/KalleKarl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com29tag:blogger.com,1999:blog-2129587383257876818.post-71385542225887914452013-05-27T15:32:00.001+02:002013-05-27T15:34:05.785+02:00Setting up Raspbian on Raspberry piThis is step by step how i installed Raspbian on my Raspberry pi:<img src="http://cdn-static.zdnet.com/i/story/70/00/005919/raspberry-pi-b-256.jpg" /><br />
<br />
<ol>
<li>On a PC (or mac/linux, i will cover the PC-version) download the file "Raspbian Wheesy" from the <a href="http://www.raspberrypi.org/downloads">website</a>, using either a torrent program like <a href="http://www.utorrent.com/">utorrent </a>or by the direct downloading-link.</li>
<li>Extract the files to a folder on the computer, remember the location!</li>
<li>Insert an SD-card in the computer, and make sure it contains nothing of value (since you will wipe all of its data later)</li>
<li>(windows users) Download the program "Win32Diskmanager" from <a href="http://sourceforge.net/projects/win32diskimager/">this site</a> (green download button).</li>
<ol>
<li> Extract the files to a folder, and open the file "Win32Diskmanager"</li>
<li>In the program, press the blue folder-button and brows to the file you downloaded and extracted in step 1-2 (something like: "<span style="font-family: "Calibri","sans-serif"; font-size: 11.0pt; line-height: 115%; mso-ansi-language: SV; mso-ascii-theme-font: minor-latin; mso-bidi-font-family: "Times New Roman"; mso-bidi-language: AR-SA; mso-bidi-theme-font: minor-bidi; mso-fareast-font-family: Calibri; mso-fareast-language: EN-US; mso-fareast-theme-font: minor-latin; mso-hansi-theme-font: minor-latin;">2013-05-12-wheeay-raspbian")</span></li>
<li>Make sure it is the right SD-card in the "Device" tab, and press the "Write" button. (only takes a couple of minutes. </li>
</ol>
<li>Move the SD-card to the Raspberry pi and connect:</li>
<ol>
<li>A mouse + keyboard</li>
<li>HDMI-cable (to screen) </li>
<li>Network cable or wifi adapter</li>
<li>Finnish by inserting the usb power adapter (at least 750mA)</li>
</ol>
<li>If you are having problems with the HDMI connection, unplug the USB-devices and restart the RPi (happens if you have a weak power supply!)</li>
<li>The "Raspi-config" box shows up: <img height="373" src="http://picoboard.pl/wp-content/uploads/Raspberry-Pi-Turbo-Mode-raspbi-config.png" width="640" /></li>
<li>Start by arrow down to "expand_rootfs" and press enter</li>
<ol>
<li>Accept by pressing enter again. This setting makes sure the whole SD-card gets used, otherwise only 2GB will be visible to the system.</li>
</ol>
<li>Configure_keyboard (takes a while to load)</li>
<ol>
<li>Try to find a match in the list/enter</li>
<li>Chose "other" at the very bottom/enter</li>
<li>page down to your language/enter</li>
<li>choose your language/enter</li>
<li>Choose "The default for the keyboard layout"/enter</li>
<li>choose "No compose key"/enter</li>
<li>change this one to "<yes>"/enter (to enable the ctr+alt+backspace (like ctrl+alt+delete on windows))</li>
</ol>
<li> Change_pass</li>
<ol>
<li>Pres "Ok" on window that pops up, (Change the standard password from "raspberry" to something else)</li>
<li>Type new password/enter</li>
<li>retype the same password/enter</li>
</ol>
<li>Change_local</li>
<ol>
<li>scroll down (or "page down") to your local (mine is "[] sv_SE.UTF-8 UTF-8") and press SPACE-key to put an "*" in the "[*]", finish with enter</li>
<li>Choose your local in the list/enter (takes a while)</li>
</ol>
<li>Change_timezone</li>
<ol>
<li>Go to your timezone in the list (Europe)/enter</li>
<li>Find a city nearby (Stockholm)/enter</li>
</ol>
<li>Overclock</li>
<ol>
<li>If you want to boost the RPi, its here! </li>
<li>I choose "modest", and it seem to work fine!</li>
</ol>
<li>Boot_behaviour</li>
<ol>
<li>confirm with yes (to skip the login-thing every time you boot up)</li>
</ol>
<li>Finnish by pressing right key twise to get to "<Finish>" and press Enter</li>
<ol>
<li>Press "Yes" to reboot</li>
</ol>
</ol>
<div>
Now you should boot straight into Raspbian Wheesy, if not type your username ("pi"/enter) and your password ("raspberry"/enter if not changed), now type "startx"/enter to get to the desktop!</div>
<div>
To get to the raspi-config again, open a terminal ("LXTerminal") and type "sudo raspi-config"/enter </div>
<div>
<img src="http://s.eeweb.com/members/kyle_olive/blog/2013/01/31/desktop-1359671517.png" /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com3tag:blogger.com,1999:blog-2129587383257876818.post-19750231900745261402013-04-11T22:01:00.001+02:002013-04-13T12:13:39.133+02:00Tutorial - USART and AVR<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="margin-left: 1em; margin-right: 1em;">
</div>
USART - a tutorial on how to setup a simple communication between the AVR chip and the computer!<br />
<br />
In this tutorial i will go through the steps on how to get the USART on an Atmega88 to send and receive commands from and to the computer.<br />
<br />
First of all you need the right hardware and software:<br />
<br />
-<a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Atmega88</a> - the microchip<br />
<br />
-<a href="http://www.ebay.co.uk/sch/i.html?_nkw=CP2102&_sacat=0&_odkw=usb+to+com&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">USB to COM-port adapter</a> - this one works on windows 7 64 bit, mac and linux. (<a href="http://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx">Drivers</a>)<br />
<br />
- <a href="http://www.compuphase.com/software_termite.htm">Termite</a> - a free windows program i used before i made my own (which i haven't yet decided if i should release or not). Anyway Termite has the capability of logging the correspondence to a file, and also has a timestamp function which is very useful!<br />
<br />
<b><span style="font-size: x-large;">Setup</span></b><br />
You only need to connect three of the cables from the USB to COM adapter to the Atmega88.<br />
<u>Atmega88</u> <u>COM adapter</u><br />
GND => GND<br />
TXD => TXD (PD1)<br />
RDX => RXD (PD0)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://thumbs1.ebaystatic.com/d/l225/m/mBcKzrob6EFgRuKFljTZb5A.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="USB 2.0 to TTL UART 6PIN Module Serial Converter CP2102 STC PRGMR Free cable" border="0" src="http://thumbs1.ebaystatic.com/d/l225/m/mBcKzrob6EFgRuKFljTZb5A.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://wearcam.org/ece385/avr/atmega48pinout.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="204" src="http://wearcam.org/ece385/avr/atmega48pinout.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Then if you want to you can use either the 5 V or 3,3 V pin from the COM adapter to supply the power to the AVR.<br />
<br />
<b><span style="font-size: x-large;">Programming</span></b><br />
I haven't put down a lot of work on this so it's probably not optimal, but i will show you how i got it to work:<br />
I had problems when i used the chip on standard 1MHz, but it worked perfectly when changing to 8MHz, so i start by the includes like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzTIHaZFRWgkaq1CEzSF8UwIiM3RO20ZjKAYBBzjzP2xKdP2oxdPM3vf6KistGp3Z9UFwhixaP4c_Q8hSz-M2OH1O_YENmZwQXdxUZ5_yY7Ud6h_1r88CCWbXzKH7gp8aaA4n9DdDDLnHC/s1600/Capture.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzTIHaZFRWgkaq1CEzSF8UwIiM3RO20ZjKAYBBzjzP2xKdP2oxdPM3vf6KistGp3Z9UFwhixaP4c_Q8hSz-M2OH1O_YENmZwQXdxUZ5_yY7Ud6h_1r88CCWbXzKH7gp8aaA4n9DdDDLnHC/s1600/Capture.PNG" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
Since the chip is fused to set the clock prescaler to a division of 8 (8MHz/8=1MHz) as factory default, i simply just change the prescaler back to "1" in code. This is accomplished by this little function: </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/AVvXsEg0-72Dabg1knLBY0f_PUthNS9B-S-qbiPck_yImt5mQ7ES3Jn53A-bOaxUq36dJofc4IX6NgTbwlGnTSp1efEeyKHEZbynQJICF5SzHld2MqS5p74up_NjlcrRUVHfYcCq_VPP9vvMIQho/s1600/Capture2.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0-72Dabg1knLBY0f_PUthNS9B-S-qbiPck_yImt5mQ7ES3Jn53A-bOaxUq36dJofc4IX6NgTbwlGnTSp1efEeyKHEZbynQJICF5SzHld2MqS5p74up_NjlcrRUVHfYcCq_VPP9vvMIQho/s1600/Capture2.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
And the USART is initialized by calling this function<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLVACtyrgRx5tJwOmW9186xGcjhZXNWOZx0Jx2cmW85CGXcsFdSXlQWtIZ8GYN8q4T_tDf5JpbWRofiDybQAvpXgD6hNYtYla9NpqVfrtUqhd2-wpM4oURh5_84RooDvMJNKoV_DSh0Ge7/s1600/Capture3.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLVACtyrgRx5tJwOmW9186xGcjhZXNWOZx0Jx2cmW85CGXcsFdSXlQWtIZ8GYN8q4T_tDf5JpbWRofiDybQAvpXgD6hNYtYla9NpqVfrtUqhd2-wpM4oURh5_84RooDvMJNKoV_DSh0Ge7/s1600/Capture3.PNG" /></a></div>
<div style="text-align: left;">
To send a byte to the computer, use this function:</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/AVvXsEiCrR00q4UQvlg0x-GNwcCcsxxzcyt6X1SezmDc9Sr8CJYpiiJ1_XTqfhWQmcQWitbN2wKvuJ7xhv3UFecOcPWkfNF8HpCDetdpPr_a6RjTypA6_1iJeS2tC6FUwqni1XLH4oPpAG3lMw_d/s1600/Capture4.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCrR00q4UQvlg0x-GNwcCcsxxzcyt6X1SezmDc9Sr8CJYpiiJ1_XTqfhWQmcQWitbN2wKvuJ7xhv3UFecOcPWkfNF8HpCDetdpPr_a6RjTypA6_1iJeS2tC6FUwqni1XLH4oPpAG3lMw_d/s1600/Capture4.PNG" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br />
And to receive a byte from the computer:</div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaVMcukxujXWcK02og0OZeEqLxSLmYSMJAebu_Pu2kAWIwa0qiNFMWz1hDIpCjsDJlw9h3HrepfsmUUamWu75ZG8v0tQ589HsEKRaTugLAheU3vIN1LqNrD71vzxy7Y90lpgtn86_MFDpI/s1600/Capture5.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: left;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaVMcukxujXWcK02og0OZeEqLxSLmYSMJAebu_Pu2kAWIwa0qiNFMWz1hDIpCjsDJlw9h3HrepfsmUUamWu75ZG8v0tQ589HsEKRaTugLAheU3vIN1LqNrD71vzxy7Y90lpgtn86_MFDpI/s1600/Capture5.PNG" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Instead of constantly calling the USART_Receive-function, I strongly recommend you to setup an interrupt, that automatically triggers when the computer sends something to your chip. The interrupt is initialized like this:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQr2v2DGvscgsJ0lmKpEzVOGsxW_vNTmAYd_m2xrpnkhgDCIKZVMjlmbon-zCwXWU6zeqWndqBRoaET9M1FC8Q-vByJoCV7duZ4HYAvh8OoG2Ofwkb7-BiYzhOqz9094hY3U365ZXy4CzD/s1600/Capture6.PNG" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQr2v2DGvscgsJ0lmKpEzVOGsxW_vNTmAYd_m2xrpnkhgDCIKZVMjlmbon-zCwXWU6zeqWndqBRoaET9M1FC8Q-vByJoCV7duZ4HYAvh8OoG2Ofwkb7-BiYzhOqz9094hY3U365ZXy4CzD/s1600/Capture6.PNG" /></a><br />
<br />
And put the function that gets triggered by the USART receive interrupt at the very bottom of your code:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDfkj63UhcufcuEz4j-OOwiGel8q_DbvV5cGi-1tsNO6z2fnrKYX_Ht6h0auC-cxmCHJ4lrTIMie3NQRd9ms1J2yOnH3O1tVhRjXJk2XxhwDH787gOXTZBYtLElWplcRWTTpD61jkxsNcu/s1600/Capture7.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDfkj63UhcufcuEz4j-OOwiGel8q_DbvV5cGi-1tsNO6z2fnrKYX_Ht6h0auC-cxmCHJ4lrTIMie3NQRd9ms1J2yOnH3O1tVhRjXJk2XxhwDH787gOXTZBYtLElWplcRWTTpD61jkxsNcu/s1600/Capture7.PNG" /></a></div>
<br />
Now here is the main function, that just waits for a USART command from the computer:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4f2EbmcVbECW7Ri-eIfekUD92bVjXj56d1oWYgpVxwMLlznPRNgzbrh2JpoTrv93EE4zTzX4GNg35sstoXeczykWfkKDoDrOcxfQH5ndCWqOeqlbiFQEyutKeCC2VMd6EZKIiTXFs1R-e/s1600/Capture8.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4f2EbmcVbECW7Ri-eIfekUD92bVjXj56d1oWYgpVxwMLlznPRNgzbrh2JpoTrv93EE4zTzX4GNg35sstoXeczykWfkKDoDrOcxfQH5ndCWqOeqlbiFQEyutKeCC2VMd6EZKIiTXFs1R-e/s1600/Capture8.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
If you for example want to send "Kalle" to the computer you would write:</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmoshBxfz-WUWWF9c-S3-p7CHqY1KBMWO8ymOgRzCnqKjiVpCyHbVw0IeI25T1oWYUqQqAA2XxPGtBsA1IFfFiJFF0oVowv-pNGrGds3B7rg6FP-K8ogRFVN_umkBLrEKyCxuWDvGrGAcG/s1600/Capture9.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmoshBxfz-WUWWF9c-S3-p7CHqY1KBMWO8ymOgRzCnqKjiVpCyHbVw0IeI25T1oWYUqQqAA2XxPGtBsA1IFfFiJFF0oVowv-pNGrGds3B7rg6FP-K8ogRFVN_umkBLrEKyCxuWDvGrGAcG/s1600/Capture9.PNG" /></a></div>
<div style="text-align: left;">
<br /></div>
<br />
<br />
<br />
<br />
<br />
<b><span style="font-size: x-large;">Setting up computer</span></b><br />
First of all, when inserting the USB to COM-adapter, Windows will not find the right driver, and will direct you to the silicon labs website. This usually works great, but if not, <a href="http://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx">here</a> is the link to the drivers.<br />
<br />
After installed, go to device manager and make sure it is set like this (default value i think, and mine still works if i change the "Stop bits" to one):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1sbRKSy5SLkXo8Cuf6SidkPRUA2vjlbGwJ4D6caF6UtUW1YywPIGbcGDiyL2kN98_2If_f69Lm64PDkZNBjoPfdeeJwvSsiXQqmFRMmMNRE2ASZlgnG0Uzw13woEgDw5AC92DhcRc_6F2/s1600/Capture1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="468" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1sbRKSy5SLkXo8Cuf6SidkPRUA2vjlbGwJ4D6caF6UtUW1YywPIGbcGDiyL2kN98_2If_f69Lm64PDkZNBjoPfdeeJwvSsiXQqmFRMmMNRE2ASZlgnG0Uzw13woEgDw5AC92DhcRc_6F2/s640/Capture1.PNG" width="640" /></a></div>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<br />
<div class="separator" style="clear: both; text-align: left;">
Now install and open "Termite.exe" and press the "Settings" button:</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/AVvXsEiHiMHhXVpEPgt7kvMskUuYlizj_CnA9q9YWBGYyH9hV_5GXB1esk7cerEFmEtNFnmCcmhv-kZflSBCL2CSxzMyQvfFc6dcReq9U9OXEaVYKVN-VYiwew51uwWx4Y37nWQ0KBQEwlTJYa_U/s1600/Capture.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHiMHhXVpEPgt7kvMskUuYlizj_CnA9q9YWBGYyH9hV_5GXB1esk7cerEFmEtNFnmCcmhv-kZflSBCL2CSxzMyQvfFc6dcReq9U9OXEaVYKVN-VYiwew51uwWx4Y37nWQ0KBQEwlTJYa_U/s1600/Capture.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
It will look something like this: change the "Port" to the port the computer chose for your adapter, and set it up like this: (no need to log the file, and put a timestamp, but nice features that i usually have set)</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/AVvXsEh3HAbm_vBahF05xpwd0-JW-E-0cNch8zFUSJyvHuq-ZsEOzZiH8HawZuzRCoff0PSEdC3BzhEj7O5NTSbHe0Qg31XGum7ionw-9DpXbYeZT0bW6Zq0VErYK9qhbi4S8bhIGbkTK70PaSTe/s1600/Capture3.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3HAbm_vBahF05xpwd0-JW-E-0cNch8zFUSJyvHuq-ZsEOzZiH8HawZuzRCoff0PSEdC3BzhEj7O5NTSbHe0Qg31XGum7ionw-9DpXbYeZT0bW6Zq0VErYK9qhbi4S8bhIGbkTK70PaSTe/s1600/Capture3.PNG" /></a></div>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
When pressing the "Log File" you get to choose where to put the logged file, and when checking the "Timestamp" you get to choose how long time every package-set is allowed to take, to still get on the same row (timestamp)...<br />
<br />
Example:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtXKJuExt8yRXldTiBLr-bLdrHJantqoDc-LJ1KkpalfZPCpwzscCNXtLZpX-7kqqhv2wmuIvKUBRBa7Q8klXn-TYitXUxLx5IrvzrG7kqM9gG3JD30JcH7tRrdSdiDd7ngVmqtNG0AoIJ/s1600/Capture4.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtXKJuExt8yRXldTiBLr-bLdrHJantqoDc-LJ1KkpalfZPCpwzscCNXtLZpX-7kqqhv2wmuIvKUBRBa7Q8klXn-TYitXUxLx5IrvzrG7kqM9gG3JD30JcH7tRrdSdiDd7ngVmqtNG0AoIJ/s1600/Capture4.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Here i send "011" to the chip (type in the bottom row and press enter), which returns ":Sent! 1#" (which is just something the chip i have connected right now is programmed to answer when it successfully sent the package "011" to my home made<a href="http://translate.google.se/translate?sl=sv&tl=en&js=n&prev=_t&hl=sv&ie=UTF-8&eotf=1&u=http%3A%2F%2Fgizmosnack.blogspot.se%2F2013%2F04%2Ftutorial-nrf24l01-and-avr.html&act=url"> IR-RF Remote control</a> after 1 retries)<br />
<br />
<br />
I think it is possible to use USART on a ATtiny chip as well, but haven't looked in to that yet! (if anyone has a working code for that, please share your experiences!)<br />
<br />
Hope this is helpful... it took me a long time to find a free program like Termite that has a timestamp and a log-file option, the only thing it lacked was the TCP-server ability that mine has ;)<br />
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRqogg2Bfp3dfdF9wGAUVzSUaPFepPpXMZNkO8fxVfCOrrluiArmqBKze455bdHQp12E97Ih5A4AM4HqjlIgGAqqnydwyk5eA46OJ09vM_fbTfE5nEe6Vk4iAkWXk5RtTQ_f5dUW9iV6aZ/s320/2.PNG" /><br />
<br />
If you have questions i might be able to help out in the comment field =)Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com7tag:blogger.com,1999:blog-2129587383257876818.post-13456145794385141752013-04-08T19:24:00.000+02:002013-12-09T21:32:38.750+01:00Tutorial - nRF24L01 and AVR<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="margin-left: 1em; margin-right: 1em;">
</div>
To start out with, you have to know that I am just a hobby programmer so if you find errors or possible improvements in my code, please give me a note so that I can correct them.<br />
<br />
If you have read my last blog posts <a href="http://translate.google.se/translate?hl=sv&sl=sv&tl=en&u=http%3A%2F%2Fgizmosnack.blogspot.se%2F2013%2F03%2Fvarldens-nordigaste-multifjarrkontroll.html">IR-RF remote control</a> and <a href="http://gizmosnack.blogspot.se/2013/04/temperature-based-flow-regulator.html">Temperature based flow regulator</a> you have noticed i like to add wireless control to my components. In this tutorial i will describe how i managed to get the nRF24L01 module to work with AVR microships like the Atmega88 (28pin), ATtiny26 (20pin) and ATtiny85 (8pin), since almost all of the tutorials out there are aimed at the Arduino users.<br />
<br />
The nRF24L01 module is an awesome RF module that works on the 2,4 GHz band and is perfect for wireless communication in a house because it will penetrate even thick concrete walls. The nRF24L01 does all the hard programming fore you, and even has a function to automatically check if the transmitted data is received at the other end.<br />
There are a couple of different versions of the nRF-family chips and they all seem to work in a similar way. I have for example used the nRF905 (433MHz) module with allmost the<a href="https://gist.github.com/klalle/83ec2a1a691523f2829f"> same code</a> as I use on the nRF24L01 and the nRF24L01+ without any problems. These little modules has an impressive range, with some versions that manages up to 1000 m (free sight) communication and up to 2000 m with a biquad antenna.<br />
<br />
<b><span style="font-size: large;">nRF24L01 versus nRF24L01+ </span></b><br />
The (+) version is the new updated version of the chip and supports data rate of 1 Mbps, 2 Mbps and a "long distance mode" of 250 kbps which is very useful when you want to extend the broadcast length.<br />
The older nRF24L01 (which i have used in my previous posts) only support 1 Mbps or 2 Mbps data rate.<br />
Both the models are compatible with each other, as long as they are set to the same data rate. Since they both costs about the same (close to nothing) I would recommend you to buy the + version!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip72hUdLVTrGEa4QVNqesg6PuwW-WiXrYwtsirZhyphenhyphenT5oRWJmA_wFvShLhGhkA3HrRRZaSQBjFdD7yTdg4Yw73fxHt70E7XUvTjAczXbOj4B93cdmKq_t9w_U66jQg1ApGaxOFjsB1ShH8M/s1600/nrf.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip72hUdLVTrGEa4QVNqesg6PuwW-WiXrYwtsirZhyphenhyphenT5oRWJmA_wFvShLhGhkA3HrRRZaSQBjFdD7yTdg4Yw73fxHt70E7XUvTjAczXbOj4B93cdmKq_t9w_U66jQg1ApGaxOFjsB1ShH8M/s1600/nrf.PNG" /></a><a href="http://thumbs1.ebaystatic.com/d/l225/m/mxIoCho9RWLt5Kx8Hhdr_RA.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://thumbs1.ebaystatic.com/d/l225/m/mxIoCho9RWLt5Kx8Hhdr_RA.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<b><span style="font-size: large;">The module</span></b><br />
An ebay search on "<a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf24l01&_sacat=0&_odkw=lg+optimus+one+hard+case&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">nRF24L01</a>" shows that there are many different versions of the modules that has the nRF24L01(+), and I have read that some of them are better then others due to better grounding and so on. But if you are after the long-range ones, make sure it has the + sign, and buy one with an extended antenna like <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf24l01+pa+lna+1000m&_sacat=0&_odkw=nrf24l01+pa+lna+1000&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">this one</a>:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://thumbs3.ebaystatic.com/d/l225/m/mECNywwrR5qx3CoY1tr5hBg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://thumbs3.ebaystatic.com/d/l225/m/mECNywwrR5qx3CoY1tr5hBg.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<b><span style="font-size: large;"><br /></span></b>
<br />
<b><span style="font-size: large;">Part one - Setup</span></b><br />
<b>Connection differences</b><br />
The nRF24L01 module has 10 connectors and the + version has 8. The difference is that the + version instead of having two 3,3 V and two GND, have its ground (the one with a white square around it) and 3,3 V supply, next to each other. If changing module from a new + version to an old one, make sure not to forget to move the GND cable to the right place, otherwise it will shorten out your circuit.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.electrokit.com/public/upload/productimage/49981-10364-4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://www.electrokit.com/public/upload/productimage/49981-10364-4.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Here is a picture of the + version (top view), where you can see all the connections labeled. The old version has two GND connections at the very top instead of at the down right corner. </div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<b>Power supply (GND & VCC)</b><br />
The module has to be powered with 3,3 V and <b>cannot </b>be powered by a 5 V power supply! Since it takes very little current I use a <a href="http://www.ebay.co.uk/sch/i.html?_nkw=LM1117+3.3v&_sacat=0&_odkw=LM1117+3%2C3v&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">linear regulator</a> to drop the voltage down to 3,3 V.<br />
To make things a little easier for us, the chip can handle 5 V on the i/O ports, which is nice since it would be a pain to regulate down all the i/O cables from the AVR chip.<br />
<br />
<b>Chip Enable (CE)</b><br />
Is used when to either send the data (transmitter) or start receive data (receiver).<br />
The CE-pin is connected to any unused i/O port on the AVR and is set as output (set bit to one in the DDx register where x is the port letter.)<br />
Atmega88: PB1, ATtiny26: PA0, ATtiny85: PB3<br />
<br />
<br />
<b>SPI Chip Select (CSN)</b><br />
Also known as "Ship select not". The CSN-pin is also connected to any unused i/O port on the AVR and set to output. The CSN pin is held high at all the time except for when to send a SPI-command from the AVR to the nRF.<br />
Atmega88: PB2, ATtiny26: PA1, ATtiny85: PB4<br />
<br />
<b>SPI Clock (SCK)</b><br />
This is the serial clock. The SCK connects to the SCK-pin on the AVR.<br />
Atmega88: PB5, ATtiny26: PB2, ATtiny85: PB2<br />
<br />
<br />
<b>SPI Master output Slave input (MOSI or MO)</b><br />
This is the data line in the SPI system.<br />
If your AVR chip supports SPI-transfere like the Atmega88, this connects to MOSI on the AVR as well and is set as output.<br />
<br />
On AVR's that lacks SPI, like the ATtiny26 and ATtiny85 they come with USI instead, and the datasheet it says:<br />
<br />
"The USI Three-wire mode is compliant to the Serial Peripheral Interface (SPI) mode 0 and 1, but<br />
does not have the slave select (SS) pin functionality. However, this feature can be implemented<br />
in software if necessary" <br />
<br />
The "SS" refered to is the same as "CSN"<br />
And after some research i found <a href="http://www.insidegadgets.com/2012/08/22/using-the-nrf24l01-wireless-module/">this blog</a> that helped me allot.<br />
<br />
To get the USI to SPI up and running I found out that I had to connect the <b>MOSI</b> pin from the nRF to the <b>MISO </b>pin on the AVR and set it as output.<br />
Atmega88: PB3, ATtiny26: PB1, ATtiny85: PB1<br />
<br />
<br />
<b>SPI Master input Slave output (MISO or MI)</b><br />
This is the data line in the SPI system.<br />
<br />
If your AVR chip supports SPI-transfere like the Atmega88, this connects to MISO on the AVR and this one stays as an input.<br />
<br />
To get it working on the ATtiny26 and ATtiny85, i had to use USI as mentioned above. This only worked when I connected the <b>MISO </b>pin on the nRF to the <b>MOSI </b>pin on the AVR and set it as input and enable internal pullup.<br />
Atmega88: PB4, ATtiny26: PB0, ATtiny85: PB0<br />
<br />
<br />
<b>Interrupt Request (IRQ)</b><br />
The IRQ pin is not necessary, but a great way of knowing when something has happened to the nRF. you can for example tell the nRF to set set the IRQ high when a package is received, or when a successful transmission is completed. Very useful!<br />
<br />
If your AVR has more than 8 pins and an available interrupt-pin i would highly suggest you to connect the IRQ to that one and setup an interrupt request.<br />
Atmega88: PD2, ATtiny26: PB6, ATtiny85: -<br />
<br />
<br />
<br />
<b><span style="font-size: large;">Part two- Programming</span></b><br />
Here i will explain the c-program that runs on the AVR-chip. You can find a working copy of my code <a href="https://gist.github.com/klalle/5652658">here</a> (easier to copy and paste from).<br />
<br />
<b>Includes</b><br />
I have included these lines to get my code to work:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgACSY67bxMcRr4v92k-_hVENtXoCcCD1o3CNy4Pc8Nu01m3lIrfBA6Ngufml-RoOusBXiZ2Aa-_vmnreMcdfNTzSHWLVztknzBQDNAWtG4kov5N75OsmXuSeeUm8FRiFORIGK0mXtWOYgO/s1600/Capture14.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgACSY67bxMcRr4v92k-_hVENtXoCcCD1o3CNy4Pc8Nu01m3lIrfBA6Ngufml-RoOusBXiZ2Aa-_vmnreMcdfNTzSHWLVztknzBQDNAWtG4kov5N75OsmXuSeeUm8FRiFORIGK0mXtWOYgO/s1600/Capture14.PNG" /></a></div>
<br />
<br />
<br />
<span style="font-size: large;"><b><br /></b></span>
<span style="font-size: large;"><b><br /></b></span>
<b><br /></b>
<br />
You can see that i am importing a file called nRF24L01.h. This is a small <a href="https://github.com/maniacbug/RF24/blob/master/nRF24L01.h">library </a>that defines the registers of the nRF so that i for example can call register "STATUS" instead of the register "0x07"... Just copy the text in the link and paste it into a file that you name "nRF24L01.h" and put it in the root of your folder.<br />
<b><br /></b>
<b>Defines</b><br />
To make the code cleaner i also put these definitions in the "nRF24L01.h"-file:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT39Vm3bif2SxsNsFQA8Z1BTe_5TNqiSTYsYIMMTt47DRYBm6sK1l2GvF-5UqHcH1YoizpuaQqmU4PgCWhUQV92zWPwA9Jkoa38tQ56bC5PHUHhzOv9bjI56jEFcilE2J1-CyAjSkg82Xe/s1600/Capture6.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgT39Vm3bif2SxsNsFQA8Z1BTe_5TNqiSTYsYIMMTt47DRYBm6sK1l2GvF-5UqHcH1YoizpuaQqmU4PgCWhUQV92zWPwA9Jkoa38tQ56bC5PHUHhzOv9bjI56jEFcilE2J1-CyAjSkg82Xe/s1600/Capture6.PNG" /></a></div>
<span style="font-size: large;"><b><br /></b></span>
<span style="font-size: large;"><b><br /></b></span>
<br />
<br />
<br />
<span style="font-size: large;"><b><br /></b></span>
And also add the defines:<br />
<span style="background-color: white;"><span style="font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: justify;"><span style="color: blue;">#define </span><span style="color: magenta;">W 1</span></span><br style="font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: justify;" /><span style="color: blue; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: justify;">#define</span><span style="font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18px; text-align: justify;"><span style="color: magenta;"> R 0</span></span></span><br />
<br />
<div style="text-align: justify;">
<span style="font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: x-small;"><span style="line-height: 18px;"><br /></span></span></div>
<b style="font-size: x-large;">SPI</b><br />
<b>Initialization</b><br />
The nRF chip communicates with the AVR-chip using SPI which has to be initialized in the AVR according to its datasheet. Here is the initializing code for Atmega88:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3-9gV1Qzkgv2ASXKCiC-Qp7taeSz_mh9B4UC-alEZRTZdsfxLLDh4SphHOnuempcr9a8gWhSuoVMYIMJfTf5sMIZL2aP1T-wMb0FWyMF7GQON7iBoBpzEVCYA6Y69soXHZLBpkQp_KwXm/s1600/Capture.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3-9gV1Qzkgv2ASXKCiC-Qp7taeSz_mh9B4UC-alEZRTZdsfxLLDh4SphHOnuempcr9a8gWhSuoVMYIMJfTf5sMIZL2aP1T-wMb0FWyMF7GQON7iBoBpzEVCYA6Y69soXHZLBpkQp_KwXm/s1600/Capture.PNG" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3-9gV1Qzkgv2ASXKCiC-Qp7taeSz_mh9B4UC-alEZRTZdsfxLLDh4SphHOnuempcr9a8gWhSuoVMYIMJfTf5sMIZL2aP1T-wMb0FWyMF7GQON7iBoBpzEVCYA6Y69soXHZLBpkQp_KwXm/s1600/Capture.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
ATtiny26:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhryiZIDXQSS0jir46qExaS6VcLHslc_KhbfK9kvFbe4icFxjZsf2givw1Gn2gmHwqouU-vVMv6f4QgwkdLn68k7M1n8gB-D6LNnLqSg7J2bkztegl4iWc2GT1130goJ8PGutLM75eWb3hj/s1600/Capture2.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhryiZIDXQSS0jir46qExaS6VcLHslc_KhbfK9kvFbe4icFxjZsf2givw1Gn2gmHwqouU-vVMv6f4QgwkdLn68k7M1n8gB-D6LNnLqSg7J2bkztegl4iWc2GT1130goJ8PGutLM75eWb3hj/s1600/Capture2.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
ATtiny85:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiIwqpaToCuLNPHwv0YVP8gc7uKAcE1XOI9D4LSZWywOqaOjA67zdLBhR-S7_lu4uV9_Kt2DPoTIIrcOcvZ0Qy1ZF49LvtBe5IYuW6ueIG5z9-aoVLT6bphFNpuozQD__PoVdXTaPAYch4/s1600/Capture3.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiIwqpaToCuLNPHwv0YVP8gc7uKAcE1XOI9D4LSZWywOqaOjA67zdLBhR-S7_lu4uV9_Kt2DPoTIIrcOcvZ0Qy1ZF49LvtBe5IYuW6ueIG5z9-aoVLT6bphFNpuozQD__PoVdXTaPAYch4/s1600/Capture3.PNG" /></a></div>
<br />
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b>Communication</b><br />
Now to send and receive a byte from the nRF with the SPI all you have to do is to use this function:<br />
Atmega88 (SPI):<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoT0GRc9p10u2Yc3toLMEhZM9JYtflB7iIiHInQfyK7LxDjsI7QvyE8c9EOv6o2r2bab-wHgR1uxgKFLnQ6vHXPXuQaFHMvWwJJJ4XuCH6UEunn5q91PQ62g_JE7T9X5ST-iCoV0_of9IC/s1600/Capture4.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoT0GRc9p10u2Yc3toLMEhZM9JYtflB7iIiHInQfyK7LxDjsI7QvyE8c9EOv6o2r2bab-wHgR1uxgKFLnQ6vHXPXuQaFHMvWwJJJ4XuCH6UEunn5q91PQ62g_JE7T9X5ST-iCoV0_of9IC/s1600/Capture4.PNG" /></a></div>
<div class="" style="clear: both; text-align: left;">
ATtiny(26 & 85) (USI as SPI):</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhACok3jY6SfCEChKVO3eA-07QlqrCiP0WQXtjlEUH7rVunkTzu5lIUAKiuWLPaHjBzNgrMn2wp9O1RGq1qGnvfXBunls94SprkSL7OjArvRc_vjNFKUtBQ7oN4wAeJ-e2PJ81ubgyEtXX1/s1600/Capture5.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhACok3jY6SfCEChKVO3eA-07QlqrCiP0WQXtjlEUH7rVunkTzu5lIUAKiuWLPaHjBzNgrMn2wp9O1RGq1qGnvfXBunls94SprkSL7OjArvRc_vjNFKUtBQ7oN4wAeJ-e2PJ81ubgyEtXX1/s1600/Capture5.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I don't think it matters if you send a char or an integer, this is just how i got it to work... Note that these functions always returns something, this returned message is only cared fore when reading data from the nRF (a more appropriate name of the function might be "Write_Read_Byte_SPI").<br />
<br />
<span style="font-size: large;"><b>nRF24L01(+) communication</b></span><br />
Now to the fun part...<br />
<b><br /></b>
<b>How it works</b><br />
1) The nRF starts listening for commands when the CSN-pin goes low.<br />
2) after a delay of 10us it accepts a single byte through SPI, which tells the nRF which bytes you want to read/write to, and if you want to read or write to it.<br />
3) a 10us delay later it then accepts further bytes which is either written to the above specified register, or a number of dummy bytes (that tells the nRF how many bytes you want to read out)<br />
4) when finished close the connection by setting CSN to high again.<br />
<br />
<b>Reading bytes from nRF</b><br />
To start off, make sure your SPI communication is working by reading out something from the nRF. Reading a register on the nRF is accomplished by this function: (all of my example codes is for Atmega88, just change to the right port and pin number for the CSN and CE to get it to work on ATtiny as well)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAsjfxX5bNlmb0OxZwQbZq0cKTv9UERCp279MinvKasafVwAR4LN5mSRmGnMnafOuxx32RmUJsh0v5bPHKmp2Ho8E5YYqMzjg6i5J8WzUSx1HOHqiT08tCnLowBNfql0oDrc19OVofgwDX/s1600/Capture8.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAsjfxX5bNlmb0OxZwQbZq0cKTv9UERCp279MinvKasafVwAR4LN5mSRmGnMnafOuxx32RmUJsh0v5bPHKmp2Ho8E5YYqMzjg6i5J8WzUSx1HOHqiT08tCnLowBNfql0oDrc19OVofgwDX/s1600/Capture8.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I recommend you to start out by reading the STATUS register like this:<br />
<b><br /></b>
<b>USART</b><br />
If you have an AVR that supports USART like the Atmega88, i highly recommend you to use that as a way of sending the data back to the computer with <a href="http://www.ebay.co.uk/sch/i.html?_nkw=CP2102&_sacat=0&_odkw=usb+to+com&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">this </a>little friend... (I have written a <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-usart-and-avr.html">small tutorial</a> in the subject)<br />
<br />
<img height="200" src="http://i.ebayimg.com/t/USB-2-0-to-TTL-UART-6PIN-Module-Serial-Converter-CP2102-STC-PRGMR-Free-cable-/00/s/NTAwWDUwMA==/$T2eC16ZHJHIE9nyseyg(BQTp)fSbq!~~60_12.JPG" width="200" /><br />
<br />
This is done simply by calling the function like this:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSXEzjRN2jB4nuWTQctIsRX1-IMB96pgQQOjh84I4h7_R9UxfA4zGE0r6R4acIZcn-8CpXc5IY2w0EevB12sSnROyRVmxiql-DOpRNlKwvDNdlQ6LoOKMJitvMTnxf6vNxQp18qcyrUaWV/s1600/Capture13.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSXEzjRN2jB4nuWTQctIsRX1-IMB96pgQQOjh84I4h7_R9UxfA4zGE0r6R4acIZcn-8CpXc5IY2w0EevB12sSnROyRVmxiql-DOpRNlKwvDNdlQ6LoOKMJitvMTnxf6vNxQp18qcyrUaWV/s1600/Capture13.PNG" /></a></div>
<br />
<br />
<br />
If you like me have a function called "USART_Transmit(uint8_t data)"<br />
The usart should send 0b00001110 (or 0x0E) to the computer since it is the preset configuration of the STATUS registry (see the end of this blogpost).<br />
<br />
<b>LED</b><br />
If you are using an ATtiny it lacks the USART and thereby the ability to write things back to the computer, then you can use a more hardcore way using an LED to turn on if the STATUS register is set correctly. Since the bites in the STATUS (0x07) register are preset to 0b00001110 (or 0x0E) you can test if this is true by this function:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbEZuPLPG_GPk5pblFzl-DkUrYayVQrMFbrhvpRgpJ1BYWaLD_UIu56AJpi3vLGWw3PrDO-_nzG6xdRukKDcFi01LiG2JQw8JUTst0rhjIV2MC78_SbiGKRf1tqQObcjnpvAltMdjbVT-/s1600/1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbEZuPLPG_GPk5pblFzl-DkUrYayVQrMFbrhvpRgpJ1BYWaLD_UIu56AJpi3vLGWw3PrDO-_nzG6xdRukKDcFi01LiG2JQw8JUTst0rhjIV2MC78_SbiGKRf1tqQObcjnpvAltMdjbVT-/s1600/1.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Make sure you remember to first set the LED-pin to output: DDRB |=(1<<5);<br />
<br />
If you are using an 8-pin ATtiny like the ATtiny85, there is not a single free pin on the chip to put the LED on, so i think a good idea would be to use the MISO-pin as a temporary LED output (since it is an output already and the SPI is not in use at the moment). Attach the LED to the PB1 and via a resistor to GND, then in the if-function above change the port number to 1. I haven't tested this my selves but i doubt it would cause any problem to the SPI-connection.<br />
<br />
<b>Writing bytes to the nRF</b><br />
Now it's time to send a command to the nRF, this is done almost the exact same way as the reading command with this function:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin_ViTh1rAQHkZspPofnoUls9YHl-L19EubtIj5h7ln1SE2OjhTvjUBmuRW9SBFMuRGu9aB68jX3ARZ3-NyZwgAxCFZf0uOD_MQPrWfklpnBLZgA2Q8FPs21Nc9E8PuaxB6p0CGcAxNEtW/s1600/Capture17.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin_ViTh1rAQHkZspPofnoUls9YHl-L19EubtIj5h7ln1SE2OjhTvjUBmuRW9SBFMuRGu9aB68jX3ARZ3-NyZwgAxCFZf0uOD_MQPrWfklpnBLZgA2Q8FPs21Nc9E8PuaxB6p0CGcAxNEtW/s1600/Capture17.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
If the register holds more then one byte, the TX_ADDR-byte for example holds five bytes, then you have to send them one at a time after each other with 10us delay in between. This makes the function a bit more complicated since C-code is unwilling to pas arrays of integers into functions as is.<br />
<br />
I also wanted to clean up my code a bit, so I decided to make one function that I can use to both read and write to the nRF. The function should also accept an array of integers and be able to return an array of integers. This is the result:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXjSSIQmSH15PL6XfThu-m8mrJFpvd0JgDxmgVd-0uvEoWFNlcU1ZpzDseD4SVTnv2iaqciGUgAMJHjxo2HCYHKINjCnna50xo2zh4n5spjjZyCdGHz_KbYPTy_w_XX1_uxIQbex_NcZdB/s1600/Capture18.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXjSSIQmSH15PL6XfThu-m8mrJFpvd0JgDxmgVd-0uvEoWFNlcU1ZpzDseD4SVTnv2iaqciGUgAMJHjxo2HCYHKINjCnna50xo2zh4n5spjjZyCdGHz_KbYPTy_w_XX1_uxIQbex_NcZdB/s1600/Capture18.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The most confusing thing whit this function is the W_TX_PAYLOAD in the if-statement... The thing is that when you want to write bytes to the W_TX_PAYLOAD you cannot add the W_REGISTER as you normally does when you want to write to a register. Have a look at the registry setup at the very bottom of this blog post, and you will see that the W_REGISTER and the W_TX_PAYLOAD is in the same "top level" of the registers. The same goes for the TX_FLUSH registers...<br />
<br />
Now here is some examples that shows how to use the function:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitqWyCpiaPfWzcirsAUOJ3iMPHH6ZLpbus0smVsx9heqQ2E01e8PzCeTyGk3j7X6Di1zvv1PWLtJd8e3sXrcIgSNSF4RCmsCJ1qb4Ct2KAJUK4yNPgNkxYN3tICBZs-wbl_tBI75a_ib2A/s1600/Capture19.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitqWyCpiaPfWzcirsAUOJ3iMPHH6ZLpbus0smVsx9heqQ2E01e8PzCeTyGk3j7X6Di1zvv1PWLtJd8e3sXrcIgSNSF4RCmsCJ1qb4Ct2KAJUK4yNPgNkxYN3tICBZs-wbl_tBI75a_ib2A/s1600/Capture19.PNG" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
To come back to the W_TX_PAYLOAD, when you want to ad the payload to the nRF, you simply use the "R" instead of the "W" to trick the WeiteToNrf-function to not add the W_REGISTER.<br />
<span style="font-size: large;"><b><br /></b></span>
<span style="font-size: large;"><b>Setting up nRF24L01(+) </b></span><br />
Now it is time to setup the nRF for your specifications. In the example codes, I will send a 5 byte payload with the nRF. This is easily changed to a 1-32 byte payload by changing a bit in the initialization step of the nRF (see below)... This is how i usually set it up for simple communication between two nRF's:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi07l5RHjrdYmzjUwC3zdVvMkk8QvGb4mch6_o5EyObo6BfnQ1e4dC0KM_vMysEj5qaJt72QhoYf4r6E8Irv-ReqAx686AC0nkRIG-_r4QUTDWe5WgJ6aNmPdQ86z5ekgDVvObGGmIdfphm/s1600/Capture20.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi07l5RHjrdYmzjUwC3zdVvMkk8QvGb4mch6_o5EyObo6BfnQ1e4dC0KM_vMysEj5qaJt72QhoYf4r6E8Irv-ReqAx686AC0nkRIG-_r4QUTDWe5WgJ6aNmPdQ86z5ekgDVvObGGmIdfphm/s1600/Capture20.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
In the code above, i missed a very important setting (if using EN_AA) that sets the number of retries and the retry delay like this:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOVfX1aIqtYRl2CmseOAV2bhniGXLdRjHYrYZAtjUgOySFXJ1l4plIvJrbc8BwFKHzoKaXbFN_kgU9jSHEYqcFUxsVwv7r0BWi_eZM0UmS8y0t4is0HY0Cbd5PlTqxwW3MKPY9lNYqhRyK/s1600/Capture5.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOVfX1aIqtYRl2CmseOAV2bhniGXLdRjHYrYZAtjUgOySFXJ1l4plIvJrbc8BwFKHzoKaXbFN_kgU9jSHEYqcFUxsVwv7r0BWi_eZM0UmS8y0t4is0HY0Cbd5PlTqxwW3MKPY9lNYqhRyK/s1600/Capture5.PNG" /></a></div>
<br />
<br />
<br />
<br />
Add these lines in the function above to set the number of retries to 15 and the delay to 750us... the delay has to be greater than 500us if you are in the 250kbps mode, or if the payload is greater than 5bytes when in 1Mbps-mode or a payload greater then 15bytes when in 2Mbps mode. Note that the default value of this is only 250us, and will therefore cause trouble when in 250kbps mode and with bigger payloads!<br />
<br />
As you can see i decided to make it a transmitter this time. This is easily changed in the code by first delay 50ms, to make sure the nRF is in sleep mode, then send 0x1F to the CONFIG register, than make it wait 50ms again before the first receive-command.<br />
<br />
<span style="font-size: large;"><b>Transmit data</b></span><br />
When in transmitting mode this is the function that sends your payload:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqiMeCDVHNm56dAqaX55veA1pToSWe_HBq5rIa2QrZHittu9-HALy5ZoxFcIiNo_4rRyrPvBNa8dVSBom6X5s9wOFK59oW0FXHnU6sFTuyLO_0j6KhYuIO5WnflWCWLUOYlPaWudIYg2DC/s1600/Capture22.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqiMeCDVHNm56dAqaX55veA1pToSWe_HBq5rIa2QrZHittu9-HALy5ZoxFcIiNo_4rRyrPvBNa8dVSBom6X5s9wOFK59oW0FXHnU6sFTuyLO_0j6KhYuIO5WnflWCWLUOYlPaWudIYg2DC/s1600/Capture22.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
And you call the transmit function like this: (now i just send 0x93 five times in a row, you can fill the array with any bytes you want to send)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijV3O3tx-u06_eB1uipNR7l-JO-t9b0M1lfT-mxNnjLv42PQHyeuVly-c06kfaaySnghqhaPvjeWha7PYdGYbdtE9f3KHflHwXMZ_TWdDyKfd_DHC3v6-C_d6kYTJF9WaVCJDH-hR1VdZJ/s1600/Capture21.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijV3O3tx-u06_eB1uipNR7l-JO-t9b0M1lfT-mxNnjLv42PQHyeuVly-c06kfaaySnghqhaPvjeWha7PYdGYbdtE9f3KHflHwXMZ_TWdDyKfd_DHC3v6-C_d6kYTJF9WaVCJDH-hR1VdZJ/s1600/Capture21.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<span style="font-size: large;"><b>Receive data</b></span><br />
When in receiver mode this is the function that listens and receives your data:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvMZt8qukKpJhwCzJ8lDbbfCS8ckJFMS3coEImWMx9yqy2ev9K0A7dsNOw9dKJBjkzVNguibSn8rR5vqQWmDiYx72TtyL514FwbOBUrg53zcQBgD7na6qdFgVyEeYHTLGSqTHDh-TzfdGw/s1600/Capture.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvMZt8qukKpJhwCzJ8lDbbfCS8ckJFMS3coEImWMx9yqy2ev9K0A7dsNOw9dKJBjkzVNguibSn8rR5vqQWmDiYx72TtyL514FwbOBUrg53zcQBgD7na6qdFgVyEeYHTLGSqTHDh-TzfdGw/s1600/Capture.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
After every received/transmitted payload the IRQ's in the nRF has to be reset in order to receive/transmit next package. This is done like this:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy2OFAlmAYR376IY9Yx_rz4wkjEoXGdiUK5zu7njJJTuwgdXWHVZl5syery-Du1zrxuiK5JkMo1Sqr-Xfk3EmNOWHCeabzP_blphmJ32LIwM4n5LA81bA_7Vu9VXQ9YNmjrP9FvRE92K4S/s1600/1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy2OFAlmAYR376IY9Yx_rz4wkjEoXGdiUK5zu7njJJTuwgdXWHVZl5syery-Du1zrxuiK5JkMo1Sqr-Xfk3EmNOWHCeabzP_blphmJ32LIwM4n5LA81bA_7Vu9VXQ9YNmjrP9FvRE92K4S/s1600/1.PNG" /></a></div>
<br />
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<b><span style="font-size: large;"><br /></span></b>
<b><span style="font-size: large;">Verify transmitted/received data using Interrupt</span></b><br />
If you have more than an 8-pin AVR, I say use an interrupt to get triggered when data is successfully received or transmitted. INT0 interrupt is setup like this:<br />
<br />
First you have to initialize the interrupt like this on Atmega88:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil6dk_PMV5hUE64TnqSe31_G1zdQ5h0lyz0OB9RyUReGhE4aPLfknJN4AWu_e5vvuHRT1Tf8cuYNjIsTtesi24A8Z1TL2iKh655aP-ysKph7Wk_0DIH1TViGIErVHx7c5TVoZOlfGbclW2/s1600/Capture3.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil6dk_PMV5hUE64TnqSe31_G1zdQ5h0lyz0OB9RyUReGhE4aPLfknJN4AWu_e5vvuHRT1Tf8cuYNjIsTtesi24A8Z1TL2iKh655aP-ysKph7Wk_0DIH1TViGIErVHx7c5TVoZOlfGbclW2/s1600/Capture3.PNG" /></a></div>
<b><br /></b>
<b><br /></b>
<b><br /></b>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
And initialization on ATtiny26:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOgtwQSbSzx0UJMB6RFytaFHa18QbjQt4N97Zsjf1aeqh8SIXMnCkoAhovZZiGukaFThY-bWDf_2RiQuW3zstM6EQuUOd9YcCBoyfWcPDeMbhtJ72s5Jmta9bOLAhYmaDmBLEbEWB6Lni5/s1600/Capture5.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOgtwQSbSzx0UJMB6RFytaFHa18QbjQt4N97Zsjf1aeqh8SIXMnCkoAhovZZiGukaFThY-bWDf_2RiQuW3zstM6EQuUOd9YcCBoyfWcPDeMbhtJ72s5Jmta9bOLAhYmaDmBLEbEWB6Lni5/s1600/Capture5.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b><br /></b>
<b>Interrupt caused when receiving data</b><br />
Setup a function triggered by the corresponding vector (INT0) at the very bottom of your code like this: (the global array "*data" is at the very top of my code...) And here i use it to send the received payload to the computer by usart:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-vzYrdD0MdrhXgvt3UrgBZhGeo_DVJjyDrC1HlSzeow_ZqToc0BnQha9UE9IF33QjUOGQTaIzDpwvkUT_dzz5-ZyjiwZRrtBu4B_Jb-2WEimcVQU2kpXtFlDTnSrABazh0b9yjhQNaEAk/s1600/Capture4.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-vzYrdD0MdrhXgvt3UrgBZhGeo_DVJjyDrC1HlSzeow_ZqToc0BnQha9UE9IF33QjUOGQTaIzDpwvkUT_dzz5-ZyjiwZRrtBu4B_Jb-2WEimcVQU2kpXtFlDTnSrABazh0b9yjhQNaEAk/s1600/Capture4.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>Interrupt caused on transmission success</b><br />
Use the same interrupt function when transmitting data but change its content to just flash the LED to tell you that transmission completed, or you can tell the nRF to switch for a receiver, if what you just sent was a question to a receiver that in turn changed to a transmitter to return your call.<br />
<br />
When you use interrupt, it is crucial that you enables the external interrupts by the command sei(); This should be done before the receive_payload, and transmit_payload is used.<br />
<br />
<b><span style="font-size: large;">Verify transmitted received data without interrupt</span></b><br />
If your chip lacks interrupt or if you ran out of free interrupt pins, you can manually check if the IRQ-flags are set in the status register after every time you either transmit data, or run the receive_payload function (before the reset function!!!)<br />
<br />
<b>Transmitting</b><br />
The easiest when you want to see if transmission succeeded or failed, is to check if the MAX_RT is set which mean it failed. This is done like this:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgregk39cCiHuI8tCkV90tIPm2hImWsx9z0GDBX0AtVLxrViCbqsYc5UE2Adbh0GlRc7RgYK9hnnS21eNdxIRGCTK7uQthDjBBRZ6fhmox4-UWjobLbCaCz5L4PjxyXBo8E5tIKUWLku5LJ/s1600/Capture7.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgregk39cCiHuI8tCkV90tIPm2hImWsx9z0GDBX0AtVLxrViCbqsYc5UE2Adbh0GlRc7RgYK9hnnS21eNdxIRGCTK7uQthDjBBRZ6fhmox4-UWjobLbCaCz5L4PjxyXBo8E5tIKUWLku5LJ/s1600/Capture7.PNG" /></a></div>
<br />
<br />
Then you know you have to resend the package.... i usually put this statement in a while loop that loops untill the package is received!<br />
<br />
<b>Receiving</b><br />
Do the same check to see if no data is received by checking the RX_DR-bit (data-ready) like this:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjilJU595C5As_OZ5VTJcO2H_FOg8LdtQnYQWs-nUeS2DXY3IIu8akmgKbrjbgwAwMiBmvD83VbAIpJZtXNBmpA8jQXeDpGPU9d6TF__nGHsp3F4f8WSiQBoAx1C-gDbjLOIWh6J1vGdW75/s1600/Capture8.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjilJU595C5As_OZ5VTJcO2H_FOg8LdtQnYQWs-nUeS2DXY3IIu8akmgKbrjbgwAwMiBmvD83VbAIpJZtXNBmpA8jQXeDpGPU9d6TF__nGHsp3F4f8WSiQBoAx1C-gDbjLOIWh6J1vGdW75/s1600/Capture8.PNG" /></a></div>
<br />
<br />
<br />
Or it might be a better idea to check if data is received by changing "!=" to "==", if not, you start the receive_payload function again!<br />
<br />
<b><span style="font-size: large;">Code overview</span></b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpvcNPZR0pRkigJd91tTGk7_PJaXeAjxUKPi7cQOcsylSWE74ls82xXA__5vU10GUFBZpwIEHRy6fQ2d4hrJC-qDOsfn0HLw46YFKxOVZfUGXngK-KPQuBzoiBuaCKlvjl7VcX6sKTmeGL/s1600/Capture6.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpvcNPZR0pRkigJd91tTGk7_PJaXeAjxUKPi7cQOcsylSWE74ls82xXA__5vU10GUFBZpwIEHRy6fQ2d4hrJC-qDOsfn0HLw46YFKxOVZfUGXngK-KPQuBzoiBuaCKlvjl7VcX6sKTmeGL/s1600/Capture6.PNG" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
If you are using the devise as a transmitter, I usually have an USART-interrupt function called "ISR(USART_RX_vect)" at the very bottom that triggers when the computer sends something to the microchip. In the usart interrupt vector it then calls transmit_payload with the data received from the usart.<br />
<br />
If you don't use usart, in the main while loop, send the data as described above "Transmit data".<br />
<br />
If you don't use the INT0-interrupt to check if the transmission succeeded put an if-statement in the main while loop to check whether the correct IRQ flag (nr 4) in the STATUS register is cleared as described earlier.<br />
<br />
If your chip is in receiver mode, in the main while loop, i usually call:<br />
while(1)<br />
{<br />
reset();<br />
receive_payload();<br />
}<br />
<br />
And if i don't have an interrupt, followed by an if-statement to see if anything was received by checking if the correct IRQ flag (nr 6) is set!<br />
<br />
<b><span style="font-size: large;">Long range mode</span></b><br />
If you have the + version, than you can set the RF_SETUP byte to 0x27 instead of 0x07, which will enable the 250 kbps mode (long range) on full power, and i also recommend you to read <a href="http://martybugs.net/wireless/biquad/">this </a>tutorial on how to build an amplifying biquad antenna. (remember to set the EN_AA-delay to at least 500us as described above)<br />
<br />
<span style="font-size: large;"><b>Registers</b></span><br />
This is straight from the datashet of the <a href="https://www.sparkfun.com/datasheets/Components/nRF24L01_prelim_prod_spec_1_2.pdf">older version</a> of the nRF24L01 (i find it easier to read thean the <a href="https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf">+ version</a>)<br />
<br />
This is the layout of the "top level" registers as i call them:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zI1OpRwlEnlGmIVSkQuZudKeO0JpazrHOwWmjApZCkQo1qg3sDpJt-NYNsS2nB3ifR9BlGXCJBj89Fx-pb5r3YIPFKm1n_TvSg_AIkY_fiiXuzh0KsUnlqyhSmz2zq6iVvx5gh666MzH/s1600/Capture10.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zI1OpRwlEnlGmIVSkQuZudKeO0JpazrHOwWmjApZCkQo1qg3sDpJt-NYNsS2nB3ifR9BlGXCJBj89Fx-pb5r3YIPFKm1n_TvSg_AIkY_fiiXuzh0KsUnlqyhSmz2zq6iVvx5gh666MzH/s1600/Capture10.PNG" /></a></div>
<br />
<br />
And here are all the other registers and there configurations:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuoGgUjqQHaMWOAb6TsikodQzb2L49nM5Gu-cyXDLGMQrJx7lPYfwo05nypB0yDdTvwO-7JxSfbfCndVkAqQzLupu2FTJjsslCQhz5jR4vxxCO6-YgE_uf8wJp8ida_nc-d1Yb4v2jJva8/s1600/Capture11.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuoGgUjqQHaMWOAb6TsikodQzb2L49nM5Gu-cyXDLGMQrJx7lPYfwo05nypB0yDdTvwO-7JxSfbfCndVkAqQzLupu2FTJjsslCQhz5jR4vxxCO6-YgE_uf8wJp8ida_nc-d1Yb4v2jJva8/s1600/Capture11.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEHfHAsTyKdcccEEcL8My941trrEZ9tmJKbAoyc0VCjciyApY57LCYImH6UoCpyqQGDSXt91NjQiBKv1_d5AIh6iCgY2nZwvft2UqWAVEm6sQogHaeLJYEnsCStb2I-i1krn837K8K-D4S/s1600/Capture12.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEHfHAsTyKdcccEEcL8My941trrEZ9tmJKbAoyc0VCjciyApY57LCYImH6UoCpyqQGDSXt91NjQiBKv1_d5AIh6iCgY2nZwvft2UqWAVEm6sQogHaeLJYEnsCStb2I-i1krn837K8K-D4S/s1600/Capture12.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVnBQAwcdqMAitFCeMqAnccMfZRZd8NmdKqZPby-4eK0bqn_mqmHlt1bB_g00BwGRi_wNEl8GCmvxrEyltkWGb5hljOXiqPgSeJshnUOufNHtooQ4u3D7OMmhrd5Dy4CetCaoxVXI_j4y6/s1600/Capture15.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVnBQAwcdqMAitFCeMqAnccMfZRZd8NmdKqZPby-4eK0bqn_mqmHlt1bB_g00BwGRi_wNEl8GCmvxrEyltkWGb5hljOXiqPgSeJshnUOufNHtooQ4u3D7OMmhrd5Dy4CetCaoxVXI_j4y6/s1600/Capture15.PNG" /></a></div>
<br />
<br />
I hope you enjoyed my tutorial...<br />
as always, if there is questions there might be an answer in the comment field.<br />
/KalleKarl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com275Umeå, Sverige63.8258471 20.26303540000003563.7137866 19.940311900000037 63.937907599999996 20.585758900000034tag:blogger.com,1999:blog-2129587383257876818.post-10860881562648832792013-04-03T19:59:00.000+02:002013-04-13T12:16:33.900+02:00Temperature based flow regulatorSince almost none of the readers of this blog understand Swedish, I decided to go international and start writing in English.<br />
<br />
In this post I will cover the construction of a temperature based flow regulator that some friends and I have built in order to make sure that the wort temperature is cooled from boiling point to 25°C in our<a href="http://vartlillabryggeri.blogspot.se/"> micro brewery</a>. This is important to make sure that the yeast is not killed when added. Since i have some experience in wireless communication we figured it would be cool to make the regulator remotely controlled from an android application.<br />
<br />
The setup is kind of similar to my previous <a href="http://gizmosnack.blogspot.se/2013/03/varldens-nordigaste-multifjarrkontroll.html">project </a>and is built around two <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Atmega88</a> with wireless communication through two <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf24l01&_sacat=0&_odkw=atmega88+dip28&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">nRF24L01</a> adapters (see my <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-nrf24l01-and-avr.html">tutorial</a> covering the nRF24L01 and AVR).<br />
<br />
<span style="font-size: x-large;"><b>Regulator setup</b></span><br />
- Power supply, 5V 2A USB-power supply (Powerful phone charger that both supplies the Atmega88 and drives the motorized ball valve)<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Atmega88</a>, the "computer", a microcontroller that takes and gives commands.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nRF24L01&_sacat=0&_odkw=lm35&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">nRF24L01</a>, 2,4 GHz module that sets up a wireless link with the other nRF-module attached to the computer.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=lm35&_sacat=0&_odkw=irf540n+n-&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">LM35</a>, Temperature sensor 10mV/°C scale factor and +-0,5°C accuracy.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=motorized+ball+valve+dn20&_sacat=0&_odkw=lg+optimus+one+hard+case&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Motorized ball valve</a>, 12V (DC-motor works perfectly on 5V, just a bit slower)<br />
<br />
- H-bridge, to drive the ball valve DC-motor in ether direction (H-bridge described well <a href="http://www.societyofrobots.com/schematics_h-bridgedes.shtml">here</a>). The components used are two <a href="http://www.ebay.co.uk/sch/i.html?_nkw=irf540n+n-&_sacat=0&_odkw=irf9540n+p-&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">IRF540N </a>(N-channel) and two <a href="http://www.ebay.co.uk/sch/i.html?_nkw=irf9540n+p-&_sacat=0&_odkw=irf9540n+p-*&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">IRF9540N</a> (P-channel) mosfets.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=10+prototype+pcb&_sacat=0&_odkw=prototype+pcb&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Prototype PCB</a>, to solder everything on.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=Stainless+Steel+Heat+Exchanger+plate&_sacat=0&_odkw=Stainless+Steel+Heat+Exchanger&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Heat-exchanger 44kW</a><br />
<br />
- Garden hose connections <a href="http://www.biltema.se/sv/Fritid/Tradgard/Bevattning-och-Pump/Snabbkopplingar-14014/">female</a>, <a href="http://www.biltema.se/sv/Fritid/Tradgard/Bevattning-och-Pump/Krananslutning-14035/">male</a>.<br />
<br />
<br />
<b><span style="font-size: x-large;">Construction</span></b><br />
Armed with a soldering iron, the process went fairly quick and the result is shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilTz5tSFF3oqLu798Djj4xAPeJSWh6Eb-BEUdDOGiZ-D4FaWh8LwgHc9f7Eaz57ShalYNyPdoVNz8x8asILJeW92JnnNIOVpMQ945ZyGpUH45cyYW1E9XYy8AKy6_inZTCxpz7eoy-a_aF/s1600/Bild02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="425" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilTz5tSFF3oqLu798Djj4xAPeJSWh6Eb-BEUdDOGiZ-D4FaWh8LwgHc9f7Eaz57ShalYNyPdoVNz8x8asILJeW92JnnNIOVpMQ945ZyGpUH45cyYW1E9XYy8AKy6_inZTCxpz7eoy-a_aF/s640/Bild02.jpg" 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 top corner is where the motorized ball valve is connected, and powered via the H-bridge (the fore black mosfets). The temperature probe is attached in the left corner, and the RF-module is the green to the left. The black thing next to the RF-module is a linear regulator that converts the 5 V to 3,3 V since it cannot work with 5 V. When the motor on the valve starts, it produces a huge voltage drop in the system, and therefore it is necessarily to put a large capacitor on the power supply. </div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIb5MLyO4_gcVqyw_k1gV3KTYE0CP2LC0qJVi_U671ZDOAo8dbbTN-tc5odwmu5Stq_w-_akrvuiltGDxg9uyFPL-HRrw_ThGGIQ_xFwRBO-BWH_Dt73FgK6ob5T_LMC4FDwuXx6uk9ixT/s1600/Bild01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="374" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIb5MLyO4_gcVqyw_k1gV3KTYE0CP2LC0qJVi_U671ZDOAo8dbbTN-tc5odwmu5Stq_w-_akrvuiltGDxg9uyFPL-HRrw_ThGGIQ_xFwRBO-BWH_Dt73FgK6ob5T_LMC4FDwuXx6uk9ixT/s640/Bild01.jpg" width="640" /></a></div>
<br />
For anyone that wants to construct a H-bridge, i found a great way of soldering them together as you can see at the very top of this picture. Put the two P-channel ones at the back row, and the two n-channel ones in the front row so they line up. Then on each p-channel mosfet you bend the two right connectors (seen from underneath) and solder them to the n-channel ones which you can cut off. For each pair of p+n-channel mosfet you then connect the right rail to respective i/o port on the micro controller, and the middle one to respective DC-motor connection. The left connectors of the P-channel mosfets connects to 5V, and the left connectors on the N-channel ones connects to ground.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhinLRmoUVhj7yIj0mtymSFhkIbYLIPRGlqdiVtVePto8TmsT9J9KzXXwYgprfnSvYVk2qmdMQVJBFR2Swh4S60p_NZU05q6q1UwOTuLdNvfz-ZVXkuLwL88n0bmpdzemY0deO8pCYeZ5sr/s1600/Bild03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhinLRmoUVhj7yIj0mtymSFhkIbYLIPRGlqdiVtVePto8TmsT9J9KzXXwYgprfnSvYVk2qmdMQVJBFR2Swh4S60p_NZU05q6q1UwOTuLdNvfz-ZVXkuLwL88n0bmpdzemY0deO8pCYeZ5sr/s640/Bild03.jpg" width="424" /></a></div>
<br />
<br />
The temperature measurements is done in the hose connector where the wort leaves the heat-exchanger. It looks a bit messy, but at least it does not leak and the quick connector still works! ;)<br />
<br />
<br />
<br />
<b><span style="font-size: x-large;">Setup</span></b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoCg_juhAOIizTGBPBBHe4u8V-O8MdWgXtjJs_cQxS2C289F-iXXDVWW2KsMZXzZq2ar0LMOBJDH7fGq5PaAI6D4DhyiPg_1TJCF5ikVOsGoApChOxzjVp72SqcGVNNtgc6hWkCA2JTxO6/s1600/Bild04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="488" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoCg_juhAOIizTGBPBBHe4u8V-O8MdWgXtjJs_cQxS2C289F-iXXDVWW2KsMZXzZq2ar0LMOBJDH7fGq5PaAI6D4DhyiPg_1TJCF5ikVOsGoApChOxzjVp72SqcGVNNtgc6hWkCA2JTxO6/s640/Bild04.jpg" width="640" /></a></div>
<br />
<br />
The heat exchanger is used as a counter current flow type, and is regulated by controlling the flow of the cold tap-water outlet, so that the temperature of the wort outlet matches its predefined value.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7iVzxBWYZuO9Axcv-QoqMjmSHNE7x3qvhgSbUz1xfxAEzh1Rj6ith-PO3psS9U-MlhFFY0nZOxxBhsY6IDRgPlmHI9kC31xszeZaTjkZfdGjyaZEDIFUy8fRCxuJLwpS4RQIlI0-qROPC/s1600/setup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="402" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7iVzxBWYZuO9Axcv-QoqMjmSHNE7x3qvhgSbUz1xfxAEzh1Rj6ith-PO3psS9U-MlhFFY0nZOxxBhsY6IDRgPlmHI9kC31xszeZaTjkZfdGjyaZEDIFUy8fRCxuJLwpS4RQIlI0-qROPC/s640/setup.png" width="640" /></a></div>
This is an overview of the complete setup of the system (the +-2°C should be -+0,5°C). The home-made module attached to the computer is a similar unit as the regulator, but instead of USB power, temperature probe and dual H-bridge it is connected to the computer via a <a href="http://www.ebay.co.uk/sch/i.html?_nkw=CP2102&_sacat=0&_odkw=usb+to+com&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">USB to COM adapter</a> like this one: (i have a small tutorial about USART and Atmega88<a href="http://gizmosnack.blogspot.se/2013/04/tutorial-usart-and-avr.html"> here</a>)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.ebayimg.com/t/USB-2-0-to-TTL-UART-6PIN-Module-Serial-Converter-CP2102-STC-PRGMR-Free-cable-/00/s/NTAwWDUwMA==/$T2eC16ZHJHIE9nyseyg(BQTp)fSbq!~~60_12.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://i.ebayimg.com/t/USB-2-0-to-TTL-UART-6PIN-Module-Serial-Converter-CP2102-STC-PRGMR-Free-cable-/00/s/NTAwWDUwMA==/$T2eC16ZHJHIE9nyseyg(BQTp)fSbq!~~60_12.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;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: x-large;"><b>Programming</b></span></div>
<br />
The android application is communication via TCP (wifi or 3G) and is controlled by the same visual basic program i built in the <a href="http://gizmosnack.blogspot.se/2013/03/varldens-nordigaste-multifjarrkontroll.html">last post</a> to control the ultimate IR-RF remote control:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRqogg2Bfp3dfdF9wGAUVzSUaPFepPpXMZNkO8fxVfCOrrluiArmqBKze455bdHQp12E97Ih5A4AM4HqjlIgGAqqnydwyk5eA46OJ09vM_fbTfE5nEe6Vk4iAkWXk5RtTQ_f5dUW9iV6aZ/s1600/2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRqogg2Bfp3dfdF9wGAUVzSUaPFepPpXMZNkO8fxVfCOrrluiArmqBKze455bdHQp12E97Ih5A4AM4HqjlIgGAqqnydwyk5eA46OJ09vM_fbTfE5nEe6Vk4iAkWXk5RtTQ_f5dUW9iV6aZ/s320/2.PNG" width="316" /></a></div>
<br />
Screenshots of the android application:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr1vqvFmyr85sOoyi6i87FyWydyqHfqCnmtoVJtqabgSAT1bO4Z4_-ckjLkJWWrqMh1_AF90CMzCPQ7rpxqQ-XrvizthF1QNJ9guPAWtrw3P3nVYV-zQe6trrD70unxKnJ0zWQTvvX7LV0/s1600/app.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="566" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr1vqvFmyr85sOoyi6i87FyWydyqHfqCnmtoVJtqabgSAT1bO4Z4_-ckjLkJWWrqMh1_AF90CMzCPQ7rpxqQ-XrvizthF1QNJ9guPAWtrw3P3nVYV-zQe6trrD70unxKnJ0zWQTvvX7LV0/s640/app.png" width="640" /></a></div>
<br />
The user can tap on the picture representing the heat exchanger above and set a new temperature for the regulator to aim for. The current temperature is automatically updated every 2 s where it now says "- °C". The two other temperature fields are not up and running at the moment, but in the future they are suppose to regulate the temperature of the boiler and the mash-tun.<br />
<br />
<br />
If anyone have questions about the build or want me to explain my projects further, please just write a comment!Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com7Umeå, Sverige63.8258471 20.26303540000003563.7137866 19.940311900000037 63.937907599999996 20.585758900000034tag:blogger.com,1999:blog-2129587383257876818.post-47305951826488766802013-03-21T23:41:00.000+01:002013-04-13T12:17:48.814+02:00Världens nördigaste multifjärrkontrollNu har jag äntligen tagit mig tid att sätta ihop vad som antagligen är världens nördigaste multifjärrkontroll!<br />
Det hela började med att jag hackade mina <a href="http://gizmosnack.blogspot.se/2013/03/rf-fjarrstrombrytare-hack.html">RF-fjärrströmbrytare</a> och mina <a href="http://gizmosnack.blogspot.se/2013/03/ir-fjarrkontroll-hack.html">IR-Fjärrkontroller</a> då jag byggde ihop ett fullt fungerande bibliotek över deras funktioner och hur de sänds.<br />
<br />
Tanken med multifjärrkontrollen är att den ska ligga ute i vardagsrummet, där IR-diodena är synliga för stereon, TVn och projektorn och RF-sändaren har bra räckvidd till de flesta rum i lägenheten (den når ca 10m).<br />
<br />
<b><span style="font-size: x-large;">Specs Fjärrkontrollen</span></b><br />
- Strömförsörjningen till fjärrkontrollen sker via en USB-kabel och en vanlig mobilladdare 5V.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf24l01&_sacat=0&_odkw=atmega88+dip28&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">nRF20L01</a> 2,4 GHz (en annan modell av RF-sändare än den som pratar med fjärrströmbrytarna). Orsaken till det är att det är väldigt lätt att skicka data mellan två nRF24L01 och de har inbyggda funktioner som t.ex. analyserar om datan mottagits mm. (se min <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-nrf24l01-and-avr.html">tutorial</a> som går igenom nRF24L01 ochAVR).<br />
<br />
-<a href="http://www.ebay.co.uk/sch/i.html?_nkw=433MHz&_sacat=0&_odkw=nrf905&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1"> RF-transmitter 433MhZ</a> för att sätta på/stänga av fjärrströmbrytarna.<br />
<br />
- IR-dioder 2st snodda från gamla fjärrkontroller (<a href="http://www.ebay.co.uk/sch/i.html?_nkw=ir+diode&_sacat=0&_odkw=ir+transmitter&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">ebay</a>) skickar kommandon till stereo, TV & projektor.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Atmega88</a> microkontroller - hjärtat i fjärrkontrollen, länken mellan nRF24L01 och övriga komponenter.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=10+prototype+pcb&_sacat=0&_odkw=prototype+pcb&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Prototypbräda</a> 5x7cm - kretskortet<br />
<br />
<b><span style="font-size: x-large;"> Byggnation Fjärrkontroll</span></b><br />
Efter nån timme med lödpennan så blev resultatet helt ok faktiskt:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOLIDFxeInzX0aZvHz8hCVxHIiZpDgC_ulo5ceK4jFIrIHuMM0UjDf8YfUWiFEP0TW5aDAl2f8tGWWQHHjdyVpuzR0W9Xf8UiPoWC0MOuZkLqGk33wEyreC_M7l13s80glMWUn52uqHcyr/s1600/Klasskort08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOLIDFxeInzX0aZvHz8hCVxHIiZpDgC_ulo5ceK4jFIrIHuMM0UjDf8YfUWiFEP0TW5aDAl2f8tGWWQHHjdyVpuzR0W9Xf8UiPoWC0MOuZkLqGk33wEyreC_M7l13s80glMWUn52uqHcyr/s640/Klasskort08.jpg" width="640" /></a></div>
<br />
ISP-kontaktena längst hitåt är för att kunna programmera Atmega88'an på plats, och linjärregulatorn till höger om nRF24L01 är för att den kräver 3,3V och resten går på 5V. Transistorn vid IR-diodena är för att jag inte ville bränna chippet då jag parallellkopplar två dioder på samma pinne. Den röda lysdioden längst bort är är bara en indikator som säger när fjärrkontrollen skickar kommandon med antingen IR lr RF (kunde inte hålla mig... ;)<br />
<br />
<b><span style="font-size: x-large;">Programvara Fjärrkontroll</span></b><br />
Programmet är skrivet i AVR (C-programmering) och gör ingenting fören nRF24L01 mottagit ett packet data, då triggar den en interrupt-pin på Atmega88'an som med hådvaru-SPI läser av de tre byten som mottagits.<br />
Den första byten säger vilken fjärrkontroll som ska simuleras, sedan om det visar sig vara en IR-fjärrkontroll så berättar andra byten vilken knapp som ska tryckas, och om det istället är en RF-fjärrkontroll så säger andra byten vilken fjärrströmbrytare som ska kontrolleras. Tredje och sista byten har endast en funktion om det är en RF-kontroll då den säger om den valda fjärrströmbrytaren ska slås av eller på.<br />
<br />
Programmet fungerar mycket bra även utan extern kristall på chippet, så jag antar att timingarna inte är så noggranna när det kommer till IR och RF!<br />
<br />
<br />
<br />
<b><span style="font-size: x-large;">Specs Datorkontrollen</span></b><br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf24l01&_sacat=0&_odkw=atmega88+dip28&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">nRF20L01</a> 2,4 GHz - för att trådlöst sända kommandon till fjärrkontrollen<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=CP2102&_sacat=0&_odkw=usb+to+com&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">USB-COM adapter</a> för att sända kommandon från datorn till Atmega88 (se min tutorial om hur man får det att funka <a href="http://gizmosnack.blogspot.se/2013/04/tutorial-usart-and-avr.html">här</a>)<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Atmega88</a> microkontroller - länken mellan USB-COM adapter och nRF24L01.<br />
<br />
- <a href="http://www.ebay.co.uk/sch/i.html?_nkw=10+prototype+pcb&_sacat=0&_odkw=prototype+pcb&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1">Prototypbräda</a> 5x7cm - kretskortet<br />
<br />
<b><span style="font-size: x-large;">Byggnation Datorkontroll</span></b><br />
<br />
Datorkontrollen har jag inte lött ihop ännu, den sitter fortfarande på en <a href="http://www.ebay.co.uk/sch/i.html?_nkw=bread+board+solderless+800&_sacat=0&_odkw=bread+board+solderless+900&LH_BIN=1&_sop=15&_jgr=1&gbr=1&_fcid=192&_osacat=0&LH_PrefLoc=2&_sc=1">test-prototypbräda</a>. Den fungerar iaf så att USB-COM adapterns Tx, Rx och GND är kopplade till Atmega88'ans respektive pinne för att möjliggöra USART-kommunikation.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://i.ebayimg.com/t/2X-800-PTS-Points-Solderless-Bread-Board-Breadboard-PCB-/19/!CD(vey!BGk~$(KGrHqR,!joE0Du4sfM8BNOVF7Uv!Q~~0_3.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="http://i.ebayimg.com/t/2X-800-PTS-Points-Solderless-Bread-Board-Breadboard-PCB-/19/!CD(vey!BGk~$(KGrHqR,!joE0Du4sfM8BNOVF7Uv!Q~~0_3.JPG" style="cursor: move;" width="400" /></a></div>
<br />
<br />
<b><span style="font-size: x-large;">Programvara Datorkontrollen</span></b><br />
<br />
Atmega88'an gör ingenting fören ett USART-interrupt går igång då datorn försöker skicka något via COM-porten. Atmegan läser då av de tre byten och skickar de direkt vidare via SPI till nRF24L01-modulen, som då sänder ut det till den mottagande multifjärrkontrollen. Efter lyckad sändning går Atmegan tillbaka till att tom-loopa.<br />
<br />
<br />
<br />
<b><span style="font-size: x-large;">Programvara Datorn</span></b><br />
Datorns programvara är ett Windows-baserat VB-program som jag har jobbat på ett tag nu som antagligen ska få ett eget inlägg i bloggen när jag få tid lust och ork, men i stort fungerar den såhär:<br />
<br />
Programmer ansluter till önskad COM-port, genom att välja ur listan och trycka på den stora knappen (eller som i mitt fall om har en "Silicon Labs CP210x" så ansluter den automatiskt när programmet startar)<br />
Jag väljer att inte returnera inkommande från COM-porten, annars går programmet in i en oändlig loop eftersom Atmegan är satt att returnera det som skickas till den, och det vill jag inte. Jag väljer också att inte vidarebefordra meddelandet som returneras från atmegan till möjliga TCP-clienter. "StopByte" används för att slippa ange längd på packetet som ska mottas från Atmegan som istället är programmerad att skicka en stopbyte efter varje packet (3 byte data + "#")<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp6ukCFaxQLAc9HFjT0vN1Hy6xx6q0XLHg7gKK8Az1kAJBbsrYH3XOAG5HPE24b-3uAROZ4TOIfmXUAvLNPRtcndgwmAoqMc-vo59qDuF8KOqZzgxOP_JfKid7lKJt6W8C-v8Cb_MeKJOJ/s1600/1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjp6ukCFaxQLAc9HFjT0vN1Hy6xx6q0XLHg7gKK8Az1kAJBbsrYH3XOAG5HPE24b-3uAROZ4TOIfmXUAvLNPRtcndgwmAoqMc-vo59qDuF8KOqZzgxOP_JfKid7lKJt6W8C-v8Cb_MeKJOJ/s1600/1.PNG" /></a></div>
<br />
Nästa tab är TCP-Servern, och den används för att tillåta inkommande data från internet/wifi. Bara att välja port, och trycka på stora knappen som innan hette "Start". Här vill jag faktiskt vidarebefodra inkommande TCP-data till COM-porten för att på så sätt kunna skicka kommandon från internet direkt till Atmegan. Jag har här valt att returnera inkommande meddelandet till TCP-clienten också, då android-appen är gjord så.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfjptVCT94unWHCfwK0MWlwScowBdafMEUtR5T6o1f6RrpvqxvGaykszkWFLzaZvsAV5whn_HDgbjPjQo1wIDpWdcw4HxUrzgCoqUFwbxYoYhtuAykZkvyf86lWyRGYU0VB-ac4GsVCWA4/s1600/3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfjptVCT94unWHCfwK0MWlwScowBdafMEUtR5T6o1f6RrpvqxvGaykszkWFLzaZvsAV5whn_HDgbjPjQo1wIDpWdcw4HxUrzgCoqUFwbxYoYhtuAykZkvyf86lWyRGYU0VB-ac4GsVCWA4/s1600/3.PNG" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
Nu på första tabben, där alla kommandon loggas, samt där man kan skriva kommandon i input text-boxen som i nuläget vidarebefodras till COM-Porten. Här visas också om COM-port är ansluten och om TCP-servern är ansluten och hur många clienter som är anslutna.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="" style="clear: both; text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1xgS_wNfVIagRJ9tRw-OmiH7SeQPCItaNhVUVzAgpeKGQafbY-Z3PIoC9xrpnxm6lTHNS50xuGXdlUEFWIZZdq9DFcqn5J8m19Ey3Lf8__G6Ohq599UStxub-Og_mWoS0_C3vWrI0h49/s1600/2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1xgS_wNfVIagRJ9tRw-OmiH7SeQPCItaNhVUVzAgpeKGQafbY-Z3PIoC9xrpnxm6lTHNS50xuGXdlUEFWIZZdq9DFcqn5J8m19Ey3Lf8__G6Ohq599UStxub-Og_mWoS0_C3vWrI0h49/s1600/2.PNG" /></a></div>
<br /></div>
De övriga flikarna styr var och om all datakommunikation ska loggas, samt vilka funktioner i programmet som ska autostarta och om hela programmet ska autostarta med windows.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
<br />
<b><span style="font-size: x-large;">Programvara Android</span></b><br />
Vad är väl en multifjärrkontroll om den inte kan styras från multi-enheter... jag satte igång och skapade en android-app som via TCP kan skicka kommandon till fjärrkontrollen:<br />
<br />
<img height="265" src="http://sphotos-a.ak.fbcdn.net/hphotos-ak-prn1/892997_10151536460934406_1518389300_o.jpg" width="640" /><br />
<br />
Förstasidan som öppnas är den vänstra, där går man in i TCP-settings och ansluter till rätt IP och Portnr, som jag då sätter till min <a href="http://whatismyipaddress.com/">externa ip-adress</a> för att kunna använda 3G och slippa ansluta till Wifi varje gång jag ska använda appen. Porten jag ansluter till har jag tidigare ställt in i routern <a href="http://www.cctvcamerapros.com/v/vspfiles/assets/images/d-link-port-forwarding.jpg">såhär</a> så att den forwardar till den rätta porten som ställts in i programmet på datorn.<br />
<br />
På förstasidan väljer man sedan att simulera IR eller RF-fjärrkontroller, eller köra förprogrammerade macron där jag bla har ställt in en sekvens som sätter på stereon på AUX, sätter på projektorn och släcker lamporna som sitter på RF-fjärrströmbrytare.<br />
<br />
Nästa uppdatering på appen är att man on the fly ska kunna programmera makron som hamnar på de tomma knapparna och sparas. Jag ska också uppdatera datorprogrammet så att det reagerar på vissa kommandon genom att sätta pausa spotify, sätta på XBMC och ändra bildinställningen till projektor-mode.<br />
<br />
<br />
Om nån vill ha mer info, så skriv en kommentar! =)Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com4Umeå, Sverige63.8258471 20.26303540000003563.7137861 19.940311900000037 63.937908099999994 20.585758900000034tag:blogger.com,1999:blog-2129587383257876818.post-61762673846376362672013-03-16T20:29:00.000+01:002013-03-21T08:56:38.439+01:00IR fjärrkontroll HackHär kommer en redogörelse för hur jag lyckades hacka mina IR-fjärrkontroller som tillsammans med de redan hackade <a href="http://gizmosnack.blogspot.se/2013/03/rf-fjarrstrombrytare-hack.html" target="_blank">RF-kontrollerna</a> tog mig ett steg närmare den ultimata nörd-fjärrkontrollen ;)<br />
<br />
Då jag nu hade tillgång till min logiska analysator var det svårare än att leta reda på de där gamla <a href="http://www.ebay.co.uk/sch/i.html?_nkw=ir+receiver+38khz&_sacat=0&_odkw=lg+optimus+one+hard+case&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">IR-mottagarna</a> som jag beställt nån gång för länge sen på ebay ;)<br />
<br />
<img height="148" src="http://i.ebayimg.com/t/5Pcs-IR-Receiver-Module-38-kHz-TSOP4838-DIP-3-mjL6-/00/s/NzMzWDk5MA==/z/yVwAAOxyyF5RSUo6/$T2eC16J,!yUE9s6NEGmuBRSUo6Yqpg~~60_57.JPG" width="200" /><br />
<br />
IR-mottagarna är världens simplaste grej! Mata med 5V på högra benet (framifrån), jord på mittenbenet, så kommer vänstra benet vara hög tills en IR-diod lyser på den (lr snarare blinkar på den i 38kHz), då går vänstra benet lågt tills blinkningarna slutar.<br />
<br />
Börja med att ställa in en kanal av den logiska analysatorn på 0 (den börjar spela in när kanalen jordas) och koppla in kanalens probe på vänstra benet av IR-mottagaren, och jord-proben på mitten. Nu är det bara att sikta en fjärrkontroll å skjuta några gånger! Då ser det ut så här:<br />
<br />
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdpWh1Cd6nuTiEKLIEUlR24tMAuxDPlGWTWaZ2PVf37WfeLMN5ojEOnO8FY7p0jNxI36p2iEZn7suY8zR-Bi2Ikbaw2fCah0TaefOOFBaxwZw1gmBB7f756tbOOBUdU19ktJQpBTj19VrL/s640/RF1.PNG" /><br />
<br />
Lite förstoring på en av signalerna, samt sampling från 3 olika knappar kan se ut så här:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_R5hhtaUJBg6V4SllsNVY6XMo2Db5y8jyvnqHsfDJZk1z5EEiH3rbWpZywcN1k3HzJ_cjau9aQWfTxrr6U-Z1Mc_vqQHD-uzpCyoHF-1v9zPJJAh-L2tHtU7jKpfpb7030-SsgJopOp4H/s1600/RF1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_R5hhtaUJBg6V4SllsNVY6XMo2Db5y8jyvnqHsfDJZk1z5EEiH3rbWpZywcN1k3HzJ_cjau9aQWfTxrr6U-Z1Mc_vqQHD-uzpCyoHF-1v9zPJJAh-L2tHtU7jKpfpb7030-SsgJopOp4H/s640/RF1.PNG" width="640" /></a></div>
<br />
Jag hade tyvärr ingen IR-diod liggandes hemma, så det blev till att offra en gammal fjärrkontroll som ändå inte användes för att kunna testa om jag verkligen lyckats...<br />
Tydligen ska man vara lite försiktig när man kopplar in IR-dioder, de flesta går på lägre än 5v, men den jag hade var 5v!<br />
Ett bra test man kan göra för att inte paja dioden man hittat är att ta upp mobilkameran och rikta den mot en vanlig fjärrkontroll medan man trycker på en av knapparna. En mobilkamera registrerar nämligen IR-ljus som lila-vitt ljus som då syns, lägg märke till hur starkt det är. Gör sedan samma sak med dioden du hittat när du kör ~1,5v, lyser den för lite så testa 3v, å annars se så den inte lyser för starkt på 5v!<br />
<br />
Om man kollar på signalerna ovan, så struntar mottagaren i att skicka ut 38 kHz, utan visar bara konstant jord om den tar emot en ljussigna, eller konstant 5v om den inte... för att mottagaren ska förstå IR-signalen måste koden använda s.k. "manchester encoding" som ser ut så här (timingarna är inte samma på min!):<br />
<br />
<img height="400" src="http://irq5.files.wordpress.com/2012/07/ir-modulations.png" width="242" /><br />
<br />
Nu till det lite kluriga, hur matar jag ut 38 kHz???<br />
Som i tidigare hacks så använder jag mig av en <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">Atmega88</a>, och det visade sig inte vara svårare än att köra vanliga _delay_us(); med 13us på och 13us av, eftersom 1/38000 ~=26us. Noggrannare än så behövdes tydligen inte (inte heller denna gång kör jag med extern kristall, å funkar klockrent ändå)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSxRVlIPTEnLdDxtwXzdeJKGxkXa7DWrNZ1A36x_YjpFmGdTlkHM7K-Le2ZXDdCTENPHVmSvZp4ULM5eokEJovmrFLkn9vrYm-WcfExOCvzQzu72JGRP3v_LhjaC6v4jiZtGlcsozFQsyI/s1600/RF1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSxRVlIPTEnLdDxtwXzdeJKGxkXa7DWrNZ1A36x_YjpFmGdTlkHM7K-Le2ZXDdCTENPHVmSvZp4ULM5eokEJovmrFLkn9vrYm-WcfExOCvzQzu72JGRP3v_LhjaC6v4jiZtGlcsozFQsyI/s1600/RF1.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Funktionen tar in en integer ("i") som bestämmer hur många gånger loopen ska köra, så längden på signalen = 26*i.<br />
<br />
Nu var det bara att sätta sig ner och spela in alla fjärrkontroller jag ville ha för att skapa mig ett bibliotek av simulerade knapptryckningar.<br />
<br />
Jag har länge stört mig på att vi inte har någon fjärrkontroll till stereon vi har i vardagsrummet som används när vi tittar på film på projektorn, sjukt drygt att resa sig upp å sätta på den eller att gå fram och sänka mm. Så när jag var klar med mitt IR-bibliotek så störde jag mig lite på att den saknades... chalange accepted!!<br />
<br />
Jag hade en gammal multifjärr hemma som hade en kod som faktiskt fungerade halvhyffsat på stereon. Dvs tryckte man på en konstig knapp så sattes radion på, och man kunde faktiskt sänka och höja med den, så jag utgick från inspelningarna jag hade av de knapparna (faktiskt de som syns i den inzoomade bilden en bit upp) så jag började med min analys:<br />
<br />
1. Självklart började jag med att försöka se ett mönster, och göra smarta gissningar för att hitta rätt kod... jag är ovanligt rik på tålamod, men gav rätt snabbt upp efter att ha sett att alla andra fjärrkontroller inte alls hade nån logik i sig.<br />
<br />
2. Nu återstår brutal force ;)<br />
<br />
3. Antar att alla signaler börjar med en hög (syns som låg på mottagaren). Det ger 26 höga/låga, vilket är 2^26 = 67108864 möjliga kombinationer aoooo ;(<br />
<br />
4. Nu till min revolutionerande upptäckt: tas första biten bort, kommer de ALLTID i antingen låg=>hög, eller hög=>låg, aldrig hög=>hög eller låg=>låg!<br />
<br />
Denna upptäckt ger 2^13 = 8192 möjliga kombinationer, vilket är en reducering med 99,987 % =) Har jag dessutom väldigt tur, så gissar jag rätt när jag antar att alla koder börjar på låg=>hög (efter startbiten och ur sändarens perspektiv), då alla tre hittills fungerande koder börjat så. Det skulle isf betyda 2^12 = 4096 olika kombinationer att testa för att hitta rätt =)<br />
<br />
Sagt och gjort, jag tillverkade (en mycket smart kod om jag får säga det själv) som loopade igenom de 8192 kombinationerna med 3s mellanrum (märkte rätt snabbt att om jag bara körde med ca 200ms mellanrum så reagerade inte stereon på de värden som de annars brukade (1066 = Vol-)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimXq51nwgj1krQeUaL_NPwKYVS4dfJTj65a8NVbPYGTZAInNhk4kXVBoOXTRNkOkn8gw7fHU-xuGlpAn3s3q-unHLo9G9Nap0dptGN5MbIDEuRfE3bL-xmejTcFwUTOuAjTSq3JTEnYUfD/s1600/RF1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimXq51nwgj1krQeUaL_NPwKYVS4dfJTj65a8NVbPYGTZAInNhk4kXVBoOXTRNkOkn8gw7fHU-xuGlpAn3s3q-unHLo9G9Nap0dptGN5MbIDEuRfE3bL-xmejTcFwUTOuAjTSq3JTEnYUfD/s1600/RF1.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1D1_F0ihMddek0JKi0FP8vAQcnQ1jlU74di5ydTAlC1lzP303eK3yp_y-Dxx5pN4IqPr1SiDefBuI0NXdSBLAgjneCGbqq7b9aEfs8H0rdRMW4fn8U3uymYqv00I_HqULd2HGqT7QH8nG/s1600/RF1.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1D1_F0ihMddek0JKi0FP8vAQcnQ1jlU74di5ydTAlC1lzP303eK3yp_y-Dxx5pN4IqPr1SiDefBuI0NXdSBLAgjneCGbqq7b9aEfs8H0rdRMW4fn8U3uymYqv00I_HqULd2HGqT7QH8nG/s1600/RF1.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Så de 8192 kombinationerna tog alltså ca 8192*3/3600 ~=6h, men då jag hade rätt med att allt fanns inom 4096, så tog det bara 3h! =) jag behövde ju inte vara så aktiv, mer än att hålla ett öga på när det hände något, och om det var det jag ville åt så kollade jag vad USARTen rapporterat till datorn! =)<br />
<br />
Nu när jag har ett komplett bibliotek med både RF och IR fjärrkontroller är det dags att börja tänka <a href="http://gizmosnack.blogspot.se/2013/03/varldens-nordigaste-multifjarrkontroll.html">multifjärrarnas multifjärrkontroll</a>!<br />
<br />
Om nån vill ha mer info, så skriv en kommentar! =)<br />
<br />Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com0Umeå, Sverige63.8258471 20.26303540000003563.7137861 19.940311900000037 63.937908099999994 20.585758900000034tag:blogger.com,1999:blog-2129587383257876818.post-59522738716741059872013-03-10T18:51:00.000+01:002014-02-15T10:38:02.636+01:00RF Fjärrströmbrytare HackHar kommit över ett gäng (~15-20st) fjärrströmbrytare med tillhörande fjärrkontroller. Strömbrytarna har länge legat i en låda för vem orkar ha 5 olika fjärrkontroller liggandes på bordet för att styra diverse lampor??<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.jula.se/mediaarchive/6138524/main/408050-jpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="http://www.jula.se/mediaarchive/6138524/main/408050-jpg.jpg" height="200" title="" width="200" /></a></div>
<br />
Jag har länge tänkt att jag ska försöka bygga en gemensam fjärrkontroll till dessa, och när jag nu äntligen fick lite energi att lägga på problemet uppstod vissa frågor:<br />
<br />
1) Hur lyssnar man av RF (radio freq.) 433MHz som det står på dem?<br />
2) Hur sänder man ut RF så att man kan simulera fjärrkontrollen?<br />
<br />
Vill du inte läsa om mitt <b>inte</b> så lyckade försök, hoppa då ner:<br />
<br />
**********************<b>Inte så lyckat försök</b>******************************************<br />
Då jag hållit på en hel del med AVR-programmering, har jag lärt mig använda en modell av RF Transceivers (transmitter och receiver i samma modul) som heter <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf24l01&_sacat=0&_odkw=atmega88+dip28&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">nRF24L01</a> och sänder datapacket på 2,4GHz-bandet, så tänkte jag att jag skulle kunna få användning av ett par <a href="http://www.ebay.co.uk/sch/i.html?_nkw=nrf905&_sacat=0&_odkw=nrf24l01&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">nRF905 </a>(433MHz) som jag faktiskt hade liggande 3st av hemma, då de fungerar på i stort sett samma kod som 24L01'orna (hur jag fick dem att funka blir ett annat inlägg när jag får tid...)<br />
<img src="http://www.marcmart.com/ebay/o/OT128/OT128-2m.jpg" height="200" width="200" /><br />
<br />
Jag tänkte att jag på nåt sätt kunde få 905'orna till att avlyssna luften efter RF-data!?<br />
Sagt och gjort (eller snarare försökt) så la jag ner nån timme på att sätta upp, först en trådlös länk mellan 2 905or... Än så länge gick det bra, jag kunde skicka ett paket data från datorn, via en <a href="http://www.ebay.co.uk/sch/i.html?_nkw=CP2102&_sacat=0&_odkw=usb+to+com&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">USB-COM adapter</a>, och en <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">Atmega88</a> till den ena nRF905, som i 433MHz-bandet trådlöst skickade det vidare till den andra 905'an, som tog emot datan, växlade till att bli tranceiver, och skickade tillbaka samma data som då visades på datorn.<br />
<br />
<img src="http://i.ebayimg.com/t/USB-2-0-to-TTL-UART-6PIN-Module-Serial-Converter-CP2102-STC-PRGMR-Free-cable-/00/s/NTAwWDUwMA==/$T2eC16ZHJHIE9nyseyg(BQTp)fSbq!~~60_12.JPG" height="200" width="200" /> <img src="http://i.ebayimg.com/t/1PCS-ATMEL-ATMEGA88-20PU-upgrade-ATMEGA88PA-PU-Microchip-8-bit-DIP28-/00/s/NDAwWDUwMA==/$T2eC16ZHJHEE9ny2sY6)BQS,2ciVPg~~60_12.JPG" height="160" width="200" /><br />
<br />
Nu tog det tvärstopp... nRFxxx har ett förprogrammerat chip som gör att man först måste skicka/lyssna efter ett antal adressbitar, som iof är programmerbara men går inte att skippa, innan den börjar mottaga datan...<br />
Jag gjorde några halvhjärtade försök att ställa in 905'an som receiver och endast använda 1 adressbyte följt av 32 datapacket-bytes, samtidigt som jag lät den andra skicka 1 adressbyte följt av 1 databyte, samtidigt som jag bombarderade receivern med fjärrkontrollen till strömbrytarna för att försöka få nåt utläst, men det sket sig och gav bara en massa dummy bytes...<br />
<br />
Nä nRFxxx är grymma på att skicka data på ett säkert och lätt sätt, men är inte gjorda för den här typen av avlyssningar..<br />
<br />
***********************<b>Lyckad metod</b>****************************************<br />
Jag vek mig och började googla och fick lite insperation av <a href="http://rezaalihussain.blogspot.se/2013/01/controlling-smart-outlet-with-arduino.html" target="_blank">denna </a>sida. Så jag beställde ett likadant kit med <a href="http://www.ebay.co.uk/sch/i.html?_nkw=433MHz&_sacat=0&_odkw=nrf905&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">en receiver och en transmitter</a> från ebay.<br />
<br />
<img src="http://i.ebayimg.com/t/433Mhz-RF-transmitter-and-receiver-link-kit-for-Arduino-ARM-MCU-WL-/00/s/MjQzWDI5OA==/$(KGrHqF,!qME88f7YGECBPW53+e7Y!~~60_35.JPG" height="163" width="200" /><br />
<br />
Problemet med hans metod var bara att han hade tillgång till en "Logic Analyzer", som inte jag hade (de kostar ~1200kr)...<br />
<br />
<img src="http://kdubois.net/img/saleae-la.jpg" height="155" width="400" /><br />
<br />
Skam den som ger sig, jag har ju AVR-chip! =)<br />
Jag byggde min egna logiska analysator genom att med en <a href="http://www.ebay.co.uk/sch/i.html?_nkw=atmega88+dip28&_sacat=0&_odkw=atmega88&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">Atmega88</a> koppla samman INT0, INT1 och mätpunkten. Aktiverade interruptet genom att sätta en på rising edge och den andra på falling edge... Med en enkel timer kunde jag sedan spara hur många mikrosekunder det var mellan varje upp, respektive nergång, som då lätt skickades till datorns USB via <a href="http://www.ebay.co.uk/sch/i.html?_nkw=CP2102&_sacat=0&_odkw=usb+to+com&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">USB-COM adapter</a>n.<br />
<br />
Jag hade såklart inte ro i kroppen att vänta in de 3-5v det kan ta för ebay-fynd att dyka upp i brevlådan, framför allt inte efter att ha läst <a href="http://www.instructables.com/id/USB-controlled-home-automation-hack/step4/Figure-out-whats-going-on-inside/" target="_blank">detta</a>...<br />
Efter att ha knäckt upp mina fjärrkontroller visade det sig att <a href="http://www.clasohlson.com/se/Fj%C3%A4rrstr%C3%B6mbrytare/Pr361860000" target="_blank">en av dem</a> hade en liknande fristående RF-modul som i länken:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPC8ZUblCQnWCT4SsSsDgD0tPlmtY9FRm9yyr026_PsKZrPOCIgZVfTUkByln6SPaf2I270vAo0RWw8Iaq5q9gJ3FPEa94MesOGsCFToeXepFNjbUhHpUH2n27AwLoIWiXQaWStsbB6spr/s1600/Klasskort05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPC8ZUblCQnWCT4SsSsDgD0tPlmtY9FRm9yyr026_PsKZrPOCIgZVfTUkByln6SPaf2I270vAo0RWw8Iaq5q9gJ3FPEa94MesOGsCFToeXepFNjbUhHpUH2n27AwLoIWiXQaWStsbB6spr/s640/Klasskort05.jpg" height="369" width="640" /></a></div>
Kabelstumparna till vänster är jord (vit) och data (orange) som jag lödde fast. Kablarna till höger kopplade jag på 12v för att batteriet var dött...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRtwh25z5y77cBZ2SztZLR7uvpQRM9irEncRmOssJklZ_ySs24b9SY5-iP2uM_fRKsy2z3uMaHq_lf1RrUAGiWMrVdkUKSm_LaN-ClWHJEKakzXLeg2WT7nCxisyW8UCTBucG1q6nkbxAM/s1600/Klasskort06.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRtwh25z5y77cBZ2SztZLR7uvpQRM9irEncRmOssJklZ_ySs24b9SY5-iP2uM_fRKsy2z3uMaHq_lf1RrUAGiWMrVdkUKSm_LaN-ClWHJEKakzXLeg2WT7nCxisyW8UCTBucG1q6nkbxAM/s400/Klasskort06.jpg" height="265" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
Här en bild på den separata RF-modulens baksida</div>
<br />
<br />
Jag kopplade in min hemgjorda logiska analysator och började logga när jag tryckte på knapp 1,2,3 osv... jag loggade 4ggr/knapp för att kunna se att det överensstämde och efter lite sammanställning i excel fick jag fram detta schema (över knapp 1on/off & 2on/off) som lätt går att se att det finns ett tydligt mönster i!<br />
(Fick inte plats, egentligen är det en lång bild med 4 rader...)<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVFAhJ74Rj7hCZRxG_6p05TPNelrfk-2IGUERMa8ZdBVlySKe9xBNmI-8WL7pkp6qZUtqVV5ypw5cRsopLexG-54UsnV1SF_Tqi4dVf69lMMtLBHj0ZIQ0eqV7pfQofZnnni9awo3ipCY4/s1600/RF1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVFAhJ74Rj7hCZRxG_6p05TPNelrfk-2IGUERMa8ZdBVlySKe9xBNmI-8WL7pkp6qZUtqVV5ypw5cRsopLexG-54UsnV1SF_Tqi4dVf69lMMtLBHj0ZIQ0eqV7pfQofZnnni9awo3ipCY4/s1600/RF1.PNG" /></a></div>
<br />
<br />
Å tro't eller ej, när jag istället för att lyssna på RF-modulens data-pinne, programmerade om Atmega88'an att skickade ut samma data, ja då kunde jag stänga av/sätta på mina fjärrströmbrytare på första försöket! Det händer ju aldrig annars att det funkar på första försöket! Jag använder inte ens en extern kristall för att få till timingarna exakt på Atmega88'an!<br />
<br />
Ska tilläggas att min hemmagjorda logiska analysator var lite flaky... det krävdes mer än ett försök att få till bra mätvärden, så jag blev mer och mer sugen på att införskaffa en vettig pryl, å efter lite sök på ebay hittade jag <a href="http://www.ebay.co.uk/sch/i.html?_nkw=CY7C68013A+%2B+board+-core&_sacat=0&_odkw=CY7C68013A+%2B+board&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">den här</a>, som efter att ha <a href="http://hanixdiy.blogspot.se/2011/03/cy7c68013a-usb-logic-analyzer.html" target="_blank">läst om den</a> verkade som ett trevligt alternativ för 75kr (ist för 1200kr), ett stycke beställdes tillsammans med <a href="http://www.ebay.co.uk/sch/i.html?_nkw=dupont+wire&_sacat=0&_odkw=dupont+vire&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">kablar </a>och <a href="http://www.ebay.co.uk/sch/i.html?_nkw=ic+probes+5&_sacat=0&_odkw=ic+probes&LH_BIN=1&_sop=15&_jgr=1&_fcid=192&gbr=1&_osacat=0&LH_PrefLoc=2&_sc=1" target="_blank">prober</a>. (Uppdaterad version för 64-bit datorer och som funkar med nyaste programvaran från Saleae <a href="http://www.ebay.co.uk/itm/New-USB-Logic-Analyzer-Device-Set-24MHz-8CH-/191036155696?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item2c7aa46730">Länk</a>)<br />
<br />
<img src="http://www.marcmart.com/ebay/o/OT272/OT272-1m.jpg" height="400" width="400" /> <img src="http://www18.tx8cdn.com/photo/eorder0612/201272014526851749.jpg" height="256" width="320" /><br />
<br />
Efter att ha sett hur den fristående RF-modulens data-pinne satt i förhållande till transistorn mm, så gjorde jag lite kvalificerade gissningar, och lyckades hitta var datan skickades (från chippet till RF-out) även på de andra fjärrkontrollerna. Efter lite piller-lödning lyckades jag sampla även deras data.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYzvpY1vMfqSTH4pZi5mqSuQjQtNzxhWHICpQcXmgw9ORXBuhCwUrPuWPny9RmZ6n0hi0jRvkdQTpG-Lc5PJE-Wq1666lGAahC4JO2Jo2RxYAYi1PnceUd4E2DFrPJiBbN5QURdnBcHxyi/s1600/Klasskort07.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYzvpY1vMfqSTH4pZi5mqSuQjQtNzxhWHICpQcXmgw9ORXBuhCwUrPuWPny9RmZ6n0hi0jRvkdQTpG-Lc5PJE-Wq1666lGAahC4JO2Jo2RxYAYi1PnceUd4E2DFrPJiBbN5QURdnBcHxyi/s640/Klasskort07.jpg" height="424" width="640" /></a></div>
Grön kabelstump är data där jag hittade data och brun ute till höger är jordningen.<br />
Denna kontroll (märke: Proov sys 2000) hade en knapp för att byta mellan 4 olika kontroller (de fyra svarta fälten till höger på bilden), och med 3 knappar/kontroll och då såg det ut såhär efter lite sammanställning:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj1-0ewDRgg2J9jTgVe0u9Rl-CgzURPIAWQocC1oVQKO1NUZ_0b7PpBydvF0jVDkoyoFfmO6gqk77Ipgzsb-hmr2VVHV3_dp-h0Z2vOwNn0b7mNBWgAeu1iurC0fUEMEvjmxO4dymac15Q/s1600/RF.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj1-0ewDRgg2J9jTgVe0u9Rl-CgzURPIAWQocC1oVQKO1NUZ_0b7PpBydvF0jVDkoyoFfmO6gqk77Ipgzsb-hmr2VVHV3_dp-h0Z2vOwNn0b7mNBWgAeu1iurC0fUEMEvjmxO4dymac15Q/s1600/RF.PNG" /></a></div>
<br />
Även dessa fick jag att fungera genom att programmera Atmega88'an och mata ut signalerna på den första fjärrkontrollens RF-modul (som fortfarande satt på kontrollen)! Den sista <a href="http://www.jula.se/fjarrstrombrytare-3-pack-408050" target="_blank">kontrollen </a>var från jula, och den kunde jag läsa av, men fick aldrig att fungera tills min logiska analysator från ebay dykte upp och det visade sig att det var delayen som inte riktigt stämde!<br />
<br />
Nu när jag äntligen hade listat ut vad som skickades, och hade t.o.m lyckats skicka datan via den första fjärrkontrollens rf-modul kunde det bara bli bättre! RF-modulen som jag beställt från ebay landade i brevlådan och fungerade även den out of the box! Skönt med tanke på att den separata RF-modulen från fjärrkontrollen krävde 12v som jag krånglade fram ur en 20v stor klumpig gamal skrivar-adapter...<br />
<br />
Även den logiska analysatorn damp ner i lådan och efter att ha letat igenom några av länkarna på ebay så hittade jag en som länkade till <a href="http://www.icstation.com/ebay/CY7C68013A.rar" target="_blank">programmet </a>(en äldre version av<a href="http://www.saleae.com/logic" target="_blank"> saleaes logic</a>, många mappnamn på kinesiska). Som <a href="http://hanixdiy.blogspot.se/2011/03/cy7c68013a-usb-logic-analyzer.html" target="_blank">bloggen </a>jag pratade om förut går igenom så funkar inte analysatorn med nyare versione, en bummer då den enda gamla versionen jag har fått tag på bara funkar med 32bitars operativsystem...<br />
<br />
Tog fram en äldre 32-bitars laptop, och där funkade allt perfekt! (installerade bara setuppen som i mappen "saleae") och behöll jumpern på! Försökte länge hitta en metod som får den att funka på 64 bitar, men då tror jag man måste byte EEPROM enligt <a href="http://sunbizhosting.co.uk/~spiral/blog/?p=117" target="_blank">detta hack</a>...<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdpWh1Cd6nuTiEKLIEUlR24tMAuxDPlGWTWaZ2PVf37WfeLMN5ojEOnO8FY7p0jNxI36p2iEZn7suY8zR-Bi2Ikbaw2fCah0TaefOOFBaxwZw1gmBB7f756tbOOBUdU19ktJQpBTj19VrL/s1600/RF1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdpWh1Cd6nuTiEKLIEUlR24tMAuxDPlGWTWaZ2PVf37WfeLMN5ojEOnO8FY7p0jNxI36p2iEZn7suY8zR-Bi2Ikbaw2fCah0TaefOOFBaxwZw1gmBB7f756tbOOBUdU19ktJQpBTj19VrL/s640/RF1.PNG" height="227" width="640" /></a></div>
Här är en bild på programmet när jag sniffar lite på en ir-fjärr (en vanlig TV-dosa).<br />
<br />
Gör inte samma misstag som jag, som råkade komma åt 12v-kabeln som driver RF-dosan jag har med en av proberna... som framgår av bilden ovan är alla prober som inte används höga (5V) förrutom ettan som är bränd och har gått låg! nu har jag bara en 7-kanals analysator, och det verkar som att kanalen "smittar av sig" till andra kanaler vilket den inte gjorde innan jag brände ettan... ;) kanske kan vara smart att göra som killen på hack-sidan ovan föreslår ändå:<br />
<br />
<img src="http://sunbizhosting.co.uk/~spiral/blog/wp-content/uploads/2012/01/Saleae-clamp.gif" height="193" width="320" /><br />
<br />
<br />
Skulle jag verkligen behöva 8 fräscha kanaler nån gång i framtiden får jag väl lägga ut 75 kr på en ny då... ;)<br />
<br />
När jag nu hade ett fullt fungerande RF-bibliotek till mina strömbrytare samt en logisk analysator tänkte jag att det var på tiden att bygga en ultranördig multifjärrkontroll (RF & IR) som styrs med android... kommer i <a href="http://gizmosnack.blogspot.se/2013/03/ir-fjarrkontroll-hack.html" target="_blank">nästa inlägg</a>!<br />
<br />
Om nån mot förmodan skulle läsa det här och vara intresserade av hur nåt av stegen gick till mer i detalj, så skriv en kommentar så ska jag förklara!Karl Hagströmhttp://www.blogger.com/profile/11528612014529851356noreply@blogger.com1Umeå, Sverige63.8258471 20.26303540000003563.7137861 19.940311900000037 63.937908099999994 20.585758900000034