どうも音飛びと時計狂いに関係が……?

投稿日:

 先日、愛用のPC「ASUS TransBook T100 Chi Z3795」とBluetoothレシーバ「SBH50」の音飛びを改善した、とこのブログに書いた。

 ところが、今日、音楽を聞こうとしたら、また音飛びするようになっている。

 得たりや、とばかり、先日と同じようにドライバをインストールし直したのだが、今度は直らない。

 ハテ……とググッてみると、Realtekのオーディオドライバでこうなる場合がある、との記事に行き当たる。

 早速「Realtek High Definition Audio Driver」を探してインストールしてみたが、どうやらこれは外していたようだ。「ASUS TransBook T100 Chi Z3795」の場合、「Realtek I2S Audio Codec」なる別物システムであるようだ。

 いろいろといじくったがどうも直らないし、ネット上にも有力な手掛かりがない。

 そうするうち、ふと、時計が大幅に遅れていることに気付いた。

 このPCは、時計が遅れることが知られている。ネット上でその情報には多く行きあたるが、Q&A掲示板の回答は大抵は半可通の答えで、ハズレである。

 こうなっているときに時計表示を見ると、体感できるくらい秒のティックが遅くなっている。手っ取り早く直すには、完全電源オフから立ち上げると一時的には直る。こうなるのは、スリープモードから復帰後に多い。

 そこで、一度完全電源オフして時計が正常化するのを確認し、それからもとの「音飛び原因探求」にとりかかろうとした。

 そうしたら、音飛びまで直ってしまっていた。

 うーむ、これは一体……?

 これまで、サウンド関係のドライバインストール後は完全電源オフではなく、「再起動」で済ませていたのだ。それが何か関係するのかもしれない。

 何らかの低いレイヤで「割り込み」のようなことが頻繁に起こっていたのではないかな、という感じがする。だが、直ってしまったので原因の探求ができなくなってしまった。

Bluetoothレシーバの音飛びを正常化

投稿日:

 日常ソニーのBluetoothレシーバ「SBH50」を愛用している。素人が音楽を楽しむ分には音質も良く、何より配線がぶらぶらしなくてよい。

 外出中や通勤中などはスマートフォンと組み合わせているが、自宅では愛用のモバイルPC「ASUS TransBook T100 Chi Z3795」と組み合わせ、快適に使用している。複数の機器とペアリングしておけるので、切り替えて使用できるほか、PCとスマホの2台で同時に待ち受けするなどの芸当(マルチポイント)も可能である。

 さて、昨日ごろまで何の支障もなく美しい音色で楽しめていたのだが、ふとダウンロード購入したスピッツの「空も飛べるはず」を聞こうとレシーバを接続したところ、激しい音飛びが生じるようになり、ほとんど聞き取れないまでにおかしくなってしまった。

 これを改善し、正常化させることができた。

 正常化させるにあたってネット情報を渉猟したのだが、効果のある要領についてどこにも書かれておらず、参考になる事項がなかった。そこで、その経過と改善要領を以下に簡単に記し、ネットに放流しておきたい。こうしておくことで、誰か他人様(ひとさま)の役に立つこともあるだろう。

  1. 症状
  2.  前掲PCに接続して音楽を聞こうとしたところ、数日前まで正常だったのに、音が激しく途切れるようになってしまっており、音楽などがまるでノイズのようにしか聞こえず、正常な利用ができなくなった。

     ハンズフリー・ヘッドセットの機能の方は正常であり、音飛びも発生しない。

  3. 処置
  4.  ASUSのサポートホームページの「ドライバーとツール」から、最新のオーディオ・ドライバをダウンロードし、インストールした。ダウンロードしたのは64Bit版の「Realtek Audio Driver(2015/08/13更新)」である。

  5. 結果
  6.  正常化した。

  7. 処置に至るまでの経過
    1. 症状の切り分け
    2.  PCのスピーカーからの音と、PCのイヤホンジャックに直接ヘッドフォンを接続した場合の音はどちらも正常だったので、はじめは「PCのサウンド関連スタック等の障害ではない」と考えた。(しかし、結果から言うとそうではなかった)

       Androidスマートフォンに接続し、使用してみた。正常に音楽を聞くことができたので、Bluetoothレシーバ側の問題ではないと考えられた。

       また、上記は同じ室内、同じ机の上で試したので、WiFi等の電波環境は同一であり、電波の干渉等の問題ではないと考えられた。

       このBluetoothレシーバはスマートフォンのアプリ経由でファームウェアをアップデートするようにできているので、この時についでにファームウェアのバージョンを確認したが、本日現在の最新バージョン「1.3.A.0.2」であった。

    3. 試してみたが効果のなかった処置
      •  PCの再起動
      •  Bluetoothレシーバの電源のON/OFF
      •  Bluetoothレシーバの初期化
      •  PCとBluetoothレシーバの再ペアリング
      •  PCのオーディオ・デバイスのプロパティで、Bluetoothレシーバを「切断」し、しばらくしてから「接続」
      •  PCのオーディオ・デバイスのプロパティで、Bluetoothレシーバを「無効」にし、しばらくしてから「有効」に
      •  デバイスマネージャからBluetoothレシーバのドライバを更新
      •  デバイスマネージャからBluetoothレシーバのドライバを削除し、PCを再起動してドライバを再インストール
      •  デバイスマネージャからBluetoothを使用する他のデバイス(キーボード・マウスその他)のドライバを全部更新

