On the electronics front - servo controllers

Since the basement is coming along at a rapid pace, I figured I better get my servo controllers finished so I have something to operate turnouts with. I’ve had the boards for the new design which uses just one relay, flipped at the center point of the servo movement for frog polarity control, for a while now. I just hadn’t gotten around to modifying my code for the old board, as well as make up a test control panel with buttons and LEDs to actually test it all out.

So the past couple of weeks, I’ve been working on that. Assmbled one of the boards. Set up one of the buck modules for the proper voltage and soldered that on. Tested the voltages all over the board. Frounded the pin that drives the relays to verify my transistor circuit was good. SO far, so good. Only thing left was the code for the microcontroller.

So this week I got that sorted out. Programmed one and stuck it in, and it actually worked. I took an old ethernet cable and cut one end off to make a control cable, soldering on a pair of LEDs and a pair of pushbuttons. Servo moves, relay clicsk on or off at the mid point, lights change. Jumpered the centering jumper, both servos go to the center.

Only one slight prblem, the servos tend to jump a few degrees clockwise every time power is cycled. None of this made sense. I even added more debugging to my code and verified the position never went out of range, and always went exactly to the endpoints I have defined. Just solved it - added an extra servo position write to the initialization, with a delay. They still jump slightly, but instantly return to the proper position. The glitch is always clockwise - so at minimum, they will jumpo to somethign higher than the 20 I have set, usually about 30, and then the init sets them back to 20. If the last position ebfore power off was at the high end, which I have set to 140, they may go to 150 and then jump back when the init routing runs. Such is how it is, it won’t really be an issue in use.

not obvious that there’s a solution (have you seen these).

One of those in there is where I got the idea for the delay. I may need to extend it.

The funny thing is, fresh startup with a newly programmed chip (so it has to run the EEPROM setup routine and then simply defaults both servos to the low end, I’m using 20 to 140 since not all servos can actually go 0-180 and it’s so far proven to be plenty of range to move Peco throwbars), it doesn’t do it. If the servo was last at the 20 position, it powers on and stays there. It’s only in subsequent power cycles that it does this, and all that does is read EEPROM to get the old position, does a Servo.write, and then a Servo.attach. The Servo commands are actually the same block of code regardless if the code had to initialize EEPROM or just read an existing saved position.

I keep the servos detached when not moving so they are quiet and to reduce current draw. So after the write and attach, I had code to set up the indicators and the relays, then it does a servo.detach. This is where I put the delay, before the detach, to give the servo enough time to react, and it mostly worked, but rapid power cycling gets the servo to creep.

Servo power is isolated from the micro power - the buck module had s filter capacitor, then I have another 1000uF, then taps off ONLY to the servo power connectiosn, then a schottkey diode and additional filters to power the micro, which also has bypass caps right next to the chip.

The first hit on the google list mentions a rather complex system of using an extra IO pin to drive a mosfet and a much larger cap for each servo - while that might work, I don’t have the spare IOs and the comemrcial servo drivers I used in the past don’t need anything like this. I’m hoping a longer delay will give things more time to settle. It’s only when powering up the boards - after that, I have been flipping servos back and forth and it always goes to the correct position and stays there. I also left it in the thrown position, both servos, b

It actually works. I still have some refactoring of the code to do to totally clean it up, but there is now just enough startup delay to allow the servos to set themselves to the correct last known position as saved in the EEPROM. Posting here if anyone is interested. Remember, I am NOT selling anything, code is free and I’ll freely give anyone the schematic and/or Gerbers for the boards. Or the source, if you use EasyEDA. An enterprising person who doesn’t mind doing surface mount could make my board a lot smaller by making all the pullup and protection resistors, and debounce caps surface mount.

  1. /*
  2. Servo Turnout Control Module v2.1
  3. Randy Rinker
  4. Trainbytes Designs
  5. This module controls two model railroad turnouts via servos
  6. along with relays for frog polarity. Local pushbuttons as well
  7. as remote control and locking are provided. Last position of
  8. each turnout are saved and remembered at next power on.
  9. */
  10. // Include libraries
  11. #include <Metro.h> //Include Metro library
  12. #include <Servo.h> //Include Servo library
  13. #include <EEPROM.h> //Include EEPROM library
  14. // Define values used with EEPROM save and load
  15. #define VERSION “TCON21”
  16. #define CONFIG_START 1010 // 504 for units based on ATTiny 85
  17. #define MEM_MAX 1000 // 500 for units based on ATTiny 85
  18. // Define pin usage
  19. #define SW1NLED 0 // Switch 1 Normal LED on Pin D0
  20. #define SW1RLED 1 // Switch 1 Reverse LED on Pin D1
  21. #define SW2NLED 2 // Switch 2 Normal LED on Pin D2
  22. #define SW2RLED 3 // Switch 2 Reverse LED on Pin D3
  23. #define SW1LCK 4 // Switch 1 Local Lockout on Pin D4