pca 9685 i2c 2 or more boards codes arduino

garry2577 Jul 23, 2020

  1. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    hi need help please .
    very little about i2c jmri running 32 servos on 2 or more pca9685 on github or internet.
    i got a code to run 1 board for 16 servo that works below but tried so many ways to use 2 boards with 2 i2c address to add to this code by soldering ao on second board and adding code like in second code below.
    working code.

    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    #include <CMRI.h>
    #include <Auto485.h>
    #define CMRI_ADDR 1 // what CMRI node is the Arduino running this sketch?
    #define DE_PIN 2 // ????????????
    #define LED01 7 // LED code left in to try running pca9685 and LEDs on same mega.
    #define button 3 // sensor for the LED

    int buttonState = 0; // set a variable to store the button state
    int Tbit[2]; // set variable for a Turnout bit number IS THIS THE ISSUE??

    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); //setup the board address 0
    Auto485 bus(DE_PIN); // arduino pin 2 for DE and RE pins
    CMRI cmri(CMRI_ADDR, 24, 48, bus); // defaults to a SMINI with address 0. SMINI = 24 inputs, 48 outputs

    void setup() {
    // LIGHTS
    pinMode(LED01, OUTPUT);
    pinMode(button, INPUT_PULLUP);
    // SERVOS
    Serial.begin(9600);
    bus.begin(9600);
    pwm.begin();
    pwm.setPWMFreq(60); // This is the maximum PWM frequency
    pwm.setPWM(0, 0, 170); //Initial setting when start up
    pwm.setPWM(1, 0, 170);
    pwm.setPWM(2, 0, 170);
    pwm.setPWM(3, 0, 170);
    pwm.setPWM(4, 0, 170);
    pwm.setPWM(5, 0, 170);
    pwm.setPWM(6, 0, 170);
    pwm.setPWM(7, 0, 170);
    pwm.setPWM(8, 0, 170);
    pwm.setPWM(9, 0, 170);
    pwm.setPWM(10, 0, 170);
    pwm.setPWM(11, 0, 170);
    pwm.setPWM(12, 0, 170);
    pwm.setPWM(13, 0, 170);
    pwm.setPWM(14, 0, 170);
    pwm.setPWM(15, 0, 170);
    }

    void loop() {
    cmri.process();
    //LIGHTS
    digitalWrite(LED01, cmri.get_bit(47)); // Light on address 1048 in JMRI
    buttonState = digitalRead(button);
    cmri.set_bit(0, buttonState);
    //
    // TURNOUTS ON BITS 0-15 I.E. ADDRESSES 1001-1016
    Tbit[0] = (cmri.get_bit(0)); //Turnout01
    Tbit[1] = (cmri.get_bit(1)); //Turnout02
    Tbit[2] = (cmri.get_bit(2)); //Turnout03
    Tbit[3] = (cmri.get_bit(3)); //Turnout04
    Tbit[4] = (cmri.get_bit(4)); //Turnout05
    Tbit[5] = (cmri.get_bit(5)); //Turnout06
    Tbit[6] = (cmri.get_bit(6)); //Turnout07
    Tbit[7] = (cmri.get_bit(7)); //Turnout08
    Tbit[8] = (cmri.get_bit(8)); //Turnout09
    Tbit[9] = (cmri.get_bit(9)); //Turnout10
    Tbit[10] = (cmri.get_bit(10)); //Turnout11
    Tbit[11] = (cmri.get_bit(11)); //Turnout12
    Tbit[12] = (cmri.get_bit(12)); //Turnout13
    Tbit[13] = (cmri.get_bit(13)); //Turnout14
    Tbit[14] = (cmri.get_bit(14)); //Turnout15
    Tbit[15] = (cmri.get_bit(15)); //Turnout16

    // TURNOUT01, ADDRESS 1001, BIT 0
    if (Tbit[0] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(0, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[0] == 0){
    pwm.setPWM(0, 0, 150);
    }

    // TURNOUT02, ADDRESS 1002, BIT 1
    if (Tbit[1] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(1, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[1] == 0){
    pwm.setPWM(1, 0, 150);
    }

    // TURNOUT03, ADDRESS 1003, BIT 2
    if (Tbit[2] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(2, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[2] == 0){
    pwm.setPWM(2, 0, 150);
    }

    // TURNOUT04, ADDRESS 1004, BIT 3
    if (Tbit[3] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(3, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[3] == 0){
    pwm.setPWM(3, 0, 150);
    }

    // TURNOUT05, ADDRESS 1005, BIT 4
    if (Tbit[4] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(4, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[4] == 0){
    pwm.setPWM(4, 0, 150);
    }

    // TURNOUT06, ADDRESS 1006, BIT 5
    if (Tbit[5] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(5, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[5] == 0){
    pwm.setPWM(5, 0, 150);
    }

    // TURNOUT07, ADDRESS 1007, BIT 6
    if (Tbit[6] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(6, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[6] == 0){
    pwm.setPWM(6, 0, 150);
    }

    // TURNOUT08, ADDRESS 1008, BIT 7
    if (Tbit[7] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(7, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[7] == 0){
    pwm.setPWM(7, 0, 150);
    }

    // TURNOUT09, ADDRESS 1009, BIT 8
    if (Tbit[8] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(8, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[8] == 0){
    pwm.setPWM(8, 0, 150);
    }

    // TURNOUT10, ADDRESS 1010, BIT 9
    if (Tbit[9] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(9, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[9] == 0){
    pwm.setPWM(9, 0, 150);
    }

    //// TURNOUT11, ADDRESS 1011, BIT 10
    if (Tbit[10] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(10, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[10] == 0){
    pwm.setPWM(10, 0, 150);
    }

    //// TURNOUT12, ADDRESS 1012, BIT 11
    if (Tbit[11] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(11, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[11] == 0){
    pwm.setPWM(11, 0, 150);
    }

    //// TURNOUT13, ADDRESS 1013, BIT 12
    if (Tbit[12] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(12, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[12] == 0){
    pwm.setPWM(12, 0, 150);
    }

    //// TURNOUT14, ADDRESS 1014, BIT 13
    if (Tbit[13] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(13, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[13] == 0){
    pwm.setPWM(13, 0, 150);
    }

    //// TURNOUT15, ADDRESS 1015, BIT 14
    if (Tbit[14] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(14, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[14] == 0){
    pwm.setPWM(14, 0, 150);
    }

    //// TURNOUT16, ADDRESS 1016, BIT 15
    if (Tbit[15] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(15, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[15] == 0){
    pwm.setPWM(15, 0, 150);
    }

    }
     
  2. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    second code ,please dont laugh i cobbled code from all over and i am totally confused i am not the brightest match in the box.i have added bits to the code and taken bits out not sure whats in or out anymore .so please please put a daft old thick man to rest .
    #include <Wire.h>
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    #include <CMRI.h>
    #include <Auto485.h>

    #define CMRI_ADDR 1 // what CMRI node is the Arduino running this sketch?
    #define DE_PIN 2 // ????????????
    #define LED01 7 // LED code left in to try running pca9685 and LEDs on same mega.
    #define button 3 // sensor for the LED


    int buttonState = 0; // set a variable to store the button state
    int Tbit[0]; // set variable for a Turnout bit number IS THIS THE ISSUE??
    byte i2c_rcv; // data received from I2C bus
    unsigned long time_start; // start time in milliseconds

    Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40); //setup the board address 0
    Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41); //setup the board address 1
    Auto485 bus(DE_PIN); // arduino pin 2 for DE and RE pins
    CMRI cmri(CMRI_ADDR, 24, 48, bus); // defaults to a SMINI with address 0. SMINI = 24 inputs, 48 outputs

    void setup() {
    // LIGHTS
    pinMode(LED01, OUTPUT);
    pinMode(button, INPUT_PULLUP);
    // SERVOS
    Serial.begin(9600);
    Wire.begin(); // join I2C bus as the master

    Wire.setClock(200000);


    // initialize global variables
    i2c_rcv = 255;
    time_start = millis();



    Serial.begin(9600);

    bus.begin(9600);
    pwm.begin();
    pwm1.begin();
    pwm.setPWMFreq(60); // This is the maximum PWM frequency
    pwm1.setPWMFreq(60); // This is the maximum PWM frequency

    pwm.setPWM(0, 0, 170); //Initial setting when start up
    pwm.setPWM(1, 0, 170);
    pwm.setPWM(2, 0, 170);
    pwm.setPWM(3, 0, 170);
    pwm.setPWM(4, 0, 170);
    pwm.setPWM(5, 0, 170);
    pwm.setPWM(6, 0, 170);
    pwm.setPWM(7, 0, 170);
    pwm.setPWM(8, 0, 170);
    pwm.setPWM(9, 0, 170);
    pwm.setPWM(10, 0, 170);
    pwm.setPWM(11, 0, 170);
    pwm.setPWM(12, 0, 170);
    pwm.setPWM(13, 0, 170);
    pwm.setPWM(14, 0, 170);
    pwm.setPWM(15, 0, 170);
    pwm1.setPWM(16, 0, 170); //Initial setting when start up
    pwm1.setPWM(17, 0, 170);
    pwm1.setPWM(18, 0, 170);
    pwm1.setPWM(19, 0, 170);
    pwm1.setPWM(20, 0, 170);
    pwm1.setPWM(21, 0, 170);
    pwm1.setPWM(22, 0, 170);
    pwm1.setPWM(23, 0, 170);
    pwm1.setPWM(24, 0, 170);

    }

    void loop() {
    cmri.process();
    //LIGHTS
    digitalWrite(LED01, cmri.get_bit(47)); // Light on address 1048 in JMRI
    buttonState = digitalRead(button);
    cmri.set_bit(0, buttonState);






    //// TURNOUTS ON BITS 0-15 I.E. ADDRESSES 1001-1016
    Tbit[0] = (cmri.get_bit(0)); //Turnout01
    Tbit[1] = (cmri.get_bit(1)); //Turnout02
    Tbit[2] = (cmri.get_bit(2)); //Turnout03
    Tbit[3] = (cmri.get_bit(3)); //Turnout04
    Tbit[4] = (cmri.get_bit(4)); //Turnout05
    Tbit[5] = (cmri.get_bit(5)); //Turnout06
    Tbit[6] = (cmri.get_bit(6)); //Turnout07
    Tbit[7] = (cmri.get_bit(7)); //Turnout08
    Tbit[8] = (cmri.get_bit(8)); //Turnout09
    Tbit[9] = (cmri.get_bit(9)); //Turnout10
    Tbit[10] = (cmri.get_bit(10)); //Turnout11
    Tbit[11] = (cmri.get_bit(11)); //Turnout12
    Tbit[12] = (cmri.get_bit(12)); //Turnout13
    Tbit[13] = (cmri.get_bit(13)); //Turnout14
    Tbit[14] = (cmri.get_bit(14)); //Turnout15
    Tbit[15] = (cmri.get_bit(15)); //Turnout16
    Tbit[16] = (cmri.get_bit(16)); //Turnout17
    Tbit[17] = (cmri.get_bit(17)); //Turnout18
    Tbit[18] = (cmri.get_bit(18)); //Turnout19
    Tbit[19] = (cmri.get_bit(19)); //Turnout20
    Tbit[20] = (cmri.get_bit(20)); //Turnout21
    Tbit[21] = (cmri.get_bit(21)); //Turnout22
    Tbit[22] = (cmri.get_bit(22)); //Turnout23
    Tbit[23] = (cmri.get_bit(23)); //Turnout24
    Tbit[24] = (cmri.get_bit(24)); //Turnout25

    if (Tbit[0] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(0, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[0] == 0){
    pwm.setPWM(0, 0, 150);
    }


    if (Tbit[1] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(1, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[1] == 0){
    pwm.setPWM(1, 0, 150);
    }


    if (Tbit[2] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(2, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[2] == 0){
    pwm.setPWM(2, 0, 150);
    }


    if (Tbit[3] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(3, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[3] == 0){
    pwm.setPWM(3, 0, 150);
    }


    if (Tbit[4] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(4, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[4] == 0){
    pwm.setPWM(4, 0, 150);
    }


    if (Tbit[5] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(5, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[5] == 0){
    pwm.setPWM(5, 0, 150);
    }


    if (Tbit[6] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(6, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[6] == 0){
    pwm.setPWM(6, 0, 150);
    }


    if (Tbit[7] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(7, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[7] == 0){
    pwm.setPWM(7, 0, 150);
    }


    if (Tbit[8] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(8, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[8] == 0){
    pwm.setPWM(8, 0, 150);
    }


    if (Tbit[9] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(9, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[9] == 0){
    pwm.setPWM(9, 0, 150);
    }


    if (Tbit[10] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(10, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[10] == 0){
    pwm.setPWM(10, 0, 150);
    }


    if (Tbit[11] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(11, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[11] == 0){
    pwm.setPWM(11, 0, 150);
    }


    if (Tbit[12] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(12, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[12] == 0){
    pwm.setPWM(12, 0, 150);
    }


    if (Tbit[13] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(13, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[13] == 0){
    pwm.setPWM(13, 0, 150);
    }


    if (Tbit[14] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(14, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[14] == 0){
    pwm.setPWM(14, 0, 150);
    }


    if (Tbit[15] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm.setPWM(15, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[15] == 0){
    pwm.setPWM(15, 0, 150);
    if (Tbit[16] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(16, 1, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[16] == 0){
    pwm1.setPWM(16, 1, 150);
    }


    if (Tbit[17] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(17, 1, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[17] == 0){
    pwm1.setPWM(17, 1, 150);
    }


    if (Tbit[18] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(18, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[8] == 0){
    pwm1.setPWM(18, 0, 150);
    }


    if (Tbit[19] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(19, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[19] == 0){
    pwm1.setPWM(19, 0, 150);
    }


    if (Tbit[20] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(20, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[20] == 0){
    pwm1.setPWM(10, 0, 150);
    }


    if (Tbit[21] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(21, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[21] == 0){
    pwm1.setPWM(21, 0, 150);
    }


    if (Tbit[22] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(22, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[22] == 0){
    pwm1.setPWM(22, 0, 150);
    }


    if (Tbit[23] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(23, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[23] == 0){
    pwm1.setPWM(23, 0, 150);
    if (Tbit[24] == 1){ //if Turnoutbit n == 1 (to throw) or 0 (to close)
    pwm1.setPWM(24, 0, 170); //set servo n (0-15), board n (0,1,2,3,4,5,etc), angle = n
    }
    if (Tbit[24] == 0){
    pwm1.setPWM(24, 0, 150);}
    }
    }
    }

    I know it can be made alot smaller by for and ifs but its easyer for me to see stuff .
    used www.motorhomesites.org /https://www.locoduino.org/ http://www.trainelectronics.com/ and https://expressoarduino.blogspot.com/2019/08/conexao-e-configuracao-da-interface-48.html /adafruit
    but code for strapping pca boards is not around for using with servos for jmri , what there is leaves things in the air like we are all programmers .i just want my trains to go round and round and in and out of turnouts and signals and go woo woo .got sprog running on laptop and hope to use pi 4 for accessory.
    Strapping servos with base station is not working for me
    thanks for any help and i am sure it may help other dcc++ users
     
  3. Ash

    Ash TrainBoard Member

    106
    66
    8
    Did you get it working? I see the second post has added the line to setup the address for the second board -- which also means that you had to physically set the I2C address on the second board.

    This might be the problem with your code.
    Example: pwm1.setPWM(24, 0, 150);
    -- the first parameter is 0-15, for each of pca9685 boards.

    Try: pwm1.setPWM(24 - 16, 0, 150);
    or: pwm1.setPWM(8, 0, 150);

    You might check this link, which has two pca9685 boards with CMRI/RS485 and JRMI.
    https://www.trainboard.com/highball...an-sg90-servo-to-respond.132584/#post-1143197

    Later, I found that CMRI emulation was looking for up to 24 inputs and 48 outputs. Now using three aduinos connected via RS485, with one pca9685 on each (along with up to two mcp23017 boards for outputs and one mcp23017 board for inputs on each arduino for buttons, lights and solenoids).
    https://www.trainboard.com/highball...-out-card-for-jmri.116454/page-2#post-1141569

    I agree with your sentiments regarding the difficulty of finding complete information. I am also new to this; servos are now installed. I had some issues with using a low mA wall wart to power the pca9685; more current was needed at start-up. And the turnouts in JMRI all show as unknown at startup. I saw that a script could be used to store the state at shut-down and another script to read it at start-up.

    I had planned to hang all the accessories off of one Mega, but the RS485 and multiple Arduinos makes for shorter I2C wiring. And I can easily add another Arduino to the RS485 bus when more outputs are needed. So far, I have the same code running on each Arduino -- just update CMRI_ADDR.

    And I'm looking for some feedback on the mcp23017 uln2803 output boards. I don't know if the design is overly cautious regarding power consumption, but the darlington transistor arrays seem to be working well for me.
     
    Last edited: Jul 25, 2020
  4. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    yes i looked into this find the rs485 bit unreliable used the boards from https://expressoarduino.blogspot.com/2019/08/interface-configuravel-para-48.html if u use chrome it translates .also had problems with powering the boards with the pins disconnecting the rs485 pins so i power using usb .got it working then had problems with it not working sometimes ,
    like i said its really got my head battered .but thanks i will try your code and set up three nodes in jmri and let you know pro mini looks best option .do you need the High Level Relay Module (1x) not sure what use it had in firing servos
     
  5. Ash

    Ash TrainBoard Member

    106
    66
    8
    I also wondered about the need for the relay. Perhaps the expressoarduino code prevents power to the relay until the Arduino has initialized. My code started like yours. Then I condensed it to the single page with two pca9685 boards. Eventually I translated parts of the code from expressoarduino applicable to the mcp23017. But I did not include other parts related to servos or configuration -- perhaps someone will advise if the expressoarduino code also takes care of the servo initialization at startup.

    I also had some RS485 problems; I had two USB/RS485 adapters that failed. My guess is that I did not have a ground connected between the RP3b/JMRI board where the USB/RS485 adapter and the RS485 TTL adapter connected to the Arduino. I also had some other wiring issues that might have been the problem as I did not understand that the negative from the motor board (to the track) is not a ground.

    I used a Mega extensively for initial setup and testing. But I might try a Nano instead of the Pro Mini and avoid the extra USB interface adapter. And with a Pro Mini, be careful to get a 5-volt version. Another reason for the Nano is the location of A4/A5 (SCL/SDA) -- on the Pro Mini it appears to be an afterthought.

    Another difficulty somewhat related to RS485: I did not understand how RS485 was using the same RX/TX connections as the USB when the Arduino was connected to my PC. Perhaps it can be different with the Mega, but I now have jumpers installed on the pcb I use for the Pro Mini and RS485, so that I can disconnect RX/TX and 5V+ when I am connected via USB.

    You mentioned multiple nodes for CMRI. To me that says multiple Arduinos. But if you want to use two pca9685 modules on one Arduino, the code can be modified to enable it. In JMRI, you would use servo numbering such as 1001-1032, covering two pca9685 boards -- as long as they are on the same Arduino. With a second node, servo numbering might be 2001-2016 for the first board.

    JMRI is doing the heavy lifting. The code on the Arduino relays the commands between JMRI and the pca9685 and mcp23017 boards. My fascia buttons (momentary contact) are JMRI sensors which will set turnouts and signals. I press the button once to throw the turnout and related signals. Press again, and turnout is closed, etc. At the wye, the polarity reversing relay is set along with the turnout and signals.
     
  6. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    all good info ash ,i am surprised about the lack of codes and stuff for 2 or more boards .there must be a lot of tracks /railways with more than 16 servos .plus running wiring from distant servos to a central board like a mega servo board is manic with a dcc++ bus ,5volt bus ,3.3 and 12 volt buses myine already looks like spagiti
    i will look into a more reliable rs485 system or can we use a canbus system with MCP2515 CAN V2.0 Transceiver Module 1Mbps + SPI control Car CANBUS but again finding codes or information is hard work .programming is not my best suit.
    again thanks ash
    garry
     
  7. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
  8. Pieter

    Pieter TrainBoard Member

    152
    46
    10
    Garry, google for "Décodeur d'accessoires DCC D18". On his web page (DCC D18 decoder) he gives a break down, with diagrams, on how he has connected his projects together. He has a link to his software on the page. His PCA9685 modules description is near the bottom of the page.

    See PGahtow's web site about the Z21. His diagrams include how to connect Max485 to Uno & Mega although using a Max485 module makes it easier to add as all the required resistors & diodes is include on the board and min. soldering. Software also available on his website.
     
  9. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    cheers pieter checked "Décodeur d'accessoires DCC D18" and its very good but find the changes required for the coding at bit confusing i am going to have a good look at it .
    PGahtow's web site is 1 i never seen i will check that over .
    coding looks like a lang from pluto it must be so easy when you understand it all but i want to run trains not learn programming .
    it must be very differcult to explain things to thickos like me without missing some basic information .plus not all arduino are based the same
     
  10. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    https://github.com
    32-turnouts-3-pca9685-cmri
    working code above for 30 turnouts on 3 pca9685 using cmri with mega or uno using i2c cables
    jmri create 1 node and add 32 turnouts in turnout table start up jmri then power arduino and first pca board (jmri needs time before power up )
    thanks to ash /motorhomer /
    [​IMG]
    Brendan Hannon
     
  11. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    help help the thicko from uk needs help again
    how do i convert this above 32-turnouts-3-pca9685-cmri to run on a Wemos D1 R32 ESP32 WiFi Bluetooth R32 4MB Flash Dual Core USB Development Board
     

Share This Page