Archive
こんばんわ~
ソフトリリース完了&定時帰りでよっぱらいのゆってぃです。

ついさっき、酔っ払った勢いでエンベデッドシステムスペシャリストを申し込んじゃいました!!(><)
応用情報のおかげで午前Ⅰは免除なので、専門の組み込み系部分だけ勉強すれば大丈夫なはず…
でも今までの下位試験とは違って、他の受験者の方々も組み込み業界では百戦錬磨の猛者ばかりのはずなので、気負けしないように頑張って勉強しなくては!

やはりRTOSを使ったことがないのは痛手なんですよ。
FreeRTOSならPICで動くし、勉強しておいた方がいいのかなぁ。。。
関連記事
スポンサーサイト
こんばんは!
いい加減寝ないとやばいゆってぃです。
これ書いたら、歯を磨いて寝ます。

少し前に、学研が出してる大人の科学シリーズで「電子ブロック」があったんですよ。
思わず衝動買いしてしまったわけですが、よくよく考えたらブレッドボード持ってるしあんまり意味が無いような…。

けれども、アンプやスピーカーもついているし、センサーやマイコンとつなげればなんだか色々遊べそうです。
こんなので遊んでたら、そりゃ結婚できるはずもありませんが、何か面白いのが出来たらここで掲載したいなぁと思います。

頑張るぞ!!

では、おやすみなさいzzz
関連記事
こんばんは。
今日はお昼まで寝ててぜんぜん眠くないゆってぃです。
明日からまた仕事…ぬおぉぉぉぉぉん(涙)

今回は、応用情報技術者受験の際に勉強した連結リスト(単方向)の復習を。
前回書いた後輩からの質問で、なんかここらへんをもう一度やりなおしたくなりました(笑)
なぐり書きなので配列の境界条件とか凄まじく怪しい…。メモリ破壊起こしてないよな…(汗)
fgets()って、最後にnull入れるんでしたっけ?strlen()ってnullは数えないんですよね??
組み込みでlinuxやってたときは標準入出力も多少は使っていましたが、制御に移ってからは全く使ってなくて
忘れてしまいました(エヘン!!)

ゆってぃなだけに、細かいところは気にしない備忘録です。

(注意)絶対に参考にしないでください!!見るなぁ!!見るなぁ!!



関連記事
こんばんは!
同窓会へ行ったら、思いっきり浮いていたゆってぃです。
給料日直後なので、ファミレスでステーキを食べてきました(笑)

さて、今回はソフトウェアコーディングのお話です。

CQ出版社から出版されているインターフェースという雑誌、ご存知の方も多いと思います。
今、「教科書には載っていない!現場で役立つプログラミングのちょい技」という企画が連載中です。
現在は、良いソースコードとはどのようなものか、という壮大なテーマに関して、記事が書かれています。

これ、難しいですよね…。
プログラマの方って、自分の記述スタイルに多かれ少なかれポリシーを持っていますし、「この記述はOK!これはNG」ってやっちゃうと、下手をすると言い争いになっちゃったりするみたいで(汗)

一応、うちのチーム内でも形だけのコーディングルールはありますが、変数・関数の命名規則やコメント記述に関するもの(ネストはダメとか)で、そんなに厳密ではありません。
けれども、この記事を読むと、やはりコードの可読性って大切だなぁと痛感させられます。

たとえば、慣れた人だと簡単な分岐には三項演算子を使用しますよね。

dens = (isNegative ? -1 : 1) * AbsVal;

みたいなやつです。

上記のような簡単な分岐ならそんなにわかりづらくありませんが、たまに三項演算子の分岐先にさらに三項演算子を入れちゃったりして、書いた本人以外はよくわからなかったりする記述を見かける時があります。(書いた本人も、1年後に見たらわからないんじゃないのか?)

確かに見た目はかっこいいですが、インターフェースの記事は、そのようなトリッキーな記述は(実行性能に影響が無ければ)するべきではないとのニュアンスで書かれています。
たとえば、ジャンボジェットのパイロットはアクロバット飛行も出来るけれど、決してそんな無茶はしない。
同じように、優秀なプログラマは、傍から見ていて頼りないと思えるほど保守的なコードを書くそうです。
実行性能に影響が無ければ、保守性を選ぶわけですね。
(保守性はJIS X 0133で定められたソフトウェア品質特性モデルのひとつですから、当然といえば当然なのかもしれませんが)

ちなみに、うちのソフトのリーダーは、たとえif文の分岐先が1行しかなくても、必ず括弧で囲むそうです。
僕は囲まない派(改行もしない)だったのですが、指摘を受けて最近はきちんと囲むようになりました。
(リーダーは制御系ではなくアプリ系出身ですが)

以前は
if(isOk) return true;
else return false;

と書いていたのが

if(isOk){
 return true;
}
else{
 return false;
}

と。
ちょっとカッコ悪いですが、まさに教科書通りの記述になった訳ですね(笑)

ただ、保守性と効率性は、やはりトレードオフになる部分もあると思います。
特に組み込み・制御系といった、リソースに限りがあり、リアルタイム性も求められる分野ではなおさらです。

必要な部分は多少トリッキーに
そうでない部分は保守性を重視して。。。

そんな風に、どの1行をとっても理由が付けられるようなプログラマになりたいものです。
関連記事
どうも、本日2回目の更新のゆってぃです。
ステーキが食べたくて仕方ないので、これを書いたら近所のファミレスに行ってくる予定です(涎)

先日、後輩からmallocに関する質問を受けました。(前に出てきた後輩とは別の、お利口な後輩です)
僕の担当部分ではmallocを使うことは滅多にありません(というか、現在のリーダーから制御チーム(チームといっても僕ひとりですが)には動的メモリ確保禁止令が出ています…)ので実はよくわからないのですが、相手は大切な後輩。
わからないなんて言おうもんなら、もともと低い僕への信頼は光の速さで地に落ち、勢いあまってアルゼンチンから出てきます!


後輩の疑問は、以下のようなものでした。
(そもそも部署が違う上、その子はアプリ担当なので、コンパイラなどの詳細は一切不明なのですが…汗)
mallocの使い方があっているか知りたいと。

--後輩のソース--

int MainFunc(void){

 ACCOUNT *account;

 (略)

 CreateAccount(account);

 (略)

}

char CreateAccount(ACCOUNT *account){

 account = (ACCOUNT*)malloc(sizeof(ACCOUNT));
 if(accout == NULL) return -1;
 memset(account, 0, sizeof(ACCOUT));

 return 0;

}

--ここまで--

ビルドは通るけど、うまく動かないとの相談でした。
どこがどううまく動かないのかは聞いていませんが(笑)
このコードのどこがいけないのか知りたい、とのことでしたね。

そのコードになんかすごく違和感があったので、僕は次のように書き直させました。

--ゆってぃのソース--

int MainFunc(void){

 ACCOUNT *account;

 (略)

 account = CreateAccount();

 (略)

}

ACCOUNT* CreateAccount(void){

 ACCOUNT *account;

 account = (ACCOUNT*)malloc(sizeof(ACCOUNT));
 if(account == NULL){
   //[TODO]なにかしかるべき処理
 }
 memset(account, 0, sizeof(ACCOUNT));

 return account;

}

--ここまで--

一応、こうしたらうまく動くようになったそうです。

正直、後輩のコードがどうしてダメなのかよくわかりません!(ドヤ顔)

たぶんmallocうんぬんじゃなくて、まだ実態の与えられていないaccountを引数として渡しちゃってることがいけないような気がしないでもないのですが、自信がないのでこの辺はお茶を濁しておきましょう。

僕の書き方が正しいのかも微妙なのですが、まぁ、NGだったらコードレビューの時にあちらの部署の先輩からなんか指摘があるでしょう(笑)

ん?でもそのときに

あちらの部署の先輩T「おい!なんでこんな訳のわからん記述をしてるんだ!」
後輩「いや、あの、ゆってぃさんがこう書けって…」
先輩T「なにぃ!あの馬鹿、また適当なこと言いやがって!!とっちめてやる!!」

ってなったらイヤだなぁ…。うぅ…。

という訳で、もしこの記事をお読みになった方で
おまえ全然わかってねーじゃねえかよ!いいか、ここはな…
というイケメンな美女がいらっしゃいましたら、ご指摘いただければうれしいです(>_<)

関連記事
3日坊主からの復帰です!
ゆってぃです。

先日、ついにNHK集金の魔の手がうちのオンボロアパートにも届いてしまいました。。。

ゆ「NHK見てないんですよ(ニュースと英語とスポーツと大河ドラマ以外は…(汗))」
N「いや、そういう問題ではなく、テレビ所有者の方は全員払わなくちゃならないんですよ」
ゆ「でも、これって強制じゃないですよね?」
N「いえ、放送法第○○条で(忘れた…)決められておりましてうんたらかんたら」
ゆ「わかりました…(しゅん…)」
N「ありがとうございます。でもお客様はラッキーですよ。この地域にお住まいの方は、通常の半額でいいんですから」
ゆ「え!そうなんですか??(ぱぁ!)」
N「はい。○○基地(ある有名な軍事施設。調べれば一瞬でヒットしますが、一応伏字に(笑))の近隣住民の方は、防衛省が半額負担する仕組みになっているんです。というのもうんたらかんたら」
ゆ「あ、じゃあ払います!!」

