Search the Community
Showing results for tags 'vintage lego'.
-
Dear All, strongly motivated by Evan Koblentz’ (@evank) “9750 LEGO Interface A hacking challenge” announced here on EB (https://www.eurobricks.com/forum/index.php?/forums/topic/195711-a-challenge-lego-9750-interface-a-hacking/), I wandered into the Atari ST world, looking at the ST’s hard- and software for the first time in my life – never had the chance to play or work with one of these beauties back then. Found three of them in “the basement” of my research institution’s labs, and one of them worked flawlessly (the other two need a little attention, as they throw bombs when booting up). Executive summary As already briefly “announced” in the referenced challenge thread: I managed to get the Atari’s “a-bit-special” 8-bit parallel port (it is fully bi-directional, but has only two control lines, strobe, STR#, and BUSY) with the help of just one (ancient) 74LS273 TTL chip, some resistors, and a 5V power supply, to operate the 9750 LEGO Interface A from 1986/7. This is a brief write-up of how I found out how the I/O hardware protocol of the Atari ST works, when using GFA BASIC 3.0 as programming language (1988). GFA program(s) and interface schematic are here: https://bricksafe.com/pages/Toastie/atari-st-and-9750. Video to follow, I am running a little short of time at the moment. Here we go, another long vintage LEGO story … According to the three challenge rules, Evan posted in the above referenced thread, namely Use any computer and any programming language you like, as long as it was for sale in 1992 or earlier (as the next-generation 9751 / Interface B debuted in 1993.) Don't use any add-on hardware that was not available back then. A breadboard is fine; an Arduino is unacceptable. It's okay to run emulators if you do not have original machines, but you can't use any additional features that did not exist back then. You can use Windows 1.0 or 2.0, but not 3.1 libraries, etc. I became very happy after reading that, as an Atari ST qualifies as a legit computer system in this challenge! My ST is from 1987 - and it features a parallel port - which gave me hopes that I can probably get this >68000 CPU loaded 32-bit power machine< (running at 8 MHz CPU clock speed with 1Mbyte of RAM available!) to controlling the 9750 LEGO Interface A. As Arduinos and the like are not allowed for interfacing, nor using any hard/software produced after 1992, I was dreaming of TTL world, as I did when I was more than 35 years younger. What did I have at my disposal for coming up with an Atari interface (that also met the three rules of the challenge)? An Atari 1040 ST(FM) (1987) with parallel and serial port GFA BASIC 3.0 (1988) with access to serial, parallel, and MIDI ports A good number of TTL chips saved from being trashed; they all date back from the 1980’s Soldering gear, an oscilloscope, multi-meter, bread board, resisitors, LED's … I began initial programming using the ST’s serial port. After all, I first had to learn GFA BASIC, and how GEM works, and so on, and so on. Never used an Atari before June 2023. I more or less “copied” (well typed in) my working DOS QuickBasic routines controlling 9750 on an IBM XT (https://bricksafe.com/pages/Toastie/lego-interface-a---9750---9771---tclogo/program-files-) into GFA BASIC – with – “some” limited success. The thing is, the Atari’s serial port has I/O buffers; the IBM XT has not. When garbage accumulates in these buffers, my Arduino “protocol” is seriously screwed up. This “protocol” does this: Send a byte to the Arduino over serial (RS232) or UBS and then immediately listen to the reply. After conversion to parallel on the Arduino, the sent byte sets the 6 outputs of 9750; the Arduino replies back the output states of 9750 in addition to the two sensor input states. This is the protocol (send and immediately receive one byte) TLG used on the IBM XT with the LEGO 9771 interface card as well, and (I believe) on all other LEGO endorsed platforms also. It turned out that the two GFA BASIC functions "boolean=OUT?(port,byte)" and "boolean=INP?(port)", which are replying the status of the ports as FALSE=busy or TRUE=available, did not really work as expected using the serial port (AUX: or “1” in GFA BASIC). In a hardwired “client/server” setting (client=Atari, server=Arduino), it is all about initialization. Once that is done, nothing much can disturb the communication other than programming errors. In other words: Whatever garbage is in the serial out buffer upon startup: just dump that. Then do the “LEGO style initialization process”: OUT 1,bin0010101; var=INP(1); IF var AND bin0011111=bin0010101 then hardware is present and works. And that worked very well on the Atari; 9750 was controllable with an Atari ST via its serial port with the help of an Arduino Nano as serial2parallel converter. SUCCESS!!! BUT, BUT, BUT: CHALLENGE RULE #2 says: Don't use any add-on hardware that was not available back then. A breadboard is fine; an Arduino is unacceptable. !BUSTED! Well, back to the drawing board. Atari forums and other websites note: The parallel (LST: or “0” in GFA BASIC) port of an ST is somewhat “special”: It lacks some control lines most printer ("Centronics") ports and parallel printers featured back in the days, such as an acknowledge (ACK) line, among others. The ST’s parallel port has (only) a “strobe” (STR#) and “busy” (BUSY) control line, the eight bit D0-D7 lines, and ground. That was good enough for most 1980’s printers, so in essence all was fine … Much more importantly, you can write to AND read from the parallel port using ALL 8 DATA BITS! WOW! As there is no reason to read the 8 bits from a printer, these Atari folks had certainly something else in mind than just printing from the parallel port. Third: Data copied to the parallel port are “transient” of nature, as the Atari operating system uses the 8 in/outputs for other purposes as well, according to Atari forums. And the internet tells you: Fast parallel data exchange via the Atari parallel port possible, using special cables, protocols, hardware, and software. What to do with that rather confusing information? Not much. Well, what did help me, was getting hold of the Atari ST PCB schematics, breaking out my good old Tektronix oscilloscope, solder/crimp a 25 sub-D connector style parallel cable (using only 11 lines: STR#, D0-D7, BUSY, GND), run GFA test programs, and poke around a bit with the two oscilloscope probes ... It quickly turned out that the Atari sends out data over the parallel port when using the GFA BASIC “OUT 0,byte” command only when BUSY=LOW. That is fully in line with the early Centronics “compliance mode” protocol: Check the BUSY=LOW condition, when that is/becomes true, put data on the data bus, assert a HIGH,LOW,HIGH) strobe (STR#) pulse of some microseconds length (Atari: 100 us), on the negative STR# slope, data are clocked into the printer, which in turn asserts BUSY=H, and when ready again, asserts an ACK LOW/HIGH/LOW pulse and then pulls BUSY to LOW again. The Atari however is lacking the ACK line; if BUSY is HIGH (=device not ready, see below though! This changes later to: BUSY=HIGH=external device ready for providing data and BUSY=LOW=external device ready for accepting data), it waits some 30 seconds and tries again before eventually timing out. The schematics of the Atari ST reveal that it’s parallel port is operated bi-directionally by the Yamaha YM2149 “sound chip” – but that chip it is much more than that: It features, among other things, two 8-bit wide I/O ports, one of which is used for the Atari parallel port; STR# is provided by one line of the osecond YM2149 I/O port, BUSY is connected to input “I0” of the Atari’s 68901 multifunctional peripheral chip. Note that the BUSY line is literally “bolted” to +5V via a 1kOhm resistor – pulling it LOW (< 0.8V!) needs a solid TTL LOW signal. All lines of the two I/O ports of YM2149 are internally pulled-up HIGH; according to the YM2149 datasheet with 60kOhm minimum resistance – here a grounded 4.7kOhm resistor should be OK to get below 0.8V = TTL LOW – 2.2kOhm should be on the safe side. Next step: Testing GFA BASIC simple input/output testing routines and record changes in the STR# and BUSY lines. BUSY was clamped to LOW and repeated OUT(0,byte) write data attempts in a simple for-next loop were performed: Worked fine. The oscilloscope trace of the STR# line is depicted schematically in panel A), top trace, in the figure below. All seems to be in line with the Centronics protocol. Check! Performed INP(0) read data attempts with the same setup – but nothing happened! Program froze up immediately, no break (CTRL+ALT+SHIFT) was possible. However, simply removing the LOW clamp from BUSY and letting it “float” (well, see schematic above, it is pulled-up via 1kOhm to +5V = HIGH) reanimated the program >instantaneously< and the upper trace in panel B) was recorded when repeatedly reading the data lines with INP(0). Check! But then … … I thought “strange” … when does the presumably negative slope trigger on the STR# line for OUT (according to the Centronics protocol) “transition” to a positive slope trigger for INP? It did not make much sense. Google was also not helpful, even after hours of searching. Which left me with: Trial and error. I love trial and error. At some point, I arbitrarily connected STR# and BUSY – did not work either, program froze again up. When trying repeated OUT commands that is. As said: Deep in trial and error territory I was. However: In retrospect, this could of course not have work but revealed the following: When turning the computer on, loading GFA BASIC, running the program, the first OUT command worked, a second did not. The oscilloscope showed: Initially (STR# + BUSY) = L. And then OUT works??? What??? This means, that a >positive< slope of STR# is supposed to clocking the data into the external device! Not the negative slope, as the Centronics protocol suggests. After the first OUT command, (STR# + BUSY) = H, so a second OUT cannot work. But an INP should – and did! After that step, (STR# + BUSY) = L again, and another OUT works etc. This also means that INP reads data on a >negative< STR# slope. The trace on the oscilloscope obtained with repeated OUT/INP loops are depicted in panel C) in the figure below. At that point, the “rules” for operating a dumb device (dumb=providing/having no control lines) >bi-directionally< using the Atari’s parallel port became rather clear: STR# + BUSY = LOW on initial OUT/INP sequence. This is straight forward: Gather the status of BUSY using OUT?(0); if FALSE then BUSY is H; if so, do one byte=INP(0) and simply dump returned byte; now BUSY=L and “endless” repeated OUT/INP sequences can be done: As the OUT data are “lost” on the parallel I/O lines at some point (according to the Atari forums after a few ms), and at latest, when reading the lines with INP, they need to be latched on the >positive< slope of STR#, see above. TLG used transparent 8 bit D-FF TTL latches with tristate outputs (74LS373) on their 9771 card. This fancy approach is not possible here, as there is are no dedicated IORead# and IOWrite# lines available, there is only “one” line (STR#=BUSY) for clocking data in and reading them out. For that purpose 74LS273 is a perfect match: 8 non-transparent D-FF TTL latches, having always logical defined outputs (L or H); all logical levels at the 8 D inputs are latched with a positive TTL slope at the CLK input and immediately show up on the 8 Q outputs. A negative slope at CLK does nothing, so when reading data with INP(0), nothing happens to the 8 Q (output) states of 74LS273. As all this is securely happening “behind” an I/O chip (YM2149) and not directly on the CPU’s data bus, and as we know that there are 60kOhm pull-up resistors on each parallel port data line, we can use a dirty trick to feed-back the Q output states of 74LS273 to its D input lines via 2.2kOhm resistors: In output mode, YM2149 easily drives the D inputs of 74LS273 to H/L, even when the corresponding Q outputs are L/H; the 2.2kOhm resistors prevent any harm: The maximum current flowing, when D=H and Q=L is 5V/2.2kOhm = 2.2mA. Each output of 74LS273 as well as each output of YM2149 easily sink/source that current (BTW, 10kOhm feedback resistors don’t work, as the voltage on the D line does not drop to or below 0.8V when Q is L. The YM2149 does not know what to do with such a voltage; it simply says it is still H, as tested). This approach of using resistors within the 8 data lines between an external device that can read and write and the Atari’s parallel port as security measure is widely known in corresponding websites and forums, see for example here: http://info-coach.fr/atari/hardware/interfaces.php#if_parallel. Finally: The two sensor lines of 9750 are routed to the D inputs 6+7 of 74LS273; on each OUT/INP sequence, the corresponding Q6+Q7 data become available to the program running on the Atari: The OUT command clocks the data in, the INP function reads them in (in addition to D0 to D5). And that’s it. Here is the schematic for the “interface” (= one 74LS273 + 8 x 2.2kOhm resistors + 5V power supply, which is not that much of an “interface” …). +5V power may be obtained from the Atari main board (this is a bit on the invasive side) or from any generic +5V power supply. Shown in the schematic is a stone-old 7805 regulator, which can be fed with DC power from +7 up-to +25V, +12V recommended. The LED’s are purely optional; with them you don’t need to connect the 9750 interface A but will have the same light show ;). The 1uF/10kOhm RC combo on the RES# input of 74LS273 ensures that it does not arbitrarily “flip flop” during power up. The very old TTL “trick”, I know. Also optional – upon initializing the parallel port, all is fine. In that case, just connect RES# to +5V. And here is the tidy, very organized and (or better but ...) working breadboard version of the Atari parallel I/O interface for controlling LEGO Interface A. As far as I know such a thing does not exist - correct me if I am wrong though!!! More on programs I am using for controlling 9750 per key clicks or per “user programs” in subsequent posts in this thread. All the best, Thorsten
- 15 replies
-
- technic control
- atari 1040 st
-
(and 2 more)
Tagged with:
-
Dear All – just another “vintage LEGO” post … Summary Letting the CodePilot directly look into the light of one of the output LEDs of LEGO Interface A (#9750) makes it happy: A QBasic program for uploading even more complex VLL scripts to this PBrick using only original LEGO hardware (from the 1980’s ) 2 resistors, 2 diodes, 1 red LED, and ½ CD4013 ;) for a total of less than $5: A “serial interface” for directly uploading programs to the CodePilot or the MicroScout PBricks via their VLL optical port using any (ancient to ultra-modern) computer with a serial (and/or USB port). A QBasic program for comfortably interacting with both PBricks via a serial/USB or parallel port, or the #9771 LEGO ISA interface card. It runs on DOS 3.3 machines with real RS232 ports all the way up to Win11/64 bit machines within the DOSBox-X emulator via USB-to-serial adapters without any change to the program, just pressing keyboard buttons required … (See below for details) Video: QBasic program for uploading and running the “Garbage Truck program” (as provided in the Technic CodePilot manual of the Technic set #8479 to the CodePilot PBrick) using an Interface A (#9750) and an IBM XT, controlling the MicroScout, and using a very simple serial VLL interface based on one CD4013 D-flip flop as described further below in this post. Two serial “interfaces”: Today’s modern USB-to-TTL adapter + ½ 74LS74 (top) and 1980’s CMOS (CD4013, bottom) chippies, wiretapping the RS232 lines DTR, GND, TX, no power supply required. Preliminary bread board versions running on RS232 power delivered by the DTR line. Left: “TTL” with 78L05 and 74LS74, Zener diode protection at the D input, diodes for wrong polarity protection; right: “CMOS” with CD4013, no voltage regulation required as the 4000 (B) series runs with +3 … +18 V. (yeah, there always is …) Introduction Decades ago, the LEGO VLL (visible light link) protocol was “deciphered”. In 2000, I heard about it when Doug Eaton posted his findings on programming the MicroScout on lugnet.com (https://news.lugnet.com/robotics/?n=9932; the website mentioned in this post doesn’t work anymore, Doug’s content is “now” here. In 2004, I copied the VLL barcode sheets Doug prepared as postscript file and kept them in a safe place). When I got my Robotics Discovery Set featuring the SCOUT in 2001, the SCOUT software development kit (SDK) became available through LEGO as well. The documentation for the SDK has a list of VLL codes available for controlling/programming the MicroScout PBrick and programming the CodePilot PBrick. The LEGO Mindstorms SDK2.5 (still available here) has a full documentation of the VLL codes, the VLL serial protocol (timing), and much more. There are many ways of generating the (serial) optical VLL code bit stream, which per VLL instruction is comprised of a start bit, 3 checksum bits, 7 data bits, and a stop bit: Any of the RCX PBricks (1.0, 1.5, 2.0) flashed with the LEGO firmware that came with the RCX2.0 (still available here, with an even newer version: https://pbrick.info/index.html-p=74.html), or the SCOUT, or all Spybotics PBricks, natively speak VLL. It also works with Arduinos, ESPs, Feathers, and so on and so forth; there are myriads of links on how to create and send VLL commands to the corresponding PBricks. However, I could not find any references regarding – guess what – running QBasic (on any DOS machine) and more importantly – using the serial port as “LED VLL driver”. Why the serial port? Because it is fun to do so, because it is serial as well ^^. The Recommended Standard 232 (or RS232) was introduced in 1960, and even today lives a very happy life. Folks this is more than 6 decades - as old as I am. Serial also means that I can use my Win11 laptop to “code” and test QBasic programs, before copying them to my IBM XT; all I need is a USB-to-RS232 converter on my Windows machine. Generating VLL bit streams via a true parallel port is even simpler than via a serial port: Only one of the 8(+) parallel lines available needs to be turned on and off – however, parallel ports are gone. The IBM XT and virtually all the other 8-bit wonders feature such a port of course and they can generate VLL bit streams (plus driving an LED) literally out of the box; the additional hardware required is a resistor and an LED. If you want to have it more fancy, just throw in a DB-25 pin connector of which 2 pins are populated; GND and one of the 8 data lines. And yes, there is the beloved #9750 Interface A with its 6 outputs. The LEDs indicating the port status are perfectly suited for emitting VLL codes. All one needs is either a LEGO #9771 ISA card and IBM (compatible) computer or any of the 8-bit wonders having a compatible interface of which I made some (link to Evan Koblentz website). Here is the CodePilot PBrick "resting" on Interface A. Its sensor looks directy into the #output 5 indicator LED used for programming. The 4.5V light brick is also hooked-up to port #5 showing the port status: It needs to be on when VLL programming begins, as the VLL start bit ist "light off"). The light bricks itself has a little light blub inside - the filament is too slow to generate sharp enough 20 ms flashes. An LED with 220 Ohm resistor works also perfectly well for VLL programming using Interface A: A close-up of the sensor position: This is the little bracket holding the CodePilot PBrick in place (it just slides in) - the odd angle of the surface of Interface A makes it a bit slippery: On modern machines, USB-to-TTL adapters work of course as well (see end of this post) but they are not “compatible” with serial ports of the pre-1990 era as they were not invented yet … and thus violate my guidelines for developing LEGO control programs. These guidelines are copied with small changes from Evan’s (@evank) challenge rules posted, see link above: Program must run on computer systems available before 1990 Computer must run operating systems and software published before 1990 Only contemporary and simple hardware additions are allowed to interact with the LEGO device BASIC is the programming language. Yes, BASIC. No C, C++, Python, Java, ALGOL, COBOL, PASCAL (although …), FORTRAN (although …) – no, it is BASIC. Experimental, results and discussion My test rig is an IBM XT from 1985 (two 5 ¼” floppy drives, each 360k, no hard drive, serial, parallel, and 9771 LEGO interface, CGA card) running DOS 3.3 as operating system, and QBasic1.1 as programming software. Yes, using the IBM’s parallel port would have been also possible, but then I can’t use any modern computer, e.g., my Win11 laptop (running DOSBox-X as DOS emulator) for programming and testing, as the parallel ports are gone since long and USB has taken over. With a USB-to-RS232 adapter, I am essentially back in the 1980’s (and even way earlier ...). The LEGO VLL devices I like to program are the MicroScout and the CodePilot PBricks. Programming means writing and storing “VLL scripts” on a computer and then uploading them to the PBricks. This is the same approach I am using for my LEGO Control Center II (#8485), or LEGO Interfaces A/B (#9750, #9751). Using plain vanilla QBasic/DOS imposes another challenge: The minimum time delay directly available in this environment is bound to the 55.6 ms (1/18 s) timer clock, which is simply too long for VLL bit stream generation. VLL is composed of 20 ms time sliced signals: A VLL logic “1” is represented by 20 ms light and 40 ms dark, a “0” by 40 ms light and 20 ms dark. The start bit is 20 ms 0 = dark, preceded by at least 400 ms 1 = light, the stop bit is 20 ms light, 60 ms dark and 120 ms light; this is all well documented, see refs. above. There are multiple ways generating shorter time “delays” than 55.6 ms in DOS/QBasic, e.g., zapping the programmable interrupt timer, using machine code, and so on and so forth – I’d like to keep it stupidly simple: I am running a loop 10000 times and the determine the time it required to finish. Which of course leads to rather different execution times on an IBM XT vs a Dell Precision: The XT executes about 120 “empty” FOR:NEXT loops in one ms as compared to several hundreds of thousands of loops when simulating a Pentium system in DOSBox-X. There is an easy way out: Calibration. What I simply do is: DIM t, dt as DOUBLE: DIM i as LONG t = TIMER ‘store seconds since computer was turned on FOR i = 1 to 10000: NEXT i dt = TIMER – t ‘seconds elapsed after 10000 loops dt/10 = time in ms for one loop – now I can calculate the number of loops required for a 20, 40, 60 etc. ms delay. Works on the IBM and on the Dell/DOSBox-X emulating a 386 system quite precisely. When emulating a Pentium – well that simply leads to division by zero errors and long integer overflows. But I simply don’t care about these systems. I am a Boomer. I usually let DOSBox-X emulate a 286 system running DOS3.3. “Synthesizing” the VLL bit stream and sending it to the RS232 serial port (or USB-to-Serial adapter, same thing) is straight forward: I am setting up a COM port with 9600 baud, 6 data bits, no parity and 1 stop bit. 9600 baud is the maximum an XT can handle without zapping its UART, which is not necessary. The 6 data bits are just for being compatible with Interface A; I made an Arduino based serial to parallel interface, so the present QBasic program does handle that as well, when connected as "serial". To make this as simple as possible, I am not using any RS232-to-TTL signal conversion, e.g. with a MAX232; that would require an external power supply. I am running everything entirely on the RS232 signal side: Here valid voltage levels are +/-3V to +/-15V. All USB-to-RS232 adapters I have, work with close to +/-9V signal levels, the IBM Asynchronous Communications Adapter (=serial card ) works with +/-12V. I am using the DTR (pin 4) and GND (5) line as power source as there is only one LED I need to drive. DTR remains high when hardware handshaking is disabled. When “idling”, the RS232 TX serial line is low; note that this is inverted on the TTL/UART side of things. A (idle=low-) high-low RS232 level pulse is generated by sending &H20, which is binary 00100000, but only 6 bits are transmitted. Since the least significant bit is sent first, this method generates one low-high-low pulse: The serial protocol on the RS232 side is start bit = high, 5x 0 = high data bits, the 6th low bit and then the (low) stop bit (and the other way around on the TTL/UART side). At 9600 baud, the time between the TX line going high and low again is 1/9600 *(1+5) = 0.625 ms, which is much shorter than the minimum duration time for VLL pulses (20 ms). Each of these &H20 transmissions represents a trigger signal for the additional “hardware” required, which is a ½ CD4013 dual D-flip flop/latch (there also two protection diodes, two resistors and one LED). One of the two D-latches in the 4013 CMOS chip is set-up as toggle flip flop (or divider-by-two) by connecting its Q# output to its D input; each time a positive slope on the clock Clk input arrives (i.e. from the TX serial line), it flips its Q and Q# outputs. The Q# output of the toggle flip flop drives a red LED via a 1kOhm resistor which generates enough light for the CodePilot/MicroScout VLL sensors. The max. current flowing in this setup is less than 10 mA through the LED; the 4013 does not burn any noticeable power. Such a current source/sink is safely available on most serial ports and USB-to-serial adapters and for sure on true serial ports. I believe the IBM card can power street lights … ok, maybe not, but its armored with SN75150’s, sourcing sustained >20 mA on RS232 high and sinking 10 mA on RS232 low level (which I do not use). This is a schematic of the – uhm – “serial VLL interface” using the CD4013 (the 10uF capacitor is a pure luxury item - I thought is would look fancier, but did not use it): This is the timing. All what happens is dividing the input clock (positive slope) by two, however the duty cycle of the clock changes widely (as per VLL protocol) – this is the main reason I could not find a way to directly using any Baud rate/serial protocol combination: QBasic program See UI screen shots above; the program has a simple user interface with the arrow keys “navigating” the codes, RETURN fires the VLL code through the serial port and the LED does happy blinking. “U” calls a “user program” for upload. “V” toggles between the code table for MicroScout and CodePilot. The CodePilot sounds OK, NotOK, or the actual sound (truck, valve, robot …) or tone when it received a corresponding VLL code, thus there is a 1s delay between consecutively sent VLL codes, otherwise the CodePilot misses every second command. The MicroScout acknowledges a received VLL programming code with a short beep, thus the delay is not necessary. It also has direct commands for immediate execution, which the CodePilot has not. A program sequence of: a = &H3F8 ‘serial port 1 address o = &H20 OUT a, o DEL20 ‘subroutine: calibrated number of FOR/NEXT loops for 20 ms OUT a, o generates a “calibrated” LED off-on cycle of about 20 ms; the LED is on when “idling”. And with that, the VLL codes can be assembled. The 3 checksum bits (cf. https://www.elecbrick.com/vll/) are calculated each time rather than being hard coded, as I like to interpret the VLL codes as 7-bit decimal numbers for reference. Many sources for VLL code generation have each instruction in the form of a 10 bit hard-coded bit stream (as on the code sheet provided with set #8479); I prefer to “synthesize” things on the fly. The checksum encoding is also available on Doug’s website and consists of some bit shifting. Programs are stored as list of VLL commands in “user programs” A, B, C, … for convenience, I just defined a rather long list of integer constants, e.g. CONST CP.MOTOR.FWD 0, to make programming a little more reading friendly. As others have reported, the CodePilot programming language is essentially comprised of ACTION [SPEED, DURATION] "lines of code", where the latter two arguments are optional. SPEED can be 20, 40, 60 or TACHO, see below. DURATION is .1 to 99. TOUCH IN/OUT halts the program but does not stop an ACTION, this is what STOP (output) or MUTE SOUND (sound) does. There are more nuances but that is fun to find out. The VLL LED needs to be “on” before any VLL code submission; should it be off after program start, pressing “T” turns it on. It does not work the other way around, since the start bit is “light off” for 20 ms … This way I just saved on hardware cost ;) by not adding a reset switch and attach that to the reset input of the 4013 … all inputs other than D(1) are tied to ground. There is also a software pulse generator (activated/deactivated by pressing “P”, frequency change with “+”/”-“ keys), which is useful for testing the sound pitch or output power on a LEGO model operated by the CodePilot PBrick. The CodePilot can use its light sensor for scanning the bar codes also as a “speedometer” or “tacho”. The faster dark/bright changes are detected by the sensor, the higher the pitch of a sound, e.g., sound motor (diesel engine) or the power of the 9V output port. In the CodePilot models which can be built with set #8479, this is accomplished by rotating the #32060 “Technic Gear Timing Wheel 8 Tooth” directly in front of the bar code sensor. I have inspected the behavior of the CodePilot PBrick TACHO function a little closer using the “pulse generator” built into the QBasic program. There are the typical 7 power levels (0 = off), which are enabled with the following frequencies (50% duty cycle, as this seems to be what the #32060 wheel does as well when reflecting the light from the red built-in LED back onto the sensor): The red dots are the calculated frequencies with QBasic (“calibrated” delays), the blue dots are from oscilloscope data I have taken. Power level 7 is reached at about 30 Hz and maxes out. There is of course some jitter and frequencies are slightly off when using the program – but hey, this is emulated DOS in DOSBox-X running a QBasic program in its UI … I’d say not bad and congratulations to the developers of DOSBox-X The sound pitch reacts in even narrower steps – it maxes out at about 24 Hz with the lowest pitch at 1 Hz. The 20, 40, 60 VLL SPEED commands seem to reasonably agree with the regression line, e.g. SPEED 40 = power level 7 * 40%. When using the serial signals on the TTL/UART side, they are inverted and go (high)-low-high – which is irrelevant for the D-flip-flop; it triggers on any positive slope. Since there is only one such slope per “&H20 pulse” and the delay until the next pulse is calibrated, it works perfectly well "on both sides", RS232 or TTL/UART. Summary The CodePilot is a very nice PBrick – the predecessor of the RCX (almost same footprint, one plate less in height, same battery cover and battery power leads, released one year before the RCX – I strongly encourage you to read Blackbird’s Technopedia entry in full (already referenced above) – he is saying what this set and PBrick deserve as a tribute: “Nothing like this set had come before, and nothing like it would ever come again …”. The MicroScout is one sweetheart – its beeping before executing an instruction or when done is really sweet (some say annoying but what do they know). DOSBox-X totally rules, QBasic will live forever – as will the serial port and protocol in its RS232 incarnation! As usual the QBasic program (as QVLL_3.BAS/EXE) and more is on BrickSafe (https://bricksafe.com/pages/Toastie/vll-codepilot-microscout), changes to the code will not change the program name. Have fun Thorsten
- 6 replies
-
- vintage lego
- codepilot
-
(and 2 more)
Tagged with: