![]() |
Forum Index : Microcontroller and PC projects : Dot-matrix printer interface for the MM
Page 1 of 4 ![]() ![]() |
|||||
Author | Message | ||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
Hi folks. ![]() This is a revised version of the code and concept originally posted by CG(CircuitGizmos) [code] P$="Hello world. This is a test message." PRINTER (P$,1,1) end sub PRINTER (P$,I,C) if I=1 then setpin D10,9:setpin D2,9:setpin D3,9:setpin D4,9:setpin D5,9 setpin D6,9:setpin D7,9:setpin D8,9:setpin D9,9:pin(D10)=1 port(D2,8)=0 endif for X=1 to len(P$) C$=mid$(P$,X,1) port(D2,8)=asc(C$):pulse D10,1:pause 1 next if C=1 then port(D2,8)=13:pulse D10,1:pause 1 port(D2,8)=10:pulse D10,1:pause 1 endif end sub [/code] Have tested this tonight, and it is working a treat. Basically, the printer will accept a length of text WITHOUT printing it, until you then issue a CR(13). At that point, the printer takes over, and prints the line. With pulses and pauses of only 1ms, the test code still works fine, and to quote CG for a moment: "It's great to hear dot-matrix again." This thread and code is just an updated version of the CG code, allowing any string to be printed on a standard parallel printer. The printout is VERY quick with the 1ms pulses on STROBE, and is just as quick as any other printout on a dot-matrix printer of old. The sub is called from the main code, with the parameters (STRING$, INITIALIZE, CRLF) STRING$ is the string of text you want printed, INITIALIZE is either zero or one, which will initialize the printer as part of the process, and CRLF is if you want the printer to issue a CR/LF at the end of the data - this bit makes the printer actually print the text out. Full credit to CG for the idea and original concept. Once I find CG's original thread, I will link to it here. Smoke makes things work. When the smoke gets out, it stops! |
||||
BobD![]() Guru ![]() Joined: 07/12/2011 Location: AustraliaPosts: 935 |
I think this is what you want http://www.thebackshed.com/forum/forum_posts.asp?TID=5647 |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
IT IS!!!!! You beat me to it - curses! ![]() I will be updating this thread, as I make additions to the code. I plan to add things like font-size etc, using the printer's built-in fonts. For the purposes of initial development, it will be around Epson-compatible 9-pin printers, such as the Panasonic 9-pin that CG used in his original thread, and what I am using here. I have several other brand printers though, so will test them all. EDIT: Just tested with a Star LC100 printer, and it works fine with this printer too. The LC100 has the nice addition of being able to select a font, and the printer does all the work for you, with no extra input from the MM at all. Smoke makes things work. When the smoke gets out, it stops! |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
I made something similar and changed my code to use the same pins as your version. :) I needed a pause 5 to get it to work on an old oki printer. It would be nice to add some checks on the fault lines to detect out of paper/paper jam and other error conditions. [code] 'Setup pins for parallel printer port SETPIN D2,9 SETPIN D3,9 SETPIN D4,9 SETPIN D5,9 SETPIN D6,9 SETPIN D7,9 SETPIN D8,9 SETPIN D9,9 SETPIN D10,9 'Initial state of the pins PIN(D10) = 1 PORT(D2, 8) = 0 PPrintLine "Hello world!" PPrint "Hello worl" PPrintChar "d" PPrintLine "!" END SUB PPrintLine(Text$) PPrint Text$ + chr$(13) + chr$(10) END SUB SUB PPrint (Text$) FOR L = 1 to LEN(Text$) PPrintChar mid$(Text$, L, 1) NEXT END SUB SUB PPrintChar (value$) 'For test remove quote from the next line 'Print values$; PORT(D2, 8) = ASC(value$) PULSE D10,1 PAUSE 5 END SUB [/code] Microblocks. Build with logic. |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
I have a couple more printers to test, so I will increase my pauses/pulses to 5ms as you did, if I can't get a response out of it. One would THINK that any dot-matrix printer of the period should be able to handle that speed, as according to Wikipedia, the standard(read: slow) LPT port speed is 12kb per second. Note that this is 12 kilo-bit, not kilo-byte. So one would think you should be able to clock in up to 1,500 characters per second without causing the printer to overflow. HOWEVER, just cos the standard is 12kb/s, that does not necessarily mean that the printer design can handle that, I guess - that is just the maximum for that standard. I am playing with paper-out lines etc now, so that I can get some feedback from the printer if something like that happens, and the MM code can show the approiate message - it only needs an extra wire or two over and above what CG came up with . I used D2-D9, as I am using D0 and D1 as COM2, but I also needed 5v tolerant pins, as plopping my multimeter on the end of the printer cable, the data lines are already at 5v with the printer at rest, so connecting the printer cable to the 3v3 pins would be - unfortunate.... ![]() QUESTION: As the printer data-lines are 5v at idle, perhaps the 10k pull-up resistors are not needed - the printer already has pull-ups internally if you see what I mean. In my testing arrangement, I have just hooked up 9 x 10k resistors on the 25-pin socket that connects to the printer cable, but I would elect to use a SIL 10k network resistor-pack-thing in the final PCB if that was needed. Can anyone suggest if we actually need the 10k pack or resistors, if the printer seems to have 5v idle-high data lines? I'm starting to think that we should not need them, as with the port setup on the MM as open-collector, the MM will just pull the data-lines from the printer to deck as needed for that byte, then clock the STROBE line - that SHOULD all be able to be done without needing pull-ups on the MM side one would think. Comments? Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
I have a shelf full of old docket printers which will benefit from a serial to parallel converter. My to-do list has a Maximite converter on the list. The speed of the interface is one thing. Without a 'buffer full' indication, the usually small buffer in the printer can overflow. This is not a problem for short printouts with plenty of time between them but is something to keep in mind. Many of the newer printers are bi-directional so it is possible to have a signal feeding into the micromite outputs. Not nice. I was considering buffers which can do the level conversion as well as protect the maximite outputs from low impedances. A series resistor should also be enough protection. I will have to consult some old printer manuals (I have a shelf of them). Jim VK7JH MMedit |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
I just found my manuals for my old Panasonic printers, and these are pretty comprehensive with control codes and printout examples etc, so I will have a read. Your point about bi-directional is well taken - I will definitely add some series resistance, so that if the printer tries to drive the MM output, the current would be limited, hopefully protecting the MM. It was my understanding that the LPT port on the computer/laptop is usually bi-directional, but the printer itself is strictly an input-only device - might be wrong on that one, but I definitely agree that a computer LPT port can be input or output. EDIT: Reading the manual for the Panasonic printers, it mentions that the minimum pulse-width of STROBE or D0-D7 is 0.5uS, but I guess each printer brand is different. I might try shortening the pulse gap to less the 1mS and see what happens... ![]() ANOTHER EDIT: Manual seems to state that Panasonic printers have a single-line buffer, and this depends on the mode. In standard draft mode, that is 80 characters, or 40 characters if you select double-width mode etc. In my case, I am only wanting to incorporate a log printer - as each event happens, it is logged to the SD card, and also printed out. I am not trying to print pages at once, only single lines at a time, so I think I am safe enough without a dedicated print buffer. Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
This is worth a read: http://en.wikipedia.org/wiki/IEEE_1284 Jim VK7JH MMedit |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
Yes, that was an interesting read. ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
And another one: http://retired.beyondlogic.org/spp/parallel.pdf Now I really must go outside and do a bit of 'real work' Jim VK7JH MMedit |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
Heh, heh - you must have read my mind!!! I'm supposed to be cleaning up the shed and cutting the grass, so without further ado... EDIT: From that nice PDF that Jim posted: Seems sensible. I think it would still be a good idea then, for me to leave the 10k pull-ups on the MM side, but I will also now be adding a series resistor to each of the printer pins I use. At this stage, I have settled on 1k, which should keep any current flow into or out of either the printer or the MM to 5mA maximum. I could use a buffer chip I guess, but is it really needed with this kind of application? I think the buffer is primarily there so that you are safe connecting to any unknown PC LPT port, whereas with the MM, we know exactly how the port is setup. Comments? Smoke makes things work. When the smoke gets out, it stops! |
||||
MOBI Guru ![]() Joined: 02/12/2012 Location: AustraliaPosts: 819 |
I did this a few years ago but used a PIC16F88 as an I2C slave to parallel for driving dot matrix printers for logging. I didn't use any pull ups or buffers and it all worked quite well. If you are strapped for pins, doing it I2C will save 7. David M. |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
Yeah, I am inclined IN THIS APPLICATION, to not bother with the buffer. I think it would still be a good idea to use the series current-limiting resistors, so I will try hooking up these into the equation, and see how we get on. Smoke makes things work. When the smoke gets out, it stops! |
||||
MicroBlocks![]() Guru ![]() Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Now that i think about it again. That 5ms was probably not needed every character but only to prevent the buffer to get full. Anyway at that moment speed was not a concern. Microblocks. Build with logic. |
||||
robert.rozee Guru ![]() Joined: 31/12/2012 Location: New ZealandPosts: 2437 |
there is a BUSY signal on pin 11 of the printer connector. connect this pin to an input pin on the micromite, then modify the cr/lf portion of Grogster's code thus: if C=1 then Do Loop Until Pin(D11) port(D2,8)=13:pulse D10,1:pause 1 port(D2,8)=10:pulse D10,1:pause 1 endif assuming pin D11 is wired up to the BUSY signal coming back from the printer. BUSY is active low, and so when low indicates that the printer is tied up doing such things as printing (probably also low when offline). when high, the printer should be able to accept data, and to process the cr/lf sequence. addendum: i may have the polarity of BUSY inverted, and it may be necessary to check it before sending data at the start of a line. so the code snippet would instead be: ... Do Loop Until Pin(D11)=0 for X=1 to len(P$) ... rob :-) |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
Yep, my new hacked-up test design uses 1k series resistors just for a little protection there, and also uses BUSY, PAPER-OUT and RESET. There is also an ACK pin on the printer port, but I don't think I need it. Printer manual says this is pulses with every successful byte clocked into the buffer, or successful command byte. I have now used up the D port(D0-D13), but I have the general-purpose I/O pins, but would have to nab one that is 5v tolerant for ACK, and I just don't think I will need it, so.... Smoke makes things work. When the smoke gets out, it stops! |
||||
BobD![]() Guru ![]() Joined: 07/12/2011 Location: AustraliaPosts: 935 |
The penalty for not using ACK is that you have to insert timing pauses to allow for printer speeds and the pause has to be longer than the longest ACK time. If you were able to use ACK then you could feed data to the printer as fast as it could take it. Your program would also work with any printer. ACK if you wish me to say more ![]() |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9593 |
ACK. Do tell. I COULD incorporate it as I am designing a supplementary PCB to go with the MM, which has the printer socket on it(among other things I need), so it would just involve adding another track on that PCB, and incorporating one more spare 5v-tolerant IO pin, of which there are still a few left. Panasonic manual says of ACK pin: There is more in the manual, but that is the important part. Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6269 |
My readings suggest that a lot of drivers don't bother testing for ACK's I am not sure if the maximite is fast enough to need them. It would need a look at the timing under real life conditions. Regarding the series resistors. Printers usually have 4.7k pullup resistors although I did read that they can be a lot lower in value. If that's the case, a 1k series resistor may not pull the lines low enough. I would use a low value around 220 - 330 ohms. Something else that the CRO will determine. Jim VK7JH MMedit |
||||
BobD![]() Guru ![]() Joined: 07/12/2011 Location: AustraliaPosts: 935 |
I read that the Maximite can take up to 100 microseconds to respond to an interrupt which was to be my method of detection of ACK. The ACK could have come and gone before the Maximite could see it. The only way with this idea, would be a pulse stretcher and then this is getting too complicated. |
||||
Page 1 of 4 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |