アクセスカウンタ

プロフィール

ブログ名
KazHatブログ
ブログ紹介
Palmwareを気の向くまま作っています。
このブログでは、最近購入したSheevaPlug+について書いていこうと思います。Linuxも初めての初心者に使えるかどうかわかりませんが、先人の知恵を借りながらチャレンジしていきます。
PICはじめました。最近は、ロビのことしか書いていませんね。
zoom RSS

Android開発環境

2017/06/24 00:48

Palmの時と同様に、Androidを使っていくうちに自分で、アプリを作ってみたくなってきました。

定番らしいAndroid Studioを使おうと思います。安定最新版、2.3.3をダウンロードして、実行します。

 

インストールが完了したら、起動してみます。

Welcome to Android Studioというタイトルのウインドウが開きました。

image

上記キャプチャは、クリックしてしてしまったので、メッセージがある表示になっていませんが、ウインドウの右下に並んでいるメニューの一番左のEventsの所に印が出ていて、見てみると、バージョンアップのお知らせでした。

 

それに従い、アップデートしてみました。すると、以下の画面が出ました。

image

特に無視する意味もありませんから、Update Nowボタンを押して更新しました。

これで、インストールできましたので、まずは簡単なプログラムを書いてみようと思います。 いわゆるHello  Worldを表示するようなものを作るのが、最初の目標だと思っています。

とは言え、初めてAndroid Studioを使いますし、おまけにJavaもプログラムしたことがなく、最近初心向けのWebページで勉強し始めたばかりという状況ですから、チュートリアルが必要です。

私は、Android プロジェクトの作成を参考に進めてみました。


最初に出てきたWelcome to Android Studioというタイトルのウインドウの中のStart a new Android Studio projectを押して開始。そのあとは、上記のページに記載のやり方に従っていけば問題ありません。単に記載されている通りに進めている状態なので、まだ自分自身で何をしているかもはっきりとはわかっていません。

 

でも手順通りにすると、いわゆるHello Worldができあがるらしいです。

 

ほぼ、ボタンを押していただけですけど、ソースプログラムが作成され、自動的に開かれました。

中身をみても、Hello Worldの文字もなく、何ができ上ったのかわからない状態です。中身の理解より、まず何ができているのか確認するため、Buildしてみました。

初めてコンパイルしたからか、私のPCが非力だからか、シンプルなプログラムとしては、結構時間がかかりました。

 

でも、問題なく、コンパイルはできたようです。

 

次に、どうやって実行するか考えようと思っていたら、充電を兼ねてUSBケーブルでHuawei P9liteがPCにつながっていたおかげで、エミュレータか実機のどちらで実行するのかというようなメッセージが書かれたポップアップウインドウが出ました。エミュレータ上で実行するのがよいかなとも思いましたが、エミュレータをインストールするとかの面倒さも考えて、実機での実行を了承しました。

しばらくすると、実機のP9liteの画面が変わり、Hello World!と表示されました。Palmと違ってHot Syncということもせずに、PCからP9liteへインストールが行われ、実行もされるとは、便利ですね。

 

実行した時に表示された画面が以下となります。

image

画面中央に、小さめのフォントでHello Worldと表示されました。

 

このアプリは、画面にメッセージを表示するだけの機能しかありませんので、特にボタンを押すとかではなく、Androidの標準機能で、ホーム画面に戻すしかありません。ホーム画面で探してみると、My first Appという名称で、Android君のアイコンのアプリがインストールされていました。

image

 

上述の通り、プログラムは、作れたものの、1行も、ソースコードを自分で書いていないので、何も理解していない状態です。それでも、自分でコンパイルしたアプリができ上がりました。まったく苦労もしていないので、コンパイルできて、プログラムがスマホ上で動いても、それほどの感慨も感動もないのが残念ですけど、ここまで簡単にプログラムが作れるというハードルの低さにびっくりです。という感じで、プログラム開発環境が整いました。

 

少し落ち着いて、Android Studioを眺めてみます。

javaのソースコード自体には、Hello Worldは書かれていないみたいです。

よく画面をみていたら、ソースコードを表示している後ろのタブに、activity_main.xmlという名称のファイルが開かれていました。

そのタブをクリックしてみると、リソースエディタみたいな画面が表示されました。ここでHello Worldを表示するようにしているようです。まだ、説明を読んだわけではありませんが、適当にクリックして、表示位置などの設定が変更できそうなことがわかりました。Hello Worldの文字を適当に変更して、再コンパイルすると、ちゃんとアプリに反映されることが確認できました。

画面構成をリアルタイムにPC画面上で確認しながら、変更できるので、自分のアプリを作るときは、便利そうです。

 

文字の大きさを変えようと思いましたが、文字の枠を広げたりしてみましたが、ダメでした。ネットで調べてみたら、サイズを変更する記述を加えればよいということがわかりました。

"Hello World"が書かれているTextViewの中に、

android:textSize="30sp"

といった記述を追加したら良いみたいです。spという単位は、スケール非依存ピクセルという単位ということ。これは、画面の解像度とユーザのフォントサイズの両方を加味して表示されるもので、フォントのサイズとして推奨とありました。単純には、ユーザの設定に合わせてサイズが変更されるサイズだと理解しました。ほかにdpという密度非依存ピクセルという、ディスプレイの解像度に応じた単位というものもありました。

 

サイズを変更してコンパイルしてみたら、大きくなって見栄えのする感じになりました。

先ほどのものと比べてみてください。「です」というのもちょっと加えてみました。

image

 

まだまだ、色々と勉強しないとアプリの開発はおぼつかないと思いますが、Palmware開発した経験を生かして、挑戦したいと思っているところです。

 

これから、どんなアプリを作ろうとしているのかは、まだ秘密にしておきます。少し形にできてからご報告したいと思います。多分、数週間は優に掛かってしまうと思われますし、本当に、次の報告ができるのかわかりませんので。

 

とりあえず、今回はここまで。

記事へブログ気持玉 / トラックバック / コメント


Windows10 Creators Updateのその後

2017/06/20 22:11

Open Live Writerがおかしい

 

先日Windows 10 Creators Updateを行ってから、このブログを書くために使用しているOpen Live Writerが落ちまくり、全然使いものにならなくなってしまいました。私の場合、何文字か入力して、その後に2文字熟語の漢字変換をしようとすると、固まってしまい、エラーメッセージが出て、落ちるという感じでした。

そのため、全然、物書きが進みません。

 

ネットで調べると同様の症状の方がちらほら見受けれました。一部の方の対処方法である、スペルチェックを無効にするというのを試してみましたが、効果なし。

 

Open Live Writerが5月にバージョンアップしてからおかしいのではないかという話とか、私と同様に、Creators Updateをしてからおかしくなっている方とかがいるようです。

 

バージョンダウンすると良いという話もありましたが、古いバージョンをダウンロードしてインストールするといったことはできず、ソースコードをコンパイルして、インストールしないといけないという感じで、簡単にできそうもないので、対処しようがありません。

 

で、今このブログはどうしているのかというと、昔のWindows Live Writerを起動して書いています。幸い、まだアンインストールされていなかったようで、まだ、PC内に残っていました。

起動してみると、設定環境とか履歴情報とかは、Open Live Writerと共有しているみたいで、直近の履歴も残った状態で、すぐに何も問題なくWindows Live Writerを使うことができました。

 

こちらは、Creators Update上でも、異常終了もなく、まったくストレスフリーですね。何か作業をしていて途中で止まるなど、非常に非効率で、特にものを書いている途中で消えてしまうと、再度同じことを書かなければならないわけですし、かといって、まったく同じ文章を覚えているわけでもないので、余計なストレスを感じるわけです。

しばらくは、Windows Live Writerを使っていこうと思っています。Open Live Writerがバージョンアップして直ってくれるのがよいのですけど、日本語にかかわっているような感じでもあるので、問題に気付いて、直して頂けるのか? 当該ページには、ブログもありますが、コメントを書けるようになってもおらず、どうしたらよいのかわかりません。まあ、気長に待ちましょう。それまでは、Windows Live Writerに頼りたいと思います。

 

では、また。

記事へブログ気持玉 / トラックバック / コメント


Windows10 Creators updateがやってきた

2017/06/16 22:25

確か4月ごろにリリースされたCreators updateがようやく私のPCにもやってきました。

その少し前に設定を更新するようなメッセージが出て、設定を行ったら、まもなくアップデートされますと言ったようなメッセージが出ました。それから数日経過したら、ようやくインストールできるようになりました。

いつものように、最終的に再起動で、更新が完了するわけですけど、この後、問題が発生しました。

その内容を少しご紹介します。

  1. Windows 10のアップデートをしたら、コントロールキーとcapslock キーの入れ替えがキャンセルされれしまいました。その再設定が必要でした。
    しかし、Xmouseの設定の方は、そのまま引き継がれて問題ありませんでした。
  2. SheevaPlug+からの アクセスが できなくなりました。
    共有設定がおかしくなったのだろうと思って、設定を確認しましたが、問題ありません。
    どうしたらよいかなと思ってしばらく考えていたのですけど、前回も同様な問題が起こったと思い出し、検索をしたところ、2016/8/11の記事にSheevaPlug+からWindows10のファイルアクセスというものを見つけました。
    ネットワークと共有センターの共有の詳細設定が、元に戻ってしまったようでした。
    パブリックフォルダーの共有の所と、パスワード保護共有の所を変更にしたら、SheevaPlug+からアクセスができるようになりました。
    余談ですけど、この問題が発生して、SheevaPlug+をいじっていたら、なぜかSheevaに接続しているUSBメモリにアクセスできません。マウントしたままにしていたはずですが、USBメモリのデバイスが/dev/sda1から、/dev/sdb1に変わってしまっていたようです。いつ変わったのかわかりませんが、再度mountすることで問題なくなりました。

以上、2つ問題が発生しましたが、すべて解決し、無事Windows10のバージョン1703となりました。

少し使っていたら、文字入力時に、ときどき画面中央に「あ」とか「A」とか表示されるようになっていました。非常にうっとうしいのですが、その表示を消せないか調べてみたらありました。
MS-IMEのプロパティで、IME入力モード切替の通知の所のチェックを外すだけでした。

image
   

簡単ですが、覚書として。

    記事へブログ気持玉 / トラックバック / コメント


    Palmの予定表データをAndroidへ (つづき)

    2017/06/12 22:37

    Palmのpdbファイルをicsファイルに変換するperlプログラムです。実行にはp5-Palmのライブラリが必要です。

    #!/usr/bin/perl


    # Convert Datebook.pdb to iCalendar
    # Copyleft 2006 Yoshizumi Endo <y-endo@ceres.dti.ne.jp>
    # Modified by K.Ohno 2017/6/7 LOCATION出力中止


    use Palm::PDB;
    use Palm::Datebook;
    use Encode qw/ from_to /;


    my $default_clss = "PRIVATE";
    my $private_disp = 1; # you can out put private records (=1) or out put public records only (=0).
    my $location_delimiter =" "; # delimiter between summary & location
    my $codeset = "utf8"; # output codeset


    my $dbfile = "$ENV{PWD}/DatebookDB.pdb";
    my $icsfile ="$ENV{PWD}/calendar.ics";


    my $data_server = "evolution-data-server-1.4";


    ## main


    my @wday_s = ( "", "DAILY", "WEEKLY", "MONTHLY", "MONTHLY", "YEARLY" );
    my @sday = ( "SU", "MO", "TU", "WE", "TH", "FR", "SA" );


    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
        = gmtime(time);
    my $gmt = sprintf("%04d%02d%02dT%02d%02d%02dZ",
                      $year + 1900, $mon +1, $mday, $hour, $min, $sec);


    my $pdb = new Palm::PDB;
    $pdb->Load($dbfile) || die "Can't open: $dbfile!\n";
    my @categories = @{$pdb->{appinfo}{categories}}; # extract each category names


    open(ICS, "> $icsfile") || die "Can't open: $icsfile!\n";
    select(ICS);


    print "BEGIN:VCALENDAR\nVERSION:2.0\n";
    print "PRODID:-//Yoshizumi Endo//NONSGML ptodo2ical.pl//EN\n";


    my $i=0;


    foreach $record (@{$pdb->{records}}) {


        if (!($record->{"attributes"}{"private"} == 1 && $private_disp == 0)) {


            print "BEGIN:VEVENT\n";         
            print "UID:ptodo2ical-$gmt-$record->{id}-$ENV{USER}\@$ENV{HOST}\n";
            print "DTSTAMP:$gmt\n";


    # Summary & Location


            my $summary = $record->{description};
            from_to($summary, "shiftjis", $codeset);

            if ($summary eq "") {
                 $summary = "Error: No summary data!";
            }

            $summary =~ s/\n//g;


    # my @tmp = split($location_delimiter, $summary);
    # $tmp[0] =~ s/ *$//;
    # print "SUMMARY:$tmp[0]\n";
             print "SUMMARY:$summary\n";


    # if ($tmp[1] ne "") {
    # print "LOCATION:$tmp[1]\n";
    # }


    # Class


    # if ($record->{"attributes"}{"private"} == 1) {
    # $class = "CONFIDENTIAL";
    # } else {
    # $class = $default_clss;
    # }
    # print "CLASS:$class\n";


    # Description


            if ($record->{note} ne "") {
                $description = $record->{note};
                from_to($description, "shiftjis", $codeset);
                my @tmp = split('\n', $description);
    #            print "LOCATION:$tmp[0]\n";
                $description =~ s/\n/\\n/g;
                print "DESCRIPTION:$description\n";
            }


    # Date & Time


            if ($record->{"start_hour"} != 255) {
                 printf ("DTSTART:%04d%02d%02dT%02d%02d%02D\n",
                         $record->{"year"}, $record->{"month"},$record->{"day"},
                        $record->{"start_hour"}, $record->{"start_minute"});
                printf ("DTEND:%04d%02d%02dT%02d%02d%02D\n",
                        $record->{"year"}, $record->{"month"},$record->{"day"},
                        $record->{"end_hour"}, $record->{"end_minute"});
            } else {
                printf ("DTSTART;VALUE=DATE:%04d%02d%02d\n",
                        $record->{"year"}, $record->{"month"},$record->{"day"});
                print "TRANSP:TRANSPARENT\n"
            }


            if ($record->{repeat}{type} != 0) {
                print "RRULE:FREQ=$wday_s[$record->{repeat}{type}]";


    # 2: weekly event
                if ($record->{repeat}{type} == 2) {
                    print ";BYDAY=";
                     my $comma = 0;

                    for (my $c = 0; $c < 7; $c++) {
                        if ($record->{repeat}{repeat_days}[$c] ==1) {
                            if ($comma == 1) {
                                 print ",";
                            }
                             print "$sday[$c]"; $comma = 1;
                        }
                     }
                }


    # 3: monthly by day
                if ($record->{repeat}{type} == 3) {
                    my $weeknum = $record->{repeat}{weeknum}+1;
                    print ";BYDAY=$weeknum$sday[$record->{repeat}{daynum}]";
                }


    # 4: monthly by date
                if ($record->{repeat}{type} == 4) {
                     print ";BYMONTHDAY=$record->{'day'}";
                }


    # repeat end date
                if ($record->{repeat}{end_year} != 0) {
                    printf (";UNTIL=%04d%02d%02d",
                             $record->{repeat}{end_year},
                            $record->{repeat}{end_month},
                            $record->{repeat}{end_day});
                }


    # repeat frequency
                if ($record->{repeat}{frequency} > 1){
                    print ";INTERVAL=$record->{repeat}{frequency}";
                }
                print "\n";


    # exceptions
                if ( @{$record->{exceptions}} > 0) {
                    print "EXDATE;VALUE=DATE:";
                     for (my $c = 0; $c < @{$record->{exceptions}}; $c++) {
                         if ($c != 0) {
                            print ",";
                        }
                        printf ("%4d%02d%02d",
                                $record->{exceptions}[$c][2],
                                 $record->{exceptions}[$c][1],
                                 $record->{exceptions}[$c][0]);
                     }
                    print "\n";
                }
            }


            print "END:VEVENT\n";
            $i++;
        }
    }


    print "END:VCALENDAR\n";


    # exec ("killall -HUP $data_server");

    では、また。

    記事へブログ気持玉 / トラックバック / コメント


    Palmの予定表データをAndroidへ

    2017/06/12 22:36

    Palmデータの移行

    移行しなければならない残る3つのデータですけど、アドレス帳は、メモ帳と同様にcsvファイルに書き出す機能があるので、どうにでもなりそうです。それに、あまりこのアドレス帳は使っていなかったですし、件数も約200件とそれほど数も多くないので、手を掛ける必要もなさそうです。


    2つ目のToDoは、export形式に簡単に処理ができるcsvなどを選択できないようなので、大変そうですけど、件数をみたら、69件と多くなく、手動でも何とかなりそうな範囲かと思いました。まあ、それでも結構面倒だとは思いますが、データベースの構造を調べたり、プログラムを組むよりは、ましかなと思っています。


    予定表のデータ

    そうすると、最後に残るデータは予定表になります。これは、10年以上にわたる個人史でもあるので、件数は、よくわかりませんが、結構な量だと推定しています。PalmDesktopで対応しているdbaデータのexport機能でファイルを出力してみたら、1MBくらいのサイズになりました。1件どのくらいの容量を使っているかわかりませんけど、コメントを追加した予定は多くはないという記憶なので、1KBも必要もないでしょうから、1000件は優に超えた件数になると思われます。


    色々やっているうちに、Palm上でメニューからApp⇒Info...というのがあったことを思い出しました。そうして、予定表のレコード数をみたら、約7000件超のレコード数とわかりました。これは、手動でやれる数ではありませんね。


    本当に必要な情報かは、わかりませんけど、どこかに行ったとかの検索をして、あ、あれはこの頃だったのね、とか、こんな風に移動したのかとか参考にするときもあるので、移行しておきたいと思いました。日記みたいな側面もありますし。もちろん行先は、Googleのカレンダーしかありませんね。


    で、いつもの通り、ネットで検索して、どうしたらよいか調べます。そうしたら、予想通りというか、色々な情報があり、一筋縄ではいくのかどうかわからない状況ですね。


    無料でできるよさげなものを試してみようと思います。


    PalmDateBookUtilで変換にトライ

    まずは、PalmDateBookUtilというもの。Hot Syncの時に使われるPC側のデータベースであるdatebook.datをコマンドラインで処理して、vCal形式に変換してくれるものとのこと。

    日本人のTakeshi Yonekiという方が作られているので、日本語も問題ないでしょう。


    ところが、残念ながら、DateBook Errorという表示が出てしまい変換してもらえませんでした。

    それ以上の情報もないので、原因を探ることも、解消することもできそうもありません。思い当たる理由としては、このソフトで対応しているのが、Palm Desktop 4.0.1となっており、私が今使っているバージョン4.2.0より古いものということでしょうか。何かデータのフォーマットに違いがあるのでしょうね。


    こういうことがあると、前途に暗雲が立ち込めてきているような予感がします。

    でも気を取り直して、別のものも調べてみます。 


    きみちゃんの人生無茶修行!?のPalmからAndroidへ・・・

    を参考にしてみます。perlを使った処理みたいです。


    まずは、p5-Palmからperlのモジュールをダウンロードしてきます。そこには、最新版の1.4.0もありましたけど、安定版の1.3.0を使ってみます。

    ファイルは、p5-Palm-1.3.0.tar.gz

    ダウンロードしたら、展開しておきます。展開すると、p5-Palm-1.003_000のディレクトリの下にファイルが展開されました。


    その直下にあるREADMEを読みながら進めます。

    Makefile.PLがあるディレクトリで作業を開始します。

    まずは、READMEのINSTALLINGに書いてあるようにインストールします。


    私の場合、実行環境は、Windows10上で、cygwinを動かして、以下を実行しています。


    501 p5-Palm-1.003_000> perl Makefile.PL
    Checking if your kit is complete...
    Looks good
    Writing Makefile for Palm
    502 p5-Palm-1.003_000> make
    cp Palm/Mail.pm blib/lib/Palm/Mail.pm
    cp Palm/Address.pm blib/lib/Palm/Address.pm
    cp Palm/PDB.pm blib/lib/Palm/PDB.pm
    cp Palm/StdAppInfo.pm blib/lib/Palm/StdAppInfo.pm
    cp Palm/ToDo.pm blib/lib/Palm/ToDo.pm
    cp Palm/Memo.pm blib/lib/Palm/Memo.pm
    cp Palm/Datebook.pm blib/lib/Palm/Datebook.pm
    cp Palm/Raw.pm blib/lib/Palm/Raw.pm
    cp util/pdbdump blib/script/pdbdump
    /usr/bin/perl.exe "-MExtUtils::MY" -e "MY->fixin(shift)" blib/script/pdbdump
    503 p5-Palm-1.003_000> make install
    Installing /usr/lib/perl5/site_perl/5.8/Palm/Address.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/Datebook.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/Mail.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/Memo.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/PDB.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/Raw.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/StdAppInfo.pm
    Installing /usr/lib/perl5/site_perl/5.8/Palm/ToDo.pm
    Installing /usr/bin/pdbdump
    Writing /usr/lib/perl5/site_perl/5.8/cygwin/auto/Palm/.packlist
    Appending installation info to /usr/lib/perl5/5.8/cygwin/perllocal.pod


    特に問題なく完了したようです。これで準備は完了だと思われます。/usrというのは、私の環境ではWindowsでいうd:\cygwinに相当しています。

    インストールしたライブラリを使うことで、簡単にPalmのデータベースを処理できるようです。


    変換スクリプトは、Palm データベースの iCalendar 形式への変換からいただきました。

    pdatebook2ical.plをダウンロードしてきます。

    これは、ファイルの中身をみたら、Linuxで使うディレクトリ構成になっているみたいで、使用する環境もLinux上を想定したスクリプトのようです。


    そこで、きみちゃんの人生無茶修行!?のPalmからAndroidへ・・・に書かれているdiffの差分が有効になるということだと理解しました。パスをWindowsとかで使いやすいような感じにしているようでした。


    コードをみると、context方式で出力されたdiffのようでしたので、patchを当ててperlのソースファイルを更新する必要があるようです。

    ところが、私のcygwin環境にpatchがありませんでした。cygwinのsetupからインストールすればよいかと思ってトライしたのですが、元のcygwinが古すぎるのか、Palm開発用のツールのprc-toolsをインストールしてしまっているからなのか、エラーが出てcygwinのsetupがうまく動きませんできませんでした。


    仕方がないので、Windows用のpatch.exeをダウンロードしました。ところが、最初GNUのサイトからダウンロードしたのですが、うまく動作しませんでした。そのため、「ソフトウェア工房α」のpatc254w.zipを試すことになりました。こちらは、うまくいきました。理由は不明です。


    早速、きみちゃんの人生無茶修行!?さんの所に掲載されていたdiff差分データを使ってperlスクリプトの更新を行おうとしましたが、エラーが出てできません。

    contextタイプのdiffフォーマットについて知らなかったのですが、それを勉強する羽目になってしまいました。

    少し泥沼にはまり始めているような状況でしたが、色々と調べていくうちに、大体の原因がわかりました。


    それは、webに掲載する関係かもしれませんが、一部文字化け、必要な情報が消えてしまっていたということでした。

    問題点は、以下の通りでした。

    • ””、’’が半角でなく、全角2バイトコードに変換されていました。
    • 比較対象のファイル側は、---と3つのマイナスになっているはずですが、web上は全角の−みたいな記号になっていて、コピーしたら、?に変わってしまいましたので、?を3つの---に変換しました。
    • diffのフォーマットである行先頭のスペース2つが消えていました。ただし、!、+で開始している行は、行頭にスペースはありません。また、範囲を示して行も対象外。
    • オリジナルのソースの行末には、スペースが付いていたが、web上のdiffにはスペースなくなっていたりしました。そのため、オリジナルのファイルと比較が適切にできない問題がありました。また、ソースは、タブを使っていましたが、web上ではスペースになっていたりしていました。
      これらは、手修正も面倒だったので、一旦ソースファイルもdiffのファイルも、タブは廃止し、スペースは1個だけにするというルールで変換し、また、行頭、行末スペースは削除という対応を取りました。
    • \nがnになっていた部分がありました。これは、オリジナルのソースを見ながら修正しました。


    上記の問題をエディタで修正して、ようやくpatchが正常に動作して、ファイルができました。

    なお、これは、管理者権限のコマンドプロンプト上で実行しました。

    D:\My_Documents\Palmデータ変換\Calendar>patch -c original\pdatebook2ical-noTabSp.pl diff
    patching file 'original\pdatebook2ical-noTabSp.pl'

    ファイルができ上ったので、ちょっと気になったGNUのpatchをもう一度、実行してみましたが、なぜか暴走してしまいましたので、GNU版のpatchの使用はあきらめました。pdatebook2ical-noTabSp.pl は、ダウンロードしたソースファイルから、上述の修正を行ったファイルです。


    最後に、上述の通り、インデントのためのTABやら、スペースをほとんどとってしまい、ソースがみにくくなってしまったので、meadow上で、整形(M-x indent-region)して、perlのスクリプトファイルを完成させました。


    あと、書き忘れましたが、webからコピーして作ったdiffは、改行コードがUNIXタイプの0x0aになるようにしておく必要があったかと思います。


    で、ここで、よくよく変更されたperlの内容を読んでみると、最初の方は、ディレクトリをWindows用に合わせているみたいなので必須ですが、後半は、データの加工に関するもののようです。

    オリジナルのものは、タイトルの空白以降を場所(Location)のデータに割り振って運用されていたようで、それに合わせた処理をしていたようです。そういう処理もしないようにしたものになっているらしいが、変更後は、コメントの1行目をLocationに書き出すようにしたとの記述がありました。
    私の場合は、コメントの1行目に場所を入れたりしていないので、修正が必要かもしれません。


    この辺の処理については、実際に自分のデータを作ってみてから、修正したいと思いました。

    では早速、icalファイルを作ってみましょう。

    処理する対象ファイルは、Datebook.pdbとのことなので、PalmDesktopからExportしたものではありません。バックアップされているはずのファイルを探すことから始めます。PalmDesktopの設定を調べると、どこにバックアップができるかわかりました。私の場合は、以下となっていました。

    D:\My_Documents\PalmDesktop\

    この下にユーザ名のディレクトリがあり、その下にアプリごとのたくさんのディレクトリがありました。しかし、残念ながらDatebook.pdbはどこにも見つかりません。


    調べてみると、このファイルは普通は、バックアップされていないみたいです。

    palm2ical ? Palm Datebook/Calendar export to iCalendarのページに、

    Obtaining the Palm Datebook/Calendar PDB fileという章があり、いくつかの取り出し方が書かれていました。一番簡単と書かれていたFileZを使って、SDカードに書き出す方法を試しました。しかし、エラーが出てしまいうまくいきませんでした。


    仕方がないので、2番目のHotSyncでPC上にバックアップする方法を試しました。これは、FileZでDatebookDB.pdbのCreaterをdateからABCDのようなものに変更して、AttrsタブにあるBackupオプションにチェック入れたら、HotsyncすればPC上にバックアップできるというものでした。

    しかし、30分くらいHotSyncでDatebookをバックアップしているような状態が続いた後、Hotsyncがようやく終わりました。そして、PCにできたファイルを見たら、Palm上では377KBもあったサイズでしたが、64KBほどしかありませんでした。中身をバイナリエディタでのぞいてみましたが、データらしきものが見えず、適切な状態ではないようでした。2回ほど、それぞれ30分以上時間をかけてトライしてみましたが、結果はかわらず、Datebook.pdbを取り出すことができませんでした。


    Palm2CSV / Palm2iCalを利用

    何か別の方法がないかと探したところありました。

    Palm2CSV / Palm2iCalというページです。ここでは、なんと、PalmDesktopからExportしたdbaファイルから変換できるとのこと。

    画面の全容は以下のキャプチャの通りです。

    image

    英語ですが、Step1から6まで順を追って説明されているので、難しくはありません。Todo (Tasks)の変換もできるみたいです。

    Date Book ArchiveフォーマットでExportしたファイルを用意し、Step4でアップロードして、Step5で、オプションの設定を行って、Step6のConvertボタンを押して、変換してみました。Webから変換後のファイルをダウンロードしたら完了です。問題なく変換できました。オプションが色々とあるので、何種類か試して、所望のファイルになるようにしました。ファイルは、テキストファイルですから後は何とかなりそうです。iCal/icsフォーマットの勉強も少ししないと、どんなフォーマットだと私の使い方に合うのかわかりませんね。

    まだ、Google Calendarへのアップロードは行っていません。


    perlでの変換に再挑戦

    上記で、iCalフォーマットのファイルに変換できましたが、せっかく変換に苦労したperlプログラムも使えるようにしたいなと思って、画策しています。


    しかし、どうやってもDatebook.pdbを取り出せないので、しばらく考えた後、こういう場合は、Palmをハードリセットしてしまうのが良いと思いました。と、ここで、ハードリセットをどうするか思い出せないので、調べものです。まだ、情報はネットに残っていました。ありがたや。


    ハードリセットのやり方:電源ボタンを押したまま、リセットピンを押します。

    電源ボタンは押したまま、最初オレンジのロゴが出て、さらに、Palm Poweredという青っぽいロゴが出てきたら、電源ボタンから手を離して構いません。

    そうすると、データを消してよいかという感じのメッセージがでるので、上ボタンを押して、リセットします。


    ハードリセット後は、素のPalmTXなので、日本語も表示できなくなっています。でも、大丈夫。起動したら、Hotsyncすれば、データが戻るはずです。

    その後に、J-OSを起動して、日本語対応にすればよいと思いました。 ただ、Hotsyncには結構時間がかかりました。


    Hotsync後、J-OSをタップしましたが、フォントデータが足りないとか言われて、少し変です。

    Hotsyncでバックアップされないものがあるようです。私のKazHatPageの記事を見て、j-os font large.prcとj-os font small.prcをインストールして、再度J-OSを起動したら、正常にインストールできました。
    リセットを促され。再起動がしたら、日本語表示ができるようになりました。久しぶりの作業だったので、ちゃんと元に戻るか不安もありましたが、使えるようになりましたので、ここで少しほっとしました。何しろ、古いマシンですし、Palm社のホームページもなく、情報も限られてきている状態ですから。


    まだ少し作業が残っていました。SDHCカードはPalmTXのデフォルト状態では使えませんので、SDHCを実行して、使えるようにしました。このPalmwareは、SDHCではないSDカードに入れておいたので、これをPalmTXに挿して、実行して、元のSDHCカードを使えるようにしました。


    これで、たぶん元の状態に戻せたはずです。

    もう一度、FileZでDatebookDB.pdbのCreatorをPDatからABCDのようなものに変更して、AttrsのタブにあるBackupにチェックを入れてHotsyncしましたが、バックアップできません。どうしようかと思いましたが、PalmTXのCalendar(予定表)の場合、もう一つCalendarDB-PDat.pdbというデータがあるとのこと、こちらの方が新しいフォーマットらしく、情報量も多いということを知りました。

    フォーマットも新しいとは言え、基本的な部分は同じものらしいので、これをダメもとでHotsyncしようと思いました。


    FileZ上で、CalendarDB-PDat.pdbのCreatorをPDatからABCDのようなものに変更して、AttrsのタブにあるBackupにチェックを入れて、Hotsyncしたら、バックアップできました。

    FileZで見た時、DatebookDBは、377KBしかありませんが、CalendarDB-PDatの方は578KBもあり、だいぶ違いが見受けられました。そして、バックアップされたファイルは、420KBと578KBより小さいサイズでした。もしかしたら、エラーか何かで全部はバックアップされなかったのかと心配しても、今はそれを確かめるすべもありません。先に進めましょう。


    早速perlで変換と思いたいところですが、perlプログラムでは、入力ファイル名がDatebookDB.pdbと固定されたプログラムとなっていたことを思い出し、ファイル名を変更しました。

    では変換してみましょう。

    Calendar> perl original/pdatebook2ical-noTabSp.pl
    No handler defined for creator "ABCD", type "DATA"

    というエラーになってしまいました。FileZでCreator名を変更していたのを忘れていました。これをバイナリエディタで元のCreator名のdateに変更しました。

    再度実行してみます。

    Calendar> perl original/pdatebook2ical-noTabSp.pl

    特に何もメッセージも出ずに終わりました。たぶん、処理が完了したようです。同じディレクトリ内を調べると、calendar.icsというファイルができ上っていました。

    このファイルはテキストですけど、文字コードは、UTF-8、改行コードはUnix (0x0A)という形式になっているようです。


    ということで、一度は挫折しましたが、何とか、icsファイルがperlを使ってもでき上がったようです。

    テキストファイルなので、UTF-8が読めるエディタで開けます。後述するデータ構造を理解して、件数を確認したら、Palm上で見た件数と一致していましたので、上述したファイルサイズの件は問題なかったと解釈したいと思います。


    ただ、perlで生成したファイルは、「きみちゃんの人生無茶修行!?」さんの使い方に合わせたフォーマット変更が入っており、少し問題がありました。それは、icsフォーマットのLOCATION情報をコメントの1行目から取得しているので、おかしな感じになってしまっていました。ここは、要修正ですね。

    ここで、2種類のicsファイルができ上った形になります。どちらかを選ぶ必要がありますが、中身がどんな状態か理解しないといけません。でも、このファイルはテキストエディタで処理できるものですから、エディタで開いて、それを見ながら、icsファイルとはどんなもので、何をGoogleカレンダーにアップロードする必要があるのか考えたいと思います。


    icsファイルの考察&最終版データの作成

    私のPalm予定表データをどのような形で引き渡すのが最適か考えました。

    その前に、Googleカレンダーはどのような情報を受け入れているのか見るために、カレンダーのデータをエクスポートしてみました。まだ少ししか入力されていませんが、それを見ることで、適切なフォーマットもわかるだろうとの予測からです。

    iCalendar(ics)の仕様に関しては、iCalendar 仕様を参考にしました。

    階層構造になっていますけど、重要なのは、BEGIN:VENENTからEND:VENENTの部分ですかね。

    ここに、日付、タイトルなどを記述する形のようです。


    DTSTART:

    DTEND:

    RRULE:

    LOCATION:

    CATEGORIES:

    DESCRIPTION:

    SUMMARY:

    といったものが、Palmでも設定していたデータでしょうかね。


    今、手元には、Webで生成したもの、perlで生成したもの、Googleカレンダーからエクスポートしたものという3つのファイルがありますので、それを比較しながら、内容をざっと見ていきます。


    LOCATIONはPalm上でも設定できますけど、使った記憶がほとんどありません。ちなみに、Webで変換したデータには、この項目は入っていませんでした。なくてもよいかもしれません。perlプログラムでも、コメントから取得してみたり、Summaryから取得してみたりしていました。ということは、Palmのデータベースに設定されていても無視されているのだと思います。実害もなさそうなので、ここは目をつむるのが良いようです。私の場合、perlプログラムから、LOCATIONを出力するのはやめた方が良い感じです。


    カテゴリも使っていませんでした。Web変換ファイルには項目は出力されていましたが、中身はすべて空でした。これは、単にそういう処理だったのか、私のデータに設定がなかったのかのどちらかですね。Palm上でカテゴリ設定した予定を作って検証することもできますが、面倒なので、やめます。

    perlプログラムで生成したファイルには、この項目はありませんでした。


    SUMMARYとDESCRIPTIONは、入力した予定のタイトルと、コメント/ノート/詳細のことなので、一番重要な情報ですね。Googleカレンダーから取得したデータを見る限り、文字コードはUTF-8であるべきみたいです。改行コードは、Windowsの(0x0D 0x0A)になっていました。

    また、コメント内の改行は、\n (0x5c 0x6e)という記述になっていました。

    Web生成ファイルでは、\n\nとなぜか2重に変換されていて、perl版では、\Nと、適切に1個でしたが、Nが大文字になっていました。これはプログラムを見てみたら、意図的に大文字にしていたみたいなので、簡単に小文字にできそうです。


    あと問題だったのは、Web生成ファイルではUTF-8が適切に出力できていないようで、エディタでちゃんと表示されなかった点です。UTF-8での出力をやめるオプションにしたら、Shift-JISのまま出力されましたが、改行コードについては、\n\nという2重出力は変わりませんでした。また意図しないところに改行(0x0A)が入っていました。どうも1行の長さが80文字を超えないようにしているようにも思えましたが、その規則性を推察することはできませんでした。

    この辺を見ると、Web版のファイルは問題がありそうですね。


    最後に気にしておいたよさそうなのは、繰り返し予定ですかね。

    RRULEというのが適切に処理されているかどうかという点ですね。ちゃんとフォーマットを勉強していませんが、何件かみたら、何となくそれっぽい状態に見えたので、大丈夫そうです。

    例えば、何日まで繰り返す予定なら、FREQ=DAILY;UNTIL=YYYYMMDDのような感じになっていました。ほかにもFREQ=WEEKLYとかもありました。


    そんなチェックしながら、DTSTARTを見ていたら、perl版は問題ないように見える時刻になっていましたが、Web版は時刻がおかしく見えました。たぶんタイムゾーンの設定の問題かもしれません。13時開始のものが、4時開始と9時間ずれていました。Web版ではTime Zoneを設定するところがあったので、Tokyoを選んだのですけど、何か勘違いしているのかもしれません。ちゃんと設定すれば解消しそうですけど、上述の問題もありましたから、Web版は却下と判断しました。


    ということで、perl版で生成したデータが所望の形になるように、上述の問題点を変更したスクリプトを用意しました。


    最終形態のperlプログラムは、あとで掲載するとして、

    Calendar> perl original/pdatebook2ical-noTabSp.pl

    と前回同様に処理をしました。この時、DatebookDB.pdb (CalendarDB-PDat.PDBのファイル名を変更し、Creator名をdateにしたもの)が、このディレクトリに存在する必要があります。

    そうすると、このディレクトリに、calendar.icsというファイルができ上ります。


    ファイルサイズは、元が420KBだったのに対して、1322KBと巨大化。ファイルの中身をざっと見ると、文字コードは、UTF-8、改行コードは、Unixタイプの0x0a(LF)となっており、コメント内の改行は、\nが1個だけとなっており、問題なさそうでした。件数もちゃんと合っています。

    いよいよ、Googleカレンダーにインポートの時です。

    でもいきなり7000件超のデータをインポートして何か問題があると、削除したり、修正するのも面倒になりますので、生成できたファイルから数件だけ残したファイルを作成してみました。色々な場合を想定して、繰り返し予定あり、なし、コメントの有無のデータというような数種類のデータがあるファイルにしました。

    それをGoogleカレンダーにインポートして、きちんと処理できたか確認しましたが、問題なさそうです。


    では、覚悟?を決めて、Palmの予定表のデータをすべて移すことにしましょう。先ほど作成したファイルは、上述の通り1.3MBと大きくそのままではダメなようです。Googleカレンダーでインポートするファイルに1MBまでというサイズ制限があるからです。そこで、2つに分割することにしました。

    ただ、半分にする訳にはいきません。ファイル構造は、各種のBEGIN〜ENDでくくられて、かつネストしている構造なので、その構造を崩さないように、ヘッダ部を残して、データ部分だけを前半残し、後半残しといった感じで2つに分割しました。


    そして、いよいよGoogleカレンダーにインポートする段階になりました。1つ問題が発生しまして、1回目は、問題なくインポートできたようで、インポートした件数が表示されて完了しました。ところが、2回目は、エラーが発生しました。
    一時的にGoogleカレンダーが使用できないというようなメッセージでした。時間をおいて、試すように書かれていましたが、何度やっても状況は変わりませんでした。そこで、データがどのようになっているのか、確認したら、なぜかデータはインポート済みのように見えました。

    確認のため、エクスポートして、データの件数を数えたところ、2回に分けてインポートした合計の件数と一致しましたので、エラーメッセージが出ましたが、問題なくインポートできたと判断しました。


    その後、Android P9liteでカレンダーを開いて、予定が反映されていることを確認しました。

    これにて、Palm予定表データのAndroidカレンダーへの移行プロジェクトは終了です。


    最後に最終版のperlプログラムを掲載したいところですが、例によって、字数オーバーになってしまったので、次の記事に回します。

    では、また。

    記事へブログ気持玉 / トラックバック / コメント


    Palmのメモ帳データをAndroidへ (perlプログラム)

    2017/05/27 15:00

    前の記事で掲載できなかったperlプログラムを掲載します。

    #!/usr/bin/perl


    # 使い方:perl read_csv1.pl
    # 引数なしで、読み込むファイルは固定。 (プログラムが面倒だったため)
    # 使用ファイル:Palmメモ帳_置換後.csv
    # exportしたファイルの改行コードを0d 0d 0aから0d 0aに置換したもの

    # 概要:Palmのメモ帳をCSV形式でexportしたファイルを処理するプログラム
    # 1レコードは、3つのフィールドで構成。タイトル、プライベート、カテゴリ
    # メモ, プライベートかどうかのフラグ, カテゴリ
    # 3つのフィールドは、どれも""で囲まれている形式だった。
    # メモのデータは、改行コード、,(カンマ)ももちろん含む。"は""となっている。


    # 1メモ1ファイルのテキストデータとして生成。ファイル名は、メモの1行目を使用。
    # カテゴリごとにフォルダを生成してそこに格納。
    # ファイル名が重なった場合は、後ろに(番号)のようなものを付ける
    # ⇒シリアル番号をつけるようにしたので、不要に。
    # プライベートメモには、〆をファイル名の前につける


    # CSVファイルの読み込み方針
    # ファイルは、バイナリとして取り扱う。
    # ダブルクォート内外を判断して処置を進める
    # ・ダブルクォートで始まっているフィールド:
    # ""(連続クォート)を無視して、単独の"まで取り込むと、
    # ""内の改行もそのまま取り込める。普通はその後に、,(カンマ)で
    # フィールドの区切りとなっているか、改行でレコードの終わりになっている。
    # ・ダブルクォートでないフィールド:
    # 単純に、次に見つかる,(カンマ)か、改行でフィールドの区切りとなっている。
    # 改行ならレコードの終わり。

    # 2017/5/26 一応完成


    #まずは、ファイルを読み込む
    $inputFile = "Palmメモ帳_置換後.csv";
    open(IN, $inputFile);
    binmode(IN);
    read(IN, $buf, -s $inputFile);


    # 読み出したバイナリデータを1バイト単位(符号なしchar型)に展開
    @data = unpack("C*", $buf);


    # 変数の初期化
    $inQuote = 0;    # "の中か?
    $fldNum = 0;    # フィールド番号
    $startPt = 0;    # 現在のフィールドの最初の位置
    $currentPt = 0;    # 現在チェックしている位置
    $recordNum = 0;    # 現在のレコード番号 (最初が0)


    $maxPt = length($buf);
    $adj = 0;    # ""で囲まれている時に文字列の長さを調整するためのもの


    printf("読み込んだファイルサイズ=%d bytes\n", $maxPt);

    do {
        $ch = chr($data[$currentPt]);    # 1文字=1バイト取り出す

        if ($inQuote == 1) {
            # クォート内の処理
            if ($ch eq '"') {
                if (chr($data[$currentPt+1]) eq '"') {
                    $currentPt++;    # 次の"を読み飛ばすため
                } else {
                    #次が"でなければ、フィールド終わり
                    $inQuote = 0;
                }
            }
        }
        else {
            # クォート外の処理
            if ($ch eq ',') {
                # 区切りのカンマが来たので、次のフィールドの処理
                $fldData[$fldNum] = substr($buf, $startPt, $currentPt - $startPt-$adj);
                $fldNum++;
                $startPt = $currentPt + 1;
            } elsif ($ch eq '"') {
                # 始まりのダブルクォート
                $inQuote = 1;
                 $startPt++;        # 前の”を外すため
                $adj = 1;
             } elsif ((ord($ch) == 0x0d) && ($data[$currentPt+1] == 0x0a)) {
                # 改行なので、レコードの終わり
                $fldData[$fldNum] = substr($buf, $startPt, $currentPt - $startPt-$adj);
                $currentPt++;    # 次の0x0aを読み飛ばすため
               
                # ここで、ファイルを作成する
                # fldData[0]の1行目をファイル名、fldData[2]をフォルダ名に使用

                # 改行コードで分割して、最初の行をファイル名にする
                $fldData[0] =~ s/""/"/g;    # データ内の""を"に変更しておく
                @filename = split(/\x0d/, $fldData[0]);


    printf("%d(%6X): %s, %s, %s\n", $recordNum, $startPt, $filename[0], $fldData[1], $fldData[2]);


                $dir = $fldData[2];
                if (!(-d $dir)) {
                     # フォルダ(ディレクトリ)があるか確認し、なければ生成。
                    mkdir($dir);
                }


                # ファイル名は以下となるように調整
                # 長すぎないように80文字位を最長にする
                # 使えない文字(\ / : * ? " < > |)以降を削除してしまう。
                # 同一ファイル名がある場合は、後ろに(番号)を付ける
                # 拡張子は、.txtとする
                # ファイル名の先頭に番号を付け、Palmの並びと同じにできるようにする


                # まず全角文字を削除して、残った半角文字に禁止文字があるか調べる
                $fn1byte = $filename[0];
                $fn1byte =~ s/[\x81-\x9f\xe0-\xfc][\x40-\x7e\x80-\xfc]//g;


                if ($fn1byte =~ /[\/:*?"<>|]/) {         
                    # 使用禁止文字が含まれていたら、
                    # 素直にスキャンして、必要な処理をする。
                    # 単に置換すると、漢字コード内の禁止文字コードまで置換される


                    $len = length($filename[0]);
                    $jj = 0;
                     while ($jj < $len) {
                        $fn1 = substr($filename[0], $jj, 1);
                        if ($fn1 =~ /[\x81-\x9f\xe0-\xfc]/) {
                            # 漢字コードの1バイト目だったら、次を読み飛ばす
                            $jj = $jj + 2;
                         }
                        else {
                            if ($fn1 =~ /[\\:*?"<>|]/) {
                                # 禁止文字だったら、改行コードに置換
                                substr($filename[0], $jj, 1, "\n");
                            } elsif ($fn1 =~ /\//) {
                                 # /だったら、-に。大抵、年月日に使用しているので。
                                substr($filename[0], $jj, 1, "-");
                             }
                            $jj++;
                        }
                     } # while
                }


                # 改行/TABコードで分割
                @filename2 = split(/[\n\t]/, $filename[0]);         
                $filename2[0] =~ s/\s+$//;        # 終わりの空白は削除         
                
                # プライベートメモには、ファイル名に〆を付ける
                if ($fldData[1] =~ /1/) { $private = '_〆';    }
                else { $private = '_'; }
                # ファイル名をパスも含めて生成
                $fn = $dir.'/'."$recordNum".$private.$filename2[0].'.txt';


                # 以下はシリアル番号をファイル名の先頭につけたので、意味なし
                $f_num = 0;
                while (-e $fn) {
                    # ファイルが存在した時は、区別するため後ろに(番号)を付ける
                    $f_num++;
                    $fn = $dir.'/'."$recordNum".'_'.$filename2[0].'('."$f_num".').txt';
                }


                # 生成するファイルをオープンする
                open(OUT, "> ".$fn);
                binmode(OUT);
                print OUT $fldData[0];
                close(OUT);


                # 次のレコードのために変数の初期化
                $fldNum = 0;
                $startPt = $currentPt + 1;
                $recordNum++;
                $adj = 0;
            }
        }
        $currentPt++;
    } while ($currentPt < $maxPt);


    close(IN);     # ファイルクローズ

    以上です。

    記事へブログ気持玉 / トラックバック / コメント


    Palmのメモ帳データをAndroidへ

    2017/05/27 14:58

    Androidを少しずつPalmのように使えるように、まずは、データの移行を始めました。

    Palmが、Palmたらしめていたと思われる4大ソフトである、予定表、メモ帳、ToDo、アドレス帳のデータが対象です。

    今頃こんなことをしている人も、それを必要とする人もいないとは思いますけど、記事にしておきます。


    メモ帳からデータを移行

    Palmでは、1つのデータベースでメモを管理しているような感じになっています。これをAndroidに移動させる場合、基本的に、1つのメモを1つのテキストファイルにする感じにしないといけないような感じですね。

    既に先人が色々とトライしたようですけど、これと言った感じのツールが見つからなかったので、自分で何とかしようかと思いました。


    PalmDesktop 4.2のMemosを開いて、Private属性にして、普通の状態では見えないようになっているメモがあれば、それも表示されるように設定しておきます。


    メニューのFile→Export...を選ぶと、ポップアップが出てきて、書き出すファイル名を聞かれます。

    image

    ファイル名は、自分がわかるように適当に入力します。

    Exportタイプは、デフォルトで、mpaとなっていますが、それをプルダウンメニューの中からcsv形式を選んで変更します。Rangeは、全部のメモを書き出すため、Allに変更します。

    image

    Exportボタンを押して、書き出します。


    すると、以下のようなポップアップが出ました。

    image

    3つのフィールドがあり、Memoは、メモの内容そのもの、Privateは、非表示属性、Categoryはカテゴリそのものとなっているようです。

    チェックボックスで書き出す情報を選べるようですが、とりあえずデフォルトのまま、つまり全部にチェックを入れたままOKを押しました。

    そうすると、あっという間にファイルが出来上がりました。私の場合、641件のメモがあり、667KBのファイルが作成されました。


    できあがったファイルの中身をチェック

    csvファイル形式なので、カンマ(,)で区切られているわけですが、指定した3つのフィールドはそれぞれ、""でくくられていました。

    Memoの所は、テキストそのものですけど、SJISで、改行コードは、なぜか0D/0D/0Aという形になっていました。普通のDOS形式だと0D/0Aだと思ったのですけどね。どうも変な感じです。バグのような。

    最初の1行分をタイトルにしているのがPalmのメモ帳の特徴でしたね。

     

    Privateの属性の所は、"1"か"0"となっていました。1がPrivateのメモで、非表示になるもののようです。

    最後のカテゴリは、Palm上でカテゴリ分けしていた時の名称が、ダブルクォーテーション””でくくられていました。

    これら3つの情報がカンマで区切られていて、最後は、0D/0Aで終わって、次のデータにつながっていました。


    先のメモフィールドの改行コードの話、ちょっと検索してみたら、0D/0D/0Aと勝手になってしまう処理系があるという記事を見つけました。0D/0Aとなっているデータを処理する際、0AというUNIXの改行コードだけを見て、DOS用に0D/0Aに変換を掛ける処理系があるらしく、置いてけぼりされた最初の0Dはそのまま残ってしまい、結果として、0D/0D/0Aとなっているとか。


    csvファイルは、テキストファイルですから、テキストエディタなら表示できるはずですけど、改行コードがおかしいせいか、Meadow (emacsのwindows版)でファイルを開いたら、文字化けして、普通に読める状態ではありませんでした。仕方がないので、バイナリエディタで、0D/0D/0Aを0D/0Aに変換したら、Meadow上でも普通に読める状態になりました。なお、元ファイルは、Excelでは読み込んでも問題ありませんでした。このくらいの違いは、Excelなら吸収してしまっているようです。


    どんなデータになっているか理解したので、先人たちの知恵を借りようと思いましたが、よい感じのものが見つかりません。

    仕方がないので、csvファイルを自分で処理しようと考えました。


    プログラム作成方針

    データ形式は、

    ”タイトル+メモ内容”,"1または0",”カテゴリ”改行

    となっているので、""内の改行は無視するようにして、改行コードまでの1行を1レコードとして処理します。


    カテゴリはフォルダ名と考え、そのフォルダにメモのタイトルをファイル名とするテキストファイルを生成していきます。private属性は、それを取り扱えるアプリがないみたいなので、ファイル名にそれとわかる適当な記号を付けることにしました。

    カテゴリは、フォルダ名になりますが、処理を進める時に、そういうフォルダが存在しなければ作成し、既にあれば何もしないようにします。


    ファイル名は、タイトルを使います。しかし、Palmと違って、ファイル名になるので、重複がないようにチェックは必要でしょうね。これは、通し番号をファイル名につけるようにしたので、自動的に重複しないようにしました。並べ替えにも番号があった方が便利ですしね。


    一番面倒な処理は、メモ内容のフィールドですね。改行コードが入っていたりするので、単に改行コードで区切りだと認識しないようにしなければなりませんね。

    また、メモの中身で、"を使っているときは、出力されたファイル上では、""と2回ダブルクォーテションになっているので、1個化しないといけません。


    だいたいのアルゴリズムもできたので、これをperlで処理しようと思います。

    当初、CSV_XSというのがうまく処理してくれるらしいので、インストールしようとしましたが、私の環境 (Windows10上で、cygwinを動かしている) ではうまくできませんでした。原因を調べるのも面倒なので、perlの標準関数などだけで処理してみようと思いました。

     

    幸いなことにcsvファイルを取り扱うためのプログラムソースがいくつか見つかりましたので、それをベースに作成します。

    Perlメモさんの 値に改行コードを含む CSV形式を扱うを参考にしました。

    csvファイルの処理は、人がルールを読むと簡単そうでしたが、ライブラリとか使わないで処理しようとしたら、結構面倒でした。


    作ったperl用のスクリプト

    以下にようになりました。この形になるまで、少しずつデバッグして、一応完成した最終形となります。

    例によって、文字数制限に引っかかってしまったので、スクリプトだけを記事に回します。

    #!/usr/bin/perl

           

    文字数制限から、ここは削除し、次の記事に回します。


    close(IN);     # ファイルクローズ

    そして、これを実行したら、全部で、11カテゴリ、計641件のメモファイルができ上がりました。

    プログラムの中にいっぱいコメントは付けたので、説明は省略します。


    この件数は、私のPalmのメモ帳に登録されている件数と同じなので、プログラムはたぶん問題なく動いたのだろうと思っています。最初は、ファイル名に使用禁止文字を使ってしまっていて、ちゃんとファイルができていなかったり、色々とありました。


    データのコピー

    データの生成は、Windows10上で実行したので、まだファイルは、PC上にあります。これをAndroid P9liteのSDカード上にコピーしました。私が最近重宝しているのは、TeamViewerのファイル転送機能です。

    何にせよ、でき上がったファイルをフォルダごと、Documentsの下にコピーしました。


    で、Android上でどうするかというと、Lesser PadというPalmのメモ帳の感じに近いアプリを先人が作られているので、それから見たりしようと思っていたのでした。

    Documentsの下のフォルダをメモ帳のカテゴリと解釈して、メモ帳データを閲覧、編集できるアプリになっていました。


    でも、1つ問題があり、上記perlで作ったデータは、Shift JISのままにしてしまったのでした。タイトルは、ファイル名なので、リストを見るのは、ファイル転送時に処理されたようで、問題なく表示されました。が、中身は、文字化けしていました。

    Lesser Padで使おうと思う方は、perlのプログラムの少しいじるか、でき上ったファイルの文字コードをutf8に変換してください。


    私はというと、たぶん一番使用頻度の高い、検索して、メモに書かれた情報を読むという用途としては、Lesser Padでは満たされないことに気づき、何かいいものがないかと調べたところ、aGrepというアプリを見つけました。アプリの説明としては、ここの説明あたりがわかりやすいと思いました。

    このaGrepで検索して、メモ帳を表示するなら、SJISのままでも問題なく表示されたので、とりあえず、面倒なコード変換はせずに、しばらく様子を見ることにしました。


    今回はここまで。次は、予定表ですかね。

    記事へブログ気持玉 / トラックバック / コメント


    Huawei P9liteのOTG化

    2017/05/04 13:42

    前回までに、root化、unix系でいうところのスーパーユーザもしくは管理者になることができました。

     

    root化により、システムファイルへのアクセスが可能になります。

    今回は、OTG対応にするためにroot化が必要だったわけです。

     

    ようやく、目的の作業に取り掛かれるところに到達できました。

     

    How to Enable OTG Support on Huawei P9 Liteというサイトの情報に従って設定していきます。

     

    必要事項:

    1. root化されていること
    2. File exploreがインストールされていること
      ES file managerかRoot Explorerを推奨とのことです。
      Root Explorerは有料ですが、ESファイルエクスプローラー無料で同等の機能のようなので、私は、ESファイルエクスプローラーをインストールしました。このアプリで後述のsystemフォルダの中身を書き換えることができるということ。

    これらの必要事項は、クリアしていますし、準備も整ったので、OTG化にトライしましょう。

    1. OTG Enabler packageの取得
      PC上にOTG Enablerパッケージを取り出します。
      以下のリンクからOTG enablerをダウンロードしました。

      Download OTG Enabler Package for Huawei P9 Lite.

      ダウンロードすると、OTG.rarというファイルがダウンロードされます。rarという圧縮形式になっているので、適当なソフトで展開します。

      のぞいてみると、OTGフォルダの中に、otg onとotg offという2つのファイルが入っていました。正直これだけっていう感じです。中身もシェルスクリプトで数行という短さでした。

    2. PCとP9liteをUSBケーブルで接続し、取り出したファイルをフォルダごとスマホ内のストレージか、SDカードにコピーします。
      PC上のエクスプローラにHUAWEI P9 liteが現れ、それをクリックすると、SDカードと内部ストレージが表示されました。
      image_thumb
      あとは、普通にファイルをコピーするように、OTGのフォルダを、SDカードにコピーすればOKです。今回は、SDカードのルートにコピーしました。

    3. コピーしたら、P9lite上で、Root Explorer(または、ESファイルエクスプローラー)を開き、OTGフォルダをSYSTEMに移動します。
      まず、SYSTEMがどこにあるのかもわかりません。ESファイルエクスプローラーの使い方もわからない状態でした。
      調べると、設定から、Rootエクスプローラのチェックを入れないといけないらしいです。
      それと、メニュー(≡)→設定でディレクトリ設定をタップ。ホームディレクトリをタップ。/sdcard/となっているのを/に変更します。←をタップすると、いくつか選択しが出てくるので、/を選択すればよいみたいです。
      そうして、画面上部のmicroSDカードの形をした内部ストレージというボタンを押すと、ファイル群がアイコンで並べられて表示されました。
      画面上部に、今いるディレクトリが表示されていて、適当にタップすると、そのディレクトリに移動できますし、アイコンをタップして移動もできるようです。簡単ですね。
      /sdcardの下にOTGフォルダを見つけました。これを長押しして、画面下に出てくるコピーをタップ、画面上部のディレクトリが表示されている所で、/をタップすると、ルートに行け、その下にsystemフォルダがありましたので、たぶんそこが目的の場所と推定しました。system内のファイル群が表示されている状態で、画面下部に貼り付けというボタンが見えるので、それをタップすると、OTGフォルダが/systemにコピーされました。
      2017-05-03-11-49-50
    4. OTGフォルダのパーミッションを755に変更
      /systemにコピーしたOTGフォルダを長押しして、画面下部にメニューが出たら、他をタップし、ポップアップメニューからプロパティを選びます。下記のような画面が表示されました。
      2017-05-03-11-52-49
      上記キャプチャの下の方にある権限の変更ボタンを押します。
      755に変更せよということなので、グループ、その他に読み込みと、実行権を与えればよいと思います。 以下のような感じですね。
      2017-05-03-11-54-26
      OKを押して設定します。
    5. 次に、Script Runner APKをインストール
      以下のサイトからファイルをダウンロードします。
      Download Script Runner APK for Huawei P9 Lite.
      rarファイルを展開後、ScriptRunnerフォルダを例のごとく、SDカードのルートにコピーします。
      ということでしたが、ファイルサイズが0になってしまっていて、おかしい状態です。
      仕方がないので、Play ストアからScriptRunnerをインストールしました。 
    6. インストールしたら、script Runner APKを開き、その指示に従ってください。
      ここの説明がこれだけだったので、何をしてよいやらという状態でしたが、/system/OTGにあるファイルをスクリプトとして、選択して、 rootにチェックを入れて実行すればよいだけのようでした。

    以上で終わりのはずでしたが、script Runnerで実行したときにエラーが発生します。

    当然、USBメモリ、USBマウスも認識されません。

    OTG ONにしようとして、エラーが発生します。
    ここからまた、苦難の道が始まりました。

     

    OTG化のための試行錯誤

    このスクリプトが何をやっているか調べました。

    #!/system/bin/sh
    echo hoston > /sys/devices/ff100000.hisi_usb/plugusb

    たった2行のスクリプトで、hostonをplugusbに書き込んでいるだけのようです。
    そのplugusbをESファイルエクスプローラーで探そうとしましたが、見つかりません。

    だから、エラーになっているように思いました。

     

    もちろん、この情報だけでOTGが動作するわけもなく、このファイルを無理やり作ってもOTGが動くわけはありません。

     

    ネットで調べたり、ESファイルエクスプローラーで探したりしていたら、見つけました。

    /sys/devices/platform/ff100000.hisi_usb/plugusb

    ディレクトリが違っています。platformというディレクトリ下になっていて、日本版は違っているのかと思いました。では、スクリプト内のディレクトリを修正したらOKだよねと思って、修正しましたが、だめでした。

    どうしてもplugusbに書き込みができません。書き込み権も付加しているのにも関わらずにです。

    plugusbファイル自体はテキストファイルで、ファイルの内容は、

    usb otg status: OTG_DEV_OFF

    write hoston/hostoff/deviceon/deviceoff to change the state.

    となっていました。つまり、hostonとかhostoffと状態を変更すれば、OTGが操作されるという意味ですね。

    現在は、OTG_DEV_OFFとなっていました。

     

    さらに調べると、どうもマウント時に書き込み不可にしてあると、書き込みできないとか、この情報はまだちゃんと確認していません。

    とにかく、書き込みができないので、OTGの状態も変更できない状態ということです。

     

    ここで、OTGチェッカーというアプリをインストールしてみたところ、エラーが表示されました。

    android.hardware.usb.host.xml

    handheld_core_hardware.xml

    というファイルがないというエラーです。

    これらをネット上から探して、/system/etc/permissionsの下に入れました。

    そうしたら、チェッカー上は、OTG対応OKという判定にはなりました。

     

    その後は泥沼でした。様々なツールやら情報を元に試行錯誤しましたが、うまくいきません。

    海外の方の映像で、USBメモリにアクセスできるようになっているのをみて、できるはずなのにと思いながら、やりましたが、私の力及ばずというところでした。

    でききれなかったのは、plugusbに書き込みができるようにすることだけだと思います。これをクリアしてもできる保証はありませんけど、力尽きて、中断としました。

     

    root化の解除

    それには、別の理由が持ち上がったためです。

    root化したことで発生する弊害があることに、遅まきながら気が付いたためです。

     

    radikoが起動しません。代替のラジオ録音なら聞くことはできました。

    Gyaoは親切にroot化している端末では使用できないというメッセージが出ました。

    Chrome上では、音声入力のアイコンがなくなり、音声入力できなくなりました。

     

    ネットで見ても、意外と多いroot化の弊害にあぜんとし、かつ、OTG化もできないので、元に戻したくなりました。OTG対応ができないので、戻すことに反対する理由はありませんから。

     

    しかし、root化したものを元に戻すことに苦労するとは、思いもよりませんでした。

    適切な情報が見当たらず、いきなり実機で試す状況になってしまったからです。

    よく調査ができていなかったという背景もありますが、調べてもあくまでも参考情報としかならず、自分の状況に合っているのか判断して進めざるを得なかったからです。

     

    まず、試したのが、SuperSuなら、簡単に非root化できるという話に飛びついてしまいました。

    私のroot化した環境では、phh Superuserというのがシステムアプリとして登録されている状態でしたが、PlayストアからSuperSuをインストールしてみました。起動すると、競合しているアプリがあるというようなメッセージが表示されたと思いますが、無視して、unrootをいきなり実行してしまいました。

    すると、何となく、rootが解除されたような感じで、ESファイルエクスプローラのroot化とかはできなくなりました。しかし、radikoやらGyaoやらは、まだ、root状態と認識していて、起動せず元に戻っていませんでした。

     

    root権限も行使できないのに、root状態と認識されるという、最もひどい状況に陥ってしまいました。

     

    ならばと、初期化を試みました。この辺から端末は、悪い方向へ転げ落ちていきます。

    でも、前回の経験があるので、少しは、考えてやっていたつもりでした。

     

    ならば、例のダウングレードを実行すればよいと思って、SDカードの/dload/にUPDATE.APPをコピーしようとしたら、PC上からアクセスできません。エクスプローラでみると、P9liteは見えるのに、その下にあるフォルダの中身が空の状態と表示されしまうのです。

    一方、HiSuiteで見ると接続できています。内部ストレージ、SDカードの使用量の表示はされています。
    どちらをクリックしても、エクスプローラではファイルが見えない状態です。ここで、かなり焦りました。

    書き込めないとどうにもなりません。本体からSDカードを出すことも考えましたが、単なる外部ストレージではないように取り扱っているように感じていたので、取り出して、書き換えしたことでさらに状況が悪化することを危惧してやめました。

    それから試行錯誤して、解決策が見つかりました。

     

    内部ストレージ、SDカードがエクスプローラで見えない時は、詳細情報→セキュリティ→HDBの仕様を許可をいったんOFFしてONするという操作をすることが良いようです。

     

    さて、話を戻して、UPDATE.APPをコピーできる状態に戻りましたので、コピーしました。

     

    そして、Android6.0へのダウンロードを実行したくて、音量上げ、音量下げ、電源の3つを押し続けました。

    しかし、音量上げと電源押しと判断されてTWRPが起動してしまいます。

    ここで、意気消沈です。TWRPというまだよくわからないソフトが割り込んでいるため、強制アップデートにいけないという事態のようです。

     

    復旧への足掛かり

    これを何とかしないといけません。

    リカバリイメージファイルを書き込まないと、いけないようですが、それが手元にありません。

    みつけた??G9青春版EMUI4.1_TWRP3.0.2 (最初の2文字は、日本の漢字でないので、ブログ上では??と表示されています)のrecovery_stock.imgをrecovery領域に、fastboot上で書き込みました。
    よく考えると、これは、先日ダウンロードしていましたね。

     

    この書き込み後、USBケーブル接続せずに、音量上げ、電源押しで、起動させても、TWRPが起動しなくなりました。

     

    リブートして、通常起動後、設定を確認しました。OEMロック解除のところは、グレーアウトしていて、ロックに戻せません。また、fastbootモード上でも、oem relockが効きませんでした。

     

    ロック状態でないと、中継パッケージがインストールできないはずですけど、ダメもとで、SDカードの/dloadフォルダに中継パッケージのUPDATE.APPを入れてみました。

     

    そして、いったん電源を切り、3つのボタン、音量上げ、下げ、電源の3つを押し続けてEMUIが起動するまで待ちました。

    そうすると、幸いなことに強制アップデートに入りました。結果がどうなるかは、わかりませんでしたけど、無事再起動して、通常の画面が現れました。初期化されているので、アプリの数は、減っていたりしますけど、ここは、そんなことは関係ありません。すでに経験済みのことなので、重要なのは、バージョンがどのようになったかです。

     

    設定→端末情報→バージョン番号を確認したところ、VNS-L22C900B300とマニュアル通りのバージョンに変わっていました。

    こうなると、復旧に期待が持てます。

     

    次にAndroid6.0にダウングレードするため、今度は、Android6.0のUPDATE.APPを/dloadフォルダに入れました。

     

    そして、前回同様に、3つのボタンを押して、強制アップデートモードに入れました。

    EMUIがアップデートを行い、リブートされると、初期設定の画面が現れました。

    そして無事Android 6.0 (VNS-L22C635B170)として、起動することができました。

    念のため、Root Checkerをインストールして、rootになっていないことを確認しました。

    radikoもインストールしてみましたが、問題なく動作します。

     

    多分、root化状態から完全に復帰できた様子です。

     

    復旧、動作確認

    多分正常状態になったように思えたので、再度Android 7.0にバージョンアップも行います。

    ダウンロードにすごく時間がかかりそうなので、別の作業も行っておきます。

     

    以下は、Android 6.0で行っています。

    まず、adbコマンドが使えなくなっていた件の確認。

    ビルド番号を7回タップして、開発者向けオプションを有効化して、USBデバッグを有効にしたら使えるようになりました。Android 6.0では、たたく回数によって、あと何回タップとかメッセージがでるのですね。親切です。たしか7.0ではそんなことはなかったような記憶が。

    また、OEMロック解除のボタンも動かせるようになっていました。

     

    root状態について調べるため、fastbootモードで見てみると、

    PHONE Unlocked
    FRP Unlock
    ←これは、OEMロック解除に連動

    となっており、root状態の時の表示と変わっていません。

     

    それなら、oem relockできるのかと思いましたが、FAILEDとなり、再ロックできませんでした。

    oem get-bootinfoを行ったら、unlockedと表示されました。

     

    この辺は、よくわかりませんが、少なくとも、radikoが聞けていますから、良しとしましょう。Gyaoも問題ありません。

    少し、すっきりできていませんが、もう少し勉強が必要でしょう。

    もしかしたら、リカバリイメージが本来のものと違っているのが、ダメなのかもしれません。

    それとも、いちどroot化したものを明確化させるため、表示だけは元に戻せないのかもしれません。

     

    完全に工場出荷時の状態にさせることはできませんでしたが、実使用上は問題ない状態に戻せましたので、良しとしましょう。

     

    ということで、P9liteでroot化、そして、元の状態に戻すということができました。

     

    肝心のOTGに関しては、もう少し調べてからトライするかもしれません。

    今回の実験で、root化しても元に戻す方法を得られましたから、よほどのことがない限り文鎮化とか、使えない状態になったりはしないという保険を持てましたので。

     

    購入したOTG対応ケーブルは、以下のようなものです。100円とは思えませんね。

    IMG_20170429_152938

    いつか活用できる日が来るとよいとは思っています。

     

    では、また。

    記事へブログ気持玉 / トラックバック / コメント


    P9lite Android 7.0でroot化・・・完了

    2017/05/03 00:05

    何とか復旧できたP9liteですが、Android 6.0でroot化というのも考えたのですけど、やっぱり最新バージョンにしておきたいと思って、7.0にバージョンアップしました。

    でもroot化、というより、USB OTGを使えるようにしたいという気持ちはありますから、また、調査を始めました。
    今度は、間違えないようにAndroid 7.0 Nougatでroot化、TWRPを使った情報に絞り込んでいくと、見つけました。

    Huawei P9 Lite Nougat Root

    という記事です。YouTubeにも動画が上がっていました。インド系の方なのですかね。英語が聞き取りにくいですね。ページの方に説明があるので、そちらを参考にしていきます。YouTubeで英語の字幕を出せるのですね。これなら、大体わかっていいですね。

     

    7.0でやろうと思っているのは、もし、またダメになっても、6.0にダウングレードしてまた元に戻すこともできることを経験済みだからです。前回はぎりぎりセーフでしたけど、そのレベル位に収まってくれれば、どうにかなるでしょう。

     

    Root化の基本的な流れ

    は、次のような感じですね。

    1. Rootファイルとこの方が言われているファイルをSDカードに書き込んでおき、
    2. recovery.imgをリカバリ領域に書き込んで、
    3. 音量上げと電源ボタンを押して起動させ、TWRPを起動させます、
    4. そして、TWRPからSDカードに書き込んでおいたファイルを本体にインストールさせる

    Rootファイルと呼ばれているものは、ダウンロードすると、複数のファイルが入っていて、boot.imgという新しいブートイメージファイルでしょうか、それと、patch.shというパッチ当てのシェルスクリプト、フォルダの中をのぞくと、superuserになるためのファイルと思われるphh.superuserという名前が入っているフォルダのなかにbase.apkというファイルなどが入っていました。

     

    記事を読むと、この方は、P9lite VNS-L21とL31でテストしたとのこと。私のL22と違いますが、調べると、電波の対応がL21と違うのがメインみたいなので、おそらくソフト的には、似ていると信じましょう。

    また、YouTubeのページのタイトルにB360とあったので、何かと思っていたのですけど、ビルド番号っぽいですね。私のL22は、ビルド番号の最後がB361となっていたので、L21のB360の次の番号ですから、そういうものなのかと考えました。

     

    なお、上述のパッチpatch.shの記述には、L22用の記述も見えたので、それなりにケアされているように思えました。

     

    覚悟を決めて、始めましょう。

     

    現在の私のP9liteは、Android 7.0ですけど、

    1. すでに開発者向けオプションは有効化され、
    2. OEMロック解除は有効になっている状態、USBデバッグも有効になっています。

    通常の動作状態になっていますが、USBケーブルでPCと接続され、HiSuiteで接続されている状態になっています。つまりPCからファイルのコピーなどは簡単に行える状態ということです。

     

    まずは、ダウンロードしたElite Kernel for P9 Lite CxxB3xx v5.1.zipをSDカードのルートにコピーしました。

     

    次に、P9liteをfastbootモードに入れます。

    あっと、その前に、HiSuite上で、バックアップを取っておきたいと思います。パスワードで暗号化はせず、全選択で、PCにバックアップします。ちょっと時間はかかりますが、念には念を入れて。

     

    USBで、PCと接続できている状態で、fastbootモードに入れます。そして、ダウンロードしておいたrecovery.imgを書き込みます。

    あれ、FAILEDとエラーメッセージが出ますね。書き込めません。

    image
    何度やってもダメです。前回はそんなこともなかったはずですけど、また、はまってしまったようです。


    少なくとも、fastbootモードの画面上では、ロックは外れていることを確認済みです。でも考えてみると、ダウングレード時にrelockを掛けた後、何もしてません。どうもそこが怪しそうと考えました。

     

    試しに、fastboot oem unlock <code>を実行してみました。

    以前に試したときは、アンロック状態でこのコマンドを入れても、既にアンロック済みと表示が出たのですが、今回は、アンロックするか?という質問の画面に行きました。

    どうも表示状態とは違い、アンロックされていなかったようです。怪しかったところが確かに悪かったようです。

     

    本体は、一旦リセットされました。再度初期化状態に戻りました。また初期化することになって不要になるかもしれませんが、色々初期設定を面倒がらず、ちゃんとやっておきます。さらにHiSuiteで、復元もしました。

     

    さて、仕切り直しです。はてさて、ちゃんと書き込めるのか?

    image

    今度は、ちゃんと無事に書き込めました。

     

    その後、ノーマル状態で、起動も確認できたので、いったん電源を切ります。

     

    USBケーブル抜き、音量上げと電源ボタンを押して、ロゴが出てくる時まで押し続けたところ、ようやく待ちに待ったオープニング画面が現れました。

    そして、まず下の左の画面となりました。

    DSCN0334

    この画面で、下部の丸を右側にスワイプしました。修正するには、スワイプしなさいと書かれていますね。

     

    すると、以下の画面となりました。

    DSCN0335

    画面上、一番上にある、Installを選びます。

     

    そして、インストールファイルを探して、選択するだけなのですけど、/sdcardの下にあるはずのファイルが見えません。
    格納場所が間違っていたのかと、一旦リブートしてみたり、ルート直下に置いたのがまずかったのかと思い、フォルダに入れようと、新たにフォルダを作りましたけど、そのフォルダ自体も見えません。何かカギになっているものがあるはずですけど、わからなかったので、見えていたフォルダにファイルを入れました。今回は、本体のPodcastsというフォルダに入れてみました。


    そして、再度上記写真の場面からInstallを押したあと、表示されるWindowsのエクスプローラみたいなものから、podcastsを探して、開いたら、ちゃんとファイルElite Kernel for P9 Lite CxxB3xx v5.1.zipが見えました。
    多分何らかの権限が関係しているのだと思いますけど、一度きりの作業ですから、深追いは避けたいと思います。

     

    そのファイルをタップして、選択しました。

    その後、画面下部に出てくる、swipe to installの指示に従って、丸をスワイプすると、インストールが開始されました。そして、上部にSuccessfulと表示されました。

     

    いよいよ最後の作業になります。画面下部のRebootボタンを押し、さらに出てきた画面では、TWRPをインストールしますかと聞かますがで、DO NOT INSTALLボタンを押して、リブートしました。

     

    何事もなく、通常通り起動しました。

    1つ変わったことがありました。通常動作時に、fastbootモードに入れるのに、今までは、adb reboot bootloaderとすればよかったのですが、今はエラーとなりfastbootモードにすることができません。
    仕方がないので、音量下げと電源ボタン長押しで対応するしかありません。

     

    まだどうしてよいかわかりませんけど、まず、本当にroot化できたか確認するため、PlayストアからRoot Checker Basicをインストールしてみました。

     

    チェックしてみると、Root化成功しているとメッセージが出ました。

    Screenshot_20170502-191403

    紆余曲折がありましたけど、何とか成功にこぎつけました。Android 7.0でもroot化できました。

    ネットの情報の扱いに注意していたつもりでしたが、バージョン違いで陳腐化しているとは思いませんでした。でも、初めてのAndroid端末で、root化の作業を試行錯誤しながらやれたので、そこそこの知識は得られたので、良しとしましょう。

     

    でも、ここまでは、本来の目的のための序章にすぎないですから、次が本題ですね。

    きりが良いので、いったんここで区切ります。

    記事へブログ気持玉 / トラックバック / コメント


    P9liteの復活!

    2017/05/02 13:23

    前回、書いたように、色々いじっているうちに、とうとう端末はまともな状態でなくなってしまいました。

    工場出荷時の状態に戻そうと思ったのですけど、途中でメモリのパーティションが壊れているので、直すかと聞かれてそうしたら、システムアプリ類の一部が破壊されてしまったようです。

    起動はしたももの

    何度か、起動方法を変えてトライしていたら、幸いなことに起動しました。
    ところが、WiFiのコードを入力するところになったら、なぜかGoogle音声入力しか表示されず、キーボードになりませんでした。もちろん、ネットにつなぐ前なので、音声入力は使えない状況です。
    どうしようもないので、スキップしながら、ホーム画面にはたどり着きましたが、さきほど書いたように少しのアプリだけが画面に表示されている状態で、惨たんたる有様でした。画面上はスカスカ状態で、さびしい状態なので、あぜんとしました。

     

    まずは、キーボードを何とかインストールしたいと思っても、ネットにつなげないので、Google Playにもつなげない状況。

    PCから何とかならないかと思って、接続設定して、USBケーブルをつなぐと、HiSuiteにはつながりました。

    今までなら、ここで、HiSuiteの復元で全アプリをP9liteに再書き込みをして、アプリや、設定を元通りにできたのですけど、今は、Huaweiバックアップアプリがないというメッセージがでて、中断します。システムアプリのバックアップも壊れてなくなってしまったようです。

    非常にあせりました。でも心を落ち着けて、まずは、ネットにつなげられるようにしようと思いました。そのためには、キーボードが使えないとキーを入力できません。

     

    USBでPCと接続して、アプリのインストール

    USB接続状態では、コマンドプロンプトからもアクセスできることは確認できました。

    apkファイルをインストールできる方法があるということを発見しました。

    HiSuiteでバックアップしたファイルの中に、キーボードアプリがないかと思って探したところ、com.google.android.inputmethod.latin.apkというものを発見。何となくそれらしいと思っただけです。

    PC上で、

    >adb install ?r com.google.android.inputmethod.latin.apk

    と入力すると、SuccessのメッセージがPC上で見え、インストールができたようでした。

    P9lite上で操作してみると、キーボードアプリとして使えることができました。

    これにより、WiFiの設定ができ、ネットにはつなぐことができました。

     

    バックアップから復元できず

    そこで、早速Playストアに行き、Huaweiバックアップを探して、インストールしようとしましたが、エラーが出て、インストールできません。再度リセットしてみたり、色々トライしましたが、どうしてもインストールできず、困り果てました。

    もちろん、そのほかのアプリは、手動で、キーボードアプリのように戻すこともできるとは思いますけど、いわゆるシステムアプリがないのは、困ります。たぶん、バックアップされているファイルには含まれていないようだと思われ、将来元に戻せる可能性もありません。

    せっかくの端末をダメにしてしまったかと、修理に出すしかないと思い始めました。

     

    Android 6.0へダウングレード

    ふと、Android 6.0へのダウングレードが、Hauweiから正式にサポートされていることを思い出しました。
    ユーザデータは消えますが、そっくり6.0のシステムに戻してくれるなら、私の端末も元に戻るかもしれないと思いました。既にユーザデータもない状態なので、怖いこともありません。怖いのは、完全に動作しなくなる文鎮化ですね。

    http://consumer.huawei.com/jp/support/mobile-phones/p9lite-jp-sup.htm
    から、マニュアル、中継パッケージ、Android 6.0パッケージをダウンロードしておきます。

     

    マニュアルを読みながら早速やってみます。
    最初に要件を読むと、既存バージョンに対して、ロック解除、Root化が行われていないことが必要と書いてありました。

    Root化は失敗したので、問題ないと思われますけど、ロック解除はしてしまっているので、元に戻さないといけません。

     

    色々調べて、試行錯誤した結果、再ロック (relock)できることがわかりました。これがロック状態と違うのかどうかもわかりません。少なくともlockはできませんでした。

     

    再度ロックかけるには、fastboot oem relock <16桁のコード>とすればよいようです。


    Tips:
    FASTBOOTモードに入れるのに、今まで、電源をオフしてから、電源ボタン+音量downを押すということを苦労してやっていました。長めに押すので、結構面倒ですね。

    でも、P9liteが普通に動作している状態で、USBケーブルをつないだ状態で、PC上で、

    adb reboot bootloader

    と実行するだけで、簡単にFASTBOOTモードに入れることが、ようやくわかりました。これは非常に便利です。
    実は、fastbootコマンドを実行できる状態、つまりFASTBOOTに入ってから、上記をやったことがあったのですが、エラーとなってしまったので、使うのをあきらめていました。使えるのがいつなのかを理解していなかったでした。


    image

     

    この後、fastbootモードにしたところ、

    PHONE Relocked

    FRP Locked

    と、FRPの方は、Lockedのままだったですけど、元に戻す方法がわからなかった(後で、わかりました。設定→開発者向けオプション→OEMロック解除を有効にするを解除すればよかったのでした)ので、この状態で、ダウングレードを開始してみました。結果として、それで問題ありませんでした。

     

    これで、要件は満たしたと思いますので、ダウングレードを実行していきます。

    Step1

    Huaweiの手順書のStep1は、バックアップですけど、ここはスキップしました。すでに本体は、バックアップするようなデータもなかったからです。

     

    次に、

    Step2の中継パッケージバージョンにアップデート

    オフィシャルサイトからダウンロードした中継パッケージのdloadフォルダ、中身は、UPDATE.APPだけですけど、これをSDカードのルートディレクトリに保存します。これは、USBケーブルでPCとつないで、PC上のエクスプローラを使って、コピーしました。

    これで準備完了です。

    電源をオフした状態から、音量+、音量-、電源ボタンの3つを同時に押して強制アップデートモードに入れるとのこと。およそ20秒ほどで、EMUIとinstallingの表示が見えるまで、押し続けました。途中10秒後くらいに、Huaweiのロゴが出ても、それに惑わされず押し続けないといけないと思われます。

    インストールが終わるまで待ちます。

     

    Step3:中継パッケージバージョンを確認

    Step3のため、電源を入れます。起動後のホーム画面は、特に変わりなく、私の端末の悲惨な状況は変わっていませんが、バージョン番号を確認せよということなので、マニュアルに記載の通りのバージョンになっていることを確認しました。うまくいったようです。

    この時、Androidのバージョンは、7.0のまま、EMUIは5.0のままでした。

     

    次に、いよいよ、

    Step4のAndroid 6.0へダウングレード

    します。

    さきほどと同様に、オフィシャルサイトからダウンロードして、同じdloadフォルダ内のUPDATE.APPをP9liteのSDカード上にコピーします。こちらは、2.75GBと非常に大きいファイルですね。(先ほどのファイルは、75MBでした) そのため、SDカードへのコピーに少し時間がかかりました。
    その後、中継バージョンの時と同様に、電源を切った状態から、3つのボタンを同時に押して、強制アップデートを行いました。

    こんどは、少し長めの時間がかかりましたけど、インストールが完了したようです。

    Step5:OS のバージョン番号の確認

    電源を入れてみると、購入直後に電源を入れた時を思い出させるように、初期化手順が始まりました。キーボードも使えています。WiFiの設定、Googleのログインなど、きちんと設定でき、ホーム画面に戻りました。

    そして、バージョンの確認をします。しっかり、Android 6.0、EMUI 4.1.1となっていることが確認できました。画面上のアイコンも、初期に入っているアプリが全部揃っている様子です。

    ツールの中には、バックアップもありました。

     

    USBケーブルで、PCと接続して、HiSuiteの復元を実行してみます。

    バックアップは、Android 7.0で行ったわけですけど、ちゃんと動き出しました。一安心です。

    そして、Android 6.0として、少し前までAndroid 7.0で使っていたアプリが復元されました。Androidのバージョンが違っていても復元できるとはすばらしいですね。2つほど未完了となりました。1つは、天気、もう1つは、迷惑フィルタでということで、実質、問題はなさそうです。

    画面の配置も元通りです。

     

    P9lite復活!

    一時は、どうなることかと思いましたが、何とか元通りになりました。ふー、よかったよかった。

     

    今回、P9liteをAndroid 7.0でroot化したのがまずかったのかもしれません。古い情報では、問題なくroot化できていたようですけど、最近の情報を見ると、7.0ではだめだったという情報が見つかりました。

     

    せっかく6.0にダウングレードしたので、root化に再挑戦してみますかね。

     

    では、また。

    記事へブログ気持玉 / トラックバック / コメント


    P9liteの使いこなし・・・root化できず、それよりひどい状態に。

    2017/05/02 11:32

    P9liteでよくTeamViewerを使います。

    フルHDのディスプレイですから、PCの画面をドットバイドットで表示されるので、非常に良い感じです。

    確かに表示は、5.2型のディスプレイに表示されることになるので、非常に細かくなりますけど、すごい技術ですね。

     

    Team Viewerは、基本的にタッチして操作するわけですが、マウスが使えると、よりWindowsライクに使いこなせるようになって、よいのではと思っていました。

     

    調べてみると、Androidスマホは、OTGがサポートされていて、microUSBから変換コネクタを介してUSB機器、例えばマウス、キーボート、USBメモリなどを、特別なことをしなくても接続して使えるということなので、ぜひやってみたいと思いました。

     

    OTG対応のmicroUSB(オス)-USB-A(メス)ケーブルを調達すれば良いようです。

    今は100円ショップでも売っているという情報を見て、近くのセリアに行ってみましたが、残念ながらありませんでした。そのあと、ちょっとキャンドゥに寄ってみたら、なんと売っているではありませんか。

    早速購入しました。たった100円ですからね。

     

    そして、早速P9liteにケーブルをつないで、USBマウスをつなぎましたが、何も変化がありません。

    調べてみると、な、な、なんとP9liteはOTGをサポートしていないということらしいです。ほとんどの機種ではOTGをサポートしているとの情報だったので、安心していたのですが、思わぬところで、落とし穴にはまってしまいました。やはり格安端末だからですかね。残念。

     

    一方、Bluetoothのマウスをちょっと試せる機会があったので、設定→Bluetooth→BluetoothをONにして、マウスを認識させると画面上にカーソルが出てきて、タップ替わりのマウスクリックで使うことができました。
    当たり前ですけど、ちゃんとBluetoothを通してマウスが使えることを確認できました。

    しかし、残念ながら、TeamViewerにはマウスを認識してもらえませんでした。う〜ん、そうなのか。それはそれで困った自体ですが、タブレットモードならOKとかという情報を見かけたりしたので、マウスを使える環境になってから考えたいと思います。

     

    ところで、OTGサポートかどうかは、設定→メモリとストレージで、USBストレージの項目があればサポートされているらしいのですが、確かにそれらしき表示はありませんでした。

     

    ここであきらめきれないので、再びネットで調べてみました。日本語のサイトではP9liteでOTGは対応できないという情報しかみつかりませんでした。しかし、海外サイトで見つけました。

    How to Enable OTG Support on Huawei P9 Lite

    https://androidtutorial.net/2017/03/02/enable-otg-support-huawei-p9-lite/

     

    デフォルト状態ではサポートされていないので、簡単にOTG対応にできるわけではありません。少し手間がかかります。書かれている情報に基づいて、トライしてみます。

    いくつかのサードパーティのAndroidデベロッパーがOTG化する方法を見つけたと書かれていて、その方法は100%成功したとのこと。

     

    期待が高まります。

     

    必要事項:

    ルート化→始めにブートローダのアンロック

    1. Huaweiからアンロックコードの入手:
      開発者向けオプション:設定→端末情報→ビルド番号を複数回(7回らしい)タップ。これにより、設定内に開発者向けオプションというメニュー項目が現れます。

      P9lite本体のアンロックコードを入手するためHuaweiに登録が必要みたいです。
      以下のページに行き、
      http://emui.huawei.com/en/plugin.php?id=unlock&mod=unlock&action=apply 
      image
      が表示されるので、Huawei IDを持っていなければ、上記キャプチャの一番下にある、Registerを押して、先に登録が必要です。
      以下のような画面が出るので、
      image
      メールアドレス+Verification code(メールアドレス入力後、この欄の右のボタンを押すと、すぐにコードが送られてくる)、パスワードの設定、どこに登録するかJapanはないので、デフォルトのHongKongのままで登録(Registerボタン)を押す。

      すると、以下のような画面に移動しました。
      image
      上に並んでいるメニューからDOWNLOADを押すと、契約条件が英語で表示され、合意するにチェックを入れ、Nextを押すと、以下の画面が出ます。
      image
      各番号の取得の方法は、入力ボックスの右側にの説明の所をクリックすると、表示されます。
      ・Product Serial number=設定→端末情報→端末の状態→製造番号
      ・Product IMEI or MEID: IMEI1をまず入力する。だめだったら、IMEI2。設定→端末情報
      ・Product ID=製品ID:*#*#1357946#*#*に電話を掛けると得られます。音声電話を契約していなくても大丈夫そうです。
      Commitボタンを押すと、同じ画面に、Your unlocking password is : ****************と、16桁の数値が得られます。
    2. 得られたアンロックコードを設定
      Unlockの手順は、上記16桁のコードを取得したCommitボタンの下にある
      Please read the unlocking procedure once you have obtained the unlock password.
      を押して出てくる画面に書いてありました。

      その手順に従って進めます。
      Step 1:
      (1) Huawei Device websiteからphoneドライバをダウンロードして、PC上にインストール。
      特にリンクとかなかったのですけど、検索してそれらしいHiSuite_5.0.1.300_OVE.zipというファイルをダウンロードしました。インストールして、起動したら、新バージョン5.0.2.300_OVEに更新するとあり、再度インストール画面になりました。
      起動すると、USBケーブルで接続するというボタンが見えたので、ボタンを押してからUSBケーブルを接続しました。でも認識されませんでした。
      設定→詳細設定→セキュリティ→HiSuiteからHDBの使用を許可
      としたら、接続が認識され、PC上にP9liteの画面が表示されました。

      (2) ADBツールキット(Google提供)をダウンロードしてPC上にインストール。fastboot.exeが入っているディレクトリを確認しておくこと。 以下は、検索して、これなら大丈夫そうという手順
      ・Jave SEの最新版をダウンロードしてインストール。jdk-8u131-windows-x64.exe
      ・Androidのデベロッパー向けサイトからAndroid SDK本体をダウンロード。将来プログラムの開発もしたいと思っているので、SDK本体だけではなく全部インストールしました。

      起動したら、ウインドウの下の方にあるconfigureからSDK Managerを選びます。
      SDK Toolsのタブで、以下の2つ
      Android SDK Platform-Tools
      Google USB Driver
      をインストールします。後者は、必要か不明でしたが、インストールされていなかったので、インストールしました。

      確認必要なのは、どこにインストールされたかということです。私の場合、以下のディレクトリでした。
      C:\Users\(ユーザ名)\AppData\Local\Android\sdk\platform-tools
      にadb.exeにあればよいようです。また、同じフォルダにfastboot.exeもありました。これらは、今後の作業に必要な重要なものです。どこからでもこれらの実行ファイルを使えるように、環境変数のPATHを変更しておくとよいかと思います。

      Step 2: アンロック
      設定→開発者向けオプション→OEMロック解除を有効にする
      PINを入力して有効化。最初このPIN何だったか思いつかなかったのですけど、電源を完全に切った後に起動したときに入力するPINと気づき設定できました。
      ここは、実際には、以下をトライして問題が生じてから気づきましたので、私が実行した手順とは正確には異なりますけど、ここに書いておきます。
      (1) デバイスをfastbootモードに入れる:
      デバイスの電源を切ります。その後、最低10秒間、電源と音量下げるボタンを押し続けて起動します。
      P9lite場合、電源ボタンを少し長押しして、画面に表示される電源を切るをタップし、再度タップを促す画面(電源をOFF)が出てきて、タップすると、電源が切れました。また、電源入れるときは、なぜかわかりませんけど、USBケーブルを接続していないと、FASTBOOT画面になりませんでした。
      そうすると、FASTBOOT&RESCUE MODEと表示された画面が出てきました。 これを出すまでにずいぶん、試行錯誤して、時間もかかりました。
      DSCN0329
      画面下の方にLockという表示が見えますね。

      (2) PCと接続:
      USBケーブルでPCと接続します。私の場合、すでに接続済みですけどね。
      PC上では、コマンドプロンプトを起動して、上記のadb.exeがあるディレクトリに移動しておきます。PATHを通しておけば、どこにいても問題ないと思います。
      そして、fastboot.exe devicesと入力してEnterを押し、接続状態の確認をします。
      番号(製造番号) fastboot
      と表示されれば、適切に接続されているようです。
      image
       
      (3) unlockコマンドの実行:
      コマンド プロンプト上で、以下のコマンドを入力します。
      fastboot oem unlock ????????????????
      ??は、Huaweiのページで取得した16桁のunlock用パスワードです。
      image
      P9liteの画面が変わりました。
      DSCN0330
      FRPの所がUnlockになりました。これは写真で画面を撮ったのですけど、この時のものだったか自信がありません。すいません。
      (追記) このFRPは、開発者向けオプションで、OEMロック解除を有効にすることで、Unlockになるということがわかりました。最初の写真は、それをしないで、Fastbootに入ったときのもので、こちらは、ちゃんとOEMロックを外した時の写真でした。

      (4) デバイスのブートローダーがアンロックするのを待ちます。
      アンロックするかどうか、Yes/Noを音量ボタンで選択(赤字が選択されている状態)して、電源ボタンを押します。
      画面に警告されているように、全個人データが消去されます。(工場出荷状態にリセット)
      DSCN0333
      まっさらな状態になるので、画面の指示に従って設定を行っていきます。
      HiSuiteでバックアップを行ったので、復元もしてみました。最初画面の指示で、たぶんGoogleがバックアップしたものを復元しましたが、画面上のアイコンの並びはめちゃくちゃになってしまいました。しかし、HiSuite上で復元したら、それも含めてきれいに直りました。ただし、アプリの復元のところで、エラーが発生しました。ESエクスプローラーが怪しそうなので、それだけ復元するのをやめてみたら、復元が成功しました。

      (5) アンロックに成功しているか確認:
      これは、上述の(1)(2)と同様にして、
      fastboot oem get-bootinfo
      をPC上で実行して、メッセージがunlockedとなっていたら成功しているということになります。
      そうしなくても、P9lite上は、FASTBOOT&RESCUE MODEの画面で、
      PHONE Unlocked
      FRP Unlock
      となっているので、確認するまでもないのかもしれません。
      通常の画面に戻すため、電源ボタンを長押ししたら、再起動がかかります。

      これでようやくroot化が完了しました。と思ったら、まだアンロックできただけでした。
    3. TWRPのインストール
      TWRPの導入が良いらしいので、入れてみます。
      以下のページに従って作業していきます。6まで完了していますね。
      https://forum.xda-developers.com/huawei-p9lite/help/twrp-root-huawei-p9-lite-t3401215

      手順の7から
      https://mega.nz/#!FtB2gZKL!vEa351gke...zlFdOMGMmucb2g
      から??G9青春版EMUI4.1_TWRP3.0.2.rarをダウンロードしました。ファイル名の中国漢字がよろしくないのかそのままでは展開できませんでしたので、ファイル名を変更して展開すると、3つファイルが入っていましたが、目的のものは、recovery_twrp.imgらしいです。
      また、Fastbootモードに入って、以下を実行します。
      fastboot flash recovery recovery_twrp.img
      これは、TWRPをリカバリ領域に書き込んでいるようです。
      OKAYと表示されていますね。問題なければ、リブートします。
      fastboot reboot
      以下は、そこまでの画面キャプチャ。
      image

      して、もう一度電源を切ります。

      SuperSuをダウンロード。これは、展開しないこと。
      今回は、SR3-SuperSU-v2.79-SR3-20170114223742.zipがダウンロードできました。

      USBケーブルを抜き、音量上げと電源ボタンを押して、TWRPに入れとのこと。この時、手を離すタイミングが大切みたいです。ロゴが出るのと同時に手を離す必要があるとのこと。
      でも、TWRPが起動しません。何回かトライしましたが、だめでした。recoveryデータに問題あるかもしれないと思い、調べてみると、しましたが、だめでした。recoveryデータに問題あるかもしれないと思い、調べてみると、別のサイトが見つかりました。
      TWRP-3.0.2-0-hi6250-v4.zip
      バージョンは、同じ3.0.2ですけど、同じファイルではなさそうです。再度書き込んで電源を落として、音量upと電源ボタンを押して、ぶるっとして、Huaweiのロゴが出たら、手を離すと、開始したとのメッセージが出た状態で、その先のTWRPの画面に移行しません。

    ここから長い試行錯誤が始まりました。ファクトリリセットとかも実行したり、そして、、、
    ほぼ文鎮化に近い状態に。何とか起動はしたものの、キーボードもでず、WiFiの設定もできず、システムアプリのバックアップアプリがなくなって、HiSuiteから復元も機能しなくなってしまいました。ネットもつながらず、キーボードもなし、入力は音声入力だけが残っていますが、ネットにつながらないので、あっても機能せずの状態。にっちもさっちもいかないような感じです。

    何がまずかったかというと、起動時にパーティションがおかしいから直すかというようなメッセージが出て、そちらを選択したため、システムファイルを破壊してしまったらしいです。

    さらに、検索範囲を最近に絞ってみていたら、Android 7.0 (これは私のP9liteのバージョン)では、TWRPが動かないとかいう情報も見つかりました。3月くらいまでは、6.0でしたから、それに基づいた情報でひたすら試行錯誤していたのでした。

    現在、意気消沈の状態ですけど、まだ、完全に動かなくなったわけではありませんから、方法を探りたいと思います。誰かのご参考になれば。

    記事へブログ気持玉 / トラックバック / コメント


    グラフィックLCDのプログラミング その4

    2017/03/26 12:39

    前回までで、全部のソースがそろいました。

     

    では、コンパイルしてみましょう。


    Memory Summary:
        Program space        used  1FF1h (  8177) of  2000h words   ( 99.8%)
        Data space           used   24Ch (   588) of   400h bytes   ( 57.4%)
        EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
        Data stack space     used     0h (     0) of   186h bytes   (  0.0%)
        Configuration bits   used     2h (     2) of     2h words   (100.0%)
        ID Location space    used     0h (     0) of     4h bytes   (  0.0%)


    You have compiled in FREE mode.
    Using Omnicient Code Generation that is available in PRO mode,
    you could have produced up to 60% smaller and 400% faster code.
    See http://www.microchip.com/MPLABXCcompilers for more information.

    make[2]: Leaving directory 'D:/My_Documents/PIC/GraphicDispUnit/DisplayUnit.X'
    make[1]: Leaving directory 'D:/My_Documents/PIC/GraphicDispUnit/DisplayUnit.X'

    BUILD SUCCESSFUL (total time: 8s)
    Loading code from D:/My_Documents/PIC/GraphicDispUnit/DisplayUnit.X/dist/default/production/DisplayUnit.X.production.hex...
    Loading completed


    という感じで、成功しました。

     

    PICkit2で、書き込みを行い、動作させると、最初に、全96文字の半角英数が表示され、オープニングのメッセージが表示された後、以下のような表示となりました。成功です。

    PIMG_20170326_115129_thumb[5]_thumb

    8ドット角の漢字も読めますね。

    でも、表示速度が意外と遅い感じとなりました。

    PICの速度を32MHz化とか行って、高速化が必要そうです。

     

    しかし、問題は、プログラムのサイズです。上記に示したように、すでに8177ワード、99.8%の大きさとなっており、ほとんど追加の余地はありません。上述したようにまだ、改善余地は色々あるのに。。。

     

    プログラム領域が8Kワードというのは、色々やるには、やっぱり狭いですね。特にフリーの環境で行う場合は、最適化が十分されないので、以前も書いたように苦しいと思います。PRO版なら、60%も小さくなるって、魅力的ですね。それより、やっぱり、64Kバイト、32Kワードもある18F26K22を使うのがよいかな。28ピンなので、ちょっと大きいのが玉に瑕。今のブレッドボードの配置だと載せきれませんね。

     

    価格も若干高めだしと思ったら、今は、260円(秋月電子)なのですね。以前購入した時は、330円でしたからずいぶん値下がりしています。16F1829は160円ですから100円の違いですね。

    でも、この1個だけ購入するというのも、送料を考えると得策ではありませんから、当面見送りですかね。

     

    まあ、悩みながら趣味を楽しみたいと思います。今回は、ここまで。

    記事へブログ気持玉 / トラックバック / コメント


    グラフィックLCDのプログラミング その3

    2017/03/26 12:33

    いよいよ最後のファイルです。lcdg.cは以下となります。

    #include "mcc_generated_files/mcc.h"
    #include "lcdg.h"
    #include "font.h"


    /*
    * AQM1248A-RN 48x128ドット SPI接続グラフィックLCD
    * 制御ルーチン
    */

    //------ Command Write -----
    void LCDgCmd(uint8_t data) {

        LCD_CSB_SetLow();   // CSB=0にして、チップセレクト
        LCD_RS_SetLow(); // RS=0にして、コマンド指定
        SPI2_Exchange8bit(data);    // data書き込み
        LCD_CSB_SetHigh();  // チップ選択解除して、終了
    }

     

    //------ Command Data -----
    void LCDgData(uint8_t data) {

        LCD_CSB_SetLow();   // CSB=0にして、チップセレクト
        LCD_RS_SetHigh(); // RS=1にして、データ指定
        SPI2_Exchange8bit(data);    // data書き込み
        LCD_CSB_SetHigh();  // チップ選択解除して、終了
    }

     

    /*
    * AQM1248A グラフィック液晶の初期化
    * メーカー推奨手順
    */
    void LCDg_init() {

        LCDgCmd(0xae); // Display = OFF
        LCDgCmd(0xa0); // ADC = normal
        LCDgCmd(0xc8); // Common output = reverse
        LCDgCmd(0xa3); // bias = 1/7

        // 内部レギュレータを順番にON
        LCDgCmd(0x2c); // power control 1
        __delay_ms(2);
        LCDgCmd(0x2e); // power control 2
        __delay_ms(2);
        LCDgCmd(0x2f); // power control 3

        // コントラスト設定
        LCDgCmd(0x23); // Vo voltage resistor ratio set
        LCDgCmd(0x81); // Electronic volume mode set
        LCDgCmd(0x1c); // Electronic volume value set

        // 表示設定
        LCDgCmd(0xa4); // display all point = normal
        LCDgCmd(0x40); // display start line = 0
        LCDgCmd(0xa6); // display normal/reverse = normal
        LCDgCmd(0xaf); // display = ON

    }

     

    /*
    * 1バイト文字表示
    * data= ASCIIコード(1バイト、0x20-0x7f)をもらう
    */
    void LCDg_chr(uint16_t data) {
        int ii;

        for (ii = 0; ii < 8; ii++) {
            LCDgData(font[data - 0x20][ii]);
        }
    }

     

    /*
    * 2バイトのShift JISも対応できるように
    */
    void LCDg_str(char *str) {
        uint16_t kanji;


        while (*str) { //文字列の終わり(00)まで継続
            if (*str < 0x20) {
                //特殊文字
                switch (*str) {
                    case 0x0a: break;
                }
            } else if (*str < 0x80) {
                LCDg_chr(*str++); //1文字出力し、ポインタ+1
            } else {
                // 2バイト文字
                kanji = *str;
            }
        }

    }

     

    /*
    * 128x48ドット
    * ドット単位で、X,Y座標を引数とする
    * ただし、Y方向は、8ドット単位に丸められる
    */
    void LCDg_pos(uint8_t x, uint8_t y) {
        // カラムアドレス設定:X方向は、ドット単位
        LCDgCmd(0x10 | (x >> 4));
        LCDgCmd(x & 0x0f);

        // ページアドレス設定:Y方向は、8ドット単位
        LCDgCmd(0xb0 | (y >>3));


    }

     

    /*
    * Screen配列に格納されている文字コードに従い、画面表示
    */
    void LCDg_Update() {
        char ii, jj, kk;
        uint8_t fontdata[8];
        //4ビットのドットデータを縦2倍に変換するテーブル
        const char trans[] = {0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,
            0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff,};

        switch (YscrMax) {
            case 3: //縦2倍モード
                for (jj = 0; jj < YscrMax; jj++) {
                    LCDg_pos(0, jj * 16);
                    for (ii = 0; ii < XscrMax; ii++) {
                        for (kk = 0; kk < 8; kk++) {
                            LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] & 0x0f]);
                            if (XscrMax == 8)
                                LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] & 0x0f]);
                        }
                    }
                }
                for (jj = 0; jj < YscrMax; jj++) {
                    LCDg_pos(0, jj * 16 + 8);
                    for (ii = 0; ii < XscrMax; ii++) {
                        for (kk = 0; kk < 8; kk++) {
                            LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] >> 4]);
                            if (XscrMax == 8)
                                LCDgData(trans[font[Screen[ii][jj] - 0x20][kk] >> 4]);
                        }
                    }
                }
                break;
            default:
                for (jj = 0; jj < YscrMax; jj++) {
                    LCDg_pos(0, jj * 8);
                    for (ii = 0; ii < XscrMax; ii++) {
                        if (Screen[ii][jj] < 0x80) {
                            LCDg_chr(Screen[ii][jj]);
                            //Xアドレスは自動的にインクリメントされる
                        } else {
                            ReadFontData(Screen[ii][jj]*256+Screen[ii+1][jj], fontdata);
                            ii++;
                            for (kk = 0; kk < 8; kk++) {
    //                            LCDgData(fontdata[kk]);
                                LCDgData(fontdata[kk]);
                            }

                        }
                    }
                }
                break;
        }
    }


    /*
    * テキスト表示のクリア
    * Screen配列に空白を書き込み、Updateする
    */
    void LCDg_cls() {
        int ii, jj;

        for (jj = 0; jj < 6; jj++) {
            for (ii = 0; ii < 16; ii++) {
                Screen[ii][jj] = 0x20;
            }
        }
        LCDg_Update();
        // 画面消去した後は、カーソル位置を0,0にする
        LCDg_setCursorPos(0, 0);
    }

     

    /*
    * カーソル位置設定
    */
    void LCDg_setCursorPos(char x, char y) {
        ScreenPosX = x;
        ScreenPosY = y;
    }

     

    /*
    * Screen配列に文字コードを書き込み、画面を更新
    *
    * 画面いっぱいになったら、スクロールする
    * カーソル位置を意識せずに、一種の表示ターミナルとして使用可能
    */
    void LCDg_print(char *str) {
        int x, y; 

        while (*str) {
            if (ScreenPosY >= YscrMax) {
                // スクロールをここに置くことで、最終行が空行に見えることがなくなる
                //Screenのデータを1行スクロールアップ
                for (y = 0; y < YscrMax - 1; y++)
                    for (x = 0; x < XscrMax; x++)
                        Screen[x][y] = Screen[x][y + 1];
                //最終行のデータをクリア
                for (x = 0; x < XscrMax; x++)
                    Screen[x][y] = ' ';
                ScreenPosY--;
            }
            switch (*str) {
                case '\n':
                    ScreenPosX = 0;
                    ScreenPosY++;
                    break;
                default:
                    Screen[ScreenPosX][ScreenPosY] = (char) *str;
                    ScreenPosX++;
                    if (*str >= 0x80) {
                        *str++;
                        Screen[ScreenPosX][ScreenPosY] = (char) *str;
                        ScreenPosX++;
                    }
                    if (ScreenPosX >= XscrMax) {
                        ScreenPosX = 0;
                        ScreenPosY++;
                    }
            }
            *str++;
        }
        LCDg_Update();
    }

     

    /*
    * 文字サイズの設定
    */
    void LCDg_setSize(char size) {
        switch (size) {
            case 2: // 縦2倍サイズ
                YscrMax = 3; //行数
                XscrMax = 16; //文字数
                break;
            case 4: // 縦横2倍サイズ
                YscrMax = 3; //行数
                XscrMax = 8; //文字数
                break;
            default:
                YscrMax = 6; //行数
                XscrMax = 16; //文字数
                break;           
        }
    }

     

    void LCDg_hex(uint8_t num) {

        LCDg_chr(hex[num >> 4]);
        LCDg_chr(hex[num & 0x0f]);
    }

    このファイル内では、LCDディスプレイの初期化ルーチン、実際にコマンド、データを送信するルーチンが記載されています。それに加えて、表示操作を簡単にさせるための関数が定義されています。

    関数名をご覧になれば、大体何をやっているかは想像がつくと思います。

    将来を見越して、色々仕込みは行っていますが、今は、美咲フォントと半角文字を等倍で表示する部分しか動かしていないことにご注意ください。

    なお、半角も8x8ドットと、漢字の全角と同じサイズになってしまっているので、1行に半角16文字を表示できるようにScreen変数を持っていますが、漢字の場合、2バイトコードなので、8文字しか表示されません。

    単純にScreen変数をuint8_tからunit16_tに変更したらよいはずですけど、コードサイズオーバーとなり、コンパイルできない状況なので、後日の課題としたいと思っています。

    半角文字をきちんと漢字の半角に、つまり美咲フォントを使う場合は、4x8ドット文字を用意することも、要検討です。

     

    以上で、すべてのソースコードの情報を提示できたと思います。

     

    とここで、また、サイズ制限になってしまったので、最後のまとめは、次回に回します。

    記事へブログ気持玉 / トラックバック / コメント


    グラフィックLCDのプログラミング その2

    2017/03/26 12:23

    早速、前回から引き続きソースの提示を行います。

    以下は、font.cのソースとなります。

    /*
    * フォントデータの構造
    * データ形式:マルチバイトの変数は、リトルエンディアンで書き込む
    * ヘッダ部:64バイト分
    *  0x00: xFD (Font Dataを示す)
    *  0x01: 0
    *  0x02: ヘッダサイズ=0x0040 (2バイト)
    *  0x08: フォント名 (8バイト) bdfのFONTの最初の- -に囲まれている部分を抽出
    *  0x10: フォントのドット幅
    *  0x12: フォントのドット高さ
    *
    * インデックス部:256バイト
    * SJISの第1バイトの0x80-0x9f、0xe0-0xffに対して、各4バイトのアドレス
    * 0x40:上位バイト0x80のデータ先頭アドレス
    * 0x44:0x8140のデータが格納されている先頭アドレスをファイル先頭から見た場所
    * …
    *
    * 実際のフォントデータ(SJIS漢字コードの2バイト目=0x40?)
    * アドレス0x0140から、データが格納される。
    * そこに最初の漢字コード0x8140(全角スペース)のデータが格納される。
    * 各文字のフォントデータが並ぶ。データ長は、16x16ドットフォントなら、
    * 32バイト。
    * 第2バイト0x40から開始されていると想定されているが、定義ない文字コードの場合は
    * 0データが格納されていて、格納アドレスが規則的に並ぶようにしてある。終わりは任意。
    *
    */

    /*
    * 2017/3/13現在、32GBのSDHCカードのルートに以下の3つのフォントファイルが格納
    * misaki.data
    * jiskan16.data
    * jiskan24.data
    *
    * 上記に合わせた半角用データは、これから準備
    *
    */

     

    #include "mcc_generated_files/mcc.h"
    #include "font.h"
    #include "pff.h"
    #include "lcdg.h"   //デバッグ用
    #include "main.h"

     

    void word2str(WORD code, char *str) {

        str[0] = hex[code >> 12];
        str[1] = hex[(code >> 8) & 0x0f];
        str[2] = hex[(code >> 4) & 0x0f];
        str[3] = hex[code & 0x0f];
        str[4] = '\0';
    }

     

    /*
    * code: 2バイトShift JISコード
    * data: フォントのデータ
    */
    void ReadFontData(uint16_t code, uint8_t *data)
    {
        char header[64];
        DWORD ofsAdd;   //32bit
        DWORD add1stCode;   //上位バイト毎に格納されているオフセットデータの場所を保持
        WORD headerSize;
        UINT br;
        char str[8];
        int size;   //1文字当たりのサイズ(バイト)
        int kk;

        // ファイルを開き、データを読み出す
        // misaki.datを開く
        if (pf_open("misaki.dat") == FR_OK) { // Open or create a file
    //            LCDg_setCursorPos(0, 1);
    //        LCDg_print("\nMisaki OK\n");
            pf_read(header, 64, &br); //ヘッダデータ取り込む
            //ヘッダサイズ+(漢字上位バイト-0x80)*4のアドレスへシーク
            if (code < 0xe000) {
                //上位バイトが0x80-0x9fの時
                add1stCode = ((code >> 8) - 0x80)*4;
            } else {
                //上位バイトが0xe0-0xffの時
                add1stCode = ((code >> 8) - 0xc0)*4;
            }
            headerSize = header[2] + header[3]*256; //ヘッダのサイズ。今は64バイト
            add1stCode += headerSize;
           
    /*
            //debug用
            word2str(add1stCode & 0xffff, str);
            LCDg_print("ad=");
            LCDg_print(str);
    */     
            if (pf_lseek(add1stCode) == FR_OK) {
                //フォント格納アドレスを取得
                if (pf_read(&ofsAdd, 4, &br) == FR_OK) {
    /*
            word2str((ofsAdd >> 16), str);
            LCDg_print(str);
            word2str((ofsAdd & 0xffff), str);
            LCDg_print(str);
    */             
           
                    //対象の文字コード上位バイトの先頭のデータが格納される4バイトのアドレスを取得
    //                ofsAdd = (code & 0xff - 0x40) * header[0x10] * header[0x11] / 8;
                    size = header[0x10] * header[0x11] / 8;
                    ofsAdd = ofsAdd + ((code & 0xff) - 0x40) * size;
                    if (pf_lseek(ofsAdd) == FR_OK) {
                        /*
            word2str((ofsAdd >> 16), str);
            LCDg_print(str);
            word2str((ofsAdd & 0xffff), str);
            LCDg_print(str);
                         */
                       
                        if (pf_read(data, size, &br) == FR_OK) {
                            /*
                            for (kk = 0; kk < 8; kk++) {
                             str[0] = hex[data[kk] >> 4];
                                str[1] = '\0';
                                LCDg_print(str);
                                str[0] = hex[data[kk] & 0x0f];
                                LCDg_print(str);
                            }
                             */
                        }
                       
                    }
                   
                }
            }
            /*
            if (pf_read(buff, 8, &br) == FR_OK) {
    //                LCDg_setCursorPos(0, 0);
                LCDg_print(":Read OK\n");
    //                LCDg_cls();
    //                LCDg_setCursorPos(0, 0);
                buff[6] = '\0';
                LCDg_print(buff);
                LCDg_print("...");
            }
             */
            /*
                        if ((Fil.fsize != 0) && (pf_lseek(&Fil, Fil.fsize) != FR_OK)) goto endSD; // Jump to the end of the file /
            //            pf_write(&Fil, "Hello world! This is text message written to sd card\r\n", 54, &bw); // Write data to the file /
            endSD:
                        //pf_close(); //pfにはclose関数がない
             */
        }
    }

    ここで行っているのは、ReadFontData()関数で、指定されたSJISのコードをもとに、misaki.datに格納されているフォントデータを呼び出し、引き渡すことです。美咲フォントは8x8ドットフォントなので、8バイトのデータを読み出して渡しています。

    また、このファイルにフォントファイルの構造が記載されています。それに従い、SDカードから必要な文字のデータを読み出しています。

    当初、ファイルの読み出しがどうもうまくできませんでした。 調べてみると、Petit FAT File Systemは、昔のMS-DOSと同様に、ファイル名の前提として、8文字+3文字の形式を想定しているみたいで、拡張子をdataのように4文字もあると適切な動作がされないようです。以前に実験した時は、test.txtというファイル名を使っていたので、気が付かなかったのでした。上記ソースでは、misaki.datとファイル名を変えていますが、まだ手付かずのものは、jiskan16.dataという感じになっているので、改造される方は、ご注意下さい。

     

    最後のLCD関係のソースです。

    lcdg.hから。

    #ifndef LCDG_H
    #define    LCDG_H

    #ifdef    __cplusplus
    extern "C" {
    #endif


    // グラフィックLCD用 1バイトキャラクタデータ 8x8ドット
    // $20?$7Fまで定義
    // bmpファイルから、perl bmp2txt.pl [bitmap.bmp] で生成する
    const char font[][8] = {
            {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}, // ' '
            {0x00, 0x00, 0x2f, 0x2f, 0x03, 0x00, 0x00, 0x00,}, // '!'
            {0x00, 0x07, 0x03, 0x00, 0x07, 0x03, 0x00, 0x00,}, // '"'
            {0x08, 0x3a, 0x3f, 0x0b, 0x3a, 0x3f, 0x0b, 0x02,}, // '#'
            {0x04, 0x2e, 0x2a, 0x7f, 0x2a, 0x3a, 0x10, 0x00,}, // '$'
            {0x26, 0x35, 0x1b, 0x0c, 0x36, 0x2b, 0x19, 0x00,}, // '%'
            {0x18, 0x3a, 0x27, 0x2d, 0x16, 0x18, 0x24, 0x00,}, // '&'
            {0x00, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,}, // '''
            {0x00, 0x00, 0x1e, 0x3f, 0x21, 0x00, 0x00, 0x00,}, // '('
            {0x00, 0x00, 0x21, 0x3f, 0x1e, 0x00, 0x00, 0x00,}, // ')'

     

    (以下$7fのコードまで定義続きますが、ブログ制限のため、省略させて下さい)

     

        };

     

    uint8_t Screen[16][6]; //16文字x6行分のキャラクタコードを格納
    char ScreenPosX, ScreenPosY;    //カーソルX,Y座標
    char XscrMax;
    char YscrMax;

     

    // LCDの画面を1枚の画面と見立てて表示させる方法と
    // 単なるターミナルのように、どんどんスクロールさせて表示させる方法の
    // 2通りの使い方が想定される。

    //-------- コマンド出力 --------------------------------------
    void LCDgCmd(uint8_t data);
    void LCDgData(uint8_t data);

    //-------- 画面消去 ----------------------------------------------
    void LCDg_cls();

    //-------- カーソル位置指定 --------------------------------------
    void LCDg_pos(uint8_t x, uint8_t y);    //ドット座標を想定
    void LCDg_setCursorPos(char x, char y); //文字座標を想定

    //-------- カーソル位置に1文字表示 -----------------------------
    void LCDg_chr(uint16_t data);

    //-------- 文字列出力 -----------------------------------------
    // 0x0aで改行
    void LCDg_str(char *str);
    void LCDg_print(char *str);
    void LCDg_hex(uint8_t num);

    //-------- 図形描画 --------------------------------
    //LCDに書き込んだデータは読み出せないので、PIC側で保持しておかないと、重ね書きが
    //できないため、表示データをPIC上でバッファとして持っていないといけない。
    void LCDg_line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
    void LCDg_box(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2);
    void LCDg_reverse(uint8_t rev);    //画面反転 1:反転、0:ノーマル

    //-------- 初期化 --------------------------------------
    void LCDg_init();
    void LCDg_setSize(char size);   //オリジナルフォントを2倍とかさせる
    void LCDg_setFont(char font);
    void LCDg_Update();
    void LCDg_scroll(char line);    //8ドット=page単位でスクロール


    #ifdef    __cplusplus
    }
    #endif

    #endif    /* LCDG_H */

    このファイルでは、グラフィックLCDに表示させるためのヘッダ情報が書かれています。

    半角の8x8ドットフォントの定義も行っています。

    文字を表示させるため、画面に表示する文字コードを格納しておく、バッファとしてScreenという配列変数を定義しています。1文字は、画面上の8x8ドットに対応していることを想定しています。

    文字を表示するには、このScreen変数に文字コードを格納して、表示は、このScreen変数を見て更新する形と考えました。そうすると、スクロールする時、変数内のコードを移動させて、表示を更新するだけで済みますので。

    本当は、文字コードではなく、グラフィックとして表示するデータそのものを持っておきたいと思っています。ただし、その場合、メモリが128ドットx48ドット/8ビット=768バイトという大きな変数が必要です。今回使用したPIC16F1829は、DataメモリがSRAMで1Kバイトと書かれており、プログラムできるかよく考える必要がありそうなので、まず動作検証が目的の今回は上記の仕様としています。

    それは、LCDから描画を行ったデータを読み出せない仕様だからです。元データを残したまま、一部の表示を変更するためには、元のデータが必要なので、そこが読み出しができないならば、データのコピーを持っている必要があります。少し残念な仕様なのでした。

     

    残りは、これから提示するlcdg.cで定義される関数のプロトタイプ宣言がされています。

     

    いよいよ最後のファイルとなりましたが、サイズオーバーになってしまったので、ここで一旦切ります。

    なお、lcdg.h内の半角フォントの定義も削除しないと、規定サイズに入らなくなったので、削除しています。ご了承ください。コピーして使われる方は、定義を忘れないようにお願いします。

    記事へブログ気持玉 / トラックバック / コメント


    グラフィックLCDのプログラミング その1

    2017/03/26 10:52

    ここから、実際にプログラミングを行っていきます。

     

    まずは、SDカード関連のところから。

    基本ルーチンは、この前実験したSDカード用ルーチンを使えばよいのですけど、0から作る感じで書いていきたいと思います。

     

    Petit FAT File System Moduleからヘッダファイルとしては、diskio.h、integer.h、pff.h、pffconf.hをコピーします。

    ソースファイルは、diskio.c、pff.cが必要となります。

     

    これらのファイルのうち、変更しなければならないのは、diskio.cだけです。

    CSピンのコントロールのため、ファイルの最初にあるSELECT()、DESELECT()の定義文を変更します。

     

    今回の場合、以下のようにしました。

    #define SELECT()    SD_CS_PORT=0 //LATC3 = 0     /* CS = L RC3に変更 */
    #define DESELECT()  SD_CS_PORT=1 //LATC3 = 1     /* CS = H RC3に変更 */
    #define MMC_SEL     !SD_CS_PORT  //!LATC3        /* CS status (true:CS == L) */


    CS用の信号は、SD_CSという名称にしましたが、そこに_PORTを付ける必要があるみたいです。

    どこで、それがわかったかというと、ヘッダファイルディレクトリの下に生成されているMCC Generated Filesというディレクトリの下に、pin_manager.hがあり、その中を見ると色々な定義があるので、探してみてください。

     

    ところで、LATとPORTの違いを正しく理解できていないかもしれません。元ファイルは、LATC3という記述だったのに、私は、PORTで定義しています。同じ定義にするなら、SD_CS_LATにすべきかもしれません。これは、あとで気づいたのですけど、PORTという設定でも、動いているので、そのままとしておきます。アドバイスを頂けると助かります。

     

    プログラムの本体を作ります。

    ほかのPICからの表示命令をもらって表示させる予定ですが、デバッグを簡単にするため、まずは、このハード単体で、漢字を含む文字を表示させるようにすることを目標とします。

     

    作成するファイルは、main.c、lcdg.c、font.c、main.h、lcdg.h、font.hの計6つとなります。

     

    ここからは、説明するのではなく、プログラムを示していくことを主体としたいと思います。また、ファイル先頭に自動的に挿入されるコメント類は省略して、文字数制限をできるだけ回避したいと思います。

     

    まずは、main.hから。

    #ifndef MAIN_H
    #define    MAIN_H

     

    #ifdef    __cplusplus
    extern "C" {
    #endif

     

    //グローバル変数
    FATFS FatFs;    /* FatFs work area needed for each volume */
    BYTE buff[16];
    UINT br;


    #ifdef    __cplusplus
    }
    #endif

     

    #endif    /* MAIN_H */

    重要なのは、グローバル変数を定義している3行だけですね。

     

    次は、main.cです。

    #include "mcc_generated_files/mcc.h"
    #include "lcdg.h"
    #include "pff.h"
    #include "font.h"
    #include "main.h"


    /*
    * シリアル転送されたコマンドにより、各種情報を表示する
    * 機能:
    * ・文字表示
    * ・スクロール
    * (・図形描画)
    * ・コントラスト変更 必要かどうか不明?
    *
    * AQM1248A-RN   48x128ドットLCD
    * 1: VDD      3.3V
    * 2: /CS      ←LCD_CSB
    * 3: /RESET オープン
    * 4: RS       ←LCD_RS
    * 5: SCLK     ←SCK2
    * 6: SDI      ←SDO2
    * 7: GND
    *
    * SDカード (SPIモード)
    * 1: CS       ←SD_CS
    * 2: DI       ←SDO1
    * 3: VSS1
    * 4: VDD      3.3V
    * 5: SCLK     ←SCK1
    * 6: VSS2
    * 7: DO       →SDI1
    *
    * PIC16F1829
    *                   _________
    *              VDD |1      20| VSS
    *      LCD_RS  RA5 |2      19| RA0  DAT
    *      LCD_CSB RA4 |3      18| RA1  CLK
    *            *MCLR |4      17|
    * from ext. RC5 RX |5      16|
    *                  |6      15| RC1 SDO2 LCD_SDI
    *        SD_CS RC3 |7      14|
    *                  |8      13| RB4 SDI1 SD_OUT
    *   SD_IN RC7 SDO1 |9      12| RB5 SDI2
    *LCD_SCLK RB7 SCK2 |10     11| RB6 SCK1 SD_CK
    *                   ---------
    * LCDとPIC間は、SPI2で接続、SDカードとの間は、SPI1で接続
    * ターゲットのPICと本表示システムとの間は、EUSARTで接続
    */

     

    /*
        Main application
    */
    void main(void) {
        int ii;
        char st[2] = " ";
        uint8_t x, y;
        uint8_t data;
        //    char currentX, currentY;
        uint8_t fontdata[8];

     

        // initialize the device
        SYSTEM_Initialize();

     

        // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
        // Use the following macros to:

        // Enable the Global Interrupts
        //INTERRUPT_GlobalInterruptEnable();

        // Enable the Peripheral Interrupts
        //INTERRUPT_PeripheralInterruptEnable();

        // Disable the Global Interrupts
        //INTERRUPT_GlobalInterruptDisable();

        // Disable the Peripheral Interrupts
        //INTERRUPT_PeripheralInterruptDisable();


        // グラフィックLCDの初期化
        LCDg_init();
        LCDg_cls();

     

        // 8x8ドット表示のデフォルト
        LCDg_setSize(0);

        //  
        //    LCDg_font();
        LCDg_pos(0, 0);

     

        //全文字を表示させる
        for (ii = 0; ii < 96; ii++) {
            LCDg_print(st);
            st[0]++;
        }

     

        __delay_ms(1000);
        __delay_ms(100);

     

        LCDg_cls();
        LCDg_setSize(0); //0:Normal, 2:縦2倍, 4:縦横2倍

     

        LCDg_print("AQM1248A Graphic LCD\n");
        //    __delay_ms(2000);
        LCDg_print("3 font size !!\n");

     

        __delay_ms(2000);

     

        LCDg_cls();

    //    LCDg_print("SDcard exp\n");
        //    __delay_ms(1000);   //ディスプレイユニットの起動を待つ

        //SDカードをSPIにモードに
        if (pf_mount(&FatFs) == FR_OK) { // Mount SD
    //        LCDg_setCursorPos(0, 0);
            LCDg_print("Mount OK\n");
        }
       
        LCDg_print("漢字もOKだよ!!\n");

        /*
        ReadFontData(0x82a0, fontdata);
        for (ii = 0; ii < 8; ii++) {
            st[0] = hex[fontdata[ii] >> 4];
            st[1] = '\0';
            LCDg_print(st);
            st[0] = hex[fontdata[ii] & 0x0f];
            LCDg_print(st);
        }
         */
        //    LCDg_setCursorPos(0, 0);
        LCDg_print("Start 漢字表\示.\n"); //表に0x5c(¥)が入るので、それを解除させる必要あり
    //    if (Screen[11][2] == 0x5c) LCDg_print("\nOK");
        LCDg_print("これは便利");

     

        while (1) {
            // Add your application code
            //        LCD_posxy(currentX, currentY); // 位置指定

            data = EUSART_Read(); // Read data received

            // グラフィックLCD用
            switch (data) {
                case 12: // クリア
                    LCDg_cls();
                    break;
                case 1: // カーソル設定
                    x = EUSART_Read(); // Read data received
                    y = EUSART_Read(); // Read data received
                    LCDg_setCursorPos(x, y);
                    break;
                default:
                    st[0] = data;
                    st[1] = '\0';
                    LCDg_print(st);
                    break;
            }
        }
    }

    結構ごちゃごちゃとコメント化されている行も見られますが、デバッグで苦戦した跡でもありますので、もし、このプログラムを使おうと思った時に、途中の状態を知るために使えるかもしれません。

    このあと説明するLCD制御関係の関数をたくさん使っているので、これだけでは理解できませんが、大体想像がつく関数名にしているので、どんなことをしているのか予想はつくと思います。

    プログラムは、LCDも含む初期化を行ってから、まずは、1バイト文字のASCIIコードでいうと、$20〜$7fまでの96文字を表示します。8x8ドット文字なので、ちょうど画面全体に表示されます。

    そのあと、オープニングメッセージを表示(これは1バイト文字のみ)してから、漢字を含むメッセージ「漢字もOKだよ!!」などと、表示します。

    まずは、SDカードからフォントデータを読み出し、漢字を含む文字を表示させることを優先させたので、文字サイズは、8x8ドット(半角も、漢字も)のみとしました。フォントも1種類のみ固定。最後のwhile (1)で永久ループで回しているところは、実質使っていません。

     

    次は、font.hです。

    #ifndef FONT_H
    #define    FONT_H

     

    #ifdef    __cplusplus
    extern "C" {
    #endif

     

    // フォント名
    enum FONT {
        MISAKI,
        JISKAN16,
        JISKAN24,   
    };

    uint8_t Font;

     

    /*
    char FontFilename[3][] = {
        "misaki.dat",
        "jiskan16.data",
        "jiskan24.data",
    };
    */
    const char hex[] = "0123456789ABCDEF";


    // フォントサイズ
    //Default, Xx2, Yx2, XYx2

     

    void ReadFontData(uint16_t code, uint8_t *data);


    #ifdef    __cplusplus
    }
    #endif

     

    #endif    /* FONT_H */

    将来3つのフォントを使えるように定義をしていますが、今回は、misakiフォントのみ使っています。

    font.cで提供される唯一の関数が、ReadFontData()です。この関数で、SDカードからフォントデータを呼び出しています。

     

    次は、font.cですが、文字数制限の関係で、ここで、いったん区切り、次回に回します。

    記事へブログ気持玉 / トラックバック / コメント


    グラフィックLCDのプログラミング その1

    2017/03/26 10:34

    ここから、実際にプログラミングを行っていきます。

     

    まずは、SDカード関連のところから。

    基本ルーチンは、この前実験したSDカード用ルーチンを使えばよいのですけど、0から作る感じで書いていきたいと思います。

     

    Petit FAT File System Moduleからヘッダファイルとしては、diskio.h、integer.h、pff.h、pffconf.hをコピーします。

    ソースファイルは、diskio.c、pff.cが必要となります。

     

    これらのファイルのうち、変更しなければならないのは、diskio.cだけです。

    CSピンのコントロールのため、ファイルの最初にあるSELECT()、DESELECT()の定義文を変更します。

     

    今回の場合、以下のようにしました。

    #define SELECT()    SD_CS_PORT=0 //LATC3 = 0     /* CS = L RC3に変更 */
    #define DESELECT()  SD_CS_PORT=1 //LATC3 = 1     /* CS = H RC3に変更 */
    #define MMC_SEL     !SD_CS_PORT  //!LATC3        /* CS status (true:CS == L) */


    CS用の信号は、SD_CSという名称にしましたが、そこに_PORTを付ける必要があるみたいです。

    どこで、それがわかったかというと、ヘッダファイルディレクトリの下に生成されているMCC Generated Filesというディレクトリの下に、pin_manager.hがあり、その中を見ると色々な定義があるので、探してみてください。

     

    ところで、LATとPORTの違いを正しく理解できていないかもしれません。元ファイルは、LATC3という記述だったのに、私は、PORTで定義しています。同じ定義にするなら、SD_CS_LATにすべきかもしれません。これは、あとで気づいたのですけど、PORTという設定でも、動いているので、そのままとしておきます。アドバイスを頂けると助かります。

     

    プログラムの本体を作ります。

    ほかのPICからの表示命令をもらって表示させる予定ですが、デバッグを簡単にするため、まずは、このハード単体で、漢字を含む文字を表示させるようにすることを目標とします。

     

    作成するファイルは、main.c、lcdg.c、font.c、main.h、lcdg.h、font.hの計6つとなります。

     

    ここからは、説明するのではなく、プログラムを示していくことを主体としたいと思います。また、ファイル先頭に自動的に挿入されるコメント類は省略して、文字数制限をできるだけ回避したいと思います。

     

    まずは、main.hから。

    #ifndef MAIN_H
    #define    MAIN_H

     

    #ifdef    __cplusplus
    extern "C" {
    #endif

     

    //グローバル変数
    FATFS FatFs;    /* FatFs work area needed for each volume */
    BYTE buff[16];
    UINT br;


    #ifdef    __cplusplus
    }
    #endif

     

    #endif    /* MAIN_H */

    重要なのは、グローバル変数を定義している3行だけですね。

     

    次は、main.cです。

    #include "mcc_generated_files/mcc.h"
    #include "lcdg.h"
    #include "pff.h"
    #include "font.h"
    #include "main.h"


    /*
    * シリアル転送されたコマンドにより、各種情報を表示する
    * 機能:
    * ・文字表示
    * ・スクロール
    * (・図形描画)
    * ・コントラスト変更 必要かどうか不明?
    *
    * AQM1248A-RN   48x128ドットLCD
    * 1: VDD      3.3V
    * 2: /CS      ←LCD_CSB
    * 3: /RESET オープン
    * 4: RS       ←LCD_RS
    * 5: SCLK     ←SCK2
    * 6: SDI      ←SDO2
    * 7: GND
    *
    * SDカード (SPIモード)
    * 1: CS       ←SD_CS
    * 2: DI       ←SDO1
    * 3: VSS1
    * 4: VDD      3.3V
    * 5: SCLK     ←SCK1
    * 6: VSS2
    * 7: DO       →SDI1
    *
    * PIC16F1829
    *                   _________
    *              VDD |1      20| VSS
    *      LCD_RS  RA5 |2      19| RA0  DAT
    *      LCD_CSB RA4 |3      18| RA1  CLK
    *            *MCLR |4      17|
    * from ext. RC5 RX |5      16|
    *                  |6      15| RC1 SDO2 LCD_SDI
    *        SD_CS RC3 |7      14|
    *                  |8      13| RB4 SDI1 SD_OUT
    *   SD_IN RC7 SDO1 |9      12| RB5 SDI2
    *LCD_SCLK RB7 SCK2 |10     11| RB6 SCK1 SD_CK
    *                   ---------
    * LCDとPIC間は、SPI2で接続、SDカードとの間は、SPI1で接続
    * ターゲットのPICと本表示システムとの間は、EUSARTで接続
    */

     

    /*
        Main application
    */
    void main(void) {
        int ii;
        char st[2] = " ";
        uint8_t x, y;
        uint8_t data;
        //    char currentX, currentY;
        uint8_t fontdata[8];

     

        // initialize the device
        SYSTEM_Initialize();

     

        // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
        // Use the following macros to:

        // Enable the Global Interrupts
        //INTERRUPT_GlobalInterruptEnable();

        // Enable the Peripheral Interrupts
        //INTERRUPT_PeripheralInterruptEnable();

        // Disable the Global Interrupts
        //INTERRUPT_GlobalInterruptDisable();

        // Disable the Peripheral Interrupts
        //INTERRUPT_PeripheralInterruptDisable();


        // グラフィックLCDの初期化
        LCDg_init();
        LCDg_cls();

     

        // 8x8ドット表示のデフォルト
        LCDg_setSize(0);

        //  
        //    LCDg_font();
        LCDg_pos(0, 0);

     

        //全文字を表示させる
        for (ii = 0; ii < 96; ii++) {
            LCDg_print(st);
            st[0]++;
        }

     

        __delay_ms(1000);
        __delay_ms(100);

     

        LCDg_cls();
        LCDg_setSize(0); //0:Normal, 2:縦2倍, 4:縦横2倍

     

        LCDg_print("AQM1248A Graphic LCD\n");
        //    __delay_ms(2000);
        LCDg_print("3 font size !!\n");

     

        __delay_ms(2000);

     

        LCDg_cls();

    //    LCDg_print("SDcard exp\n");
        //    __delay_ms(1000);   //ディスプレイユニットの起動を待つ

        //SDカードをSPIにモードに
        if (pf_mount(&FatFs) == FR_OK) { // Mount SD
    //        LCDg_setCursorPos(0, 0);
            LCDg_print("Mount OK\n");
        }
       
        LCDg_print("漢字もOKだよ!!\n");

        /*
        ReadFontData(0x82a0, fontdata);
        for (ii = 0; ii < 8; ii++) {
            st[0] = hex[fontdata[ii] >> 4];
            st[1] = '\0';
            LCDg_print(st);
            st[0] = hex[fontdata[ii] & 0x0f];
            LCDg_print(st);
        }
         */
        //    LCDg_setCursorPos(0, 0);
        LCDg_print("Start 漢字表\示.\n"); //表に0x5c(¥)が入るので、それを解除させる必要あり
    //    if (Screen[11][2] == 0x5c) LCDg_print("\nOK");
        LCDg_print("これは便利");

     

        while (1) {
            // Add your application code
            //        LCD_posxy(currentX, currentY); // 位置指定

            data = EUSART_Read(); // Read data received

            // グラフィックLCD用
            switch (data) {
                case 12: // クリア
                    LCDg_cls();
                    break;
                case 1: // カーソル設定
                    x = EUSART_Read(); // Read data received
                    y = EUSART_Read(); // Read data received
                    LCDg_setCursorPos(x, y);
                    break;
                default:
                    st[0] = data;
                    st[1] = '\0';
                    LCDg_print(st);
                    break;
            }
        }
    }

    結構ごちゃごちゃとコメント化されている行も見られますが、デバッグで苦戦した跡でもありますので、もし、このプログラムを使おうと思った時に、途中の状態を知るために使えるかもしれません。

    このあと説明するLCD制御関係の関数をたくさん使っているので、これだけでは理解できませんが、大体想像がつく関数名にしているので、どんなことをしているのか予想はつくと思います。

    プログラムは、LCDも含む初期化を行ってから、まずは、1バイト文字のASCIIコードでいうと、$20〜$7fまでの96文字を表示します。8x8ドット文字なので、ちょうど画面全体に表示されます。

    そのあと、オープニングメッセージを表示(これは1バイト文字のみ)してから、漢字を含むメッセージ「漢字もOKだよ!!」などと、表示します。

    まずは、SDカードからフォントデータを読み出し、漢字を含む文字を表示させることを優先させたので、文字サイズは、8x8ドット(半角も、漢字も)のみとしました。フォントも1種類のみ固定。最後のwhile (1)で永久ループで回しているところは、実質使っていません。

     

    次は、font.hです。

    #ifndef FONT_H
    #define    FONT_H

     

    #ifdef    __cplusplus
    extern "C" {
    #endif

     

    // フォント名
    enum FONT {
        MISAKI,
        JISKAN16,
        JISKAN24,   
    };

    uint8_t Font;

     

    /*
    char FontFilename[3][] = {
        "misaki.dat",
        "jiskan16.data",
        "jiskan24.data",
    };
    */
    const char hex[] = "0123456789ABCDEF";


    // フォントサイズ
    //Default, Xx2, Yx2, XYx2

     

    void ReadFontData(uint16_t code, uint8_t *data);


    #ifdef    __cplusplus
    }
    #endif

     

    #endif    /* FONT_H */

    将来3つのフォントを使えるように定義をしていますが、今回は、misakiフォントのみ使っています。

    font.cで提供される唯一の関数が、ReadFontData()です。この関数で、SDカードからフォントデータを呼び出しています。

     

    次は、font.cですが、文字数制限の関係で、ここで、いったん区切り、次回に回します。

    記事へブログ気持玉 / トラックバック / コメント


    グラフィックLCDのプログラミングの準備

    2017/03/25 20:54

    前回フォントデータを作りましたので、プログラムの作成に入ります。

    この前書いたように、ハードはまだ作っていませんが、ハードの構成もプログラムの設定を行うときに、同時に決めていくことになります。

     

    早速、MPLAB Xを起動して、新規プロジェクトを作成します。やり方は、以前説明したので、簡単なフローのみを示すことにします。

    New Project

    Standaloneを選んで、Next

    使用するPIC、今回は16F1829を選択して、Next

    ヘッダはNoneを選択して、Next

    ツール選択は、PICkit2は選べないので、緑のランプがついているものを適当に選択して、Next

    コンパイラは、最新のXC8 (v1.40)を選択して、Next

    プロジェクト名(例:DisplayUnit)を記入し、ファイル格納ディレクトリを設定して、Finish。

    なお、Encodingは、Shift JIS。

     

    これによりプロジェクト用のフォルダが作成されます。

    まずは、メインのCファイルの作成から始めます。

     

    Projectウインドウ内のSource Filesディレクトリ上で、マウス右クリックして、New→main.c…を選ぶと、ポップアップウインドウが出るので、ファイル名を設定して、Finishを押すと、生成されます。

     

    次にMCCのお世話になるため、MCCボタンimageを押します。すると、MPLAB Code Configuratorのタブが表示されます。

    PICのパッケージの絵が表示されますが、違っていたら、画面下のウインドウにあるPin ManagerのPackageのプルダウンメニューから適切なものを選びます。今回は、PDIP20を選択します。

     

    順番に設定を行っていきましょう。

    System ModuleでPICの基本動作モードの設定

    1. グラフィックLCDにデータを表示させるには、データ量もキャラクタLCDより多くなりますから、早めの動作周波数の設定にしておいた方がよいように思い、早めの16MHzの設定とします。
      Easy Setupのタブで、INTOSC、16MHz_HFを選択します。 PLLは使いません。
      本当は、32MHz動作ができると思っていたのですけど、選択肢の中に見つからなくて、16MHzにしました。 →後日談:8MHz_HFを選択して、PLL Enabledの所にチェックをいれたら、32MHz動作になることがわかりました。下記キャプチャは、16MHz動作の設定です。この絵では表示されていませんが、Oscillator Selectの上にCurrent System clockという表示項目が出てきて、8MHzとPLL Enabledで32MHz (4x PLL)という表示で、32MHz動作設定になったことがわかるようになっていました。最初は、Internal Clockのプルダウン項目に32MHzのものがあるものとばっかり思っていましたので、見つからなかったわけです。
      image 

     

    ピンの設定

    Pin ModuleとOutputのところで設定します。ハードの構成に依存しますが、PIC側の制約もあるので、先にソフト側で割り振りが適切にできるか検討を先に行った方がよいというのが、今までの経験からの教訓です。ということで、ここで、ハードのピン構成が決められると思います。

    1. PICkitとの接続ピン
      デバッグの容易さから、PICkitに接続するピンは、使わないようにしておくと便利なので、いつもそうしています。ピンが足りている間は、そうした方が工作実験では絶対に便利です。
      今回のPIC16F1829では、VPP/MCLR=4ピン、VDD=1ピン、VSS=20ピン、ICSPDAT(RA0)=19ピン、ICSPCLK(RA1)=18ピンの計5ピンが、PICkit2との接続専用となります。この並びがPICkit2のコネクタの並びと一致するので、接続しやすいのは、ご存知の通り。
    2. LCDと接続ピン
      以前に記載した通り、使用するAQM1248A-RNでは、/CS、RS、SCLK、SDIの4ピンが必要です。SPI通信を行います。PIC側ではGPIOで2ピン分の出力と、SCK、SDOの計4ピンを用意します。
    3. デバッグしたいPICとの通信用ピン
      デバッグするPICからのコマンドやデータを受信するためのピンが必要です。ピン数を最小限とさせるため、1ピンだけ使って、EUSART通信を行います。
    4. SDカードとの接続ピン
      SDカードとのインタフェースとして、SPI+CSが必要です。実際には、SCLK、SDI、SDOとCSの計4ピンを用意します。

    早速、設定していきます。

    1. PICkitとの接続ピンに関しては、何も必要ありません。デフォルト状態のままで対応されます。
    2. LCDとの接続ピンの設定
      MPLAB X上で、MCCを開いたら、Device Resourcesの中から、MSSP→MSSP2をダブルクリックして、SPIの機能を追加します。そして、定義を行います。今回は、以前実験した接続がMSSP2を使っていたので、そのままにしていますが、MSSP1でもよいと思います。 MPLAB X上では、画面が自動的に切り替わるので、MSSP2のEasy Setupのタブで設定していきます。ModeをSPI Masterに変更して、SPI Modeは2になるように、SPI Clockは、最速のFOSC/4=4MHzにしました。
      データシートを見ると、3.3Vなら20MHz、2.7Vで10MHz、1.8Vで5MHzでは動くみたいなので、4MHzの設定なら問題なさそうです。
      image 
      Pin Managerのウインドウを見ると、10ピンがSCK2、15ピンがSDO2になることがわかります。12ピンのSDI2は、今回は使いません。しかし、無効化して、別の用途に使うことはできないみたいです。そういうメッセージがポップアップしました。なお、SDO2は、2ピンに変更することもできますので、ご自由に。 
       
      残りの/CSとRSは、GPIOを出力ピンとして定義します。以前の設定にならい、RA4=3ピンに/CS、RA5=2ピンをRSを割り当てました。設定する時は、Pin Moduleのテーブルで、GPIOのoutput欄のところで、必要な個所をクリックして緑色背景のカギがロックした絵にすればOKです。下記では、RA4,5の所が設定された状態になっています。
      image
      そして次に、System→Pin Moduleをクリックして、Pin Moduleを表示させ、対象のピンが所望の動作になるように設定します。RA4=/CSは、Start High、Digital(Analogのチェックを外します)にしました。RA5=RSは、特に変更しませんでした。
      わかりやすいように、ピンの名称も変更しておきます。/CSの方は、/が使えない文字のようなので、CSBとしておきました。以下のような感じに。左から4列目のCustom Nameの所で、好きな名前に書き換えればOKです。その名前をプログラムで使用します。
      image
    3. 他のPICとの通信用ピン設定
      EUSARTを使います。Device Resourcesの中から、EUSARTをダブルクリックして、追加します。
      今回は、デバッグしたいPICから、このLCDディスプレイユニットへの一方通行でデータが送られることを想定しているので、RX inputだけを設定すればよいと思います。EUSARTのinputでは、RB5とRC5のどちらかを選択できますが、MSSP2でRB5が既に使われいますので、その設定とぶつからないように、RC5=5ピンをクリックしてロックしました。
      image
      EUSARTの設定も行いましょう。以前は、9600bpsにしていましたが、スピードアップを図るため、115.2kbpsと最速の設定にしてみます。8ビット、パリティなしという設定というのは、そのままとしておきます。今回は、ボーレートの所だけしか変更していませんが、キャプチャを載せておきます。
      image
    4. SDカードとの接続ピン
      最後の設定です。また、SPIが必要なので、Device Resourceの中から、残ったMSSP1をダブルクリックで加えます。
      MSSP1のEasy Setupで、ModeをSPI Masterにします。 SPI Modeは3、クロックスピードは、400kHzにしました。
      一方、ピンの定義を見ると、SCK1(RB6)=11ピン、SDI1(RB4)=13ピン、SDO1(RC7)=9ピンが使われることがわかります。 
      設定した画面は、以下のようになります。
      image 
      CSピンは、GPIOの中から、まだ未使用のピンを選べばよいと思います。
      この前のSDカードの実験をした時と同じRC3=7ピンを出力に選びました。
      そうすると、最終的に以下のようになりました。
      image
       
      image
       
      2つCSが必要になったので、上記の絵の通り、名称は変更しました。ついでにRSの方も。

      最終的にPICのピン設定は、以下のようになりました。このピンに合わせて、ブレッドボード上でPICとLCD、SDカードを接続すればよいと思います。SPI1がSDカードSPI2がLCDと接続することになります。
      image
      以上で、設定が完了したので、Generateボタンを押して、ソースを生成します。 問題がなければ、Successで、Generation completeで完了するはずです。

     

    ここからは、普通のプログラミングと同じく、ソースファイルを作っていきます。

    また、上記の設定により、ハードの構成も決まりましたので、並行してブレッドボードも組みましょう。

     

    出来上がったハードは、以下の写真のようになりました。

    IMG_20170325_190320IMG_20170325_190529

    左の写真が完成図、右の写真は、配線が見やすいように、LCDとSDカードのユニットを外したものです。この接続は、上記で設定したピンの定義通りになっています。中央で、ケーブルが伸びているように見えるのが、PICkit2と接続する信号群となります。

    回路図を書いていないので、これで代用したいと思います。

     

    次回、本格的にプログラミングに入ります。

    記事へブログ気持玉 / トラックバック / コメント


    PIC用ディスプレイユニットに漢字表示を!(フォントデータ作成)

    2017/03/20 19:55

    LCD用のフォントデータ作成のためのawkプログラムを載せておきます。使い方も最初の所に書いていますので、ご参考にして下さい。

     

    この時、フォーマットも決めています。

    ヘッダとして、64バイトあり、SJISの第1バイト毎に、4バイトのインデックステーブルを置いた後、実際のフォントデータを格納しています。

    第1バイトは、0x80〜0x9f、0xe0〜0xffだけのインデックステーブルを持ち、

    第2バイトは、0x40から開始するものとして、データは若干圧縮しています。

     

    詳細は、プログラムをご覧ください。

    # bdfファイルのフォントをPICディスプレイで使用できる形式に変換
    #
    # gawk -v BINMODE=w -f <このファイル> <フォント.bdf> <出力ファイル.dat>
    # gawk -v BINMODE=w -v datafile="font2.data" -f bdf2data.awk jiskan24-kai.bdf
    #   gawkであれば、バイナリ出力が可能

    # 例:JISKAN24
    # gawk -v BINMODE=w -v datafile="jiskan24.data" -f bdf2data.awk jiskan24-kai.bdf
    # JISKAN16
    # gawk -v BINMODE=w -v datafile="jiskan16.data" -f bdf2data.awk jiskan16-1990.bdf
    # 例:美咲フォントの生成
    # gawk -v BINMODE=w -v datafile="misaki.data" -f bdf2data.awk misaki_bdf_2012-06-03/misaki_gothic.bdf

    # 出力データ形式:マルチバイトの変数は、リトルエンディアンで書き込む
    # ヘッダ部:64バイト分
    #  0x00: FD
    #  0x02: ヘッダサイズ=0x0040 (2バイト)
    #  0x08: フォント名 (8バイト) bdfのFONTの最初の- -に囲まれている部分を抽出
    #  0x10: フォント幅
    #  0x12: フォント高さ
    #
    # インデックス部:256バイト
    # SJISの第1バイトの0x80〜0x9f、0xe0〜0xffに対して、各4バイトのアドレス
    # 0x40:0x80
    # 0x44:0x8140のデータが格納されているファイル先頭からのアドレス
    # …
    #
    # 実際のフォントデータ(SJIS漢字コードの2バイト目=0x40〜)
    #  各文字のフォントデータが並ぶ
    # 16x16ドットフォントなら、全32バイトずつ
    # 第2バイト0x40から、定義ない場合は0データを格納していく。終わりは任意。
    #

    # 16進数の1桁を数値に変更
    function h2d(hex,   hexstr, num) {
        # hexstrとnumは局所変数
        hexstr = "0123456789ABCDEF";
        num = index(hexstr, toupper(hex))-1;
        return num;
    }

    # JIS文字をSJIS文字に変換する関数
    function jis2sjis(jis,  jj, knj1, knj2) {
        # jisは、4文字の文字列でもらう
        # jj, knj1, knj2は局所変数
        for (jj=1; jj<=4; jj++) {
            jishex[jj] = h2d(substr(jis, jj, 1));
        }
        knj1 = jishex[1] * 16 + jishex[2];
        knj2 = jishex[3] * 16 + jishex[4];

        if (knj1 % 2) {    # knj1 & 0x01 の代用
            # 奇数の時
            knj1 = ((knj1+1)/2)+ 0x70;
            knj2 = knj2 + 0x1f;
        }
        else {
            knj1 = (knj1/2)+ 0x70;
            knj2 = knj2 + 0x7d
        }
        if (knj1 >= 0xa0) knj1 = knj1 + 0x40;
        if (knj2 >= 0x7f) knj2++;
       
        return (knj1*256 + knj2);
       
    }

    BEGIN {
        # 変数の初期化
        header = 1; #ヘッダ処理中は1。フォント部に処理が移ったら0
        startBitmap = 0; #フォントを処理中は1にする

        # インデックステーブル
        # 上位バイト0x80〜0xffに対して、4バイトのオフセットアドレスを格納
        # 下位は、0x40〜コード定義なくても、データを詰め込む。
        # 終わりは特に詰め込む必要なし。普通は、0xfcまでしかデータはないはず

        headSize = 64;
        indexSize = 256;

        fontfile = "fonttmp.tmp";    # フォント用テンポラリファイル

        printf("") > fontfile;
        fontAddOffset = headSize + indexSize;

        Char1 = 0x80;
        Char2 = 0x40;
        indexTable[0x80] = 0;
    }

    {
    # フォントの基本情報をbdfファイルから取得
        if (header==1) {
            # フォントサイズ
            if ($1 ~ /FONTBOUNDINGBOX/) {
                fontX = $2;
                fontY = $3;
                printf("Font Size=%d x %d\n", fontX, fontY);
            }
            else if ($1 ~ /ENDPROPERTIES/) {
                header = 0;    #ヘッダ終了
            }
            else if ($1 == "FONT") {
                split($2, item, "-");
                FontName = item[2];
                printf("Font name = %s\n", FontName);
            }
        }
        else {
            # フォントコードを取得
            if ($1 ~ /ENCODING/) {
                # STARCHARだと、最初の空白が、JISKAN24は2121とhex、JISKAN16は、01-01と句点方式で統一できなかった
                jischar = sprintf("%4x", $2);    #10進
                sjis = jis2sjis(jischar);
                sjis1 = rshift(sjis, 8);    # 文字コード第1バイト
                sjis2 = sjis % 256;            # 文字コード第2バイト

                # 第1バイトが予定値と違ったら、インデックスを設定
                if (sjis1 != Char1) {
                    indexTable[sjis1] = fontAddOffset;
                    Char1 = sjis1;
                    Char2 = 0x40;
                }
                # 第2バイトが予定値と違ったら、0パディングする
                if (sjis2 > Char2) {
                    while (sjis2 > Char2) {
                        for (jj=0; jj<(fontX*fontY/8); jj++) {
                            printf("%c", 0) >> fontfile;
                            fontAddOffset++;
                        }
                        printf("+0 \n");
                        Char2++;
                    }

                }
                printf("%X \n", sjis);

            }
            else if ($1 ~ /BITMAP/) {
                # 次からフォントデータ
                startBitmap = 1;
                lineCount = 0;
            }
            else if ($1 == "ENDCHAR") {
                # フォントデータ終了
                startBitmap = 0;
                if (lineCount != 0) {
                    # 取り込んだデータが残っていた時の処理(8ドットの倍数でない時)
                    # 今回は、8ドットの倍数のフォントを想定しているので、
                    #ここの処理は省略
                }
                Char2++;    # 次の予定コードに設定
            }
            else if (startBitmap == 1) {
                # BITMAPの次の行からのフォントデータ
                bdfdata[lineCount] = $0;
                lineCount++;
                if (lineCount >= 8) {
                    lineCount = 0;
                    # 縦8ドット分のデータが取り込まれたら、データ生成処理を開始する
                    for (xx=1; xx <= fontX/4; xx++) {
                        for (yy=7; yy>=0; yy--) {
                            # xx文字目=4ドット分、8行分のデータを数値化
                            dot[yy] = h2d(substr(bdfdata[yy], xx, 1));
                        }
                        for (jj=0; jj<4; jj++) {
                            # 縦8ドット分をfdataに作成を4ドット分繰り返す
                            loc = rshift(0x8, jj); # 0x8 >> jj;
                            fdata = 0;
                            for (yy=7; yy>=0; yy--) {
                                fdata = fdata *2;    # fdata << 1
                                if (and(dot[yy], loc)!=0) fdata++;
                            }
                            printf("%c", fdata) >> fontfile;
                            fontAddOffset++;
                        }
                    }
    #                printf("\n");
                }
            }


        }
    }

    END {
        #ヘッダ情報書き込み (64バイト)
        printf("%c", 0xfd) > datafile;
        printf("%c%c", headSize/0xff, headSize%0xff) >> datafile;
        for (jj=0; jj<5; jj++) printf("%c", 0) >> datafile;
        printf("%-8s", FontName) >> datafile;

        printf("%c", fontX) >> datafile;
        printf("%c", fontY) >> datafile;
        for (jj=0; jj<46; jj++) printf("%c", 0) >> datafile;

        #インデックステーブルの書き込み
        # indexTableの内容を表示
        # 4バイト=32ビット、リトルエンディアン
        for (ii=0x80; ii<=0x9f; ii++) {
    #        printf("%2x: %08x\n", ii, indexTable[ii]);
            printf("%c%c%c%c", indexTable[ii] % 0x100, rshift(indexTable[ii], 8) % 0x100, rshift(indexTable[ii], 16) % 0x100, rshift(indexTable[ii], 24)) >> datafile;
        }
        for (ii=0xe0; ii<=0xff; ii++) {
    #        printf("%2x: %08x\n", ii, indexTable[ii]);
            printf("%c%c%c%c", indexTable[ii] % 0x100, rshift(indexTable[ii], 8) % 0x100, rshift(indexTable[ii], 16) % 0x100, rshift(indexTable[ii], 24)) >> datafile;
        }
        # フォントデータを連結
        system("cat "fontfile" >> "datafile);
        system("rm "fontfile);
       
    }

     

    今回は、ここまで。

    記事へブログ気持玉 / トラックバック / コメント


    PIC用ディスプレイユニットに漢字表示を!

    2017/03/20 19:53

    先日ディスプレイユニットをとりあえずという感じで作成しました。

    とりあえずと書いたように、使い勝手もあまりよく考えておりませんでした。

    特にグラフィック液晶の方は、表示ができただけという状況で、本当は、8x2文字のLCDより表現能力があるはずなのに、有効に使えていないのが、ちょっと残念に感じていました。

     

    そこで、今回、SDカードの読み出しができるようになったこともあり、グラフィック液晶に漢字も含めて表示できるようにして、ディスプレイ装置として、汎用的に使える環境を整備しようかなと思いました。メモリが貧弱なPICでも、SDカードがあれば、大きなサイズのフォントデータが必要な漢字も取り扱えるのではないかと考えたからです。

     

    グラフィック液晶は、128x48ドットあります。例えば、16x16ドットで漢字表示すれば、8文字x3行のキャラクタ表示が可能です。英数字なら、例えば8x8ドットで十分ですから、16文字x6行と今までPIC用に使ったディスプレイの中で一番情報量が多いディスプレイとして活用できるはずです。

     

    漢字のフォントサイズとして、8x8、12x12、16x16、24x24あたりのサイズを用意しておけば、色々と表示方法に選択の幅が広がるので、その辺まで対応できればいいなとは思っています。

     

    漢字コードは、シフトJISを使用するつもりです。今時のコードではないとは思いますけど、PICにはちょうどよいと思います。プログラムの処理も簡単だろうと思っています。

    漢字を表示させるためには、フォントのデータが必要になります。JIS第1水準、第2水準位の文字なら、フリーのフォントが見つかると思うので、何とかなりそうです。開発環境のMPLAB X IDEもSJIS設定にしているので相性も良いだろうと思っています。

     

    さて、まず、コンセプトを考えておきたいと思います。

     

    グラフィック液晶は、今、使用しているPIC16F1829で制御しようと思っています。特に意味はありません。

    以前の経験からは、メモリ容量が大きなPICの方が、フリー環境でプログラムしている人には、優しいとは思います。

     

    ハードウエアの方は、表示したいPICからは、単線でUSARTインタフェースで接続するというコンセプトは、今と変えないようにしようと思っています。

    PICに必要なインタフェースとしては、大きく3つに分けられます。

    1. グラフィックLCD用に、SPI(SCK,SDI)+RS+CSの4本
    2. SDカード用にSPI(SCK,SDI,SDO)+CSの4本、
    3. 表示情報をこのディスプレイユニットに伝えるためのUSARTの1本

    以上の計9本のI/Oが必要です。基本的にどんなPICでもよいのではないかと思います。できれば、MPLAB X上で、MCCが使えるPICを選択した方が、楽にプログラムできると思います。

     

    さて、表示させる方法は、色々あります。

    単にいわゆる通信ターミナル端末のように、文字情報を受け取って、どんどんスクロールアップさせるような表示方法。

    もう1つは、画面は固定させて、自分で好きな場所に文字を書き込むようなもの。

     

    1番目の方法は、文字列を受け取って、どんどん表示していき、行がいっぱいになったら次の行に行き、画面の下まで来たら、スクロールアップすると極めて単純なアルゴリズムでプログラムできます。

    2番目の方法は、どこに何を書くのか、その都度、情報をもらって描画することになりますが、画面のデータを固定したまま、一部の情報だけを更新するような表示も可能となります。また、せっかくのグラフィックLCDですから、図形の描画もできるようにしたいと思っています。こちらの方式では、たぶんコマンド+データをもらって、表示するような形になるので、若干プログラムが複雑になると思います。

     

    今回は、2番目の方法で行こうかなと思います。

    コマンドセットを用意する必要がありますが、ぱっと思いつくところとして、

    1. 画面クリア
    2. カーソル位置、表示開始座標の指定
    3. 文字列表示
    4. 改行 (文字列表示の一部)
    5. スクロール (1番目の方法に近い使用法もできるように)
    6. フォントの指定

    といったものが最低限必要になるでしょう。

    文字の大きさを自由に変更したいところですが、それはたぶん、PICには荷が重いので、せめて、横2倍角、縦2倍角のようなサイズ変更ができるとよいかもしれません。

     

    グラフィック表示として、線を引いたり、円を描いたりということも、したいところですね。

    また、単にビットマップの絵を表示させるとかという使い方もいいかもしれません。

     

    まあ、PICのメモリ容量の問題もありますから、どこまで入れられるかは、それと相談になると思います。

     

    まずは、必要最小限の機能を実現させてから、機能の充実化を考えていきたいと思います。

     


    使用予定のPIC16F1829の仕様をおさらいしておきたいと思います。

    プログラムメモリ:8Kワード

    SRAM:1Kバイト

    ということなので、それほど大したプログラムは組めそうもないと、考えておく必要があります。コンパイラもフリー版なので、サイズが大きめになってしまうという問題もありますから。

    ターゲットのグラフィック液晶は、AQM1248A-RNというもので、48x128ドットの表示ができます。

     

    グラフィック描画をさせようとした場合、すでに描画されているデータはそのままで、線を加えるといったことをするためには、表示用グラフィックのデータをバッファと持っておく必要があります。

    というのも、このグラフィックLCDは、書き込んだデータをリードすることができないからです。

    書き込んだデータをPIC側にコピーとして持つには、128x48=6144ビット=768バイト必要となりますね。1KバイトのSRAMがあるから、それは何とかなるでしょうか?

     

    このLCDについて説明しておくと、モノクロのグラフィック液晶で、表示用のRAMは、縦8ドットx横128ドットのPageと呼ばれる領域があり、それが縦に6枚並んでいる構成だそうです。実際には、縦に8枚分=64ドット分のRAMを持っていて、表示開始位置を変えることで表示されない領域を表示させたりできるとのこと。表示開始位置は、0〜63ドットのいずれでも設定できます。スムーススクロールとかができそうですね。

     

    このLCDに漢字を表示させるには、その構成に合わせて、フォントデータを作っておく必要があります。

    1バイト=8ビット=縦8ドット分が同じアドレスとなっており、これを単位に、横方向に並べるような構成のデータだと、変換するとかせずに、楽に表示できます。

    横方向に並べるのは、アドレスが横方法に増える構成であり、かつ、LCDにデータを書き込むと、自動的にアドレスがインクリメントされるため、次のデータの書き込みではアドレスの指定を省略でき、便利だからです。

     

    16x16ドットの文字とか、24x24ドットの文字なら、縦が8ドットの倍数なら、処理にちょうどよいですが、12ドットの文字を表示しようと思ったら、ちょっと処理が面倒そうです。 そういう、面倒そうなものは、最初は排除してプログラムしていこうと思います。

     

    漢字フォントは、以前Palm用に漢音訓というプログラムを作ったときにお世話になったjiskan24という24x24ドットのフォントとか、jiskan16というフリーのフォントが利用できそうです。

     

    大体構想がまとまってきました。

    まずは、シンプルに、次のようにしたいと思います。

    1. 画面を8x8ドット単位に区切り、そこに文字を表示させるようにします。
    2. 文字を表示させる場所は、1のマスになりますが、そのマスごとに座標を割り振り、文字表示の場所は指定できるようにします。
    3. 文字列の中で、改行、スクロールはできるようにする。つまり、最終行に文字列を書いていて、次の行に掛かってしまう場合は、今まで描画した文字列をスクロールアップさせるということ。

    さて、では、漢字データの作成から始めます。

     

    16x16ドットフォントなら、単純にフォントの上半分の16x8ドット分、16バイトと、下半分の16バイトの計32バイトのデータを格納していけば良いのですが、その32バイトの塊を、アクセスしやすいように並べておく必要があります。 コードはSJISコードを使おうと思っていますが、文字コードは結構飛び飛びになっています。

    文字コード順に並べても、SDカードの容量から考えると、特に問題はありません。

    SJISですと、大まかに、第1バイトは64通り、第2バイトは、192通りあるので、掛け算すると、約12,000漢字があることになります。16x16ドットフォント1文字当たり、32バイト必要ですから、約380KBのサイズが必要となる計算です。PICのメモリサイズから見ると非常に大きいですが、1000円もしないSDHCカードで16GBといった容量ですから、全然問題になりません。

    ということで、あまりフォーマットを気にする必要もないかもしれません。フォーマットについては、あとでどうしたか書きます。

     

    フォントは、jiskan16、jiskan24、misakiの3つのフリーフォントを使わせていただくことにしました。

     

    まずは、8x8ドットフォントのmisakiフォントを使えるようにしてみました。

    どのフォントデータも大体同じなのですが、1バイトのデータは、横方向8ドットとなっているようです。

    これを今回のLCDに合わせて縦方向8ドットに形式に変換するわけです。

     

    例えば、亜という漢字の場合、以下のような絵になっています。

    image

    赤枠を付けた所が対象の文字の領域で、8x8ドットとなっています。

     

    このフォントの場合、0xfe, 0x28, 0xfe, 0xaa, 0x0xfe, 0x28, 0xfe, 0x00というデータになっています。

    それを今回のLCD用に、0x5d, 0x55, 0x7f, 0x55, 0x7f, 0x55, 0x5d, 0x00というデータに変換するわけです。

    LCD用にするには、縦方向の8ドットを上側LSB、下側MSBとする必要があります。

     

    今回は、bdfファイルから変換する方法をとりました。従来は、モノクロのbmpファイルのデータを読み取るという結構面倒な方法を使っていました。たまたま、bdfファイルがテキストファイルであることがわかり、文字コード情報も加わっていて、処理に便利と分かったので、bdfファイルからバイナリファイルを生成することにしました。

    misaki_mincho.bdfファイルにおいて、亜に相当する部分のデータは以下のようになっています。

    STARTCHAR 3021
    ENCODING 12321
    SWIDTH 960 0
    DWIDTH 8 0
    BBX 8 8 0 -2
    BITMAP
    fe
    28
    fe
    aa
    fe
    28
    fe
    00
    ENDCHAR

     

    BITMAPとENDCHARの間が、先ほど書いた8バイトのデータとなります。3021が16進のJISコードで、これをSJISに変換すると、889fとなるわけです。

    これを、awkで処理してLCD用データを作成しました。

     

    以下にプログラム全部を載せておこうと思いましたが、1記事の上限サイズに引っかかってしまったので、次の記事に回します。

    記事へブログ気持玉 / トラックバック / コメント


    Palmを卒業してAndroid端末を導入しました

    2017/02/19 17:10

    Palm TXを2007年から使って来ましたが、液晶のバックライトの輝度も低くなり、充電池も持ちが悪くなってきて、また、何か新しいことをしようと思っても、マシンパワーがないことも気になってきていてました。

    会社からiPhoneが支給され、使用頻度も減って来てしまっている状況でもありました。

     

    そろそろPalmから卒業する潮時かと思い、次なる端末を物色していました。

    とは言え、Palmの代わりになる同様のものはiPod touch位しか見当たりません。それ以外となると、やはりスマホを選択するよりないと思いました。

     

    何年も前ですけど、Appleの端末の導入を検討をしたことがあったのですが、自作プログラムを作ろうとしたら、iMacがないと開発環境が揃えられないという状況でしたので、Windows PCしか持たない私としては、iPhoneも含めて却下せざるを得ないと判断していました。

     

    そうすると、消去法に見えますけど、Android端末しかありません。Windowsモバイルもあるかもしれませんが、まだ市民権も取れていないような状況ですから、見合わせです。

     

    Android端末を選択するとして、どこから購入するかも考えねばなりません。例えば、スマホをドコモなどのキャリアから調達した場合、今まで掛かっていなかった月々の費用が必要になってしまいます。大体4000円とか5000円とかだと思っていますが、年5万円とかになってしまいます。電話は、ほとんどしないので、ちょっと費用がかかりすぎるようにも思いました。 一方、端末代金は、ほとんど見えないような仕組みになっているようなので、ハイエンド機種が10万に迫る値段だと思えば、2年縛りをして、本体価格レベル+αというのも理解できます。この辺が総務省の言うわかりにくい料金体系というものだと思いました。

     

    私の場合、たぶん2年以上は使うだろうと考えると、ランニングコストを抑える方が得策と考えていました。PalmTXも約10年使いました。どの位お金をかけたかと計算してみると、4万円そこそこ。つまり1年たったの4000円、月々300円ちょっとという超低コストでした。

    それに見合うくらいのものは望むべきもないかもしれませんけど、できるだけ安く済ませたいと思っています。

     

    そこで、CMも頻繁にされているMVNO、いわゆる格安スマホの方が選択肢として私には合っていると考えました。実際に月々の料金を考えると、安そうです。また、最近は、大手キャリアのように、本体も込み込みでの利用料金の設定もあるようです。

     

    色々と情報を見ていると、どのような選択肢でも、何だかんだ言って、本体を一括で購入するのが、費用的にベストだと思われました。もちろん一括で支払うので、一時的にお金が必要になりますけど、それさえ用意できれば、全体での支払額が少なくなります。これはローンや、分割払いと同じで、月々少しずつ払うと利息とか手数料のため、合計の支払額が多くなるのは、必然ですね。

     

    自分で端末を調達するため、どんな端末がよいのか検討してみました。

    私は、以下を備えているものを必要条件として、探してみました。

    1. SIMフリー:MVNOを利用することを想定していますので。
    2. フルHD 1920x1080:いわゆるHD (1280x800)は不足と考えました。 詳細理由は後述
    3. 指紋認証:簡単に使いながら、セキュリティを考えると必須。会社支給のiPhone 5Sで実感しています。Palmでは何も設定していませんでしたけどね。
    4. GPS搭載:まあ、これは当たり前かもしれません。ナビを想定
    5. microSDカード対応:色々データを取り込むのに必要と考えました。
    6. 本体サイズあまり大きくなく5インチクラス程度:PalmTX並みが望ましい

    あとは、価格が3万円以下レベルとしました。これは、Palm TXがその位の価格だったからですけどね。

    中古で購入したのですけど、記録をみると、22,800円となっていました。

    こういう条件で探すと、意外に多くはないことがわかります。選択肢が少ないので、決めるのはたやすくて助かります。

     

    そして、最後に残ったのが、Huawei P9 liteという機種でした。

    2016年発売の機種で、フルHD、指紋センサ、GPS/AGPS/Glonass、microSD対応、5.2インチ、サイズ約72.6×146.8×7.5mm、約147gというスペックです。

     

    ちなみに、Android 6.0、CPU:Huawei Kirin650 オクタコア (4×2.0GHz+4x1.7GHz)、RAM:2GB / ROM:16GBという構成です。メモリが少ないですが、SDカードが使えるので良いと思いました。

    カメラは、1300万画素と800万画素、センサーは、加速度、コンパス、環境光、近接が搭載されていました。ジャイロがないので、ポケモンGoのARは対応できないそうです。

    で、定価は2万9800円。

    ネットで探したら、Amazonで2万4000円(税込み)ほどで販売していました。ちょうどウインターセールとかをやっていて、さらに1割引きで購入できました。

    奇しくも、大体PalmTXを購入した時と同じ価格となりました。


    Palm TXのスペックは、Palm OS Garnet v.5.4.9、CPU312 MHz Intel XScale PXA 270、RAM:32MB / Flash 128MB、SDカード (ソフトによりSDHCも対応可)、78.2mm W x 120.9mm H x 15.5mm D、148.83g、画面サイズ:55.5x80.5ぐらいの320x480ドット、16bitカラー、Touchscreenというものでした。

     

    ネットから2つの写真を拾ってきました。

    Palm TX HandheldP9lite

    2台を大体縮尺が同じになるようにして、並べてみました。P9 liteが縦長なのがわかります。

     

    両方を比べると、重さが大体同じですが、高さが2cmほどP9 liteの方が長いが、約半分の薄さ、幅も5mmくらい狭いというところですね。胸ポケットには、薄いので、すっと入りますが、少しポケットから出っ張ってしまいます。

     

    使ったことはありませんが、P9 liteには、お財布ケータイとか、ワンセグとかはありません。

    防水機能もありません。でも、できれば防水機能があったらお風呂とかで、簡単に使えたのにと思いました。でも、100円ショップで購入した防水ケースに入れて、お風呂でも楽しんでいます。

     

    Amazonで注文してから約1週間したら、本体が到着しました。初めてのAndroid端末です。

    箱も素敵で、本体もなかなかいい感じと思いました。画面保護フィルムは貼り付け済み、ケースも付属と至れり尽くせりでした。

    早速、電源を入れて初期化しました。どのように初期化したか記録をしませんでしたが、簡単だったと書いておくにとどめます。

    この時点では、まだSIMカードの契約をしていないので、家の中で、WiFiで接続して、設定も行いました。

    WiFiさえあれば、回線契約なくても、普通に使えますね。

     

    まだ、環境の整備も終わったとは思えませんが、以下のように動作を少しずつ確認しながら移行中です。一部Playストアからインストールしたアプリもあります。

    1. 動画閲覧:VLC
      これにより、microSDカードに格納した映像を見ることができます。Palmの時は、フォーマットを変換して、Palm上で、TCPMPで表示できる形式にする必要がありましたけど、さすがに今のスマホはCPU能力も高いので、PCで見ているファイルのままで問題ないようです。ちゃんと表示できました。映像もきれいです。Palmにとっては動画は重い処理でしたが、P9 liteというミドルレンジの機種でも問題まったくありませんね。
    2. 音楽:これは、もともとインストールされていた「音楽」で十分対応可
    3. スケジュール:まだ、どうするか思案中
    4. メモ帳:検討中
      最近、簡単なメモは、Google Keepを使っています。そうすると、どこのPCからも見ることも、入力することもできるので便利だからです。P9 liteにもKeepというアプリをインストールしました。
      Palmのメモ帳と同等のものを、元Palmユーザの方が作ったいうLesser Padというのもインストールしましたが、まだ試せていません。
    5. 電卓:あまりにたくさんアプリがあり、どれがよいのかさっぱりわかりませんが、関数電卓 (無料版)というものをインストールしてみました。できれば、自作ソフトに入れ替えたいと思っていますけど。。。
    6. リモートアクセス:TeamViewer
      私の場合、家のWindows PCが母艦であり、そこにどこからでもアクセスできる環境を作っておきたいという希望があります。スマホだとキーボード、マウスがないので、使い勝手が悪いのですが、とりあえず。会社からTeamViewerのアクセスはブロックされてしまったので、何か良い方法がないかなと思っていたところで、スマホからのアクセスはできるようにしておこうかなと思いました。そのためもあり、フルHDの端末にこだわりました。WiFiでないと、データ量が多くなりすぎMVNOの回線でも費用がかさむ可能性もあるので、自由にどこでも使えるようにはならないかもしれませんがね。
      WiFi環境下なら、PC上でTVを表示して、Team Viewer上でその映像を視聴することは問題ないことを確認しました。これで、ワンセグとかフルセグとかなくても、大丈夫そうです。
      また、当初、上記動画ファイルのSDカードへのコピーは、PC上で行っていました。しかし、スマホはSDカードを頻繁に抜き差しすることを想定していない構造になっているので、面倒でした。TeamViewerには、リモートアクセスのほか、ファイルの転送を行う機能もあることに気づきました。WiFi環境下でPCとスマホ間でファイルを転送してみると、それなりに使うことができることがわかりました。正確には測定できていませんが、直接SDカードに書き込むより時間はかかるようにも思えますが、実用範囲内ということで、今は、microSDはスマホに入れたまま、ファイルをPCとやり取りしています。PCに取り込んだビデオファイルを転送すれば、スマホで視聴できる状態になるわけです。

     

    上記のうち、うまく移行できそうもないスケジュールですけど、仕事では、Outlookベースで会議のスケジュール管理がされるようになり、以前のように自分の手帳で、スケジュール管理する必要がなくなっていて、Palmの出番がなくなっています。会社支給のiPhoneにもOutlookが入っており、自分の席のPCと同様にどこでもスケジュール管理ができるので、個人のスケジュールとして管理する必要性がそれほどない今、スマホのカレンダー、これはGoogleカレンダーですかね、に素直に移行してしまうのがよいのかもしれません。

     

    メモ帳のデータにも記録として残しておきたいものがあるので、それをどうするかはこれから考えたいと思います。Palm Desktopで見てみると、638件もあるので、1件1件コピーするようなことはできそうもありませんから。

     

    この機種、レビューも色々ネットに上がっていますが、総合的にみて、正解だと私個人的には思っています。

    1つ遊び道具が増えてしまったけど、時間がないので、まだ、Androidプログラム開発環境もインストールできていません。

     

    まずは、スマホデビューというか(回線契約してないので)、Palm使いの人が、Android端末を使い始めたということで、第1弾の投稿とさせていただきます。

    記事へブログ気持玉 / トラックバック / コメント


    続きを見る

    トップへ

    月別リンク

    KazHatブログ/BIGLOBEウェブリブログ
    文字サイズ:       閉じる