You can define UART sections at the top level of the config file and refer to them where they are used:
uart1:
txd_pin: gpio.0
rxd_pin: gpio.4
rts_pin: gpio.13
baud: 115200
mode: 8N1
uart2:
txd_pin: gpio.22
rxd_pin: gpio.21
baud: 115200
mode: 8N1
uart0 is the USB serial console one; you cannot define or change it because it is so important for startup messaging.
Within a Spindle class, you can still use the old syntax where there is a subordinate "uart:" subsection, or, alternatively, you can refer to an externally-defined uart section with:
NowForever:
uart_num: 1
modbus_id: 1
Trinamic UART devices like TMC2208 and TMC2209 no longer support the subordinate "uart:" subsection (making that work was just too hard); you must use the external UART section with "uart_num: N":
axes:
x:
motor0:
tmc_2209:
uart_num: 2
addr: 2
...
z:
motor0:
tmc_2209:
uart_num: 2
addr: 1
...
With this scheme it should be possible to use, say, 5 TMC UART devices by using two UARTs, getting around the limitation of 4 device addresses.
Dynamixel2 is like Trinamic; you must use "uart_num: N":
axes:
x:
motor0:
dynamixel2:
uart_num: 1
id: 3
The Dynamixel driver, as currently written, can use only one UART for all the Dynamixels.
UART channel create a new Grbl interface on a UART. This is designed for displays, pendants and external controllers. It can use a report interval so the client does not need to query status. You will get a prompt status update when anything major changes and regular updates when the axes are moving.
We have some starter code if you want to make your own display or interface.
uart_channel1:
uart_num: 2
report_interval_ms: 75
message_level: info
The new channel will accept input just like the USB serial channel, the telnet channels, the websocket channels, etc.
You can also do uart_channel1 or uart_channel2. uart_channel0 is the implied USB serial channel and is always on by default
There are only three physical UART engines on ESP32, so if you try to do too much you will run out of UARTs. If you are using a UART for a VFD spindle and another for TMC drivers, you can't make another uart_channel . UARTs can only be shared among like devices, such as multiple TMC drivers or multiple modbus VFD spindles.
None of this is on any released firmware. See discussion here. This wiki page section is just gathering info from the discussion on Discord
This covers ways of adding I/O over a UART channel. For example: An MCU with inputs (switches, etc) and outputs could be connected via UART. This could potencially be used by senders, the WebUI, or websockets.
On input state transition the device will send one of 2 new realtime charatecters UART_IO_HIGH
or UART_IO_LOW
then a single character representing the input number that changed. The channel will reply with UART_IO_ACK
or UART_IO_NAK
.
UART_IO_HIGH = 0xC0, // UART Input pin high notification
UART_IO_LOW = 0xC1, // UART Input pin low notification
UART_IO_ACK = 0xC2, // UART OK with last message
UART_IO_NAK = 0xC3, // UART rejected last message
A new message level will be used. Something like this.
[MSG:CTL: Cmd:Set|Val:1]
All messages sent will be in the standard [MSG: ..... ] format. The command type will follow MSG:. Here are the currently defined command types, but the receiver should be robust enough the ignore any new ones that it does not support yet.
[MSG:INI: ... ] ; initialize the item
[MSG:SET: ... ] ; set a value on the item
[MSG:GET: ... ] ; get the current value of the item
Parameters are set with a key:values format. Example hz:5000. If a key has no value it is assumed to be "true". If there is a single numeric value (int or float) it is assumed to be the primary value of the feature. There can only be one of these. The order of parameters does not matter.
[MSG:INI: io.1=inp,low,pu] ; Initialize io1 with a pullup and set the active state to low.
[MSG:INI: io.2=pwm,hz:5000,inv] ; Initialize io2 as pwm with a freq and it is inverted
[MSG:SET: io.1=1] ; Set the output to 1
[MSG:GET: io.1] ; Get the value of io1
[MSG:GET io.*] ; Get all input values. Used at startup
[MSG:SET: io.2=0.5] ; Set the duty to 50%
If a parameter is not sent it should use these values. If it was previously set, that value should be used.
Device should report an error via NAK if it cannot comply.