なんでも、ある軍事施設の近くに住んでいる場合は半額免除になるらしいです。
一応もういい大人ですし、半額に惹かれて(?)きちんと払うことにしました(笑)


さて、今日は信号の反射のお話です。

以前にもチャタノイズに関して書かせていただきましたが、書いた矢先、自らが反射ノイズの罠にはまってしまいました…。

具体的には、ある外部割込み端子に以下のような記述をしていました。
IntIrq()関数は、その割り込みハンドラです。(IrqはInterrupt ReQuestの略です)

void IntIrq(){

 static unsigned char sucCount = 0;

 (前略)

 if(sucCount >= 10){
  func1();
  sucCount = 0;
 }
 else sucCount++;

 (後略)

}

要するに、その割り込みが10回入ってきたら、func1()を呼ぶというものです。
しかし、試作ボードでいろいろ動かしてみると、どうも様子がおかしい。変な場所でfunc1()が呼ばれているのです。

どうやらIntIrq()が意図していないところで呼ばれてsucCountがインクリメントされてしまい、func1()の呼び出しタイミングがズレてしまうようでした。
ですので
「ああ、きっと割り込み信号にノイズが乗ってるんだな」
と考え、オシロで確認したところ(パッと見は)とてもキレイな波形でしたorz

仕方がないので、割り込みハンドラ内で空いている出力ポートから信号を出す、いわゆる出力ポートデバッグを行いました。ここでは、以下のように出力ポートAの1ビット目をパタパタさせて確認しました。

void IntIrq(){

 static unsigned char sucCount = 0;

 (前略)

 PORT_A |= 0x01;
 PORT_A &= 0xFE;

 if(sucCount >= 10){
  func1();
  sucCount = 0;
 }
 else sucCount++;

 (後略)

}

そして、得られた波形はこれ…
(言い忘れていましたが、割り込み信号の立下りエッジでIntIrq()を呼んでいます)

割込信号
んん!?
なんかへんなのがいねぇか??

そう、なぜかたま~に立ち上がりエッジでもIntIrq()が呼ばれていたのです。
結論から言えば、やはりノイズが原因だったのですが、その発生場所が最悪でした。
上の図で問題のあった位置を拡大してみると…

割込信号拡大

このマイコンの割り込み端子はシュミット入力になっていたので余裕かましてましたが
それでも吸収しきれないくらいのノイズが乗っていました。。。
このノイズのせいで、マイコンは「立下りエッジがきた!」と勘違いしていたのですね。
(マイコン自身は正しく動いているので、勘違いというのは語弊がありますが)

実は、この割り込み信号の発生元からマイコンまでが、きちんとフィルタ回路を入れていなかった上に、中継ボードを介しているためコネクタ二段構えという、反射おこりまくりんぐな経路になっていたため、こんなことが生じていたのです。

組み込み経験が浅い新入社員の方などは、先輩方から信号品質に関していろいろ口うるさく言われてしまい、
「反射やらなまりなら、信号品質ってそんなに重要なの?」
とふてくされている方もいるかと思います。
自分も数年前はそうでした。

この際、はっきり言いましょう。

超重要です!

この手のノイズのタチが悪いのは、周波数成分が高いため、通常のパッシブプローブじゃ拾いきれないケースが多いのです。上に書いた信号の拡大図は、パッシブプローブでは拾えませんでした(FETプローブでようやく見つけることが出来ました)

組み込み・制御エンジニアにとって、回路設計は他人事ではありません。
電源などの難しい部分は回路屋さんに譲るとして、デジタル信号部分は自分たちで開発・設計・評価が出来るくらいのスキルを身に付けたいものです。(もちろん、僕自身にも言えることです)

という訳で、今回の記事はここまでです。
今日も最後まで読んでくださって、ありがとうございました(感謝)

重要:筆者はあくまでも「ど素人」エンジニアなので、話半分でお読みくださいね(笑)
関連記事
こんにちは!

仕事が始まってげんなりのゆってぃです。
更新が遅くなってしまいごめんなさい。

