前にも書いたネタかもしれませんが、やり直しているので忘備録的に記事をアップします。Nikonの万能投影機の座標をコンピュータに取り込んで自動でDXFデータを作成するためのプロジェクト。以前はRhinocerosのplug-inのGrasshopperにデータを入れて処理をしていましたが、色々と使いにくいのでmacOSかRasPIのPythonでDXFを書き出すプログラムに変更しようと作り直してます。
次の写真が基板。

投影機のカウンタsc102の出力からArduino megaにつないでmegaでシリアル通信でデータを送れる形に変換しています。以下はそのプログラム。以前は基板上のボタンを押すとデータを送信していましたが、今回は一定間隔でデータを送信しているだけになってます。
//Nikon profile projector data processing unit sc102
//Arduino Mega
//RasPi3にシリアル通信でデータを送る。データは連続して送るだけ。
//データフォーマットはx=0000.000,y=0000.000;
//Arduino上のボタンは使用しない。
//ピンの定義
const int ledPin8 = 54;
const int ledPin7 = 55;
const int ledPin6 = 56;
const int ledPin5 = 57;
const int ledPin4 = 58;
const int ledPin3 = 59;
const int ledPin2 = 60;
const int ledPin1 = 61;
const int buttonPin8 = 65;
const int buttonPin7 = 64;
const int buttonPin6 = 63;
const int buttonPin5 = 62;
const int buttonPin4 = 69;
const int buttonPin3 = 68;
const int buttonPin2 = 67;
const int buttonPin1 = 66;
//data pin
//X-AXE
const int X_D8 = 38;
const int X_D7 = 39;
const int X_D6 = 40;
const int X_D5 = 41;
const int X_D4 = 42;
const int X_D3 = 43;
const int X_D2 = 44;
const int X_D1 = 45;
const int X_D = 46;
const int X_C = 47;
const int X_B = 48;
const int X_A = 49;
//Y-AXE
const int Y_D8 = 22;
const int Y_D7 = 23;
const int Y_D6 = 24;
const int Y_D5 = 25;
const int Y_D4 = 26;
const int Y_D3 = 27;
const int Y_D2 = 28;
const int Y_D1 = 29;
const int Y_D = 30;
const int Y_C = 31;
const int Y_B = 32;
const int Y_A = 33;
int xAxe[8];
int yAxe[8];
String sendString = "";
String lastSendString = "";
void setup() {
Serial.begin(57600);
//initilize array
for (int i = 0 ; i < 8 ; i++) {
xAxe[i] = 0;
yAxe[i] = 0;
}
//set pinmode for led
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(ledPin7, OUTPUT);
pinMode(ledPin8, OUTPUT);
//set pinmode for button pin
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);
pinMode(buttonPin5, INPUT);
pinMode(buttonPin6, INPUT);
pinMode(buttonPin7, INPUT);
pinMode(buttonPin8, INPUT);
//set pinmode for data input
pinMode(X_D8, INPUT);
pinMode(X_D7, INPUT);
pinMode(X_D6, INPUT);
pinMode(X_D5, INPUT);
pinMode(X_D4, INPUT);
pinMode(X_D3, INPUT);
pinMode(X_D2, INPUT);
pinMode(X_D1, INPUT);
pinMode(Y_D8, INPUT);
pinMode(Y_D7, INPUT);
pinMode(Y_D6, INPUT);
pinMode(Y_D5, INPUT);
pinMode(Y_D4, INPUT);
pinMode(Y_D3, INPUT);
pinMode(Y_D2, INPUT);
pinMode(Y_D1, INPUT);
pinMode(Y_D, INPUT);
pinMode(Y_C, INPUT);
pinMode(Y_B, INPUT);
pinMode(Y_A, INPUT);
pinMode(X_D, INPUT);
pinMode(X_C, INPUT);
pinMode(X_B, INPUT);
pinMode(X_A, INPUT);
//led all off
digitalWrite(ledPin1, LOW);
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin3, LOW);
digitalWrite(ledPin4, LOW);
digitalWrite(ledPin5, LOW);
digitalWrite(ledPin6, LOW);
digitalWrite(ledPin7, LOW);
digitalWrite(ledPin8, LOW);
}
//SC102に表示されるX、Yの文字列を返すfunction
String counterString(int data[8]) {
char outputChar;
String outStr;
for (int i = 0 ; i < 8 ; i++) {
switch (data[i]) {
case 11:
outputChar = ' ';
break;
case 10:
outputChar = '-';
break;
case 0:
outputChar = '0';
break;
case 1:
outputChar = '1';
break;
case 2:
outputChar = '2';
break;
case 3:
outputChar = '3';
break;
case 4:
outputChar = '4' ;
break;
case 5:
outputChar = '5';
break;
case 6:
outputChar = '6';
break;
case 7:
outputChar = '7';
break;
case 8:
outputChar = '8';
break;
case 9:
outputChar = '9';
break;
}
outStr += outputChar;
if (i == 4) {
outStr += '.';
}
}
return outStr;
//Serial.println(outStr);
}
//シリアルでデータ送信
void sendXYData() {
//Serial.println("x=" + counterString(xAxe));
//Serial.println("y=" + counterString(yAxe));
String sendString = "x=" + counterString(xAxe) + ", y=" + counterString(yAxe) + ";";//送信するデータをxAxe,yAxeから作る。
Serial.println(sendString);//シリアル出力
}
int readXBCD_data() {
int A = digitalRead(X_A);
int B = digitalRead(X_B);
int C = digitalRead(X_C);
int D = digitalRead(X_D);
int Value = A + B * 2 + C * 4 + D * 8;
return (Value);
}
int readYBCD_data() {
int A = digitalRead(Y_A);
int B = digitalRead(Y_B);
int C = digitalRead(Y_C);
int D = digitalRead(Y_D);
int Value = A + B * 2 + C * 4 + D * 8;
return (Value);
}
void readSC102data_X() {
//D8がlowからhighに変わるところを捕まえる。最長で7370μSec
//Serial.println("start readSC102data_X");
while (digitalRead(X_D8) == HIGH) {
//D8がHIGHの時はこのループで待つ
// Serial.println("digitalRead(X_D8) is not HIGH");
}
while (digitalRead(X_D8) == LOW) {
//D8がLOWの時はこのループで待つ
//Serial.println("digitalRead(X_D8) is not LOW");
}
//D8がHIGHになった。800μSecの間にABCDのデータを読み込む。
xAxe[0] = readXBCD_data();
//Serial.println("X[0]");
while (digitalRead(X_D7) == LOW)
{
//D7がLOWの時はこのループで待つ
}
xAxe[1] = readXBCD_data();
//Serial.println("X[1]");
while (digitalRead(X_D6) == LOW)
{
//D6がLOWの時はこのループで待つ
}
xAxe[2] = readXBCD_data();
//Serial.println("X[2]");
while (digitalRead(X_D5) == LOW)
{
//D5がLOWの時はこのループで待つ
}
xAxe[3] = readXBCD_data();
//Serial.println("X[3]");
while (digitalRead(X_D4) == LOW)
{
//D4がLOWの時はこのループで待つ
}
xAxe[4] = readXBCD_data();
//Serial.println("X[4]");
while (digitalRead(X_D3) == LOW)
{
//D3がLOWの時はこのループで待つ
}
xAxe[5] = readXBCD_data();
//Serial.println("X[5]");
while (digitalRead(X_D2) == LOW)
{
//D2がLOWの時はこのループで待つ
}
xAxe[6] = readXBCD_data();
//Serial.println("X[6]");
while (digitalRead(X_D1) == LOW)
{
//D1がLOWの時はこのループで待つ
}
xAxe[7] = readXBCD_data();
//Serial.println("X[7]");
}
void readSC102data_Y() {
//D8がlowからhighに変わるところを捕まえる。最長で7370μSec
while (digitalRead(Y_D8) == HIGH) {
//D8がHIGHの時はこのループで待つ
}
while (digitalRead(Y_D8) == LOW) {
//D8がLOWの時はこのループで待つ
}
//D8がHIGHになった。800μSecの間にABCDのデータを読み込む。
yAxe[0] = readYBCD_data();
//Serial.println("Y[0]");
while (digitalRead(Y_D7) == LOW)
{
//D7がLOWの時はこのループで待つ
}
yAxe[1] = readYBCD_data();
//Serial.println("Y[1]");
while (digitalRead(Y_D6) == LOW)
{
//D6がLOWの時はこのループで待つ
}
yAxe[2] = readYBCD_data();
//Serial.println("Y[2]");
while (digitalRead(Y_D5) == LOW)
{
//D5がLOWの時はこのループで待つ
}
yAxe[3] = readYBCD_data();
//Serial.println("Y[3]");
while (digitalRead(Y_D4) == LOW)
{
//D4がLOWの時はこのループで待つ
}
yAxe[4] = readYBCD_data();
//Serial.println("Y[4]");
while (digitalRead(Y_D3) == LOW)
{
//D3がLOWの時はこのループで待つ
}
yAxe[5] = readYBCD_data();
//Serial.println("Y[5]");
while (digitalRead(Y_D2) == LOW)
{
//D2がLOWの時はこのループで待つ
}
yAxe[6] = readYBCD_data();
//Serial.println("Y[6]");
while (digitalRead(Y_D1) == LOW)
{
//D1がLOWの時はこのループで待つ
}
yAxe[7] = readYBCD_data();
//Serial.println("Y[7]");
}
void readSC102data() {
for (int i = 0 ; i < 10000; i++) {
//X-AXE Input
int xA = digitalRead(X_A);
int xB = digitalRead(X_B);
int xC = digitalRead(X_C);
int xD = digitalRead(X_D);
//Y-AXE Input
int yA = digitalRead(Y_A);
int yB = digitalRead(Y_B);
int yC = digitalRead(Y_C);
int yD = digitalRead(Y_D);
int xD1 = digitalRead(X_D1);
int xD2 = digitalRead(X_D2);
int xD3 = digitalRead(X_D3);
int xD4 = digitalRead(X_D4);
int xD5 = digitalRead(X_D5);
int xD6 = digitalRead(X_D6);
int xD7 = digitalRead(X_D7);
int xD8 = digitalRead(X_D8);
int yD1 = digitalRead(Y_D1);
int yD2 = digitalRead(Y_D2);
int yD3 = digitalRead(Y_D3);
int yD4 = digitalRead(Y_D4);
int yD5 = digitalRead(Y_D5);
int yD6 = digitalRead(Y_D6);
int yD7 = digitalRead(Y_D7);
int yD8 = digitalRead(Y_D8);
int yValue = yA + yB * 2 + yC * 4 + yD * 8;
int xValue = xA + xB * 2 + xC * 4 + xD * 8;
if (xD1) xAxe[7] = xValue;
if (xD2) xAxe[6] = xValue;
if (xD3) xAxe[5] = xValue;
if (xD4) xAxe[4] = xValue;
if (xD5) xAxe[3] = xValue;
if (xD6) xAxe[2] = xValue;
if (xD7) xAxe[1] = xValue;
if (xD8) xAxe[0] = xValue;
if (yD1) yAxe[7] = yValue;
if (yD2) yAxe[6] = yValue;
if (yD3) yAxe[5] = yValue;
if (yD4) yAxe[4] = yValue;
if (yD5) yAxe[3] = yValue;
if (yD6) yAxe[2] = yValue;
if (yD7) yAxe[1] = yValue;
if (yD8) yAxe[0] = yValue;
}
}
void loop() {
// readSC102data();
readSC102data_X();
readSC102data_Y();
sendXYData();
delay(100);//最高速度を1/10secに決めておく
}
