スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Arduinoもどきを使ったフォークリフト(おもちゃ)運転の自動化

例年連休になると、いつもは時間がかかってなかなか手が出せない課題をやることにしているが、今回はオーディオでは無く、おもちゃいじりである。
子供の頃を思い出し、心をくすぐるものがあります。
(尤もコマーシャルの一環でもあるので、休み前から進んでおりますが・・・)

さて、お題は、「Arduinoもどきを使ったフォークリフトの自動運転」です。

FRK_4.jpg
最近のおもちゃは、なかなか手が込んでいます。Amazonで売ってます。
これはかなり大きな1/8スケールモデルなので、全長45cm、全高35cm、全幅15cmもあります。
ラジコンで前後進、左右旋回、リフト上下、クラクション操作ができ、運転操作を覚えさせると自動運転までできます。

FRK_5.jpg

でも、やはりおもちゃはおもちゃです。
・旋回半径が大きい。
・旋回が安定しない。
・急停止できない。
と、今回の課題をこなすには少し荷が重いです。

課題は安全教育に使うための以下のデモ走行ができることです。

1.フォーンを2回鳴らして発進・走行後、急停止する(フォーク上の荷が滑る)
2.同上発進・走行後、急旋回する(後輪の外輪差が大きくはみ出す)

この動作を常に安定して再現させなければなりません。ラジコンの手動ではどうも再現性に乏しいです。

FRK_1.jpg
中を開けてみると、基本的な構造はしっかりしているようです。

・駆動輪にはディファレンシャル・ギアが付いていますので(ハンドル安定すれば)、旋回動作はしっかりできます。
 しかし、速度調整機能がありません。スピードが速過ぎます(暴走フォークリフトの感強い)
 また、停止する際は電源OFFだけなのでブレーキ停止になりません。モータの短絡ブレーキ改造が必要です。

・旋回輪の角度が足りません。ロッドを削って角度を増やしました。
 また、装着されていた旋回角度用駆動モータは内部スリップするためトルクが足りません。
 汎用サーボに交換します。
 
FRK_6.jpg

Arduinoもどきの秋月・AE-ATmegaボードです。汎用サーボを付けて動作テストしました。
(4,5年前に買っておいた機材が役にたってます。当りでした。理由は下記)

いつも愛用しているPICを使用せずArduinoを使った理由は2つあります。
・servoをコントロールする関数を内蔵しており、servo動作に安定性がある。
・ポテンションボリュームからの電圧を計測し、動作させる中心サーボ角等を調整する値を演算する場合、mapという関数がありとてもプログラムが楽に行える。

忘備録1:Arduino化するためブートローダーをBitBang法(こちら)で書き込もうとしたがうまくいかなかった。結局AtmelStdioのToolsにあるDeviceProgrammingとAVRライターを使うことになった。しかし、その後はマイコン(ATMEGA328)を新品に変えてもBitBang法が使えるようになった。PC側の状態が変わったとしか思えないのですが、その根源が不明です(継続調査中)

忘備録2:Arduinoの電源とサーボの電源を同時に入れると、サーボが0位置付近まで動いてしまう。これではフォークリフトのハンドル角がロック状態になるので問題となる。サーボの電源はArduino起動後にArduinoで入れるようにする。これならば少しの揺るぎで収束します。

発進前のフォーン音やエンジン音(最近はバッテリフォークに変わって来たので不要?)もマイコンで鳴らします。

FRK_7.jpg

汎用基板に効果音IC2種とアンプを付けました。3V~5Vで駆動できます。5cm程の小さなスピーカーを鳴らします。
エンジン音は電源を入れておくと12秒程度鳴ってOFFします。フォーンは信号ピンをHIGHにすると鳴ります。マイコンで駆動できます。
詳細はデジットを参照してください。HK637シリーズの4,5とHT82V739アンプを使いました。
2つのICからの出力を1つのアンプに入れると音はミキシングされます。IC出力側に個別の半固定抵抗でボリュームを付けました。

さて以上の準備ができれば、制御回路作りと、Arduinoのプログラミングですが、その前に頭の中をまとめる必要があります。
要点は、できるだけプログラムは修正せずとも、ハードで調整ができるように作っておくことです。

FRK_2.jpg

【制御基板回路図】
FRK_8.jpg

サーボへの信号はマイコンから直接出ます。その電源はNPNトランジスタ出力で駆動するリレー経由で供給します。
フォーンへの信号は念のためNPNトランジスタ経由で出します。多分マイコン直接でもOKです。
駆動モータへの電源はCMOSトランジスタスイッチでで供給しますが、これがOFFの時はモータ回路がリレーによって短絡し、ブレーキがかかるようになっています。
ただ、このままではリレー応答遅れや故障時に電源ショートになるため、本番では回路変更の可能性があります。
速度調整はMOTOR端子後に設けた切り替えスイッチ(図には無い)で固定抵抗値を切り替えて行います。走行させてみないと速度が判らないので完成後の抵抗値選択になります。

【基板図】
FRK_3.jpg

Arduinoもどき基板AE-ATmegaの上に差し込めるように作りました。

さあてと、基板を作ってプログラムを流し込めば動くはずです。結果は連休明けです。




スポンサーサイト

FET計測ツールの製作

ある方からの問い合わせで、FET計測ツールを再製作することになりました。

以前製作したこれは、ぺるけさんオリジナルこちらのかたがダブル化(JとPチャンネル両方が計測できる)したものであるが、これを私がマイコンタイプにしたものです。

ぺるけさんのツールを久しぶりにググってみると、なんと改訂版が発表されていました。
ボリュームでIdを調整するタイプから、固定抵抗をセレクトするタイプになり、更には定電流特性の温度変化を安定化する回路が付与されています。流石、ぺるけさんです。

早速この回路を真似てみることにしました。頻度を考えるとPチャンネルFETの計測はほとんどないのでダブル化は止めました。

【EAGLE回路図】
FET_Tool_1_sch.jpg

左下側がベースの計測回路です。
まずこちら側を完成させて性能を確かめ、テスター計測の値をえます。
そのご右側にあるオペアンプとマイコンによる計測、表示部を完成させるという流れです。

【EAGLEボード図】
FET_Tool_2_brd.jpg

以前の作例では、切り替えスイッチと基板間の配線が山のようにあってごちゃごちゃしてました。
今回はスイッチを基板に直付けし、そのスイッチで基板をぶら下げようと思います。よって、足サイズが大きい汎用スイッチを基板に付けるため、EAGLE用スイッチパーツを作りました(左下、右下に見える2回路2接点スイッチです)。左下は電電スイッチ用なので、片側の穴しか使いません。

【Id 計測】
FET_Tool_3_Id.jpg

2SK170BL を使ってテスト計測しています。

中央ジャンパーで2mAセットの抵抗を選択しています(ここはセレクタースイッチに接続されます)

S1スイッチが上、S2スイッチが下で Id 計測モードです。100Ωの両端電圧で計測しますので、2mA×100=200mVです。
ほんの少し誤差があって2.002mAですが、Id セットですからこれくらいの誤差で十分です。問題は安定度です。ピタッと決まって動きません。現在使っているボリューム調整品比べれば雲泥の差です。

【Idss 計測】
FET_Tool_4_Idss.jpg

これも100Ωで計測してます。953mV→9.53mAということになります。これは定電流回路を通さないので時間と共に数値が若干変化します。LEDを通すので印加電圧は電源電圧12V電圧が10Vに下がってます。

【Vgs 計測】
FET_Tool_5_Vgs.jpg

ぺるけさんがFET選別に使う特性 Vgs 計測です。ここで先に選択した2mA定電流が使われます。安定した計測です。

本日はここまでです。
次は、マイコン装着(ソフトも再製作)になります。

--------- 2015/7/15 追記 ---------

マイコン装着での電圧、電流計測範囲をチェックしていたら、次の問題があると気が付きました。

・以前私がこのツールを作った時の計測対象FETは2SK170が主であったが、2SA30Aや2SK246を計測するとすると、Vgsの計測レンジがマイコンの計測範囲を超える場合が生ずる。

