Main Site Documentation

Serial Connection to Gameboy Thermal Printer [Hardware + Software]


#1

I’m currently working on getting a thermal printer set up with my FEZ Spider. I’m a little weak on the hardware side so I’m working on wrapping my head around what I need to do.

I’m using a gameboy printer that has a serial cable connection, the internals: http://dl.dropbox.com/u/62995/Gameboy%20images/photo1.jpg

I’m at the stage where I need to get the hardware side functioning before I can do anything with the coding/programming side.

[line]

Part 1 - Connecting the printer
Here is where I’m stuck right now. I need to hard-wire the printer to my FEZ Spider through a serial connection to start transmitting data. It looks like any socket type U can accept incoming serial connections based on this page: http://gadgeteer.codeplex.com/wikipage?title=Socket%20Type%20U

The Gameboy printer includes a serial connection cable that has 4 separate wires. These are SIN, SOUT, SCK and GND. basically, serial in, serial out, serial clock(?) and ground.

It seems like I would be able to connect SIN and SOUT to the RX (pin 5) and TX (pin 4) and the GND to GND(pin 10) and the SCK to either GPIO! (pin 3) or GPIO (pin 6). Is this correct?

Here is my wiring diagram: http://dl.dropbox.com/u/62995/Gameboy%20images/Wiring.png

Do I need to add pullup resistors or anything else anywhere to make this work? Is the voltage per pin enough (3.5 and 5v?) can I literally strip and solder the connections together or do I need to go about it in another way ?

I saw this a few times, but I don’t know exactly what it means, what is full duplex?

“The Gameboy Printer requires only lines SIN, SOUT, and serial port CLK Gameboy. Everything is in 0/5V. SIN and SOUT are crossed in the cable (full duplex).”

Some good information about converting the serial connection to USB: http://furrtek.free.fr/index.php?p=crea&a=gbpcable&i=2

additional links:

[ulist]

someone wiring up a serial connection to pins 4,5,6 and 10: http://www.tinyclr.com/forum/21/6022/

example gameboy serial to parallel port cable: http://www.ziegler.desaign.de/gb2pp7.gif

One more description of how data is sent and received: http://furrtek.free.fr/index.php?p=crea&a=gbprinter
[/ulist]

[line]

I hope this all makes sense, I feel like I’m so close to getting it functioning, but I missing a few things here and there. I’m not expecting you guys to read all of these links/threads, but who knows they may come in handy.

Is all of this too complex? would it make sense to just go with this?: http://electronicfields…thermal-printer-dot-net/ + http://www.sparkfun.com/products/10438

EDIT: fixed my links


#2

SCK implies that this is a SPI device, not a true “UART” serial device. You’ll be needing an S socket instead.


#3

Awesome, thanks for your fast response!

so could I use something like Serial SPI connection (seems to use almost exactly the same protocol as the Gameboy printer): http://wiki.tinyclr.com/index.php?title=SPI_-_MP3_Decoder

It seems almost identical in many mays, but I just want to double check.


#4

Pass. I didn’t go to that level of detail, but you may find that this is pretty close and therefore just works.

Sorry, I forgot to say “welcome” too, since that was your first post ! So here’s a big belated WELCOME !!!


#5

Thanks for the kind welcome!

Just to be super clear about this (I’m a noob after all) would the Gameboy’s SIN and SOUT connect with pin 7 and pin 8? http://gadgeteer.codeplex.com/wikipage?title=Socket%20Type%20S

I know the question might be redundant, but I just want to be sure.

would I still be able to just strip and solder the wires together?


#6

SOUT from the printers perspective would most likely be MISO
SIN from the printers perspective would most likely by MOSI

If you get it wrong, luckily nothing bad should happen, but nothing will work :slight_smile: Swap them and then you should be good to go.

http://wiki.tinyclr.com/index.php?title=Gadgeteer_Sockets is the best reference to use when it comes to pin mapping - it’s based on the Gadgeteer specs but is a great succinct place to get your head around the mapping. If you have the MakeBread module or the Extender module, you can do this without too much cutting/soldering - which I would recommend especially when you’re unsure how it should connect up and work :slight_smile:


#7

boom :slight_smile:

I’ll try your advice if it doesn’t seem to be working, hopefully I can talk to it tonight. Thanks so much for your help.


#8

sweet - those modules are gold. Well they should be :slight_smile:

If you want a tip - instead of soldering wires directly onto them, you can solder .1" headers (either male or female, your choice) and then use breadboard jumper wires. The other option is soldering male headers pointing down so you can plug it into a breadboard. Either way, breadboarding this kind of thing will save some time with the soldering iron.


#9

Well I’ve made an attempt to put some code together but I’ve failed miserably :’( I can’t really figure out how to speak to the printer. The only progress I’ve made is the SPI config, but the actual communication is beyond what I can understand. Perhaps someone can’t point me in the right direction?

Here is the code I am trying to replicate: http://milesburton.com/images/e/ec/GBPrinter_Arduino_Alpha_0.01.pde

My main references are Thermaldotnet (a lib for the sparkfun printer) https://github.com/yukimizake/ThermalDotNet

SPI on Spider: http://tinyclr.com/forum/21/6621/

and a basic SPI example: http://wiki.tinyclr.com/index.php?title=SPI_-_MP3_Decoder

How can I see the byte transfer to tell if anything is actually working?

what I have so far:

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Touch;
using Microsoft.SPOT.Hardware;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace printTherm
{
    public partial class Program
    {
        static SPI MySPI = null;
        public static void Sub()
        {

            InputPort Therm;
            Therm = new InputPort(Cpu.Pin.GPIO_Pin8, false, Port.ResistorMode.PullUp);

            SPI.Configuration MyConfig =
                 new SPI.Configuration(Cpu.Pin.GPIO_Pin8,
                 false, 0, 0, true, true, 1000, SPI.SPI_module.SPI1);
            MySPI = new SPI(MyConfig);

            

            bool exit = false;
            do
            {
                byte[] tx_data = new byte[1];
                byte[] rx_data = new byte[0];
                while (Therm.Read() == true) ;
                
                tx_data[0] = 0x01;
                tx_data[1] = 0x00;
                
                MySPI.WriteRead(tx_data, rx_data);

                while (Therm.Read() == false) ;
                byte[] tx_data2 = new byte[28];
                byte[] rx_data2 = new byte[28];
                for (int i = 0; i < 28; i++)
                {
                    tx_data2[i] = 0xFF;
                    rx_data2[i] = 0x00;
                }
                MySPI.WriteRead(tx_data2, rx_data2);
            } while (exit == false);
              

            Thread.Sleep(100);
        }

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
           
            Debug.Print("Program Started");
        }
    }
}


It’s almost exactly the same as the code above, except I’ve change the Pin to 8 (MISO) and added some array stuff. I’m really just going blind at this point. I feel bad coming into this with such poor knowledge, but any little help would be greatly appreciated.

some more resources for anyone interested in this:
full music shield code: http://code.tinyclr.com/project/330/fez-music-shield/

edits for clarification


#10

I have read the links you provided and came up with this:

using Gadgeteer;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace GadgeteerApp3
{
    public partial class Program
    {
        void ProgramStarted()
        {
            var socket = Socket.GetSocket(extender.ExtenderSocketNumber, true, extender, null);
            var spiConfig = new SPI.Configuration(socket.CpuPins[6], false, 0, 0, true, true, 10, socket.SPIModule);
            var spi = new SPI(spiConfig);

            var initRequest = new byte[] {0x88, 0x33, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00};
            spi.Write(initRequest);

            var ack = ReadByte(spi);
            var status = ReadByte(spi);

            Debug.Print("Ack = " + ack);
            Debug.Print("Status = " + status);

            var initialized = ack == 0x80 || ack == 0x81;
            Debug.Print(initialized ? "SUCCESS" : "ERROR");
        }

        private static byte ReadByte(SPI spi)
        {
            var dummyByte = new byte[] { 0x00 };
            var result = new byte[1];
            spi.WriteRead(dummyByte, result);
            return result[0];
        }
    }
}

This code requires you add an extender module in the designer and connect it with the mainboard. Also I’m using pure NET MF class for SPI to avoid errors, it can be replaced with the Gadgeteer class if this sample works. I have no way to test it so you have to do it and post the results. If it fails try to switch the Pin 7 and Pin 8. I hope it helps.


#11

This is how the designer should look like


#12

Thanks for taking the time to look at this, your code looks great.
For some reason my extender module had been named extender1 and that confused me for a while :-[

However, I’m still getting an error dump in the output. So I tried switching the pins and I still got the same results. I know it’s not very helpful as the issue could be hardware. Let me know if there is anything else to test

Using mainboard GHIElectronics-FEZSpider version 1.0
Ack = 0
Status = 0
ERROR

edit: oh yeah, sometimes I get ack = 255 but that may just the the rise/fall of the clock? not sure why it’s happening


#13

One thing that i noticed about your code was that you are using 1 MHz clock and it’s written here

http://furrtek.free.fr/index.php?p=crea&a=gbprinter

I assume 20Kbps isequal to 20KHz (?) so i used 10 instead of 1000 for the clock. I’m no hardware guy and i think we need a lower level support. The code i have provided should work… Things that i would like more expirience members to anwser:

Should this be done or does the CPU or SPI implementation pull up those pins automaticaly?

It’s 2:00 am here so excuse me for this question, but what is the MISO/MOSI voltage level, is it 0-5 or 0-3.3 ?


#14

Maybe change the code with something like this and use debug to see the value of initResponse after the WriteRead executes. I’m not sure which combination of Pin 7 and Pin 8 is valid so try both.

var initRequest = new byte[] {0x88, 0x33, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00};
var initResponse = new byte[initRequest.Length];
spi.WriteRead(initRequest,initResponse);

#15

It looks like 7 + 8 are 0-3.3v

raising the clock speed to 10000 returned 2 different values for ack (1) and status (255) - it’s probably not significant but who knows,

Edit: don’t go crazy trying to solve it if it’s 2am, I’ll try out what you suggested and report back, thanks a ton :stuck_out_tongue:


#16

Edit: ok maybe I got a bit excited, I’m not able to reproduce it so I think it was a false positive.
I have a feeling I need to set up the 5v pull-up resistor for the MISO as per Gralin’s response:
“INS side Gameboy (SOUT GBPrinter side) must be pulled to 5V by 15kOhms.”

Am I correct that the max pull-up per pin is 2.2k? it seems to be floating 2.3v according to my meter (isn’t it supposed to be 3.3v?)
I’m going to try to figure this out tomorrow, but any tips/tricks would be greatly appreciated!


woo!

Using mainboard GHIElectronics-FEZSpider version 1.0
System.Byte[]
Ack = 129
Status = 129
SUCCESS

#17

It worked? What did you change/add?


#18

I’m kicking myself so hard because I didn’t immediately run it again with the debugger to watch it. However, I couldn’t get it to return a success again. Now I’ve started watching the debugger on every run, But I’ve been so obsessively fiddling, that I’m starting to get mixed up on things I tried and things I didn’t.

Anyway, here are some different debugger dumps I’m just messing around with different variables, a lot of times, running it twice might not even give the same ack value twice:

(this one is the same as sent)


initResponse [8] = {136,51,1,0,0,0,1,0}


initResponse [8] = {136,51,1,0,0,0,1,7}

(higher clock speed)


initResponse [8] = {255,255,255,255,255,192,1,0}

It really varies a lot but I just can’t get it to validate again.


initResponse [8] = {136,51,1,7,255,255,255,255} 


#19

I found the official programming manual, printer stuff starts on page 233

Thanks again for your input so far!


#20

I would try this:

[ol]Send all data as one array (expand the request with those two 0x00 bytes) and see what is the result
Send all data byte by byte and print response to each sent byte
Replace 0x01 (both) with 0x0F and to the above (0x01 is init comand and 0x0F is null command)[/ol]