Skip to main content

Replies sorted oldest to newest

If this is original sound file and the wheels are clean and traction tires work, no binding, and the flywheel tape is clean with good gap.  There really isn't much you can do.  The software is programmed.

 

Chasing motor imbalances will make you pull your hair out.  Clean the motors and check gear lash.  Shim if you think necessary. At that point if your off a set value you can start making a new tape.  Less stripes then 24/24 and the board thinks the engine is going to slow and will compensate to make it move faster.  So reducing a stripe pair speeds up the train.  Adding stripes slows it down.  IF it is with in a 1-2mph range. Lashed up the track coupling will moderate it.  If you want a train to match unlashed you will have to work it, though many will do fine.  The oddball won't.   G

George, if you lash up two engines that aren't quite matched in speed, will you end up with a bad motor? I'd like your opinion on this. I know Phil Klopp had some problems with a couple of engines and I think had to replace a motor or two. I'm not sure MTH ever got the two diesel engines to match speed. I know Phil likes to run lash ups and he's favoring Legacy to do it these days. If Phil reads this, I hope I got it right Phil.

If the difference is not too great you should be ok.  Many folks lash up no issues.  I don't have empirical data though.

 

Legacy has a pretty good gear design so that you can turn the driver and rotate the motor.  That means less drag if a motor is lagging.  That also allows the legacy and TMCC to be lashed up/MU.

 

A good test is running together uncoupled.  If they match closely I don't think you will have an issue.  Where you can get into trouble is upgraded engines were scale speed is way off.  G


MTH and others still use a worm set up that does not allow the wheel to turn the motor.  The gears lock.

 

Running with shells off can really help see what is going on.  Some motors that lag, with drive trains that are tight can bind and stop and than get dragged in a stall condition.  That will definitely burn the motor up.   Sometimes they only stop in reverse not forward.  I think it has a lot to do with the gear lash and lateral movement of the axle gear.  G

Last edited by GGG

I did run those 2 identical engines as a lashup after getting approval here on the forum that all would be fine, motor-wise.

 

I don't recall the order, but a few replies suggested either the faster or slower one as the lead - they felt it could make a small difference in eliminating any motor drag.

 

I sold all of my stuff about 3 years ago - that's why I can't comment with certainty.  I know a forumite bought the 2 engines and ran them as a lashup because he showed them on a thread and talked about what a great deal he got.  I asked him to check something that I knew would identify them as mine, he did, and they were the ones that I sold off.  But he said they ran well as a lashup.

 

- walt

Last edited by walt rapp

Since the locos are firmly coupled together, it shouldn't make any difference which is in the lead.  All motors will run at the same RPM under such conditions, assuming the same gear ratio and wheel diameter.  I believe all MTH diesels (I didn't say rapid transit units) have the same wheel diameter, with few exceptions; cf the traction tire chart.

 

What will happen is that, regardless of position in the lashup, the DCS board in the loco that wants to go faster will feed more current to its motors than will the loco that wants to go slower, meaning the the motors in the former will generate more heat.  The greater the difference in the speeds the locos want to go, the greater the heat generated in the former.  If the difference becomes too great, the former's motors could be damaged.  Notice, we are talking relative terms;  there is no hard and fast rule for the electrically permissible speed difference.

Last edited by RJR

I can help here a little with some info. I run two rail mainly so there's no traction tires. I run large consists all the time. I have never lost a motor in a MTH engine.

 When the engines are in a consist on my RR, they help each other move the train. They work well together. If one stutters a little at very slow speeds, the others seem to help smooth it out. I can put my hand on the cars in a large train and they are under very little strain. The smaller 2 rail flanges on the cars I have will stay on the rails. I have always been amazed at this smooth operation.

 I do check all my engines periodically to make sure they are running smoothly and will match up. I have found nails from the track pulled into the speaker magnets on several occasions that had fooled me into thinking I had some bigger issues.

 I also run G gauge and they have traction tires. A slightly faster or slower engine will still behave and runs better in consist. I have had a few that are way out of spec on speeds. I fix those before running them in the consist. I have been running them in consists for ten years now. Too many cars for one engine on my RR!

I was thinking of putting this in the thread on questions for DCS, but as I don't own any DCS products, don't have a vested interest in the outcome, and honestly think it is only academic as slight differences in engine speed don't seem to matter in most cases, I figure it belongs here instead. 

 

I'm wondering why there would be any difference in speed in a system that used scale speed as it's measurement system.  It sounds like a simple lack of caring to make the speed accurate is the only answer, as the electronics are already in place to count the tach stripes, and the math is not very hard. At least relative to many other things.  The only hitch in the programing would be that if the number of tach stripes doesn't work out to an exact match with other motors, for example if the exact point the locomotive moves whatever distance is used as a reference, say one scale foot, and that leaves the tac somewhere between two stripes, there would be a one strip speed difference either way.  even this, however can be solved in the electronics with a 'leap year code" that says for every so many turns of the motor add an extra or take away one.  

 

The short version, with an update to the code in the engines there is no reason that DCS locomotives couldn't all move at perfect scale speeds.  (minus errors from wheel slip and improperly thick tires, etc. ) I will, however, think of the quote on GRJ's signature.  

Last edited by JohnGaltLine

John,

I'm wondering why there would be any difference in speed in a system that used scale speed as it's measurement system.  It sounds like a simple lack of caring to make the speed accurate is the only answer, as the electronics are already in place to count the tach stripes, and the math is not very hard

You may not have a real appreciation of what it costs to get the last .05% of accuracy, which is what we're discussing. These models aren't manufactured to military specifications. If they were manufactured to MilSpec, they'd be considerably more expensive.

 

There's "slop" in the gears and other factors that make the last .05% very, very elusive and expensive to obtain.

with an update to the code in the engines there is no reason that DCS locomotives couldn't all move at perfect scale speeds

Again, talk to me after you've written a few hundred thousand lines of code, as have some of us, and then tell me how easy it is to obtain perfection of scale speed.

 