Raspberry Pi 2 Model B に WiFi、AD変換ICでアナログ入力

投稿日:
とりあえず無線LANにする

 Raspberry Pi、線がダラダラつながっているのは面倒くさいから、メインのifをWiFiにしてみたい。たまたま、Raspberry Piと相性がいいと言われるUSBのWiFiアダプタ「PLANEX GW-USNano2」というのをかなり前から持っている。

 USBポートにとりあえずこれを挿入し、

# lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 2019:ab2a PLANEX GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS]

……もう、サクッとプラグアンドプレイの一発認識である。

# ifconfig
eth0      Link encap:イーサネット  ハードウェアアドレス b8:27:eb:45:1d:d0
          inetアドレス:192.168.1.105 ブロードキャスト:192.168.1.255  マスク:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:498 エラー:0 損失:1 オーバラン:0 フレーム:0
          TXパケット:253 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:46665 (45.5 KiB)  TXバイト:34011 (33.2 KiB)

lo        Link encap:ローカルループバック
          inetアドレス:127.0.0.1 マスク:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  メトリック:1
          RXパケット:8 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:8 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:0
          RXバイト:1104 (1.0 KiB)  TXバイト:1104 (1.0 KiB)

wlan0     Link encap:イーサネット  ハードウェアアドレス 00:22:cf:97:fe:b9
          inetアドレス:192.168.1.107 ブロードキャスト:192.168.1.255  マスク:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:506 エラー:0 損失:169 オーバラン:0 フレーム:0
          TXパケット:25 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000
          RXバイト:128714 (125.6 KiB)  TXバイト:4541 (4.4 KiB)

 これも、もう、イッパツ。

 で、# shutdown -i0 -g0 -y、LANケーブル抜いて電源を入れなおす。

 サクッとつながる。ケーブルがだらだらつながっていたのが減って、これはとてもいいなあ。

USBのWiFiアダプタが快調に作動している様子
IMG_3308

アナログ入力をしてみる

 さて、今度はいろいろといじってみよう。

 Raspberry PiとArduinoにはいろいろと違いがある。その違い認識は世間ではもうとうの昔に確定済みであるようだが、私はその無視できない一つが「アナログ入力のあるなしではないだろうか?」と思い至っている。

 Arduinoはシンプルで扱いやすいにもかかわらず、10ビットのアナログ入力が6個もあり、これは意外と使い応えがある。抵抗やポテンショメータ、サーミスタ、CDSセル、音声など、実にいろいろなものをつなぐことができるのだ。

 だが、Raspberry Piにはアナログ入力は、ない。

 アナログ入力をしたければ、手段の一つに「Arduinoをつなぐ」というのがある。Arduinoを持っているなら、これは良い手段だが、なんだか無駄が大きい。

 もう一つが、「A/D変換器をつなぐ」ということだ。A/D変換IC、つまり「ADC」は、百何十円~数百円だから安い。合理的である。

 これについて解説しておられるサイトはたくさんある。それを参考にさせていただき、早速秋葉原へ行って2種類ばかりICを買い込む。

 これは、マイクロチップ・テクノロジー社製の「MCP3008-I/P」。8チャンネル10ビット、千石電商で320円。

MCP3008-I/P
IMG_3309

 コッチは、同じくマイクロチップ・テクノロジー社の「MCP3208-CI/P」。こちらも8チャンネルだが、幅は12ビット。秋月電子でソケット付き、データシート付きで320円。

MCP3208-CI/P
IMG_3310

 ついでにこの前壊したTLC5940NTも二つ買い込む。これも390円。

TLC5940NT
IMG_3311

 で、まずはMCP3208から試してみよう。

 Raspberry PiとICは、SPI通信でつなぐ。そのため、まず、Raspberry PiでSPI通信を行う要領を知る必要がある。

 Raspberry Piの場合は、SPIのモジュールをインストールしたり、ブラックリストから外すなどの着意が必要であったようだが、Raspberry Pi 2 の場合は、どうやらそのような操作は必要がなく、「# raspi-config」でAdvancedの中からSPIを選び、enableにすればよい。

 lsmodで確認し、次のように「spi_bcm2835」というモジュールが入っていればSPIが使える。

