モノ創りで国造りを

ハード/ソフト問わず知見をまとめてます

UpBoard使い方まとめ

在庫管理がうっとおしい

モノを色々作っていると、部品の在庫管理が面倒になってきました。
在庫管理は一つ間違うと最終製品の納期遅延につながるし、さらに経理とも絡むので厄介です。
今までは頻繁に個数をチェックしてましたが、部品数が多くなるにつれて時間かかりすぎる。
部品の在庫管理を自動化したい!というモチベーションで、システムを構築することにしました。

在庫管理システムの概要

在庫管理したいモノを大きく分類すると以下のようになります。

重さ\増減 多い(10個以上) 少ない(10個未満)
重い(1g/個以上) A: ネジ、ナット B: Assy品、モジュール品、大きい電子部品
軽い(1g/個未満) C: 汎用の電子部品 D: 用途が限定される電子部品

在庫を自動で管理するために、 Aは重さで個数を管理したいと考えました。
質量計から箱の質量を差し引き、予め入力された1個当たりの質量から自動で個数が算出されるようにします。

その他は、箱に取り付けたスイッチ付きのデバイスで管理したいと考えました。
箱から部品を取り出したら、個数をデクリメントし、箱に部品を入れたら個数をインクリメントします。

データをGoogleスプレッドシートに表示することで、在庫数の確認や発注手配のアラートが出せたりします。
f:id:yuji2yuji:20190625112340p:plain

Rasberry Piより高機能なUpBoard

基板は自作すると一個あたり1,000~1,500円くらいです。
各基板に電源ケーブルを接続するのはイケてないので、電池駆動式にします。
省電力化が重要になります。

各基板のデータを収集しスプレッドシートに抽出する母艦はRaspiで開発するつもりでしたが、
余っていたUpBoardを使う事にしました。

UpBoardは使った事がないので、セットアップ含めて使い方を以下にまとめていきます。

UpBoardのセットアップ

まずはISOを書き込む必要がありますが、とりあえずubilinuxを使用します。
ubilinuxは組み込みLinux用のディストリビューションです。
これを使っておけば、UpBoardのGPIOが簡単に使用可能です。
注)そこそこなメモリがあるので、Ubuntuも使えますが、
GPIOを簡単に使うためには別途カーネルを差し換える必要があるので面倒

1: emutexのHPからubilinuxをダウンロード
2: Rufusをダウンロード
3: RufusでUSBにイメージを書き込む
設定は以下の通り。
f:id:yuji2yuji:20190625113748p:plain

4: USBと優先のキーボードとHDMIをUpBoardに接続する
5: UpBoardに電源を接続する
6: UpBoardが起動するので、ubilinux installer UEFI CD (interactive)を選択する(上から二番目) 7: インストール完了したら、電源抜いて再起動する
8:パスワードを聞かれるので"ubilinux"と入力し起動する。

これで使用できるようになりました。

とりあえずLチカ

GPIOを使えるように以下をターミナルに打ち込みます。

$ sudo apt update  
$ sudo apt upgrade
$ sudo apt install python-rpi.gpio

スクリプトscript.pyを実行する場合は以下のコマンドを打ちます。

$ sudo python script.py

UpBoardのピンアサインはラズパイと互換性があります。
ラズパイのピンアサインは以下の通りです。
f:id:yuji2yuji:20190625131019p:plain
1ピンの位置は基板上の▽マークで記載されています。

GPIOでLチカするために、以下のスクリプトを記載します。
こちらを参考にしました。

import RPi.GPIO as GPIO
import time

LED1=14
LED2=15
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED1, GPIO.OUT)
GPIO.setup(LED2, GPIO.OUT)

flag = 1
while True:
    GPIO.output(LED1, flag)
    GPIO.output(LED2, flag ^ 1)
    flag = flag ^ 1
    time.sleep(1)

14ピンをLED1という名前に割り当てます。
15ピンをLED2という名前に割り当てます。
GPIO.setmode(GPIO.BCM)で役割ピン番号モードに設定します(上図のLinux GPIOの番号を使用する)。
* 基板のピン番号に設定したい場合はGPIO.setmode(GPIO.BOARD)とします。
GPIO.setup(LED1, GPIO.OUT)でLED1をGPIOの出力として使用する設定にします。
GPIO.setup(LED2, GPIO.OUT)でLED2をGPIOの出力として使用する設定にします。

while True:で以下を繰り返すようにします。
1: GPIO.output(LED1, flag)でLED1の出力をflag(1で出力H、0で出力L)にします。
2: GPIO.output(LED2, flag ^ 1)でLED2の出力をflagの反転にします。つまりLED1の逆になります。
3: flag = flag ^1 でflagを反転させます。
4: time.sleep(1)で1秒間待ちます。

これで「LED1が点灯/LED2が消灯」=> 「LED2が点灯/LED1が消灯」を
1秒ごとに繰り返すようになります。

UpBoardとGPIOの使い方まで理解できました。
次はUARTとI2Cを使ってみようと思います。

技術士二次試験(電気電子)での気になるワードまとめ

要把握なワード

製品・経済系

EV車
人工衛星
火星探査機
ロケット
ドローン
ロボット
水中ロボット
農業ロボット
パワーアシストロボット
オプトエレクトロニクス
データセンターとハードウェア
タッチパネル
3Dプリンタ
エレクトロニクスとスポーツ
IoT
VR
AR

開発系:

安全設計(フェールセーフ、フォールトアボイダンス、フォールトトレランス)
FMEA

回路系:

ブラシレスDCモーター
センサレスモーター制御
モータードライバ
PLL
マイクアレイ
USB Type-C
HDMI
ボード線図
FRA
AMとFM
制御理論
ミリ波レーダー
5G
無線充電

素子・部品系:

ダイオード
MOSFET
SiC
FPGA
ASIC
マイコン
ADコンバーター
DCDC電源
LDO
CMRR
PSRR
入力換算ノイズ
ノイズフィギュア
半導体プロセス 7nm
GPU
コモンモードノイズ
TVS
バリスタ
ESD
有機LED
オペアンプ

センサ系:

臭気センサ
サーモセンサ
MEMSセンサ
触覚センサ
圧力センサ

計測器系:

オシロスコープ
電子負荷
スペクトラムアナライザ
安定化電源
電流クランプメーター
マルチメーター(アナログ/デジタル)

AI・ロボ系:

AI
RPA
画像認識
音声認識
SLAM(自律移動)
LiDAR
自動運転
ADAS

政策系:

RoHS
水素燃料
太陽電池
リチウムイオン電池
鉛畜電池
全固体電池
メガソーラー
FIT(固定買取制度)
水車(らせん水車)
バイオマス発電
AEC-Q100/AEC-Q101
風力発電(洋上風力) マイクログリッド

令和元年の技術士試験をうけるぞー!

!?・・・次試験内容が・・・・・・、変わった・・・?

特に理由もなく技術士になりたいと思ってかれこれ数年。
3年前に技術士一次試験を受けて、見事合格し、その翌年には二次試験を受ける気満々だったのに
子供生まれたり転職したりで仕事もプライベートも忙しすぎて、申し込みすらできず。
その翌年(昨年)も仕事がブラックで、身動きとれず。

でも勉強はちょこちょこっとしてたんですよね。
通勤時間に、電車の中で、択一式の問題解いて。

で、家庭も仕事もそこそこ落ち着いて、今年は受けるぞーと思ったんですが ・・・

技術士二次試験筆記試験内容
技術士二次試験筆記試験内容

んー?んんー!?択一式がない? これ総監の試験内容かと思ったけど、"総監を除く"なので、通常の技術部門の試験内容で間違いないよな・・・

・・・試験の内容が・・・・・・、・・・変わった・・・?
試験内容が変わった

ここ鉛筆で文章なんて書いてないのに、計5時間30分も文章を書き続けるのですか。
途中で書きたい内容が変わったら、全部消しゴムで消すんですか。 そんなことしたら用紙が真っ黒になってしまうのでは。
力加減を誤ったら、用紙が破れてしまうのでは。
消しゴムにシャーシンを埋め込むいたずらをされたら、消せば消すほど用紙が汚れてしまうのでは。
右手の小指側も真っ黒になるのでは。
終わるころには、腕がパンパンになるのでは。

