[VMware]JISキーボードがASCII配列に誤認識されるのを修正する

VMwareでゲストOSがWindows XPのVMを作成しているのですが、先日VMware Converterを使用して仮想マシンのバージョンを変更したら、キーボードの配列がASCIIと誤認識されてしまいました。

その時に修正した方法をメモしておきます。
(今回はVMwareが原因で問題が起きましたが、解決方法はWin XPの一般的な作業方法です)


コントロールパネルよりキーボードを選択し、ハードウェアタブのプロパティを選択します。


ドライバの更新をクリックし、ウィザードで”いいえ、今回は接続しません”を選択します。


“一覧または特定の場所からインストールするを選択します”を選択します。


“検索しないでインストールするドライバを選択する”を選択します。



互換性のあるのチェックボックスをオフにし、標準キーボードの日本語 PS2キーボード(Ctrl+英数)を選択します。


このあと警告が出ますが、はいをクリックします。
ドライバのインストール後、再起動を要求されるので指示に従います。


これで、JIS配列キーボードとして無事認識されるようになります。

[Spy++]謎の横長ウィンドウが表示されている原因を調査する

最近PCを使っていると、下のようなウィンドウが表示されいることがあります。


気が付くと表示されていて何がきっかけになっているのか分かりません。タスクマネージャにも出てこないし気持ち悪いので、何者なのかちょっと調べてみました。




という訳でどうやって調べたか、方法を説明します。
ちなみに、使っているOSはWindows7 x64です。

まずは、このウィンドウのプロセスを調べます。
このPCにはVisual Studioが入っているので、Spy++というソフトで調査します。このソフトを使うと、画面に表示されているウィンドウを指定して、そのプログラムの情報を表示してくれます。


Spy++を起動したら、検索->ウィンドウ検索を選択します。



すると、以下の様なダイアログが表示されるので、矢印の先にある黒い丸をドラッグして、調べたいウィンドウにドロップします。


そうすると、対象のウィンドウハンドルが表示されます。今回は00C406F0でした。



OKをクリックすると、メインウィンドウで該当のウィンドウハンドルが反転されています。右クリックから、プロパティを選択します。



プロセスタブをクリックすると、プロセスIDが判明します。このIDはリンクになっているのでダブルクリックします。



すると、プロセスの情報が表示されます。ACRRD32という事は、Acrobat Readerですね(今はAdobe Readerという名前に変わってますが)。ACRRD32って何?という人でもgoogle検索すれば直ぐに判明します。


タスクマネージャで確認したところ、AcroRd32.exeが複数常駐していました。


ウィルスかも?と思って、プロパティを見てみましたが、パスは正しそうなので大丈夫っぽいです。


というところまで調査したところで、常駐していたAcroRd32.exeを強制終了させると、無事謎のウィンドウは消えてくれました。Adobe Readerはアップデートの有無をバックグラウンドでチェックしてくれてたはずですが、その関係の不具合でしょうか…?


Windowsデバッグの極意 ツールを使いこなして、バグハント!

[PIC]C18コンパイラでstrcpy()使用時,文字列セットが出来ない

PICのプログラムをC18コンパイラを使用して開発している場合、以下のコードは正しく動作せず、Bufferに”hello”という文字列がセットされません。
(当然ですが、このコードはVisual C++の様な普通のCコンパイラだと正しく動きます)

char Buffer[32];
strcpy( Buffer, "Hello" );




これは、”Hello”の文字列定数がプログラムメモリに配置されるのに対して、strcpy()関数は指定された番地のRAM(File Register)からデータをReadしようとする為です。

PICはハーバードアーキテクチャを使用しているため、プログラムメモリとRAMのアドレス空間が分離しています。上記のコードでは、”Hello”が保存されているプログラムメモリの番地をRAMの番地と見なして、メモリコピーが行われるため、結果として不正な番地のデータを読み出してしまうことになります。


これを防ぐには、プログラムメモリからデータを読み込むよう明示する必要があります。
C18コンパイラではこのような場合の為にstrcpypgm2ram()という関数を用意しています。

問題のコードを以下の様に変更すると、想定どおりBuffer配列に”hello”という文字列がセットされます。

char Buffer[32];
strcpypgm2ram( Buffer, "hello" );



[PHP]goto文を使用すると「syntax error, unexpected T_STRING」エラーが発生

PHPでgoto文を使用したプログラムを書いていたのですが、手元の開発環境だと動作するのに、サーバにアップロードすると以下のエラーが発生するという問題が発生しました。

Parse error: syntax error, unexpected T_STRING in ...




手元の環境だと動くという事は、環境の問題なので、まずはphpinfo()でバージョンを確認してみます。

開発環境

PHP Version 5.3.1
System  Windows NT 5.1 build 2600 (Windows XP Professional Service Pack 3) i586



本番環境

PHP Version 5.2.17
System  Linux 2.6.18-308.11.1.el5PAE #1 SMP Tue Jul 10 09:29:33 EDT 2012 i686




PHPのオンラインマニュアルで確認したところ,そのものずばりの答えがありました。
gotoがサポートされたのはバージョン5.3以降だそうです。

http://php.net/manual/en/control-structures.goto.php より


goto 演算子を使用すると、 プログラム中の他の命令にジャンプすることができます。 ジャンプ先はラベルとコロンで表し、 goto の後にそのラベルを指定します。 これは、完全に制約のない goto というわけではありません。 対象となるラベルは同じファイル上の同じコンテキストになければなりません。 つまり、関数やメソッドの外に飛び出したり 関数やメソッドの中に突入したりすることはできないということです。 また、いかなるループや switch 構造の中にも突入することができません。 逆にループや switch 構造から抜け出すことはできます。一般的な用法としては、 goto を複数レベルの break として使うものがあります。



マニュアルにもあるように、PHPのgotoはC言語などと比べて制限があり、多重ループの抜け出しなどの特定の状況でしか使えません。

例えば以下のコードはエラーになるそうです。

<?php
goto loop;
for($i=0,$j=50; $i<100; $i++) {
  while($j--) {
    loop:
  }
}
echo "$i = $i";
?>




一般に”gotoは悪”と言われてますが、個人的には共通の終了処理有りのガード節を書く時に良く使うので、goto禁止はちょっと不便です…。 try-finallyで代替しようにも、PHPにはfinallyが無いし困ったもんだ。

[PHP]SimpleXMLでxmlツリーを作成し、綺麗に整形して出力する

PHPでSimpleXMLを使用してxmlの作成を行います。

プログラム

<?php
$rootNode = new SimpleXMLElement( "<?xml version='1.0' encoding='SHIFT_JIS' standalone='yes'?><items></items>" );
 
// ノードの追加
$itemNode = $rootNode->addChild('item');
$itemNode->addChild( 'itemCode', 'mk' );
$itemNode->addChild( 'itemName', 'orange' );
 
$itemNode = $rootNode->addChild('item');
$itemNode->addChild( 'itemCode', 'ap' );
$itemNode->addChild( 'itemName', 'apple' );
 
$itemNode = $rootNode->addChild('item');
$itemNode->addChild( 'itemCode', 'tof' );
$itemNode->addChild( 'itemName', '豆腐' );
 
// ノードに属性を追加
$itemNode->addAttribute('stock', 'none');
 
// 作ったxmlツリーを出力する
echo $rootNode->asXML();



実行結果

<?xml version="1.0" encoding="SHIFT_JIS" standalone="yes"?>
<items><item><itemCode>mk</itemCode><itemName>orange</itemName></item><item><itemCode>ap</itemCode><itemName>apple</itemName></item><item stock="none"><itemCode>tof</itemCode><itemName>豆腐</itemName></item></items>





asXML()でxmlが出力されますが、改行が入らないので人が見たときに可読性に劣ります。
このような場合は、SimpleXMLを利用すると綺麗にインデントされます。

プログラム(最初のプログラムのasXMLを以下のコードに置き換える)

$dom = new DOMDocument( '1.0' );
$dom->loadXML( $rootNode->asXML() );
$dom->formatOutput = true;
echo $dom->saveXML();



実行結果

<?xml version="1.0" encoding="SHIFT_JIS" standalone="yes"?>
<items>
  <item>
    <itemCode>mk</itemCode>
    <itemName>orange</itemName>
  </item>
  <item>
    <itemCode>ap</itemCode>
    <itemName>apple</itemName>
  </item>
  <item stock="none">
    <itemCode>tof</itemCode>
    <itemName>豆腐</itemName>
  </item>
</items>



これでだいぶ見やすくなりました。

[PHP]改行なしスペース(&nbsp;、0xA0)を、普通の空白(0x20)に置換する

PHPで改行無しのスペース(&nbsp;)は文字コード0xA0で表現されます。
この改行無しスペースを普通のスペースに置換するには、以下のコードを使用します。

$str = trim( $str, chr(0xC2).chr(0xA0) );



正規表現を使用する場合は以下のパターンになります。

$str = preg_replace( "/^\xC2\xA0/", "", $str );



0xA0なので、chr(0xC2).chr(0xA0)ではなくchr(0xA0)では?と思われるかもしれませんが、UnicodeとISO/IEC 10646規格上において、”nbspは、UTF-8エンコードでは0xC2 0xA0と表現する。”となっている為です。

[C言語]文字コードがACSIIで無い場合にコンパイルエラーを出す方法

上手い事プリプロセッサ命令を使ってるなと思ったのでメモ。
#ifで、アルファベット’a’の文字コードを調べることで判定しています。

gawk3.1.5のソース(eval.c)より。

#if 'a' == 97	/* it's ascii */
	// ...文字コードがASCIIだったときの処理
#else
#include "You lose. You will need a translation table for your character set."
#endif

電子回路用CADのEAGLEをインストールする


今回は、電子工作用の回路図作成やプリント基板(PCB)のレイアウトソフトとして有名な、eagleのインストールを行います。


EAGLEは商用のソフトなのですが、非営利目的なら一部制限がありつつもほぼ全ての機能がフリーで使用することが出来ます。仕事で使うのなら商用ライセンスが必要ですが、個人のホビーユースならフリー版でも十分に利用する事が出来ます。

フリー版の制限は以下の通りです。

ボードのサイズが100 x 80 mm (4 x 3.2 inches)までに制限される。
多層基板は作成で傷、2面(両面実装の基板)までしか作成できない。
プロジェクト内に回路図は1枚しか作成できない。


個人が趣味レベルで作る場合は多層基板を作る必要は少ないですし、回路図の制限もプロジェクトを分ければ問題ありません。ですので実質的は制限はサイズだけです。


インストール手順


まずは、eagle開発元であるCadSoftのサイトにアクセスします。
CadSoft EAGLE PCB Design Software – EAGLE Support, Tutorials, Shop


ページ上部のメニューよりDownload EAGLEを選択します。




ダウンロードページよりWindows版を選択します。
今回は説明しませんが、Linux,Mac版も用意されています。

ファイルのダウンロードが完了したら、exeを実行します。


ファイル展開のダイアログが出るのでSetupをクリックします。



ファイルの展開が完了したらセットアップの開始画面です。
Nextをクリックします。



ライセンス内容を確認後、Yesをクリックします。



インストール先フォルダを選択し、Nextを選択します。
デフォルトと異なる場所にインストールしたい場合は”Browse”ボタンをクリックして、場所を指定します。


インストール前の最終確認です(といっても、フォルダ指定をしただけですが…)
確認後Nextを選択します。インストール作業は比較的短時間で完了します。




ラインセンスモードの選択です。今回はフリー版として使用したいので”Run as Freeware”を選択します。
ちなみにFreemium codeというのは、30日お試し期間付きの製品版です。
無償版ではないので注意してください。


これでセットアップ完了です。Finishを選択します。




次にEAGLEを起動します。スタートメニューより、EAGLEを選択します。


プロジェクトファイルの保存先指定です。デフォルトではマイドキュメントの下にeagleフォルダが作られるのですが、メッセージにあるように後で変更できるのでとりあえずそのままYesを選択します。
もし、このフォルダ以外に保存したい場合は、一旦Noをクリックした後、メニューのOption->Directoriesで指定できます。
(Projectsの”$HOME\eagle”という部分で、$HOMEはマイドキュメントを意味しています)


EAGLEの起動画面です。フリー版としてインストールした場合は、右側に”Light Edition”と表示されるはずです


File->New->Projectを選択します。


Projectフォルダが追加されるので、適当な名前に変更しておきます。


さらにPrjectフォルダを右クリックし、Schematic(回路図面)を新規作成します。


図面作成ウィンドウが表示されました。



これでEAGLEのインストールと起動確認の作業は完了です。
次回はEAGLEを使用して簡単な回路を書いてみます。

[HI-TECH C] “Warning [228] illegal character”警告が出る場合の対処法

HI-TECH Cでプログラムをコンパイルすると、以下のようにWarning [228]の警告が出ることがあります。
これは”警告”なのでコンパイルは完了し、大抵の場合プログラムは想定どおり動作することが多いです。


Make: The target "C:\home\project\pic\16F84A_LCD\main.p1" is out of date.
Executing: "C:\Program Files\HI-TECH Software\PICC\9.83\bin\picc.exe" --pass1 C:\main.c ..."
Warning [228] C:\home\project\pic\16F84A_LCD\main.c; 11.17 illegal character (0xC3)




原因

これは、プログラムのソースコード中にASCII以外の文字が出現した時に発生します。
ASCII文字はいわゆる半角の英数字で、ASCII以外というのは全角文字や、半角カナを意味します。

例えば以下のコードだと警告が表示されてしまいます。

char msg[8+1] = "テスト";



LCDを使うと文字出力に半角カナを使用することがあり,LCD制御プログラムで発生することが多いです。


対処法

この警告の表示を抑制するためには、以下のpragma命令をファイルの先頭付近に記述すればOKです。

#pragma jis




#pragma jisの意味

#pragma jisを書くと、ソースコード中に2バイト文字が含まれる事をCコンパイラに伝える事が出来ます。
このpragmaはWarning [228]の抑制以外にも、2byte目が0x5c(バックスラッシュ)を含む文字列リテラルでエラーが起きる現象も抑制できます。

例えば全角カタカナの”ソ”は、”0x83 0x5c”で、2byte目が”\”となり、通常ではこれがエスケープシーケンス記号であるとコンパイラに認識され、エラーが発生します。

char msg[2+1] ="ソ";
 
  ↓
 
Warning [228] C:\home\project\pic\16F84A_LCD\main.c; 11.15 illegal character (0x83)
Error   [311] C:\home\project\pic\16F84A_LCD\main.c; 11.15 closing quote expected
Error   [372] C:\home\project\pic\16F84A_LCD\main.c; 12.1 "," expected



このエラーも#pragma jisを記述する事で対処できます。
#pragma命令は、C言語の規格であるANSI Cでは、コンパイラ依存の命令(コンパイラ自身に対する指示)と定められています。

入門ANSI‐C

PIC16F84Aで,HI-TECH Cを使用してLCD出力を行う



PIC16シリーズの定番、PIC16F84Aを使用してLCDへの出力を行うプログラムです。
16F84AでC言語を使用したLCD制御のサンプルは、意外と見つからないので公開しておきます。

LCDは16文字x2行表示が行えるSC1602を使用します。


また、Cコンパイラは、HI-TECH Cを使用します。HI-TECH Cは、PICC LITEとも呼ばれています。
HI-TECH CにはLCD制御用のライブラリがない為、プロトコルを確認してコマンド送信を自前で実装する必要があります。

動作確認はPIC16F84Aで行っていますが、特殊な事はしてないので16Fシリーズなら基本的にどのチップでもそのまま動くはずです。もし、16F84A以外のPICを使用する場合で、出力ピンがANxと共用になっている場合はピンがデジタル出力モードになっていることを確認してください。


LCDのピンアサイン

SC1602の代表的なピンアサインは以下の通りです。
基本的にこれと同じはずですが、モノによってはVccとGND(ピン1,2)が逆になっているモノも有るので、注意してください。
また、LCDはバックライト有り/無しのものが有りますが、動作確認する上ではどちらでもかまいません。



LCD接続の回路図


SC1602のキャラクタLCDは、データバスの接続が8bitモードと4bitモードが有ります。
今回はPIC16F84Aで、ピン数が少ないので4bitモードを使用します。


また、LCDデータの読み書きを制御するのにR/Wピンが有りますが、これも使用しません。
R/Wピンを使用すると、LCDに書き込み可能か、BusyステータスをReadすることで確認できるのですが、PICの使用ピン数を減らすために接続せず、GNDに落としておきます。R/WピンがLowだと常にWriteモードになります。そうするとPIC側からLCDに書き込み可能かを知ることができないのですが、そこはデータシートで定められた時間分delayをかけることで対応します。これは、LCD制御で接続ピン数を最小にしたい場合に良く取られる手法です。

ピンアサインは、LCD.cの先頭のdefineで定義しています。

#define LCD_RS     PORTAbits.RA0
#define LCD_ENABLE PORTAbits.RA2
#define LCD_DATA   PORTB
#define LCD_DATA_IS_LOW		// PortBの下位4bitをLCDのDB4-7に接続





それでは、プログラムのソースを確認していきます。

メイン関数

まずは、LCD処理の呼び出し元側のmainです。
特に説明することが無いほどのプログラムです。

#include <htc.h>
#include "lcd.h"
 
//--------------------------------------
// コンフィグレーションビットの指定
//--------------------------------------
__CONFIG ( FOSC_HS & WDTE_OFF & PWRTE_ON & CP_OFF );	
 
void main( void )
{
 
	TRISA = 0x00; // RA0-7をOutputにする
	TRISB = 0x00; // RB0-7をOutputにする
 
	// LCD初期化
	lcd_init();
 
	// LCD画面クリア
	lcd_cls();
 
	// LCDに文字列出力
	lcd_locate( 0, 0 );
	lcd_puts( "Hello world" );
 
	lcd_locate( 1, 0 );
	lcd_puts( "コンニチワ" );
 
 
	while( 1 ) {
		; // nop
	}
}




LCD制御用ライブラリ


次に、ライブラリです。

lcd.h


#ifndef _LCD_H_
#define _LCD_H_
 
void lcd_init( void );
 
void lcd_cls( void );
void lcd_locate( unsigned char x, unsigned char y );
void lcd_putc( char c );
void lcd_puts( const char *p );
 
#endif




lcd.c


#include <htc.h>
#include "lcd.h"
#define _XTAL_FREQ 8000000	// __delay_ms()用クロック定義 (8MHz駆動)
 
 
//-----------------------------
// PIC-LCDのピンアサイン
//-----------------------------
#define LCD_RS     PORTAbits.RA0
//#define LCD_RW   PORTAbits.RA1 // 未使用
#define LCD_ENABLE PORTAbits.RA2
#define LCD_DATA   PORTB
#define LCD_DATA_IS_LOW		// PortBの下位4bitをLCDのDB4-7に接続
 
// 内部関数のプロトタイプ宣言
static void lcd_write_cmd( unsigned char data );
static void lcd_write_databus( unsigned char data );
 
//****************************************************************************************
// Function	: lcd_init
// Description: LCD初期化処理(4bitモード)
//****************************************************************************************
void lcd_init( void )
{
 
	//-------------------
	// 制御ピンの初期化
	//-------------------
	LCD_RS     = 0;
	LCD_ENABLE = 0;
#ifdef LCD_DATA_IS_HIGH
	LCD_DATA   = (LCD_DATA & 0x0f);
#else
	LCD_DATA   = (LCD_DATA & 0xf0);
#endif
 
	__delay_ms( 20 );			// 15mSec以上ウェイト		
 
 
	//-------------------
	// LCD初期化処理
	//-------------------	
	lcd_write_databus( 0x03 );		
	__delay_ms( 10 );			// 4.1mSec以上ウェイト
 
	lcd_write_databus( 0x03 );	
	__delay_us( 200 );			// 100uSec以上ウェイト
 
	lcd_write_databus( 0x03 );	
 
	// モードの指定
	lcd_write_databus( 0x02 );	// 4bitモードに変更する
	__delay_ms( 1 );			// 40uSec以上ウェイト
 
 
	//--------------------
	// 画面のクリア
	//--------------------
	lcd_write_cmd( 0x28 );	// ファンクションセット(2行表示、5*7dot)
	__delay_ms( 1 );
 
	// Display off
	lcd_write_cmd( 0x08 );	// ディスプレイ・カーソルの設定(カーソル非表示)
	__delay_ms( 1 );
 
	lcd_write_cmd( 0x01 );	// clear display
	__delay_ms( 1 );
 
	lcd_write_cmd( 0x06 );	// エントリモード(1:右にスクロール、0:シフトなし)
	__delay_ms( 1 );
 
//	lcd_write_cmd( 0x0F );	// ディスプレイ・カーソルの設定(ディスプレイ:ON, カーソル:ON , カーソル点滅:ON)
//	lcd_write_cmd( 0x0E );	// ディスプレイ・カーソルの設定(ディスプレイ:ON, カーソル:ON , カーソル点滅:OFF)
	lcd_write_cmd( 0x0C );	// ディスプレイ・カーソルの設定(ディスプレイ:ON, カーソル:OFF, カーソル点滅:OFF)	
}
 
 
//*****************************************************************************
// Function 		: lcd_locate
// Description	: 印字位置の指定
//*****************************************************************************
void lcd_locate( unsigned char x, unsigned char y )
{
	unsigned char writeData;
 
	writeData = 0x40 * x + y;	// 表示位置を決定(2行目に出すときは,3bit目を立てる)
	writeData |= 0x80;			// 最上位ビットを立てる
	lcd_write_cmd( writeData );	
}
 
 
//*****************************************************************************
// Function 		: lcd_cls
// Description	: LCD画面クリア
//*****************************************************************************
void lcd_cls()
{
	lcd_write_cmd( 0x01 );	// clear display
	__delay_ms( 3 );		// 1.64mSec以上ウェイト
}
 
 
//*****************************************************************************
// Function 		: lcd_putc
// Description	: LCDに1文字出力
//*****************************************************************************
void lcd_putc( char c )
{
	LCD_RS = 1;
	__delay_us( 1 );	// 40nSec以上
 
	lcd_write_databus( (c & 0xf0) >> 4 );
	lcd_write_databus( (c & 0x0f)      );
}
 
 
//*****************************************************************************
// Function 		: lcd_puts
// Description	: LCDに文字列出力
//*****************************************************************************
void lcd_puts( const char *p )
{
	while( *p != '\0' ) {
		lcd_putc( *p );
		p++;
	}
}
 
 
//*****************************************************************************
// Function 		: lcd_write_cmd
// Description	: 4bitモードでの命令書き込み(RS=LOW)
// 				  命令は上位ビットから順に送る
//*****************************************************************************
static void lcd_write_cmd( unsigned char data )
{
	LCD_RS = 0;
	__delay_us( 1 );	// 40nSec以上
 
	lcd_write_databus( (data & 0xf0) >> 4 );
	lcd_write_databus( (data & 0x0f)      );	
}
 
 
//*****************************************************************************
// Function 		: lcd_write_databus
// Description	: dataで指定された下位4bit分のデータをDB4-7に書き込む
//*****************************************************************************
static void lcd_write_databus( unsigned char data )
{
	// まずEnableをactiveする
	LCD_ENABLE = 1;
 
	// 書き込むべきデータをセット
#ifdef LCD_DATA_IS_HIGH
	LCD_DATA = (LCD_DATA & 0x0f) | ( (data<<4) & 0xf0);
#else
	// 下位4bitにセットする
	LCD_DATA = (LCD_DATA & 0xf0) | (data & 0x0f);
#endif
	__delay_us( 1 );	// 80nSec以上
 
 
	// Enableをinactiveにする
	LCD_ENABLE = 0;
	__delay_us( 1 );	// 10nSec以上
 
	// データをALL0でクリアしておく
#ifdef LCD_DATA_IS_HIGH
	LCD_DATA = (LCD_DATA & 0x0f); // 上位4bitをクリア
#else
	LCD_DATA = (LCD_DATA & 0xf0); // 下位4bitをクリア
#endif
}



実行結果

プログラムの実行結果は、以下の様な感じになります。


今回のプログラムは8MHz駆動させています。8MHz以外で使用する場合は_XTAL_FREQのdefineを変更してください。


使用メモリ

16F84はプログラムメモリが1kしかないので、C言語でプログラムするとこれだけで25%もメモリを使ってしまいます。
これは、今回HI-TECH CをLiteモードで使っており、コードサイズの最適化が行われない事も影響しています。

HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode)  V9.83
Copyright (C) 2011 Microchip Technology Inc.
(1273) Omniscient Code Generation not available in Lite mode (warning)
 
Memory Summary:
    Program space        used   106h (   262) of   400h words   ( 25.6%)
    Data space           used     Bh (    11) of    44h bytes   ( 16.2%)
    EEPROM space         used     0h (     0) of    40h bytes   (  0.0%)
    Configuration bits   used     1h (     1) of     1h word    (100.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)




トラブルシューティング

LCDは良く使われるデバイスでありながら、初期化シーケンスが複雑で、しかも正しく初期化出来ないとLCDは何も言ってくれないので、動作がおかしい場合は何がおかしいのかの切り分けが結構難しいです。
上手く動作しない場合は、以下の点を確認してください。

1.LCDの電源/GNDピンが正しいか

キャラクタLCDは、製品によっては1,2ピンの割り当て(+5V,GND)が逆になっているものがあります。
必ず購入した製品のデータシートを確認し、想定した結線になっていることを確認してください。

2.LCDのコントラスト調整が出来ているか

実際に文字出力が出来ていてもLCDのコントラストが薄すぎで表示が見えなくなっているだけの場合があります。通常だと3番ピンがコントラスト調整ですので、10kの可変抵抗を入れてコントラスト調整をしてください。Vcc,GND,コントラスト調整だけの線を接続した場合、LCDは全てのドットが黒となる表示をするはずなので、この状態で可変抵抗を調整して、ドットが薄い黒になるようにしておきます。

3.配線があっているか

結線間違いは一番ありがちなミスです。
プログラムで指定したピンアサインと、実際の回路があっているかをテスタで通電チェックしてください。

4.駆動電圧があっているか

LCDモジュールは5V駆動以外に3.3V駆動のモノも出回っています。3.3V駆動のものを5Vにつないでしまうと、壊れてしまうので注意してください。
(品番でgoogle検索してデータシートを確認してください)

3.3V駆動のものをつないでしまうと、コントラストを目一杯絞っても真っ黒になってしまうはずです。

5.各コマンド送信後の待ち時間が有っているか

LCDのデバイスによっては、コマンド送信前後の待ち時間が異なるものが有ります。今回のプログラムは有る程度の余裕を持たせていますが、出力が文字化けする場合はタイミング調整してみてください。
(遅くする分には問題ないので、全て10倍する等の極端な待ちを入れてしまってもOKです)

わかるPICマイコン製作集 16F84プログラミングの世界へ


ダウンロード

今回説明したプログラムのソースコードです。
MPLABのプロジェクト形式になっています。

ダウンロード:16F84A_LCD.zip

[VMware]各製品で作ることが出来る仮想ハードウェアのバージョン



VMwareで作成する仮想マシンは、元となるハードウェアに幾つかのバージョンが有ります。
使用する製品によって、作成することが出来る仮想ハードウェアのバージョンが決まっているのですが、その一覧は以下の通りです。

Version 9
    VMware ESXi 5.1
    VMware Fusion 5.x
    VMware Workstation 9.x
    VMware Player 5.x
 
Version8
    VMware ESXi 5.x
    VMware Fusion 4.x
    VMware Workstation 8.x
    VMware Player 4.x
 
Version7    
    VMware ESXi/ESX 4.x
    VMware Fusion 3.x
    VMware Fusion 2.x
    VMware Workstation 7.x
    VMware Workstation 6.5.x
    VMware Player 3.x
    VMware Server 2.x
 
Version6 
    VMware Workstation 6.0.x
 
Version4
    VMware ACE 2.x
    VMware ESX 3.x
    VMware Fusion 1.x
    VMware Player 2.x
 
Version3と4
    VMware ACE 1.x
    VMware Lab Manager 2.x
    VMware Player 1.x
    VMware Server 1.x
    VMware Workstation 5.x
    VMware Workstation 4.x
 
Version3
    VMware ESX 2.x
    VMware GSX Server 3.x



基本的に新しいバージョンのほうが多機能ですが、原則として過去の製品で新しいバージョンのVMを起動させることは出来ません(例えば,Version9のVMをVMware Server1.xで起動することは出来ません)。逆に新しい製品で、古いVMの起動は可能です。

VMware Workstation 6.x以降、VMware Converter 3.x以降、VMware Fusion 2.x以降では古い仮想ハードウェアにダウングレード出来るらしいです(…らしい,というのは該当の製品を持ってないので実際に操作してた事はないです)。

また、VMware Player以外の製品では、最新の仮想ハードウェアにアップグレードできます。



仮想ハードウェアもVersion4ぐらいだとUSB1.0しか使えなかったのですが、Version7にアップグレードすると、以下のようにUSB2.0が選択可能になります。
(もちろん使用するにはゲストOS側でのサポートは必要ですが)

USBを頻繁に使用する環境を使用している場合は、アップグレードすると使い勝手がかなり変わるので一度検討してみるのも良いかと思います。
もしもの時にそなえてアップグレード前にはフルバックアップは忘れずに!!


VMwareによる仮想マシンの構築・活用
はじめてのVMware

[PIC]ICD2デバッグ時に「ICD0154エラー」が出た場合の対処法

エラーの内容

MPLABでMicrochip ICDを使用してプログラム書き込み/デバッグを行っている時に,以下のエラーが発生する(メッセージ中の”TM = Running”の部分は、変わる場合があります)。



MPLAB ICD 2 ready for next operation
ICD0154: Invalid target mode for requested operation (TM = Running)Running Target
ICD0083: Debug:  Unable to enter debug mode.  Please double click this message for more information.
ICD0069: Debug:  Unable to run target




エラーの理由

MPLAB ICD2は、内部的にプログラムモードとデバッグモードという2つのモードを持っています。
通常だと、これらのモードをプログラマが意識する事は無く自動で切り替わっているのですが、ICD2の内部処理の遅延等で自動で切り替わる事が出来なかった時にこのエラーが出ることがあります。


対処方法

エラーが発生する理由は様々ですが、再発する場合は以下の点を確認してみて下さい。

ROMライタにPICが正しく接続されているか確認します。
 
MPLAB ICD2がPICと結線されているか確認します。
 
PICとICD2に正しく電源が供給されているか確認します。
 
MPLABの開発環境をを再起動させてみます。
 
ICD2をPCから一旦外した後再接続させてみて、問題が再発するか確認します。
 
デバッグモードでエラーが出る場合、コンフィギュレーションビットのデバッグがONになっているか確認します。


エラー”vmware-update-agent.exe は動作を停止しました”が発生する場合にする事

VMwareを以下の環境で使用している場合、”vmware-update-agent.exe は動作を停止しました”というエラーが出ることがあります。

VMware Workstation 2011上で Windows VistaのVMを作る。
作ったVMを、VMWare Player 4.0で使用する。
インストール済みのVMware Tools をアップデートさせる。


この問題が発生する場合、Windows Vistaのコントロールパネルに有る “プログラムと機能の一覧”から VMware Update Agentを削除すればOKです。

[VMware]ゲストOSでUSB3.0/USB2.0を使用する方法

VMwareでUSB2.0やUSB3.0を使用する方法です。

*.vmxに以下の2行を追加すればUSB2.0が使用可能になります。

usb.present  = "TRUE"
ehci.present = "TRUE"





但し、ehci.presentが使えるのはVMware FusionやVMware Workstationの6.0以降で作ったVMな必要じゃないとサポートされていません。(設定を追加してもehci機能はOFFとなってしまいUSB2.0は使えない)


使用しているVMが対応しているかは、*.vmxファイルのvirtualHW.versionを確認し、バージョンが6以上になっていればOKです。

virtualHW.version = "6"





USB3.0は、Ubuntu Linux10.10で、かつカーネル バージョン 2.6.35 以降だと、USB3.0対応の仮想xHCI USBコントローラが用意されています。

usb_xhci.present = “true”.


Windowsでは、xHCIコントローラが無いので、この設定を使用しても動作しません。

[PIC]MPLAB ICDで、「ICDWarn0015エラー」出た場合の対処法

現象

MPLABでICDを使用してデバッグしようとすると、以下のエラーメッセージが表示される。


ICDWarn0015: Program memory has changed since last program operation?  
Continue with Debug operation?



コンソール上では、以下の様なメッセージが出力されます。


ICD0083: Debug:  Unable to enter debug mode.  Please double click this message for more information.
ICDWarn0015: Program memory has changed since last program operation?  Continue with Debug operation?
ICD0200: Operation Aborted (Warning 15).
ICD0069: Debug:  Unable to run targetMPLAB ICD 2 ready for next operation




エラーの理由

PICへプログラム書き込み後にソースが編集されているため、エディタの内容と実行するプログラムに不一致が発生しています。MPLABでは、一応この状態のでデバッグを開始する事は可能ですが、実行しているのが最新のプログラムではないため、デバッグする意味が有りません。


対処法

一旦キャンセルを押して、F10キーを押します(又はメニューよりProject->Makeを選択します)。
その後再度デバッグ実行すれば、警告は表示されなくなります。


プログラムの実行結果がリアルタイムで確認できる開発環境

プログラムの動作をリアルタイムプレビューできる開発環境についてのデモです。ほかにも、電子回路や動画編集など、色々なデモがありますがプログラマ的には最初の20分ぐらいを見れば伝えたい事は分かります

プレゼンは英語ですが、英語が分からなくでも十分に理解できるレベルです。

Bret Victor – Inventing on Principle from CUSEC on Vimeo.


プログラムについては、大きく3つのデモを行ってます。

3:30~ canvasに画像を出力するプログラム
10:45~ スーパーマリオ風横スクロールゲーム
        (特に12:40以降が見どころ!!)
18:05~ バイナリサーチ



書いたコードの振る舞いに対する結果がimmediateにフィードバックされると如何に効率がアップするか、このプレゼンを見ると実感できます。HTMLとかだと、HTMLエディタでCtrl-Sしたタイミングでブラウザをリロードさせる様なスクリプトを良く書いたりするのですが、そのプログラム版です。

気になるのは、ゲームなどのメモリだけで動くプログラムだと問題ないだろうけど、業務アプリみたいにDBが絡むと(というかプログラムの外部で状態を持たせるものはといったほうが正確?)、開発環境を実装するのはかなり難しそうに思います。

…とは言うものの、VisualStudioとかで部分的にも実装してくれれば、かなり効率はアップするはず。

[PIC]ICDWarn0013エラーが出る時の対処法

MPLABでPICのライタにICD2を使用している場合、プログラムをデバッグ実行しようとした時に以下のエラーが出る事があります。


ICDWarn0013: Low Voltage Programming cannot be enabled when ICD 2 is used as a debugger.  
Disable Low Voltage Programming?




これはPICのICD2をデバッガとして使用するときに,ICD2がLVPに対応していないからです。
LVPというのはLow Voltage Programmingの略で、低電圧でPICへプログラム書き込みを行う機能です。

このエラーが出ないようにするには、*.cファイルに以下のpragma命令を追加してください。
(例はC18コンパイラを使用している場合のものです)

#pragma config LVP = OFF // Single-Supply ICSP disabled


[PHP]DOMとSimpleXMLの相互変換

PHPではバージョン5.0以降でSimpleXML拡張モジュールというものが追加されました。
SimpleXMLを使用すると、これまでのDOMオブジェクトに比べてXMLの操作が容易になります。

ですが、古いバージョンを元にしたライブラリではDOMベースのプログラムも少なくありません。
そこで今回はDOMとSimpleXMLの相互変換関数を確認しておきます。



SimpleXML -> DOM


SimpleXMLからDOMの変換はdom_import_simplexml関数を使用します。

関数仕様

DOMElement dom_import_simplexml( SimpleXMLElement $node )



プログラム例

// SimpleXMLオブジェクトを作成
$xmlStr = '<items><item>item1</item><item>item2</item></items>';
$sxml = simplexml_load_string( $xmlStr );
 
// DomNodeオブジェクトに変換
$dxml = dom_import_simplexml( $sxml );
 
// 変換後のオブジェクトから情報を取得
foreach( $dxml->childNodes as $data ) {
    echo( $data->getNodePath() . ": " . $data->C14N() . "\n" );
}



実行結果

/items/item[1]: <item>item1</item>
/items/item[2]: <item>item2</item>





DOM -> SimpleXML


逆にDOMからSimpleXMLに変換する場合は、simplexml_import_dom()です。

関数仕様

SimpleXMLElement simplexml_import_dom ( DOMNode $node [, string $class_name = "SimpleXMLElement" ] )



プログラム例

// DOMオブジェクトを作成
$xmlStr = '<items><item>item1</item><item>item2</item></items>';
$dxml   = new DOMDocument;
$dxml->loadXML( $xmlStr );
 
// SimpleXmlオブジェクトに変換
$sxml = simplexml_import_dom( $dxml );
 
// 変換後のオブジェクトをダンプ
var_dump( $sxml );



実行結果

object(SimpleXMLElement)[2]
  public 'item' => 
    array
      0 => string 'item1' (length=5)
      1 => string 'item2' (length=5)

楽天のウィジェットに見たことある商品ばかり表示されるのでhostsを編集して非表示にさせる

最近いろんなサイトが楽天のウィジェットを設置しているので、それらのサイトを訪問すると「過去に楽天で購入した商品」や「過去に楽天で閲覧したけど買わなかった商品」などが表示され、あまりいい気持ちはしません。

というわけで、楽天の商品閲覧履歴をこの際オフにしておきます。

楽天のウィジェットに見たことある商品ばかり表示されるので閲覧履歴をオフにするより

F.Ko-Jiさんのサイトにて、楽天側で閲覧履歴を取らせないようにすることで、楽天ウィジェットの表示内容を制限する方法を紹介されています。


説明されている手順で、自分の閲覧履歴に関連する商品は表示されなくなりますが、替わりに興味が無い商品が表示されてしまいます。楽天のウィジェットは商品画像がアニメーションされており結構目障りなので、ウィジェット自体を非表示にさせてみます。


まずは、自分のPCの中にあるhostsファイルを開きます。
windowsの場合、以下のフォルダ辺りにあります。

C:\Windows\System32\drivers\etc




このhostsファイルを、メモ帳などのエディタで開いて、以下の2行を追加します。

127.0.0.1 xml.affiliate.rakuten.co.jp
127.0.0.1 static.affiliate.rakuten.co.jp






ファイルを保存後、ブラウザで楽天ウィジェットがあるサイトを閲覧してみます。
以下のようにウィジェットが非表示になりました。

hosts変更前

  ↓
hosts変更後

[PHP]Eclipse PDTで,関数の検索&関数仕様を検索する方法

PHPのプログラムをEclipse PDT環境で開発している場合に、関数の検索と、関数仕様を調べる方法です。


ウィンドウ->ビューの表示->PHP関数を選択します。


試しにfread()関数を検索してみます。
PHP関数の検索枠が出てくるので、関数名を途中まで入力すると候補が下に表示されます。

選択肢にはmysqli_resultとかも出ていますが、これはクラスのメソッドとして”fre”で始まるものがあるからです。”+”をクリックして展開すると、ヒットしたメソッドが表示されます。

ワイルドカードも使えるので、”f*ad”とか”*read”といった感じで検索も出来ます。


表示された関数をダブルクリックすると、エディタ上に関数名がコピーされます。


右クリック->マニュアルを開くで、http://jp.php.net/manualのヘルプが表示されます。


Pleiades All in One Eclipse等だと日本語で表示されますが、荘でなければ英語版のヘルプが出るかもしれません。これを日本語版に変更したい場合は、アクセス先のURLを変更します。
マニュアルを開く時にアクセスするURLは、ウィンドウ->設定画面から、以下の場所で設定できます。

“http://www.php.net/manual/ja”を指定して、デフォルトにしてあげれば日本語のマニュアルが表示されるようになります。

Eclipse PDTではじめるPHPプログラミング入門