DCC++ Wi-Fi Receiver Trackside or Onboard

Simon Mitchell Oct 30, 2016

  1. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    The ESP8266 board by itself would be 24mm x 16mmx 3mm. the WeMos D1 mini that I am using is 34.2mm x 25.6mm. So a naked board in HO Gauge would be reasonable. I'll keep you posted once I get to the sound side of things. Kettles create issues!
     
    Scott Eric Catalano likes this.
  2. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    And the code for the DRV8833 has now been done. Found a little library that made life really easy. My emergency stop routine didn't work, and I've now found out that pin D0 doesn't have PWM, so back to the firebox fade routine.

    Next up is lashing up the Hardware and checking that it actually does what the serial monitor suggests. That won't be until Monday as I'm off down the coast tomorrow for a trip on my 100yo small ferry, and off to trainworks at Thirlmere on Sunday.
     
    Scott Eric Catalano and TwinDad like this.
  3. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    Had fun today. I ditched the drv8833 library as it was not working as expected. With direct speed control (no momentum or braking), it was all very simple to do. Motor control is now working as desired, but nowhere near enough grunt. With a 1s 2000MaH LiPo, and a Pololu 9v step up I needed 70/126 to get it to even start turning, with no load. 126/126 was pretty darned slow. I think I need the whole 12v to successfully drive the Mashima 1844. I have some battery management boards which will enable me to onboard balance charge a 3 or 4s LiPo, just need to work out how I want to manage the charging process. On track charging would be the ideal, I'd need a bridge rectifier etc. So it could handle anything from the track...

    Servos are working (front, rear coupler and reverse gear), and I am de-bugging the LEDs. Firebox glow is happening, but directional lighting is behaving rather strangely. I was hoping to have 1 LED running parallel to the onboard LED, so I could have some feedback as the ESP8266 fires up.

    I tried to upload a pic, haven't worked that out yet..

    I've started searching for a JMRI DIY Arduino throttle. Dave Bodinar has a DCC++ throttle, but I don't think JMRI takes DCC++ throttle commands. I'd rather not do The Whole WiThrottle exercise if I can avoid it.
     
    Scott Eric Catalano likes this.
  4. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    So turns out ESP8266 PWM cycle is 0-1023, not 0-255. So I now have a motor running at a decent speed and lots of torque. That was a good find, I was hunting for PWM frequency when I found out about the PWM range. I'll be interested to see how smoothly the motor starts under a load. There is more that could be done here (lots more!) including a whole new PWM sdk per ESP8266_new_pwm

    Next problem is that at full speed (nSpeed 126) one of the coupler servos suddenly go wild. So I may need to look at the sleep mode in servo.h or how the power supply is hooked up.

    And finally, I have directional lighting working, but it is not updating for a change of direction, unless I turn lights off and on again. Probably just need to call functions() as part of parseCommands(), rather than move functions() into the loop(). I'm not sure what difference that would make.
     
    Scott Eric Catalano likes this.
  5. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    So this all works ok now. I did drop functions() into parseCommands() and the directional lighting all works fine now. The motor drive was fine, until it dropped out pin 7, but that was a poor solder joint on a WeMos which I had already soldered the header boards up to. I'll buy a couple more boards as they are so cheap and do a proper install and actually fix my Jubilee 'Victoria' 45565 up so she works at long last!!

    I've uploaded the project to Github

    I dare say there is a lot more work to be done before it could be considered part of the DCC++ resources, but it works well enough for me for now. Next up is a JMRI Hardware Throttle. Thanks for all your help Steve!
     
    Scott Eric Catalano likes this.
  6. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    I would have a look at porting one of Dave B's throttles to ESP. With a view initially to direct control from the throttle (no PC with JMRI).

    You could even do some development in multiple address management.

    ESP will support up to 4 simultaneous connections, which I would look at turning into an add hoc IP address manager, in theory handling as many as you want. For the most part you don't need more than one active connection at a time anyways.

    Thoughts?
     
    Scott Eric Catalano likes this.
  7. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    That would be interesting to do. I want JMRI for the VSD, unless someone ports that across to DCC++...

    I've spent some time today getting JMRI updated and working. It did send commands to the Decoder, but because silly me hadn't set up the throttle response message, it went a bit haywire. but they were connected! I had thought I'd connect up a uno as a standard base station, and it would pr Vide the responses. It could be connected to the track for visiting locos. I'm not cleaning the track tho...

    My idea of having a JMRI connection as a base station is clunky. It shows up in the menu bar up the top of JMRI. That's not workable, as you'd have 20 connections. I'll need to find out more about the networking, as you sagely suggested previously, and see what I can come up with. It could include a throttle with a connection to JMRI and also to individual locos.
     
    Scott Eric Catalano likes this.
  8. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    And there in you've started to hit the bigger networking issues.

    If it were me, I'd start with ESP as a first line solution. Purely because you can 'program' ESP and you're now becoming familiar with with it's protocols.
    Writing an API for JMRI would be a challenge in it's self.
    And what of the latest version of this super chip, the ESP 32? I'm going to start playing around with a few of those anytime soon, it's right at the bleeding edge though at the moment, but promises to be the next big thing if you go look at the specs.

    Maybe a ESP 'network manager router' attached to JMRI with USB/Serial would be a better way to go?
    Kinda where you are thinking of dropping in the UNO right now.
     
    Scott Eric Catalano likes this.
  9. Atani

    Atani TrainBoard Member

    1,473
    1,775
    37
    I just got 10 ESP-01 in the mail yesterday and plan on testing it for a variety of usages. I will have an update to my version of Dave's throttle hopefully this weekend. As well as an update to the BaseStation to use an ESP in place of one of the other networking boards.
     
  10. TwinDad

    TwinDad TrainBoard Member

    1,844
    551
    34
    I'm about *this* close to having a WiThrottle interpreter for the networked version of DCC++ ... just waiting on some hardware in the mail for testing and debugging. The idea is a network-attached DCC++ base station could have (for now) 1 WiThrottle phone directly connected without JMRI or anything else. Later, of course, I'll try to crack the "multiple phone throttles" nut, but baby steps.

    So far it appears to be a pretty lightweight addition (just an alternate parser/interpreter hooked into SerialCommand::process()), so if/when it works you should be able to port it into your decoder pretty easily.

    Just a thought.
     
  11. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    I've already done a lot of the work regarding the use of an ESP as a Base Station network device.
    In fact out of the box with the stock AT firmware you can pretty much get the things talking as WiFi/Serial bridges without too much effort or knowledge. Almost as easy as setting up Dave's Radio/Serial bridges.

    Moving up a level, we can program the modules to use the WebSocket protocol. Which is basically TCP for HTML/Web browsers.

    Then you can write throttle apps for any WiFi connected device that can run a browser.

    Again this is all work I successfully developed last year. Not a lot of interest though :(

    More recently I've been developing a premium Hardware Throttle also using the WebSocket protocol. The ESP is so fast and powerful that a port of the Base Station code might not be out of the question on an ESP32 later this year.

    Oh, and 2, 3 or 4 perhaps HTML throttles at the same time?, no problem :) done that already.
    And they all synchronise with each other.
     
    Last edited: Jan 25, 2017
  12. esfeld

    esfeld TrainBoard Member

    443
    382
    17
    Mark, So glad you clarified this ...... I've been following along, but as an N scaler I was anxiously awaiting the end result.
    Steve F
     
  13. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    The previous iteration of my Decoder was based on the entire base station sketch, with addenda. So it will 'fit' on an ESP8266 It should be pretty easy to update the motorshield page to reflect a suitable motor shield. Apparently not the WeMos one because it's firmware is flakey and it freezes if you look at it sideways. I might try that and see if the DCC++ server makes things happen. Can you guess that I know stuff all about networking!?! It does kinda make sense for the connection to the loco to be at the base station level, as that is the way DCC++ is designed. I.e. WiThrottle=>JMRI=>DCC++=>Decoder (be it wifi or DCC).

    I'm very interested to see an Arduino based WiThrottle, I've not found one as yet in my recent searches.

    Meanwhile I'm doing some more stuff with the Decoder, just moving variables from the code body to declarations, and dropping in an if(debug) for all the Serial.print stuff. I'm hoping that Serial.print is the right way to 'reply' as client.print and interface.print were not happy (undeclared)
     
    Scott Eric Catalano likes this.
  14. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    Client.print. Der. Capitals matter! Not tested yet, Australia Day here, so some attendance outside a pub with a New Orleans style brass band was required. With beers. Very good.

    I just re-looked at this. I'm still at the 'don't understand enough to appreciate' stage. Many others may be in the same camp.

    Hmm. So if they are all swapping the DCC++ packets with each other, isn't that what I want my decoders to be doing (except they will action them)? However even in O gauge, I will probably have 20 locos... There was I thinking it was a free for all once you'd joined the wifi network. Seems not to be the case.

    Meanwhile, you've given me plenty of keywords to go searching the meanings of, thanks!
     
    Scott Eric Catalano likes this.
  15. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    I'll try to explain in simple terms.

    Your decoders will each log on to your router as separate clients.
    At this stage they are nothing more than registered nodes if you like, each with it's own IP address.

    So how do we get one instance of JMRI to talk to upwards of 20 different IP addresses?

    On an ESP acting as a server we can connect up to 4 client nodes at the same time. Using the websocket protocol we can write to all those clients
    simultaneously. Vanilla TCP would be slightly more longer in the programming, but dooable as I understand it.

    Now the ESP was not really pointed towards doing that kind of work, it's a nice little addition for a miniature network application.

    Hence my up to 4 throttles talking to one Base Station Server ESP. They stay in sync because Base Stations replies go out to all at the same time,
    and ESP can handle the multiplexed structure of the 4 incoming streams. So if one throttle sends <t2 456 43 1>, Base Station will send back <T2 43 1> to all connected throttles which then update their status accordingly.

    Your whole project is hinged upon being able to do that for the 20 simultaneous connections of a large layout.

    I'll knock up a little websocket server application that you can run on an ESP. Along with a simple webpage that you can run on up to 4 separate devices simultaneously, you can then see in practice what this type of networking actually involves.

    Basically you can type in some text on a serial monitor connected to the ESP server, then it will instantly appear in every client connection on the other devices.

    Back soon :)
     
  16. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    So here's an iteration of the basic server code that I used to run on the Base Station ESP.

    I've since gone on to much more advanced versions but we don't need all that for this demonstration.

    You will need additional libraries for the Arduino IDE before you can compile this example.
    https://github.com/me-no-dev/ESPAsyncTCP
    https://github.com/me-no-dev/ESPAsyncWebServer

    You fill in your network credentials SSID & Password compile and flash to your ESP.

    All being well, it should log on to your network and sit waiting for WebSocket connections.

    We do that by using a webpage. Simply open the page on any network connected device change the address to suit the server IP and click connect.
    A message should come back from the ESP.

    "Welcome. Server Ready *" Where ' * ' will be a client number.

    Open a serial monitor connected to the ESP, make sure line feed is appended. Type Hello World and hit return.

    That's one client, now repeat up to 4 devices by copying the page to your smartphones, tablets, laptops whatever.

    Then do the Hello World again with up to 4 connections at the same time.

    The webpage looks like below, only change the numbers for the connection address not the rest of the format.

    This simple concept allows me to do my multi throttle connections to a Base Station ESP Server. Why WebSockets? Well browser security doesn't allow for open connections of the ordinary TCP variety. And websockets are real easy to program (thanks to the guys who wrote the libraries), both on ESP and in HTML/Javascript. So the skys the limit, you can write complex cross platform front ends for your throttles or switch controllers what ever. You don't need a PC running more layers of complexity like JMRI. Whats not to like?

    The webpage below could be upgraded with a few extra lines of HTML/Javascript to include a return message input field, then you would see how that little ESP handles the incoming stuff as well. And that is basically all a throttle is, a text sending webpage, simples :).

    Change the extension of the .txt attachment to .html for the webpage. (We can't attach HTML files here)


    CaptureWSM.PNG

    Code:
    #include <ESP8266WiFi.h>
    #include <ESP8266mDNS.h>
    #include <WiFiUdp.h>
    #include <FS.h>
    #include <Hash.h>
    #include <ESPAsyncTCP.h>
    #include <ESPAsyncWebServer.h>
    
    // SKETCH BEGIN
    AsyncWebServer server(80);
    //WiFiServer TcpServer(23);
    WiFiClient Client;
    
    AsyncWebSocket webSocket("/ws");
    
    void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) {
      if (type == WS_EVT_CONNECT) {
        //os_printf("ws[%s][%u] connect\n", server->url(), client->id());
        client->printf("Welcome. Server Ready %u", client->id());
    
      } else if (type == WS_EVT_DATA) {
        for (size_t i = 0; i < len; i++) {
          Serial.write(data[i]);
        }
      }
    }
    //IPAddress ip(101,101,10,10); //Change and uncomment to suit your config for a Static IP
    //IPAddress gateway(101,101,10,1);
    //IPAddress subnet(255,255,255,0);
    
    const char* ssid = "SSID";
    const char* password = "password";
    
    String reply = "";
    
    extern "C" void system_set_os_print(uint8 onoff);
    extern "C" void ets_install_putc1(void* routine);
    
    //Use the internal hardware buffer
    static void _u0_putc(char c) {
      while (((U0S >> USTXC) & 0x7F) == 0x7F);
      U0F = c;
    }
    
    void initSerial() {
      Serial.begin(115200);
      ets_install_putc1((void *) &_u0_putc);
      system_set_os_print(1);
    }
    
    void setup() {
      initSerial();
      WiFi.mode(WIFI_STA);
      //WiFi.config(ip, gateway, subnet);//Uncomment to initiate a static IP
      WiFi.begin(ssid, password);
      if (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.printf("STA: Failed!\n");
        WiFi.disconnect(false);
        delay(1000);
        WiFi.begin(ssid, password);
      }
    
    
      reply.reserve(80);
    
      webSocket.onEvent(onEvent);
      server.addHandler(&webSocket);
    
      server.begin();
      //TcpServer.begin();
    }
    
    void loop() {
    /*
      if (TcpServer.hasClient()) {
        if (!Client || !Client.connected()) {
          if (Client) Client.stop();
          Client = TcpServer.available();
        } else {
          TcpServer.available().stop();
        }
      }
      if (Client && Client.connected() && Client.available()) {
        while (Client.available())
          Serial.write(Client.read());
      }
    */
    
      while (Serial.available()) {
        char inChar = (char)Serial.read();
        reply += inChar;
    
        if (inChar == '\n') {
          webSocket.textAll(reply);////This simple line sends to all clients :)
          //Client.print(reply);
          reply = "";
        }
      }
    }
     

    Attached Files:

  17. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    Thanks Steve, once again, really appreciate the help. Unfortunately I can't experiment with hardware for a while as we have guests over during the weekend and I was playing on the kitchen table (because my workshop is too cluttered!).

    Sorry if I am being an ignorant sod and you've already told me this. I'm still beavering away at using extant methods of getting the data out of JMRI, given the VSD requirement. I noted above the option "DCC++ over TCP"

    So I ferreted around in the DCC++ base station code for the log on to the DCC++ 0ver TCP server log in details, but have not yet found it. I also had a look at Mark (TD's) Github but didn't find it, most likely sheer ignorance.

    Mark, may I ask if I'm barking up the wrong tree? eg does the server only receive packets, but doesn't re-broadcast them? and have you published the Arduino Code?
     
    Scott Eric Catalano likes this.
  18. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    Hi Simon

    I note that no one has bothered to download the code I posted above! Perhaps you can see the sheer mountain one faces in getting people to even try with some basic experiments in WiFi technology. I wonder if most folks baulk at doing something simple like getting their new cellphone connected to their home network? WiFi is everywhere and we'd be hard pushed to do without it in this day and age, yet getting folks away from those cables seems like an impossible task. What's more ironic is that the cost of setting up hardwired links is considerably more expensive these days than doing the same with some cheap wifi modules.

    Anyways back to your 'issue'. Essentially what you need is a server at the output of JMRI, be that done in software or hardware. There are numerous server/client solutions already available for JMRI to cover a comprehensive range of networking scenarios. It maybe that the solution is already there for you. What the server needs to be capable of is accepting a large number of clients (your decoders) so at power up all clients would be pointed to a single IP address (the server). Then as JMRI sends out it's command messages, all connected clients get a copy at the same time.

    My example above is a hardware solution able to do a max of 4 client connections, you need to do the same with 20 plus connections.

    The nearest I've ever got to working with servers is a copy of Apache (file server) running on an old laptop. Once set up properly the principal is just the same. With the machine exposed to a network (the internet) anyone (a client) can access the server by pointing at it's IP address, a single address serves multiple clients.
     
  19. UK Steve

    UK Steve TrainBoard Member

    453
    683
    12
    A little digging reveals...

    A java server app is a relatively simple few lines of code. The multi user chat app here is a good example http://cs.lmu.edu/~ray/notes/javanetexamples/

    If there is nothing that can do that already in the JMRI package, then look to building something like the example as a standalone.

    On youtube /watch?v=uYRTpMGdf1g

    Jmri outputs as one of the clients (just point jmri to the server) and all the decoder clients just log in and listen.

    If that works (no reason why it shouldn't) then look to doing a proper job as a jmri option.

    You only need the server side code, client is done already for both jmri and the esp's
     
    Last edited: Jan 27, 2017
    Scott Eric Catalano likes this.
  20. Simon Mitchell

    Simon Mitchell TrainBoard Member

    113
    105
    7
    Thanks Steve, I'll take a shot at it Monday afternoon.
     
    Scott Eric Catalano likes this.

Share This Page