Large Display Size Middle Display Size Small Display Size

2017 年 9月 の日記


2017/9/23(土)

fig.
▲キャラをぐりぐり動かせます。

サイドビューキャラをJavaScriptで動かそう!

今月6日に作ったプログラムのver. up です。

左の画像リンクをクリックすると文書へ移動します。

ガンプラみたいにポーズ作って遊べます。

(※足と腰はまだ動きません)




2017/9/22(金)

fig.
▲「月別画像リンク」へのリンク

このページの上部のメニュー内に「月別画像リンク」というページへのリンクを設置しました。

このリンクをクリックすると…



fig.
▲「月別画像リンク」

「月別画像リンク」のページを開きます。

このページではhomepage6047の月々のページのスクリーンショットから各ページへ移動できます。

左の画像リンクをクリックすると文書へ移動します。




2017/9/18(日)

WEBツール「小窓方眼紙」

[no canvas]
▲「小窓方眼紙」

左の表の横軸を「時間」にして縦軸を「音階(ドレミ)」にして、表の上に長方形の図形を自由に乗せることができれば、音楽のメロディをかなでる「シーケンサー」として機能させることができます。

これはそのための、「表」だけの試作品です。

「DEBUG TOOLS」と書かれた部分にマウスを乗せるとメニューが現れます。たとえば「goto←」をクリック連打すると表がスクロールします。どれをクリックしても特に壊れたりしないので適当に操作してみてください。

今できるのはそれだけです。

将来、ちょっとしたメロディを作ってこの方眼紙で表示すれば「こんなメロディどう?」みたいな記事が書きやすくなると思います。



技術が一般化して専門家の立場があやうい

「作曲は誰でもできるものではない」というのが常識ですが、簡単に作曲できる方法は以前このホームページで紹介しました。(一番上のメニューの「カテゴリ/一般実用」の「誰にでもできる作曲」 →これ

「カメラ 」は昔は「カメラマン」と言われる専門家でないと綺麗な写真は撮れませんでした。しかし今ではデジカメの機能も充実して誰でも綺麗な写真を 撮影することができます。「料理」も母親からおふくろの味として伝授されなくてもクックパッドでかなりおいしい料理が作れます。「映画」も最近はユー チューバーがいろいろ動画を作って人気を得ています。たぶん絵コンテみたいなことをやって計画を立てながら映画監督さながらに動画制作しているのでしょう。

そういうわけで、最近は専門家の立場があやういです。情報化社会ともなれば、さまざまなテクニックが流通して、そうなることも当然でしょう。でも昔からの専門家の人はちょっとさびしい思いをしているのではないでしょうか。

テクニックが誰にでも習得できたとしても、あまりうまく言えませんが、カメラマンにしかできないこと、母親にしかできないこと、映画監督にしかできないことがあるんじゃないでしょうか。

私が言いたいのは「昔からの専門家の人はちょっとさびしい思いをしているのではないでしょうか」の1つです。それを無視して前に進むことはできません。

ちなみに私は専門家ではありませんが、アマチュアプログラマー歴が長めです。

最近はみんながプログラミングできるからさびしい思いをしているのでは…?

うーん、さびしい思いはしていません。もしも世の中の新しいプログラマーの皆さんが、みんなそろってライブラリを一切使わず、メモリーの中 の様子に興味を持ち、JavaだけじゃだめだC言語やアセンブラもやらないと応用が…とか取り組んでいたら、さびしいと思うのかもしれません。


大きく出ましたわね

カメラにしろ、料理にしろ、作曲にしろ、新しい人たちは結局は経験の量では古い人にかなわないのでしょうか。

そこで実際どうなのかなと思って「専門家 初心者」で検索したところ、こんな研究が現れました。

専門家と初心者の問題解決

短い記事ですが、ここで言われているのは「初心者は知識が表面的であり、専門家は原理に基づいた知識になっている」ということです。

私も「作曲できるぞ~」なんて言っていますが、本腰入れて音楽を勉強しようなんて思っていませんから…。専門家の地位は原理でしっかり固められているので「さびしい」なんて心配はないのでしょう。(でも音楽の原理って、太古の原人が獲物を捕らえて「今夜はごちそうじゃ やんや、やんや、太鼓をたたけ 声を出して歌え 」ではないかって個人的に思うんですが…要は音を出すことを楽しめと。)

小窓方眼紙の技術的なところ

以前のシーケンサー(これ)ではHTML要素を駆使して画面を構成していました。

今回も最初はHTML要素で始めましたが、座標関係で一晩頑張って挫折しました。

どうも、HTML要素の特殊なしくみは、どこかプログラミングの思考を妨害しているような気がしました。

そこで試しにHTML要素を使わず、CANVAS(いわゆるCG描画)を使って画面を構成してみようと思って今回できたのがこの「小窓方眼紙」です。ちゃんとうまくいったので、無理にHTML要素を使うことはないんだなと思いました。(HTML要素は"しきい"が低く、CANVASは"しきい"が高い気がしていた)

人のソースコードはホームページでバーンと載せられても、ほとんど読めないものです。

近々、もうちょっと読めるようにいくらか工夫してみたいと思います。(関数ごとに色分け、イラストを交える、キャラに説明させる、など)

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>Javascript CANVAS</title>
<style>
</style>
<script>
console.log( "=============== script ==============" );
/*
『名称未設定』

使用手順:
Hello World!:
言葉遣い:
言葉
	
語源
	
	
意味
EL
	
	
ELement
	
	
HTML要素
AR
	
	
ARea
	
	
描画要素(エリア)
sx,ex
	
	
	
	
start x, end x
GR
	
	
GRaphics
	
画面座標
RL
	
	
ReaL
	
	
実寸座標
*/


function $( id ) {
	
return document.getElementById( id );
	
}
var HereDocument = /\/\*\s*([^]*?)\s*\*\//;

var canvasEL, canvas;

function onloadx() {
canvasEL = $( "canvasELID" );
canvas = canvasEL.getContext( '2d' );
//setCanvasResolution( canvasEL, canvas, 2 );

xMargin = 32;
yMargin = 32;
graphARWidth = canvasEL.width - xMargin;
graphARHeight = canvasEL.height - yMargin;
globalXRL = 0;
globalYRL = 0;

graphAR = new Axis( xMargin, yMargin, graphARWidth, graphARHeight );
graphAR.columnLineColor = "salmon";
graphAR.rowLineColor = "lightgreen";
graphAR.setDrawFLGs( { labelX : false, labelY : false, lineX : true, lineY : true } );
graphAR.globalRL = new XY( globalXRL, globalYRL );
graphAR.rateGRDivRL = new XY( 1, 1 );

axisX = new Axis( graphAR.leftGR, 0, graphARWidth, yMargin );
axisX.backgroundColor = "salmon";
axisX.setDrawFLGs( { labelX : true, labelY : false, lineX : true, lineY : false } );
axisX.globalRL = graphAR.globalRL;
axisX.rateGRDivRL = graphAR.rateGRDivRL;

axisY = new Axis( 0, graphAR.topGR, xMargin, graphARHeight );
axisY.backgroundColor = "lightgreen";
axisY.setDrawFLGs( { labelX : false, labelY : true, lineX : false, lineY : true } );
axisY.globalRL = graphAR.globalRL;
axisY.rateGRDivRL = graphAR.rateGRDivRL;


draw( canvas );

debugToolsBuild();
}

function draw( g ) {
g.clearRect( 0, 0, canvasEL.width, canvasEL.height );

axisX.draw( g );
axisY.draw( g );
graphAR.draw( g );
}

function XY( x, y ) {
this.x = x;
this.y = y;
}

function Axis( leftGR, topGR, widthGR, heightGR ) {
//画面上 表示位置、サイズ
this.leftGR = leftGR;
this.topGR = topGR;
this.widthGR = widthGR;
this.heightGR = heightGR;
//実寸 表示中の位置
this.globalRL = new XY( 0, 0 );
//見た目の倍率(画面表示/実寸)
this.rateGRDivRL = new XY( 1, 1 );
//実寸 目盛りはいくつ毎か
this.gagePerXRL = 100;
this.gagePerYRL = 100;

//色設定
this.backgroundColor = "white";
this.columnLineColor = "black";
this.rowLineColor = "black";
//ラベルを表示するかどうか、目盛りを表示するかどうか
this.setDrawFLGs( { labelX : false, labelY : false, lineX : false, lineY : false } );
}
Axis.prototype.setDrawFLGs = function( flgs ) {
this.drawLabelXFLG = flgs.labelX;
this.drawLabelYFLG = flgs.labelY;
this.drawLineXFLG = flgs.lineX;
this.drawLineYFLG = flgs.lineY;
}
Axis.prototype.draw = function( g ) {
g.save(); g.translate( this.leftGR, this.topGR);
g.fillStyle = this.backgroundColor;
g.fillRect( 0, 0, this.widthGR, this.heightGR );

g.beginPath();
g.rect( 0, 0, this.widthGR, this.heightGR );
g.clip();

//横目盛り描画
var modXRL = this.globalRL.x % this.gagePerXRL;
var cursorXRL = this.globalRL.x - modXRL;
g.strokeStyle = this.columnLineColor;
do {
cursorXGR = ( cursorXRL - this.globalRL.x ) * this.rateGRDivRL.x;
//check.
if( cursorXGR > this.widthGR ) break;
if( this.drawLineXFLG )
gline( g, cursorXGR, 0, cursorXGR, this.heightGR );
if( this.drawLabelXFLG ) {
g.fillStyle = "black";
gtext( g, cursorXRL, cursorXGR, 9, 9 );
}
cursorXRL += this.gagePerXRL;
} while( true );

//縦目盛り描画
var modYRL = this.globalRL.y % this.gagePerYRL;
var cursorYRL = this.globalRL.y - modYRL;
g.strokeStyle = this.rowLineColor;
do {
cursorYGR = ( cursorYRL - this.globalRL.y ) * this.rateGRDivRL.y;
//check.
if( cursorYGR > this.heightGR ) break;
if( this.drawLineYFLG )
gline( g, 0, cursorYGR, this.widthGR, cursorYGR );
if( this.drawLabelYFLG ) {
g.fillStyle = "black";
gtext( g, cursorYRL, 0, cursorYGR + 9, 9 );
}
cursorYRL += this.gagePerYRL;
} while( true );

g.restore();

//debug print
var DPs = document.getElementsByName( "debugprint" );
for( var i = 0; i < DPs.length; i++ ) {
var DP = DPs[ i ];
//check.
if( ! DP.printFLG ) continue;
DP.innerHTML = DP.evalSTR + ": " + eval( DP.evalSTR );
}

}

function gline( g, sx, sy, ex, ey ) {
g.beginPath();
g.moveTo( sx, sy );
g.lineTo( ex, ey );
g.stroke();
}
function gtext( g, str, x, y, sz ) {
g.font = sz + "px 'MS ゴシック'";
g.fillText( str, x, y );
}

function debugToolsBuild() {
toolEL = document.createElement( "DIV" );
	
	
document.body.appendChild( toolEL );
with( toolEL.style ) {
width
	
	
=
	
"10em";
border
	
	
=
	
"solid 2px black";
backgroundColor
	
=
	
"silver";
cursor
	
	
=
	
"pointer";
}
toolEL.innerHTML = ( function() {/*
<b>DEBUG TOOLS</b><BR>

<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisX.globalRL.x += 10;
draw( canvas );
">map→</div>

<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisX.globalRL.x -= 10;
draw( canvas );
">map←</div>

<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisY.globalRL.y += 10;
draw( canvas );
">map↓</div>

<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisY.globalRL.y -= 10;
draw( canvas );
">map↑</div>

<div id="axisX.globalRL.x_DP" name="debugprint" onmousedown="event.preventDefault(); event.stopPropagation();" onclick='
//check.
if( ! this.evalSTR ) this.evalSTR = this.innerHTML;
this.printFLG = !this.printFLG;
this.style.color = this.style.color == "blue" ? "" : "blue";
draw( canvas );
'>axisX.globalRL.x</div>

<div id="axisY.globalRL.y_DP" name="debugprint" onmousedown="event.preventDefault(); event.stopPropagation();" onclick='
//check.
if( ! this.evalSTR ) this.evalSTR = this.innerHTML;
this.printFLG = !this.printFLG;
this.style.color = this.style.color == "blue" ? "" : "blue";
draw( canvas );
'>axisY.globalRL.y</div>

<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisX.rateGRDivRL.x += 0.1;
draw( canvas );
">x zoom+</div>
<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisX.rateGRDivRL.x -= 0.1;
//check.
if( axisX.rateGRDivRL.x < 0.1 ) axisX.rateGRDivRL.x = 0.1;
console.log( axisX.rateGRDivRL.x );
draw( canvas );
">x zoom-</div>

<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisY.rateGRDivRL.y += 0.1;
draw( canvas );
">y zoom+</div>
<div onmousedown="event.preventDefault(); event.stopPropagation();" onclick="
axisY.rateGRDivRL.y -= 0.1;
//check.
if( axisY.rateGRDivRL.y < 0.1 ) axisY.rateGRDivRL.y = 0.1;
draw( canvas );
">y zoom-</div>


*/} ).toString().match( HereDocument )[ 1 ];
//toolEL開閉
toolEL.onmouseover = function( e ) {
for( var i = 0; i < toolEL.childNodes.length; i++ ) {
var child = toolEL.childNodes[ i ];
if( child.tagName )
with( child.style ) {
display
	
=
	
"block";
}
}
}
toolEL.onmouseout = function( e ) {
for( var i = 0; i < toolEL.childNodes.length; i++ ) {
var child = toolEL.childNodes[ i ];
if( child.printFLG ) {
with( child.style ) {
display
	
=
	
"block";
}
} else {
//check.
if( child.tagName != "DIV" ) continue;
with( child.style ) {
display
	
=
	
"none";
}
}
}
}
toolEL.onmouseout( null );

}

</script>
</head>
<body onload="onloadx();" style="
background-color
	
:
	
lightgray;
">
<canvas id="canvasELID" width="512" height="448" style="
background-color
	
:
	
white;
">[no canvas]</canvas>
</body>
</html>

 新しいウィンドウで実行  [小WINで表示]


2017/9/10(日)

fig.
▲今回ドラクエの戦闘開始部分を再現した

ゲームプログラムでは画面の動きをアニメーションとして、タイマーで管理する必要があります。特にRPGではイベント処理といって、ゲームの世界で起こる出来事に合わせて画面をフラッシュさせたり、つづいてメッセージを表示したりと、複雑なアニメーションのプログラムが必要になります。

ここではそのプログラムの実現の一例を紹介しています。あまり丁寧な説明はなく、他人(私)が作った理解しづらいソースコードを載せているだけなので、参考として読む程度にしてください。

左の画像リンクをクリックすると文書へ移動します。




2017/9/6(火)

サイドビューキャラをJavaScriptで動かそう!

3つのスライダを使って、手前の腕だけ動かせます。

ガンダムのプラモデルと同じ感覚でポーズを取ってみてください。


there is no canvas.
肩(上腕) -100200
ひじ(腕) -1505
手首(手) -9060

ソースコード: 単独ファイル
<html lang="ja">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>untitled script</title>
<script>
function $( id ) { return document.getElementById( id ); }

//===サイドビューキャラ プログラム 開始

/*
オブジェクト
画像ソース
画像、canvas.path

描く
回転プロパティを反映
*/

function SideviewChar() {
this.x = 0;
this.y = 0;
this.rotate = 0;
this.imageSRC = {
path
	
:
	
new Array(),
pict
	
:
	
new Image(),
};
this.children = new Array();
}

SideviewChar.prototype.draw = function( canvas ) {
//座標軸などを保存
canvas.save();

//座標軸などを変更
canvas.translate( this.x, this.y );
canvas.rotate( this.rotate );
/*
save,restoreとtranslate,rotateをこのように使用して
肩以下をまとめて回転し、ひじ以下をまとめて回転、が実現されている。
私もこういうのに詳しいわけではないが、たまたまこれで思うようになった。
*/

//画像ソース描画(パス)
/*
imageSRC.path[ 1つのパス ][ 0 ][ そのパスの塗り色、線色 ] で1つのパスの色を設定している
imageSRC.path[ 1つのパス ][ パスを構成する1つの点 ][ x, y ]で1つのパスの形を設定している
*/
for( var j = 0; j < this.imageSRC.path.length; j++ ) {
//パスの色を設定
var styles = this.imageSRC.path[ j ][ 0 ];
	
//fill, stroke styles.
canvas.fillStyle = styles[ 0 ];
	
	
//fillStyle
canvas.strokeStyle = styles[ 1 ];
	
//strokeStyle

//1つのパスの形をcanvas上に作る
canvas.beginPath();
for( var i = 1; i < this.imageSRC.path[ j ].length; i++ ) {
var point = this.imageSRC.path[ j ][ i ];
if( i == 1 ) {
canvas.moveTo( point[ 0 ], point[ 1 ] );
} else {
canvas.lineTo( point[ 0 ], point[ 1 ] );
}
}
canvas.closePath();

//パスを描く
if( styles[ 0 ] != null ) canvas.fill();
if( styles[ 1 ] != null ) canvas.stroke();
}

//回転の中心 しるし
//
	
	
canvas.beginPath();
//
	
	
	
canvas.arc( 0,0,4,0, 6.28,false );
//
	
	
canvas.closePath();
//
	
	
canvas.stroke();

//親子関係の子たちを描く
for( var i = 0; i < this.children.length; i++ ) {
var child = this.children[ i ];
child.draw( canvas );
}

//座標軸などを戻す
canvas.restore();

};

function onloadx() {
//canvas用意
canvasEL = $( "canvasELID" );
canvas = canvasEL.getContext( "2d" );

//パーツ作成(腕を3つに分割してそれぞれ作成)
jouwan = new SideviewChar();
jouwan.imageSRC.path = [
[
[ "RGB(255,255,204)", null ],
[ -20, -22 ],
[ 120, -20 ],
[ 120, 20 ],
[ -20, 24 ]
]
];
ude = new SideviewChar();
	
//ひじから下を何と言うか知らないので「うで」と呼ぶことにした
ude.imageSRC.path = [
[
[ "RGB(255,255,204)", null ],
[ -20, -20 ],
[ 100, -20 ],
[ 100, 20 ],
[ -20, 20 ]
]
];
te = new SideviewChar();
te.imageSRC.path = [
[
[ "RGB(255,255,204)", null ],
[ 0, -25 ],
[ 50, -25 ],
[ 50, 25 ],
[ 0, 25 ]
]
];

//パーツの親子関係
jouwan.children.push( ude );
ude.children.push( te );

//パーツの位置(親パーツからの相対位置、回転なしの状態での位置)
jouwan.x = 250;
	
jouwan.y = 195;
ude.x = 100;
te.x = 102;

//各パーツの回転(初期位置)
jouwan.rotate = 3.14 / 4;
ude.rotate = -3.14 / 4;
te.rotate = -3.14 / 4;
draw( canvas );

}
function draw( canvas ) {
canvas.clearRect( 0, 0, canvasEL.width, canvasEL.height );
jouwan.draw( canvas );
}

//---スライダ関係
function s_onloadx() {
	
//s_はスライダのs
//各スライダ 取得
jouwan_kaiten = $( "jouwan_kaiten" );
ude_kaiten = $( "ude_kaiten" );
te_kaiten = $( "te_kaiten" );
//各スライダの隣のspan取得
jouwan_valdisp = $( "jouwan_valdisp" );
ude_valdisp = $( "ude_valdisp" );
te_valdisp = $( "te_valdisp" );

//スライダオブジェクトにJavaScriptオブジェクトを入れておく
jouwan_kaiten.targetChar = jouwan;
ude_kaiten.targetChar = ude;
te_kaiten.targetChar = te;

//JavaScriptオブジェクトに設定されている回転の値を、スライダへ反映する
jouwan_kaiten.value = 180 / 3.14 * jouwan.rotate;
ude_kaiten.value = 180 / 3.14 * ude.rotate;
te_kaiten.value = 180 / 3.14 * te.rotate;

s_draw();
}

function s_draw() {
//現在の値をスライダの隣に表示
jouwan_valdisp.innerHTML = jouwan_kaiten.value;
ude_valdisp.innerHTML = ude_kaiten.value;
te_valdisp.innerHTML = te_kaiten.value;
}

function onslidechangex( e ) {
//スライダが動いたら
s_draw();
e.target.targetChar.rotate = 3.14 / 180 * e.target.value;
draw( canvas );
}

//===サイドビューキャラ プログラム 終了

</script>
</head>

<body id="bodyID" onload="onloadx(); s_onloadx()">
サイドビューキャラをJavaScriptで動かそう<BR>
<img src="図1.png">
<canvas id="canvasELID" width="480" height="480" style="
position
	
:
	
absolute;
left
	
	
:
	
0px;
top
	
	
	
:
	
0px;
">
there is no canvas.
</canvas>
<BR>

<pre>
肩(上腕)
	
-100<input type="range" value="0" min="-100" max="200" id="jouwan_kaiten" oninput="onslidechangex(event)">200
	
<span id="jouwan_valdisp"></span>度


ひじ(腕)
	
-150<input type="range" value="0" min="-150" max="5" id="ude_kaiten" oninput="onslidechangex(event)">5
	
<span id="ude_valdisp"></span>度


手首(手)
	
-90<input type="range" value="0" min="-90" max="60" id="te_kaiten" oninput="onslidechangex(event)">60
	
<span id="te_valdisp"></span>度
</pre>

</body>
</html>

2017/9/2(土)


電子回路の話が苦手な方もいるかもしれませんが
また電子回路の話題です。


国家資格である「電子機器組立て1級」の実技試験を受けてきました。

※この文面は「資格の実技試験の紹介」に加え、「今回の私のNGの一部始終」を詳細な図入りで語っているので長文になっています。わかってもらうためにはどうしても図が必要になります。訪問者の方が、将来取り組むことのない専門的な事柄について「わかった」としてもどんな得になるのか少し疑問ですが、私はどうしても一般向けにわかるように話さずにはいられない性格のようです。


この資格は「学科」と「実技」の2つを合格して資格の合格となります。どちらか片方を合格すればその合格は記録され、次回はもう片方を受験すればよいというものです。

実技試験の内容を少し紹介しましょう。

一般の方に通じるように、たとえば「シャーシ」という言葉を使わず「ボディ」と表現したりしています。


▲「省エネコントローラー」

実技試験で作成する「省エネコントローラー」は家庭のAC100Vのコンセントと家電製品のあいだに取り付けるボックスタイプの機械で、光センサーと人物センサー(景色の動きセンサー)を搭載しています。光センサーにより夜間になると作動し、人物センサー(焦電素子)により人がいるあいだは家電製品の電源をオンして人がいなくなると電源オフします(逆も可能)。たとえば部屋で就寝中はライトの電源がオフになり人がムクっと起き上がるとライトが自動で点灯するようなことができます。

機械のボディ(シャーシ)にはLED表示と、家電製品を接続する端子、電源コード、電源スイッチなどがあります。


▲ボディ正面 LED表示がある。

▲ボディ背面 端子類が並ぶ。









機械の内部には電気配線がたくさんあり「束線」と呼ばれています。電気コードを束でまとめるのでそう呼ばれています。業界によってはハーネスとも呼ばれています(なにかの映画で「ハーネスがイカレたようだ!!直してくる!」というセリフがありました。wikipedia)。そして大小2つの基板があります。


▲内部には電気配線があり、束ねてある。
(※当ホームページで扱っている「暗記ツール」はこの中央の大基板の上に乗る部品の配置を暗記するものです)

基板、束線、ボディなどはそれ以上分割できないバラバラの細かい部品(コンデンサ1個、ネジ1個といった部品)の状態で配られて、試験開始から4時間かけて完成させて動作確認して提出します。

綺麗に作っても動かなければ不合格です。そういうのは「ただの綺麗な箱」といった表現をよく耳にします。どんなに綺麗に作成しても、回路にどこかミスがあって動きがおかしいと使い物になりません。パソコンも「ソフト(OS)がなければただの箱(ガラクタ)」と言われますがそれと同じです。

逆にちゃんと動いても、見た目の綺麗さについて減点が多すぎると不合格になります。動作と綺麗さの両立が必要なんです。

2級のころから練習のためにこの省エネコントローラーを購入していたから、今では部屋に5台くらい同じものが置いてあります。そんなに省エネしたら電気代30円になっちゃうでしょ…ならないって

以上、実技試験の紹介でした。


そして今回、私の実技試験の結果はNGでした。

私は試験開始から、束線作成、ボディ作成(シャーシと周辺部品の取り付け、束線と周辺部品のはんだ付け)までは順調でしたが、大基板を作成している途中で残り1時間になってしまいました。残り1時間で、「大基板作成」の完了(15分くらい)、「小基板作成(1時間)」、「その大小基板のボディへの取り付け(15分)」、そして「動作確認(5分)」、「配線を整える整形(5分)」はできません。4時間を超えて30分の延長時間(減点される)を利用できますが、それでも時間が足りないのでは?

そこで急ぎ始めました。

大基板は あわてつつも終わりましたが、小基板で配線がうまくいかない事態になり、どうしてうまくいかないのかと思って 混乱しながら確認すると、小基板に取り付けるICの上下を間違えてはんだ付けしていました。部品の1つが上下逆なら周囲の配線もおかしくなるでしょう。


▲赤い太枠の部分の上下を間違えた。(写真は正常)

このICには16本のピンがあり、この16本を小基板にじかに はんだ付けしています。この16本のはんだを同時に解除するのは時間があっても非常に困難です。ICはそのままにして配線を組み替える方法もありますが、配線も16本とも基板にしっかりとはんだ付けしてあるのでまず無理です。残り1時間ではもうこの試験の合格は不可能です。

それがわかったので、呆然とし脱力しました。悲しい気持ちのオーラが私をまといました。そういうオーラって、はためから見てわかるんじゃないかな、なんて思ったりして。

しかし、あきらめず、ゆっくりですが状況確認を続けることにしました。

そしたら、アレっ? よくよく見たらICの上下は間違えていませんでした。急いでいたために正常なのに間違えたと勘違いしたんです。

そんなことで時間を取られ さらに大変な状況になったので、もう作品の見た目は無視して小基板の配線を「空中配線」することにしました。通常は基板上にきちんとはんだ付けするところ、空中に浮いた状態にしました。これならはんだする時間を省けるので近道です。


▲(ネット上には1級の小基板の写真が少ないので大きめの写真を用意しました。ただし誰からも何も指示を受けない独学での作成なので、細かい部分のやり方が間違っているかもしれません。参考程度に見てください)

そして一度はもうだめだと思ったのに、空中配線ではありますが小基板を完成させることができました。あきらめていれば完成の喜びはありませんでした。

しかし、もう4時間まであと少しで時間がない!

空中配線の次は「基板の取り付けを省く」ことにしました。つまり基板とボディの設備的な固定をしないで、配線だけ基板へ接続して少なくとも回路を成り立たせようとしました(スペーサーやネジの取り付けをしないで基板がぶらぶらした状態)。見た目として完成できない、なおかつ動作もしない という「両方ダメ」なのを避けて、少なくとも動作することを目指しました。「動作確認への直行」!


▲太枠部分で示した設備的な固定(スペーサー)をすべて省いた。

これはたとえば、マラソン大会でほかの選手はみんなゴールしていて大会はもう終了して片づけしてる(記録はつかない)けど、自分はまだゴールしていなくてそれでも途中でやめずにゴールまで走り切ろうとする、そういう状況に似ています。もう合格(記録)は求めず、目的の1つである動作確認(ゴール)を目指したんです。

ちなみにその際に、「シャーシアース」というはんだ付け(上図黄色い太枠につながる一本の黒い配線)がありましたがこれも省きました。「シャーシアース」は機械使用の安全上は必要ですが回路の動作上は不要だからです。そういう「電子回路エンジニア」的な判断は我ながら良かったと思います。(エンジニアではなく、その端くれにもなっていませんが…)

大小基板の回路接続が終わり、目的の動作確認に到達! あきらめないことの価値を感じました。

地球温暖化対策もあきらめないほうが良いでしょう。

機械をコンセントに接続してスイッチをオンすると―――― …… !

LEDの数字表示がありません。無灯火。「9」を表示するはずなんですが。

ダメねえ

不要と思ったシャーシアースはやはり必要なのか? そう思って、はんだを省いたその配線を指でボディ(シャーシ)へ くっつけましたが変化なし。やはり不要なはずなのだ。

「あっ」と思い、ディップスイッチの未設定を発見しました。これを「9」に設定しなければいけません。(この回路ではディップスイッチのオンとオフを逆にしています。未設定による見た目のすべてオフは回路ではすべてオンになっており、2進4桁の全オンは10進で「15」ですよね。数字を表示するLEDは数字1桁の表示なので15は2桁だから表示できません。今74HC4511というIC(4本の配線による2進4桁のパターン(数値を表す)を、数字を表示するLED部品の点灯用パターン(点灯すべきLEDの位置を表す)へ変換してくれるIC)のデータシートを見たら、4桁全オンはBLANK(無灯火)と書いてありました)


▲赤い太枠のディップスイッチが未設定で、黄色い太枠のジャンパを取り付けていなかった。

しかし、ディップスイッチを「9」に設定しても何か様子がおかしい。

図の青い小さな部品が上に2つ並び、下に1個ありますが、私は動作確認はまともにできないと予想していたので保険として、青い部品のダイヤルは最初に規定の場所まで回しておきました。それだと試験の規定(規定の電圧)から外れる可能性があるので、ほんとに保険(プランB)なやり方ですが。それはともかく…

よく見ると、ジャンパ(レセプタクル)2個の取り付けをしていませんでした。

これは、機械の「動作モード/調整モード」を切り替えたり、設定の「分/秒」を切り替える、いわば「設定」の役割があるジャンパです。これがないと機械は、動作なのか調整なのかわからない状態で動作の様子がおかしくなる原因になっているかもしれません。

1個は取り付けしましたが、もう1個を取り付けようとしたとき!

「延長時間終了です!」と言われ、試験終了となりました。

私はバカ正直なのか、正しいのかわかりませんが、「そこでなんとか取り付けちゃう」ということをしません。ジャンパ 一個、ちょいと挿すだけなんですけどね。

動作確認が完了せず、残念! もしかしたら正常動作したかもしれないのに!

挿しちゃえばいいのに!

←思い出のジャンパピン(れせぷたくる)記念になるぞと思って取っておきました。(今思えばホームページの話題にはなりますが、記念にはなりません)

…?

というわけで実技試験はNGでした。

以上の機械の各写真は自宅で通し練習をしたときの写真です。これでも最上級のできばえの方の物と比べると「平凡なできばえ」と言えます。ほんとにできる方は、配線すべてが美しい曲線や、整然とした直線を描き整列されていて、非の打ちどころがなく、ひと目で美しいと感じるものになっています。


作業失敗の原因は何かを考えました。

まず、小基板の作成で配線がうまくいかないと勘違いした原因は、大基板の途中で「時間がない!」と気づいて急ぎ始めたことです。急ぐといろいろなミスを引き起こします。(あと、小基板の練習や配線の暗記が足りなかったというのも勘違いをした原因です)

そして、時間の余裕がなくなり急ぐことになった原因は、それまでの前半の作業で ”適度な急ぎの姿勢” がなく、まったりと作業していたことです。「自分はてきぱきと作業している」と勘違いしていました。

というわけで、情けないですが、全体の進み具合(時間)の管理がなかったことがおおもとの原因と言えそうです。「束線は何分で完成させるぞ。何分早い、何分遅い」とか「ボディは何分で完成させるぞ。何分早い、何分遅い」とか、試験中に管理していませんでした。てきぱきと作業しているように思えて油断してしまい、時間の遅れについてノーマークだったんです。遅れていると思えば即座にスピードを早めたり、多少の綺麗さを犠牲にする英断もできたはずです。それがなかった。

あと、試験日前、1か月ほど実技の練習をさぼっていた期間があったというのもあります。最近の体の不調や仕事の忙しさで練習しなかったという理由がありますが、言い訳かもしれません。でもお盆の休みに入ったとき それまでサボっていた練習を、急にたくさんやり始めたので仕事が忙しく、体が不調だったという理由は、確かにそうなのかもしれません。しかしこれは言い訳としてとらえておいたほうが良さそうです。理由さえあればやらない、という形にするとやれないでしょうから。体調が悪くてもやる人はいるし、仕事が忙しくてもやる人はいます。


それでも今回の成果は、

  • 失敗してもあきらめないことのすばらしさ(あきらめなかったから小基板完成!動作確認までこぎつけた!)を体験したこと。これは大きな成果だと思いました。
  • 小基板のようなユニバーサル基板(基板上にパターンがなく作業者が自由に針金(軟銅線というはだかの電気線)を はわせて作ることができる自由な基板)の作成スキルが上がったこと。趣味でユニバーサル基板を使うことがあるので…
  • 私の隣の席にいた見ず知らずの方は四苦八苦しつつも完成させたようで、後片付けをしているときに「完成したんですか?よかったですねえ」と思い切って話しかけたら(温和そうだったんで話しかけたら)いろいろお話を聞かせてもらえました。そういうのも良かったかな。
  • 失敗の原因がわかって次への課題がわかったこと

以上の4つです。

誰に言っているのかわかりませんが、ありがとうございました。

(※学科のほうの試験は自己採点では合格となっています)



試験勉強から解放されて
ほんとによかった!



ページ制作 homepage6047



ページの上端へ (もくじ開く)