UART controlled stepper drivers and linuxcnc
- maarten12100
- Offline
- New Member
- Posts: 6
- Thank you received: 0
Yes there is a register that can be read from the drive called MSCNT at address 0x6A.Is there any way to read back the step-counts from the drivers? The problem with sending a step-rate is that you don't actually know where the motor is unless you get feedback.
Yeah I cought on to this when I looked into the stepgen and motmod essentially if you can get fb as to how many steps were taken you can put anything there instead of the stepgen.Use the parallel port driver as a model, but keep only the servo-thread part. Note that the base-thread part reports back how many steps have actually been made, to allow the servo-thread part of the driver to calculate the required step rate.
I saw the Mesa UART documentation they seem the recommended way. Actually I haven't found any implementations of UART for the serial or parallel port related to linuxcnc. In the end I just read up on the various registers in the more modern parallel port which support bi-directional data pins. At first I wrote code that could read the 8 pins as if it was 8 independent serial ports and this worked really well when the data pin sampling time was much lower than the bittime. When the sampling time was about half of the bittime it however starts mising bits. Essentially this is just nyquiest criterion preventing reconstruction.The Mesa drivers work very similarly, except that they send a step-rate to an FPGA. Again, it needs to have a feedback of the number of steps _actually_ made.
github.com/LinuxCNC/linuxcnc/blob/master...a-hostmot2/stepgen.c
There is a lot in there, but the "prepare_tram_write" is the bit that sends the step rate to the FPGA.
Realtime UART control _is_ possible. If I was doing it I would use the Mesa UARTs as they are _definitely_ realtime.
Sample UART driver:
github.com/LinuxCNC/linuxcnc/blob/master...ivers/mesa_uart.comp
After that waste of time I decided to just poll as fast as possible for the start bit (on all 8 data lines) and then poll every bittime to record the data. Then process the data afterwards to get rid of start bit and stop bits (idk about other ttl adapters but this cp2102 throws in more than one stop bit). While I will be sending data read requests to all 8 datalines at the same time I wasn't sure if the response would make it back around the same time so I decided to just oversize the raw data buffer. Technically 80 bits (80 bytes total for all 8 data lines) is enough but add in an extra 8 for the optional extra stop bit and the signals not arriving at the same time I made it 100. Sampling this way you can probably go as high as the parallel ports minimum read time I tested up to 500kbps.
When you know what the signal you are measuring is like, sampling slower at very specific intervals actually gives you more useful information than just sampling a lot whenever. So I'm happy with this implemenation even though it's less elegant and needs signals to arrive around the same time.
For reference I used the windows version of arduino ide's serial monitor on another pc which did allow me to select 500k unlike the linux version. I connected the ground of the usb to ttl cp2012 to the ground of the parallel port and connected the tx pin trough a 1.8kohm resistor to two data pins. The parallel port apparently is a fragile port (it's not like this part is standardized though) and you can't just have an external circuit pulling pins high or low and exceed a couple mA so the resistor prevents that.
For a working system the following functionalities will be needed:
reading (retrieving step position and feeding it back to motmod)
crc checking
writing (calculating and sending the requested step velocity, and send requests for the step position)
Thus far I have only done the reading and CRC haven't actually connected the reading part to output pins of the component yet. That part is pretty trivial though. The CRC was a complete pain to implement even after reading up on it I was stuck on it for days until I figured out that the CRC input had to be MSB to LSB so I had to flip the input. I think it's correct now but only communication with the actual driver will tell me. Also while I do have some snippets at the bottom for writing high and lows to all data pins at timed intervals I haven't written functions for sending data concurently similar. If you just have a register with what you want to send for all 8 data pins adding their bitvalue will give what you need to write to the port at every time step, again not that complicated.
First we start with a unsigned char initialized to zero. Then if we want to turn on D0 we add 1, for D1 turned high we'd add 2 and for D7 we'd add 128. These opperations are the same as flipping the bits in the unsigned char but I found this the easiest way to do it in C.
I added a copy of the component file even though it's unfinished I think it's already usefull for people to see how easy it is to read and write from the parallel port and use it for things like creating 8 high speed half duplex uart ports. With the ch382 IC based parallel port I'm using flipping or reading 8 lines takes just 1.1us for example. Added bonus is that when you enable the reading ability of a bidirectional parallel port you need to write a register which also controls 4 output pins, so you get those at no extra IO processing cost.
Please Log in or Create an account to join the conversation.