Anyway for RC5 decoding on the RasPI you could use LIRC.
Looks interesting. Software solution should work too, and requires no soldering or extra stuff. I might go for LIRC if it does not work, we'll see !
LIRC is a software solution! You will not need hardware since you'll be dealing with the electric signal (*) and not with an IR remote.
(*) That is if you are going to use (or replicate) the port of the Palcom.
Ah, my bad, I first sumbled on a page with a little PCB and stuff when googling for it.
I'll need to use the Palcom port, the IR remote solution would work only partially because the Laerdisc is sending some data back to the MSX ("stop playing" & "command processed"), so some wires are required, at least from the Laser unit to the MSX.
Capturing the NEC IR signal using PC line-input works. I plugged GND and pin 7 (EXT CONTROL) to the right channel of my PC audio line-input, typed a "call ld" command on the Palcom and got this result:
Does seem to match what's described about the NEC IR protocol:
Will also try to have a look at how openMSX handles that (is it using a real low level emulation with signal analysis or are there some "shortcuts" ?).
I received my Raspberry Pi last week (choosed a recent model 2 version). Some wirings are needed to get the audo and composite signal correctly from the 4 poles jack plug:
But it finally works:
The default "omxplayer" video player can be controlled from an external application, using the dbuscontrol protocal, so I might not even need to code something new for video.
The NEC IR signal decoding works, you just need a diode and resistor to avoid frying your Pi or MSX (or both):
That's the commands / address pairs I'm receiving when doing a "call ld" from BASIC:
Code to do that is super-simple on the Raspberry using the wiringPi library:
#include #include enum { DELAY_LEAD, DELAY_SPACE, DELAY_LONG, DELAY_SHORT }; typedef enum { STATE_LEAD, STATE_SPACE, STATE_DATA, STATE_FOOTER, STATE_SUCCESS, } tdState; #define SAMPLE_LENGTH_US 12 #define LEAD_LENGTH_US 9000 #define SPACE_LENGTH_US 4500 #define LONG_LENGTH_US 1687 #define SHORT_LENGTH_US 562 /* ======================================================================================================================= ======================================================================================================================= */ char cGetDelay(int iV) { if(iV > (SPACE_LENGTH_US + LEAD_LENGTH_US) / (2 * SAMPLE_LENGTH_US)) return DELAY_LEAD; if(iV > (LONG_LENGTH_US + SPACE_LENGTH_US) / (2 * SAMPLE_LENGTH_US)) return DELAY_SPACE; if(iV > (SHORT_LENGTH_US + LONG_LENGTH_US) / (2 * SAMPLE_LENGTH_US)) return DELAY_LONG; return DELAY_SHORT; } /* ======================================================================================================================= ======================================================================================================================= */ void itoan(unsigned int i, char b[], unsigned char base, unsigned char length) { /*~~~~~~~~~~~*/ char *p = b; /*~~~~~~~~~~~*/ if(!length) { /*~~~~~~~~~~~~~~~~~~~~*/ unsigned int shifter; /*~~~~~~~~~~~~~~~~~~~~*/ shifter = i; do { ++p; shifter /= base; } while(shifter); } else { p += length; } *p = '\0'; do { p--; *p = (i % base) + '0'; if(*p > '9') *p += '@' - '9'; i /= base; } while(p > b); } /* ======================================================================================================================= ======================================================================================================================= */ int main(void) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ int count0 = 0; int count1 = 0; int previousInput = 0; int newInput; int iBitCount; unsigned int uiPreviousTime; unsigned int uiData; tdState eState; char buffer[9]; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ wiringPiSetup(); pinMode(2, INPUT); pullUpDnControl(2, PUD_DOWN); while(1) { eState = STATE_LEAD; do { uiPreviousTime = micros(); newInput = 1 - digitalRead(2); if(newInput == 1) { count1++; } else { count0++; } if(previousInput != newInput) { if(newInput == 0) { count1 = cGetDelay(count1); switch(eState) { case STATE_LEAD: if(count1 == DELAY_LEAD) eState = STATE_SPACE; break; case STATE_SPACE: eState = STATE_LEAD; break; case STATE_DATA: if((count1 == DELAY_SHORT) && ((iBitCount & 1) == 0)) { iBitCount++; } else eState = STATE_LEAD; break; case STATE_FOOTER: if(count1 == DELAY_SHORT) eState = STATE_SUCCESS; else eState = STATE_LEAD; break; } count1 = 0; } else { count0 = cGetDelay(count0); switch(eState) { case STATE_LEAD: break; case STATE_SPACE: eState = STATE_DATA; uiData = 0; iBitCount = 0; break; case STATE_DATA: if((iBitCount & 1) == 1) { iBitCount++; uiData >>= 1; if(count0 == DELAY_LONG) uiData |= 0x80000000; else if(count0 != DELAY_SHORT) eState = STATE_LEAD; if(iBitCount == 64) eState = STATE_FOOTER; } else eState = STATE_LEAD; break; case STATE_FOOTER: eState = STATE_LEAD; break; } count0 = 0; } } previousInput = newInput; while(micros() < uiPreviousTime + SAMPLE_LENGTH_US); } while(eState != STATE_SUCCESS); itoan((uiData >> 0) & 0xFF, buffer, 2, 8); printf("AddressN: %s\n", buffer); itoan((uiData >> 8) & 0xFF, buffer, 2, 8); printf("AddressI: %s\n", buffer); itoan((uiData >> 16) & 0xFF, buffer, 2, 8); printf("DataN: %s\n", buffer); itoan((uiData >> 24) & 0xFF, buffer, 2, 8); printf("DataI: %s\n\n", buffer); } }
I now need to figure out what are the voltages send from the LD-700 to the MSX when a command is aknowledged or when something stops playing. And also send the good commands to the omxplayer through dbuscontrol when something is received from MSX. Maybe something could be demoed at Nijmegen this year.
Some open questions I have now (well, would'nt mind some help on this ):
- How to interpret the command / address pairs I'm receiving from the MSX ? That should be somewhere in the openMSX sources, but where ?
- Are the .OGV files used by openMSX indexed in some ways or are the jumps made to direct timings in the video ?
- What are the voltages used by the PLD-700 for the EXT/STOP & ACK signals ? The Raspberry can send 3.3V positive voltage through GPIO, not sure if that's enough if the MSX expects 5V logic signal ? And is the polarity even OK ?
Check this from line 160: https://github.com/openMSX/openMSX/blob/master/src/laserdisc... for info about remote control signals used
http://openmsx.org/manual/setup.html#laserdisc for info about the special index coding in the OGV files
HTH...
HTH...
It definitively does, thanks a lot Manuel
It works, Badlands is quite playable. Here are some pictures of the thing, it just needs to be plugged on a Palcom MSX instead of a real Laserdisc player:
The little diode on the side blinks when commands are sent from MSX to PiLD.
I'll post a video of Badlands tomorrow.
A small video of me playing Badlands with PiLD. Use to go further in the game but it was late, my cowboy senses were not too sharp...
PiLD - Playing Konami's Badlands Laserdisc game
Yeah, I know, a simple joystick is enough to play the game, but the Sega gun is definitively enjoyable, even if you don't need to aim at the screen :)
I'll give a little break on this project (need to polish the new SofaRun before Christmas) but I will demo it at Nijmegen. Maybe we could even make a small Badlands contest during the day ?