FC2ブログ
*admin*entry*file*plugin| 文字サイズ  


以前に公開したアドオンをちょっと改良したのでその紹介です
動作は「選択領域」を基に「一つ飛ばし」で頂点を選択する
というもので、基本的に領域拡大しか出来ませんでした。
あと、ボタンを何度も押す必要があるのでそこの改良です。

データはこちらのページに置いてあります
ここをクリック

改良後の全ソースがこちら


bl_info = {
"name": "Skip Select(Loop)",
"author": "Mithril",
"version": (0, 0, 2),
"blender": (2, 7, 9),
"location": "3DView > Tools > Skip Select > Edit Mode ",
"description": "Loop selection for one skip",
"tracker_url": "http://mithrilproject.blog66.fc2.com/",
"warning": "",
"category": "Tools"}

import bpy
import bmesh
from bpy.props import *

def SkipSelectMore(verts_back):
#Only Edit Mode
if bpy.context.object.mode != "EDIT":return {'FINISHED'}

obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='EDIT')
#Vertex Mord
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
mesh = bmesh.from_edit_mesh(obj.data)

#Get Select Vertex(s)
if ( verts_back == []) :
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1
else :
m = 0
for vert in verts_back:
m += 1

verts = []
i = 0
for vert in mesh.verts:
if (vert.index == verts_back[i]) :
vert.select = True
verts.append(vert.index)
i += 1
if ( i == m ) : break

#Select More
bpy.ops.mesh.select_more()
#Select Inverse
bpy.ops.mesh.select_all(action='INVERT')

#Reselect
k = 0
for v in mesh.verts:
if k == i : break
if v.index == verts[k]:
v.select = True
k = k+1
if k == i : break

#Select Inverse
bpy.ops.mesh.select_all(action='INVERT')

verts_back.clear()

for vert in mesh.verts:
if vert.select == True:
verts_back.append(vert.index)

return verts_back


def SkipSelectLess(verts_back):
#Only Edit Mode
if bpy.context.object.mode != "EDIT":return {'FINISHED'}

obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='EDIT')
#Vertex Mord
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
mesh = bmesh.from_edit_mesh(obj.data)

#Get Select Vertex(s)
if ( verts_back == []) :
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1
else :
m = 0
for vert in verts_back:
m += 1

verts = []
i = 0
for vert in mesh.verts:
if (vert.index == verts_back[i]) :
vert.select = True
verts.append(vert.index)
i += 1
if ( i == m ) : break

#Select More
bpy.ops.mesh.select_more()
#Select Less
bpy.ops.mesh.select_less()

#Reselect
k = 0
for v in mesh.verts:
if k == i : break
if v.index == verts[k]:
v.select = False
k = k+1
if k == i : break

#Select Inverse
bpy.ops.mesh.select_all(action='INVERT')
bpy.ops.mesh.select_all(action='INVERT')

verts_back.clear()

for vert in mesh.verts:
if vert.select == True:
verts_back.append(vert.index)

return verts_back

class UI(bpy.types.Panel):
bl_label = "Skip Select"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = 'Tools'

@classmethod
def poll(self, context):
obj = context.active_object
if obj and obj.type == 'MESH':
return{'FINISHED'}

def draw(self, context):
row = self.layout.row(align=True)
row.operator('skip.select', icon='LATTICE_DATA')
row.enabled = len([o for o in context.selected_objects if o.mode == 'EDIT'])

class Skip_Select(bpy.types.Operator):
bl_idname = "skip.select"
bl_label = "Select (More)"
bl_options = {'REGISTER', 'UNDO'}

repeat_c = IntProperty(name='Repeat',
description='Repeat Count',
min=0,
max=100,
default=0)
count = 0
verts_back = []

## EXECUTE #######
def execute(self, context):

obj = bpy.context.active_object
more = self.repeat_c- self.count
#print(self.count)
#print(self.repeat_c)
#print(more)
#print(obj.data.total_vert_sel)

if ( self.count == 0 ) :
self.repeat_c = 1
more = 1
self.verts_back = []

verts_back = self.verts_back

if ( more == 1 ) :
SkipSelectMore(verts_back)
elif ( more == -1 ) :
SkipSelectLess(verts_back)
elif ( more > 1 ) :
for i in range(more) :
SkipSelectMore(verts_back)
elif ( more < 1 ) :
for i in range(more * -1 ) :
SkipSelectLess(verts_back)

self.verts_back = verts_back
self.count += more
if ( self.verts_back == [] and self.count == 0) :
self.repeat_c = 0
return {'FINISHED'}

### REGISTER ######

def register():
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)

if __name__ == '__main__':
register()



まず最初に「追加のプロパティ」を設定します。


class Skip_Select(bpy.types.Operator):
bl_idname = "skip.select"
bl_label = "Select (More)"
bl_options = {'REGISTER', 'UNDO'}

repeat_c = IntProperty(name='Repeat',
description='Repeat Count',
min=0,
max=100,
default=0)
count = 0
verts_back = []

とりあえずこれで追加だけならできるみたいです。
数値変更は出来ますが特に何も動作はしません。
追加の変数も2つほど入れてます

「count」は「ツールのボタンを押した」時の動作で
「初期化」させるようにしています。

「verts_back」は頂点の一時保管場所として定義


そして、メインの処理がこちら


#Get Select Vertex(s)
if ( verts_back == []) :
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1
else :
m = 0
for vert in verts_back:
m += 1

verts = []
i = 0
for vert in mesh.verts:
if (vert.index == verts_back[i]) :
vert.select = True
verts.append(vert.index)
i += 1
if ( i == m ) : break


結果的に特に大した処理をしているわけではないのですが、
どうも、ボタンを押すのとプロパティを操作するのでは
挙動が異なるらしく同じような処理が出来ませんでした。

「プロパティ」が更新されても「頂点情報が更新されない」
という罠にひかかりまして、それで一時保管場所を作りました
「領域縮小」はただ単に逆の動作になっているだけです。

使うと解かりますが、メッシュの頂点数の上限までやっちゃうと
プロパティの動作では戻らなくなっちゃいます。
このときは一度プロパティを「0」にすると初期化されます

処理速度について
最初に改良していたのはこんな感じで


verts = []
i = 0
for vert in mesh.verts:
for m in verts_back :
if vert.select == True and vert.index == m :
verts.append(vert.index)
i += 1
elif (vert.index == m) :
vert.select = True
verts.append(vert.index)
i += 1


これでも、動作するのですが使ってみるとめっちゃ重いです。
理由は簡単で「全ての頂点情報ひとつひとつ」に対して
「保管されている頂点」全てを照合させているから、
そりゃぁ重くなるよ。で、処理を軽くするために
今のソースになってます。一応「サブディビジョンサーフェス」
「10」の後に更に「2」をかけたぐらいの密度なら
ストレス無く動作します、多分

やりすぎるとBlenderが落ちるので程々に
使う使わないは別にして、アドオン作成のお勉強にはなったかな?


スポンサーサイト


また、久しぶりの更新ですが
今回アップしたアドオンについての説明です。
何をするものかというと・・・

これを簡略化できないかなぁ・・・

こういう選択を簡単に行うためのものです。
「何に使うねん」っていうと「ポリゴン削減」が
主な目的ですかね・・・

すでにあるかもしれませんが見つけられ
なかったので作ってみました。
最初に選択されている頂点が基準になります
これにより縦向きか、横向きかを決めます。
アドオンの作り方の勉強にもなるし良いかなぁって
実行すると・・・

これが
これを簡略化できないかなぁ・・・

こうなります
これを簡略化できないかなぁ・・・
ボタンを押すほど選択範囲が広がります。

物自体はココに置いてあるのでお好きにどうぞ
ここをクリック

ソースコードはこんな感じです


#アドオンの情報
bl_info = {
"name": "Skip Select(Loop)",
"author": "Mithril",
"version": (0, 0, 1),
"blender": (2, 7, 9),
"location": "3DView > Tools > Skip Select > Edit Mode ",
"description": "Loop selection for one skip",
"tracker_url": "http://mithrilproject.blog66.fc2.com/",
"warning": "",
"category": "Tools"}

#必要なインポート
import bpy
import bmesh

#メインの処理
def SkipSelect():
#エディットモードじゃなければ終了
if bpy.context.object.mode != "EDIT":return {'FINISHED'}

obj = bpy.context.active_object
#エディットモードに変更(別に要らないけど)
bpy.ops.object.mode_set(mode='EDIT')
#頂点モードに変更
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
mesh = bmesh.from_edit_mesh(obj.data)

#選択頂点取得
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1

#選択範囲拡張
bpy.ops.mesh.select_more()
#インバース選択
bpy.ops.mesh.select_all(action='INVERT')

