Jump to content

Toastie

Eurobricks Dukes
  • Posts

    3,991
  • Joined

  • Last visited

Everything posted by Toastie

  1. Hello @maehw, it was the last diagram, and it is of course wrong in that place as 0x10 is not 0000 0010 sorry for that, will clear that up when I find the damned diagram. In my QBasic program to speed up things a lill bit, I don't even check for any value other than 0, as I never found any other information in that byte. I shall correct that! Thanks again for noticing! All the best Thorsten
  2. Wait - I believe the Baud rate >needs to be< 2400? And everything else does not work? I was under the impression that the software used to communicate with the CM brick does set the Baud rate to 2400? It does not matter what is in the driver section, as the software you use takes care of that? Best Thorsten
  3. Congratulations! And this is also owing to @BrickTronic! I looked up one's and two's complement on the webs - it still is sooo confusing to me. All websites I found talk about signed bytes/integers. There is even a one's complement calculator website ^^, which works perfectly well, but only in the range 0 to 127 - and of course -128 to 0. There is no -128 on the RCX ...well it depends of course on the universe. On the RCX it is 0-255. In the signed world, where such complements make total sense, it is the same range, but expressed as -128 to 127 ... On the RCX it is simply 255 - x. Which flips all bits. In the signed world, 128 is impossible. But the RCX lives in the unsigned world ... Well. Just cool you got it to work!!!! All the best Thorsten
  4. Not exactly: The one's (here is to @BrickTronic) complement of your checksum is wrong: 0xFF-0x5B=0xA4, if I am not mistaken. Best Thorsten
  5. Hi Jo, I am aware of that - however, a good number of references out there describe it as just that for the RCX: As two's complement. A few years ago, it took me literally days to figure out, how this two's complement should ever work on an RCX. I did not. I figured out though (by intercepting reply messages from the RCX) that 0xFF - 0xYZ does. I did not want to run into trouble and thought "so be it". You are absolutely right, of course! All the best, and so good to have you around!!! Thorsten
  6. Not exactly ... but close: The two's complement is what follows each message byte = opcode and databyte(s). The preamble is always 0x55, 0xFF, 0x00. For the PlaySound opcode (59) the two's complement is 0xFF-0x59=0xA6. Then you send the data byte, let's say for sound 1, and its two's complement 0xFF-0x01=0xFE. Next is the checksum and its two's complement. Checksum for 0x59+0x01=0x5A (only the lower 8 bits are sent, in this case not necessary to strip any high bits), the two's complement is 0xFF-0x5A=0xA5 The entire message for "PlaySound 1" should thus be 0x55, 0xFF, 0x00, 0x59, 0xA6, 0x01, 0xFE, 0x5A, 0xA5 Now, when you want to send "PlaySound 1" again right after the previous "PlaySound 1" or even repeatedly, you have to "toggle" bit #4 (0x08) in the opcode: 0x59-0x08=0x51 and vice versa. This of course also changes the complement of the opcode as well as the checksum and should be: 0x55, 0xFF, 0x00, 0x51, 0xAE, 0x01, 0xFE, 0x52, 0xAD. When you send another command after the first "PlaySound 1" message, you don't need to change the toggle bit. Here is how I assemble my RCX messages (I am using a pure SetMessage protocol for my RCX equipped trains, which is simply train ID + action = 2x consecutive SetMessages), so the first 5 bytes in each message are always the same (preamble + opcode SetMessage + two's complement = 0x55, 0xFF, 0x00, 0xF7, 0x08) then I simply append the message byte. Note that SetMessage (opcode 0xF7) does not need to change the toggle bit, when sending it twice or multiple times: const uint8_t RCXMessageHeader[5] = {0x55,0xFF,0x00,0xF7,0x08}; if (Flag_ComMode == ManualMode){ // Build full RCX message from ID and databyte manually entered for (int i=0; i<5; i++) ZXBytes[i] = RCXMessageHeader[i]; // Preamble + command message //ZXBytes[5] = ID; // From ManualInput. ZXBytes[6] = 0xFF-ZXBytes[5]; // RCX' two's complement ZXBytes[7] = lowByte(0xF7+ZXBytes[5]); // checksum of "real" data bytes in msg ZXBytes[8] = 0xFF-ZXBytes[7]; // RCX' two's complement for (int i=9; i<14; i++) ZXBytes[i] = RCXMessageHeader[i-9]; // Preamble + command message //ZXBytes[14] = databyte; // From ManualInput. ZXBytes[15] = 0xFF-ZXBytes[14]; // RCX' two's complement ZXBytes[16] = lowByte(0xF7+ZXBytes[14]); // checksum of "real" data bytes in msg ZXBytes[17] = 0xFF-ZXBytes[16]; // RCX' two's complement } Forgive me my horrible C++ coding - I am a BASIC person, so I code C++ as if it were BASIC Let me know whether this works (the PlaySound messages) - I started all this more than 25 years ago using MS QBASIC. I still have these programs on my laptop (Win11/64bit - using DOSBox-X) and my IBM XT (PCDOS 3.2) ; they run well on both machines. If not, I shall break out my test RCX, the IR tower and check. Could be that I screwed up the hex numbers above ... Best Thorsten
  7. Sure Firstly, your "command" is not complete. The mralligator page you are using lists "just" bare opcodes. Each of these, including any data byte(s), e.g., "0x01" for sound one, have to be followed by their two's complements (RCX uses: 0xFF - 8-bit opcode or 8-bit data byte as two's complement tc). Then the checksum needs to be appended, which are just the 8 low bits of the sum of all payload bytes (opcode + data bytes), excluding all two's complements, and lastly the two's complement of the checksum. Once you have coded the synthesizing of the entire data packet, it is all smooth and easy: preamble (0x55, 0xFF, 0x00), opcode, tc of opcode, data byte, tc of data byte, ..., checksum, tc of checksum. That is one full RCX command. Don't forget to flip the toggle bit of the opcode, when resending the command. When you scroll down on this post to the "Protocol bit/byte streams encoding" of old LEGO protocols, you'll find details for the RCX in section 4: Best Thorsten
  8. @AJB2K3 This is the place! I think maybe also this link provides some structured info about the Interface B protocol - it was put together some time ago with the help of many people her on EB: There is more further down as well, a bit on A/D conversion and so on. Best Thorsten
  9. Wow, that is strange, I shall try that out. Also, I shall attach my 9V-speed-regulator-to-RCX input interface on CCII/9571. The "regular" operation of CCII is +9V/GND, GND/+9V or open output = stop. If I recall correctly, stopping an CCII output lets the motors float, i.e., both CCII terminals are not connected to GND. Should that work, you can definitely use CCII, as well as 9V train regulators ;) to record programs on 9751. All that just for fun. Will report. All the best, Thorsten
  10. Well, maybe. On the other hand, it is too easy to just use a 9V cable and connect an input of 9751 to an output of 9751 ... but who knows ... Your idea can work, however, only with external circuitry. For further illustration, here I had summarized the input characteristics of 9751: The 9751 inputs have a range of 0 - +5V. Their internal resistance is 10kOhm. They are thus somewhat similar to RCX inputs. Which reminded me of the following: The outputs of CCII are 0 - +9V. So one could use a voltage divider (see below), taking into consideration the internal resistance of the 9751 inputs and keeping track of the polarity: GND CCII out to GND 9751 GND in. The positive wire from CCII (+9V when on, fwd) goes to the voltage divider, and that goes to the other input terminal of 9751. However, the CCII outputs change polarity when going in reverse (using the dial), and now all of a sudden +9V is connected to GND, which is bad. This can also be taken care of; one example is using an external “offset” power supply and a resistor network. This is getting a bit hairy, but it really works; I used that approach for my RCX (also 0 - +5V input range), when I was reading the power levels of a 9V train regulator. The output on that one goes (in steps) from 0 to +9V - when you dial into reverse, it switches polarity as well and goes to +9V on the other terminal pin. So yes, it can be done, needs some extra pieces though - wait, I'll try to find that thing ... man this is old stuff ... --- 30 minutes later --- Here it is: 3x +9V - 0 and 0 - +9V IN to 3x 0 - +5V OUT using resistors and an external power supply (the blue brick is used as terminal, this photo is from 10 minutes ago - as my wife always says: Why are you keeping all this "stuff"): It was sitting inside the rack below; the RCX sent out/listened to RF signals, whenever I changed the position of one of the three dials. This photo is from 2008 - back then I thought 3 trains retrofitted with RF transceivers would suffice ... rather sooner than later the train count was >20 and this approach was considered too expensive ... Wow, 2008. I wasn't even on EB back then ... The rack is gone since long, but the approach you are looking for is exactly the same. It is even simpler: CCII just goes full forward/stop/full reverse. So it should be much easier to use 9751 + Control Lab for decoding the keys you were pressing. All the best Thorsten
  11. There are no dumb questions - there are mainly dumb replies When you hold down A+B while turning the CCII on, you are entering this "demo" or "debugging" mode, as you have found out and posted also in the other thread, isn't it? What exactly do you want to accomplish? Pressing buttons on the CCII and record/store these sequences on 9751? If so, then replay them on CCII or on the 9751? Best Thorsten
  12. Or do even program these sequences with or without the pause in QBASIC you can actually turn this feature on and off, see first post, LCC.PAUSEF.ON does it w/ timestamps, LCC.PAUSEF.OFF does it w/o LCC.PAUSEF.ON 'turn on PAUSE function - all program delays 'are recorded/timestamped LCC.OUT "AF" 'A on forward, button A pressed and held down, 'timestamped Delay 1 '1 sec delay LCC.OUT "BF" 'B on forward (A remains on), timestamp recorded Delay 1 ' LCC.OUT "CF" 'C on forward (A+B remain on), timestamp recorded Delay 1 ' LCC.OUT "ASBSCS" 'all outputs off, timestamp recorded Delay 2 'with LCC.PAUSEF.ON, this 2 sec delay is 'recorded (equivalent to no buttons pressed) 'PAUSE LED is on LCC.PAUSEF.OFF 'from now on, delays to be recorded must 'use LCC.PAUSE, as all motors are off. This is 'exactly the same in manual control LCC.OUT "AR" 'A on reverse, stimestamped Delay 1 ' LCC.OUT "AS" 'A off, timestamped LCC.PAUSE 2 'PAUSE is recorded, although all motors are 'off LCC.OUT "BF" 'B on forward Delay 1 ' LCC.STOP 'end program download; this also stops all 'motors without recording the motor stop 'event LCC.PAUSEF.ON looks like this (it is similar to pressing the pause button on the CCII): SUB LCC.PAUSEF.ON 'mimicking "press PAUSE button once" '%=integer OldIOStatus% = IOStatus 'save current IOStatus, motors maybe on IOStatus = IOStatus OR 3 '000011 bits 0+1 on, 2-5 unchanged WriteOutputPort '("press PAUSE button") Delay (LCCKEYDEL) '#8485 key scan catch up IOStatus = OldIOStatus% 'restore IOStatus WriteOutputPort '("release PAUSE button") Delay (LCCKEYDEL) '#8485 key scan catch up END SUB This is what I wrote in the original post: "There is one exception: When all motors are off, and then one motor is turned on for some time, then turned off and after a delay turned on again, the delay timestamps are not recorded; the motor spins continuously for the added times without stopping in-between. If one wants to record “all motors off” delays, the PAUSE function has to be used." Best wishes Thorsten
  13. Yes, that was it. Back in my days, using QBASIC (I am still using and will "never" stop using it, owing to DOSBox-X), that was the way to get "in". With NQC and foremost BricxCC, things got relatively "easy" ;) When folks want to go from scratch today, well, then use the "from scratch" information, which is all out there. AI so far does know that much about it, it will learn though, of course. All the best Thorsten
  14. The RCX needed that string as well, as far as I remember, without the ### and $$$ ... Best Thorsten
  15. I guess it isn't? This is only relevant for getting "access" to Interface B = starting its serial data spit-out frenzy, isn't it? You even need the 5 chars in front of the "phrase", I forgot how many of these chars it actually reads, maybe all. Interface A requires no initialization at all, just the I/O chips in the computer driving it may need port direction initialization. Best Thorsten
  16. Heehee, oh yes. Just read these 31 bytes, and the byte bombarding begins ... Here it is, in QBASIC PRINT #1, "p" + CHR$(0) + "###Do you byte, when I knock?$$$"; 'Programm stalls here, when USB2Ser adapter was unplugged during run 'time and then plugged back in; CTRL NumLock = break into program. R$ = INPUT$(31, #1) '"###Just a bit off the block!$$$"=31 byte 'If it is 31 byte, just throw it away; if not throw an error. Fun time. Best Thorsten
  17. ... when you do not double-check Maybe all the wonderful AI machines cannot fathom how slow motion serial buses (or SMOSB) could work at all Good luck though with the reboot! Best Thorsten
  18. Hi there, IR tower indicator LED goes on upon sending data to the tower? All three RCX' lost their firmware? If so: You can establish a connection to an RCX w/o firmware, but the "icon" does not work/show up without firmware present, as virtually all other things don't. This is more or less what the RCX can do: Wait for a firmware to arrive ... and run the 5 built it test programs, so you know it is alive. Best Thorsten
  19. Well thank you very much @maehw for this excellent summary of 22 forum pages!!! This is exactly what I am missing from time to time: Good summaries. I believe what you are speculating at the end of your summary is a really nice proposal - it really may work! All the best Thorsten
  20. Well ... maybe when using the accompanying LEGO software ... But when you want to control Interface B using BASIC, quite some "code" optimization is needed to get that going on a vintage machine. It took me a while to figure even out the data stream logic. And programming that thing for some autonomous action requires seriously more lines of code ... With Interface A it does not get simpler: PEEK/POKE (IN/OUT) one address (after one more POKE for port direction initialization) The one thing I still have not implemented is PWM control for Interface A. But as we have figured out how that works in 8086 assembly, even that seems to be within reach. Here is to the wimps Best Thorsten
  21. So you do the initialization by sending the appropriate bytes, right? And then you send a motor command, the brick replies by flashing its LED 3 times, correct? I just got put my CMs + RF tower: Using BricxCC, upon pressing "find brick", the Tower LED flashes briefly, then again, then for maybe a second, then 3 times briefly. The CM bricks replies 2 times with 5 flashes each. Now, I am believing to recall that whenever the tower sends out certain commands, a reply is expected. The incoming reply is indicated by the second flash of the tower LED and by the 5 flashes on the CM brick. So what I believe is happening upon establishing a connection is sending a byte code, get the reply, send the unlocking string, get a reply. Furthermore, I can't confirm the necessity of sending repeated "keep alive" messages on short time scales (that was the case with Interface B): In BricxCC I set the power down time of the CM brick to 15 min. Then sent a motor A on command, then unplugged the RF tower from the USB2Ser adapter, waited for a couple of minutes, plugged it in again, sent the motor A sop command - works. The power down time is reset to 15 min upon receiving a new command. Regards Thorsten
  22. I believe the card @Gunners TekZone posted above (on the left) can do that. Two 6522's = 4 freely programmable 8 bit I/O ports: https://en.wikipedia.org/wiki/MOS_Technology_6522 The 6522 have more on board that you don't need at all for your purpose. All these features seem to be exposed on the multiple pins on top as well, I believe. Any chance that there are more of such cards floating around? I can't figure out the address decoding - and I have no clue how an Apple II addresses cards sitting on these bus sockets. On the IBM XT cards are freely addressable (with exception to ISA socket 8) but I don't know how that works on the Apple II. I have the feeling there is some socket dependent addressing (see card on the left, which is "socket selective"), but again, pure speculation here. Other know for sure better! Best wishes Thorsten
  23. Does it play sounds? Does it activate the third output? CMs are known to have bad motors - the disc magnets inside regularly went bad. Do your wheels spin freely (or with the resistance of a good geared down motor? I have 5 CM bricks of which 1 + 1/2 is working motorwise. Everything else is fine (communication, memory=programming, 3rd output). Best Thorsten
  24. What does that mean? Flashing as it turns its LED on and off (but that is it), or actually executing a command? Best Thorsten
×
×
  • Create New...