Wirenboard 5の電子インクまたはGoでバーコードを描く

こんにちは、Habr! 開発プロセス中に、アプリケーションをテストするための自転車ツールを発明しなければならない場合があり、それらの一部は、たとえばホームオートメーションで役立つことがあります。 これは私の個人的な経験からのケースです。 モバイルデータ収集端末用のアプリケーションを開発する際、バーコードを紙に印刷せずにレーザースキャナーをテストする必要がありました。 残念ながら、これらのスキャナーは通常の画面から読み取ることができません。 彼らに紙を与えてください、しかし、彼らはまた、電子ペーパーがとても好きでした。

画像

Habr E-bookのディスプレイとしての記事を思い出しました。古い半死状態のSony PRS-505リーダーを棚から取り出して、自動化コントローラーの画面の役割で第二の人生を送ることにしました。 ただし、フラッシュメモリ経由で写真を送信することはお勧めできません。 電子書籍のRAMを直接操作する方法を学ぶ必要がありました。 これにより、表示速度と信頼性が向上します。 Goでの描画の経験をバーコードジェネレーターの例と共有し、Wirenboar 5コントローラーを介して電子書籍に表示させてください。

タスク


  1. 壊れることはありません。 新しい機能を追加するだけです。
  2. 電子ブックはポートをリッスンし、 1秒以内に画像を表示できる必要あります
  3. RAMのバッファのみを使用し、フラッシュメモリは使用しない
  4. great ddコマンドで出力をテストする
  5. Goで目的のサイズのバーコードを描画し、キャンバスの中央に配置します
  6. 画像を電子書籍のクリップボードに転送する
  7. 結果をお楽しみください

USB経由のRAMドライブ


Sony PRS-505にはwi-fiがなく、USBガジェットカーネルモジュールのg_file_storageのみがあるため、これが画像をすばやく転送する唯一の方法です。 幸いなことに、 PRSPlusのファームウェアは、電子書籍の電源を入れたときに任意のスクリプトを実行できます。 必要なのは、必要なファイルをディレクトリ/データベース/システム/ PRSPlusフォルダーに入れるだけで、prsp.shスクリプトがブート時に起動されます。

フラッシュメモリをバッファとして使用することはできません。そのため、USB経由でアクセスできるRAMに小さなtmpfsディスクが必要です。g_file_storageカーネルモジュールをアンロードし、USB経由で作成されたRAMディスクを公開するために必要なパラメーターをロードする必要があります。 次に、特定の領域の変更を追跡し、電子インクディスプレイに画像を表示する必要があります。

prsp.sh
#!/ bin / sh
echo $ '\ n ================ \ nSTART SCRYPT \ n' >> / dev / console

#TODO "代わりにカーネルイベントが必要です。そして、最下部にスリープします"
関数waitnewdata
{
echo $ '\ n ================= \ n新しいデータを待つ\ n' >> / dev / console

#画像ファイルの変更時間のみ表示
MODIFYTIMEOLD = `ls -l --full-time /tmp/raw.img | awk '{print $ 9}' '
MODIFYTIMENEW = $ MODIFYTIMEOLD

while ["$ MODIFYTIMEOLD" == "$ MODIFYTIMENEW"]
する
MODIFYTIMENEW = `ls -l --full-time /tmp/raw.img | awk '{print $ 9}' '

寝る0.2
やった

if ["$ MODIFYTIMEOLD"!= "$ MODIFYTIMENEW"]
それから
派手な
fi
}

関数showpic
{
echo $ '\ n ================ \ n新しいデータを受信\ n' >> / dev / console

#最適なクリアe-inkのためのバック画面の生成(オプション)
dd if = / dev / zero of = / tmp / img.raw bs = 1k count = 480
/ tmp / showpic /tmp/img.raw

dd if = / tmp / raw.img of = / tmp / img.raw bs = 1k count = 480
/ tmp / showpic /tmp/img.raw

waitnewdata
}

#ldconfig
PATH = "/ usr / local / bin:/ usr / bin:/ bin:/ usr / bin / X11:/ usr / games:/ usr / local / sony / bin:/ usr / sbin:/ sbin"
LD_LIBRARY_PATH = "/ Data / opt / sony / ebook / application:/ lib:/ usr / lib:/ usr / local / sony / lib:/ opt / sony / ebook / lib"
エクスポートパスLD_LIBRARY_PATH

