tag:crieit.net,2005:https://crieit.net/tags/PIC12F675/feed 「PIC12F675」の記事 - Crieit Crieitでタグ「PIC12F675」に投稿された最近の記事 2018-10-30T20:49:07+09:00 https://crieit.net/tags/PIC12F675/feed tag:crieit.net,2005:PublicArticle/14372 2014-05-27T09:00:00+09:00 2018-10-30T20:49:07+09:00 https://crieit.net/posts/05baae08c9140b09b9ecafb4aa550fa4 ダイソーのプチ電車をリモコンで操作できるよう改造 <p>ダイソーのプチ電車をリモコンで前進、後退、ストップの操作ができるようになりましたので<br /> 詳細を公開します。<br /> <a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/?p=395" target="_blank">失敗談はこちら</a></p> <p>まず構成を説明します。<br /> ダイソーのプチ電車は3台連結構成になっており、<br /> 中央に電池を入れてモーターを動かす仕組みになっています。</p> <p>失敗談でも書きましたが、改造のために何度も分解していると<br /> タイヤが空回りするようになったり、ギアが壊れたりするので<br /> 中央の車体は一切改造せず、モーターに導線を伸ばして接続するだけ、<br /> という形にしました。<br /> これで何かあって回路を外しても通常通りに遊ぶことも出来ます。</p> <p>ということで先頭車両に回路を入れ、この2台は必須な構成となります。<br /> 電池ボックスと回路でギリギリなので中身の余分なプラスチックを切り落とします。<br /> これくらいの改造だったら回路無しに戻すのにも特に支障はありません。<br /> 板を切り落とすだけなのでシンプルでした。<br /> <a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/wp-content/uploads/2014/05/DSC_0269.jpg"><img class="alignnone size-medium wp-image-405" src="http://program.alphabrend.com/wp-content/uploads/2014/05/DSC_0269-300x225.jpg" alt="DSC_0269" width="300" height="225" /></a></p> <p>これに下記の回路を載っけます。<br /> 電源スイッチ、赤外線受信部、LEDは位置を調整できるよう空中配線です。<br /> 単4電池2本ボックス、回路ともに丁度外枠と同じサイズです。<br /> (ユニバーサル基板16x9だったと思います)<br /> <a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/wp-content/uploads/2014/05/DSC_0270.jpg"><img class="alignnone size-medium wp-image-406" src="http://program.alphabrend.com/wp-content/uploads/2014/05/DSC_0270-300x225.jpg" alt="DSC_0270" width="300" height="225" /></a></p> <p>蓋を閉めたところ。<br /> <a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/wp-content/uploads/2014/05/DSC_0271.jpg"><img class="alignnone size-medium wp-image-407" src="http://program.alphabrend.com/wp-content/uploads/2014/05/DSC_0271-300x225.jpg" alt="DSC_0271" width="300" height="225" /></a><br /> 電源スイッチ、赤外線受信部は面倒だったので窓から出しています。<br /> 気になる人はどこかに設置すると良いと思います。<br /> 窓から回路が丸見えになるので、窓には内側から車内の絵を貼ったりすると<br /> 見栄えが良くなると思います。</p> <p>これが実際に操作したところです。<br /> [video width="640" height="360" mp4="http://program.alphabrend.com/wp-content/uploads/2014/05/ir_train_encoded.mp4"][/video]</p> <p>では回路の説明をします。<br /> ・PIC12F675<br /> ・単4電池2本<br /> ・赤外線受信モジュールでソニーリモコンを受信して操作<br /> ・Y14H-1C-5DSのリレーを使って電池のオン、オフを操作<br /> ・941H-2C-5Dのリレーを使って前後、左右の切り替え<br /> ・上記2個のリレーにより、モーターと電池を直結。<br /> ・回路側はHT7750Aで5Vに昇圧<br /> ・電池用にスイッチを設置。<br /> 恐らく赤外線受信モジュールがずっと動いているせいで<br /> 以前失敗した9Vの電池も放置しておいたらなくなっていたので<br /> 手動スイッチ必須っぽいです。</p> <p>挫折していたEagleですが<br /> 久々にやってみたらすんなり回路がかけたっぽい気がするので公開します。<br /> 何か間違っていたらすみません。<br /> <a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/wp-content/uploads/2014/05/irtrain_circuit.png"><img class="alignnone size-medium wp-image-404" src="http://program.alphabrend.com/wp-content/uploads/2014/05/irtrain_circuit-300x184.png" alt="irtrain_circuit" width="300" height="184" /></a></p> <p>プログラムです。<br /> 赤外線受信の詳細は<a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/?p=211" target="_blank">こちらの記事</a>で解説しています。</p> <blockquote> <p>|c|</p> </blockquote> <h1 id="include &lt;xc.h>"><a href="#include+%26lt%3Bxc.h%3E">include <xc.h></a></h1> <h1 id="pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF"><a href="#pragma+config+FOSC+%3D+INTRCIO%2C+WDTE+%3D+OFF%2C+PWRTE+%3D+ON%2C+MCLRE+%3D+OFF">pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF</a></h1> <h1 id="define IR GPIO5"><a href="#define+IR+GPIO5">define IR GPIO5</a></h1> <h1 id="define LED GPIO2"><a href="#define+LED+GPIO2">define LED GPIO2</a></h1> <h1 id="define RELAY_ON GPIO1"><a href="#define+RELAY_ON+GPIO1">define RELAY_ON GPIO1</a></h1> <h1 id="define RELAY_DIR GPIO0"><a href="#define+RELAY_DIR+GPIO0">define RELAY_DIR GPIO0</a></h1> <h1 id="define TIMEOUT 27500"><a href="#define+TIMEOUT+27500">define TIMEOUT 27500</a></h1> <h1 id="define _XTAL_FREQ 4000000 // delay用に必要(クロック32MHzを指定)"><a href="#define+_XTAL_FREQ+4000000+%2F%2F+delay%E7%94%A8%E3%81%AB%E5%BF%85%E8%A6%81%28%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF32MHz%E3%82%92%E6%8C%87%E5%AE%9A%29">define _XTAL_FREQ 4000000 // delay用に必要(クロック32MHzを指定)</a></h1> <h1 id="define __delay(x) _delay((unsigned long)((x)))"><a href="#define+__delay%28x%29+_delay%28%28unsigned+long%29%28%28x%29%29%29">define __delay(x) _delay((unsigned long)((x)))</a></h1> <h1 id="define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000UL)))"><a href="#define+__delay_us%28x%29+_delay%28%28unsigned+long%29%28%28x%29%2A%28_XTAL_FREQ%2F4000000UL%29%29%29">define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000UL)))</a></h1> <h1 id="define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000UL)))"><a href="#define+__delay_ms%28x%29+_delay%28%28unsigned+long%29%28%28x%29%2A%28_XTAL_FREQ%2F4000UL%29%29%29">define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000UL)))</a></h1> <p>char lastInput = 1;<br /> char isSony = 0;<br /> char data = 0;<br /> unsigned long time = 0;<br /> unsigned char inputCount = 0;<br /> unsigned char dataCount = 0;</p> <p>void setData(int no, char row) {<br /> //sonyは7bitなのでそれ以外は無視<br /> if (no >= 7) return;<br /> data |= row << no;<br /> }</p> <p>void motorGo() {<br /> RELAY_ON = 0;<br /> RELAY_DIR = 0;<br /> __delay_ms(1);<br /> LED = 1;<br /> RELAY_ON = 1;<br /> }</p> <p>void motorBack() {<br /> RELAY_ON = 0;<br /> RELAY_DIR = 1;<br /> __delay_ms(1);<br /> LED = 1;<br /> RELAY_ON = 1;<br /> }</p> <p>void motorStop() {<br /> __delay_ms(1);<br /> LED = 0;<br /> RELAY_ON = 0;<br /> RELAY_DIR = 0;<br /> }</p> <p>main() {<br /> GPIO = 0;<br /> CMCON = 0x07; // コンパレータ未使用<br /> TRISIO = 0b00100000;<br /> //プリスケーラ8=8μS…カウント75で600μ(1T)…だけどなぜか64くらいっぽい…<br /> OPTION_REG = 0b10000010;<br /> TMR0 = 0;<br /> ANSEL = 0b00110000;</p> <pre><code>char val; while(1) { val = IR; while (val == lastInput) { if (TMR0 > 200) { time += TMR0; TMR0 = 0; } if (time + TMR0 > TIMEOUT) { if (inputCount > 2 && isSony) { switch (data) { case 1: motorGo(); break; case 4: motorStop(); break; case 7: motorBack(); break; } } isSony = 0; inputCount = 0; dataCount = 0; data = 0; } val = IR; } time += TMR0; inputCount++; if (inputCount == 2) { if (192 &lt; time && time &lt; 320) { isSony = 1; } } else if (inputCount > 2) { if (isSony && !(inputCount % 2)) { if (time &lt; 100) { setData(dataCount, 0); } else { setData(dataCount, 1); } dataCount++; } } lastInput = val; time = 0; TMR0 = 0; } </code></pre> <p>}<br /> ||</p> <p>ちょっとスピードが速いので自前PWMした方がいいかもしれません。</p> <p>車体以外にも色々パーツがあったような気がするので<br /> 他にも色々連動させて作れないか試してみたいですね。<br /> あと、もう1車両後ろにも連結できるので<br /> 何か思いついたらそっちに回路を入れて拡張することも出来そうです。</p> <p>プラレールは非常に高いので、<br /> プチ電車で大掛かりなシステムが構築できたら<br /> 安価で無改造プラレールを超える遊びが出来そうな気がします。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14373 2014-05-25T09:00:00+09:00 2018-10-26T15:05:38+09:00 https://crieit.net/posts/65818a44842875fe513d290d8deeebb4 ダイソーのプチ電車をリモコンで操作できるよう改造失敗談編 <p>ついにダイソーのプチ電車を<br /> テレビリモコンで操作できるような改造に成功しました。</p> <p>初歩的な知識もなくなかなかうまく行きませんでした。<br /> 電子工作をはじめたくらいに作り始めたので<br /> 数ヶ月経ってしまったと思います。<br /> プログラムや回路はまた後日公開したいと思いますので<br /> 今回はどういう風に失敗していったかを書いていきます。<br /> 同じく初心者には役立つ部分もあるかもしれません。</p> <p>モータードライバで試す</p> <p>仕様としては家にあったソニーのテレビリモコンで<br /> 前進、後退ができるようにしよう、という感じでした。</p> <p>モーターの前進、後退といえばモータードライバ。<br /> 早速秋月で購入して試してみました。</p> <p>…しかし上手くいかない。<br /> 通常、4.5Vのモータードライバを使うのが流行っていると思いますが<br /> よく分からなかった自分は足が少ないという理由で<br /> 6Vのモータードライバを買ってしまいました。<br /> なので単3電池4本ないと動きません。</p> <p>しかしプチ電車はタカラのプラレールと比べてもちいさく、<br /> 単3電池4本は無理です。<br /> 無知だった僕はボタン電池を複数重ねて電圧を上げて試したり<br /> 無駄なことをしていました。<br /> (電圧は足りますが、電流がめちゃくちゃ少ないので<br /> ボタン電池ではモーターは動かせません)</p> <p>やむなくネットで色々調べることにしました…。</p> <p>後になって分かりましたが、<br /> 4.5Vのモータードライバでも無理だったと思います。<br /> モータードライバで電圧が2.5Vほど下がるので、<br /> モーターを動かすには4Vつまり単3電池3本必要。<br /> プチ電車には入りません。</p> <p>9V電池を試す</p> <p>プラレールの改造を色々調べていると、<br /> 9V電池を使っている方を見つけました。<br /> 3端子レギュレータで5Vに落とす方法です。</p> <p>これならモータードライバもモーターも<br /> 電池1個で動かせるのではないか、と思いましたが<br /> 実際やってみるとダメでした。<br /> 9V電池の中身はボタン電池と同じみたいですね…。<br /> 結局単3電池が必要という結論に至りました。</p> <p>リレーを試す</p> <p>同じサイトで、リレーというものを知りました。<br /> 電圧をかけることでスイッチを動かすものなので、<br /> 1.5V電池を完全に別回路に分離できるわけです。</p> <p>ここで同じくらいに知識を得ていた<br /> ステップアップDC/DCコンバータを用いて、<br /> 電池1個でも行けるのではないか、と考えました。</p> <p>しかし、実際に電池1本でやってみるとリレーが動かない。<br /> どうもなんか足りないみたいでした。</p> <p>リレー+9V電池で試す</p> <p>電池1本はダメみたいなので<br /> ロジック回路の方は9V電池を降圧してやることにしました。</p> <p>ただ、この時点で成功したものは、<br /> 前進、停止のみしか出来ないものでした。<br /> リレーを1個しか使ってなかったためです。<br /> しかしそれでも2両分かつかつだったのでバックは諦め、<br /> これで組み込むことにしました。</p> <p>が、かつかつでなかなかカバーが閉まらない、<br /> 且つ改造により車輪やギアが壊れていたので<br /> 動かなくなり、億劫になってしばらくやめていました…。</p> <p>成功</p> <p>それから時間が空き、<br /> 僕も色々と知識を得て、工作にも多少慣れてきました。<br /> 色々とまとめて、やはり電池1本で試してみよう、<br /> と再度挑戦してみることにしました。</p> <p>ステップアップDC/DCコンバータですが、<br /> その後も何回も挫折していました。<br /> 本当に5Vになっているのだろうかと。</p> <p>回路を組んでちゃんとテスターで試してみたところ、<br /> ちゃんと昇圧されていました。</p> <p>しかしやはりリレーが動かない…。<br /> もう一度調べてみると、どうもやはり電流が足りないので、<br /> トランジスタを使う必要があるようでした。<br /> しかもGND側に付け、電気の流れをスイッチする、という方法でした。<br /> またきむ茶さんのサイトに辿り着き<br /> 同じPIC12F675でリレーを操作する説明があったので助かりました。</p> <p>実際に試してみたところ成功…!<br /> しかしこれはリレー1個目です。<br /> 別につけているLEDもかなり薄い光になっています…。<br /> おそるおそる2個めのリレーを試してみると…</p> <p>…ダメでした。<br /> 多分リレー2個は電流不足っぽいです。</p> <p>困り果ててまた色々調べているうちに、<br /> そういえば単2とか単4ってどういう違いがあるんだろう?<br /> と思い色々ネットで調べてみました。</p> <p>どうやら電流量みたいでした。<br /> 単1,2とかのほうが電流量が多いみたいです。<br /> もしやそれならリレー2個でもうごくのでは…?<br /> と思いましたが、そもそもそんな大きな電池は<br /> プチ電車の中には入りません。</p> <p>と、単4電池を2個だとどうなんだろう、と思って試してみました。<br /> すると、動きました!<br /> しかも、丁度プチ電車に入るサイズなんです!<br /> 感動しました。</p> <p>回路を出来るだけ小さくまとめ、<br /> 長さ的にも丁度電池と回路が入る大きさに仕上がりました。<br /> そして今日、ついに完成しました。<br /> (ただし、単4電池2本そのままなのでちょっと速すぎる感じです)</p> <p>ネットでも同様の改造情報は見当たりませんし、<br /> 一般の情報公開は日本初かもしれませんね。<br /> 後日また詳細を公開します。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14410 2014-03-30T15:03:59+09:00 2014-03-30T15:03:59+09:00 https://crieit.net/posts/b30ceaec5eea312248e2573e6be7f596 初のユニバーサル基板への取り付け <p>初めてユニバーサル基板への回路取り付けを行った。<br /> 使ったのは<a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/?p=179">CDSの回路</a>。<br /> ちっちゃい回路なのでユニバーサル基板もダイソーの金鋸で切ってちっちゃくし、風船に入れた。<br /> 暗い間だけ光る風船。</p> <p>実際に使ってみると橙色の風船に白LEDを1個入れただけなので結構光は弱い。<br /> もうちょっと考えないと実用性はなさそうだ。<br /> 一応トイレの前に置いておいた。<br /> おそらく嫁が幽霊かと思って一瞬ビビるだろう。</p> <p>あとプログラムにも問題があり、<br /> 現状ほとんど予期していなかったPWMのようになっていて<br /> 明るいところでは消灯、暗いところでは点灯、となっているので<br /> 多分夜ずっと点灯していて電池がどれくらい持つか不明。<br /> 1回転灯したら数分は絶対点灯したまま、と変えないとダメっぽい。</p> <p>実は何日か前に作ってはいたのだが、上手く動かないので今日見なおした。<br /> テスターも買って試したのだが、LEDを直接テスターで点灯させてしまって1個壊れた。<br /> その他なにか壊れて動かないのかと思ったけど特にそういうわけでもなかった。<br /> ハンダ付けの失敗でもなかった。</p> <p>では何だったかというと、単純に回路を間違えていた。<br /> 本来3ピンにつけるはずだった部分を4ピンにつけてしまっていた。<br /> ブレッドボード上のものを撮影しておいて助かった。</p> <p>次はダイソーのモーター付き電車を改造して<br /> テレビのリモコンで操作できるようにしたいと思う。</p> <p>[caption id="attachment_222" align="alignnone" width="225" caption="表"]<a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/wp-content/uploads/2014/03/DSC_0218.jpg"><img class="size-medium wp-image-222" title="DSC_0218" src="http://program.alphabrend.com/wp-content/uploads/2014/03/DSC_0218-225x300.jpg" alt="cdsuniversal" width="225" height="300" /></a>[/caption]</p> <p>[caption id="attachment_223" align="alignnone" width="225" caption="裏"]<a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/wp-content/uploads/2014/03/DSC_0219.jpg"><img class="size-medium wp-image-223" title="DSC_0219" src="http://program.alphabrend.com/wp-content/uploads/2014/03/DSC_0219-225x300.jpg" alt="cdsuniversal_ura" width="225" height="300" /></a>[/caption]</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14411 2014-03-30T15:03:58+09:00 2018-09-12T23:01:43+09:00 https://crieit.net/posts/PIC12F675 PIC12F675で赤外線受信 <p>ようやくPIC12F675でリモコンの赤外線受信に成功した。<br /> 環境は下記の通り。<br /> ・SONYのテレビリモコン<br /> ・MPLAB X IDE<br /> ・XC8<br /> ・pickit3<br /> ・受信モジュールPL−IRM2161−XD1</p> <p><a target="_blank" rel="nofollow noopener" href="http://elm-chan.org/docs/ir_format.html" target="_blank">sonyの赤外線フォーマット</a>は書いてあるとおりだけど、<br /> 簡単に説明するとT = 600μsが全ての信号の単位長さになっており、<br /> Frameというところに書かれている様に信号群がやってくる。<br /> なので最初にLeaderが4THIGHできてあとは<br /> 1TLOW+(1or2)HIGHがひたすらくる。</p> <p>8ピンPICでは詳細なデバッグが出来ないので、<br /> 信号の解析はarduinoのシリアル通信で行った。<br /> スケッチは下記の通り。</p> <blockquote> <p>|c|<br /> const int PIN = 7;<br /> const long TIMEOUT = 250000;<br /> const int DATA_MAX = 400;</p> </blockquote> <p>unsigned int lastInput = HIGH;<br /> unsigned long startTime = micros();<br /> int inputCount = 0;<br /> int dataCount = 0;<br /> unsigned int val;<br /> unsigned long currentTime;<br /> boolean data[100];<br /> boolean highVal;<br /> boolean isSony = false;<br /> String str = "";</p> <p>void setup() {<br /> Serial.begin(57600);<br /> pinMode(PIN, INPUT);<br /> }</p> <p>void loop() {<br /> val = digitalRead(PIN);<br /> unsigned long time;</p> <p>while (val == lastInput) {<br /> if (micros() - startTime > TIMEOUT) {<br /> if (inputCount > 2 && isSony) {<br /> String tmp = "";<br /> for (int i = 0; i < dataCount; i++) {<br /> tmp += String(data[i]) + " ";<br /> }<br /> Serial.println(tmp);<br /> // Serial.println(str);<br /> }<br /> isSony = false;<br /> inputCount = 0;<br /> dataCount = 0;<br /> str = "";<br /> break;<br /> }<br /> val = digitalRead(PIN);<br /> }</p> <p>currentTime = micros();<br /> time = currentTime - startTime;<br /> str += String(time) + " ";<br /> inputCount++;<br /> if (inputCount == 3) {<br /> if (1800 < time && time < 3000) {<br /> isSony = true;<br /> }<br /> } else if (inputCount > 3) {<br /> if (isSony && (inputCount % 2)) {<br /> if (time < 1000) {<br /> data[dataCount] = 0;<br /> } else {<br /> data[dataCount] = 1;<br /> }<br /> dataCount++;<br /> }<br /> }<br /> lastInput = val;<br /> startTime = currentTime;<br /> }<br /> ||<br /> これを実行するとリーダー以降の値の0と1の並びを確認できる。<br /> 実際の値も見たい場合はstr変数周りを使用してみると良い。</p> <p>んで実行してみるとわかるんだけど<br /> 2チャンネルボタンは<br /> 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1<br /> 3チャンネルボタンは<br /> 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1<br /> のようになっていて、仕様書通り左の7bitを見てみると<br /> 1〜9チャンネルボタンは右詰めbitにすると普通に0〜8の値になっている。<br /> とても簡単だ。<br /> Addressという部分はよくわからなかったので今回は無視することにした。<br /> charだけで判断できるようになるし。<br /> BDのリモコンでBDとかTVとか切り替えができるので、多分そのあたりで変えているのだと思う。<br /> (ただしその関係で、ボタンを長押しには対応できていないので<br /> 長押ししてると別のボタンと判断してしまう場合があるので<br /> 必要であれば残りは自分で解析して下さい)</p> <p>上を元にPIC側のプログラムを作ってみた。<br /> デバッグ方法がLEDしかないので、<br /> 想定通りの値が来ていたらLED点灯…等のようにして<br /> ひたすら細かいデバッグを行っていった。大変…。<br /> 最初はシリアル通信かLCDかpickitでデバッグできるピン数の多いICで<br /> 作成した方が効率よさげ…。<br /> delayとかのdefineが確認用なので実際は不要。<br /> 受信解析に成功するとチャンネル番号-1回LEDが光るようになっている。</p> <blockquote> <p>|c|</p> </blockquote> <h1 id="include &lt;xc.h>"><a href="#include+%26lt%3Bxc.h%3E">include <xc.h></a></h1> <h1 id="pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF"><a href="#pragma+config+FOSC+%3D+INTRCIO%2C+WDTE+%3D+OFF%2C+PWRTE+%3D+ON%2C+MCLRE+%3D+OFF">pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF</a></h1> <h1 id="define IR GPIO4"><a href="#define+IR+GPIO4">define IR GPIO4</a></h1> <h1 id="define LED GPIO2"><a href="#define+LED+GPIO2">define LED GPIO2</a></h1> <h1 id="define MOTOR GPIO0"><a href="#define+MOTOR+GPIO0">define MOTOR GPIO0</a></h1> <h1 id="define TIMEOUT 27500"><a href="#define+TIMEOUT+27500">define TIMEOUT 27500</a></h1> <h1 id="define _XTAL_FREQ 4000000 // delay用に必要(クロック4MHzを指定)"><a href="#define+_XTAL_FREQ+4000000+%2F%2F+delay%E7%94%A8%E3%81%AB%E5%BF%85%E8%A6%81%28%E3%82%AF%E3%83%AD%E3%83%83%E3%82%AF4MHz%E3%82%92%E6%8C%87%E5%AE%9A%29">define _XTAL_FREQ 4000000 // delay用に必要(クロック4MHzを指定)</a></h1> <h1 id="define __delay(x) _delay((unsigned long)((x)))"><a href="#define+__delay%28x%29+_delay%28%28unsigned+long%29%28%28x%29%29%29">define __delay(x) _delay((unsigned long)((x)))</a></h1> <h1 id="define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000UL)))"><a href="#define+__delay_us%28x%29+_delay%28%28unsigned+long%29%28%28x%29%2A%28_XTAL_FREQ%2F4000000UL%29%29%29">define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000UL)))</a></h1> <h1 id="define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000UL)))"><a href="#define+__delay_ms%28x%29+_delay%28%28unsigned+long%29%28%28x%29%2A%28_XTAL_FREQ%2F4000UL%29%29%29">define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000UL)))</a></h1> <p>const char buttons[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; //0=1チャンネルボタン<br /> const char buttonSize = sizeof(buttons) / sizeof(char);</p> <p>char lastInput = 1;<br /> char isSony = 0;<br /> char data = 0;<br /> unsigned long time = 0;<br /> unsigned char inputCount = 0;<br /> unsigned char dataCount = 0;</p> <p>void setData(int no, char row) {<br /> //sonyは7bitなのでそれ以外は無視<br /> if (no >= 7) return;<br /> data |= row << no;<br /> }</p> <p>main() {<br /> GPIO = 0;<br /> CMCON = 0x07; // コンパレータ未使用<br /> TRISIO = 0b00010000; // GP4:in<br /> //プリスケーラ8=8μS…カウント75で600μ(1T)…だけどなんか64くらいっぽい…<br /> OPTION_REG = 0b10000010;<br /> TMR0 = 0;<br /> ANSEL = 0b00110000;</p> <pre><code>char val; while(1) { val = IR; while (val == lastInput) { if (TMR0 > 200) { time += TMR0; TMR0 = 0; } if (time + TMR0 > TIMEOUT) { if (inputCount > 2 && isSony) { for (char i = 0; i &lt; buttonSize; i++) { if (buttons[i] == data) { for (char j = 0; j &lt; i; j++) { LED = 1; __delay_ms(200); LED = 0; __delay_ms(200); } } } } isSony = 0; inputCount = 0; dataCount = 0; data = 0; } val = IR; } time += TMR0; inputCount++; if (inputCount == 160) LED = 1; if (inputCount == 2) { if (192 &lt; time && time &lt; 320) { isSony = 1; } } else if (inputCount > 2) { if (isSony && !(inputCount % 2)) { if (time &lt; 100) { setData(dataCount, 0); } else { setData(dataCount, 1); } dataCount++; } } lastInput = val; time = 0; TMR0 = 0; } </code></pre> <p>}<br /> ||</p> <p>はまったところのメモ。</p> <p>前述のように信号は0と1の並びで来るのだが、<br /> ボタンを離すまで信号が連続していることに気づかず<br /> 大量の0と1が必要と勘違いしていた。<br /> そうすると入力内容を保存しているdata変数を配列にしてしまっていたのだが、<br /> なんとこのICは64バイトくらいしかメモリを使用できないらしく、<br /> 大量に値を保存するプログラムにするとビルドに失敗する。<br /> その辺りで四苦八苦していた名残でdataは1バイトのcharに<br /> 綺麗にまとまった作りになっている。<br /> button2 = {1, 0, 0, 0, 0, 0, 0}<br /> 等とは間違ってもやらないように…。</p> <p>あとarduinoのスケッチとほぼ同じように作ったつもりなのだが、<br /> arduino側は信号群の先頭2つがゴミ、<br /> PIC側は先頭一つだけがゴミ、<br /> となっておりそれが原因で上手くマッチング出来ず困っていた。<br /> いまだに原因はわからないのでとりあえず注意。</p> <p>とりあえずおもちゃの電車を動かしたいと思っていただけなので<br /> ボタン長押し不要のためこれで問題ない。<br /> ラジコンなどを作りたいひとはaddressの部分やループの部分も作りこんで下さい。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14414 2014-03-26T09:00:00+09:00 2014-03-26T09:00:00+09:00 https://crieit.net/posts/PIC12F675-cds PIC12F675でcdsを使用したアナログ入力 <p>環境は次の通り。<br /> ・MPLAB X IDE v2.0<br /> ・コンパイラはXC8<br /> ・pickit3使用</p> <p>回路は<a target="_blank" rel="nofollow noopener" href="http://program.alphabrend.com/?p=166" target="_blank">LED点滅</a>と同じで、<br /> これに<a target="_blank" rel="nofollow noopener" href="http://www.geocities.jp/zattouka/GarageHouse/micon/Arduino/FirstMicon/main.htm" target="_blank">おとうさんといっしょに遊ぶ初めてのマイコン</a>の<br /> cdsの箇所と同じようにして空いているAN3にcdsをつけた。<br /> cdsの説明書を見ると100kΩの抵抗が必要らしいが<br /> 手元になかったのでとりあえず10kΩをつけている。</p> <p>プログラムは後述だが、<br /> 暗くなるとLEDが点灯し、明るくなるか1分くらい経つと消える。<br /> (1440をコメントアウトのままにしてしまったのでこのままだと5秒位で消えちゃう)<br /> 夜寝る前とかリビングを離れる際とかに便利かもしれない。<br /> 回路を風船にでも入れて嫁を驚かそうかと思っている。<br /> 記念すべき初のユニバーサル基板実装にする予定。</p> <p><a target="_blank" rel="nofollow noopener" href="http://natural966.wordpress.com/2013/02/09/%E5%B0%91%E3%81%97%E3%81%AFpic%E3%81%AE%E4%BD%9C%E6%A5%AD%E3%82%82%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%99-10-ad%E5%A4%89%E6%8F%9B%E3%81%AE%E7%BF%92%E4%BD%9C/" target="_blank">少しはPICの作業もやってみます #10 – A/D変換の習作</a>と<br /> <a target="_blank" rel="nofollow noopener" href="http://www.geocities.jp/zattouka/GarageHouse/micon/MPLAB/12F675/VRtoLED/VRtoLED.htm" target="_blank">可変抵抗のツマミを回してLEDの点滅速度を可変します</a>を参考にした。<br /> きむ茶さんのところは分かりやすすぎて<br /> 検索しているうちに気がつくとそこにたどり着いている感じでかなり助かる。</p> <blockquote> <p>|c|</p> </blockquote> <h1 id="include &lt;xc.h>"><a href="#include+%26lt%3Bxc.h%3E">include <xc.h></a></h1> <h1 id="pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF"><a href="#pragma+config+FOSC+%3D+INTRCIO%2C+WDTE+%3D+OFF%2C+PWRTE+%3D+ON%2C+MCLRE+%3D+OFF">pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF</a></h1> <p>static bit lighting = 0;<br /> static bit offing = 0;<br /> static bit doOff = 0;<br /> static int count = 0;<br /> static int cds = 0;</p> <p>static void interrupt inter() {<br /> T0IF = 0;</p> <pre><code>if (offing) { if (++count >= /*1440*/120) { doOff = 1; offing = 0; } } </code></pre> <p>}</p> <p>main() {<br /> GPIO = 0;<br /> CMCON = 0x07; // コンパレータ未使用<br /> TRISIO = 0b00010000; // GP4:in<br /> OPTION_REG = 0b10000111; //プリスケーラ256<br /> TMR0 = 0x00; //カウント0<br /> T0IE = 1; //タイマー0使う<br /> GIE = 1; //タイマー使う</p> <pre><code>ADCS1 = 1; ADCS0 = 1; //アナログ3を使用 ANS0 = 0; ANS1 = 0; ANS2 = 0; ANS3 = 1; //左からアナログデータ右づめ、アナログ3使用(2つのbit)、アナログ有効化 ADCON0 = 0b10001101; while(1) { GO_DONE = 1; while (GO_DONE); cds = ADRESH * 256 + ADRESL; if (cds &lt; 768) { if (GPIO2) { GPIO2 = 0; offing = 0; doOff = 0; } } else { if (!GPIO2) { GPIO2 = 1; offing = 1; count = 0; doOff = 0; } } if (doOff) { doOff = 0; GPIO2 = 0; } } </code></pre> <p>}<br /> ||</p> <p>ちなみにこれも電池3本の3Vで動いているみたい。<br /> なんでか分からないがそのうち何か壊しそうだな…。</p> <p>あとアナログ変換のスタートである<br /> GO_DONE = 1;<br /> を<br /> GO_DONE;<br /> と間違えていたせいでどうやっても上手くいかなかったので<br /> デバッグしてみようと思ったが、<br /> どうもPIC12F675だとうまくデバッグが出来なかった。<br /> プログラム送信時にエラーが出る。<br /> 検索しても出てこないしデータシートも記述が少ないし無理なやつかもしれない。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14415 2014-03-25T09:00:01+09:00 2014-03-25T09:00:01+09:00 https://crieit.net/posts/PIC12F675-PWM PIC12F675でPWM <p>PWMに挑戦しようと思って以前見かけたサイトを見てみたら、<br /> どうも12F675じゃない。<br /> おかしいと思いデータシートを見てみたら、<br /> どうもそこに書かれていたレジスタ(CCPR3Lとか)が無い。<br /> 12Fは自前で実装しないといけないのか…。</p> <p>しかたがないので自前で試しにやってみた。<br /> うまく調整しないと普通に点滅して見えちゃう。<br /> for文でディレイしているサイトも見かけたが<br /> 恐らくあまり実用的ではないと思うので一応タイマーでやってみている。</p> <p>詳しいことは分からないが、別で見かけたサイトを参考にして<br /> 割り込み関数内では変数の切り替えだけにするようにして<br /> なるべくmainの方でLEDの操作の方は行うようにしている。<br /> もちろん詳しいことはわからないので無意味かもしれない。</p> <p>環境は次の通り。<br /> ・MPLAB X IDE v2.0<br /> ・コンパイラはXC8<br /> ・pickit3使用</p> <blockquote> <p>|c|</p> </blockquote> <h1 id="include &lt;xc.h>"><a href="#include+%26lt%3Bxc.h%3E">include <xc.h></a></h1> <h1 id="pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF"><a href="#pragma+config+FOSC+%3D+INTRCIO%2C+WDTE+%3D+OFF%2C+PWRTE+%3D+ON%2C+MCLRE+%3D+OFF">pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF</a></h1> <p>static unsigned char count;<br /> static unsigned char flag;<br /> static bit uping;<br /> static unsigned char maxcount;<br /> static unsigned char wait;</p> <p>static void interrupt inter() {<br /> T0IF = 0;</p> <pre><code>count++; if (count == 4) { flag = 1; } else if (count == maxcount) { flag = 0; count = 0; if (++wait == 10) { if (uping) { maxcount++; if (maxcount == 32) { uping = 0; } } else { maxcount--; if (maxcount == 7) { uping = 1; } } wait = 0; } } </code></pre> <p>}</p> <p>main() {<br /> GPIO = 0;<br /> CMCON = 0x07; // コンパレータ未使用<br /> ANSEL = 0x00; // AN未使用<br /> TRISIO = 0x3B; // GP2:out<br /> OPTION_REG = 0x80; //プリスケーラ2<br /> TMR0 = 0x00; //カウント0<br /> T0IE = 1; //タイマー0使う<br /> GIE = 1; //タイマー使う</p> <pre><code>count = 0; flag = 0; uping = 1; maxcount = 8; wait = 0; while(1) { if (flag == 1 && GPIO2) { GPIO2 = 0; } else if (flag == 0 && !GPIO2) { GPIO2 = 1; } } </code></pre> <p>}<br /> ||</p> <p>しかし予習ではPIC+白LEDは3Vじゃ動かないはずだったんだけど<br /> pickit外して1.5Vの電池2本で動いた。<br /> まだまだ良くわからないことだらけだ。</p> <p>はんだの練習もしたいので一応12F675でちょっとしたものは作るつもりだが、<br /> それでなんだかんだできたらPIC18F14K50も試してみようと思っている。<br /> 秋月にUSB付きのがあるので一回それで色々やってみる。<br /> やっぱシリアル通信できないと幅が広がらない。<br /> arduinoで毎回2000円以上かけてUSB使うとか金が飛んでしょうがないだろうし。<br /> うまくいったら回路図を元に自分で量産できるようにしてみたい。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14416 2014-03-25T09:00:00+09:00 2018-10-06T17:55:36+09:00 https://crieit.net/posts/PIC12F675-LED PIC12F675でLED点滅 <p>arduinoは簡単すぎて素人でもすぐになんでもできるが<br /> PICは色々難しそうなのでなるべく細かいことも<br /> 備忘録として残しておくことにする。</p> <p>とりあえずLED点滅が出来たのでメモ。<br /> 環境は次の通り。<br /> ・MPLAB X IDE v2.0<br /> ・コンパイラはXC8<br /> ・pickit3使用<br /> ・書き込み&テスト回路は下記<br /> <a target="_blank" rel="nofollow noopener" href="http://www.geocities.jp/zattouka/GarageHouse/micon/MPLAB/socket/ICSP.htm" target="_blank">ブレッドボードとPICKit3でPICに書き込む</a><br /> ピンソケットを買い忘れピンヘッダばっかり買ってたので<br /> pickit3と回路はジャンパーワイヤでそのままつないだ。<br /> ・プログラムは<a target="_blank" rel="nofollow noopener" href="http://homepage3.nifty.com/mitt/pic/xc8/xc8_675_02.html" target="_blank">LEDを点滅させる</a>を参考にして改変して<br /> 下記のようになった。<br /> __CONFIGではなくpragmaで書くようになっているらしい。</p> <blockquote> <p>|c|</p> </blockquote> <h1 id="include"><a href="#include">include</a></h1> <h1 id="pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, O, MCLRE = OFF"><a href="#pragma+config+FOSC+%3D+INTRCIO%2C+WDTE+%3D+OFF%2C+PWRTE+%3D+ON%2C+O%2C+MCLRE+%3D+OFF">pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = ON, O, MCLRE = OFF</a></h1> <h1 id="define LED GPIO4"><a href="#define+LED+GPIO4">define LED GPIO4</a></h1> <h1 id="define _XTAL_FREQ 4000000"><a href="#define+_XTAL_FREQ+4000000">define _XTAL_FREQ 4000000</a></h1> <p>int main(void)<br /> {<br /> GPIO = 0;<br /> CMCON = 0x07;<br /> TRISIO = 0;<br /> ANSEL = 0b00110000;<br /> OPTION_REG = 0b10000010;</p> <pre><code>while(1) { LED = 1; __delay_ms(65); LED = 0; __delay_ms(65); } return 0; </code></pre> <p>}<br /> ||</p> <p>すぐ成功するかな〜と思ったけど数時間かかった。<br /> 問題は書き込みの失敗。<br /> Failed to program device<br /> というエラーがでて全く書き込みが出来なかった。<br /> IDE、IPEどちらでもいろいろ試してみたがダメ。</p> <p>結局問題は電源供給だった。<br /> ネットで検索すると、pickit3からの電源供給を<br /> 3.25としているところが多かったのでそれに見習ってやっていたのだが、<br /> ダメ元4.5にしてみたところあっさり書込みでき、LEDが光った。<br /> このあたり素人にはむずかしいところだ…。<br /> (追記:3.25は多分PIC24の記事とかを見て参考にしてしまったんだと思う)</p> <p>まあなにはともあれ動かすことが出来たので<br /> 引き続き色々試していきたい。</p> だら@Crieit開発者