ESP32 Lua Wireless Joystick Control

Happy holidays all.

My Christmas project has been to build the LUA Wireless Joystick. Its been a lot of fun learning about the Lua workspace and programming ESP32s.

The code seems to be running, but it doesnt seem to be communicating or sending GCODE through the JSON server.

I have successfully run the Joystick test code and tweaked my debouncing logic.

Here is what Im seeing in the console widget.

A couple of worrying elements that I havent resolved.

“local UDP socket address / port: 0.0.0.0:8988” → In johns video this returned a value.

“Going to connect to websocket on 192.168.1.101 and see if TinyG exists…” → In johns video this announced that a TinyG was found.

I am programming using MAC OS Catlina 10.15.7 ( Serial Port JSON Server v1.92

musmpsmfvh9l.local)

I also upgrade my RPi Serial Port JSON Server v1.96 CNCPi

I have an init.lua that contains
“dofile(“main_chilipeppr_joystick.lc”)”

================================================

Make sure to update your Wifi network ssid’s and passwords in esp32_wifi.lua
Initializing pins
Initting LED pin for ESP32 device: ESP32_Lolin32 pin: 5
e[0;32mI (42456) gpio: GPIO[5]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 e[0m
Initting LED pin for ESP32 device: ESP32_TTGO pin: 13
e[0;32mI (42466) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 e[0m
Initting LED pin for ESP32 device: ESP32_DOIT pin: 2
e[0;32mI (42486) gpio: GPIO[2]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 e[0m
Initting LED pin for ESP32 device: ESP32_Wemos pin: 16
e[0;32mI (42496) gpio: GPIO[16]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 e[0m
Setting up wifi
Attempting to connect to wifi…
I (42516) wifi: wifi timer task: 3ffe7588, prio:22, stack:3584
I (42526) wifi: mode : sta (3c:71:bf:5a:83:5c)

Wifi started
I (43866) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1
I (44526) wifi: state: init → auth (b0)
I (44526) wifi: state: auth → assoc (0)
I (44536) wifi: state: assoc → run (10)
I (44566) wifi: connected with Ukelele, channel 11
Wifi connected. ssid: Ukelele , bssid: 18:78:d4:26:4d:66 , channel: 11 , auth: 3
We should then get an ip…
e[0;32mI (46516) event: ip: 192.168.1.216, mask: 255.255.255.0, gw: 192.168.1.1e[0m
Oh, we got ourselves an IP: 192.168.1.216 , Netmask: 255.255.255.0 , GW: 192.168.1.1
Got wifi. IP: 192.168.1.216 Netmask: 255.255.255.0 GW: 192.168.1.1
Init…
local UDP socket address / port: 0.0.0.0:8988
UDP Server started on port 8988
Announce to broadcast ip: 192.168.1.255
Announce: {“JsonTag”:“{"Icon":"https://raw.githubusercontent.com/chilipeppr/widget-cayenn/master/joystick.png\",\“Name\”:\"Joystick for TinyG","Desc":"This joystick auto-connects to SPJS and sends GCode commands to jog"}”,“MyDeviceId”:“chip:0x283c71bf5a83-ip:192.168.1.216”,“Announce”:“i-am-a-client”,“Widget”:“com-chilipeppr-widget-undefined”}
TCP Recv {“Announce”:“i-am-your-server”,“Widget”:“com-chilipeppr-widget-undefined”,“YourDeviceId”:“chip:0x283c71bf5a83-ip:192.168.1.216”,“ServerIp”:“192.168.1.101”,“JsonTag”:“”}, peerIp:192.168.1.101, peerPort:40860
Got a server:{“192.168.1.101”:true}
Going to connect to websocket on 192.168.1.101 and see if TinyG exists…
Websocket connecting to: 192.168.1.101 port: 8989 path: /ws
GET /ws HTTP/1.1
Host: 192.168.1.101
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: esp32

Websocket found hdr
Websocket connected to host: 192.168.1.101 port: 8989 path: /ws
Websocket doing send. data: list
I (54536) wifi: pm start, type:0

Ping
Got pong. We’re alive.

I think the later version of Lua for ESP32 stopped returning the IP address in the same way, thus you’re getting 0.0.0.0 which won’t work as it needs to send to the correct IP address. Why not just hard code that IP address as a workaround?

1 Like

Thanks John.

It was returning 0.0.0.0 for the UDP address which seems not to matter. You demo video showed the same result - I does connect okay and obtains a local TCP IP address ok.

I think my problem now is that the code that interprets the returned JSON strings from the websocket isnt working as I am not discovering the tinyg

The returned JSON string from the websocket look fine. so this portion of the code doesnt seem to be executing. Included below the JSON str.

Line:117 from chilipeppr_tinyg_V2.lua
– print(“JSON:”, json)
local ports = json.decode(jsonStr)
if ports and ports.SerialPorts then
for k,v in pairs(ports.SerialPorts) do
print(k, v.Name, v.Friendly, v.IsOpen, v.IsPrimary, v.BufferAlgorithm)
if v.IsOpen and v.IsPrimary then
– we have a candidate
if v.BufferAlgorithm == “tinyg” or v.BufferAlgorithm == “tinygg2” then
print(“We found an active TinyG. Awesome!”)
m.tinyg = v
m.tinyg.ip = m.serverBeingChecked
end
end
end

====================================================================
Going to connect to websocket on 192.168.1.101 and see if TinyG exists…
Websocket connecting to: 192.168.1.101 port: 8989 path: /ws
GET /ws HTTP/1.1
Host: 192.168.1.101
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: esp32

====================================================================
Websocket found hdr
Got data:{“Version” : “1.96”} �~{“Commands” : [“list”, “open [portName] [baud] [bufferAlgorithm (optional)]”, “send [portName] [cmd]”, “sendnobuf [portName] [cmd]”, “sendjson {P:portName, Data:[{D:cmdStr, Id:idStr}]}”, “close [portName]”, “bufferalgorithms”, “baudrates”, “restart”, “exit”, “broadcast [anythingToRegurgitate]”, “hostname”, “version”, “program [portName] [core:architecture:name] [path/to/binOrHexFile]”, “programfromurl [portName] [core:architecture:name] [urlToBinOrHexFile]”, “execruntime”, “exec [command] [arg1] [arg2] […]”]} �{“Hostname” : “CNCPi”} , fin: true
Websocket connected to host: 192.168.1.101 port: 8989 path: /ws
Websocket doing send. data: list
Got data:list, fin: true
Got data:{
“SerialPorts”: [
{
“Name”: “/dev/ttyAMA0”,
“Friendly”: “ttyAMA0”,
“SerialNumber”: “”,
“DeviceClass”: “”,
“IsOpen”: false,
“IsPrimary”: false,
“RelatedNames”: null,
“Baud”: 0,
“BufferAlgorithm”: “”,
“AvailableBufferAlgorithms”: [
“default”,
“timed”,
“nodemcu”,
“tinyg”,
“tinyg_old”,
“tinyg_linemode”,
“tinyg_tidmode”,
“tinygg2”,
“grbl”,
“marlin”
],
“Ver”: 1.96,
“UsbVid”: “”,
“UsbPid”: “”,
“FeedRateOverride”: 0
},
{
“Name”: “/dev/ttyUSB0”,
“Friendly”: “FTDI FT230X Basic UART (ttyUSB0)”,
“SerialNumber”: “DN00WN9S”,
“DeviceClass”: “00”,
“IsOpen”: true,
“IsPrimary”: true,
“RelatedNames”: null,
“Baud”: 115200,
“BufferAlgorithm”: “tinyg”,
“AvailableBufferAlgorithms”: [
“default”,
“timed”,
“nodemcu”,
“tinyg”,
“tinyg_old”,
“tinyg_linemode”,
“tinyg_tidmode”,
“tinygg2”,
“grbl”,
“marlin”
],
“Ver”: 1.96,
“UsbVid”: “0403”,
“UsbPid”: “6015”,
“FeedRateOverride”: 0
}
]
}, fin: true

Ok, yeah it does appear you’re successfully connected to the websocket on your SPJS. This means the ESP32 could start sending X and Y movements.

It does look like you’re correct that if it can’t parse the JSON it is not able to execute the lines of code you identified, which means it can’t figure out which serial port is the tinyg, thus it doesn’t know which serial port to send the XY movements to.

I wrote my own JSON parser before there was a C version library for ESP32 and that was included in this project. It was not the best parser. You can actually just swap to use the new JSON parser that’s part of the nodemcu project and that may solve your problem. Or, see if there’s a way to string replace the parts of the JSON that are failing to be an empty string to make the current JSON parser not fail.

1 Like

Its cool John, this hobby is as much about the journey as it is the destination. the body of work you have created is a marvel and fun to play with.

Ill figure it out. The parser seems to work fine and Im learning about Luas handling of tables and how you iterate through the table/array objects is very interesting.

Ill keep you posted once I have.

This is all a pre-curser for another project I have and that is to control my VSD using Modbus RTU protocol via SPJS and a new spindle VSD widget once I get there. Im deciding wither to use a NodeMCU variant or use python from the RPi directly going through an RS485 converter.

Grant

1 Like

Success!!!

I stripped out the following to the JSON text before referencing it to json.decode()

m.buffer=string.gsub(m.buffer,"\t*","")
m.buffer=string.gsub(m.buffer,"\n*","")
m.buffer=string.gsub(m.buffer,“list{”,"{")
although stripping out the \t and\n wasnt essential to make json.decode work

SPJS is probably returning the “list” unbound by {“list”: …}

Thank you for your help and encouragement. (I also had fun testing the Lua code in Zerobrane.)

Grant

2 Likes

That’s awesome you got it working.

2 Likes