Jump to content
 

Arduino Applications and Programs


Simond
 Share

Recommended Posts

1 hour ago, melmerby said:

Seems to very similar to the Velleman KA03 but that  uses an L298D.

 

Couple of topics on the Arduino Forum (there are others):

https://forum.arduino.cc/index.php?topic=277150.0

https://forum.arduino.cc/index.php?topic=332397.0

 

Thanks for that. I'd actually found the first but the second was new to me. After a bit of fiddling about I've got the LEDs that indicate output to the motor terminals blinking and fading nicely in response to various sketches. Current issue is, once one motor terminal has faded up and down, to then swap the up/down output to the other terminal to reverse the direction of the loco motor. I can't see it being too hard, but, working in the evenings, I'm a bit tired and slow so it might take a few goes. 

Link to post
Share on other sites

  • RMweb Premium
1 hour ago, PatB said:

Thanks for that. I'd actually found the first but the second was new to me. After a bit of fiddling about I've got the LEDs that indicate output to the motor terminals blinking and fading nicely in response to various sketches. Current issue is, once one motor terminal has faded up and down, to then swap the up/down output to the other terminal to reverse the direction of the loco motor. I can't see it being too hard, but, working in the evenings, I'm a bit tired and slow so it might take a few goes. 

I'm like that all the time!

  • Like 1
Link to post
Share on other sites

As promised a few posts ago, Here's the sketch for a basic, timed shuttle. You can muck about with the parameters to adjust speed and acceleration (and thus time and distance from end to end), and the waiting time at either end. Sorry about the "goto", which, I gather, is rather disapproved of, but I spent ages shuffling brackets to try and get it to loop indefinitely, to no avail. If anyone can get it to work without (probably very simple, but I appear to be simpler), please feel free to share.

 

Here's a short video of a Hornby J13 shuttling happily back and forth on a temporary benchtop oval.

 

 

Link to post
Share on other sites

Pat

 

I was puzzled by your sketch, and your “goto”.

 

I suggest you remove the “for i” and “for k” loops, as they don’t seem necessary.  If you split your loop into two sections, going up & going down, and write your outputs for direction in each section, and then use the accel / decel loops you have, you don’t need the goto.

 

i have a very tatty version of your sketch (I just used the serial monitor to simulate the outputs) which I could upload if you really want it!

 

atb

Simon

  • Thanks 1
Link to post
Share on other sites

2 hours ago, Simond said:

Pat

 

I was puzzled by your sketch, and your “goto”.

 

I suggest you remove the “for i” and “for k” loops, as they don’t seem necessary.  If you split your loop into two sections, going up & going down, and write your outputs for direction in each section, and then use the accel / decel loops you have, you don’t need the goto.

 

i have a very tatty version of your sketch (I just used the serial monitor to simulate the outputs) which I could upload if you really want it!

 

atb

Simon

Thanks for the tips. Much appreciated. Although I now have a sketch that does what I need, it's been bugging me that it is less tidy than it could be. I'll have a go at what you suggest next time I have a few minutes to sit down and play with the code. Any working example, tatty or not, would be great. Please do upload it. 

 

Once again, thanks for taking an interest. I'm very new to the Arduino, although, many years ago, I did some moderately sophisticated programming in C+ (as it then was) as part of my engineering degree. It's been so long, though, I've no idea if it'll come back. 

Link to post
Share on other sites

Pat,

 

it's like riding a bike...  ('cept it hurts less when it falls over!)

 

I'm at work so just looked at it quickly.  try copying this into your IDE and uploading it, I think it will work  as I've commented it.   I have not used the board you are using to drive the motor, but guess they are all similar.  Presume you write one rail low, and PWM the other high, and then reverse them to go the other way.

 

I would change your program so that the "delay(30)" becomes "delay(delaytime)" and set the value of delaytime in your setup.

 

Then, assuming it works, I'd have a Boolean variable "direction", and call a function "RunTrain(direction)" from the loop.  The function would have the lines that set the pin low, and the loop that PWMs the other pin.  You would need an "if / else " using "direction" to set the correct pin low and PWM the other pin.    You can then use external triggers (buttons, etc, connected to other pins)  to update variables within your loop to set the train off, rather than it always doing exactly the same thing.

 

hth

Simon

 

 

 

 

void setup() {
  pinMode(10, OUTPUT);  //sets PWM pins to output mode
  pinMode(11, OUTPUT);  //pins 10 & 11 correspond to Motor B on shield
}

void loop() {
  start:
  int x = 1;  //Set increments for loop counters
  int y = 1;  //sets increment for forward acceleration step
  int z = 1;  //sets increment for reverse acceleration step
 
//   for (int i = 0; i <= 1; i+x) {                 // DONT NEED THIS

// GOING ONE WAY
    digitalWrite(10, LOW);                      //sets negative rail polarity
    for (int j = 0; j > -1; j = j + y) {
      analogWrite(11, j);                         //sets positive rail PWM value 
      if (j == 255) {
        y = -1;                                            // switch direction at peak  - SURELY SWITCH FROM ACCELERATION TO DECELERATION??
      }
      delay(30);                                         //sets rate of acceleration in forward direction
    }
  delay(5000);                                        //sets wait time at end A of shuttle track  

 

 


//  for (int k = 0; k <= 1; k+x) {              // DONT NEED THIS EITHER

// GOING THE OTHER WAY
    digitalWrite(11, LOW);                     //sets negative rail polarity (opposite rail for reverse)
    for (int m = 0; m > -1; m = m + z) {
      analogWrite(10, m);                       //sets positive rail PWM value (opposite rail for reverse)
      if (m == 255) {
        z = -1;                                                 // switch direction at peak
      }
      delay(30);                        //sets rate of acceleration in reverse direction
    }
  delay(5000);                          //sets wait time at end B of shuttle track
 //    goto start;                           //returns sketch to start as I couldn't get it to loop by other means  // DONT NEED THIS
  }                                               // DONT NEED THIS
}                                                 // DONT NEED THIS
}                                                //  YOU DEFINITELY DO NEED THIS!!! - this is the end of the loop function

Edited by Simond
  • Thanks 1
Link to post
Share on other sites

On 26/06/2019 at 15:17, Simond said:

Pat,

 

it's like riding a bike...  ('cept it hurts less when it falls over!)

 

I'm at work so just looked at it quickly.  try copying this into your IDE and uploading it, I think it will work  as I've commented it.   I have not used the board you are using to drive the motor, but guess they are all similar.  Presume you write one rail low, and PWM the other high, and then reverse them to go the other way.

 

I would change your program so that the "delay(30)" becomes "delay(delaytime)" and set the value of delaytime in your setup.

 

Then, assuming it works, I'd have a Boolean variable "direction", and call a function "RunTrain(direction)" from the loop.  The function would have the lines that set the pin low, and the loop that PWMs the other pin.  You would need an "if / else " using "direction" to set the correct pin low and PWM the other pin.    You can then use external triggers (buttons, etc, connected to other pins)  to update variables within your loop to set the train off, rather than it always doing exactly the same thing.

 

hth

Simon

 

 

 

Well whaddya know? Worked like a charm. Thanks so much. I haven't split it into separate functions yet, as I don't yet need to, but it's all looking much tidier. I found, though, that declaring "delaytime" (or, rather, "AccelDelay" to distinguish it from any other delays I might need to use) in setup didn't seem to work. I got "AccelDelay not declared in this scope" from the compiler. Moving it to the top of the loop, along with the acceleration step increments seemed to work though.

 

Currently adding a few lines to use some pins to drive a simple LED 2-aspect signal at each end of the shuttle track, to add a little more visual interest. Everybody likes lights that do stuff ;-).

Link to post
Share on other sites

3 hours ago, PatB said:

 

 I found, though, that declaring "delaytime" (or, rather, "AccelDelay" to distinguish it from any other delays I might need to use) in setup didn't seem to work.

If you declare a variable within a function it is a local variable which only exists within the function. The simplest solution is to make it a global variable by declaring it before setup(). You can then access it anywhere in the program.

 

...R

Edited by Robin2
  • Thanks 1
Link to post
Share on other sites

  • 3 weeks later...

Hi everyone,  I am playing around with a few Arduinos on my DC analogue OO gauge layout, mainly to operate points & decouplers (cheap servos) and home made signals so that the signals can react correctly to point settings and loco presence detection (using TCRT5000 sensors).  I decided to see if I could control the trains from the Arduino code so that the software can know where trains are, their direction & speed to make other stuff on the layout happen, mainly sound files played via cheap MP3 players.  All good fun. When first attempted I got a horrid whine from the loco motors, regardless of speed which stumped me.. until I found a super library & code by Ken Shores called "Trainmotor" on the web that totally eliminates the issue.  Fantastic, and all worked perfectly on a test track.  Transferring to my layout, however, causes all kinds of power fluctuation issues whenever a loco traverses some of my live frog points or an isolation section join. I guess it's mini 'shorts', but I can't think how to fix it. Has anyone else done this and found a solution (apart from tear up & re-lay all the track!!) ??

 

Link to post
Share on other sites

Please post a link to where you got the TrainMotor code.

 

What Arduino board are you using?

 

Did you try the code prior to TrainMotor on your layout and if so did it exhibit the same problem as the TrainMotor version?

 

What sort of motor driver h-bridge are you using? - post a link to their datasheet. You can get motor driver h-bridges that can withstand short circuits.

 

What power supply (volts and amps) are you using for the track power? Is it separate from the Arduino power?

 

...R

Edited by Robin2
Link to post
Share on other sites

Arduino is a standard UNO R3, The motor driver is a Deek-Robot L298p off Ebay, can't see a datasheet.... https://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItemVersion&item=291942380591&view=all&tid=1696068034019

 

Code with previous library had same issues but also loud noise from the motor.   Power is from old Hornby controller 12v/1Amp uncontrolled output, UNO powered from 9v battery.  Snipped through the power feed from the L298 to Uno to ensure independance.

 

Problem much less with a newer class 08 Hornby shunter than with the older S15 class so maybe I have issues with this loco?

 

A capacitor across the track feed outputs has helped quite a lot.

 

Library if from Github https://github.com/KensCode/TrainMotor

 

 

 

 

 

Link to post
Share on other sites

There is an awful lot of code in that library - sorry, but I am too lazy to study it all. I don't think there is as much code in the program I wrote for wireless control of trains on a club layout :)

 

I don't think there is anything technically unusual in the program. However it writes directly to the Arduino registers rather than using analogWrite() for motor control and it would take a long time to understand the register code well enough to know if there is anything unusual.

 

The L298 is an old-technology and inefficient motor driver chip. It has a large ON resistance that wastes a lot of energy - maybe as much as 2 volts get lost in the motor driver. Also I don't think they take kindly to short circuits. On two separate occasions I brought L298s to club meetings and wet home with one side of the L298 broken :) .   I have been using Infineon TLE 5206 h-bridge chips - they are good for up to 5 amps and have short circuit protection.

 

...R

Edited by Robin2
Link to post
Share on other sites

I'd suspect that the whine is the audible result of feeding the motor PWM rather than a steady DC voltage. The loco in my project does it too, but not loudly enough to be a problem. There are circuit diagrams on the Web for "converters" to turn PWM into smooth(ish) DC, which might help. My guess is that this is what your output capacitor is doing to some extent. 

Link to post
Share on other sites

On 17/07/2019 at 17:20, Paul4256 said:

Thanks for your thoughts.. the Infineon TLE 5206 sounds interesting and worth further investigation.  Robin, any chance of a copy of some code to work with it?  Thanks.

It's a very simple thing to use. There are two inputs one for FWD and one for REV. To go FWD (for example) set the REV pin LOW and analogWrite() to the other pin. Vice versa to go in reverse. This does mean using two PWM pins on the Arduino. And, of course, which is FWD and which is REV depends on how your motor is wired. Be sure to study the datasheet for the part.

 

The code I use is like this

if (direction == 'F') {
    analogWrite(revPin, 0);
    analogWrite(fwdPin, pwmVal);
}
else {
    analogWrite(fwdPin, 0);
    analogWrite(revPin, pwmVal);
}

 

...R

EDIT ... 19 July to add code snippet which I thought I had added earlier

Edited by Robin2
  • Like 1
  • Informative/Useful 1
Link to post
Share on other sites

This is the RS Components link for the part I have used

https://uk.rs-online.com/web/cp/1658151,9062978,9062978P/?pst=TLE52062SAKSA1&sra=p

 

As far as I can see they are still readily available and I don't think the newer Infineon products are available in the same convenient package. Unfortunately the trend is to design everything for surface mounting.

 

...R

PS ... I thought I had included a code snippet in my earlier Reply - i must have omitted to press "save". I have added it now.

Edited by Robin2
Link to post
Share on other sites

I wouldn’t worry about the “not for new design” thing.  If you were committing lots of money in product development, you’d want to know if a key component would be discontinued within the product lifecycle, but I’d guess there will be parts around for a few years yet, certainly in model-making quantities.

 

atb

simon

Link to post
Share on other sites

16 hours ago, Robin2 said:

As far as I can see they are still readily available and I don't think the newer Infineon products are available in the same convenient package. Unfortunately the trend is to design everything for surface mounting.

 

...R

 

 

Thanks.

 

Just out of curiosity do you know (or know how to find out) what the suggested new part is?

 

Frederick

Edited by fcwilt
Link to post
Share on other sites

4 hours ago, fcwilt said:

Just out of curiosity do you know (or know how to find out) what the suggested new part ?

If I recall correctly it took me a long time to find the TLE 5206 by searching through RS Components' online catalogue. One of the problems is that things are "filed" according the the words used by the manufacturer to describe the part which means that a search term may not find all the items that would actually be suitable. And often finds dozens of things that are unsuitable.

 

All I can suggest is that you begin searching. I did not search the other big suppliers such as Farnell, Digikey or Mouser simply because I can collect stuff from RS.

 

...R

Link to post
Share on other sites

  • 2 weeks later...

Still playing with the L298 motor shield... came across this funny.  If I test my potentiometer directly on the Uno just using +5v, GND & A0 for the reading, I get a lovely smooth progression from 0 to 1023 with 512 ish at the centre of rotation. If I now drop the motor shield on top, connect through to the same pins from  the shield  and rotate the knob it reads from 0 to around 260 at about 95% turn, then jumps to 700/800 then to 1023 at full turn. Most strange and I can't figure out what's going on. Makes no difference if the shield is powered or not.  Code on the Uno is next to nothing....

 

int potPin = 0;    // select the input pin for the potentiometer
int val = 0;       // variable to store the value coming from the sensor
void setup() {
Serial.begin(9600);
}

void loop() {
  val = analogRead(potPin);    // read the value from the sensor
  Serial.println(val);
}

 

 

Link to post
Share on other sites

10 hours ago, Paul4256 said:

 it reads from 0 to around 260 at about 95% turn, then jumps to 700/800 then to 1023 at full turn.

My suspicion is a bad connection somewhere.

 

Or maybe the motor shield uses A0 for something. Have you tried connecting your pot to a different analogue pin?

 

...R

Edited by Robin2
Link to post
Share on other sites

10 hours ago, Paul4256 said:

If I test my potentiometer directly on the Uno just using +5v, GND & A0 for the reading, I get a lovely smooth progression from 0 to 1023 with 512 ish at the centre of rotation. If I now drop the motor shield on top, connect through to the same pins from  the shield  and rotate the knob it reads from 0 to around 260 at about 95% turn, then jumps to 700/800 then to 1023 at full turn.

 

That sounds like the shield board has a resistor between the wiper and ground connections you are using; from the figures probably around a third the resistance of your pot.

 

Try disconnecting the pot ground and see if you still get a varying input? If it does, though not very linear, if there is a resistor. If not it should just read full scale all the time.

 

A fixed resistor on the input may be a stray pulldown or it could be intended to allow a two wire variable resistance input, or an active input from an opamp.

 

Edited by RobjUK
clarification
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...