2018年9月29日土曜日

[PICマイコン] マイコンとライタを購入

PICマイコンとライタを購入しました。PICマイコンは今回始めて使います。

○マイコン
・PIC32MX210F016B-I/SP   \190
         32bit-40MHz, RAM:4kB, ROM:16kB, ~3.6V, USB有
・PIC32MX270F256B-50I/SP   \380
         32bit-50MHz, RAM:64kB, ROM:256kB, ~3.6V, USB有
・PIC32MM0064GPL028-I/SP  \175
         32bit-25MHz, RAM:8kB, ROM:64kB, ~3.6V
・PIC16F1823-I/SP   \120
         8bit-32MHz, RAM:128B, ROM2kB, ~5.5V

高性能なPIC32マイコンを使ってUSBデバイスを開発してみたかったので、秋月で購入可能な最も安いUSB対応マイコンPIC32MX210F016Bと、メモリ不足などで動作しない場合を考えてPIC32MX270F256Bを購入。また、PIC32系で最安のPIC32MM0064GPL028も購入。さらに、PICマイコン初心者なので情報の多いPIC16F系マイコンのPIC16F1823を購入しました。

○PICライタ
・PICkit4   \5700
  情報量はPICkit3が多いですが、多くのマイコンはβサポートながらPICkit3と同様に扱え、さらに高性能なようなので購入しました。

2018年2月23日金曜日

[自作PC] 電源について

PCを自作するとき電源は、PCの性能に直接かかわらないので、あまり重視されないことも多いですが、自分はかなり重要なパーツだと思います。今回は自分が体験した電源が原因のPCの不調について書こうと思います。


1. 再起動ループ
 PCの電源が原因で起きる故障というとまずこれを思い浮かべる人も多いと思います。原因は起動時が最も電源に負荷がかかるタイミングのため、電源容量に十分な余裕があっても、電源電圧が不安定になってしまうからです。特にHDDやFANなどのモーターが使われる機器がつながっていると起きやすいと思います。
 また、寒い日にも電源電圧が不安定になりやすく、電源があたたまるまで再起動を繰り返させないと起動出来ないこともありますが、これを行うとHDD、MB、GPUなど様々な(ほぼ全ての)パーツが悪くなるので行わないほうが良いです。

2. ソフトウェアが落ちる、フリーズする(ブルースクリーンも)
 電源電圧が安定しないと時々ソフトウェアが落ちたり、フリーズしたりすることがあります。なぜ起きるのかははっきりとは分かりませんが、おそらくCPUの割り込み失敗で起きているのではないかと思います。
 録画サーバー内で自動エンコードのための自作プログラムを動かしていたとき何故か数日経つと停止していることがありましたが、電源を変えて以来連続で3ヶ月程度動かしても発生していません。

3. 突然のシャットダウン(KP41)
 突然シャットダウンが起きるとエラーログにKP41と書かれますが、これは突然のシャットダウンが起きたという情報しか持ちません。そのため原因を探すことは非常に困難で、解決策を調べても治らないことも多いです。ただ個人的にはこのエラーはCPUに何らかの異常が起きたときに起きるものだと思います。(ソフトウェアの欠陥ならブルースクリーンになるはずで、突然のシャットダウンはCPUが停止したことによると考えられる為)
 電源電圧が突然変化することによりCPUの設計上の対応可能な領域から外れることで起きるのだと思います。 ただし、これはマザーボードやCPU自体が問題の原因となっている可能性があります。

4. マザーボードを傷める
 多少の不安定な電圧はマザーボードのコンデンサが吸収してくれますが、電圧変動の大きな電源を使っているとコンデンサが消耗し性能が悪くなることがあります。
 自分の場合は正常なシャットダウンができなくなりました。(OSのシャットダウンが終了しても電源ランプが消えず、MBから電源へのシャットダウン信号が送られていないのではと思います。)これは電源を交換しても治りませんでした。


以上が自分が体験した電源に関するトラブルです。
 特に2や3のトラブルは他にも様々な原因が考えられるトラブルかつデータやOSが壊れる可能性もあるので電源は良いものを買った方がいいと思います。
 また、近年の電源ならば、よほどの電源でなければ問題ないと考え、80Plus認証がある評判の悪くないメーカー製なら大丈夫だという人もいますが、上記のトラブルは2016-2017年にENERMAX製の80Plus(GOLD)の電源で起きたものです。(24時間稼働で2ヶ月後に2つめ、4ヶ月後に3つめ、6ヶ月後に1つめが起きました)PCの稼働時間が長い使い方をする場合特に良い電源を選んだほうが良いと思います。






