24 IN / 48 OUT card for JMRI

nopxor Apr 16, 2018

  1. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    Great! Yes of course I will upload these files; it will be in a couple of days since we are any minute about to leave for the weekend,
    grts,
    Erik

    PS: I did try just now anyway to upload (zip file) but I get an "error uploading"..???

    (the last few days I am unable to upload anything: what's up??)
     
    Last edited: Jan 18, 2020
    vasilis likes this.
  2. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    Upload of original nopxor .sch, .brd and gerber files.
    Mind you, these gerbers are for a specific manufacturer.
    If needed, I can upload my own gerbers suitable for Elecrow.
     

    Attached Files:

  3. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    And here my SMD version, and with IDC cable connectors, for 16p flat cable, for the outputs.

    I also have made boards receiving the ouputs an converting them to PWM servo motor signals, as well as boards receiving inputs over 16 channels each, to be connected with the digital inputs on this board. All driven by one Arduino Pro Mini.
    The Pro Mini sits on a "motherboard", on which are stacked max 4 pwm servo output boards and max 3 boards with 16 channel inputs each.
     

    Attached Files:

    vasilis likes this.
  4. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    And here is the completed PCB with IDC connectors. A version without IDC (yellow) uses standard pinheaders for both input and output.

    upload_2020-1-27_19-14-59.jpeg

    upload_2020-1-27_19-15-21.jpeg
     
    vasilis likes this.
  5. Keith Ledbetter

    Keith Ledbetter TrainBoard Member

    279
    195
    12
    As promised a couple images of the original board. Here populated with everything except the ICs. I will add a few more when I stick the ICs on.

    IMG_20200128_160906.jpg IMG_20200128_160915.jpg IMG_20200128_160906.jpg
     
  6. vasilis

    vasilis TrainBoard Member

    110
    39
    10
    Erik, Keith if I will have any circuit, you MUST design the board:)
     
    Erik84750 likes this.
  7. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    Hi Vasilis, sure I will! Send the schematics.
    Grts,
    Erik
     
    vasilis likes this.
  8. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    Hi Keith, very nice! I am interested in hearing of your test results.
    Mine could not yet be tested: I am awaiting delivery of the MAX485 SOP8 chips.

    Grts,
    Erik
     
  9. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    Here I present you my follow-up on the 24IN/48OUT JMRI/CMRI board by nopxor:
    1. PCA9685 16 channel PWM output board for servo's (Adafruit PCA9685 piggy-backed on this board)
    2. Motherboard for max 6x MCP23017 16 channel inputs, max 6x PCA9685 16 channel servo drivers, and a Pro Mini to drive the board.
    3. MCP23017 16 channel input board for inputs (using MCP23017 SSOP28)
    All SMD components.

    The concept uses the 24IN/48OUT boards (original by nopxor) modified by me for IDC 16p connectors.

    The MCP23017 receives inputs from the 24IN/48OUT board; the Pro Mini reads these inputs and converts this to the corresponding PCA9685 and its corresponding output.

    The MCP23017 and PCA9685 act in pairs: address b000 on a MCP23017 will act on a PCA9685 on address x000000 etc...
    Hence each 24IN/48OUT board will need 3 pairs of these boards. Since max 6 of each can be placed on the motherboard 2 boards 24IN/48OUT can be connected to one fully equipped motherboard.

    The software automatically detects and reads all boards on the motherboard. The software only needs to be configured for the particular servos in use.

    The software further does the following:
    1. read sequentially each MCP23017 and each of its inputs
    2. when a state change is detected a software debounce is activated, false or stray pulses are discarded
    3. when a state change is verified correct then the corresponding output on the corresponding PCA9685 is activated.

    Ground is connected separately: minimum 0.75mm² wire is recommended between the 24IN/48OUT, and the motherboard.

    A separate 5V supply is recommended for the motherboard.

    A separate power supply is recommended for the servos. Ground to be connected between servo and the motherboard.

    The software for the Pro Mini is in finalisation stage; will be posted here when complete.
     

    Attached Files:

    Last edited: Feb 10, 2020
    vasilis likes this.
  10. nopxor

    nopxor New Member

    6
    14
    3
    Hello,

    Sorry but the images of my first post are no longer hosted by lightpics.net and I can't edit this first post.
    So I give the new images in this post.

    [​IMG]

    [​IMG]

    [​IMG]
     
    vasilis, Erik84750 and tnt23 like this.
  11. Sumner

    Sumner TrainBoard Member

    2,798
    5,840
    63
    Thanks for the update and ....

    [​IMG]

    .... where did you get the thumb drive with the terminal on the end. I'd like some of those and searched last night and couldn't find one like that. I found some with all the pinouts but I'm assuming that one just breaks out the 5 volt + and -.

    Thanks.

    Sumner
     
  12. nopxor

    nopxor New Member

    6
    14
    3
  13. Sumner

    Sumner TrainBoard Member

    2,798
    5,840
    63
    Thanks so it is serial not power. Thanks for the link,

    Sumner
     
  14. Ash

    Ash TrainBoard Member

    106
    67
    8
    I came close to ordering some boards, but I decided on an alternate path.

    I'm new to Arduino and just starting with DCC++/JMRI/CMRI. But I ordered a few parts, used the new Dex installer for DCC++/JMRI, and then struggled to figure out what was needed for an accessory controller, etc.

    So here is where I am today.

    1. For CMRI, I will use a USB/RS485 adapter on the JMRI-RP3b. I selected this one with A/B/Gnd terminals.
    [​IMG]

    2. Arduino Pro Mini and RS485 adapter socketed on a prototype board with connectors for PCA9685 (x1) and MCP23017 (x3) boards.
    [​IMG]

    3. The MCP23017 boards used for relays, signals and fascia lights are each socketed on separate prototype boards along with two ULN2803A Darlington transistor arrays and resistors. I haven't decided whether the 12v+ will be included on the prototype board when only used with LEDs. (Do I even need the transistor arrays for LEDs?)

    [​IMG]

    4. A prototype board will not be needed for the MCP23017 boards used for fascia buttons and sensors.

    5. Also planning to use this for occupancy detection, based on first board from this post:
    https://model-railroad-hobbyist.com/node/31270#comment-302930

    [​IMG]

    Caution: I don't yet have anything connected to the layout. I have no idea if my selection for bridge rectifier is appropriate, etc. In other words, don't hesitate to let me know if you notice issues.


    6. In the sketch below, I had modified the numbering of the MCP23017 boards to match my testing setup. And my initial code was using multiple PCA9685 boards. Then I found the code for the MCP23017 (in Portuguese), and I included the minimum to get started.
    This sketch allows 1 PCA9685 board and 3 MCP23017 boards. (48 outputs/16 inputs)

    // Define MCP23017 modules
    mcp0.begin(1);
    mcp1.begin(0);
    mcp2.begin(2);
    Here is a link to the translated website:
    https://translate.google.com/transl...m/2019/08/interface-configuravel-para-48.html

    Code:
    //  MCP23017 code -- some parts translated from Portugese
    #include <Wire.h>
    #include <Adafruit_PWMServoDriver.h>
    #include <CMRI.h>
    #include <Auto485.h>
    #include <Adafruit_MCP23017.h>
    
    //#define RS485Serial Serial1
    
    #define CMRI_ADDR 1
    #define DE_PIN 2
    
    int Tbit[16];           // number of servos
    uint8_t servonum = 0;   // servo counter
    uint8_t lastservo = 16;
    
    Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);    //setup the board address 0
    // Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);    //setup the board address 1
    Auto485 bus(DE_PIN); // Arduino pin 2 -> MAX485 DE and RE pins
    CMRI cmri(CMRI_ADDR, 24, 48, bus);
    
    // Initialize I2C MCP23017
    Adafruit_MCP23017 mcp0;
    Adafruit_MCP23017 mcp1;
    Adafruit_MCP23017 mcp2;
    
    byte UpdateOutputValue=1;
    byte OutputValue[6];   //Each byte is 8 bits - 8x4 32 bits
    byte InputValue[3]; //Each byte is 8 bits - 8x3 24 bits
    unsigned long TimerLoadInput;
     
    
    void setup() {
      Serial.begin(9600);
      bus.begin(9600, SERIAL_8N2);
      pwm1.begin();
      // pwm2.begin();
      pwm1.setPWMFreq(60);
      // pwm2.setPWMFreq(60);
    
      // Define MCP23017 modules
      mcp0.begin(1);
      mcp1.begin(0);
      mcp2.begin(2);
     
      InitializePortsMCP23017();
     
      Serial.println("setup1 complete");
    }
    
    void loop() {
     //  Serial.println(bus.read());
       cmri.process();
    
      // Load Input Values
       if (millis()-TimerLoadInput>500) {
          LoadInputValues();
          TimerLoadInput = millis();
        }
      
       for(servonum = 0 ; servonum < lastservo; servonum ++){
    
        Tbit[servonum] = (cmri.get_bit(servonum));     
      // Serial.println(servonum, Tbit[servonum]);
        if(servonum <16) {
            if (Tbit[servonum] == 1){
                pwm1.setPWM(servonum, 0, 100);
          //      Serial.println("throw");
              }
            if (Tbit[servonum] == 0){
                pwm1.setPWM(servonum, 0, 400);
          //      Serial.println("close 1");
              }
          }
      /*
        if(servonum >=16 && servonum <= 31){
            if (Tbit[servonum] == 1){
                pwm2.setPWM(servonum - 16, 0, 100);
                Serial.println("throw2");
              }
            if (Tbit[servonum] == 0){
                pwm2.setPWM(servonum - 16, 0, 400);
                Serial.println("close 2");
              }
          }
        */     
        // add additional lines for additional boards
    
      }
    
      // Check for change in output values
      for(int i = 0; i < 6; i++) {
        byte NewValue;
        NewValue = cmri.get_byte(i);
      //  Serial.println(NewValue);
        if (NewValue != OutputValue[i]) {
          CompareOutputBits(NewValue, i);
        }
      }
    
      // Update of Output Values
      if (UpdateOutputValue>0) UpdateOutput();
    }
    
    void CompareOutputBits(byte tmpValue, byte bBlock) {
      //Compare the New Value bits
      for(byte i = 0; i < 8; i++) {
        if (bitRead(tmpValue, i) != bitRead(OutputValue[bBlock],i)) {
          if (bBlock<2) {
            i = i;  // This is where the servo code was called
                    // -- review could improve efficiency
                    // -- also a reason for only using one pca9685 pwm board
         //   NovoValueServo(bBlock * 8 + i, bitRead(tmpValue, i)); 
          }
          else
          {
            UpdateOutputValue=1;
          }
        }
      }
      OutputValue[bBlock] = tmpValue;
    }
    
    void LoadInputValues() {
      for (byte i = 0; i < 2; i++) {
        // Input Values MCP23017
        byte NewValue = ReturnValueEnteredMCP23017(i);
            
        // Check value change
        if (NewValue != InputValue[i]) {
          cmri.set_byte(i, ~NewValue);
          InputValue[i] = NewValue;
        }
      }
    }
    
    byte ReturnValueEnteredMCP23017(byte bInput) {
      byte bValue;
      // Input ports 0 - MCP23017 0 / Port A
      if (bInput==0) bValue=mcp0.readGPIO(0);
      // Input ports 1 - MCP23017 0 / Port B
      if (bInput==1) bValue=mcp0.readGPIO(1);
      // Returns bValue
      return bValue;
    }
    
    void InitializePortsMCP23017() {
      //Module 0 - Input
      for (int p=0;p<16;p++) {
        mcp0.pinMode(p, INPUT);
        mcp0.pullUp(p, HIGH); 
      }
      //Module 1 - Output
      for (int p=0;p<16;p++) {
        mcp1.pinMode(p, OUTPUT);
      }
      //Module 2 - Output
      for (int p=0;p<16;p++) {
        mcp2.pinMode(p, OUTPUT);
      }
    }
    
    void UpdateOutput() {
      int tmpAB;
     
      // Output ports 2 and 3 (17 to 32) - MCP23017 1
      tmpAB = OutputValue[3];
      tmpAB <<= 8;
      tmpAB |= OutputValue[2];
      mcp1.writeGPIOAB(tmpAB);
     
      // Output ports 4 and 5 (32 to 48)- MCP23017 2
      tmpAB = OutputValue[5];
      tmpAB <<= 8;
      tmpAB |= OutputValue[4];
      mcp2.writeGPIOAB(tmpAB);
    }
    
     

    Attached Files:

    BigJake and Erik84750 like this.
  15. Erik84750

    Erik84750 TrainBoard Member

    334
    134
    12
    Top contribution!! Congratulations!! And nice programming too.

    Just a few comments/questions:
    1. the first link, to model-railroad-hobbyist does not work
    2. the second link to a translated google site works but the connections from the rS485 converter tot the nano are not clear: which pins to which pins? By the way, this is a great post too: yours?
    3. the wiring on your drawings is bizarre, not quite readable imh; I am sure you have it perfectly working but I would not be able to reproduce it. And I am very keen on trying this out.

    Maybe a block schematic and then a detailed schematic?
    Grts
    Erik
     
  16. Ash

    Ash TrainBoard Member

    106
    67
    8
    Perhaps temporarily out of service. It is working now, and has a nice schematic and additional comments that led me to this solution to use the SFH628A-4 optoisolators. I got a couple of -2 and -3 for initial testing. Current plan is to use the -4 version as they result in tripping the sensor with 12k-ohm resistance on a 12-volt DCC track (7k-ohm for -2; 10k-ohm for -3). They also function with straight DC power.

    I found the translated website after much searching. It is using a similar approach and components. I took your lead from the 24/48 card, and am using the Arduino Pro Mini 5-volt.
    RX1 --> RO
    TX0 --> DI
    2 --> DE+RE
    also GND, VCC
    RS485 wiring to the USB/RS485 adapter is A, B, GND

    The RS485 adapters I use look like the ones on this link:
    https://arduinoinfo.mywikis.net/wiki/RS485-Modules


    [/QUOTE]
    3. the wiring on your drawings is bizarre, not quite readable imh; I am sure you have it perfectly working but I would not be able to reproduce it. And I am very keen on trying this out.

    Maybe a block schematic and then a detailed schematic?
    Grts
    Erik[/QUOTE]

    I do plan further documentation. Perhaps a .pdf will help.
     

    Attached Files:

  17. Ash

    Ash TrainBoard Member

    106
    67
    8
    Update after assembling a few of the MCP23017 ULN2803 output boards. More information in attached file.

    [​IMG]
     

    Attached Files:

  18. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    Module MCP23017 I / O I2C (3x);
    CJMCU-2317 MCP23017 I2C Serial Interface 16 bit I/O Expander Serial Module are these module any good dont see why you need two ULN2803A Darlington transistor arrays and resistors.
     
  19. Ash

    Ash TrainBoard Member

    106
    67
    8
    I have used some CJMCU-2317 versions -- the layout with two rows of pins is fine for inputs. The modules with a single row of I/O pins work better for my use with the Darlington transistor arrays. I also like the double row of pins VCC/GND/SCL/SDA and the mounting holes.

    Resistors limit the current for LEDs. And I saw that Darlington transistor arrays could be useful where I don't yet know the power requirements.

    I'm open to suggestion on how to do it differently. I found this link for constructing a relay board which demonstrated using various voltages and higher current.
    https://www.instructables.com/id/I2C-Relay-Board/
    The resistors are there for convenience, when I am using 12-volts and would otherwise need to connect a resistor for a LED. If I use a relay module with its own logic, I can connect directly to the mcp23017. For a LED/signal with its own resistors in line, I can connect before the resistor.
     
  20. garry2577

    garry2577 TrainBoard Member

    17
    1
    3
    Ash on your MCP23017 ULN2803 output boards can i use the vcc on the mcp23017 for led power rather than the external 12 volts .on your diagram its not connected.
     

Share This Page