From fbeb25eee0834019ce6130db8c3607e89c0639cd Mon Sep 17 00:00:00 2001 From: rob tillaart Date: Thu, 25 Jun 2020 10:19:33 +0200 Subject: [PATCH] 0.2.0 version --- LICENSE | 2 +- ParallelPrinter.cpp | 164 ++++++++++++++++++ ParallelPrinter.h | 60 +++++++ README.md | 44 ++++- .../ParallelPrinter_test.ino | 82 +++++++++ .../PrinterSimulator/PrinterSimulator.ino | 63 +++++++ .../Serial2ParallelPrinter.ino | 32 ++++ library.json | 21 +++ library.properties | 11 ++ 9 files changed, 477 insertions(+), 2 deletions(-) create mode 100644 ParallelPrinter.cpp create mode 100644 ParallelPrinter.h create mode 100644 examples/ParallelPrinter_test/ParallelPrinter_test.ino create mode 100644 examples/PrinterSimulator/PrinterSimulator.ino create mode 100644 examples/Serial2ParallelPrinter/Serial2ParallelPrinter.ino create mode 100644 library.json create mode 100644 library.properties diff --git a/LICENSE b/LICENSE index 3d51ae3..2fc1cc5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Rob Tillaart +Copyright (c) 2013-2020 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/ParallelPrinter.cpp b/ParallelPrinter.cpp new file mode 100644 index 0000000..bb6930e --- /dev/null +++ b/ParallelPrinter.cpp @@ -0,0 +1,164 @@ +// +// FILE: ParallelPrinter.cpp +// AUTHOR: Rob Tillaart +// VERSION: 0.2.0 +// PURPOSE: parallel printer class that implements the Print interface +// DATE: 2013-09-30 +// URL: https://github.com/RobTillaart/ParallelPrinter +// +// HISTORY +// 0.1.0 2013-09-30 initial release +// 0.2.0 2020-05-26 refactor, examples + +#include "ParallelPrinter.h" + +ParallelPrinter::ParallelPrinter() +{ + uint8_t dataPins[] = {3, 4, 5, 6, 7, 8, 9, 10}; + ParallelPrinter(13, 2, 12, dataPins ); +} + + +ParallelPrinter::ParallelPrinter(uint8_t STROBE, uint8_t BUSY, uint8_t OOP, uint8_t * p ) +{ + // CONTROL LINES + _strobePin = STROBE; + _busyPin = BUSY; + _oopPin = OOP; + pinMode(_oopPin, INPUT); + pinMode(_busyPin, INPUT); + pinMode(_strobePin, OUTPUT); + + // DATA LINES + for (uint8_t i = 0; i < 8; i++) + { + _pin[i] = p[i]; + pinMode(_pin[i], OUTPUT); + } +} + +void ParallelPrinter::begin(uint8_t lineLength, uint8_t pageLength) +{ + _pos = 0; + _lineNr = 0; + _pageNr = 0; + _tabSize = 2; + _lineFeed = 1; + _strobeDelay = 2000; + _printLineNumber = false; + + // page size parameters. + _lineLength = lineLength; + _pageLength = pageLength; +} + + +void ParallelPrinter::setTabSize(uint8_t n) +{ + // 2,4,6,8 allowed + _tabSize = (n > 8) ? 8 : n/2 * 2; + if (_tabSize < 2) _tabSize = 2; +} + + +// write() implements the virtual write of the Print class +size_t ParallelPrinter::write(uint8_t c) +{ + if (c == '\t') + { + uint8_t spaces = _tabSize - _pos % _tabSize; + for (uint8_t i = 0; i < spaces; i++) processSingleChar(' '); + return spaces; + } + if (c == '\n') + { + for (uint8_t i = 0; i < _lineFeed; i++) + { + processSingleChar(c); + _pos = 0; + _lineNr++; + } + return _lineFeed; + } + processSingleChar(c); + return 1; +} + + +void ParallelPrinter::processSingleChar(uint8_t c) +{ + _pos++; + if ((_pos == 1) && _printLineNumber) + { + // not nice - implicit recursion... + print(_lineNr); + print('\t'); + } + if (c == FORMFEED) + { + sendByte(c); + sendByte('\n'); + _pos = 0; + _lineNr = 0; + _pageNr++; + } + else + { + sendByte(c); + } + + // HANDLE FULL LINE + if (_pos > _lineLength) + { + _pos = 0; + for (uint8_t i = 0; i < _lineFeed; i++) + { + sendByte('\n'); + _lineNr++; + } + } + // HANDLE FULL PAGE + if (_lineNr > _pageLength) + { + sendByte(FORMFEED); + sendByte('\n'); + _pos = 0; + _lineNr = 0; + _lineNr = 0; + _pageNr++; + } + +} + + +// lowest level communication +void ParallelPrinter::sendByte(uint8_t c) +{ + // BLOCK WHEN OUT OF PAPER TODO + // while (digitalRead(_oopPin) == LOW) yield(); + // indication in hardware? + + Serial.write(c); // debugging + return; + + + // wait until printer is ready. + while (digitalRead(_busyPin) == HIGH) yield(); + + uint8_t mask = 0x80; + for (uint8_t i = 0; i < 8; i++) + { + digitalWrite(_pin[i], c & mask ); + mask >>= 1; + } + digitalWrite(_strobePin, LOW); + // time consuming part + if (_strobeDelay) delayMicroseconds(_strobeDelay); + digitalWrite(_strobePin, HIGH); + + // wait till data is read by printer. + while (digitalRead(_busyPin) == LOW) yield(); +} + + +// -- END OF FILE -- diff --git a/ParallelPrinter.h b/ParallelPrinter.h new file mode 100644 index 0000000..fd3f6de --- /dev/null +++ b/ParallelPrinter.h @@ -0,0 +1,60 @@ +#pragma once +// +// FILE: ParallelPrinter.h +// AUTHOR: Rob Tillaart +// VERSION: 0.2.0 +// PURPOSE: parallel printer class that implements the Print interface +// DATE: 2013-09-30 +// URL: https://github.com/RobTillaart/ParallelPrinter +// + +#include "Arduino.h" + +#define PARALLELPRINTER_VERSION "0.2.0" + +#define FORMFEED 12 + +class ParallelPrinter: public Print +{ +public: + ParallelPrinter(); // assume fixed pins for now, need 11 pins in total! + ParallelPrinter(uint8_t STROBE, uint8_t BUSY, uint8_t OOP, uint8_t * dataPins ); + + void begin(uint8_t lineLength = 80, uint8_t pageLength = 60); + size_t write(uint8_t c); + + // n = 2,4,6,8 + void setTabSize(uint8_t n); + // n = 1,2,3 + void setLineFeed(uint8_t n) { _lineFeed = constrain(n, 1, 3); }; + void printLineNumber(bool b) { _printLineNumber = b; }; + void formfeed() { write(FORMFEED); }; + bool isOutOfPaper() { return digitalRead(_oopPin) == LOW; }; + + // n = typical 2000; use with care + void setStrobeDelay(uint16_t n) { _strobeDelay = n; }; + +private: + // COMMUNICATION + uint8_t _strobePin; // inform printer new data on the line. + uint8_t _busyPin; // feedback from printer + uint8_t _oopPin; // Out of paper. + uint8_t _pin[8]; // data pins + + void processSingleChar(uint8_t c); + void sendByte(uint8_t c); + + // BEHAVIOR + uint8_t _pos; + uint8_t _lineLength; + uint8_t _lineNr; + uint8_t _pageLength; + uint8_t _pageNr; + uint8_t _tabSize; + uint8_t _lineFeed; + + bool _printLineNumber; + uint16_t _strobeDelay; +}; + +// -- END OF FILE -- diff --git a/README.md b/README.md index bb351b2..65ebd84 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,44 @@ # ParallelPrinter -Arduino library that implements a parallel printer - print interface + +Arduino library that implements a parallel printer - uses print interface + +## Description + +This **experimental** library defines a simple parallel printer object. + +It implements the **Print interface** to be able to print all datatypes. +It writes every byte over 8 parallel lines including a **STROBE** (clock) pulse, +while waiting for the connected printer to not be **BUSY** or **OUT OF PAPER**. + +This library is meant to be a starting point to make a "printer driver" for a +specific parallel printer. These can often be bought in 2nd hand stores or so. + +Have fun! + +Note: _This lib is a extended redo of the ParPrinter class._ + +## Interface + +* **ParallelPrinter(strobe, busy, oop, arr)** define 3 control pins + 8 datapins (= arr) + +* **begin(linelength, pagelength)** set page parameters +* **write(c)** send a single byte to printer, implements Print interface. + +* **setTabSize(n)** tabs are replaced by spaces. n = 2,4,6,8 +* **setLineFeed(n)** n = 1,2,3 1 = default +* **printLineNr(b)** true, false +* **formfeed()** to eject current page +* **isOutOfPaper()** check paper tray before printing starts + +* **setStrobeDelay(n)** make the strobe pulse shorter == faster printing +allows tuning of performance. Typical value = 2000. Time in micros. +use with care. + + +## See also + +https://en.wikipedia.org/wiki/Parallel_port#Centronics + +## Operation + +See examples diff --git a/examples/ParallelPrinter_test/ParallelPrinter_test.ino b/examples/ParallelPrinter_test/ParallelPrinter_test.ino new file mode 100644 index 0000000..98b2248 --- /dev/null +++ b/examples/ParallelPrinter_test/ParallelPrinter_test.ino @@ -0,0 +1,82 @@ +// +// FILE: ParPrinter_test.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo +// DATE: 2020-05-26 +// (c) : MIT +// + +#include "ParallelPrinter.h" + +ParallelPrinter PP; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + PP.begin(); + test1(); + test2(); + test3(); + Serial.println("\ndone..."); +} + +void loop() +{ + +} + +void test1() +{ + Serial.println(__FUNCTION__); + PP.formfeed(); + for (int i = 0; i < 10; i++) PP.println("Hello World"); + delay(100); +} + +void test2() +{ + Serial.println(__FUNCTION__); + PP.setLineFeed(3); + PP.formfeed(); + for (int i = 0; i < 30; i++) PP.println("Hello World"); + delay(100); +} + +void test3() +{ + Serial.println(__FUNCTION__); + PP.setLineFeed(2); + PP.formfeed(); + + //PP.setTabSize(0); + PP.printLineNumber(true); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + PP.printLineNumber(false); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + + PP.setTabSize(4); + PP.printLineNumber(true); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + PP.printLineNumber(false); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + + PP.setTabSize(6); + PP.printLineNumber(true); + for (int i = 0; i < 300; i++) PP.print("Hello World "); + PP.printLineNumber(false); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + + PP.setTabSize(8); + PP.printLineNumber(true); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + PP.printLineNumber(false); + for (int i = 0; i < 100; i++) PP.print("Hello World "); + + delay(100); +} + + +// -- END OF FILE -- diff --git a/examples/PrinterSimulator/PrinterSimulator.ino b/examples/PrinterSimulator/PrinterSimulator.ino new file mode 100644 index 0000000..bbd4caa --- /dev/null +++ b/examples/PrinterSimulator/PrinterSimulator.ino @@ -0,0 +1,63 @@ +// +// FILE: PrinterSimulator.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// PURPOSE: demo +// DATE: 2020-06-24 +// (c) : MIT + +// Simple parallel printer simulator, prints to serial... +// version could be made with a shiftin register .... + +#include "Arduino.h" + +uint8_t STROBE = 2; +uint8_t BUSY = 13; +uint8_t OOP = 10; +uint8_t dataPins[] = { 3, 4, 5, 6, 7, 8, 9, 10 }; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + pinMode(STROBE, INPUT); + pinMode(OOP, OUTPUT); + pinMode(BUSY, OUTPUT); // build in LED UNO. + + for (uint8_t i = 0; i < 8; i++) + { + pinMode(dataPins[i], INPUT); + } + + digitalWrite(OOP, HIGH); // HIGH is OK + digitalWrite(BUSY, HIGH); // BUSY during startup + + delay(5000); // do startup thingies. +} + +void loop() +{ + handleInput(); + // do other things here +} + +void handleInput() +{ + uint8_t x = 0; + + digitalWrite(BUSY, LOW); + while (digitalRead(STROBE) == HIGH) yield(); + for (int i = 0; i < 8; i++) + { + x <<= 1; + if (digitalRead(dataPins[i]) == HIGH) x += 1; + } + while (digitalRead(STROBE) == LOW) yield(); + digitalWrite(BUSY, HIGH); + + // process data + Serial.write(x); +} + +// -- END OF FILE -- diff --git a/examples/Serial2ParallelPrinter/Serial2ParallelPrinter.ino b/examples/Serial2ParallelPrinter/Serial2ParallelPrinter.ino new file mode 100644 index 0000000..d2b29c7 --- /dev/null +++ b/examples/Serial2ParallelPrinter/Serial2ParallelPrinter.ino @@ -0,0 +1,32 @@ +// +// FILE: Serial2ParPrinter.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.1.1 +// PURPOSE: demo +// DATE: 2020-05-26 +// (c) : MIT +// + +#include "ParallelPrinter.h" + +// uses defaults +// uint8_t p[] = {3, 4, 5, 6, 7, 8, 9, 10}; +// ParPrinter(13, 2, 12, p ); + +ParallelPrinter PP; + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + + PP.begin(); +} + +void loop() +{ + if (Serial.available()) PP.write(Serial.read()); +} + + +// -- END OF FILE -- diff --git a/library.json b/library.json new file mode 100644 index 0000000..32c3a93 --- /dev/null +++ b/library.json @@ -0,0 +1,21 @@ +{ + "name": "ParallelPrinter", + "keywords": "Parallel,printer", + "description": "Experimental (not complete) library to connect a parallel printer to Arduino. Implements printer interface.", + "authors": + [ + { + "name": "Rob Tillaart", + "email": "Rob.Tillaart@gmail.com", + "maintainer": true + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/RobTillaart/ParallelPrinter.git + }, + "version":"0.2.0", + "frameworks": "arduino", + "platforms": "*" +} diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..c106392 --- /dev/null +++ b/library.properties @@ -0,0 +1,11 @@ +name=ParallelPrinter +version=0.2.0 +author=Rob Tillaart +maintainer=Rob Tillaart +sentence=Experimental (not complete) library to connect a parallel printer to Arduino. +paragraph=Implements printer interface. +category=Communication +url=https://github.com/RobTillaart/ParallelPrinter +architectures=* +includes=ParallelPrinter.h +depends=