以前に書いたArduinoを使った印刷用のインターフェースについて、暫定版ができた。
基板に実装するため、秋月電子のAE-ATMEGA-328 MINIを使用。
当初はプリンタ側はデジタルポートで、ポケコン側はアナログポートをデジタルとする予定だったが、ポケコン側の信号を割り込み処理で実行するため、一部の配線がめんどいことになってしまった。
仕様としては以下の通り。
インターフェース仕様
・CE-126とLPRTの両方をサポート
・リセット時に文字セット初期化を行うので、ポケコン側から初期化コマンドを送る必要なし
・プリンタへの出力が、そのままシリアルポートに出力される
・プリンタへの出力をOFFにできる(シリアルポートはそのまま出力される)
CE-126 mode
・ポケコン側の仕様に影響される
・1行24桁固定
・シリアルポートの出力は24桁で、不足分は空白で置き換わる。
・空行でも24桁の空白
・7Fh~9Fh,F0h~F4h,F8h~FFhあたりはポケコン側で空白に変換したり、別のコードに変換している
・MONモードやTEXTモードなどでも印刷できる
LPRT mode
・LPRINT CHR$コマンドで、指定したコードをそのまま出力する。
・MONモードやTEXTモードなどでは印刷できない
・プリンタが対応していればハードコピーが可能(予定)(暫定版では正常動作せず)9/14追記
・印刷が若干遅い(シフトレジスタICを使ったロジック回路でも同様)
まずはCE-126 modeで印刷してみる。
1行24桁固定で印刷され、一部の文字コードは印刷されない。
MONモードでダンプリストの印刷も行ってみる。
CE-126でなければ印刷できなかったものも印刷できた。
ついでにシリアルポートからの出力は以下のとおり。
!"#$%&'()*+,-./01234567 89<=>?@ABCDEFGHIJKLMNO PQRSTUVWXYZ[\]^_`abcdefg hijklmnopqrstuvwxyz{|}~ 。「」、・ヲァィゥェォャュョッ ーアイウエオカキクケコサシスセソタチツテトナニヌ ネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚
10:REM OPEN "LPRT:" 11:REM LPRINT CHR$ &H1B;"t"; CHR$ 1 12:REM LPRINT CHR$ &H1B;"R"; CHR$ 8 20:FOR A=32 TO 255 29:PRINT CHR$ A; 30:LPRINT CHR$ A; 40:NEXT 50:LPRINT
0100 : AF CD 5F 11 ッヘ_. (CB) 11 04 02 21 ...! 42 01 CD 20 B.ヘ 11 CD 8F 0A .ヘ . 0110 : 2A A2 11 56 *「.V (E8) 23 5E 23 ED #^# 53 01 7D 7E S.}~ 32 03 7D 23 2.}# 0120 : 7E B7 F4 7B ~キ (1E) 0A 2A A4 11 .*、. 22 04 7D 3E ".}> 01 32 00 7D .2.}
次にLPRTモードで印刷した場合。
こちらは、20h以降の文字がすべて印刷されている。
また、1行も用紙の幅いっぱい印刷されている。
シリアルポートからの出力は以下の通り。
!"#$%&'()*+,-./0123456789<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚珮粤蒟跚韜・・ⅰ涇・
80h~9Fh,E0h~FFhの部分はShiftJISで使っている領域になるので文字が化けている。
10:OPEN "LPRT:" 11:REM LPRINT CHR$ &H1B;"t"; CHR$ 1 12:REM LPRINT CHR$ &H1B;"R"; CHR$ 8 20:FOR A=32 TO 255 29:PRINT CHR$ A; 30:LPRINT CHR$ A; 40:NEXT 50:LPRINT
最後に、暫定版Arduinoスケッチ。
// Emulator Sharp CE-126P fur PC-1401 u. PC-E500 const int OUT_ACK = 17; // ACK Sharp CE-126P, pin 9 der 11-pol. Buchsenleiste const int IN_Xout = 3; // Xout Sharp PC-1401, pin 7 der 11-pol. Buchsenleiste / INT1 const int IN_Dout = 16; // Dout Sharp PC-1401, pin 5 der 11-pol. Buchsenleiste const int IN_Busy = 2; // Busy Sharp PC-1401, pin 4 der 11-pol. Buchsenleiste / INT0 const int InfoLED = 13; // printer interface const int Pstrb = 15; // Printer STROBE const int PD0out = 14; // Printer D0 const int PD1out = 4; // Printer D1 const int PD2out = 5; // Printer D2 const int PD3out = 6; // Printer D3 const int PD4out = 7; // Printer D4 const int PD5out = 8; // Printer D5 const int PD6out = 9; // Printer D6 const int PD7out = 10; // Printer D7 const int Pbusy = 11; // Printer BUSY // Mode SW const int EMmode = 12; // Emulator mode SW (Hi:CE126P/Lo:LPRT) const int EMsw = 18; // Emulator SW (Hi:Serial and Parallel / Lo:Serial only) boolean Busy; // Busy signal boolean Xout; // Xout signal boolean Dout; // Dout signal int DataBit; // work of CE-126P mode int DataByte; // work of CE-126P mode long Timeout; int i; byte SPif; // work of LPRT mode boolean PrtBusy; // work of Printer interface //////////////////////////////////////////////////////////////////////////////////////////// void setup() { // Serial port 98600BPS Serial.begin(9600); // E500/G8xx interface set pinMode(OUT_ACK, OUTPUT); pinMode(IN_Xout, INPUT); pinMode(IN_Dout, INPUT); pinMode(IN_Busy, INPUT); pinMode(InfoLED, OUTPUT); // Printer interface set pinMode(PD0out, OUTPUT); pinMode(PD1out, OUTPUT); pinMode(PD2out, OUTPUT); pinMode(PD3out, OUTPUT); pinMode(PD4out, OUTPUT); pinMode(PD5out, OUTPUT); pinMode(PD6out, OUTPUT); pinMode(PD7out, OUTPUT); pinMode(Pstrb, OUTPUT); pinMode(Pbusy, INPUT); // Emulator mode SW pinMode(EMmode, INPUT); pinMode(EMsw, INPUT); // Sirial header Serial.println(); Serial.println("Bereit:"); Serial.println(); // Printer STROBE is HIGH digitalWrite(Pstrb, HIGH); // Printer BUSY pull up digitalWrite(Pbusy, HIGH); // sw port pull up digitalWrite(EMmode, HIGH); digitalWrite(EMsw, HIGH); // ESC/POS printer init PRTinit (); } //////////////////////////////////////////////////////////////////////////////////////////// void loop() { if (digitalRead(EMmode) == HIGH ){ ce126pemu(); } else { lprtemu(); } } // Ende loop //////////////////////////////////////////////////////////////////////////////////////////// // Emulator Sharp CE-126P void ce126pemu() { do{ digitalWrite(InfoLED, LOW); Xout = digitalRead(IN_Xout); if (Xout) { // DeviceSelect: digitalWrite(InfoLED, HIGH); delayMicroseconds(50); i = 0; do { digitalWrite(OUT_ACK, HIGH); Timeout = millis(); do { Busy = digitalRead(IN_Busy); if (millis() - Timeout > 50) break; } while (!Busy); delayMicroseconds(50); digitalWrite(OUT_ACK, LOW); do { Busy = digitalRead(IN_Busy); } while (Busy); delayMicroseconds(150); i++; } while (i < 8); } Busy = digitalRead(IN_Busy); if (Busy && !Xout) { // Daten: digitalWrite(InfoLED, HIGH); i = 0; DataByte = 0; do { do { Busy = digitalRead(IN_Busy); } while (!Busy); delayMicroseconds(50); DataBit = digitalRead(IN_Dout); digitalWrite(OUT_ACK, HIGH); do { Busy = digitalRead(IN_Busy); } while (Busy); delayMicroseconds(50); if (i != 8) digitalWrite(OUT_ACK, LOW); // add : now receve to low. but printing is high DataByte = DataByte | (DataBit << i); i++; } while (i < 8); // Ausgabe: switch (DataByte) { case 13: Serial.println(); praout(0x0d); // CR praout(0x0A); // LF break; case 48: Serial.print("O"); // Buchstabe "O" praout(0x4f); break; case 240: Serial.print("0"); // Ziffer Null praout(0x30); break; default: if (DataByte >= 31 && DataByte <= 255) { Serial.print(char(DataByte)); praout(byte(DataByte)); } } if (i == 8) digitalWrite(OUT_ACK, LOW); // add : print after ack low } } while (digitalRead(EMmode) == HIGH ); } //////////////////////////////////////////////////////////////////////////////////////////// // Emulator LPRT: void lprtemu() { // Interrupt set attachInterrupt(0,IntBusy,RISING); attachInterrupt(1,IntXout,RISING); do{ digitalRead(EMmode); // dummy } while (digitalRead(EMmode) == LOW ); // Interrupt off detachInterrupt(0); detachInterrupt(1); } //////////////////////////////////////////////////////////////////////////////////////////// // Interrupt routine // BUSY to High (strobe) void IntBusy() { digitalWrite(OUT_ACK, HIGH); digitalWrite(InfoLED, HIGH); Serial.print(char(SPif)); praout(SPif); SPif=0; delay(5); digitalWrite(InfoLED, LOW); digitalWrite(OUT_ACK, LOW); } // Xout to High (data clock) void IntXout() { SPif = SPif << 1 ; if (digitalRead(IN_Dout) == HIGH) { SPif++; } } //////////////////////////////////////////////////////////////////////////////////////////// // init ESC/POS printer caractor set to Jananese void PRTinit () { // init print char set // ESC t n : Select international character set praout(0x1b); // ESC praout(0x74); // t praout(0x01); // 1:Katakana // ESC R n : Select character code table praout(0x1b); // ESC praout(0x52); // R praout(0x08); // 8:Japan delay(10); } //////////////////////////////////////////////////////////////////////////////////////////// // Parallel Printer interface void praout (byte POdata) { // If EMsw is low as no operation if (digitalRead(EMsw) == LOW) return; // wait busy low PrtBusy=digitalRead(Pbusy); do { PrtBusy=digitalRead(Pbusy); } while (PrtBusy != LOW); // Printer data output digitalWrite(PD0out, bitRead(POdata,0)); digitalWrite(PD1out, bitRead(POdata,1)); digitalWrite(PD2out, bitRead(POdata,2)); digitalWrite(PD3out, bitRead(POdata,3)); digitalWrite(PD4out, bitRead(POdata,4)); digitalWrite(PD5out, bitRead(POdata,5)); digitalWrite(PD6out, bitRead(POdata,6)); digitalWrite(PD7out, bitRead(POdata,7)); delayMicroseconds(1); // Strobe to low digitalWrite(Pstrb,LOW); // wait busy high Timeout = millis(); do { PrtBusy=digitalRead(Pbusy); //if (millis() - Timeout > 50) break; } while (PrtBusy == HIGH); // Strobe to high delayMicroseconds(50); digitalWrite(Pstrb, HIGH); // wait busy low do { PrtBusy=digitalRead(Pbusy); } while (PrtBusy != LOW); delayMicroseconds(50); }
シリアルポートから印刷データを垂れ流しているので、少し手直しすればプリンタシールドでも利用可能かもしれない。
雑な作りなので少し手直しは必要かも。