2016年4月29日金曜日

さぁ大型連休だ(久しぶりにimodelaで基板切削)

ずっとやりたかった基板切削。久しぶりに思い立った。
いろいろ忘れているので、また試行錯誤になってしまった。

今回はAmis用の基板を切削する。





基本的には過去の自分の投稿通りなのだか…
http://continue-to-challenge.blogspot.jp/2014/11/imodelaeagle.html
http://continue-to-challenge.blogspot.jp/2014/11/imodelaeagle_29.html

いくつかハマった点。
・eagleでベタパターンどうするんだっけ?
→ポリゴンを使う。名前をGNDにする。
http://www.piclist.com/images/www/hobby_elec/eagle32.htm

・未結線ってどうやって調べるんだっけ?
→Ratsnestボタンでウィンドウ左下に未結線数が出てくる
http://easylabo.com/2014/07/eagle/1609/
→で、結局どこなのさ? プラグインで表示可能
http://eeebaka.blog47.fc2.com/blog-entry-202.html

・ガーバーデータの出力ってどうやるんだっけ?
http://www.p-ban.com/gerber/eagle.html

そしてひたすら切削。。うるせーー

 久しぶりすぎて水平がとれていなかったらしい。
面だししなきゃOrz

2016年4月16日土曜日

electron.jsで外部プログラムの標準入出力を制御

概要
electron.jsでjavascriptなプログラムをクロスプラットフォームで使えるのだけど、
速度重視やデバイスに依存するプログラムにはまだ適さないように思う。
その場合、c/c++などを用いることになるが、でもGUIまで作るのは非常に骨が折れる…
GUIはelectronを使ってhtmlベースでサックリと済ましてしまって、他の部分はc/c++に頑張ってもらう構成を考えた。
なんだか.netみたいな考えになってしまうけど。



構成
コアとなるのは、サーバー側のindex.jsとレンダラ側のmyapp.js間のIPC通信と
外部プログラム制御のためのchildp.jsのchild_process。

外部プログラム「ec_child_test」
CUIベースのカウントアップダウンタイマーとした
STARTでカウント開始、UPでカウントアップ、DWONでカウントダウン
カウントは1秒周期、STOPでカウント停止、EXITでプログラム停止という単純なもの。
プログラムは最後にまとめて載せた。(gistで部分的に表示する方法は無いのかな・・)
と思ったら、あった。embeddedコードに「?file=[ファイル名]」とすれば良いみたい。
#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h> // sleep()を定義
using namespace std;
int counter = 0;
int CNT_MODE = 0;
int CNT_FLG = 0;
int EXIT_FLG = 0;
// ワークスレッド
void* work_thread( void* args )
{
while(1){ //for(int i = 0; i < 10; i++){
if(CNT_FLG == 1){
if((counter < 100 ) && (CNT_MODE == 0)) counter++;
else if((counter > 0 ) && (CNT_MODE == 1)) counter--;
}
cout << "count : " << counter << endl;
sleep(1); // スレッド 1 秒停止
}
return NULL;
}
//UIスレッド
void* ui_thread( void* args )
{
string input_data;
do{
cin >> input_data;
cout << "RCV : " << input_data << endl;
if(input_data == "START") CNT_FLG = 1;
else if(input_data == "UP" ) CNT_MODE = 0;
else if(input_data == "DOWN" ) CNT_MODE = 1;
else if(input_data == "STOP" ) CNT_FLG = 0;
}while (input_data != "EXIT");
EXIT_FLG = 1;
return NULL;
}
int main() {
cout << "開始" << endl;
pthread_t wk_th;
pthread_t ui_th;
pthread_create( &ui_th, NULL, ui_thread, (void *)NULL );
pthread_create( &wk_th, NULL, work_thread, (void *)NULL );
// スレッド終了を待つ
pthread_join( ui_th, NULL );
if(EXIT_FLG == 1){
pthread_cancel(wk_th);
}else{
pthread_join( wk_th, NULL );
}
cout << "終了" << endl;
return 0;
}


