tag:blogger.com,1999:blog-34628707588325743262024-03-08T06:32:21.033-05:00MakeatronicsNich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.comBlogger29125tag:blogger.com,1999:blog-3462870758832574326.post-76932960949121029512015-10-29T19:38:00.006-04:002015-10-29T19:38:56.732-04:00Recent Makeatronics Store PurchasesTo all those who have made a purchase since September 1st, I apologize for the radio silence on your order status. I am currently manufacturing boards and plan to ship by the end of the week.<br />
<br />
Because some of you have waited far longer than you should have had to, I will be offering a 75% reimbursement to any open orders placed before October 1st and and 40% to orders placed from Oct 1st through 17th.<br />
<br />
As for the future of the Makeatronics Store I am currently exploring alternative manufacturers. Production is outpacing what I can comfortably keep up with which is leaving me little to no time to devote to new development. I will continue or take orders until other arrangements are made.<br />
<br />
Again, I apologize for the lack of communication. Even with a busy schedule there's really no excuse for the lack of communication.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com4tag:blogger.com,1999:blog-3462870758832574326.post-5406263034122310652015-03-25T00:00:00.001-04:002015-03-25T00:00:08.135-04:00Smart BLDC Commutator AssemblyI added an option to the Smart BLDC Commutator in the Makeatronics Store. You can now order a fully assembled board! Hopefully this will be useful to those of you who would like a BLDC driver but don't want to get dirty with SMD soldering.<br />
<br />
More surface mount assemblies will be in the store in the coming weeks, so keep checking back.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com3tag:blogger.com,1999:blog-3462870758832574326.post-80138231199769330912015-01-02T22:35:00.003-05:002015-01-02T22:35:59.349-05:00New Year UpdateOk, so this page has been pretty quiet for a while now. I am in the middle of a huge house renovation project that has been taking a lot of my time, but I have had a few projects going in the background, so I'll give an update on those.<br />
<br />
First off, prices for the 24V AC SSR and Smart BLDC Commutator circuits have been reduced a little. Purchasing higher volumes of components has brought my price down and I wanted to pass those savings on to you. Also, I removed the "temporarily out of stock" note on the Smart BLDC board (d'oh!).<br />
<br />
The Wireless HVAC Sensor circuits now have a PCB + Components option. No assembly at this time, but that brings me to my next point.<br />
<br />
I have things in motion to resurrect my old reflow toaster oven to start offering full assemblies of the surface mount circuits. Solder paste stencils are on order and I've been rewiring the oven to be more permanent than its last incarnation. Along with that, I will be writing a blog post on how I converted my toaster oven and the control logic used.<br />
<br />
And since I will have a reflow oven I ordered prototypes of a SMD version of the popular 24V AC SSR board. This will hopefully offer even more savings on the assembled option once everything is up and running. Bare PCB and PCB + Component options will continue to ship as the through hole version.<br />
<br />
My 3D printer is still in progress. No major advancements in the last several months, but lots of sourcing parts and CAD modeling. It is my plan to have it finished before the end of 2015.<br />
<br />
I have some other ideas floating around in my head that I will start to tinker with as I have time available. Keep checking back for updates!Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com2tag:blogger.com,1999:blog-3462870758832574326.post-1053488317633480532014-09-30T16:16:00.001-04:002014-09-30T16:16:36.907-04:00Smart BLDC Commutator Back in StockGood news! The Smart BLDC Commutator is back in stock.<br />
<br />
Also, I am back from vacation and will resume shipping orders. All those who ordered from the Makeatronics Store in the past week will be receiving shipping notices tomorrow.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com3tag:blogger.com,1999:blog-3462870758832574326.post-18770364696828697542014-09-14T21:22:00.000-04:002014-09-14T21:22:46.137-04:00Makeatronics Store Stock and ShippingWow. The Smart BLDC Commutator board has been a hot item. My stock of PCB's has been depleted much faster than I anticipated. I placed an order for a while back, they are on their way with expected arrival in the first week of October.<br />
<br />
Also, I am going to be out of town and not shipping orders from Sept 18 - Oct 1. Any orders placed by end of day Tuesday (that are in stock, of course) will be shipped out before I leave. You can still place orders after that but they won't ship until Oct 2.<br />
<br />
Thanks everybody for your support!Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com1tag:blogger.com,1999:blog-3462870758832574326.post-34551417728720544272014-09-14T11:59:00.002-04:002014-09-14T12:24:42.576-04:00Wireless HVAC Sensors - V3 now availableAt last we have it. V3 of my wireless HVAC sensor board has been tested and the hardware is done. There were some tweaks to the board over <a href="http://makeatronics.blogspot.com/2014/07/wireless-hvac-sensors-part-2.html" target="_blank">V2</a>, one to fix a mis-routed trace and several geometric improvements to get it to fit inside an electrical box. And now all is well.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQi6kiw1-WCaHo6k46iF_H4S_-L0FLV-59ocPxUtBxiu8dRgyPGtVNdCTGMB6sXGTGDqPX1hFevIbQJCXifzifvlPEbRYytE9zJP4BpuQ_04d_sHPl8xKmCwcdewoosFrKieegwMvfDGNY/s1600/IMG_20140914_102002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQi6kiw1-WCaHo6k46iF_H4S_-L0FLV-59ocPxUtBxiu8dRgyPGtVNdCTGMB6sXGTGDqPX1hFevIbQJCXifzifvlPEbRYytE9zJP4BpuQ_04d_sHPl8xKmCwcdewoosFrKieegwMvfDGNY/s1600/IMG_20140914_102002.jpg" height="320" width="236" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3s0zhP23unzTh3bGbwBi4WIopLTmlHTN1XFslC6PQKzOSZZwLcyAJl_QZIlQvGfzFZ2kx-dL_CKaQQ8GjfOphdMVzF9xQiZ9eife1HxNdjKbkx4DQtoeCl8r2vI-YmFbYu_RbFwyrvc4H/s1600/IMG_20140914_101951.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3s0zhP23unzTh3bGbwBi4WIopLTmlHTN1XFslC6PQKzOSZZwLcyAJl_QZIlQvGfzFZ2kx-dL_CKaQQ8GjfOphdMVzF9xQiZ9eife1HxNdjKbkx4DQtoeCl8r2vI-YmFbYu_RbFwyrvc4H/s1600/IMG_20140914_101951.jpg" height="320" width="236" /></a></div>
<br />
<a name='more'></a>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLrCdvRxJe6sy7zAwK-basfRsmjCS7nyPTRc4bbBuB_c43eT6shPFakykBzsmt8otEzYEv8syoHoRI_1tS0ICXSw0uJNE0gjL7td7L2jPMeQcKJIfV3pEmD9Tx-PfgwC1FRpGAGn96cPxr/s1600/IMG_20140914_101754.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLrCdvRxJe6sy7zAwK-basfRsmjCS7nyPTRc4bbBuB_c43eT6shPFakykBzsmt8otEzYEv8syoHoRI_1tS0ICXSw0uJNE0gjL7td7L2jPMeQcKJIfV3pEmD9Tx-PfgwC1FRpGAGn96cPxr/s1600/IMG_20140914_101754.jpg" height="320" width="236" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJARzO4NXVUZMGpsAyS_JE5vS3Jj2WgaGCxVAlMVfZAfLS97O7oEKmQgPD930HMiHLl7IFjRFASscsIhrlTKiarXgf_Rb7h7WDT7vy2Q00RQWACJyHFJcnaJ3AKWBOhHuLhKAqdlOw_7d/s1600/IMG_20140914_101815.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJJARzO4NXVUZMGpsAyS_JE5vS3Jj2WgaGCxVAlMVfZAfLS97O7oEKmQgPD930HMiHLl7IFjRFASscsIhrlTKiarXgf_Rb7h7WDT7vy2Q00RQWACJyHFJcnaJ3AKWBOhHuLhKAqdlOw_7d/s1600/IMG_20140914_101815.jpg" height="320" width="236" /></a></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/AVvXsEjPe9avlzheGMvnwheJTcxumIUuiTNI7rNVyIS2evMzEjUFoe-Ek4STvtGdZvbmluJveIZEnN21lLJRoW-JmZbCTDDa0mWTiQfAKcf-i1Uu8HW7H0XaFseq6LOMkcT4ykRGXjtIFIN9cIes/s1600/IMG_20140914_101841.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPe9avlzheGMvnwheJTcxumIUuiTNI7rNVyIS2evMzEjUFoe-Ek4STvtGdZvbmluJveIZEnN21lLJRoW-JmZbCTDDa0mWTiQfAKcf-i1Uu8HW7H0XaFseq6LOMkcT4ykRGXjtIFIN9cIes/s1600/IMG_20140914_101841.jpg" height="320" width="236" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfnzGroBWWHEM1R82ZJhQPp18Wbkn0mIRSLncrikf59Vxhub3ddlt1tGW8M00eM1BglIlJqOh2PVTFxOf0xncj_f9gNiYBRFFiwi2WYg_iVaBZVJG3Y2TaEf2cG5TuzErOlkw-7m3r-RoU/s1600/IMG_20140914_101859.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfnzGroBWWHEM1R82ZJhQPp18Wbkn0mIRSLncrikf59Vxhub3ddlt1tGW8M00eM1BglIlJqOh2PVTFxOf0xncj_f9gNiYBRFFiwi2WYg_iVaBZVJG3Y2TaEf2cG5TuzErOlkw-7m3r-RoU/s1600/IMG_20140914_101859.jpg" height="320" width="236" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://raw.githubusercontent.com/fugalster/Wireless-HVAC-Sensors/master/schematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://raw.githubusercontent.com/fugalster/Wireless-HVAC-Sensors/master/schematic.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://raw.githubusercontent.com/fugalster/Wireless-HVAC-Sensors/master/board.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="137" src="https://raw.githubusercontent.com/fugalster/Wireless-HVAC-Sensors/master/board.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
As I said above, the hardware is done, meaning I don't have any (immediate) plans of changing the hardware. The software, on the other hand, is only functional and far from done. I'm hoping the community out there can help to make large improvements over what I've started. Here is a summary of what I've done with the software so far, though there's room for improvement on many of these:<br />
<ul>
<li>Software SPI interface to radio with hard coded register configurations</li>
<li>Communication with sensors</li>
<li>Breaking various sensor readings into several bytes ready for radio communication</li>
<li>Power off sensors when not in use</li>
<li>Power off radio when not in use</li>
<li>Monitor battery voltage and decide whether to turn off boost circuit (run on batteries directly when sleeping until battery voltage drops below brownout threshold, then keep boost circuit on)</li>
</ul>
<div>
<br /></div>
<div>
And here's a list of things I hope the software will include:</div>
<div>
<ul>
<li>uC sleep mode to save battery</li>
<li>User configurable radio settings (without software reflash)</li>
<li>User select of which sensors to read</li>
<li>User select of how often to transmit data</li>
</ul>
<div>
<br /></div>
</div>
I am putting the board on sale in the Makeatronics store. For now I am only selling the bare PCB (no components or assembly). You can get the bill of materials <a href="https://github.com/fugalster/Wireless-HVAC-Sensors/blob/master/BOM.csv" target="_blank">here</a>. Hopefully sometime in the next month or two I will start selling the components and assembly as well.<br />
<br />
The <a href="https://github.com/fugalster/Wireless-HVAC-Sensors" target="_blank">design files</a> are hosted on GitHub and are licenced under <a href="http://ohwr.org/cernohl" style="background-color: white; color: #777777; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.4799995422363px; text-decoration: none;" target="_blank">CERN OHL v.1.2</a><span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.4799995422363px;">.</span><br />
<span style="font-family: inherit;"><span style="background-color: white; line-height: 18.4799995422363px;">The <a href="https://github.com/fugalster/Wireless-HVAC-Sensors-Software/tree/master" target="_blank">software</a> is</span><span style="background-color: white; line-height: 18.4799995422363px;"> hosted on GitHub under the <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD 3 clause</a> license.</span></span>Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com4tag:blogger.com,1999:blog-3462870758832574326.post-40829406562988594482014-08-23T11:54:00.000-04:002014-08-23T11:56:34.754-04:003D Printer ProgressDespite the lack of posts on the subject, progress is slowly being made on my 3D printer. A few months ago I got the structure pretty well flushed out in CAD. As sized in the model, this allows for something more than a 12 inch diameter build area. The height of the build is limited by how long I want to make the drive axes, in this version I targeted 12 inches tall.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Rx7YUT-FWqloH2dQgWtmpCguCmdNR6SRPLl3hezPemm86ppMJXGQO7IEACc6tjo0GccbGLoannhMkVrf-OI3GAdjCBOurTK4VX04RpQzzVjVcOYa6FrBEr2wq_xBaP6UP7x7idIXAFTe/s1600/3dprinter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_Rx7YUT-FWqloH2dQgWtmpCguCmdNR6SRPLl3hezPemm86ppMJXGQO7IEACc6tjo0GccbGLoannhMkVrf-OI3GAdjCBOurTK4VX04RpQzzVjVcOYa6FrBEr2wq_xBaP6UP7x7idIXAFTe/s1600/3dprinter.png" width="400" /></a></div>
<br />
<a name='more'></a><br /><br />
As part of the <a href="http://makeatronics.blogspot.com/2014/08/smart-bldc-commutator-hardware.html">Smart BLDC Commutator</a> development I needed something to hold the hall sensor board in the correct position relative to the motor. With the CAD model far enough along I went ahead and had the motor mounting plate made by a friend with a CNC machine in his garage. You may recognize it from the videos I posted.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNvBjOJ33QQfFYc-itA2qfX4OnmcyvmGHp7r3z2WcFK75S8zQheS42r2SmPHCExmDVX-WLUve0haRhVS1ubJADNfm8bt5MVmYCDbtSVNaMSjDrPY79_yPHq1FdzTJY5dkTVsYmbPO6nbDs/s1600/IMG_20140501_224208.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNvBjOJ33QQfFYc-itA2qfX4OnmcyvmGHp7r3z2WcFK75S8zQheS42r2SmPHCExmDVX-WLUve0haRhVS1ubJADNfm8bt5MVmYCDbtSVNaMSjDrPY79_yPHq1FdzTJY5dkTVsYmbPO6nbDs/s1600/IMG_20140501_224208.jpg" width="400" /></a></div>
<br />
As I neared the end of the Smart BLDC Commutator development I started putting together a shortened version of the drive axes (shortened because it's cheaper and I want to work out all the bugs and make any unforseen design changes).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3b7HNB3TCDfnwYuTmLf5loNHqQwtEfR-WFjh9ezahq2bJXAVz6TGWZZNlP_0QHmniLw_YnnayDiL9I7xtgcqIHCAQKzlADVMIaKeGUt4MHrHQGde54b0q24FKzt6ehIdIlaxpMNpyrEKF/s1600/Clipboard01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3b7HNB3TCDfnwYuTmLf5loNHqQwtEfR-WFjh9ezahq2bJXAVz6TGWZZNlP_0QHmniLw_YnnayDiL9I7xtgcqIHCAQKzlADVMIaKeGUt4MHrHQGde54b0q24FKzt6ehIdIlaxpMNpyrEKF/s1600/Clipboard01.png" width="400" /></a></div>
<br />
I'm trying hard to keep the number of custom parts too a minimum, but there are a few that require machining. The two trapezoidal plates on either end, the black carriage in the middle (that piece could probably be 3D printed), the threaded rod has some modifications on either side, and the motor has a new drive shaft to extend out the bottom of the motor. I plan on releasing the mechanical drawings and CAD files for all these components, and depending on interest I may even try to find a source for them.<br />
<br />
The frame of the printer is made from extruded aluminum t-slot rails. I'm using the 80/20 brand because I already work with one of their vendors at my job. I was just going to buy a piece long enough for the one drive axes, but that didn't meet their minimum order amount, so I ordered a few of the other pieces, too.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1DGVYSXivEo7b-TSREx4mr8OWhKHN0DU4EEfRodEDQS3MKwNcv2t_Bywv1Kbr9pbGte1bTOvGMIZ8FqoX9lazog63HPwLQUXV1b39YwN8ssMGFKQEkx2SUnofVJdjMSKPDI4JzU9DpNiA/s1600/IMG_20140816_230821.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1DGVYSXivEo7b-TSREx4mr8OWhKHN0DU4EEfRodEDQS3MKwNcv2t_Bywv1Kbr9pbGte1bTOvGMIZ8FqoX9lazog63HPwLQUXV1b39YwN8ssMGFKQEkx2SUnofVJdjMSKPDI4JzU9DpNiA/s1600/IMG_20140816_230821.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ_blaXezyS56PtG4oeSW388RBsrhIcxeCLPs2KoEAXc672gzxEFjFVo-AeUvV5LZlwMBBEhNouL7Z3vqe__bFeNp8YMOyx8kXWwz2Z8jjemMZwhHimGX0Hgc5JLnVLtRTAmlLKWiBf-z_/s1600/IMG_20140816_230855.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ_blaXezyS56PtG4oeSW388RBsrhIcxeCLPs2KoEAXc672gzxEFjFVo-AeUvV5LZlwMBBEhNouL7Z3vqe__bFeNp8YMOyx8kXWwz2Z8jjemMZwhHimGX0Hgc5JLnVLtRTAmlLKWiBf-z_/s1600/IMG_20140816_230855.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcVOZZea0CwB-jSTumAgm3XGDLyruukvqQITo2_Ev2oiJ6n4VEOE8ZSbf_EpX6QlLhU3xx8R1XreJhszkNKxsuBsKy7aNUphxneGqs9yevriS0A68rK8DLoR1Oh2DpXl-2UI_PT1IX9sMh/s1600/IMG_20140816_230933.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcVOZZea0CwB-jSTumAgm3XGDLyruukvqQITo2_Ev2oiJ6n4VEOE8ZSbf_EpX6QlLhU3xx8R1XreJhszkNKxsuBsKy7aNUphxneGqs9yevriS0A68rK8DLoR1Oh2DpXl-2UI_PT1IX9sMh/s1600/IMG_20140816_230933.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
My next task is to work on the system identification of the drive axes, which in layman terms is getting an equation that approximates how the position responds to a given input to the motor. Once I have that I can start coding the closed loop controller and tweaking it to get the very best position accuracy I can. I'll start posting code and videos as I get it figured out..</div>
<br />Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com11tag:blogger.com,1999:blog-3462870758832574326.post-12731252123429989552014-08-18T21:26:00.001-04:002014-08-18T21:26:56.509-04:00Smart BLDC Commutator For SaleThe wait is over, the <a href="http://makeatronics.blogspot.com/2014/08/smart-bldc-commutator-hardware.html">Smart BLDC Commutator</a> is now available for purchase in the <a href="http://makeatronics.blogspot.com/p/store.html">Makeatronics Store</a>.<br />
<br />
Unlike my other boards so far, I am not (yet) offering this one as a complete assembly. It's all surface mount and takes too long for me to assemble them myself. I am working on getting a stencil made so I can reflow them in my hacked toaster oven.<br />
<br />
Thanks for checking in!Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com1tag:blogger.com,1999:blog-3462870758832574326.post-20584322136794554052014-08-08T23:19:00.004-04:002014-09-07T23:48:04.603-04:00Smart BLDC Commutator - Hardware<div class="separator" style="clear: both; text-align: center;">
</div>
Of all my circuits to date, the <a href="http://makeatronics.blogspot.com/2014/05/bldc-motor-control.html">Smart BLDC Commutator</a> is probably the one I'm most proud of. To those coming here for the first time, this board is for driving brushless DC (BLDC) motors. I spent a lot of time researching and prototyping to come up with this board. If you are trying to figure out how to drive a BLDC motor I think you will find the information below very helpful.<br />
<br />
From a high level, I wanted an interface to a BLDC motor that behaved much like a H-bridge does for a brushed DC motor. The result is a board that handles the heavy work of commutating of a BLDC motor using hall effect feedback. After hooking up power, motor wires and hall sensors, the minimal inputs required to the board are direction (high/low) and PWM. Everything else is taken care of to properly spin the motor. Pretty nifty.<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;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-1OpVsMlGWWp5kUXc3B999QmT4du3D88EzUwx4SJhZx__zqHjdJeu5LbrmQ45yCWhdK5KRLCh6Rl5G5Vs7TOuUQsAmSBhnESUysoMG-cGOtcZ3dGrdPCKGV5INSxzMZsPTH1_bOl73eoo/s1600/IMG_20140818_202834~2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-1OpVsMlGWWp5kUXc3B999QmT4du3D88EzUwx4SJhZx__zqHjdJeu5LbrmQ45yCWhdK5KRLCh6Rl5G5Vs7TOuUQsAmSBhnESUysoMG-cGOtcZ3dGrdPCKGV5INSxzMZsPTH1_bOl73eoo/s1600/IMG_20140818_202834~2.jpg" height="298" width="400" /></a></div>
<a name='more'></a><div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlpBXVUVXOTktf3rJp3BslC008SOC9jVGgHnLzjtZc3fFRVL5S5SZqAs1Z3luwp4ZHlHjD2n9L-LjGQe6U2PY46vtPRWlN60HqsxryrDbofWv6YokNsGTm89Y7KAxy6TtDdlTvjtOkFCm9/s1600/IMG_20140818_202858~2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlpBXVUVXOTktf3rJp3BslC008SOC9jVGgHnLzjtZc3fFRVL5S5SZqAs1Z3luwp4ZHlHjD2n9L-LjGQe6U2PY46vtPRWlN60HqsxryrDbofWv6YokNsGTm89Y7KAxy6TtDdlTvjtOkFCm9/s1600/IMG_20140818_202858~2.jpg" height="300" width="400" /></a></div>
<br />
The smart part of this board is that it can act as a SPI slave, keeping track of position of the motor via the hall effect sensors (using a 3-phase adaptation of <a href="http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html" target="_blank">this quadrature decoding method</a>), or optionally a quadrature encoder (breakout pins included). The SPI master can set a sample-and-hold pin high to tell the Smart BLDC Commutator to sample the current position and get it ready for communication over SPI. Then the master can initiate the SPI transfer at its leisure to read the position at the time the sample-and-hold pin was set. This is particularly useful for closed loop control on multiple motors so that each iteration through the control loop you can read the positions of the various motors at the same instant in time.<br />
<br />
Many people will probably ask why I don't offload the control loop itself to the Smart BLDC Commutator, transferring the desired position over SPI and letting the board do the rest. While I have build the board with that possibility in mind, there is a problem when trying to sync multiple motors. That problem is variations in clock speed between multiple Smart BLDC Commutator boards. In college I attempted to build a differential drive robot with a separate uC controlling each wheel and a master uC relaying position commands to them. Because one uC will inherently run ever so slightly faster than the other that means one wheel will spin ever so slightly faster. Therefore, instead of driving in a straight line the robot would drive along an arc. To fix the robot I had to disable on of the uC's and add a lot of magnet wire to get one uC controlling both wheels.<br />
<br />
Enough overview. Let's dig into the hardware.<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;">
<a href="https://raw.githubusercontent.com/fugalster/Smart-BLDC-Commutator-Hardware/master/SmartBLDC_sch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://raw.githubusercontent.com/fugalster/Smart-BLDC-Commutator-Hardware/master/SmartBLDC_sch.png" width="400" /></a></div>
<br />
At the heart of the Smart BLDC Commutator is an atmega328p uC, identical to the one found on the Arduino Uno. For easy compatibility with the Arduino IDE, I have a 16MHz external clock on board. A reset button is included because I've learned my lesson about not including them while repeatedly disconnecting and reconnecting power over and over again with reset buttonless designs. An LED lives on board for good measure, connected to an I/O pin to be fully configurable.<br />
<br />
Each of the three motor wires, lovingly called A, B, and C, are driven by discrete power MOSFETs: a high-side (P-channel) and low-side (N-channel). At any given time during active commutation there is exactly one high-side MOSFET and on low-side MOSFET conducting, but never both on the same motor wire (which would be a short to ground). Driving the gates of these MOSFETs are a collection of small N-channel MOSFETs and voltage dividers which are used to take the low voltage uC signals (3.3-5V) up to higher voltages required for the power MOSFETs (4-18V).<br />
<br />
Because the high-side MOSFETs are P-channel the gate voltage is referenced relative to the source (connected to VM). When the source-to-gate voltage is 0 (i.e. the gate voltage is at VM) then the MOSFET is non-conducting. when the source-to-gate voltage is enough negative (i.e. the gate voltage is less than VM) then the MOSFET is conducting. It is driven as follows: when the AH signal (C7) is low the MOSFET Q1 acts as an open switch. This effectively removes R4 from the picture and what's left is a 10k pull-up resistor R3. When the AH signal is high then Q1 acts as a closed switch to ground, introducing R4 back into the picture and creating a voltage divider to drive the gate of the A high-side MOSFET thus turning it on.<br />
<br />
The low-side MOSFETs are N-channel and behave more intuitively. The relevant voltage for N-channels is the gate-to-drain voltage and since the drain is connected to ground here then the gate-to-drain voltage is the same as the gate-to-ground voltage. To make the following description less awkward assume that the PWM value is a steady high signal (100% duty cycle), therefore the voltage at the gate of the small MOSFET Q6 (location C6) is the OPPOSITE of the AL signal (due to the NOT portion of the NAND gate). Now the low-side MOSFETs are driven as follows: when the signal on AL is low then Q6 is conducting, connecting the gate of the A low-side MOSFET to ground making it non-conducting. When AL is high then Q6 is like an open switch, so the A low-side gate gets pulled through R9 to the VGL voltage (set by the voltage divider made by R1 and R2) which makes the A low-side MOSFET conducting.<br />
<br />
Now a little about that NAND gate, the 4011B. One of my goals was to have a single PWM input to the Smart BLDC Commutator for power control to the motor. The PWM needs to be routed to each of the three motor wires. Instead of having the onboard uC attempt read PWM from the master and then commutate the motor with the same PWM, I routed the masters PWM to all three motor wires. I then ANDed the PWM with the commutated control signals. However, MOSFET driving circuit meant that a low on AL/BL/CL would result in the A/B/C low-side MOSFET conducting, and a high on AL/BL/CL would be non-conducting. This feels backward and is opposite the high-side MOSFETs and made it hard to keep track of what the code was doing. But changing the AND gate to a NAND gate reversed everything and made it all make sense.<br />
<br />
As for how all this gets power to the motor, suppose that the A high-side and B low-side MOSFETs are conducting--current will flow from VM (location D8), through the A high-side MOSFET (D7), out motor wire A and through the motor windings back through motor wire B, and then to ground through the B low-side MOSFET (G6) to complete its journey. As the motor turns and is detected by the hall sensors the uC updates which hi-side and which low-side MOSFETs get turned on, keeping the motor perpetually spinning.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmYi-3rHPUew2ggloQy-Gmcn8r4_0KCdDvGs2qSOQzDLeC_3Bd6xlSwlH0HI9k_lUsjXjSqLohA4MLwjzC1w_f9I7L8HrGITnkUfxN5NysUwlBmTlM76Z3W6qODWSXXOiQQjrB0hOuhbYh/s1600/bldc+commutating.gif" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS9DnlOaAalxESo7V78MCjw5HcgLoH2N-tqVKs2UAutu7pQ4CshKHZjE4qdzz7W6Q5PZ95bJbL2Kkc6y9-RDT9PwGciwFmQhLA9qSby0H7r_KHJoDgbEVp1HwklDYkbJRr4zyi6pPZOcZ2/s1600/bldc+commutating+01.3.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Click on image for animated version.</td></tr>
</tbody></table>
<br />
To set all the motor control signals (AH, AL, BH, etc.) I wanted to take advantage of port manipulation on the uC in order to quickly change all pins at once. To allow this I made sure that all the signals were connected to the same port on the uC, in this case port C (PC0-PC5). Now to set the signals all I have to do is write a 6-bit binary number to <span style="font-family: Courier New, Courier, monospace;">PORTC</span>. For example<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">PORTC = 0b001010;</span><br />
<br />
sets AH and BL signals high and all the others low.<br />
<br />
For the sample-and-hold and direction inputs from the master into the Smart BLDC Commutator, as well as the hall effect sensors, I wanted to use pin change interrupts for maximum speed and code efficiency, so likewise I ensured that all these signals were connected to a common port, in this case port D. In software I set up an interrupt handler to trigger when any one of the above pins changes, which updates the commutation phase and motor position.<br />
<br />
The <a href="https://github.com/fugalster/Smart-BLDC-Commutator-Hardware" target="_blank">design files</a> are hosted on GitHub and are licensed under <a href="http://ohwr.org/cernohl" target="_blank">CERN OHL v.1.2</a>.<br />
The <a href="https://github.com/fugalster/Smart-BLDC-Commutator" target="_blank">firmware</a> is also hosted on GitHub but under the BSD 3 clause license. The firmware will be discussed in detail in a coming post.<br />
<br />
Smart BLDC Commutator PCBs will soon be available in the <a href="http://makeatronics.blogspot.com/p/store.html">makeatronics store</a> for $15.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com40tag:blogger.com,1999:blog-3462870758832574326.post-90898802412820475772014-08-05T00:28:00.004-04:002014-08-05T00:33:17.260-04:00Scrap Yard<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">Check out the new <a href="http://makeatronics.blogspot.com/p/scrap-yard.html" target="_blank">Scrap Yard</a>!</span><br />
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;"><br /></span>
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">The process of making good designs often includes a few mistakes. Sometimes I'm lucky and get things working on the first try, but more often it takes two or three revisions to get it there. And since the PCB manufacturer I use has a minimum order quantity I end up with a fair amount of scrap.</span><br />
<br style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;" />
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">Rather than throwing them away, I've decided to sell the extra boards at discount price. It's up to you to get them working. I will provide details of fixes I have made to get them functional, just click on the images to be taken to the details.</span><br />
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;"><br /></span>
<span style="background-color: white; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">Obviously, I have a limited quantity of these boards. Once they are gone they will be deleted from the scrap yard never to return. Check back as often as you like, this page will be changing as I embark on new (and revisit old) projects. </span>Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com1tag:blogger.com,1999:blog-3462870758832574326.post-58793417286086207682014-08-04T12:40:00.002-04:002014-09-07T23:51:51.182-04:00Smart BLDC Commutator Coming SoonI recently received a small batch of Smart BLDC Commutator boards to verify V3 routing. I'm pleased to announce that it tested flawlessly. I made a few changes to the silkscreen, including some equations to the back side to help in using motors with voltages outside the current design limits, and placed an order for a larger batch.<br />
<br />
I expect boards to be in by the end of August 2014. After a quick overview to make sure all is well I will put them up for sale in the Makeatronics Store.<br />
<br />
Once I get some time I will write up a detailed post on the hardware changes and the firmware running on it. Until then, here's the schematic if anybody wants to benefit from my experimenting.<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;">
<a href="https://raw.githubusercontent.com/fugalster/Smart-BLDC-Commutator-Hardware/master/SmartBLDC_sch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://raw.githubusercontent.com/fugalster/Smart-BLDC-Commutator-Hardware/master/SmartBLDC_sch.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://raw.githubusercontent.com/fugalster/Smart-BLDC-Commutator-Hardware/master/SmartBLDC_brd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="233" src="https://raw.githubusercontent.com/fugalster/Smart-BLDC-Commutator-Hardware/master/SmartBLDC_brd.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://github.com/fugalster/Smart-BLDC-Commutator-Hardware" target="_blank">Design files</a> are hosted on GitHub and licensed under <a href="http://ohwr.org/cernohl" target="_blank">CERN OHL v.1.2</a>.</div>
<div class="separator" style="clear: both; text-align: left;">
<a href="https://github.com/fugalster/Smart-BLDC-Commutator" target="_blank">Firmware</a> is hosted on GitHub and licensed under the BSD 3 clause license.</div>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com0tag:blogger.com,1999:blog-3462870758832574326.post-44010933483281968252014-07-27T00:14:00.000-04:002014-08-05T00:32:10.567-04:00Wireless HVAC Sensors - Part 2Previously I introduced the idea of a <a href="http://makeatronics.blogspot.com/2013/10/wireless-hvac-sensors-temperature-and.html" target="_blank">battery operated wireless sensor board</a> for sensing temperature and humidity. The intent is to get information to my Raspberry Pi (or Arduino, or any other microcontroller) so that it can intelligently <a href="http://makeatronics.blogspot.com/2013/06/24v-ac-solid-state-relay-board.html" target="_blank">control the HVAC</a> system in my house. Today I give you an update on the project.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPbkOKJPjSpsIhXQFy446KRXzpTG1sKnzVM77TexH4NCwjRwcuZJTpZgeIaN2AA3oU1DTCnQw_ymSfG_JPr2vRVq9Xydh1B-OW3pBP6D3ANNFW_y_Tvp1I7IWiK-dDVB51JB31Z9qZ0Zrq/s1600/IMG_20140726_212807%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPbkOKJPjSpsIhXQFy446KRXzpTG1sKnzVM77TexH4NCwjRwcuZJTpZgeIaN2AA3oU1DTCnQw_ymSfG_JPr2vRVq9Xydh1B-OW3pBP6D3ANNFW_y_Tvp1I7IWiK-dDVB51JB31Z9qZ0Zrq/s1600/IMG_20140726_212807%257E2.jpg" height="400" width="177" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH6zJG7yFzjKINmCN9kzT86p9t3upT7HIa-GUGUvjj_y_WXtSvE8e0UWmOki6o_IA7jVbr8-w_1x4aUsh-qyZ1R2eP6QI1lZkvp3NjahGJ30frxta-TXRxGEFDJfcWacs9D5HNrQFZTQHd/s1600/IMG_20140726_212819%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH6zJG7yFzjKINmCN9kzT86p9t3upT7HIa-GUGUvjj_y_WXtSvE8e0UWmOki6o_IA7jVbr8-w_1x4aUsh-qyZ1R2eP6QI1lZkvp3NjahGJ30frxta-TXRxGEFDJfcWacs9D5HNrQFZTQHd/s1600/IMG_20140726_212819%257E2.jpg" height="400" width="172" /></a></div>
<br />
<div>
<a name='more'></a>To recap, what I wanted was a battery powered wireless sensor to communicate with my Raspberry Pi. In addition to all the regular good stuff (cheap, re-programable, etc.), I wanted the thing to be discrete and not just a bulk of electronics and wires sitting on a shelf or hung on the wall. So I designed it to fit in a standard electrical box behind a light switch face plate. And now we have V2.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMUcKkwIM_K66pKyEIP8tbeBUGkOo1wOsJxVwPwzG03c_rCroNEUYqkWr-1r-rByRHVp0yEJidXaA_PMGxDs75cHqFr57TNsuOIxr5Cr0m8ijkLITDoC717Rp4DdprPpyilfFCHwKiuI_3/s1600/IMG_20140726_212743%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMUcKkwIM_K66pKyEIP8tbeBUGkOo1wOsJxVwPwzG03c_rCroNEUYqkWr-1r-rByRHVp0yEJidXaA_PMGxDs75cHqFr57TNsuOIxr5Cr0m8ijkLITDoC717Rp4DdprPpyilfFCHwKiuI_3/s1600/IMG_20140726_212743%257E2.jpg" height="400" width="277" /></a></div>
<div>
<br /></div>
<div>
There were three main motivations behind this new version:</div>
<div>
<ul>
<li>Fix the numerous flaws in V1.</li>
<li>Increased battery life by going to two AAA batteries rather than a single button cell.</li>
<li>Better aesthetics in the face plate opening.</li>
</ul>
<div>
<br />
I won't beat around the bush. V1 was chock full of issues. There were traces in the wrong places connecting the wrong things, the analog output of the humidity sensor was unbuffered so reading the line changed the value, the battery life was not at all what I was hoping it would be (though I don't think I have sleep functions working properly yet), and if you studied what was visible through the light switch opening it was kind of messy.</div>
<div>
<br /></div>
<div>
So I fixed the routing in eagle... or so I thought. Turns out I had the SPI reset node hooked up to the wrong pin in the schematic. So I had to cut another trace and add another jumper wire to continue testing. I also made to board too wide where it mates with the electrical box. Such is life.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoJydAAVbb8-gSMl9ClXO4uom-84evJaLAdyyelFcwSfAFy8nPwi6qpXC-YX_7igmhU4EqymRPw3eSrUB0j3llGDLltd7PTzjuGS9jmnbHBGjihPfMpxMy3Ss0YCUbTT4DBI_A03Rf-GQi/s1600/IMG_20140726_212726%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoJydAAVbb8-gSMl9ClXO4uom-84evJaLAdyyelFcwSfAFy8nPwi6qpXC-YX_7igmhU4EqymRPw3eSrUB0j3llGDLltd7PTzjuGS9jmnbHBGjihPfMpxMy3Ss0YCUbTT4DBI_A03Rf-GQi/s1600/IMG_20140726_212726%257E2.jpg" height="400" width="255" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
</div>
</div>
<div>
But I did make and validate some improvements, so it wasn't a total loss. I added an additional sensor option. Now the user can choose between the accurate but pricey <a href="http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf" target="_blank">DS18B20</a> digital temperature sensor or the much cheaper analog <a href="http://www.analog.com/static/imported-files/data_sheets/TMP35_36_37.pdf" target="_blank">TMP36</a>. I also added a 2 channel op-amp to buffer the two analog sensors. </div>
<div>
<br /></div>
<div>
Why go through the trouble of an op-amp, you ask? Though it's not often thought about in the hobby world, it is important to guard the output of an analog sensor from the effects of reading it. The ADC (Analog to Digital Converter) pins on an Arduino, when activated, act like a ~50k pull-down resistor to ground. Many analog sensors have such a weak output that this pull-down can significantly change their reading. That means you probably have an inaccurate or maybe even bogus number if you didn't properly buffer the signal. Op-amps are great at buffering. When connected as a <a href="http://en.wikipedia.org/wiki/Operational_amplifier_applications#Voltage_follower_.28unity_buffer_amplifier.29" target="_blank">voltage follower</a> they appear as an open circuit to the sensor (nothing pulling on it one direction or the other) while the op-amp can draw from its own power supply to hold the output at the level of what's on the input. I hooked the outputs of the <a href="http://sensing.honeywell.com/honeywell-sensing-hih5030-5031%20series-product-sheet-009050-2-en.pdf?name=HIH-5030-001" target="_blank">HIH-5030</a> humidity sensor and the TMP36 temperature sensor to the two channels of the op-amp and came out with properly buffered signals that the micro can read with no worries. </div>
<div>
<br /></div>
<div>
I also put in a few solder jumpers to close when either of the analog sensors are left off the board. This is done to prevent the input to the op-amp from floating, which would most likely result in wild oscillations of the op-amp output, drawing more power than it would otherwise (bad for a battery operated design). From the datasheet I also read that the op-amp uses the least power when it's output is halfway between the power lines, so I connected the opposite side of the jumpers to some areas that remain more or less at one half of 3.3v.</div>
<div>
<br /></div>
<div>
As for battery life, the button cell battery of V1 only lasted a few days. I'm pretty sure that I didn't have the sleep modes on the attiny working properly and that's the number one cause of the battery life fail. But I also learned something about the <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/22234B.pdf" target="_blank">MCP1640</a> boost converter. Its job is to take the input voltage (from the battery, 1.5v per cell for alkaline batteries) and boost it up to a higher voltage (3.3v in this design). It does so with the help of an inductor and capacitor and switching the inductor on and off at a resonant frequency. While the MCP1640 is perfectly capable of stepping the voltage up from 1.5v to 3.3v (it's can start with as low as 0.65v on the input), efficiency degrades with lower input voltages. Going with two batteries in series means a nominal 3v on the input. That's a lot less of a step up to 3.3v allowing the MCP1640 to operate in a more efficient region, improving battery life. Also, AAA batteries have such a large capacity compared to the button cell I was using on V1. I'm talking 8x more capacity. That, combined with (hopefully) figuring out sleep mode and the improved efficiency of the MCP1640 should mean a good while between battery changes.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaHIO_d-uzH1kZ8BiVkO0swd0hQyDj_MAbvddZ53Yjq8UnIEDA1QrUU4GrB0_WRdhBFPTmoJcE0ovpZE7DKIHW0riqdtcDR3NWKCIoVow32BdLk01DAajMMs8U-8NRdJtIfZinB3VlPW73/s1600/IMG_20140726_212620%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaHIO_d-uzH1kZ8BiVkO0swd0hQyDj_MAbvddZ53Yjq8UnIEDA1QrUU4GrB0_WRdhBFPTmoJcE0ovpZE7DKIHW0riqdtcDR3NWKCIoVow32BdLk01DAajMMs8U-8NRdJtIfZinB3VlPW73/s1600/IMG_20140726_212620%257E2.jpg" height="400" width="300" /></a></div>
<br /></div>
<div>
Of course there were good features from V1 that are unchanged on V2 and are worth mentioning again:</div>
<div>
<ul>
<li>Each of the sensors (and now the op-amp) are powered from a digital output of the attiny. That means that the sensors can be powered down when not in use. </li>
<li>The battery (pre boost converter) is connected to an analog input so the attiny can monitor battery level and send a warning when they are getting close to dying.</li>
</ul>
<div>
For those interested, see below for the schematic of the design (V2 errors corrected). I'm working on cleaning up the board design as I have time. Hopefully I'll be ordering V3 boards soon, and hopefully they will be the final version.</div>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvnotCmYqktb1XEaGnnvXhyphenhyphenPp8SG25e5fTcKWT9u3ihWzl47YMYLGd9Am5J1nAwSQ61KgclJCriq2ouc_GYSQPGPdEXTwRWHHERBw5aYS40hq7ev24GhcUoc2GFuYi_pu6zgVhsG49j3wo/s1600/Schematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvnotCmYqktb1XEaGnnvXhyphenhyphenPp8SG25e5fTcKWT9u3ihWzl47YMYLGd9Am5J1nAwSQ61KgclJCriq2ouc_GYSQPGPdEXTwRWHHERBw5aYS40hq7ev24GhcUoc2GFuYi_pu6zgVhsG49j3wo/s1600/Schematic.png" height="450" width="600" /></a></div>
<div>
<br />
<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7D9eOdQtWDOtcA0RwQwqiGQfmYkOGuHPgsIdvFOcuoP0L3ZpTmqe_mDizqxt7n7qrZEAJQamlW57ET32tYsvW_SYwOHnqnqBIxqyKSKzpC3R-xY7CGqZsIC82IXVM2tLAJdeXhJz7OZhN/s1600/IMG_20140726_212637%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7D9eOdQtWDOtcA0RwQwqiGQfmYkOGuHPgsIdvFOcuoP0L3ZpTmqe_mDizqxt7n7qrZEAJQamlW57ET32tYsvW_SYwOHnqnqBIxqyKSKzpC3R-xY7CGqZsIC82IXVM2tLAJdeXhJz7OZhN/s1600/IMG_20140726_212637%257E2.jpg" height="400" width="163" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq_w-XAGaT1qJ_QlNkPHxUBCWGAlm1F058hDP7Jagh_fhbgy-HM3HZt2vt2f1mNSJ_EXMF8IBLM-GBt9ciuaYP0pnGgH-sCef8mZee0zCDofO3Gge5a2RDaDjgEKHqFlgQcA14-T4Mlous/s1600/IMG_20140726_212650%257E2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq_w-XAGaT1qJ_QlNkPHxUBCWGAlm1F058hDP7Jagh_fhbgy-HM3HZt2vt2f1mNSJ_EXMF8IBLM-GBt9ciuaYP0pnGgH-sCef8mZee0zCDofO3Gge5a2RDaDjgEKHqFlgQcA14-T4Mlous/s1600/IMG_20140726_212650%257E2.jpg" height="400" width="290" /></a></div>
</div>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com10tag:blogger.com,1999:blog-3462870758832574326.post-67224618679658644572014-05-18T15:37:00.000-04:002014-05-18T21:38:06.385-04:00Makeatronics Store Now OnlineUp to this point all products I've put up for sale have been so only through the blog post that described them. This quickly got confusing and cumbersome as I've slowly finished more projects and released them for sale. Now I've built a simple store to host everything. Blog posts where things used to be for sale have been updated to point to the store.<br />
<br />
Up to now I have only offered a few bare PCB's for sale. I am now offering the PCB's with loose components and fully assembled products. As time goes on I hope to also have mechanical items available (think 3D printer parts) plus who knows what else.<br />
<br />
If you like the projects you see on this blog the best way to support is to make a purchase in the store. Funds received through sales have a direct impact on the time and money I can spend on new and exciting projects.<br />
<br />
Without further adieu, follow this link to the store:<br />
<a href="http://makeatronics.blogspot.com/p/store.html" target="_blank">makeatronics.blogspot.com/p/store.html</a>Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com0tag:blogger.com,1999:blog-3462870758832574326.post-50104091498306781792014-05-04T22:54:00.001-04:002015-06-22T20:58:07.788-04:00BLDC Hall Effect SensorsSo I've had <a href="http://makeatronics.blogspot.com/2014/01/3d-printer-motor-control-part-1.html">two</a> <a href="http://makeatronics.blogspot.com/2014/05/bldc-motor-control.html">posts</a> now where I talk about adding hall effect sensors to a BLDC motor. I figure it's time to explain a bit more how the process works.<br />
<br />
This method only works with an outrunner style motor (that is, the rotor spins around the outside of the stator) with the magnets exposed on the underside of the rotor, such as this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.rctecnic.com/1341-thickbox_default/motor-brushless-emax-cf2822-combo-2-outrunner.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="http://www.rctecnic.com/1341-thickbox_default/motor-brushless-emax-cf2822-combo-2-outrunner.jpg" height="320" title="Image source: http://www.rctecnic.com/1341-thickbox_default/motor-brushless-emax-cf2822-combo-2-outrunner.jpg" width="320" /></a></div>
<br />
<a name='more'></a><br />
<br />
It involves designing a custom PCB to hold the hall sensors at the proper spacing/curvature, and some sort of mounting holes. Along with the mounting holes you need to make sure there is the ability to rotate the sensors with respect to the stator to adjust timing correctly. I've done this on two motors now and took slightly different approaches with timing adjustment on each. The first one I did was an EMAX CF2822 motor (above). That red flange at the base can be rotated with respect to the stator, so the sensor PCB bolted directly to the flange and I could adjust timing by rotating the flange.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk2e8bbsMtATm1mtOacVG1hU75x6XVSLJ8b4SW_zEkNcbiEB2tM-Y6c_uhYVTaui2Dx5kSxUEASJXJy5jpoDrE4u1egY_EWXghDk1Va1BJxdxursxsOErYT0vPfxx9LYS2bftfcjwDoQfY/s1600/IMG_20140112_174213.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk2e8bbsMtATm1mtOacVG1hU75x6XVSLJ8b4SW_zEkNcbiEB2tM-Y6c_uhYVTaui2Dx5kSxUEASJXJy5jpoDrE4u1egY_EWXghDk1Va1BJxdxursxsOErYT0vPfxx9LYS2bftfcjwDoQfY/s1600/IMG_20140112_174213.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihvpOr1NXTHSJ1DsHfHNS957DjEuXytJJfc6Col0UScwChEWHvQpjwjQiifJgTGSFrijwfs4oZ5C9xF3J1OdQmTz-iNKJiM6ML-hrZ9X3vxINEggiIF9QFZS5l94SOXbtE0kp8i2Gg-qqu/s1600/IMG_20140112_174312.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihvpOr1NXTHSJ1DsHfHNS957DjEuXytJJfc6Col0UScwChEWHvQpjwjQiifJgTGSFrijwfs4oZ5C9xF3J1OdQmTz-iNKJiM6ML-hrZ9X3vxINEggiIF9QFZS5l94SOXbtE0kp8i2Gg-qqu/s1600/IMG_20140112_174312.jpg" width="320" /></a></div>
<br />
The next motor was a Turnigy Multistar 4822. It didn't have anywhere on the motor I could mount to, so I had to include mounting features on the plate that the motor was going to be mounted to.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjXW4vYapGOSXpZ11CdQ4zey9DGRHuoxTv885UAeDnJVCii2BVsEsjFcbuQnAV6vCHpw2eSmY56f9jpxGK8W9xlItQtgvh6syX5JqYz3r41hUsS3gM93dV360Y0dgoBL1cD9soKsBp47wq/s1600/IMG_20140501_224353.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjXW4vYapGOSXpZ11CdQ4zey9DGRHuoxTv885UAeDnJVCii2BVsEsjFcbuQnAV6vCHpw2eSmY56f9jpxGK8W9xlItQtgvh6syX5JqYz3r41hUsS3gM93dV360Y0dgoBL1cD9soKsBp47wq/s1600/IMG_20140501_224353.jpg" width="240" /></a></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/AVvXsEhqClWaMk5JKvB66BX1Qw3SBNAzdj2IQZ6F_GbQocirXO7mc90Al715Qwqh_lPesP8lfbbWT7mTB6jUEzqmw5CHVFYGjbm7MA5MM_4CQcc8OE3f_2SQaCytEzi5bBSOeiy2yzPXjrekUWKA/s1600/IMG_20140501_224208.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqClWaMk5JKvB66BX1Qw3SBNAzdj2IQZ6F_GbQocirXO7mc90Al715Qwqh_lPesP8lfbbWT7mTB6jUEzqmw5CHVFYGjbm7MA5MM_4CQcc8OE3f_2SQaCytEzi5bBSOeiy2yzPXjrekUWKA/s1600/IMG_20140501_224208.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
These PCB's are simple, small, and cheap (less than $2 each). Since they are so cheap I can afford to splurge on the hall sensors and get top of the line Honeywell SS360's at $1.44 each from <a href="http://www.digikey.com/product-detail/en/SS360NT/480-5410-1-ND/3306007" target="_blank">Digi-Key</a>. The sensor board requires 5 connection points: power, ground, and 3 hall sensors. Pull-up resistors need to be included somewhere in the circuit, I like using the internal pull-up resistors in the atmega microcontroller. Good PCB practice also dictates that you include a ~0.1uF decoupling ceramic capacitor between Vcc and GND.<br />
<br />
The hardest part about this whole thing is getting the sensors in the correct position. You will need to know the middle diameter of the magnets which requires either having the motor on hand to measure or a detailed drawing of the motor. You also need to know the number of magnets (sometimes called poles) or pole pairs (half of the number poles). From the pole pairs you can calculate the angular spacing between the sensors with the equation<br />
<br />
360 deg / (3*pole pairs)<br />
<br />
In the case of the Turnigy Multistar 4822, which is a 22 pole motor<br />
<br />
360 deg / (3*11) = 10.909<span style="color: #545454;"><span style="background-color: white; line-height: 18.200000762939453px;"> deg</span></span><br />
<br />
This is how far each sensor is rotated around the center of the mounting circle from its neighbor. From here it's just a game of sines and cosines and the mounting diameter to calculate the coordinates of each sensor to place them on the board. The amount of adjustment you need for timing to guarantee you can get the sensors lined up properly should be at minimum the same number of degrees that the sensors are spaced at.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_HWizKIc_9zVCodgIvSvy4OvA3K1een-u2wutgbRxlSF9_rUovCU6AsfPynriUP8KPOwt0Bxtnb-AFlpGqk7uJpd0MbxD1qiJLCOWXsKkucsa1Pr6z-WuaWPvnjxywBeyxdfvTCeIZVWH/s1600/hallsensors.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="308" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_HWizKIc_9zVCodgIvSvy4OvA3K1een-u2wutgbRxlSF9_rUovCU6AsfPynriUP8KPOwt0Bxtnb-AFlpGqk7uJpd0MbxD1qiJLCOWXsKkucsa1Pr6z-WuaWPvnjxywBeyxdfvTCeIZVWH/s640/hallsensors.png" width="640" /></a></div>
<br />
Hopefully this is all the information you need to design your own hall effect sensor PCB for your motor. If your motor happens to be one of the two featured in this post, you are welcome to use my designs <a href="https://drive.google.com/file/d/0B9DuE3f5Cnm7NWk1Q0VFYTJnTW8/edit?usp=sharing" target="_blank">here</a> and <a href="https://drive.google.com/file/d/0B9DuE3f5Cnm7c0trNmJEb1hXMFU/edit?usp=sharing" target="_blank">here</a>. You can even order them straight from OSH Park <a href="http://oshpark.com/shared_projects/quxtpvHN" target="_blank">here</a> and <a href="http://oshpark.com/shared_projects/JIbWEGJh" target="_blank">here</a>. If you want help designing your own feel free to email me and I'm sure we can work out a deal.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com5tag:blogger.com,1999:blog-3462870758832574326.post-25419689541631103702014-05-04T00:25:00.000-04:002014-08-12T22:02:48.610-04:00BLDC Motor ControlAs part of my <a href="http://makeatronics.blogspot.com/2013/08/building-3d-printer.html">3D printer project</a>, one of the big electronics hurdles to overcome was a motor controller for a BLDC (BrushLess Direct Current) motor. Searching for a cheap, off the shelf controllers that would interface easily with a microcontroller turned up fruitless, so I took the opportunity to design my own circuit. It was a major project in itself, and while there's still a few hardware tweaks to make I'm quite happy with how it has turned out.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRue8sz03gsY0rNRGjt5nk0yRqf3sB0iFgHzPdI4Rc96JUyU3FZRqu5QsB3eHvGj2eXFNiGhvy-ZyH7-Q8BkVkrffFZVC8qF45W2OuuPngz8LTHeNtWywL3ncOH_barxUPn9g2Q5NK5sxL/s1600/IMG_20140222_152040.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRue8sz03gsY0rNRGjt5nk0yRqf3sB0iFgHzPdI4Rc96JUyU3FZRqu5QsB3eHvGj2eXFNiGhvy-ZyH7-Q8BkVkrffFZVC8qF45W2OuuPngz8LTHeNtWywL3ncOH_barxUPn9g2Q5NK5sxL/s1600/IMG_20140222_152040.jpg" height="275" width="400" /></a></div>
<br />
<a name='more'></a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU8lt5QqcB_g0MA8ch_werzL9WNXUNi9q1BgfB9zEPmfR0kh1-KQ7P5CR0VpfUJ3eIWwQbuB1cOZhtIODLtd8Fznd_8ZkoLEcI_Iy-JUqoCmhkMR_6YQwTWsHZ82IJEsl4bAMxHj6WF4hX/s1600/IMG_20140222_152106.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU8lt5QqcB_g0MA8ch_werzL9WNXUNi9q1BgfB9zEPmfR0kh1-KQ7P5CR0VpfUJ3eIWwQbuB1cOZhtIODLtd8Fznd_8ZkoLEcI_Iy-JUqoCmhkMR_6YQwTWsHZ82IJEsl4bAMxHj6WF4hX/s1600/IMG_20140222_152106.jpg" height="363" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Before starting any project it always goes smoother when you take the time to clearly define the features/requirements. After a lot of thought and conversations with others, I came up with the following list of features:<br />
<ul>
<li>A single input for motor direction</li>
<li>A single input for PWM (motor speed/torque)</li>
<li>Commutate the motor windings based on <a href="http://makeatronics.blogspot.com/2014/05/bldc-hall-effect-sensors.html">hall sensor feedback</a></li>
<li>Keep track of position through hall sensor feedback and communicate position to external microcontroller</li>
<li>Inputs for optional quadrature encoder</li>
<li>A "sample and hold" input to save the position at an instant in time into a buffer (for synchronizing multiple motors/controllers)</li>
<li>Some kind of communication protocol to communicate with external microcontroller</li>
<li>Works with 3.3v or 5v control circuitry and 8-36v motor power</li>
<li>As fast as possible using pin change interrupts and hardware communication</li>
</ul>
<div>
At the heart of this control board is an atmega328p microcontroller running at 16MHz, the same as used on the Arduino Uno, and programming is accomplished via an external ISP programmer. I played around with the idea of using a smaller/cheaper microcontroller, but after including all the features above I ended up using all but 3 of the available pins on the 328. Plus, going with the standard Arduino chip has the benefit of familiarity for me and many others.<br />
<br /></div>
<h3>
Direction and PWM Inputs</h3>
A necessary part of any DC motor is that the current direction through the windings alternates as the motor rotates (commutation). The way a typical (brushed) DC motor handles this requirement is via brushes riding on a split ring on the shaft of the motor.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://humanoids.dem.ist.utl.pt/Images/servo/dcmotor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="http://humanoids.dem.ist.utl.pt/Images/servo/dcmotor.jpg" height="257" title="Image source: http://humanoids.dem.ist.utl.pt/Images/servo/dcmotor.jpg" width="320" /></a></div>
<br />
This design makes controlling the motor very easy. Simply apply voltage to the two wires and the motor spins. If you reverse the two wires the motor direction reverses. Then for speed control you add PWM to the motor power.<br />
<br />
A BLDC motor has no brushes (by definition) and no split ring to do the commutating. Instead, the commutating is controlled by some kind of logic circuit. This circuit must know the position of the magnets relative to the windings in order to commutate correctly. Also, the majority of BLDC motors have 3 wires coming out of them (3 phase = 3 sets of windings in the motor). Voltage is applied across only 2 of the wires at any given time. Which 2 wires and the polarity of the voltage across them is always changing as the motor rotates. It is the job of the control circuit to do this correctly.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.datasheetdir.com/circuits/7/Sensorless-Regulation-Of-Brushless-Dc-Motor-With-C164cm-Voltage-Detection-Mode.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="http://www.datasheetdir.com/circuits/7/Sensorless-Regulation-Of-Brushless-Dc-Motor-With-C164cm-Voltage-Detection-Mode.jpg" height="166" title="Image source: http://www.datasheetdir.com/circuits/7/Sensorless-Regulation-Of-Brushless-Dc-Motor-With-C164cm-Voltage-Detection-Mode.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In the image above you can see that there are a total of 6 switches (3 phases * 2 polarities), and for this instant in time voltage is applied across coil A (positive) and coil B (negative). Replace the switches with MOSFETs and you have a basic driver circuit. To get variable speed control you would switch the MOSFETs on and off with a PWM signal at the gate. A total of 3 PWM signals are needed (only one for each coil), the other 3 MOSFETs are plain on or off.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For my control board I wanted to have a single PWM input from an external microcontroller control all 3 coils. I accomplished this with some AND gates on board. The control circuit would set the 6 pins for the 6 MOSFETs, 3 of them are routed into one side of the AND gates (separate AND for each of the 3) and the PWM into the other side of the AND. The outputs from the AND gates are PWM modulated versions of what the control circuit is providing, and these signals are then routed to the MOSFETs.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The direction of the motor is handled by an input pin from an external microcontroller (or switch) to the control circuit. The on-board software then takes care of changing the control signals to reverse the motor.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The choice to have the PWM and direction be inputs from an external source was to keep the control board as close as possible to the way you would drive a typical DC motor. Of course, with a change in software these things could be handled from the control board itself.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h3>
Hall Sensor Feedback for Commutation and Position</h3>
<div>
As far as I know there are 3 ways to commutate a BLDC motor: manually at a given rate, sensing the back EMF in the unpowerd coil to deduce rotor position, and sensing the rotor position with hall effect sensors.<br />
<br />
Manually commutating at a given speed is basically the same idea as controlling a stepper motor, but is usually frowned upon in BLDC motors. One of the reasons is that it wastes a lot of energy because the winding resistance of a BLDC motor is a lot less than a stepper motor, so a lot more current flows, generating excess head in the motor and the MOSFETs.<br />
<br />
Sensing back EMF is usually what ESC controllers do. They are more complicated with the added sensing hardware, but allow the motors to be cheaper since they don't have to come with sensors built in. They also have the advantage of being able to adjust the motors timing on the fly. This kind of control is good for controlling the speed of the motor at high spin speeds, but is not a good solution for low speed/high torque applications. This control board does not have the necessary hardware built in to run in this mode.<br />
<br />
Hall sensors are generally more expensive and the motor timing is hard set, but they give good low speed performance. This is the intended operating mode for my control board. There are many good articles available on the internet that explain how to commutate the motor once you have feedback from the sensors. I'll leave the explanation to those other sources and present here only this handy diagram that shows the polarity of each of the 3 motor phases with respect to the hall sensor feedback (referred to as switches in the image).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.groschopp.com/wp-content/uploads/BLDC-Timing-Diagram-for-Hall-Switches.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="http://www.groschopp.com/wp-content/uploads/BLDC-Timing-Diagram-for-Hall-Switches.jpg" height="396" title="Image source: http://www.groschopp.com/wp-content/uploads/BLDC-Timing-Diagram-for-Hall-Switches.jpg" width="400" /></a></div>
<br />
Turns out that finding motors with integrated sensors is hard to do unless you're looking for industrial sized motors. There are a few intended for RC cars, but they have a low pole count and are not suitable for precise positioning. In lieu of finding good sensored motors, I decided to add sensors to my own motor. Turns out adding sensors to an outrunner BLDC is pretty straight forward (see my blog post <a href="http://makeatronics.blogspot.com/2014/01/3d-printer-motor-control-part-1.html">here</a> for more info). Plug these sensors into the control board, make sure you have the 3 motor wires plugged in in the proper order (trial and error is a good approach), and set the timing appropriately and you have all the makings of a sensored BLDC driver.<br />
<br />
One thing I've found particularly exciting is that I've come up with a way to use the hall sensor information to simultaneously keep track of the position of the motor. It's only as precise to 1/(number of magnets * 3) revolutions, but if you have a high enough pole count on the motor you can get away with using the hall sensors in place of an external encoder. That is a significant cost saver on position feedback. In case a higher resolution is needed, there are two additional pins broken out for the A and B channels of a quadrature encoder, and the software can be updated to monitor the position of the encoder rather than the hall sensors.<br />
<br />
As for how the position feedback from the hall sensors work, it is very similar to the method I presented in my <a href="http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html">quadrature post</a>. If you haven't done so already, I suggest you go and read it since I'll only talk about the differences here rather than going through all the details again.<br />
<br />
The operating principle of reading quadrature was to use the previous and current states of the two channels combined together to become the index for a lookup table. The value in the lookup table would then be added to the position to either increment it, decrement it, or do nothing. In the quadrature case the index value is a 4-bit integer (2 bits for the previous state of channels A and B, 2 bits for the current state), so the lookup table is 2^4 = 16 elements long. Using the same thought process, it's possible to build a lookup table using the previous and current states of the 3 hall sensors. Since there are 3 sensors, the index value becomes a 6-bit integer and the lookup table becomes 2^6 = 64 elements long. It's a lot more work to fill out a 64 element table as opposed to a 16 element table, but it's a one time deal and the performance is just as fast as the 4-bit quadrature version.<br />
<br />
The end result of all this trickery is a free encoder (if you count the cost of the hall sensors as required even without the position feedback). Although it is admittedly coarse in comparison to most quadrature encoders, when a high pole count motor is coupled with a geared down drive (such as a lead screw) the resolution becomes good enough for fine position control. For example, a 22 pole motor gives 66 counts per revolution, and when combined with a 16 threads per inch lead screw the positioning accuracy comes in at (1/16) / 66 = 0.00095 inches per count.<br />
<br />
See <a href="http://makeatronics.blogspot.com/2014/05/bldc-hall-effect-sensors.html">this post</a> for details on the hall effect sensor PCB.</div>
<h3>
Sample and Hold</h3>
<div>
It's not uncommon practice in data acquisition hardware for there to be a feature called "sample and hold." What this feature does is take a signal from the host microcontroller/computer/whatever which then causes the hardware to freeze the values on all the analog inputs. The reason this is important is because it takes a finite amount of time to read the analog signal, especially if there are multiple pins to read. During this read time it's quite likely that the signals are changing, and by the time the microcontroller gets around to reading the last input some amount of time has passed since reading the first input and the value has changed from what it was when you first started sampling.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://images.books24x7.com/bookimages/id_17244/fig10-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="http://images.books24x7.com/bookimages/id_17244/fig10-1.jpg" height="332" title="Image source: http://images.books24x7.com/bookimages/id_17244/fig10-1.jpg" width="400" /></a></div>
<div>
<br /></div>
<div>
Imagine you had analog signals coming in to each of the 6 analog inputs on an Arduino. These incoming signals are changing fast, perhaps reading accelerometers on a vibrating object. You want to sample all 6 sensors at the same instant in time. Without sample and hold, you would read the first input at t=0. Say it takes y amount of time to complete the analog read. Now the Arduino moves on to read the second input at t=y, third input at t=2y... sixth input at t=5y. The sixth sensor has not in fact been measured at the same time as the first sensor, but rather 5y amount of time later. Usually y is not a lot of time (on the microsecond scale), but depending on your application and what else is happening with the sample (perhaps lots of math) it may be important. Sample and hold will eliminate this problem by sampling all sensors instantaneously and holding the value while the measurements are being taken.</div>
<div>
<br /></div>
<div>
In my 3D printer I plan to have multiple motors, each with their own control board. The control boards are keeping track of the position of their respective motors and sending that position back to the master controller when requested. In order to keep the closed loop control of these three motors as accurate as possible, I decided to implement a sample and hold feature on the control boards. It works like this: when the master controller is ready to read the position of all the motors, it sets the sample and hold pin high. This one pin is routed to all of the control boards. Once the control boards see that sample and hold has gone high (on a pin change interrupt), they take their current position and save it into a buffer. Then, when communication for the position begins it is read out of the buffer (rather than the actual current position, which may have changed from the time that sample and hold was set). Once the position has been read from all the control boards, the master sets the sample and hold pin low and the control boards are ready to do the whole thing over again.<br />
<br /></div>
<h3>
Communication to External Microcontroller</h3>
<div>
Everything I've explained to this point is all taken care of by the on-board software and the only hookups required to operate a BLDC motor are power connections (logic power, motor power and ground), motor connections (coils ABC), hall effect sensors, and direction and PWM inputs. For the minimalist user it is very easy to get a motor spinning.<br />
<br />
But since the hall effect sensors can keep track of motor position there needs to be a way to get that information from the control board to an external microcontroller. I opted to go with SPI communication for two main reasons: the SPI pins already need to be broken out to a header for programming the on-board microcontroller (via an <a href="http://www.adafruit.com/products/46?&main_page=product_info&cPath=16&products_id=46" target="_blank">ISP programmer</a>), and SPI is FAST (up to 4MHz clock rate on Arduino, 10x faster than I2C).<br />
<br />
To avoid redundant headers on the board, I chose to go with the standard 6-pin ISP programing header (2x3) used on Arduino and expand it with 4 additional pins to a 10-pin header (2x5) for slave select, direction, PWM, and sample and hold. I particularly like 2 x whatever headers because connection cables are easy to make with ribbon cable and clamp on insulation displacement connectors like <a href="http://www.digikey.com/product-search/en?WT.z_header=search_go&lang=en&site=us&keywords=HSR10H-ND&x=0&y=0&formaction=on" target="_blank">this</a>.<br />
<br />
The control board is running as a slave on the SPI bus. When the board detects that the sample and hold pin has been set high it takes a snapshot of the position (32 bit integer) and breaks it into 4 byte sized chunks. The master then requests each chunk individually and the slave responds with the appropriate byte. It's then up to the master to re-assemble the 4 bytes into a single 32 bit integer. So far this is the only SPI communication available on the control board, but in the future I plan to be able to have the master write contents directly to the control boards EEPROM which will be read on start-up to configure things such as the order the motors 3 wires are plugged in.<br />
<br />
The Arduino SPI library only supports SPI in master mode. I was a little bit bummed by this, but not too bad since I've been digging more into the bare atmega instructions anyway. Through a lot of datasheet surfing, head banging against the computer screen, and trial and error I eventually got hardware SPI working in slave mode. As far as the amount of code it's not all that bad. Straight forward, really, once you get your head wrapped around it. But getting to that point... not the easiest task ever.<br />
<br />
<h3>
Operating Voltage Levels</h3>
</div>
<div>
As stated at the top of this post, the end goal is to be able to run the control circuit on 3.3 or 5 volts and drive a motor with 8 - 36 volt supply. My current version of hardware falls short of these specs. Currently I am limited to 5v only on the control side and 5-12v for the motor. I have identified the problem in the schematic and updated the design so that it should work to spec, but I have not yet ordered the new PCB's to verify the design.</div>
<div>
<br /></div>
<div>
For my 3D printer, which was the motivation behind this control board, I plan to use an Arduino Due as the external controller because of it's impressive speed. The Due only operates at 3.3v, so it is imperative that I get 3.3v working on the control board.</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
That's it for the hardware description of this board. I'm really pleased with the progress I've made here. I think I've come up with a design that offers both simplicity for interfacing with external controllers and a good selection of features for a high performance controller. In an upcoming post I will describe the software that I am running on the controller. Until then, check out this video of the thing in action.</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/yCA11a3h6fU?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
As with all my circuit boards, I plan on selling this one to anybody interested. However, at this time the board has the limitations detailed in the Operating Voltage Levels section. If you want to get your hands on one of this version, or if you're dying to get the updated version, leave a comment or email me. Depending on the response I get from the public I may choose to accelerate my plans.<br />
<br />
<br />
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div style="margin: 0px;">
<div style="font-style: normal;">
UPDATE: V2 has been tested and is running after a few modifications. A V3 design has captured these latest modifications and is on order (hopefully the last version). If V3 works as expected I will post the design files and start selling it in the Makeatronics Store. In the meantime here's a video of V2 in action. I will post more videos shortly with position and velocity control.</div>
<div class="separator" style="clear: both; font-style: normal; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/eMslHyssvhs?feature=player_embedded' frameborder='0'></iframe></div>
<div style="font-style: normal;">
<br /></div>
<div style="font-style: normal;">
<br /></div>
<div style="font-style: normal;">
<br /></div>
<div style="font-style: normal;">
<br /></div>
<div style="font-style: normal;">
<br /></div>
UPDATE #2: I have completed V3 of this board which has the hardware tweaks sorted out and is ready for release to the public. I have a new post that talks about <a href="http://makeatronics.blogspot.com/2014/08/smart-bldc-commutator-hardware.html">the hardware in detail</a>.</div>
</div>
</div>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com18tag:blogger.com,1999:blog-3462870758832574326.post-2321414468581502052014-01-12T18:13:00.001-05:002014-05-18T22:07:40.312-04:003D Printer Motor Control - Part 1So I've been moving forward with my 3D printer plans slowly but surely. I've mainly been focusing on the drive axes up to this point, more specifically the details of controlling the motor. As outlined in my <a href="http://makeatronics.blogspot.com/2013/08/building-3d-printer.html">3D printer post</a>, I am planning on using closed loop position control with brushless DC (BLDC) motors, rather than the standard open loop control with stepper motors.<br />
<br />
<a name='more'></a><br /><br />
My first thought was to simply replace a stepper motor in the typical belt drive assembly with a BLDC motor and then add an encoder... somewhere. I never decided where to put the encoder because it wasn't long before I realized that that particular approach wouldn't work too well, at least without its fair share of software complications. One of the specs on every BLDC is the number of poles, or pole-pairs (there are always twice as many poles and there are pole-pairs). While not exactly the same, [number of poles] x 3 (or [number of pole-pairs] x 6) can be considered to be the equivalent of the number of steps per revolution in a stepper motor. The problem is that the number of poles on a BLDC is quite small in comparison to a stepper motor, so driving an axis directly wouldn't have the required positioning accuracy, at least not with a much more complicated motor control software. (The robotics industry has figured it out and use it all the time. It's roughly the equivalent of micro-stepping, I think...)<br />
<br />
I thought through a few other design ideas all centered around some kind of speed reduction (gears, pulleys, threaded shafts) which has the advantage of increasing the effective number of steps in a revolution by the same factor that speed is reduced by. For example, an 8:1 gear reduction means that for every 8 revolutions on the input shaft (motor end), there is 1 revolution on the output shaft (connected to the drive axis). The speed is reduced by 8 while the effective [number of poles] x 3, or "steps per revolution" is multiplied by 8. Eventually, I landed on this design for one of the drive axes. It uses a 14 pole "medium speed" motor (1200kv), a 8:1 gear reduction from the motor to drive shaft (yellow and green features), and a 10 threads per inch shaft for even further speed reduction (torque multiplication). All in all this would give 80 motor revolutions per inch of travel, plenty (overkill?) of positioning accuracy without the need for any micro-stepping.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8LMoLSTc_P8vhFio64mPAlVw2hZFYtnMKuKS448Qqhzhlxcd1nzHg2g4Ut5tw53T7iLluP-rEv5qgRTpS44Noutb6VnPYykQP-zh7NOQFyzt61zAtV5rmoNeliBwDtjzq0DATB8-az6KJ/s1600/asm.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8LMoLSTc_P8vhFio64mPAlVw2hZFYtnMKuKS448Qqhzhlxcd1nzHg2g4Ut5tw53T7iLluP-rEv5qgRTpS44Noutb6VnPYykQP-zh7NOQFyzt61zAtV5rmoNeliBwDtjzq0DATB8-az6KJ/s1600/asm.jpg" height="400" width="172" /></a></div>
<br />
But I still had two problems. One, to get good low speed torque and accurate positioning out of a BLDC motor it really should be a sensored motor, meaning it has 3 hall effect sensors in the motor aligned so that as the magnets of the motor rotate the sensors will tell the controller when to turn on or off each of the three phases in the motor. (See the first 4 pages of this <a href="http://ww1.microchip.com/downloads/en/appnotes/00857a.pdf">application note</a> for a good explanation of BLDC commutation). The problem I had here is that the only sensored motors I could find were either far too few poles or way too expensive. One possible remedy to this problem, I thought, was to use the signal from the encoder to commutate the motor, thus negating the need for a sensored motor. The other problem was that I underestimated the price of quality encoders--the cheapest ones I found of acceptable quality were $40 and ENORMOUS (see that big black bulk in the image above?), smaller packaged encoders were in the $80+ range. It was almost enough to drive me back in the direction of stepper motors.<br />
<br />
But one day as I was discussing the matter with a friend at work it dawned on me: it should be possible to design a small (cheap) circuit board that mounts to the motor and adds sensors to an otherwise sensorless BLDC motor. I did some research and found that other people have similarly hacked their motors and so I drew up a quick PCB to fit my motor. As I was going through that process I had a second epiphany: I should be able to use the sensors on the motor in a <a href="http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html">similar way as an encoder</a> to get position feedback! It would be a much coarser encoder than I was planning on, but if I had a properly geared drive system so that I didn't need "micro-stepping" than I was never going to use that extra encoder resolution anyway.<br />
<br />
I finished designing the PCB, which was small enough that it only cost a few dollars, and added high quality hall effect sensors. The end result was something around $6 for a sensored hack to my motor, and it worked perfectly (see <a href="http://makeatronics.blogspot.com/2014/05/bldc-hall-effect-sensors.html">here</a> for the details of the design process). The downside to these sensors is that they will only work with a specific motor.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-l0-xkDFSFDYpoJefAbutDYvjxkvnGn6_2BMKTngw_wZIr-YntAmCu9cdORb_713gKzJWduhIOhqcc_Kc-t5X2w_yKU7RCiY_TFAv3lkLK1wiZ4iQ9Kv8WeQgpYbUYRDVIfgeDlJArG9k/s1600/IMG_20140103_204050.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-l0-xkDFSFDYpoJefAbutDYvjxkvnGn6_2BMKTngw_wZIr-YntAmCu9cdORb_713gKzJWduhIOhqcc_Kc-t5X2w_yKU7RCiY_TFAv3lkLK1wiZ4iQ9Kv8WeQgpYbUYRDVIfgeDlJArG9k/s1600/IMG_20140103_204050.jpg" height="300" width="400" /></a></div>
<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/AVvXsEilZiiUeIA1CWpcsnHeaIfL4ftcSBmQuwIwW430KhmB6bZs0nvgRjOJ7CWWX1dkr3uSatiAAqYdzibzTYpFjhOdDXi-rKzTEDMdORJK9K5Am9b1D_3NSiTzuYPL0DIJDnUsnt953S4TDPGt/s1600/IMG_20140112_174213.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilZiiUeIA1CWpcsnHeaIfL4ftcSBmQuwIwW430KhmB6bZs0nvgRjOJ7CWWX1dkr3uSatiAAqYdzibzTYpFjhOdDXi-rKzTEDMdORJK9K5Am9b1D_3NSiTzuYPL0DIJDnUsnt953S4TDPGt/s1600/IMG_20140112_174213.jpg" height="400" width="300" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGCibEZI4cWpsO_PQmuNzutpbyXvZEA4e1bbDnMyrZJOHvF5LAjvgHf2YUOUx5rH-G-u4LXWDkHeplQtU5Hr-SSn6LZeWX5SJUD8rlc6FiyeKm3LlPTtjkg5pKYIutpRsFZPa2OtxyT3ml/s1600/IMG_20140112_174312.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGCibEZI4cWpsO_PQmuNzutpbyXvZEA4e1bbDnMyrZJOHvF5LAjvgHf2YUOUx5rH-G-u4LXWDkHeplQtU5Hr-SSn6LZeWX5SJUD8rlc6FiyeKm3LlPTtjkg5pKYIutpRsFZPa2OtxyT3ml/s1600/IMG_20140112_174312.jpg" height="300" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
After some further design work, I came to the conclusion that if my motor had enough torque, enough poles, and I used a high enough threads per inch threaded rod for the drive shaft, I could do direct drive from the motor to the shaft, greatly simplifying the design of the drive system. My newest design uses a much slower/torque-ier 22 pole motor (390kv) with added hall sensors, no encoder (66 counts per revolution provided by hall sensors), and a 1/4"-16 ACME threaded rod. This setup gives me slightly better than 0.001" [0.025mm] positioning accuracy along the direction of the axis (assuming everything else about the structure is perfect). I also upgraded the linear bearings to be sturdier and more readily available.<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/AVvXsEiKK_MrX198BPOkebjm3Lhg4h8Q3OyJS4eBW1Cq1PzMEh23SQlSoJ_HJJcSzBGlO3DAqkrV9VnLBud1yVx-czD9zl1rfGYa3Q47t9apBNaU0Q7nyQGvT1GGgMIm3apDwQDhURNYK5nmtDwH/s1600/3dprinterdrive.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKK_MrX198BPOkebjm3Lhg4h8Q3OyJS4eBW1Cq1PzMEh23SQlSoJ_HJJcSzBGlO3DAqkrV9VnLBud1yVx-czD9zl1rfGYa3Q47t9apBNaU0Q7nyQGvT1GGgMIm3apDwQDhURNYK5nmtDwH/s1600/3dprinterdrive.jpg" height="400" width="186" /></a></div>
<br />
Another aspect that I'm happy with on this design is that being direct drive I eliminate some concerns I was having about backlash in my gear system. That is, if the gears don't perfectly mesh then whenever the direction of rotation reverses there's some "dead space" where the motor is turning (and reading position changes) but the drive shaft isn't actually doing anything. In practice all gears have some amount of backlash. There's ways of dealing with it in "zero backlash" which are actually two gears loaded under a spring to take up the backlash, but those are expensive and hard to come by. But with direct drive I don't have to deal with any of that.<br />
<br />
Also, with this design the motor sits prominently up on top of the axis, visible for all to see. This is further accentuated by the fact that the motor is an outrunner, meaning the part that rotates is the outer most diameter of the motor, which will look pretty cool watch.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com7tag:blogger.com,1999:blog-3462870758832574326.post-9253721016472427632013-10-19T23:43:00.000-04:002014-05-18T22:08:26.110-04:00Wireless HVAC Sensors (temperature and humidity)As I've been working to transition control of my HVAC systems over to my Raspberry Pi there has always been one big hurdle to overcome: how to I get the temperature reading from the room I'm interested in to the Raspberry Pi in the basement?<br />
<br />
<a name='more'></a><br /><br />
When I first set up my <a href="http://makeatronics.blogspot.com/2013/04/raspberry-pi-thermostat-hookups.html">Raspberry Pi thermostat</a> project, I was collecting temperature on an Arduino with RN-XV wifi module for communicating with the Raspberry Pi. This worked well enough to get things started, but was far from ideal. First off, the RN-XV put off some heat that would show up by as much as +5 degrees on the temperature sensor (significantly less when putting the module to sleep). Second, the price of the RN-XV was somewhat prohibitive, coming in at <a href="https://www.sparkfun.com/products/10822">$35 each from Sparkfun</a>, and that's not even including the supporting Arduino. I'd like to monitor temperature in multiple rooms and maybe even set up zones, so a minimum of $35 in each room is a tad steep. Third, powering the thing meant having it tethered to an outlet somewhere.<br />
<br />
I wanted a cheap, wireless, battery operated sensor that I could place anywhere in the house. In addition, I wanted it to look more or less like it belonged there. So I've been putting in a fair amount of time recently to develop a new circuit board.<br />
<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/AVvXsEhmK4vxQQz7HIks5xJHN7VuYuJk3NmEVFV9tovEH-pNUT0OyCTCPUfKTCLERAbZq-csU0k4kCNYaRee6VF7UpojFuY7QOVb6ccmg6A6mWj5MfOqtpSXGS7ZrThwzUSLaTsE517LdbH139X3/s1600/IMG_20131019_221420.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmK4vxQQz7HIks5xJHN7VuYuJk3NmEVFV9tovEH-pNUT0OyCTCPUfKTCLERAbZq-csU0k4kCNYaRee6VF7UpojFuY7QOVb6ccmg6A6mWj5MfOqtpSXGS7ZrThwzUSLaTsE517LdbH139X3/s320/IMG_20131019_221420.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYfRzJnP7xP2SS254zmZ_G8TJAPbCelpuHEUUwj6s-P_Clixao2CSgcvo4MfGfeldbzxyMAGwiWoso42knXOdkz3h4IlOoYLxorNa2DdVbcEtR3GS5kJ1KvX9df4s_WwCoAxP5MTYGyBmn/s1600/IMG_20131019_213815.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYfRzJnP7xP2SS254zmZ_G8TJAPbCelpuHEUUwj6s-P_Clixao2CSgcvo4MfGfeldbzxyMAGwiWoso42knXOdkz3h4IlOoYLxorNa2DdVbcEtR3GS5kJ1KvX9df4s_WwCoAxP5MTYGyBmn/s320/IMG_20131019_213815.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBuPd3jwnnwhpyCzairAaU8ZSlJMbd4CRxV6LeflWMNeQQQboYun8RIwQsrDFoLQxWNf_JitQA-QUdeAMlCxKYCfVNhiBtz2ilzDLnuWXDFmBxhdPuq5Ac_SbxenBgPQn0zUkUaGCmsLUM/s1600/IMG_20131019_213744.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBuPd3jwnnwhpyCzairAaU8ZSlJMbd4CRxV6LeflWMNeQQQboYun8RIwQsrDFoLQxWNf_JitQA-QUdeAMlCxKYCfVNhiBtz2ilzDLnuWXDFmBxhdPuq5Ac_SbxenBgPQn0zUkUaGCmsLUM/s320/IMG_20131019_213744.jpg" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
For wireless communication, I'm using the easy to find and unbelievably cheap nRF24L01+ module (black daughter PCB in images above). I found on eBay a set of 10 for a little over $12. The micro controller is an <a href="http://www.atmel.com/Images/doc8006.pdf">ATTINY84</a> running on the 1MHz internal oscillator. On the sensor side, I have space for a <a href="http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf">DS18B20</a> and <a href="http://www.analog.com/static/imported-files/data_sheets/TMP35_36_37.pdf">TMP36</a> temperature sensors (presumably you would only use one or the other) and a <a href="http://sensing.honeywell.com/index.php?ci_id=49692">HIH5030</a> humidity sensor. For power, I use a single LR44 button cell battery with a MCP1640 boost converter to boost the voltage to 2.7V. I have estimated the battery life to be somewhere in the 6 month to 1 year range using sleep modes where ever possible, but that's yet to be confirmed. I have set up the micro to be able to read the battery voltage to be able to send out a low battery warning.<br />
<br />
You may be wondering about the shape of the PCB. Like I said above, I wanted this to look like it belongs in my house when installed. The various holes on the ends allow it to mount inside a standard electrical box under any of the common size face plates (I would not recommend putting it in the same box where house mains power is present). When used with a light switch face plate, the sensors are positioned to be directly behind the small rectangular opening to allow for good air flow to the sensors.<br />
<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/AVvXsEiDWd2iw26DVXCZZr0hBYselP4yj4xT8EYOz_TAkrDiwB08ZJnaot8_LEy8kB2cui80opKqHOzT7ZL269j-BnFyrmYTFs32e8D5-Npsub-v43h2P03n92pUPb2C2Cdv0D9CBXJaliifj-CB/s1600/IMG_20131019_213711.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDWd2iw26DVXCZZr0hBYselP4yj4xT8EYOz_TAkrDiwB08ZJnaot8_LEy8kB2cui80opKqHOzT7ZL269j-BnFyrmYTFs32e8D5-Npsub-v43h2P03n92pUPb2C2Cdv0D9CBXJaliifj-CB/s320/IMG_20131019_213711.jpg" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjrGJJATC5xocW1IRiqoNQxjqcAkRNSXLp6iMyQ_Tgn6LDxRQto4waYdoB5SyzLKydG4tF9lcmjcCPfttmXs4xRHM_usyVjTazxX7948NTD6u_Vm4KgvOqcpITdRF43CzcS4xTdpd7JS0R/s1600/IMG_20131019_213518.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjrGJJATC5xocW1IRiqoNQxjqcAkRNSXLp6iMyQ_Tgn6LDxRQto4waYdoB5SyzLKydG4tF9lcmjcCPfttmXs4xRHM_usyVjTazxX7948NTD6u_Vm4KgvOqcpITdRF43CzcS4xTdpd7JS0R/s320/IMG_20131019_213518.jpg" height="320" width="240" /></a></div>
<br />
<br />
Software on here was a lot more difficult than I was planning on, mainly due to the wireless module. The ATTINY84 does not have a dedicated SPI bus, so I was forced to learn how to communicate to the nRF24L01+ in software via bit-banging. I did get it figured out, though, and things seem to be working fine now. As far as the programming language, I found <a href="http://hlt.media.mit.edu/?p=1695">this site</a> that explained how to get it up and running in the Arduino IDE, and most Arduino functions work on the ATTINY84 as expected. It does require an ISP programmer to upload the code. I would highly recommend buying a dedicated programmer, but a spare Arduino can be <a href="http://arduino.cc/en/Tutorial/ArduinoISP">made to work</a> in a pinch.<br />
<br />
There are about $10 of components on the board including the wireless module, but not including any of the sensors (a TMP36 is fairly cheap, but the other two are pricey). This is my first version of this PCB and its far from perfect (as you can see in the images above), so I'm not going to put this one for sale just yet. I do have a load of these boards though, so if you want to play with it send me a message and we'll work something out.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com9tag:blogger.com,1999:blog-3462870758832574326.post-30611291053378730742013-08-24T22:19:00.000-04:002014-05-18T22:08:39.380-04:00IR Remote RepeaterLast year I installed my TV on the wall. I really liked how it turned out, but I didn't like the look of cables running up the wall from my DVD player. So I put a recessed box behind the TV, routed the A/V cables through the wall and stowed the equipment in a nearby closet. It cleaned up the look of the room a lot, but there was a hurdle to overcome: how to I control the A/V equipment with a remote? I needed an infrared (IR) repeater to pick up the signal near the TV and repeat it in the closet where the media equipment is. I know there's commercial solutions to this problem, but I figured it would be easy enough to build my own.<br />
<br />
<a name='more'></a><br /><br />
To start, you should know a little bit about how a typical IR remote control works. For that, I'll steal <a href="http://en.wikipedia.org/wiki/RC-5" target="_blank">an image from Wikipedia</a>:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://upload.wikimedia.org/wikipedia/commons/c/c7/Rc-5_protocol_details.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://upload.wikimedia.org/wikipedia/commons/c/c7/Rc-5_protocol_details.jpg" height="640" width="530" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Without getting too heavy into the protocol, I'll walk you through it. Starting from the bottom of the image and working up, you see there's a time period where the signal is on and it repeats every so often (as long as the button is held down). Inside that signal we see the bits of information (high and low sequence). Each button on the remote has a unique sequence of high's and low's. Zooming in further we see that whenever the signal is high, it's actually modulating on and off at some even higher frequency, termed the carrier frequency. This modulated signal is what's sent to the IR LED at the front of the remote.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The purpose of the carrier frequency is for noise rejection--while you can easily have stray IR beams that might falsely trigger a dumb receiver, it's highly unlikely that you will have any stray IR beams at a this specific frequency. All the IR receivers in TV's, DVD players, etc., have a little sensor designed to look for a specific frequency. When it sees the carrier frequency, it de-modulates it and puts out a solid high (or low, depending on the device) for as long as the modulated signal is there. Once the signal turns off, the sensor puts out a low (or high). The majority of consumer electronics use a 36-38kHz carrier frequency, though those limits can extend out to 33-40kHz depending on the device. Another class of devices use a carrier frequency of 50-60kHz.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You can buy these de-modulating sensors for fairly cheap, you just need to know what carrier frequency you have. <a href="http://www.digikey.com/scripts/DKSearch/dksus.dll?keywords=751-1227-ND" target="_blank">This one</a> is rated for a 38kHz carrier frequency, but still works decently well for +/-10% frequency tolerance (that's 34.2-41.8kHz for those keeping score).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So here's the beauty of these IR repeaters: you don't need to know squat about the protocol, only the carrier frequency so you can buy the correct sensor. Once you get the sensor you then have a sequence of high and low pulses that can be sent across wires and then modulated again onto a carrier frequency on the other end. A <a href="http://www.digikey.com/product-detail/en/NE555P/296-1411-5-ND/277057" target="_blank">555 timer</a> happens to work perfectly for the modulation task.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
555 timers are handy little devices. There's no shortage of tutorials on how to set them up, so I'll leave those details to the adventurous googler. Suffice it to say that with a few resistors and capacitors you can set the 555 output to oscillate at a speed and duty cycle determined by those components. And since it has a handy enable pin, we can control when the output is on (oscillating) or off. BINGO! All we need to do is feed the output of the IR sensor into the enable pin of the 555, and then hook an IR LED to the output of the 555, so that the LED correctly mimics whatever the remote LED is transmitting. No protocol decoding, no software, no super fancy componentry. Just a few basic, dumb components.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So of course I designed a circuit board to do all this. It takes a 6-12V power input through a barrel jack (same as your Arduino power supply), or an optional pre-regulated 5V on a micro-USB plug (read: phone charger). I put a visible LED in parallel with the IR LED so that you can see that it's working, though it works just fine without it. To go from where you want to aim your remote (presumably where the TV mounts) to where the media equipment lives, it uses a standard ethernet (or phone cable by choosing the proper jack) cable which transmits power to and signal from the IR sensor. Run the cable to wherever you need it, put a sensor on one end of the cable (I just soldered the sensor leads directly to the cable wires), this circuit board on the other end, point the board at the device(s) to be controlled and there you have it.</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/AVvXsEgggG3DMlz3qtTqV4rInJBgNh9JBVigMN2S89E2eIHy0btehjtSX9CBaJvELIhGk9QakhjVJVQ3cV01TX-Vtbe6toYzeKFGG44ejnsAz4k06B_pKbrbHiS-Z2lQGpNKaYJ4fV65qrHNue-U/s1600/ir+extenter.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgggG3DMlz3qtTqV4rInJBgNh9JBVigMN2S89E2eIHy0btehjtSX9CBaJvELIhGk9QakhjVJVQ3cV01TX-Vtbe6toYzeKFGG44ejnsAz4k06B_pKbrbHiS-Z2lQGpNKaYJ4fV65qrHNue-U/s320/ir+extenter.jpg" height="302" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgll6YgkdjLd7Fng1vXVNTzzsSZAm-owr6OzhNKHsz8IPXF5pVhCrwB86dszBZztPQbK9GFFTOSmfNZSZL3LDV-wC-UXk8E4lavirzpMB0yXXANi3MuSlwQLFYkGInInbKUtdpUHpugWCiG/s1600/IMG_20130823_222449.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgll6YgkdjLd7Fng1vXVNTzzsSZAm-owr6OzhNKHsz8IPXF5pVhCrwB86dszBZztPQbK9GFFTOSmfNZSZL3LDV-wC-UXk8E4lavirzpMB0yXXANi3MuSlwQLFYkGInInbKUtdpUHpugWCiG/s400/IMG_20130823_222449.jpg" height="400" width="300" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNk11Mhjvh8E7GM-werq4mjQ2lXvGt7-KHLvAgLr7aNPDFwwnCYj348lOvI0e47wKmKUW0Dz-vzTs1c1Homc1PECrZrrbYqRn32xM_3Z-30A4iQFDpO301AlpeckzHkwFv_ih0oBwKCN1o/s1600/IMG_20130823_220335.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNk11Mhjvh8E7GM-werq4mjQ2lXvGt7-KHLvAgLr7aNPDFwwnCYj348lOvI0e47wKmKUW0Dz-vzTs1c1Homc1PECrZrrbYqRn32xM_3Z-30A4iQFDpO301AlpeckzHkwFv_ih0oBwKCN1o/s400/IMG_20130823_220335.jpg" height="300" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: x-small; text-align: left;">Cool trick: if you shine your remote into your smart phone camera, it will show up as purple on the screen. That's why this photo has a purple looking LED.</span></td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
You'll notice that I included a 5k potentiometer on the board. This is to allow you adjust the 555 frequency by several kHz and also allow your components to be of the non-precision variety. The values listed on the board are assuming you want the 555 timer running somewhere in the vicinity of 38kHz. If you want to use it in the 50-60kHz range you will need to replace the relevant resistors and/or capacitors. There's many calculators out there that will help you do this, just remember that the potentiometer is in series with one of the resistors. The 555 will see the resistance of that resistor plus whatever the pot is set at (0 - 5kohm). If you use 2.5kohm as the potentiometer value in your calculations, that will give you maximum adjustability around that range.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Like all my other circuit boards, I'm making the design files freely available:</div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<ul>
<li><a href="https://docs.google.com/file/d/0B9DuE3f5Cnm7OXR5U29Rd3BnUzg/edit?usp=sharing" target="_blank">IR_Repeater.zip</a></li>
<li><a href="https://docs.google.com/spreadsheet/ccc?key=0AtDuE3f5Cnm7dHc5R1hZamttdldnZG9BcUF6a1pqX0E&usp=sharing" target="_blank">IR_Repeater - partslist</a></li>
</ul>
<div>
For sale in the <a href="http://makeatronics.blogspot.com/p/store.html" target="_blank">Makeatronics Store</a>.</div>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com2tag:blogger.com,1999:blog-3462870758832574326.post-89123418345890963942013-08-20T22:53:00.000-04:002014-05-18T22:08:55.782-04:00Building a 3D PrinterI've decided to do it. I'm going to join the ranks of those who have a 3D printer in their homes. While having the ability to print custom parts for future projects will be a definite benefit, I must say that the lion's share of the fun will be in the making of it.<br />
<br />
Now, I know there is no shortage of plans and designs available for <a href="http://reprap.org/" target="_blank">DIY 3D printers</a> contributed to by a community of makers, hackers, hobbyists, etc., I've decided not to go with an existing design. My schooling focused on robotic kinematics and control as well as mechanical design. It seems a shame not to put that learning to good use. Perhaps I'll blaze some new trails in the process.<br />
<br />
<a name='more'></a><br /><br />
I plan to break away from the ubiquitous rep-rap concept. While it's a cool idea on paper to have a self replicating machine, I don't think that 3D printed parts have the accuracy or rigidity required to be used as primary components in this type of a machine. <i>Any</i> inaccuracies introduced by geometry, sloppy fit or flexing is reflected or amplified in the printed part. Instead, I'll be using a mixture of off-the-shelf and machined components. Of course it will end up costing more, but it's a trade off I'm willing to make. I do have a goal to keep it below $1,000. Compared to some of the higher end kits available ($2,200 for <a href="http://store.makerbot.com/replicator2.html" target="_blank">Makerbot Replicator 2</a>, $1,600 for <a href="http://store.makerstoolworks.com/printer-kits/mendelmax-2-0-standard-kit/" target="_blank">MendelMax 2.0</a>) it isn't too bad.<br />
<br />
Additionally, and I expect this to be somewhat controversial, I won't be using any stepper motors on this printer. I know they are the de facto motor for DIY printers, but something about open loop control on a robot just doesn't sit well with me. Instead, I'll be using brushless DC motors with full closed loop control for (hopefully) greater speed and accuracy. Ideally, I will be able to program them with an operational space controller, which basically means that each motor will be aware of all the others, and if one gets snagged or otherwise held up, the others will react to it so as not cause an error in position.<br />
<br />
In addition to improved control schemes, going with DC motors will allow for smaller, lighter motors in place of their clunky stepper counterparts. This will be most beneficial for the filament extruder--keeping the weight of the moving head as low as possible will improve both speed and accuracy. Since stepper motors do not have any feedback, they rely on high torque output to ensure that the actual number of steps achieved matched the commanded number of steps. In essence, you have a severely oversized motor. Going with a DC motor allows for better use of available resources, but it does come with its own share of drawbacks: cost and complexity. But again, building is more than half the fun, so why not make it exciting?<br />
<br />
For the printer design, I decided to go with a delta platform configuration (like <a href="http://www.kickstarter.com/projects/deltamaker/deltamaker-an-elegant-3d-printer-0" target="_blank">this</a>). Aside from being entirely captivating to watch, this platform does offer some advantages over the basic cartesian (XYZ) platform:<br />
<br />
<ul>
<li>The printed part is stationary at all times--no need to limit speed or build height to keep the part stable.</li>
<li>The three axes each have a more fluid motion, minimizing the effects of taking sharp corners.</li>
<li>Accuracy is greatest at the center of the build platform, so small parts can have tighter tolerances.</li>
<li>It looks freakin' awesome.</li>
</ul>
<div>
Of course, there's the whole complexity thing again. But as it turns out, the inverse kinematics (that is, what axis positions are needed to give the desired XYZ coordinates?) aren't that difficult, so basic control won't be much, if any, harder than a cartesian robot. The forward kinematics (my axis positions are such, what are my XYZ coordinates?), required for the operational space controller mentioned above, are more involved and will take a fair amount of work to get through. But that's the fun part.</div>
<br />
As for electronics, I haven't given that much thought at this point. For the brushless motors I know I'll need different motor controllers than are used on any of readily available printer plans. A basic ESC won't cut it since those are designed for speed control, not position control, so a custom control board may come into the mix. For the processing I'll probably need something with quite a lot more umph than an Arduino. An Arduino Due would probably work in terms of processing power, but I'd like more external interrupts than that one has to offer. The <a href="https://www.sparkfun.com/products/11280" target="_blank">Maple Mini</a> from <a href="http://leaflabs.com/" target="_blank">LeafLabs</a> looks promising.... We shall see.<br />
<br />
So that's my high level plan. It's going to be a complex project, and will probably take a year or two to complete. I'll try to post updates of any progress I make as it happens. Wish me luck!<br />
<br />
<b>Posts in this series:</b><br />
<br />
<ul>
<li><a href="http://makeatronics.blogspot.com/2013/08/building-3d-printer.html">Building a 3D Printer</a></li>
<li><a href="http://makeatronics.blogspot.com/2014/01/3d-printer-motor-control-part-1.html">3D Printer Motor Control - Part 1</a></li>
<li><a href="http://makeatronics.blogspot.com/2014/05/bldc-motor-control.html" target="_blank">BLDC Motor Control</a></li>
</ul>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com7tag:blogger.com,1999:blog-3462870758832574326.post-51863870187710064062013-06-23T23:04:00.001-04:002014-08-01T21:23:23.306-04:0024V AC Solid State Relay BoardMy post on the <a href="http://makeatronics.blogspot.com/2013/04/raspberry-pi-thermostat-hookups.html">hardware connections between my Raspberry Pi and HVAC wires</a> has become one of my higher traffic posts so far. Apparently people are searching for ways to connect Raspberry Pi's to thermostats (or Arduino or any other microcontroller for that matter). So I decided to design a circuit board to fill that space.<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>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWrLWX9BQBnm61R6pFtJl8kh9l-rtXPoLMYFB-N0umFuUUEk2tzoPMCeIIJCYssvgoZOWcoZp0MkKtDdFBeR6tXTQa2Nh4gD8dJa9pqsNeGA3gaq_dGBvJwcO67fTZysEkU13Sm3PT7_vI/s1600/24VAC+SSR+Board.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWrLWX9BQBnm61R6pFtJl8kh9l-rtXPoLMYFB-N0umFuUUEk2tzoPMCeIIJCYssvgoZOWcoZp0MkKtDdFBeR6tXTQa2Nh4gD8dJa9pqsNeGA3gaq_dGBvJwcO67fTZysEkU13Sm3PT7_vI/s1600/24VAC+SSR+Board.png" height="381" width="400" /></a></div>
<br />
<a name='more'></a><br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_fOpYMypp2XPlSNj1jU-aYs_6oTFAt8HKbNYC_5aFSU7QuqcJQ4jWJn2eos7dw7J8A0kUjY9vVbWumiLPj0wQ2rSpjVTXfpXInowYuMInCTnvr6fzLKOWZcBawrx7yz7k1DlkMCx1uKJT/s1600/24V_AC_SSR.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_fOpYMypp2XPlSNj1jU-aYs_6oTFAt8HKbNYC_5aFSU7QuqcJQ4jWJn2eos7dw7J8A0kUjY9vVbWumiLPj0wQ2rSpjVTXfpXInowYuMInCTnvr6fzLKOWZcBawrx7yz7k1DlkMCx1uKJT/s400/24V_AC_SSR.jpg" height="390" width="400" /></a></div>
<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;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBEqswL3U_q5q5NWYuHGco65tg7ZOcjyEytsynuTZCSwJrDWuTykyLjZX0PtJzFltaBHS_Fygq2M92vCqVX_i6r9qAG5vQziLAApL_wEgViC7W5aXoUpK3_Yng_3702o96cOEIB60YcD8z/s1600/IMG_20131209_203215.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBEqswL3U_q5q5NWYuHGco65tg7ZOcjyEytsynuTZCSwJrDWuTykyLjZX0PtJzFltaBHS_Fygq2M92vCqVX_i6r9qAG5vQziLAApL_wEgViC7W5aXoUpK3_Yng_3702o96cOEIB60YcD8z/s400/IMG_20131209_203215.jpg" height="400" width="300" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNDqsUEWYis2p1NrzO_M79gTMp4hU-L5ungdQP43U2TI56CkhKFxequxEBdZemg9ZdTYfFMMuJZyfM_USNXz4jvtqXsBxIuBppLDX7z8ZkUpBxc0QqlDbMuuYhhWd6fXHBUtVNpgSHNedu/s1600/IMG_20131209_203227.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNDqsUEWYis2p1NrzO_M79gTMp4hU-L5ungdQP43U2TI56CkhKFxequxEBdZemg9ZdTYfFMMuJZyfM_USNXz4jvtqXsBxIuBppLDX7z8ZkUpBxc0QqlDbMuuYhhWd6fXHBUtVNpgSHNedu/s400/IMG_20131209_203227.jpg" height="400" width="300" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLJRtds3_OUVleZIvwcpVxnieFP5wrVf50QlTYE-OloRj2lsGbgo39oQLAprOPVZKBwH8Ytc60V8iaNOf1-GoGaxdDeS3O1_9njXHeFuMc1wPkyHUzMg75ThYMiPqxuXSqUON-qCWIRaES/s1600/IMG_20131209_203241.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLJRtds3_OUVleZIvwcpVxnieFP5wrVf50QlTYE-OloRj2lsGbgo39oQLAprOPVZKBwH8Ytc60V8iaNOf1-GoGaxdDeS3O1_9njXHeFuMc1wPkyHUzMg75ThYMiPqxuXSqUON-qCWIRaES/s400/IMG_20131209_203241.jpg" height="400" width="300" /></a></div>
<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/AVvXsEiJ6upqMusNb371bs8uEUaRk30xWDSezy-cAHL-ROovmYpuch78iLymQJZN930GoLNP7VEgYIMoVLxIWKU73-iEiEpMVu9xLtpV08hIwIBraNwbgE7j_a-LsBHtkTELvjC1-dnFdPxUb_4w/s1600/2013-07-25+22.03.01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJ6upqMusNb371bs8uEUaRk30xWDSezy-cAHL-ROovmYpuch78iLymQJZN930GoLNP7VEgYIMoVLxIWKU73-iEiEpMVu9xLtpV08hIwIBraNwbgE7j_a-LsBHtkTELvjC1-dnFdPxUb_4w/s400/2013-07-25+22.03.01.jpg" height="238" width="400" /></a></div>
<br />
<br />
It's nothing fancy, and it can all be breadboarded very easily. But sometimes it's just nice to have it all in one neat little package, so here it is. It's capable of switching three 24V AC lines (think furnace, air conditioner, and blower fan). Simply screw the hot wire into the terminal labeled HOT, the three lines you want to control into 1, 2 and 3 on the DRIVEN side, and the low voltage control signals into 1, 2 and 3 on the DRIVER side. You'll also need a ground wire going from the micro to the GND terminal. I included an extra empty terminal next to HOT in case your wiring includes the common wire of the 24V supply (mine doesn't). It does absolutely nothing, just there to keep the wire from feeling left out and causing potential mischief. There's space for 3 optional LED's for some nice visual feedback of what's switched and what's not. And that's it! Pretty simple, really.<br />
<br />
And the design files:<br />
<ul>
<li><a href="https://docs.google.com/file/d/0B9DuE3f5Cnm7N1JXZkV6QlRBVkk/edit?usp=sharing">24V_AC_SSR_Board-eagle.zip</a></li>
<li><a href="https://docs.google.com/spreadsheet/ccc?key=0AtDuE3f5Cnm7dEU3MWFEeTU0RnZyTUNfVUxrX1FVdXc&usp=sharing">24V_AC_SSR_Board-partslist</a></li>
</ul>
<br />
For the software side of this, you could try using my simple script from <a href="http://makeatronics.blogspot.com/2013/04/thermostat-software.html">here</a>, but I'll admit it's not very user friendly (or code efficient). For much better software complete with browser interface, check out <a href="http://wyattwinters.com/rubustat-the-raspberry-pi-thermostat.html">Wyatt Winters Rubustat</a> made using this board.<br />
<br />
For sale in the <a href="http://makeatronics.blogspot.com/p/store.html" target="_blank">Makeatronics Store</a>.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com54tag:blogger.com,1999:blog-3462870758832574326.post-66329088048837557812013-05-12T17:15:00.001-04:002014-08-01T21:21:26.204-04:00Sous Vide Part 3: Advanced DevelopmentIn <a href="http://makeatronics.blogspot.com/2013/02/sous-vide-part-1-what-and-why.html">part 1</a> I introduced the concept of sous vide and why you should be interested in it. <a href="http://makeatronics.blogspot.com/2013/04/sous-vide-part-2-early-version.html">Part 2</a> covered a basic and low cost way to get your feet wet with sous vide. Today, part 3 will detail the more advanced stand alone controller I designed.<br />
<br />
<a name='more'></a><br />
<br />
There were a few drawbacks of my arduino controller. First, a lack of a user interface which required me to upload new code whenever I wanted to change the temperature, and the only way I could monitor the temperature was over the serial line which required a computer and more cables. Second, wires were always coming loose from the breadboard, or I would use the arduino for a different project, so I was always having to remember what wires went where. Third, it took up far too much counter space what with all the wires hanging out everywhere.<br />
<br />
After playing around with sous vide for a few months and deciding it was definitely something I wanted to stick with I decided to put some effort and money into a stand alone controller. I had done a little bit of circuit board design over the past several months, but this would easily be the most complex to date. I started out by making a list of important features:<br />
<br />
<ul>
<li>It should be based off of an atmega microcontroller for simplicity. An atmega8 proved to have too little memory, so now I use an atmega328p.</li>
<li>It would need a user input device and display. A 8x2 character LCD display with an encoder knob and button fit the bill nicely.</li>
<li>I wanted the ability to switch as large of a heater as I might ever want to connect to the thing, so I stuck with the BTA20 triac, capable of switching 20 amps AC, with an appropriately sized heat sink. Since most home outlets are connected to a 15A circuit breaker, this would be plenty. </li>
<li>Since I would have the capability to switch such high current, I figured a zero cross detection circuit to switch the power on only when the AC waveform was crossing 0 volts (in essence easing into full current draw) would be a nice touch. I used <a href="http://www.dextrel.net/diyzerocrosser.htm">this design.</a></li>
<li>It should have a audible sound for alerting the user. I used a DC buzzer.</li>
<li>It should use the same DS18B20 temperature sensor that I had been using, but should be able to interface with different sensors if I ever wanted it to. I broke out the I2C lines for this.</li>
<li>It should be able to interface with a computer for logging data to a file. I included an FTDI header for that.</li>
<li>It should be self powered from the one power cord plugged into the outlet. I.e. I didn't want to have a separate 5V power supply for the digital circuitry.</li>
</ul>
<div>
I spent what time I could between classes and homework jams and came up with a working design. I refined it a bit over the following years and version 3 looks like so:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKRG1Y5RkRVYm99hTQvB4_HtghPlwr-AT5JtKRG4LfVlugdoShKmOdAmstlHHTsjtXvHlQwtkVLAk0Of5JB7RGVI8cJQMLmQ9abSTM3eSnt3ssU3uN5sHMo-j9nM2f6o-I6WhvBex6pzjF/s1600/board.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKRG1Y5RkRVYm99hTQvB4_HtghPlwr-AT5JtKRG4LfVlugdoShKmOdAmstlHHTsjtXvHlQwtkVLAk0Of5JB7RGVI8cJQMLmQ9abSTM3eSnt3ssU3uN5sHMo-j9nM2f6o-I6WhvBex6pzjF/s1600/board.png" height="400" width="391" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibxMbMfXw9d0iUPTjGVyT-_qLQXJ9axiUsKuD2li7019-qR8qEPdr0jZGVS13gpopTmA04dkYuHLXm4gGNjGu5k4J7K0QYskg60m7Cl_aLfa4y5k9HHYGMv77fvMdDQwdUih3ws8lrbghe/s1600/schematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibxMbMfXw9d0iUPTjGVyT-_qLQXJ9axiUsKuD2li7019-qR8qEPdr0jZGVS13gpopTmA04dkYuHLXm4gGNjGu5k4J7K0QYskg60m7Cl_aLfa4y5k9HHYGMv77fvMdDQwdUih3ws8lrbghe/s1600/schematic.png" height="345" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEnlN0SQG2WyzkSQazAZdeNGXXjOCVGC1ethOELODTz0c55Ci0lHl1horXGixpUtP5SNxggTrNLWsU91lejOW1UCeNpKrDCOPOtsxtkUXfIjvNitNV-u0BFUtd8foqIeW5G0HiTTdxvhPf/s1600/2012-04-06+15.35.08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEnlN0SQG2WyzkSQazAZdeNGXXjOCVGC1ethOELODTz0c55Ci0lHl1horXGixpUtP5SNxggTrNLWsU91lejOW1UCeNpKrDCOPOtsxtkUXfIjvNitNV-u0BFUtd8foqIeW5G0HiTTdxvhPf/s400/2012-04-06+15.35.08.jpg" height="300" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga5hB9dMeAXb7BFI068akSKkrxC0weQciRmZr9SQcFwVLExtlv6RwyATC_OXYHV_Jrm9JIHWldEfhNbhK5Jgx7qiWTV8n-wxzb7UVel9xglIXQjDUGNvJnAOXTaeTselG_eDx9qt94sZI8/s1600/2012-05-16+18.16.31.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga5hB9dMeAXb7BFI068akSKkrxC0weQciRmZr9SQcFwVLExtlv6RwyATC_OXYHV_Jrm9JIHWldEfhNbhK5Jgx7qiWTV8n-wxzb7UVel9xglIXQjDUGNvJnAOXTaeTselG_eDx9qt94sZI8/s400/2012-05-16+18.16.31.jpg" height="300" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAYOLv9sH_Af4D_gi-gZ-EPmteSjVYMXsbbWYzxGu_iJPEW-4ywf0DO8709jQFk_pYFO2nCiw5QMaK475asbbUWpbtIt5c2j0oGLiCwbdewcAmj0h50wso34iQSaPWtOkNZjMeoZgmWaau/s1600/2012-12-27+14.27.43.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAYOLv9sH_Af4D_gi-gZ-EPmteSjVYMXsbbWYzxGu_iJPEW-4ywf0DO8709jQFk_pYFO2nCiw5QMaK475asbbUWpbtIt5c2j0oGLiCwbdewcAmj0h50wso34iQSaPWtOkNZjMeoZgmWaau/s400/2012-12-27+14.27.43.jpg" height="300" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br /></div>
<div>
Design files are linked to at the end of this post.<br />
<br /></div>
<div>
A warning: </div>
<div>
This circuit is connected directly to the mains power lines that carry potentially lethal voltages. Exercise extreme caution while using, and install the circuit board in an appropriate enclosure to reduce the risk of electric shock. By downloading and using these design files you agree to release me of any and all responsibility regarding its use. I am working on a 3d printable case for this to greatly reduce the risk involved.</div>
<div>
<br />
For the pot, I decided to go with something that was a little bigger. Ok, so I went with something that was a lot bigger. I purchased a stainless steel 16 qt stock pot and a 1500W 10" water heater heating element to go inside. That's a 400% increase in volume and 790% increase in power over the crock pot I had been using.<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/AVvXsEgxDDrR4KYPsNs2IQX0nG9W1CUALAd8MScfIXtP_9ytFcuRvDF3PlBahZHRdFbhZOWzD23yuqvGcXBsJXMh9eM9n1vthdWae-xNIZiJ_qkmNoMmzelExdSmBR1peBIXFhRDDXPwijhan2Wx/s1600/2012-12-25+11.30.31.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxDDrR4KYPsNs2IQX0nG9W1CUALAd8MScfIXtP_9ytFcuRvDF3PlBahZHRdFbhZOWzD23yuqvGcXBsJXMh9eM9n1vthdWae-xNIZiJ_qkmNoMmzelExdSmBR1peBIXFhRDDXPwijhan2Wx/s320/2012-12-25+11.30.31.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgA-r6xZTYq_t8Ioy-X0fvzAHiJ_sJoygfG3Rbrx-xphtrGuz6ZEswiAtVnoAJhoaskAEvaBIqmeEHBL1E4MXegGf3aZ8jy6w4_ppmA9HkZJ6do2qDYyAWnuRPpcHplD54mC6lGUNRsKbv/s1600/2012-12-26+20.34.45.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgA-r6xZTYq_t8Ioy-X0fvzAHiJ_sJoygfG3Rbrx-xphtrGuz6ZEswiAtVnoAJhoaskAEvaBIqmeEHBL1E4MXegGf3aZ8jy6w4_ppmA9HkZJ6do2qDYyAWnuRPpcHplD54mC6lGUNRsKbv/s320/2012-12-26+20.34.45.jpg" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJDoVZ5xsoL0gAkQ-oZis3PqHhI9jzWn3GwQk1mIslpx96WJ0_Sy2DzyMxiM9nzQxELMXYPp0oaB1uiqeq9rAk_YiSHTkxj-xOesm2hogDZDhr_8V3ryU5TrsTc9V_Dw4NUW4fw3CsNPW3/s1600/2012-12-27+14.27.00.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJDoVZ5xsoL0gAkQ-oZis3PqHhI9jzWn3GwQk1mIslpx96WJ0_Sy2DzyMxiM9nzQxELMXYPp0oaB1uiqeq9rAk_YiSHTkxj-xOesm2hogDZDhr_8V3ryU5TrsTc9V_Dw4NUW4fw3CsNPW3/s320/2012-12-27+14.27.00.jpg" height="240" width="320" /></a></div>
<br />
The increase in volume has obvious benefits. The increase in power means that even with 4 gallons of water it can go from cold tap water to set temperature in 20 minutes (as opposed to 1-2 hours with the small crock pot) and recover from dropping in several chunks of cold meat in less than 5 minutes (20-30 minutes with the crock pot).<br />
<br />
I went with a heating element inside the pot for one main reason: I figured it was the cheapest route. Shortly after I purchased the parts my brother asked me why I didn't just use a hot plate. Because I didn't realize how cheap hot plates actually were. Turns out the heating element and matching nut were about the same price as a hot plate, but I could have used any pot in the kitchen rather than buying a dedicated pot and drilling a hole in the side. However, each setup has it's pros and cons. Here's the ones I can think of.<br />
<br />
Heating element inside pot<br />
<ul>
<li>Pros</li>
<ul>
<li>100% of heating power is transferred directly to the water</li>
<li>System is easier to model since power input is known</li>
<li>No thermal inertia to worry about (i.e. water temperature doesn't keep rising after power is shut off due to a large thermal mass on the outside of the pot)</li>
<li>Set the gains once and forget about it</li>
</ul>
<li>Cons</li>
<ul>
<li>Requires a fair amount of labor to get the heating element through the side wall of the pot</li>
<li>It is a large, dedicated item that requires it's own storage space</li>
<li>Screw terminals where wires attach are exposed and hazardous</li>
<li>The heating element gets a bit rusty with extensive use (non-hazerdous to the food, though)</li>
</ul>
</ul>
<div>
Hot plate with pot on top</div>
<div>
<ul>
<li>Pros</li>
<ul>
<li>Hot plate is small and can be stored easily</li>
<li>Any pot could easily be used</li>
<li>No assembly required</li>
<li>No exposed wires to worry about (aside from the circuit board, of course)</li>
</ul>
<li>Cons</li>
<ul>
<li>PID gains might be different enough between pot sizes to require individual tuning</li>
<li>There is an unknown portion of heating power that doesn't make it to the water, making theoretical modeling difficult</li>
<li>Thermal inertia could make tuning the controller difficult (but once tuned the controller would be perfectly capable of handling it)</li>
</ul>
</ul>
<div>
<br />
In the end I'm glad I ended up with the setup I have, but I don't see any strong reason not to go with a hot plate.</div>
</div>
<div>
<br /></div>
<div>
As for selecting the PID gains and tuning the controller, I'll leave that for another post. For this system I ended up with gains of 23, 0.01, and 0 for the P, I, and D gains, respectively. </div>
<div>
<br /></div>
<div>
Several people have asked me if I plan on insulating the pot. The answer is a firm no. While insulation may seem intuitive on a first pass (and it seemed that way to me, too), it can have some ill side effects. In a typical closed loop controller you have the ability to command the system in either direction (think position control on a robot). However, with a heater setup there is no [practical] way of driving the system in the cold direction. Therefore, if you overshoot your temperature (which will happen to some degree on any controller with an integral component, guaranteed) your only recourse is to wait for it to cool down naturally. Insulation would only increase the amount of time it takes to cool. In theory the insulation would help to make the temperature more stable using less power, but I haven't found either factor to be a problem without insulation. The controller is perfectly capable of controlling the temperature to within the resolution of the temperature sensor, and during steady state operation the system is only consuming on average 70W of power. With my electricity rates that amounts to about $0.15 for 24 hours of run time.</div>
<br />
<br /></div>
<div>
So that's the hardware side. Now for the software.</div>
<div>
<br /></div>
<div>
Again, I started with a list of what I wanted it to do. The list grew over time as I thought of more features to add. This is how it is now:</div>
<div>
<ul>
<li>The user should be able to intuitively navigate a menu system with the encoder knob and button.</li>
<li>Within the menu system, the user should be able to:</li>
<ul>
<li>set the desired temperature</li>
<li>set the temperature units (Fahrenheit or Celsius)</li>
<li>set the PID gains</li>
<li>set the timer direction (count up/down), and if down set duration</li>
<li>choose whether the buzzer is active</li>
<li>choose whether to log to an external computer</li>
</ul>
<li>The current state of everything should be saved to EEPROM to be remembered through a power cycle</li>
<li>The user should be able to save and load up to 8 profiles (temperature, gains, timer) in EEPROM</li>
<li>The user should be able to adjust any of the settings "on the fly" while the controller is active</li>
<li>The controller should operate off the zero cross detection interrupt by default, and off a timer interrupt in the absence of zero cross detection</li>
<li>In the event of a power failure, the controller should resume as it was before the failure</li>
</ul>
</div>
<div>
Implementing all of this led to the largest arduino program I've written to date. It's over 1000 lines of code, most of it going to the menu system. At first I was able to just build off of what I had already written as I added features. Each time I added a feature the code would grow more convoluted and harder to follow. Finally, when I decided to implement changing settings on the fly, I realized a complete rewrite of the code was necessary. </div>
<div>
<br /></div>
<div>
I recognized that my code lent itself to being a state machine, and it was a state machine in some sense, so I decided to go all out with the state machine concept upon the rewrite. I also decided to do something I've heard a lot about, but never though I needed until now--diagram the code. </div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiupP6HDIB5_v0Dfd7TltbQh2uLp9_H4QbXxI7_vGXjf0N6lnJK7qN0xR-MZSyI_cHgz_QA-SmDLnylFMn5HVBaGHlUgqJ3zVUzqoT4oZrvTITPvtDckJ42QlPWAB9scNtSqSq_CbjrC1QP/s1600/menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiupP6HDIB5_v0Dfd7TltbQh2uLp9_H4QbXxI7_vGXjf0N6lnJK7qN0xR-MZSyI_cHgz_QA-SmDLnylFMn5HVBaGHlUgqJ3zVUzqoT4oZrvTITPvtDckJ42QlPWAB9scNtSqSq_CbjrC1QP/s1600/menu.png" height="408" width="640" /></a></div>
<br /></div>
<div>
Diagramming the state machine was a bit tedious, but oh so helpful. First, it forced me to think through the layers of the menu system. Second, it allowed me to see improvements that I probably would have missed otherwise. Third, I gained back much more time in the coding phase by having a clear direction than I spent on the diagram. If you have a decent sized program that you have to write, I highly encourage you to diagram what the code does before you start coding.</div>
<div>
<br /></div>
<div>
There's no way I'm going to talk about all of the code here. I'll let you pour through it at your own pace, I think I've done a decent job commenting it. But feel free to ask any questions you may have about it in the comments. But there are a few things I'd like to address here.</div>
<div>
<br /></div>
<div>
Different from the controller in <a href="http://makeatronics.blogspot.com/2013/04/sous-vide-part-2-early-version.html">part 2</a>, this new version relies on the zero cross detection signal for the timing of the control loop. In every period of the AC waveform there are two places where the voltage crosses zero. Keeping with the same 1 second control strategy, there are 120 zero cross events per control loop. Between each zero cross event is 1/120 = 8.33ms. It is important that whatever code is run in the ISR be done in under this amount of time. This wasn't enough time for the microcontroller to run both the getTemp() function and controller during the same zero cross event. So I opted to run the getTemp() function on the 119th zero cross event and the controller on the 120th (or 0th) zero cross event. Going a little further, I combed through the OneWire.h library, took out the parts that weren't relevant to this application, and changed the bus requests to broadcast mode which eliminated any handshaking between the DS18B20 and microcontroller at the expense of being able to only have one sensor on the bus. With these changes I was able to get the DS18B20 temperature requests to run reliably in less than 6ms, which is good enough for me.
<br />
<br />
<pre class="prettyprint">void zcd() { // zero cross detection ISR
Cross++;
if (Cross > Num_On) { // turn off AC when # of ZC exceeds num_on
digitalWrite(GATE, LOW);
}
if (Cross == 119) { // get temperature in this 8ms time slot
Current_Temp = getTemp();
}
if (Cross == 120) { // compute num_on in this 8ms time slot
if (Gate_Allow) {
Num_On = control(); // controller computes num_on
} else {
Num_On = 0;
}
Cross = 0;
if (Num_On != 0) {
digitalWrite(GATE, HIGH); // every 120 ZC's except when num_on is 0
}
}
}
uint8_t control() {
static float _set_temp_celsius = Set_Temp;
if ((Units&1) == 1) {
_set_temp_celsius = Set_Temp;
} else if ((Units&1) == 0) {
_set_temp_celsius = round(temp_convert(Set_Temp, 1) * 2) / 2.0;
}
// calculate PID output
long _val = Kp*Err + Ki*Err_Integral + Kd*(Err-Err_Prev);
// compute errors
Err_Prev = Err;
Err = _set_temp_celsius - Current_Temp; // always work in degrees C
if (_val < 120 && _val > 0) { // integrator anti-windup
Err_Integral += Err;
}
// constrain the output
_val = constrain(_val, 0, 120);
return _val;
}
</pre>
<br />
The output of the controller (run once every second) is a number between 0 and 120 (< 7 bits). This number is used as how many zero cross events must pass before power is shut off. This is different than the timer interrupt used in <a href="http://makeatronics.blogspot.com/2013/04/sous-vide-part-2-early-version.html">part 2</a> which had an output between 0 and 1023 (10 bits), and the gains need to be scaled to match. It seems like a big drop going from 10 bit PWM resolution to less than 7. But with triac switching it is impossible to switch faster than 2x the AC frequency, so nothing is lost in practice.
<br />
For the encoder input knob I use the same technique that I described in <a href="http://makeatronics.blogspot.com/2013/02/efficiently-reading-quadrature-with.html">this post</a>:
<br />
<br />
For the input button, I found <a href="http://www.mathertel.de/Arduino/OneButtonLibrary.aspx">this handy little library</a> that lets me easily distinguish between short and long button presses (and double clicks, but I don't use that here).<br />
<br />
<pre class="prettyprint">OneButton encoder_button(BUTTON, false);
// more code here
void setup() {
// more code here
encoder_button.attachClick(encoder_click);
encoder_button.attachPress(encoder_press);
encoder_button.setClickTicks(100); // single click timeout 100ms
encoder_button.setPressTicks(1000); // long press timeout 1000ms
// more code here
}</pre>
<br />
The GNU toolchain for AVR microcontrollers doesn't have any support for floating point formatted printing. However, I found this lovely trick for redirecting STDOUT to allow fprintf of floats, making my life a whole lot easier.<br />
<br />
<pre class="prettyprint">LiquidCrystal lcd(LCD_RS,LCD_EN,LCD_DB4,LCD_DB5,LCD_DB6,LCD_DB7);
static FILE lcdout = {0};
// more code here
void setup() {
lcd.begin(8,2);
fdev_setup_stream (&lcdout, lcd_putchar, NULL, _FDEV_SETUP_WRITE);
// more code here
}
</pre>
</div>
<br />
Which allows me to fprintf to the lcd like so:<br />
<br />
<pre class="prettyprint">lcd.setCursor(0,1);
fprintf(&lcdout, "%2d:00:00", Timer);
</pre>
<br />
<br />
You can download the full code and design files here:<br />
<ul>
<li><a href="https://docs.google.com/file/d/0B9DuE3f5Cnm7YndzdVhMejlCQ28/edit?usp=sharing">SousVide_code.zip</a></li>
<li><a href="https://docs.google.com/file/d/0B9DuE3f5Cnm7eEJEcThmV0dLS0U/edit?usp=sharing">SousVide_eagle.zip</a></li>
<li><a href="https://docs.google.com/spreadsheet/ccc?key=0AtDuE3f5Cnm7dGVyT05zMlZSMlUwRDhpcVlQVEREUGc&usp=sharing">SousVide_partslist</a></li>
</ul>
<br />
For sale in the <a href="http://makeatronics.blogspot.com/p/store.html" target="_blank">Makeatronics Store</a>.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com6tag:blogger.com,1999:blog-3462870758832574326.post-77479489567963092622013-04-29T00:25:00.000-04:002014-05-18T22:10:13.410-04:00Thermostat Software----<br />
<br />
EDIT: I don't profess to be a programmer, even though I can make my way through a few different languages. The code I present here works fine, but it's not very pretty or efficient. I think it's still useful from an educational standpoint and has a few ideas in there that are worth looking at and it's easy to get up and running. But I will soon be ditching this software in favor for some written by Wyatt Winters for his <a href="http://wyattwinters.com/rubustat-the-raspberry-pi-thermostat.html">Rubustat</a> (though I'll try to find a way to re-implement the checking of outdoor temperature to determine heating/cooling).<br />
<div>
<br />
----<br />
<br /></div>
In <a href="http://makeatronics.blogspot.com/2013/04/thermostat-graphs.html">this post</a> I explained that I tasked my Raspberry Pi with controlling the furnace and air conditioner in my house. Here I describe the software that went into it.<br />
<br />
The requirements I wanted were simple enough:<br />
<ol>
<li>Behave similarly to a commercial thermostat</li>
<li>Schedule temperature set points</li>
<li>Automatic switching between heating and cooling based on outdoor temperature</li>
</ol>
<br />
<a name='more'></a><br /><br />
<div>
To satisfy requirement 1, the HVAC control algorithms behave very similar to an actual thermostat: a bang-bang controller with hysteresis. The bang-bang bit means that the HVAC is either full-on or full-off, no percent power or anything like that allowed. The hysteresis prevents the system from cycling on/off very frequently by requiring that the temperature drop below/rise above the set point by a certain amount before a new action is taken. A typical hysteresis is 0.5 degrees, but I have it set as a variable so I can change it later on if I want to tune the performance. I have also found it beneficial to define separate active and inactive hystereses to reduce overshoot. (For the hardware connections to the Raspberry Pi, look <a href="http://makeatronics.blogspot.com/2013/04/raspberry-pi-thermostat-hookups.html">here</a>.)<br />
<br />
For requirement 2 I am currently scheduling the set temperature using the /etc/crontab file on the Raspberry Pi to write the set point to a file (i.e. "echo 72 > set_temp") which is read when the thermostat program is called. Using cron is fairly straight forward and there's plenty of examples of how to use cron available on the internet.<br />
<br />
Requirement 3 was fun to fulfill. Rather than having a second temperature sensor outdoors, I decided to query the internet. The internet knows everything. Knowing the outdoor temperature the Raspberry Pi can decide whether to turn on the air conditioner if it's hot outside or make me open a window if it's cool out (with similar behavior for the reverse, of course). This will be especially helpful for the spring and fall months where the outdoor temperature is close to the set point for the indoor temperature, eliminating the need to flip a heat/cool switch back and forth.<br />
<br />
Combining all this together into Python I came out with the following code:</div>
<pre class="prettyprint linenums">#! /usr/bin/python
import sys
import subprocess
import os
indoor_temp = subprocess.check_output("get_indoor_temp.sh")
outdoor_temp = subprocess.check_output("get_outdoor_temp.sh")
file = open("set_temp", "r")
set_temp = float(file.readline())
file.close()
hvac_state = int(subprocess.check_output("get_hvac_state.sh")
active_hysteresis = 0.0
inactive_hysteresis = 0.5
outdoor_temp_buffer = 5
# heater mode
if outdoor_temp < set_temp - out_temp_buffer:
if hvac_state == 0
if indoor_temp < set_temp - inactive_hysteresis:
os.system("hvac_heat.sh")
hvac_state = 1
elif hvac_state == 1:
if indoor_temp > set_temp + active_hysteresis:
os.system("hvac_idle.sh")
elif hvac_state == -1: # it's cold out, why is the AC running?
os.system("hvac_idle.sh")
# ac mode
elif outdoor_temp > set_temp + outdoor_temp_buffer:
if hvac_state == 0:
if indoor_temp > set_temp + inactive_hysteresis:
os.system("hvac_cool.sh")
hvac_state = -1
elif hvac_state == -1
if indoor_temp < set_temp - active_hysteresis:
os.system("hvac_idle.sh")
hvac_state = 0
elif hvac_state == 1 # it's hot out, why is the heater on?
os.system("hvac_idle.sh")
else # it's nice out, open a window
os.system("hvac_idle.sh")
</pre>
The get_indoor_temp.sh program will be dependent on whatever temperature sensor you have hooked up to your Rasberry Pi. Currently I have a BMP085 sensor connected to an Arduino connected to my wifi network with an RN-XV wireless module. The wifi has not been a stalwart of stability so far and has resulted in some cold mornings and hot afternoons when connection was lost for extended periods of time. I will be hard wiring some DS18B20 into various rooms in the coming weeks to rectify this.
get_outdoor_temp.sh uses a program called curl to download an RSS feed from AccuWeather.com which then gets parsed to find the current outdoor temperature. There may be a simpler way to do this, but this works well for me (at least until AccuWeather changes their RSS format...):
<br />
<pre class="prettyprint linenums">#! /bin/bash
METRIC=0 # 0 for F, 1 for C
ZIP=(your zip here)
curl -s -m 20 http://rss.accuweather.com/rss/liveweather_rss.asp\?metric\=${METRIC}\&locCode\=${ZIP} | grep -i -m1 'currently' | grep -o '\-\?[0-9]\+'
</pre>
The get_hvac_state.sh program checks the current state of the gpio pins connected to the HVAC to determine if the heater, AC, or neither are active:
<br />
<pre class="prettyprint linenums">#! /bin/bash
HEAT=$(cat /sys/class/gpio/gpio23/value)
AC=$(cat /sys/class/gpio/gpio24/value)
FAN=$(cat /sys/class/gpio/gpio25/value)
if [ $HEAT == 0 -a $AC == 0 -a $FAN == 0 ]; then
echo 0 # idle
elif [ $HEAT == 1 -a $AC == 0 ]; then
echo 1 # heater acive
elif [ $HEAT == 0 -a $AC == 1 ]; then
echo -1 # AC active
else
echo 2 # something is wrong...
fi
</pre>
hvac_cool.sh, hvac_heat.sh, and hvac_idle.sh are simple scripts that write value(s) to the appropriate gpio(s). For example, hvac_idle.sh would be something like:
<br />
<pre class="prettyprint linenums">#! /bin/bash
echo 0 > /sys/class/gpio/gpio23/value # heater
echo 0 > /sys/class/gpio/gpio24/value # AC
echo 0 > /sys/class/gpio/gpio25/value # fan
</pre>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com20tag:blogger.com,1999:blog-3462870758832574326.post-15199515943804562282013-04-14T12:07:00.001-04:002014-08-01T21:18:02.593-04:00Sous Vide Part 2: The Early VersionIn <a href="http://makeatronics.blogspot.com/2013/02/sous-vide-part-1-what-and-why.html">part 1 of this post</a> I talked about what sous vide is and a little about how it can transform foods. I'm not going to delve into the world of opinions on how fantastic it is, unlocking unheard of flavors, tenderness beyond belief, etc etc. I assume that if you've come this far on the internet you've already read a lot about all that, so I don't need to convince you. Instead, I'll lay out my experience tinkering with my homemade controller, how I did it, and how you can do it, too.<br />
<br />
<a name='more'></a><br />
<br />
My first attempt at sous vide was actually a sort of pseudo sous vide. I would throw the meat in a zip-lock bag, suck all the air out and put in in a crock pot full of water. The results were a small step above boiling the meat, but really weren't all that great. Curious what temperature I was actually cooking at, I placed my thermocouple in the water and logged it over time.<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/AVvXsEixStZzpuJtemB7mUFu9aQ6A3SED_wwnwBtBO8BS9f62AbCdjp1YysSzVGM0Ji6oFgfdkYx8z9KROtCGOZ4KlWxcUcsHQmq_XB_pWlr9rsq1vLR7IrpDksZSqb7_HY3iS6MwLQzKLMxMrTY/s1600/crockpot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixStZzpuJtemB7mUFu9aQ6A3SED_wwnwBtBO8BS9f62AbCdjp1YysSzVGM0Ji6oFgfdkYx8z9KROtCGOZ4KlWxcUcsHQmq_XB_pWlr9rsq1vLR7IrpDksZSqb7_HY3iS6MwLQzKLMxMrTY/s1600/crockpot.png" height="240" width="320" /></a></div>
<br />
In about two hours the temperature hits a corner and levels off just below boiling. This test was done about 4500 feet above sea level, so that's why it's not quite 100 C. I did another test with the crock pot dial set to low and found that the same temperature is reached, it just takes about three times as long to reach steady state. Clearly my crock pot wasn't going to get me very far in the world of sous vide.<br />
<br />
Around the time of these experiments I was taking a class on classical control systems and decided to apply my education to the problem at hand. Armed with the theory behind closed loop control, I decided to try and implement a simple PI (Proportional-Integral) feedback controller in the crock pot setup. I won't get into the theory of such controllers here, but will save that for a later post. For now I'll just say that the controller reads the temperature, computes the error between the set point and current temperature, and runs that through an equation to determine what power output is required to reach the set temperature.<br />
<br />
I wanted to keep the setup free of any necessary modifications to my crock pot, so I decided the best way to control the power to the crock pot would be something I could plug into the wall and then plug the crock pot into that.<br />
<br />
A basic requirement for closed loop control is that you have analog (or pseudo analog) control of the output (output of the controller, which is input to the system). Since the crock pot runs on 120V AC (it could just as easily run on DC, but I didn't want to add that much complexity to the circuit), getting continuous control of the power is tricky. Using a variable resistor is out of the question because they are horridly inefficient and produce A LOT of heat if your pulling a lot of power through them. For a 190W crock pot running at 50% power through a variable resistor, it means 95W of power is being dissipated by the resistor!<br />
<br />
PWM seems like an obvious choice here, but it's hard to modulate an AC waveform at PWM frequencies without first rectifying it. But since the response time of the crock pot is on the order of minutes, an extra slow PWM frequency is acceptable. Ultimately I decided on a 1Hz PWM-esque switching controller using TRIAC's as the switch (essentially a home built Solid State Relay (SSR)). This means that once every second the controller reads the temperature, computes the required output, and turns on the power for a percentage of that second.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AyxVgkRosv4bkeafnopj9jIG_35b3u8b-fO9xq98kMZv9cInLzQmQlBkr5HSDtCUCkgUfU1wxFwCktyVJHvQSDbialrYKyPtz82ECcI8WsukWU6_9AIaIJYhz0YwA48uZMjIVtiaCJ4W/s1600/2012-03-25+12.41.03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1AyxVgkRosv4bkeafnopj9jIG_35b3u8b-fO9xq98kMZv9cInLzQmQlBkr5HSDtCUCkgUfU1wxFwCktyVJHvQSDbialrYKyPtz82ECcI8WsukWU6_9AIaIJYhz0YwA48uZMjIVtiaCJ4W/s640/2012-03-25+12.41.03.jpg" height="480" width="640" /></a></div>
<br />
There it is, my first sous vide controller. There's a lot of extra stuff on the breadboard left over from the last circuit I had hooked up to the Arduino. The only things actively connected to the arduino are the temperature sensor (a waterproofed <a href="https://www.sparkfun.com/products/11050">DS18B20</a>), it's required pull-up resistor, and the long red and green wires headed to the TRIAC daughter board. There's also an LED connected in parallel with the TRIAC board so I can see when the crock pot has power. The TRIAC circuit is identical to the one described in <a href="http://makeatronics.blogspot.com/2013/04/raspberry-pi-thermostat-hookups.html">this post</a>, but the two TRIAC's are different part numbers: MOC3023 for the little guy and BTA20 for the big one. (That BTA20 is capable of switching 20A with an appropriate heat sink!)<br />
<br />
The first version of software was pretty simple. I set up a 1 second timer interrupt, and in the ISR (interrupt service routine) I read the temperature sensor, computed the controller output, and set the PWM output (on a 1Hz frequency).<br />
<br />
<pre class="prettyprint linenums">#include "TimerOne.h"
<onewire .h="">
int potPin = 9; // pin the crockpot is connected to
float setTemp = 57.5; // desired temperature
void setup() {
Timer1.initialize(1000000); // 1 second in microseconds
Timer1.attachInterrupt(control); // call the controller every so often
Timer1.pwm(potPin,0);
}
void loop() {
// controller is taken care of in timer interrupt function
}
void control() {
static float kp = 200;
static float ki = .08;
static float err_integral = 0.0;
// retrieve temperature
float temp = getTemp();
// calculate error
float err = setTemp - temp;
// calculate error integral with integral anti-windup
if (pwm < 1023 && pwm > 0) {
err_integral += err;
}
// calculate PI output
int pwm = kp*err + ki*err_integral;
// constrain the output
pwm = constrain(pwm, 0, 1023);
// set the output
Timer1.setPwmDuty(potPin, pwm);
}
</onewire></pre>
I've left off the getTemp() function for clarity, you can use your own for whatever sensor you're using.<br />
<br />
A couple of things to note here.<br />
<br />
<ul>
<li>Everything is done in the control ISR that gets called once per second by Timer1 (lines 16-34)</li>
<li>The controller gains, kp and ki (lines 17-18), are not trivial to set. If you're using a crock pot these numbers will get your pretty close, but you may have to do some tuning on your own (don't worry, I'll cover that in a future post)</li>
<li>Integrator anti-windup, i.e. preventing the integrator from integrating if the PWM is at it's limits, is necessary, especially when the system is slow to respond (lines 25-27)</li>
<li>Once the gains are set, the controller equation is quite simple (line 29), but make sure it's constrained to within valid PWM numbers (line 31)</li>
</ul>
<div>
In the end this setup performed pretty well. Once the temperature got close to it's set point the controller kicked in and started modulating the power line to keep the temperature at the correct level to within a fraction of a degree.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0PySzFNdi97QqRcajfLqxFbRtC5rCsH5gPZNuDm0FIe0FnRP2ES9GUR7AlVsUXUQNqo2RKh0tb1yOuaCu6t8SR8BwOIas-ETgahpBUYABxE5QeHdxR4oxBHcIjii3zZBHFcCRkGAc32Do/s1600/sous+vide+graph.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0PySzFNdi97QqRcajfLqxFbRtC5rCsH5gPZNuDm0FIe0FnRP2ES9GUR7AlVsUXUQNqo2RKh0tb1yOuaCu6t8SR8BwOIas-ETgahpBUYABxE5QeHdxR4oxBHcIjii3zZBHFcCRkGAc32Do/s1600/sous+vide+graph.jpg" height="480" width="640" /></a></div>
<br /></div>
<h3>
</h3>
<h3>
<a href="http://makeatronics.blogspot.com/2013/05/sous-vide-part-3-advanced-development.html">Part 3</a> Teaser</h3>
<div>
This crock pot setup proved to me that Sous Vide cooking is pretty much the most delicious thing imaginable. But the setup fell short in several ways. First, if I wanted to change the temperature or controller gains I had to pull out my computer and reprogram the arduino. Second, every time I wanted to cook sous vide I would have to remind myself how to connect everything since my arduino was constantly project hopping. Third, with the low power crock pot it takes a long time to get up to temperature and a long time to recover after dropping in a big chunk of cold meat. Fourth, the crock pot was pretty small and couldn't hold a lot of food since there is the requirement that the food be completely surrounded by water.</div>
<div>
<br /></div>
<div>
My solution to the first two problems was to design a stand alone circuit board complete with a user interface.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgImc8njH8z7Dw721V6giLs8f8D4Tt2eRy8VcHHv6WRYXRlOS7Jr9hen7e4dWRYpPGqarkv9ADXBIS2XoHE8OVpqiRxIqaUYd1gWuYLkKhBsIbsrKcUWhBURLByF7C5eg8Mss_w4yIQnEwe/s1600/2012-04-06+15.35.08.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgImc8njH8z7Dw721V6giLs8f8D4Tt2eRy8VcHHv6WRYXRlOS7Jr9hen7e4dWRYpPGqarkv9ADXBIS2XoHE8OVpqiRxIqaUYd1gWuYLkKhBsIbsrKcUWhBURLByF7C5eg8Mss_w4yIQnEwe/s400/2012-04-06+15.35.08.jpg" height="300" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_LDJlSI9CUoRymFCOBV5lUXSfXow9vJRstjVyLuQGJK_HihkgUTDpeEZ-awcbNhbPOr8YGirXRgWn3NkY6HtLFLFy3SHKWlKRz0LAErAzXvHfAN_Rhx5fjVM8KmkTG-ACqkqoB0c-QF2B/s1600/2012-05-16+18.16.31.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_LDJlSI9CUoRymFCOBV5lUXSfXow9vJRstjVyLuQGJK_HihkgUTDpeEZ-awcbNhbPOr8YGirXRgWn3NkY6HtLFLFy3SHKWlKRz0LAErAzXvHfAN_Rhx5fjVM8KmkTG-ACqkqoB0c-QF2B/s400/2012-05-16+18.16.31.jpg" height="300" width="400" /></a></div>
<div>
<br /></div>
<div>
For the third and fourth problems, remember how I said the BTA20 TRIAC can switch up to 20 amps? This 1500W water heater element only draws 12.5 amps....</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs1vSjYFwjzZ3DxZfhkNnUAsvuENXRT1vKclvsHEn5z1M6JpimgqVUiqRT9waAjYu_RLfg_0_sSRFIje-frz4z7XvhmrYX_d0ULcYQ4u98eEcyfQuZhR9SVg4BUGjOGWWbsBTwyz4vyAfh/s1600/2012-12-26+20.34.45.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs1vSjYFwjzZ3DxZfhkNnUAsvuENXRT1vKclvsHEn5z1M6JpimgqVUiqRT9waAjYu_RLfg_0_sSRFIje-frz4z7XvhmrYX_d0ULcYQ4u98eEcyfQuZhR9SVg4BUGjOGWWbsBTwyz4vyAfh/s400/2012-12-26+20.34.45.jpg" height="300" width="400" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg68hlL3RdJ4TDKXkrSdrrxcKKGz2yoG-w_UhH5PoTOjVWDsIq2syxdRRz4qsemRZ-S0C-tgwfIGjPf3oaC9dcnZYuCVXjIxNn2voIlDFrhyphenhyphen7iDoxaWNIbtjj2lU9NFwlcXzz7nW47ialrH/s1600/2012-12-27+14.27.43.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg68hlL3RdJ4TDKXkrSdrrxcKKGz2yoG-w_UhH5PoTOjVWDsIq2syxdRRz4qsemRZ-S0C-tgwfIGjPf3oaC9dcnZYuCVXjIxNn2voIlDFrhyphenhyphen7iDoxaWNIbtjj2lU9NFwlcXzz7nW47ialrH/s400/2012-12-27+14.27.43.jpg" height="300" width="400" /></a></div>
<br />
<div>
<br /></div>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com1tag:blogger.com,1999:blog-3462870758832574326.post-55710712559324542142013-04-13T22:46:00.000-04:002014-08-01T21:16:27.394-04:00Raspberry Pi Thermostat HookupsI recently <a href="http://makeatronics.blogspot.com/2013/04/thermostat-graphs.html">replaced my thermostat with my Raspberry Pi</a>. In this post I explain how to make the hardware connections between the Raspberry Pi and the house wiring. Check out the <a href="http://makeatronics.blogspot.com/p/store.html" target="_blank">Makeatronics Store</a> if you want a PCB that does the connections for you.<br />
<br />
In my house (and the vast majority of others) the thermostat wiring runs at 24V AC. There's a live wire (or two, depending on the setup) coming into the thermostat, and several others leaving to control the different components of the HVAC system. The thermostat's job is to close the circuit between the live wire and the appropriate control wire based on the temperature. A relay is an easy way to do it, but I find relay's cumbersome with their (usually) breadboard unfriendly pin layout and larger-than-can-be-supplied-by-gpio switching current requirements.<br />
<br />
<a name='more'></a><br />
<br />
I have found, in my opinion, a much better way of switching AC current: the <a href="http://en.wikipedia.org/wiki/TRIAC">TRIAC</a>. If you've ever used a MOSFET for DC current switching, a TRIAC is similar in application (but not physics), only for AC current. There are some important differences, however. Probably the biggest difference is that once a TRIAC is activated, it will not deactivate until the current through it drops below some small threshold current, and I'm not talking about the gate current. Because of this the TRIAC is pretty useless for DC since once there's current flowing it will never drop (unless you have another switch somewhere, which kinda defeats the purpose, or the battery dies...). In AC, the voltage (and hence current) will go to zero twice every cycle, so shutting the thing off is not an issue. An important side effect of this is that it's impossible to switch a TRIAC faster than the frequency of the AC line it's connected to, so you can forget about using it for PWM. But you CAN control when in the cycle it turns on to control the average current flow available to whatever it's connected to, and this is exactly what light dimmer switches do.<br />
<br />
The 3 pin device is connected in line with the wire you want to switch, and a current is applied to the gate to turn the switch on. But TRIAC's are a little more complicated than MOSFET's. If you want to switch any appreciable amount of current (I was very surprised to learn that my HVAC control lines draw nearly 1.5A at 24V AC) you probably can't switch the TRIAC directly with a gpio. You need a second, smaller TRIAC as an intermediary. But don't fret, it's a very simple circuit.<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;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimYmA4D0IQcQF0hwGjEBLtt7ewyRCfzYG32SIC-dGtWu6HviFWk0amVPcJsQERNccZolKa8KxsYT7TFGhYOWxBv-cpcWb5Gm-y_7wQqBbJhMY2cP3whJYViBZ0XuJ7ldf7dtx1vRt4G0Lm/s1600/triac_driver.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimYmA4D0IQcQF0hwGjEBLtt7ewyRCfzYG32SIC-dGtWu6HviFWk0amVPcJsQERNccZolKa8KxsYT7TFGhYOWxBv-cpcWb5Gm-y_7wQqBbJhMY2cP3whJYViBZ0XuJ7ldf7dtx1vRt4G0Lm/s1600/triac_driver.png" height="346" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
I use an opto-coupled TRIAC as my small one for an added layer of isolation between the gpio and what I'm switching. Plus, it makes turning on and off the switch as easy as turning on and off an LED. All that needs to be done is to apply a voltage across the LED of the opto through the current limiting resistor R1.<br />
<br />
The two TRIAC's are connected together as shown in the schematic, with the smaller one connecting the live wire to the gate of the larger TRIAC. Since the smaller one is actually quite small, R2 is necessary to limit the amount of current that would rush through it once it's activated. It is also important to get the order of the AC wires correct. Just because it's AC doesn't mean the wires are interchangeable!<br />
<br />
Getting back to the thermostat, my house has 3 control wires that I'm interested in: the blower fan, heater, and air conditioner. That means I need 3 of these TRIAC circuits. The live 24V AC wire feeds into each of them, and the control wire goes on the load side. Connect the 3 opto's to 3 gpio's on the Raspberry Pi and voila! I have control.<br />
<br />
In my setup I've used the following components:<br />
R1 - 560 ohm<br />
R2 - 100 ohm<br />
Opto-TRIAC - MOC3063<br />
TRIAC - BT134<br />
<br />
The two TRIAC's are pretty cheap, $1.27 for the pair at the time of purchase from Digi-key. For all three channels I came in less than $5 for everything I needed to interface with the Raspberry Pi.<br />
<br />
If you would like all 3 channels on a PCB instead of a breadboard, check out <a href="http://makeatronics.blogspot.com/2013/06/24v-ac-solid-state-relay-board.html">here</a>.Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com19tag:blogger.com,1999:blog-3462870758832574326.post-266445269853472992013-03-14T23:16:00.000-04:002014-05-18T22:12:14.916-04:00Little Wire SMDI came across the <a href="http://littlewire.cc/" target="_blank">Little Wire</a> a few months back. I thought it was a pretty cool idea to have a few GPIO's accessible over USB. More than that, it also offers several serial protocols (I2C, SPI, etc), dual channel ADC, and even works as an AVR programmer, all in a neat little package! To make it even littler, I designed an SMD version of it.<br />
<br />
I especially liked it for using a software implementation of the USB protocol on an attiny, which means I should be able to use an attiny in place of the much larger (and more expensive) FTDI chip.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2HZ2_rZRsqO3t6D_3V08IMMixdfj3-jZns3UtAAO3nMZRSF4SPakYNgYkCOBtbu4FNfmhl-vcYwX47MrxN-3CXMcp9Es4Zsxv-Tg1aPg7JPcXP79QpNUzE8vmWfFa8coGbaHUx0muocph/s1600/2013-03-10+00.31.55.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2HZ2_rZRsqO3t6D_3V08IMMixdfj3-jZns3UtAAO3nMZRSF4SPakYNgYkCOBtbu4FNfmhl-vcYwX47MrxN-3CXMcp9Es4Zsxv-Tg1aPg7JPcXP79QpNUzE8vmWfFa8coGbaHUx0muocph/s320/2013-03-10+00.31.55.jpg" height="320" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<a name='more'></a><br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhczogX_Q5L10uRkF0Ez642WBA2GOR_juEkjfCXoSCaO1vMKL80vQTy2FfqeOxri5HhaV0rv4TiWqCqTByzoj6z-tTkePyLLQMmONBEeas0UW33Wk6JCfHuBPYLS0KiIupyVrE7mAWNEEZ3/s1600/2013-03-14+22.41.21.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhczogX_Q5L10uRkF0Ez642WBA2GOR_juEkjfCXoSCaO1vMKL80vQTy2FfqeOxri5HhaV0rv4TiWqCqTByzoj6z-tTkePyLLQMmONBEeas0UW33Wk6JCfHuBPYLS0KiIupyVrE7mAWNEEZ3/s320/2013-03-14+22.41.21.jpg" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
The SMD version tested out flawlessly (that's a first!). The only problem is the silk screen lettering is a bit too small to be reliably printed.<br />
<br />
Here's the design files for anybody interested:<br />
<ul>
<li><a href="https://docs.google.com/file/d/0B9DuE3f5Cnm7NlJ6Z1hSWVAzMlE/edit?usp=sharing" target="_blank">LittleWire-smd_eagle.zip</a></li>
<li><a href="https://docs.google.com/spreadsheet/ccc?key=0AtDuE3f5Cnm7dEh2Y081QThGYVYwRXhmUk0xZHNialE&usp=sharing" target="_blank">LittleWire-smd_partslist</a></li>
</ul>
<div>
For sale in the <a href="http://makeatronics.blogspot.com/p/store.html" target="_blank">Makeatronics Store</a>.</div>
Nich Fugalhttp://www.blogger.com/profile/01260987815174387425noreply@blogger.com5