I have an early PS2 with strobe tape on the flywheel but most of my engines have painted strobe flywheels.  The older engine runs about 10% faster than the others when set at the same SMPH so I adjust the SMPH accordingly and keep my eye on it (and my finger on the boost/brake button) when running it on the same track as others.

Originally Posted by Barry Broskowitz:

John,

I'm wondering why there would be any difference in speed in a system that used scale speed as it's measurement system.  It sounds like a simple lack of caring to make the speed accurate is the only answer, as the electronics are already in place to count the tach stripes, and the math is not very hard

You may not have a real appreciation of what it costs to get the last .05% of accuracy, which is what we're discussing. These models aren't manufactured to military specifications. If they were manufactured to MilSpec, they'd be considerably more expensive.

 

There's "slop" in the gears and other factors that make the last .05% very, very elusive and expensive to obtain.

with an update to the code in the engines there is no reason that DCS locomotives couldn't all move at perfect scale speeds

Again, talk to me after you've written a few hundred thousand lines of code, as have some of us, and then tell me how easy it is to obtain perfection of scale speed.

 

Working backwards here, My skills with code are a bit limited as far as complex projects go, but My father was a programer on Interact, Commodore (20/64/128), and pc, writing at hex-level throughout, and I did pick up quite a bit in the way of understanding what can and can not be done, and how tough it is to do.  Trying to fit very complex programs with graphics on a machine with 64K of memory led to writing very tight code, and that has stuck with me.  I understand that the code running in a DCS loco is likely quite complex, compared to what most hobbyists do,but compared to the autonomous robot I helped my father build it doesn't seem like much.  With capability for 128 inputs, 256 Digital outs, PWM motor control for motors drawing several amps each, 5 striped optic tachs to make sure it knew exactly how far it moved and to correct any drift or wheel slip, ultrasonic range detection, and a perimeter of 24 micro switches to detect any obstructions I thik the code was a bit more involved that reading one motor.  Mind you this was done in the mid 90's so all the electronics were scratch built to interface with the 8bit port on a commodore64.  That said just to point out that I have some understanding of what is involved to code a thing or two.  I agree that that last .05% is a pain... but ...

 

The original post didn't get too precise with how far off the speeds were, but I read it as being somewhere around maybe one half mile per hour off. in terms of the scale used for these locomotives, that isn't .05%.  it's 50% error.  Here I'm going to make up some numbers, because I don't know the actual figures, but I will try to use a best guess.  Say this is a steam engine as in the original post.  The drivers are maybe 1.5 inch diameter?  Lets say the worm/drive gear ratio is 24-1, and the flywheel has 28 stripes.  

1.5 * Pi = 4.71...inches pur turn.

4.71 / 24 /28 = .0070 inches travel per tach stripe.  

that means , if my math is right, one scale mile is 15,500 tach stripes   

or 4.3 stripes per second at 1 SMPH.  

I find it hard to believe that the code can not be cleaned up to not skip every third tach stripe.  as in effect if it is off by half a MPH the program is, in this example, missing a third of the tach stripes to be off by half a MPH.  

 

As for gear slop and the like, yes, gears have slop, if you tell the motor to go back and forth in small increments, the slop will leave you without movement, however, unless you have a serious problem, gears don't skip teeth.  in the above example, 672 tach stripes will Always be one full turn of the wheels you may have to deal with slop for the first tenth of a second, or as you change the speed but with a locomotive running at a constant speed, slop between gears has no role in the math.  I will add here that wheel slip will give you problems here, but for purposes of the example we can pretend that each engine will experience similar slip and it should not dramatically affect two engines running on the same track.  

 

In the end I think it's just a case of simple math.  .05% error would be losing one stripe in 500... and what we are seeing is losing one in three, or 33% error, say between 25% and 50% error depending on the actual gear ratios involved.  Now on the electronic level I can see losing reads when traveling fast, as say at 200 SMPH you have over 800 strips per second, which would require very tight code on a high level micro-controler such as an arduino or PIC... then again having a single chip that has the job of 'count stripes and report back every tenth of a second' would eliminate that problem... also 200MPH is not very prototypical for a most engines.  

 

Sorry for the long reply for something that is just an academic curiousity to me, but thought I should follow up.  

 

Last edited by JohnGaltLine

John, Get an MTH engine or 2 and DCS and try it.

 

Gearing is one important factor.  Legacy drive trains on diesels are totally different then what you have seen before. Steam maybe too. The drive train was one reason Lionel engineers gave for why a Legacy upgrade kit would not be had. 

 

I don't fully understand it, but I imagine the consistency between Legacy engines would be at risk with someone else's not legacy driven train.  The diesel trucks are a wonderful improvement.  Maybe MTH will go that way, but R&D has been into other things that no one else is really doing.  So you can't fully blame a company for seeking profits in different markets, though we can certainly complain about it.

 

For MTH, there are hardware issues with as chosen equipment.  Tach reader specs for counting frequency, 24 stripes pairs.  These ultimately limit what accuracy you can get too. Removing 1 pair is a 4% change.

 

Plus all the other factors already mentioned.  Lash them up and that inaccuracy doesn't matter anymore.

 

So how much do you want to spend for an engine that can match speed uncoupled when you easily can set one a 12smph and the other at 11 to get them moving the same relative speed?

 

There is memory limits also, especially when your loading all sorts of additional sounds, features, playback etc...  Which seem to be the features the majority want.  G

John,

 

You are generalizing from a specific instance, which is a ad practice.

 

I own and operate 97 PS2 and PS3 engines, and speed check each one on a measured course. Speed accuracy of all of them vary by no more than .05% at 30 SMPH. That's + or - 1.5 SMPH, with the great preponderance of them within less than 1 SMPH.

 

Any engine that's out of this range is typically suffering from a defective tach tape/porous painted flywheel, an out of spec tach reader or a sound file that contains errors in the peed control parameters.

 

As far as practical code development experience is concerned, it's something we actually accumulate by doing, it's not inherited.

