Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marlin2.0 LPC1768 Software Serial(UART) for TMC2208, it seems to work fine #13197

Closed
Msq001 opened this issue Feb 18, 2019 · 67 comments
Closed

Comments

@Msq001
Copy link
Contributor

Msq001 commented Feb 18, 2019

I have modified the firmware for the TMC2208 UART and LPC1768 software serial lib sections, Now it's not necessary to use interrupt IO for RX, Does anyone want to test it? I can send you the complete project.

@gloomyandy
Copy link
Contributor

Hi I've also been working on exactly this. I've just got things working and can also run using any pin my only extra requirement is the use of the RIT interrupt. I'd be interested to see your implementation. What baud rates have you tested? Have you run into any issues with jitter when printing due to the time taken by the various Marlin interrupt routines? What parts of Marlin did you need to change? My intention was to only need to changes to the SoftwareSerial files (though I ,may also change the baud rate used by the TMC code).

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 18, 2019

Hi I've also been working on exactly this. I've just got things working and can also run using any pin my only extra requirement is the use of the RIT interrupt. I'd be interested to see your implementation. What baud rates have you tested? Have you run into any issues with jitter when printing due to the time taken by the various Marlin interrupt routines? What parts of Marlin did you need to change? My intention was to only need to changes to the SoftwareSerial files (though I ,may also change the baud rate used by the TMC code).

open file C:\Users\<user name>\.platformio\packages\framework-arduino-lpc176x\cores\arduino\SoftwareSerial.cpp and uncomment DELAY_TABLE table[] in line 62-70, then you can use the software serial.

@gloomyandy
Copy link
Contributor

Yes I'm very familiar with that code, but it requires pins that generate a software interrupt on change for the receive line. Have you made other changes?

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 18, 2019

Yes, I also add some functions in this file and changed the TMC2208Stepper.cpp file line 94 uint32_t TMC2208Stepper::read(uint8_t addr), In order to make the pins without interruption function can also be used as RX, there is a little change in the Arduino framework. I think this is not good, so we need to discuss it. I will update the change to github tomorrow, and let you know

@gloomyandy
Copy link
Contributor

OK, I hope to be able to start testing my solution with a TMC2208 later today. So far I've been testing with a terminal connection and a scope to check on timings etc. Have you had the code that checks the 2208 temperatures during operation (MONITOR_DRIVER_STATUS in Configuration_adv) running? I had a look at the stepper code timing and it looked like that could cause problems for timing of read and write operations when using software serial.

Looking forward to seeing your solution.

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 19, 2019

@gloomyandy
Copy link
Contributor

Thanks! Will give your version a test and see how I get on. It is much simpler than what I've been doing (which is good!).

@PeteBurgess
Copy link

What board are you guys testing with ? Following this with interest.

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 20, 2019

I tested it with BIGTREE SKR V1.3

@boelle
Copy link
Contributor

boelle commented Feb 20, 2019

@Msq001 please submit a PR against bugfix 2.0

@boelle
Copy link
Contributor

boelle commented Feb 20, 2019

i personaly can use this and will use with re-arm+ramps 1.4SB

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 20, 2019

@boelle Hello, I changed the library file, SoftwareSerial.cpp of lpc1768 and TMC2208Stepper.cpp , Did not change the marlin source file,So, I can't create a PR for marlin , https://github.com/Msq001/marlin_2.0_bugfix_tmc2208. You can download this project to test

@PeteBurgess
Copy link

Skr v1.3.? v1.2 isn’t available yet.

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 20, 2019

@PeteBurgess skr v1.2 is a debug version, v1.3 is testing now, and will be released soon. if you have a motherboard with LPC1768, add software series pins to the <pins_board_name.h> file and you can use this project.

@teemuatlut
Copy link
Member

@Msq001 I recommend rather than simply uploading the files, you fork Marlin/TMCStepper/whatever. It's way easier to see the changes and allows you to actually make pull requests.

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 20, 2019

@boelle
Copy link
Contributor

boelle commented Feb 20, 2019

@Msq001 i think he meant to fork marlin git and not his own git

https://github.com/MarlinFirmware/Marlin/tree/bugfix-2.0.x

@gloomyandy
Copy link
Contributor

OK So I now have some results from testing this approach and from some further tests on an alternative that uses the RIT timer to generate and read the software serial signals. Before I give the results let me explain the tests I've been using and the types of error I'm trying to detect...

When you talk to a TMC2208 commands are sent to the driver using short 4 byte packets and responses are received as an 8 byte packet. In both cases the packets contain a single byte checksum. The majority of commands do not have a response (as they are used to set values). If the checksum of the command is not correct the command will simply be discarded by the TMC2208. This raises the obvious question of how do we know if there is a problem when we send a command? The long answer is that the TMC2208 does provide a mechanism (using sequence numbers), that will allow you to detect if a command has worked, but this is not used by the current TMC library. So the short answer is that at the moment there is no easy way to test commands that do not send a response back to the control board. However it is possible to use commands that get a response to detect both send and receive errors. Receive errors are easy we simply compute the checksum on the data we get back and if it does not match there has been an error. But what about if there is an error writing the command to the TMC2208? Well in this case the device will simply ignore the command and with the current code we will read a response that is all zeros. Unfortunately the checksum checking code will not identify this as an error (as the checksum of all zeros is zero), however no valid response is ever all zero (as it must have a special start byte ) so we can detect the all zero case. So write errors will show up as an all zero response and read errors as a checksum.

As I said above the majority of commands (used to set values) do not generate a response from the TMC2208 so it is not easy to use these for testing purposes. However if we enable the MONITOR_DRIVER_STATUS option this will read the status registers on a frequent basis and so can be used to test both command and response handling (since a read request sends a command and reads the response). Unfortunately by default the TMC code does not monitor the status of drivers using software serial, nor does it check the response either for a bad checksum or a zero packet (the checksum is computed, and errors are noted, but nothing ever checks the error flag). But these problems are easy to fix by small modifications to the TMC library.

OK so the test setup is one in which we have the modified TMC library that has status monitoring of the device enabled and that has extra code to count the number of CRC (receive errors) and zero responses (write errors). I have a test board (SKR V1.1) with two TMC2208 devices (and 2 TMC2130s but we can ignore them). The test consists of three parts. Part one is simply to power the board on (which initialises the devices) and note any errors detected during this process. Test two is to leave the board idle for two minutes (during which the status of the devices will be tested repeatedly), test three is to run a 30 minute test gcode file. At the end we report the detected errors from each test. So here are the results obtained using the modified SoftwareSerial class running at 115200 baud using polling for receiving data. The results are given as read errors/write errors for each test.

Configuration          Startup          Static          GCode
SS115200                0/0             96/0            7692/0

Obviously we need to dig a little deeper. See next post

@gloomyandy
Copy link
Contributor

gloomyandy commented Feb 20, 2019

Ok so those results do not look very good, interestingly we have a lot of read errors but zero write errors. So what is going on. We need to understand what is causing the errors and it is all about timing. Basically we are are generating the serial pulse train by timing the gaps between the various on/off states of the pins. Similarly when we are receiving a byte we are sampling the state of the pins then waiting a fixed time and sampling again. Just to understand the scale of things at 115200 baud we have a gap between the pulses that represent the data of about 8uS. Now computers are reasonably good at timing things at this sort of scale so what is going wrong? Basically interrupts. These are used in Marlin to do things like generate the stepper pulses, check temperatures, handle serial and USB I/O etc. The thing is an interrupt is a bit of a bully and will push other code out of the way when it needs to run, in this case the code that is being pushed out of the way is our receive loop and its associated timing code. Imagine what happens to our code that is sampling the data every 8uS if along comes a pulse generation interrupt that can run for up to 10uS! Yep that is exactly what can happen. Given that these interrupts can occur every 20uS it is a wonder that we manage to get any good data at all.

Now you may be wondering why we are not getting any write errors, surely the interrupt issue should be screwing up our output pulse generation just as much? Well yes it should except that our write code has a secret weapon, it disables interrupts when generating the pulses for each 8 bit character (which is actually 10 bits long because of start and stop bits). This means that the timing for the pulses is actually pretty good with no "jitter" due to those pesky interrupts. So can we turn off interrupts when receiving data? Well Yes we can and when we do we get the following results....

Configuration          Startup          Static          GCode
SS115200                0/0             96/0            7692/0
SS115200IN              0/0             11/0            1049/0

Which is clearly much better, but why are we still getting read errors. Well we are only turning interrupts of for each 8 bit character, we enable them between each one. This is OK on the write side of things as it doesn't matter how big the gap is between each byte (well not that much). However on the read side we don't control when the bits arrive and if our sampling code is not there ready to go when the first bit of a byte arrives, well we miss it. So simple we just leave the interrupts off until we have all of the 8 bytes we need? Unfortunately those steppers are not going to be running very smoothly if we stop feeding them pulses for 8108uS (8 characters 10 bits per character 8uS per bit) so 640uS. In fact turning interrupts off for 80uS is probably pushing our luck a little.

So what else can we try?

@AnHardt
Copy link
Contributor

AnHardt commented Feb 20, 2019

We already use advanced tricks to no miss any of the hardware serials rx-interrupts.
With hardware serial we get 1 Interrupt per byte.
With software serial and pin-change interrupts we get at least 8/2 + 2 = 6 positive flanks/interrupts per byte (in average). That's a lot more challenging.
With software serial and polling we have the choice. Either we can receive a message over the rx-line, or we can step in time. There is no chance to do both at the same time.

The trick how to Address Multiple Slaves with a single serial is described in chapter 4.4 (page 21) of the datasheet. The pins for setting the gates are by far less demanding, don't need to create interrupts, don't have to be on an U(S)ART, could be any output pins.
But a tiny bit of additional hardware is required (less then 2 € for 40 drivers). The software is not challenging then.

@GriffinPaquette
Copy link

I have several boards sitting here with direct wire connection for 2208 UART. If you gentlemen don’t mind me snagging a zip of your modified Marlin, I would be more than happy to test.

@gloomyandy
Copy link
Contributor

@AnHardt Yes I agree that a hardware serial solution (possibly with extra switching hardware) is the best way to go. I wonder if anyone would be interested in a hardware add-on that would do the multiplexing?

But it's still an interesting challenge to see what you can actually get out of the hardware you already have, without making hardware changes. Especially if like me you are a software sort of guy! So I'm going to continue to investigate further. Of course if I was a board manufacturer (or someone testing a prototype board) I would definitely be pushing to have that hardware solution added to the board! At the end of the day any software hack is likely not to be 100% perfect and may impact print quality (see my point above about disabling interrupts).

I think a simple polled SoftwareSerial implementation (with interrupts turned off during send/receive), is good enough for performing TMC2208 UART based configuration. But it probably is not a good idea to use this approach for monitoring the drivers or talking to them at all during printing. You can probably use that solution on pretty much any board that has pins available (well 32 bit boards anyway). It's a bit of a hack, a little like using the enable pins as chip select lines for TMC2130 drivers with the SKR V1.1 board, but some people may be happy to have that.

For now I'm still digging that hole trying to get better software monitoring of the drivers.

@gloomyandy
Copy link
Contributor

Continuing on in my investigations and testing. So far we have been running the SoftwareSerial UART at 115200 baud, now that's nice, but it does impose some pretty tight timing requirements (for software at least, even on a 32bit board). At the moment we need to be able to measure reasonably accurately delays of around 8uS or so and we are operating in an environment that has a pulse generating interrupt that can in some circumstances take 10uS or so. This is not a good combination. So an obvious solution is to relax some of the constraints in this case the baud rate. A lower baud rate will make the timing far less critical if we drop the speed to say 38400 we now have a pulse length of around 26uS which is somewhat more manageable and we may even be able. Pushing a little further we really only have a few bytes to move around, so why not drop the speed down towards the minimum speed that the drivers support (9000bps), so 9600 baud. This it turns out is the speed used by Klipper for these devices, so it seems to work fine (at least for configuration). With that our pulse timing goes up to a very manageable 104uS. But with this length of pulse we really can't continue to disable interrupts (arguably we never should have). So what do the numbers look like with these configurations?

Configuration          Startup          Static          GCode
SS115200                0/0             96/0            7692/0
SS115200IN              0/0             11/0            1049/0
SS38400NI               0/0             1/11            1072/1260
SS9600NI                0/0             0/0             82/28

As we can see no longer disabling interrupts mean that we are now getting write errors but the slower speeds clearly help with the timing. Out of interest I did test with the ints disabled and the steppers basically stopped working! Oh and just in case you are wondering all of these tests actually perform the same number of checks on the drivers (the poll routine always runs for the same period).

@gloomyandy
Copy link
Contributor

So the final thing I've taken a look at with this polling approach is how the delays are generated. The code in the LPC176X framework creates some very accurate delays, but these delays are based on executing code that takes a certain number of cycles to run. This code is then executed a number of times based upon the desired delay and the speed of the cpu. But what happens if part way through delay of say 104uS there is an interrupt that takes 10uS? Well you end up with a delay of 114uS (or so). Now it turns out that this can mess with some of our timing. So replacing the delay routines with one that uses one of the hardware timers can have interesting results:

Configuration          Startup          Static          GCode
SS115200                0/0             96/0            7692/0
SS115200IN              0/0             11/0            1049/0
SS38400NI               0/0             1/11            1072/1260
SS9600NI                0/0             0/0             82/28
SS38400NINT             0/0             0/0             48/53
SS9600NINT              0/0             0/0             0/1

As you can see correcting the timing to allow for any interrupts helps a lot (final two results above), lowering the error rate pretty much to zero when running at 9600 baud.

@GriffinPaquette
Copy link

@gloomyandy I was considering using a coprocessor like the STM32F030K6T6 or STM32F103C8T6 to handle all of the UART setup and monitoring for the drivers. There should be enough IO’s to handle the process for plenty of drivers and I think that the M3 processor of the F103 would be easily up to the task. It would take a lot of load off processors such as this and reduce the pin count to ideally a single hardware UART connection back to the main CPU that reports back if the driver throws an error, etc. I have no problem handling the hardware aspect but I cannot handle any of the software.

@GriffinPaquette
Copy link

@Msq001 I flashed your code and do not have RX errors anymore but I am getting command not recognized when I try a M911. Current to drivers do not seem to change either whereas I could definitely note a holding torque change when using the current bug fix version.

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 22, 2019

@gloomyandy With regard to MONITOR_DRIVER_STATUS when printing, I intend to replace both RX and TX in the interrupt of the timer instead of using delay_us, and I am working on that now. I think it would be much better. The only disadvantage is that it takes up extra timer. If there's any progress, I'll let you know in the first time

@Msq001
Copy link
Contributor Author

Msq001 commented Feb 22, 2019

@griffin-117 hi~ Have you tried M906 command? I can change the current with M906 command.

@gloomyandy
Copy link
Contributor

@Msq001 you may want to wait a couple of days and take a look at the code I'm working on. It uses the RIT interrupt for timing and also only needs a single I/O pin per TMC2208. I have it working reasonably well at the moment but want to clear up a few things. It does not require any polling for the I/O.

@VanessaE
Copy link
Contributor

VanessaE commented Mar 2, 2019

@gloomyandy so, I think I get it now, but can you summarize the state of 2208 support on SKR 1.1, for those of us who don't speak code? 😉

@gloomyandy
Copy link
Contributor

There is a new SoftwareSerial implementation for LPC1768 based boards. This new version can operate with TMC2208 drivers using just a single pin per driver and that pin does not need to be interrupt capable. The driver should also work with the TMC2208 in two pin mode, but this has not been tested. The new driver is now included as part of the LPC1768 framework and so should "just work" if you configure Marlin to use it, no special version of the TMC libs are required.

Some additional notes:

  • I do not claim it will work with "any pin" as some pins have very special characteristics (like they are open collector drivers), or may have additional hardware attached (like endstop pins which often have various resistors and capacitors to form a filter).
  • The current version contains code that overrides the selected baud rate to allow it to work with the existing TMC library. This means that it is not a general purpose SoftwareSerial driver.
  • The code is all new, the way it works is also new. So testing is required, there may be situations in which it does not work, or in which it impacts print quality.

@VanessaE
Copy link
Contributor

VanessaE commented Mar 5, 2019

@gloomyandy Ok. I've updated Marlin to commit 2513f6b, and the soft serial library is already at 0.1.0... using single-wire connections, with your previously-mentioned pins definition (wrapped in #if HAS_DRIVER(TMC2208) [...] #endif), the drivers report back as good, if I'm reading the output of M122 correctly:

M122 output
>>> m122
SENDING:M122
		X	Y	Z	E
Enabled		false	false	false	false
Set current	600	600	800	400
RMS current	581	581	795	397
MAX current	819	819	1121	560
Run current	18/31	18/31	25/31	12/31
Hold current	9/31	9/31	12/31	6/31
CS actual		9/31	9/31	12/31	6/31
PWM scale	33	11	14	7
vsense		1=.18	1=.18	1=.18	1=.18
stealthChop	true	true	true	true
msteps		16	16	16	16
tstep		max	max	max	max
pwm
threshold		0	0	0	0
[mm/s]		-	-	-	-
OT prewarn	false	false	false	false
off time		3	3	3	0
blank time	24	24	24	24
hysteresis
-end		-1	-1	-1	-1
-start		1	1	1	1
Stallguard thrs
DRVSTATUS	X	Y	Z	E
stst		X	X	X	X
olb
ola
s2gb
s2ga
otpw
ot
157C
150C
143C
120C
s2vsa
s2vsb
Driver registers:
		X	0xC0:09:00:00
		Y	0xC0:09:00:00
		Z	0xC0:0C:00:00
		E	0xC0:06:00:00
Testing X connection... OK
Testing Y connection... OK
Testing Z connection... OK
Testing E connection... OK
.

However, the motors won't move in TMC2208 mode. If I switch them to TMC2208_STANDALONE mode, they try to move, as long as the UART wires are not connected (I have no jumper shunts on the board, so the default microstepping is way wrong, whatever it is. 😛 ).

Did I miss a step?

Configs: Marlin-configs-32bit-20190304-2.zip

@gloomyandy
Copy link
Contributor

You have SOFTWARE_DRIVER_ENABLE set, unless you have added a wire from the driver enable pin to ground (and disconnected the pin that goes to the board connector) I suspect that may cause problems. I've also not tried that mode of operation with TMC2208 drivers. I would also be tempted to set the current to at least 800mA to begin with and reduce it once you have things working. I would also enable MONITOR_DRIVER_STATUS when you have things working as it provides very useful information about driver temps.

By default you will be operating with 1/8th microstepping I think.

Oh and and on this board you may run into problems using LIN_ADVANCE it seems to mess up the pulse timing. You may need to set a MINIMUM_STEPPER_PULSE value of 1 or more. Search the issues for details of why.

@VanessaE
Copy link
Contributor

VanessaE commented Mar 5, 2019

SOFTWARE_DRIVER_ENABLE, MONITOR_DRIVER_STATUS, MINIMUM_STEPPER_PULSE

Now unset, set, and set, respectively. This got me going, thanks! Now I can actually test stuff. 😃

Oh, as for currents, those values are from earlier use of my 2208's on an Arduino/RAMPS stack, and are already mostly appropriate for my hardware. Had to turn the E current up a bit from there, though.

@gloomyandy
Copy link
Contributor

Are you using 12V or 24V? If 24V you may want to change CHOPPER_TIMING as well. Lots of folks seem to have to run E steppers in spreadCycle mode (especially with linear advance), but I guess that is all down to fine tuning.

@VanessaE
Copy link
Contributor

VanessaE commented Mar 5, 2019

I'm using a 12v system. I looked at that setting a while back and couldn't make sense of it.

Interesting.... I have to run E in spreadCycle mode also (it's not apparent from my config, but it's "forced" by fast retracts that exceed the hybrid threshold).

@VanessaE
Copy link
Contributor

VanessaE commented Mar 5, 2019

Initial impressions after a couple of test/calibration objects and a small wade's gear that I've been needing to print:

It's working really well for me. Short and sweet 😃

There is one thing that I think should be addressed, but it's not specific to the 2208 (rather, to all TMCs I guess): if accelerating/decelerating during a move would cross the stealthChop/spreadCycle hybrid threshold, find some way to avoid confusing the TMC's math -- they get noisy when close to the threshold because of double/quad stepping. Maybe split the accel/decel periods into many short moves and let the TMC driver itself handle them, instead of banging on step/dir?

@gloomyandy
Copy link
Contributor

@VanessaE Good to hear that it is working. Thanks for trying it.

As to your comment about the acceleration/deceleration and TMC driver, you may want to create a new issue and explain the problem and possible solution there. I'm not at all familiar with that side of how the drivers function, I'm sure @teemuatlut and others could comment, but I'd rather keep this thread focused on the software UART if we can.

@VanessaE
Copy link
Contributor

VanessaE commented Mar 5, 2019

Fair enough. Comment moved to a new issue. (#13316)

@VanessaE
Copy link
Contributor

VanessaE commented Mar 17, 2019

Can we get the pins definitions in @gloomyandy's post (step 4) officially added to pins_BIQU_SKR_V1.1 ? They "seem to work fine", after all 😉 (and in fact, do; it would be good to establish a standard).

@gloomyandy
Copy link
Contributor

I intend to create a PR for this (there needs to be an alternative for when using a TFT screen, which I'd really like to test before creating the PR). There are other changes also needed to finish this off completely. Like for instance you will not be running the monitoring code unless you have modified tmc_util to remove the requirement for a hardware UART. There are also changes needed to make the baud rate more suitable for use with this modification (at the moment there is a hack in the framework code to do this).

If all goes well I hope to get to this later this week.

@gretel
Copy link

gretel commented Mar 31, 2019

Are you using 12V or 24V? If 24V you may want to change CHOPPER_TIMING as well. Lots of folks seem to have to run E steppers in spreadCycle mode (especially with linear advance), but I guess that is all down to fine tuning.

agreed, spreadCycle on E steppers is good for me at least.

@jokejoke
Copy link

jokejoke commented May 8, 2019

Ok so I've got a first pass of my solution to this problem. It basically uses the RIT timer to generate the output stream and to sample (using oversampling) the input stream. It supports the use of any pin and supports half duplex operation so only a single pin is needed per TMC2208. It supports the use of MONITOR_DRIVER_STATUS (though changes are needed to Marlin to enable this). No changes are needed to the TMC library to use it (though it does include a bit of a hack to make this possible and I'll be working to put together a PR for the TMC lib in the future to clean this up). The approach used is based on one originally suggested by @p3p and uses input from this thread and a discussion over on discord.

I have tested it a little with four TMC2208s on an SKR V1.1 board (with an LCD display) and on my "production" printer that uses an SBase board with two external TMS2208s. I have not seen any issue with various test prints. I have not tested this code using separate TX/RX pins nor have I tested it as general purpose software serial code.

The changes are based upon a version of Marlin from about a week or so ago. I will be updating and testing with the latest version as soon as I get chance but I would expect things to work with the current version. Note that my LPC1768 framework tree contains other changes. I provide instructions on how to use my SoftwareSerial code below, you do not need to use my trees.

My Marlin tree is here: https://github.com/gloomyandy/Marlin/tree/myskr
My LPC2768 tree is here: https://github.com/gloomyandy/pio-framework-arduino-lpc176x/tree/software-serial

The two files that contain the new implementation are:
https://github.com/gloomyandy/pio-framework-arduino-lpc176x/blob/software-serial/cores/arduino/SoftwareSerial.cpp
https://github.com/gloomyandy/pio-framework-arduino-lpc176x/blob/software-serial/cores/arduino/SoftwareSerial.h

NOTE: The SoftwareSerial code is now part of the LPC1768 framework version 0.1.0 so you should no longer need to perform steps 1 and 2 below. You may need to force an update of the platformio libs.

If you wish to try this code then these are the steps you will need. Note that this is not final code and you use it at your own risk! You should make a backup of any files you overwrite or change.

  1. You need to locate the LPC1768 framework directory on your machine. This is stored at location that will look like: C:\Users.platformio\packages\framework-arduino-lpc176x
  2. locate the directory cores\arduino which should contain files called SoftwareSerial.cpp and SoftwareSerial.h. Make a copy of these files in a safe location and replace them with my version given above.
  3. Edit your configuration file to define which TMC2208 drivers you have (set them to be of type TMC2208).
  4. Edit your pins.h file to define what pins you are going to use for the UART connections. For the SKR V1.1 I use the following:
  #define X_SERIAL_TX_PIN    P2_06
  #define X_SERIAL_RX_PIN    P2_06
  #define Y_SERIAL_TX_PIN    P1_31
  #define Y_SERIAL_RX_PIN    P1_31
  #define Z_SERIAL_TX_PIN    P1_23
  #define Z_SERIAL_RX_PIN    P1_23
  #define E0_SERIAL_TX_PIN   P0_03
  #define E0_SERIAL_RX_PIN   P0_03
  //#define E1_SERIAL_TX_PIN   P0_02
  //#define E1_SERIAL_RX_PIN   P0_02
  1. Wire up a single connection between each of the selected pins and the PDN pin on the TMC2208. I used a direct connection and so far this has worked fine. However it may make sense to include a 1K resistor in the connection. You do not need a Y lead.
  2. Edit the Configuration_adv.h file and define #define TMC_DEBUG to enable the use of the m122 command.
  3. Build Marlin and install the new version. You should not get any sort of error message on the display. Issuing m122 should give output that ends with something like:
22:31:24.530 : Driver registers:
22:31:24.537 : X	0xC0:0C:00:00
22:31:24.544 : Y	0xC0:0C:00:00
22:31:24.552 : Z	0xC0:0C:00:00
22:31:24.559 : E	0xC0:0C:00:00
22:31:24.567 : Testing X connection... OK
22:31:24.574 : Testing Y connection... OK
22:31:24.581 : Testing Z connection... OK
22:31:24.589 : Testing E connection... OK
  1. If you wish to use the MONITOR_DRIVER_STATUS option you can set this in Configuration_adv.h you will also need to edit the tmc_util.cpp file and change the HAS_HW_COMMS macro to remove the requirement for a hardware UART. You can see my version of the file here:
    https://github.com/gloomyandy/Marlin/blob/myskr/Marlin/src/feature/tmc_util.cpp
  2. Let me know how you get on. Please note I will have limited time over the next week or so, so may not be able to help debug issues very much, so please don't try this unless you are happy to wait for help!

Here is my SKR configured as above....
img_20190224_235344

@gloomyandy Nice work :) Is this change of SoftwareSerial library usable also for 8bit microcontrollers (Atmega2560)? Because FYSETC F6 1.3 board has problem with RX pins without PCINT #12800 (comment). Thank you :)

@gloomyandy
Copy link
Contributor

Probably not and certainly not without re-implementation. This code is really LPC176x specific.

@lightface79
Copy link

Hi!! is this 1 pin serial sullution inplemented in the latest 2.0 builds u can download? or do i need to use the serial files from u @gloomyandy

Bulding a new 3dprinter with Sbase 1.3 with the lc1768 chip and TMC2208 drivers..

best regards Jan // Sweden

@ManuelMcLure
Copy link
Contributor

At least on Re-ARM it looks like it's implemented - the pins.h file for Re-ARM shows the same pin being used for TX and RX.

@lightface79
Copy link

hmm... weerd... its the same lpc1768 chip on both re-arm and my mks sbase it should work... wonder whats the difference between the 2 cards sowftware wise,...

@gloomyandy
Copy link
Contributor

This should work fine on the sbase board (that's what I originally developed it on!). What exactly are you trying to do and what pins on the Sbase are you trying to use for the software serial interface? What makes you think it is not working? I assume you are trying to talk to a TMC device, which one? Are you sure you have the driver modules configured correctly? Also the Sbase 1.3 has onboard drivers so are you not using them?

@lightface79
Copy link

Hi and thnks for anwsering.
In the middle of the build of my new 3d printer...
Using tmc2208 drivers.
Not going to use the sbase internal drivers sins they ar terrible...
So i made a Extennsion board with the 5 tmc2208 with separate 24v feeding them.
Used the same setup on my Delta printer but with Klipper FW with the 1 wire uart and without a 1K resistor and that worked perfect..

So when u say half duplex comms is it just Write or Read depending on the resistore or is it Both on a single wire on the sbase?

Should i just re config the sbase/pins.h so that both RX/tx is on the same pins?

Is there som pins that is better to use for the serial com to the drivers?

Best regads Janne

@lightface79
Copy link

  • TMC2208/TMC2209 stepper drivers
    *
    • The shortage of pins becomes apparent.
    • Worst case you may have to give up the LCD
    • RX pins need to be interrupt capable
      */
      #define X_SERIAL_TX_PIN P1_22 // J8-2
      #define X_SERIAL_RX_PIN P2_12 // J8-4 Interrupt Capable
      #define Y_SERIAL_TX_PIN P1_23 // J8-3
      #define Y_SERIAL_RX_PIN P2_11 // J8-5 Interrupt Capable
      #define Z_SERIAL_TX_PIN P2_12 // J8-4
      #define Z_SERIAL_RX_PIN P0_25 // TH3
      #define E0_SERIAL_TX_PIN P4_28 // J8-6
      #define E0_SERIAL_RX_PIN P0_26 // TH4

Whitch ones do u recomend? have 5 tmc2208

Have a double Z steppers.. or shoud i scrap 1 driver and just go Y-Harnes on 1 Z driver To 2 pcs of z stepper motors and ramp up the current on that driver?

@gloomyandy
Copy link
Contributor

It does read/write on the same pin. You just need to define both the RX and TX pins to be the same pin. I'd use 5 pins on the J8 connector so..

#define X_SERIAL_TX_PIN P1_22 // J8-2
#define X_SERIAL_RX_PIN P1_22
#define Y_SERIAL_TX_PIN P1_23 // J8-3
#define Y_SERIAL_RX_PIN P1_23
#define Z_SERIAL_TX_PIN P2_12 // J8-4
#define Z_SERIAL_RX_PIN P2_12
#define E0_SERIAL_TX_PIN P4_28 // J8-6
#define E0_SERIAL_RX_PIN P4_28

Note I've not tested this! If you want to use E1/Z2 then you will need to find another suitable pin. You could use pin P0_02 or P0_03 if you are not planning on using the UART interface to talk to any sort of touch screen. I'd avoid trying to use the endstop/thermistor pins if you possibly can as they will have extra pullups etc. on them that may cause problems.

@lightface79
Copy link

ok... thanks alot... =) will put this in my fW and have a go on the test bench =)

@github-actions
Copy link

github-actions bot commented Jul 4, 2020

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked and limited conversation to collaborators Jul 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests