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

<channel>
	<title>HE Qichen&#039;s Hackspace &#187; Arduino</title>
	<atom:link href="http://heqichen.cn/wp/category/arduino/feed/" rel="self" type="application/rss+xml" />
	<link>http://heqichen.cn/wp</link>
	<description>DE BH4CQF K</description>
	<lastBuildDate>Sun, 01 May 2022 11:50:39 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>3D打印机械臂</title>
		<link>http://heqichen.cn/wp/3d%e6%89%93%e5%8d%b0%e6%9c%ba%e6%a2%b0%e8%87%82/</link>
		<comments>http://heqichen.cn/wp/3d%e6%89%93%e5%8d%b0%e6%9c%ba%e6%a2%b0%e8%87%82/#comments</comments>
		<pubDate>Tue, 28 Jan 2020 18:28:21 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://heqichen.cn/wp/?p=1026</guid>
		<description><![CDATA[<p>&#160; &#160; 话说2018年春节的时候，3d打印了一个机械臂。 还是老样子，在纸上先画一个机械臂大概的形状   在CAD中画出具体参数，看看用什么养的配置比较合适，作业半径会是多少。  确定参数就可以开始做三维建模。 一步一步开始搭建机械臂的每个部分。 底座 &#160; 第一关节 第二关节 第三关节，上面可以安装夹具 所有的配件就是这些 &#160; &#160; 机械手臂上当然是要有手了 XD 用机械手来帮你选一瓶饮料 还是再切一个合适的手给机械臂 当然机械臂也可以很欢乐 7,011&#160;total views, 2&#160;views today</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/3d%e6%89%93%e5%8d%b0%e6%9c%ba%e6%a2%b0%e8%87%82/">3D打印机械臂</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>&nbsp;</p>
<p>&nbsp;</p>
<p>话说2018年春节的时候，3d打印了一个机械臂。</p>
<p>还是老样子，在纸上先画一个机械臂大概的形状</p>
<p><a style="font-size: 1rem;" href="http://heqichen.cn/wp/wp-content/uploads/2020/01/01.-微信图片_20200129003823.jpg"><img class="alignnone size-large wp-image-1027" alt="01. 微信图片_20200129003823" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/01.-微信图片_20200129003823-768x1024.jpg" width="625" height="833" /></a><span style="font-size: 1rem;"> </span></p>
<p>在CAD中画出具体参数，看看用什么养的配置比较合适，作业半径会是多少。<a style="font-size: 1rem;" href="http://heqichen.cn/wp/wp-content/uploads/2020/01/02.-IMG_20180217_171804.jpg"><img class="alignnone size-large wp-image-1028" alt="02. IMG_20180217_171804" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/02.-IMG_20180217_171804.jpg" width="625" height="351" /></a><span style="font-size: 1rem;"> </span></p>
<p>确定参数就可以开始做三维建模。</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/03.-IMG_20181231_150924.jpg"><img class="alignnone size-large wp-image-1029" alt="03. IMG_20181231_150924" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/03.-IMG_20181231_150924.jpg" width="625" height="351" /></a></p>
<p>一步一步开始搭建机械臂的每个部分。<br />
<span id="more-1026"></span><br />
底座</p>
<p>&nbsp;</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/04.-IMG_20180218_022221.jpg"><img class="alignnone size-large wp-image-1030" alt="04. IMG_20180218_022221" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/04.-IMG_20180218_022221.jpg" width="625" height="351" /></a></p>
<p>第一关节</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/05.-IMG_20180219_020454.jpg"><img class="alignnone size-large wp-image-1031" alt="05. IMG_20180219_020454" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/05.-IMG_20180219_020454-576x1024.jpg" width="576" height="1024" /></a></p>
<p>第二关节</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/06.-IMG_20180219_115319.jpg"><img class="alignnone size-large wp-image-1032" alt="06. IMG_20180219_115319" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/06.-IMG_20180219_115319-576x1024.jpg" width="576" height="1024" /></a></p>
<p>第三关节，上面可以安装夹具</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/07.-IMG_20180221_171606.jpg"><img class="alignnone size-large wp-image-1033" alt="07. IMG_20180221_171606" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/07.-IMG_20180221_171606-575x1024.jpg" width="575" height="1024" /></a></p>
<p>所有的配件就是这些</p>
<p>&nbsp;</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/08.-DSCF0624.jpg"><img class="alignnone size-large wp-image-1034" alt="08. DSCF0624" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/08.-DSCF0624-1024x575.jpg" width="625" height="350" /></a> <a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/09.-DSCF0626.jpg"><img class="alignnone size-large wp-image-1035" alt="09. DSCF0626" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/09.-DSCF0626.jpg" width="625" height="416" /></a> <a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/10.-DSCF0627.jpg"><img class="alignnone size-large wp-image-1036" alt="10. DSCF0627" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/10.-DSCF0627.jpg" width="625" height="416" /></a></p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/11.-roboticArm.gif"><img class="alignnone size-large wp-image-1037" alt="11. roboticArm" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/11.-roboticArm.gif" width="500" height="750" /></a></p>
<p>&nbsp;</p>
<p>机械手臂上当然是要有手了 XD</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/12.-DSCF2028.jpg"><img class="alignnone size-large wp-image-1038" alt="12. DSCF2028" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/12.-DSCF2028-682x1024.jpg" width="625" height="938" /></a></p>
<p>用机械手来帮你选一瓶饮料</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/13.-DSCF1981.jpg"><img class="alignnone size-large wp-image-1039" alt="13. DSCF1981" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/13.-DSCF1981.jpg" width="625" height="468" /></a></p>
<p>还是再切一个合适的手给机械臂</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/14.-DSCF2039.jpg"><img class="alignnone size-large wp-image-1040" alt="14. DSCF2039" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/14.-DSCF2039.jpg" width="625" height="416" /></a> <a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/15.-DSCF2046.jpg"><img class="alignnone size-large wp-image-1041" alt="15. DSCF2046" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/15.-DSCF2046-575x1024.jpg" width="575" height="1024" /></a></p>
<p>当然机械臂也可以很欢乐</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2020/01/16.-IMG_20180424_185649.jpg"><img class="alignnone size-large wp-image-1042" alt="16. IMG_20180424_185649" src="http://heqichen.cn/wp/wp-content/uploads/2020/01/16.-IMG_20180424_185649-576x1024.jpg" width="576" height="1024" /></a><br />
<iframe src="http://player.youku.com/embed/XNDUyNTczMDEyOA==" height="498" width="510" allowfullscreen="" frameborder="0"></iframe>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="1026">7,011&nbsp;total views, 2&nbsp;views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/3d%e6%89%93%e5%8d%b0%e6%9c%ba%e6%a2%b0%e8%87%82/">3D打印机械臂</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/3d%e6%89%93%e5%8d%b0%e6%9c%ba%e6%a2%b0%e8%87%82/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RC522读RFID卡</title>
		<link>http://heqichen.cn/wp/rc522-on-arduino/</link>
		<comments>http://heqichen.cn/wp/rc522-on-arduino/#comments</comments>
		<pubDate>Mon, 05 Oct 2015 10:54:58 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://heqichen.cn/wp/?p=879</guid>
		<description><![CDATA[<p>&#160; 为了造一套门禁系统，淘宝上搞来了一套RFID读卡器。 RC522，看上去是比较多的型号，哪家店都买得到。 本来想拔整个模块装进一个接线盒里，但是这尺寸刚刚好，如果放进去就没法盖盖子了。。。无奈，先裸奔。   &#160; Youtube连接：https://www.youtube.com/watch?v=4yIT7Gunn6c 也是网上找来的代码 &#160; #include &#60;SPI.h&#62; #define uchar unsigned char #define uint unsigned int //data array maxium length #define MAX_LEN 16 ///////////////////////////////////////////////////////////////////// //set the pin ///////////////////////////////////////////////////////////////////// const int chipSelectPin = 10; const int NRSTPD = 5; &#160; //MF522 command bits #define PCD_IDLE 0x00 //NO action; cancel current commands #define PCD_AUTHENT [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/rc522-on-arduino/">RC522读RFID卡</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>&nbsp;</p>
<p>为了造一套门禁系统，淘宝上搞来了一套RFID读卡器。</p>
<p>RC522，看上去是比较多的型号，哪家店都买得到。</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_1938.jpg"><img class="alignnone size-large wp-image-880" alt="IMG_1938" src="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_1938-1024x682.jpg" width="625" height="416" /></a> <a href="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_1978.jpg"><img class="alignnone size-large wp-image-881" alt="IMG_1978" src="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_1978-1024x682.jpg" width="625" height="416" /></a></p>
<p><span id="more-879"></span></p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_2018.jpg"><img alt="IMG_2018" src="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_2018-1024x682.jpg" width="625" height="416" /></a></p>
<p>本来想拔整个模块装进一个接线盒里，但是这尺寸刚刚好，如果放进去就没法盖盖子了。。。无奈，先裸奔。</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_2012.jpg"><img class="alignnone size-large wp-image-882" alt="IMG_2012" src="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_2012-682x1024.jpg" width="625" height="938" /></a>  <a href="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_2029.jpg"><img class="alignnone size-large wp-image-884" alt="IMG_2029" src="http://heqichen.cn/wp/wp-content/uploads/2015/10/IMG_2029-1024x682.jpg" width="625" height="416" /></a></p>
<p>&nbsp;</p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMTM1MjU2Nzk2MA==/v.swf" /><param name="allowfullscreen" value="true" /><param name="quality" value="high" /><param name="allowscriptaccess" value="always" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMTM1MjU2Nzk2MA==/v.swf" allowfullscreen="true" quality="high" allowscriptaccess="always" align="middle" /></object></p>
<p>Youtube连接：<a href="https://www.youtube.com/watch?v=4yIT7Gunn6c">https://www.youtube.com/watch?v=4yIT7Gunn6c</a></p>
<p>也是网上找来的代码</p>
<blockquote><p>&nbsp;</p>
<p>#include &lt;SPI.h&gt;</p>
<p>#define uchar unsigned char<br />
#define uint unsigned int</p>
<p>//data array maxium length<br />
#define MAX_LEN 16</p>
<p>/////////////////////////////////////////////////////////////////////<br />
//set the pin<br />
/////////////////////////////////////////////////////////////////////<br />
const int chipSelectPin = 10;<br />
const int NRSTPD = 5;</p>
<p>&nbsp;</p>
<p>//MF522 command bits<br />
#define PCD_IDLE 0x00 //NO action; cancel current commands<br />
#define PCD_AUTHENT 0x0E //verify password key<br />
#define PCD_RECEIVE 0x08 //receive data<br />
#define PCD_TRANSMIT 0x04 //send data<br />
#define PCD_TRANSCEIVE 0x0C //send and receive data<br />
#define PCD_RESETPHASE 0x0F //reset<br />
#define PCD_CALCCRC 0x03 //CRC check and caculation</p>
<p>//Mifare_One card command bits<br />
#define PICC_REQIDL 0x26 //Search the cards that not into sleep mode in the antenna area<br />
#define PICC_REQALL 0x52 //Search all the cards in the antenna area<br />
#define PICC_ANTICOLL 0x93 //prevent conflict<br />
#define PICC_SElECTTAG 0x93 //select card<br />
#define PICC_AUTHENT1A 0x60 //verify A password key<br />
#define PICC_AUTHENT1B 0x61 //verify B password key<br />
#define PICC_READ 0x30 //read<br />
#define PICC_WRITE 0xA0 //write<br />
#define PICC_DECREMENT 0xC0 //deduct value<br />
#define PICC_INCREMENT 0xC1 //charge up value<br />
#define PICC_RESTORE 0xC2 //Restore data into buffer<br />
#define PICC_TRANSFER 0xB0 //Save data into buffer<br />
#define PICC_HALT 0x50 //sleep mode<br />
//THe mistake code that return when communicate with MF522<br />
#define MI_OK 0<br />
#define MI_NOTAGERR 1<br />
#define MI_ERR 2<br />
//------------------MFRC522 register ---------------<br />
//Page 0:Command and Status<br />
#define Reserved00 0x00<br />
#define CommandReg 0x01<br />
#define CommIEnReg 0x02<br />
#define DivlEnReg 0x03<br />
#define CommIrqReg 0x04<br />
#define DivIrqReg 0x05<br />
#define ErrorReg 0x06<br />
#define Status1Reg 0x07<br />
#define Status2Reg 0x08<br />
#define FIFODataReg 0x09<br />
#define FIFOLevelReg 0x0A<br />
#define WaterLevelReg 0x0B<br />
#define ControlReg 0x0C<br />
#define BitFramingReg 0x0D<br />
#define CollReg 0x0E<br />
#define Reserved01 0x0F<br />
//Page 1:Command<br />
#define Reserved10 0x10<br />
#define ModeReg 0x11<br />
#define TxModeReg 0x12<br />
#define RxModeReg 0x13<br />
#define TxControlReg 0x14<br />
#define TxAutoReg 0x15<br />
#define TxSelReg 0x16<br />
#define RxSelReg 0x17<br />
#define RxThresholdReg 0x18<br />
#define DemodReg 0x19<br />
#define Reserved11 0x1A<br />
#define Reserved12 0x1B<br />
#define MifareReg 0x1C<br />
#define Reserved13 0x1D<br />
#define Reserved14 0x1E<br />
#define SerialSpeedReg 0x1F<br />
//Page 2:CFG<br />
#define Reserved20 0x20<br />
#define CRCResultRegM 0x21<br />
#define CRCResultRegL 0x22<br />
#define Reserved21 0x23<br />
#define ModWidthReg 0x24<br />
#define Reserved22 0x25<br />
#define RFCfgReg 0x26<br />
#define GsNReg 0x27<br />
#define CWGsPReg 0x28<br />
#define ModGsPReg 0x29<br />
#define TModeReg 0x2A<br />
#define TPrescalerReg 0x2B<br />
#define TReloadRegH 0x2C<br />
#define TReloadRegL 0x2D<br />
#define TCounterValueRegH 0x2E<br />
#define TCounterValueRegL 0x2F<br />
//Page 3:TestRegister<br />
#define Reserved30 0x30<br />
#define TestSel1Reg 0x31<br />
#define TestSel2Reg 0x32<br />
#define TestPinEnReg 0x33<br />
#define TestPinValueReg 0x34<br />
#define TestBusReg 0x35<br />
#define AutoTestReg 0x36<br />
#define VersionReg 0x37<br />
#define AnalogTestReg 0x38<br />
#define TestDAC1Reg 0x39<br />
#define TestDAC2Reg 0x3A<br />
#define TestADCReg 0x3B<br />
#define Reserved31 0x3C<br />
#define Reserved32 0x3D<br />
#define Reserved33 0x3E<br />
#define Reserved34 0x3F<br />
//-----------------------------------------------</p>
<p>//4 bytes Serial number of card, the 5 bytes is verfiy bytes<br />
uchar serNum[5];</p>
<p>int AUTHED_ID_NUM = 8;</p>
<p>unsigned char AUTHED_ID_LIST[][4] =<br />
{<br />
{0x72, 0xBB, 0x7C, 0x6F},<br />
{0xF1, 0x6D, 0xB3, 0x85},<br />
{0x09, 0x11, 0x8F, 0x87},<br />
{0xCF, 0x9C, 0x24, 0x71},<br />
{0x88, 0x04, 0xBF, 0xC5},<br />
{0x88, 0x04, 0x5D, 0x9E},<br />
{0x88, 0x04, 0xF6, 0x8A},<br />
{0x88, 0x99, 0xA5, 0xCA}<br />
};</p>
<p>char *AUTHED_NAME_LIST[] =<br />
{<br />
"key-chain",<br />
"white-card",<br />
"Shanghai-transport",<br />
"Beijing-transport",<br />
"Guangzhou-Metro",<br />
"Shenzhen-Metro",<br />
"train-ticket #1",<br />
"train-ticket #2"<br />
};</p>
<p>&nbsp;</p>
<p>void setup()<br />
{<br />
Serial.begin(57600);</p>
<p>SPI.begin();</p>
<p>pinMode(chipSelectPin,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin<br />
digitalWrite(chipSelectPin, LOW); // Activate the RFID reader<br />
pinMode(NRSTPD,OUTPUT); // Set digital pin 5 , Not Reset and Power-down</p>
<p>MFRC522_Init();</p>
<p>pinMode(4, OUTPUT);<br />
digitalWrite(4, LOW);<br />
}</p>
<p>void showCardDetail()<br />
{</p>
<p>uchar status;<br />
uchar str[MAX_LEN];<br />
// Show card type<br />
ShowCardType(str);</p>
<p>//Prevent conflict, return the 4 bytes Serial number of the card<br />
status = MFRC522_Anticoll(str);</p>
<p>// str[0..3]: serial number of the card<br />
// str[4]: XOR checksum of the SN.<br />
if (status == MI_OK)<br />
{<br />
Serial.print("The card's number is: ");<br />
memcpy(serNum, str, 5);<br />
ShowCardID(serNum);</p>
<p>// Check people associated with card ID<br />
uchar* id = serNum;<br />
if( id[0]==0x4B &amp;&amp; id[1]==0xE6 &amp;&amp; id[2]==0xD1 &amp;&amp; id[3]==0x3B ) {<br />
Serial.println("Hello Mary!");<br />
} else if(id[0]==0x3B &amp;&amp; id[1]==0xE6 &amp;&amp; id[2]==0xD1 &amp;&amp; id[3]==0x3B) {<br />
Serial.println("Hello Greg!");<br />
}else{<br />
Serial.println("Hello unkown guy!");<br />
}<br />
}</p>
<p>}</p>
<p>unsigned long lastFoundTime = 0;<br />
int lastFoundCard = -1;</p>
<p>void loop()<br />
{</p>
<p>uchar status;<br />
uchar str[MAX_LEN];<br />
// Search card, return card types<br />
status = MFRC522_Request(PICC_REQIDL, str);<br />
if (status != MI_OK)<br />
{<br />
return;<br />
}</p>
<p>//showCardDetail();<br />
status = MFRC522_Anticoll(str);<br />
if (status == MI_OK)<br />
{<br />
memcpy(serNum, str, 5);<br />
uchar* id = serNum;<br />
int authedId = findInAuthedList(id);<br />
if (authedId &gt;= 0)<br />
{<br />
if (lastFoundCard != authedId || (millis() - lastFoundTime) &gt; 2000)<br />
{<br />
Serial.print("Card read: ");<br />
Serial.println(AUTHED_NAME_LIST[authedId]);<br />
lastFoundTime = millis();<br />
digitalWrite(4, HIGH);<br />
delay(50);<br />
digitalWrite(4, LOW);<br />
}</p>
<p>}<br />
else<br />
{<br />
Serial.print("unknown card found: ");<br />
ShowCardID(serNum);<br />
}<br />
lastFoundCard = authedId;<br />
}</p>
<p>MFRC522_Halt(); //command the card into sleep mode</p>
<p>delay(200);<br />
}</p>
<p>int findInAuthedList(uchar *id)<br />
{<br />
int i;<br />
int j;<br />
for (i=0; i&lt;AUTHED_ID_NUM; ++i)<br />
{<br />
for (j=0; j&lt;4; ++j)<br />
{<br />
if (AUTHED_ID_LIST[i][j] != id[j])<br />
{<br />
break;<br />
}<br />
}<br />
if(j &gt;= 4)<br />
{<br />
return i;<br />
}<br />
}<br />
return -1;<br />
}</p>
<p>/*<br />
* Function：ShowCardID<br />
* Description：Show Card ID<br />
* Input parameter：ID string<br />
* Return：Null<br />
*/<br />
void ShowCardID(uchar *id)<br />
{<br />
int IDlen=4;<br />
for(int i=0; i&lt;IDlen; i++){<br />
Serial.print(0x0F &amp; (id[i]&gt;&gt;4), HEX);<br />
Serial.print(0x0F &amp; id[i],HEX);<br />
}<br />
Serial.println("");<br />
}</p>
<p>/*<br />
* Function：ShowCardType<br />
* Description：Show Card type<br />
* Input parameter：Type string<br />
* Return：Null<br />
*/<br />
void ShowCardType(uchar* type)<br />
{<br />
Serial.print("Card type: ");<br />
if(type[0]==0x04&amp;&amp;type[1]==0x00)<br />
Serial.println("MFOne-S50");<br />
else if(type[0]==0x02&amp;&amp;type[1]==0x00)<br />
Serial.println("MFOne-S70");<br />
else if(type[0]==0x44&amp;&amp;type[1]==0x00)<br />
Serial.println("MF-UltraLight");<br />
else if(type[0]==0x08&amp;&amp;type[1]==0x00)<br />
Serial.println("MF-Pro");<br />
else if(type[0]==0x44&amp;&amp;type[1]==0x03)<br />
Serial.println("MF Desire");<br />
else<br />
Serial.println("Unknown");<br />
}</p>
<p>/*<br />
* Function：Write_MFRC5200<br />
* Description：write a byte data into one register of MR RC522<br />
* Input parameter：addr--register address；val--the value that need to write in<br />
* Return：Null<br />
*/<br />
void Write_MFRC522(uchar addr, uchar val)<br />
{<br />
digitalWrite(chipSelectPin, LOW);</p>
<p>//address format：0XXXXXX0<br />
SPI.transfer((addr&lt;&lt;1)&amp;0x7E);<br />
SPI.transfer(val);</p>
<p>digitalWrite(chipSelectPin, HIGH);<br />
}<br />
/*<br />
* Function：Read_MFRC522<br />
* Description：read a byte data into one register of MR RC522<br />
* Input parameter：addr--register address<br />
* Return：return the read value<br />
*/<br />
uchar Read_MFRC522(uchar addr)<br />
{<br />
uchar val;</p>
<p>digitalWrite(chipSelectPin, LOW);</p>
<p>//address format：1XXXXXX0<br />
SPI.transfer(((addr&lt;&lt;1)&amp;0x7E) | 0x80);<br />
val =SPI.transfer(0x00);</p>
<p>digitalWrite(chipSelectPin, HIGH);</p>
<p>return val;<br />
}</p>
<p>/*<br />
* Function：SetBitMask<br />
* Description：set RC522 register bit<br />
* Input parameter：reg--register address;mask--value<br />
* Return：null<br />
*/<br />
void SetBitMask(uchar reg, uchar mask)<br />
{<br />
uchar tmp;<br />
tmp = Read_MFRC522(reg);<br />
Write_MFRC522(reg, tmp | mask); // set bit mask<br />
}<br />
/*<br />
* Function：ClearBitMask<br />
* Description：clear RC522 register bit<br />
* Input parameter：reg--register address;mask--value<br />
* Return：null<br />
*/<br />
void ClearBitMask(uchar reg, uchar mask)<br />
{<br />
uchar tmp;<br />
tmp = Read_MFRC522(reg);<br />
Write_MFRC522(reg, tmp &amp; (~mask)); // clear bit mask<br />
}<br />
/*<br />
* Function：AntennaOn<br />
* Description：Turn on antenna, every time turn on or shut down antenna need at least 1ms delay<br />
* Input parameter：null<br />
* Return：null<br />
*/<br />
void AntennaOn(void)<br />
{<br />
uchar temp;</p>
<p>temp = Read_MFRC522(TxControlReg);<br />
if (!(temp &amp; 0x03))<br />
{<br />
SetBitMask(TxControlReg, 0x03);<br />
}<br />
}<br />
/*<br />
* Function：AntennaOff<br />
* Description：Turn off antenna, every time turn on or shut down antenna need at least 1ms delay<br />
* Input parameter：null<br />
* Return：null<br />
*/<br />
void AntennaOff(void)<br />
{<br />
ClearBitMask(TxControlReg, 0x03);<br />
}<br />
/*<br />
* Function：ResetMFRC522<br />
* Description： reset RC522<br />
* Input parameter：null<br />
* Return：null<br />
*/<br />
void MFRC522_Reset(void)<br />
{<br />
Write_MFRC522(CommandReg, PCD_RESETPHASE);<br />
}<br />
/*<br />
* Function：InitMFRC522<br />
* Description：initilize RC522<br />
* Input parameter：null<br />
* Return：null<br />
*/<br />
void MFRC522_Init(void)<br />
{<br />
digitalWrite(NRSTPD,HIGH);</p>
<p>MFRC522_Reset();</p>
<p>//Timer: TPrescaler*TreloadVal/6.78MHz = 24ms<br />
Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler<br />
Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg<br />
Write_MFRC522(TReloadRegL, 30);<br />
Write_MFRC522(TReloadRegH, 0);</p>
<p>Write_MFRC522(TxAutoReg, 0x40); //100%ASK<br />
Write_MFRC522(ModeReg, 0x3D); //CRC initilizate value 0x6363 ???</p>
<p>//ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0<br />
//Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0]<br />
//Write_MFRC522(RFCfgReg, 0x7F); //RxGain = 48dB</p>
<p>AntennaOn(); //turn on antenna<br />
}<br />
/*<br />
* Function：MFRC522_Request<br />
* Description：Searching card, read card type<br />
* Input parameter：reqMode--search methods，<br />
* TagType--return card types<br />
* 0x4400 = Mifare_UltraLight<br />
* 0x0400 = Mifare_One(S50)<br />
* 0x0200 = Mifare_One(S70)<br />
* 0x0800 = Mifare_Pro(X)<br />
* 0x4403 = Mifare_DESFire<br />
* return：return MI_OK if successed<br />
*/<br />
uchar MFRC522_Request(uchar reqMode, uchar *TagType)<br />
{<br />
uchar status;<br />
uint backBits; //the data bits that received</p>
<p>Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ???</p>
<p>TagType[0] = reqMode;<br />
status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &amp;backBits);</p>
<p>if ((status != MI_OK) || (backBits != 0x10))<br />
{<br />
status = MI_ERR;<br />
}</p>
<p>return status;<br />
}<br />
/*<br />
* Function：MFRC522_ToCard<br />
* Description：communicate between RC522 and ISO14443<br />
* Input parameter：command--MF522 command bits<br />
* sendData--send data to card via rc522<br />
* sendLen--send data length<br />
* backData--the return data from card<br />
* backLen--the length of return data<br />
* return：return MI_OK if successed<br />
*/<br />
uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)<br />
{<br />
uchar status = MI_ERR;<br />
uchar irqEn = 0x00;<br />
uchar waitIRq = 0x00;<br />
uchar lastBits;<br />
uchar n;<br />
uint i;</p>
<p>switch (command)<br />
{<br />
case PCD_AUTHENT: //verify card password<br />
{<br />
irqEn = 0x12;<br />
waitIRq = 0x10;<br />
break;<br />
}<br />
case PCD_TRANSCEIVE: //send data in the FIFO<br />
{<br />
irqEn = 0x77;<br />
waitIRq = 0x30;<br />
break;<br />
}<br />
default:<br />
break;<br />
}</p>
<p>Write_MFRC522(CommIEnReg, irqEn|0x80); //Allow interruption<br />
ClearBitMask(CommIrqReg, 0x80); //Clear all the interrupt bits<br />
SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO initilizate</p>
<p>Write_MFRC522(CommandReg, PCD_IDLE); //NO action;cancel current command ???</p>
<p>//write data into FIFO<br />
for (i=0; i&lt;sendLen; i++)<br />
{<br />
Write_MFRC522(FIFODataReg, sendData[i]);<br />
}</p>
<p>//procceed it<br />
Write_MFRC522(CommandReg, command);<br />
if (command == PCD_TRANSCEIVE)<br />
{<br />
SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts<br />
}</p>
<p>//waite receive data is finished<br />
i = 2000; //i should adjust according the clock, the maxium the waiting time should be 25 ms???<br />
do<br />
{<br />
//CommIrqReg[7..0]<br />
//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq<br />
n = Read_MFRC522(CommIrqReg);<br />
i--;<br />
}<br />
while ((i!=0) &amp;&amp; !(n&amp;0x01) &amp;&amp; !(n&amp;waitIRq));</p>
<p>ClearBitMask(BitFramingReg, 0x80); //StartSend=0</p>
<p>if (i != 0)<br />
{<br />
if(!(Read_MFRC522(ErrorReg) &amp; 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr<br />
{<br />
status = MI_OK;<br />
if (n &amp; irqEn &amp; 0x01)<br />
{<br />
status = MI_NOTAGERR; //??<br />
}</p>
<p>if (command == PCD_TRANSCEIVE)<br />
{<br />
n = Read_MFRC522(FIFOLevelReg);<br />
lastBits = Read_MFRC522(ControlReg) &amp; 0x07;<br />
if (lastBits)<br />
{<br />
*backLen = (n-1)*8 + lastBits;<br />
}<br />
else<br />
{<br />
*backLen = n*8;<br />
}</p>
<p>if (n == 0)<br />
{<br />
n = 1;<br />
}<br />
if (n &gt; MAX_LEN)<br />
{<br />
n = MAX_LEN;<br />
}</p>
<p>//read the data from FIFO<br />
for (i=0; i&lt;n; i++)<br />
{<br />
backData[i] = Read_MFRC522(FIFODataReg);<br />
}<br />
}<br />
}<br />
else<br />
{<br />
status = MI_ERR;<br />
}</p>
<p>}</p>
<p>//SetBitMask(ControlReg,0x80); //timer stops<br />
//Write_MFRC522(CommandReg, PCD_IDLE);</p>
<p>return status;<br />
}<br />
/*<br />
* Function：MFRC522_Anticoll<br />
* Description：Prevent conflict, read the card serial number<br />
* Input parameter：serNum--return the 4 bytes card serial number, the 5th byte is recheck byte<br />
* return：return MI_OK if successed<br />
*/<br />
uchar MFRC522_Anticoll(uchar *serNum)<br />
{<br />
uchar status;<br />
uchar i;<br />
uchar serNumCheck=0;<br />
uint unLen;</p>
<p>//ClearBitMask(Status2Reg, 0x08); //strSensclear<br />
//ClearBitMask(CollReg,0x80); //ValuesAfterColl<br />
Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]</p>
<p>serNum[0] = PICC_ANTICOLL;<br />
serNum[1] = 0x20;<br />
status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &amp;unLen);</p>
<p>if (status == MI_OK)<br />
{<br />
//Verify card serial number<br />
for (i=0; i&lt;4; i++)<br />
{<br />
serNumCheck ^= serNum[i];<br />
}<br />
if (serNumCheck != serNum[i])<br />
{<br />
status = MI_ERR;<br />
}<br />
}</p>
<p>//SetBitMask(CollReg, 0x80); //ValuesAfterColl=1</p>
<p>return status;<br />
}<br />
/*<br />
* Function：CalulateCRC<br />
* Description：Use MF522 to caculate CRC<br />
* Input parameter：pIndata--the CRC data need to be read，len--data length，pOutData-- the caculated result of CRC<br />
* return：Null<br />
*/<br />
void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)<br />
{<br />
uchar i, n;</p>
<p>ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0<br />
SetBitMask(FIFOLevelReg, 0x80); //Clear FIFO pointer<br />
//Write_MFRC522(CommandReg, PCD_IDLE);</p>
<p>//Write data into FIFO<br />
for (i=0; i&lt;len; i++)<br />
{<br />
Write_MFRC522(FIFODataReg, *(pIndata+i));<br />
}<br />
Write_MFRC522(CommandReg, PCD_CALCCRC);</p>
<p>//waite CRC caculation to finish<br />
i = 0xFF;<br />
do<br />
{<br />
n = Read_MFRC522(DivIrqReg);<br />
i--;<br />
}<br />
while ((i!=0) &amp;&amp; !(n&amp;0x04)); //CRCIrq = 1</p>
<p>//read CRC caculation result<br />
pOutData[0] = Read_MFRC522(CRCResultRegL);<br />
pOutData[1] = Read_MFRC522(CRCResultRegM);<br />
}</p>
<p>&nbsp;</p>
<p>/*<br />
* Function：MFRC522_Write<br />
* Description：write block data<br />
* Input parameters：blockAddr--block address;writeData--Write 16 bytes data into block<br />
* return：return MI_OK if successed<br />
*/<br />
uchar MFRC522_Write(uchar blockAddr, uchar *writeData)<br />
{<br />
uchar status;<br />
uint recvBits;<br />
uchar i;<br />
uchar buff[18];</p>
<p>buff[0] = PICC_WRITE;<br />
buff[1] = blockAddr;<br />
CalulateCRC(buff, 2, &amp;buff[2]);<br />
status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &amp;recvBits);</p>
<p>if ((status != MI_OK) || (recvBits != 4) || ((buff[0] &amp; 0x0F) != 0x0A))<br />
{<br />
status = MI_ERR;<br />
}</p>
<p>if (status == MI_OK)<br />
{<br />
for (i=0; i&lt;16; i++) //Write 16 bytes data into FIFO<br />
{<br />
buff[i] = *(writeData+i);<br />
}<br />
CalulateCRC(buff, 16, &amp;buff[16]);<br />
status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &amp;recvBits);</p>
<p>if ((status != MI_OK) || (recvBits != 4) || ((buff[0] &amp; 0x0F) != 0x0A))<br />
{<br />
status = MI_ERR;<br />
}<br />
}</p>
<p>return status;<br />
}<br />
/*<br />
* Function：MFRC522_Halt<br />
* Description：Command the cards into sleep mode<br />
* Input parameters：null<br />
* return：null<br />
*/<br />
void MFRC522_Halt(void)<br />
{<br />
uchar status;<br />
uint unLen;<br />
uchar buff[4];</p>
<p>buff[0] = PICC_HALT;<br />
buff[1] = 0;<br />
CalulateCRC(buff, 2, &amp;buff[2]);</p>
<p>status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&amp;unLen);<br />
}</p></blockquote>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="879">6,633&nbsp;total views, no views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/rc522-on-arduino/">RC522读RFID卡</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/rc522-on-arduino/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解决Mac上无法对Arduino Nano编程的问题</title>
		<link>http://heqichen.cn/wp/solving-nano-problem-on-mac/</link>
		<comments>http://heqichen.cn/wp/solving-nano-problem-on-mac/#comments</comments>
		<pubDate>Tue, 04 Feb 2014 05:30:28 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=58</guid>
		<description><![CDATA[<p>用Mac对Nano编程，但是碰到了这个问题 点击下载后，出现了这个问题 avrdude: stk500_recv(): programmer is not responding 我能保证Board和Serial都没有选错，板子型号为: Arduino Nano w/ ATmega328, 串口为: /dev/tty.usbserial-A92D9FNR，但是还是出现问题。 截图当中，为了模拟这个问题，所以将串口选到了/dev/tty.Bluetooth-incoming-Port，所以，出现这个问题，第一就应该先检查板子型号和对应的串口名称，因为最可能是这方面出现的错误。 经过搜索，发现网上也有同样的问题： http://forum.arduino.cc/index.php?topic=123573.0全文如下 I had the same problem! If you are using an Arduino Nano w/ OSX you need to install the drivers. Download and execute it: http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_14.dmg And you'll find this files: FTDIUSBSerialDriver_10_3.pkg which is specific to OSX 10.3 [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/solving-nano-problem-on-mac/">解决Mac上无法对Arduino Nano编程的问题</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>用Mac对Nano编程，但是碰到了这个问题</p>
<p><a href="http://heqichen.cn/wp/wp-content/uploads/2014/02/Screen-Shot-2014-02-04-at-1.18.31-PM.png"><img class="alignnone size-full wp-image-59" alt="Screen Shot 2014-02-04 at 1.18.31 PM" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/Screen-Shot-2014-02-04-at-1.18.31-PM.png" width="640" data-pinit="registered" /></a></p>
<p>点击下载后，出现了这个问题<br />
<font color="red">avrdude: stk500_recv(): programmer is not responding</font><br />
我能保证Board和Serial都没有选错，板子型号为: <b>Arduino Nano w/ ATmega328</b>, 串口为: <b>/dev/tty.usbserial-A92D9FNR</b>，但是还是出现问题。<br />
截图当中，为了模拟这个问题，所以将串口选到了<b>/dev/tty.Bluetooth-incoming-Port</b>，所以，出现这个问题，第一就应该先检查板子型号和对应的串口名称，因为最可能是这方面出现的错误。 </p>
<p>经过搜索，发现网上也有同样的问题：<br />
<a href="http://forum.arduino.cc/index.php?topic=123573.0" target="_blank">http://forum.arduino.cc/index.php?topic=123573.0</a><br />全文如下</p>
<p><q></p>
<pre>
I had the same problem!

If you are using an Arduino Nano w/ OSX you need to install the drivers.

Download and execute it:

http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_14.dmg

And you'll find this files:

    FTDIUSBSerialDriver_10_3.pkg which is specific to OSX 10.3 (Panther)
    FTDIUSBSerialDriver_10_4_10_5_10_6.pkg which is specific to OSX 10.4 (Tiger), OSX 10.5 (Leopard)
    and 10.6 (Snow Leopard).


Execute "FTDIUSBSerialDriver_10_4_10_5_10_6.pkg" if you are using OSX 10.5+ (Leopard+)

Best!
</pre>
<p></q></p>
<p>所以，到这个网址下载最新的FTDI驱动，安装好就可以使用了 <img src="http://heqichen.cn/wp/wp-includes/images/smilies/icon_smile.gif" alt=":-)" class="wp-smiley" /> <br />
<a href="http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_14.dmg">http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_14.dmg</a></p>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="58">2,313&nbsp;total views, no views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/solving-nano-problem-on-mac/">解决Mac上无法对Arduino Nano编程的问题</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/solving-nano-problem-on-mac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino控制多电调控制测试</title>
		<link>http://heqichen.cn/wp/arduino-multiple-esc/</link>
		<comments>http://heqichen.cn/wp/arduino-multiple-esc/#comments</comments>
		<pubDate>Fri, 27 May 2011 19:54:28 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=239</guid>
		<description><![CDATA[<p>很长时间没折腾了，因为前段时间忙家里的事情、学校的事情，所以就耽搁了。昨天搞了一个通宵，搞定了今天上午的一个报告，下午就继续搞飞机了。 我们原定的目标就是通过Arduino来作为四轴飞行器的控制板，那么必然就需要用Arduino来控制四个电机的转速，其实就是多PWM输出。在去年我已经实现了单电机的输出，发现了不少问题。 首先，舵机的信号格式和我们用的电调的信号格式是相同的，一般来说，航模上的电调信号线接于接收器的三号通道上，但是，如果接在别的通道上也是能正常工作的，这也证明了他们之间信号是相同的。 但是，上次通过Arduino上的Servo库来控制电机时，发现Servo库输出的pwm宽度会超过电调接收的范围，从而导致电机无法启动。然而，通过遥控器遥控时就不存在这个问题。所以，我今天就首先对遥控器的pwm信号进行测量，然后对Arduino输出的pwm信号进行测量。然后计算出控制方式。注意：这里的pwm信号是通过Arudino上Servo库输出的pwm信号，它是脉冲宽度调制，不是Arduino默认的pwm，默认的pwm是通过占空比来模拟一个模拟量。 好了，不多说，上图。 首先，测试电池是否有能力带动两个电机同时稳定地工作，我用遥控器电路对他们进行了测试。先搭建了一个下图所示的电路，进行测试。 http://v.youku.com/v_show/id_XMjcwNzAxNzY0.html 然后就需要测量遥控器输出的脉冲宽度和Arduino输出的脉冲宽度，搭了下面这个电路。为此我还去买了能测占空比的ut10a，但是那个万用表实在不给力，根本没有办法量到数据。-_-b 这张图当中电调只是起到供电的作用，所以并没有连电机。 无奈，但是发现Arduino有pulseIn()这个函数，可以计算一个高电平或低电平持续时间，正好，把数据拿下了。 最高位： 1900us 最低位： 1100us 那么就碰到了另外一个问题，既然没有仪器来测量脉冲宽度，那如何去测量Arduino输出的PWM脉冲的宽度呢？我在万念俱灰的情况下，把两个Arduino上的数字端口连在了一起，就像下面图中的一样，看看是否能自己测量自己。 结果很出乎意料，居然得到数据了，真的很佩服Arduino写底层库的人，中断控制得如此完美:-) 可以看到，Servo库在输出0时，对应的脉冲宽度为522ms；而输出180时，对应的脉冲宽度为2373ms。远远大于遥控器输出的范围，所以导致一开始电调无法识别Arduino的pwm信号。这样经过简单的计算就可得出，电调的最低位应为56度，最高位应为133度。:-D 有了这个重要的数据，下面就可以用它来控制电机了。不过首先还是先让程序控制舵机，保证他能正常运行，呵呵。 测试通过之后，就上电机啦。通过控制板上的两个旋钮，其实就是可变电阻，来控制电机的速度。 上视频 http://v.youku.com/v_show/id_XMjcwNzA0MDAw.html 控制板特写 右边的电源模块特写，整个系统的动力电源和控制电源分为两路，控制电源由我自己做的手机电池包来提供． 电机特写，呵呵，山寨味道太浓了 最后，我测了下电机的电流，在两个电机空载，半油门的情况下，电流为4A左右。这两个电机都是经过风风雨雨的，什么坠机、落水都经历过，轴已经有点不正常了，所以也只是带大概估计一下。 下面就是测试程序 #include &#60;Servo.h&#62; //Author: HE Qichen //Date: 2011-5-27 //Website: http://heqichen.cn //Email: heqichen(a)gmail.com #define inputPin1 A8 #define inputPin2 A9 #define motorPin1 5 #define motorPin2 6 Servo motor1; Servo motor2; void setup() [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/arduino-multiple-esc/">Arduino控制多电调控制测试</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>很长时间没折腾了，因为前段时间忙家里的事情、学校的事情，所以就耽搁了。昨天搞了一个通宵，搞定了今天上午的一个报告，下午就继续搞飞机了。</p>
<p>我们原定的目标就是通过Arduino来作为四轴飞行器的控制板，那么必然就需要用Arduino来控制四个电机的转速，其实就是多PWM输出。在去年我已经实现了单电机的输出，发现了不少问题。</p>
<p>首先，舵机的信号格式和我们用的电调的信号格式是相同的，一般来说，航模上的电调信号线接于接收器的三号通道上，但是，如果接在别的通道上也是能正常工作的，这也证明了他们之间信号是相同的。</p>
<p>但是，上次通过Arduino上的Servo库来控制电机时，发现Servo库输出的pwm宽度会超过电调接收的范围，从而导致电机无法启动。然而，通过遥控器遥控时就不存在这个问题。所以，我今天就首先对遥控器的pwm信号进行测量，然后对Arduino输出的pwm信号进行测量。然后计算出控制方式。注意：这里的pwm信号是通过Arudino上Servo库输出的pwm信号，它是脉冲宽度调制，不是Arduino默认的pwm，默认的pwm是通过占空比来模拟一个模拟量。</p>
<p>好了，不多说，上图。</p>
<p>首先，测试电池是否有能力带动两个电机同时稳定地工作，我用遥控器电路对他们进行了测试。先搭建了一个下图所示的电路，进行测试。</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052801.jpg" data-pinit="registered" /></p>
<p class="video"><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMjcwNzAxNzY0/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMjcwNzAxNzY0/v.swf" quality="high" allowscriptaccess="sameDomain" align="middle" /></object><br />
<a href="http://v.youku.com/v_show/id_XMjcwNzAxNzY0.html">http://v.youku.com/v_show/id_XMjcwNzAxNzY0.html</a></p>
<p>然后就需要测量遥控器输出的脉冲宽度和Arduino输出的脉冲宽度，搭了下面这个电路。为此我还去买了能测占空比的ut10a，但是那个万用表实在不给力，根本没有办法量到数据。-_-b</p>
<p>这张图当中电调只是起到供电的作用，所以并没有连电机。</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052802.jpg" data-pinit="registered" /></p>
<p>无奈，但是发现Arduino有pulseIn()这个函数，可以计算一个高电平或低电平持续时间，正好，把数据拿下了。</p>
<pre class="code">最高位：	1900us
最低位：	1100us</pre>
<p>那么就碰到了另外一个问题，既然没有仪器来测量脉冲宽度，那如何去测量Arduino输出的PWM脉冲的宽度呢？我在万念俱灰的情况下，把两个Arduino上的数字端口连在了一起，就像下面图中的一样，看看是否能自己测量自己。</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052803.jpg" data-pinit="registered" /></p>
<p>结果很出乎意料，居然得到数据了，真的很佩服Arduino写底层库的人，中断控制得如此完美:-)</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052804.jpg" data-pinit="registered" /><br />
<img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052805.jpg" data-pinit="registered" /></p>
<p>可以看到，Servo库在输出0时，对应的脉冲宽度为522ms；而输出180时，对应的脉冲宽度为2373ms。远远大于遥控器输出的范围，所以导致一开始电调无法识别Arduino的pwm信号。这样经过简单的计算就可得出，电调的最低位应为56度，最高位应为133度。:-D</p>
<p>有了这个重要的数据，下面就可以用它来控制电机了。不过首先还是先让程序控制舵机，保证他能正常运行，呵呵。</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052806.jpg" data-pinit="registered" /></p>
<p>测试通过之后，就上电机啦。通过控制板上的两个旋钮，其实就是可变电阻，来控制电机的速度。</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052807.jpg" data-pinit="registered" /></p>
<p>上视频</p>
<p class="video"><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMjcwNzA0MDAw/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMjcwNzA0MDAw/v.swf" quality="high" allowscriptaccess="sameDomain" align="middle" /></object><br />
<a href="http://v.youku.com/v_show/id_XMjcwNzA0MDAw.html">http://v.youku.com/v_show/id_XMjcwNzA0MDAw.html</a></p>
<p>控制板特写</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052808.jpg" data-pinit="registered" /></p>
<p>右边的电源模块特写，整个系统的动力电源和控制电源分为两路，控制电源由我自己做的手机电池包来提供．</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052809.jpg" data-pinit="registered" /></p>
<p>电机特写，呵呵，山寨味道太浓了</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052810.jpg" data-pinit="registered" /></p>
<p>最后，我测了下电机的电流，在两个电机空载，半油门的情况下，电流为4A左右。这两个电机都是经过风风雨雨的，什么坠机、落水都经历过，轴已经有点不正常了，所以也只是带大概估计一下。</p>
<p><img class="photo" alt="img" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011052811.jpg" data-pinit="registered" /></p>
<p>下面就是测试程序</p>
<pre class="code">#include &lt;Servo.h&gt;

//Author:	HE Qichen
//Date:	2011-5-27
//Website:	http://heqichen.cn
//Email:	heqichen(a)gmail.com

#define inputPin1  A8
#define inputPin2  A9

#define motorPin1  5
#define motorPin2  6

Servo motor1;
Servo motor2;

void setup()
{
  motor1.attach(motorPin1);
  motor2.attach(motorPin2);
  motor1.write(motorSpeedTransfer(0));
  motor2.write(motorSpeedTransfer(0));
  Serial.begin(9600);
}

void loop()
{
  int input1, input2;
  int speed1, speed2;
  input1 = analogRead(inputPin1);
  input2 = analogRead(inputPin2);
  speed1 = motorSpeedTransfer(input1);
  speed2 = motorSpeedTransfer(input2);
  motor1.write(speed1);
  motor2.write(speed2);
  Serial.print("#1 value: ");
  Serial.print(speed1, DEC);
  Serial.print("    #2 value: ");
  Serial.println(speed2, DEC);

  delay(500);
}

int motorSpeedTransfer(int s)
{
  return (s/13 + 56);
}</pre>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="239">3,255&nbsp;total views, no views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/arduino-multiple-esc/">Arduino控制多电调控制测试</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/arduino-multiple-esc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>遥控小车的改造</title>
		<link>http://heqichen.cn/wp/hack-toy-car/</link>
		<comments>http://heqichen.cn/wp/hack-toy-car/#comments</comments>
		<pubDate>Mon, 02 May 2011 19:56:50 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=242</guid>
		<description><![CDATA[<p>今天完成了遥控车的改造，这是自主控制的第一步。这辆车是在淘宝上买的，结构很简单，控制很简陋。方向就是将电机打死，这时候电流会非常大，而且对于将来的自主移动的精细控制带来不利因素。所以很早就想把它改成舵机控制的了，下面就是整个改造的过程。 这就是需要改造的部分。 先将需要改造的部分画下来，便于设计框架结构。我不是机械出身的，所以就画个大概吧。 结构图完成 在图纸上设计新的结构 根据设计切割材料 最后完成的样子，由于是临时电路，也就没固定，看上去有点像垃圾车-_-b 改造部分的特写 再来一张 这些只是机械部份，然后就是控制部份。由于舵机能够转动的角度范围到180度，而该车的转向轮仅能转动在30-40度之间。同时，自主移动机器人目标是在Arduino上面开发。所以我就一步到位，先用Arduino读取天地飞的pwm信号，然后经过转换，输出新的pwm信号给舵机，这样就不会因为卡住而损坏舵机了。 最后效果如下 http://v.youku.com/v_show/id_XMjYzOTc2NzA4.html 使用的程序非常简单，如下： #include &#60;Servo.h&#62; //Author: HE Qichen //Date: 2011-5-3 //Website: http://heqichen.cn //Email: heqichen(a)gmail.com Servo directionServo; void setup() { pinMode(2, INPUT); directionServo.attach(3); } void loop() { int t, a; t = pulseIn(2, HIGH); a = map(t, 1000, 2000, 65, 115); directionServo.write(a); } 1,929&#160;total views, no [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/hack-toy-car/">遥控小车的改造</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>今天完成了遥控车的改造，这是自主控制的第一步。这辆车是在淘宝上买的，结构很简单，控制很简陋。方向就是将电机打死，这时候电流会非常大，而且对于将来的自主移动的精细控制带来不利因素。所以很早就想把它改成舵机控制的了，下面就是整个改造的过程。</p>
<p>这就是需要改造的部分。</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050301.jpg" alt="photo" ></p>
<p>先将需要改造的部分画下来，便于设计框架结构。我不是机械出身的，所以就画个大概吧。</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050302.jpg" alt="photo" ></p>
<p>结构图完成</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050303.jpg" alt="photo" ></p>
<p>在图纸上设计新的结构</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050304.jpg" alt="photo" ></p>
<p>根据设计切割材料</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050305.jpg" alt="photo" ></p>
<p>最后完成的样子，由于是临时电路，也就没固定，看上去有点像垃圾车-_-b</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050306.jpg" alt="photo" ></p>
<p>改造部分的特写</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050307.jpg" alt="photo" ></p>
<p>再来一张</p>
<p><img class="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050308.jpg" alt="photo" ></p>
<p>这些只是机械部份，然后就是控制部份。由于舵机能够转动的角度范围到180度，而该车的转向轮仅能转动在30-40度之间。同时，自主移动机器人目标是在Arduino上面开发。所以我就一步到位，先用Arduino读取天地飞的pwm信号，然后经过转换，输出新的pwm信号给舵机，这样就不会因为卡住而损坏舵机了。</p>
<p>最后效果如下</p>
<p class="video">
<embed src="http://player.youku.com/player.php/sid/XMjYzOTc2NzA4/v.swf" quality="high" width="480" height="400" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed><br />
<a href="http://v.youku.com/v_show/id_XMjYzOTc2NzA4.html">http://v.youku.com/v_show/id_XMjYzOTc2NzA4.html</a>
</p>
<p>使用的程序非常简单，如下：</p>
<pre class="code">

#include &lt;Servo.h&gt;

//Author:	HE Qichen
//Date:	2011-5-3
//Website:	http://heqichen.cn
//Email:	heqichen(a)gmail.com

Servo directionServo;

void setup()
{
  pinMode(2, INPUT);
  directionServo.attach(3);
  
}

void loop()
{
  int t, a;
  t = pulseIn(2, HIGH);
  a = map(t, 1000, 2000, 65, 115);
  directionServo.write(a);
  
  
}
</pre>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="242">1,929&nbsp;total views, no views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/hack-toy-car/">遥控小车的改造</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/hack-toy-car/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arduino读取g-sensor数据</title>
		<link>http://heqichen.cn/wp/arduino-read-accelerometer/</link>
		<comments>http://heqichen.cn/wp/arduino-read-accelerometer/#comments</comments>
		<pubDate>Sun, 01 May 2011 19:58:56 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=244</guid>
		<description><![CDATA[<p>在四轴飞行器上除了要有陀螺仪外，还要有个重要的传感器就是重力传感器。由于它们各自的误差，若使用单一的传感器会造成严重的精读问题，使飞行器丧失稳定性。所以要用两个传感器进行相互矫正。 现在重力传感器应用非常广，目前iphone等智能手机上都有重力传感器，包括笔者的一台山寨手机上都有重力传感器。 这次就是要用Android来读取重力传感器的数据。这个重力传感器模块是从淘宝购买的，模块非常简单，自己够买芯片来焊接也不成问题。根据它的datasheet，就能够知道如何使用这款重力加速度模块了。下面就进行详细的介绍 这个模块使用的芯片型号是MMA7260Q，(datasheet下载[PDF,229KB])，测试中的电路就是下面图片中的样子 控制的目标是通过重力传感器的数据来控制舵机的转动。但是发现会有少量的抖动，于是在程序中加入了一个简单的滤波器，阶数没有仔细调，但是基本上能够进行控制了。 http://v.youku.com/v_show/id_XMjYzNjIyODIw.html 下面是芯片的特写 下面是用到的代码 #include &#60;Servo.h&#62; //Author: HE Qichen //Email: heqichen(a)gmail.com //Website: http://heqichen.cn //Date: 2011-5-2 #define FILTER_LEVEL 3 class Filter { private: int buffer[FILTER_LEVEL]; public: Filter() { int i; for (i=0; i&#60;FILTER_LEVEL; ++i) { buffer[i] = 0; } } int filter(int value) { int i; int sum; for (i=0; i&#60;FILTER_LEVEL-1; ++i) [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/arduino-read-accelerometer/">Arduino读取g-sensor数据</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>在四轴飞行器上除了要有陀螺仪外，还要有个重要的传感器就是重力传感器。由于它们各自的误差，若使用单一的传感器会造成严重的精读问题，使飞行器丧失稳定性。所以要用两个传感器进行相互矫正。</p>
<p>现在重力传感器应用非常广，目前iphone等智能手机上都有重力传感器，包括笔者的一台山寨手机上都有重力传感器。</p>
<p>这次就是要用Android来读取重力传感器的数据。这个重力传感器模块是从淘宝购买的，模块非常简单，自己够买芯片来焊接也不成问题。根据它的datasheet，就能够知道如何使用这款重力加速度模块了。下面就进行详细的介绍</p>
<p>这个模块使用的芯片型号是MMA7260Q，(datasheet<a href="/promotion/download/25270_MOTOROLA_MMA7260Q.pdf">下载</a>[PDF,229KB])，测试中的电路就是下面图片中的样子</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050201.jpg" data-pinit="registered" /></p>
<p>控制的目标是通过重力传感器的数据来控制舵机的转动。但是发现会有少量的抖动，于是在程序中加入了一个简单的滤波器，阶数没有仔细调，但是基本上能够进行控制了。</p>
<p class="video"><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMjYzNjIyODIw/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMjYzNjIyODIw/v.swf" quality="high" allowscriptaccess="sameDomain" align="middle" /></object><br />
<a href="http://v.youku.com/v_show/id_XMjYzNjIyODIw.html">http://v.youku.com/v_show/id_XMjYzNjIyODIw.html</a></p>
<p>下面是芯片的特写</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050202.jpg" data-pinit="registered" /><br />
<img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050203.jpg" data-pinit="registered" /><br />
<span id="more-244"></span></p>
<p>下面是用到的代码</p>
<pre class="code">#include &lt;Servo.h&gt;

//Author:  HE Qichen
//Email:  heqichen(a)gmail.com
//Website:  http://heqichen.cn
//Date:  2011-5-2

#define FILTER_LEVEL  3

class Filter
{
  private:
    int buffer[FILTER_LEVEL];
  public:
    Filter()
    {
      int i;
      for (i=0; i&lt;FILTER_LEVEL; ++i)
      {
        buffer[i] = 0;
      }
    }
    int filter(int value)
    {
      int i;
      int sum;
      for (i=0; i&lt;FILTER_LEVEL-1; ++i)
      {
        buffer[i] = buffer[i+1];
      }
      buffer[FILTER_LEVEL-1] = value;
      sum = 0;
      for (i=0; i&lt;FILTER_LEVEL; ++i)
      {
        sum += buffer[i];
      }
      return sum / FILTER_LEVEL;
    }
};

Servo testServo;
Filter xFilter, yFilter, zFilter;

void setup()
{
  Serial.begin(9600);
  testServo.attach(2);
}

void loop()
{
  int gx, gy, gz;
  gx = analogRead(A0);
  gy = analogRead(A1);
  gz = analogRead(A2);

  Serial.print("x: ");
  Serial.print(gx, DEC);
  Serial.print("  y: ");
  Serial.print(gy, DEC);
  Serial.print("  z: ");
  Serial.println(gz, DEC);

  int fgx, fgy, fgz;
  fgx = xFilter.filter(gx);
  fgy = yFilter.filter(gy);
  fgz = zFilter.filter(gz);
  Serial.print("  fx: ");
  Serial.print(fgx, DEC);
  Serial.print("  fy: ");
  Serial.print(fgy, DEC);
  Serial.print("  fz: ");
  Serial.println(fgz, DEC);

  testServo.write((fgz-100)/3);
  //delay(10);

}</pre>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="244">1,875&nbsp;total views, 3&nbsp;views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/arduino-read-accelerometer/">Arduino读取g-sensor数据</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/arduino-read-accelerometer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在Arduino上使用陀螺仪控制舵机</title>
		<link>http://heqichen.cn/wp/arduino-control-servo-using-gyro/</link>
		<comments>http://heqichen.cn/wp/arduino-control-servo-using-gyro/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 20:08:08 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=250</guid>
		<description><![CDATA[<p>今天拿到了四轴飞行器的一个重要部件，就是陀螺仪。^_^ 下面这张图上的就是了，这是一个三轴陀螺仪，seeedstudio GROVE套装的一个部件。 这个陀螺仪使用ITG3200芯片，可以直接使用了I2C接口连接到Arduino上面。默认的地址是0x68，但是可以修改成0x69，只要将板子上的JP1连起来就可以修改。接口四个针脚的定义就像下面这张图中所画的。 是的。。你没看错，他们用红色作为地线 -_-b 舵机就是最简单的使用pwm的口就可以了。最后链接成下面这张图中的样子。 我写了一个程序，代码在下方，能够做到让陀螺仪的转动直接反应在舵机的摇臂上面。但是，这样也会遇到问题，就是当动的次数比较多的时候，舵机的角度就会越来越大，直到超过最大的范围，所以这也是陀螺仪不是很精确的地方。另外就是，在陀螺仪静止的情况下，z轴的输出不为0，始终为-1。也就是说，这个陀螺仪的零点可能是不准确的，同时，正负转动的也有可能有差别，不知道这回对将来飞控算法带来多大的影响。 最后用到的程序就是下面这段。 #include &#60;Wire.h&#62; #include &#60;Servo.h&#62; #define GYRO_ADDR 0x68 Servo servo; int currentPos; void setup() { Wire.begin(); initGyro(); servo.attach(2); currentPos = 90; //Serial.begin(9600); pinMode(3, INPUT); } void loop() { int x; int v; x = readx(); v = ready(); v = readz(); currentPos = currentPos + x; int [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/arduino-control-servo-using-gyro/">在Arduino上使用陀螺仪控制舵机</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>今天拿到了四轴飞行器的一个重要部件，就是陀螺仪。^_^ 下面这张图上的就是了，这是一个三轴陀螺仪，seeedstudio GROVE套装的一个部件。</p>
<p><img class="photo" title="gyro" alt="gyro" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050101.jpg" data-pinit="registered" /></p>
<p>这个陀螺仪使用ITG3200芯片，可以直接使用了I2C接口连接到Arduino上面。默认的地址是0x68，但是可以修改成0x69，只要将板子上的JP1连起来就可以修改。接口四个针脚的定义就像下面这张图中所画的。</p>
<p><img class="photo" title="gyro pin define" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050102.jpg" data-pinit="registered" /></p>
<p>是的。。你没看错，他们用红色作为地线 -_-b<br />
<span id="more-250"></span></p>
<p>舵机就是最简单的使用pwm的口就可以了。最后链接成下面这张图中的样子。</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050103.jpg" data-pinit="registered" /></p>
<p>我写了一个程序，代码在下方，能够做到让陀螺仪的转动直接反应在舵机的摇臂上面。但是，这样也会遇到问题，就是当动的次数比较多的时候，舵机的角度就会越来越大，直到超过最大的范围，所以这也是陀螺仪不是很精确的地方。另外就是，在陀螺仪静止的情况下，z轴的输出不为0，始终为-1。也就是说，这个陀螺仪的零点可能是不准确的，同时，正负转动的也有可能有差别，不知道这回对将来飞控算法带来多大的影响。</p>
<p>最后用到的程序就是下面这段。</p>
<pre class="code">#include &lt;Wire.h&gt;
#include &lt;Servo.h&gt;

#define GYRO_ADDR  0x68

Servo servo;

int currentPos;

void setup()
{
  Wire.begin();
  initGyro();
  servo.attach(2);
  currentPos = 90;
  //Serial.begin(9600);
  pinMode(3, INPUT);
}

void loop()
{
  int x;
  int v;
  x = readx();
  v = ready();
  v = readz();
  currentPos = currentPos + x;

  int buttonState;
  buttonState = digitalRead(3);
  if (buttonState == HIGH)
  {

    currentPos = 90;
  }
  else
  {
    //Serial.println("LOW");
  }

  servo.write(currentPos);

}

int readx()
{
  int x;
  x = readGyro(0x1d, 0x1e);
  return x;
}

int ready()
{
  int y;
  y = readGyro(0x1f, 0x20);
  return y;
}

int readz()
{
  int z;
  z = readGyro(0x21, 0x22);
  return z;
}

char readGyro(unsigned char addrH, unsigned char addrL)
{
  char ret;
  Wire.beginTransmission(GYRO_ADDR);
  Wire.send(addrH);
  Wire.endTransmission();
  Wire.requestFrom(GYRO_ADDR, 1);
  if (Wire.available() &gt; 0)
  {
    ret = Wire.receive();
  }
  Wire.beginTransmission(GYRO_ADDR);
  Wire.send(addrL);
  Wire.endTransmission();
  Wire.requestFrom(GYRO_ADDR, 1);
  if (Wire.available() &gt; 0)
  {
    ret != Wire.receive()&lt;&lt;8;
  }

  return ret;
}

void initGyro()
{
  Wire.beginTransmission(GYRO_ADDR);
  Wire.send(0x3E);
  Wire.send(0x80);  //send a reset to the device
  Wire.endTransmission(); //end transmission

  Wire.beginTransmission(GYRO_ADDR);
  Wire.send(0x15);
  Wire.send(0x00);   //sample rate divider
  Wire.endTransmission(); //end transmission

  Wire.beginTransmission(GYRO_ADDR);
  Wire.send(0x16);
  Wire.send(0x18); // ±2000 degrees/s (default value)
  Wire.endTransmission(); //end transmission
}</pre>
<p>程序当中Wire库就是使用I2C，具体文档可以看下面的链接。</p>
<p><a href="http://arduino.cc/en/Reference/Wire">http://arduino.cc/en/Reference/Wire</a><br />
<object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMjYzMTg2ODQ0/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMjYzMTg2ODQ0/v.swf" quality="high" allowscriptaccess="sameDomain" align="middle" /></object><br />
<a href="http://v.youku.com/v_show/id_XMjYzMTg2ODQ0.html">http://v.youku.com/v_show/id_XMjYzMTg2ODQ0.html</a>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="250">1,972&nbsp;total views, no views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/arduino-control-servo-using-gyro/">在Arduino上使用陀螺仪控制舵机</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/arduino-control-servo-using-gyro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>嵌入之梦-圆梦小车开发</title>
		<link>http://heqichen.cn/wp/embedreamcar/</link>
		<comments>http://heqichen.cn/wp/embedreamcar/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 20:04:19 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=248</guid>
		<description><![CDATA[<p>今天看到一台嵌入之梦的小车，但是上电之后发了疯似的乱跑，所以刷之。但新车间却没有网络，没办法，自己一点一点试。。结果如下 CT1 接受pwm，控制速度 CT2 前进控制信号，高电位转动 CT3 后退控制信号，高电位转动 但是由于小车上的UNO与我的Ubuntu连接有问题，貌似只有Windows是好的，Mac OS有时也会出问题。所以最后车上改用了Mega 1280。 但是又发现一个问题，就是Arduino使用USB供电的时候很正常，然而，使用车上接出来的5V电源时，程序就会混乱，完全没有一点规律。猜测可能是由于电机转动导致整个系统的电压下降，无法提供足够的电压给Arduino的板子上。这大概也是之前uno不会发疯的原因。没办法，在小车上再接一块9V层叠式电池，作为Arduino的电源。最后终于行了。 后面程序的作用是往前走，遇到前方有物体是后退，打弯，然后继续往前，一个简单的壁障程序。没有用到速度控制。下面就是这个小车最后的样子，手机拍的，将就看吧 左侧照 右侧照 再来一张 http://v.youku.com/v_show/id_XMjYzMzY0NzA0.html 用到的程序就是下面的 //Author: HE Qichen //Email: heqichen(a)gmail.com //Website: http://heqichen.cn //Date: 2011-5-1 int status; #define LEFT_SPEED 6 #define LEFT_FORWARD 7 #define LEFT_BACKWARD 8 #define RIGHT_SPEED 10 #define RIGHT_FORWARD 11 #define RIGHT_BACKWARD 12 #define ULTRASONIC_ECHO 3 #define ULTRASONIC_TRIG 4 #define NORMAL_SPEED 100 [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/embedreamcar/">嵌入之梦-圆梦小车开发</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>今天看到一台嵌入之梦的小车，但是上电之后发了疯似的乱跑，所以刷之。但新车间却没有网络，没办法，自己一点一点试。。结果如下</p>
<pre class="code">CT1	接受pwm，控制速度
CT2	前进控制信号，高电位转动
CT3	后退控制信号，高电位转动</pre>
<p>但是由于小车上的UNO与我的Ubuntu连接有问题，貌似只有Windows是好的，Mac OS有时也会出问题。所以最后车上改用了Mega 1280。</p>
<p>但是又发现一个问题，就是Arduino使用USB供电的时候很正常，然而，使用车上接出来的5V电源时，程序就会混乱，完全没有一点规律。猜测可能是由于电机转动导致整个系统的电压下降，无法提供足够的电压给Arduino的板子上。这大概也是之前uno不会发疯的原因。没办法，在小车上再接一块9V层叠式电池，作为Arduino的电源。最后终于行了。</p>
<p>后面程序的作用是往前走，遇到前方有物体是后退，打弯，然后继续往前，一个简单的壁障程序。没有用到速度控制。下面就是这个小车最后的样子，手机拍的，将就看吧</p>
<p><img class="photo" title="正面照" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050104.jpg" data-pinit="registered" /><br />
<span id="more-248"></span><br />
左侧照</p>
<p><img class="photo" title="左侧照" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050105.jpg" data-pinit="registered" /></p>
<p>右侧照</p>
<p><img class="photo" title="右侧照" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050106.jpg" data-pinit="registered" /></p>
<p>再来一张</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2011050107.jpg" data-pinit="registered" /><br />
<object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMjYzMzY0NzA0/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMjYzMzY0NzA0/v.swf" quality="high" allowscriptaccess="sameDomain" align="middle" /></object><br />
<a href="http://v.youku.com/v_show/id_XMjYzMzY0NzA0.html">http://v.youku.com/v_show/id_XMjYzMzY0NzA0.html</a></p>
<p>用到的程序就是下面的</p>
<pre class="code">//Author:	HE Qichen
//Email:	heqichen(a)gmail.com
//Website:	http://heqichen.cn
//Date:	2011-5-1

int status;

#define LEFT_SPEED   6
#define LEFT_FORWARD  7
#define LEFT_BACKWARD  8

#define RIGHT_SPEED  10
#define RIGHT_FORWARD  11
#define RIGHT_BACKWARD  12

#define ULTRASONIC_ECHO  3
#define ULTRASONIC_TRIG  4

#define NORMAL_SPEED  100
#define STOP_SPEED  0

void setup()
{
  Serial.begin(9600);
  setupMove();
  setupUltrasonic();
}

void loop()
{
  unsigned int d;
  moveForward();
  d = readDistance();
  Serial.println(d, DEC);
  if (d &lt; 700)
  {
    moveBackward();
    delay(500);
    turnLeft();
    delay(200);
  }
}

void moveForward()
{
  analogWrite(LEFT_SPEED, NORMAL_SPEED);
  digitalWrite(LEFT_BACKWARD, LOW);
  digitalWrite(LEFT_FORWARD, HIGH);
  analogWrite(RIGHT_SPEED, NORMAL_SPEED);
  digitalWrite(RIGHT_BACKWARD, LOW);
  digitalWrite(RIGHT_FORWARD, HIGH);
}

void moveBackward()
{
  analogWrite(LEFT_SPEED, NORMAL_SPEED);
  digitalWrite(LEFT_BACKWARD, HIGH);
  digitalWrite(LEFT_FORWARD, LOW);
  analogWrite(RIGHT_SPEED, NORMAL_SPEED);
  digitalWrite(RIGHT_BACKWARD, HIGH);
  digitalWrite(RIGHT_FORWARD, LOW);
}

void turnLeft()
{
  analogWrite(LEFT_SPEED, NORMAL_SPEED);
  digitalWrite(LEFT_BACKWARD, HIGH);
  digitalWrite(LEFT_FORWARD, LOW);
  analogWrite(RIGHT_SPEED, NORMAL_SPEED);
  digitalWrite(RIGHT_BACKWARD, LOW);
  digitalWrite(RIGHT_FORWARD, HIGH);
}

void turnRight()
{
  analogWrite(LEFT_SPEED, NORMAL_SPEED);
  digitalWrite(LEFT_BACKWARD, LOW);
  digitalWrite(LEFT_FORWARD, HIGH);
  analogWrite(RIGHT_SPEED, NORMAL_SPEED);
  digitalWrite(RIGHT_BACKWARD, HIGH);
  digitalWrite(RIGHT_FORWARD, LOW);
}

void moveStop()
{
  analogWrite(LEFT_SPEED, STOP_SPEED);
  digitalWrite(LEFT_BACKWARD, LOW);
  digitalWrite(LEFT_FORWARD, LOW);
  analogWrite(RIGHT_SPEED, STOP_SPEED);
  digitalWrite(RIGHT_BACKWARD, LOW);
  digitalWrite(RIGHT_FORWARD, LOW);
}

void setupMove()
{
  pinMode(LEFT_SPEED, OUTPUT);
  pinMode(LEFT_FORWARD, OUTPUT);
  pinMode(LEFT_BACKWARD, OUTPUT);
  pinMode(RIGHT_SPEED, OUTPUT);
  pinMode(RIGHT_FORWARD, OUTPUT);
  pinMode(RIGHT_BACKWARD, OUTPUT);

  analogWrite(LEFT_SPEED, STOP_SPEED);
  digitalWrite(LEFT_FORWARD, LOW);
  digitalWrite(LEFT_BACKWARD, LOW);
  analogWrite(RIGHT_SPEED, STOP_SPEED);
  digitalWrite(RIGHT_FORWARD, LOW);
  digitalWrite(RIGHT_BACKWARD, LOW);
}

unsigned int readDistance()
{

  int duration;
  digitalWrite(ULTRASONIC_TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(ULTRASONIC_TRIG, HIGH);
  delayMicroseconds(5);
  digitalWrite(ULTRASONIC_TRIG, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  duration = pulseIn(ULTRASONIC_ECHO, HIGH);
  return duration;

}

void  setupUltrasonic()
{
  pinMode(ULTRASONIC_TRIG, OUTPUT);
  pinMode(ULTRASONIC_ECHO, INPUT);

  digitalWrite(ULTRASONIC_TRIG, LOW);
}</pre>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="248">2,115&nbsp;total views, 1&nbsp;views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/embedreamcar/">嵌入之梦-圆梦小车开发</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/embedreamcar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>自主机器人项目</title>
		<link>http://heqichen.cn/wp/art-project/</link>
		<comments>http://heqichen.cn/wp/art-project/#comments</comments>
		<pubDate>Fri, 31 Dec 2010 20:10:09 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=252</guid>
		<description><![CDATA[<p>我想通过改造一辆遥控小车，造出个自主移动机器人，遥控车就是下面这张图片中的车。 并且希望通过大家的智慧，把这个机器人做好，比如说，想在上面放一个无线摄像头；比如说，在上面放一个机械手臂；比如说，在这上面装一个超声测距模块……我将集中大家的智慧，集合到这个小车上面，^_^ http://v.youku.com/v_show/id_XMjYyMzQ4OTYw.html 如果你有想法，请告诉我 1,993&#160;total views, no views today</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/art-project/">自主机器人项目</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>我想通过改造一辆遥控小车，造出个自主移动机器人，遥控车就是下面这张图片中的车。</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/110.jpg" data-pinit="registered" /></p>
<p>并且希望通过大家的智慧，把这个机器人做好，比如说，想在上面放一个无线摄像头；比如说，在上面放一个机械手臂；比如说，在这上面装一个超声测距模块……我将集中大家的智慧，集合到这个小车上面，^_^</p>
<p><object width="480" height="400" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" align="middle"><param name="src" value="http://player.youku.com/player.php/sid/XMjYyMzQ4OTYw/v.swf" /><param name="quality" value="high" /><param name="allowscriptaccess" value="sameDomain" /><embed width="480" height="400" type="application/x-shockwave-flash" src="http://player.youku.com/player.php/sid/XMjYyMzQ4OTYw/v.swf" quality="high" allowscriptaccess="sameDomain" align="middle" /></object><br />
<a href="http://v.youku.com/v_show/id_XMjYyMzQ4OTYw.html">http://v.youku.com/v_show/id_XMjYyMzQ4OTYw.html</a></p>
<p>如果你有想法，请告诉我
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="252">1,993&nbsp;total views, no views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/art-project/">自主机器人项目</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/art-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>四轴飞行器进展</title>
		<link>http://heqichen.cn/wp/process-of-quadcopter/</link>
		<comments>http://heqichen.cn/wp/process-of-quadcopter/#comments</comments>
		<pubDate>Thu, 09 Dec 2010 20:12:03 +0000</pubDate>
		<dc:creator><![CDATA[heqichen]]></dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hacker]]></category>

		<guid isPermaLink="false">http://gaishi.vicp.net/wp/?p=255</guid>
		<description><![CDATA[<p>经过了几个星期的折腾，四轴飞行器电机控制方式终于有所突破，先上图 哈哈 其实这个电路十分简单，就是两个按钮接入Arduino，然后Arduino输出PWM信号到电调，电调再输出电流到电机，从而就行成了按钮控制电机的一个装置。 不过，在完成这样一个小小的系统也经历了很多挫折。 首先，舵机还是电调都是通过PWM波进行控制的，比如下面这张图当中 这个就是一般航模用的遥控器，接收机接收到射频信号后，将信号解调成PWM输出到舵机或者是电调中。所以电调和舵机都能够接收PWM信号，且信号格式是统一的。 但是，PWM信号到底是什么格式，频率多少，占空比多少，在网上查了查，却没有一个确切的数据。有个数据比就是futata的标准，pwm频率是50Hz, 脉冲宽度为920usec到2120usec，这样对应了舵机的0度到180度。 对于这个数值，我用51做了一个PWM的发生器，通过在电脑上输入角度（0到180度），然后产生一个特定的PWM波输出到舵机，就是下面这张图中的。 可是结果发现，舵机行程明显不足180度，只能勉强算是90左右，看来920usec-2120usec并不是对于舵机确切的控制数据，或者说对于除futaba以外的舵机的控制格式。 经过调试，发现要使舵机达到0度到180度的行程，PWM波的脉冲宽度要在800usec到2800usec之间。同时也有个有趣的现象。如果给舵机的信号线一个脉冲信号，宽度在800usec到2800usec之间，然后持续低电位，舵机会保持在该脉冲所对应角度不变，也就是说，PWM的频率是可以低于 50Hz的。 回到Arduino上，Arduino自带Servo的库，可以编程实现从特定的角度输出特定的PWM波。就可以是用这样的PWM信号来控制电调，从而控制电机。这里有必须介绍一下电调的特点。我们是用的电调是比较廉价的新西达电调，但是它也带模式设定的功能，可以根据不同的场合来设定电调的工作模式。设定的过程就是，PWM信号为最高时，给电调上电。具体的设定过程可以在网上查到。经过实验发现Arduino输出角度为0的PWM信号根本不会对电调有任何影响，电调完全无视这个信号的存在-_-b。经过仔细思考后发现，会不会是因为电调是用的是futaba的PWM格式，而800usec或者 Arduino最低的pwm信号对于电调来说过低，导致电调不能够辨认。 以下就是能够控制电机速度的程序代码 #include &#60;Servo.h&#62; Servo myservo; int pos = 0; int buttonState = 0; int lastButtonState = 0; int currentAngle; int MAX_ANGLE = 140; int MIN_ANGLE = 100; void setup() { myservo.attach(9); pinMode(13, OUTPUT); pinMode(2, INPUT); pinMode(3, INPUT); currentAngle = 100; } [&#8230;]</p>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/process-of-quadcopter/">四轴飞行器进展</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></description>
				<content:encoded><![CDATA[<p>经过了几个星期的折腾，四轴飞行器电机控制方式终于有所突破，先上图 哈哈</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2010123001.jpg" data-pinit="registered" /></p>
<p>其实这个电路十分简单，就是两个按钮接入Arduino，然后Arduino输出PWM信号到电调，电调再输出电流到电机，从而就行成了按钮控制电机的一个装置。</p>
<p>不过，在完成这样一个小小的系统也经历了很多挫折。<br />
<span id="more-255"></span><br />
首先，舵机还是电调都是通过PWM波进行控制的，比如下面这张图当中</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2010123002.jpg" data-pinit="registered" /></p>
<p>这个就是一般航模用的遥控器，接收机接收到射频信号后，将信号解调成PWM输出到舵机或者是电调中。所以电调和舵机都能够接收PWM信号，且信号格式是统一的。</p>
<p>但是，PWM信号到底是什么格式，频率多少，占空比多少，在网上查了查，却没有一个确切的数据。有个数据比就是futata的标准，pwm频率是50Hz, 脉冲宽度为920usec到2120usec，这样对应了舵机的0度到180度。</p>
<p>对于这个数值，我用51做了一个PWM的发生器，通过在电脑上输入角度（0到180度），然后产生一个特定的PWM波输出到舵机，就是下面这张图中的。</p>
<p><img class="photo" alt="photo" src="http://heqichen.cn/wp/wp-content/uploads/2014/02/2010123003.jpg" data-pinit="registered" /></p>
<p>可是结果发现，舵机行程明显不足180度，只能勉强算是90左右，看来920usec-2120usec并不是对于舵机确切的控制数据，或者说对于除futaba以外的舵机的控制格式。<br />
经过调试，发现要使舵机达到0度到180度的行程，PWM波的脉冲宽度要在800usec到2800usec之间。同时也有个有趣的现象。如果给舵机的信号线一个脉冲信号，宽度在800usec到2800usec之间，然后持续低电位，舵机会保持在该脉冲所对应角度不变，也就是说，PWM的频率是可以低于 50Hz的。</p>
<p>回到Arduino上，Arduino自带Servo的库，可以编程实现从特定的角度输出特定的PWM波。就可以是用这样的PWM信号来控制电调，从而控制电机。这里有必须介绍一下电调的特点。我们是用的电调是比较廉价的新西达电调，但是它也带模式设定的功能，可以根据不同的场合来设定电调的工作模式。设定的过程就是，PWM信号为最高时，给电调上电。具体的设定过程可以在网上查到。经过实验发现Arduino输出角度为0的PWM信号根本不会对电调有任何影响，电调完全无视这个信号的存在-_-b。经过仔细思考后发现，会不会是因为电调是用的是futaba的PWM格式，而800usec或者 Arduino最低的pwm信号对于电调来说过低，导致电调不能够辨认。</p>
<p>以下就是能够控制电机速度的程序代码</p>
<pre class="code">#include &lt;Servo.h&gt;

Servo myservo;
int pos = 0;
int buttonState = 0;
int lastButtonState = 0;

int currentAngle;
int MAX_ANGLE = 140;
int MIN_ANGLE = 100;
void setup()
{
 myservo.attach(9);
 pinMode(13, OUTPUT);
 pinMode(2, INPUT);
 pinMode(3, INPUT);
 currentAngle = 100;
}

void loop()
{
 buttonState = digitalRead(2);
 if (buttonState == HIGH)
 {
 digitalWrite(13, HIGH);
 if (currentAngle &lt; MAX_ANGLE)  {  currentAngle = currentAngle + 1;  }  }  else  {  buttonState = digitalRead(3);  if (buttonState == HIGH)  {  digitalWrite(13, HIGH);  if (currentAngle &gt; MIN_ANGLE)
 {
 currentAngle = currentAngle - 1;
 }
 }
 }
 if (buttonState == LOW)
 {
 digitalWrite(13, LOW);
 }
 myservo.write(currentAngle);
 delay(30);

}</pre>
<div class="pvc_clear"></div>
<p class="pvc_stats" element-id="255">2,841&nbsp;total views, 3&nbsp;views today</p>
<div class="pvc_clear"></div>
<p>The post <a rel="nofollow" href="http://heqichen.cn/wp/process-of-quadcopter/">四轴飞行器进展</a> appeared first on <a rel="nofollow" href="http://heqichen.cn/wp">HE Qichen&#039;s Hackspace</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://heqichen.cn/wp/process-of-quadcopter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
