ESP32 Command Station

Atani Dec 10, 2017

  1. Les B49

    Les B49 TrainBoard Member

    37
    3
    7
    Good clarification - can rule out water shorting it then...

    Pity. I was going to buy whatever you'd got to work.

    ATANI: Can you tell ghruei which brand of ESP32 you use with the Deek-Robot motor shield (is there only one version of this shield?) on your current working setup;
    and can you advise me on which ESP32 (Uno form-factor) you've had working best with the Arduino Rev 3 Motor shield - and any problems you hit with it?
     
  2. Les B49

    Les B49 TrainBoard Member

    37
    3
    7
    How do I eMail you? Is that by clicking on your name and "starting a conversation"?
     
  3. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    There are images of the board on the wiki here. This board can be found on Aliexpress or similar sites.

    That would work fine.
     
  4. ghruei

    ghruei TrainBoard Member

    33
    6
    2
    Ok the board shown in the wiki is the board I have the "WeMos" Uno ESP32. This really confusing. I do not understand if it works for Atani it should work for us. I am wondering why it is the same issue no matter what ESP32 or motorshield is used.

    I have gone back to the ESP32 Development board(same as in the wiki) and the Motorshield and added a 3.3v supply. But again same problem.

    I am going to have have another think about this.
     
  5. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    Ok, so if you have the same board and use the same motor shield you should be able to use the defaults in the config files with only a jumper added to bridge A0/A1 to the respective inputs since A0 and A1 are not usable pins on this board (why they picked GPIO 0 and 4 for these pins I don't know)

    How are you powering the ESP32? I have a dedicated 7.5VDC power supply for the ESP32 using the barrel connector on the PCB. I also have a Nextion and OLED display connected and powered via the 5V pin on the ESP32 (only because I don't have a dedicated 5VDC supply hooked up currently).

    However, I'm actively moving towards a TTGO T1 board with a custom PCB instead of having multiple different boards. Once I have the PCBs ready (and tested) I'll be able to share the files to create them.
     
  6. ghruei

    ghruei TrainBoard Member

    33
    6
    2
    I have the jumpers in place. Though I did not use a separate power supply. I will add that tomorrow and test it again.
    I would like to see if I can get this to work. I am really wanting to know what is causing it to fail at the moment.

    The custom PCB sounds interesting.
     
    Atani likes this.
  7. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    For reference here is a pic of the CS on my layout currently, it has a few features enabled outside of the normal setup since I'm testing for the next release (and the version number is wrong on it still).

    Once I have the next release fully tested I'll be cleaning this up a bit, too many jumper wires .

    But in this pic we have the WeMos D-duino-32, Deek-Robot motor shield, OLED, Nextion and LCC (CAN) all running off the "wall wart" power supply. To the left of the power strip is an LCC PowerPoint with an RJ45 cable to the CS and the other running behind the layout to my computer for an LCC Buffer (PC CAN bus adapter). To the left of the PowerPoint I have a 15VDC (track), 12VDC (LED), and 5VDC (misc) power supplies. [​IMG]

    Sent from my ONEPLUS A5010 using Tapatalk
     
    Lormedy likes this.
  8. ghruei

    ghruei TrainBoard Member

    33
    6
    2
    Ok. I have now added a 7.5v supply for the ESP32 UNO board. Rechecked the two jumpers powered up and the same issue.
    I am wondering if there is now an issue in the code as I am not using anything extra other than the two boards as opposed to Atani which has all the bells and whistles in his setup shown in the photo. I am going to see if I can download an earlier version of the code, before the Nextion and LCC was added and see if that makes any difference.

    If that does not work then I will have to write some code just to do the dcc part and nothing else, as we know that the motorshield turns on so it must be some issue with the DCC PWN pins for the both the prog and main.

    I was also having a look through this thread https://www.trainboard.com/highball...ed-–-heltec-wifi-kit-32-dcc-questions.122660/ for clues as the are using a different ESP32 board. It appears they got it to work in the end.
     
  9. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    Nextion and LCC are off by default and unless you enable them they won't make any difference.

    I can't think of anything that would prevent the CS code from working in a generic setup, I've tested it quite extensively with multiple ESP32 boards as have others. It is just a bit puzzling why you are having issues, I'm trying to figure out what might be different here.
     
  10. ghruei

    ghruei TrainBoard Member

    33
    6
    2
    Yes I am just using all the defaults at the moment to try and keep things as simple. It is the fact the LES B49 and me are using different ESP32 boards but having the same issue which I am sure should point to something. The other point is that the motorshield does work fine with the Arudino UNO setup that was what made me wonder if something weird with the code now.

    Does the current feedback from PINS A0/A1 have any impact on the DCC signal?
     
  11. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    Not in the slightest. What it will have an impact on is if the signal is ON or OFF. With the Uno board using ADC2 pins (0, 4) under A0 and A1 they are not usable for analog input when WiFi is active (which is always the case with the CS). That won't have any impact on if the code is generating a HIGH/LOW signal on the SIGNAL/DIR pin though.

    Can you post the serial console output from the ESP32 when you have only one light on? For this can you adjust this line to have ARDUHAL_LOG_LEVEL_VERBOSE instead of ARDUHAL_LOG_LEVEL_INFO?

    This will enable a lot of additional log output on the serial console for the underlying arduino-esp32 code as well as a number of diagnostic logging that normally is OFF for the CS code.
     
  12. ghruei

    ghruei TrainBoard Member

    33
    6
    2
    Log file below. Not sure if it really shows anything useful.

    [WiFiInterface.cpp:161] begin(): Waiting for WiFi to connect
    [D][WiFiGeneric.cpp:342] _eventCallback(): Event: 7 - STA_GOT_IP
    [D][WiFiGeneric.cpp:385] _eventCallback(): STA IP: 192.168.5.30, MASK: 255.255.255.0, GW: 192.168.5.1
    [WiFiInterface.cpp:123] operator()(): WiFi IP: 192.168.5.30
    [WiFiInterface.cpp:128] operator()(): Adding dccpp.tcp service to mDNS advertiser
    [WiFiInterface.cpp:189] begin(): WiFi connected!
    [D][WiFiGeneric.cpp:342] _eventCallback(): Event: 7 - STA_GOT_IP
    [D][WiFiGeneric.cpp:385] _eventCallback(): STA IP: 192.168.5.30, MASK: 255.255.255.0, GW: 192.168.5.1
    [MotorBoard.cpp:42] GenericMotorBoard(): [OPS] Configuring motor board [ADC1 Channel: 0, currentLimit: 3584, enablePin: 25]
    [MotorBoard.cpp:42] GenericMotorBoard(): [PROG] Configuring motor board [ADC1 Channel: 3, currentLimit: 614, enablePin: 23]
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command t
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command f
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command C
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command a
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command 1
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command 0
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command c
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command s
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command R
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command W
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command B
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command w
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command b
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command e
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command E
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command Z
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command T
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command S
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command RS
    [V][DCCppProtocol.cpp:302] registerCommand(): Registering interface command F
    [V][Outputs.cpp:99] init(): Initializing outputs
    [ConfigurationManager.cpp:127] load(): Loading /DCCppESP32/outputs.json
    [V][Outputs.cpp:103] init(): Found 0 outputs
    [V][Turnouts.cpp:84] init(): Initializing turnout list
    [ConfigurationManager.cpp:127] load(): Loading /DCCppESP32/turnouts.json
    [V][Turnouts.cpp:88] init(): Found 0 turnouts
    [V][Sensors.cpp:84] init(): Initializing sensors list
    [ConfigurationManager.cpp:127] load(): Loading /DCCppESP32/sensors.json
    [V][Sensors.cpp:88] init(): Found 0 sensors
    [V][RemoteSensors.cpp:98] init(): Scanning for RemoteSensors DISABLED, remote sensors will only be created after reporting state
    [ConfigurationManager.cpp:127] load(): Loading /DCCppESP32/roster.json
    [V][LocomotiveManager.cpp:210] init(): Found 0 RosterEntries
    [ConfigurationManager.cpp:127] load(): Loading /DCCppESP32/consists.json
    [V][LocomotiveManager.cpp:220] init(): Found 0 Consists
    [DCCppESP32.cpp:392] setup(): DCC++ESP32 READY!
    [MotorBoard.cpp:46] powerOn(): [OPS] Enabling DCC Signal
    [MotorBoard.cpp:58] powerOff(): [OPS] Disabling DCC Signal
    [MotorBoard.cpp:46] powerOn(): [PROG] Enabling DCC Signal
    [MotorBoard.cpp:58] powerOff(): [PROG] Disabling DCC Signal
     
  13. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    Something is definitely going wrong as there are missing log entries like this one. How are you turning on the track power? Is it via JMRI or the web interface? If via the web interface, are you clicking the power button for the individual outputs or are you clicking on the overall power toggle below the table?

    If you are clicking on a single line in the table that will only set the ENABLE pin to HIGH and not start the DCC signal (which is a bug!). If you click on the overall power toggle below the table it will turn on the DCC signal and enable the OPS output. PROG should not be enabled by default and will only be energized when the PROG track is actively being used.

    I think the web interface may need a small tweak to drop the power icon from the PROG track so it doesn't unintentionally become energized when it shouldn't be. I'll also fix the bug where enabling OPS doesn't enable the DCC signal.

    EDIT: the development branch has an update which may fix your issue...
     
    Last edited: May 1, 2019
  14. ghruei

    ghruei TrainBoard Member

    33
    6
    2
    Ahh yes we finally have both LED's Working and the logfile

    [MotorBoard.cpp:176] powerOnAll(): Enabling DCC Signal for all boards
    [MotorBoard.cpp:46] powerOn(): [OPS] Enabling DCC Signal
    [DCCSignalGenerator.cpp:151] startSignal(): [OPS] Adding reset packet (25 repeats) to packet queue[V][DCCSignalGenerator.cpp:70] loadPacket(): [OPS] queue: 0 / 512
    [DCCSignalGenerator.cpp:154] startSignal(): [OPS] Adding idle packet to packet queue
    [V][DCCSignalGenerator.cpp:70] loadPacket(): [OPS] queue: 1 / 511
    [DCCSignalGenerator_Timer.cpp:55] enable(): [OPS] Configuring Timer(1) for generating DCC Signal
    [DCCSignalGenerator_Timer.cpp:57] enable(): [OPS] Attaching interrupt handler to Timer(1)[DCCSignalGenerator_Timer.cpp:63] enable(): [OPS] Configuring alarm on Timer(1) to 58us
    [DCCSignalGenerator_Timer.cpp:65] enable(): [OPS] Setting load on Timer(1) to zero[DCCSignalGenerator_Timer.cpp:68] enable(): [OPS] Enabling alarm on Timer(1)

    I had been using the web interface. I cannot get the decoder recognised and the system then crashed. So tomorrow I start looking at this.
    However looks like finally getting some where. Thanks for the help.
     
  15. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    Ok now that the lights are right the decoder should work as you expect as long as the track power outputs show an AC voltage about 1V lower than the track power supply.

    Sent from my ONEPLUS A5010 using Tapatalk
     
  16. Les B49

    Les B49 TrainBoard Member

    37
    3
    7
    Hmmm...

    I hadn't picked up that power had to be started through the lower button. I've now got both lights on and I can acquire my "loco" and drive it. Thanks so much for that clarification.

    I am now finding though that the response time after making a speed change is very slow - like 5 or 6 seconds before the loco starts to alter its speed. Even the Emergency Stop doesn't kick in for that sort of time. It would be impossible to control an engine to slow to a nice stop in a station, say. Any thoughts?

    There is no such delay when using DCC++ through the Mega2560 (direct link, not wi-fi). And neither is there a delay using the ESP32 to run an Arduino Sketch I've produced which just switches sets of points to set up different routes on my track, so the quality of the wi-fi signal wouldn't appear to be the issue.)

    Les

    PS I've sent you a "conversation" message.
     
  17. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    This is an area that I'm working on resolving the performance issues. Part of the problem is due to the requests not reaching the webserver code in a timely manner. I've reproduced this outside of the web interface throttle and I'm working on some fixes for this to improve it. I'm looking at reintroducing a persistent connection from the web throttle to the CS, this was problematic before but there may be a few fixes if this is internally used instead. This is partially the direction I'm looking at taking with the standalone Nextion throttle, which needs a lot more data than what the web throttle needs today.
     
  18. crusader27529

    crusader27529 TrainBoard Member

    247
    167
    11
    I'd like to ask some questions about the basic config and architecture of how this all fits together.

    I'm interested in your ESP-32 primarily because of 2 things.......first, it's currently being developed (thank you, Mike), and second, it's a very high performance platform with dual cores(maybe more in some future time).

    Obviously, it supports WiFi, but when I compare to what's connected to what compared to DCC++ with JMRI and an external router, exactly what your design can be configured to do is far from simple.

    How does it connect to JMRI? I assume with a USB cable, but you know about assumptions......does it use an external router, or only the on-board WiFi? Can it use both?

    One of the things I've done with DCC++ was to strip out all the control and sense stuff to free-up memory so I can add room to control 32 or so locos, and support for multiple power districts. Since JMRI doesn't support multiple power districts, I've added that functionality with automatic power recycling if a short is detected, which is absolutely required when having multiple power districts. My direction is for controlling club layouts from small to reasonably large, for minimal cost. I use RS-485 modules simply to extend the distances that the individual enable signals and DCC waveform can be used reliably. I've tested the design with 100' cabling(standard Cat-5) without any issues.

    The one issue that prevents going beyond that distance is the analog voltage signal for overcurrent detection, but I've 'solved' that issue in a different way. In the environment that I'm working toward, actual current values for each power district isn't important, just detection beyond a threshold is. My design uses a remote connection board that converts the RS-485 back to TTL levels, and inverts that signal as needed by the IBT-2 motor drivers that I use. I wanted to add circuit breakers to the design because commercial stuff is just too expensive, and I decided that if the remote connector boards could sense the current, they could do the polarity reversal that's required when a train crosses a block boundary that requires such a reversal. In order to do that, I need to know the allowable current for the connected block so I can decide when there's a short, which implies that I have some way to specify how much current a block can be allowed to use.

    When I figured out how to do that, I quickly realized that the reversing power district can just as easily be configured as a programmable power district, so I added 2 pins that the now extra Arduino NANO can read at boot to determine the current allowed, and if a reversing short is applicable. I also decided that trying to generate an analog signal back to the DCC++ system so it could determine if there was an overcurrentwas superflous, and instead of trying to simulate low voltage level proportional to the actual current, I'd just send a logic 0 or 1, and that would be interpreted as a low current, or an excessive current by the analog sense pins on the Ardiono.

    I finally decided that the DCC++ arduino doesn't need to actually sense the current(except for the program track), so the remote connector board with the Arduino could automatically do the power cycle as required, and/or the polarity reversal if that's what it was configured for. The same code would do both based on a jumper and the current limit jumpers that I already had as part of the design.

    So, I need to understand what you configuration can do(obviously it has the necessary HP do do what I need) and how to use it in my design. My work is completely open source, and setup for minimal cost and DIY, and should be implements as a motherboard when the ESP32 would attach. My current Arduino design can implement a complete 4 power district system for about $80, depending in EBAY prices. Except for the basic PCBs, everything else is EBAY sourced.

    Assuming I can figure out how your system works, and if I can figure out how to use GitHub, I'm offering everything I do(hopefully with your code base) to you and everyone who wants it. My work is commercial quality, and is NOT hobby level stuff. One of my other projects uses/used FreeRTOS for an Arduino, whick was trick to make do what I needed, timeing wise.
     
  19. Atani

    Atani TrainBoard Member

    1,468
    1,754
    37
    Actually USB is not used for JMRI (and can't be). It is only accessible via WiFi. In JMRI it would be listed as Ethernet (or network?).

    On the ESP32 side we don't have the memory limitations that the AVR hardware does. The ESP32 side also doesn't have a specific hard limit of number of "active" locomotives and can natively support up to six power districts (with current sense, one of which is for PROG).

    This is currently supported and it will restore power after ~10sec or log a warning if the short exists still.

    This is very similar to how the LCC approach is done. With LCC the CAN physical spec declares that a CAT-5 cable has two wires (one pair) that carries an A/B signal pair (like RS-485) that can be used to rebuild the DCC signal at remote locations (boosters).

    Yes, that is the general nature of TTL signals at length of wire, they degrade to the point of non-usable. The LCC CAN physical spec sets a limit of 100ft between "nodes" with a general recommendation of closer to 20ft (I believe, I'd have to look at the spec again).

    With the limitations of the DCC++ text based protocol it doesn't need to know or support it. In general though most layouts will have one DCC signal (OPS) with boosters that do not report back to JMRI. However, DCC++ESP32 can report all registered districts back to JMRI and JMRI will react accordingly; if one district is not ON though the behavior in JMRI is a bit erratic.

    Correct and a further point, the CS doesn't need to care about the actual power district state itself generally. The default setup for the CS is to generate two DCC signals (OPS and PROG) and leave the extra districts for standalone devices which can manage those itself (commercial or DIY). But the code today supports it in the same manner as I used in the AVR version of the code that I was maintaining previously.

    Sounds like a good design really. I'm leaning towards the LCC side where the booster will broadcast a message saying it is over current or returns to normal current etc. With this approach JMRI will listen for these messages and display them accordingly.

    Exactly, the CS doesn't really care other than on its "OPS" output and the "PROG" output what the current draw really is. For secondary power districts/reversers/boosters/etc can (and should) operate autonomously.

    Virtually all aspects are configurable today to do what you are after.

    That is a very attractive price. I'm working on a custom PCB myself which will use a handful of "off-the-shelf" components which I'll include as part of a kit (or assembled/tested). My current price target is around $20 for the CS with OLED/LCD display or a bit less for a booster (can also have OLED). The added benefit of what I'm looking at producing is single PCB with built in LCC support, so you would just need to connect the two devices with a CAT-5 cable and connect power supplies for outputs. I'm looking at having the PCBs made up soon for testing and sharing soon thereafter.
     
  20. crusader27529

    crusader27529 TrainBoard Member

    247
    167
    11
    I still don't quite understand how you connect/communicate to JMRI(which is communicating wirelssly to the wireless controllers using smart phones).

    I'm not so sure that I want to use any sophisticated protocols to link the power districts(like LCC or any such derrivitives) as the target audience (DCC DIY people) have enough difficulty with using DCC in general already, that adding LCC and the associated wiring and termination issues would prevent that part of the community from adopting the system. My implementation of RS-485 is exclusively as a dumb, one-way signal extender, with indicators at both ends so the user can SEE if the connection is completed. The CAT-5 cabling I use only has 4 connections(2 signals and ground for each) which allows duplicating the connections in the cables to increase reliability, and again to keep it technically simple.

    I'm leaning to not support the program track except in really simplistic systems, simply because doing the programming on a separate CS makes more sense to me, since operating the layout would cause conflicts to some degree. In my club environment, locos would be added to the roster from the maintenance area of the layout(and that file would be imported to the main CS). Operations where programming on the main would be used would be limited by the yard master who would configure any MU configs before turning over that set to an engineer. That's the theory anyway.

    I want/need lots of power districts because in my config, a reverse loop section 'uses' a power district, so I'd like the capacity for as many as I can get. My system natively supports 8 power districts(with or without a program track) and has the ability to tie 2 systems together to actually support 16 power districts. All this is modular, amd can be expanded as required by just adding parts and/or using jumpers.

    I stripped out all that extraneous stuff from DCC++ for 2 reasons......I need the extra memory to run 32 locos, plus in a club environment, signaling/detection and controlling turnouts ought to be run from another system, probably based on LocoNET or some other network. That also would allow a dispatcher to control the layout movements separate from the primary CS used to actually run trains directly.

    If JMRI is 'running' the layout, why do you use/need OLED displays on your system? How do multiple ESP32 modules communicate? I guess that I'd like to see a block diagram of how it all works together. Maybe we could continue this technical discussion with private messages, or by email or Skype.
     

Share This Page