2015年8月25日火曜日

Windows10になったLatitude10とポメラDM100

Latitude10をWindows10にアップグレードしたので、ポメラDM100のBluetooth接続を試してみました。

ポメラDM100をBluetoothキーボードとして接続させてみると、問題なく認識しました。ところが、ファイル転送をさせようとしてもペアリングの手続きは現れますが、接続が完了しません。以前のメモでいうとステップ(5)で、ファイル転送のサービスが表示されないのです。

Windows8、8.1と使えていたので、ハードウェア上の問題はないはず。Windows10の標準のBluetoothドライバーが問題なのかと思い、DELLのサポートページからWindows8のBluetoothドライバーをダウンロードしてきてインストールしてみました。インストール中にタスクバーに表示されるアイコンは空欄になってしまい怪しかったのですが、無事にインストールできました。再度、DM100のBluetoothファイル転送を試みると、これまで同様に使えるようになりました。

これで、ポメラDM100とのBluetooth連携も問題なくできそうです。キーボードとして使うと、相変わらずキートップの表示とは異なる文字が入力されるキーがありますが、pythonで書いたスクリプトで回避しています。

ファイル転送は、PCを開いたデバイス欄にDM100アイコンが追加されるので、それを開くだけでファイル転送ができます。もちろん、ポメラはBluetoothのファイル転送状態にしておきます。フォルダが開かれたところで、ポメラのほうは接続完了状態になりました。


ファイル転送できるようになると、DM100アイコンがデバイスとドライブに追加された


DM100以下には、Main MemoryとSDカードがあり、これはMainMemoryを開いたところ



2015年8月19日水曜日

Latitude10のOSをWindows10にアップグレードした

DELLのLatitude10は、Windows8からWindows8.1にアップグレードして利用していた。Windows10への無償アップグレードが開始され、8月頭にそれを予約しておいたが、しばらくなにも起こらなかった。やっと先に進めるような通知が現れたので、さっそくアップグレードを実行してみた。

アップグレードは簡単で、指示にしたがって、ただ放置しておくだけであった。途中、何度か再起動がかかったが、そのときDELLのロゴ表示後に何も画面に表示されない長い時間が存在した。このときは、アップグレードに失敗して起動できなくなったのだろうかと不安になりつつも、電源ボタンに触るのを我慢し待ったところ、先に進みアップグレードは無事に終了した。ブラウザを起動して、とくに操作不能になるような不具合はなさそうだと思いつつ、それ以上触る時間もないので、電源を落としておいた。

問題に気づいたのは、 翌日、電源を入れてから。Windows10は起動したようだが、タッチパネルをスワイプしてもロック画面から先にすすめない。USBマウスと、キーボードを接続しログインしたところ、タッチパネルでも操作できるようになった。どうやら起動直後にタッチパネルが動いていないようである。デジタイザペンは最初認識している様子だったが、いざアプリケーションでデジタイザペンを使おうとすると、使えなくなっていた。

タブレットであるLatitude10でタッチパネルやデジタイザペンが使えないのは不便なので、使えるようにしたいところ。デバイスマネージャーを見てみると、特にエラーになっている様子はない。DELLのサポートページを見てみると、Latitude10は、Windows10ではサポートされていない様子。デジタイザ用にTABLET PC - Enhanced Tablet Driver 7.3.1-7をインストールしてみたり、デジタイザのユーザー設定を削除したりを行うと、一時的に使えるようになる。

そうこうしているうちに、デジタイザペンを使わずにある程度時間がたつと認識しなくなることが分かる。節電のためにデジタイザをオフをにするような動作だ。デバイスドライバの一覧からWacom Deviceのプロパティにある電源管理のタブを開くと、「電力節約のために、コンピュータでこのデバイスの電源をオフにできるようにする」があるので、このチェックをはずしたところ、無事にデジタイザペンを継続して使えるようになった。タッチパネルも同様かと思い、I2C HIDデバイスのプロパティから同様に設定すると、こちらも起動直後から使えるようになった。

とりあえず、入力デバイスが利用できるようになったので、一安心。Pythonで作ったGraffitiっぽい入力ができるソフトウェアキーボードも無事に動いている。 


2015年7月8日水曜日

MinGW gcc とctypesモジュールを用いてpythonからc関数を呼び出してみる 2

前に構造体を渡すような関数までやったけど、構造体の配列を渡すようなこともよくありそう。簡単な例で試してみたのでメモしておきます。
呼び出されるc関数は、以下の通り。

#include <stdio.h>

typedef struct {
 char name[20];
 int age;
} NAMEandAGE;

int sum_ages(int sz, NAMEandAGE *na)
{
 int i;
 int sum = 0;
 
 for (i=0; i<sz; i++){
  printf("%s %d\n", na[i].name, na[i].age);
  sum = sum + na[i].age;
 }
 return sum;
}
文字列と整数のフィールドをもつ、構造体NAMEandAGEの配列を渡して、 要素の値を表示し、ageの和を返す関数です。
配列は、pythonスクリプトで作成するため、その長さが分からないので、 整数szで長さを渡しています。

ソースファイルをstructures.cというファイルに保存して、

gcc -Wall -c structures.c

でコンパイルします。structures.oというオブジェクトファイルができますので、