さて、今回のお題はAD値取得のための抵抗分割の知識でしたね。
組み込み・制御系エンジニアにとって欠かせないアイテムに、センサーがあります。
一口にセンサーといっても、温度センサー・加速度センサー・照度センサー・タッチセンサー・エンコーダーなどなど…ここでは書きつくせないほどのセンサーが世の中には存在しています。
これらのセンサーは、アナログセンサーデジタルセンサーに分けることが出来ます。

アナログセンサーとは、センシングした結果を文字通りアナログの電気信号にて出力するセンサーです。その出力は、マイコンのA/D入力ポートにつなげる必要があります。
アナログセンサーは安価で種類も豊富ですが、ノイズに弱かったり、出力の増幅出荷時にキャリブレーションが必要などの手間がかかります。
しかし、今年は国内マイコン最大手のルネサスエレクトロニクスさんから、Smart Analog ICという果てしなく便利そうなアイテムも登場予定ですので、今まで手間だった部分は今後どんどんラクになっていきそうですね!
もっとも、古今東西、製品の機能性とコストは反比例の関係にありますから、便利でも製品に搭載可能かは不明ですが…。
ルネサス様!ひとつお手ごろな価格でお願いします!

話がそれてしまいましたね(汗)
もうひとつのデジタルセンサーとは、センシングした結果をセンサー内でデジタル化し、デジタルデータとして出力してくれるセンサーのことをいいます。ですので、マイコンとセンサーがI2CやSPIなどのインターフェイスで通信を行い、マイコン内に出力を取り込みます。
デジタルセンサーは高価ですが、出力にノイズが乗らない・キャリブレーションが必要ないなどのメリットがあります。
ただ、僕はデジタルセンサーを使ったことがありませんので、全部聞いた話ですが(ぉぃ)

ここでは、アナログセンサーの代表格であるサーミスタと、そこから出力されたアナログデータの取得方法についてお話したいと思います。

サーミスタとは、温度によって抵抗値の変化する特殊な抵抗です。
温度が高くなると抵抗も大きくなるものをPTCサーミスタ、抵抗値の小さくなるものをNTCサーミスタと呼びます。

通常、サーミスタは別の抵抗と直列につなげて使用します。
そして、その抵抗の上に一定電圧を加えます。
(通常はマイコンの電源電圧を回します。そうしないと、AD入力端子に電源以上の電圧が入力される恐れが出てきますので)
そのようにして抵抗分割した中間の電圧を測定し、その電圧値からサーミスタの温度を取得するのです。
ただ、ここでテーミスタと直列につなげる抵抗値を最適なものにしないと、サーミスタの出力電圧の美味しい範囲が取れなかったりします。
サーミスタ制御の詳細は、別サイトや工学書をお読みいただきたいのですが、サーミスタの特性と、基準電圧から、最適な抵抗値を求められるようにしておきましょう。
おそらくハード屋さんが最適な抵抗をぶら下げてくれるはずですが、組み込みプログラマ側でもしっかりと理解しておくべきでしょう。

関連記事
あけましておめでとうございます!

実家の近所にある神社で、数え切れないほどのお願いをしてきたゆってぃです。
いいですか皆さん、初詣でお願い事をする時は、以下の手順でお祈りするんですよ!

1.まず、昨年のお礼をする。
2.次に、「今年もよろしくお願いいたします」と挨拶をする。
3.続いて、今年の「お願い」を伝える。
4.そして、その「お願い」を達成するために、「自分自身が努力する内容」を伝える。
5.最後に、もう一度「よろしくお願いいたします」と挨拶をする。

言うまでもなく、4が最も重要です。
ちなみに、ソースはたまたま聞いていたラジオに出てきた神主さんです(^^)
神主さんいわく、ただお願いをするだけでは、神様はその人の背中を押してはくれないそうです。
ただ、「自分はここまで頑張りますので、どうかお力をお貸しください」というお願いをし、
神様と約束をしたところまで頑張ることが出来れば、そのとき初めて、神様はその力を貸してくれるそうです。

もちろん、お願いが成就された時は、すぐにお礼を言いにいかなければなりませんよ。



さて、今日のテーマは、組み込み・制御系エンジニアとハードウェアの関係です。

組み込みエンジニアにとって、回路などのハードウェアはどうしても無視することは出来ません。
制御系のエンジニアでは、それに加えてメカに対しても考慮が必要になる場合があります。
(筆者は幸いにして、優秀なメカトロ屋さんとしか組んだ事がないので、あまり気にしたことはありませんが)

では、組み込みエンジニアが知らなければならない回路の知識とはどの程度なのか。
筆者はど素人なので、ぶっちゃけどの程度の知識があればよいのかよくわからないのですが
今までで必要だったレベルでは以下の項目があげられます。

