Bliss Posted Friday at 02:13 PM Author Posted Friday at 02:13 PM (edited) 5 hours ago, AJB2K3 said: You can’t if you don’t have a serial adapter for the phone As I tested previously and successfully, it is very possible with a bluetooth to serial adapter. See: and: Edited Friday at 02:15 PM by Bliss Quote
Wapata Posted Friday at 07:25 PM Posted Friday at 07:25 PM Yes, a Bluetooth one should be the better choice here. I'll keep the cable for the old computer without Bluetooth. If I did have BT on both, the BT-TTL will be soldered inside the interface-B Quote
Bliss Posted Friday at 10:48 PM Author Posted Friday at 10:48 PM Ok, here is a little something new: The Lego Interface B Online Blockly is now Installable on your PC (Windows, Linux, OSX etc). It should run offline, without internet (have not tested it without internet yet). It runs as a standalone app without address bar etc. But to install, you must at least connect to internet once to go to the my blockly page and click on this little icon in the address bar: Quote
Wapata Posted Saturday at 07:02 AM Posted Saturday at 07:02 AM You know what ? You did a great job here ... Waw Quote
Toastie Posted Saturday at 02:55 PM Posted Saturday at 02:55 PM 15 hours ago, Bliss said: The Lego Interface B Online Blockly is now Installable on your PC (Windows, Linux, OSX etc). It should run offline, without internet (have not tested it without internet yet). @Bliss For me, this is a dream coming true!!! For the very first time, I have successfully "programmed" Interface B - and this was done using your Blockly app, which I downloaded an hour ago as per your instructions. So far I have just trying things out with LEGO's Control Lab software without getting anywhere - the learning curve there is rather steep - for me. I am also simply not good with Logo ... something in my brain refuses to grasp the logic. Well I guess more frequent programming hours and Logo will become logic as well; after all, all programming languages share at least some of the same logic However, the principle logic behind your Blockly code just connected directly to my brain ... I will have a lot to learn, but this is fun. It is just amazing when realizing how elegant and easy it is to get it going! Instead of generating a "Hello world" printout or having the program count from one to one hundred, I made a very simple program, that monitors input B of 9751 and then turns on/off the outputs B and F (as they are in one "column"). In fact, I was doing that using my Control Center II (CC, red output operated by keys A and B) connected with my lill opto coupler interface as briefly described here (this is @amine's idea!): This is "My First 9751 Program" using your code - please bear with me, it is certainly horrible, but it works: This program turns on/off 9751's outputs B and F depending on the raw data value at input 2: When I press button A on Control Center (CC), 9751's output B is turned on, and F off. Button B on CC turns output B on 9751 off and output F on. No button pressed on CC = both outputs B/F on 9751 off. I do visualize this with 9V lamps, this is why I use two 9751 outputs (B is for fwd, F for rev). This is not necessary when "recording" CC key sequences; this is what @amine is looking for, I believe: Storing longer than 50 or so programming steps for a CC model operated with 9751, but using the CC as keypad with is nice big yellow dial and two A/B buttons. @amine you'll love this, it works like a charm! @Bliss For now only one question: When I do not include the "wait 0.001" seconds at the end of the "repeat while true" loop, the program stalls at once. This is absolutely normal behavior, right? With that delay, the response of pressing buttons A/B on CC and B/F lights going on/off on 9751 is almost immediately, this is so impressive!!! The input data have to be received over the BT serial line, processed, and the response has to be sent back over the same connection! Wow. Thank you very much for sharing this phenomenal achievement!!! All the best Thorsten Quote
amine Posted Saturday at 03:06 PM Posted Saturday at 03:06 PM (edited) 24 minutes ago, Toastie said: @Bliss For me, this is a dream coming true!!! For the very first time, I have successfully "programmed" Interface B - and this was done using your Blockly app, which I downloaded an hour ago as per your instructions. So far I have just trying things out with LEGO's Control Lab software without getting anywhere - the learning curve there is rather steep - for me. I am also simply not good with Logo ... something in my brain refuses to grasp the logic. Well I guess more frequent programming hours and Logo will become logic as well; after all, all programming languages share at least some of the same logic However, the principle logic behind your Blockly code just connected directly to my brain ... I will have a lot to learn, but this is fun. It is just amazing when realizing how elegant and easy it is to get it going! Instead of generating a "Hello world" printout or having the program count from one to one hundred, I made a very simple program, that monitors input B of 9751 and then turns on/off the outputs B and F (as they are in one "column"). In fact, I was doing that using my Control Center II (CC, red output operated by keys A and B) connected with my lill opto coupler interface as briefly described here (this is @amine's idea!): This is "My First 9751 Program" using your code - please bear with me, it is certainly horrible, but it works: This program turns on/off 9751's outputs B and F depending on the raw data value at input 2: When I press button A on Control Center (CC), 9751's output B is turned on, and F off. Button B on CC turns output B on 9751 off and output F on. No button pressed on CC = both outputs B/F on 9751 off. I do visualize this with 9V lamps, this is why I use two 9751 outputs (B is for fwd, F for rev). This is not necessary when "recording" CC key sequences; this is what @amine is looking for, I believe: Storing longer than 50 or so programming steps for a CC model operated with 9751, but using the CC as keypad with is nice big yellow dial and two A/B buttons. @amine you'll love this, it works like a charm! @Bliss For now only one question: When I do not include the "wait 0.001" seconds at the end of the "repeat while true" loop, the program stalls at once. This is absolutely normal behavior, right? With that delay, the response of pressing buttons A/B on CC and B/F lights going on/off on 9751 is almost immediately, this is so impressive!!! The input data have to be received over the BT serial line, processed, and the response has to be sent back over the same connection! Wow. Thank you very much for sharing this phenomenal achievement!!! All the best Thorsten I absolutely need to translate that in french if possible. There is anoter benefit of using cc with the control lab, I didn't realize it first but control lab has 8 outputs then you should be able to control more than 3 motors with your CC. Edited Saturday at 03:23 PM by amine Quote
Toastie Posted Saturday at 05:01 PM Posted Saturday at 05:01 PM 1 hour ago, amine said: There is anoter benefit of using cc with the control lab, I didn't realize it first but control lab has 8 outputs then you should be able to control more than 3 motors with your CC. Or use two CCs - that would be cool as well! Best Thorsten Quote
Wapata Posted Saturday at 05:34 PM Posted Saturday at 05:34 PM I briefly read that the program can react to CC Midi messages... It doesn't (yet) lol Quote
Bliss Posted Saturday at 07:51 PM Author Posted Saturday at 07:51 PM 4 hours ago, Toastie said: ...For me, this is a dream coming true!!!... This is "My First 9751 Program" using your code - please bear with me, it is certainly horrible, but it works... @Bliss For now only one question: When I do not include the "wait 0.001" seconds at the end of the "repeat while true" loop, the program stalls at once. This is absolutely normal behavior, right? With that delay, the response of pressing buttons A/B on CC and B/F lights going on/off on 9751 is almost immediately, this is so impressive!!! The input data have to be received over the BT serial line, processed, and the response has to be sent back over the same connection! Wow. @Toastie, That makes me very happy to know that my Blockly project can help some people realize some dreams :-) I think you did a very good program. It's intuitive and visually tells what it does. You're right about forever loops, a small wait is required to leave the UI some time to manage things I guess... I'll look after that if it could be implicit... But for now, it's the way to do. And actually, your program gave me the idea to add a new comparison block: A block that outputs True if Input number between min and max number which would replace the bunch of <= and >= and the "AND" blocks you merged to achieve this result. You talk about the Control Center CC and got me curious about this... I don't know what it does... So I'm going to read about this equipment. So, do I understand you tested quite a few things with the Lego Blockly? : - You used the installable feature to install the standalone version to work offline? - You used a BT to Serial Converter? Thanks for the good words. Quote
Toastie Posted Saturday at 09:21 PM Posted Saturday at 09:21 PM (edited) 1 hour ago, Bliss said: That makes me very happy to know that my Blockly project can help some people realize some dreams :-) @Bliss it IS really like that. It took me about 30 min from "installing" your standalone version (it is really just clicking on "download" on your website and double-click the newly crated desktop shortcut icon), connect to Interface B (which was a mouse click), getting familiar with the environment, left/right mouse buttons, the gear icon, trash bin, and - beginning programming! As said, I looked into the Control Lab (DOS) software - this must have been a blast (and for me still is today) back in the 1990's, as it creates a graphical UI and unleashes the programming power of Logo. However, the Logo program control flow was hard to grasp - for me that is. Interface B (9751) is "just" an 8-channel output driver and an 8-channel sensor (raw and encoded) data provider. So is - partly - Interface A (9750). The big difference is that 9751 spits out the sensor data, like it or not, an 9750 wants to be polled. And of course serial vs parallel is another big challange on vintage machines. In other words: Computer control of 9751 (for me) was so far reading input data and pressing buttons to operate the outputs using QBasic. The real power of any input/output device is the "controller" in between. Which is in case of 9751 and 9750 the connected computer. And which is different for PBricks, as they want to be programmed to take over the controller task. This has now totally changed, as I can use 9751 as a controlled (via your software) device. That is so unbelievably cool. 1 hour ago, Bliss said: But for now, it's the way to do. I believe it is the right way to do! This is how it is done elsewhere. The user can decide, when the UI/program needs to breathe! There should maybe a hint in doing so. But I have crashed so many programs on Arduinos and ESPs simply by cutting off their breathing ... 1 hour ago, Bliss said: And actually, your program gave me the idea to add a new comparison block: A block that outputs True if Input number between min and max number which would replace the bunch of <= and >= and the "AND" blocks you merged to achieve this result. That would make things easier, as this is a frequently encountered situation, when working with raw input data. I am aware that "automated" on/off values are making things easier, but there are so many hardware issues that may happen: Touch sensor contacts simply age. Never to the extent that they don't work anymore, but to the extent that built-in software thresholds for on/off with hysteresis shift so much, that they seem not working anymore. This is why I prefer the raw data ("value" in your code) mode for sensors whenever feasible. It is more flexible. 1 hour ago, Bliss said: So, do I understand you tested quite a few things with the Lego Blockly? I am testing like a maniac - as I am simply so positively fired up! I added the good old "Sensor_2_old" variable (as I do in so many of my QBasic programs to avoid loop execution if not required): If var_old != var then var_old = var do something using var (or var_old) else wait some time endif This reduces traffic on the serial bus (output data) - which may not be any issue on modern computers but frequently is on vintage machines ... 1 hour ago, Bliss said: - You used the installable feature to install the standalone version to work offline? - You used a BT to Serial Converter? Yes and yes. The BT adapter is a simple HC05 + TTL to serial adapter duo (out of 3 that I am using with my LEGO interfaces in addition to a BOLUTEK BT to serial adapter) - they are all nicely lining up in the "connect" dialogue window of your Blockly UI. It is so easy to connect to any of them!!! 1 hour ago, Bliss said: Thanks for the good words. You know, they are certainly not sufficient, but what should I say: I really believe that I am dreaming! All the best and thank you very much for creating this programming environment Thorsten Edited Saturday at 09:26 PM by Toastie Quote
Bliss Posted Saturday at 10:03 PM Author Posted Saturday at 10:03 PM (edited) 7 hours ago, Toastie said: If var_old != var then var_old = var do something using var (or var_old) else wait some time endif This reduces traffic on the serial bus (output data) - which may not be any issue on modern computers but frequently is on vintage machines ... This is good programming. Your first version is intuitive too, but it could send same commands to serial every scan we might think. But I also did some output commands caching in the code (FOR LEGO INTERFACE B ONLY NOT RCX YET) that prevents sending same consecutive commands. There are a couple of exceptions like the REVERSE command which I cannot cache, so care must be taken when using it. I added the "Is Between" block in the logic category. To update, you must go online with chome on my page. Check in the logic category if you see the new [ ] <= [ ] <= [ ] block. If not, To force page refresh, press Ctrl-Shift-R. A banner should appear at the bottom with update button. I'm improving this update thing (the bottom banner that appear gets the blockly scroll bars over it... will be fixed soon). It does (Sensor_2) > 20 AND (Sensor_2 < 200) Note that the first number can be > than the last number. for example, 200 < Sensor_2 < 20 which is equivalent to Sensor_2 >200 OR Sensor_2 < 20. Edited 23 hours ago by Bliss Quote
Toastie Posted Saturday at 10:35 PM Posted Saturday at 10:35 PM 10 minutes ago, Bliss said: I added the "Is Between" block in the logic category. So nice - update worked with one mouse click! Regarding Control Center I/II (CC): Essentially it is a "closed" Siemens 680X microcontroller driven three 9V output (with no sensor inputs) device, which is recording output activation/deactivation sequences including the pauses in between. There are two programming slots and a total of some 50 steps. It has two keys A/B for output A (fwd/rev) and a yellow dial type button, which can activate any two outputs B/C in fwd/rev direction. @amine had the really cool idea of using CC's three outputs (ABC) connected to any three 9751 inputs as some sort of "key pad", and then record these key sequences. This way, 9751 is mimicking CC, but with way more programming steps available, in addition to program storage. CC can only hold one or two programs internally. Here is one thread on EB, there is so much more out there! @amine's case is special - but nicely aligning with the idea of using old LEGO programmable devices with either old or modern computers. Best Thorsten Quote
Bliss Posted Saturday at 11:06 PM Author Posted Saturday at 11:06 PM (edited) Now the Updates should be automatic when you go on the web page. I removed the update button and banner... (But for now, there is not new important updates) Thanks for CC info! Edited Saturday at 11:07 PM by Bliss Quote
amine Posted 22 hours ago Posted 22 hours ago 6 hours ago, Bliss said: Now the Updates should be automatic when you go on the web page. I removed the update button and banner... (But for now, there is not new important updates) Thanks for CC info! I have translated in french the win 95 version of lego dacta control lab. You can make it to fit your own language with a bit of modding.The software is portable and works on win10. https://archive.org/details/clab_20260328 Quote
AJB2K3 Posted 21 hours ago Posted 21 hours ago (edited) Wow, looks so much cleaner than my attempt. Sorry having a brain fail moment. Is the BT adapter acting as a bridge to pas the raw data from the interface to the host computer? Edited 21 hours ago by AJB2K3 Quote
Wapata Posted 20 hours ago Posted 20 hours ago (edited) Hello ! Can you please double check what does "set power 8" ? It look like it make the motor go back to "1"... And is there a Fast way to set back "who is who" after reloading a program ? For the program at the beginning of the post, i need to click on aaaall the "No Lego B" to put them back to "Lego B1" for example. Edited 20 hours ago by Wapata Quote
Toastie Posted 17 hours ago Posted 17 hours ago 2 hours ago, Wapata said: For the program at the beginning of the post, i need to click on aaaall the "No Lego B" to put them back to "Lego B1" for example. Here is what I do: Once I have programmed a (test)version of any program (with 9751 turned off/lost connection), I save the programit, turn 9751 on/reconnect, load the last program saved and all "No LEGO B" change automatically back to "LEGO B1". Best, Thorsten 3 hours ago, AJB2K3 said: Is the BT adapter acting as a bridge to pas the raw data from the interface to the host computer? Yes, and it is used to send back the output commands to the interface. In essence, it just replaces a serial cable: (Win11+built-in BT) <-> (BT2TTL adapter + TTL2Serial adapter). I also have this BT2Ser adapter with no need to do extra TTL2Ser conversion, works as well. Best Thorsten Quote
AJB2K3 Posted 17 hours ago Posted 17 hours ago 7 minutes ago, Toastie said: Here is what I do: Once I have programmed a (test)version of any program (with 9751 turned off/lost connection), I save the programit, turn 9751 on/reconnect, load the last program saved and all "No LEGO B" change automatically back to "LEGO B1". Best, Thorsten Yes, and it is used to send back the output commands to the interface. In essence, it just replaces a serial cable: (Win11+built-in BT) <-> (BT2TTL adapter + TTL2Serial adapter). I also have this BT2Ser adapter with no need to do extra TTL2Ser conversion, works as well. Best Thorsten thanks Quote
Bliss Posted 14 hours ago Author Posted 14 hours ago (edited) @Wapata, The "Power" must be a number from 0 to 7 (3 bits, 000 to 111 binary), the program "AND"'s your number with 7 (111) whatever number you give, so 8 = 1000 binary AND 0111 = 0000= pwr 0 the lowest power. I just added tooltip on the Lego B power Block to inform about the range 0-7 of the power. As @Toastie said, the LegoBx name is saved with your project (if you use the save button) but you have to "load" back your program after reconnecting your com port(s) that generates the Device Name automatically. I might try to change this in the future but for now, it was for me the simplest way to do things. Edited 14 hours ago by Bliss Quote
Bliss Posted 13 hours ago Author Posted 13 hours ago 7 hours ago, AJB2K3 said: Wow, looks so much cleaner than my attempt. Sorry having a brain fail moment. Is the BT adapter acting as a bridge to pas the raw data from the interface to the host computer? Both USB to Serial and BT to Serial adapters are seen the same for the online Lego Blockly and it uses the webserial API for both (BT serial adapter generates a "COM" port in the windows device manager for example). I had to do a little something in the code though to have it run on ANDROID phone/tablet as there is no "COM" ports. But it still use the webserial API... Quote
Toastie Posted 8 hours ago Posted 8 hours ago (edited) @Bliss I am really enjoying your LEGO Blockly programming environment very much! I have a couple of questions and there will certainly be more - is this the right place to ask? I am just starting with a couple, if it is OK Are newly defined variables always global? So when I call a function, does the function know about variables declared in the main program or do I have to pass them to the function (see below)? What is the substitute in Blockly for a subroutine in QBasic, e.g. "ChangeOutputA(value or variable)". Is that done by declaring a function with no output, if there is no return value? I don't understand how the functions function ;) Let's say I have declared the function "ChangeOutputA". There is the "input" feature, which is by default "x". Is x a local variable to the function, that accepts a passed on value by the main program? The function would say: "to ChangeOutputA with x". Can I use x within the function? Here is an example: When I have this on the UI, and press "Run", it does not work, no outputs are turned on/off. The right function is just on the UI, it is not called, nor does it have a proper name etc. It is just sitting there "in preparation". This is what I usually do in Basic: Write some subroutines, but never call them. The main loop does what it has to do. When I drag the entire function into the trash bin, so only the left loop is on the UI, and then press "Run", it works fine. What am I missing? I bet it has to do with how Blockly wants the blocks arranged? Or do I need to declare a "main" program, so the Blockly knows where to go when pressing "Run"? Thank you very much and all the best, Thorsten Edited 8 hours ago by Toastie Quote
Gunners TekZone Posted 7 hours ago Posted 7 hours ago (edited) I have been keeping my testing simple lately... As I was making other things, and needed to recoup from that energy expenditure. So this time I am sticking with a single Int-A and an RCX Serial tower. Here are some observations... - No "Save As" option. I must remember to change the name of my saved program after the fact. - A saved program doesn't retain and reconnect device connections... This one had me doing a bunch of troubleshooting before realising that all the device allocations in my test program were listed "No RCX" and "No Lego B", thus requiring the manual reconnection and assignment of all devices in the program. Or doing such device connection (presumably in correct order?) prior to reloading a saved program. - On a wim, I tried having two RCX's online at the same time... Half expecting them to just be recognised as a single unit (for simple in-coming commands at least). But as soon as I turn the 2nd one on, the program stops running, and will not restart without turning off (any one) of the "extra" RCX bricks. Now, I was using the "While Rcx1 alive?" loop, so that might be a factor? I am guessing that in order to have multiple RCX bricks running, one needs a dedicated IR tower for each? It has been a long time since I messed with these little yellow bricks, but I thought these had some form of internal ID and could run multiples on a single tower? Edited 7 hours ago by Gunners TekZone Quote
Toastie Posted 6 hours ago Posted 6 hours ago (edited) 33 minutes ago, Gunners TekZone said: I am guessing that in order to have multiple RCX bricks running, one needs a dedicated IR tower for each? It has been a long time since I messed with these little yellow bricks, but I thought these had some form of internal ID and could run multiples on a single tower? @Gunners TekZone No, they actually don't. Once you send out IR light through the tower, all RCX' will recognize that call and all will reply (depending on which command you sent). This naturally and instantaneously messes up any traffic ... Even with multiple towers, each RCX in range will reply to each tower light emission. See above ... One way to resolve is: SendMessage(byte). There is no inherent RCX reply, when it receives messages. So this is my workaround: As all my RCX' are running programs to do something, be it run a PID controlled train or switching lights on a display on/off, I included a "receive message task" for each of them. Within that task, each RCX has its personal ID (byte value) and knows about individual commands (byte value), provided through defined variables. Example: There are 2 trains, each operated by an RCX. Train1 has ID 200, and train2 201. The defined commands within each RCX program are 1=this, 2= that, and so on. This and that could be increase speed, decrease speed, turn nose light on, etc. So what I send out is: ID (message 1) and action (message 2). This way only the addressed RCX is "doing" something. They all respond, again via messaging, but only the addressed RCX does and the computer control program knows the message came through. Here is an example (from 2010, oh my ...) //********************************************************************************************************************* task receive_message() { /* Message protocol: 2 bytes. Structure of first byte (address byte): Incoming (own) binary Address = 10 XX XXXX; base 192 Outgoing (own) binary Address = 01 XX XXXX; base 160 101 X XXXX = 5 bit (= 32 adresses) range. Structure of second byte (data byte) : See program header. Range is 95 - 1 due to return byte increment. data_byte is incremented in send_error_message to avoid confusion with the tower echo upon error checking in VBasic. Possible errors are: 223 + 1 = timeout; 224 + 1 = C_BUSY; 225 + 1 = invalid data_byte (send_error_message increments databyte). Due to memory shortage on Scout only minimal error checking is implemented. */ while (true) { ClearMessage(); //Flush message buffer. until (Message() == MYID_IN); //Check if Message = MyID (in) = bin_110_X_XXXX, as #defined. ClearMessage(); //Flush message buffer. ClearTimer(0); //Reset timeout Timer(0). while ((Message() == 0) && (Timer(0) < 10)); //Check for timeout after ID detection (Note: hardly occurs under if (Message() == 0) //remote program control). { //Wait for next message or 1 s timeout (100 ms timer slice): data_byte = C_TIME_OUT; //Timeout occurred; just for preventing brick to "hang". send_error_message(); //either send error message timeout or simply restart loop. continue; // } data_byte = Message(); //Message was not 0; load data_byte with message. SNIP BTW, message commands don't need to have the "repeated command" bit flipped. Best wishes Thorsten Edited 6 hours ago by Toastie Quote
Bliss Posted 5 hours ago Author Posted 5 hours ago I'm glad to see this thread a bit busier ;-) @Toastie, It appears that the function blocks (part of blockly internals) are not working anymore. I must have broken something and will look into that. I don't know much about blockly functions yet but it is a great way to make more object oriented programming. So if your main repeat forever loop becomes more complex, you can use function to modularize your program. When you drag a function block into the code area, you can rename it and it creates automatically in the toolbox, category Functions, a calling block for your function. You can the use the called block into your Main Repeat loop. I don't know but I doubt there is the notion of local variable. I would believe that all variables are Global... I have to test more... Also, when you create input variable for the function, it creates X by default and you can see this x variable in the Variable Category of the toolbox. If you right click on the variable in the toolbox, you can rename it... I think you're right, ChangeOutputA(value or variable) would be the same as a Function with no return value. Let me fix the Function blocks so you can test it without issues. Quote
Bliss Posted 4 hours ago Author Posted 4 hours ago (edited) @Toastie, I think I fixed the issue with the Function blocks. I tested the following with success: I added a FOOTER and the version should now be: Version: 2026-03-29-1947 Edited 3 hours ago by Bliss Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.