• Pic® Basic


  • Mini Parallel Printer project.

    Mini Printer driver

    I am working on a project for the office, which will eventually take a serial input, interrogate the input data stream and if it finds a match with certain error strings, sound an alarm and print the details out onto a small printer. Additionally I would like the circuit to look for the midnight Time stamp, when it will update a software clock, and print out a comfort message without an alarm...

    But first of all, I have to make the printer work!

    What do we need?

    In addition to the Amicus18 we are going to need A printer, (I got this Epson printer second hand, on Ebay for £21.00 including a box of till rolls),


    We'll also require a Parallel Printer cable a connector and some cable to make the connections and in addition to a soldering iron we will need some tools.


    In the picture above you will see one of the most useful tools known to man... Bluetack... It's invaluable for stopping components running away whilst you are trying to solder wires onto them. wire cutters and a wire stripper are also useful.
    I prefer to use "Flush Cut" wire cutters, because they don't tend to leave such sharp points on the wires that you cut. and I have to admit, I also tend to use wire currers for stripping the insulation off wires in preference to strippers... Naughty, but saves me time.



    This picture shows a Parallel Printer cable 25Pin Male 'D' pule to 36 pin 'Centronics' connectors on a 2 metre cable.
    Note! there are two connectors in the image above, the right hand conector is the female 'D' connector I intend to use for the project, the left hand one is a Male 'D' plug which serves two purposes, in the picture it shows the 'Solder Bucket' connections on the back, that the wiring is soldered into, and when testing this will plug into the female connector and make it easier to connect the test meter, whick I will use too confirm connectivity later.

    How does it work?

    If you google Parallel Printer communications protocol you will find a number of web sites that discuss the Niceties of the various printer protocol's, I have taken a number of these pages, looked carefully at a lot of the information included and ignored most of it... This is my typical crude approach to making a circuit work...

    A parallel printer port usually connects a printer to a computer, the Computer shovels data (one byte at a time) onto an eight bit output port and tells the printer it's there,
    the Printer takes the data and tells the computer it's done so...
    this process continues until the message has been passed...
    Sounds easy!
    Beware, Not all Printers are born equal.

    Some printers can take plain text and print it directly, others have to be fed graphical representations of the image it's required to print. (Some printers can do both!)

    Dot matrix and thermal printers often accept text directly... Lazer printers and Inkjet printers seem to take graphical representations...

    I have never tried to interface with either a lazerjet or Inkjet printer.
    If you have one with a Parallel printer interface you could try this project.

    What do we need to connect?




    It would be useful to have information relating to the Pin designations on the Parallel Printer cable connector,
    Above is a table of connections and an image of the Connector type that we will be using to connect to the Amicus18 port connectors. (if you Google the Printer port connections you will see which of these are inputs and which are outputs. If you decide to integrate more of these into your project, it will be useful information for setting up the Tris registers (Tristate Registers define whether the pin is an input or an output)


    it would also be useful to know where the connections are on the Amicus18 board. I have copied an image of the Amicus board for information.

    I propose to use the eight data bits and only two other signals, 'Busy' and 'Strobe' plus Ground (GND).
    We could connect any of these ten signals to any digital port on the Amicus18 PCB, but it's usual to give the task of port allocation a little thought.
    It' usually easier to deal with associated signals, on the same interface port. so, for instance the eight data bit's, would all be best connected to the same port in the order in which the bits are normally arranged. (this saves effort later)

    The Amicus appears to have three eight bit ports,
    Port A (Offers both digital I/O and Analogue Input capabilities.)
    Port B (Offers both digital I/O and limmited analogue port capabilities, in addition to Programming capabilities)
    Port C (Offers Digital I/O multiplexed with Serial I/O and Clock functions)


    Port selection is often complicated by circuit functionality conflicts, for instance the Amicus18 board has both internal and external oscillator capabilities. If you use the external Crystal oscillator (Default) then Ports RC0 and RC1 are not available as digital I/O ports, (the Serial Bootloader (Amicus18 Default) uses ports RC6 and RC7, so these ports are not available for Digital I/O either). So port C is no good for the 8bit Data interface.

    Port A is better left for analogue inputs for later projects.

    Port B is shared with the ICSP (In Circuit Serial Programming) port As the Amicus18 this would usually be the ideal port for the 8 bit Data port. Our printer port will not load the ICSP pins excessively so the iCSP and data can co exist (Both features require manipulation of other pins in order to complete their normal functions, so as long as you sequence your program functions properly there will be no interoperation problems).


    The remaining two signals can connected to ports RC2, RC3, RC4 or RC5... I have chosen to use RC2 & RC3. (See table at top of section.)



    The picture above shows the connections onthe 25 pin 'D' plug. (Note the Green wire in the three wire ribbon cable, has a long tail which straps pind 18 to 25, to Gnd)
    Yellow is used for the Strobe signal, Blue is used for the Busy Signal.
    The remaining eight connections are the Data pins,
    I have used a piece of scrap category5 Patch cord which has four twisted pairs of wires.
    These are coloured Blue & White/Blue (Bu-Bu/W), Orange & White/Orange (0-0/W), Green & White/Green (G-G/W), Brown & White/Brown (Bn-w/Bn).

    In this case the White/Colour Wires, are predominantly white, with a thin coloured stripe sometimes they are predominently white with intermittent bands of colour.
    Generally these wires are used in the order as above.
    Pin Designation Colour of wire Plug Pin
    Data0 - PortB.0 Blue 2
    Data1 - PortB.1 White/Blue 3
    Data2 - PortB.2 Orange 4
    Data3 - PortB.3 White/Orange 5
    Data4 - Portb.4 Green 6
    Data5 - PortB.5 White/Green 7
    Data6 - PortB.6 Brown 8
    Data7 - PortB.7 White/Brown 9






    The picture above shows how I have used SIL Headers (Single In Line connectors), to connect to the three connectors on one side of the Amicus18 board.

    Note1! I have marked the connectors with Snopake to ensure that I f I unplug the connectors, I can re connect them in the correct sockets, in the correct orientation.

    Note2! the act of stripping, tinning, trimming and soldering these connections has caused some 'droppings' on the desktop.

    Make sure you tidy these away, before they cause shortcircuits under the Amicus PCB
    If you look closely you will see that the Bluetack was used to stop the Amicus Board moving around whilst the wires were soldered into position.

    As you will see in the diagram above, I have connected the ten signal wires and one earth wire, completing the required wiring.
    Please test the connections with a test meter or similar, to ensure the wres are connected to the correct places and that there are no short circuits.

    And now to make the 'Wheels' go round...

    At this stage we could do with a bit of a program.

    As mentioned at the top, I have a purpose in mind for this project,
    however before I get to that, I would like to test some functions...
    1, What Font's are available direct from the printer.
    2, can I make the printer cut the paper to separate the reports?.
    Please see the attached program... below.

    Code:
     
    '****************************************************************
    '* Name : Mini Printer Project *
    '* Author : [John Tabb] *
    '* Notice : Copyright (c) 2010 [Magpie Systems] *
    '* : All Rights Reserved *
    '* Date : 01/03/2010 *
    '* Version : 1.0 *
    '* Notes : Program used with Epson POS Printer TM-T88III *
    '* : May work with other Parallel printers *
    '****************************************************************
    Device 18F25K20 
    EData "Escape Sequence = Esc , " ' Store characters Directly into EEPROM when programming 24 Chars'
    Xtal 64 ' advise Processor Speed so that Compiler can adjust delays and time critical items
    Config_Start ' Begin Configuration settings for the 18F25K20
    FOSC = HSPLL ' HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1)
    FCMEN = OFF ' Fail-Safe Clock Monitor disabled
    IESO = OFF ' Oscillator Switchover mode disabled
    PWRT = OFF ' PWRT disabled
    BOREN = OFF ' Brown-out Reset disabled in hardware and software
    BORV = 22 ' VBOR set to 2.2 V nominal
    WDTEN = OFF ' WDT is controlled by SWDTEN bit of the WDTCON register
    WDTPS = 32768 ' 1:32768
    MCLRE = On ' RE3 input pin disabled; MCLR enabled
    HFOFST = OFF ' The system clock is held off until the HF-INTOSC is stable.
    LPT1OSC = OFF ' Disabled, T1 operates in standard power mode.
    PBADEN = OFF ' PORTB<4:0> pins are configured as digital I/O on Reset
    STVREN = OFF ' Stack full/underflow will not cause Reset
    LVP = OFF ' Single-Supply ICSP disabled
    XINST = OFF ' Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
    Debug = OFF ' Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
    Config_End
    All_Digital = true : ADCON1=15 'Stop all analogue port settings 
    Clear ' Clear the RAM values in the Microcontroller
    DelayMS 2000 ' Delay program execution for 2 seconds
    Dim s As Byte ' Create Variable to assist with string manipulation
    Dim Style As Byte ' Temporary Variable for loops
    Dim Counts2 As Byte ' Temporary Variable for loops
    Dim HeadText As Byte ' Temporary Variable for loops
    Dim StyleIndex[11] As Byte ' Create byte array for converted Style value
    Dim StyleNo[10] As Byte ' Create an array of 10 values to contain Style Values
    Symbol Busy PORTC.2 ' Create a symbol to make the program more readable
    Symbol Strobe PORTC.3 ' Create a symbol to make the program more readable
    ' Symbol nAck PORTC.4 ' Redundant Symbols the ' changes all following characters to a comment
    ' Symbol PaperOut PORTC.5 ' Redundant Symbols
    ' Symbol nAutoLF PORTA.0 ' Redundant Symbols
    ' Symbol nError PORTA.1 ' Redundant Symbols
    ' Symbol nInitialise PORTA.2 ' Redundant Symbols
    ' Symbol nSelectPrinter PORTA.3 ' Redundant Symbols
    Symbol PrintData = PORTB ' Create a symbol to make the program more readable
    StyleNo [0]= 0 :StyleNo [1]= 8 :StyleNo [2]= 24 :StyleNo [3]= 56 :StyleNo [4]= 184 ' Store Values in an array
    StyleNo [5]= 1 :StyleNo [6]= 9 :StyleNo [7]= 25 :StyleNo [8]= 57 :StyleNo [9]= 185 ' Store Values in an array
    High Strobe ': High nAutoLF : High nInitialise : (Set initial condition of Strobe signal, note redundant settings)
    TRISB = %00000000 ' Configure all ports in PortB as Outputs
    TRISC = %11110111 ' Configure Most ports in PortC as Inputs
    GoSub Cut ' Initialise paper by cutting any excess paper off
    For Style = 0 To 9 ' set up an action or series of actions to occur ten times (For Next loop)
    PrintData = 27 ' Sent Escape character to Printer
    GoSub PrintOut ' Print character above
    PrintData = 33 ' Send second element of Escape Sequence to change type font parameters
    GoSub PrintOut ' Print character above
    s= StyleNo[Style] ' Fugde to resolve Logic Problem
    PrintData = s ' Fudge as above (See comments in Article) Send third element of Escape Seq.
    GoSub PrintOut ' Print character above
    GoSub PrintNum ' Print record of Escape Sequence code
    GoSub PrintIt ' Initiate Subroutine "Printit" (Print Characters A to S in current typeface)
    Next Style ' Terminate For Next loop
    PrintData = 10 ' Line Feed Character
    GoSub PrintOut ' Print character above
    GoSub Cut ' cut report paper off
    PrintData = 10 ' Line Feed Character
    GoSub PrintOut ' Print character above
    End ' indicate end of Main program segment to prevent further processing 
    PrintNum: ' Subroutine Label
    PrintData = 10 ' Line Feed Character
    GoSub PrintOut ' Print character above
    For HeadText = 0 To 23 ' Initiate Print 24 characters from EEPROM (For Next Loop 
    PrintData = ERead HeadText 'Print character above
    GoSub PrintOut ' Print character above
    ' PrintData = HeadText+ 65 ' Redundant Code used to prove Amicus Edata problem
    ' GoSub PrintOut ' Print character above
    Next HeadText ' End For Next Loop
    StrN StyleIndex = Str$(Dec s) ' Convert the Integer to a String representation of the integer
    PrintData = StyleIndex[0] ' Send first character of String
    GoSub PrintOut ' Print character above
    PrintData = StyleIndex[1] ' Send Second character of String (If Present)
    GoSub PrintOut ' Print character above
    PrintData = StyleIndex[2] ' Send third character of String (If Present)
    GoSub PrintOut ' Print character above
    PrintData = 10 ' Line Feed Character
    GoSub PrintOut ' Print character above
    Return ' Sub Routine Terminator
    Cut: ' Subroutine Label
    PrintData = 27 '\
    GoSub PrintOut '\
    PrintData = 64 ' Initialise printer
    GoSub PrintOut '/
    PrintData = 10 ' Line Feed (
    GoSub PrintOut ' Print character above
    PrintData = 29 '\
    GoSub PrintOut '\
    PrintData = 86 ' Control Codes to initiate Paper Cut Function
    GoSub PrintOut '/
    PrintData = 66 '/
    GoSub PrintOut '/
    Return ' Sub Routine Terminator
     
    PrintIt: ' Subroutine Label
    For PrintData = 65 To 83 ' select chaacters A to S in sequence (for Next Loop)
    GoSub PrintOut ' Print character above
    Next PrintData ' Terminate For Next loop
    ' Sub Routine Terminator
    Return 
     
    PrintOut: ' Subroutine Label
    Low Strobe ' Lower Strobe signal to instruct printer to accept data on input
    DelayUS 2 ' Delay long enough for Printer to accept character
    High Strobe ' Raise strobe to prepare for next Character
    While Busy = 1 ' This line and the next prevent progress untip printer is ready
    Wend ' Probably Redundant
    Return ' Sub Routine Terminator
    One of the most important lessons I learned is... Nothing gets printed until you send a Line Feed command (Ascii Character 10)

    The picture above shows the different fonts available directly from this printer...

    The code is heavily doccumented and should generally be understandable,
    there are a couple of issues which may need further comment

    1, there is a section where I have included a Fudge factor...
    I tried to use :-


    PrintData = StyleNo[Style] ' Which didn't work So I used....
    s= StyleNo[Style] ' Fugde to resolve Logic Problem
    PrintData = s ' Fudge as above (See comments in Article) Send third element of Escape Seq.

    It would appear that the compiler cannot resolve an array variable with a variable as the index when it's being applied directly to a port or port symbol.

    2, there is a section where I have included an additional Print character in the Amicus version of this program, because there appears to be an error in the Edata command Implementation.

    For HeadText = 0 To 23 ' Initiate Print 24 characters from EEPROM (For Next Loop
    PrintData = ERead HeadText ' Print character above
    GoSub PrintOut ' Print character above
    ' PrintData = HeadText+ 65 ' Redundant Code used to prove Amicus Edata problem
    ' GoSub PrintOut ' Print character above
    Next HeadText ' End For Next Loop

    When compiled on Proton Compiler and run on the Amicus hardware I would expect to see :-
    Escape Sequence = Esc , 24

    And if the two commented out lined are restored, Iwould expect to see:-
    EAsBcCaDpEeF GSHeIqJuKeLnMcNeO P=Q RESsTcU V,W X24

    Where the Red letters are the new set of characters caused by the extra lines. The Black letters are the letters recovered from EEProm and the Blue Characters are the Style number from the program.


    When compiled on Amicus Compiler and run on the Amicus hardware I would expect to see :-
    Escape Sequence = Esc , 24
    but I actually saw:-
    cp eune=Ec , 24

    And if the two commented out lined are restored, Iwould expect to see:-
    EAsBcCaDpEeF GSHeIqJuKeLnMcNeO P=Q RESsTcU V,W X24
    however I actually saw:-
    AcBpC DeEuFnGeHIJKLMNOP=QERcS,TUVWX24

    Where the Red letters are the new set of characters caused by the extra lines. The Black letters are the letters recovered from EEProm and the Blue Characters are the Style number from the program.

    It would appear that ther is a problem with the Edata command within the Amicus Compiler...


    I hope that you have enjoyed this article and try something similar yourselves.

    Regards JohnTabb.

    If you notice any spelling mistakes or errors please PM me.