Jon, (lionel CTO) indicated to me that when an MU or multiheader consist is created with Legacy engines, they have the trailing engine in software going slightly slower than the lead engine. While my fleet of MTH engines (50 or so) is less than Barry's, I to have found all them to be within one smph of each other. One MU (Rdg Alco S2 and V1000) did not play well together (more than 1.5 smph difference) and after having the Alco S2 in for repair twice (not positively identified as the cause but it was the leading suspect), I sold the V1000.  All my other 10 MUs (2 to 4 units) have never had any issues.  For kicks I even had an Erie Triplex and a WM SD 40-2 that ran without issues.

I want to start here by going out of my way to make the point that this is an academic topic for me. It is a question of why the error can't be fixed with modern (decades old, really) technology. I'm not attacking anyone, anyone's experience, any of the manufactures, or their products. The real world answer was already addressed, I think. The answer being that a slight speed difference is not worth putting any trouble into fixing because it just doesn't matter enough to waste any time on.

 

That said, the rest of this is split into three parts. First, just responding to what others have said. I'm taking the skeptical view in my replies, nothing against anyone, just intentionally going for the most fault I can find in any idea. Second, some things I learned while taking a unique approach to answering the criticism I received in my thoughts, namely the idea that I don't understand the problems in the coding of the program. The last section is my response to that, The code for fairly precise speed control using a $2 ATMega micro-processor. (same as used in the Arduino Uno)

Enjoy.

 

GGG,

Gearing is one important factor.  Legacy drive trains on diesels are totally different then what you have seen before. Steam maybe too. The drive train was one reason Lionel engineers gave for why a Legacy upgrade kit would not be had. 

 

I don't fully understand it, but I imagine the consistency between Legacy engines would be at risk with someone else's not legacy driven train.  The diesel trucks are a wonderful improvement.  Maybe MTH will go that way, but R&D has been into other things that no one else is really doing.  So you can't fully blame a company for seeking profits in different markets, though we can certainly complain about it.”

 

I can see how the gearing could affect the precision at which the tach can read, and a better gear box would help things. I'm not familiar with what Legacy engines use, but even the simple worm gear and tach strip on the flywheel seems adequate for the purpose of maintaining speeds within less than 1/8 MPH.

 

 

For MTH, there are hardware issues with as chosen equipment.  Tach reader specs for counting frequency, 24 stripes pairs.  These ultimately limit what accuracy you can get too. Removing 1 pair is a 4% change.”

This is the mechanical limitation of the design. The reader doesn't know if it just reached the new stripe, or if it is almost touching the next one. I don't know what the coding is in these engines, but to take best advantage of the design, it should be reading stripes and not-stripes, so you really have twice as many points of information than you do stripes. This leaves you about 2% margin for error per turn if you had one more or less stripe. In any case I think we agree on the point that there is a built in limit on how accurate you can read the speed. Even if we say it is as much as 5% off per turn, that equated to 1SMPH for every 20 which I think most folks would notice.

 

Plus all the other factors already mentioned.  Lash them up and that inaccuracy doesn't matter anymore.

 

So how much do you want to spend for an engine that can match speed uncoupled when you easily can set one a 12smph and the other at 11 to get them moving the same relative speed”

 

I agree that it just doesn't matter in reality, but I can't help but wondering why things would be as far as 1 SMPH off without a mechanical error such as the wrong tach tape as addressed above.

 

There is memory limits also, especially when your loading all sorts of additional sounds, features, playback etc...  Which seem to be the features the majority want.”

 

The code to do speed control is pretty simple, and I can't actually see how it would be error prone to that degree except as I'll discuss below. I found this old thread https://ogrforum.com/t...r-a-2meg-proto2-chip

that shows that MTH is using a 2MB memory chip and it references that older boards used a 1MB chip. I don't think a few lines of code will break the bank here, but you can judge from the example below.

 

 

Barry:

You are generalizing from a specific instance, which is a ad practice.

 

I own and operate 97 PS2 and PS3 engines, and speed check each one on a measured course. Speed accuracy of all of them vary by no more than .05% at 30 SMPH. That's + or - 1.5 SMPH, with the great preponderance of them within less than 1 SMPH.”

 

Here you say it is a specific instance, then go on to confirm that your 97 engines are as much as 1.5 SMPH out of sync at 30 SMPH, so I'm not sure what your going for as you seem to be contradicting yourself. I know that wasn't what you intended, but I read it as saying that +/- 1.5SMPH is the normal range for MTH locomotives which is the same range of error that I'm curious as to why it exists.

 

In addition, I think we have a problem with decimal points going on, leading to some of my confusion in your responses. You say .05%, but in the example you give of being 1.5MPH off at 30 MPH, that is 5.00% 100 times greater difference. I fully agree with your previous posting that that last .05% is a nightmare to program and even to mechanically achieve, but 5.00% is quite substantial in the world of computers. 0.05% of 30 SMPH is just 0.015 Miles per hour or a Sixty-Sixth of a mile per hour.

 

Any engine that's out of this range is typically suffering from a defective tach tape/porous painted flywheel, an out of spec tach reader or a sound file that contains errors in the peed control parameters.”

 

In the case of being 5% off, 1.5mph at 30mph, I'd first check for mechanical error such as being +/- a tach stripe, so I think we agree here that mechanical error is the first thing to check. As far as my original question goes I was aiming for the half MPH error range.

 

As far as practical code development experience is concerned, it's something we actually accumulate by doing, it's not inherited.”

 

In most cases I would tend to agree with you, but I think I have a special circumstance to consider. My father here has Cerebral Palsy, and had limited physical ability, My mother and I typed most of the code for him. I have typed countless thousands of lines of code, though I will admit to not understanding all of it all the time, but I understood enough to make my original point in mentioning it. Namely that I have rather good understanding of what can be done and exactly how difficult it is to accomplish various things. For further background on the above noted robot project I also built most everything, probably have brain damage from soldering with 60/40 lead since I was 6 years old.

 

Part 2:

 

For the this section I'm going to be using some best guess figures and some simplified figures to make things simple. Here's what I'm going to use, though it may not reflect any actual locomotive the numbers are close enough for the examples. Your milage may vary with real engines.

Sample figures used from her on:

Drive wheel diameter: 1.25 inches (chosen for being about half way between scale steam and diesel.)

Drive gear ratio: 32:1 (chosen based on it being the ratio on the MTH product I own.)

Tach stripes on the flywheel: 24 (chosen based on other forum posts mentioning this as a common size.)

Top speed: 150 Scale MPH (This is sort of a made up number but I think represents a value higher than what we are likely to see in our models.)

 

Also of note, I'm going to skip the narrative of explaining what various terms mean, under the assumption that anyone interested in the subject to this extent will know what I mean. Just ask if some abbreviation or other has you at a loss.

 

While investigating what is involved in accomplishing speed control with minimal error I put a lot of thought into finding where error can occur and what to do about it. The first thing is the actual limitation of the hardware involved. I'd like to assume that the electronics can keep up with the tach reader, in the example about 258,000 tach stripes should be read per mile, or about 11,000 per second at 150 MPH. I do not know what speed the Proto2/3 processor is, not for lack of trying , but it seems my google-fu is weak. If we assume it is absolutely awful and obsolete since 1985, it's at least a 1MHz clock speed, and I'd like to think they used something fairly modern in the at least 16MHz range and probably higher yet if it is processing sounds. At 16MHz then the processor needs to read the tach once every 1450 cycles, not a problem if that is all it's doing, but could be an issue if the same processor is doing other things... If the cpu in use can't keep up with the tac there are several solutions I have. You could use a separate processor to run the speed control, or use a counter such as a 74ls161 to handle the counting and be read only when the processor has time. I decided that I will use a separate micro-controller for speed control as it is the simplest solution using the fewest parts. In production I'm not sure if this is the best option, but I think it works well to use one processor like this to operate speed control, speed adjustment, and the h-bridge for direction control.

The mechanical limitations of the system is about 0.5% at 1 SMPH. this is caused because not enough stripes move past the reader. This error is cumulative in the first code that came to mind, but I think it becomes a single error of .005MPH with a bit more thought put into the code.

 

The next major thing that comes into play is that computers don't like decimal points. When you use floats (numbers with decimal points) computers tend to make things up and you leave a lot of room for error. To circumvent this I'll be using a pretty old and common technique of multiplying the figures to use whole integers in the math. In addition floats are relatively processor intensive, so using long ints makes for faster code. (correction: by using the speed table I eliminated the need for fractional numbers. )

 

To help lessen the error caused by these two problems I'm implementing a speed table method to adjust speed where the control system/primary cpu in the locomotive will issue a 4 byte command to the speed module, that will give speed and direction information. The command will be a speed based on the number of stripe state changes desired to occur in 1/10 of a second. I do not know how responsive the system in use is, but based on the mechanical limits of the system any faster sample size will cause reading problems and errors in speed control at very low speed... and it seems to me that a constant speed control is most valuable at the low end of the scale. Even 1/10 second may prove troublesome and I'll have to experiment with a working model to determine what the best read time should be.

 

Part 3:

A sample program for constant speed control in 1 scale mile per hour increments with minimal error of speed. Aka cruise control and command control of a locomotive for speed and direction.

 

This section is dedicated to the idea that what is involved in programing a better cruise control is too complex to understand and that it is easy to say it should be better, but in reality is very hard to implement. Rooted in the comment that :

You may not have a real appreciation of what it costs to get the last .05% of accuracy, which is what we're discussing. These models aren't manufactured to military specifications. If they were manufactured to MilSpec, they'd be considerably more expensive.”

 

First, I'd like to note again there seems to be an error of decimal points, as .05% error even at a top speed of 150 SMPH would be only 0.075 miles per hour. Far, far FAR below the mechanical limitations of the hardware in use of about .5%. in the sample of being within one less than one mile per hour at 30 SMPH, that is an error of up to 3.3%. When you also take into consideration that one engine could be running 3.3% fast, and another 3.3% slow you can see that margin of “slop” involved is 6.6%. I'm going to use the lesser error of 5% for examples from here on. Again to note the decimal point issue, the mentioned of “the last .05% of accuracy, which is what we're discussing” is not at all what we are discussing. 0.05% is 100 times more precise than the margin of error we are discussing. My theory is that it can very easily be reduced to .5%, and in implementation of speeds over, say 10 SMPH, you can even get to that .05% level.

 

And more specific:

 

...talk to me after you've written a few hundred thousand lines of code, as have some of us, and then tell me how easy it is to obtain perfection of scale speed.”

 

Well, here it is. You judge how easy it is based on the following information: I have no formal training in computers, programing, or electronics. I've been playing with the platform I used for less than 5 months and have never used C language until that time. I spent about 10 hours on research, most of that spent finding a solution to dealing with decimal points in math in C language, only to come up with a better solution. The program it's self took about 8 hours of my time to write, then another hour or two to go back through to add comments to make it easier to follow. If I can do the thing in my spare time in about a week, someone being paid to design a speed control should be able to do a better job and do it faster. The simplicity of the code involved makes me really wonder what programing experience someone had, that thinks it is difficult.

 

As for the cost involved, I am forced to reaffirm my original assumed answer in my first post in the thread. The hardware is already present. In writing this code, I came to the conclusion that writing the code to do the job, in the simplest way is pretty accurate, and the error we see is well beyond what even the most kludged solution to coding would offer... reaffirming that someone just doesn't care somewhere along the line and is not using engine specific figures in the cruise system. One other cause of error came up, which is the possibility that the micro-processor used is just too slow to count the tach while doing other things with sound and command control. In this case the solution would indeed increase the cost of the locomotive... you would need to add a counter IC to keep counting while the processor is doing other things. I know we are concerned with making things “considerably more expensive” and I know this will really break the bank here on a locomotive that costs over $500 on the low end of the spectrum... 74161 binary counter, good for pulse speeds of at least 4MHz (2.0 volts and running in an oven (25MHz under normal conditions)) costs the astronomical sum of $0.10 each in low production quantities.

 

The problem at hand is pretty much a 6th grade story problem, where the information needed is the diameter of the drive wheels, the gear ratio of the drive train, the number of pulses per revolution of the motor for the tachometer, and the scale used, in this case 1:48. In addition you need to know some constants such a Pi being 3.141592...,an hour is 3600 seconds, a mile is 5280 feet, and a foot is 12 inches... assuming we use imperial measures... we could go metric, but as the standard is scale MILES per hour, it seems fitting to use imperial throughout. This is all you need to figure out the scale speed you are moving at. In the code you need to also increase or decrease speed to match to the desired value.

 

Here's the premise of how it works in this example: an ATMega328 chip (The processor in an arduino uno) reads the signal from the tach and times pulses in a sample window of 1/10th of a second. It then compares the number of pulses to the speed it received from the command system. If the difference is significant defined as error of more than 1/16 SMPH (apx. 0.042% at 30 SMPH), adjust speed as needed. The ATMega micro-processor will receive a serial data signal from the command system or other processor in the locomotive that is 4bytes long. I'm using 14 bits for speed information, and 2 for motor direction, allowing the cruise to share space with the 'e-unit' and the PWM for motor drive. One byte is used to send a base value to start the pwm signal for a given speed. The last byte is a simple start byte used to tell the processor that the following three bytes are valid information.

 

I decided to use the ATMega328 because I am familiar with how it works and the language used to program it better than more cost effective solutions like a PIC. The ATMega328 cost about $1.69 each in production quantities. Not cheapest way to go, but far from prohibitively expensive.

 

Here we go:

 

// top note. there are likely errors here. the code has not been tested

// in the real world. Still I think it serves the purpose of showing

// how complex... or not complex, cruise control really is.

 

/* About the program / notes.

 

Note 1: As written this code takes 3,714 bytes of the 32,256 available on

the ATMega328. This includes the librarys and boot loader for Arduino.

 

Note 2, sample values to be used:

Drive wheel diameter: 1.25 inches

Drive gear ratio: 32:1

Tach stripes on the flywheel: 24

Top speed: 150 Scale MPH

 

note 3:

This system uses an engine specific input to set the desired speed.

the value sent to the program will vary based on what locomotive is in use.

this number table will be stored in the main control board's memory and will

take about 5KB memory. Later I'll see about putting the table in the

ATMega's memory, but this has the disadvantage that the cruise module

becomes engine specific. The reason for the table is to reduce error caused

by the tach reading sensitivity. This error multiples with each speed step

if you simply tell the code that 2SMPH is twice as many tach reads as 1SMPH

as 1 mph may be 7.25 stripes, so 40mph with simple multiplication would

be 280 stripes when in reality it is 290.

 

With the sample figures used here:

258,151.8641741437 stripes per mile.

x2 because we count stripes and not stripes.

= 143.4177023189687 tach counts per second per SMPH

14.34177023189687 stripes in the 1/10 second read cycle I am using.

table example:

1mph=14, 2mph=29 3mph=43, 4mph=57, 5mph=72, 10mph=143, 25mph=359, 50mph=717

 

*/

 

//Define constant variables for the program

unsigned int requestedSpeedStep = 0; //Define var and set speed to zero on power up. (unsigned int allows numbers up to 65,535. much higher than we need with the current design, but this allows a much tighter stripe wheel for higher resolution to be implemented in the hardware)

int tachPin = 2; // define GPIO pin to read the tach sensor.

int pwmPin = 5; // define pwm output pin.

int hBridgeLeftLow = 4; // no pwm

int hBridgeLeftHigh = 5; // pwm

int hBridgeRightHigh = 6; // pwm

int hBridgeRightLow = 7; // no pwm

unsigned int lastRequestedSpeed = 0; // define var to detect change in requested speed.

unsigned int currentRequestedSpeed = 0; // define var to detect current requested speed.

int readCycleTime = 100; // set read time to 100 milliseconds.

int currentStripeState = 0; // define var to detect new tach information

int lastStripeState = 0; // define vsr to detect stripe state change.

unsigned long clock = 0; // define var for clock counter. time in milliseconds. stores value up to 4,294,967,295, or almost 50 days continuous runtime. after this time the clock will loop to zero which will provide one cycle that could confuse the code. there are ways to work around this, but I decided that 50 days is beyond the realistic time a locomotive will be run without being powered off.

unsigned long startClock = 0; // define clock time for start of read cycle.

int inByte = 0; // define var for incoming serial data.

int byteOne = 0; // define var for serial byte one

int byteTwo = 0; // define var for serial byte two

int byteThree = 0; // define var for serial byte three

int pwmByte = 0; // define var for base pwm setting.

int serialFlush = 0; // define var for garbage serial data flush.

long stripesThisCycle = 0; // define var for counter loop

long stripeCounts = 0; // define var for counter return

int currentPwmStep = 0; // define var for pwm.

int dirBits = 0; // define var for engine direction bits.

int currentDirection = 0; // define var for engine direction.

int ruleSeventeenLight = 0; // define var for rule 17 light dimming

int cabLight = 0; // define var for cab light

int fireBoxGlow = 0; // define var for firebox glow intensity

int ashPanGlow = 0; // define var for ash pan glow intensity.

int tenderLight = 0; // define var for tender back up light.

int ruleSeventeenLightPin = 13; // define atMega pin for headlight output. probably needs a transistor to boost current for high intensity LED or incandescent bulb.

int cabLightPin = 12; // define atMega pin for cab light ditto above transistor.

int fireBoxGlowPin = 11; // define atMega pin for cab light ditto above transistor.

int ashPanGlowPin = 10; // define atMega pin for cab light ditto above transistor.

int tenderLightPin = 9; // define atMega pin for cab light ditto above transistor.

 

 

//Loop that runs once when the processor powers up:

void setup() {

Serial.begin(9600); // initialize the serial port on AtMega.

 

// set GPIO pins to input or output mode as needed

tachPin = INPUT;

pwmPin = OUTPUT;

hBridgeLeftLow = OUTPUT;

hBridgeLeftHigh = OUTPUT;

hBridgeRightHigh = OUTPUT;

hBridgeRightLow = OUTPUT;

ruleSeventeenLightPin = OUTPUT;

cabLightPin = OUTPUT;

fireBoxGlowPin = OUTPUT;

ashPanGlowPin = OUTPUT;

tenderLightPin = OUTPUT;

 

}

 

//Loop that runs while processor is powered on.

void loop() {

// check if there is new serial speed data.

getSetSpeed();

 

// break from cruise if new speed has been sent and change to that speed.

checkAndSetNewSpeed();

 

// check current speed.

stripeCounter();

 

 

 

// check if speed is different from desired speed.

// --> if so adjust as needed

// stripesThisCycle - return value from stripe counter.

// requestedSpeedStep - return desired stripes

if (stripesThisCycle > requestedSpeedStep) { // going too fast?

currentPwmStep = currentPwmStep--; // then lower pwm setting by one.

} // may need to add code to prevent overflow roll over

if (stripesThisCycle < requestedSpeedStep) { // going too slow?

currentPwmStep = currentPwmStep++; // then raise pwm setting by one.

} // may need to add code to prevent overflow roll over

 

// if one pwm step is too much of a change, the step will go up and down each cycle,

// averaging the speed between. this will have some error with the default 8 bit

// pwm resolution, but will be lessened if 10 bit resolution is used.

setDirection();

 

 

 

}

 

 

// tab loops:

// getSetSpeed() - read data from serial and set vars

// checkAndSetNewSpeed() - Check for new speed setting and change speed to match.

// stripeCounter() - count stripes for set sample time and return value

// setDirection() - sets h-bridge for direction and speed. also sets features.

 

// Tab getSetSpeed

 

void getSetSpeed() { // read serial data and define the desired speed.

/*

Vars used in this loop. Defined in main tab.

int inByte = 0; // define var for incoming serial data.

int byteOne = 0; // define var for serial byte one

int byteTwo = 0; // define var for serial byte two

int byteThree = 0; // define var for serial byte three

*/

 

if (Serial.available() > 0) {

inByte = Serial.read();

if (inByte == 0xAA) {

byteTwo = Serial.read();

byteThree = Serial.read();

pwmByte = Serial.read();

 

}

else {

serialFlush = Serial.read();

}

 

}

 

 

// RETURNS THE unsigned long of requestedSpeedStep

int byteTwoShiftA = byteOne << 2; // shift out direction data.

int byteTwoShiftBack = byteTwoShiftA >> 2; // move data back.

long byteTwoShifted = byteTwoShiftBack << 8; // bit shift first byte by 8 bits.

 

 

requestedSpeedStep = (byteTwoShifted + byteThree);

// EDIT HERE.  removed the line: currentPwmStep = pwmByte; // set default speed step.

// EDIT HERE.  explained below.  

 

// get direction information

dirBits = byteTwo >> 6;

 

if (requestedSpeedStep = 0) { //if speed is set to zero, set direction to netural

dirBits = 0B01;

}

 

 

 

 

}

// Need to error check this part of the code.

// it is not important to the functionality of the cruise,

// only to get the desired speed from the command system.

 

// tab = checkAndSetNewSpeed

 

void checkAndSetNewSpeed() {

/* this loop will check if the desired speed has changed and set the

motor driver to the base pwm for the new speed if it has changed.

 

I had a bit of trouble with this section, as originally I was sending

only the desired speed steps to the controller. The two solutions I came

up with were to either add another byte of data to the speed table, or to

add a routine for large jumps in speed adjustment if the speed change is

great. I decided to use the base pwm byte of data to make response time better.

 

 

basically all that happens here is to check for new speed data and run the

direction loop controlling the H-Bridge.

*/

 

if (requestedSpeedStep != lastRequestedSpeed) {

currentRequestedSpeed = requestedSpeedStep;

lastRequestedSpeed = currentRequestedSpeed;

 // EDIT HERE.  Next line added:

currentPwmStep = pwmByte; // set default speed step.

// EDIT Above.  Above line added.  Seen notes below.  

 

// set pwm to default step for chosen speed

 

setDirection();

 

delay(100); // give a bit of time here for the engine to adjust to new speed before letting the cruise start making adjustments.

 

}

}

 

 

// tab for setDirection()

 

// this loop will set the h bridge for motor direction.

// the pwm step is implemented here.

// it also runs a number of features such as rule 17 lighting, firebox glow and tender backup light.

 

 

 

void setDirection() {

if (dirBits = 0B11) { currentDirection = 1; } // if bits are high go forward

if (dirBits = 0B00) { currentDirection = 2; } // if bits are low go reverse

if (dirBits = 0B01) { currentDirection = 0; } // if bits are not set go neutral

if (dirBits = 0B10) { currentDirection = 0; } // if bits are not set go neutral

 

 

 

if (currentDirection = 0) { // if set to neutral..

digitalWrite(hBridgeLeftHigh, LOW);

digitalWrite(hBridgeLeftLow, LOW);

digitalWrite(hBridgeLeftHigh, LOW);

digitalWrite(hBridgeLeftLow, LOW);

 

analogWrite(ruleSeventeenLight, 128); // set headlight to half bright in neutral.

digitalWrite(cabLight, HIGH); // turn on cab light in neutral

analogWrite(fireBoxGlow, 64); // set fire box to 1/4 brightness (may need to adjust for proper effect.)

analogWrite(ashPanGlow, 32); //set ash pan to 1/8 brightness (may need to adjust for proper effect.)

digitalWrite(tenderLight, LOW); // set tender light off in neutral.

 

}

 

if (currentDirection = 1) { // if set to forward..

analogWrite(hBridgeLeftHigh, currentPwmStep);

digitalWrite(hBridgeLeftLow, LOW);

digitalWrite(hBridgeLeftHigh, LOW);

digitalWrite(hBridgeLeftLow, HIGH);

 

digitalWrite(ruleSeventeenLight, HIGH); // set headlight to full bright in forward.

digitalWrite(cabLight, LOW); // turn off cab light in forward

analogWrite(fireBoxGlow, pwmByte); // set fire box to pwm base for speed (may need to adjust for proper effect.)

analogWrite(ashPanGlow, pwmByte); //set ash pan to pwm base for this speed (may need to adjust for proper effect.)

digitalWrite(tenderLight, LOW); // set tender light off in forward.

}

 

if (currentDirection = 2) { // if set to reverse..

digitalWrite(hBridgeLeftHigh, LOW);

digitalWrite(hBridgeLeftLow, HIGH);

analogWrite(hBridgeLeftHigh, currentPwmStep);

digitalWrite(hBridgeLeftLow, LOW);

 

digitalWrite(ruleSeventeenLight, LOW); // set headlight to off bright in reverse.

digitalWrite(cabLight, LOW); // turn off cab light in reverse

analogWrite(fireBoxGlow, pwmByte); // set fire box to pwm base for speed (may need to adjust for proper effect.)

analogWrite(ashPanGlow, pwmByte); //set ash pan to pwm base for this speed (may need to adjust for proper effect.)

digitalWrite(tenderLight, HIGH); // set tender light ON in reverse.

}

}

 

 

