N.Yamazaki's blog

主に音声合成について思ったことを書いてみようと思います。
CentOS i386(32bit)でC++11を使う

環境:CentOS 6.9 i386

 

■debtoolsetでGCCのバージョンアップ

CentOSのGCCが4.4.7であり、C++11が使えない。GCCのバージョンアップを行うことにした。
ネットの情報によると、Software Collections のDeveloper Toolset というのをインストールすればよいとのこと。

しかし、その情報の通りに行うと、次のコマンドがエラーになってインストールできない。

# yum install devtoolset-4-gcc

[Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found"

原因は、導入したリポジトリがx86_64用であるため。

 

■i386用のリポジトリ
そこで、見つけたi386用のリポジトリがこちら。
https://copr.fedorainfracloud.org/coprs/hhorak/devtoolset-4-rebuild-bootstrap2/

 

■インストール

# cd /etc/yum.repos.d/
# wget https://copr.fedorainfracloud.org/coprs/mlampe/devtoolset-4.1/repo/epel-6/mlampe-devtoolset-4.1-epel-6.repo
# yum install devtoolset-4-gcc devtoolset-4-binutils devtoolset-4-gcc-c++

 

■環境の切り替え
新しいバージョンのGCCを使うには次のコマンドで変更。

$ scl enable devtoolset-4 'bash'
$ g++ --version

これで、GCC 5.3.1の環境になり、C++11が無事に使えるようになった。

 

ちなみに、

 GCCはC++11 ABIの安定性の保証をバージョン5.1以降でのみ提供しています。

とのこと。

また、devtoolset-7(GCC 7.2)のリポジトリもあるようだ。
https://copr.fedorainfracloud.org/coprs/mlampe/devtoolset-7/repo/epel-6/mlampe-devtoolset-7-epel-6.repo


■参考LINK

「Developer Toolset 4でCentOS6にお手軽にGCC5.2をインストール」

CentOSで新しいGCCなどといった開発ツールを使いたい場合のメモ

CentOS 6でC/C++開発環境を整える

 

| その他 | 19:40 | - | - |
Windows10でスリープから復帰できなくなった【真っ黒画面】
ノートPCをスリープから復帰しようとしたら、画面が真っ黒のまま、何も操作できない。

そんなときは、Ctrl+Alt+Delをお試しあれ。

はっきりしないが、Windows10のSR1を入れてからこの状態が発生するようになったと思う。

スリープから復帰させようと、何らかのキーボードを押下すると、モニタのはONになり(信号が入った)、マウスポインタも表示され動くのだが、画面は真っ黒のままで、どのキーを押しても変化しない。ただ、常にこの現象が起きるわけではない。

ネットで調べると、ドライバーとかハードの不具合とかあるけれど、自分の場合は直感的に違うような気がする。
何かの設定で、この不具合を解消できる気もするが、そんなの知る由も無し。

とりあえず、Ctrl+Alt+Delすれば、ログイン画面が出るので、当面はこれで乗り切ることに。


環境:Windows10 Home(32bit),  Ver.1511, OSビルド10586.36, ASUS X205TA
| その他 | 16:41 | - | - |
リアプロ Grand WEGA(KDF-60HD800)の偏光板の交換修理
10年以上使い続けているSONYのリアプロジェクションテレビ。
購入当時、60インチの大画面はちょっと自慢でした。

ところが最近、急に画面下側に緑色のオーロラのような曇りが目立つようになり、
特に暗い映像を観るとき気になるというか、よく見えなくなってきました。
液晶テレビに買い替えを検討するも、こちらのサイトを見て、試しに修理してみようと。
ダメだったら買い替えればいいじゃないか!


(緑の雲がかかった黒画像 写りのせいで、実際はココまで酷くない)

まずは、原因を探るため、光学ユニットを取り外し偏光板をチェック。
すると、やはり緑の偏光板が・・・
片側が溶けたように劣化していた。これを貼りなおせば直りそうだ。


(劣化した偏光板)

そこで偏光板を取り寄せ。これには先のサイトで勧められてたMUHD40S。
送料代引き込みで9000円弱。3x4cmを3枚だけなので、もっと小さくて安いのがあればよいのだけど・・・

緑の偏光板だけ張り替えて描画チェック。

うーむ。なんか色がぜんぜん変。偏光板の特性がオリジナルと異なるから?
さらに、画面中央付近に1箇所、小さく白がマゼンダになる部位があって、
顔にニキビがあるように見えてとても気になる。
そこで、赤と青の偏光板も張り替えて、ついでにニキビの原因も探ることに。
ニキビの原因は緑の液晶パネルに付いてたゴミがでした。
組み立ての際にはレンズ等にゴミやホコリがついてないか要確認です。

偏光板を3枚とも張り替えて、再度描画チェック。
今度はどうしても黒が緑がかってしまい、パラメータの調整でも対処できません。

頑張って偏光板レンズの角度をすこしづつ動かし、黒の輝度が下がり、且つ、黒に色がつかないように調整。

その後、メモリースティックのカラーバー表示にてパラメータ(480i)を調整し、
その値を1080i側のパラメータ初期値とし放送番組の肌の色をたよりに細かい調整を行いました。
(FYI:最終的なパラメータ RDRV:50 RCUT:31 GDRV:35 GCUT:30 BDRV:55 BCUT:47)

結果、曇りがなくなり、さらに前よりずっと明るくなりました。大変満足!
液晶TVへの買い替えは、しばらく先になりそう。


(修理後の黒画像)


(修理後のカラーバー)
 
以下、作業メモ(間違っていることもあるかもしれません。念のため)。

■光学ユニットの取り外し
この参考にしたサイトにも詳細ありますが、HD800シリーズは少し違っているみたいなので補足。
今回、スクリーン部分は外さないで作業しました。
  1. バックパネルの取り外し(ネジ14本)。特に難しいことは何も無いです。
  2. 金属製のステーが左右と中央に3つ縦にならんでいるのでこれを外す(ネジ8本)。
  3. フロント向かって左のパネルを外して、金属製のメッシュパネルを外し(ネジ2本)、アースの平型端子を外しておく。これは、基板ユニットを引き出すときに引っかかるので必須です。
  4. 基板ユニットをゆっくり引き出す。入出力端子や電源など全部一体になってます。左右を少し上に持ち上げて引き出すと良いです。配線をクリップで留めているので、必要なクリップは緩めておきます。
  5. 中央に見えるのが光学ユニットです。光学ユニットの配線は、信号線の束4本(灰、赤、白、オレンジ)とファン1本の計5本で接続されてるのでこれをすべて外します。
  6. 本体と光学ユニットは、ユニット左右の下側に後ろから正面に向かってネジ2本で固定されています。このネジは抜けない構造になってますので、ドライバーで思う存分緩めて大丈夫です。
  7. あとはゆっくり引き出せば光学ユニットを取り出せます。


(フロントのメッシュパネルの取り外し)


(3本の金属ステーで縦の補強をしてる)


(基板ユニットを引き出した。中央の黒いのが光学ユニット)


(取り出した光学ユニット)

■光学ユニットの分解
  1. 上部の黒いプラパネル2つ(ネジ3本)
  2. ランプ部分の金属パネル(ネジ4本)
  3. 基板の上部金属カバー(ネジ7本)
  4. 基板(ネジ4本、液晶パネルとのフレキケーブル3本を外すの忘れずに)
  5. レンズユニットと本体を接続しているネジ 上側のみ4本
  6. ユニット本体のネジ(12本くらい?ひとつだけ溝の中にある)。これでユニットを上下に分割できます(そーっと分割)。
入射側偏光板(レンズつき)を外すときは、ネジに付属のバネを下に落とさないように!
ちなみに、ランプに近い側から赤、緑、青になります。


(レンズユニットと本体を接続しているネジ)


(はずした部品)


(光学ユニット内部)

■偏光板の張替(貼り替え)
まずは偏光の向きを調べておきます。
パソコンの液晶モニターを使って偏光の向きを合わせられます。
なお、偏光板の表裏で違うので貼る面も考慮します。
基本45度の傾きです。(モニターの偏光軸も45度傾いてました)
各レンズごとに透過と遮断の角度の写真をとっておくと間違いないです。

古い偏光板を剥がします。
ちょっと大変な作業です。ダイソーのシールはがしは全くダメで、無水イソプロピルアルコールを使いました。
2層になってて、一層目は比較的簡単にまとまって剥がれましたが、2層目はイソプロを少しずつ垂らしながら端からすこしずつ剥がしました。その後、まだ接着剤が残ってるので、これもイソプロとプラのへらでこすって布で拭いて落とします。

偏光板を貼ります。
偏光板は両面に保護フィルムが付いてるので、あらかじめどちらが糊面か確認してマークしておきます。
向きを確認してカッターでカット。気泡などは特に意識することなく簡単に綺麗に貼れました。
念のため、偏光の向きが正しいか確認しておきます。

■偏光板レンズの角度調整
バネつきのネジで角度を調整することができるようになってます。問題は、この偏光板の向きをどのように調整するかです。
偏光板の偏光軸と液晶の配向軸を合わせるべきと理解してるのですが、そもそも液晶の配向軸がわかりません。

そこで、最も暗くなる角度から90度戻した位置が最適な角度と考え、次のようにセットしました。
ランプ側から懐中電灯を照らして、投射レンズを覗き、偏光板の向きをずらしながら最も暗くなる角度をマークし、そこから90度戻した角度に調整する。
残念ながら、この方法だと私の場合赤だけ輝度が出ませんでした。理論的に正しくないのかな?

結局、とりあえず目視で水平に調整して、どうしても気になる場合に表示を見ながら角度調整するのが良さそうです。
といっても、この角度調整は、その都度光学ユニットを取り出す作業になるのでかなり大変です。
なお、この調整は光学ユニットをバラす必要はなく、上部の黒いプラパネルをはずすだけでネジを回せます。
今回は試してませんが、スクリーンを外せば上から表示したまま調整できるかもしれません(真っ黒の表示で輝度が小さくなるように調整)。
そうそう、描画チェックで角度調整する前に、下記方法でパラメータをデフォルト値に設定しておきます。

(角度調整ネジ 赤は写真左中央、緑と青は写真下)

■パラメータの調整
ここでのパラメータとは、ソフト的に内部にセットされている機器固有の設定値のことです。
今回対象のとするパラメータは、MCP-ADJ1項目のRDRV RCUT GDRV GCUT BDRV BCUTの6つです。
RGBそれぞれのdrive gain control(DRV)とcutoff control(CUT)を意味し、DRVで白レベルを調整、CUTで黒レベルを調整します。
これらパラメータの調整はサービスモードに入って行います。
サービスモードの入り方やパラメータの変更方法はネットで調べます。
ちなみに私は「mcp-adj1 sony」のキーワードで検索して、KF-60DX100のサービスマニュアルをゲット。

まずはパラメータをデフォルト値にセットします(DRVは50、CUTは40)。
出荷時に機器固有のパラメータが書き込まれてますが、それらは偏光板の交換によって無意味になるので・・・。
描画チェックには、背景が黒で白+RGB純色の値がそれぞれ0-255の値で変化するテスト画像を用いました。
その後、DRVを調整して白に色がつかずに明るく調整。CUTで黒に色がつかずに暗くなるように調整。
また、RGB各色の明るさの変化が同じようになるように調整。

注意点は、
  •  念のため元の設定値をメモしておくこと。
  •  パラメータは入力信号の種類毎(480i/1080iなど)に分かれてて、それぞれ設定が必要。
  •  調整した後は [消音]->[12] で書き込むことを忘れない。
  •  時間が経ったり、入力ソースが変わると編集中のパラメータが元に戻る。

■カラーバーを表示して描画チェック
メモリースティックにカラーバー画像を保存して、これを表示してチェックや調整をしました。
本機はメモリースティックに単にjpgファイルを保存しただけでは再生できません。
カメラ用にフォーマットし、DCF規格に従って画像ファイルを書き込む必要があります。
これには、PC上のアプリ、「Memory Stick Formatter(メモリースティック フォーマッタ)」と「Image Creator1.5」が使えます。
*メモリースティックが鬼門かも。すでにMSを使えるPCは壊滅だし、かろうじてMSが使えるUSBカードリーダが残ってたので助かりました。

■その他
・表示チェックの時、特定の色が出なかったり、縦に何本も筋が入ったりする現象がありました。
これは、液晶ユニットと基板をつないでるフレキシブルケーブルの接触不良で、接点復活剤で対処。

・経年変化によるプラスチック部品の劣化があります。製造から十数年なので仕方ないですが。今回、ランプファンが汚れていたので分解掃除しようとしたら、ファン外側のケースがバラバラになり、この補修に手間取りました。余計なことはしないほうが良いですね。あと、光学ユニット下側も割れ易いので注意です。
 

偏光板の張り替えにチャレンジされる方、余った偏光板を有償でお分けします。ご希望の方は infoaqあっとa-quest.comまでご連絡ください。

以上、今でも大事にリアプロ使っている希少な方々の参考になれば、でした。
| その他 | 17:50 | - | - |
MCP2210 DLL用のheaderとlibファイル

■概要
MCP2210はMicrochipのUSB-SPIブリッジです。
これは、WindowsからはHIDデバイスとして認識され、専用ドライバーが不要で、COMポートの選択もいらないので、使い勝手が良さそうです。
また、Microchipから提供される"MCP2210 DLL"を使えば、HID APIを使わずにSPIを操作する感覚でホストのプログラムが書けます。
しかし、残念なことに"MCP2210 DLL"には、headerとlibファイルが付属していません。そこで、DLLから.h/.libを作成したので公開します。


■ダウンロード

mcp2210dll-hdr-lib.zip
(MCP2210DLL-UM.lib, MCP2210DLL-UM.h, msvcp90.dll, msvcr90.dll)


■備考

  • "MCP2210 DLL"のバージョンは Ver. 1.2.0 (MCP2210DLL_2014-10-29.zip)
  • MCP2210DLL-UM.dllのアーキテクチャはx86(Win32)、呼び出し規約は __stdcall
  • ヘッダファイルは、"Using the Unmanaged DLL.pdf"の関数一覧のテキストから抽出しました。
  • namespaceはすべて省略しました。
  • "Using the Unmanaged DLL.pdf"とMCP2210DLL-UM.dllは、下の2つの関数名が違って定義されています。差異は.defファイルで吸収したので、pdfの関数名で呼び出せます。
    "Using the Unmanaged DLL.pdf"       MCP2210DLL-UM.dll
      GetSpiActiveCsValue                        GetSpiCsActiveValue
      GetSpiIdleCsValue                           GetSpiCsIdleValue
  • C++/CLIの変数型の"String^"を使っている以下の関数は省きました。
        GetSelectedDevInfo     EnterAccessPasswd     SetNewPasswd
  • 実行には、"MCP2210 DLL"付属のmsvcp100.dllとmsvcr100.dllは使わず、msvcp90.dllとmsvcr90.dllが必要です。


■使用例
 

#include "stdafx.h"
#include "MCP2210DLL-UM.h"
const UINT32 MCP2210_VID = 0x04D8;   // VID for Microchip Technology Inc.
const UINT32 MCP2210_PID = 0x00DE;   // PID for MCP2210
int _tmain(int argc, _TCHAR* argv[])
{
    int i;
    DllInit(MCP2210_VID,MCP2210_PID);
    // check device connection
    int isConnected = GetConnectionStatus();
    if(isConnected) {
        // GP1->CS    GP0,GP2-GP8->GPIO
        const byte   gpioPinDes[] = {0, 1, 0, 0, 0, 0, 0, 0, 0};
        // GP0->OUT/LOW GP2->OUT/HIGH GP3-GP8->INPUT
        SetAllChipSettings(CURRENT_SETTINGS_ONLY,(byte*)gpioPinDes,
            0xFFFE,0xFFFA,0,0,0);
        // GP0->HIGH GP2->LOW
        SetGpioPinVal(0xFFFB);
        // set sample tx data
        WORD size;    //[byte]
        byte bufTx[64];
        byte bufRx[64];
        size = 16;
        for(i=0;i<size;i++){
            bufTx[i]=(byte)('A'+i);
        }
        // baudRate:1MHz idleCsVal:all-HIGH activeCsVal:onlyGP1-to-LOW SPI:Mode0
        SetAllSpiSettings(CURRENT_SETTINGS_ONLY, 1000000, 0xFFFF, 0xFFFD, 
            0, 0, 0, size, 0);
        // SPI transfer
        TxferSpiData(bufTx, bufRx);
        for(i=0;i<size;i++){
            printf("%x ",bufRx[i]);
        }
        // GP0->LOW GP2->HIGH
        SetGpioPinVal(0xFFFE);
    }
    DllCleanUp();
    return 0;
}

 


■LINK

「MCP2210 - USB Bridges」Microchip
「Wintab の開発環境構築」


■注意

Microchipより配布されている"MCP2210 Utility"は、信じられないことですが、下記のようにビットの並びが項目によって異なります。



Microchipより配布されている"MCP2210 SPI Terminal"の、GPIO/Chip-Select/DedicatedFuncのセレクタはFakeです。ソースコード見たら、デバイス側へはすべてChip-Selectで送られてます。


 

 

| その他 | 10:41 | - | - |
簡単!ATmega328Pにブートローダを書きこむ(第2弾)
ブートローダが書き込まれていないATmega328PにArduinoのブートローダを書き込む方法です。
以前に書いたOptifixを使う方法だと、ブートローダのバージョンがかなり古いので、今回は最新の方法を紹介します。

現在のArduinoIDE(Ver.1.6)にはメニューに『ブートローダを書き込む』というのがあります。
今回はこれで、買ったばかりの新品のATmega328p-puにブートローダを書き込んでみましょう。

用意するもの
ハードウェア
  • Arduino Uno(互換ボードも可)
  • ブレッドボード
  • ATmega328P
  • セラロック(8MHz-16MHz適当でよい)またはXtal
ソフトウェア
  • ArduinoIDE

boot_write_brd
(2015/04/27 ピン接続がずれてる間違いを修正)
(セラロックでなくXtalを使う場合は18-22pFのコンデンサx2も必要です)


作業手順
  1. ブレッドボードとArduino Unoを上図のように配線
  2. PCとArduino UnoをUSBケーブルで接続
  3. ファイル>スケッチの例>ArduinoISP
  4. ファイル>マイコンボードに書き込む
  5. ツール>ボード>Arduino Uno  (おそらく選択済み)
  6. ツール>書き込み装置>Arduino as ISP  (ArduinoISPのほうではない!)
  7. ツール>ブートローダを書き込む
  8. ステータス表示が「マイコンボードにブートローダを書き込んでいます」から「ブートローダーの書き込みが完了しました」になれば出来上がり!

注意
すでにブートローダが書かれてるデバイスや、セラロックが正しく接続されていないと以下のエラーが出ます。

avrdude: Yikes!  Invalid device signature.




おまけ 外部オシレータ(セラロックやXtal)無しでブートローダを書き込む

本来、ATmega328Pの工場出荷時は内蔵RSオシレータを使う設定なので、外付けのXtal無しでも動作し、ブートローダだって書き込めるはずです。本家の記述(http://arduino.cc/en/Tutorial/ArduinoISP)でも外部オシレータ無しでできると書いてあるのですが、実際にやってみると、この方法では外部オシレータ無しでブートローダの書き込みはできません。


なぜ、外部オシレータが必要なの?
その原因を調査したところ、ArduinoIDEは、ブートローダの書き込みの際に最初にデバイスにErase処理を行ってから、次に、ブートローダのプログラムを書き込んでいます。そして、この最初のEraseの際にFuseの設定を内蔵オシレータから外部オシレータに変更してしまっているため、ブートローダの書き込みの段階では外部オシレータが必要になるのです。
このとき外部オシレータがついていないと、ArduinoIDEは「avrdude: Yikes!  Invalid device signature.」というエラーを出します。実際のところはデバイスシグネチャーが違っているわけでなく、デバイスシグネチャーが正しく読めていない状態のようです。
 

それなら、外部オシレータを使わないで書き込むには・・・
Eraseの段階ではFuse設定は変更せずに、ブートローダを書き込んだ最後にfuseを設定するようにすればOKです。
実際には、¥arduino¥hardware¥arduino¥avr¥platform.txt の中の2行を次のように編集します。

tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m
 ↓
tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m

tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m
 ↓
tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m -U lock:w:{bootloader.lock_bits}:m


とりあえずこの方法で、Xtalやセラロックなしでも、素のAtmega328P-PUにブートローダを書き込めるようになります。

一度ブートローダを書き込んだものなどFuse設定が外部オシレータになっているものは、外部オシレータをつけて書き込むしかなさそうです。

(本記事執筆時点のArduinoIDEのバージョンは1.6.1)

 
| その他 | 22:37 | - | - |
ArduinoのWireライブラリはI2Cのリピーテッド・スタートが使えます
ArduinoのWireライブラリは、読み出しの際のリピート・スタート・コンディションが使えないって書いてあるサイトが多くありますが、今は使えるようになってます。

通常、I2Cデバイスにデータを書き込むときは単にwrite()を連続すれば良いのですが、I2Cデバイスからデータを取得するときは、読み込むレジスタのアドレスを指定(Write)してから、データを読み込む2段階の処理となります。
以下は、I2Cデバイスにレジスタのアドレス(1byte)を指定した後、2byteのデータを読み込むありふれたコードです。

  Wire.beginTransmission(DEVICE_I2C_ADDRESS);
  Wire.write((byte)REG_ADDR);
  Wire.endTransmission();

  Wire.requestFrom(DEVICE_I2C_ADDRESS, 2);
  uint16_t val = Wire.read();
  val = (val << 8) | Wire.read();


このコードでは、beginTransmission()からendTransmission()までの通信と、その後のread()はそれぞれ独立した通信です。具体的には、endTransmission()でストップビットが発生し、一旦バスが開放されます。

問題は、I2Cデバイスの中には、データ取得の際にレジスタのアドレス指定とデータの読み込みを1つの通信、すなわちリピーテッド・スタート・コンディションを用いて行うように指定しているものがあります。
そこで、これをArduinoのWireライブラリを使って書くと以下のようになります。
 

  Wire.beginTransmission(DEVICE_I2C_ADDRESS);
  Wire.write((byte)REG_ADDR);
  Wire.endTransmission(false);    // Stopしないで継続

  Wire.requestFrom(DEVICE_I2C_ADDRESS, 2, false);     // まだ、Stopしないで継続
  uint16_t val = Wire.read();
  val = (val << 8) | Wire.read();
  Wire.endTransmission(true); // ここでStop


endTransmission()、requestFrom()に引数を追加しているのがミソです。
これにより、ストップビットを出さずに、Write()/Read()を繰り返すことができます。
requestFrom()の最後の引数をtrueにして、最後のendTransmission()を省略してもよいかもしれません(未確認)。
ちなみに、これらの引数はWireライブラリのマニュアルにちゃんと書いてありました。
 
| その他 | 15:49 | - | - |
テスターMAS-345の通信仕様
音声テスター作成のために、秋月電子で入手したデジタルマルチメータ(テスター)「MAS-345」のRS232C通信部分を調査。



テスター写真

ハード



テスターの基板に書いてあったRS232C端子端子の名称です。




RS232C近辺の回路です。
端子はフォトカプラで絶縁されています。
RS232Cといっても出力電圧はホストのDTRとRTSの電位差から取っているようです。


インターフェース

data format: 7n2 at 600 baud (7 bits, no parity, 2 stop bits).
Control lines:
   DTR and RTS lines are used to power the TX line: RTS is clear
   for -12 supply; DTR is set for +12 supply. Data transmission is
   solicited sending whatever character to the RX line.
Data string format:
   MAS-345 sends a 14 bytes string with:
         <mode>< ><sign><value>< ><units><return>

     BYTE 1-2     : MEASURING MODE (ex;DC,AC,OH,CA,TE...)
     BYTE 3        : one space
     BYTE 4        : SIGN(-) or space
     BYTE 5-9    : Decimal point and value
              Current measurement value(ex;10.00, OL.,3.999)
     BYTE 10-13 : Unit (ex; mV,A,kOhm,nF...)
     BYTE 14      : Carriage Return '¥r'

   <mode>:  two bytes with the oerating mode: DC, AC, OH, CA, TE ...
   <sign>:  one byte with - or space
   <value>: five bytes with four digits and one decimal dot.(ex;10.00,  OL ,3.999)
   <units>: four bytes with the units: V,mV, A, kOhm, nF ...
   <return>: '¥r'
   One space is inserted between <mode> and <sign>, one between   <value> and <units>.
上は、ネットでみつけた情報です。テスター付属のCDにも情報があったけど、若干内容が違うようです。
600bpsの7bitノンパリティ、2ストップビットのUART通信となります。ホスト側から任意の内容の1バイトを送信すると、CRをデリミタとした1行(14byte固定)のASCIIテキストで、モードや測定値などを返す仕様になっています。


0123456789012
OH   O.L MOhm
OH  000.4 Ohm
OH  098.6kOhm
OH  0.032kOhm
OH  09.43kOhm
DC  3.306   V
DC  0.001   V
DC  05.05   V
DI  1624   mV
DI    OL   mV
TE -  OL    C
TE  0022    C
CA   .OL   nF
CA  137.4  nF
CA   .OL   nF
CA   OL.   nF
CA  000.8  nF
DC  015.5  mA
DC  000.0  mA
DC  0.051  mA
DC  0.974  mA
DC  001.0  mA
DC -00.00   A

これは、実際にテスターから返ってきた情報の例です。

あくまでも手元のテスターの1つでの調査なので、個体差があるかもしれません。
| その他 | 12:35 | - | - |
AVR Studio5.0 には stk500.exe が入っていない!
 AVRチップのプログラム(Flashを焼く意)にstk500.exe を使おうとしたら、どこにも見つからない。どうやらAVR Studio5.0 には stk500.exe が入っていないようだ。

入手先:
http://www.atmel.no/beta_ware/AVRCommandLineTools/AVRCommandLineTools.zip

展開後、AVRCommandLineTools.exe を実行してインストール。
デフォルトインストールでは、
C:¥Program Files¥Atmel¥AVR Tools¥Stk500
にstk500.exeが入っているはず。

ただし、このままstk500.exeを実行すると、libelfdwarfparser.dll が無いと怒られたので、隣のフォルダ(Stk600)から当該DLLをコピーして、一件落着。



| その他 | 00:08 | - | - |
I2C マスタ・レシーバで可変長のデータを送受信するには?
AVRでI2Cの通信を実装してる最中、可変長のデータを転送する方法でちょっと悩んだ。

I2Cの仕様では、「Start条件からStop条件間の1回の転送で伝送できるバイト数には制限がなく、何バイトでも送ることができます。」とある。これ自体は何ら問題がない。

転送するデータ長(バイト数)が固定でなく、応答に応じて変化する場合は、ACKかNOACKを返すことにより転送の打ち切りを示すことが出来る。これもAgree.

この辺のことは、こちらにとてもわかりやすくまとまっている。

上記で1つ問題になるのは、マスタ・レシーバ状態、すなわちスレーブ側からマスタにデータ転送する場合にスレーブ側から転送を終了するモードである。

例えば、スレーブ側が可変長の文字列をマスタに返すことを考えてみる。
返される文字列の長さはマスターは知らず、スレーブしか知らない。
このような使用例は沢山あると思うのだが…

マスタ・レシーバのデータ転送中にACK/NOACKを返すのは常にマスタであるので、スレーブ側はNOACKを返すこともできず、ひたすらマスタからの要求に従って結果を返し続けなくてはならない。

一体、どうすれば良いのだろう?

I2Cの仕様書を見てみたが、やっぱりわからない。

あれこれ実験してみたが、そこは省略。

最終的には、
スレーブは、最後のデータを送信した後は0xFFしか返さないように実装。
マスタは、受信で0xFFが返ってきたら、もうデータが無いと判断して、Stop条件で転送を完了するように実装する。

特に0xFFでなくても良いのだが、スレーブが応答しないときもSDAがHiに張り付いて0xFFになるので、これに合わせるのが順当だろう。

なお、この方法では0xFFが特殊な意味に使われてしまうので、バイナリデータ転送では使えない。この場合には、データの最初にデータ長を指定するなどの方法で対処するしかなさそうだ。

いずれにせよ、もっとスマートな方法は無いのだろうか?




| その他 | 09:29 | - | - |
AVRマイコン プログラムでEEPROMが読めても書けなかったのは
AVR Studio環境にてAVRマイコンのプログラミング中、
データシートのサンプルコード(C言語)に従ってEEPROMのデータを書き換えようとしたところ、読み出しは出来るのだが、書き込みが行われない現象が生じた。
実機でもシミュレータでも同じ症状。

原因は・・・

なんてことない。
コンパイラの最適化がオプションが外れていて、
EECRレジスタのEEPMEビットを「1」にセットしてから4クロック以内にEECRレジスタのEEPEビットを「1」にセット
というのが間に合っていなかった。
コンパイラの最適化オプションを設定して解決。
「XXクロック以内」って条件が書かれていたら、アセンブラを確認したほうが良さそうだ。


| その他 | 15:22 | - | - |
PROFILE
Follow
CATEGORIES
LATEST ENTRIES
SEARCH THIS SITE
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
SONY MDR-CD900ST
SONY MDR-CD900ST (JUGEMレビュー »)

普段これで開発しています。
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND