98ノートのプリンタポートチェッカー (PC-9801単方向 20pinタイプ)を作成しました。(その3)
Arduino Nanoに書き込んだスケッチ(プログラム)は以下のとおりです。Arduino Nanoのほぼ全I/Oピンを使用します。A0からA7で8bitのプリンタライン信号を読み取ります。Arduinoアナログ入力ピンは、デジタル入力ピンとして設定して利用します。但しArduino NanoのA6とA7については、デジタル入力ピンとしては利用できず、アナログ入力ピンとしての利用になりますが、analogRead関数でも対応可能です。PC-9801NX/Cのプリンタ信号のHIGHおよび、Arduino NanoのI/OのHIGHの電圧はともに約5Vですので、analogRead関数の返り値で閾値を300で判断するとうまく動作します。また、9801側からデータ送信時の同期のためSTROBE信号は、他のラインとは異なり、ビット反転しています。STROBE ONではLOW、STROBE OFFではHIGHとなります。Arduino NanoのD13は、Arduino NanoのオンボードLEDに接続されていますが、I/OPinの数が足りなくなることから、BUSY信号の出力と内蔵LEDをモニタとして兼用しています。通信手順の処理については、少々難解かもしれません。詳しくは、以下のスケッチ(プログラム)を読み解いてみてくださいもし、Bugがあれば教えてください。#define LED_PRN_Data_Bit_0 2#define LED_PRN_Data_Bit_1 3#define LED_PRN_Data_Bit_2 4#define LED_PRN_Data_Bit_3 5#define LED_PRN_Data_Bit_4 6#define LED_PRN_Data_Bit_5 7#define LED_PRN_Data_Bit_6 8#define LED_PRN_Data_Bit_7 9#define LED_PRN_Strobe 10#define BTN_Busy_Toggle 11#define IN_PRN_Strobe 12#define OUT_and_LED_PRN_Busy LED_BUILTIN //13と同じ定義#define IN_PRN_Data_Bit_0 A0#define IN_PRN_Data_Bit_1 A1#define IN_PRN_Data_Bit_2 A2#define IN_PRN_Data_Bit_3 A3#define IN_PRN_Data_Bit_4 A4#define IN_PRN_Data_Bit_5 A5#define IN_PRN_Data_Bit_6 A6#define IN_PRN_Data_Bit_7 A7unsigned char Bit_Data = 0b00000000;unsigned char Bit_Data_Back = 0b00000000;boolean Status_BUSY = false;boolean Status_STROBE = false;char sendPacket[24] = "";int Status_Flag = 0;// the setup function runs once when you press reset or power the boardvoid setup(){ // initialize serial communication at 9600 bits per second: Serial.begin(9600); pinMode(LED_PRN_Data_Bit_0, OUTPUT); pinMode(LED_PRN_Data_Bit_1, OUTPUT); pinMode(LED_PRN_Data_Bit_2, OUTPUT); pinMode(LED_PRN_Data_Bit_3, OUTPUT); pinMode(LED_PRN_Data_Bit_4, OUTPUT); pinMode(LED_PRN_Data_Bit_5, OUTPUT); pinMode(LED_PRN_Data_Bit_6, OUTPUT); pinMode(LED_PRN_Data_Bit_7, OUTPUT); pinMode(LED_PRN_Strobe, OUTPUT); pinMode(BTN_Busy_Toggle, INPUT_PULLUP); pinMode(IN_PRN_Strobe, INPUT_PULLUP); pinMode(OUT_and_LED_PRN_Busy, OUTPUT); pinMode(IN_PRN_Data_Bit_0, INPUT_PULLUP); pinMode(IN_PRN_Data_Bit_1, INPUT_PULLUP); pinMode(IN_PRN_Data_Bit_2, INPUT_PULLUP); pinMode(IN_PRN_Data_Bit_3, INPUT_PULLUP); pinMode(IN_PRN_Data_Bit_4, INPUT_PULLUP); pinMode(IN_PRN_Data_Bit_5, INPUT_PULLUP);// pinMode(IN_PRN_Data_Bit_6, INPUT_PULLUP);//Arduino Nanoは、A6とA7がアナログ入力専用// pinMode(IN_PRN_Data_Bit_7, INPUT_PULLUP);//Arduino Nanoは、A6とA7がアナログ入力専用}// the loop function runs over and over again forevervoid loop() {//================================================ //Printer Data bit(0-9), Strobeのステータスの読み込み及びLED出力 //================================================ if (digitalRead(IN_PRN_Data_Bit_0)) { Bit_Data = Bit_Data | 0b00000001; digitalWrite(LED_PRN_Data_Bit_0, HIGH); } else { Bit_Data = Bit_Data & 0b11111110; digitalWrite(LED_PRN_Data_Bit_0, LOW); } if (digitalRead(IN_PRN_Data_Bit_1)) { Bit_Data = Bit_Data | 0b00000010; digitalWrite(LED_PRN_Data_Bit_1, HIGH); } else { Bit_Data = Bit_Data & 0b11111101; digitalWrite(LED_PRN_Data_Bit_1, LOW); } if (digitalRead(IN_PRN_Data_Bit_2)) { Bit_Data = Bit_Data | 0b00000100; digitalWrite(LED_PRN_Data_Bit_2, HIGH); } else { Bit_Data = Bit_Data & 0b11111011; digitalWrite(LED_PRN_Data_Bit_2, LOW); } if (digitalRead(IN_PRN_Data_Bit_3)) { Bit_Data = Bit_Data | 0b00001000; digitalWrite(LED_PRN_Data_Bit_3, HIGH); } else { Bit_Data = Bit_Data & 0b11110111; digitalWrite(LED_PRN_Data_Bit_3, LOW); } if (digitalRead(IN_PRN_Data_Bit_4)) { Bit_Data = Bit_Data | 0b00010000; digitalWrite(LED_PRN_Data_Bit_4, HIGH); } else { Bit_Data = Bit_Data & 0b11101111; digitalWrite(LED_PRN_Data_Bit_4, LOW); } if (digitalRead(IN_PRN_Data_Bit_5)) { Bit_Data = Bit_Data | 0b00100000; digitalWrite(LED_PRN_Data_Bit_5, HIGH); } else { Bit_Data = Bit_Data & 0b11011111; digitalWrite(LED_PRN_Data_Bit_5, LOW); } if (analogRead(IN_PRN_Data_Bit_6) > 300)//Arduino Nanoは、A6とA7がアナログ入力専用 { Bit_Data = Bit_Data | 0b01000000; digitalWrite(LED_PRN_Data_Bit_6, HIGH); } else { Bit_Data = Bit_Data & 0b10111111; digitalWrite(LED_PRN_Data_Bit_6, LOW); } if (analogRead(IN_PRN_Data_Bit_7) > 300)//Arduino Nanoは、A6とA7がアナログ入力専用 { Bit_Data = Bit_Data | 0b10000000; digitalWrite(LED_PRN_Data_Bit_7, HIGH); } else { Bit_Data = Bit_Data & 0b01111111; digitalWrite(LED_PRN_Data_Bit_7, LOW); } if (!digitalRead(IN_PRN_Strobe))//Printer Strobe信号は反転している STROBE ONでLOW、STROBE OFFでHIGH { Status_STROBE = true; digitalWrite(LED_PRN_Strobe, HIGH); } else { Status_STROBE = false; digitalWrite(LED_PRN_Strobe, LOW); }//================================================ //BUSY トグル ボタンの処理//================================================ if (!digitalRead(BTN_Busy_Toggle))//ボタンが押されLOW { if(Status_BUSY) { Status_BUSY = false; digitalWrite(OUT_and_LED_PRN_Busy, LOW); Serial.print("BUSY => NOT BUSY by user\r\n"); if(Status_STROBE) { Status_Flag = 1; } else { Status_Flag = 4; } } else { Status_BUSY = true; digitalWrite(OUT_and_LED_PRN_Busy, HIGH); Serial.print("NOT BUSY => BUSY by user\r\n"); if(Status_STROBE) { Status_Flag = 2; } else { Status_Flag = 3; } }// Status_Flag = 0;//STROBE ON and BUSY delay(100); }//================================================ //プロトコル(通信手順)の処理//================================================ if (Status_STROBE && !Status_BUSY) { if(Status_Flag!=1) { Serial.print("====================\r\n"); Serial.print("Detect STROBE ON\r\n"); Status_BUSY = true; digitalWrite(OUT_and_LED_PRN_Busy, HIGH); Serial.print("NOT BUSY => BUSY (Auto)\r\n"); Serial.print("Read PRN Data bit\r\n"); Serial.print("--------------------\r\n"); putb(Bit_Data); Serial.print("--------------------\r\n"); Status_Flag = 1;//STROBE ON and BUSY } } else if (Status_STROBE && Status_BUSY) { if(Status_Flag!=2) { Serial.print("Waiting STROBE OFF\r\n"); Status_Flag = 2;//STROBE ON and BUSY } delay(100); } else if (!Status_STROBE && Status_BUSY) { if(Status_Flag!=3) { Serial.print("Detect STROBE OFF\r\n"); Status_BUSY = false; digitalWrite(OUT_and_LED_PRN_Busy, LOW); Serial.print("BUSY => NOT BUSY (Auto)\r\n"); Status_Flag = 3;//STROBE OFF and NOT BUSY } } else//!Status_STROBE && !Status_BUSY { if(Status_Flag!=4) { Serial.print("Waiting STROBE ON\r\n"); Serial.print("Ready to read bit DATA!\r\n"); //putb(Bit_Data); Status_Flag = 4;//STROBE OFF and NOT BUSY } delay(100); }}void printb(unsigned char v) { unsigned char mask = (char)1 << (sizeof(v) * 7); do Serial.print(mask & v ? '1' : '0'); while (mask >>= 1);}void putb(unsigned char v) { Serial.print('0'), Serial.print('b'), printb(v), Serial.print("\r\n");}