Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    ESP32 controller over WIFI

    Scheduled Pinned Locked Moved
    Third-party software
    4
    18
    734
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • cjccjjundefined
      cjccjj
      last edited by cjccjj

      Update:
      Thanks for the support from this community, the controller is now working. Here are some pictures.
      It is quite basic but if you want to take a look into the code here it is https://github.com/cjccjj/Duet-ESP32-WIFI-Controller
      20230410_011324.jpg
      20230410_010249.jpg
      20230410_010258.jpg
      20230410_010422.jpg

      Hi, I have a ESP32 board that integrated with a small OLED display and a few buttons. I want to make it a simple wifi controller for my Duet Printer which doesn't have a screen. It will only do simple tasks like start / stop / pause / resume / load upload filament / and maybe a few Gcode macro. After some research I am thinking to make use of the Telnet communication, to send Gcode to Duet board, which seems to be the easiest way. Is Telnet the best way for this? Please if anyone has any suggestion. Thank you!

      stuartofmtundefined o_lampeundefined 2 Replies Last reply Reply Quote 0
      • stuartofmtundefined
        stuartofmt @cjccjj
        last edited by stuartofmt

        @cjccjj

        A quick look at the specs suggests that it has a http client capability. Given that, maybe all you need is to use the http interface.

        cjccjjundefined 1 Reply Last reply Reply Quote 2
        • cjccjjundefined
          cjccjj @stuartofmt
          last edited by

          @stuartofmt Thank you for the reply, yes, it has http client. My question is more about the coding difficulties for my use. The Json response like rr_status looks clear but is depreciated or soon will be. The more powerful Object Model Framework looks very complicated to me, and I didn't find examples that can be direct reference. So, as I just want it to be a simple interface that shows minimal status and send a few Gcode, I wonder if I there is simpler way to write code for this.

          dc42undefined stuartofmtundefined 2 Replies Last reply Reply Quote 0
          • o_lampeundefined
            o_lampe @cjccjj
            last edited by

            @cjccjj How much RAM will be available? In my mind, you'd have to get the file list from Duets SD card, display it on the OLED and then select the file you want to "start". Same for macros...
            You might be able to split the file list into small chunks?

            cjccjjundefined 1 Reply Last reply Reply Quote 0
            • dc42undefined
              dc42 administrators @cjccjj
              last edited by

              @cjccjj the object model response needs a JSON parser, then it is easy to use. You could look for an off-the-shelf JSON parser library, or use the one in PanelDueFirmware at https://github.com/Duet3D/PanelDueFirmware/blob/master/src/Hardware/SerialIo.cpp.

              Duet WiFi hardware designer and firmware engineer
              Please do not ask me for Duet support via PM or email, use the forum
              http://www.escher3d.com, https://miscsolutions.wordpress.com

              cjccjjundefined 1 Reply Last reply Reply Quote 0
              • stuartofmtundefined
                stuartofmt @cjccjj
                last edited by

                @cjccjj said in ESP32 controller over WIFI:

                @stuartofmt The more powerful Object Model Framework looks very complicated to me, and I didn't find examples that can be direct reference.

                The object model is no more complicated than rr_status, just a different structure. If you go the http route I, and many others,can assist. You'd be basically looking at at loop every "n' seconds for status that you are interested in and either a http get of post for sending commands (again depending on what you want).

                As @dc42 pointed out - most of the work would be done by the json parser and, of course, any code relating to the ESP32 interfaces.

                cjccjjundefined 1 Reply Last reply Reply Quote 0
                • cjccjjundefined
                  cjccjj @o_lampe
                  last edited by

                  @o_lampe ESP32 has 520KB of ram, I think it is more then enough to show file list. I will still use PC but it is located in another room than the printer. So the controller is only for quick easy operations that have to be done in front of the printer.

                  1 Reply Last reply Reply Quote 0
                  • cjccjjundefined
                    cjccjj @dc42
                    last edited by

                    @dc42 Thank you, I will definitely look into it. I have been using ArduinoJson library for some simple project, I think it will work.

                    1 Reply Last reply Reply Quote 0
                    • cjccjjundefined
                      cjccjj @stuartofmt
                      last edited by

                      @stuartofmt Thank you for the help and yes interfaces and network would be fine as I have done similar I think what I need is to understand the structure, and a little encouragement. I am just learning these in spare time and found it fun to play with both hardware and software.

                      stuartofmtundefined 1 Reply Last reply Reply Quote 0
                      • stuartofmtundefined
                        stuartofmt @cjccjj
                        last edited by

                        @cjccjj

                        I use python but the main thing to remember with SBC is that you need to include a header in the http calls.

                        Below is some skeletal code to give you the idea

                        def urlCall(url, post):
                                    if post is False:
                                        r = requests.get(url, timeout=timelimit, headers=urlHeaders)
                                    else:
                                        r = requests.post(url, data=post, headers=urlHeaders)
                                   return r
                        

                        I get the header with some code like this:

                        global urlHeaders
                        urlHeaders = {}
                                URL = ('http://' + duet + '/machine/connect?password=' + password) # Connect with password
                                r = urlCall(URL,  False)
                                code = r.status_code
                                if code == 200:
                                    j = json.loads(r.text)
                                    sessionKey = j['sessionKey']
                                    urlHeaders = {'X-Session-Key': sessionKey}
                        

                        thereafter calls can be made like this

                        def getLayer()
                                URL = ('http://' + duet + '/machine/status')
                                r = urlCall(URL,  False)
                                if r.ok:
                                    try:
                                        j = json.loads(r.text)
                                        layer = j['job']['layer']
                                        if layer is None:
                                            layer = -1  
                                        return layer
                                    except Exception as e:
                                        print('Could not get Layer Info')
                                       print(e)
                        
                        
                        cjccjjundefined 1 Reply Last reply Reply Quote 0
                        • cjccjjundefined
                          cjccjj @stuartofmt
                          last edited by cjccjj

                          @stuartofmt Thank you for the reminder and the examples. I think I now have a basic idea how to code the controller, that I send request as follows, parse the responses, add some logic and organize the information on the screen ( I am using a standalone board, /machine/status doesn't work)

                          url = "printer/rr_connect"  #Connect
                          url = "printer/rr_filelist?dir=0:/gcodes/" #List job files
                          url = "printer/rr_gcode?gcode=" #Run Gcode
                          url = "printer/rr_model?key=state&flags=v" #Get object at the key of "state"
                          

                          One thing I am not sure about is how to constantly get the most common status. The "state" key of the object model is not a replacement of "rr_status". It seems to me it will require several http requests to collect status information across the model at different keys (one request per key). It is not very efficient and perhaps will slow down the update routine and performance.

                          stuartofmtundefined dc42undefined 2 Replies Last reply Reply Quote 0
                          • stuartofmtundefined
                            stuartofmt @cjccjj
                            last edited by

                            @cjccjj said in ESP32 controller over WIFI:

                            @stuartofmt
                            One thing I am not sure about is how to constantly get the most common status.

                            Ah - a read one of your earlier posts as if you were using SBC.

                            A couple of comments / suggestions as it relates to standalone and the rr_ calls

                            1. you do not need a session header nor do you need to use rr_connect first (unless you use password).

                            2. Take a look at what you want to do and only implement (in the interest of space) those calls you need.

                            3. rr_model?key=state returns a variety of information that you can parse down into. Note that some of the fields can return null so you do need to test to see if they are populated. What status do you think you want? Given the screen realestate - I'm guessing not a lot.

                            4. In general, you don't need to poll too often and any commands (like pause / resume etc) can just be sent when needed,

                            If you take a look at DuetLapse3.py, I implement both models. Search for ?key= and you will see some useful options
                            https://github.com/stuartofmt/DuetLapse3

                            A skeletal example that may help:

                                    URL = ('http://' + duet + '/rr_model?key=state')
                                        r = urlCall(URL,  False)
                                        if r.ok:
                                                j = json.loads(r.text)
                                                status = j['result']['status']
                                                message = ''
                                                if j['result'].get('messageBox') != None:
                                                    if j['result']['messageBox'].get('message') != None:
                                                        message = j['result']['messageBox']['message']
                                                        seq = j['result']['messageBox']['seq']
                            
                            cjccjjundefined 1 Reply Last reply Reply Quote 0
                            • dc42undefined
                              dc42 administrators @cjccjj
                              last edited by dc42

                              @cjccjj said:

                              One thing I am not sure about is how to constantly get the most common status. The "state" key of the object model is not a replacement of "rr_status". It seems to me it will require several http requests to collect status information across the model at different keys (one request per key).

                              Request the root key with the 'f' flag set. That will return all the frequently-changing status in a single operation.

                              Duet WiFi hardware designer and firmware engineer
                              Please do not ask me for Duet support via PM or email, use the forum
                              http://www.escher3d.com, https://miscsolutions.wordpress.com

                              cjccjjundefined 1 Reply Last reply Reply Quote 0
                              • cjccjjundefined
                                cjccjj @dc42
                                last edited by

                                @dc42 This saved me a lot of time. I looked into DWC and copied the flag set in it. Thank you.

                                1 Reply Last reply Reply Quote 0
                                • cjccjjundefined
                                  cjccjj @stuartofmt
                                  last edited by cjccjj

                                  @stuartofmt Thank you, the comments and suggestions are very helpful.

                                  I was able to get it running over the weekend. It now shows basic printing job information and status, and can also run any Gcode stored on the board SD (thanks to the M98 command).

                                  The coding is pretty sloppy and not very useful to others as I didn't handle the Json response very well it only works on my specific setup, but I uploaded it to https://github.com/cjccjj/Duet-ESP32-WIFI-Controller for my own record and just in case anyone want to take a look.

                                  stuartofmtundefined 1 Reply Last reply Reply Quote 0
                                  • stuartofmtundefined
                                    stuartofmt @cjccjj
                                    last edited by

                                    @cjccjj

                                    Congratulations. I have not used the flags. I could not find any description of their behavior.

                                    If you found something - please let me know.

                                    cjccjjundefined 1 Reply Last reply Reply Quote 0
                                    • cjccjjundefined
                                      cjccjj @stuartofmt
                                      last edited by

                                      @stuartofmt the root key with flags? I just opened DWC with Chrome developer tool, and looked how it updates. It communicates using rr_model?flags=d99fn which is actually explained here https://docs.duet3d.com/User_manual/Reference/Gcodes#m409-query-object-model
                                      31ae330a-8f8e-45ec-82b7-d4befee4328f-image.png

                                      stuartofmtundefined 1 Reply Last reply Reply Quote 0
                                      • stuartofmtundefined
                                        stuartofmt @cjccjj
                                        last edited by stuartofmt

                                        @cjccjj said in ESP32 controller over WIFI:

                                        @stuartofmt
                                        ... which is actually explained here https://docs.duet3d.com/User_manual/Reference/Gcodes#m409-query-object-model

                                        Ah - I never used M409, just http calls and never made the association. Thx.

                                        In any case - I've recently moved to SBC , so cannot test further on standalone. Those flags don't exist according the the OpenAPI reference
                                        https://github.com/Duet3D/DuetSoftwareFramework/blob/v3.4-dev/OpenAPI.yaml
                                        which makes sense in that there is a "big" processor involved 🙂

                                        You should post some images when you can. Others will likely be interested.

                                        1 Reply Last reply Reply Quote 0
                                        • First post
                                          Last post
                                        Unless otherwise noted, all forum content is licensed under CC-BY-SA