前にも書いたネタかもしれませんが、やり直しているので忘備録的に記事をアップします。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に決めておく }