変更一回目で過去問あるのかとか、採点基準はとか色々と不安はありますが、がんばります!!

日々学んだことを忘れないようにブログに書いてこ。

大手からベンチャーへ転職してから2ヶ月経っての感想

この記事は転職しようかと悶々とされてる方のために
少しでも参考になればと思い書きます。

転職時のブログは↓
yuji2yuji.hatenablog.com

大手企業から転職して二ヶ月経ちました。

簡単に自己紹介ですが
・理系の大学院卒
・ハードウェアエンジニア
・年齢は30代前半
・妻子持ち(子供は0歳と1歳の二人)
・マイホーム購入したばかり(ローン3000万)
・貯金1000万
・転職理由は、自分の仕事が世界の進歩に貢献してない気がするから

前職の会社の状況は
東証一部上場の誰もが知ってる大手企業
・人間関係は良好
・労働時間は、残業月平均40時間(電通事件によって、さらに改善中)
・通勤時間はドアツードアで1時間弱
・給料は750万弱

転職後の会社は
・社員数30人未満のベンチャー
・人間関係は良好
・労働時間は残業月平均50時間(裁量権が強く、人による)
・通勤時間はドアツードアで1時間40分
・給料は600万

転職について現在の心境は、「転職してよかったー!!」です。
前職のつまらない仕事をなぜ何年間もやってたのか不思議。
前職のの閉塞感を思い出すと反吐が出ます。
前職のみんなに転職を勧めたい位です。
これは転職サイトのステマではありません。本当に本心からの言葉です。
転職最高。エブリバディ、レッツ転職。

自分自身、特に変わったなと思ったのは、他人に嫉妬しなくなったこと。
例えば有名人の収入や株で儲けたとかそういった話を聞くと
昔は楽して稼ぎやがって、とか、どうせすぐ大損するさってかしろといった
嫉妬心が強かったのですが
最近では他人のそういった羨ましい事に対して特に何とも思わなくなりました。
自分の意志に従って決断し行動するというだけで、ここまで心境が変化するのかと驚いています。
今までは自分の人生はどこかで人が操作していて
運が良かったり悪かったりするといった考えが頭の片隅にあったのかもしれません。
自分の意志に従う。転職によってようやく自分の人生が始まったような気さえしてます。

ちょっとポエム入りましたが、自分の転職が成功と思えるのは
転職先の社員がみんな非常に優秀だからというのが大きいです。
正直なところ、転職前は大手で何年も働いたしベンチャーなんて余裕だろと
舐めてかかってましたが、いやはや日本のトップ集団は本当にすごい。
*東大・京大・東工大の博士が多数在籍。
好奇心旺盛で吸収力は高く思慮が深い。
自分が働いてる間、彼らも当然働いていたわけで
ポテンシャルを考慮すると自分が負けているのは当たり前と自分自身をフォローしてます。
自分は大手だったが故に仕事内容は狭く深くに加えて雑用多数だったので
ベンチャー特有の幅広い仕事をこなしてきた彼らは、複数分野の知識があり驚くとともに
今まで自分は何してたんだと、くだらない仕事させやがってと無為に過ごした時間を後悔してます。
そしてみんな、優秀が故に性格が良く人間性が高い。美人は性格も良いのと同じです。

最後にもう一度。
転職最高。エブリバディ、レッツ転職。

以上が総括。以下は蛇足。

転職前に一番不安だったのは通勤。
早起きすることで座席を確保し読書、勉強、たまに睡眠と有効利用してます。
給料は下がりましたが、生活する上で何ら問題なし。貯金も出来てます。
ちょっと不安だった嫁の機嫌ですが、今まで以上にフォローしてくれてます。
前職は安い社食があったので、転職によってご飯代が少し高くつくようになりましたが
社食はレパートリーが少なく美味しくもなかったので、今の方が満足。

転職最高。エブリバディ、レッツ転職。

大手からベンチャーへの転職

一部上場の大手企業からベンチャーへの転職を決意し ついに会社に報告しました。

転職活動中や転職を決意するまでにとても悩み苦しみました。
その時に転職経験者のブログに大変救われたので
今回自分も何かの役に立てばと思いここにまとめておきます。

簡単に自己紹介ですが
・理系の大学院卒
・ハードウェアエンジニア
・年齢は30代前半
・妻子持ち(1歳、二人目妊娠中)
・マイホーム購入したばかり(ローン3000万)
・貯金1000万

このスペックだと 会社が激務で給料が低く家族を養えないとかでもなければ
転職を検討する人はいないのではと思います。

会社の状況はというと
東証一部上場の誰もが知ってる大手企業
・給料良い(30代前半で年収700万以上)
・人間関係は良好
・労働時間は数年前に比べれば改善された
 (以前は毎月80時間残業だったのが、最近は50時間位以内に収まってる)
・職場まではさほど遠くない(ドアツードアで1時間)

この状況でありながらなぜ転職活動を始めたかというと
①自分の技術領域を広げたい
②新しい事をやりたい
③開発する製品の隅々まで自分でコントロールしたい
そんな理由からです。

この時点では、
部署異動で対応できるんじゃないか
よっぽど興味がある会社があれば話を聞いてみようかな
転職するかどうかは受かってから考えればいいや
ぐらいに思ってました。

ひとまず転職サイトに登録して
ベンチャー企業に的を絞って調査しました。
なぜベンチャーかというと大手企業の場合
上記の①~③が実現できないと知っているからです。

あまり興味を引く求人がない中、
ついにビビッとくる求人に巡り会いました。
ここ面白そう!と思い、即座に面談を依頼。

とんとん拍子で進むと思いきや
面接が平日限定ということで、なかなか自分が都合をつけれない
という問題が発生し手間取りました。

運良く内定をもらえましたが
最初に申し込みをしてからかれこれ2か月以上かかりました。

受かったので転職を本格的に検討開始。
と言っても自分としてはそれまでに業界を調査し
この会社に転職したいと本気で思っていました。

ここで問題となるのが
”家族の了解が得られるか”
です。
巷では嫁ブロックと言われていますが
例に漏れず自分も見事にブロックされました。

二人目の子供が生まれるのに何を言ってんだと
アホかとバカかと。小一時間問い詰められました。

一番のネックはお金の問題です。
子供が二人いて、家のローンもあって、やってけるのかと。
正直に言えば、ベンチャーが提示した年収は、
元の会社の年収より120万低かったです。
これだけ見ると反発される気持ちはわかるかと思います。

そこで自分は考えました。
この年収で問題が発生するかと。
毎月の出費、将来の子供の学費、リホーム代など細かく計算した結果、
ベンチャーの年収でも何ら問題なく
ローンを払い、家族を養えて、貯蓄も年間100万できることがわかりました。
このことを妻に強く主張しました。
何度も頭を下げ、最終的には味方になってくれました。

人生を全うする上で必要な事は何か。
それはお金を貯金する事では決してありません。
目的があってお金を貯めるのはわかります。
しかし、漠然と将来が不安だからお金を貯めるというのは
計画性がないもしくは考えるのが面倒くさいという怠慢です。

とカッコいい事を言ったいいのですが
やはり転職するには勇気が必要で
なかなか会社の上司に伝える気が起きませんでした。

悶々とした日々を過ごし、仕事中に自分の将来を考え
年収下がるけどいいのかな
ベンチャーは不安定だけど大丈夫かな
会社遠くなるけど通勤ラッシュ耐えられるかな
こんな事で自問自答を繰り返していましたが
最終的には、

自分の人生は一度きりで
その人生で、世界を未来に進めるような仕事がしたい

こんな気持ちで自分を鼓舞しついに決心。

上司に打ち明けることで、ほぼ転職決定だと思うと
なかなか緊張しました。
あー言えばこう言う、こう言えばあー言うといろいろと深く考えました。
怒られるかな、落胆されるかな、今までの恩はないのかとか言われるかな
と不安は募るばかりでしたが、いざ報告すると

