denshikobo’s blog

PICプログラミングやPCの操作で感じた日々の由無し事を綴ります

Oscilogiの連続計測試験に失敗した

(2016.09.07)
9月4日にOscilogiのknown bugが無くなり、反復計測機能の組み込みを終え、最終テストに臨みました。

データ・ロガー・モードで反復計測します。データが一杯になったら計測値をファイルに書き出し、再びロガー・モードで計測を続けると言う動作を延々と繰り返します。24時間以上連続計測出来れば、最終テストに合格!ということだったんですが・・・

凡そ1時間ほど経過したところでOsci_logi_Console(JAVAプログラム)がダウンしました。orz

一体何が起きたのでしょう?

計測プログラムのあちこちにデバッグ文を書き込んで、動作を追いかけました。

そして、読み取る計測データのサイズがi2c_readの最大サイズ(1024バイト)を超える場合があることが判りました。データ・ロガー・モードでは高々数10バイトだったので、受信データ・サイズのチェックを入れていませんでした。
(将来的にはbcmlib_for_javaの方でチェックする予定です)

取りあえず、受信データ・サイズを1024バイト以下にして、再度連続計測試験に臨んだのですが・・・

今度は計測コマンドの送信でI2Cエラーを起こして止まりました。orz

読み取る計測データのサイズ異常の原因は何か?
I2Cエラーの原因は何か?

さらに、詳細なデータを取るためにデバッグ文を追加して、テストに挑みます。

12時からテストを始めて、1時間経過しました。今の所、ログ・ファイルには異常は記録されていません。

さて、このあとどうなるのか?

ドキドキ

---------------------------------------------------------

追記(2016.09.07)

14時前に、データ受信でI2Cエラーを起こして止まりました。
I2Cエラーを起こしたときにI2Cをリスタートする機能を組み込んで試験を再開します。
ただ今の記録は1時間52分です。

Oscilogiのデータ・ロガー・モードが動き出した

(2016.08.30)
読み取りデータを指定するコマンドに読み取り開始位置を追加して、部分データの読み取りはすんなり実現しました。

一画面分のデータ表示が毎秒1回可能(Raspi2Bで700mS掛かる)ということが判ったので、部分データの表示は止めて従来の表示のままで行く(画面左端から全部書き直す)ことにしました。

データ・バッファが一杯になった後も計測を継続して、データ・バッファを上書きする部分(従来のOscilogiには無かった処理)で、暫く手こずりましたがなんとか不具合箇所を見つけました。

f:id:denshikobo:20160830173440p:plain

1mHzサンプリングだと4CH計測でも20日を超える計測が可能になります。
充電器とバッテリーの動作テストには十分な機能が実現したんですが・・・


自分が必要としている最低限の機能が実現すると、急速に開発マインドが低下していくのを感じます。(^_^;)

しかし今回は、何とか完成を目指して開発を続けようと思います。
良い加減Oscilogi410の開発はお仕舞いにして、Oscilogi1616(既に基板はできている)、Oscilogi32EF(10MSPSに挑む)に取りかからなければなりません。

 

敢えてこの場で宣言して、自分を追い込む作戦です。¥(^_^)

 

Oscilogiの新たな課題に取り組むことにした

(2016.08.25)
Oscilogiの開発は『自分が必要となった機能を実現する』という方針で進めてきました。

今やりたいのは、(これ↓)の動作テストです。
https://www.amazon.co.jp/gp/product/B010FJTEFC/ref=oh_aui_detailpage_o03_s00?ie=UTF8&psc=1

充電器とバッテリー電圧をモニタしながら、18650リチウムバッテリーを充放電させて、その挙動を調べる計画です。Oscilogiにデータ・ロガー モードを設けて、数時間に及ぶ連続計測を行えるようにしようと考えました。

計測時間の設定単位にmHz(現状はHzとkHzの二つ)を加えれば、データ・ロガーになると簡単に考えていたのですが・・・

Osci_Logi_Console(JAVAプログラム)に設定単位を追加するのは簡単な作業でした。
PICの計測は1秒単位に行い、メモリに格納するときにデータを間引くという方法で、長時間の計測を実現しました。動かして初めて大きな問題に気付きました。

Oscilogiは計測データをPICに蓄え、計測終了時にそれをOsci_Logi_Consoleが読み取って、グラフ表示しています。つまり計測終了までデータ表示は行いません。計測時間が短ければ、何も問題なかったのですが、数時間に及ぶ計測の場合、途中経過が判らないということでは困ります。

そこで、計測中にOsci_Logi_Consoleがデータを読み取ってグラフ表示する機能を組み込むことにしました。

開発手順はこんな感じです
(1)データ・ロガー・モード設定ボタン追加
(2)データ・ロガー計測中のI2Cコマンド送受
(3)DMAポインタの読み取り
(4)計測途中に部分データ読み取り
(5)部分データの表示

『設定ボタン追加』といっても、サンプリング・レートが20Hz以上では無効にするとか、細かなロジックの組み込みが必要です。(3)まで済んで、いよいよ計測中のデータ読み取りと部分データの表示に取り組みます。

何か、とっても楽しい~

 

Oscilogiの大きな課題が解決した

(2016.08.21)
そこそこ動いて、それなりに使えているOscilogi410なんですが、実は大きな課題を抱えていました。

bcmlib_for_javaは1回に送受できるデータ量に1024バイトの制限があります。Oscilogi410の計測データは(オシロとロジアナ合わせて)24kバイトなので、24回に分けて計測データを取り込んでいます。

しかし、1024バイトのデータ読み出しに対して、何故か『PIC側のポインタが1025進んでしまう』という現象を生じていました。やむを得ず、1024バイト読み取る度にOsci_logi_Console(JAVAプログラム)からPICのポインタを一つ戻すコマンドを送って、不具合を回避する処置を講じていたのです。何が悪いのか判らず、少しだけBCM2835ライブラリを疑ったりしていました(ゴメン Mike )。

動き出したOscilogi410を使って、I2Cの動作を調べてみることにしました。
テスト・プログラムはこんな感じです。

(データ受信コマンドを送り、10バイト読み出す)
public class I2c_test {
    public static void main(String args) {
        String send_string = "RCV 0";
        byte
receive_buff = new byte[16];
        
        bcm2835.bi_init(args[0]);
        bcm2835.i2c_begin();
        bcm2835.i2c_setSlaveAddress( (byte)0x31 );
        bcm2835.i2c_set_baudrate( 100000 );
        bcm2835.ope_sync();
        byte ret = bcm2835.i2c_write( send_string, send_string.length() );
        ret = bcm2835.i2c_read( receive_buff, 10 );
        if( ret == 0 )try {
         String rec;
           rec = new String( receive_buff , "UTF-8");
            System.out.print("I2C receive="+rec +"\n");
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(I2c.class.getName()).log(Level.SEVERE, null, ex);
            rec = "";
        }
        System.out.print("i2c_read ="+(int)ret+"\n");
        bcm2835.i2c_end();
        bcm2835.bi_close();
    }
}

計測したI2Cの信号は正しく、5バイト送信し10バイト受信する様子を示していました。
つまりBCM2835ライブラリは正しく動作しているのです。(疑ってゴメン Mike )

自分で書いたPIC側のI2Cドライバの動作をdebug_dumpで調べ・・・

 void __ISR(_I2C_2_VECTOR, ipl1AUTO) _IntHandlerDrvI2CInstance0(void)
{
    static unsigned char i2c_single_buff;
    if( !PLIB_I2C_SlaveReadIsRequested(I2C_ID_2) )
    {
       if( PLIB_I2C_SlaveAddressIsDetected(I2C_ID_2) )
       {
         DRV_I2C0_SetUpByteRead();
         DRV_I2C0_ByteRead();
       }
       else
       {
         DRV_I2C0_SetUpByteRead();
          i2c_single_buff = DRV_I2C0_ByteRead();
          if( i2c_single_buff == 'B')
          {
              break_flag = FLAG_ON;
          }
          put_receive_buff(i2c_single_buff);
       }
       status_from_master();
    }
    else if ( PLIB_I2C_SlaveAddressIsDetected(I2C_ID_2) )
    {
        DRV_I2C0_SetUpByteRead();
        DRV_I2C0_ByteRead();
        DRV_I2C0_ByteWrite( get_send_data() );
        PLIB_I2C_SlaveClockRelease(I2C_ID_2);
        status_to_master();
    }
    else
    {
        if( I2C2STATbits.ACKSTAT == 0 )<==これを追加した
        {
          DRV_I2C0_ByteWrite(get_send_data());
          PLIB_I2C_SlaveClockRelease(I2C_ID_2);
          status_to_master();
        }
    }
    PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_I2C_2_SLAVE);
    PLIB_INT_SourceFlagClear(INT_ID_0, INT_SOURCE_I2C_2_ERROR);
}

1バイト送信した後のI2C割込で、I2C2STATbits.ACKSTATが1になったときは次のデータは読み出さない、という処理に替えてようやくデータポインタが一つ余計に進んでしまうという課題が解決しました。

やれやれ

Oscilogi on Raspi3問題が解決した

(2016.08.16)
Mike McCauleyから”bcm2835_i2c_setClockDivider(uint16_t divider) 関数を使え”と言われ困っていました。つまり、core_freqの値に合わせてClockDivederの値を替えるしかない、ということです。

そのcore_freqのdefault値がRaspi2では250MHz、Raspi3では400MHzというのが今回の不具合の原因です。

--------------------------------
BCM2835ライブラリはcore_freq=250MHzを基準にbaudrateを設定している。400/250=1.6なので、Raspi2でbaudrate=100kHzのClockDivider設定を行うとRaspi3では1.6倍の160kHzになってしまう。
--------------------------------

core_freqの値さえ判れば何とかなりそうなのですが、その値がどこに記されているのか、調べた限りでは見つかりませんでした。

その代わり、動作しているRaspiのModelが/proc/device-tree/modelに記されていることがわかりました。
cat /proc/device-tree/model
Raspi2B==>Raspberry Pi 2 Model B Rev. 1.1
Raspi3B==>Raspberry Pi 3 Model B Rev. 1.2

これを読み取って、core_freqの値を推定して、ClockDivider設定を行う・・・
なんてことを考えたのですが、もっと簡単な方法が見つかりました。

Raspi3Bの/boot/config.txtに”core_freq=250”を追記します。

この設定が他にどのような影響を与えるか判りませんが、OscilogiはI2Cで問題を起こさず、Raspi3上で動作するようになりました。

まずは、目出度し目出度し

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

追記

core_freqの値を調べる方法が判りました。

vcgencmd measure_clock core

これです。

measure_clockって、どうやって計っているんだろう?

他にもこんなパラメータが指定出来るらしい

arm h264 isp v3d uart pwm emmc pixel vec hdmi dpi

 

Mike McCauleyから返事が来た

(2016.08.15)
i2c_set_baudrate関数の件でBCM2835のGoogleグループ(ここです)に質問を投げてみました。(spelling errorは毎度のことなので諦めています)

するとMike McCauley(BCM2835ライブラリの作者)から返事が・・・
Hi,
still unable to investigate this since my scope failed.
A few more days until new one arrives.

Mike McCauley

どうやら彼のオシロスコープが壊れているようです。

『私のOscilogi410を提供できなくて残念』と返しておきました。

少しは彼の役に立てると良いなぁ~

Raspi-3でオシロジが動いた(その2)

(2016.08.11)
Raspi-3でオシロジが動かなかった原因が判明しました。

Raspi2BのオシロジでRaspi3のSDAとSCLをモニタして、baudrateがおかしい(100kHzの設定に対して160kHzで動作している)ことに気付きました。PIC32mxのbaudrateを100kHzに設定しているので、SCLが160kHzでは正しく送受できなかったものと推察されます。

sudo cat /sys/momdule/i2c_bcm2708/baudrateを調べたところ

(2016.08.15 誤り訂正)

sudo cat /sys/module/i2c_bcm2708/parameters/baudrateを調べたところ
Raspi2 ==>100000
Raspi3 ==>0 ????

Raspi2は正しい値(100kHz)を示しますが、Raspi3は何故か0です。

 /boot/config.txtにdtparam=i2c_arm_baudrate=50000を追記しても
Raspi2==>50000
Raspi3==>0 !!!!

やっぱり、Raspi3は0です。

Osci_logi_console(JAVAプログラム)で使っているi2c_set_baudrate関数の引数を100000から50000に変更してみると・・・
ビンゴ~

Raspi2BのOscilogiでモニタしているSCLが80kHzになりました。
そしてようやく、Raspi3でオシロジが動きました。

f:id:denshikobo:20160811152724p:plain

パチパチパチ~

JAVAからbcm2835ライブラリを呼び出しているのですが、bcm2835ライブラリのi2c_set_baudrate関数がRaspi2とRaspi3のクロックレートの違いを上手く吸収できていないために生じた不具合のようです。

/boot/config.txtでI2Cのbaudrateが設定出来ない件は、当面ペンディングにします。

気になるのは、むき出しの状態でvcgencmd measure_tempの指示値が70℃を超えていることです。Raspi3でオシロジを使うためにはcooling fanが必要かもしれません。