サーバー側「index.js」と「childp.js」
・index.js
  IPC通信でレンダラからもらった命令をchildp.jsに伝えているだけ
var app = require('app');
var ipc = require('ipc');
var BrowserWindow = require('browser-window');
var cp = require('./childp.js');
require('crash-reporter').start();
var mainWindow = null;
var debug_my_name = "[index.js] ";
app.on('window-all-closed', function () {
//if (process.platform != 'darwin')
app.quit();
});
app.on('ready', function () {
// ブラウザ(Chromium)の起動, 初期画面のロード
mainWindow = new BrowserWindow({
width: 1100,height: 800
});
mainWindow.openDevTools();
mainWindow.loadUrl('file://' + __dirname + '/index.html');
//document.getElementById("str").textContent="引数はです。";
mainWindow.on('closed', function () {
mainWindow = null;
});
});
// 非同期プロセス通信
ipc.on('async-req', function( event, args ){
if(args['cmd']){
console.log(debug_my_name + "IPC受信 cmd->"+args['cmd']);
if(args['cmd'] == 'run'){
console.log(debug_my_name + "外部プログラム起動を要求");
cp.run( function (rarg){
console.log(debug_my_name + "result="+rarg["result"]+" rdata="+rarg["data"]);
// レンダラプロセスへsend
event.sender.send('async-rep', rarg);
});
/*以下 外部プログラムに対して標準入力にて通知するもの */
}else if(args['cmd'] == 'kill'){
console.log(debug_my_name + "外部プログラム終了を要求");
cp.stdin_write("EXIT");
}else if(args['cmd'] == 'start'){
console.log(debug_my_name + "外部プログラムに["+args['cmd']+"]を通知" );
cp.stdin_write("START");
}else if(args['cmd'] == 'stop'){
console.log(debug_my_name + "外部プログラムに["+args['cmd']+"]を通知" );
cp.stdin_write("STOP");
}else if(args['cmd'] == 'down'){
console.log(debug_my_name + "外部プログラムに["+args['cmd']+"]を通知" );
cp.stdin_write("DOWN");
}
else if(args['cmd'] == 'up'){
console.log(debug_my_name + "外部プログラムに["+args['cmd']+"]を通知" );
cp.stdin_write("UP");
}
}
});
view raw index.js hosted with ❤ by GitHub
・childp.js
  外部プログラムの制御担当
  といっても子プロセスでプログラムを起動して、その標準入出力に読み書きを
  行っているだけ。プロセスの生成監視はもっと厳密にしないといけないが、
  今回はこのまま。
  あと、node側が終了しても子プロセスが生きているので、別途終了処理が必要。
//子プロセス制御用
var spawn = require("child_process").spawn;
var child = null;
var debug_my_name = "[childp.js] ";
var cmd = "./ec_child_test";
exports.stdin_write = function stdin_write(str){
if(child == null){
console.log(debug_my_name + "プロセスが生成されていない");
}else{
console.log(debug_my_name + "["+str+"]を標準入力へ");
child.stdin.write(str + "\n");
}
}
exports.run = function run(callback_func) {
if(child != null){
console.log(debug_my_name + "既にプロセスが生成されている");
return
}
child = shspawn(cmd);
/* 標準出力の処理 */
child.stdout.on('data',function(data){
if(callback_func != null){
var retval = data+"\n";
retval = retval.replace(/(\r|\n|\r\n)/g,"");
console.log(debug_my_name + "["+retval+"]を返答");
callback_func({result:"stdout",data:retval});
}
});
child.stderr.on('data',function (data){
console.log(debug_my_name + 'exec error: '+data);
});
child.on('close',function(code) {
// コマンド実行後の処理
if(callback_func != null){
console.log(debug_my_name + "[終了]を返答");
callback_func({result:"close",data:"終了"});
child = null;
}
});
}
function shspawn(command) {
return spawn('sh', ['-c', command]);
}
view raw childp.js hosted with ❤ by GitHub

レンダラ側「index.html」と「myapp.js」
・index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>外部プログラムとの通信サンプル | ec_child_test</title>
<link rel="stylesheet" href="css/foundation.css" />
<script>window.jQuery = window.$ = require('./js/vendor/jquery.min.js');</script>
<script src="js/foundation.min.js"></script>
<script src="js/myapp.js"></script>
</head>
<body>
<div class="small button-group">
<button class="button" id="run_btn" >起動</button>
<button class="success button" id="start_btn" >開始</button>
<button class="warning button" id="up_btn" >アップ</button>
<button class="warning button" id="down_btn" >ダウン</button>
<button class="warning button" id="stop_btn" >停止</button>
<button class="alert button" id="kill_btn">終了</button>
</div>
<label id="status_label">[待機中]</label>
<div class="progress" role="progressbar" >
<span class="progress-meter" id="progress-gra" style="width:0%">
<p class="progress-meter-text" id="progress-num">0%</p>
</span>
</div>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
  
・myapp.js
//レンダラ側のプログラム
// IPC通信を行う
var ipc = require('ipc');
var remote = require('remote');
var dialog = remote.require('dialog');
var browserWindow = remote.require('browser-window');
var debug_my_name = "[myapp.js] ";
window.onload = function () {
//reqInitDataAsync();
};
$(function(){
$(document).foundation();
$('#run_btn').on('click',function(){
console.log(debug_my_name + "起動ボタン Click");
ipc.send('async-req', { cmd:"run" });
});
$('#start_btn').on('click',function(){
console.log(debug_my_name + "スタートボタン Click");
ipc.send('async-req', { cmd:"start" });
});
$('#stop_btn').on('click',function(){
console.log(debug_my_name + "ストップボタン Click");
ipc.send('async-req', { cmd:"stop" });
});
$('#kill_btn').on('click',function(){
console.log(debug_my_name + "終了ボタン Click");
ipc.send('async-req', { cmd:"kill" });
});
$('#down_btn').on('click',function(){
console.log(debug_my_name + "カウントダウンボタン Click");
ipc.send('async-req', { cmd:"down" });
});
$('#up_btn').on('click',function(){
console.log(debug_my_name + "カウントアップボタン Click");
ipc.send('async-req', { cmd:"up" });
});
/*コールバックの処理*/
ipc.on('async-rep', function(arg) {
if(arg["result"] == "stdout"){
console.log(debug_my_name + "IPC通信 応答:" + arg["data"]);
$("#status_label").text("状態:"+arg["data"]);
if(arg["data"].indexOf(":") > 0){
var rdatas = arg["data"].split(':');
if(rdatas[0].trim() == "count"){
var progress = Number(rdatas[1]);
$("#progress-num").text(progress+"%");
$("#progress-gra").width(progress+"%");
}
}
}else if(arg["result"] == "close"){
console.log(debug_my_name + "終了");
$("#status_label").text("[終了]");
}
});
});
view raw myapp.js hosted with ❤ by GitHub

参考
いろいろなHPを参考にさせてもらいましたが、たくさんありすぎて+時間が経ちすぎて忘れたOrz

その他
「ググるよりもググられたい」という広告が出ていた。刺さる。
なかなか実現できないこともあるけど、まだ諦めずに頑張ろうと思う。


2016年4月3日日曜日

AmisとCGIとの接続(名前付きパイプFIFO)

概要
webからの操作で、AmisボードのLEDを操作する準備として
Amisボードと通信するプログラムと、webでユーザー操作を受け持つcgiとの接続を検討した。

構成
dd-Wrt上のLighttpd(Port81)を使ってwebサーバーを立ち上げる
仮にAmiscommServer.cgi とする
Amisボードとの通信プログラムをAmis-Commとする

考え方は以下とか本を参考にした。
http://www.ncad.co.jp/~komata/c-kouza12.htm
C言語による実践Linuxシステムプログラミング

web側はまだ作成中

CSSフレームワークを使うとなんとなくそれっぽくできるから良いね。
foundation.js を使った。