gcc -shared -o structures.so structures.o

として、structures.soという、共有ライブラリファイルを作成します。
これを呼び出す、pythonスクリプトは、以下の通り。

import ctypes

class NAMEandAGE(ctypes.Structure):
    _fields_ = [('name', ctypes.c_char*20),
                ('age', ctypes.c_int)]

if __name__ == '__main__':
    mydll = ctypes.CDLL("structures.so")

    data = [('name1', 1), ('name2', 2)] 
    nameandages = (NAMEandAGE * len(data))()
    for n, d in zip(nameandages, data):
        n.name = d[0]
        n.age = d[1]

    result = mydll.sum_ages(ctypes.c_int(len(data)), ctypes.pointer(nameandages))
    print result

配列は、(構造体のクラス * 要素数)で構造体配列のクラスを作って、それを用いてインスタンスを生成するようです。 その後、リストdataの値で、各要素のフィールドを設定しました。
関数を呼び出すときは、ctypes.pointer()を使って、構造体配列のポインタを渡せばよいようです。

2015年5月30日土曜日

Zenfone2を手に入れた

IDEOSでは、OCN mobileのデータSIMを利用していたのですが、 3Gでしか利用していなかったので、ちょっともったいない気がしていました。 画面が小さいため、ほぼモバイルルーターとしてしか使用しないという状況。 Zenfone2が発売されたので、乗り換えました。 メモリ2GB、ストレージ32GBのモデルです。 IDEOSでもmicro SIMを使っていたので、SIMを入れ替えるだけですぐに使えました。 データSIMだけど、セルスタンバイ1%だって。問題がない様子。 画面をダブルタップで、スリープのON/OFFができるのはとても便利ですね。

QPythonを入れてみたところ、便利な計算機として、使えそうではあります。 さらにkivyを用いて、PC上でimageViewerを書き、Zenfone2へインストールしてみました。 しかしながら、QPythonではいるkivyのバージョンは1.8で、バージョン1.9からの in-memory loadingを利用したため、QPythonからは実行できませんでした。

Kivyのページを見たところ、AndroidにはKivy Launcherというものがあるらしいので、 そちらで試すことに。 Kivy Launcherは、kivyのバージョンが1.9で、無事に動作しました。 これで、PC上で作成したGUIつきのpythonスクリプトを、Zenfone2でもそのまま動かせそうです。

2015年5月23日土曜日

matplotlibのMultiCursor AutoScale時の挙動修正

matplotlibのMultiCursor()の使い方は、公式のページにありますが、matplotlib 1.3.0あたりからクロスラインカーソルも利用できます。

multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=True)
のように、horizOnキーワード引数にTrueを渡すと水平線を描画します。

ここで、クロスラインカーソルを表示したいaxes、(ax1, ax2)を渡しているのですが、
最後のax2でないaxes、ここではax1の軸がオートスケールになっていると、あれっ?
と思う挙動をします。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor

t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)+400
s2 = np.sin(4*np.pi*t)
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(t, s1)

ax2 = fig.add_subplot(212, sharex=ax1)
ax2.plot(t, s2)

multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=True)
plt.show()
ax1に描画する波形を400だけオフセットしただけですが、実行すると、以下のようになります。
y軸のレンジが0からになってしまいます。 オートスケールで期待する結果とは異なります。 matplotlibパッケージのwidgets.pyにある、MultiCursorのクラスを見てみると、 どうやら、カーソル線の初期位置の計算に、渡したaxesの最後のものだけを使っているために 生じるようです。

これをwidgets.pyをいじらずに回避するには、MultiCursorの__init__()で行なわれる カーソル線の生成を、別に行えばよさそうです。 そこで、MultiCursorの__init__()には、vertOn、 horizOnともにFalseを渡します。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import MultiCursor

class MyMultiCursor(MultiCursor):
    def __init__(self, canvas, axes, 
            useblit=True, horizOn=True, vertOn=True, **lineprops): 
        MultiCursor.__init__(self, canvas, axes, 
                useblit=useblit, horizOn=False, vertOn=False, **lineprops)

        xmids = [0.5 * (xmin + xmax) for xmin, xmax in [ax.get_xlim() for ax in axes]] 
        ymids = [0.5 * (ymin + ymax) for ymin, ymax in [ax.get_ylim() for ax in axes]] 

        if self.useblit:
            lineprops['animated'] = True
        if vertOn:
            self.vlines = [ax.axvline(xmids[i], visible=False, **lineprops)
                           for i, ax in enumerate(axes)]
        else:
            self.vlines = []

        if horizOn:
            self.hlines = [ax.axhline(ymids[i], visible=False, **lineprops)
                           for i, ax in enumerate(axes)]
        else:
            self.hlines = []

        self.vertOn, self.horizOn = vertOn, horizOn


t = np.arange(0.0, 2.0, 0.01)
s1 = np.sin(2*np.pi*t)+400
s2 = np.sin(4*np.pi*t)
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(t, s1)

ax2 = fig.add_subplot(212, sharex=ax1)
ax2.plot(t, s2)

multi = MyMultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=True)
plt.show()

MultiCursorを継承したMyMultiCursorを利用します。 実行すると、以下のように期待されたグラフが得られました。