1.チャタ(ノイズ含む)取りにおけるRC回路の知識
2.AD値取得のための抵抗分割の知識
3.デジトラの知識

などです。
つまり、制御に関わる部分の波形品質に関する知識ですね。
(今回は内容が長くなるので、複数回に分けてお伝えしたいと思います)

まず1ですが、これは開発する製品・装置によって大きく異なります。
絶対に誤動作してはいけない装置を開発する場合、ソフトのチャタ取りのみでは
不安で夜も眠れません。
そういう場合は、シュミットトリガなどを用いてH/Wで確実にチャタ除去をするようにしましょう。
というか、何も言わなくてもハード屋さんがそうしてくれる筈です。

しかし、H/Wでの対応は、コスト的にも実装面積的にも不利になります。
そのため、基本的には、複数回入力端子を見に行くポーリングにて対応します。
この場合は、チャタの発生する周期とポーリング周期をマッチングさせないといけません。
(たとえば、チャタ周期が10m秒だった場合、1m秒毎に3回見に行っても意味はありません)
たまに、タイマーを使用せずにfor文などの繰り返しでポーリングをする記述を見ることがあります。
しかしながら、これでは動作周波数の高いマイコンにソースを移植された場合、ポーリング周期が早すぎる可能性があります。
チャタ除去なんぞにわざわざタイマーを使用するのは手間に感じるかもしれませんが、空いているタイマーがあれば、最適なポーリング周期できちんとチャタ取りを行うようにしましょう。

ただし、あくまでこれは対処療法ですので、理想的にはチャタを回路で除去してしまうのが一番なのです。

そこで活躍するのが、大学1年で習うRC回路(積分回路)です。(筆者は理論物理出身なので習いませんでしたが…)
RC回路を用いることで、任意の周波数以上の信号を除去することが出来ます。
一言で言えば、「チャタみたいな高周波(※)成分はを取り除いちゃおう!」ということですね。
(※高周波と言うと数GHzとかイメージしちゃいますが、ここでは違いますよ(汗))
ただし、時定数を大きくすると信号の波形がなまってしまって、入力がHレベル(あるいはLレベル)になるのが遅れてしまうので、そこはオシロでよく確認をしましょう。
せっかくチャタを除去しても、反応が遅くて誤動作…なんて本末転倒ですからね。
なお、RC回路の詳細は、先人達が残してくださった資料をご参考下さい。
(例のごとく、またまた逃げます。。。本当にごめんなさい…)

特に制御系の場合、制御対象となるメカ部品(あるいは駆動用ICなど)の電気特性は、制御プログラマが確認しなければならないケースも少なくありません。(特に、ハード屋さんが不足しているプロジェクトでは)
ですので、その場合はしっかりと制御対象のスペックシートを確認したうえで、RCが最適な定数になるよう、ハード屋さんにフィードバックをしましょう。
納期直前で、信号の立ち上がり時間がスペック外だった事が発覚!!
・・・なんて事がないように(汗)

今回はここまでにして、次回は2以降に関してお話したいと思います。
最後までお読み下さって、ありがとうございましたm(_ _)m

重要:筆者はあくまでも「ど素人」エンジニアなので、話半分でお読みくださいね(笑)

関連記事
ご訪問者様
プロフィール

ゆってぃ

Author:ゆってぃ
経歴7年の組み込み系・制御系エンジニアです。
("ど素人"という文言は取りました…笑)
ソフトウェア開発経験ゼロの状態から、なんとか実務がこなせるようになってきた現在に至るまでの経験を、備忘録代わりに綴っていきたいと思います。
入門者の方、大歓迎!
(上級者の方、ごめんなさい…)

あと、ブログには全然関係ないですが、Bumpy Headというバンドのギターをやっています。
ライブ情報なんかも書いたりすることがあるので、その時に「行ってもいいよ~」といった感じのコメントを戴けると、泣いて喜びます(泣)
ブログ読んでくださってる方なら、チケット代サービスしちゃいます!

最後に…滅多に流用することは無いでしょうが、このブログに書かれているソースは、特に指定の無い限りMITライセンスとします。ただし、一部それ以外のものもございますのでご注意下さい。
※ブログのリンク先にあるコードに関しては、リンク先のポリシーに従ってください。

最新記事
最新コメント
カテゴリ
RSSリンクの表示
メールフォーム

名前:
メール:
件名:
本文:

twitter
リンク
ブロとも申請フォーム
スポンサードリンク