・この打開策として、マイコンでもテスターでも計測できるようにと試みたが、オペアンプに微弱電圧をかけた場合に流れる微弱電流の影響が、テスターでの計測値に影響する。言い換えると、オペアンプ計測回路流入電流が大元の値をドリフトさせるという問題がある。
これでは両用にはできない。

悩んだ結果、大量に計測しないというユーザーさんの環境を加味し、マイコン計測無しの仕様にしました。

【完成品】
FET_Tool_6.jpg

とてもシンプルな外観になりました。電源スイッチが変な場所になってますが、一体基板上配置の制約なのでご容赦。
2SK170BL の Vgs を計測しています。

左上がbias電流を切り替える3択スイッチです。
計測項目の選択は、右下2個のスイッチを組み合わせて行います。

Idss:スイッチ2個共に上に上げる。  読み値例(0.946Vは946mVなのでその1/100の9.46mA)
Vgs :スイッチ2個共に下に下げる。  読み値例(-252.3mVは直読の-0.2523V)
Id  :左S1を上(Id)、右S2を下(Var) 読み値例(200.4mVはその1/100の2.004mA)、bias電流を確認します。




Fusion PCB へ基板をオーダーしてみました (2回目:DHL輸送を追加)

「Seeed Studioという会社が、Fusin PCBという名前で基板を激安で作っている」という記事を目にしていたので、PCM2706 USB DAC基板の回路を変えることがあるので頼んでみました。

以下、発注から基板入手までのプロセスを簡単に記載します(詳細手順は他のNET記事を参照願います)
以下、備忘録です。

1.Seeed Studio にユーザー登録をします。ありがとうというメールが届きます。

2.Seeed Stdio のPCB設計基準に合った設計にしておかねばなりません。
  私の場合、φ0.3のスルーホールをφ0.5に変更するのが大きな変更で、他は特にありませんでした。
  また専用のデータ形式でデータを用意する必要があります。
  私はEagleユーザーですが、Eagle用のDRCチェックやデータ出力用camファイルも用意されています。
  詳細は他のNET記事を参照してください(不親切ダナア)

3.ユーザーID(メルアド)とパスワードでseeed StdioのHP にログインし、基板を発注します。
  サイズ(5cm×5cm以内、10cm×10cm以内等)や、厚さ、枚数等の発注スペックを選択し、先に用意して
  おいたデータ(zip形式)をアップロードします。

  以前はオーダーエントリーしたオーダー番号を基板裏に書かねばならなかったらしいですが不要になってます。

4.オーダーを入れると間髪をおかずメールが来ます。

  seeed_1.jpg

  オーダーした10日も108円/ドルだったので、基板費10枚は2365円、送料715円、合計3,080円でした。
  同じものをP板での発注20枚で約3万円だったので、1,500円/枚が300円/枚、1/5の費用になります。
  これは激安です。さて品質はどうなるでしょうか。とても気になるところです。

5.10日には「作ってるよ」、4日目(13日)には、「送ったよ」、というメールが来ました。おっ、意外に早いな。

  seeed_2.jpg

  seeed_3.jpg

  ここまでは早かったですが、問題はこれからです。私は費用の安い一般メール便にしたからです。

6.送ったものが何処まで行っているかを追いかけることができます。

  seeed_4.jpg
  seeed にログインして自分がオーダーした案件の Tracking Number を調べます。
  Truck This Order という緑のボタンを押します。

  seeed_5.jpg

  Tracking Number という英数字が追いかける対象の番号です。
  Or Track Here というボタンを押しても多分エラーになります。
  そこで、日本郵便から追いかけをします。

7.確かではありませんが、日本向けの郵便に託されるAir Mail のTracking 情報は、
  現地の海外発送所に託された時点で日本郵便の Tracking 情報にアップされるようです。
  (ebayからの他の荷物受け取りで推測)

  seeed_6.jpg

  先ほどの Tracking Number を日本郵便の追跡サービスに入力すると情報が表示されます。
  この画面は私の所に到着した全ての経過が記録されたものです。

  最初の SINGAPOLE S05 局が受け入れたのが18日です。Shiped メールを貰ってから5日経っています。
  即ち、Shiped メールを貰ってから5日間はTracking ができませんでした。
  この5日間は、中国からシンガポールの国際交換局までの移送期間と考えられます。
  この期間は国際交換局までの距離や手続き関連でバラツクのでしょうね。
  ebay では国際交換局は中国本土のようで、到着まで3日間でした。

  その後の輸送期間は見ての通りです。
  日本の郵便交換局に到達するまで5日間です。これはebay でも同じでした。
  後は日本郵便の迅速な処理で2日間で入手できます。

  ここまで、seeedにオンライン・オーダーしてから15日を要して入手できました。

8.荷姿
  基板がたったの10枚なのですが、予想に反して箱に入ってました。

  seeed_7.jpg

  アドレスシートは2枚貼ってありました。各々使い分けがあるのでしょうが、詳細はわかりません。

  seeed_8.jpg

  綺麗にパックされてました。残念ながら10枚きっちりでした。おまけはありませんでした。

9.肝心の基板品質です

  seeed_9.jpg

  基板そのものには殆ど問題ありません。
  パターンやスルーホールも綺麗です。レジスト品質や光沢(即ちムラ)にも問題は皆無です。

  でも、やはりNET評価にあるように小さな文字のシルク印刷はかすれるようだ。
  品質的な問題ではないのですが、0,5φのスルーホールにはレジスト流入が数多くあります。

  内心心配していたのは、外周ギリギリにあけたドリルホールです。
  でも、完璧なカットができていました。周囲の崩れも無くOKです。

10.総括

  P板に頼むと約7日間で作ってくる基板が、約二倍の15日かかるが 、約1/5価格でできてくるのは魅力です。
  データを直接送るので、P板でやってくれるボンミスチェックは無いと思うようでしょうね。
  基板設計に自信のある方は頼んでみると良いでしょう。

--------------------------------------------------------------------------------------------
21014/11/14 追記

2回目のオーダーをしました。今度は30ドルの輸送費をかけDHL輸送をしてみました。さて早く届いたでしょうか?

1.11月2日にオーダーしました。DACのHPA側基板をスマホ用Li-ion電池(並列)に変更したもの10枚です。
  基板が18.9ドルなのに、DHL送料は何と30.4ドルもします。
seeed_13.jpg

2.11月6日に製作し、11月7日に発送したよとメールが来ました。ここまでは5日目発送で、前回と同じです。

3.DHL発送なのでDHLのTrackingをかけましたが、seeedからの追跡番号ではヒットしません。
  3日ほど経過した後、seeedのTracking番号が変わってます。この番号でDHLをTrackingします。

  荷物が届いた後の最終のTracking結果です。

seeed_10.jpg

 何と、DHLが荷物を引き取ったのは11月9日、しかも深夜でした。この2日間はどこで何してたのでしょうか?

 その後は、翌10日にDHLで出荷処理、11日早朝便で日本到着、12日は不在だったので13日に受け取りました。
 2日にオーダーして12日に受け取れたら10日間かかったことになります。前回は15日間でした。
 ちなみに宅配はSAGAWA便でした。

 6ドル送料が30ドル送料になって5日間の短縮ですが、これは微妙です。安いほうが良さそうです。

 DHLに託してからは超迅速なのですが、そこまでの中国本土内の物流プロセスに問題がありそうです。

今回のパッケージはこんなでした。
seeed_11.jpg

大きなDHLの袋です。

seeed_12.jpg

軽く真空引きされたビニール袋に入ってました。

基板そのものに問題は何もないのですが、シルク印刷品質はチョットダメですね。
小さな文字は完全にかすれて見えません。





WAVプレーヤーの製作(その12 小型TFT LCD, part2)

先回、小型TFT LCDについて述べたが、まだ諦めきれずに弄っています。

課題は
1.このアイコン背景色の問題
2.タッチパネルが4線式のA/D入力なのでSPIに慣れた身には未体験領域だ。安定度が心配です。
  ソフトも新作を要します。
3.タッチの割り込みはどうやるのだろうか? A/Dの割り込みってあるの? 動作安定するの?

1.は一応の暫定処置ができたので、今回は2.と3.です。

【タッチができるようになりました】
stm32_proj_47.jpg

