DCC++ Hardware - Throttles

KE4NYV Jan 25, 2016

  1. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    Yes as you figured out. I sent you a PM about the building,

    Sumner
     
  2. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    Would someone please check me on this wiring plan. The Arduino mini pro was attached to a larger empty board. Header pins attached on left and right sides. Top right 5 GND black header pins all with continuity (2nd photo) and top left 5 (5V) red header pins all with continuity. 1) the keypad will be connected to the bottom left (5 pins on the mini) and the bottom right (2 pins) as per Dave's diagram. Th GND pin on the mini (Pin 4 - 4th pin down from the top, left side of mini will be connected to one of the 5 GND pins top right. The GND pins from the LCD display, the two buttons and the potentiometer will be attached to one of the 4 remaining GND pins on the top right. PIN 21 (VDD - 5V) connection will got to one of the red headers on the top left. The LCD and potentiometer will be attached to one of the red power headers (top left). Pin 1 (TXO) will go to one of the bottom 3 yellow headers along with one connection from the 5V power (red headers) and one from the black GND headers (yes, I just realized I need one more GND pin in continuity with the other 5). A3 (red wire soldered to pro mini already will got to the center pin of the potentiometer. PINs 3 and 4 on the Arduino mini Pro (labeled wires 6 and 7) go to the other connections on each of the two buttons). Finally the bottom 3 yellow pins will be connected to a long cable and to the DCC++ base station for power and data. This is the first electronics I have ever wired, so is this correct? I have tried to do the wiring in a logical way but I'm not sure reasoning is electrically sound. QUESTIONS: 1) I'm at a lose to know where the SDA and SCL (A4 and A5 wires) go to from the LCD display. I don't see any other A4 and A5 on the diagram nor on the mini pro board. 2) There is a Reset button on the left side of the diagram from the RST pin on the mini to GND. I don't see a rest button on the actual photos of the throttle anywhere. Is this button intended to be inside the case? Is it necessary or can you just push Reset button on the mini pro board if necessary? 3) my potentiometer rotates through about 270 - 280 degrees (from about noon - till 10 PM). Is this the wrong type of potentiometer for this corded build? The instructions say the center position of the potentiometer is stop and then right for forward and left from that center position for reverse. Will mine work or do I need a different type and if so, what type? Thanks to anyone who will read all this and help!!! Front1.jpg Back1.jpg
     
  3. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    [​IMG]
    A4 and A5 are just to the inside of the other pins on the two pads there. So you won't solder to them on the socket if you use one which I would do. Dave addressed this by pin/sockets coming from the bottom of the circuit board....

    [​IMG]

    You can see the two added pin sockets under the socket for the pro mini above.

    Have you considered contacting Dave and see if he still has any of those circuit bds left. They were very inexpensive and I think well worth getting. If you can't find a contact for him PM me,

    Sumner
     
  4. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    Steve I was having a hard time reading through your questions so broke it up some. Below is a reprint of them. Hope that was OK. Also I'd sure recommend getting his PC board for this. I don't think I'd attempt it without it as like you it has been a long time since I put a project together (Heath kit stereo).

    =====================================================

    Would someone please check me on this wiring plan.

    The Arduino mini pro was attached to a larger empty board.

    Header pins attached on left and right sides.

    Top right 5 GND black header pins all with continuity (2nd photo)

    and top left 5 (5V) red header pins all with continuity.


    1. the keypad will be connected to the bottom left (5 pins on the mini) and the bottom right (2 pins) as per Dave's diagram.

      Th GND pin on the mini (Pin 4 - 4th pin down from the top, left side of mini will be connected to one of the 5 GND pins top right.

      The GND pins from the LCD display, the two buttons and the potentiometer will be attached to one of the 4 remaining GND pins on the top right.

      PIN 21 (VDD - 5V) connection will got to one of the red headers on the top left. The LCD and potentiometer will be attached to one of the red power headers (top left).

      Pin 1 (TXO) will go to one of the bottom 3 yellow headers along with one connection from the 5V power (red headers) and one from the black GND headers (yes, I just realized I need one more GND pin in continuity with the other 5).

      A3 (red wire soldered to pro mini already will got to the center pin of the potentiometer.

      PINs 3 and 4 on the Arduino mini Pro (labeled wires 6 and 7) go to the other connections on each of the two buttons).

      Finally the bottom 3 yellow pins will be connected to a long cable and to the DCC++ base station for power and data.

      This is the first electronics I have ever wired, so is this correct? I have tried to do the wiring in a logical way but I'm not sure reasoning is electrically sound.

      QUESTIONS:

      1) I'm at a lose to know where the SDA and SCL (A4 and A5 wires) go to from the LCD display. I don't see any other A4 and A5 on the diagram nor on the mini pro board.

      2) There is a Reset button on the left side of the diagram from the RST pin on the mini to GND. I don't see a rest button on the actual photos of the throttle anywhere. Is this button intended to be inside the case? Is it necessary or can you just push Reset button on the mini pro board if necessary?

      3) my potentiometer rotates through about 270 - 280 degrees (from about noon - till 10 PM). Is this the wrong type of potentiometer for this corded build? The instructions say the center position of the potentiometer is stop and then right for forward and left from that center position for reverse. Will mine work or do I need a different type and if so, what type?

      Thanks to anyone who will read all this and help!!!
     
  5. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    Well, I finished wiring the throttle. Did not pack it all in the throttle case since I wanted to make sure it worked before I did. It did power up and I got a display of sorts that looked similar to what should have shown. Buttons did not works as I thought they should and keypad did not return correct numbers when pressed so I need to go back through everything and check all the connections. Not sure if wiring to blame (more likely) or coding I uploaded. Thanks for all the help here. Will let you know if I get it working properly.
     
    Sumner likes this.
  6. IronMan1963

    IronMan1963 TrainBoard Member

    161
    173
    9
    There are some keypads that are wired up backwards. You might need to flip the keyboard connection. This is something Dave mentions for this throttle.
    Later Richard
     
    Erik84750 likes this.
  7. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    I tried flipping them and it helped a little. I can now make loco move but it only moves forward whether the direction shows forward or reverse. I have sound but not at correct keys. I see the following in Dave's code -

    Code:
    // Array set for 4 Loco2 - change the 7 numbers in the next 7 declarations
    int maxLocos = 4;// number of loco addresses
    int LocoAddress[4] = {1830, 3, 999, 4444};
    int LocoDirection[4] = {1, 1, 1, 1};
    int LocoSpeed[4] = {0, 0, 0, 0};
    byte LocoFN0to4[4];
    byte LocoFN5to8[4];
    byte Locofn9to12[4];// 9-12 not yet implemented
    
    It says to change numbers in next 7 declarations but I have no idea what to change them to? I can't seem to enter addresses but it just so happens that Loco 2 seems to work. Maybe because int LocoAddress[4] = {1830, 3, 999, 4444} and my Loco address is actually 0003. What should LocoDirection be? Maybe {1,1,0,0}? Anyone?
     
    Last edited: Feb 8, 2021
  8. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    Hopefully someone else will respond as I'm guessing at what that does.

    Right now the number of loco's you can run with the throttle is 4. If you wanted to run 6 with the throttle you would change the [4] in the 7 lines of code to [6].

    He also put in loco's with 4 DCC addresses and yours runs as loco number 2 as it uses an address of '3', which I assume is the current DCC address (the common one for a newly purchased loco). If you had locos with addresses 1830,999,4444 they would also run when you selected loco #1, #3 and number #4. I'm assuming he just put those numbers in and when you assign loco #1, #3, and #4 to different loco's that have different DCC addresses those numbers will be overwritten with the ones you input. That also goes for loco #2 that is assigned DCC address 3 at the moment.

    If you would change that loco's address from 3 to say 1010 then you could change loco #1 (1830) to (1010) and when you had loco #1 selected with the throttle the loco that use to have 3 as the DCC address would run with the new 1010 address. Also if you change loco #1 to a 3 address from 1830 you should be able to run the loco by choosing either #1 or #2 with the throttle.

    int LocoDirection[4] = {1, 1, 1, 1};
    int LocoSpeed[4] = {0, 0, 0, 0};

    The above in the code is setting the initial state of the locos so that they won't start up and run as soon as the throttle is turned on. Those will be automatically changed as soon as you select a direction and speed with the throttle so you don't change those. My best guess without looking at the whole code. If they are at the very top part of the code that is what they are doing.

    Sumner
     
  9. IronMan1963

    IronMan1963 TrainBoard Member

    161
    173
    9
    That is for changing the number of locos the throttle will run at 1 time. You need to enter hit the enter new loco address button. The loco should change direction with the direction arrow. We need to see the code you have to figure out more.
     
  10. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    I changed int LocoDirection[4] = {1,1,1,1} to {1,1,0,0} and that worked and I got both directions working.

    This is my complete code .....

    Code:
    #include "Arduino.h"
    byte Key;
    #include<EEPROM.h>
    char key ;
    int LED = 13; // LED to blink when DCC packets are sent in loop
    byte Fx = 0;
    // Array set for 4 Loco2 - change the 7 numbers in the next 7 declarations
    int maxLocos = 4;// number of loco addresses
    int LocoAddress[4] = {0003, 0003, 0003, 0003};
    int LocoDirection[4] = {1, 1, 0, 0};
    int LocoSpeed[4] = {0, 0, 0, 0};
    byte LocoFN0to4[4];
    byte LocoFN5to8[4];
    byte Locofn9to12[4];// 9-12 not yet implemented
    int xxxxx = 0;
    int pot1Pin = A3;
    int potValue = 0;
    int NewPotValue = 0;
    int potValueOld = 0;
    int counter = 0;
    int Trigger1 = 3;
    int Trigger2 = 4;
    int TrigVal1 = 0;
    int TrigVal2 = 0;
    int old_speed = 0;
    int ZeroSpeedFlag = 0;
    int ActiveAddress = 0; // make address1 active
    #include <Wire.h>
    #include <LCD.h>
    #include <LiquidCrystal_I2C.h>
    #define I2C_ADDR    0x27 // <<----- Add your address here.  Find it from I2C Scanner
    #define BACKLIGHT_PIN     3
    #define En_pin  2
    #define Rw_pin  1
    #define Rs_pin  0
    #define D4_pin  4
    #define D5_pin  5
    #define D6_pin  6
    #define D7_pin  7
    LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);
    int z = 0;
    int powerTemp = 0;
    int i = 0;
    char VersionNum[] = "1.7F "; ///////////////////////// //////////////////////VERSION HERE///////
    #include <Keypad.h>
    const byte ROWS = 4; //four rows
    const byte COLS = 3; //three columns
    char keys[ROWS][COLS] = {
      {'1', '2', '3'},
      {'4', '5', '6'},
      {'7', '8', '9'},
      {'*', '0', '#'}
    };
    byte rowPins[ROWS] = {5, 6, 7, 8 }; //{8,7,6,5 }; //connect to the row pinouts of the keypad
    byte colPins[COLS] = {9, 10, 11}; // {11,10,9}; //connect to the column pinouts of the keypad
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
    byte ledPin = 13;
    boolean blink = false;
    boolean ledPin_state;
    int debug = 0; // set to 1 to show debug info on serial port - may cause issues with DCC++ depending on what is sent
    
    void setup() {
      pinMode(Trigger1, INPUT);
      pinMode(Trigger2, INPUT);
      digitalWrite(Trigger1, HIGH);// turn on pullup resistors
      digitalWrite(Trigger2, HIGH);// turn on pullup resistors
      // randomSeed(analogRead(0));
      pinMode(LED, OUTPUT);
      lcd.begin (16, 2); //  LCD is 16 characters x 2 lines
      lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
      lcd.setBacklight(HIGH);  // Switch on the backlight
      lcd.home (); // go home
      Serial.begin (115200);
      lcd.setCursor(0, 0);
      lcd.print("DCC++ Throttle");
      lcd.setCursor(0, 1);
      lcd.print("5-26-16 - v");
      for (int i = 0; i < 4; i++) {
        lcd.print(VersionNum[i]);
        //delay(500);
      }
      getAddresses();  // read eeprom
      Serial.print("5-22-2016  version ");
      for (int i = 0; i < 4; i++) {
        Serial.print(VersionNum[i]);
        //delay(500);
      }
      if (debug == 1) Serial.println("");
      Serial.print("<0>");// power off to DCC++ unit
      delay(1500);
    
      pinMode(ledPin, OUTPUT);              // Sets the digital pin as output.
      digitalWrite(ledPin, HIGH);           // Turn the LED on.
      ledPin_state = digitalRead(ledPin);   // Store initial LED state. HIGH when LED is on.
      keypad.addEventListener(keypadEvent); // Add an event listener for this keypad
    
      // showFirstLine();
      lcd.clear();
    
    }  // END SETUP
    
    
     
  11. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    Code after //END SETUP .....

    Code:
    void loop() {
      TrigVal1 = digitalRead(Trigger1);   // read the input pin
      TrigVal2 = digitalRead(Trigger2);   // read the input pin
      key = keypad.getKey();
      // if (key) {
      if (key == 42) { // *
        all2ZeroSpeeed();
        getLocoAddress();
        key = 0;
      }
      // }
      if (TrigVal1 == 0) {
        all2ZeroSpeeed();
        getLocoAddress();
        //   showFirstLine();
      }
      potValue = analogRead(pot1Pin);    // read the value from the sensor
      if (potValue != potValueOld) {
        NewPotValue = 1;
        //doMainLCD();
      }
      else NewPotValue = 0;
      potValueOld = potValue;
      potValue = (potValue / 4) - 128;
      if (potValue <= 0) {
        LocoDirection[ActiveAddress] = 0; // backward
      }
      else LocoDirection[ActiveAddress] = 1; // forward
      potValue = abs(potValue);
      if (potValue >= 126) potValue = 126; // max is 127
      if (potValue <= 3) potValue = 0; // set to zero if close to zero
      LocoSpeed[ActiveAddress] =   potValue;
      if (NewPotValue == 1) {
        doDCC();
        doMainLCD();
        NewPotValue = 0;
        delay(50);
      }
      if (key == 35) { // #
        ActiveAddress++;
        if (ActiveAddress >= 4) ActiveAddress = 0;
        //showFirstLine();
        doMainLCD();
        delay(200);
        key = 0;
      }
      if (TrigVal2 == 0) {   // change loco # on right button press
        ActiveAddress++;
        if (ActiveAddress >= 4) ActiveAddress = 0;
        //showFirstLine();
        doMainLCD();
        delay(200);
      }
      //  key = keypad.getKey();
      //    Serial.print("KKKKKKKKKKKKKKKKKEY =");
      //    Serial.println(key);
      if (key != 42 && key != 35 && key >= 40) {
        //   if (key == 42) Serial.println("****************************");
        //   Serial.print("KEY =");
        //   Serial.println(key);
        doFunction();
      }
      // doMainLCD();
    }  //END LOOP
    
    
    //START DO FUNCTION BUTTONS
    int doFunction() {
      key = key - 48 - 1; // convert from ascii value
      lcd.setCursor (14, 1);       // go to end of 2nd line
      ///  lcd.print("FN code ");
      lcd.print(key, DEC);
      if (debug == 1) Serial.print("got a keypad button ");
      if (debug == 1) Serial.println(key, DEC);
      if (key <= 4) {
        if (bitRead(LocoFN0to4[ActiveAddress], key) == 0 ) {
          bitWrite(LocoFN0to4[ActiveAddress], key, 1);
        }
        else {
          if (bitRead(LocoFN0to4[ActiveAddress], key) == 1 ) {
            bitWrite(LocoFN0to4[ActiveAddress], key, 0);
          }
        }
        doDCCfunction04();
        Serial.print(LocoFN0to4[ActiveAddress], BIN);
        if (debug == 1) Serial.println(" LocoFN0to4[ActiveAddress] d ");
        Serial.print(LocoFN0to4[ActiveAddress], DEC);
        if (debug == 1) Serial.println(" LocoFN0to4[ActiveAddress]");
      }
      if (key >= 5 && key <= 8) {
        key = key - 5;
        if (bitRead(LocoFN5to8[ActiveAddress], key) == 0 ) {
          bitWrite(LocoFN5to8[ActiveAddress], key, 1);
        }
        else {
          if (bitRead(LocoFN5to8[ActiveAddress], key) == 1 ) {
            bitWrite(LocoFN5to8[ActiveAddress], key, 0);
          }
        }
        doDCCfunction58();
        Serial.print(LocoFN5to8[ActiveAddress], BIN);
        if (debug == 1) Serial.println(" LocoFN5to8[ActiveAddress] d ");
        Serial.print(LocoFN5to8[ActiveAddress], DEC);
        if (debug == 1) Serial.println(" LocoFN5to8[ActiveAddress]");
      }
      if (key == -1)
      {
        lcd.setCursor (14, 1);       // go to end of 2nd line
        ///    lcd.print("FN code ");
        lcd.print(key, DEC);
        key = 0;
        LocoFN0to4[ActiveAddress] = B00000000; //clear variables for which functions are set
        LocoFN5to8[ActiveAddress] = B00000000;
        doDCCfunction04();
        doDCCfunction58();
        delay(500);
        key = 0;
      }
      key = 0;
      // delay(500);
      doMainLCD();
    }
    //END DO FUNCTION BUTTONS
    
    void showFirstLine() {
      // break;
      if (debug == 1) Serial.println(" ");
      lcd.setCursor(0, 0);
      lcd.print("                ");// clear
      lcd.setCursor(0, 0);
      lcd.print("L");
      lcd.print(ActiveAddress + 1);
      lcd.print("=");
      lcd.print(LocoAddress[ActiveAddress]);
    
      for (int zzz = 0; zzz <= 3; zzz++) {
        if (debug == 1) Serial.print("add # ");
        if (debug == 1) Serial.print(zzz + 1);
        if (debug == 1) Serial.print(" ");
        if (debug == 1) Serial.println(LocoAddress[zzz]);
    
      }
    
    
    }
    
    void getLocoAddress() {
      Serial.print("<0>");// power off to DCC++ unit
      int total = 0;
      counter = 0;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Set Dcc Addr # ");
      lcd.print(ActiveAddress + 1);
      if (debug == 1) Serial.println(" @ top");
      do {
        TrigVal2 = digitalRead(Trigger2);   // read the input pin
        if (TrigVal2 == 0) break; // exit routine if right button pressed - ABORT new address
        key = keypad.getKey();
        if (key) {
          counter++;
          int number =  key - 48;
          total = total * 10 + number;
          if (debug == 1) Serial.print("TOTAL= ");
          if (debug == 1) Serial.println(total);
          lcd.setCursor(0, 1);
          if (total == 0) {   // print multiple zeros for leading zero number
            for (int tempx = 1; tempx <= counter; tempx++) {
              lcd.print("0");
            }
          }
          else lcd.print(total);
          if (debug == 1) Serial.print("Counter = ");
          if (debug == 1) Serial.print(counter);
          if (debug == 1) Serial.print("  key= ");
          if (debug == 1) Serial.print(key);
    
          if (debug == 1) Serial.print("   val =");
          if (debug == 1) Serial.println(number);
        }
        TrigVal2 = digitalRead(Trigger2);   // read the input pin
      }
      while (counter <= 3); //  collect exactly 4 digits
      //  while (  TrigVal2 == 1);
      LocoAddress[ActiveAddress] = total;
      saveAddresses();
      lcd.clear();
      doMainLCD();
    }
    
    
    // Taking care of some special events.
    void keypadEvent(KeypadEvent key) {
      switch (keypad.getState()) {
        case PRESSED:
          if (key == '#') {
            digitalWrite(ledPin, !digitalRead(ledPin));
            ledPin_state = digitalRead(ledPin);        // Remember LED state, lit or unlit.
          }
          break;
    
        case RELEASED:
          if (key == '*') {
            digitalWrite(ledPin, ledPin_state);   // Restore LED state from before it started blinking.
            blink = false;
          }
          break;
    
        case HOLD:
          if (key == '*') {
            blink = true;    // Blink the LED when holding the * key.
          }
          break;
      }
    }
    
    
    void doDCC() {
      //Serial.print("d = ");
      if (debug == 1) Serial.println(LocoDirection[ActiveAddress] );
      Serial.print("<1>");
      Serial.print("<t1 ");
      Serial.print(LocoAddress[ActiveAddress] );//locoID);
      Serial.print(" ");
      Serial.print(LocoSpeed[ActiveAddress] );
      Serial.print(" ");
      Serial.print(LocoDirection[ActiveAddress] );
      Serial.write(">");
    }
    
    void doDCCfunction04() {
      Serial.write("<f ");
      Serial.print(LocoAddress[ActiveAddress] );
      Serial.print(" ");
      int fx = LocoFN0to4[ActiveAddress] + 128;
      Serial.print(fx);
      Serial.print(" >");
    }
    
    void doDCCfunction58() {
      Serial.write("<f ");
      Serial.print(LocoAddress[ActiveAddress] );
      Serial.print(" ");
      int fx = LocoFN5to8[ActiveAddress] + 176;
      Serial.print(fx);
      Serial.print(" >");
    }
    
    void all2ZeroSpeeed() {  // set flag to 1 to stop, set to 0 to restore
      for (int tempx = 0; tempx <= maxLocos; tempx++) {
        Serial.print("<t1 ");
        Serial.print(LocoAddress[tempx] );//locoID);
        Serial.print(" ");
        if (ZeroSpeedFlag == 1) {
          Serial.print(0);//LocoSpeed[0] );
        }
        else Serial.print(LocoSpeed[0] );
        Serial.print(" ");
        Serial.print(LocoDirection[1] );
        Serial.write(">");
      }
    }
    
    void getAddresses() {
      int xxx = 0;
      for (int xyz = 0; xyz <= maxLocos - 1; xyz++) {
        LocoAddress[xyz] = EEPROM.read(xyz * 2) * 256;
        LocoAddress[xyz] = LocoAddress[xyz] + EEPROM.read(xyz * 2 + 1);
        if (LocoAddress[xyz] >= 10000) LocoAddress[xyz] = 3;
    
        if (debug == 1) Serial.println(" ");
        if (debug == 1) Serial.print("loco = ");
        if (debug == 1) Serial.print(LocoAddress[xyz]);
        if (debug == 1) Serial.print("  address# = ");
        if (debug == 1) Serial.print(xyz + 1);
      }
      if (debug == 1) Serial.println(" ");
    }
    
    void saveAddresses() {
      int xxx = 0;
      for (int xyz = 0; xyz <= maxLocos - 1; xyz++) {
        xxx = LocoAddress[xyz] / 256;
        if (debug == 1) Serial.println(" ");
        if (debug == 1) Serial.print("loco = ");
        if (debug == 1) Serial.print(LocoAddress[xyz]);
        if (debug == 1) Serial.print("  address# = ");
        if (debug == 1) Serial.print(xyz);
        if (debug == 1) Serial.print(" msb ");
        if (debug == 1) Serial.print(xxx);
        if (debug == 1) Serial.print(" writing to ");
        if (debug == 1) Serial.print(xyz * 2);
        if (debug == 1) Serial.print(" and ");
        if (debug == 1) Serial.print(xyz * 2 + 1);
        EEPROM.write(xyz * 2, xxx);
        xxx = LocoAddress[xyz] - (xxx * 256);
        if (debug == 1) Serial.print(" lsb ");
        if (debug == 1) Serial.print(xxx);
        EEPROM.write(xyz * 2 + 1, xxx);
      }
    }
    
    
    void doMainLCD() {
      //lcd.setCursor(0, 0);
      //lcd.print("               ");
      lcd.setCursor(0, 0);
      lcd.print("S=");
      lcd.print(LocoSpeed[ActiveAddress], DEC);
      lcd.print("  ");
      lcd.setCursor(6, 0);
      if (LocoDirection[ActiveAddress] == 1 ) {
        lcd.print(">");
      }
      else {
        lcd.print("<");
      }
    
      lcd.setCursor(8, 0);
    
      lcd.print("L=");
      if (LocoAddress[ActiveAddress] <= 9) {
        lcd.print("0");  // add leading zero for single digit addresses
      }
      lcd.print(LocoAddress[ActiveAddress] , DEC);
      lcd.print("   ");
      lcd.setCursor(14, 0);
      lcd.print("#");
      lcd.setCursor (15, 0);       // go to end of 1st line
      lcd.print(ActiveAddress + 1);
      lcd.setCursor(5, 1); // start of 2nd line
      String temp = "0000" + String(LocoFN0to4[ActiveAddress], BIN);  // pad with leading zeros
      int tlen = temp.length() - 5;
      lcd.print(temp.substring(tlen));
      temp = "000" + String(LocoFN5to8[ActiveAddress], BIN);
      tlen = temp.length() - 4;
      lcd.setCursor(0, 1); // start of 2nd line
      lcd.print(temp.substring(tlen));
    
    }
    
     
  12. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    Also odd is that the code I have from Dave's setup show the keypad setup as .....

    Code:
    #include <Keypad.h>
    const byte ROWS = 4; //four rows
    const byte COLS = 3; //three columns
    char keys[ROWS][COLS] = {
      {'1', '2', '3'},
      {'4', '5', '6'},
      {'7', '8', '9'},
      {'*', '0', '#'}
    };
    byte rowPins[ROWS] = {5, 6, 7, 8 }; //{8,7,6,5 }; //connect to the row pinouts of the keypad
    byte colPins[COLS] = {9, 10, 11}; // {11,10,9}; //connect to the column pinouts of the keypad
    
    
    However a search for 3 X 4 keypad setup shows this as how to program the keypad
    
    #include <Keypad.h>
    
    const byte ROWS = 4;
    const byte COLS = 3;
    
    char hexaKeys[ROWS][COLS] = {
      {'1', '2', '3'},
      {'4', '5', '6'},
      {'7', '8', '9'},
      {'*', '0', '#'}
    };
    
    byte rowPins[ROWS] = {9, 8, 7, 6};
    byte colPins[COLS] = {5, 4, 3};
    
    Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
    
    Difference in BOLD.  Could this explain why keypad not working as expected?
    
     
  13. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    Hopefully someone else will comment as I'm at the beginning stages of working with this language. I don't see where changing the {1,1,1,1} to {1,1,0,0} would of fixed the problem you were having but if it did then good. The [1,1,1,1} is in the setup part of the code to set the initial state of things and was setting all 4 loco's (if there are that many) to an initial stage of going forward. Once you change the direction of any of them that code is never read again as the program is then running in the void loop() { where it will read what you are doing with the throttle over and over again.

    Not sure what is going on with the keypad code. Do you have exactly the same keypad as what he used?

    Sumner
     
  14. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    Looks like the ...

    byte rowPins[ROWS] = {x,x,x,x};
    byte colPins[COLS] = {x,x,x};

    defines which pins of the socket are attached to the leads coming off the keyboard and could be whichever pins you wanted to use. But in his case it doesn't look like the pins he is assigning to be read match the pins in the schematic.

    To me it looks like they should be using the following pins for rows and columns

    8,9,10,11,12,13,14 as those look like the pins the schematic has you connecting the keyboard to.

    Anyone else??

    Sumner
     
    Last edited: Feb 10, 2021
  15. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    Thanks Sumner, I'll look more carefully at the keyboard assignments. What you are saying about the LocoDirection makes sense now too. The fact the loco was suddenly acting correctly had nothing to do with me changing it to {1, 1, 0, 0} because the next time I plugged everything back in, it was only going forward again. Guess I will just study the coding and try to understand it. It is starting to make a little sense. No reason to keep bothering people here about it. I'll learn more and be able to make it work the way I want by understanding it myself. I do appreciate all the help.

    Oh and my keypad looks exactly like the one on Dave's train electronics page where he gives all the information and coding of the throttle. However, it may be that although the keypad I have looks like his, it's possible the internal wiring has changed in the 4 years between his post and my purchase of a similar looking keypad.
     
    Last edited: Feb 10, 2021
  16. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    Played around with the coding and everything working now. Thanks all.
     
  17. Sumner

    Sumner TrainBoard Member

    2,835
    5,969
    63
    Congrats and we are going to need to see pictures or video at some point ;).

    Can you post the code you ended up with? Also did you end up using a Pot or Encoder?

    Thanks,

    Sumner
     
    Erik84750 likes this.
  18. Steve Micinski

    Steve Micinski TrainBoard Member

    19
    7
    4
    I'll try to post some pictures in a day or so. I used a pot not an encoder. I may make another one in the future that's wireless and uses an encoder. I'm not happy with the sensitivity of the pot. I'll try to post the code later too. Most of the changes were for the keypad's pin assignments and for the sensitivity of the pot. I learned a lot just struggling through it. Nevertheless, everyone's comments and suggestions helped me with understanding the code better and getting it built. I'm pretty happy that with some help I was able to use a blank circuit board to arrange all my wiring in a fairly organized manner. My one regret is not having sufficient colors to make sure things were consistently color coded for ground, power, send and receive wiring but it worked out.
     
    Last edited: Feb 11, 2021
  19. IronMan1963

    IronMan1963 TrainBoard Member

    161
    173
    9
    Glad to hear you got it worked out.
     
  20. Erik84750

    Erik84750 TrainBoard Member

    345
    136
    12
    Glad I read this, that is why these boards are so useful :)
    Instead of having to experiment with pots I now know my throttle will be with a rotary encoder.

    By the way, if it can be of help, I am available for custom pcb design: just make a suggestion, and if enough people are interested we can make a separate conversation group to discuss design.

    Grts,
    Erik
     
    BigJake likes this.

Share This Page