Some more/better explanation of the changes by Ben:
1) In our set-up, the PID-controller is used to calculate the change in speed of the puller. The original version calculated the next puller speed.
Why: In the original code, when the line_position is above the setpoint (meaning a value between 0 and 1500 and setpoint equals 1500) the PID controller calculated a puller speed of 0. This was way to abrupt and made the filament swing way too much around the setpoint. Line 29 in PID.cpp “PID::SetOutputLimits(0, 255);” is the culprit. In our code we deleted line 29 in PID.cpp and added a similar line in the setup() routine. More specifically, we added “pullPID.SetOutputLimits(-5, 5);”. Below more on why we choose -5 and 5.
2) In our set-up the puller motor was such that puller speed values that worked for us, had to range between 20 and 60 and are mostly between 30 and 50. So the actual control range is pretty small, 40 (=60-20) at best, but actually only 20 (=50-30). We observed that if the change in speed is large it was quickly followed by a correction, about equally large, but with a different sign. So, for example, if the change in speed was 10, then soon we observed a change in speed of -8 or so. Since the PID is executed 10 times a second, we limited the change in speed to be between -5 and 5. Hence the statement “pullPID.SetOutputLimits(-5, 5);”.
3) In our set-up the puller motor stopped when the speed was set to 18 or below. When the extruder is still working, having the puller motor not turning is not a good idea. So in our set up we kept the speed to 20, unless the PID controller calculated a lower speed for longer than 2.5 seconds.
4) The four ldr’s of the sensor are positioned such that it happened quite regularly that the filament was between two ldr’s and the sensor did not pick this up. Instead it calculated a line_position of either 0 or 3000. So, it could happen that the last line_position calculated was 1050 and that the next calculation yielded 0, where in reality the filament was actually a bit closer to the setpoint, but its shadow fell mostly between two ldr’s. Calibration did not help in this case. We changed the line_position calculation such that when the original calculated 0 or 3000, we looked up a stored past value and used that instead, when
a. That past value was less than 1 second old
b. Or, when the past value was between 400 and 2600.
Our reasoning was as follows: the Nano measures the line_position easily 100 times per second (the PID controller is executed only 10 times per second) So, if, for example, the calculated line_position is 0, it should have gone past a value between 0 and 400 first. Similarly, for a position of 3000, one would have seen a value between 2600 and 3000 first.
Our alterations seem to work much better now (as in, getting winding that does not stutter all over the place and seems to be able to keep the filament around one stable position on the sensor. As I've made quite some changes to the mechanical setup, we are not there yet.