左右・上下計測を順に行うために、DC電圧出力とA/D計測を順に切り替えながら計測しなければならないので、これは大変かなと覚悟していたのですが、結構あっさりとできました。

ボールペンでスクリーンの真ん中へんを押してます。xは上下、yは左右方向です。
左上にタッチされた座標を表示させていますが、下一桁が0なので、ぴったり安定のように見えてしまいますが、実際の表示はかなり数値がバラツイテいます。

これだけならば、良さそうに思ってしまいますが、実はx、y方向の数値分布がゆがんでます。

stm32_proj_48.jpg

この画像はスクリーン9箇所をタッチして、おおよその値を読んだものです。上の画像とは異なり (x左右,y上下)で表記してます。
スクリーンの中央付近の上下左右電圧を読んで、(0-320,0-240)になるようにスケーリングしてあります。左下がゼロです。

ところが、左右・上下がかなり歪の大きい値になります。特に、左側の上下方向は酷い状態で使い物になりません。

この4線抵抗膜式タッチスクリーンのAD値はタッチしないとほぼゼロで、タッチするとある値以上にピッと上がるので、「アナログウォッチドック」という割り込み機能を使えば(まだ調べていないが)、音楽演奏中に停止時間僅かでボリューム変更ができるのだが、タッチ精度が悪いと操作ができないとなってしまう。

まあ、この小さなTFT液晶は、表示専用か、タッチ機能を使うとしても大雑把な機能に減退されるのかもしれません。


折角、タッチができるようになったので、その処理内容を備忘録とします。
-----------------
私はこれまでpicマイコンを使ってきたので、後閑さんのタッチスクリーンの記事を参考にさせて頂きました。
ここにはタッチスクリーンの原理が、とっても解りやすく図解されているので、stm32のソフトに反映するのがとても楽にできました。

・stm32側で用意するハード
 1) アナログ入力とGPIO入力に切り替えできるピンを2個、これを LCDタッチの y-,x- 端子に配線する
 2) GPIO出力と入力が切り替えられるピンを2個、 これを LCDの y+,x+端子に配線する
(picと違い、stm32には訳も無いことですね)
 3) ノイズ防止のため、この4ピンは10kぐらいの抵抗でプルダウンしておく。
 4) A/D入力に使うピン2個には、これもノイズ防止のため0.1uF程度のコンデンサをGND間に付ける。

・ソフト
動作と計測の手順は
 計測してもらう側:座標数値を大きくしたい側に+3V、反対側を0(GND)にする
 計測する側   :一方をアナログ計測、もう一方を入力(フローティング)とする → 電圧を計測する

 以上の動作をするチャンネルを切り替えて別方向の座標を計測する。

【GPIOを切り替えてx,yを交互に計測する部分】
この後で、計測した10回の rPoint データの真ん中辺3点の平均値を使ってます。

