2017年12月7日木曜日

Visual studio code ENOSPC エラー


Visual studio code で拡張機能を作っているとたまに下記のようなエラーが出ることがあります。

fs.js:1385
    throw error;
    ^

Error: watch /home/kiya/Documents/vsc/nekoaisle.encode ENOSPC
    at _errnoException (util.js:1019:11)
    at FSWatcher.start (fs.js:1383:19)
    at Object.fs.watch (fs.js:1409:11)
    at watchPresentDirectory (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:2635:42)
    at fsWatchDirectory (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:2620:21)
    at Object.watchDirectory (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:2768:28)
    at addDirectoryWatcher (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:56930:21)
    at Object.watchDirectory (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:59955:20)
    at createDirectoryWatcher (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:59381:35)
    at watchFailedLookupLocationOfResolution (/home/kiya/Documents/vsc/libs/node_modules/typescript/lib/tsc.js:59348:81)

ビルド タスクのウォッチが終了しました。

このエラーたち悪いことの出たり出なかったりして悩んでいたのですがやっと解決方法がわかったのでメモ書きします。

もと情報はこちら https://vscode-doc-jp.github.io/docs/setup/linux.html#ENOSPC-エラー

1. 現在の設定の確認

$ sudo cat /proc/sys/fs/inotify/max_user_watches
65536

2. 設定ファイルの編集

$ sudo vi /etc/sysctl.conf

ファイルの末尾に下記を追加

fs.inotify.max_user_watches=524288

3. 設定を反映

$ sudo sudo sysctl -p

以上です。

2017年10月17日火曜日

Fcitx スキン名 Ubuntu Gnome 17.04

Ubuntu Gnome 17.04 にて Fcitx のスキンを変えたいなと設定画面を開いてみると、セレクトボックスではなくテキストボックス…

なんて名前のスキンがあるんだ?

まぁ、たいていは /user/share だろうとのぞくとあったあった /usr/share/fcitx/skin/ に classc, dark, default の3つが。

早速 dark に変更。いい感じだ。

最近物忘れがひどくてあれ?確か以前にやったよな?なんてことばかりなので備忘録。

2017年9月27日水曜日

Ubuntu Gnome: Window snap (edge-tiling) を無効にする

Ubuntu Gnome の Snapping Window という機能がとにかくうざい。Window を画面上端に合わせようとすると最大化してしまう><;小さな親切大きなお世話!

これを止めようと調べてみたもののどうもよくわからなかったのですがようやく止め方がわかったので備忘録として残します。

無効にしたいとき

kiya@kiya-ubuntu:~$ gsettings set org.gnome.shell.overrides edge-tiling false

有効にしたいとき

kiya@kiya-ubuntu:~$ gsettings set org.gnome.shell.overrides edge-tiling true

この方法が書かれていたサイト:GNOME のエアロスナップみたいな機能(Edge Tiling)を無効にする方法

2017年9月7日木曜日

pixmap は pixbuf @@

Ubuntu 17.04 にてコンソールからthunar を起動したところ大量のワーニングが…

kiya@kiya-ubuntu:~/Documents$ thunar ~/Documents/
Gtk-Message: Failed to load module "overlay-scrollbar"

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "adwaita",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "pixmap",

(thunar:17427): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "adwaita",

(thunar:17427): Gdk-WARNING **: gdk_window_set_icon_list: icons too large

軽くググると「gtk2-engines-xxxx」をインストールとか書いてあったので

kiya@kiya-ubuntu:~/Documents$ sudo apt-get install gtk2-engines-pixmap
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
E: パッケージ gtk2-engines-pixmap が見つかりません

え〜〜〜><;

更にググるとそのものズバリが…
Gtk-WARNING **: module_path にはテーマ・エンジンがありません: “pixmap”
kiya@kiya-ubuntu:~/Documents$ sudo apt-get install gtk2-engines-pixbuf

う〜ん、pixmap -> pixbuf なのか…

Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "adwaita"

Linux adwaita waring GTKがらみを消す方法
kiya@kiya-ubuntu:~/Documents$ sudo apt-get install gnome-themes-standard

kiya@kiya-ubuntu:~/Documents$ thunar ~/Documents/
Gtk-Message: Failed to load module "overlay-scrollbar"

(thunar:17837): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "adwaita",

(thunar:17837): Gtk-WARNING **: module_path にはテーマ・エンジンがありません: "adwaita",

(thunar:17837): Gdk-WARNING **: gdk_window_set_icon_list: icons too large
kiya@kiya-ubuntu:~/Documents$ sudo apt-get install gnome-themes-standard
-- snip --
gnome-themes-standard:amd64 (3.22.3-1ubuntu1) を展開しています...
gnome-themes-standard:amd64 (3.22.3-1ubuntu1) を設定しています ...
kiya@kiya-ubuntu:~/Documents$ thunar ~/Documents/
Gtk-Message: Failed to load module "overlay-scrollbar"

(thunar:3433): Gdk-WARNING **: gdk_window_set_icon_list: icons too large

残念ながら残りの2つのワーニングはあれこれ試してみたのですが治りませんでした><;

2017-09-12 追記

後日 Visual Studio Code を 1.16.0 にバージョンアプしたところ拡張機能をデバッグしようとすると overlay-scrollbar のエラーが出てデバッグできないという状況に陥ったので、さらにあれこれ試したところなんとか解決できました。

Gtk-Message: Failed to load module "overlay-scrollbar"

Gtk-Message: Failed to load module "overlay-scrollbar"
kiya@kiya-ubuntu:~/Documents$ sudo apt-get remove overlay-scrollbar
overlay-scrollbar (0.2.17.1+16.04.20151117-0ubuntu2) を設定しています ...
kiya@kiya-ubuntu:~/Documents$ sudo apt-get purge overlay-scrollbar

再起動

kiya@kiya-ubuntu:~/Documents$ sudo apt-get install overlay-scrollbar
kiya@kiya-ubuntu:~/Documents$ sudo apt-get install overlay-scrollbar-gtk2

kiya@kiya-ubuntu:~/Documents$ thunar

(thunar:7000): Gdk-WARNING **: gdk_window_set_icon_list: icons too large

残念ながら最後のワーニングはあれこれ試してみたのですがいまのところ治っていません><;

2017年8月28日月曜日

Thunar で選択したファイル名をクリップボードへコピー

Windows 用には Clipcopy というフリーソフトを昔に作って使ってたんだけど、Ubuntu 用はないかなと物色していたところファイラー(Thunar)のアクションを設定すれば使えるらしいということで早速試してみたところうまく行ったので備忘録。


まずは普通にコマンド欄に下記を入れてみました。

コマンド(C): echo %F | xset -bi

これだけでできるのですが、ちょっと残念なことに複数ファイルを選択したときに半角スペース区切りとなってしまい、ファイル名のスペースと区切り文字のスペースの区別がつきません。そこでひと工夫

コマンド(C): echo '%F' | xset -bi

これで各ファイル名がシングルクォートでくくられるようです。おそらく、Thunarがシングルクォート区切りを吐いていて、それをさらにシングルクォートでくくっているのでそのまま出ているのではないかと思います。

これはこれで使えるのですが、複数ファイル名が欲しいときってバッチを作ったりする際だったりするのでできれば改行区切りがいいなぁと…

そこで簡単なシェルスクリプトを作成

~/bin/prm_split.sh

if [ $# -eq 1 ]; then
    echo -n "$1"
else
    for f in "$@"; do
        echo $f
    done
fi

引数の数を見ているのは、1個のファイル名を貼り付けるケースというのはコマンドラインが多く、コマンドラインでは改行が入っては不都合だからです。スペース区切りと改行区切りの2つのアクションを作るのであれば for 〜 done だけで十分です。

コマンド(C): prm_split.sh %F | xset -bi

これで期待通りの動作\(^_^)/

で、端末にファイル名を貼り付けようとしたら…張り付かない><;

ちょっといじって

コマンド(C): prm_split.sh %F | xset -pi

これだとうまく行く…
仕方がないので2回実行

コマンド(C): prm_split.sh %F | xset -bi;prm_split.sh %F | xset -pi

はいこれで期待通りの動作。

2017年8月8日火曜日

Ubuntu gnome 17.04 に Canon MG6230 用ドライバーをインストール

Canonのホームページにドライバーがあったのでこれをインストールするだけかと思ったら、エラーが出てインストールできなかったので備忘録。

エラーの内容ですが、プリンタードライバーでは下記のようになります。

yoshio@yoshio-ubuntu:~/Documents/cnijfilter-mg6200series-3.60-1-deb$ sudo ./install.sh
==================================================

Canon Inkjet Printer Driver
Version 3.60
Copyright CANON INC. 2001-2011
All Rights Reserved.

==================================================
実行コマンド = sudo dpkg -iG ./packages/cnijfilter-common_3.60-1_amd64.deb
以前に未選択のパッケージ cnijfilter-common を選択しています。
(データベースを読み込んでいます ... 現在 229886 個のファイルとディレクトリがインストールされています。)
.../cnijfilter-common_3.60-1_amd64.deb を展開する準備をしています ...
cnijfilter-common (3.60-1) を展開しています...
cnijfilter-common (3.60-1) を設定しています ...
libc-bin (2.24-9ubuntu2.2) のトリガを処理しています ...
実行コマンド = sudo dpkg -iG ./packages/cnijfilter-mg6200series_3.60-1_amd64.deb
以前に未選択のパッケージ cnijfilter-mg6200series を選択しています。
(データベースを読み込んでいます ... 現在 229902 個のファイルとディレクトリがインストールされています。)
.../cnijfilter-mg6200series_3.60-1_amd64.deb を展開する準備をしています ...
cnijfilter-mg6200series (3.60-1) を展開しています...
dpkg: 依存関係の問題により cnijfilter-mg6200series の設定ができません:
cnijfilter-mg6200series は以下に依存 (depends) します: libpng12-0 (>= 1.2.8rel) ...しかし:
パッケージ libpng12-0 はまだインストールされていません。
cnijfilter-mg6200series は以下に依存 (depends) します: libtiff4 ...しかし:
パッケージ libtiff4 はまだインストールされていません。

dpkg: パッケージ cnijfilter-mg6200series の処理中にエラーが発生しました (--install):
依存関係の問題 - 設定を見送ります
処理中にエラーが発生しました:
cnijfilter-mg6200series
実行コマンド = sudo dpkg -P cnijfilter-mg6200series
(データベースを読み込んでいます ... 現在 230105 個のファイルとディレクトリがインストールされています。)
cnijfilter-mg6200series (3.60-1) を削除しています ...
cnijfilter-mg6200series (3.60-1) の設定ファイルを削除しています ...
libc-bin (2.24-9ubuntu2.2) のトリガを処理しています ...
実行コマンド = sudo dpkg -P cnijfilter-common
(データベースを読み込んでいます ... 現在 229901 個のファイルとディレクトリがインストールされています。)
cnijfilter-common (3.60-1) を削除しています ...
cnijfilter-common (3.60-1) の設定ファイルを削除しています ...
libc-bin (2.24-9ubuntu2.2) のトリガを処理しています ...

スキャナードライバーでは下記のようになります。

yoshio@yoshio-ubuntu:~/Documents$ cd scangearmp-mg6200series-1.80-1-deb/
yoshio@yoshio-ubuntu:~/Documents/scangearmp-mg6200series-1.80-1-deb$ sudo ./install.sh
==================================================

ScanGear MP
Version 1.80
Copyright CANON INC. 2007-2011
All Rights Reserved.

==================================================
実行コマンド = sudo dpkg -iG ./packages/scangearmp-common_1.80-1_amd64.deb
以前に未選択のパッケージ scangearmp-common を選択しています。
(データベースを読み込んでいます ... 現在 229886 個のファイルとディレクトリがインストールされています。)
.../scangearmp-common_1.80-1_amd64.deb を展開する準備をしています ...
scangearmp-common (1.80-1) を展開しています...
dpkg: 依存関係の問題により scangearmp-common の設定ができません:
 scangearmp-common は以下に依存 (depends) します: libpng12-0 (>= 1.2.8rel) ...しかし:
  パッケージ libpng12-0 はまだインストールされていません。
 scangearmp-common は以下に依存 (depends) します: libusb-0.1-4 (>= 2:0.1.10a) ...しかし:
  パッケージ libusb-0.1-4 はまだインストールされていません。

dpkg: パッケージ scangearmp-common の処理中にエラーが発生しました (--install):
 依存関係の問題 - 設定を見送ります
処理中にエラーが発生しました:
 scangearmp-common
実行コマンド = sudo dpkg -P scangearmp-common
(データベースを読み込んでいます ... 現在 229933 個のファイルとディレクトリがインストールされています。)
scangearmp-common (1.80-1) を削除しています ...
scangearmp-common (1.80-1) の設定ファイルを削除しています ...


要するにプリンタードライバーでは「libpng12-0」と「libtiff4」が、スキャナドライバーには「libusb-0.1-4」が足りないようです。

ところが apt-get でインストールしようとしてもそんなパッケージはないと怒られてしまいます。

yoshio@yoshio-ubuntu:~/Documents/scangearmp-mg6200series-1.80-1-deb$ sudo apt-get install libtiff4
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
E: パッケージ libtiff4 が見つかりません

そこでグーグル先生に尋ねたところ下記のページを見つけました。
How-to Install libtiff4 for Ubuntu 14.04 Trusty LTS Linux Easy Guide

ということでここに書かれていることをやってからドライバーをインストールしたところ無事に使えるようになりました。

不足しているパッケージのインストール
  • sudo su -
  • apt-get install libtiff5 libtiff5-dev
  • echo 'deb http://cz.archive.ubuntu.com/ubuntu precise main universe' >> /etc/apt/sources.list.d/extra.list
  • apt-get update
  • apt-get install libpng12-0
  • apt-get install libtiff4
  • apt-get install libusb-0.1-4
  • exit
ドライバーのインストール
※ドライバーのインストール方法はCanonのページにあります。
  • cd cnijfilter-mg6200series-3.60-1-deb
  • sudo ./install.sh
  • cd scangearmp-mg6200series-1.80-1-deb/
  • sudo ./install.sh
後始末
  • sudo /etc/apt/sources.list.d/extra.list /etc/apt/sources.list.d/extra.list.bak
  • apt-get update

2017年7月20日木曜日

Ubuntu上のVirtualBox仮想マシン(Windows10)のHDDを圧縮


検索するとホストOSがWindowsでゲストOSがUbuntuのケースはいっぱい出てくるのですが逆のケースがほとんど無いので備忘録として記します。

1. SDelete の入手

マイクロソフトが配布している sdelete というツールを使って未使用領域をクリアします。
https://technet.microsoft.com/ja-jp/sysinternals/sdelete.aspx

2. ゲストOS上で未使用領域をクリアします。

C:\SDelete>sdelete -z C:

SDelete v2.0 - Secure file delete
Copyright (C) 1999-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

SDelete is set for 1 pass.
Zeroing free space on C:\: 0%
これ結構時間かかりました。気をつけなければいけないは、画面に100%と表示が出てから本当に処理が終わるまでの時間がものすごく長いことです。また、sdelete64.exe は sdelete.exe の28倍かかったと言っている人もいました。私の場合1TBのHDDを処理するのに金曜の朝から初めて8時間では終わらず土日放置、月曜に見たら終わっていたと言った感じでした。

3. C:\SDELTEMP1 を削除します。

なんか 1. をやる前のHDDの使用量が48GB程度だったのに終わったあとは340GB!なんだ?と思って調べてみるとC:ドライブのルートに巨大なファイルができていました。
なんだかわからないけどとりあえずサクッと削除^^;
※このファイルが残らないこともありました。

4. ゲストOSをシャットダウン


5. ホストOSにて vboxmanager を使って圧縮します。

# UUIDを調べる
kiya@kiya-ubuntu:~$ vboxmanage list hdds
UUID:           ab123456-c7d8-90e1-e2f3-a4567890b12c
Parent UUID:    base
State:          locked write
Type:           normal (base)
Location:       /home/kiya/VirtualBox VMs/vhd/kiya-win10-c.vdi
Storage format: VDI
Capacity:       953869 MBytes
Encryption:     disabled

# 圧縮
kiya@kiya-ubuntu:~$ vboxmanage modifyhd ab123456-c7d8-90e1-e2f3-a4567890b12c --compact
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

ハマりどころは vboxmanager。私のマシンにはなぜか VBoxManager というものも入っていていくらこれを叩いてもUUIDが取れず???としばらく悩んでしまいました。

2017年7月18日火曜日

Arduino でモールス信号

中華通販で買ったArduino。封も切らずに保管していていざ使おうとした不良品だったなんてことが何回かありまして商品が届くごとにとりあえずLチカだけはしていたわけですが、最初から Blink.ino が入っているものもあるので、見分けるためにちょっと凝った BlinkMorse.ino を作ってみました。

その際にモールス信号を生成するクラスを作成しました。このクラスは KyaMorseBase クラスと KyaMorse というテンプレートから構成されています。

KyaMorseBase は与えられた文字列からモールス信号を作成、ONとすべきタイミングで音にすべき時間を引数として KyaMorseBase::callback() を呼び出します。callback() は virtual となっていますのでこのクラスを基本クラスとしてやることにより LED を点灯するなり ブザーを鳴らすなり自由な処理を行えます。

また、KyaMorse はテンプレートでメンバー変数として KyaMorse<クラス名> とすることによりメンバー関数をコールバックとする事ができます。多重継承がお嫌いな方にはこちらが良いかもしれません。

KyaMorse.h

/**
 * モールス信号処理
 *
 * filename:  KyaMorse.h
 *
 * @package
 * @version   1.0.0
 * @copyright Copyright (C) 2017 Yoshio Kiya
 * @date      2017-07-15
 * @author    木屋 善夫
 */
#ifndef _KyaMorse_h_
#define _KyaMorse_h_
#include

class KyaMorseBase {
public:
  // モールス符号情報
  static const uint16_t morses[59];

  // 短点の時間(msec)
  uint32_t mTime = 100;

  /**
   * 構築
   */
  KyaMorseBase() {
  }

  /**
   * 構築
   * @param  uint32_t time 短点の時間(msec)
   */
  KyaMorseBase(uint32_t time) : mTime(time) {
  }

  /**
   * モールス信号送信処理
   *
   * @access public
   * @param  char* str 送信する文字列
   * @return
   * @throw
   */
  void send(char* str);

  /**
   * コールバック処理
   * ※派生クラス(テンプレート)でオーバーライドするためのメンバー関数
   *
   * @access public
   * @param  uint32_t time 待ち時間(msec)
   */
   virtual void callback(uint32_t time) {}
};

template
class KyaMorse : public KyaMorseBase {
public:
  typedef void (T::*CALLBACK)(uint32_t);

protected:
  T* mObj;
  CALLBACK mMethod;

public:
  /**
   * 構築
   */
  KyaMorse( ) : KyaMorseBase() {
  }

  /**
   * 構築
   * @param  uint32_t time 短点の時間(msec)
   */
  KyaMorse(uint32_t time) : KyaMorseBase(time) {
  }

  /**
   * モールス信号送信処理
   *
   * @access public
   * @param  char* str 送信する文字列
   * @return
   * @throw
   */
  void send(char* str, T* obj, CALLBACK method) {
    mObj = obj;
    mMethod = method;
    KyaMorseBase::send(str);
  }

  /**
   * コールバック処理
   * ※派生クラス(テンプレート)でオーバーライドするためのメンバー関数
   *
   * @access public
   * @param  uint32_t time 待ち時間(msec)
   */
   virtual void callback(uint32_t time) {
    (mObj->*mMethod)(time);
   }
};

#endif

KyaMorse.cpp

/**
 * モールス信号処理
 *
 * filename:  KyaMorse.cpp
 *
 * @package
 * @version   1.0.0
 * @copyright Copyright (C) 2017 Yoshio Kiya
 * @date    2017-07-15
 * @author    木屋 善夫
 */

/**
 * インクルード
 */
#include "KyaMorse.h"

/**
 * モールス信号送信処理
 *
 * @access public
 * @param  char* str 送信する文字列
 * @return
 * @throw
 */
void KyaMorseBase::send(char* str) {
  for (; *str; ++ str) {
    char c = *str;
    if ((c >= ' ') && (c <= 'Z')) {
      uint16_t b = morses[c - 0x20];
      for (; b; b <<= 2) {
        switch (b & 0xC000) {
          // エンドマーク
        case 0x0000:
          b = 0;
          break;
          // 語間 短点7つ分の無音
        case 0x4000:
          delay(mTime * (7-1-3));
          break;
          // 短点
        case 0x8000:
          callback(mTime * 1);
          break;
          // 長点
        case 0xC000:
          callback(mTime * 3);
          break;
        }

        // 文字間 短点1つ分の無音
        delay(mTime * 1);
      }
      // 文字間 短点3つ分の無音
      delay(mTime * 3);
    }
  }
}

// MSBから2ビットずつ取り出す(最大8点)
// 00 = 終了
// 01 = 語間 短点7つ分の無音
// 10 = 短点 + 文字間の短点1つ分の無音
// 11 = 長点 短点3つ分 + 文字間の短点1つ分の無音
const uint16_t KyaMorseBase::morses[59] = {
  (B01000000 * 256) + B00000000,    // " "  0x20   xxxxxxx
  (B00000000 * 256) + B00000000,    // "!"  0x21  xxxxxxxx
  (B00000000 * 256) + B00000000,    // """  0x22  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "#"  0x23  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "$"  0x24  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "%"  0x25  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "&"  0x26  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "'"  0x27  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "("  0x28  xxxxxxxx
  (B00000000 * 256) + B00000000,    // ")"  0x29  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "*"  0x2A  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "+"  0x2B  xxxxxxxx
  (B11111010 * 256) + B11110000,    // ","  0x2C  --・・--xx
  (B11101010 * 256) + B10110000,    // "-"  0x2D  -・・・・-xx
  (B10111011 * 256) + B10110000,    // "."  0x2E  ・-・-・-xx
  (B11101011 * 256) + B10000000,    // "/"  0x2F  -・・-・xxx
  (B11111111 * 256) + B11000000,    // "0"  0x30  -----xxx
  (B10111111 * 256) + B11000000,    // "1"  0x31  ・----xxx
  (B10101111 * 256) + B11000000,    // "2"  0x32  ・・---xxx
  (B10101011 * 256) + B11000000,    // "3"  0x33  ・・・--xxx
  (B10101010 * 256) + B11000000,    // "4"  0x34  ・・・・-xxx
  (B10101010 * 256) + B10000000,    // "5"  0x35  ・・・・・xxx
  (B11101010 * 256) + B10000000,    // "6"  0x36  -・・・・xxx
  (B11111010 * 256) + B10000000,    // "7"  0x37  --・・・xxx
  (B11111110 * 256) + B10000000,    // "8"  0x38  ---・・xxx
  (B11111111 * 256) + B10000000,    // "9"  0x39  ----・xxx
  (B00000000 * 256) + B00000000,    // ":"  0x3A  xxxxxxxx
  (B00000000 * 256) + B00000000,    // ";"  0x3B  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "<"  0x3C  xxxxxxxx
  (B00000000 * 256) + B00000000,    // "="  0x3D  xxxxxxxx
  (B00000000 * 256) + B00000000,    // ">"  0x3E  xxxxxxxx
  (B10101111 * 256) + B10100000,    // "?"  0x3F  ・・--・・xx
  (B10111110 * 256) + B11100000,    // "@"  0x40  ・--・-・xx
  (B10110000 * 256) + B00000000,    // "A"  0x41  ・-xxxxxx
  (B11101010 * 256) + B00000000,    // "B"  0x42  -・・・xxxx
  (B11101110 * 256) + B00000000,    // "C"  0x43  -・-・xxxx
  (B11101000 * 256) + B00000000,    // "D"  0x44  -・・xxxxx
  (B10000000 * 256) + B00000000,    // "E"  0x45  ・xxxxxxx
  (B10101110 * 256) + B00000000,    // "F"  0x46  ・・-・xxxx
  (B11111000 * 256) + B00000000,    // "G"  0x47  --・xxxxx
  (B10101010 * 256) + B00000000,    // "H"  0x48  ・・・・xxxx
  (B10100000 * 256) + B00000000,    // "I"  0x49  ・・xxxxxx
  (B10111111 * 256) + B00000000,    // "J"  0x4A  ・---xxxx
  (B11101100 * 256) + B00000000,    // "K"  0x4B  -・-xxxxx
  (B10111010 * 256) + B00000000,    // "L"  0x4C  ・-・・xxxx
  (B11110000 * 256) + B00000000,    // "M"  0x4D  --xxxxxx
  (B11100000 * 256) + B00000000,    // "N"  0x4E  -・xxxxxx
  (B11111100 * 256) + B00000000,    // "O"  0x4F  ---xxxxx
  (B10111110 * 256) + B00000000,    // "P"  0x50  ・--・xxxx
  (B11111011 * 256) + B00000000,    // "Q"  0x51  --・-xxxx
  (B10111000 * 256) + B00000000,    // "R"  0x52  ・-・xxxxx
  (B10101000 * 256) + B00000000,    // "S"  0x53  ・・・xxxxx
  (B11000000 * 256) + B00000000,    // "T"  0x54  -xxxxxxx
  (B10101100 * 256) + B00000000,    // "U"  0x55  ・・-xxxxx
  (B10101011 * 256) + B00000000,    // "V"  0x56  ・・・-xxxx
  (B10111100 * 256) + B00000000,    // "W"  0x57  ・--xxxxx
  (B11101011 * 256) + B00000000,    // "X"  0x58  -・・-xxxx
  (B11101111 * 256) + B00000000,    // "Y"  0x59  -・--xxxx
  (B11111010 * 256) + B00000000,    // "Z"  0x5A  --・・xxxx
};

2017年7月17日月曜日

Arduinoアプリケーション用基本クラス

Arduino用の実験アプリをあれこれ作っているわけですが、アプリを作る場合、最低限必要な機能があるのでアプリケーション用基本クラスを作成しました。今後公開するアプリはみなこのクラスの派生クラスとして実装しますので、とりあえず公開しておきます。
時間を見てgithubに公開しようと思いますがそれまでの仮です^^;

KyaDefine.h

#ifndef _KyaDefine_h_
#define _KyaDefine_h_
/**
 * 定数定義
 *
 * filename:  KyaDefine.h
 *
 * @package
 * @version   1.0.0
 * @copyright Copyright (C) 2017 Yoshio Kiya
 * @date      2017-05-16
 * @author    木屋 善夫
 */
#define UINT unsigned int

// Arduino15\packages\digistump\hardware\avr\1.6.7\cores\tiny/Print.h で使っている!
//#ifndef BYTE
//  #define BYTE unsigned char
//#endif

#ifndef WORD
  #define WORD unsigned short
#endif

#ifndef DWORD
  #define DWORD unsigned long
#endif

#ifndef PCSTR
  #define PCSTR const char*
#endif

// 要素数を返す
#define numberof( a ) ((sizeof a) / (sizeof a[0]))

#define TRUE 1
#define FALSE 0

#if !defined( D0 ) && defined( ARDUINO_AVR_UNO )
  enum {
    D0  =  0,
    D1  =  1,
    D2  =  2,
    D3  =  3,
    D4  =  4,
    D5  =  5,
    D6  =  6,
    D7  =  7,
    D8  =  8,
    D9  =  9,
    D10 = 10,
    D11 = 11,
    D12 = 12,
    D13 = 13,
  };
#endif

#endif

KyaApp.h

#ifndef _KyaApp_h_
#define _KyaApp_h_
/**
 * アプリケーションの基本クラス
 *
 * filename:  KyaApp.h
 *
 * @package
 * @version   1.0.0
 * @copyright Copyright (C) 2017 Yoshio Kiya
 * @date      2017-05-16
 * @author    木屋 善夫
 */
#include
#ifdef KYA_TIMER_INTERVAL
  #ifndef ESP8266
    #include
  #else
    // ミリ秒をクロック数に換算 (@80MHz)
    #define MSEC2CLOCK(ms)  (ms * 80000L)
  #endif
#endif

#include

#ifdef KYA_DEBUG
#define TRACE KyaApp::trace( __FUNCTION__, __FILE__, __LINE__ );
#else
#define TRACE
#endif

// 3Dベクター
template
class KyaVec3 {
public:
  TYPE x;
  TYPE y;
  TYPE z;
};

// 時刻
typedef union KyaTime {
  DWORD val;
  struct {
    uint8_t s;
    uint8_t m;
    WORD h;
  };
};

//printf で小数を扱うためのマクロ
// ex. printf( "%d.%02d", printfFloat( val, 100 ) );
// 小数点以下2桁が表示される
#define printfFloat( v, c ) (int)v, abs( (int)((v - (int)v) * c) )

//// イベントハンドル
//@@ 関数ポインターではなくメンバー関数へのポインターにしなければならない
//template
//class KyaHandle
//{
//public:
//  void *mFunc( TYPE );
//  int mMilli;
//  TYPE mArg;
//
//  KyaHandle( void *func( TYPE ), int delay, TYPE arg ) {
//    mFunc = func;
//    mMilli = millis() + delay;
//    mArg = arg;
//  }
//}

class KyaApp
{
private:

protected:

public:
  static KyaApp* app;
  static char gPfb[256];

  /**
   * 構築
   *
   * @access public
   */
  KyaApp( ) {
    app = this;
  };

  /**
   * 設定
   *
   * @access public
   */
  virtual void onSetup( ) {
    TRACE
#ifdef KYA_TIMER_INTERVAL
  #ifndef ESP8266
    MsTimer2::set( KYA_TIMER_INTERVAL, timerEntry );  // 割り込みハンドラの設定
    MsTimer2::start();                                // タイマー割り込み開始
    Serial.println( "MsTimer2::start()" );
  #else
    // タイマ割り込みの設定
    noInterrupts();

    timer0_isr_init();

    // ハンドラのエントリを設定
    timer0_attachInterrupt( timerEntry );

    // 次回の割り込みが発生するまでの時間を設定
    timer0_write(ESP.getCycleCount() + MSEC2CLOCK(KYA_TIMER_INTERVAL) ); // 10msec

    interrupts();
  #endif
#endif  // KYA_TIMER_INTERVAL
  }

  /**
   * ループの中身
   *
   * @access public
   */
  virtual void onLoop() {
  }

  /**
   * タイマーハンドラ
   *
   * @access public
   */
  virtual void onTimer( ) {
  }

  /**
   * ミリ秒を 時分秒でシリアルに出力
   *
   * @param  DWORD ms ミリ秒
   * @param  const char* suffix 時分秒のあとに付ける文字列
   */
  void printMillis( DWORD ms, const char* suffix = NULL );

#ifdef KYA_TIMER_INTERVAL
  /**
   * 17ms毎にここが呼び出される
   */
  static void timerEntry( ) {
  #ifdef ESP8266
    // 次回の割り込みが発生するまでの時間を設定
    timer0_write(ESP.getCycleCount() + MSEC2CLOCK(KYA_TIMER_INTERVAL) ); // 10msec
  #endif

    // 割り込み処理ハンドラを呼び出す
    if ( KyaApp::app ) {
      KyaApp::app->onTimer( );
    }
  }
#endif  // KYA_TIMER_INTERVAL

  /**
   * LED 点滅
   *
   * @access public
   * @param
   */
//  static void blinkLED( UINT port, UINT blight, UINT usec, UINT count = 1, UINT duty = 128 );
  static void blinkLED( uint8_t port, uint8_t usec, uint8_t count = 1, uint8_t blight = 255, uint8_t duty = 128 );

  /**
   * LED 点滅
   *
   * @param  uint8_t port ピン番号
   * @param  WORD counter カウンター
   * @param  WORD high HIGH にする回数
   * @param  WORD low  LOW にする回数
   * @return WORD カウンター
   */
  static WORD blinkLED2( uint8_t port, WORD counter, WORD high, WORD low );

  /**
   * LED 点滅
   *
   * @param  uint8_t port ピン番号
   * @param  int high HIGH の時間(msec)
   * @param  int low  LOW  の時間(msec)
   */
  static void blinkLED3( uint8_t port, int high, int low );

  /**
   * LED 点滅
   *
   * @param  uint8_t port  ポート
   * @param  WORD pos   現在位置
   * @param  WORD speed 速度
   * @return 次の位置
   */
  static WORD winkLED( uint8_t port, WORD pos, WORD speed = 1 );

  /**
   * 書式付きコンソール出力
   *
   * @param  PCSTR format 書式文字列
   */
  static void printf( PCSTR format, ... );

  static void puts( PCSTR str ) {
    Serial.println( str );
  }

  static void putstr( PCSTR str ) {
    Serial.print( str );
  }

  /**
   * ミリ秒から時分秒を取得
   *
   * @access public
   * @param  unsigned long msec ミリ秒
   * @return KyaTime 時分秒
   */
  KyaTime msecToTime( unsigned long msec );

  /**
   * トレース
   *
   * @param
   * @return
   */
  static void trace( PCSTR func, PCSTR file, int line );
};

#endif

KyaApp.cpp

/**
 * アプリケーションの基本クラス
 *
 * filename:  KyaApp.cpp
 *
 * @package
 * @version   1.0.0
 * @copyright Copyright (C) 2017 Yoshio Kiya
 * @date      2017-05-16
 * @author    木屋 善夫
 */
#include "KyaApp.h"

KyaApp* KyaApp::app = NULL;
char KyaApp::gPfb[256];

/**
 * ミリ秒を 時分秒でシリアルに出力
 *
 * @param  DWORD ms ミリ秒
 * @param  const char* suffix 時分秒のあとに付ける文字列
 */
void KyaApp::printMillis( DWORD ms, const char* suffix ) {
  // 起動してからの時間を表示
  int h, m, s;
  s = ms / 1000;
  if ( s >= 60 ) {
    m = s / 60;
    s = s % 60;
    if ( m >= 60 ) {
      h = m / 60;
      m = m % 60;
    } else {
      h = 0;
    }
  } else {
    h = 0;
    m = 0;
  }

  char buff[255];
  sprintf( buff, "%02d:%02d:%02d", h, m, s );
  Serial.print( buff );

  if ( suffix ) {
    Serial.print( suffix );
  }
}

/**
 * LED 点滅
 *
 * @param
 * @return
 */
//void KyaApp::blinkLED( UINT port, UINT blight, UINT usec, UINT count, UINT duty )
void KyaApp::blinkLED( uint8_t port, uint8_t usec, uint8_t count, uint8_t blight, uint8_t duty )
{
  while ( (count --) > 0 ) {
    // on
    if ( blight < 255 ) {
      analogWrite( port, blight );
    } else {
      digitalWrite( port, HIGH );
    }
    if ( duty != 0 ) {
      delay( (usec * duty) >> 8 );
    }

    // off
    digitalWrite( port, LOW );
    if ( duty != 255 ) {
      delay( (usec * (255 - duty)) >> 8 );
    }
  }
}

/**
 * LED 点滅
 *
 * @param  uint8_t port ピン番号
 * @param  WORD counter カウンター
 * @param  WORD high HIGH にする回数
 * @param  WORD low  LOW にする回数
 * @return WORD カウンター
 */
WORD KyaApp::blinkLED2( uint8_t port, WORD counter, WORD high, WORD low ) {
  WORD t = (counter ++) % (high + low);

  if ( t < high ) {
    digitalWrite( port, HIGH );
  } else {
    digitalWrite( port, LOW );
  }

  return counter;
}

/**
 * LED 点滅
 *
 * @param  uint8_t port ピン番号
 * @param  int high HIGH の時間(msec)
 * @param  int low  LOW  の時間(msec)
 */
void KyaApp::blinkLED3( uint8_t port, int high, int low ) {
  int t = millis( ) % (high + low);
  if ( t < high ) {
    digitalWrite( port, HIGH );
  } else {
    digitalWrite( port, LOW  );
  }
}


/**
 * LED 点滅
 *
 * @param  uint8_t port  ポート
 * @param  WORD pos   現在位置
 * @param  WORD speed 速度
 * @return 次の位置
 */
WORD KyaApp::winkLED( uint8_t port, WORD pos, WORD speed ) {
  // LEDの点滅
  uint8_t b;
  if ( !(pos & 0x100) ) {
    // < 0x100 is rise
    b = (uint8_t)pos;
  } else {
    // >= 0x100 is set
    b = 0xFF - (uint8_t)pos;
  }
  analogWrite( port, b );

  return pos + speed;
}

/**
 * 書式付きコンソール出力
 *
 * @param  PCSTR format 書式文字列
 */
void KyaApp::printf( PCSTR format, ... ) {
  char buff[256];
  va_list arg;

  va_start( arg, format );
  vsnprintf( buff, sizeof( buff ) - 1, format, arg );
  va_end( arg );

  // 改行で分割しながら描画
  char* p = buff;
  char* f;
  while ( (f = strchr( p, '\n' )) != NULL ) {
    // 終端文字を設定
    *f = 0;
    // 改行付きで主力
    Serial.println( p );
    // 見つけた改行文字の次
    p = f + 1;
  }

  // 文字列が残っていたら主力する
  if ( *p ) {
    Serial.print( buff );
  }
}

/**
 * ミリ秒から時分秒を取得
 *
 * @access public
 * @param  unsigned long msec ミリ秒
 * @return KyaTime 時分秒
 */
KyaTime KyaApp::msecToTime( unsigned long msec )
{
  KyaTime res;

  // 秒単位に変換
  msec = msec / 1000;

  // 秒数を抽出
  res.s = (uint8_t)(msec % 60);

  // 分単位に変換
  msec = msec / 60;

  // 分数を算出
  res.m = (uint8_t)(msec % 60);

  // 時単位に変換
  msec = msec / 60;

  // 時間数を取得
  res.h = (WORD)msec;

  return res;
}


/**
 * トレース
 *
 * @param
 * @return
 */
void KyaApp::trace( PCSTR func, PCSTR file, int line ) {
  Serial.print( func );
  Serial.print( "() " );
  Serial.print( file );
  Serial.print( "(" );
  Serial.print( line );
  Serial.print( ")" );
  Serial.println( );
}

/**
 * 設定エントリ
 */
void setup() {
  Serial.begin( 115200 );
  Serial.println( "" );

  if ( KyaApp::app != NULL ) {
    KyaApp::app->onSetup( );
  } else {
    Serial.println( "KyaApp::app == NULL." );
  }
}

/**
 * ループエントリ
 */
void loop() {
  if ( KyaApp::app != NULL ) {
    KyaApp::app->onLoop( );
  } else {
    Serial.println( "KyaApp::app == NULL." );
    delay( 60 * 1000 );
  }
}

2017年7月7日金曜日

Ubuntu で Digispark Kickstarter

OS を Windows 10 から Ubuntu 17.04 に変えまして、Arduino IDE を使い始めたのですが Digispark Kickstarter に書き込みをしようとしたところエラーが発生しました。このあたりについてに日本語の情報が少ないようなのでメモ書き程度ですが記事にします。

■ スケッチ書き込み時に libusb-0.1-4 が見つからないと言われる

マイコンボードに書き込む」ボタンを押し「> Please plug in the device ... 」と表示されたところでUSBを差すと「error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory」とエラーが発生します。

最大6012バイトのフラッシュメモリのうち、スケッチが812バイト(13%)を使っています。
グローバル変数は13バイトのRAMを使用しています。
Running Digispark Uploader...
Plug in device now... (will timeout in 60 seconds)
/home/kiya/.arduino15/packages/digistump/tools/micronucleus/2.0a4/micronucleus: error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory
どうやらライブラリーが足りないようです。

解決策は下記のページに書かれていました。
https://askubuntu.com/questions/311401/libusb-0-1-so-4-shared-lib-error-in-ubuntu-64-bit-system

[kiya@kiya ~]$ sudo apt-get install libusb-0.1-4

■ スケッチ書き込み時に micronucleus で例外が発生したと言われる

これでうまくゆくかと思ったら今度は「micronucleus: library/micronucleus_lib.c:66: micronucleus_connect: Assertion `res >= 4' failed.」というエラーが発生します…

最大6012バイトのフラッシュメモリのうち、スケッチが812バイト(13%)を使っています。
グローバル変数は13バイトのRAMを使用しています。
Running Digispark Uploader...
Plug in device now... (will timeout in 60 seconds)
> Please plug in the device ...
micronucleus: library/micronucleus_lib.c:66: micronucleus_connect: Assertion `res >= 4' failed.
> Press CTRL+C to terminate the program.
Aborted (core dumped)
え〜、ツールの中で例外が発生したの?そんなこと言われたってどうしたいいのかわからないです…

対策は下記のページに書かれていました。どうやらデバイスへのアクセス権が不足しているらしいです。
https://digistump.com/wiki/digispark/tutorials/linuxtroubleshooting

1. 下記の内容の「/etc/udev/rules.d/49-micronucleus.rules」というファイルを作ります。

[kiya@kiya ~]$ sudo vi /etc/udev/rules.d/49-micronucleus.rules
# UDEV Rules for Micronucleus boards including the Digispark.
# This file must be placed at:
#
# /etc/udev/rules.d/49-micronucleus.rules    (preferred location)
#   or
# /lib/udev/rules.d/49-micronucleus.rules    (req'd on some broken systems)
#
# After this file is copied, physically unplug and reconnect the board.
#
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666"
KERNEL=="ttyACM*", ATTRS{idVendor}=="16d0", ATTRS{idProduct}=="0753", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1"
#
# If you share your linux system with other users, or just don't like the
# idea of write permission for everybody, you can replace MODE:="0666" with
# OWNER:="yourusername" to create the device owned by you, or with
# GROUP:="somegroupname" and mange access using standard unix groups.
2. ルールをリロードします。
[kiya@kiya ~]$ sudo udevadm control --reload-rules

以上でスケッチを書き込めるようになりました。


2017年6月14日水曜日

Pro Micro (クローン) 不明なUSBデバイス

Sparkfun Pro Micro、コピー品だと Amazo で 500円、AliExpress なら 340円ほどで手に入ります。
Leonardo 互換でこのサイズなのでなにかと使いやすいのですが、ちょっとだけ癖がありますので備忘録として残します。

Arduino IDE で書き込む際に、「ボード」にて「Sparkfun  Pro Micro」を選択するのですが、その際現れる「プロセッサ」にはデフォルトで「ATmega32U4(3.3V,8MHz)」が選択されています。

5V,16MHz版にこの状態で書き込んでしまうとブートローダーが破壊され「不明なUSBデバイス(デバイス記述子要求の失敗)」と表示されてシリアル接続ができなくなり、以後書き込むことができなくなってしまうのです。

こうなってしまった場合は単独では復旧させることは難しいと思います。

私の場合は、AdruinoISP スケッチを書き込んだ Arduino UNO に Pro Micro を接続して、「書込装置」に「Arduino as ISP」を選択して「ブートローダーを書き込む」にて復旧させることができました。

Arduino UNO Pro Micro 信号
D13 15 SCK
D12 14 MISO
D11 16 MOSI
D10 RST RESET
5V VCC
GND GND