ESP32 Command Station

Atani Dec 10, 2017

  1. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    Has anyone experimented much with writing CVs on the main track using this base station? I was previously having some trouble writing CVs to a soundtraxx loco decoder (I could write some but not others, and writing seemed to be inconsistent), however now I'm trying to work with one of Geoff Bunza's accessory decoders and I cannot write any CVs at all, even though changing the state of the accessories is working just fine. I've been banging my head against this issue for the past week and was reading through a thread of a similar problem folks were having with the DCC++ base station, so I thought it might be worth asking if there has been any testing of this function yet...
     
  2. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    I haven't tested it recently but it should be working. For Geoff's decoders there is no feedback iirc so prog track may not work. Do you have a serial connection to the decoder to do some debugging on when it receives a CV write? It could also be a bug in the dcc library used by the decoder. I haven't experimented with them much yet.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  3. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    Yeah I have the serial console connected for the decoder and using telnet to send commands to the base. There is no debugging out put from the NmraDcc library by default but I've added in some output to try and get a sense of what is going on. When I start up the decoder it seems to write fresh values to CV7, 8, and 29. The cab address set in the code is 24 so I'm sending commands such as <w 24 41 2> (to change the value of CV41 to 2), but I can find no indication that the CV command is even being received.
     
  4. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    There should be a define somewhere at the top of the sketch to disable CV reset on startup. If you reboot the decoder for any reason the CVs will get lost. Looks like it is DECODER_LOADED.

    Also it looks like the default sketches hardcoded the address as 40 and ignore the CV value for the same. If you modify the sketch to store the address when notifyCVWrite is called and use that stored address in notifyDccAccState you should be able to make it work.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  5. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    Regarding the CV address, CV_To_Store_SET_CV_Address is passed through the Dcc.init processes and then referenced as DccProcState.OpsModeAddressBaseCV within the NmrcDcc library... but it seems to only be referenced once within a section for handling functions and there's some code referencing a FakeOps which I'm not following. The only code I see that actually writes a CV seems to be around line 560 under processDirectOpsOperation() and I've added a block of debug output there which never appears to be called. That function can be called at the very end of processMultiFunctionMessage()

    I did try writing my CVs to cab 40 as well, but still nothing happening. And yes, DECODER_LOADED is defined. I've had to flip it back and forth a few times as I updated my code, however I've also made changes such as for the blinking LEDs where it reads the live value from the CV for the flash rate, so that sort of thing should immediately change without a full reset on the arduino.

    Discovered one issue with my debugs... if you have a function defined for notifyCVWrite() then it does NOT write the new value to eeprom, so I've moved my debug messages directly into the original call and removed my own function definition. I'll have to back-track on some of my testing to make sure nothing else I tried was blocked from updating the CVs by this.

    Ah well, so it's probably not an issue with the base station code. I'm working with Geoff through email as well and hoping something will shake loose. One significant change I had to make was to free up pins 2-3 for I2C communications, so I moved the Dcc interrupt to pin 0(Rx). All of the turnout commands worked fine except there was about a 5-second delay for some reason. Last night I moved it to pin 1(Tx) and suddenly the delay is gone so now my servos respond immediately. I was really hoping this would also clear up the CV problem, but alas it hasn't. Ah well I'll keep poking at it.
     
  6. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    OK so here's an interesting bit of info... Geoff uses JMRI to write his CV values and said there are differences between it and DCC++. Maybe this is causing my issues? Anyway I've been digging deep into NmraDcc.cpp adding a bunch of debugging output and I found something interesting in the processServiceModeOperation() function. Here's some variable values of interest...

    Code:
    processMultiFunctionMessage(41,0,236,40,2)
      CmdMasked = 224
      DccProcState.OpsModeAddressBaseCV = 121
      FakeOpsAddr = 24
      OpsAddr = 41
    Now keep in mind that the accessory address is 40, but the CV cab address is 24 (which is stored at CV121). I am sending the command <w 24 41 2> and received the above output. We can ignore the "0,236" values received, however it seems the first value should be 24, not 41. So the question here is where is the wrong value coming from? The code works for Geoff to set CVs through JMRI so I have to wonder if anything on the base station has been changed recently that might affect the info being received by the decoder?

    I found that if I turn off the test for the cab number in this function then CV41 is in fact being updated to the new value, but of course that means the decoder will respond to CV writes for ANY cab number. At least now I know the commands are being received, they're just not being processed correctly. I'll keep digging in the NmraDcc library to see if I figure out a change that will make this work right.
     
  7. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    So I've been playing with trying to set CVs on the loco and seem to be failing miserably. CV3 is my acceleration rate and CV4 is my deceleration rate. I can set CV3 every time, alternating between 16 and 64 for the value, which makes a noticeable difference in the loco taking off. However when I try to set CV4 (for example -- <w 03 4 32> ) nothing changes. When I drop the throttle the loco instantly stops. Another test was trying to set it to use a predefined speed table. For that I need to set bit 4 of CV29 to 1 -- <b 03 29 4 1>. Again nothing is changing. I tried to change the cab address in CV1, then I tried to set a long address by setting CV17 and CV18 followed by setting bit 5 of CV29, but the loco still responds on 03. I just don't understand why only CV4 seems to be the only one I can set, but I'm wondering if this is related to the issue I'm having on the accessory decoder?
     
  8. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    This is unrelated to the base station and is purely in the decoder sketch. The address check is being done against a #define value in every example I have seen and this is not configured outside of reflashing the Arduino code.

    Jmri and DCC++ are entirely unrelated as well JMRI can talk to multiple base stations using different protocols but all base stations follow NMRA standards when sending commands onto the rails. So unless Geoff has a different version of the sketch that doesn't use a #define I can't see how he is doing it, regardless of the base station type.

    I can send you a decoder that will work but I won't be able to send you anything until early next week (I'll be offline after tomorrow afternoon until the end of the weekend).

    Sent from my ONEPLUS A5010 using Tapatalk
     
  9. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    Yeah I'd be interested in seeing your decoder sketch, couldn't hurt to try something else. However the code I'm looking at sets CV121 and CV122 to hold the value of that #define, with 121 being passed in the init to NmraDcc. After the init, the library does all of its lookups for the cab address from those defined CVs, so if things are working right you could change the cab number by writing new CVs.

    I'm also curious what you think about the issues in trying to program the loco decoder? That is production equipment, there shouldn't be any issues with writing new values to it.
     
  10. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    While the nmradcc library is not referencing the define the handler code in the sketch is. So even if you reset the address CV the sketch will ignore the new address as it has an explicit check for the base address in it.

    I'll post the decoder once I get a chance to do so.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  11. Dan Worth

    Dan Worth TrainBoard Member

    26
    36
    2
    After figuring out that the default pins used for current sense for the Pololu MC33926 Motor Shield would map to analog pins that are inactive when in WiFi mode on the ESP32, I decided to just go ahead an cut all of the jumpers and remap to match the pins define in config.h. That way none of the DCC++32 code would need to be modified.

    I made a diagram of the resulting connections which can be used as anyone sees fit:

    Here is the .pdf version: https://drive.google.com/file/d/1LvALIB0IDxQLHzDqPZ6wbjhZp1uCXX7O/view?usp=sharing

    and the .jpg version: https://drive.google.com/file/d/1pXgEDtQA51tCmkrpwF6tO9P9-yTiFJ8y/view?usp=sharing
     
    Atani likes this.
  12. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    I've been continuing to dig into this issue with writing CVs and I really think there's a problem somewhere. After spending a lot of time adding debug info to the NmraDcc library I decided to load up RB_DCC_Sniffer_v2 (if I remember right that was Rudy's code?) to compare the information I am seeing, and both sets of code seem to show the same issue. Note the NmraDcc lines are showing output from two different sections of code, with the part in the parenthesis showing address, type, command, data1, data2. When I send a function command, 'address' holds the cab number and it appears the rest of the NmraDcc code also expects to see a cab number in the address field when writing a CV. Hope that's clear?

    <w 23 45 56>
    NmrcDcc: 45 236 88 112 87 (45,0,236,44,56)
    Sniffer: Loc 45 CV Write Addr 45 Value 56 Data 101101 11101100 101100 111000

    <w 24 45 56>
    NmraDcc: 45 236 88 112 175 (45,0,236,44,56)
    Sniffer: Loc 45 CV Write Addr 45 Value 56 Data 101101 11101100 101100 111000

    Basically in every write command I try, both sets of code are receiving the same number for both the cab and CV numbers. Remember I said before that on my loco decoder I have only been able to make changes to CV3, and the loco's cab number is still at the default value of 3, which corresponds to the cab number always being read as the CV number. I thought I would try a bit write as well, and I got similar results...

    <b 9 8 7 1>
    Sniffer: Loc 8 CV Bit verify Addr 8 Bit 7=1 Data 1000 11101000 111 11111111

    I checked my code for DCCppESP32 and I currently have v1.1.0 from Feb 16th installed. Not sure if there have been any changes since then that might affect the DCC output? I have also tried accessory, function, throttle, and turnout commands -- all of them work exactly as expected and the debugs confirm the right values are being received for the various parameters. I think this weekend I'll try to get a programming track hooked up and see if there are any differences. I'm guessing most people actually write their CVs on the programming track instead of the main so maybe nobody else has run into this before? I can't quite rule out a hardware problem but it seems strange that only these two particular commands are being affected so it seems much more likely to be a software issue. I'm just not sure what else I can do to try and isolate the problem.
     
  13. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    No changes have gone in that would impact this. I have done programming only on the programming track without issues. There may be a bug in program on main. When I get back home I can take a look at the packets and ensure they are valid but they are virtually identical to DCC++ on the Arduino.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  14. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    OK I'll let you know what I find out when I set up my programming track. I might be able to do a test tonight, I just need to switch the wires from the main over to the other side of the ESP.
     
  15. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    Well a lot to grumble about here. I ran into a problem in that there seems to be no signal going to DCC_SIGNAL_PIN_PROGRAMMING unless I define it as pin 26 (moving the operation pin to another number of course). I'll have to dig into that later, but I DID manage to get it to work. The next thing to groan about is the fact that writing a CV is different between main and prog, so it wasn't really a fair test (I was expecting that both operations use the same function in the code). Well yes, as a matter of fact I CAN write other CVs to my loco when it is on the programming track.

    ... And wow, I just took a peek and the DCCppESP32 code and found the problem... in DCCppProtocol.cpp, line 152...
    Code:
    class WriteCVByteOpsCommand : public DCCPPProtocolCommand {
    public:
      void process(const std::vector<String> arguments) {
        writeOpsCVByte(arguments[1].toInt(),
          arguments[1].toInt(),
          arguments[2].toInt());
      }
    Notice we're writing arguments[1] twice? It has the same thing under the bit write. OK I'm gonna update those two functions and see if I can write on the mainline afterwards.
     
  16. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    Well, that would explain it sending bad packets on main. Oops :) send me a diff or pull request on GitHub and I'll get it merged on Sunday when I am home again.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  17. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    14
    I'm afraid I don't really know git enough to send a pull request, however the changes are easy... in both of the WriteCV***OpsCommand classes you need to change the first argument to zero, so the looks like:

    writeOpsCVBit(arguments[0].toInt(),

    I tested it on my loco, and I've been able to write multiple CVs on the main track now. Looks like it is working! I also flashed the arduino back to my accessory decoder, and while it needs some tweaks the information being read makes a lot more sense now. Whew that was fun!
     
    Atani likes this.
  18. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    Ok great, i'll review it this weekend and get it merged.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  19. Curn

    Curn TrainBoard Member

    752
    500
    32
    How do I set a higher max current threshold or adjust the sensitivity of the current sense?

    My Lilygo T-8 ESP32 board showed up, I made a protoshield for it, and have been testing it out on my layout. Its included 3D antenna gives it enough range to work in my garage, and with an external antenna attached I can probably go down the street. I’m having an issue with a few of my N scale engines that I never had with Arduino DCC++ systems. Some sound decoders are tripping the overload protection, but I know they are not drawing anywhere near an amp. It has also happened with a small engine where I was messing with the PWM of the decoder (kick) trying to get it to crawl. It is occurring with multiple motor boards so I don’t think it is a fault with the current sensors. I can’t clearly see in the code (using the master branch) where this can be adjusted, but I’m pretty sure it’s in MotorBoard.cpp. I’m using a Deeks Robot Motor Shield which should have a 1 amp max, and I’m seeing in the code that looks to be setting the limit at 980 mA for the Arduino Shield case, which seems appropriate. Is there a smoothing factor or signal integration time that might be more appropriate to adjust?

    Thanks,

    Matt
     
  20. Atani

    Atani TrainBoard Member

    1,473
    1,774
    37
    There was a bug with an overflow occurring where the trip level would get set to zero under some circumstances. If you are on master it should be there as long as the file looks like this line:
    https://github.com/atanisoft/DCCppESP32/blob/master/src/MotorBoard.cpp#L31

    If not, I would suggest update to the latest code from master (or even development if you want to try out some new features but be warned it may be unstable).

    As for smoothing of the signal, there isn't any at this time but it should likely be adjusted to do multiple samples over a short period of time rather than the single shot approach that is used today: https://github.com/atanisoft/DCCppESP32/blob/master/src/MotorBoard.cpp#L71

    I haven't seen any issues with it tripping on sound locos or non-sound when I have tested. If you connect a serial cable and capture the data it should give us a bit more of a clue if there is a problem with the calculations or current sense.
     

Share This Page