ESP32 Command Station

Atani Dec 10, 2017

  1. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    All right, I was finally able to get set up good enough to get some info, but I think there is nothing here of any use. It appears that the ESP starts up fairly normally, and then there's absolutely nothing after that I connected and turned track power on and off several times, verified the state from the output on the screen, and even restarted the ESP a couple times, but there is nothing here except the boot process. Is there a config flag I need to set somewhere to turn on the serial output?


    ets Jun 8 2016 00:22:57

    rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
    flash read err, 1000
    ets_main.c 371
    ets Jun 8 2016 00:22:57

    rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:812
    load:0x40078000,len:0
    load:0x40078000,len:11392
    entry 0x40078a9c
     
    Scott Eric Catalano likes this.
  2. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    Ok the serial output is not complete. I am guessing you are using Arduino ide and not platformio ide? If you are using platformio it should automatically enable diagnostic output on serial. If you are using Arduino ide then you may need to check the menus for core debug level settings. Set that to the highest level and it will expand the console output a lot.

    Sent from my ONEPLUS A5010 using Tapatalk
     
    Scott Eric Catalano likes this.
  3. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    I don't think I have that feature in the arduino IDE. Would you be able to generate and send me the bin files for a build? There should be an *.ino.bin and a *.ino.partitions.bin, then I can just write them straight from the command line.
     
    Scott Eric Catalano likes this.
  4. Jimbo20

    Jimbo20 TrainBoard Member

    274
    178
    11
    I can do this for the esp8266 in the arduino IDE; I assume its the same on the 32? (you also need to turn on the debug port - the next item up on that same menu)
     

    Attached Files:

    Scott Eric Catalano likes this.
  5. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    I would rather not send the binaries as they would contain the AP info and you would not be able to customize them unfortunately. however, you can turn on the debugging in the Arduino IDE as I show below.

    It is very similar.

    In the attached photo I have opened the menu to show which it is. Select the Verbose setting and recompile. You will likely need to set your board type to "ESP32 Dev Module" for this menu option to be available.

    I am going to adjust the code in an upcoming release to not require this debug level as it also enables some of the underlying Arduino ESP32 logging that may not be as useful.
     

    Attached Files:

    Scott Eric Catalano likes this.
  6. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    Ah I got it... that seems to be available *only* if you choose the right board module. Working on it now...
     
    Scott Eric Catalano and Atani like this.
  7. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    Well that was easy enough (glad something finally went easy this week). And the overcurrent warnings at the bottom just keep repeating...

    Code:
    [I][DCCppESP32.ino:164] setup(): DCC++ ESP starting up
    [I][WiFiInterface.cpp:53] begin(): Connecting to WiFi: wifitrain
    [D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
    [I][WiFiInterface.cpp:55] begin(): Waiting for WiFi to connect
    [D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
    [W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 2 - AUTH_EXPIRE
    [D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
    [D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
    [I][MotorBoard.cpp:37] GenericMotorBoard(): [MAIN] Configuring motor board [ADC1 Channel: 0, currentLimit: 0, enablePin: 25]
    [I][MotorBoard.cpp:37] GenericMotorBoard(): [PROG] Configuring motor board [ADC1 Channel: 3, currentLimit: 0, enablePin: 16]
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command t
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command f
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command a
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command 1
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command 0
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command c
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command s
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command R
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command W
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command B
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command w
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command b
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command e
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command E
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command Z
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command T
    [V][DCCppProtocol.cpp:262] registerCommand(): Registering interface command S
    [I][Outputs.cpp:100] init(): Initializing outputs
    [E][Preferences.cpp:330] getUShort(): nvs_get_u16 fail: OutputCount NOT_FOUND
    [I][Outputs.cpp:102] init(): Found 0 outputs
    [I][Turnouts.cpp:78] init(): Initializing turnout list
    [E][Preferences.cpp:330] getUShort(): nvs_get_u16 fail: TurnoutCount NOT_FOUND
    [I][Turnouts.cpp:80] init(): Found 0 turnouts
    [I][Sensors.cpp:81] init(): Initializing sensors list
    [E][Preferences.cpp:330] getUShort(): nvs_get_u16 fail: SensorCount NOT_FOUND
    [I][Sensors.cpp:83] init(): Found 0 sensors
    [I][SignalGenerator.cpp:217] startSignal(): [OPS] Adding reset packet to packet queue
    [I][SignalGenerator.cpp:219] startSignal(): [OPS] Adding idle packet to packet queue
    [I][SignalGenerator.cpp:222] startSignal(): [OPS] Configuring Timer(0) for generating DCC Signal (Full Wave)
    [I][SignalGenerator.cpp:224] startSignal(): [OPS] Attaching interrupt handler to Timer(0)
    [I][SignalGenerator.cpp:226] startSignal(): [OPS] Configuring alarm on Timer(0) to 116us
    [I][SignalGenerator.cpp:228] startSignal(): [OPS] Setting load on Timer(0) to zero
    [I][SignalGenerator.cpp:231] startSignal(): [OPS] Configuring Timer(1) for generating DCC Signal (Half Wave)
    [I][SignalGenerator.cpp:233] startSignal(): [OPS] Attaching interrupt handler to Timer(1)
    [I][SignalGenerator.cpp:235] startSignal(): [OPS] Configuring alarm on Timer(1) to 58us
    [I][SignalGenerator.cpp:237] startSignal(): [OPS] Setting load on Timer(1) to zero
    [I][SignalGenerator.cpp:240] startSignal(): [OPS] Enabling alarm on Timer(0)
    [I][SignalGenerator.cpp:242] startSignal(): [OPS] Enabling alarm on Timer(1)
    [I][SignalGenerator.cpp:217] startSignal(): [PROG] Adding reset packet to packet queue
    [I][SignalGenerator.cpp:219] startSignal(): [PROG] Adding idle packet to packet queue
    [I][SignalGenerator.cpp:222] startSignal(): [PROG] Configuring Timer(2) for generating DCC Signal (Full Wave)
    [I][SignalGenerator.cpp:224] startSignal(): [PROG] Attaching interrupt handler to Timer(2)
    [I][SignalGenerator.cpp:226] startSignal(): [PROG] Configuring alarm on Timer(2) to 116us
    [I][SignalGenerator.cpp:228] startSignal(): [PROG] Setting load on Timer(2) to zero
    [I][SignalGenerator.cpp:231] startSignal(): [PROG] Configuring Timer(3) for generating DCC Signal (Half Wave)
    [I][SignalGenerator.cpp:233] startSignal(): [PROG] Attaching interrupt handler to Timer(3)
    [I][SignalGenerator.cpp:235] startSignal(): [PROG] Configuring alarm on Timer(3) to 58us
    [I][SignalGenerator.cpp:237] startSignal(): [PROG] Setting load on Timer(3) to zero
    [I][SignalGenerator.cpp:240] startSignal(): [PROG] Enabling alarm on Timer(2)
    [I][SignalGenerator.cpp:242] startSignal(): [PROG] Enabling alarm on Timer(3)
    [I][DCCppESP32.ino:192] setup(): DCC++ READY!
    
    [W][AsyncTCP.cpp:539] _poll(): rx timeout 4
    [W][AsyncTCP.cpp:539] _poll(): rx timeout 4
    
    [I][MotorBoard.cpp:132] powerOnAll(): Enabling DCC Signal for all boards
    [I][MotorBoard.cpp:41] powerOn(): [MAIN] Enabling DCC Signal
    [I][MotorBoard.cpp:41] powerOn(): [PROG] Enabling DCC Signal
    [I][MotorBoard.cpp:77] check(): [MAIN] Overcurrent detected 0.00 mA
    [I][MotorBoard.cpp:50] powerOff(): [MAIN] Disabling DCC Signal
    [I][MotorBoard.cpp:77] check(): [PROG] Overcurrent detected 0.00 mA
    [I][MotorBoard.cpp:50] powerOff(): [PROG] Disabling DCC Signal
    [I][MotorBoard.cpp:84] check(): [MAIN] Overcurrent persists (250 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [PROG] Overcurrent persists (250 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [MAIN] Overcurrent persists (500 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [PROG] Overcurrent persists (500 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [MAIN] Overcurrent persists (750 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [PROG] Overcurrent persists (750 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [MAIN] Overcurrent persists (1000 ms) 0.00 mA
    [I][MotorBoard.cpp:84] check(): [PROG] Overcurrent persists (1000 ms) 0.00 mA
    
    Ah... finally figured out how to mark a code block on this site.

    Oh one more thing -- I just tried grounding out SVN, the current-sense line for the programming track, and it still shows PROG is faulting. So at least the error isn't due to the line floating.
     
    Last edited: Feb 3, 2018
    Scott Eric Catalano likes this.
  8. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    This is why it is constantly going to the Fault state. The calculated current limit is not correct. It should look something like this:
    Code:
    [I][MotorBoard.cpp:37] GenericMotorBoard(): [MAIN] Configuring motor board [ADC1 Channel: 0, currentLimit: 1960, enablePin: 25]
    [I][MotorBoard.cpp:37] GenericMotorBoard(): [PROG] Configuring motor board [ADC1 Channel: 3, currentLimit: 1960, enablePin: 23]
    
    What do you have in MotorBoard.cpp in the registerBoard method? It looks like the third and fourth parameter to GenericMotorBoard() are not correct.

    EDIT: looks like it is a bug with BTS7960B_5A / BTS7960B_10A defines. I am looking for a solution.
     
    Scott Eric Catalano likes this.
  9. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    Hey is it just me, or should there be a variable for the max current in the definition of registerBoard() ? I'm not familiar with methods so I don't know if that first line should include all the same parameters.
     
    Scott Eric Catalano likes this.
  10. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    I just pushed to the s88 branch the fix for the BTS7960 boards in the overcurrent detection. Seems the ESP32 was overflowing, not sure where or how but it was. If you pull the latest code from that branch it should work. This branch will be merged to master and a new version released later this weekend after I complete some more testing.

    The third parameter to GenericMotorBoard() is the trigger current in mA, the fourth is the max mA that the motor board supports. From these values the trigger current is calculated. For the programming track the max current for the board is used to calculate what a 60mA pulse would show up as when the DCC decoder responds to a CV read/write.
     
    Scott Eric Catalano likes this.
  11. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    All right, we're looking better here, no errors showing. It's not having any problems with applying power to the track, but I am just getting a straight DC voltage on the tracks rather than AC. I need to re-check my wiring going into the h-bridge, might have something crossed (I put this big one in place at the same time I started testing the newer code so I haven't actually had it working yet), but unfortunately I'm out of time again. If I don't get another chance to poke at it today then I will get back on it tomorrow.
     
    Scott Eric Catalano and Atani like this.
  12. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    Straight DC doesn't sound right. It sounds like the transistor is not inverting the signal pin correctly. But it is progress !

    Sent from my ONEPLUS A5010 using Tapatalk
     
    Scott Eric Catalano likes this.
  13. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    Well that was surprising... turns out the PWM jumper wire from the ESP to the transistor was bad. Must have pulled too hard on it at some point or bent it funny. That bridge test script above that I wrote really comes in handy for testing with the multimeter when you don't have a scope. :)

    OK so I reloaded the new code, and now I'm getting the same ~1.8Vac that I was measuring with the old code and the 2A bridge (the meter claims 'true RMS' but the meter also only cost $12). I also noticed my meter will measure frequency, and it looks like I have about a 7.5kHz wave across the tracks... does that sound right? I also tested shorting the tracks and power is cut within about 1/2 second, and when I remove the short power comes back up in about 1-2 seconds. Next step is to wire up a light bulb so I can pull a decent amount of current and see how the meter reading compares to the ESP's display. Unfortunately that'll have to wait until tomorrow, we're off to a friend's house for the evening. Anything else you want me to check when I get back to it? I don't have any decoders yet, but have all the components now, so the next step for me will be building a quick turnout decoder to work with the servo board, which should show me if the base station is working properly.
     
    Scott Eric Catalano likes this.
  14. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    That sounds about right. It should be a square wave around 8khz. The exact timing is dependent on the packets being sent so it will fluctuate a bit.

    Glad that you were able to narrow down the issue with the circuit. I am also very glad that the cut off was fast. That means the analog read from the motor board is working. It should be around 250ms or less for cut off. The check frequency should be around that or faster.

    Now it sounds like you are about ready to put a train on your dcc enabled track!

    Sent from my ONEPLUS A5010 using Tapatalk
     
    Scott Eric Catalano likes this.
  15. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    For your decoder board.. if you have any issues let me know and I can try and help. I am also working on a similar setup for my layout and will have the code for it up in GitHub once I get time to test everything. I need to rewire my power supply cored ad I moved it and broke the ground wire on accident.. oops...

    Sent from my ONEPLUS A5010 using Tapatalk
     
    Scott Eric Catalano and wvgca like this.
  16. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    For the turnout decoder I'm planning on using an ATtiny85. I have some nice little boards with a usb programming port built in, and I think I really only need the three wires for the servo controller and one wire to read the DCC signal from the track. I've seen a few examples of decoding DCC on this board so it shouldn't be hard to find exactly what I'm looking for.
     
    Scott Eric Catalano likes this.
  17. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    Sounds good. You may want a second pin for the decoder ack as well. I plan on using Arduino promini boards for a few usages on my layout: block detector, turnout decoder, signal system (maybe).

    Sent from my ONEPLUS A5010 using Tapatalk
     
    Scott Eric Catalano and wvgca like this.
  18. Shdwdrgn

    Shdwdrgn TrainBoard Member

    251
    182
    13
    Running some experiments for drawing current with a light bulb, and when I got back to my desk I noticed the following bits in the serial monitor:

    Code:
    [I][MotorBoard.cpp:77] check(): [MAIN] Overcurrent detected 103.35 mA
    [I][MotorBoard.cpp:50] powerOff(): [MAIN] Disabling DCC Signal
    [I][MotorBoard.cpp:92] check(): [MAIN] Overcurrent cleared, 9750 ms before re-enable
    [I][MotorBoard.cpp:92] check(): [MAIN] Overcurrent cleared, 9500 ms before re-enable
    [I][MotorBoard.cpp:92] check(): [MAIN] Overcurrent cleared, 9250 ms before re-enable
    
    ...
    So first off, it's disabling main power at only 103mA? (And I did briefly observe 0.1xx A on the meter.) That's a far cry from the 5A I was expecting. I wish I actually HAD a loco available to drop on the tracks, but last time I was working with this guy a couple weeks ago I had an issue with the esp8266 onboard, and I haven't gotten back to it again.

    Second, it looks to me like it is waiting 10 seconds before re-enabling track power. Is that how long it's supposed to take? Not saying it is good or bad, I guess I was just under the impression that it would be faster than that.

    I also measured track voltage through the regulator setup I have on my test loco, and after it goes through the diode bridge and smoothing capacitor I'm reading 14.9VDC available to drive the motor. The source power pack is at 16.4VDC so that's not too bad of a drop, and leaves plenty of room a regulator to drop the voltage to 12V for the locos that need it.
     
    Scott Eric Catalano likes this.
  19. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    This is likely an overflow condition that I missed. I will do some checking and confirm.

    Yes, 10 sec. This is not configurable at this time but I can add a define for it in Config.h if needed. It should also be noted that this is just a safety check to confirm the short has been cleared before automatically re-enabling the power. In the Arduino base station code once a short appears the power was never turned back on! I think this area could use a bit of a revisit possibly to document and allow configuration of it.

    That isn't too bad really, of the 1.5V loss you are observing most of it is from the diode bridge (1.4V typically). With the DCC decoders something similar could be observed as well. This is part of the reason why the power supply needs to be 2-3V higher than the max power you want the trains to receive. When you also calculate the resistance from the DCC bus and the rails themselves you may see another small drop but it shouldn't be too significant, at least until you have more than 100ft of DCC bus wire and considerably higher lengths of rail. The rail resistance is mostly mitigated by having multiple feeder drops, this also helps with signal degradation from dirty rails etc.
     
    Scott Eric Catalano likes this.
  20. Atani

    Atani TrainBoard Member

    1,466
    1,736
    37
    I can confirm there is an overflow occurring. It seems the ESP32 is discarding the multiplier. I think I have a solution but don't have a test setup currently (still need to repair the wire, need to find my wire crimps today). Here is something you can try in the meantime, in MotorBoard.h replace this function:
    Code:
        float getCurrentDraw() {
            return (float)((_current * _maxMilliAmps) / 4096.0f);
        }
    
    The problem on the ESP32 is the floating point precision leaves a bit to be desired, the original code was doing _maxMilliAmps / 4096.0f which for the BTS7960 comes out to around 10.4980mA per bit in _current. It seems though that the ESP32 overflows with the math and ends up with a value of 1 instead. For other cases it was worse, it came out as zero (like in the over current trigger value)
     
    Scott Eric Catalano likes this.

Share This Page