DCC++ Hardware - Throttles

KE4NYV Jan 25, 2016

  1. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    All,

    While testing my rotary encoder with Encoder.h referenced above I got some undesirable behaviour (for me anyway) that I wanted to correct for my throttle code.

    First, it is not necessary to squirt every value from 0 to 126 when winding to full throttle or vice versa.
    Doing so much Serial.print can slow other things down for one.

    I've found sampling every 100ms works just fine.

    Second, if you wind below zero or above 126 even when you know 'constrain' is limiting values output, the the encoder counter is still counting (in my example anyway).
    This means if you overshoot by say 10 detents on the encoder, you will need to reverse by the same amount before you get an output again.

    To correct this I came up with the following. As I'm not a programmer there are probably easier ways to do this, maybe by re-configuring the library.
    One can get the general idea though, note this sketch is for an ESP8266 but similar would apply for Arduino.

    #include <Encoder.h>;

    Encoder myEnc(4, 5);


    int oldPosition = 255;
    unsigned long previousMillis = 0;
    const long interval = 100;


    void setup() {
    Serial.begin(115200);
    Serial.println();
    Serial.println("Basic Encoder Test:");
    pinMode(4, INPUT_PULLUP);
    pinMode(5, INPUT_PULLUP);

    }


    void loop() {

    unsigned long currentMillis = millis();
    int newPosition;

    if (myEnc.read() <= 0) { //Checking for counter over run to the negative
    myEnc.write(0); //Reset if true
    }
    if (myEnc.read() >= 504) { //Checking for counter over run to the positive
    myEnc.write(504); //Reset if true **********Note using constrain does not contain the underlying counter value**********
    }
    newPosition = constrain(myEnc.read(), 0, 504) / 4; //constrain anyway to keep the funtion in check

    if (newPosition != oldPosition) {

    if (currentMillis - previousMillis >= interval) { // applies a psuedo delay so the mcu can carry on with other things. A better way to put delays in loops.
    previousMillis = currentMillis; // the effect is to limit the number of readings printed when winding the throttle quickly. One can change interval at top of sketch.
    oldPosition = newPosition; //

    if (myEnc.read() <= 0) { // Before we print that newPosition, check if were already at zero or overun
    myEnc.write(0); // Reset if true
    Serial.println(0); // Print the zero here
    return; // Exit back to top of loop
    }
    if (myEnc.read() >= 504) { // Same as above for a 126 count.......
    myEnc.write(504);
    Serial.println(126);
    return;
    }
    Serial.println(newPosition); // Print other values >0 or <126

    }
    }
    }
     
    Last edited: Jul 1, 2016
    Scott Eric Catalano and Atani like this.
  2. Atani

    Atani TrainBoard Member

    1,469
    1,757
    37
    I agree, it spits out every update and will also go well beyond the limits of the encoder, I am going to limit the updates to at least a +/- 5 diff as well as 100ms.

    Out of curiousity, why did you go for 504 / 4?
     
    Scott Eric Catalano and UK Steve like this.
  3. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    @Atani

    I'm using a precision CNC type encoder of 100 ppr. With just A and B connected the library counts full quadrature of 4 counts per detent, hence 504/4.
    If you know how I could change this count in the library code, I'd much appreciate your help.

    Thanks

    Steve.
     
    Scott Eric Catalano likes this.
  4. Atani

    Atani TrainBoard Member

    1,469
    1,757
    37
    I am not sure unfortunately on that type of encoder. The library uses a lot of ASM code that I can't unfortunately read for this processor (if I look up a manual for it I might be able to though, I do know x86 ASM). From looking at what the 100ppm RE looks like, it is certainly a higher precision RE. The ones that I have been using are the ultra cheap ones that mount direct to PCB and have five pins total (3 for RE and 2 for push button). I will add a couple defines in config.h for "ENCODER_LIMIT" and "ENCODER_DIVIDER" (default to 126 / 1) that way you can use your higher precision one and handle the detents with a small edit.
     
    UK Steve and Scott Eric Catalano like this.
  5. Atani

    Atani TrainBoard Member

    1,469
    1,757
    37
    UK Steve and Scott Eric Catalano like this.
  6. Atani

    Atani TrainBoard Member

    1,469
    1,757
    37
    just a heads up, if you are using my DCCThrottle code ports got shifted up to free up port #2 since it is used by MRBus which I am exploring integrating as the communication channel to the base station. May need to adjust DCC++ BaseStation code to accommodate the change as well. MRBus has forced usage of Serial 0 and port #2 for toggling RX/TX on RS-485. A quick look through the code shows that we can shift it around a bit but it may be easier to adjust DCC++ as it doesn't do a lot of direct bit manipulation.

    edit: MRBus won't compile cleanly, going to explore other options. ports shifted will remain for now.
     
    Last edited: Jul 2, 2016
    Scott Eric Catalano likes this.
  7. esfeld

    esfeld TrainBoard Member

    443
    382
    17
    Dave
    Not sure either but the zip you sent worked .... Thank you. Waiting for some additional key pads from China .... the one I attached is giving me erratic behavior .... I've cchecked and rechecked all connections and still get no response to "0" and other numbers mixed up.
    Steve F
     
    Scott Eric Catalano likes this.
  8. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    Steve - try turning the connector over & recheck the wiring to the Arduino pins -

    Good to hear that it compiles! I'll take success any way I can get it!

    dave
     
    HVT and Scott Eric Catalano like this.
  9. Scott Eric Catalano

    Scott Eric Catalano TrainBoard Member

    205
    57
    6
    Hello Dave,

    my package arrived and I am waiting for other parts to show up..thanks!
     
  10. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    Scott - thanks for letting me know it arrived - when you stack the acrylic pieces note that one of them (marked FIRST) has a slightly larger hole to accommodate the edge of the LCD display - if you stack them in a different order it will not fit properly -

    dave
     
    Scott Eric Catalano likes this.
  11. esfeld

    esfeld TrainBoard Member

    443
    382
    17
    Dave
    I'm still playing with the matrix keypad, (while waiting for some new ones) ... Please just verify if I have this right ....looking at the top of the keypad pin #1 is on the right and goes to D5 then moving left 2/D6 .. 3/D7 .. 4/D8 .. 5/D9 .. 6/D10 .. 7/D11 ...... if this is correct then I just have a bad keypad as I am getting mixed up results.
    Thank you for your help
    Steve F
     
    Scott Eric Catalano likes this.
  12. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    Steve - I have yet to get a bad keypad (have tested about a dozen) & the circuit within it is really simple so I suspect a bad connection

    Install the cable with the solid part of the header pointing up (so you can't see the 7 notches where the silver of the contacts is visible)

    To make sure your wiring is OK try this:

    Put the display into loco address mode (press "*") or watch the 9 zeros across the bottom of the display - all to the right is 1, all the way to the left is 9

    Use a jumper to short the two outside pins (pin 1) closest to the pins for the LDC and pin 7 ( closest to the board edge) on the header that would connect D5 and D11 - you should get a "3" (1x7=3)
    Jumper the 2nd pin from the LCD pins, pin 2, and pin 7 - you should get a "2" (27=2)
    Jumper pin 3 and 7 - you should get a "1" (3x7=1)
    pins 1 and 6 = "6" (1x6=6)
    2 and 6 = "5" (2x6=5)
    3 and 6 ="4" (3x6=4)
    4 and 6 = "0" (4x6=0)
    1 and 5 = "9" (1x5=9)
    2 and 5 ="8" (2x5=8)
    3 and 5 ="7" (3x5=7)
    4 and 2 = "0" (4x2=0)
    4 and 3 "*" (4x3=*) - will put you into loco address mode
    4 and 1 "#" (4x1=#) - will switch the loco number

    If all of those work your wiring is good - if you are missing any use an ohm meter to check the continuity between the pin for the display and the Arduino pin

    The holes I use for that header are a tight fit and it is easy to have a bad connection

    Hope that makes sense. If you determine the keypad is bad let me know and I'll send you another one.

    dave
     
    Scott Eric Catalano likes this.
  13. esfeld

    esfeld TrainBoard Member

    443
    382
    17
    Dave

    Spent the weekend sorting things out … not easy because I am not using your pc board and my perf board is set up differently….. but verified the integrity of all my connections … still got no “0” and mixed results … being impatient (my key pads from China are weeks away) I located a new one locally .. plugged it in and voila, everything is fine. On to the next step since I can’t get the power LEDs on the motor shield to light using the HC12s .. tried a direct jumper from Motor Shield Rx to Pro Mini Tx still no power … I see the “Serial print <1>” in the code … is there a way to implement it without turning the throttle on/off? I’ll keep at it later today and see if I can sort it out. Again, thanks

    Steve F
     
    Scott Eric Catalano likes this.
  14. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    Sorry for the troubles, Steve - if you take off the paper that covers the adhesive side you can shine a light through the keypad and see how simple the connections are - some of the connecting traces must have failed.

    The <1> command turns on the power at the motor shield - I send it out with every new command just to make sure things are active - Not sure if that answers your question.

    Before the HC-12's will work they have to be set to 115,200 baud - have you done that?

    dave
     
    Scott Eric Catalano likes this.
  15. PGW

    PGW TrainBoard Member

    13
    16
    3
    Dave in your pictures the capacitor on your board in front of the regulator. Is that in place of the 2 caps on the encoder? And what value is that? Are the 2 caps on the encoder 1.o - 10 0r 0.1 ?
     
    Scott Eric Catalano likes this.
  16. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    I always put a cap before, after or both before & after a voltage regulator to keep it from going into oscillation - the values are not critical - I frequently put a 100 uf on the input side and a 1 uf on the output side. That does NOT replace the caps on the encoder. Again the value is not critical - I used 0.1 uf

    dave
     
    Scott Eric Catalano likes this.
  17. PGW

    PGW TrainBoard Member

    13
    16
    3
    Thanks, I see you have 2 on the schematic before and after the regulator but your pics only show one after, and I don't see an obvious spot for one before. Could you recommend the best placement if there is one for the other.
    Thanks,
    Paul
     
    Scott Eric Catalano likes this.
  18. David Bodnar

    David Bodnar TrainBoard Member

    264
    481
    13
    Paul - the capacitor before the regulator goes between ground and the input pin (I use an electrolytic cap which has its negative pole marked) - make sure that it is rated for at least double the voltage you plan on sending to the regulator (ie if you are sending 12 volts select a 100 uf x 25 volt cap)

    dave
     
    Scott Eric Catalano likes this.
  19. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    Update ESP8266 - Nextion throttle

    All,

    This evening I got the Nextion display successfully working with the throttle. I can only say I am very pleased with how the concept is working so far.
    I'm still on a learning curve as far as the display 'programming' goes, however I got 10 buttons to send separate loco id's to the ESP and my code is working
    beautifully. Tomorrow I'll fix the return info, and for proof of concept we have a prototype.

    The code base came out surprisingly compact and works extremely well. Parsing the return strings was the way to go - I now fully appreciate Gregg's brilliance, in the design of this system.
    Later I'll add some function buttons and such but that aside I'm nearly there.

    Then I've got a little something else to start over the summer ;)

    Steve.
     
  20. Atani

    Atani TrainBoard Member

    1,469
    1,757
    37
    Pic of the throttle I am working on assembling:
    https://goo.gl/photos/jaK7VGcKEqYJ3mjb7

    Will have a 3x4 keypad to start with. May upgrade to 4x4 as I still have a couple pins left on the pro mini.

    This will be a wired throttle as I don't have the wireless chips and don't really want to deal with the batteries for now. This will communicate with the base station (and boosters!) via RS485 rather than serial and have a set of 2mm LEDs (dialight 555-4003) for diagnostics of the RS485 bus. I will be pushing the new throttle code and a modification to the base station to my github repos as soon as I complete testing (maybe next week). A new schematic drawing has been posted for this as well: https://github.com/atanisoft/DCCThrottle/blob/master/throttle-schematic.png. It is still based on the one that Dave posted on his site but has been modified for RS-485 (not finalized yet, pins *WILL* be changing)

    I am also putting together a board designed for the plugins along the fascia. I have a pair of RJ45 (8p8c) plugins that will poke through the fascia and each has a green and yellow led in them to indicate track power on (green) and short/overpower detected (yellow). On the back of the board is an 8pin molex to connect to the main bus, this could be another RJ45 (8p8c) as well but I opted for the molex as I don't have enough of the other plugins and I have plenty of these currently.
     
    Scott Eric Catalano and KC Smith like this.

Share This Page