PrusaOwners / Marlin

Optimized firmware for RepRap 3D printers based on the Arduino platform.
http://www.marlinfw.org/
GNU General Public License v3.0
15 stars 4 forks source link

Fan tacho check - Safety Feature #12

Open stahlfabrik opened 5 years ago

stahlfabrik commented 5 years ago

Add fan Tacho speed check to abort a print if a fan fails and kill heaters to prevent further damage to the machine

repvik commented 5 years ago

Could code checking for F99-style stall sensor be added as well, as a config option?

matthew-humphrey commented 5 years ago

@repvik - is that an alternate to the tach, i.e. a fan signal that goes active when the fan is stalled?

repvik commented 5 years ago

@matthew-humphrey Yes, that is the alternative to the tach. On Sunon F99 fans, the wire is white instead of yellow. I've got a few to spare. If someone wants to test I can send one.

matthew-humphrey commented 5 years ago

I have evaluated two different approaches to calculating the fan RPMs from the tach lines:

  1. Using ISRs to detect a state change on the fan pins. I could implement this with one common ISR, or with a separate ISR for each fan. In the ISR I would increment a count. Then in some method that is called periodically, for example thermalManager.manage_heater. I could periodically check that some minimum time span had passed, and then inside a "critical section" (there's a macro for this - it just temporarily suspends interrupts) it would grab the counter values from the ISR and reset them to zero. If we assume two 7000 RPM fans that generate an interrupt twice a rotation, this would be ~466 interrupts per second. The ISR can be kept relatively short by just incrementing the counter and leaving.

  2. Inside the existing temperature sampling ISR, which runs at approximately 977 interrupts/sec, I could read the value of the fan pins and detect a change. Because each fan tach line changes state at an (estimated) max rate of 233 times per second, we are comfortably above the Nyquist rate. We can just accumulate values and periodically write them off to another variable, just exactly like the temperature sampling code does. Then periodically we can turn these into an average RPM value.

I am going to go with option 2, because it avoids the overhead of two additional ISRs. There is nothing here that is critical, and some error in the fan reading is completely acceptable. Also, this approach is a less impactful change.

I also have a plan for checking for fan error, but I will write that up later.

stahlfabrik commented 5 years ago

Well if you are above nyquist rate there should not even be an error then. I just wonder if thermal manager is conceptually the right place or if a new fan manager would be better. But I guess the fans are also all about temperature so that is good. Are the fan duty cycles set by chance in the thermal manager code already?

matthew-humphrey commented 5 years ago

Thats a good question about duty cycles, I'll see where that code is. I'll probably put the bulk of the code in a separate H/CPP file, though. But the ISR I need to add to is in thermal manager, so that will have to be modified.

matthew-humphrey commented 5 years ago

Basic fan tach reading has been implemented - use g-code M198. I'll be working on a fan check g-code next.