// Tab stripeCounter();

 

void stripeCounter() { // this will count the number of stripe state changes

// over the read Cycle Time. I plan to later experiment

// with having the cycle time lessen as speed increases

// Allowing for better response time as there are more

// stripes to be counted.

 

clock = millis(); // set clock var to cpu clock time.

startClock = clock; // Set the starting time (start the stop watch)

 

while (clock < (startClock + readCycleTime)); { // run loop while clock is less than cycle time plus start time.

clock = millis(); // advance clock to current time

currentStripeState = digitalRead(tachPin); // check the sensor

if (currentStripeState != lastStripeState) { // check is sensor changed states

lastStripeState = currentStripeState; // reset check value

stripesThisCycle = stripesThisCycle++; // advance the counter

}

stripeCounts = stripesThisCycle; // set global var for stripe count

stripesThisCycle = 0; // Reset the stripe counter.

 

 

}

}

 

 

 

 

 

 

 

// fin.

 

Fin.

 

Thanks for your consideration.  

 

"A creative man is motivated by the desire to achieve, not by the desire to beat others."


"The question isn't who is going to let me; it's who is going to stop me."

  --  Ayn Rand

Last edited by JohnGaltLine

  I run almost all MU as seen in the video. Initially i checked each engine for speed matching and all were close enough using specs in the O Gauge Companion. I improved speed matching and smooth performance by gear end play shimming as well as additional under the shell services. I also said if i burned out a motor so be it. Motors are cheap.

  55 seconds into the video, this MU has 4.2k scale miles runs smooth and all motors are original. The motor commutators do get a electromotive cleaning every 500 scale miles or so as well as a truck service(mostly removing debris)

  In conclusion...these dc can motors and ps2/3 boards are pretty tough at least in my train world so i say hook them all together and spool up that thumb wheeland gear service.

DSC00821.jpg Idler gear end play

Attachments

Images (1)
  • DSC00821.jpg Idler gear end play
Last edited by willygee
 
Originally Posted by rtr12:

How are you testing all this? It all may sound good in theory, but until it's been thoroughly and completely tested with many different engines I don't know how it could be declared functional and working without error?

As I said above I have not done any real world test as of yet, the purpose was to illustrate  what the code could look like and the level of complexity involved.  If I have time over the next week or two I will build a working model, and I'm sure there will be bugs to fix.  Most likely there will be timing errors that need delays added to the code, as well as a few places where the code thinks that 255+1 = 0 that can cause problems.  I'll get it sorted out on a model at some point as I plan to use similar code in a wireless control system I'm playing with.  

 

 

 

Originally Posted by gunrunnerjohn:

It's very hard to follow exactly what is being attempted here.  Perhaps a concise description of what you're trying to do would help.

I'll try to keep it short.  Based on the original post:  
 
Originally Posted by litegide24:

I have two protosound 2.0 steam engines that run different speeds.  Never been a problem but when I run them on the same loop one catches up To the other.

 

I would say they are not quite 1mph off because if I run one at 9mph and the other 10mph, the 1mph difference over compensates.  

 

Is is there a way to sync the DCS speeds so they run at the same speed?

 

 

From that, as well as comments in later posts, I came to the conclusion that the speeds are as much as 1/2 Scale mile per hour.  (twice that when you consider that one could be +.5mph, and another could be -.5mph.)  I asked why it was not more precise, and was told it would be too difficult.  My brain said... everything is already in the engine, and software doesn't seem hard to make a frequency comparator, so I made one.  
 
That's what the post is about.  as for the program/ micro-processor its self, it is a simple curse control/ speed adjustment/ e-unit.  I added rule 17 lighting, cab, firebox, ash pan, and tender light.  I understand the code is messy,  I don't do this for a living, and to be honest I didn't put any effort into making it neat.  For folks that are not programers, or familiar with C type languages it may as well be written in greek.  Then again the harshest critics were making mention of the  hundreds of thousands of lines of code they have written.  I assumed those folks would follow along, comment how poor and unnecessarily complex my code writing is, and I don't mind if others don't follow the code.  
f
 

Well, I actually do program in C and have for many years.  I just wasn't sure what you were trying to accomplish. 

 

Clearly, nobody is going to reprogram their DCS locomotives, there's a lot more than just the speed control and lighting effects involved.  Given that fact, posting the code didn't seem all that useful to me. While I briefly thought of actually wading through the code, since I don't see a practical application for it, I didn't want to invest the time.

 

Do you have plans to actually try to implement this code?  That would make it a lot more interesting.  As for reading the code, formatting it with the HTML <code> tags would help the readability a bunch.

 

If you get this all working in an engine or two of your own and get them perfectly speed matched, that would be a very good accomplishment. However, I still don't think this will represent the complexity MTH would face in speed matching all the engines in their vast catalog of PS2 & PS3 offerings. Maybe I am missing something, but it still seems like apples and oranges to me?