#初期日付を設定
/ビン/日付0101000007

#カーネルモジュールのアンロード
rmmod g_file_storage

#生ファイル1Mbを作成
dd if = / dev / zero of = / tmp / raw.img bs = 1k count = 1k

grep Data / proc / mtd> / dev / null
[$? == 0]; それから

NUM = `grep Data / proc / mtd | awk -F: '{print $ 1}' | awk -Fd '{print $ 2}' '
insmod /lib/modules/2.4.17_n12/kernel/drivers/usb/g_file_storage.o file = / dev / mtdblock $ NUM、/ dev / sdmscard / r5c807b、/ dev / sdmscard / r5c807a、/ tmp / raw.img ProductID = $ MODEL VendorSpecific = $ VENDOR sn_select = 0 iSerialNumber = $ ID
他に
insmod /lib/modules/2.4.17_n12/kernel/drivers/usb/g_file_storage.o file = / dev / sdmscard / r5c807b、/ dev / sdmscard / r5c807a、/ tmp / raw.img ProductID = $ MODEL VendorSpecific = $ VENDOR sn_lect = 0 iSerialNumber = $ ID
fi

#kbookアプリケーションの起動
nohup / opt / sony / ebook / application / tinyhttp> / dev / null&

cp /データ/データベース/システム/ PRSPlus / showpic / tmp /

waitnewdata

psrp.shスクリプトのハイライト


これで、私たちの電子書籍は聞くことができ、同時に、以前と同じように本を読むことができます。 スクリプトを開始し、画像を転送するために留意する必要がある主なことは、USB e-bookがオンになっている場合、ケーブルを接続しないことです。 それ以外の場合、本はprsp.shスクリプトなしでロードされます。 つまり、最初に本の電源を入れ、シェルがロードされるのを待ってから、USBケーブルを接続します。 (この機能はデフォルトでPRSPlusファームウェアに登録されていますが、必要に応じて変更して独自のイメージを作成することもできます)

確認する


電子書籍で[リセット]をクリックし、ダウンロードが完了するのを待って、USBケーブルを接続します。 確認のために、テスト画像を送信できます。 たとえば、Ubuntuの場合、これは次のように実行できます。

リーダーが読み込まれたときにスクリプトが正常に起動した場合、USB経由で接続すると、サイズが1 MBのデバイスが表示されます。

 fdisk -l 

次の行を見つけます。

 Disk /dev/sdx: 1 MB, 1048576 bytes 

これで、電子書籍/dev/sdxのRAMが/dev/sdx

jpegから変換するには、djpegが必要です。必要なパッケージをインストールします。

 apt-get install libjpeg-turbo-progs 

次に、お気に入りのエディターでJPEGファイルを作成し、サイズを600x800にして、電子書籍に送信します。

 djpeg -pnm -grayscale test.jpg | dd bs=1 skip=15 | dd of=/dev/sdx bs=480k 

このパイプラインでは、jpegをモノクロのpgmに変換し、ヘッダーをスキップして、単一ブロック内の480Kbを/ dev / sdxデバイスに転送します。 そして、結果が表示されます。

バーコードジェネレーターとデバイスへの送信


Golangでバーコードを描画するには、追加のライブラリが必要です。

 go get github.com/boombuler/barcode go get golang.org/x/image/bmp 

main.go
 package main import ( "bytes" "fmt" "image" "log" "os" "image/color" "image/draw" "golang.org/x/image/bmp" "syscall" "github.com/boombuler/barcode" "github.com/boombuler/barcode/ean" "github.com/boombuler/barcode/qr" ) func main() { switch string(os.Args[2]) { case "qr": base64 := os.Args[3] log.Println("Original data:", base64) code1pixel, err := qr.Encode(base64, qr.L, qr.Unicode) if err != nil { log.Fatal(err) } log.Println("Encoded data: ", code1pixel.Content()) if base64 != code1pixel.Content() { log.Fatal("data differs") } log.Println("Encoded data: ", code1pixel.Content()) if base64 != code1pixel.Content() { log.Fatal("data differs") } codeScalled, err := barcode.Scale(code1pixel, 300, 200) if err != nil { log.Fatal(err) } drtest(codeScalled) case "ean": // code, err := ean.Encode("123456789012") code1pixel, err := ean.Encode(os.Args[3]) if err != nil { log.Fatal(err) } log.Println("Encoded data: ", code1pixel.Content()) codeScalled, err := barcode.Scale(code1pixel, 300, 300) if err != nil { log.Fatal(err) } drtest(codeScalled) } } func drtest(imgSrc image.Image) { // create a new Image with the same dimension of image newImg := image.NewGray(image.Rect(0, 0, 600, 800)) // we will use white background to replace background // you can change it to whichever color you want with // a new color.RGBA{} and use image.NewUniform(color.RGBA{<fill in color>}) function draw.Draw(newImg, newImg.Bounds(), &image.Uniform{color.White}, image.Point{}, draw.Src) // paste image OVER to newImage draw.Draw(newImg, newImg.Bounds().Add(image.Point{150, 300}), imgSrc, imgSrc.Bounds().Min, draw.Over) buf := new(bytes.Buffer) err := bmp.Encode(buf, newImg) if err != nil { fmt.Println(err) os.Exit(1) } send_s3 := buf.Bytes() fmt.Println("OK") if os.Args[1] != "false" { devout(send_s3[1078:]) } } func devout(buffer []byte) { // disk := "/dev/sde" disk := os.Args[1] var fd, numread int var err error fd, err = syscall.Open(disk, syscall.O_RDWR, 0777) if err != nil { fmt.Print(err.Error(), "\n") return } //WRITE numread, err = syscall.Write(fd, buffer) if err != nil { fmt.Print(err.Error(), "\n") } fmt.Printf("Numbytes write: %d\n", numread) // fmt.Printf("Buffer: %x\n", buffer[:1000]) err = syscall.Close(fd) if err != nil { fmt.Print(err.Error(), "\n") } } 

コードのハイライト:

  1. EANの例を使用して、最初に1ピクセルの厚さのバーコードを描画します。

     code1pixel, err := ean.Encode(os.Args[3]) 

  2. 希望のサイズに伸ばします:

     codeScalled, err := barcode.Scale(code1pixel, 300, 300) 

  3. 画面サイズに合わせて600x800のキャンバスを作成します。

     newImg := image.NewGray(image.Rect(0, 0, 600, 800)) 

  4. 目的の色で塗りつぶします。

     draw.Draw(newImg, newImg.Bounds(), &image.Uniform{color.White}, image.Point{}, draw.Src) 

  5. キャンバスにバーコード画像を追加します。

     draw.Draw(newImg, newImg.Bounds().Add(image.Point{150, 300}), imgSrc, imgSrc.Bounds().Min, draw.Over) 

  6. 次に、記録のためにデバイスを開き、BMPヘッダーを除くデータをそこに送信します。

     devout(send_s3[1078:]) 

Wirenboard 5でのクロスコンパイル


Wirenboard開発者は、Dockerコンテナに基づく非常に便利なクロスコンパイルツールを提供します。 しかし、この記事の枠組みでは、それを考慮しません。 ARMv5では、シンプルなアプリケーションを1つのチームで組み立てることができます。

 GOOS=linux GOARCH=arm GOARM=5 go build main.go 

すべてをWirenboard 5に転送します。

 scp main root@192.168.xx:/tmp 

Wirenboardに移動して、サイズが1 MBのデバイスの名前を見てください。この例では/ dev / sddです。

以下を開始します。

 /tmp/main /dev/sdd qr "Privet Habr" 



結論


電子書籍を画面として使用するのは現実的です。 その可能性により、電子インク技術はインテリアデザインでの使用を促進します。 E-inkスクリーンは、特に明るい壁でよく見えます。 ホームコントローラーから有用な情報を表示できます。

ご清聴ありがとうございました!

PSソース、 こちらこちらをご覧ください。 電子書籍用ファームウェアPRSPlusはこちら

Source: https://habr.com/ru/post/J321238/


All Articles