2017年3月26日日曜日

[録画サーバー]運用経過3

冬の間の録画サーバーの調子の報告です。

1.KP41問題
 前回にも書きましたが、GPU (intel HD graphics) に急に負荷がかかると突然電源が落ちるようです。Chromeでの動画視聴時に特に起きやすいようです。Firefoxではあまりおきませんでしたが、GPUドライバが落ちることがありました。また、Windows8の画面分割を行おうとした時にも発生しました。
 画面分割時の電源落ちの後、PCを立ち上げ、Chromeを起動すると、Chromeで見ていた動画が表示されました。しかし、画面分割の操作時にChromeは既に(手動で)閉じていたので、この電源断は、Chromeのプロセスが正常に終了せずに悪さをした可能性が考えられます。

2.再起動を繰り返す問題
 起動させようとすると(更新のための再起動を含む)、画面が表示される前に(電源ボタンが点いて0.5秒くらいで)電源が落ち、さらに再起動し、また落ちることを繰り返す現象が高頻度で発生しました。HDDやTVのチューナーカードを外すと起動するので、起動時に電源電圧が不安定になっているものと思われます。
 起動させるには、再起動を繰り返す状態を放置して起動するのを待つか、HDDを外してしばらく動かしたからシャットダウンし、HDDを付け直して起動する方法がありました。

3.原因不明のコマ落ちの解決
 前回は、原因が分からなかったコマ落ちですが、解決法が分かりました。
 PX-W3PEにはカードリーダーが付いていますが、これを使うとコマ落ちがおきてしまうようです。なので、外付けのカードリーダーを使うことによって解決しました。


<<前



2017年1月22日日曜日

[STM32マイコン]SW4STM32を使う(USB-HIDデバイス:複数デバイス)

今回は、前回作ったHIDマウスのプログラムを改造して、HIDマウス&キーボードとしてF401REをPCに認識させます。

○USB-HID規格について
まず、USBのHID規格についての基礎知識があったほうがいいので下記のリンクを見ていくと参考になります。

・USB-HIDクラスの概要:http://www.cqpub.co.jp/hanbai/books/33/33381/33381.pdf

・HIDの各ディスクリプタ:http://www.wdic.org/w/TECH/USB%20HID%20%E3%82%AF%E3%83%A9%E3%82%B9

・HIDのレポートディスクリプタの詳細:http://wiki.onakasuita.org/pukiwiki/?%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF

・USB-HIDの通信の詳細等(PCIマイコン):http://www.geocities.jp/zattouka/GarageHouse/micon/USB/USB5.htm


○変更箇所について
次に、SW4STM32でプログラムを行うときに、大まかにどこを変えていけばいいのかについては、下記のサイトなどが参考になります。
  http://damogranlabs.com/2016/03/stm32-custom-usb-hid-device-yes-please/

さらに、複数のHIDデバイスとして認識させるために下記のサイトを参考にします。
   https://stm32f4-discovery.net/2014/09/library-34-stm32f4-usb-hid-device/
このページの下のほうにある "TM STM32F4 USB HID Device Library" をダウンロードして中にある "usbd_hid_core.c" を見ることでどのようにディスクリプタを変更すればよいかが分かり、 "usbd_hid_core.h" を見ることでどこでディスクリプタのサイズを変更するのかが分かります。
ただし、HALドライバーでかかれていないので、このライブラリ自体をそのまま使うことはできないと思います。
また、このライブラリによって、HIDのマウス・キーボード・ゲームパッド(ジョイスティック)についてどのようにレポートディスクリプタを書けばよいかが分かります。

○プログラムについて
・ usbd_hid.c 内の変更点
 1) USBD_HID_CfgDesc[ ] の変更
  "bInterfaceSubClass" を "no boot" にする : 0x01→ 0x00
  "nInterfaceProtocol" を "none" にする : 0x02 → 0x00
 2) HID_MOUSE_ReportDesc[ ] の変更
   "TM STM32F4 USB HID Device Library" の "usbd_hid_core.c" のレポートディスクリプタを参考にしてキーボードとマウスのディスクリプタに書き換える。
・ usbd_hid.h 内の変更
 定義されている "HID_MOUSE_REPORT_DESC_SIZE" のサイズ(Byte)を、usbd_hid.c内のレポートディスクリプタのサイズ(Byte)に変更

ここまでで、PCに接続するとキーボードとマウスとして認識すると思います。
(認識しないときは、一番下の"※1"を参考にしてください)
最後に、PCにマウスとキーボードの値を送ります。
main()関数内の初期化終了後の位置に、下記の配列を用意します。
・キーボード:
     uint8_t hid_keyboard[9]={1,0b00000000,1,0,0,0,0,0,0};
           //ReportID, button1-8, reverse, key1, key2, key3, key4, key5, key6
・マウス:
     int8_t hid_mouse[5]={2,0,-5,0,0};
           //ReportID,button1-3,x,y,wheelこれは、 "TM STM32F4 USB HID Device Library"とそれがあったページを参考にしています。
これらの配列を各々PCに下記のようにして送ることができます。
     USBD_HID_SendReport(&hUsbDeviceFS,hid_keyboard,9); 
     USBD_HID_SendReport(&hUsbDeviceFS,hid_mouse,5);
送る配列の中身を書き換えることで、PCにマウスとキーボードの情報を送ります。

※1. 上記ではうまく動かない可能性があります
 usbd_hid.c 内の USBD_HID_DeviceQualifierDesc[ ] 配列をコメントアウトし、
 USBD_HID_GetDeviceQualifierDesc() 関数の中身を return NULL; とする。
 これによって解決するかも知れないです。

2016年12月23日金曜日

[STM32マイコン]SW4STM32を使う(USB-HIDデバイス)

F401REではUSBデバイスの開発ができるのでHIDのマウスとしてPCに認識させたいと思います。

○CubeMXでUSBを使う設定にする
まず、"Pinout"タブでUSBを使う設定をします。 Peripherals >> USB_OGT_FS >> MODE を Device_Only にします。 MiddleWares >> USB_DEVICE >> Class_for_FS_IP を "Human_Interface_Device" に設定する。
さらに、USBでは正確な高速クロック(HSEの設定)が必要なため、クリスタルが必要ですが、今回使うボードにはデバッグボード上にしか必要なクリスタルがないため、それを使うよう設定します。そのため、"Pinout"タブでHSEを使う設定にします。Peripherals >> RCC >>HSE を"BYPASS_Clock_Source"に設定します。
次に、このままではエラーが出てしまうのでクロック周りの設定をしてHSEでのクロックを有効にします。"Clock configuration"タブに移動するとクロック周りの問題を治すかどうか聞かれるので’Yes’を選択すると自動で設定してくれます。
最後にジェネレートして終わりです。

○SW4STM32でプログラミング
SW4STM32を起動しインポートします。そして、main.cファイルの中のmain関数のwhileループのところに下記のようにします。
//---------------------------------
  int8_t hid_mouse[4]={0,-5,0,0};//button1-3,x,y,wheel
  while(1){
    HAL_Delay(5000);
    USBD_HID_SendReport(&hUsbDeviceFS,hid_mouse,4);
  }
//---------------------------------
このようにすると五秒に一回左にマウスポインターが動くようなマウスができます。
CubeMXで上記の設定をするとジェネレートされるコードはHIDマウスです。(デバイスディスクリプタ等がそのように設定されているため)

○STM32F401RE(Nucleo64マイコンボード)の配線
PA12ピンをUSBのD+、PA11ピンをUSBのD-、GNDをUSBのGNDに接続するが、USBのVbusは接続しません。(USBから電源を取るときはVbusをE5Vピンに接続し、リセットボタン下の電源を選ぶジャンパーをE5Vにする) また、必要なUSBケーブルは100円ショップ等で買うこともできます。大抵のケーブルはVbusが赤、D+が緑、D-が白、GNDは黒のコードですが、念のため、VbusとGNDを確かめるためUSB充電器とLEDを使って確認します。また、F401REではPA9ピンを3.3[V]ピンに接続しておきます。(F401REではこれが無いとUSBの機能が動きません)





[STM32マイコン]SW4STM32を使う(複数のADコンバータ)

F401RE(STM32系マイコン)で、SW4STM32とCubeMXを使って複数のADCをHALライブラリを用いて使おうとしたとき、情報があまりなかったので、その方法を残しておきます。

今回行う方法は、ADCを使って値を読み取るたびに、使うADCのチャンネルをセットしなおす方法です。
※HAL_ADCEx_MultiMode系の関数を使ったほうが速いかもしれないが、HALライブラリはあまり詳しいわけではなく、使い方がよく分からなかったので試すことができなかった。

まず、CubeMXでADCで使うピンを設定したら、プロジェクトをジェネレートします。

次にプログラムを行っていきます。
プログラムは使いやすいように新しい関数を作りますが、mainファイル内に自動生成された MX_ADC1_Init()関数を利用します。この関数でチャンネルを決めているのは "sConfig.Channel=ADC_CHANNEL_0;"となっている部分なので、ここを変えてチャンネルを選んで値を取得できるようにします。
[追記・訂正]以前のものだと正常に動作しない場合があったためDelayを入れ修正しました
//---------------------------
uint16_t ADCsGetValue(uint32_t ch)
{
  HAL_ADC_Stop(&hadc1);
 //------ ADC Channel Select
  ADC_ChannelConfTypeDef sConfig;
  sConfig.Channel = ch;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
 //------ ADC Read
  HAL_ADC_Start(&hadc1);
  HAL_Delay(1);
  return HAL_ADC_GetValue(&hadc1);
}
//---------------------------
今回作った関数は引数にチャンネル(ADC_CHANNEL_0等)、返り値にそのチャンネルの値を持ちます。
また、値を読んだ直後にHAL_ADC_Stopを置くと値を取得できませんでした。原因は分かりませんが、HAL_ADC_Stopまでに時間があるほうがいいようです。(DelayをStop前に置くとうまくいく)
→ StartしてからGetValueまでの間にDelayを入れるとうまくいく (おそらくStartの後AD変換が行われ、その後出ないと正確な値がGetValueで読み出せないのだと思われる)
 ↓↓
割り込みなどを使った方が良いと考えられる。





[STM32マイコン]SW4STM32を使う(ADコンバータ)

今回は、F401REでアナログ電圧を読み(ADCを使う)、それをシリアル通信でPCに表示するプログラムをSW4STM32とCubeMXを使って作成します。
※ライブラリはHALを使用

○CubeMXでADコンバータ(ADC)を使う設定にする
 前回のシリアル通信をするものに、ADCを使う設置を追加します。
 前回同様にCubeMXを起動し、LoadProjectで前回までのプロジェクトを開く。
 次に、"Pinout"タブでADCピンを割り当てる。今回は"ADC1_IN0" (F401REのPA0端子) を使う。
 左の "Configuration" >> "Peripherals" >> "ADC1" のIN0にチェックをいれる。
最後に、プロジェクトをジェネレートしなおす。

○SW4STM32の準備
SW4STM32を再起動するか、プロジェクトをリフレッシュして、プロジェクトを読み込みなおす。
エラーが出たときは、プロジェクトのCleanとBuildでエラーを消す。それでもエラーが消えないときは、プロジェクトをSW4STM32上から削除し、インポートしなおす。

○プログラミング
main.c内のmain()関数で、whileループのところに下記のように書き加えます。
//---------------------------------------------
  char str[32]={0};
  sprintf(str,"\nSTART\n");
  HAL_UART_Transmit( &huart2, str, strlen(str), 0xFFFF );

  while(1){
      HAL_ADC_Start(&hadc1);
      int val=HAL_ADC_GetValue(&hadc1);
      sprintf(str,"ADC_IN0 : %4d (%4d[mV]) \r", val, val*3300/0xfff);
      HAL_UART_Transmit( &huart2, str, strlen(str), 0xFFFF );

      HAL_ADC_Stop(&hadc1);
      HAL_Delay(1000);
  }

//----------------------------------------------
・"HAL_ADC_GetValue"で得られる値は0~4095(0xfff)で、F401REは、3.3[V] (3300[mV]) で動作しているので、"val*3300/0xfff"とすれば、[mV]で値を読み取れる。
 ※ 3.3[V] で動作しているので5[V]端子にADCの端子をつながないように注意が必要。
・ "HAL_ADC_GetValue" の前に "HAL_ADC_Start"、後に "HAL_ADC_Stop" を行わないと連続で値を読めない。
 ※ "HAL_ADC_Start"を行わないと値が読めない。

最後は、実行して、TeraTerm等で表示し、ADCが使えていることが確認できればOKです。
※ 端子に何も繋がないときは値が揺れます。