John, you are more or less right in not wasting the time.  There was no intended practical application, the point was simply to show that writing cruise control is very, very, simple stuff. 

 

all the program does is:   

1, check if a new speed has been sent from the control system.

2, if it has, increase or decrease speed to the new speed desired.  

3, count how many tach strips go by in a given amount of time.

4 if too many go by, go slower.  if not enough go by, go faster.

 

I don't expect anyone to do anything with this, except to understand that cruise control is not rocket science.  Perhaps also that there may be folks about that enjoy chatting about odd technical things for no good reason.  Some folks count rivets while I couldn't care less if a box car is dull orange with rubber cows shaking through it.  When it comes to simple electronic projects and computer controls, I'm sure most folks would rather have a rivet put through their forehead, but I find it fun to talk about.  

OK, I guess I was reading too much into it.  Having designed and programmed several servo systems for avionics that were a lot more critical than the model train speed control, I didn't think it was any big deal to do basic speed or positioning control.  The most critical part is probably the design of the components to allow you the speed step resolution desired.

 

Truthfully, I think the back-EMF speed control is a bit trickier, especially what Jon Z. talked about.  Not only does he use back-EMF, but at slow speeds he uses the commutator transitions.  I'd like to get a peek at that code, as well as how that was sensed in the hardware.

 

Originally Posted by gunrunnerjohn:

... 

Truthfully, I think the back-EMF speed control is a bit trickier, especially what Jon Z. talked about.  Not only does he use back-EMF, but at slow speeds he uses the commutator transitions.  I'd like to get a peek at that code, as well as how that was sensed in the hardware.

 

I would tend to agree 100% with you on this.  I understand the concept, but actually making it work is beyond what my skills are capable of.  My example was just on hardware already in place on mth locomotives with the optical tach tape sensor.  I'd love to see how the back emf systems work, and one day may have a nice rambling, incoherent, post about that to share as well, but for now it's beyond me.  If faced with a motor where using the sensor on a flywheel was not an option, such as an old style open frame universal motor, I think a simpler solution would be to paint the back of a drive wheel and use a sensor there as you did for the optical chuff switch you shared.  The resolution wouldn't be very good, but it would be enough at speeds above a crawl.  

I understand how the basic back-EMF works, I think Jon add a nice wrinkle with the sensing the commutator transition for slow speeds.

 

Basically, whenever a permanent magnet DC motor is running, there is a back-EMF generated, that being a current opposite the driving current, it's really acting as a generator.  The back-EMF is directly related to the speed of the motor, a handy attribute.  So, if you run the motor with PWM, you can measure the back-EMF during the off times of the PWM waveform and the amplitude gives you a gauge of how fast the motor is turning.  You can then adjust the motor drive based on the back-EMF to maintain a constant value.  You just measure the back-EMF with an A/D channel during the PWM off times.

 

It's easy to write this down, and that part isn't that hard to do.  I'm not sure how the commutator transition is sensed for the Cruise Commander.

 

 

 

Like I said above, I understand the concept, but actually building a working model (of a back EMF speed sensor) is something that I don't think is in my current skill set.  I do appreciate the nice concise expiation.  Perhaps one day I'll play with it, as I do love the idea of a universal control board for any dc/universal motor.  

If I ever come up with a reason to build one, I'm sure I could do it.  Since I'm just coming back up to speed programming after years of being away from it, I'm starting with small projects and working my way up to the more complex stuff.  Also, you have to have the hardware to support this functionality.  I'm currently considering some other projects that have more promise.

 

This is an old thread.  Why not resurrect it?!

I've managed with a lot of dead ends to get exactly this far:

I took a Mabuchi RS-365sh motor.   I measured its resistance (by measure its stall current and calculating).  I came up with something around 5 ohms.  I put a second resistor of the same ohms next to the motor in series.  I wired it up to a power source.   I measured the voltage drop on the resistor in series -- this is supposedly the back emf of the running motor.

Oh, I forget, I previously calculated motor constant Kv by measuring motor RPM using a handheld tachometer.  I used a hand held drill for this and spun the motor and measured the voltage coming out of it at a couple of different RPMs -- took an average.

Using Kv, I calculated the RPM at various bemf voltages from the that voltage drop scenario and came seemingly dang close to what the tach said in that case.  In other words the motor this time was running off a battery source not the drill and I got the bemf from the resister on a hand held meter.  I then multiplied kv * bemf and got an RPM -- and compared that by hand to a tachometer reading I made by hand.

I declared a limited success.

Now I believe I'm going to take a much smaller resistor and get a tiny voltage drop -- see if I multiply the change between motor and this tiny result I get the same answer as the resistor originally which is of same size as the motor itself. 

I did try this with a 1 ohm resistor -- the smallest I have -- and this seemed to hang together but I was in a rush and need to repeat.

Nothing going into a computer though yet.

(previous to this, i have run motors through a pwm source and read values off an adc through a  serial line... all very painfully acquired things but that all worked)

Examples:

Drill on Motor 
RPM1608
Volt Bemf Meter1.5
vbemf = rpm/kv 
kv = rpm/vbemf1072
rpm = kv x vbemf 

 

Using kv above (actually an average of several at different drill speeds but the result is close to that)

I then ran the motor from a power source and compared bemf rpm vs observed.

 

RPM18868 measured with handheld tach
BatV source20 18 v lithium ion, meter says 20 v though
amps?   
vbemf = rpm/kv17.690691 using kv
v drop resister1.3 5.6 ohm, near motor resistance
bemf = Vs - ( 2 x Vdrop)17.4 using voltage supply - (2 x Voltage drop above)
rpm = kv x vbemf (calculated)18557.963 Hmmm dang close

 

 

 

 

Add Reply

Post
The DCS Forum is sponsored by

OGR Publishing, Inc., 1310 Eastside Centre Ct, Ste 6, Mountain Home, AR 72653
800-980-OGRR (6477)
www.ogaugerr.com

×
×
×
×
Link copied to your clipboard.
×
×