I want to use an Arduino to send TMCC commands to my various TMCC engines, just like I can with my TMCC handheld controller. Emulate my TMCC controller with an Arduino. How do I get the TMCC RF parts to do this? Cannibalize an existing TMCC controller? Anyone tried to do this?
Replies sorted oldest to newest
That sounds interesting as well. First project is to sense input from two I/R sensors, compute scale speed, and output it to a 3 digit 7-segment display. Fun stuff!
Both these ideas can be realized by connecting an Arduino to the DB9 serial port of a Base-1, Base-1L or Legacy Base. The TMCC and Legacy command specification is freely available. Note that to work with the full Legacy command set, an LCS SRE2 module is required. The SER2 is compatible with the Legacy and Base-1L, but not the original Trainmaster/Base-1 command base.
get the spec here: http://www.lionel.com/lcs/LCSP...er/styled/index.html
I thought that the DB9 port only allowed the TMCC base unit to talk to the TMCC controllers (ASC, BPC, etc.) but not to the engines via RF. I want to be able to communicate with the engines via the Arduino. Maybe I need to use the third wire that the Action Recorder uses. Can you send me a link to a TMCC spec that might explain all this?
OK, I see the spec now! I can control an engine from the DB9 port. Thanks! Wonder if anyone has done this with an Arduino or do I write my own code?
The DB9 port on the Base unit is also an input that will accept any commands in the proper format. I've been doing that for 20 years with PIC based circuitry.
You might also want to check out my Windows and Android TMCC/Legacy/LCS software. Click on the links in my signature below for more information. Please let me know if you have any questions.
Thanks, Harvy, I'll check it out. But I need to slow the TMCC trains based on conditions on the layout, not from my Android phone. But the smartphone software would be neat as well.
Check out a previous post.
New life for a ECU-1 Train Control Transmitter
It is able to control any TMCC command.
Hi Don - it's pretty easy to read and write TMCC or Legacy commands to and from the command base serial ports. As Rudy mentioned, a SER2 is the most convenient way to go. Do keep in mind that the earth ground (ground for the command base) is supposed to be isolated from layout common (outside rail).
If you take a look at this link, you can find some of my Arduino projects. "Train Control" is a very complex system that automates train control, controls switches, signals, and accessories, and communicates with JMRI running on a computer. But you will find examples of how to send TMCC, Legacy, and DCS commands over the Arduino serial port.
"Uncoupler Monitor" is a much simpler program that listens to the serial stream from the command base, and activates a relay module in response to commands directed to ACC 1-8. Essentially a cheap and customizable version of the ASC.
For layout control I like the Arduino Mega, because it has four hardware serial ports. For accessories like the uncoupler monitor I like the Arduino Pro Mini, which is very small and costs less than $10. I am fiddling with transmitting commands from the Legacy base to HC-12 radio modules, with Arduino Minis in rolling stock picking up the radio commands (like a cheap and customizable Mini Commander).
I've been working on an Arduino-based project that controls my trains via Legacy, very much as Professor Chaos has done. As Rudy says, you'll need an SER2 but the programming is pretty easy and Prof Chaos has been kind enough to share what he has done to help you get started.
To send Legacy commands, you'll need the Legacy spec which requires (or used to require?) becoming an LCS Partner -- which is simple enough but you'll need to sign an NDA.
Here are the videos that Professor Chaos made that really inspired me on this project: https://www.youtube.com/channe...1UcTotGFTEih-nNVzL_w
I'm using 7 Arduino Megas, and my software monitors the location of all trains, throws turnouts, reserves and releases sections of track, blows the whistle, makes announcements, control accessories, and slowly accelerates and decelerates each train as it departs and arrives. I've provided more detail in other posts, so if you're interested you might search my older posts.
Attachments
You do not need to be a LCS Partner to get the Legacy Spec. The TMCC and Legacy Specs are available in one document on Lionel's LCS page. Now to get the the specs for all of the LCS modules and the format of the commands on the LCS bus, you will need to be an LCS Partner. But if you just want to send Legacy commands you do not need to know anything about LCS, but you will need a SER2. The SER2 is the only thing that will accept Legacy formated commands. If you want to send them over wifi and use the LCS Wi-Fi module, then you will need to become an LCS Partner, like myself.
Harvy is exactly right. There has NEVER been an NDA requirement to get a copy of the Legacy spec and the TMCC commands have ALWAYS been available (they are published in the original CAB1/BASE1 manual).
Since I'll only be talking to the TMCC Base Unit I think that I only need the TMCC command subset, so I don't think I need any specific Legacy information. I think I have the codes I need but a link to an on-line copy of the original TMCC CAB1/BASE1 manual would be helpful.
If you are only going to use TMCC commands and not Legacy, then you don't even need a SER2. You can connect directly to the Base-1's DB9 serial port. In fact, I don't think it would work if you went through a SER2. If you did I don't think the Base-1 would be able to recognize the commands. As far as I know the Base-1 can only recognize native TMCC commands, and that would not be what it would be receiving if you went through a SER2. I don't think any LCS module would work with the Base-1. Rudy can confirn that.
If you have a hard copy of the TMCC manual, then you have everything you need. If you prefer an online copy you can search for it on Lionel's site under "Support". I don't think the manual has ever changed though.
I just downloaded the original TMCC manual from Lionel. I have attached it here.
Attachments
Harvy posted:If you are only going to use TMCC commands and not Legacy, then you don't even need a SER2. You can connect directly to the Base-1's DB9 serial port. In fact, I don't think it would work if you went through a SER2. If you did I don't think the Base-1 would be able to recognize the commands. As far as I know the Base-1 can only recognize native TMCC commands, and that would not be what it would be receiving if you went through a SER2.. I don't think any LCS module would work with the Base-1. Rudy can confirn that.
Correct, the original Base1 aka Trainmaster Command System is not compatible with and of the Layout Control System/LCS modules. Base1L and Base2 aka 990 Legacy Control System will both work with all LCS modules.
Based on the original poster's needs, no SER2 required.
Thanks Harvy for the link to the TMCC Manual. It has the general TMCC info that I already know. Now I need to know the protocol for talking from the Arduino to the DB9 port on the TMCC Base Unit. Where can I get that additional level of detail?
Don Furgerson posted:Thanks Harvy for the link to the TMCC Manual. It has the general TMCC info that I already know. Now I need to know the protocol for talking from the Arduino to the DB9 port on the TMCC Base Unit. Where can I get that additional level of detail?
All of the information is in the attachment starting on page 36. Let me know if you need help deciphering it.
Don, the documentation for the protocol is here.
If you look in my Train Control program under the _interface tab, you will see routines for transmitting TMCC and the various kinds of Legacy commands.
I find it useful to have all the routines deposit commands in a circular buffer; another routine called from loop() sends commands out the serial port if at least 30 milliseconds have elapsed since the last command sent.
Thanks guys for helping me get started talking to the TMCC base unit. I'm new at this so how do I access your Train Control code? Any suggestions for a programming guide as it's been a few years since I've written any "C" code?
There should be a link to Dropbox in my previous post, where you can find the projects as well as the libraries needed to support them. You should be able to download them from Dropbox.
Some of the most useful programming resources I have found are the Arduino Reference Pages and this C++ tutorial.
I dont know anything about Arduino. By looking at the programmers reference, I don't think any of my code would help you. Although my code is in C#, the framework is totaly different. I can help with talking to the TMCC base unit and the command format if you need it.
After looking at a number of Arduino tutorials last night I think I want an Arduino Mega 2560 with an RFID shield. Our train club has a 12-block O-Gauge main line controlled with one TMCC base unit. I want to run 4 trains on that loop with automatic speed reductions to avoid rear end collisions. I've automated our 16-block (non DCC) HO main loop that way with current sensors and slowdown resistors, and have implemented that strategy on 3 of our O-Gauge block pairs, with limited success. Works fine for engines running in conventional mode but for TMCC not so much. The TMCC engine boards don't like the reduced voltage technique. They slow down some but if you get it too low they will stop and flash their headlight. Then a engine reset is needed <AUX1><0>. I want to put an RFID sensor between the tracks at the beginning of each block (we run only one direction) and have the Arduino read the TMCC engine number from an RFID chip fastened under each TMCC/Legacy engine (we have 18). The engine number will be stored in an array of blocks for later reference. So I will know the engine number of all running engines. When a train enters block "n" the Arduino will check if there is an engine in block "n+1". If there is (engine number in the array) it will issue a TMCC command thru the DB9 port to slow the engine in block "n", and so on. How long do you think it will take me to do this, and has anyone else attempted this?
Don, this would be a fun and relatively simple project -- assuming you've overcome the initial challenge of learning how to use an Arduino. Both the TMCC control and the RFID communication can be done via serial ports, so the interface is really easy. Back in 2015, I played with the ID-20 RFID reader. It has a good range, so you can put it in a trackside structure and still be able to register RFID tags that have been placed in motive power as it passes by. There may be something even better out now, but I was very pleased with the ID-20 and I believe it's what Professor Chaos uses on his layout.
Note that this isn't, and probably shouldn't be a "shield", because it will be simpler to keep the RFID readers trackside and keep your Arduino in a more convenient location. You'll just need a few wires for power and the serial signal.
The challenge I see is that you propose placing RFID readers at every block -- which presumably means a bunch of them. This was my original idea as well, with my autonomously-controlled layout. However I soon realized that if I can just determine where each train is initially (perhaps using a single RFID reader, or by typing in a starting position for each train), I can use any sort of occupancy detection (such as an isolated rail section) and "know" which train is tripping it -- by virtue of where it was before and which direction it was heading. On my own layout, I "register" trains at the beginning of a session (using an A/N display and rotary encoder) -- defaulting to the last-known position so it's usually trivial -- and then let my software track them using about 50 isolated track sections from that point forward. I wound up not needing the RFID reader at all. Another approach would have been to register trains by driving each of them past the RFID reader -- but that would have been a lot more effort for the operator than the solution I ultimately chose.
If you decide you still want to use multiple RFID readers, you'll need to figure out how to get them all to talk to your Arduino. Serial readers might be possible using Software Serial and a Mega, or you could try to find readers that used a different communication protocol such as I2C or SPI.
Please keep us posted on your progress!
Thanks for your input Randy. You are right, if I input the engine numbers of the running trains in the correct order then my software can track them. I like that plan. Any suggestions on how to format the data needed to be sent to the TMCC base unit? Just make up some interesting arrays? Be nice to find an Arduino sketch that talks to a TMCC base via the serial port!
Don, Professor Chaos has generously posted all of his code in a public Dropbox folder. He included a link in this thread, above. You’ll find Arduino code that sends commands to locos just like you want to do.
Randy
I'm sorry to be such a neophyte but I need a bit of additional hand-holding. I am using the web-based Arduino IDE and have tailored my own "Blink" program to run on my new Arduino Uno last night. And I have the link to Dr. Chaos's public dropbox (Thanks!) but don't know how to use it. Don't know yet what an ".ino" file is or how to open it. I could use a bit more help to find the specific Arduino code I need to send TMCC commands to the TMCC Base Unit (i.e. electronically "Turn the Red Knob"). Thanks for the help you have given so far. Thanks again for helping.
Don, I learned everything I know about Arduino by watching YouTube videos, reading tutorial websites, and reading *numerous* Arduino books -- repeatedly. Then I learned how to send commands from an Arduino to a TMCC loco by studying Professor Chaos's code and writing very small proof-of-concept sketches. Just getting an engine to toot its whistle was a huge milestone, and extremely satisfying.
I started by watching this series of tutorials (several times) by Jeremy Blum: https://www.youtube.com/watch?v=fCxzA9_kg6s I strongly suggest you start there. He also has a book which covers pretty much the same material.
From your last post, I can say this is likely going to take you a lot of time. I personally spent hundreds of hours learning and experimenting, and I enjoyed every minute of it. But if you're really only interested in getting to the goal, the reward is not going to be worth the effort. To an experienced Arduino programmer, especially someone who is already up to speed with the TMCC and Legacy protocols etc., what you are trying to do is a relatively trivial project -- probably less than a hundred lines of code (versus thousands of lines of code for my Legacy control project, so far.) But for a novice, it's a long haul and only makes sense if the joy is in the journey.
For beginner books, I recommend Programming Arduino by Simon Monk. It covers basic programming concepts as well as how to interface with various devices such as LEDs, sensors, motors, etc. There is a second "advanced" volume that contains more good information for beginners.
After you understand the basics, for more of a deep dive into Arduino programming (with little emphasis on electronics), I highly recommend Beginning C for Arduino by Jack Purdum.
Good luck, and keep us posted on your progress!
Thanks again for helping me with this project. I'm a retired EE & SW engineer and wrote a lot of code back in the day, but mainly in assembler and FORTRAN (sigh). Have done a fair amount of C but never migrated to C++. But I found the C++ libraries for TMCC train control, just hope that I can figure out how to use them. But I'm retired now and since my wife is gone I have plenty of time to run the train room at my retirement community, especially the electrical part. So I'm fully dedicated to the journey as well as the goal. Now can I toot the whistle on my N&W 611 engine from my Arduino in under 100 days? Then I must interface to an RFID reader and a small LCD display to complete my project. Let the fun begin! [Should I put the first curly brace on a separate line or on the same line with the function call? (-: ]
I would definitely put the opening curly brace on a separate line. I think it makes methods easier to read. I'm always here to answer the really important questions. LOL.
Don: I did a recent post called Arduino Lesson: How to Create a Library that may be helpful to you. I have not used the Web based IDE so I'm not sure what that is like. I would encourage you to go ahead and download the IDE software if that is a possibility. It's very easy.
TMCC is not on my resume but I think the idea is to send data through a serial port to the base unit over RS232. That should be fairly simple; see the Serial librarypage.
Great project! Good luck!
-- Leo
Randy P,
I followed your project when you were posting about it and you made it look (or sound) easy. I feel much better knowing that it took you quite a while to get it all mastered. I am still struggling off and on with Arduinos, but other projects keep popping up and sidetracking me. Grandson has me helping with RC vehicles right now (another subject I knew nothing about until a few weeks ago). Your project looks like it turned out very nicely, pictures look great!! Also, thanks for the Jeremy Blum links and recommended books. I have watched a couple of Jeremy's videos, very sharp young fellow! Thanks for all the extra info here.
Don,
I have also been trying to follow Leo's thread (above), it's a very good one! But, the sidetracking has me once again for now.
One thing that came to mind immediately when I saw the TMCC command specification was how to express binary literals in C++ and the Arduino. The newer standards allow the form:
variable = 0B011010;
alternate = 0b10010;
The prefix 0B (zero, B) in either case indicates a binary literal. This is consistent with the octal and hexadecimal versions; leading 0 for octal, and leading 0x for hex. I wasn't sure about the binary version until I looked it up. Then I ran a quick check on the Arduino IDE and it compiled without complaining.
Thanks Leo for the info. I'm ready to dive into the Arduino - TMCC communications serial interface with gusto the week. For religious purposes that are beyond the scope of this post my major C programming efforts predate C++ and while I intellectually understand it's somewhat convoluted elegance I just refuse to get immersed in it. Subsequently I'm poring over Prof Chaos TMCC class libraries and I will write a conventional C function this week called "outputToTMCC" which will be a bool function returning "true" if successful, providing that the TMCC Base Unit can provide that. This should be educational and fun. Looks looks I'm going to need a Mega, not a Uno since I need multiple serial ports. One for the TMCC base unit, one for the RFID reader (engine identification) and my programming laptop and a mul-line LCD readout display.
Wish I knew more about the TMCC Action Controller which has a 3-wire connection to the TMCC Base, I assume TX, RX and GND! I don't use the Action Recorder but I do have the 3-wire cables. All the other TMCC controllers use only TX from the base (the controllers RX) and ground, hence two wires, ("Data" and "Comm") as they are "simplex" devices which only send data to the TMCC controllers (I use 18 ASCs and 6 BPCs, and 6 TPCs) but get no dialog back except maybe an ACK of NAK. The Action Recorder seems to be the exception. I want to ( and am determined to) build my own virtual Action Recorder that I can command with the Arduino. It would be neat to have complete specs on the Action Recorder.
Can I just connect the TMCC Base Unit to the Tx and Rx and ground pins on the Ardrino and avoid taking up DB9 serial connector? Can I just create (assimilate/concatenate) the HEX command string to the TMCC base unit and just send it out? I see the the raw commands on page 36 of the original TMCC manual but it doesn't tell me timing quirks. Just what packets need to be sent out and what timing anomalies will I incur. Any hints would be helpful.
Now time to decipher Professor Chaos TMCC classes and write me C function to do successful TMCC output without the entanglements associated with his specific train control philosophy. I will devise my own train control philosophy to suit our specific layout needs - as I know exactly how I want to run it but just don't have the software yet. That's the fun part. So creating the operating paradigm is as fun (sometimes more) than watching the finished product drive trains around out layout. I want to savor both!
Please wish me luck and send me any TMCC quirks that I may get trapped with along the way. I'll keep you posted on my project and publicly share my code when I'm done. I'll prototype on the Uno and move to the Mega for final integration. Remember that I must also interface with the RFID reader and small LCD display, plus other assorted digital I/O, such as current-sensing track occupancy detectors, which are all ready in place. Should be fun!
And I agree with Randy, the journey is as much fun as the goal!
I'm using the Web-based Arduino IDE and it is visually different from the downloaded native Windows IDE and all the examples show the physical appearance of the native IDE, not the Web IDE. I also didn't see how to import an existing .ido file from my computer into my Web-based sketch book. What am I missing here?
Would it be better to switch to the Windows-based native IDE and stop using the Web IDE? For example I'd like to print my modified Blink sketch but I see no "Print" function in the Web-based IDE. And there's no handy menu bar at the top of the Web-based IDE. Which IDE do you use and recommend? Whit print program can print the sketch exactly as it appears on my screen, colors and all?
Randy P. posted:Don, I learned everything I know about Arduino by watching YouTube videos, reading tutorial websites, and reading *numerous* Arduino books -- repeatedly. Then I learned how to send commands from an Arduino to a TMCC loco by studying Professor Chaos's code and writing very small proof-of-concept sketches. Just getting an engine to toot its whistle was a huge milestone, and extremely satisfying.
I started by watching this series of tutorials (several times) by Jeremy Blum: https://www.youtube.com/watch?v=fCxzA9_kg6s I strongly suggest you start there. He also has a book which covers pretty much the same material.
From your last post, I can say this is likely going to take you a lot of time. I personally spent hundreds of hours learning and experimenting, and I enjoyed every minute of it. But if you're really only interested in getting to the goal, the reward is not going to be worth the effort. To an experienced Arduino programmer, especially someone who is already up to speed with the TMCC and Legacy protocols etc., what you are trying to do is a relatively trivial project -- probably less than a hundred lines of code (versus thousands of lines of code for my Legacy control project, so far.) But for a novice, it's a long haul and only makes sense if the joy is in the journey.
For beginner books, I recommend Programming Arduino by Simon Monk. It covers basic programming concepts as well as how to interface with various devices such as LEDs, sensors, motors, etc. There is a second "advanced" volume that contains more good information for beginners.
After you understand the basics, for more of a deep dive into Arduino programming (with little emphasis on electronics), I highly recommend Beginning C for Arduino by Jack Purdum.
Good luck, and keep us posted on your progress!
Can I get a copy of your code to blow the whistle? It might jump-start me. And I do have the Arduino Uno starter kit and Simon Monk's book. Very informative so far.
Please recommend a good trackside RFID reader, I've now decided that I need only one reader. Once my 4 trains pass the reader (in the middle of Block 2 of 12) just one time I can gather enough data to build my own train registration array and the automation will sync up with that so I can easily know which train (TMCC ENG #) is in each occupied block and sequence them around the layout. The registration array will be indexed by the TMCC engine number - 2, so our Engine 2 (PRR 0-4-0) will be array row 0. So I need a static trackside reader with USB (or some interface) back to the Arduino plus some small RFID transmitters to mount on/in each engine. That's 22 engines needing RFID transmitters so I would appreciate low cost. Any suggestions?
I just thought of another glitch in my plans. Currently I only want to talk to my TMCC (and Legacy) engines but I might want to talk to some of my TMCC controllers as well. I currently use 3 base units to control 3 separate groups of controllers (ASC, BPC, etc.) and only one of them connects the RF to the outside rail (to avoid interference). That all works fine. So if I want to communicate with engines I must communicate with the one base unit that is connected to the track. But a serial connector is already connected to that base unit. So do I just use my 3-wire serial connector and use all 3 wires (TX, RX, GND) to the Arduino first, then daisy-chain TX and GND (just two wires) to the other local controllers? I can (have to) live with that limitation that I can control all engines but only the ancillary controllers daisy-chained to the one base unit that the Arduino is connected to. The other controllers cannot be controlled from the Arduino, only by my CAB-1 controllers. Small inconvenience. Could use 3 Arduinos somehow connected together, but that adds complications I don't want to deal with right now. Any ideas?
Don, that's a lot of questions ;-)
* I agree, you'll be fine just writing your code in C, no need for C++. C++ is another steep curve for an old-school programmer (I go back to FORTRAN and punch cards as well) but became necessary due to the complexity of my project.
* I wasn't even aware that there was a web-based IDE for Arduino. But it sounds like you need to install the traditional Windows-based IDE to help answer your questions about Prof. Chaos's code. I personally use Microsoft Visual Studio with a plug-in called Visual Micro -- it makes editing and debugging Arduino code significantly easier, but again there is a steep learning curve. Definitely not necessary for the straightforward project you're describing.
* I've never interfaced directly to TMCC, only to Legacy. But I doubt you can just connect wires directly between an Arduino and a TMCC base because the Arduino works on 5v signals, and some RS232 signals are higher voltage. You can buy an "RS232 to TTL Converter Module" on eBay for $5, which allows you to use a regular 9-pin serial cable. I've attached a photo of the adapter I use to connect to Legacy -- you should be able to plug a 9-pin serial cable directly into your TMCC base unit (you don't need an SER2 unless yo're connecting to Legacy) -- but I'm just guessing. Note that I needed a couple of in-line adapters to get the right wires talking (the mini adapter swaps RX and TX if I recall correctly? - it's been a long time since I hooked this up and it was just trial and error until I got it working.)
* I don't know what it means to talk to a TMCC controller? I'm only sending commands to engines via the base unit, and there is no feedback from the base unit. If you look at the signals that the base unit is sending out, you'll see that it sends everything three times, for good measure I guess. So if you connect to any base unit that's connected to your track -- I'm not sure what more you would need? Unless you've got different base units programmed for different trains -- i.e. if only certain base units are able to send commands to certain trains? My knowledge here is a little fuzzy. I've got a couple of controllers but only one primary base unit.
* As I mentioned previously, I recommended the ID-20 RFID reader, which will connect directly to your Arduino's serial port (and yes, you should be using a Mega so you'll have four hardware serial ports.) That was the best unit I could find in 2015 -- there may be something better now.
* I no longer have my proof-of-concept code to blow the whistle, but it was less than 10 lines. My real code is more complex than what you'll need, as I'm talking to Legacy, and (like Prof. Chaos), I dump my outgoing commands into a circular buffer. Then I poll the buffer and keep track of the time, to send commands at least 25ms apart, and send each command three times. These numbers and more are all pre-defined CONSTants. But here is some info that may help -- with the caveat that it's very hard to read without any formatting!
I start by setting up byte variables to hold each of the up-to-9 bytes of an outgoing command. For TMCC there are only three outgoing bytes, but Legacy can have up to 9 bytes. This is done at the top of the code, in setup():
// First define global bytes for each of the 9 possible used in Legacy commands.
// Most commands only use simple 3-byte Legacy (or TMCC) commands.
// Nine-byte commands are for Dialogue, Fx, and Control "extended" commands.
byte legacy11 = 0x00; // F8 for Engine, or F9 for Train (or FE for emergency stop all or TMCC)
byte legacy12 = 0x00;
byte legacy13 = 0x00;
byte legacy21 = 0xFB; // Always FB for 2nd and 3rd "words", when used
byte legacy22 = 0x00;
byte legacy23 = 0x00;
byte legacy31 = 0xFB; // Always FB for 2nd and 3rd "words", when used
byte legacy32 = 0x00;
byte legacy33 = 0x00; // This will hold checksum for "multi-word" commands
Then I populate the bytes as needed for whatever command I want to send. For example, to send an "Absolute Speed" command here is the code -- please note that it won't make a lot of sense because I'm using a structure with pre-defined values, adding a checksum for Legacy, and other features too deep to go into here:
case 'A': // Set absolute speed
if (actionElement.deviceType == 'E') { // This is an engine
legacy11 = 0xF8;
} else { // This is a train
legacy11 = 0xF9;
}
legacy12 = actionElement.deviceNum * 2; // Shift left one bit, fill with zero (deviceNum is train or engine ID)
legacy13 = actionElement.parm1; // parm1 will be the desired speed i.e. 50
legacyCmdBufEnqueue(legacy11); // This puts the three-byte command into my outgoing buffer
legacyCmdBufEnqueue(legacy12);
legacyCmdBufEnqueue(legacy13);
legacyCmdBufTransmit(); // attempt immediate execution
break;
Here are the guts of the function that actually sends the data out the serial port. I only write in bursts of three bytes, even if it's a longer (9-byte) Legacy command:
static unsigned long legacyLastTransmit = millis();
byte b;
if (!legacyCmdBufIsEmpty()) {
if ((millis() - legacyLastTransmit) > LEGACY_MIN_INTERVAL_MS) { // Enough time since last transmit, so okay to transmit again
b = legacyCmdBufDequeue(); // Get first byte of the command
if (b==0xF8 || b==0xF9 || b==0xFB) { // It's a Legacy command
} else if (b == 0xFE) { // It's a TMCC command
} else {
Serial.print("FATAL ERROR. Unexpected data in Legacy buffer: ");
Serial.println(b, HEX);
endWithFlashingLED(7); // Should never hit this!
}
Serial3.write(b); // Write 1st of 3 bytes
b = legacyCmdBufDequeue(); // Get the 2nd byte of 3
Serial3.write(b); // Write 2nd of 3 bytes
b = legacyCmdBufDequeue(); // Get the 3rd byte of 3
Serial3.write(b); // Write 3rd of 3 bytes
legacyLastTransmit = millis();
shortChirp(); // Do a little chirp just so I can hear when a command is sent to Legacy, i.e. in relation to when I see a train hit a sensor, to assess latency.
}
return;
}
At the end of the day, you can see that all you do is put the data in three 1-byte variables, and execute "Serial.write(data);" three times in your code. So you could accomplish the above in six lines -- three to define the contents of each byte to be broadcast, and three Serial.writes. Or just three lines if you put the data in the Serial.write() parameter ;-)
Okay Don, there is a lot to get you thinking. Now I need to get back on track (ha ha) with my own project ;-)