日々の記録

ほどよく書いてきます。

MPL3115A2

2020-05-22 23:56:59 | プログラム

さて、随分前に使ったきり、そのままだった気圧計を再度使ってみる。
シリアルでデータを出力するが、受け取る側が適当だったので、Processingなるソフトでロガーを作って記録してみた。そして気がついたことがある。

MPL3115A2はフリップ実装すると光の影響を受ける。

縦軸は計算した標高、横軸は時間(h)である。

上記はある日一日の0時から日付が変わるちょっと前までのデータ。最後のほうにディップが見られるが、これはデスクランプの白熱灯を点灯した際の影響である。

60m位を指していた値が電気をつけてしばらくしたら、40mを下回っていて、そんな馬鹿なと思って思い立ったのが光の影響。当該のチップは表裏反転して実装しているため、おそらくシリコンウエハがむき出しに近い状態になっており、光の影響を受けていると気がついた。

朝6時少し前に日の出がきっとあったのだろう。10:30くらいには日が陰ったのだろうか。などなどを考えるとそれらしいグラフである。暗いときは安定だが、明るくなると怪しい。

 

センサーは暗い場所に設置するに限る。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

SEM-EDS出力ファイルの名前変更スクリプト

2020-03-22 22:52:42 | プログラム

電子顕微鏡には元素分析装置がついている場合がある。測定結果、特にマッピング分析というものをしたあと、個別のデータを画像で出力すると次のようになる。

sample1 IMG1.jpg
sample1 C K.jpg
sample1 O K.jpg
sample1 Si K.jpg
sample1 Cr K.jpg
sample1 Fe K.jpg
sample1 Ni K.jpg
sample1 Pt L.jpg

このままでもいいのだが、ファイル名の順番にソートすると原子番号がくちゃくちゃになってしまうので原子番号を付与したファイル名に付け替えたい。

ファイル名は

代表名␣元素記号␣X線.jpg

というようなルールになっている。代表名にスペースがあるかもしれないため、ファイルをスペースで区切って、元素記号に相当するところを2桁の原子番号+元素記号として名前を付け替える。

だいたい次のようなもので処理ができる。goo blogはプログラムコードを乗せると時々何らかの記号を省略するので画像とコードと両方を乗せることにする。

rename.vbsのようなファイルに下記の内容を記載し、保存。このvbsファイルにjpgファイルなどをまとめてドロップすれば名前を付け替えてくれる。

VBにはあるのだが、VBScriptにはformat関数がなかったので、原子番号2桁の処理は1000+原子番号の右側2文字を使うようにした。元素名前の配列は、原子番号をnとするとZ(n)が元素記号になるようあものを作って実施。Z(0)になにか入れないと行けないので、0を入れることにした。

IMGというものがつくのはマッピングエリアにおけるSEM像なのでファイル名でソートして一番上に来てほしいので00IMGとなるようにした。ファイル名を処理すると次のようになり、ファイル名ソートで原子番号ソートになってくれる。

sample1 00IMG1.jpg
sample1 06C K.jpg
sample1 08O K.jpg
sample1 14Si K.jpg
sample1 24Cr K.jpg
sample1 26Fe K.jpg
sample1 28Ni K.jpg
sample1 78Pt L.jpg

 

 

Option Explicit
Dim Z
Z = split("0,H,He,Li,Be,B,C,N,O,F,Ne,Na,Mg,Al,Si,P,S,Cl,Ar,K,Ca,Sc,Ti,V,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U",",")
 
Dim GetPathArray
Set GetPathArray = WScript.Arguments
 
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
Dim pt
Dim FileName
Dim FileObj
Dim SplitedFileName
Dim ElementName
Dim i
 
for each pt in GetPathArray
    FileName = objFSO.GetFileName(pt)
    set FileObj = objFSO.GetFile(pt)
    SplitedFileName = Split(FileName," ")
    ElementName = SplitedFileName(UBound(SplitedFileName)-1)
    For i = 1 to 92
        if ElementName = Z(i) then
            SplitedFilename(UBound(SplitedFileName)-1) = right(1000+i,2) & ElementName
            FileObj.Name = Join(SplitedFilename," ")
        end if
    next
    if left(SplitedFileName(UBound(SplitedFileName)),3)="IMG" then
        SplitedFileName(UBound(SplitedFileName))="00" & SplitedFileName(UBound(SplitedFileName))
        FileObj.Name = Join(SplitedFilename," ")
    end if
next
Set objFSO = Nothing
Set FileObj = Nothing
 
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

硬さ換算(JavaScript)

2019-06-03 01:38:20 | プログラム

鋼材硬さの相互計算を行う。入力はいろいろ選べる。引張強さは硬さじゃないけど参考に(単位はMPa)
・計算元の値は黄色
・範囲外はグレー
・入力セルがそもそも範囲外の場合は赤
というような出力を行う。

あくまでも参考である。

ソースを投稿しようとしたが、HTMLのタグなどが消えてしまう問題があり、投稿できない。どうしたらいいのだろうか。htmlのタグなどが結構消える。試行錯誤の結果、タグをタグと認識させないことが大事だとわかったので、 <>のタグを全角大文字にして投稿してみる。テキストエディタで<をに置換してからやってみるとできる、かな。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>硬さ換算テーブル</title>
    <style>
    body {
    "MS Pゴシック", sans-serif;
    }
    table{
        border-collapse: collapse;
    }
    table td{
        padding: 0px;
        border: 1px solid black;
        width: 100px;
        text-align: center;
    }
    input{
        padding:2px;
        width:78px;
        border:none;
        text-align: center;
        font-size:100%;
    }
    </style>
    <script>
    var DataList=[
        ['HV',85,940,85,90,95,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,245,250,255,260,265,270,275,280,285,290,295,300,310,320,330,340,350,360,370,380,390,400,410,420,430,440,450,460,470,480,490,500,510,520,530,540,550,560,570,580,590,600,610,620,630,640,650,660,670,680,690,700,720,740,760,780,800,820,840,860,880,900,920,940],
        ['HRA',60.7,85.6,,,,,,,,,,,,,,,,,,60.7,61.2,61.6,62,62.4,62.7,63.1,63.5,63.8,64.2,64.5,64.8,65.2,65.8,66.4,67,67.6,68.1,68.7,69.2,69.8,70.3,70.8,71.4,71.8,72.3,72.8,73.3,73.6,74.1,74.5,74.9,75.3,75.7,76.1,76.4,76.7,77,77.4,77.8,78,78.4,78.6,78.9,79.2,79.5,79.8,80,80.3,80.6,80.8,81.1,81.3,81.8,82.2,82.6,83,83.4,83.8,84.1,84.4,84.7,85,85.3,85.6],
        ['HRB',41,110,41,48,52,56.2,62.3,66.7,71.2,75,78.7,81.7,85,87.1,89.5,91.5,93.4,95,96.7,98.1,98.8,99.5,100.25,101,101.5,102,102.75,103.5,104,104.5,105,105.5,106.25,107,107.5,108,108.5,109,109.5,110,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],
        ['HRC',0,68,,,,,,,,,,0,3,6,8.5,11,13.4,15.7,18,20.3,21.3,22.2,23.1,24,24.8,25.6,26.4,27.1,27.8,28.5,29.2,29.8,31,32.2,33.3,34.4,35.5,36.6,37.7,38.8,39.8,40.8,41.8,42.7,43.6,44.5,45.3,46.1,46.9,47.7,48.4,49.1,49.8,50.5,51.1,51.7,52.3,53,53.6,54.1,54.7,55.2,55.7,56.3,56.8,57.3,57.8,58.3,58.8,59.2,59.7,60.1,61,61.8,62.5,63.3,64,64.7,65.3,65.9,66.4,67,67.5,68],
        ['HRD',40.3,76.9,,,,,,,,,,,,,,,,,,40.3,41.1,41.7,42.2,43.1,43.7,44.3,44.9,45.3,46,46.5,47.1,47.5,48.4,49.4,50.2,51.1,51.9,52.8,53.6,54.4,55.2,56,56.8,57.5,58.2,58.8,59.4,60.1,60.7,61.3,61.6,62.2,62.9,63.5,63.9,64.4,64.8,65.4,65.8,66.2,66.7,67,67.5,67.9,68.3,68.7,69,69.4,69.8,70.1,70.5,70.8,71.5,72.1,72.6,73.3,73.8,74.3,74.8,75.3,75.7,76.1,76.5,76.9],
        ['HR15N',69.6,93.2,,,,,,,,,,,,,,,,,,69.6,70.1,70.6,71.1,71.6,72.1,72.6,73,73.4,73.8,74.2,74.6,74.9,75.6,76.2,76.8,77.4,78,78.6,79.2,79.8,80.3,81,81.4,81.8,82.3,82.8,83.2,83.6,83.9,84.3,84.7,85,85.4,85.7,86,86.3,86.6,86.9,87.2,87.5,87.8,88,88.2,88.5,88.8,89,89.2,89.5,89.7,89.8,90.1,90.3,90.7,91,91.2,91.5,91.8,92.1,92.3,92.5,92.7,92.9,93,93.2],
        ['HR30N',41.7,84.4,,,,,,,,,,,,,,,,,,41.7,42.5,43.4,44.2,45,45.7,46.4,47.2,47.8,48.8,49,49.7,50.2,51.3,52.3,53.6,54.4,55.4,56.4,57.4,58.4,59.3,60.2,61.1,61.9,62.7,63.5,64.3,64.9,65.7,66.4,67.1,67.7,68.3,69,69.5,70,70.5,71.2,71.7,72.1,72.7,73.2,73.6,74.2,74.6,75.1,75.5,75.9,76.4,76.8,77.2,77.6,78.4,79.1,79.7,80.4,81.1,81.7,82.2,82.7,83.1,83.6,84,84.4],
        ['HR45N',19.9,75.4,,,,,,,,,,,,,,,,,,19.9,21.1,22.2,23.2,24.3,25.2,26.2,27.1,27.9,28.7,29.5,30.4,31.1,32.5,33.9,35.2,36.5,37.8,39.1,40.4,41.7,42.9,44.1,45.3,46.4,47.4,48.4,49.4,50.4,51.3,52.2,53.1,53.9,54.7,55.6,56.2,57,57.8,58.6,59.3,59.9,60.5,61.2,61.7,62.4,63,63.5,64.1,64.7,65.3,65.7,66.2,66.7,67.7,68.6,69.4,70.2,71,71.8,72.2,73.1,73.6,74.2,74.8,75.4],
        ['HS',16.3,98,,,,16.3,17.6,19.4,20.8,22.3,23.8,25.2,26.6,28,29.4,30.7,32,33.4,34.7,36,36.6,37.2,37.9,38.5,39.1,39.7,40.4,41,41.6,42.2,42.8,43.4,44.6,45.7,46.9,48.1,49.2,50.3,51.4,52.5,53.6,54.6,55.7,56.7,57.8,58.8,59.8,60.8,61.8,62.8,63.7,64.7,65.6,66.6,67.5,68.4,69.3,70.2,71.1,72,72.8,73.7,74.5,75.4,76.2,77,77.8,78.6,79.4,80.2,81,81.8,83.3,84.8,86.2,87.6,89,90.4,91.7,93.1,94.3,95.6,96.8,98],
        ['HBW',71,767,71,86,90,95,105,114,124,133,143,152,162,171,181,190,200,209,219,228,233,238,243,247,252,256,261,265,270,275,280,284,294,303,313,322,331,341,350,360,369,378,388,397,405,415,425,433,442,452,460,471,478,488,497,507,517,525,535,545,554,564,573,582,591,601,611,620,630,638,647,656,670,684,698,710,722,733,745,757,767,,,],
        ['TensileStrength',283,2055,283,299,314,330,361,390,425,455,490,515,545,580,605,635,670,695,730,765,780,795,805,825,840,855,875,890,905,915,935,950,980,1005,1035,1070,1095,1130,1170,1205,1240,1290,1330,1370,1410,1460,1495,1530,1570,1620,1660,1705,1750,1795,1825,1860,1905,1950,1985,2020,2055,,,,,,,,,,,,,,,,,,,,,,,]
    ];
    //データのフォーマットは
    //指標の名前、最小値、最大値、データ列(85HV~940HVに対応した値)
    //DataList[n][0]が名前、DataList[n][1]が最小値、Datalist[n][2]が最大値、DataList[n][3]~DataList[n][DataList[n].Length]がデータ

    function calc(){

    //    console.log(document.form.InputData.length);
    //    console.log(document.form.Output.length);
        var Input = document.form.InputData;

        var ErrorMessage = "";      //エラー出たときの記録。これがブランクなら、処理を継続する?どうする?
        var RnageOver = false;

        //入力された硬さが何かを調べる。複数入力には対応していない。
        var i;
        var HardnessIndex=-1;
        for(i=0; i<Input.length;i++){
            if(Input[i].value!=""){
                HardnessIndex=i;
                break;
            }
        }
        if(HardnessIndex==-1){
            ErrorMessage += "データが入力されていません\n";
            //ここで止めたいけど止められないので、else以下に続く
        }
        else{
            //ビッカース硬さ以外だったら一旦ビッカース硬さを求める。
            if(HardnessIndex!=0){
                //硬さの範囲が適正か調べる
                var InputValue = Input[HardnessIndex].value;
                var LowLimit = DataList[HardnessIndex][1];
                var HiLimit = DataList[HardnessIndex][2];
                if((LowLimit-InputValue)*(HiLimit-InputValue)<=0){
                    //範囲が適正だったら
                    for(i=3;i<DataList[HardnessIndex].length-1;i++){
                        if((DataList[HardnessIndex][i]-InputValue)*(DataList[HardnessIndex][i+1]-InputValue)<=0){
                            DataIndex = i;
                            console.log("data "+DataIndex + " is between " + DataList[HardnessIndex][DataIndex] + " and "+DataList[HardnessIndex][DataIndex+1]);
                            console.log("HV is around "+ DataList[0][DataIndex] + " to " + DataList[0][DataIndex+1]);
                            break;
                        }
                    }
                    var HV = InteriorDivision(DataList[HardnessIndex][DataIndex],DataList[0][DataIndex],DataList[HardnessIndex][DataIndex+1],DataList[0][DataIndex+1],InputValue);
                    Input[0].value = HV
                    console.log(HV);
                }
                else{
                    //範囲外だったら
                    ErrorMessage += "入力値が範囲外です\n";
                    RnageOver = true;
                    ;
                }
            }
            //ビッカースかた各種硬さを求める
        }
        HV=Input[0].value;
        //ここまでにビッカース硬さが求められているはず。
        console.log(ErrorMessage);
        var OutDataArray = new Array(DataList.length);
        OutDataArray[0]=HV;
        if(ErrorMessage==""){
            for(i=1;i<DataList.length;i++){
                //ビッカース以外も計算していく
                for(var j=3;j<DataList[0].length-1;j++){
                    if((DataList[0][j]-HV)*(DataList[0][j+1]-HV)<=0){
                        OutDataArray[i] = InteriorDivision(DataList[0][j],DataList[i][j],DataList[0][j+1],DataList[i][j+1],HV);
                        break;
                    }
                    //データ探し
                    ;

                }
                console.log(DataList[i][0] + "=" + OutDataArray[i]);
            }
        }

        console.log(ErrorMessage);0

        var table = document.getElementById("table");
        var row = table.insertRow(-1);
        var AddedCell;  
        AddedCell = row.insertCell(-1);
        AddedCell.innerHTML = "換算結果";
        for(i=0;i<11;i++){
            AddedCell = row.insertCell(-1);
            AddedCell.innerHTML = (OutDataArray[i]*1).toFixed(1);
            Input[i].value = "";    
            if(i==HardnessIndex){
                AddedCell.innerHTML = '<div style="background-color:#FFFFaa;width:100%">'+(OutDataArray[i]*1).toFixed(1)+'</div>';
                if(RnageOver){
                    AddedCell.innerHTML = '<div style="background-color:red;width:100%">範囲外</div>';
                }
            }
            if(AddedCell.innerHTML=="NaN"){
                AddedCell.innerHTML = '<div style="background-color:gray;width:100%">範囲外</div>';
            }
        }
    }
    function InteriorDivision(x1,y1,x2,y2,x){
        //内分点を求める関数。(x1,y2)から(x2,y2)に含まれる点xにおけるy座標を返す。計算上外分点でも返してしまうがとりあえず無視。
        var s = (x-x1)/(x2-x1);
        return s*y2+(1-s)*y1;
    }
    function enter(){
        if(window.event.keyCode==13){
            calc();
        }
    }
    </script>
  </head>
  <body>
鋼材の硬さの換算を行います。入力の枠のいずれかに数字を入れてEnterキーまたは変換ボタンを押してください。<br>
換算結果は表の下に都度追加されていきます。<br>
<br>
  <form name="form">
      <table id="table">
          <tbody>
            <tr>
              <td>硬さ</td>
              <td>HV</td>
              <td>HRA</td>
              <td>HRB</td>
              <td>HRC</td>
              <td>HRD</td>
              <td>HR15N</td>
              <td>HR30N</td>
              <td>HR45N</td>
              <td>HS</td>
              <td>HBW</td>
              <td>引張強度</td>
            </tr>
              <tr style="font-size:small;">
                <td>入出力範囲</td>
                <td>85-940</td>
                <td>61-85</td>
                <td>41-110</td>
                <td>10-68</td>
                <td>41-76</td>
                <td>70-93</td>
                <td>42-84</td>
                <td>20-75</td>
                <td>17-98</td>
                <td>71-767</td>
                <td>283-2055MPa</td>
              </tr>
              <tr>
                <td>入力</td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
                <td><input type="text" name="InputData" onkeypress="enter();"></td>
            </tr>
          </tbody>
      </table>
      <button type="button" onclick="calc();">計算</button>
</form><br>
計算はSAE J 417に基づき、HBWや引張強度はネットのデータから借用しています。あくまでも上記は換算結果であり、目安にとどめてください。
</body>
</html>

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

csvファイルを読み込んでグラフまで作成するマクロ(メモ)

2019-03-24 23:40:20 | プログラム

仕事ではcsvファイルに出力されたデータを同じような出力でまとめる必要がある場合がある。そのときにマクロが便利なのだが、グラフ領域を引き渡したらグラフを作ってくれるものができないかと考えていた。

調べると。Workbooks().sheets().ChartObject.Add()という方法でグラフのオブジェクトを作成してパラメータを設定していくような方法ができるらしいのでその方法で作ってみた。ChartObjectへの値設定のための引数が膨大になるので、GraphParamというものを作って、そこにいろいろな変数を放り込んでおいてグラフ作成サブルーチンを使うという方法をとった。

とりあえず仕事では使い物になっている程度のものはできているが、改造のために家でも同じようなものを作っておく。一部使わなくなったパラメータがあるがご愛嬌。

Option Explicit
Private Type GraphParam
    BookName As String 'グラフ作成対象のブック
    SheetIndex As Integer 'グラフ作成対象のワークシート番号
    SheetName As String 'グラフ作成対象のシート名
    DataStartRow As Long 'データ開始行番号
    TitleRow As Long 'データの凡例?に表示される名前のある行番号
    xPosition As Double 'グラフ左上の出力先x座標
    yPosition As Double '同y座標
    xDataCol As Long 'xy散布図を作るときのxデータの列番号
    yDataStartCol As Long '同yデータ開始列番号(複数データを許容する)
    yDataCount As Long 'yデータの個数(x, y1, y2,,, ynというように複数のデータを持つ散布図が作成できるようにしておく)
    Width As Double 'グラフの幅
    Height As Double 'グラフの高さ
    PlotAreaWidth As Double '多分使わない?
    PlotAreaLeft As Double '同上
End Type

Private Sub CommandButton1_Click()
Dim FileName As String
Dim Fn As Integer
Dim param1 As Double
Dim param2 As Double
Dim i As Long
Dim gp As GraphParam

FileName = Application.GetOpenFilename("csv file, *.csv", , "select a csv file", , False)
If FileName = "False" Then Exit Sub

Workbooks.Add
Fn = FreeFile
i = 1
With ActiveWorkbook.ActiveSheet
    .Cells(i, 2) = "param1"
    .Cells(i, 3) = "param2"
    i = i + 1
    Open FileName For Input As #Fn
        Do Until EOF(Fn)
            Input #Fn, param1, param2
            .Cells(i, 2) = param1
            .Cells(i, 3) = param2
            i = i + 1
        Loop
    Close #Fn
   
End With

gp.BookName = ActiveWorkbook.Name
gp.SheetIndex = ActiveSheet.Index

gp.TitleRow = 1
gp.xDataCol = 2
gp.yDataStartCol = 3
gp.yDataCount = 1

gp.DataStartRow = 2

gp.xPosition = 30
gp.yPosition = 30
gp.Width = 300
gp.Height = 200

Call CreatGraph(gp)
End Sub

Private Sub CreatGraph(GraphParameter As GraphParam)
Dim oGraph As ChartObject
Dim lRows As Long
Dim i As Long
Dim NameOfSheet As String
Dim DataRangeX As String
Dim DataRangeY() As String
Dim DataRangeName() As String
Dim DataRangeCol As Integer

With GraphParameter
    Set oGraph = Workbooks(.BookName).Sheets(.SheetIndex).ChartObjects.Add(.xPosition, .yPosition, .Width, .Height)
    DataRangeCol = .xDataCol
    lRows = Workbooks(.BookName).Sheets(.SheetIndex).Cells(.DataStartRow, .yDataStartCol).End(xlDown).Row
    NameOfSheet = Trim(Workbooks(.BookName).Sheets(.SheetIndex).Name)
    DataRangeX = "=" & NameOfSheet & "!R" & Trim(Str(.DataStartRow)) & "C" & Trim(Str(DataRangeCol)) & ":R" & Trim(Str(lRows)) & "C" & Trim(Str(DataRangeCol))
    
    ReDim Preserve DataRangeY(.yDataCount)
    ReDim Preserve DataRangeName(.yDataCount)
    
    For i = 1 To .yDataCount
        DataRangeCol = .yDataStartCol + i - 1
        DataRangeY(i) = "=" & NameOfSheet & "!R" & Trim(Str(.DataStartRow)) & "C" & Trim(Str(DataRangeCol)) & ":R" & Trim(Str(lRows)) & "C" & Trim(Str(DataRangeCol))
        DataRangeName(i) = "=" & NameOfSheet & "!R" & Trim(Str(.TitleRow)) & "C" & Trim(Str(DataRangeCol))
    Next i
End With

With oGraph.Chart

    For i = 1 To GraphParameter.yDataCount
        .SeriesCollection.NewSeries
        With .SeriesCollection(i)
            .ChartType = xlXYScatterLinesNoMarkers
            .XValues = DataRangeX
            .Values = DataRangeY(i)
            .Name = DataRangeName(i)
            
            
        End With
    Next i

End With
Set oGraph = Nothing

End Sub
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

keyence VHX画像データから測定値を吸い上げる

2018-06-02 22:31:35 | プログラム

キーエンスのVHXというデジタルマイクロスコープをよく使っているが、寸法計測した値をたくさん処理するときに面倒があった。

csvファイルを保存してそのデータを読み込む。→面倒くさい

しかし、VHXの画面上でjpg画像を見るとデータありみたいなアイコンになるので、jpgファイルにデータが埋め込まれているはずだと考えた。

自動でまとめまでできれば、jpgだけ持って帰って処理すればいいので楽になる。

バイナリデータを見る限り、末尾に測定値が埋め込まれているようだ。しかもプレーンテキストで。ラッキー。
では、これらを取り出して必要なデータを取り出せばcsvファイル出力の一手間が省略できる。

[メイン]以下のデータだけで済むだろうから、そこを取り出す。おそらくバイナリを比較して[ メイン ]の文字を探して行けばいいが、作り始めたときはjpgデータ無いに文字列と同じバイナリ列があるかもと思ってjpgファイルのFFD9(0xFF 0xD9)のデータを探したあとに文字列を探すことにした。

jpgファイルは、0xFFが特徴的な識別子になっていて、jpg構造の最後には0xFF 0xD9の2バイト並びでファイルが終了する。しかし、サムネイルを含んでいる場合はサムネイルもまたjpg構造を持っているので、ファイルの最後の0xFF 0xD9を探し、それ以降のテキストを比較することにした。

 

command button1,2は上のボタンです。出力行が21だったり、変数固定の部分がいくらかあります。赤文字は上の表の当該セルなので場所を変えたらソースも変えてください。

Const StartCol = 20
Option Explicit
Private Sub CommandButton1_Click()
Dim FileName
Dim FileNames

FileNames = Application.GetOpenFilename("VHX jpg files,*.jpg", , , , True)
If TypeName(FileNames) <> "Variant()" Then
    Exit Sub
End If

For Each FileName In FileNames
    Call ConvertVHXimageFile(FileName, ConvertFileName(FileName))
    
Next FileName

MsgBox "done"

End Sub

Function ConvertFileName(VHXimageFileName) As String
    'ファイル名の拡張子をtxtにするだけ。関数にせんでもよかったな。
    ConvertFileName = Left(VHXimageFileName, InStrRev(VHXimageFileName, ".")) & "csv"
End Function

Sub ConvertVHXimageFile(VHXimageFileName, OutputTextFileName As String)

Dim Fn As Integer   'ファイル入出力番号として
Dim i As Long       'どっかで使う
Dim j As Long

Dim EOBinary As Long    'jpgのバイナリが終わる位置
Dim TxtStart As Long    'テキスト開始位置
Dim VHXimage() As Byte  'jpg画像のバイナリを入れる配列

'ファイルを開いて配列に入れる
Fn = FreeFile
Open VHXimageFileName For Binary As #Fn
    ReDim VHXimage(LOF(Fn))
    Get #Fn, , VHXimage
Close #Fn

'jpgデータ終わりを示すFFD9を探す
'なぜかVHXの画像には複数のFFD9があるから最後まで探す
For i = 0 To UBound(VHXimage) - 1
    If VHXimage(i) = &HFF And VHXimage(i + 1) = &HD9 Then
        EOBinary = i
    End If
Next i

'[ メイン ]の文字列を探す
Dim HeaderOfText() As Byte
HeaderOfText = StrConv("""[ メイン ]""", vbFromUnicode) '文字列をバイナリ配列にしておく
Dim SizeOfHeader As Long
    SizeOfHeader = UBound(HeaderOfText)

'データ探し
For i = EOBinary To UBound(VHXimage) - SizeOfHeader
    For j = 0 To SizeOfHeader
        If VHXimage(i + j) <> HeaderOfText(j) Then '文字列が違ったらすっ飛ばし
            Exit For
        End If
        
        If j = 9 Then       '文字列合致が9回?連続したら本物 ■9回じゃなくて、変数にできるやろ
            TxtStart = i    'そこがtextの開始行だ!
            Exit For
        End If
    Next j
Next i

'出力ファイルの準備。
Dim OutTxt() As Byte
'サイズの定義
ReDim OutTxt(UBound(VHXimage) - TxtStart)

For i = TxtStart To UBound(VHXimage)
    OutTxt(i - TxtStart) = VHXimage(i)
Next i

'ファイル出力
Fn = FreeFile
Open OutputTextFileName For Binary As #Fn
    For i = 0 To UBound(OutTxt) - 1
        Put #Fn, , OutTxt(i)
    Next i
Close #Fn
End Sub
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

microSDカード転送速度

2018-04-13 20:58:18 | プログラム

Toshiba Exceria 64GB

-----------------------------------------------------------------------
CrystalDiskMark 6.0.0 x64 (UWP) (C) 2007-2017 hiyohiyo
Crystal Dew World : https://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes

Sequential Read (Q= 32,T= 1) : 90.231 MB/s
Sequential Write (Q= 32,T= 1) : 23.724 MB/s
Random Read 4KiB (Q= 8,T= 8) : 6.073 MB/s [ 1482.7 IOPS]
Random Write 4KiB (Q= 8,T= 8) : 0.471 MB/s [ 115.0 IOPS]
Random Read 4KiB (Q= 32,T= 1) : 5.988 MB/s [ 1461.9 IOPS]
Random Write 4KiB (Q= 32,T= 1) : 0.469 MB/s [ 114.5 IOPS]
Random Read 4KiB (Q= 1,T= 1) : 5.213 MB/s [ 1272.7 IOPS]
Random Write 4KiB (Q= 1,T= 1) : 0.460 MB/s [ 112.3 IOPS]

Test : 100 MiB [I: 7.8% (4.5/57.7 GiB)] (x1) [Interval=5 sec]
Date : 2018/04/13 20:55:16
OS : Windows 10 [10.0 Build 16299] (x64)

 

Sandisk Ultra A1 128GB

-----------------------------------------------------------------------
CrystalDiskMark 6.0.0 x64 (UWP) (C) 2007-2017 hiyohiyo
Crystal Dew World : https://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 bytes/s [SATA/600 = 600,000,000 bytes/s]
* KB = 1000 bytes, KiB = 1024 bytes

Sequential Read (Q= 32,T= 1) : 92.303 MB/s
Sequential Write (Q= 32,T= 1) : 52.746 MB/s
Random Read 4KiB (Q= 8,T= 8) : 6.875 MB/s [ 1678.5 IOPS]
Random Write 4KiB (Q= 8,T= 8) : 2.752 MB/s [ 671.9 IOPS]
Random Read 4KiB (Q= 32,T= 1) : 6.833 MB/s [ 1668.2 IOPS]
Random Write 4KiB (Q= 32,T= 1) : 2.667 MB/s [ 651.1 IOPS]
Random Read 4KiB (Q= 1,T= 1) : 6.761 MB/s [ 1650.6 IOPS]
Random Write 4KiB (Q= 1,T= 1) : 2.541 MB/s [ 620.4 IOPS]

Test : 100 MiB [I: 30.3% (36.0/119.1 GiB)] (x1) [Interval=5 sec]
Date : 2018/04/13 20:59:33
OS : Windows 10 [10.0 Build 16299] (x64)

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Rigaku XRDのrasファイル処理

2018-01-28 22:41:26 | プログラム

RigakuのXRDを使っているが、出力されるrasファイルの中身が実際にはただのテキストファイルなので、それを読み込んでまとめてしまうマクロを作ろうと思っている。
解析は専用の解析ソフトがあるのだが、なんとなく画面キャプチャではなく、グラフはエクセルで書いて出そうなんて思っている。

rasファイルのフォーマットは

*RAS_DATA_START
*RAS_HEADER_START
*DISP_FMT_X "%.2f"
*DISP_FMT_Y "%.0f"

~中略~

*MEAS_SCAN_UNIT_X "deg"
*MEAS_SCAN_UNIT_Y "counts"
*RAS_HEADER_END
*RAS_INT_START
30.0000 877.0000 1.0000
30.0100 911.0000 1.0000

~測定データが続く~

79.9900 189.0000 1.0000
80.0000 189.0000 1.0000
*RAS_INT_END
*RAS_DATA_END

 

というようなファイル形式となっている。

測定データ以外の行は*で始まるので、これ以外の行の数字を処理していく。

データの並びは、

2θ 検出X線強度 アッテネータ減衰率

の並びであるので、出力としては

2θ, 検出X線強度×アッテネータ減衰率を出力すればよい。

 

 作ったコードはこんな感じ。5000点あるデータを12個処理するのに5秒くらいかかる鈍足だが、手でやるよりは早い。

Private Sub CommandButton1_Click()
Dim TwoTheta() As Double
Dim XrayIntensity() As Double
Dim FileName
Dim FileNames
Dim i As Long
Dim j As Long
Dim T1 As Double
Dim T2 As Double

ChDrive ThisWorkbook.Path


'複数のファイルを開く
FileNames = Application.GetOpenFilename("RAS File,*.ras", , , , True)
'キャンセルのとき、Booleanが帰ってくるので、Variant()のときだけ処理実行
If TypeName(FileNames) <> "Variant()" Then
    Exit Sub
End If

Application.ScreenUpdating = False

T1 = Timer()

'マクロに値を出力したくないので新しいワークブックを作る
Workbooks.Add
With ActiveWorkbook.Sheets(1)

j = 2

For Each FileName In FileNames  'ファイル名ごとに中身を調べていく
    
    Call LoadRasFile(FileName, TwoTheta(), XrayIntensity)
        .Cells(2, j + 1) = GetFileNameOnly(FileName)    'ファイル名を出力しておく
        For i = 1 To UBound(TwoTheta())                 '値の出力
            .Cells(i + 2, j) = TwoTheta(i)
            .Cells(i + 2, j + 1) = XrayIntensity(i)
        Next i
    j = j + 2
Next FileName
End With

T2 = Timer()
Application.ScreenUpdating = True
Application.StatusBar = "処理時間=" & Format(T2 - T1, "0.00") & "[s]"
  
End Sub
Function GetFileNameOnly(FullPath) As String
'ファイルのフルパスからファイル名のみを取り出す
GetFileNameOnly = Right(FullPath, Len(FullPath) - InStrRev(FullPath, "\"))  '最後の\より右側を取り出す
GetFileNameOnly = Left(GetFileNameOnly, InStrRev(GetFileNameOnly, ".") - 1)    '拡張子のピリオドで切り落とす

End Function

Sub LoadRasFile(FileName, ByRef TwoTheta() As Double, ByRef XrayIntensity() As Double)
'rasファイルの中身を読み込んでくる。TwoThetaに2θを、XrayIntensityにX線強度を格納する。
Dim TempString As String
Dim SplitedTempString() As String
Dim Fn As Integer
Dim i As Long
i = 1

Fn = FreeFile
Open FileName For Input As #Fn
    
    '■ヘッダ読み飛ばし
    Do
        Line Input #Fn, TempString
    Loop While Left(TempString, 1) = "*"
    
    
    '■データ読み込み
    Do
        SplitedTempString = Split(TempString, " ")
           
        ReDim Preserve TwoTheta(i)
        ReDim Preserve XrayIntensity(i)
        
        TwoTheta(i) = Val(SplitedTempString(0))
        XrayIntensity(i) = Val(SplitedTempString(1)) * Val(SplitedTempString(2))
        
        Line Input #Fn, TempString
        SplitedTempString = Split(TempString, " ")
                
        i = i + 1
        
    Loop Until Left(TempString, 1) = "*"
    
Close Fn
End Sub
コメント (1)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

画像一覧HTML作成のスクリプト

2017-01-23 00:12:12 | プログラム
画像を表にして整理するのに便利なので作ってみた。
観察データを横並びに確認したいときなど、Excelに貼るよりも便利だから。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- 20170121 -->
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>画像サムネイル一覧テーブル作成</title>
<style type="text/css">
    .param{
        width:100px;
    }
</style>
<script type="text/javascript">
function MakeTable(){
    var StartTime = new Date();
    var FileNameList = document.form.FileList;
    var htmlOut = document.form.HTMLOut;
    var note = document.form.Note;
    var ChSet = document.form.chrSet.value;
    var ImgDir = document.form.ImgDir.value;
    var LinkDir = document.form.LinkDir.value;
    var ColNum = document.form.TableCol.value;
    var TempText = "";

    FileNameList.value = FileNameList.value.replace(/\r\n/g, "\n");
    FileNameList.value = FileNameList.value.replace(/[\n]+$/g,"").trim(); //最後の改行コード処理
    
    if(FileNameList.value.length===0){
        alert("Input File Names");
    }
    
    else{
        var FileNameArray = FileNameList.value.split("\n");
        TempText += '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n';
        TempText += '<html>\n<head>\n<meta content="text/html; charset='+ChSet+'" http-equiv="Content-Type">\n';
        TempText += '<style type="text/css">\ntable{\n';
        TempText += '  border-collapse:collapse;\n}';
        TempText += '\ntd{\n';
        TempText += '  border:1px black solid;\n';
        TempText += '  text-align:center;\n}';
        TempText += '\n';
        TempText += '<\/style>\n';
        TempText += '<title>Image Table<\/title>\n<\/head>\n<body>\n\n<table>\n';
        var i = 0;
        var j = 1;
        TempText += '  <tr><td><\/td><td colspan="' + ColNum + '">Image(s)<\/td><\/tr>\n  <tr>\n    <td>Index' + j++ + '<\/td>\n';
        for(i=0;i<FileNameArray.length;i++){
            if((i % ColNum ===0) && (i !== 0 )){
                TempText += '  <\/tr>\n  <tr>\n    <td>Index' + j++ + '<\/td>\n';
            }
        TempText += '    <td><img alt="" src="' + ImgDir + FileNameArray[i] + '" title="' + FileNameArray[i] + '"><\/td>\n';
        }
        if(FileNameArray.length % ColNum !==0){
            for(i=(FileNameArray.length % ColNum); i<ColNum ; i++){
                TempText += '    <td><\/td>\n';
            }
        }
    }
    TempText += '  <\/tr>\n<\/table>\n<\/body>\n<\/html>';
    
    htmlOut.value = TempText;
    
    var StopTime = new Date();
    var dT=StopTime-StartTime;
    note.value = "処理時間:" + dT + "[ms]";

}
</script>
</head>
<body>
	画像サムネイル一覧テーブル作成<br>
	<form name="form" action="post">
		<input type="text" name="ImgDir" value="small/" class="param"><span>:dir of the thumbnail images</span><br>
		<input type="text" name="LinkDir" value="org/" class="param"><span>:dir of the images</span><br>
		<input type="text" name="TableCol" value="11" class="param"><span>:number of columns</span><br>
		<input type="text" name="chrSet" value="sjis" class="param"><span>:charactor set</span><br>
		<textarea name="FileList" cols="40" rows="15">
                </textarea>
		<textarea name="HTMLOut" cols="120" rows="15">HTML output</textarea><br>
		<input type="button" value="Generate" onclick="MakeTable()"><br>
		<textarea name="Note" cols="50" rows="2">Log</textarea><br>
	</form>

</body>

</html>

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

JavaScriptを使った文字列連結を使ってファイル名一覧、コマンド一覧などを作成する。

2017-01-09 19:27:58 | プログラム

仕事で網羅的な観察データを作成するとき、ある程度規則的なファイル名になることがある。
そのファイル名を一覧表にするのにファイル名から一覧表を作ればいいのだが、時折サンプルがなかったりと欠落がある場合がある。
そんな時のために網羅的なデータの一覧を作成しておいて、表を作っておくと便利じゃないかと思って作ってみた。

左から順番に文字列を網羅的に連結していくだけ。毎回プログラムっていうのも面倒臭いので、こうしたものがあると多少は便利になるかなと。

文字列を連結するだけなので、フォルダ作成のコマンドを大量に作るという用途にも使えるのでは無いだろうか。

 

連結したい文字列を増やす場合はhtmlソースの<textarea name="List" cols="15" rows="10">List[n]</textarea>を増やせばよい。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>文字列結合</title>
<script type="text/javascript">
    function MakeNameList(){
    var StartTime = new Date();
    var NameListArray = new Array();
    var textOut = document.form.FileNameOutput;

    //配列の格納、末尾の改行はreplaceで削除しておく。
    for(i=0;i<document.form.List.length;i++){
        NameListArray[i] = document.form.List[i].value.replace(/\n+$/g,"").split("\n");
    }

    var TempText = "";
    var tempArray = new Array();

    //配列に構造があるが、データは無い、とするため、""のブランクを入れておく。    
    tempArray[0]="";
    for(var k=0, lenk = NameListArray.length;k<lenk;k++){
        TempText = "";
        for(var i=0, leni = tempArray.length;i<leni;i++){
            var lenj = NameListArray[k].length;
            for(var j=0, lenj=NameListArray[k].length;j<lenj;j++){
                TempText += tempArray[i] + NameListArray[k][j] + "\n";
            }
        }
        tempArray = TempText.replace(/\n+$/g,"").split("\n");
    }
    textOut.value = TempText;
    TempText = "";

    var StopTime = new Date();
    var dT = StopTime - StartTime;
    document.form.Note.value = tempArray.length + "データ\n" + "処理時間" + dT + "[ms]"; 
}
</script>
</head>

<body>
<form name="form" action="post">
<textarea name="List" cols="15" rows="10">List1</textarea>
<textarea name="List" cols="15" rows="10">List2</textarea>
<textarea name="List" cols="15" rows="10">List3</textarea>
<textarea name="List" cols="15" rows="10">List4</textarea>
<textarea name="List" cols="15" rows="10">List5</textarea>
<textarea name="List" cols="15" rows="10">List6</textarea>
<textarea name="List" cols="15" rows="10">List7</textarea>
<br>
<textarea name="FileNameOutput" cols="125" rows="10">output</textarea><br>
<textarea name="Note" cols="50" rows="2">ログ</textarea><br>
<input type="button" value="Generate" onclick="MakeNameList()"><br>
</form>
</body>

</html>
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

バッチファイルでファイル名の一部を削除する

2015-11-03 18:20:52 | プログラム

備忘録。以下のバッチファイルで「キーワード」の文字列をファイル名から削除できる。
DSC_0000.jpgから、DSC_を削除したり、ソフトが連続して出力するファイル名からある文字列を策s所し

setlocal enabledelayedexpansion
cd /d %~dp0
set keyword=キーワード
for /f "tokens=*" %%i in ('dir /b ^| findstr /i "%keyword%"') do (
set a=%%i
ren "!a!" "!a:%keyword%=!"
)
pause

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

renameコマンドの処理(備忘録)

2014-10-18 17:12:14 | プログラム

Webカメラを使って連続写真を撮っていて動画にしようなどともくろんでいる。
しかしながら現在インターネットから手に入れたフリーソフトが画像を記録すると、ファイル名のフォーマットが

yyyymmddhmmss.jpg

になっている。hourがhhじゃないので、名前の順にソートするとおかしくなるので、更新日時の順番にソートしなくてはならない。まずコマンドプロンプトで

dir /b /od > _dir.txt

と入力してファイル名を_dir.txtファイルに入れる。テキストファイルの先頭のアンダーバーはソートしたときに一番上に来るようにするのが目的なので、別に無くてもいい。
次に、ファイル名を順番に名前変更するのだが、今までエクセルを使っていたのだが、以下のJavaScriptコードで実行することにした。ダミーデータでの試験ではうまく言っているようだ。 

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metacontent="text/html; charset=utf-8"http-equiv="Content-Type">
<title>Make Rename Command</title>
<script type="text/javascript">
function MakeRenameCommand(){
    var StartTime = new Date();
    var textIn = document.form.TextIn;
    var textOut = document.form.TextOut;
    textOut.value="";
    var note = document.form.Note;
    var FnArray = textIn.value.split("\n");
    var inIndex=0;
    var outIndex=1;
    for(inIndex=0;inIndex<FnArray.length;inIndex++){
        if(FnArray[inIndex].slice(-4)===".jpg" || FnArray[inIndex].slice(-4)===".JPG"){
            textOut.value += 'rename "' + FnArray[inIndex] + '" "' + ('0000'+outIndex).slice(-4) + '.jpg"\n';
            outIndex++;
        }
    }
    var StopTime = new Date();
    var dT = StopTime - StartTime;
    note.value = outIndex + "files\n";
    note.value += "it took " + dT/1000 + "sec\n";
}
</script>
</head>
<body>
    <formname="form"action="post">
        <textareaname="TextIn"cols="50"rows="20"></textarea>
        <textareaname="TextOut"cols="50"rows="20"></textarea><br>
        <inputtype="button"value="Make Rename commands"onclick="MakeRenameCommand()"><br>
        <textareaname="Note"cols="50"rows="2"></textarea><br>

    </form>
</body>
</html>

4000行弱のデータを処理させたときの速度だが、ChromeとFirefoxは許容できるレベル。
Google Chromeは1.8秒
Firefox 2.6秒
IE11 31秒
インターネットエクスプローラが劇的に遅い。。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

備忘録(シンタックスハイライト, Syntax Highlight)

2014-05-01 13:34:06 | プログラム

ソースコードをそのまま載せるとき、<などを変換してくれる。
http://sei-street.sakura.ne.jp/page/doujin/site/doc/tool_text2html/index.html

 

きれいに見せたいときは次で変換かな。文字数がブログのリミットに迫るから厳しい時もあるけど。
http://hilite.me/

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void Start_ADC(void)	/*ADC変換を開始する。自動トリガでADC1の値を読み込み続ける。プログラムからはADCを読めばよい*/
{
	//10bit分解能用ルーチン ADCは連続で動作させる
	//デジタル入出力からの切り離し
	DIDR0
	= (0<<ADC0D)	//ADC0ピンの切り離し。しかし、ADC0はリセット端子になってるから設定しちゃダメ
	| (1<<ADC1D)	//同ADC1, PB2
	| (0<<ADC2D)	//同ADC2, PB4
	| (0<<ADC3D);	//同ADC3, PB3

	ADMUX
	= (0<<REFS0)	//Reference: 0でVCC参照, 1で1.1V内部電圧源
	| (0<<ADLAR)	//ADC Left Adjust Result: 1にセットすると左詰で結果を出してくる 
	| (1);			//ADMUX1, ADMUX0で入力チャンネルを選べる 00から11までADC0からADC3まで対応 今はADC1を使う

	ADCSRA
	= (1<<ADEN)	//ADC enable
	| (1<<ADSC)	//ADC Start Conversion 1にすると変換開始
	| (1<<ADATE)	//ADC Auto Trigger Enable (for Continuous Conversion)
	| (0<<ADIF)	//ADC Interrupt Flag 変換完了すると1になるらしい
	| (0<<ADIE)	//ADC Interrupt Enable 変換完了したときに割り込み許可
	| (0b101);		//Clock Division: ADコンバータはクロック50-200kHzで性能がよい
	//分周は0のとき2、それ以上の時2^n分周。クロック4.8MHzのとき32分周(101)で150kHz。
	//ADCは起動時にアナログ回路リセットが入るので変換に25クロック(167us)必要
	//以降連続変換で回せば13クロックサイクル(87us)で変換完了→87us以内にADC読みに行くと前の値と同じってことになる

}
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Nikon DSLR IR Remote (ATTiny13A)

2013-08-16 20:24:08 | プログラム
定期的な撮影のため、マイコンからニコンのDSLR(デジタル一眼レフ)のリモコン信号を出すものを作った。デバイスはATTiny13Aです。8pinの安いやつ。
内蔵RC発信器を使うので、時間間隔は割といい加減だが、そこはご愛敬。
Time Lapseの撮影とか、連続的に星の写真を撮ることを目的としているので、連続的にシャッター操作ができたらいいのだ。

なお、運用して思ったが、夜間30秒の露光をしてどんどん撮影していくような場合、1秒ごとにリモコンコマンドを送るようにしておけば良いことに気がついた。
撮影終了後1秒以内に撮影コマンドがやってくるので、ほぼ連続的な動作が出来る。

このリモコンの時間設定を行う場合は、きっと昼間の連続撮影だろうな。

しかしソースコードを載せるのは面倒くさいな。

/*
 * _20130716_Nikon_IR_Remote.c
 *
 * Created: 2013/07/16 22:53:07
 *  Author: mako
*
 *          ATTiny13A
 *          +--------+
 *  -Reset ++        ++ Vcc
 *          |        |
 *     PB3 ++        ++ PB2
 *          |        |
 *     PB4 ++        ++ PB1 for IR LED output
 *          |        |
 *     GND ++        ++ PB0
 *          +--------+
 *
*
* PB1 --- 270ohm --- IR LED---GND // I think it work WITHOUT resistor.
* 4ch DIP switch or Rotary encoder(comprementary) connects PB0,PB2-PB4 to GND.
*
 */
 

#define F_CPU 1200000 //正確にしたい場合、微調節必要だが、そもそも内蔵RCクロックなのでアテにはならない
#defineSignalTime 100 //信号間隔を後でキャンセルするために設定

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
       
unsigned char IntervalStatus;
        DDRB  
=0b00010;               //Set PB1 for output, PB0,PB2-PB5 for input
        PORTB
=0b11101;                //Pull Up PB0, PB2-PB5 with internal resister
        // note DDR[Port][Number]=0 AND PORT[Port][Number]=1 -> Internal resistor pull up
       

        TCCR0A
=0b00000011;    //start counter prescaler 1/1
         // (0<

        OCR0A
=31;  // set duration : 31 count takes 31/1.2MHz = 25.8us nealy equal to 26.3us (38kHz)
        OCR0B
=10;  // set duty about 1/3

       
while(1)
       
{
               //Start Sending Shutter Command for Nikon DSLR
               //TCCR0Aの5bitの1/0で出力on/offさせている。タイマーは回しっぱなしで出力するかどうかを選択。
               //DDRDなどで制御してもいいかもしれない。
                TCCR0A
=0b100011;              _delay_us(2000);
                TCCR0A
=0b000011;              _delay_us(27850);
                TCCR0A
=0b100011;              _delay_us(  390);
                TCCR0A
=0b000011;              _delay_us(1580);
                TCCR0A
=0b100011;              _delay_us(  410);
                TCCR0A
=0b000011;              _delay_us(3580);
                TCCR0A
=0b100011;              _delay_us(  400);
                TCCR0A
=0b000011;              _delay_us(63200);
               
//Total 99.4ms

               
IntervalStatus=(((PINB & 0b11101)+1)>>1)^0b1111;       //Pinの入力は反転。pull upで
                //1加算することで、0b11101の配列が0b11110になる。そして、1ビットシフトし、0b1111とXOR演算し、
                //コンプリメンタリーのスイッチの状態を読み込める

                 //以下一行にif文を入れてしまったので、少々わかりにくいかもしれないが、ひたすら入力ピンに合わせてひたすら信号間隔を決めるだけ
                //なお、待ち時間が長いときに設定変更する場合、リセット端子が便利なので、リセットスイッチor電源スイッチを活用しよう

                 //時間間隔は必要に応じて変更
                if(IntervalStatus ==   0)  {_delay_ms(  1000-SignalTime);}  //Inteval for 1sec
               
if(IntervalStatus ==   1)  {_delay_ms(  2000-SignalTime);}  //Inteval for 2sec
               
if(IntervalStatus ==   2)  {_delay_ms(  3000-SignalTime);}  //Inteval for 3sec
               
if(IntervalStatus ==   3)  {_delay_ms(  4000-SignalTime);}  //Inteval for 4sec
               
if(IntervalStatus ==   4)  {_delay_ms(  5000-SignalTime);}  //Inteval for 5sec
               
if(IntervalStatus ==   5)  {_delay_ms(10000-SignalTime);}  //Inteval for 10sec
               
if(IntervalStatus ==   6)  {_delay_ms(15000-SignalTime);}  //Inteval for 15sec
               
if(IntervalStatus ==   7)  {_delay_ms(20000-SignalTime);}  //Inteval for 20sec
               
if(IntervalStatus ==   8)  {_delay_ms(25000-SignalTime);}  //Inteval for 25sec
               
if(IntervalStatus ==   9)  {_delay_ms(30000-SignalTime);}  //Inteval for 30sec
               
if(IntervalStatus ==  10)  {_delay_ms(45000-SignalTime);}  //Inteval for 45sec
               
if(IntervalStatus ==  11)  {_delay_ms(60000-SignalTime);}  //Inteval for 1min
               
if(IntervalStatus ==  12)  {_delay_ms(120000-SignalTime);}  //Inteval for 2min
               
if(IntervalStatus ==  13)  {_delay_ms(180000-SignalTime);}  //Inteval for 3min
               
if(IntervalStatus ==  14)  {_delay_ms(240000-SignalTime);}  //Inteval for 4min
               
if(IntervalStatus ==  15)  {_delay_ms(   200-SignalTime);}    //when open for testing.
 
       
}
}
コメント (2)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

測定器制御

2012-02-02 23:25:43 | プログラム
会社でいろいろな測定をするが、測定ソフトに不満を持つことがある。
汎用の測定器を使っていて、さらにユーザーがどんな測定をするのかわからないから仕方がない部分がある。

しかしだ、不満をそのまま残しておくのもアレなので、制御ソフトを作ってしまおうと思ったのだ。

しかしプログラミング言語がない。しかし、MS Officeなら入っている。
測定器は当然のようにGPIB経由で制御。

いける。Excel VBAから装置の制御が可能だ。

というわけで作成開始したわけであります。VBAでも何とかなるもんだね。Office2010なんだけど、すごく使いづらい・・・^^;
VBAはVB6.0形式のままで助かった。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

オイル交換

2007-11-16 02:18:32 | プログラム
オイル交換をした。久しぶりのオイル交換なので、ビクビク・・・しなかったな。

とりあえずドレンボルト開いてオイルを抜く。おおっ、黒いぜ。

今回はオイルフィルターも交換してみるのだが・・・なにやら鉄粉が多いような気が!?

今回は久しぶりにフィルター周りのパッキンも交換しました。Oリングが変形してたよ。オイルフィルターにOリングついてくるんだけどなかなか交換が面倒くさいから交換しなかったのだが、今回は交換しました。

まあ、いいや。フィルターの磁石に引っかかっているということはエンジンの中に残っていないということだ。機械部品の数から考えたら大した量じゃないような気もするけど、どうなんだろうな。今回はオイルフィルターの中の磁石まで観察したから気になる程度の鉄粉があったけど、どんなもんだろう。

わがVTRはドレンボルトにも磁石が埋め込まれていて、そこについている鉄粉は以前と変わらない量である。問題ないだろうな。きっと。そう信じよう。HONDAの250cc V2を信じよう。頼むぞMC15E


さて、今回はCastrolのPower1 4Tというのを投入。まあ、前回からですが。なんとなく15W-50を入れてみた。純正指定は10W-40なのですが、なんとなく固めのオイルのほうがいいかな、なんて。バイク古いし。と思ったけどどうなんだろうね~。

最低限の潤滑ができているのなら問題ないか、という発想です。

さて、エンジンオイル交換するとさすがにフィーリングよくなりますね。非常にいい!とまではいきませんが、なんとも表現できない向上がありますね。オイルの粘度が上がったようなかんじ?気のせいかもしれませんけどね。


さて、わがVTRはそろそろ56789kmにさしかかろうと思います。寿命の半分ほどになるのでしょうか、いや、明日つぶれてしまうかもしれません。不安です。不安です。壊れるまで乗ってあげたいのですが、来年は大学にいないので、無理かなと。
会社に入ると寮生活なのですが、バイクは一台のみだそうです。どこかにガレージ借りようにも、いい場所探すのに時間かかりそうですしね。

ガレージほしい~~~。

最近CBR250RRとVTR250をとっかえひっかえ乗っているのですが、それぞれにいいところがありますね。CBRはブンブン回して楽しいし、VTRはマッタリ走るのにいい感じ。やっぱりバイクは複数台所持したいな~。

ふと思った、車の駐車場を一台分借りて、そこにバイクを並べたら三台くらい入るんじゃないかと。考えてみよう。


ぜんぜんオイル交換から話がずれちゃったけど、まあ、気にしない。ちょっと酔っているので。

駄文、長文失礼。
コメント (2)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする