Header:
Hal-Zuzzu Model Railway Build Blog
 
  Published: Friday, April 28, 2023  
  Post: #143/174 - Views: 45006
 
 

 
Subscribe to my YouTube Channel HERE!


| Go to Blog Index | Scale Calculator | Visitor's Log |
 
   
 

Setting up my layout using the PCA9685.

Without getting into too much detail, I will attempt to explain how I got the PCA9685 to work with my current setup. For those who have not read the previous post, I am running my layout using two DCC controllers. A z21 Start to drive the trains and an Arduino system to control all the accessories. I am using the Digikeijs DR4024 servo controllers to throw turnouts but have had to replace the MegaPoints Controllers as I overloaded them and sadly, both boards died. 

Moving forward. Now that I have an Arduino controller, I was very pleased when I saw the PCA9685 module. After doing some research, I was very pleased to find out that for under €5 each I can have 16 turnouts working. This was a very cost-effective replacement for the dead controllers, so, being so affordable, I ordered a few.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/2023426204212.jpg

Wiring:

Since the PCA9685 does not run off the regular DCC bus wire, I had to add some more wires to the underside of the layout. I needed to add four more wires as shown in this diagram.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/2023427212329.png

Daisy-chain

The 5v input from the Arduino board will only power the PCA9685, therefore you will need an external 5v DC rated a minimum of 2Amps to power your servos. This is all the wiring you will need unless you want to daisy-chain the PCA9685 to another for an additional 16 servos like I am doing. Here's how that is done.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/2023427212329v2.png

As you can see it is rather simple when it comes to understanding the wiring involved. Keep note that you will need a 5v DC 2Amps power supply for each board you add. 

Addressing the boards

The next step would be addressing the different boards. To address an individual servo on any board on your layout, we first need to give each board a unique address. The image below shows how this is changed for each board to have a unique address on your layout. The tabs on the top right of the board need to be joined according to the address you intend on giving them. The default address of all boards is 0x40.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/2023427212329v3.png

Joining the two tabs labelled A0 will give you an address of 0x41, joining the two tabs on A0 and the two tabs on A1 will give you an address of 0x43 etc. Follow the table below for what you might need.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/2023427212329v4.png

Servo connection

Now for the fun part. As you already know you can attach 16 servos to each of these boards but before any of this can happen, we need to declare these boards to the software in Arduino. In DCC-EX, this is already included and the default entries are as shown below:

  PCA9685::create(100, 16, 0x40);

  PCA9685::create(116, 16, 0x41);

The first line creates an entry, introducing a device (PCA9685) with address 0x40 having 16 ports where the address of the first port is 100. Therefore 16 ports with addresses starting from 100 and ending at 115 (both inclusive) are being created on board 1 having address 0x40.

The second line does the same, but for a second board with address 0x41, also has 16 ports with port addresses starting from 116 and ending in 131.

If you need to add more boards, you will need to define the additional boards using the PCA9685::create command as shown above using the correct details. This can be added in a file called "IODevice.cpp" without quotes.

Great. Now we have 32 ports ready for use, but how do we use them? Here is how.

Create a file in Arduino IDE and call it "myAutomation.h" without quotes. The following is the content of my file:

// FIRST BOARD - 16 SERVOS

SERVO_TURNOUT( 1, 100, 325,425, Slow, "T1")

SERVO_TURNOUT( 2, 101, 325,425, Slow, "T2 - Where I would love to tie my boss")

SERVO_TURNOUT( 3, 102, 325,425, Slow, "T3")

SERVO_TURNOUT( 4, 103, 325,425, Slow, "T4")

SERVO_TURNOUT( 5, 104, 325,425, Slow, "T5")

SERVO_TURNOUT( 6, 105, 325,425, Slow, "T6")

SERVO_TURNOUT( 7, 106, 325,425, Slow, "T7")

SERVO_TURNOUT( 8, 107, 325,425, Slow, "T8")

SERVO_TURNOUT( 9, 108, 325,425, Slow, "T9")

SERVO_TURNOUT( 10, 109, 325,425, Slow, "T10")

SERVO_TURNOUT( 11, 110, 325,425, Slow, "T11")

SERVO_TURNOUT( 12, 111, 325,425, Slow, "T12")

SERVO_TURNOUT( 13, 112, 325,425, Slow, "T13")

SERVO_TURNOUT( 14, 113, 325,425, Slow, "T14")

SERVO_TURNOUT( 15, 114, 325,425, Slow, "T15")

SERVO_TURNOUT( 16, 115, 325,425, Slow, "T16")

// SECOND BOARD - 16 SERVOS

SERVO_TURNOUT( 17, 116, 325,425, Slow, "T17")

SERVO_TURNOUT( 18, 117, 325,425, Slow, "T18")

SERVO_TURNOUT( 19, 118, 325,425, Slow, "T19")

SERVO_TURNOUT( 20, 119, 325,425, Slow, "T20")

SERVO_TURNOUT( 21, 120, 325,425, Slow, "T21")

SERVO_TURNOUT( 22, 121, 325,425, Slow, "T22")

SERVO_TURNOUT( 23, 122, 325,425, Slow, "T23")

SERVO_TURNOUT( 24, 123, 325,425, Slow, "T24")

SERVO_TURNOUT( 25, 124, 325,425, Slow, "T25")

SERVO_TURNOUT( 26, 125, 325,425, Slow, "T26")

SERVO_TURNOUT( 27, 126, 325,425, Slow, "T27")

SERVO_TURNOUT( 28, 127, 325,425, Slow, "T28")

SERVO_TURNOUT( 29, 128, 325,425, Slow, "T29")

SERVO_TURNOUT( 30, 129, 325,425, Slow, "T30")

SERVO_TURNOUT( 31, 130, 325,425, Slow, "T31")

SERVO_TURNOUT( 32, 131, 325,425, Slow, "T32")

Explanation:

SERVO_TURNOUT(id, vpin, active_angle, inactive_angle, profile [, "description"])

SERVO_TURNOUT: A command to define the action of a servo

id: A unique DCC ID which is shared on your DCC layout. 

vpin: The pin number on your board

active_angle: An end-point for your servo to travel to.

inactive_angle: The opposite end-point to the one above. (Note: if you need to reverse the function of your servo, simply swap the values of active_angle and inactive_angle)

profile: Instant, Fast, Medium, Slow, and Bounce (Bounce should not be used for use with turnouts)

description: Something for you to understand what this entry is for!!

Now plug in your servos. The colour-coded pins on the board make it very simple to understand which way the servo plugs go in.

Testing:

At this point, everything should work. So let's test. Download and install an app called EX-Toolbox. Open it and connect it to the Arduino IP address. Swipe left or right till you get to the servo page. The default address is 100. Change that to 1 (as in my case, the first servo has a unique ID of 1) and press Throw or Close and adjust the travel of the turnout fork to the desired distance, using the + and - buttons (image below). The profile defaults to Instant which is fine for testing. Once you have the desired travel distance, update the correct turnout entry in "myAutomation.h" above.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/ex-servos.jpg

Remember: You will need to compile and upload your sketch each time you make changes, for it to affect your layout.

iTrain Use:

A small change is required to use the PCA9685 with iTrain. I am using version 5.1.7 and it works great. In your accessories, select the desired turnouts. Change the "Output device" from Default to Turnout. This is required for iTrain to send 1 or 0 for the Arduino to understand what to do with the command. Make sure you have the correct Interface selected.

http://joecontirc.com/rc-social/users/%7b09419227-35DE-4966-81E4-935F80A5C53C%7d/images/iTrain_DCC-EX.png

Hope you enjoyed this as much as I enjoyed writing it.

Part 1 of this post is here

Stay tuned and don't forget to register for post updates...

Check out the live CCTV camera HERE