そっかー、まー、しょうがないよね
好きなことをやるのがいいよね

とがっかりされながらも、すぐに理解を示してくれました。
上司もおそらく若いうちに好きなことが出来る仕事に
転職すべきだったと後悔しているのかもなと思いました。

翌日、さらに上の人に話が伝わり
この状況で転職するのはばかだろ、とか
せめて3月まではいてくれとか
色々と責められましたが先方との予定があるため
強く意思表示を示し予定通り辞めれる事となりました。

転職に思い悩んでいる人へ
・会社は案外理解を示してくれる
・家族も案外理解を示してくれる
・お金はやりくりすればなんとかなる
大丈夫です。安心してください。人生なんとかなります。

ジョブスが言ってました。
明日死ぬなら今やってることをやるか、それで後悔しないかと。
人生一度きりですから、本当にやるべきだと思ったことをやりましょう。

ベンチャー就職して数ヵ月後に
実際に転職してみてどうだったかを報告したいと思います。

転職して2カ月後の心境は↓

yuji2yuji.hatenablog.com

アナログ回路の個別設計--基本事項--

Makersの課題

PCが安くなり、ソフトのツールがほぼ無料になった結果、
プログラミングの個人開発が容易になった。
加えてArduinoやラズパイ、それらに接続できる各種モジュールも安価で販売されるようになり、
個人でハードウェアの利用が可能となった。
さらには、個人で基板開発を行う上で障壁となっていた回路・基板CADも無料・安価に利用できるようになり、
製造も中国ベンダーによる低価格化が進んだ結果、 個人でハードウェアを設計・開発できるまでになった。

現時点で、個人がモノづくりを行うに必要な土壌はすべて整っており、
個人の技術力だけ唯一の障壁となっている。

ソフトウェアはトライアンドエラーを無料で行える一方で、ハードウェアは、安価になったとはいえ、一度のトライにお金がかかる。
ここでは、ハードウェア開発を行うにあたって、ミスを最小化できるよう、基本事項をまとめておく。

前提

ICの周辺回路設計の基本は、
ICのデータシートを読みこみ、レファレンス回路を流用・微調整すること。
危ない橋は渡らず、極力レファレンス回路を真似するのが、動作する基板を開発するための近道。

電源

電源は大きく分けてLDOとDCDC電源がある。
LDOの呼称はLow Drop Outの頭文字による。
"Low Drop Out"とは入力電圧と出力電圧の差が小さいことを意味している。
"DCDC"は、DC電源から(電圧の異なる)DC電源を生成することを意味している。
それぞれの特徴は大雑把に書くと以下の通り。

項目 LDO DCDC
構成 シンプル 複雑
ノイズ 小さい 大きい
効率 悪い 良い

LDO(Low Drop Out)

LDOの使い方

LDOの使い方は極めて簡単。やることと言ったら出力電圧の設定のために、FB抵抗の値を決めるくらい。

電源オフ時に注意が必要な時代もあった

入力電源供給を遮断した場合に、出力電圧>入力電圧となり、入力側の機器を壊す恐れがある。
最近のLDOダイオード内蔵が多いが、データシートを確認して、
ダイオードがなければダイオードを実装するのが良い。

LDOは効率が悪い

LDOは入力と出力の電圧は異なるが電流は等しい。

入力の電力 Pin = Vin x Iin
出力の電力 Pout = Vout x Iout

とした場合、IinとIoutが等しいので、消費電力は

Pross = Pin - Pout = (Vin - Vout) x Iin

となる。例えば入力電圧5V、出力電圧3.3V、電流1Aとした場合

Pin = 5 x 1 = 5W
Pout = 3.3 x 1 = 3.3W
Pross = 1.7W
効率 η = 3.3/5 = 66%

となる。
Prossの1.7WはすべてIC内部で熱になる。基板を使って放熱する必要がある。

ちょっとレベルアップ