void readTouch(void)
{
  uint16_t rPoint[2][10],temp = 0;
  uint8_t t,t1,count;

  // OUT DC GPIOB_Pin7(Y+), IN DC GPIOA_Pin3(Y-)
  GPIO_Conf_touchY();     // y 方向への切り替え

  GPIO_SetBits(GPIOB,GPIO_Pin_7);   //PB7(Y+) is OUT DC
  GPIO_ResetBits(GPIOA,GPIO_Pin_3); //PA3(Y-) is IN DC
  GPIO_ResetBits(GPIOB,GPIO_Pin_6); //PB6(X+) is IN DC
                                      //PA2(X-) is Analog IN
  delay_ms(5);  // 安定時間
  for(count = 0; count<10; count++ )  //10回計測する
    {
      Present_ParamY = ReadADC1(ADC123_IN2_CH);   //STBee.hへDefine追加してます
      delay_ms(1);
      if(Present_ParamY > 3000 || Present_ParamY < 5000){
          rPoint[0][count] = Present_ParamY;
      }
    }

  // OUT DC GPIOB_Pin6(X+), IN DC GPIOA_Pin2(X-)
  GPIO_Conf_touchX();   // x 方向に切り替える

  GPIO_SetBits(GPIOB,GPIO_Pin_6);   //PB6(X+) is OUT DC
  GPIO_ResetBits(GPIOA,GPIO_Pin_2); //PA2(X-) is IN DC
  GPIO_ResetBits(GPIOB,GPIO_Pin_7); //PB7(Y+) is IN DC
                                      //PA3(Y-) is Analog IN
  delay_ms(5);  // 安定時間
  for(count = 0; count<10; count++ )
    {
      Present_ParamX = ReadADC1(ADC123_IN3_CH);  //STBee.hへ追加
      delay_ms(1);
      if(Present_ParamX > 3000 || Present_ParamX < 5000){
          rPoint[1][count] = Present_ParamX;
      }
    }


【y方向へ切り替え】
void GPIO_Conf_touchY(void)
{
  //GPIOD,GPIOE clock set
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitTypeDef GPIO_initstruc;

  // OUT DC (Y+) pin = PB7
  GPIO_initstruc.GPIO_Pin=GPIO_Pin_7;
  GPIO_initstruc.GPIO_Mode=GPIO_Mode_Out_PP;
  GPIO_initstruc.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_initstruc);

  // IN DC (Y-) pin = PA3
  GPIO_initstruc.GPIO_Pin=GPIO_Pin_3;
  GPIO_initstruc.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  GPIO_initstruc.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_initstruc);

  // IN DC (X+) pin = PB6
  GPIO_initstruc.GPIO_Pin=GPIO_Pin_6;
  GPIO_initstruc.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  GPIO_initstruc.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_initstruc);
  ADC_InitTypeDef  ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* ADCCLK = PCLK2/6 = 72/6 = 12MHz*/
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | ADC_IN0_3_GPIO_RCC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = ADC123_IN2_PIN;  // PA2(X-) pin is Analog IN
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(ADC123_IN2_PORT, &GPIO_InitStructure);
}

【x方向に切り替え】
void GPIO_Conf_touchX(void)
{
  //GPIOD,GPIOE clock set
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitTypeDef GPIO_initstruc;

  // OUT DC (X+) pin = PB6
  GPIO_initstruc.GPIO_Pin=GPIO_Pin_6;
  GPIO_initstruc.GPIO_Mode=GPIO_Mode_Out_PP;
  GPIO_initstruc.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_initstruc);

  // IN DC (X-) pin = PA2
  GPIO_initstruc.GPIO_Pin=GPIO_Pin_2;
  GPIO_initstruc.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  GPIO_initstruc.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_initstruc);

  // IN DC (Y+) pin = PB7
  GPIO_initstruc.GPIO_Pin=GPIO_Pin_7;
  GPIO_initstruc.GPIO_Mode=GPIO_Mode_IN_FLOATING;
  GPIO_initstruc.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_Init(GPIOB,&GPIO_initstruc);

  ADC_InitTypeDef  ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  /* ADCCLK = PCLK2/6 = 72/6 = 12MHz*/
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | ADC_IN0_3_GPIO_RCC, ENABLE);

  GPIO_InitStructure.GPIO_Pin = ADC123_IN3_PIN;  // PA3(Y-) pin is Analog IN
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(ADC123_IN3_PORT, &GPIO_InitStructure);
}

この他に、ADチャンネルの設定、読み込みがありますが、一般的な設定なので省略します。



・・・小型化は諦めてプレーヤーを完成させなくてはなりません。




WAVプレーヤーの製作(その11 小型TFT LCDに嵌る)

小型コンパクト機器を作るのが身上なので、今使っている3.2インチよりもずっと小さい2.4インチの物が目に止まった。50%off祭りとかで、何と!625円です。

TFT液晶の動作も勉強になるだろうと思い、ポチッとしたのが運のつきでした。

【やっと動いた2.4インチTFT液晶・S95417】 oh! 撮影のデジカメが反射で写ってます。

stm32_proj_39.jpg

上が3.2インチ液晶です。長さ比は75%なのですが、面積比は約半分なので、やはり半分に見えます。
S95417がこの液晶の商品型番ですが、コントローラチップはst7787です。
これを使うに当たり、いちばん難しいところは初期化コードなのですが、ねむいさんのところのものをお借りするつもりでおりました。

・・・・・・・ところが、ところがですよ、うんともすんとも動きません。フルに4日間を費やしましたヨ。
あれやこれやと試しましたが、功無く挫折か?

気を取り直し、ハード故障かなと思いを転じ、複数個(激安なので)買っておいたものに交換しようとして、ハット気がつきました。この1個だけのシルク印刷が違うのです!  

・・・・・・交換したら、何のことなく動くではありませんか。
何だこれは。ヘロヘロです。

【誤品だったTFT液晶・cp2401】  4日間の激闘でパネルの保護シートが剥がれかけてます。
stm32_proj_41.jpg

外見がS95417にそっくりなcp2401です。白の印字を良く見ると[2401]と見えます。
一番上の写真がs95417ですが、これはこれで、s95417等の型番は付いてません。0h! 中華品質?
cp2401の初期化コードに換えると、 ハイ、これも見事に動きました。 やれやれでした。


出鼻をくじかれて始まった小型液晶ですが、動くとなるとssd1289コントローラ搭載の3.2インチ液晶の画面を出したくなります。動かない時にNETを徘徊したのですが、s95417(st7787)を動かしたという記事は、ねむいさんところでしか見つけられませんでした。

st7787のドライバー・コードを見ると、グラフィック・データを表示するルーチンはありますが、点、線、文字を表示させるコードはありませんね。こうなれば、ssd1289のコードやデータシートをベースにして、st7787のデータシートを辿っていかねばなりません。

以下、備忘録です。
-----------------------------------------------------------------------------------------
・線や文字を表示させるベースは「点」を打つこと。スタートは、Draw_Pixel()です。
void Draw_Pixel(uint16_t x, uint16_t y, uint16_t color)
{
  Set_Cursor(x, y);  // 1) 液晶のGDRAM位置を指定する
  Write_GDDRAM_Prepare(); // 2) 液晶に出力するコマンドを出す
  Write_Data(color); // 3) カラーデータをGDRAMに書き込む
}
以上の 1)、2)、3) が基本、これは具体的にはどうなっているか

1)
void Set_Cursor(uint16_t x, uint16_t y){  //ssd1289
  Write_Command(0x004E, x);  // 0x4Eというコマンドとxの位置を指定する
  Write_Command(0x004F, y);   // 0x4F、同上 y
}

2)
void Write_GDDRAM_Prepare(void){
  LCD->Register = 0x0022;  // GDRAMへ書き取り・読み取りコマンド0x0022を書き込む
}

3)
void Write_Data(uint16_t data){
  LCD->Data = data;
}

これを st7787に適用します。異なるところは、1) と 2) です。

これらのことはst7787 DataSheet のこのような表にまとめられていました。
stm32_proj_38.jpg
1) ssd1289は簡単にx,yを指定できましたが、st7787には点を指定するコマンドは無く、「範囲指定」する機能を使うことになります。
void st7787_rect(uint16_t x_start, uint16_t y_start, uint16_t x_end, uint16_t y_end){

        // 後述しますが、x <-> y を入れ替えしています
        Write_Cmd(0x002A);              // x-start & x-end RAM ADDR
        Write_Data( y_start>>8);
        Write_Data( y_start);              // start
        Write_Data(y_end>>8);
        Write_Data(y_end);                // end

        Write_Cmd(0x002B);             //  y-start & end RAM ADDR
        Write_Data( x_start>>8);
        Write_Data( x_start);              // start
        Write_Data( x_end)>>8);
        Write_Data( x_end);                // end
}

2)  Write_Cmd(0x002C);              // Write Data to GRAM

・グラフィック液晶は指定した座標位置から連続して点を打っていく機能がベースになっていますが、これのスタート点とその方向を決める必要があり、初期化コード内で行っています。ssd1289液晶がベースになっていますので、st7787(s95417)液晶も同じにすれば、線や文字、そしてグラフィックなどを表示させる関数がそのまま使えるようになるはずです。

そこでやったことは、ssd1289に0,0点から始まる斜め線を描かせ、「原点位置と、x,y方向」を調べる。

#if USE_SSD1289 == 1
  Clear_Screen(LCD_GBLUE);  //for SSD1289
#else
  st7787_clear(LCD_GBLUE);  //for st7787
#endif

//LCD原点&x,y方向テスト
while(1) {
    //座標テスト
    //(x0,y0)-(x100,y100)ライン
    Draw_Line(0, 0, 100, 100, LCD_BLACK);

    //(x0,y0)-(x239,y319) SSD1289 FULL POINT
    Draw_Line(0, 0, 239, 319, LCD_RED);

    //(x0,y0)-(x239,y200)
    Draw_Line(0, 0, 239, 200, LCD_BLUE);


【ssd1289】
stm32_proj_42.jpg
右上が作図開始点、←x方向、↓y方向

初期化プログラムの設定記述内容は
  /*
   * Entry Mode R11h = 6018h
   *
   * DFM1 = 1, DFM0 = 1 => 65k Color Mode
   * ID0 = 1, AM = 1    => the way of automatic incrementing
   *                       of address counter in RAM
   */

  Write_Command(0x0011, 0x6018);




0x0011 でカラーモードとGRAMのアドレスカウンター方向を設定している。
0x18部分がアドレスカウンターの原点と方向を決めるので、0x18は下図の右上図になる。
(写真は下図に対し、時計方向に90度回っている)


さて、st7787で同じ向きになるような設定をするには、データシートのこのデータを参考にする。



原点は左上(B点)、x方向 を下図の下側に、y方向 を右側にするのがこの設定。即ち、MX=MY=0,MV=1



とすると、初期化プログラムは以下の通り(0x0036部分のみ表記)

  Write_Cmd(0x0036);
  Write_Data(0x0020);   //縦:x=320,y=240, st7787_rect(0,0,x,y) 左スタート

この設定を行うことで、LCDは以下の表示となる。ssd1289と同じです。

【st7787(st95417)】
stm32_proj_43.jpg

・・・と、ここまで記述してきて、やっと解りました。 9.12.2 の表を見ると、「X-Y Exchange」とあります。
先に記述した、void st7787_rect() 関数で、x、yを入れ替えた原因はここにあったのです。

【s95417での表示画面】
stm32_proj_40.jpg

苦労してやっと動いたs95417ですが、アイコン・バックが透過しません。色々と設定を変えてみましたが直りません。背景色を何故 BLUEと認識してしまうのだろうか? それが解りません。

このLCDは小さくて好きなのですが、
1.このアイコン背景色の問題
2.タッチパネルが4線式のA/D入力なのでSPIに慣れた身には未体験領域だ。安定度が心配です。
  ソフトも新作を要します。
3.タッチの割り込みはどうやるのだろうか? A/Dの割り込みってあるの? 動作安定するの?

安い代わりに手がかかりすぎるのが最大の欠点のようです。  どうしようかな?

625円で貴重な勉強をさせて頂きました、ということで THE END かな?

------------------------------------------------------
6月16日追記

アイコンバックカラーNGの原因が判りました。
stm32_proj_46.jpg

原因はバックカラーの取得結果が正常値になっていなかったです。過去形で書くと直ったように思えますが、恒久的にはダメ状態が続いています。
上の画像では修復されたように見えますが、実は自分で塗ったバックカラー0x07FFをアイコン作図のバックカラーデータを強制的に割り当てただけです。

st7787ではバックカラー取得に0x002E コマンドを使いますが、正常ならば 0x07FFが取得できるはずなので、取得データは 0x00FCです。色々と設定を試しましたがうまくできません。

まあ、背景に複雑な画像を配置しないプレーンな1色塗りだったら、アイコンの背景色にそれを使えば一応の解決策にはなるかな。それにしても65k色のLCDなのだから、背景色16ビットが読み取れない訳がないはずなのだが・・・ まだ何かを見落としているのかもしれない。





プロフィール

haiga

Author:haiga
私のブログへようこそ!
電気オンチが始めた自作オーディオです
2010/3/17 電子工作をプラスしました。

自作オーディオの楽しみ共有のため、私が作ったパーツ提供をしてます。質問や要望を遠慮なくコメント欄に書き込んでください。

FC2カウンター
その日1回目にアクセスいただいた方の総カウントです
最新記事
最新コメント
最新トラックバック
カテゴリ
月別アーカイブ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。