アクセスカウンタ

プロフィール

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

グラフィック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弾の投稿とさせていただきます。

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


Open Live Writerを使ってみた

2017/01/30 22:16

今まで、このブログは、Windows Live Writerというソフトを使って書いていました。

このソフトは、Version 2012と言われているもののようで、Microsoftのサポートは、今年1月10日で終了となったとのことです。

サポートが切れると、今の時代、色々と問題が生じたりしますから、別のソフトを探して乗り換えることを考えねばなりません。

調べると、後継のソフトとして、オープンソース化されたOpen Live Writerというものがあるということなので、使ってみようと思いました。

早速、サイトからダウンロードしてきて、インストールしました。

 

ダウンロードしたファイルをクリックすると、即インストールされるみたいで、デスクトップ上にショートカットが置かれました。

image_thumb

これをクリックすると、設定を行うためのConfigureが始まります。

質問に従って設定を進めます。

使っているサイトのURL、ユーザ名、パスワードを入力すると、通信を行って、設定が完了し、Windows Live Writerと同じに見えるウインドウが開きました。

 

ただし、全部英語表記ですね。

 

でも日本語を入力することはできますので、しばらく使ってみることにします。

 

ちょっと使った感じですと、Windows Live Writerの後継というだけあって、ファイルの履歴とか書きかけのドラフトファイルとかの引継ぎは自動的になされたので、すぐに乗り換えて作業を始められそうです。

 

この記事も途中まで、Windows Live Writerで書いていて、インストールが終わった後、Open Live Writerでそのあとを引き継いで書くということができました。

 

一つ残念な感じなのは、バージョン履歴を見ると、去年(2016年)の2/13に、今のVersion 0.6がリリースされてから更新はされていないことですかね。 今さら頻繁に更新するようなモチベーションもないのかもしれませんし、十分成熟しているとみるか。

 

でも、まあ何かあったときは、サポートのあるOpen Live Writerの方がよいと思って、このOpen Live Writerを中心にしばらく使ってみたいと思います。

 

今日は、ここまで。

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


PICでSDHCカードを制御してみる実験(2)

2017/01/26 22:16

ようやく、続きを報告することができます。かなり苦戦しましたので。

 

SDカードは、FATと呼ばれるファイルシステムで構成されています。その辺も勉強しないといけないと思って、調べ始めました。

ところが、FATを理解する前に、前回書いたように、SDカードにはSPIモードがあり、PICのようなマイコンでも手軽にアクセスできることを初めて知ったわけです。

 

一方、FATというファイルシステムにアクセスするのは、色々と手続きが面倒そうです。 その辺は、コツコツ勉強しながら、処理するプログラムを作るしかないかなと思っていました。

でも、メジャーなSDカードですから、調べてみると色々と有用な情報が見つかりました。

 

私がよいかなと思ったページは、Interfacing SD Card With PIC Microcontroller ? XC8というものです。英語ですが、かなり詳しく記述されています。

 

そこには、SDカードにアクセスする複雑な関数とか、手順とかを完全に理解するところまでやりたくない人は、SDカードライブラリを使うとよいと書かれており、1つの例として、Chanという人が作ったFatFsというモジュールが紹介されていました。 FatFsとは別に、さらに小さいサイズ(コードサイズで2〜4KB)のプチFatFsというのものもあると紹介されていました。しかもフリーです。

 

PICのメモリ容量の問題もありますから、これが何となく良さげに思えたので、これを導入することにしました。

 

まず、基本的に、このFatFsは、FATを扱うFatFs関数と、Disk I/Oレイヤーの2つに分かれているということを理解しました。

 

もう少し勉強していきましょう。Petit FAT File System Moduleに、オープンソースのプチFatFsと呼んでいるFatFsのサブセットの説明がありました。

 

定義されている関数は、以下の7つあります。

大体名称をみれば、どんなことをするか何となくわかりますね。 プログラムで使うときは、これらの関数を使って、アクセスしていくとよいような感じです。

 

ただし、上記の他に、実際のDisk I/Oインタフェースは、別に用意が必要とのことでした。これが別レイヤーということのようです。

 

そのインタフェースに必要なファンクションは3つあり、それらは、自分で作る(プログラムする)必要があるということでした。

 

以下がその3つです。

disk_initialize - Initialize storage device
disk_readp - Read a partial sector
disk_writep - Divided write to a sector

たったの3つだけですが、これをPICのSPI制御で、SDカードを初期化、読み書きできるように関数を作らないといけません。

 

できるかなと不安を覚えましたが、さらに説明を見ていくと、幸いなことに、これらのDisk I/Oに関しては、Interfacing SD Card With PIC Microcontroller ? XC8の中でSD_Card_FatFsのMPLABXプロジェクトコードがあり、そこにSPIを使ったdiskio.c/diskio.hというソースコードが提供されていました。 ありがたや、ありがたや。

 

これは、フルセット版用ですが、そこからプチFatFsに必要なものだけを取り出して、少し修正すれば何とかなるのではないかと思いました。

 

ここまでで、必要な材料がそろったので、少しずつ理解しながら、プログラムに取り込んでいきましょう。

 

まず最初に、プチFatFsのファイルpff3.zipを展開して、srcディレクトリ内にある、6つのファイル

diskio.h、diskio.c、pff.h、pff.c、pffconf.h、integer.hを実験中のMPLABXのプロジェクトのHeader FilesとSource Filesディレクトリにコピーしました。

その作業は、例えば、MPLABXのディレクトリ表示ウインドウのSource Filesのところで、マウス右クリックすると、下記の図のようにAdd Existing Item...という項目があるので、それをクリックして、上記でコピーしたファイルをプロジェクトに加えていけばよいと思います。複数ファイルを同時に選択もできますので、やりやすい方法を選びましょう

キャプチャ

これらのファイルの中で、diskio.cは、上述のように、具体的に動作させる部分のコードが空になっています。そこは、自分で作らないといけないわけですが、先ほど書いたSD_Card_FatFs.zipの中から、diskio.cを拝借させてもらおうという考えです。

繰り返しになりますけど、フルセット版のまま使わないのは、メモリ使用量が気になるからです。

 


ここで、ちょっと脇道にそれます。

 

今は、、PICとSDカードスロットをつなげただけの簡単なハードですが、ディスプレイユニットに表示させられるようにしておこうと思います。そのため、プロジェクトにMCCを使って、EUSARTを追加しました。

ディスプレイユニットは、グラフィックLCDを使ってみるで紹介したもので、シリアル信号一本で、情報をLCDに表示させるものです。ただし、今回は、キャラクタLCD側だけ使用しています。

 

RA4をTXに設定。当初RC5に設定しようとしましたが、このピンは、使えないとWarning (メッセージは、Function “DT” does not have output setting “RC5PPS” set to pin “RC5”)が出ました。無理やり、コンパイルしても動作しなかったので別のピンに割り当てました。RC4にしても、Warning出ていますが、CK機能は使っていないので、無視してOKのようです。

Pin Module上、Start=H、Analog=設定せず、Output=チェック、WPU=設定せずに変更。(デフォルトではNG)

EUSART上、Enable EUSARTにチェック(デフォルト通り)、Enable Transmitにチェック(デフォルトでチェックなし)、9600Baud、8bit TransmissionBits、8bit ReceptionBitsとかはデフォルト状態のままです。

 

最終的に以下のような設定となりました。

image

image

 

こうして、以前作成したディスプレイ用の関数をインクロードして、呼び出せるようにすれば、プログラムの状況をLCDに簡単に表示ができるので、デバッグには大変便利になります。

 

この部分の詳細の説明は省かせていただいて、話をSDカードのプロジェクトに戻します。


 

ということで、diskio.cを作っていく段階に入ったわけですけど、色々とネットで調べていて、より簡単な方法を見つけたので、ちょっと方針を変えようと思います。

diskio.cは、上記のSD_Card_FatFs.zipからではなく、 Petit FAT File System Moduleのページの最後に示されていたSample projects for various platformsのものを使うことにしました。プチFatFsを作った方がリリースされたもののようなので、親和性もよいのではないかと、心変わりしたからです。

 

ダウンロードしたpfsample.zipを展開すると、いくつかディレクトリが現れました。その中から、picというディレクトリにあったpic24_mmcp.cを使わせてもらおうと思います。ターゲットのPICが、現在使っているPIC16F1705とは違いますが、親和性はいいと信じて、進めたいと思います。

 

ここからは、ごちょごちょとプログラムをいじりながら、SDカードの勉強もしながら、デバッグしながら進めます。

しかし、一番最初の段階で、ちっともSDカードを認識してくれないという状況に陥りました。

 

初期化の所からおかしいようで、ある種ブラックボックス的なMCCを使ったのが悪かったかとも思いながら、あちこちの状態を調べるため、変数をLCDに表示させながらデバッグを続けました。

でも、全然解決につながりません。ハードの問題の可能性もありますし、どうしたものかと思案しました。

 

そこで、はたと気が付いたのは、SPIモードの設定が怪しいのではないかと。ここまで至るのに相当時間が経過してます。

 

前回SPIモードを0にしたと書きました。でも、参考にさせていただいている別の方のプログラムでは、モード3に設定しています。3でも動くような記述も見ましたけど、まだ、きちんと理解していない状態ですから、ここは、先人が設定している状態と同じところから始めてみようと思いました。

そこで、SPI Modeが3になるように、Clock PolarityとClock Edgeを下記のように変更してみました。

キャプチャ2

上記をご覧になればお分かりの通り、Clock周波数も250kHzに変更しています。それは、SDカードをSPIモードに変更するためのクロック速度は、100k〜400kHzに設定せよという記述を見かけたからです。

 

そうしてコンパイルして動作させたら、何ということでしょう。状況に変化が見えたのです。

初期化ができた時に通るルーチンに来たら表示されるメッセージがLCDに表示されたのです。

具体的には、pf_mount()関数で、SDカードを初期化する時に、最初に呼び出される低レベルレイヤーのdisk_initialize()関数の中で、コマンド送信して、その結果を受け取るわけですけど、最初のCMD0を送信して、リセットができなかったのが、できるようになったのです。

まだ、理由を理解できていませんが、SPI Mode=3にすることが必要だったということで、少し前に進めました。

 

一旦、少しでも、動き出せればこちらものです。

 

ひとくくりの処理ごとにデバッグを進め、pf_mount()が動くようになりました。

 

なお、diskio.cにコピーしたpic24_mmcp.cで使われているsend_cmd()関数では、ACMDと定義されている0x80以上のコマンド送出のため、再帰呼び出しを行っていましたが、PIC16F用に使っているXC8コンパイラでは、再帰呼び出しをサポートとしていないため、コンパイルエラーとなります。そこの書き換えは必要でした。デバッグ最初の頃は、そこはコメント化して、おきましたが、処理の後の方で、2回コマンドを送信する必要があるコマンドACMDが、再帰呼び出しの処理が必要になったとわかったので、再帰呼び出ししないようにプログラムを書き換えました。

 

ここで、SDカードの初期化の手順を記載しておきます。

  1. CS=Hにして、最低74回のクロックを入力
  2. CMD0をCS=0(Asserted)でソフトウエアリセット
    1が返ってきたら、正常終了。 ←上述のSPI Modeを3に変更して、ここがまず確認できたのです。
  3. SDHCに対応させるために、CMD8+0x1AAを送信してチェック
    1が返ってきたら、SDv2というSDHC/SDXCカードだということ、そうでなければ、SDカード(またはMMC)ということでした。
    さらに、SDHCカードの場合、32ビットの戻り値が返って来て、下位12ビットが0x1AAなら、2.7V〜3.6V対応らしい。
    手持ちのSDHCと、SDカードを入れ替えて確認すると、きちんとそのように判定されました。
  4. ここからは、SDHCカードの場合だけについて、書きます。
    カードの初期化のため、ACMD41+HCS=1を送信して、初期化が終わる返り値が0になるまで、繰り返します。1秒まで繰り返して、だめだったらタイムアウトとして、終了します。
  5. CMD58を送信して、返り値CCSを確認。0なら標準のSDHC、1だったら大容量ブロックアドレッシング対応SDHCということで、512バイト単位のアクセスが必要とのこと。

以上で、SDカードアクセスの初期設定が完了します。

 

pf_mount()が正しくどうさせることができたので、あとは、あまり中身を追ってみておかなくてもプログラムは動かせそうに思いました。ということで、ここからは、プチFatFsのAPIを使わせてもらって進めたいと思います。

 

上記で詳しく説明したのは、初期設定を行うpf_mount()の中で行われているdisk_initialize()の処理でした。

ここでは、手持ちのSDカード(2GB以下)とSDHCカードを使って実験しましたけど、両方ともきちんとマウントできました。

そこでマウントができたら、次は、pf_open("ファイル名")を使ってファイルをオープンしてみます。pf_open()のプログラムの中身はまだ見ていませんが、ちゃんとファイルをオープンできました。もちろん、ファイルが存在しなければ、エラーになることも確認済みです。

 

何となく、SDカードへのアクセスができそうな雰囲気になってきたので、試しに、テキストファイルとして、

ABCdef

とだけ書いたファイルを、test.txtというファイル名で、SDカードに保存しました。これは、PC上で行いました。

 

そのSDカードをPICの実験ソケットに入れ、PIC側で、上述のpf_mount()、pf_open(“test.txt”)としてから、pf_read(buff, 16, &br)とバッファ変数buffに16バイト分呼び出し、brに読み出したバイト数が入る処理を行って、buffに入った文字を表示してみました。ここでディスプレイユニットの力を発揮できました。

 

そうすると、ちゃんとABCdefと読み出せました。

 

ここまでできれば、PICを使って、データをSDカードから読み取ることができる基礎ができたかなと思います。

 

これで、大きなデータをSDカードに格納しておいて、必要な時にPICに取り込むといったことができるようになると考えています。

PICのメモリ容量は小さめで、以前にも少し大きなデータを取り扱おうとすると、限界に突き当たってしまっていました。

例えば、アラームのメロディーを複数格納しておきたいとか、グラフィックLCDに表示するデータを格納しておくとか、いろいろと用途は考えられますからね。

アラームのデータは、以前に作った温湿度計付き時計の時に、もっとデータ領域があればいいなと思ったこともありました。SDカードなら、まず容量で困ることはないと思っています。

 

とりあえず、ここまで実験が成功裏に終わりましたので、いったん、終わりとしたいと思います。

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


PICでSDHCカードを制御してみる実験(1)

2017/01/10 21:52

久々にPICで遊びました。

思うところがあって、SDカードを使えるようにしたいと思っています。

 

しばらく開発環境もさわっていなかったので、確認してみると、MPLABXは、v3.50にアップデートされ、XC8もv1.40になっていました。これらをまずインストール。

 

今回の実験のためのハードとして特殊なものは、SDカードですけど、ソケットが必要です。これは、昔購入しておいたSDカードソケットを使おうと思います。

これは、元々、最初にPICを使い始めた時に参考にした「PICを使ったデータ・ロガーの製作」に付属の基板に取り付けるつもりで購入したのです。当時の記事はここ

しかし、結局使わずにしまっていたものでした。

 

このソケットを使うにしても、そのままでは、実験するのに使い勝手が悪いので、ブレッドボードに挿せられるようにユニバーサル基板上に載せてみました。

それが、以下の写真です。

DSCN0327msohtmlclipclip_image001

 

ユニバーサル基板は、秋月電子の十字配線ユニバーサル基板 Cタイプをカットして使っています。

十字配線の一部をカットすることで配線なしに接続が可能なので、配線が不要で便利でしたが、ご覧のように、見た目は汚くなってしまいました。

SDカードとのインタフェース用に9ピン分のヘッダを取り付けていますが、実際には、写真の左から8ピン分しかつなげていません。SDカードの右端のPin8に相当するピンは、中途半端な位置にあるためと、PICと接続する場合、SPIモードで使うことから、不要なピンとなるので、接続することをやめたためです。

 

また、ソケット側には、カード挿入検出ピンもありますが、これも接続するのに面倒な状態なので、接続をあきらめました。

 

PICでの実験では、SDカードのPin1〜7だけあれば事足りるということなので、問題はないでしょう。後で必要なら、Pin8も接続できるようにヘッダピンは用意しているのは、その時の保険と考えてください。

 

さて、次には、回路を組む必要があります。

まずは、ターゲットのPICを決める必要があります。少ない手持ちのPICから選択するわけですけど、SDカードの読み書きには、512バイトのバッファが必要というような情報から、RAMは最低それ以上ないと困りそうです。そうすると、あまり小さいPICではだめそうです。

 

PIC18F14K50が使えそうですけど、MPLABX上でMCCを使うと楽ができることを学んでいるので、MCCを使いたいところですけど、最新のMCCでも18F14K50は、対象のPICには入っていませんでした。残念。そのため、対象から外します。

 

手持ちにPIC16F1705というものがありました。これは内部にオペアンプが入っているという変わり種で、面白そうなので、入手しておいたものでした。これはMCCのサポート対象となっているので、これを使ってみようと思います。今回はオペアンプは関係ありませんけどね。

 

普通なら、回路を先に作るのがよいのかもしれませんが、PICはピンの選択に色々とソフト上の制約があったりしますから、先にMCCで設定をしてしまおうと思います。

それに合わせて回路を構築しようという、普通とは逆の順序で進めようかと思います。

 

MPLABXを起動して、新規のプロジェクトを作成します。ここは従来と変わるところがありませんから、説明は省略します。

そして、MCCボタンを押して、System ModuleのEasy Setupの設定をします。

INTOSCで、16MHz_HFにして完了させます。

 

次に、SPIインタフェースのため、Device ResourcesからMSSPを選択してダブルクリックして追加します。

ModeをSPI Masterに変更します。通信速度をいくらにすべきかよくわかりませんが、とりあえずデフォルトのままFOSC/4、すなわち4MHzにしておきました。5MHz設定にしたという情報をネットで見かけましたので、問題ないと信じたいと思います。

 

SPIの動作モードは、モード0で良いらしいのですが、モード3に設定していても動作するとのこと。

この辺、混乱しています。モード0とは、CLKがLowでアイドル状態で、立ち上がりエッジでデータを取り込む仕様ということらしいですが、MCCでは、そういう設定にすると、表示上は、SPI Mode=1となってしまいます。モード0と表示して欲しいところですが、私が間違っているのかもしれません。

だめだったら、後で治すことにして、下記のように設定しました。

無題0

 

SDカードのCSピンは、SPIとは別に制御必要そうなので、1ピン追加します。

Pin Manager (最初表示されていなくて戸惑いましたが、ウインドウの一番下のステータスバーの所にあり、クリックしたらウインドウが表示されました)を使って、どのピンが適切かわかりませんが、今回は、RC3をGPIO Outputに定義しました。実際には空いているカギの絵をロックされたカギの絵に変更します。

無題1

 

そして、どのようにデバッグしたらよいか?できるだけ最小のハードで実験したいので、まずは、書き込み実験だけを行うことを考えました。

SWを1つ取り付け、SWを押したら、ファイルに適当な情報を書き込むと言った感じ。

その後、SDカードのデータをPCで読み出してみようという計画です。

 

そのため、SW用にRC4をGPIO Inputに定義しました。設定はデフォルトのまま、WPU (Weak Pull-up)の設定がされています。これをプッシュスイッチを介してGNDにつなげば、ボタンを押したときにLowが伝わります。

状態は、以下のように変更されました。

無題2

 

なお、RA0 (ICSPDAT)とRA1 (ICSPCLK)は、PICKit2と接続して、プログラムを書き込むために使用しますので、空けています。

ここで、SPIのデフォルト設定では、SDOが設定されていないことに気づきました。SDOの所で、RC2を割り当てました。

Pin Managerの上の方にあるMSSPの所で、以下のように変更しました。

無題3

 

動作確認用のLEDも追加しておいた方がよいと思いつき、RA5に割り当てました。設定はデフォルトのまま、WUPで、LEDの-側をRA5に接続し、2KΩの抵抗を介して、VDDに接続します。RA5を0にしたらLEDが光るという設定ですね。

 

以下が今回の最終形となります。

無題4

無題5

名称もプログラムで分かりやすいように変更しています。

 

以上で設定が完了したので、Generateボタンを押して、ソースプログラムを生成します。

 

接続が決まりましたので、上記の設定に従って、ブレッドボードを組みます。

DSCN0328

大体こんな感じです。回路図は書いていませんが、単純なので、お許しください。

 

プログラムの作成に入ります。

 

プログラムは、ボタンを押したら、カウントアップしていき、かつ、ファイルヘッダ名+カウンタというファイル名でファイルを生成して、中身にカウント値を書き込むという感じにしてみます。

 

初めて使うPICなので、まずは、LEDを点灯させることから始めてから、上述の動作を実現させる本格的プログラミングに移行したいと思います。

 

名称を変更しているので、LED_PORT=0;とだけプログラムして、コンパイルします。

問題なくコンパイルできました。

 

で、ここで、大問題が判明しました。PICkit2では、16F1705をサポートされていないことに。

 

せっかく購入したのに使えないものを買ってしまった。別のPICに変更しなくてはいけないかなどと考え始めました。でも、ちょっと思い返して、ネットで調べてみようと思いつきました。さすが、頼りになるのが、ネットの力。からくり工房「ききょうや」さんが、そのものずばりのPIC16F1705をPICkit2で使うという記事をアップしていました。

定義ファイルを頂き、PICkit2で16F1705を認識させることができました。ありがとうございました。

ありがたく使わせていただきたいと思います。

これで、心置きなく16F1705を使うことができます。めでたしめでたし。

 

おかげさまで、ちゃんとプログラムを書き込め、LEDを点灯させるという第一歩はクリアできました。

でも、点灯だけだと、ちょっと心配だったので、点滅するようにちょっとプログラムを書き換えてみたりして、ちゃんと使えることは確認しました。

 

さて、SDカードの読み書きですが、これをゼロから作るのは大変そうだし、そんな労力をかける必要はないと思い、先人たちのソースを活用させて頂くことにしたいと思います。

それでも、どうなっているか理解して使わせてもらおうかと思っていますけど。

 

ここからは、少しボリュームが必要かと思うので、ここで、いったん切りたいと思います。

続きは後日。連休中に終わらなかったので、次まで少し時間が空くかもしれません。

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


ISO Recorder 3.1でDVD-Rへ書き込み

2016/12/23 11:23

ISOファイルを生成した後、DVDに書き込むソフトとしてISO Recorderなるものを使ってみました。

 

インストール後、対象のファイル上で、マウスの右クリックを押すと、プログラムから開くの中に、ISO Recorderというそのままの名前が出てきますので、それを選択します。

すると、ISO Recorderが起動して、以下のウインドウが出てきます。

image

書き込む対象のファイルは、Sourceの欄のImage fileの所にあります。

記録装置側の設定は、Recorderの欄内にあり、私の環境では、FドライブがDVDドライブになっています。

また、16倍速対応のDVD-Rを使っているので、16xが選択されている状態になっています。

 

ここで、Nextボタンを押すと、書き込みがすぐ始まります。

 

完了すると、以下の画面が表示され、Finishを押すと、終了となります。

image

 

あまりいじるところもなく、非常にシンプルですが、必要十分な機能が無料で提供されていること感謝したいと思います。

 

今日はこれだけ。

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


DVDStylerを使ってDVDファイルを作成

2016/12/20 21:55

映像ファイルをDVD化するソフトとして、DVDStylerというのを見つけました。

結構使いやすかったので、紹介します。

これは、バージョン 2.6.1をベースにしています。確認してみたら、今は最新版として3.0.2となっていました。まだ試していませんが、この記事も参考になると願っています。

 

作成手順:

 

最初に起動した時、以下の画面が出ます。

映像形式、横縦比、音声形式の初期値を設定します。

image

設定を保存しておけば、下半分にある既存のプロジェクトから選択もできます。

 

新規を選んだ場合の手順

 

1.背景画像選択

以下のメニュー用のテンプレートを選択します。

image

これは、お好みで、選択します。

 

そうすると、以下のような感じになります。

image

右側の大きな画面が、選択したメニューのテンプレートになっています。

その中に、白い四角が3行ほど見えると思います。最初これが何かわからなかったのですが、日本語が文字化けしているものとわかりました。

ダブルクリックして、フォントを選択し直すときちんと表示されます。

 

まずは、タイトル部をダブルクリックすると、以下のウインドウが表示されます。

image

 

テキストを必要に応じて変更して、その右にあるフォント設定ボタンを押します。

そうすると、以下のウインドウが開きます。

image

タイトルなので、文字は大きめに48のサイズに設定をしました。

つまり、タイトルをダブルクリックして変更したのは、テキストの文字と、フォント設定だけということになります。

 

次に、タイトルの下の2行の文字化けを同様に変更します。

ただ、2行は、ボタンとなっており、ちょっとタイトルとは変更できる内容が異なります。

imageimage

フォントの設定だけを行いました。

 

設定が完了した後の画面は、以下のような感じになりました。

image

ウインドウの下に2つのメニュー、メニュー1とメニュー2という画面が表示されています。これは、DVD再生時に表示されるメインメニューと、メインメニューで、タイトル選択を押した時に表示されるサブメニューです。

「その横に動画ファイルをファイルブラウザーからここにドラッグします」と書かれている通り作業をします。

 

DVDに格納したい映像ファイルを、左のタブのファイルブラウザ、もしくは、エクスプローラなどから下のメニューの隣へ、ファイルをドラッグします。

ここのポイント! この時、Ctrlを押しながらやると、1つのタイトルとして読み込まれます。

よくわかっていませんが、複数のタイトルとしてDVD作るより、チャプターを複数にした方が、連続したビデオの作成には、再生時に便利ではないかと個人的には思ったので、こうしました。

 

4つのファイルを読み込むと、以下のような感じになります。

image

上記の絵のように、Ctrlを押して読み込むと、タイトル1からタイトル1-4のように表示され、全体が黒く囲まれて1つのタイトルになっているような表示になりました。Ctrlを押さずに読み込むと、各ファイルは独立したタイトル番号となり、1つ1つの間は白いままで独立しているという感じに見えます。

この例では、1つ30分、2話の映像を4つ分取り込んでいます。約2時間分ですね。

 

このまま、DVD書き込み(F9もしくは、メニューバーの赤い丸いディスクマークを押してもOK)もできます。

しかし、それだと頭出しが面倒なので、チャプター設定をしてみます。

 

そのためには、下に表示されている読み込んだ映像ファイルをダブルクリックして、プロパティ設定画面を出します。

image

ここで、チャプター位置という箇所(中央やや下)の右端の...ボタンを押します。

そうすると、以下のようなウインドウがでます。

image

+でチャプターの追加、−で削除、スパナのマークで設定変更ができます。

上記では、4つのチャプターが表示されていますが、7分おきという設定で自動的に設定されたものです。(初期値では10分置きらしい)

必要なチャプターを選択して、ダブルクリックか、スパナマークを押すと以下のウインドウが出ます。

image

ここで、スライダーを左右に動かすか、時間の右の上下ボタンで、チャプターの開始位置を設定します。 まだ、バグがあるのか、2組ある上下ボタンの右側の細かい時間設定ができる方のボタンは、進む側は動作するものの、戻る側が機能しませんでした。

 

30分番組で、2話入っているソースだったので、オープニング、1話開始、2話開始、エンディングの4か所にチャプターを設定しました。

同様に、ほかのデータにもチャプターを設定します。

 

次にメニュー2をダブルクリックします。

image

そうすると、メイン画面に4つの白枠が表示されていることがわかります。

まず左上の四角をダブルクリックします。

image

アクションのジャンプ先で、このボタン=四角を押した時、どの部分から再生するかを指定します。

また、外観という下半分の所で、映像の...のボタンを押すと、このボタンに表示させる画面を指定できます。

image

 

これで、準備は、完了したはずです。

 

メニュー部の赤いドーナッツ、もしくは、ファイル→DVD 書き込み、またはF9を押してDVDファイルを作ります。

以下のようなウインドウが出ました。

image

今回は、DVDに直接書き込まず、ISOイメージファイルを作ることにしました。

 

開始ボタンを押すと、生成が始まりました。下記ような感じで進んでいきます。

image

終了するまでにそれなりの時間はかかりました。PCの能力に依存すると思いますけどね。

 

出来上がったISOファイルをVLCメディアプレーヤーで開いて内容を確認したら、完了です。

必要なら、ここで、DVDに焼けばOK。

 

ということで、ビデオキャプチャした映像をインデックス付きで、DVD化できるようになりました。

 

今回は、ここまで。

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


ビデオのDVD化 HandBrake使用記

2016/12/19 22:44

DVD作成用にisoファイル化してしまったものから映像ファイルを取り出し、一部の映像を入れ替える作業が必要になりました。オリジナルのファイルを削除してしまったので。

 

探してみると、.isoファイルからデータの取り出しには、HandBrakeというソフトがあることがわかりました。これは、評判が良さそうだったので、使ってみました。

 

でも、このソフト、起動後の画面がちょっととっつきにくい感じでした。

しかし、この辺のページをみて、やってみたら、簡単に使えましたので、以下に書いておきます。

 

まず、使った感想を。

 

面倒な点:

ISOファイル内の映像データに複数のチャプタがあった時(今回はそれに当たります)、それをそれぞれ別ファイルとしようと思うと、Destinationのファイル名を1回ごと変更しなければなりませんでした。これが、結構手間がかかりました。連番で作成してくれれば、もっと簡単なのだけれども。

 

よかった点:

下半分のVideoタブでQualityの処で、Avg Bitrateを選択して、2-Pass Encodingにチェックを入れたら、キャプチャした時より、絵がきれいになりました。これは思わぬ朗報でした。

ビデオの映像のキャプチャは720x480ドットで行いましたが、結構ノイズもあり、ブロックノイズのような感じの映像に見えていましたが、2-Pass Encodingにより結構きれいにエンコードできました。

 

以下のキャプチャは、ISOファイルを読み込んで、設定したところです。

image

このISOファイルには、16チャプタあり、MP4で出力しました。上記キャプチャした画面は、最後の16番目のチャプタを取り出す設定を示しています。

面倒な点の所で書いた通り、いちいちファイル名を設定しなければなりませんが、最初は、Startボタンで始め、2回目以降は、その右のAdd To Queueをおせば、どんどんキューにためていけますので、1つのエンコードが終わるまで待つような必要はなく、特に待ち時間といったストレスがなかったことは助かりました。

 

でもDVDの圧縮はそんなにされていないことがわかりました。元のISOファイルサイズが、4.4GBもあったのに、MP4で出力した16個のファイルの合計サイズは、たったの808MBしかありませんでした。約5分の1の小ささです。

 

DVDにしなければ、MP4で保存しておく方が経済的ということがわかりました。

 

今回は、DVDのISOファイルから、映像ファイルを取り出すところまで。では、また。

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


VMware上のXPで、VHSファイルのキャプチャ

2016/12/18 17:01

古いもの整理中ですが、VHSテープも、取っておく必要あるのという感じですけど、一部とっておきたいものがあったので、キャプチャしておこうと思い立ちました。

 

何年か前にXSPEED-F1というビデオキャプチャ装置について、書いたことがありました。

その時は、Windows7を使っていた訳ですが、Windows XPでないとXSPEEDが使えないため、苦労した話を書きました。

 

今、Windows10を使っているので、当時と同様に、XP環境を整えないといけない訳ですが、先日来、古い時代のWindowsソフトを動作させるために、VMwareを使うことで、Windows 98を動作させることができることがわかりましたし、そこにたどり着く前に、XPも動かせるようにしていたことも書きました。

 

そこで、WindowsXP SP3のインストールができた環境を使って、PCへのキャプチャ環境を整えてみようと思いました。

 

その話をする前に、少し別の環境でのWindows XP環境も作りましたので、その経緯を。

VMwareを使わない場合、実際にWindows XPをインストールするしかないのですけど、現在の環境も保持しておく必要があります。もちろん、現在の環境がメインだからです。

 

現在のPCの構成は、以下のようになっています。

2TBのHDDにWindowsの環境ができています。こちらは、AHCIでの動作に問題ありません。また、IDEモードでも動作させることはできます。

もう1台、500GBのHDDに、Windows XPの環境を構築しました。

ただし、こちらは、残念ながら、IDEモードだけでの動作となっています。XPでもAHCI動作させることはできるようですが、トライしていません。

 

この2つをBIOS設定で切り替えて運用します。

PCを起動直後、DELキーを押して、BIOS設定画面を表示させ、HDDのどちらを優先させるかを指定して、起動させます。そうすると、選択したHDDにインストールされているWindowsが起動するという訳です。

(追記: 私が使っているマザーボードのメーカーであるASRockのBIOSでは、起動時にBootオプションというのがあり、F11を押すと、どのHDDから起動するかを選択できることがわかりました。その選択は一時的なので、次に起動する時は、元々設定しているHDDから起動するので、切り替えは簡単になりました。)

 

キャプチャしたい時は、XPを起動して、XSPEED-F1付属のUlead Video Studio SE DVDを使い、キャプチャします。キャプチャして、前後の不要部分をカットする作業を行って、ファイルを今のWindows環境に引き渡すことにしました。

 

DVDは、約2時間ほどの動画を格納できますから、複数のVHSのデータを一緒にすることもできます。そういう作業は、時間もかかるので、メインのWindows上でやれば、他のこともやりながらできますので、都合がよいのです。

 

DVDへの書き込みソフトは、どうしようかと考えていましたが、Source ForgeからDVDStylerという素晴らしいソフトが出ていることがわかりました。

 

これは、DVDメニューの設定などもでき、初心者でも比較的に使いこなせる感じなので、お勧めです。

 

これで、XP上でキャプチャして、OSを切り替えて普通の使い方を行うという環境はできました。

しかし、キャプチャは、実時間かかるので、2時間のVHSなら2時間、XPが動く状態を維持しなければならず、普段の作業が滞るということで非常にストレスがたまる環境でした。

 

そこで、VMware上で動作している、WindowsXP SP3上で、USBが認識できるのかとかも含め、動作確認を行ったところできたというわけです。これは、今の環境はそのままなので、作業も並行に行うことができるので、非常に効率的で、別ウインドウで動作しているキャプチャが何時間でも、まったく気にならない環境となりました。

 

以下は、その環境と実際に使うときのメモとなります。

  1. VMwareからXP SP3を起動します。
  2. XSPEEDに付属していたUlead VideoStudioは、XPでないといけないので、VMware上のXPにインストール。これは、普通にインストールできます。
  3. XP上でないと動作しないXSPEED-F1を用意します。まだ、USB接続しません。
  4. Ulead VideoStudioを起動。
  5. Uleadの使い方:
    初期画面で、VideoStudio Editor側を選択し、メインウインドウを出す。
    キャプチャは、タブのCaptureをを選択。右中央部にCapture Videoというのがあるので、クリックすると、準備がほぼ完了。
    ここで、XSPEEDをUSBに接続します。エミュレートされているXPでそのUSBが認識されるので、キャプチャできるようになりました。ここが一番心配していたところでしたが、ちゃんと動きました。
    2回目以降の起動で、すでに接続されていた場合、コネクタを抜き差ししないと、認識されないので注意。
    きちんと認識されると、下記ポップアップがXP上で出て来ました。
    image
    はいを選択して、先に進めます。
  6. 使用方法:
    Source: easycap video adapter
    Format: DVD
    という感じの設定にすれば、OKかと思われます。Formatは、DVDでよいかと思う。お好みで。
    この時、どんな設定でキャプチャされるかは、画面下部のInformationの所に出ています。
    DVDだと、720x480, DVD, Variable Bit R…、MPEG Audio ? Layer 2, 48000といった設定になりました。
    設定を変更したければ、Source/Formatと同じ枠内のOptionsを押して、Video and Audio Capture Property Settingsを選択すれば、ポップアップウインドウが出て、変更ができます。
    なお、このポップアップで、SourceのタブのAudioの所で、Preview audio with USB deviceの所のチェックボックスにチェックを入れておくと、PC側で音が聞こえます。
  7. これで、VHSビデオを再生して、キャプチャを始めたいと思う適当な時間に、Source/Formatと同じ枠内、下側にある、Capture Videoを押すと、録画(PCでのキャプチャ)が始まります。
  8. 終わるときは、同じところを押せば終了です。

という感じの手順でキャプチャはできました。

 

キャプチャしたファイルは、そのままメインのPCでMPEGファイルとして保存しても構いませんが、編集も可能です。私の場合は、TV録画のものだったりするので、CMをカットするなどしました。

 

編集は、キャプチャが終わってから、上部のメニューバーにあるEditタブを押します。

先ほどキャプチャしたファイルが、右側にサムネイル付きであるはずです。それをクリックすると、左側の映像表示ウインドウに表示されます。

 

編集は、次のようにカット作業を繰り返せばOKです。

[と]のボタンが映像ウインドウの真下に見えると思います。

これを使って、取り出したい部分を決めます。小さいウインドウで、少し作業がやりにくいかもしれません。その時は、はさみのボタンの右のボタンを押して、ウインドウを拡大すると作業がやりやすくなるかもしれません。

 

細かい位置決めをしたい時は、[、]のボタンの下に見える時間の所で、時分秒かその下の2桁の所をクリックします。そうすると、数字が点滅するので、その時間表示の右端にある上下三角の所をクリックして、時間を進めたり、戻したりして決めることができます。この時、上下のカーソルキーでも作業が可能でした。

適切な位置になったら、最初[か、最後]を示すボタンを押せばOKです。

範囲が決まったら、メニューのClip→Save Trimmed Videoを押して、指定された範囲の映像を別ファイルとして保存します。

 

この作業を必要なだけ行っていくと、出来上がったファイルは、右側のサムネイルの所にあるので、適切な順番で、画面下部のタイムラインの所に並べていきます。

 

並べ終わったら、上部メニューバーにあるShareタブを押します。(これはわかりにくい名称ですね)

そうすると、画面右中央部にコマンドメニューが表示されるので、その中から適当なものをクリックします。今回は、Create Video Fileを押して、出てくるプルダウンメニューから、Same as Project Settingsを選びました。そうすると、ファイル名を聞いてくるので、適当な名前を付けて保存します。

 

これで、編集されたファイルができあがるということになります。

あとは、そのファイルをメイン側のPCがアクセスできるところに持っていけば完了です。

 

ということで、今はたぶん、誰にも役に立たない覚え書きでした。

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


今頃FDDの整理中

2016/10/18 12:53

先日、古いPC関係のものを整理しているという話をしました。まだ、続けています。

 

3.5インチFD(フロッピーディスク)がたくさん出てきたのですが、そのまま捨てるのは忍びなく、できる限りデータを吸い出してしまいたいと思っています。重要な情報は、当時引き継いだはずですが、それほどでもないものは、そのままにしていたのではないかと、はっきりしない記憶状態なので、確認したいという気持ちなのです。

 

ところが、FDの中のデータを取り出すためのFDD (フロッピーディスクドライブ)が、私のまわりからなくなってしまったことに気づきました。

常にどこかのPCでFDDを使えるようにしておいて、必要なら取り出せるようにしておこうと思っていたはずだったのに。。。

メインの自作マシン用のFDDは残っているのですが、前回マザーボードを買い換えた時、FDDインタフェースがなくなっていたので、接続できない状態のまま、今に至っています。そのFDDが接続できるマザーボードは、あまり意識せずに、売却してしまっています。

たぶん、自作PCで使えなくても、実家のPCやら、会社のPCとかを使えば何とかなると思ったような記憶です。しかし、年月が経過して、今現在、FDDを持つPCがまったくなくなっていることに気づいたという次第です。

 

自宅に唯一PC-9821Cx、通称CanBeがあることはあるのですが、この頃のPCには、USBなんてありませんから、読み出せたとしても、今のDOS/VベースのWindowsへデータを持ってくる方法がなくなっているのです。 もし、CanBeを使って何とかしようとしたとしても、相当苦労しそうです。

それは、このCanBeは、HDDで運用していたのですが、そのHDDが故障していたことを何年か前に確認しているので、まず、IDEインタフェースのHDDがなければ、システムの再構築ができい状況だからです。別の案として、FDDベースで使わなければならないとすると、非常に面倒そうです。1台しかFDDはついていませんから、コピーもままならず、ネットも当時モデムを外付けで付けてダイヤルアップで使っていましたから何かを取り込むのも難しそうです。

USBメモリ代わりにインタフェースとして使えそうなのは、RS-232Cくらいしかありませんが、当時CanBeでRS-232Cを使って他のPCと通信をさせるようなことはしたことがないので、そういった環境を構築するのも難しそうです。

 

という訳で、長々書いてしまいましたが、今のPCにFDDをつなぐのが一番よさそうです。ネットで調べると、USB接続のFDDが使えそうです。中古なら1000円程度で買えることがわかりました。

 

FDは100枚くらいありましたから、1枚当たり10円程度の読み出し費用なら、まあ許容できるかと思いました。たぶん今やらないと、将来できないかもしれませんし、最後のチャンスと思って、USB-FDDを調達することにしました。

Logitec LFD-31UEというものです。

 

ネットの情報では、NECの標準フォーマットだった1.2MBタイプ、IBMフォーマットの1.44MB、1MBレベルになる前の720KBタイプの読み出しができる3モードFDDということです。フォーマットは、普通1.2MBはサポートされていないらしいですが、これはできるという情報でした。

 

USB接続して、FDを入れたら、Windows10上のエクスプローラでAドライブとして、普通に読み込むことはできました。

 

まあ、これからフロッピーを使うこともありませんが、フォーマットも試してみました。

NECフォーマットである、1.2MBが可能かどうか確かめてみたかったらです。次のコマンドを打ってみます。もちろんコマンドプロンプト上で。

format a: /f:1232

普通に進みましたが、最後に、ボリュームラベルを入力して下さいというメッセージが出て、特にラベルが不要だったので、そのままEnterを押して進ませました。しかし、最終的にフォーマットに失敗しましたというメッセージが出ました。

 

image

 

こうなると、このフロッピーに対して、もう何も操作できなくなりました。

もう一度フォーマットしようとしても、現在のディレクトリは無効です。というメッセージが出て終わってしまいます。もうこのFDは使えそうもありません。(元々捨てるつもりでしたけど)

なぜかな?

 

悩んでも仕方ありませんし、新たなフォーマットでFDを使う予定もないので、先に進めます。

 

次は、エクスプローラ上で、1.44MBにフォーマットしてみました。これは、問題なく完了しました。

そのFDに対して、今度は、コマンドプロンプト上から、format a: /f:1.23 として、1.2Mフォーマットを試してみます。だめでした。

 

ちなみに2種類のフォーマットの情報を書いておきます。

NECフォーマット:1.23MB、1024バイト/セクタ

DOSフォーマット:1.44MB、512バイト/セクタ

 

あと、このUSB-FDDの挙動不審な点というか使いにくいところがありましたので、書いておきます。

 

1枚目のFDをエクスプローラ上で開いて、コピーなりの作業後、2枚目のFDに入れ替えを行い、同様の作業を行おうとしています。

この時、Windowsがバッファしていた前のFD情報が表示され、新たなFDに入れ替えたことを認識していないような振る舞いをしていることがありました。

 

フロッピーディスクを入れ替えた時の挙動不審状況は以下のような感じです。

 

C:\Users\ohno>chkdsk a:
ファイル システムの種類は RAW です。
RAW ドライブに CHKDSK は使用できません。


C:\Users\ohno>chkdsk a:
ファイル システムの種類は FAT です。
ファイルとフォルダーを検査しています...
ファイルとフォルダーの検査を完了しました。

Windows でファイル システムのスキャンが終了しました。
問題は見つかりませんでした。
これ以上の操作は必要ありません。

    1,250,304 バイト : 全ディスク領域
        1,024 バイト : 1 個の隠しファイル
      560,128 バイト : 32 個のファイル
      689,152 バイト : 使用可能ディスク領域

        1,024 バイト : アロケーション ユニット サイズ
        1,221 個     : 全アロケーション ユニット
          673 個     : 利用可能アロケーション ユニット

 

上記2回のコマンド間には何もFDに対して操作していません。なぜか、2回目には、新たなFDを認識するような感じです。

 

こんな感じでFDの入れ替え時に問題がある場合がありましたが、手持ちの1.2MB、1.44MBのFDのデータをWindows上からコピーして吸い上げることができました。

一部FDでは読み出しができないものもありましたけど、劣化してしまったものと考え、あきらめました。

 

約1000円のUSB-FDDは中々役立ちました。たぶん、これでお役御免でしょうけど、しばらく保存しておこうとは思っています。FDのデータは吸い上げましたけど、システム系、ゲーム系のオリジナルのFDはもう少し保管しておこうかと思っているからです。

 

今回は、ここまで。

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


Windows95の頃のアドベンチャーソフトを動かす

2016/09/22 11:32

ジャーニーマンプロジェクト2・Buried in TimeをVMware上のWindows XPにインストールできた話を書きました。その後日談を少し。

 

プレイし始め、特に問題なく動かせたと思ったのですが、問題がありました。

それは、ゲーム中に表示されるアニメーション動画が適切に表示されないというものです。

 

最初のうちは、表示されていたのですが、だんだん表示されないようになってしまいました。せっかくの動画表示ですし、表示がまともでないと、プレイもままならない場面もあります。そのため、そのままにしておくこともできません。これの対策を考える必要が出てきました。

 

この症状が現れて、その昔、XPに変わったときに表示がおかしくなったソフトがあったことを思い出しました。

これは恐らく、OSの表示機構が変わったためのような気がしてきました。

ゲームのマニュアルを読むと、Windows3.1では、Video for Windows1.1が必要だけど、Windows95では直接再生機能を使っているような記述がありました。これがXPではさらに変わってしまったのでしょう。

 

さて、どうしたらよいのか、解決策がなかなか見つかりませんでした。動作条件であるWin95が必要なのかもしれません。

そうこうしているうちに、Windows98のインストールディスクが出てきました。PC-98からDOS/Vマシンに変わって初めてのDSP版Windowsです。前の記事では、32ビットのWindowsのインストールディスクで所持しているのがXPだけだと記載しましたが、Win98があったのでした。XPへ移行した時何も不便がなかったので、Win98が再度必要になることもなかったので、ディスクも含めすっかり忘却の彼方に行ってしまっていたのでした。

 

そのWin98ですが、WinXPよりWin95に近いので、もしかしたら、うまく動くかもしれないと思って、VMware上でインストールしてみました。インストール作業自体は、スムーズに進みました。Windows Updateのような仕組みも不明なので、オリジナルのまま動作させようと思っています。しかし、古いOSであるためか、VMwareのデフォルト状態では、音はならない、マウスの動きにクセがあるといった具合でした。

音がならないのは、今回のゲームプレイに支障を来たします。

調べてみると、Creative社のサウンドドライバがあれば音が出るらしいと分かりました。

Creative ENSONIQ AudioPCI on Windows 95/98というスタンドアローンなドライバなら、VMwareで使えるという情報を得ました。ES1371というカード用のものみたいです。

epw9xup.exeというファイルをダウンロードして、Win 98上でインストールしてみました。

Creative社には、今も提供していただいていること感謝したいと思います。

 

インストールが終わると、音が鳴るようになりました。これはうれしい。

なお、この対策が可能になったのは、VMWare Player 上の Windows 98 で音を鳴らすという記事のおかげです。

 

一方マウスの方は、これといった対処法が見つかりませんでした。多少ましになったと思った設定は、親のWin10上でのマウス設定で、余計な機能 (自動的に既定のボタン上へ移動とかポインタの速度の設定とか) を外すということだけだったと思います。

 

以上のように、Win98の環境が整ったところで、BIT (Buried in Time)をインストールしました。

動作させてみると、XPの時とは異なり、動画表示もばっちりです。

 

しかし、問題が1つありました。CDROMの仮想化環境です。Win98用の仮想化ソフトを見つける必要がありました。XPで使ったMicrosoft製のものはWin98では使えないので、別のものが必要です。しかし、古いOS用のものを見つけるのも面倒です。 少し悩んでいたら、VMwareでISOファイルをマウントする機能があることがわかりました。それを利用してみました。

仮想マシン設定で、ハードウエアのタブで、追加...を押して設定を開始します。ハードウエアの種類で、CD/DVDドライブを選択し、ドライブ接続の選択でISOイメージを使用するとして、ファイルを指定したらマウントが完了します。

 

今回の場合、BITの3つのISOイメージを別々のドライブに割り当てました。

そして、BITの3枚のCD-ROMがどのドライブレターに当たるかを、c:\Windows\Bitmpc.iniに記述することで、CDの入れ替えなしにゲームのプレイができるようになりました。

 

めでたしめでたしです。

 

さて、BITの方ですが、アドベンチャータイプなので、中々前に進ませることができません。全部自力でやることより、完了させたいというのが希望なのです。

 

古いソフトですが、ネットの力を借りられないか調べてみたところ、見つかりました。

日本語版の情報はありませんでしたが、本家がまだ生きていたようです。

Buried in Time

http://thejourneymanproject.com/presto/journeyman2/bithints.html

というページがあり、そこに、ゲームのヒントが英語の記載でしたがありました。

昔やったのは、全体の7割方といった感じで、ようやく、最後まで見ることができました。

 

ヒントが若干わかりにくい表現だったりしていましたし、アクションが必要な画面も出てきたので、ヒントを見たからと言って単純に終わらせられませんでしたから、十分楽しめました。

 

なお、Win XP/Vista/7対応のBITの新バージョン (内容は同じかもしれません)は、オンラインで購入できるようです。価格は、$5.99と昔の購入価格 (9800円でした)から見ると、非常に安いですね。BITは中々のやりごたえがありましたから、興味のある方はお試しあれ。でも英語版だけなので、ハードル高いでしょうけど。

 

皆さんももし、やりかけのソフトがあったら、仮想化してやり直してみるのもよいかもしれませんよ。

 

私は、あと1つ、RIVENという知る人ぞ知るMYSTの後継のアドベンチャーをこれまた、やりかけのままお蔵入りさせていたものがありましたので、こちらもトライしてみようと思っています。

こちらは、さらにCDの枚数が多く、5枚組という豪華なものなので、CD-ROMの仮想化の恩恵も十分得られると思っています。確かこれは、あまり進められず、途中であきらめてしまったのでした。でも、再挑戦しようと思います。これもWin95用なので、たぶんWin98の環境で動かせると思っています。

 

RIVENも上記のBITと同じく、gog.comでMYSTと共にダウンロード販売されているのが見えました。GAMES→ADVENTUREのカテゴリでトップに表示されてるので、いまだに素晴らしいソフトだということだと思います。私は、その前身のMYSTも持っていて、こちらは最後までやりましたけど、非常によいソフトだったと記憶しています。

 

では、また。

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


Windows95の頃のアドベンチャーソフトをXPで動かす

2016/09/18 15:10

古いWindowsゲームソフトを動かす

PC関係の古いがらくたを整理し始めました。

 

そうしたら、Win95の頃に購入したゲームソフトが出てきました。

ジャーニーマンプロジェクト2/Buried in Timeというアドベンチャータイプのソフトです。

このソフトは、途中までやったものの、最後まで終えることができないまま、環境の変化などで、そのままお蔵入りになっていたものですが、終わりまでいかなかったので、ちょっと気になっていたのです。

 

ずいぶん昔のものですが、Windows用なので、今のWin10で動くのかなと思い、試しにインストールしてみましたが、インストールすらできませんでした。

このソフトは、Windows3.1と95が動作環境となっていました。

ちなみに当時Buried in Timeを動かしていたマシンは、PC-98で、たぶんWindows95だったのではないかと思われます。

でもWin10 (64ビット版)にインストールもできないのは、なぜなの?と思い調べてみると、当時のOSは、おそらく16ビット版と思われますが、それに対応したソフトは、今の64ビットのWindowsでは動かせないということらしいです。16ビットから32ビットに移行していく時は、下位のOS用のソフトを動作させるサポートソフトがあったらしいですが、Win10でWin95 の対応ソフトを動かすようなサポートはないということだということらしいとわかりました。

 

でも、何とか動かせないのかと思って、調べているうちに、上述のように32ビットのWindowsなら、16ビットのソフトも動くようにするWindowsのソフトのサポートがあるらしいことがわかりました。ですが、64ビットになってしまった今、その恩恵には預かれないということらしいです。

じゃあ、昔のWindowsを引っ張り出すかしないと思いましたが、私の所有しているOSで32ビットのものは、XPしかありません。その次に購入したWin7は32ビットかと思いきや、64ビットだったのでした。ということでターゲットは必然的にXPとなります。

 

でも、XPを単にインストールして使うのは面倒ですし、既存のWin10とは別に運用しなければなりませんから、管理が面倒そうです。何か良い方法はないかなと思って調べてみると、仮想化の技術を使って、Win10上で、XPを動かせることが最適ではないかということがわかりました。

仮想化のソフトはいくつかあるようですが、私は、メジャーなVMware Workstation Playerを選んでみました。

 

VMware WorkstationにXPをインストール

VMwareの設定を行い、DSP版CD-ROMからWindowsXPをインストールしました。今のマシンは、当時と比べるまでもなく高速なので、それほど時間はかからずに完了しました。

 

しかし、そこから、少し問題が発生しました。XPはすでにMicrosoftのサポートが終了していたということです。XPがMicrosoftにサポートされていた間は、インストール後、Windows Updateによって、どんどんパッチが当たっていったわけですが、そういうことができなくなってしまっていたのです。XPのサポート終了時は、将来XPを使うことも予定していなかったので、アップデート用のサービスパックも保存していません。

私の持っているXPは、SP1です。それを何とかSP3までにはしたいと思ったわけです。でも自動的にそれが実現できないので、別の方法を考えねばなりません。

 

SP+メーカー

ここで、SP+メーカーというソフトがあることを思い出しました。これは、オリジナルのディスクに、アップデートソフトをパッチを当てて、所望のバージョンのインストールディスクを作るものです。

これなら、もしかしたら何とかできるかも、と思って起動しましたが、アップデートプログラムがその格納場所からなくなっていたりして、途中でエラーとなって完了できませんでした。

 

アップデートするソフトの一覧は、SP+メーカーが持っていたので、それを見て、何とかならないかと調べると、アーカイブとして保存しているサイトを利用するのが1つの対処法ということがわかりました。

それは、XPのService Packがダウンロードできなくなった対処方法2016年2月という記事に書かれているように、INTERNET ARCHIVEのサービスで、ダウンロードしたいURLを入力して見つかったら、それをダウンロードするという手法です。

結構面倒な作業でしたが、何とかSP+メーカーのlistフォルダに格納されていたdefault_wxp.lstに記載があった214個のファイルほぼ全部を手動でダウンロードしました。不要と考えたIE6/7関係のプログラムはスキップしました。

手動でダウンロードはしましたが、結局アーカイブサービスからダウンロードする必要があったのは、5件だけでした。

残りが全部、Microsoftのサイトの元の格納個所にあったわけでなく、20件だけは、Microsoftからダウンロードしたものの、Microsoft Updateカタログのページで検索してダウンロードする必要がありました。しかも、このページは、ieでアクセスする必要がありましたので、少し面倒でしたし、ファイル名も変わっているものがあったりして、推定して元のファイル名に変更して、SP+メーカーで認識できるようにしました。

 

必要なソフトを全部ダウンロードしたら、SP+メーカーでは、ダウロードしたフォルダを指定することで、ダウンロードさせないようにして、SP3のディスクを生成できました。これで、WinXP SP3を直接インストールすることができるようになったはずです。

 

そう書いたのは、上記を完了する前に、VMware上にインストールしたXP SP1上で、ダウンロードしたSP3を使って、アップデートできてしまったからです。そうしたら、Windows Updateがまだ機能しているようで、しばらく時間が経過すると、自動アップデートも動いてたぶんSP3のインストールだけでは不足だったアップデートのインストールをするように促す黄色のアイコンが現れたりしました。

 

ということは、SP1ではWindows Updateは動作しませんでしたが、SP3ならまだ、必要なセキュリティパッチが自動で当たるようにMicrosoftのサーバが稼働しているのだろうと思いました。

 

でも、それもいつまで動いているかわかりませんから、上述のSP+メーカーで最新版のSP3のインストールディスクを作っておくのもよいと思いました。結局今回は、これは使っていないので、動作確認して置く必要がありますね。時間があったらやりたいと思います。

 

これで、32ビットOSであるXPの環境が用意できました。

 

Buried in Timeのインストール

いよいよ、Buried in Timeをインストールしてみます。これは、豪華CD3枚組のソフトです。

そのため、ゲーム途中でCDを入れ替えるようにメッセージが出て動かすのですが、それが結構面倒だったことを思い出しました。でもCDチェンジャー(懐かしい名前ですね)対応となっており、ドライブが複数あれば、どのドライブにどのCDが入っているのかをあらかじめ設定しておけば、CDを入れ替えずにゲームが使える仕組みになっています。

今は、物理ドライブは1つしかありませんので、ここは、CDの仮想化を行って、CDを入れ替えなしで、プレイしたいと思いました。

 

まず、CDROMの内容をisoファイルにする必要があります。それは、簡単でした。Win10のエクスプローラで、CDを挿入したドライブをマウス右クリックすると、以下のようなポップアップがでます。

image

その中から、Create image from CD/DVDという項目を選択します。

そうすると、Record CD/DVDというタイトルのソフトが立ち上がるので、isoファイル作成先を指定してNextを押せばコピーされます。

image

これは、Windowsの標準機能だそうです。便利になったものです。

コピーが完了したら、Finishを押して終了させます。

 

CDのデータをISOファイルとして準備できたら、次は肝心のCD-ROM仮想化ソフトを用意しないといけません。探してみたら、Microsoft謹製のVirtual CDRom Control Panelというソフトが良さそうです。これは、XPから7まで使えるソフトなので、VMware上のXPにもインストールできます。

 

ダウンロードしたwinxpvirtualcdcontrolpanel_21.exeを実行すると、3つのファイルが生成されました。

readme.txt、VCdControlTool.exe、VCdRom.sysです。

readmeに手順が書いてあるので、それに従って作業を進めます。

VCdRom.sysは、%systemroot%\system32\driversフォルダに入れます。

そして、VCdControlTool.exeを実行します。

仮想ドライブの追加を行い、先ほど作成したisoファイルをその追加したドライブにマウントします。

 

これで、CD-ROMがなくても、仮想的にアクセスできるようになりました。

 

準備ができたところで、Buried in TimeをXP上でインストールしてみます。Win10の時とは異なり、ちゃんとインストールできました。

そして、実行してみると、ちゃんと動きました。すばらしい。

でも、設定を忘れていました。上述したように3枚のCDROMがどのドライブに入っているか指定しないといけません。c:\Windowsの下に、BITMPC.INIというファイルができているはずなので、DiskPath1=W:\、DiskPath2=X:\、DiskPath3=Y:\のような感じで、3枚のCDがどのドライブにあるかを記述しました。これで、CDを入れ替えずに、ゲームを進行させられます。

 

では、さっそく楽しみたいと思います。涼しくなってきたので、こういうアドベンチャータイプのものを楽しむのによい季節ですから。

 

なお、マウス、サウンド、ディスプレイ等は、VMwareの標準状態で対応できており、特別に何かする必要はありませんでした。

 

ではまた。

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


停電からSheeva関連で問題発生した時の経緯

2016/09/16 22:16

東京電力からスマートメータに取り換えると連絡があり、一時的に停電となりました。

その後、色々と問題が発生しました。

外部からSheevaPlug+のWebサーバにアクセスできなくなりました。

停電だけが問題ではなく、この前のOSのバージョンアップも絡んでいたようです。

 

SheevaPlug+上で動作させていたソフトの初期設定が必要みたいです。

サーバはずっと稼働させっぱなし状態みたいなものでしたから、すっかり何をしたか忘れてしまっています。

過去の記事やらを見ながら設定していきます。

 

まずは、サーバが外部からアクセスできるようにしないといけません。

無料ダイナミックDNSを使っていましたが、たぶん、WAN側のIPアドレスが変わってしまったように思えます。

 

私の場合、kazhat.dip.jpという名称で、家サーバさんのところで登録管理してもらっています。

 

そこからddns-update.plをダウンロードしてきて、そのプログラム内に、$ACCOUNT、$DOMAIN、$PASSWORDを設定します。

これを/usr/lcoal/ddnsディレクトリに格納しました。

Debianの新バージョンをインストールした後、これをすっかり忘れていて、何もしていなかったのでした。

ここの設定に関しては、ダイナミックDNSサービスを利用してみるに、書いていました。

 

以下のように実行していきました。

/usr/local/ddns$ sudo crontab -e
[sudo] password for ohno:

エディタが開くので、

5,35 * * * * /usr/local/ddns/ddns-update.pl

を書き込んで、^xを入力すると、/tmp/crontab.0nuDqH/crontabに書き込むみたいです。

 

crontab: installing new crontab

という表示が出て、終了しました。

 

でも、終わってみると、書き込んだはずのファイルは、そこには、ありません。

どうも、/var/spool/cron/の下のcrontabsの下に格納されたみたいです。

 

 

/usr/local/ddns$ sudo ./ddns-update.pl

と入力して、試しに起動したところ、うまく動いたみたいです。

 

current_ipとip_update.logというファイルが生成されました。

 

crontabも実行したので、たぶん、30分ごとに更新されるはずです。

 

この後、外部からアクセスできるようになりました。

 

大した話ではありませんでしたが、今回はこれで終わりです。

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


続きを見る

トップへ

月別リンク

KazHatブログ/BIGLOBEウェブリブログ
文字サイズ:       閉じる