目次
コメントはありません。 Comments/tomise
電源ラインのコネクタを新しくつけ直した所、接触不良は完全に直った。
赤外線LEDの入力が反応しなくなったのをテスタで確認したら、ちゃんと0V <-> 5Vで電圧は変化していた。
でも割込は発生しない。なぜに?
フォトカプラはやっぱりうんともすんとも言わない。
入力側に電圧をかけても出力はぴくりとも動かないで5Vのまま。
どうも根本的に違っている気がしてきた。
電源ラインの修復と、赤外線LEDによる回転検出の確認。
3端子レギュレータは生きていたが、どうも端子が駄目になったらしく何度半田付けし直しても接触不良状態。
ある角度なら動くが、コネクタの予備もないのでとりあえずUSB経由で。
12Vからのフォトカプラによる入力が相変わらず駄目。
今回はショートさせないように慎重に各端子の電圧を見ていくと、一応どの端子も計算通りの電圧になっていた。
アノード-カソード間は約1.9Vなので発光側はOK.
出力側がおかしい? データシートを見ながら別の回路に変更したが、やはり無反応。
続いて設置前には成功していた赤外線LEDによる回転検出の確認。
前まで不安定さもなく問題なく動いていたのに、なぜかうんともすんとも言わない。
今までなかった接触不良も一応確認したが、どうも違う。
ここまできて1つも実機動作確認できないのは悔しいが、時間切れ。
駄目だった分は原因分析して次につなげたい。
後付け装備のせいでメータ周りのカウルを外すのが滅茶苦茶面倒な車体なので、とりあえずはバッテリに直接つないで12V周りの確認をした。
3端子レギュレータの通電はOK.
次に、と行こうと思ったら一定間隔でリセットとフリーズを繰り返している状態。
外部端子が多いのでただの接触不良かと思ったが、全て外しても、人が触れて無くてもなるのでどうも他の要因。
しばらく悩んであれこれ試した挙げ句、どうもスイッチの入力を拾うとこうなることが判明。
スイッチを読みに行かなければ安定して動作した。
スイッチはただの表示切替なのでとりあえずは除外してその他の動作確認へ。
次にフォトカプラ経由での点火パルスの入力。
これがどうも割込入力できていない様子で、うんともすんとも言わない。
回路は直したはずなのにと、ふと回路を直した時にピンを1つずらしたのを思い出し、ピンの設定を修正。
でもまだ反応無し。
テスタでフォトカプラ周りから電源周りまで順に追っていたら、うっかり12Vをショートさせてしまって煙を上げて焦げた。
通電しなくなったのでお亡くなりになったのかと焦ったが、USB通電だとOK.
基板裏を見たら3端子レギュレータ手前の12Vの端子が焦げてハンダが切れていた。
3端子レギュレータが亡くなっていないことを祈る。
車体側はバッ直だったので全然問題なし。
気温が低すぎて外での作業が辛いのでとりあえず本日はここまで。
フォトカプラ周りの配線がおかしかったので再修正。
後はプログラムを実機に合わせて書いた。
センサー用の配線を全て完了して、12V -> 5V用の3端子レギュレータを設置。
後はプログラムを完成させて、配線して実機確認をするだけに。
サービスデータより
フロントタイヤ 100/80-17 52S
幅100mm 扁平率(タイヤの高さ÷タイヤ幅×100)80% リム径17インチより、
直径 = (17 * 25.4) + (100 * 0.8 * 2) = 591.8mm
外周 = 591.8 * 3.1415 = 1859.2mm
1速 2.600(39/15) 2速 1.789(34/19) 3速 1.409(31/22) 4速 1.160(29/25) 5速 1.000(27/27) 6速 0.892(25/28) 1次減速比 3.086(71/23) 2次減速比 3.357(47/14)
タイヤの回転数 = エンジン回転数 / (1次減速比 * 2次減速比 * n速減速比) 減速比 = エンジン回転数 / (タイヤ回転数 * 1次減速比 * 2次減速比)
ホイールは3本スポークなので、立ち上がり、下がりの片方だけの割込なら、1回転で3カウント分。
// これは使わない // 速度(km/h) = (エンジン回転数 / 最終減速比) * タイヤ外周 * 60 / (1000^2) 速度(km/h) = (タイヤ回転数 * タイヤ外周 / 経過時間) * (経過時間から1時間分へ)
前回のitos()は0だと表示されないので一行追加。
桁数以下の幅を指定したらまずいのは同様。
void itos(char *s, int i, int width) { s[width] = '\0'; s[width - 1] = '0'; for (; i; i /= 10) s[--width] = i % 10 + '0'; while (width) s[--width] = ' '; }
割込ルーチンでどのピンの割込なのかを確かめてからカウント。
#pragma interrupt_handler INT_GPIO void INT_GPIO(void) { if ((PRT0DR & (0x01 << 7)) == 0) ++wheel; }
他も適当に組んで、赤外線LEDを動かすとカウントされるのを確認した。
カウントはcounterモジュールをつかっても良さそうだけど、これぐらいなら使わなくても良さそう。
起動時の動作チェックアニメーションを何パターンか作成した。
液晶に全て0xff(黒塗り)を表示させる。
sprintf()の代りにcsprintf()があったが、桁オプションが使えなくて結局使えなかった。
仕方ないので、文字幅を指定してintを文字列にする関数を作った。
/* * sに整数iをwidth幅で文字列化して格納する * widthが文字列幅以下にならないように注意 * itos(s, 16, 3); // " 16" * itos(s, 8, 5); // " 8" */ void itos(char *s, int i, int width) { s[width] = '\0'; for (; i; i /= 10) s[--width] = i % 10 + '0'; while (width) s[--width] = ' '; }
単位表示で3文字も幅を取るのが勿体ないのでCGRAMに単位文字を定義しようと思ったが、5x7ドットではさすがに難しい。
素直に3文字分(km/h, kph, rpm)使っておくのが無難か?
点火と回転は割込でcountしようと思ったが、割込は同じ関数が呼び出される。
関数内でポートの状態を見て、どのピンからの割込かを調べてcount?
表示更新は割込関数内ではせずにmain()か定期的なタイマー割込でした方が良さそう。
磁気抵抗素子の値の変化が小さすぎてテスタでもわからないので、赤外線LEDと受光素子に方向転換。
エミッタ接地回路でコレクタに100Ωを繋げると5.0 <-> 4.5V
10kΩに変更して4 <-> 0V
これならデジタル入力に使えそう。
磁気抵抗素子DM-106Bの配置と測定。
配線ミスやら、入力ピンに制限があることに気付かず、無駄に時間を取られた。
SAR6で値を取ってみると、磁石を殆ど接触させた状態で1, それ以外は0という値。
ADCの使い方が間違っている?
PGA経由でGainを色々変えてみても大して変わらない。
スイッチ割込でカウント、タイマー割込で定期的に表示更新まで。
mainのループは空にできた。
PSoCGPIOINT.asmはこんな感じに。
;@PSoC_UserCode_BODY@ (Do not change this line.) ;--------------------------------------------------- ; Insert your custom code below this banner ;--------------------------------------------------- ljmp _INT_GPIO ;--------------------------------------------------- ; Insert your custom code above this banner ;--------------------------------------------------- ;@PSoC_UserCode_END@ (Do not change this line.)
main.cはこんな感じに。先程のPSoCGPIOINT.asmに書いた関数名の先頭から'_'を除いた名前で宣言。
#pragma interrupt_handler INT_GPIO void INT_GPIO(void) { // ... }
調べていて見つけた情報。割込に使ったポートと同じポートに出力するとはまる可能性。
sprintf()が使えないので、itoa()で。
#include <stdlib.h>
char line[17] = {'\0'}; itoa(line, 12345, 10);
でもこれだと桁揃えがしにくい。
それを改善したマクロが見つかるが、if分岐で何とかしても良さそう?
if (count < 10) ; else if (count < 100) ; else if (count < 1000) ; else if (count < 10000) ; else ;
前回の配線図通りに配線。初めにピンを間違えて大幅な時間ロスをした。
コントラスト調整用に10kΩの可変抵抗をつけるべき所に普通の抵抗をつけてしまって、かなり見にくい状態だったのでとりあえずGND直結で動作確認。
文字列の表示はこんな感じ。
LCD_1_Start(); LCD_1_Position(0, 0); // 行, 列 LCD_1_PrCString("LCD Test");
datasheetを見ていると、棒グラフを表示させるなんていう面白いAPIを発見。
ドット単位のパターンを用意して実現している様子。
デバッグやらにも便利に使えそう。
SC1602は1文字を5 * 7ドットで表現しているので、横棒グラフなら5 * 16 = 80ドット、縦棒グラフなら7 * 2 = 14ドット。
使い方はこんな感じ。
LCD_1_InitBG(LCD_1_SOLID_BG); LCD_1_DrawBG(0, 0, 16, 72); // 行, 開始列, 終了行, グラフの長さ
DrawBG()の引数がちょっとわかりにくいけど、次のような感じ。
LCD_1_DrawBG(0, 0, 16, 50); // 0行目の0〜16文字を使って50ドットの長さ LCD_1_DrawBG(0, 1, 5, 60); // 0行目の1〜5文字を使って60ドット(5 * 5 = 25を超えるけど超えた分は表示されないから25ドットになる)
良く考えたら16文字だからDrawBG(0, 0, 15, ...)が正しい気がする。
データシートと睨めっこした結果、こんな感じになった。
配線距離が長いが、ユニバーサル基板に液晶を取り付けたときのバランスを考えると、どうしても隅っこになってしまう。
何を作りたいかの発表と、その中からどれを実際に作っていくか、大体の方針の決定。
皆実装に縛られない自由な案を出していて、実装前提で考えている自分は何だか縛られている感じがした。
次回までにキャラクタ液晶の配線を考えておく。
FIRST TOUCHでCapSenseを試した後、ユニバーサル基板にICソケット、LED、抵抗、スイッチを配置して半田付けの作業。
PSoCの開発環境を整え、FIRST TOUCHを使ってLEDを光らせる所まで。
PSoC入門:PSoC First Touch編に従って、プロジェクトの作成、モジュールの配置、配線、設定の一通りの流れを実施。
プログラムを書く前の設定作業が多いなあと思ったが、それだけ自由度が高いということか。
バージョンが更新されたようでPSoC入門:PSoC First Touch編とは異なる箇所がいくつかあった。