$ lsmod
Module                  Size  Used by
cfg80211              420690  0
rfkill                 16659  1 cfg80211
snd_bcm2835            19769  0
snd_pcm                74825  1 snd_bcm2835
snd_seq                53561  0
snd_seq_device          3650  1 snd_seq
snd_timer              18157  2 snd_pcm,snd_seq
snd                    52116  5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
8192cu                528485  0
spi_bcm2835             7100  0
i2c_bcm2708             5014  0
uio_pdrv_genirq         2966  0
uio                     8235  1 uio_pdrv_genirq

 さっそくブレッドボードにMCP3208を配置し宮城大学のサイトの記事にあるコードを使わせてもらったのだが、これがそのままでは動かず、ハマッた、ハマッた……。

ブレッドボードの状況
IMG_3312

 何か、Raspberry PiとRaspberry Pi 2 で、ioctrlに渡すデータ長に違いでもあるらしく、かなり試行錯誤した末、このようになった。

 宮城大学のサイトにあった元のコード(“raspSPI.cpp”内)

//  sendRecN: Nバイトデータの送信と受信(2048バイトまで)
void SPI::sendRecN (unsigned char *send, unsigned char *rec, int n)
{
    //  setup a block
    struct spi_ioc_transfer tr[1];
    tr[0].tx_buf = (unsigned int) send;
    tr[0].rx_buf = (unsigned int) rec;
    tr[0].len    = n;
    tr[0].speed_hz      = clock;
    tr[0].delay_usecs   = SPI_DELAY;
    tr[0].bits_per_word = SPI_BITS;
    tr[0].cs_change     = 0;
    //  send this byte
    int ret = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
    if (ret < 0) {
        printf("error: cannot send spi message (SPI::sendRecN)\n");
        exit(-1);
    }
}

 Raspberry Pi model Bで動くように少し変更したコード(tr[]の個数と、tr[0]に渡す値のキャストを「int」から「unsigned long」に変更している)

//  sendRecN: Nバイトデータの送信と受信(2048バイトまで)
void SPI::sendRecN (unsigned char *send, unsigned char *rec, int n)
{
    //  setup a block
    struct spi_ioc_transfer tr[3];
    tr[0].tx_buf = (unsigned long) send;
    tr[0].rx_buf = (unsigned long) rec;
    tr[0].len    = n;
    tr[0].speed_hz      = clock;
    tr[0].delay_usecs   = SPI_DELAY;
    tr[0].bits_per_word = SPI_BITS;
    tr[0].cs_change     = 0;
    //  send this byte
    int ret = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
    if (ret < 0) {
        printf("error: cannot send spi message (SPI::sendRecN)\n");
        exit(-1);
    }
}

(作動させた画面の様子)

  1132   867   827   829   833   838   877  2670
  1090   829   787   787   792   797   845  2668
  1028   768   725   721   724   732   796  2671
   929   678   631   623   625   636   737  2669
   791   534   471   444   429   435   572  2667
   408   172    94    54    29    53   281  2668
    84     0     0     0     0     0   111  2666
     0     0     0     0     0     0    20  2671
     0     0     0     0     0     0     0  2670
     0     0     0     0     0     0     0  2668
    19    29    34    39    41    36    27  2670
    87    93   101   110   114   107    81  2670
   173   173   183   195   201   186   146  2671
   274   276   300   327   347   339   276  2667
   614   609   650   692   727   698   552  2668
   948   901   907   902   911   916   741  2672
  1102   916   878   886   894   899   854  2670
  1160   888   865   868   873   878   913  2671
  1137   872   832   833   838   843   903  2665
  1093   830   788   787   792   796   869  2668
  1027   767   723   717   721   727   815  2669
   938   685   638   631   632   643   748  2669
   821   566   504   482   467   474   603  2665
   447   206   128    89    62    85   303  2669
   107     0     0     0     0     0   123  2670
     0     0     0     0     0     0    32  2669
     0     0     0     0     0     0     0  2667
     0     0     0     0     0     0     0  2670
    14    23    29    34    37    32    29  2669
    81    86    94   102   104    98    80  2665
   170   167   177   186   191   174   141  2671
   267   267   290   314   333   323   263  2668
   598   593   631   669   702   672   536  2670
   936   888   908   904   913   914   723  2669
  1098   917   876   888   894   899   840  2668
  1157   895   864   869   875   878   904  2668
  1138   873   834   835   841   844   902  2667

 7番ピンにポテンショメータをつなぎ、残りのピンは解放してあるので、乱雑な値が出ている。