ノイズレベルの確認。
LDOのデータシートにこんなグラフがある。
f:id:yuji2yuji:20181017013553p:plain
これは電源電圧変動除去比といって、
入力電圧のAC成分をLDOを通すことでどの程度除去できるかを示したもの。
例えば、横軸1kHzにおいて縦軸が60dBだった場合、
入力電圧に含まれる周波数1kHzのAC成分は、このLDOを通すことで
60dB(=1000分の1)抑制されることを意味している。

DCDC電源

DCDC電源には入力電圧と出力電圧の関係で、大きく分けて4種類ある。
基本的な構成は、コントローラICとFET or ダイオードで構成される。
FETのほうが効率は良いが、価格・サイズがアップする傾向にある。

降圧コンバー

出力電圧<入力電圧となるもの
以下のような回路で構成される。 f:id:yuji2yuji:20181017015045p:plain
出力段にコイルとコンデンサによるフィルタが構成されるので、
出力電源のノイズはそこそこ抑えられる。

昇圧コンバー

出力電圧>入力電圧となるもの 以下のような回路で構成される。 f:id:yuji2yuji:20181017015349p:plain
昇圧コンバータで注意が必要なのは、 電源ICが使用されない状態(Swをオフ)にしても
出力側に電源が供給され続ける点である。

SEPICコンバー

出力電圧が正圧で、入力電圧と出力電圧の大小関係はなし。 f:id:yuji2yuji:20181017015708p:plain
回路構成はかなり複雑だが、専用ICとそのデータシートがあれば誰でも簡単に実装が可能。

Cukeコンバー

出力電圧が負圧で、入力電圧と出力電圧の大小関係はなし。 f:id:yuji2yuji:20181017015847p:plain

チャージポンプ

昇圧/SEPIC/Cukeコンバータにはチャージポンプ回路を接続することで、
出力電圧を容易に2倍、3倍・・・と増幅できる。

FETの選び方

FETにはPMOSとNMOSがある。 f:id:yuji2yuji:20181017020452p:plain
FETの説明を見ると、小難しいグラフが記載されているが
個人開発での部品選定においては、ほぼ無視してOK。
とりあえず重要なのは、以下の4点。 印加電圧・電流がデータシートに記載されている定格値を超えるとFETは破損するので注意。

VGS(ゲートソース間電圧)

ゲートとソース間の電圧。ゲート側が+。

VDS(ドレインソース間電圧)

ゲートとソース間の電圧。ゲート側が+。

Idrain(ドレイン電流)

FETオン時に流れる電流値。

Ron(オン抵抗)

FETオン時のドレインソース間の抵抗。 大電流を流す場合、オン抵抗が大きいと発熱が大きくなり最悪燃えるので注意。
FET内部の消費電力の計算は以下で求められる。

消費電力 Pross = Idrain x Idrain x Ron

ロードスイッチ

一つの電源ラインから複数の機器に電源供給する場合に、
各機器の電源入力のOn/Offを切り替えたい事がある。
その場合、ロードスイッチを使用する。
小型のロードスイッチICも多数存在するが、
大電流用途ではNMOSとPMOSで構成するのが一般的。
電圧と電流によってFETを選択する。
f:id:yuji2yuji:20181017021054p:plain
1A程度であれば小型のICが売られている。

オペアンプ

センサのアナログ信号をデジタル化する際にADコンバータでAD変換する。
AD変換する前に信号レベルをADコンバーターのフルスケールに合わせるため、
オペアンプで信号を増幅する。

反転増幅回路

一般的な構成。出力が±反転される。 *+と-を間違えないように注意。 f:id:yuji2yuji:20181017021237p:plain
入力電圧と出力電圧の関係は以下となる。

Vout = -(R2/R1) x Vin

非反転増幅回路

出力を反転させないで増幅する場合はこの回路構成をで行う。
*+と-を間違えないように注意。 f:id:yuji2yuji:20181017021357p:plain
入力電圧と出力電圧の関係は以下となる。

Vout = (1+ R2/R1) x Vin

バッファアンプ(ボルテージフォロワ)

信号を増幅させない場合の回路構成。
電流が必要な場合や、フィルタを多段にする場合に使う。
f:id:yuji2yuji:20181017021501p:plain
*非反転増幅でR1 = R2 = 0の場合と等価

プルアップ/プルダウン

信号がデジタル値の場合、信号レベルのデフォルト状態をHかLに固定しておきたいことがある。
その場合に、信号-電源間または信号-GND間に抵抗を接続する。

インターフェース

IC間で信号をやり取りする場合、双方のインターフェースをあらかじめ統一しておく必要がある。
代表的なものは以下。

I2C

データ線とクロック線の2本で通信を行う。2本ともプルアップ抵抗を接続するのが一般的。

SPI

送信用のデータ線(MOSI)と受信用のデータ線(MISO)とクロック線(CLK)とチップセレクト信号(CS)の4線式。
MasterとSlaveを予め決めておく必要がある。 *MOSIはMaster Out Slave In、MISOはMaster In Slave Outを意味。 クロックに対するデータの読み出しタイミングで4通りのモードがある。

UART

送信用のデータ線と受信用のデータ線の2線式。
予めデータの周波数(ボーレート)を決めておく必要がある。

オープンコレクタ(オープンドレイン)

信号線をプルアップし、スレーブ側のICが信号レベルをGNDに落とすことで通信する。
信号の電圧レベルをマスター側が自由に設定できるメリットがある。

PICマイコンの覚書

Print文の出力

XC8の場合、PICでprint文を表示するには、printf関数を書くだけではなくputch関数を記載する必要がある。 XC16では、 printf関数は通常使用が可能。

環境

型番 PIC18F25K80
コンパイラ XC8

実装

なにはともあれ#include <stdio.h>を記述。
main関数内にpirntf("%d",hensu);と記述すると問題なくコンパイル通るもののprint文は記述されない。
print文を表示させるには、以下のputch関数を記載する。
putch関数の記載場所によってはredefineエラーが出る。
その場合は記載場所を変える(とりあえずmain.cに記載すればOK)。
レジスタ名称はPICのシリーズや型番によって若干異なるので注意。
* 以下の例はUSART1に表示する場合。
* USART2に表示する場合は12に変えれば良い。

void putch(char Data){
    while(!TXSTA1bits.TRMT);
    TXREG1 = Data;
}

CAN通信

PICでCAN通信を開通するために、MCCでIDを設定したが、設定した結果はMASKとFilterに反映される。
CANのIOピンの設定がどこに反映されているか不明だったため、念のためPRAGMAを設定した。

環境

:--: :--:
型番 PIC18F25K80
コンパイラ XC8

MaskとFilterについて

CAN通信モジュールは、MCCで使用するIDを設定できる。
全てのIDを受信可能にもできるが、ノイズを考慮し、必要な分だけ受信できるように設定したほうが良い。
設定結果はFilterとMaskに反映される。
Maskで1となっている全bitについて、Filterに記載された値と受信データの値が等しい場合のみ、データは受信できる。
例えばMask=0x3E、Filter=0xA7の場合、受信データは0bxx10011xとなる(xは0/1どちらでも良い)。

Hex BIN
Mask 0x3E 0b0011_1110
Filter 0xA7 0b1010_0111
Valid Data 0bxx10_011x

CANモジュールのPRAGMA設定

なにかしらのヘッダーに以下を追加。

#pragma config CANMX = PORTB

コメントアウトしてもうまくいったので、多分必要ないんだろうけど、
今後のことを考えてブログに残しておく。

ADC

dsPICでADCの設定をMCCに任せっきりにした場合、
単chのADCはうまくいったが、複数chをスキャンする場合にAD変換できなかった。
調査した結果、ADCを行えるようになったのでメモ。

環境

シリーズ dsPIC33E
コンパイラ XC16

実装1:単chのAD変換

CH0にAN0を1っ回だけAD変換する場合は以下。 下記以外の設定はMCCに任せてよい。

AD1CON2bits.CHPS = 0;//CH0をセット
AD1CHS0bits.CH0SA = 0;//AN0をセット

AD1CON1bits.SAMP = 1;//サンプリングを開始する
int i = 0;
for( i=0;i <1000;i++){}//サンプリングするため一定時間設ける
AD1CON1bits.SAMP = 0;//サンプリングを止める           
while(!AD1CON1bits.DONE){}//サンプリングデータのAD変換完了を待つ

printf("%x",ADC1BUF0);//データはADC1BUF0で取り出せる。

実装2:複数chのAD変換(スキャンモード)

CH0にAN0~AN5をAD変換(スキャン)する場合は以下。

AD1CON1bits.ASAM = 1;//自動変換モードをセット
AD1CON2bits.CHPS = 0;//Ch0を使用
AD1CON2bits.BUFM = 0;/バッファのモードを設定
AD1CON2bits.ALTS = 0;//MUXAのみ使用する
AD1CON4bits.ADDMAEN = 0;//DMAは使用しない
AD1CON2bits.CSCNA = 1;//CH0をスキャンモードに使用する

AD1CON2bits.SMPI = 0x5;//AD変換6回実施後に変換完了したことを割り込みで伝える
AD1CSSL = 0x3F;//スキャンするCHをセット(ここでは0~5))
AD1CON1bits.SSRC = 0x7;//サンプリングを自動開始するようにセット


int main(void){
    while(!AD1CON1bits.DONE){}//AD変換完了を待つ
//各信号のAD変換結果はADC1BUFxから取得できる。
    printf("BUF0:0x%x\r\n",ADC1BUF0);
    printf("BUF1:0x%x\r\n",ADC1BUF1);
    printf("BUF2:0x%x\r\n",ADC1BUF2);
    printf("BUF3:0x%x\r\n",ADC1BUF3);
    printf("BUF4:0x%x\r\n",ADC1BUF4);
    printf("BUF5:0x%x\r\n",ADC1BUF5);
}

PWM制御

モーター駆動用にPWM制御を実装した。PWM周期の基準クロックはFosc/2でなくFoscな点に注意。
勘違いしてハマりました。

環境

シリーズ dsPIC33E
コンパイラ XC16

実装

PWMモジュールには、ハイサイドとローサイドのスイッチを制御するモードが用意されている。
PWMを一定周期で動作させるには、タイムベースをプライマリに設定する。
PWM周期は、PTPERレジスタで設定する。
例えばFoscが30MHzかつクロック分周が1:1、PTPERが100だった場合、PWM周期は

1秒 / 30MHz x 100 = 3.3マイクロ秒

となる。
PWMのDutyは、ハイサイドはPDCxレジスタ、ローサイドはSDCxレジスタで設定する。
PDCx/SDCxレジスタの値とPTPERの値の比がDuty比となる。
例えばFoscが30MHzかつクロック分周が1:1、PDC1を40とした場合、PWM1Hピンが'H'となる時間は

1秒 / 30MHz x 40 = 1.32マイクロ秒

となる。

Timer割り込み

PWM周期毎にDuty比変えるためにタイマー2の割り込みを使用。

環境

シリーズ dsPIC33E
コンパイラ XC16

実装

Timer2の割り込みをEnableにする。
割り込みのタイミングはTMR2レジスタで決まる。基準となるクロックはFosc/2。
PWM周期毎にDuty比変えるには、TMR2レジスタ値はPTPERレジスタの半分にする必要がある。
またはPTPERレジスタ値を2倍にするか、PWMのクロック分周を1:2にすれば良い。
割り込み時に実行する処理は、mccで生成されたtmr2.c内にあるCallBack関数内に記述する。

delay関数

delay関数でマイクロ秒以下の制御を行うには、_delay();を使う。

環境

型番 PIC18F25K80
コンパイラ XC8

実装

例えばシステムクロックが16MHzの場合、以下の記述で250ns遅延させられる。

_delay(1);

括弧内の1は実行する命令数。
1命令あたり4クロック必要なので、
1秒/16MHz X 4CLK = 250ns の遅延となる。

余談

if文やfor文を使用すると、それだけで命令が実行される。
その遅れを避けるためには、マイクロで関数のようなものを記述すればよい。

for(int i =0;i<4;i++){
     function();
}

この場合は、

#define FUNC function();
#define FUNC4 FUNC FUNC FUNC FUNC

void main(){
    FUNC4
}

もっといい方法ありそうなもんですが。