2012年1月31日火曜日

libusb with pyUSB

pythonでUSBを使わなければならなかったので、試行錯誤の結果をメモ。
必要なもの。
1. libusb
2. pyUSB
3. SnoopyPo

ターゲットはUSB接続のA/D、D/Aモジュール。windows XPまでしかサポートされていないがwindows 7で使いたい。
1)開発環境はUbuntuなのでlibusbとpyUSBはapt-getでinstall
2)SnoopyPoでUSB通信を傍受。使い方は同梱のsnnopy_pro.txtに書いてある。xmlにexportしてBULK_OR_INTERRUPT_TRANSFERのendpointとpayloadbytesに注目
例えば今回の8bitD/A出力だと
    <urb    sequence="13">
        <function>
            BULK_OR_INTERRUPT_TRANSFER
        </function>
        <endpoint>
            -1
        </endpoint>
        <packetcount>
            1
        </packetcount>
        <payload    packet="0">
            <payloadcount>
                4
            </payloadcount>
            <payloadbytes>
                29033300
            </payloadbytes>
        </payload>
    </urb>
 となっている。
3)pyUSBの基礎は他を当たってね。
4)2)の情報からD/A出力は
usb_dev.handle.interruptWrite(usb_dev.endpoints[0].address, [0x29, 0x03, 0xff, 0x34], timeout)

追記:

http://www.jespersaur.com/drupal/book/export/html/21
http://www.cs.indiana.edu/~bpisupat/work/usb.html
http://www.ladyada.net/learn/diykinect/
http://www.linuxjournal.com/article/7353
http://tali.admingilde.org/linux-docbook/writing_usb_driver.pdf
http://www.reactivated.net/weblog-content/20050806-reverse-0.2.txt
http://matthias.vallentin.net/blog/2007/04/writing-a-linux-kernel-driver-for-an-unknown-usb-device/

2012年1月28日土曜日

linuxでUSB vender ID

$lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 002: ID 058f:6377 Alcor Micro Corp. Multimedia Card Reader
Bus 003 Device 003: ID 0bd5:0120 

2012年1月24日火曜日

HttpResponseRedirectにcontextを渡す。

あるページにリダイレクトして、リダイレクト元のページに戻るれるようボタンを表示したい。

    request.session['send_page'] = reverse('send_page')
    return HttpResponseRedirect(u'page_send_to')

リダイレクト先のテンプレートで
        {% if request.session.send_paget %}
            <a href="{{ request.session.send_page }}"><img src="{{ MEDIA_URL }}path2img/back.png" alt="Back to Tree" /></a>
        {% endif %}

2012年1月23日月曜日

DjangoでformのForeignKey選択設定

Djangoでmodelを与えてformを作成すると、勝手にForeignKeyはselectionをoptionで用意してくれる
tutorialの
class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length=200)
    votes = models.IntegerField() 
 なら、pollはclass Select(Widget)でoptionに選択可能なqueryの結果が表示される。
でもここではその中でも特定の要素を持つものに絞りたい。
form.fields['poll'].queryset = Poll.objects.filter(hoge=fuga) 
 
さらに、特定の値をデフォルトにするには、 
form.fields['poll'].initial = Poll.objects.get(pk=fuga) 

2012年1月10日火曜日

matplotlibで日本語

ここを参考にさせて頂きました。knaka20blueさんありがとうございます。
前の投稿分に日本語でタイトル追加。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Used to guarantee to use at least Wx2.8
import wxversion
wxversion.ensureMinimal('2.8')

import wx
import wx.aui
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx
import matplotlib.font_manager as fm

class Plot(wx.Panel):
    def __init__(self, parent, id = -1, dpi = None, **kwargs):
        wx.Panel.__init__(self, parent, id=id, **kwargs)

        self.figure = matplotlib.figure.Figure(dpi=dpi, figsize=(2,2))
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(sizer)

    def get_figure(self):
        return self.figure

def demo():
    app = wx.PySimpleApp()
    frame = wx.Frame(None, -1, 'Plotter')

    plot = Plot(frame)
    sizer = wx.BoxSizer()
    sizer.Add(plot, 1, wx.EXPAND)
    frame.SetSizer(sizer)

    axes = plot.get_figure().gca()
    axes.plot([1, 2, 3, 4, ],[2, 1, 4, 1, ])
    prop = fm.FontProperties(fname='/usr/share/fonts/opentype/ipafont/ipag.ttf')
    plot.get_figure().gca(kwargs='title').set_title(u'グラフだぴょーん', size='24', fontproperties=prop)

    frame.Show()
    app.MainLoop()

if __name__ == "__main__":
    demo()

matplotlibでグラフ

GL220を使って取り込んだデーターをグラフ化したい。
探してきたのは「matplotlib
wxWidgetsともバインドできるらしい。という事でサンプルを見てみたが、手が込んでいて猿脳にはわからない。ということで最小限化してみた。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Used to guarantee to use at least Wx2.8
import wxversion
wxversion.ensureMinimal('2.8')

import wx
import wx.aui
import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx

class Plot(wx.Panel):
    def __init__(self, parent, id = -1, dpi = None, **kwargs):
        wx.Panel.__init__(self, parent, id=id, **kwargs)

        self.figure = matplotlib.figure.Figure(dpi=dpi, figsize=(2,2))
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(sizer)

    def get_figure(self):
        return self.figure

def demo():
    app = wx.PySimpleApp()
    frame = wx.Frame(None, -1, 'Plotter')

    plot = Plot(frame)
    sizer = wx.BoxSizer()
    sizer.Add(plot, 1, wx.EXPAND)
    frame.SetSizer(sizer)

    axes = plot.get_figure().gca()
    axes.plot([1, 2, 3, 4, ],[2, 1, 4, 1, ])

    frame.Show()
    app.MainLoop()

if __name__ == "__main__":
    demo()
もとは、embedding_in_wx5.py 。wxPanel上にFigureCanvasWxAggを重ねて、そのパネルをwxFrameにwxBoxSizerで貼りつけた。

2011年12月24日土曜日

自炊?

書籍電子化:代行は「違法」 「自炊」業者を提訴 浅田次郎さんら7人、差し止め求め
この著者や出版社は電子出版しようと努力しているのだろうか?

私は、本は大好きだが、
1.引越しのたびに泣く泣く 蔵書を少しずつでも処分している。
2.あと何年生きれて、死んだあとその後蔵書を処分してもらうこと。
この2つのことを考えて数年前から本を買うのをやめてしまった。

君たちは、 電子出版しようと努力して無いのだったら、自ら顧客を無くしてしまっていることを自覚した方がいい。


追記:
ところで、浅田次郎って誰?

郵パックがトホホ

郵パックで送ろうと思って、ちょうど手元に送り状があった。
それに書いて郵便局に持って行くと、送り状が古くてバーコードが登録できないから新しいのに書きなおせだと。

そんなのだから赤字垂れ流しになるんじゃ。
ほんとどこ向いて 仕事しているんじゃ!
きっと新規システムを導入するとき、「ケッチって」古い番号を捨てたのだろう。
業者は「そんなことしたら大変なことにになりますよ」と指摘しても強行したに違いない。

もう二度と利用しない。

追記:
郵パックって安いというイメージがあったけれど今確認するとヤマトと50円しか変わらない。拠点の遠さ不愉快な思いをすることを考えたら、やっぱり。

もう二度と利用しない。

と言っていたら、「読経」が聞こえてきた。

まあ、郵便なんてなくなっても困らないし。郵貯と簡保は国債とご臨終になるだろうし。
もともと、役人と労組が食い物にしてきたのだし、清算してもいいんじゃない。「チーン!」

追記1:
海の向こうの方が早そうだ。
米郵政公社が250の集配施設を閉鎖、3万5千人削減へ

追記2:
12月26日午前中に届いたはずの荷物の「お届けしました葉書」昨日の30日についた。わざわざ北海道まで転送して投函したのだろうか?4日もかかるなんて。

GL220の受信データーを加工(struct編)

ここではint(char.encode('hex'), 16)を使っていたが、電圧や湿度、熱電対の温度に変換して出したい。

import struct

buffer_list = struct.unpack('!23h', buffer)
でおしまい。
structこりゃあ便利だ。Format Charactersを指定することで変換できちゃう。
!:network (= big-endian)
h:short 2byte
23:23回繰り返し(=46byte)
つまりbig-endianのsigned-short, 23 times

2011年12月22日木曜日

GL220の受信データー

忘れないようにGL220は10CHだから':MEAS:OUTP:ONE?'コマンドでの受信データーは46byteだからヘッダーは'#6000046 '

データ受信関連仕様書(GL220_820).pdfの4ページ

例) 端子台20CH、 内部バッファ内データ2点の場合

受信データ, 説明
#6******, ヘッダ(ASCII): #6は接頭文字で固定。次の6文字でその後の******で受信されるバイト数を表します。
 1:CH1アナログデータ, 1chデータのバイナリ(2byte)
 2:CH2アナログデータ, 2chデータのバイナリ(2byte)
   :(中略), : (中略)
10:CH10アナログデータ, 10chデータのバイナリ(2byte)
CH11アナログデータ, 11chデータのバイナリ(2byte)
:(中略), : (中略)
CH20アナログデータ, 20chデータのバイナリ(2byte)
11:パルス1データ1, パルス1データ上位2byte, パルスデータは上位2byte、下位2byteを合計した4byte(32bit)データ
12:パルス1データ2, パルス1データ下位2byte
13:パルス2データ1, パルス2データ上位2byte
14:パルス2データ2, パルス2データ下位2byte
15:パルス3データ1, パルス3データ上位2byte
16:パルス3データ2, パルス3データ下位2byte
17:パルス4データ1, パルス4データ上位2byte
18:パルス4データ2, パルス4データ下位2byte
19:ロジックデータ, ロジックデータのバイナリ(2byte)
20:アラームデータ1, CH1~CH10のアラームデータ(2byte)
アラームデータ2, CH11~CH20のアラームデータ(2byte)
21:アラームデータ(ロジック/パルス), ロジックとパルスのアラームデータ(2Byte)
22:アラーム出力データ, アラーム出力データ(2Byte)
23:ステータス, データの状態を表す情報(2byte), CH1アナログデータ

23×2byte=46byte

アラームデータ2, CH11~CH20のアラームデータ(2byte)  の部分に気が付かずに48byteになるがなと唸っていたぞ。

2011年12月21日水曜日

create_string_bufferからデーターリスト

create_string_bufferでデーター(data)が帰ってきているとき扱いやすいように

print repr(data.raw)
data_list = [int(char.encode('hex'), 16) for char in data]
print data_list

ふふふ、内包表記じゃ

2011年12月20日火曜日

pythonでgraphtec GL220

ctypes初めて使った。
CDからドライバーをインストールして。gtcusbr.dllをお側に。

        Open device
        HANDLE __stdcall GtcUSBr_OpenDevice(void);

        Close device
        BOOL __stdcall GtcUSBr_CloseDevice(
            HANDLE hDev        # Handle to the USB to be I/O
        );

        Read (Block mode)
        BOOL __stdcall GtcUSBr_ReadDevice(
            HANDLE hDev,                    # Handle to the USB to be read
            LPVOID lpBuffer,                # Pointer to the buffer that receives the data read from the USB
            DWORD nNumberOfBytesToRead,        # Number of bytes to read
            LPDWORD lpNumberOfBytesRead,    # Pointer to the number of bytes read
            DWORD dwTimeOut                    # TimeOut(ms)
        );

        Write (Block mode)
        BOOL __stdcall GtcUSBr_WriteDevice(
            HANDLE hDev,                    # Handle to the USB to be write
            LPVOID lpBuffer,                # Pointer to the buffer that sends the data write to the USB
            DWORD nNumberOfBytesToWrite,    # Number of bytes to write
            LPDWORD lpNumberOfBytesWrite,   # Pointer to the number of bytes write
            DWORD dwTimeOut                    # TimeOut(ms)
        );
あたりを使う。

橋渡しは
LPVOID        ctypes.create_string_buffer()
DWORD       ctypes.c_ulong()
LPDWORD  ctypes.pointer(ctypes.c_ulong())

読むときはクエリーの時はASCIIが帰ってくる。1文字づつ読もう。
フリーランニングで、:MEAS:OUTP:ONE?で瞬時データを読むときは、
まずASCIIで8byteヘッダーを読んで「#6******」アスタリスクの部分をintに変えて続きのdataを読む。


どうでもいいけど。その1
マニュアルGL220 GL820 インターフェイスコマンド(GL220_820 IF_Command_Japanese.pdf)12ページのバッファ構成の欄の「は:MEAS:OUTO:STAT?で確認できます。」はバグ。正しくは「は:MEAS:OUTP:STAT?で確認できます。」

どうでもいいけど。その2
HPの「お問い合わせ」でくるメールの
###### 引用初め
本メールの配信に身に覚えのない場合、お手数ですが以下まで
ご連絡お願いいたします。

webmaster@grephtec.co.jp
###### 引用終わり
にはワロタ。