#選択頂点を再選択
k = 0
for v in mesh.verts:
if k == i : break
if v.index == verts[k]:
v.select = True
k = k+1
if k == i : break

#インバース選択
bpy.ops.mesh.select_all(action='INVERT')

class UI(bpy.types.Panel):
#UI情報
bl_label = "Skip Select"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = 'Tools'

#オブジェクトが「メッシュ」以外だと非表示
@classmethod
def poll(self, context):
obj = context.active_object
if obj and obj.type == 'MESH':
return{'FINISHED'}

#ボタン配置
#エディットモード以外だとグレーアウト
def draw(self, context):
row = self.layout.row(align=True)
row.operator('skip.select', icon='LATTICE_DATA')
row.enabled = len([o for o in context.selected_objects if o.mode == 'EDIT'])

#ボタン押したら実行するやつ、たぶん
class Skip_Select(bpy.types.Operator):
bl_idname = "skip.select"
bl_label = "Select (More)"

### EXECUTE #######
def execute(self, context):
SkipSelect()
return {'FINISHED'}

#インストールとアンインストールの処理
def register():
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)

if __name__ == '__main__':
register()


まず最初のところはアドオンの情報ですね
インストール時にこのあたりに表示されたり。

アドオンの情報

その次は必要なインポートで「bpy」「bmesh」の
2つ入れてます、「bpy」はほぼ確実に必要なものですね。

で、次の「SkipSelect()」が今回作ったメインの部分
手動でやるところをコードに起こしただけですが、

①選択された頂点を取得
②選択範囲拡張
③インバース選択
④①を再選択
⑤インバース選択

これをやってるだけ

本当は
①選択された頂点を取得
②選択範囲拡張
③①を非選択

これでもいけるはずなんだけど、何故かうまくいかなくて
ちょっと回りくどいやり方になってます。
その他の具体的なコードの説明は冒頭のソースコードの
コメントにしてるのでそれを参照していただければ。

「Run Script」で行うだけなら「SkipSelect()」の
中身だけで事足りますが、アドオンにするときはインストール
やらボタンやらレジストリやらなんやかんやついてきて
まぁ、面倒ですね。

「SkipSelect()」の部分を外に出しているのはそのほうが都合が
良さそうだからで、「Class」の中でやるとどうも「print」が
使えないんですよね、これ使えないとデバックできないじゃん
ってことで外に出しました。

Blenderはマウスオーバーのときにソースコピーきますし、
「Python Console」使えば「Ctrl」+「スペース」でリスト出ますし
アドオン作る上では色々便利になってますね。

また何かあれば記事にするかも



今日もプログラミングのお話です。
お題は 「switchで文字判断」

本来switchは数値を見て判断させるわけで
文字の判断なんか普通はできない・・・らしい。
でも、記述が簡単だし文字判断が出来ると嬉しい
と、いうことでほぼ無理やり判断させてみます。

int *h,bh;
h = &bh;

h = (int*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi("0").ToPointer();//String^ -> int*

switch(*h){
case 0x30: break;
}

String^からint*への変換

int*じゃないと上手く数値拾えなかったんだけど、
なんだろうかこれは?まぁ、どうでもいいけど。
二行目で一応アドレス指定しているけど使わねぇ。

これでswitch文へ投げることができるようになりました。
判断させるのは大文字のアルファベットと数字と記号が
少々なので一個ずつ書いてもさほどかさばりません。
イレギュラーな文字入ってきたときはdefaultで無効にします。

で、何故こんなことをするのかというと外部から数値を読み込む
ときは元々数値で問題なくても、PCから飛ばすときは文字なわけで。
その文字一つ一つがとある規則によって変換が必要なのです。
そのまま送信すると相手方に「何送ってんの?」と文句言われます。
規則があるのならそれをプログラムに組み込めばいいのだけど、
考えるの面倒だからとりあえず1つずつ変換したという経緯。



ネットが

引っ越しの前後ということでただ今モデム回収されて自宅の
ネット環境が無くなっちゃいました。引越し先でももちろんいるので
契約をしていたのですが、なんと最悪1ヶ月以上時間がかかるとのこと。
これはなかなか面白い状況になってますな、使えん奴らめ。
こうならないようにいつも早めに手を打ってるのに。

・・・こんな事もあろうかと手元にはポケットWi-Fiがあったりして。
メインのデスクトップには基本無線機能無いのだけど、都合よく
USBで受信できる機器が手元にあったりとネットは以前健在なのです。
ただ、速度ががくんと落ちちゃうから大容量の通信は控えることに(´・ω・`)

お引越しの方はほぼ完了したのですが、このあともまだイベントが
続いていましてもうしばらく忙しいのです。
Twitterもお留守状態ですがたまに覗いてます。
つぶやいてはいませんが、居留守みたいな状態です。



主要な機能は大体乗せたのであとは実機で
通信しての調整が必要になるわけですが。
この通信でおそらく必要となる機能のひとつに
マルチスレッドがあります。今日はこのお話。

送信するにしても受信するにしてもwhileとかfor
でぐるぐる回して通信します。その時なんにも
していないとフリーズ状態に陥ります。
この回避の手段としてマルチスレッドをつかいます。
やることはたぶんこんな感じ

・フリーズの原因になる処理を新しいスレッドとして定義
・こいつをバックグラウンドで動かす
・割り込みの処理を仕込んでおく

たぶんこの3つだと思うのだけど。
最後のが必要なのは途中で止めたいっていう時に必要だから
で、書くソースはこんな感じに
作ってるのはVC++のフォームアプリ


using namespace System::Threading;


まずこれが必要、これないと動かない。


Thread^ Read = gcnew Thread(gcnew ThreadStart(this, &Form1::Read));
Read->IsBackground = true;
Read->Start();


こんな感じで書いてみる、どうも変数の代入は無理らしい。
なんかエラーが出て上手くいかない。test(int i)ってやつね
(int i)ではなく()にしておかないといけないみたい。
コレ出来ると結構便利なんだけど、別の記述なのだろうか?
今回はなくても特に問題はなさそうだけど。
そして割り込み処理はDelegateを使うといいらしい。


private: delegate System::Void ReadDataDelegate(String^ tx);//関数+Delegateって名前にしてみる
private: System::Void ReadData(String^ tx){//実際処理するやつ
//なんか書く
}

BeginInvoke(gcnew ReadDataDelegate(this, &Form1::ReadData), tx);//使うときはこうなる



まずDelegateで代入する変数を決めておく、別に変数無くてもいい。
実際のところDelegateじゃなくてもただの名前だから何でもいい。
勝手に「関数 + Delegate」って名前にしてるだけ。
そしてその下辺りに処理する関数を作っておく。
これを使うのはバックグラウンドで動いてる処理では
テキストボックスとかにアクセスが出来ないから。
ただ、メッセージボックスは普通に動くみたい。

で、実際の割り込みはバックグラウンド処理から「BeginInvoke」
をつかってDelegateの処理を呼び出します、これは見れば判るか。
今回通信処理をしているわけですが、ReadFileの待ち時間は
「0」に設定しています。つまり信号を受け取っていようがいまいが
値を返してReadFileから抜け出します。ReadFileで永遠に待つという
処理も可能ですが、その場合ReadFileから出てこないから
その後の処理ができなくなるのであまりおすすめできない。

ReadFileも作ったソースならいいのだけどそうじゃないから
下手に弄れないし、なのですぐに出て値持ってないかどうかで
処理を分岐させるという方法をとっているわけです。


こんな感じでマルチスレッドの処理をしたわけですが、
実は以前にも似たような事がありまして。なんかやった覚えがと感じ
つつもコーディングをしてました。ほんとソースどこ行ったよ(´・ω・`)
そしてようやく実機でのテスト通信をすることになりいろいろ
やってました。うむ、想定の範囲内の修正でどうにかなりそう。
このぐらいのソフトならフリーで転がってますが、私自身が作ることで
好きに編集できるという大きな利点がありこうなってます。
中途半端に通信できるとどこをどう修正したらいいのか解らないので。

今回NC機との通信ソフトを自作しているわけですが、障害はほぼ解消
されたのであとはなるようになるのではないかと。このソフトももちろん
必要な物なのですが、もう一つ欲しいものがあったりします。
それはGコードからの描画機能を持ったソフトです。
一応、CAD/CAM入ってるので軌跡の描画自体は可能です、可能ですが
Gコード吐いたらそのままという丸投げっぷり。
高価なソフトのくせして肝心なところでは役立たず。

理想:Gコード→描画(Gコードを追尾)
現実:描画→Gコード

実際のところGコードからの描画が現場としては一番欲しいところ。
欲を言うと相互変換できると更にいいけどまぁこれは無くてもなんとかなる。
アプローチの向きが逆なんですよ、なんでこんな仕様にしてるの?
現時点でもあるにはあるのですが3軸までで4軸つまりB軸が入ると機能しない
とか、FANUCのフォーマットしか対応していないとかIとJが効かないとか、
色々と使いにくい癖があるようで。でもさすがにこれを作るのは大変そう。

DirectXとかOpenGL等で画面への描画処理しないといけないから。
残念ながらこの手の処理をコーディングしたことはないのです。
(Gコード自体はすんごい単純だからそこの処理は大した問題ではない)
できなくはないと思うけど一筋縄ではいかないよねぇ・・・
そこまで時間が費やせればいいけど、暇があれば片鱗だけでも作るかも?
たしかDirectX11の本買ってたような気もするのだけど見当たらない。




さて、もうじきお引越しなので更にドタバタ感が増しております。
落ち着くのは来月の第二週辺りかなぁ。



新しい環境で使用するソフトを自作しようといきがって、
カタカタプログラムをコーディングしてましたが、なんか順調。
シリアル通信をさせるのが主な目的でインターフェイスは
RS232Cです。こんなレガシーデバイス今どきあれなのですが、
如何せんこれしか通信手段がない物がありまして。

ずばりNC機とかとのやりとりをさせるわけで、今現在でも
一応は通信手段を確立できてます。が、複数のソフトを
介してやっと成り立っている状態なので非常に不便。
まとめて処理できる物があればいいなぁと思ってもそんな
都合のいい物は当然ない。じゃぁ作ろうというお話でした。

ちょっと困るのはUSBからの変換ができないということ。
いや、できないというかたぶんまともに通信が確立できない。
この2つはどうも互換性に問題があるらしく動く保証がない。
かと言ってRS232Cのボード乗せるわけにもいかず、結論として
LANからの変換で対応させることにしました。
これは試したことがないのであれですが、今のところ正常に
動作しているような気分。お願いだから問題は起きないで。

LANを使うもう一つの理由は配線ですね。RS232Cの場合たしか
延ばせる距離が30mぐらいしかなかったはず。
使用するケーブル長さはこれより長くなりそうなので途中まで
LANを這わせようというお話になったわけです。

ちょっと詰まることはあっても大した問題でないことが
ほとんどで、いまのところ致命的な問題は発生していません。

どうしようか悩みそうなところ

・複数フォームの値のやり取り
・ポートの開き方及びデータ送受信
・目的のコードに変換

とりあえずデータの受け渡しから
①Form1.hの頭でForm2.hをインクルード

#pragma once

#include "Form2.h"//Form2


②Form2.hでイベントを定義

private:
///
/// 必要なデザイナ変数です。
///

System::ComponentModel::Container ^components;
public:
System::Void Form2_Load(System::Object^ sender, System::EventArgs^ e);//このへんに書く


③Form2.cppでゴニョゴニョ

#include "StdAfx.h"
#include "Form1.h"
#include "Form2.h" //cppに両方インクルード

using namespace test;

HANDLE hCom;

String^ Setting(){//ポートの有無検索。とりあえずCOM5まで
int i;
String ^ CountCom = "";

array^ addCOMData = {
"COM1","COM2","COM3","COM4","COM5"
};

for (i = 0 ; i < addCOMData->Length ; i++){
hCom = CreateFile(
addCOMData[i],
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if ( hCom != INVALID_HANDLE_VALUE ) {
CountCom += "1";
CloseHandle( hCom );
}
else {
CountCom += "0";
}

}
return CountCom;
}

System::Void SerialConfig::SerialConfig_Load(System::Object^ sender, System::EventArgs^ e) {
//なんか書く
}


まず最初に考えるのはForm1とForm2の値の引き渡しです。
Form1からForm2を開き、Form2の値をFoem1に引き渡すことが
必要になります。つまり相互に受け渡ししなくてはなりません。

Form1からForm2を開く場合「Form1.h」に「#include "Form2.h"」で
ヘッダーを読み込み次いでインスタンスを生成して呼び出します。
これを「Form2.h」でも同じことをしたいわけです。
一般的にForm2に「#include "Form1.h"」としそうになりますが、
互いが互いを参照しあっって無限回廊に彷徨い込みます。
当然コンパイルは通らない。

そこでForm2はヘッダーではなくcppにその記述を持っていきます。
それが上記のソース

Form1とForm2両方のヘッダーを読み込みゴニョゴニョしてます。
「Form2.h」で一度定義しておいて同じものを「Form2.cpp」にも
書きます、このcppで処理させればおk。
Form1への受け渡しはポインタを使ってますが説明は割愛。
これでこの問題は解決。


続いてポートの処理について
ポートを開くには「CreateFile」をつかっています。
おそらくこれが一般的な方法なのかな?詳しくは知らないけど。


HANDLE hCom;

hCom = CreateFile(
"COM1",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);


これでポート開放が可能なのですが、最初の"COM1"これがデフォルトの
設定だどエラーが出てコンパイルが通りません。
理由は文字コード?が問題らしくプロジェクトのプロパティの
文字セットで「マルチバイトを使用する」を選択しておきます。

プロパティ


これで無事コンパイルが通るようになりました。
ポートが問題なく開けたので早速送受信のテストをしてみました。
・・・・うむ、ちゃんと送信できてるみたい。
要の部分がほぼできちゃったのであとは適当にデータ変換して微調整。
変数の型が違うとか文句言われることもありますが、まぁ問題ないでしょ。

あ、でもひとつ気になったことがありました。シリアル通信で
制御コードも送りたいわけで、その時「0x11」とかをテキストボックス
にいれて送信します。その方法についてです。

これ普通に「text == "0x11"」とかいれてて上手く行かなかったんですよ。
同じ値のはずなのに何故かif分素通りしやがりまして。
なので、フォーマットを指定してif文に通しました。

一応テキストボックスには「\x11」と入れると制御コードが送れます。
とりあえず0x01~0x1Fまで送れるようにしてます。
普通に変数「i」を変換して代入させようとしたのですが、これもまた
思うとおりに代入されない(´・ω・`)。なので配列作ってその中身を
「i」で指定させることにしました。


array^ addbufData = {
"\x1","\x2","\x3","\x4","\x5","\x6","\x7","\x8","\x9","\xa","\xb","\xc","\xd","\xe","\xf","\x10"
,"\x11","\x12","\x13","\x14","\x15","\x16","\x17","\x18","\x19","\x1b","\x1c","\x1d","\x1e","\x1f"
};//addbufData [i]で制御コード指定



0x01と0x1を同一視させる必要もあるのですが、面倒なので今は放置。
今のままだとたぶん0x01みたいな0が付属しているのは認識しない、と思う。
実際のところ0x11(DC1)~0x14(DC4)の4つで十分だけどね、たぶん。
あと改行コードとかがありますが、ケースバイケースで。

これが必要な理由は頭とおしりにコード挟む必要があったりするから。
「今から送るよ」とか「送り終わったよ」っていう合図ね。
今扱ってるシリアル通信は基本垂れ流しだし\(^o^)/

それと受信に関してなのですがこれは多少厄介かもしれない。
受信自体は正常にできているようなのですが、どうも中身がおかしい。
これもしかして文字コードが特殊なんじゃね?って思って調べてみると
案の定なんか変なコードになってるし。えぇ・・・これ全部変換するの?
送信時は特に弄らなくても相手はちゃんと受信できてたんだけどなぁ。


あ、そういえば忘れていたことが。今実験しているのはNCとPCの中間に
いる機器でこれで記憶してNC機に更に出力させる形になってます。
こんなの

PC <--> 携帯記憶機器 <--> NC機

つまり・・・今処理している入出力信号が逆転してしまうわけですよ。
自作ソフトからの出力が実際の入力に、逆に入力は出力になるわけで。
小さい問題でも矢継ぎ早に出てこられると結構鬱陶しい。

プログラミングも久方ぶりだからこの程度で手をこまねいてるよ。
やってることはすんごい簡単なはずなんだけど・・・


超過密スケジュール

この先1ヶ月ほどの予定があり得ないことになってます、最近気づいた。
ここまで変なスケジュールになったの今までで初めてかもしれない。
あまりに多いからダブルブッキングさせちゃったよ、どうするよ。


Mithril

Author:Mithril


趣味は主に雑学です。
どうでもいいこと書いてます。

Blenderやプログラムに
ついても書いたりするかも。
私のPC環境はこちら

メールはこちらから↓
mithrilp★yahoo.co.jp
(★を@に変えて下さい)

07 | 2019/08 | 09
- - - - 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 28 29 30 31
QRコード