Prusa Mini with MK3S Extruder/Filament Sensor
So I had an idea a couple of days ago, why spend the cash on the Bondtech and external sensor for the Prusa Mini when the MK3S extruder has both?
I worked up the STL files, and the installation went really well. I now have a MK3S extruder and sensor in place, and everything appears to fit great.
I'm stuck on the firmware for the Mini, however. I pulled the git, and I have it compiling cleanly. I cut the appendix and uploaded the beta and all is well there.
Specifically, I'm having trouble finding:
1.) Invert filament sensor logic for MK3S:
- I found filament_sensor.cpp:
typedef enum {
M600_on_edge = 0,
M600_on_level = 1,
M600_never = 2
} send_M600_on_t;
Q: Will this do it, or is there somewhere else to look? I'm in C:\Mini\Prusa-Firmware-Buddy-RELEASE-4.3.0\src
Secondly, I can't find a reference .h or .cpp for the mini (like configuration.h or the like that I'm used to seeing in other prusa/marlin folders) to change the e steps per mm to the needed 140. Anyone know where to change this at the firmware level?
I appreciate any help you good folks are willing to provide. Once I have the firmware up, tested & verified, and proven I'll share the extruder design up on thingiverse. All in all, the petg parts and gears/sensor only set me back about $25.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
So I had an idea a couple of days ago, why spend the cash on the Bondtech and external sensor for the Prusa Mini when the MK3S extruder has both?
I worked up the STL files, and the installation went really well. I now have a MK3S extruder and sensor in place, and everything appears to fit great.
I'm stuck on the firmware for the Mini, however. I pulled the git, and I have it compiling cleanly. I cut the appendix and uploaded the beta and all is well there.
Specifically, I'm having trouble finding:
1.) Invert filament sensor logic for MK3S:
- I found filament_sensor.cpp:
typedef enum {
M600_on_edge = 0,
M600_on_level = 1,
M600_never = 2
} send_M600_on_t;Q: Will this do it, or is there somewhere else to look? I'm in C:\Mini\Prusa-Firmware-Buddy-RELEASE-4.3.0\src
Secondly, I can't find a reference .h or .cpp for the mini (like configuration.h or the like that I'm used to seeing in other prusa/marlin folders) to change the e steps per mm to the needed 140. Anyone know where to change this at the firmware level?
I appreciate any help you good folks are willing to provide. Once I have the firmware up, tested & verified, and proven I'll share the extruder design up on thingiverse. All in all, the petg parts and gears/sensor only set me back about $25.
Prusa Mini invert Sensor logic:
filament_sensor.cpp
original (line 212):
static void _cycle0() {
if (gpio_get(PIN_FSENSOR) == 1) {
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLDOWN, GPIO_SPEED_FREQ_VERY_HIGH); // pulldown
status.meas_cycle = 1; //next cycle shall be 1
modified:
static void _cycle0() {
if (gpio_get(PIN_FSENSOR) == 0) {
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLDOWN, GPIO_SPEED_FREQ_VERY_HIGH); // pulldown
status.meas_cycle = 1; //next cycle shall be 1
original (line 244):
//called only in fs_cycle
static void _cycle1() {
//pulldown was set in cycle 0
_set_state(gpio_get(PIN_FSENSOR) == 1 ? FS_HAS_FILAMENT : FS_NOT_CONNECTED);
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_FREQ_VERY_HIGH); // pullup
status.meas_cycle = 0; //next cycle shall be 0
}
modified:
//called only in fs_cycle
static void _cycle1() {
//pulldown was set in cycle 0
_set_state(gpio_get(PIN_FSENSOR) == 0 ? FS_HAS_FILAMENT : FS_NOT_CONNECTED);
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_FREQ_VERY_HIGH); // pullup
status.meas_cycle = 0; //next cycle shall be 0
}
Prusa Mini change esteps:
Configuration_A3ides_2209_MINI.h
original:
* Default Axis Steps Per Unit (steps/mm)
* Override with M92
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
*/
//#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 280 } //E0 280 295
#define DEFAULT_AXIS_STEPS_PER_UNIT \
{ 100, 100, 400, 325 } //E0 280 295
//#define DEFAULT_AXIS_STEPS_PER_UNIT { 800, 800, 3200, 1120 } //E0 280 295
//#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 1120 } //E0 280 295
modified:
* Default Axis Steps Per Unit (steps/mm)
* Override with M92
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
*/
//#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 280 } //E0 280 295
#define DEFAULT_AXIS_STEPS_PER_UNIT \
{ 100, 100, 400, 140 } //E0 280 295 // E -> 140=8 microsteps (280=16 microsteps)
//#define DEFAULT_AXIS_STEPS_PER_UNIT { 800, 800, 3200, 1120 } //E0 280 295
//#define DEFAULT_AXIS_STEPS_PER_UNIT { 100, 100, 400, 1120 } //E0 280 295
Statt zu klagen, dass wir nicht alles haben, was wir wollen, sollten wir lieber dankbar sein, dass wir nicht alles bekommen, was wir verdienen.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
@karl-herbert
The new firmware syntax is a little different, but the approach was the same:
static void _cycle0() {
if (fSensor.read() == Pin::State::low) {
fSensor.pullDown();
status.meas_cycle = 1; //next cycle shall be 1
} else {
static void _cycle1() {
//pulldown was set in cycle 0
_set_state(fSensor.read() == Pin::State::low ? fsensor_t::HasFilament : fsensor_t::NotConnected);
fSensor.pullUp();
status.meas_cycle = 0; //next cycle shall be 0
I compiled, uploaded, and tested the new firmware and it checks GOOD! Thanks for the help. I've attached the resultant .bbf for anyone that wants to follow this. I'll put the link to TVerse here in a few.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
If anyone runs across this thread, here is the link: https://www.thingiverse.com/thing:4761746
I put the firmware up as well.
Enjoy!
RE: Prusa Mini with MK3S Extruder/Filament Sensor
@djkirkendall
This is quite possible. I have made these and other changes in 4.2.0. But I hope that this still helped.
A small correction to the following line:
{ 100, 100, 400, 140 } //E0 280 295 // E -> 140=8 microsteps (280=16 microsteps)
I increased E from 16 to 32 microsteps (not from 8 to 16 as stated). Currently X/Y/E=32 microsteps, Z=16 microsteps
Interesting project and thanks for making it available in Thingiverse 👍
Statt zu klagen, dass wir nicht alles haben, was wir wollen, sollten wir lieber dankbar sein, dass wir nicht alles bekommen, was wir verdienen.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
Hi Guys,
i am runing mk3s extruder since a while:
The project is here: https://www.prusaprinters.org/prints/37939-prusa-mini-mk3s-bear-ultra-upgraded
Best Regards
RE: Prusa Mini with MK3S Extruder/Filament Sensor
@3dpgva
Well done 👍
The new MK-Mini so to speak 😊
Statt zu klagen, dass wir nicht alles haben, was wir wollen, sollten wir lieber dankbar sein, dass wir nicht alles bekommen, was wir verdienen.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
@3dpgva
Neat!!
I was looking to eat Bondtech's lunch with my design.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
@3dpgva
Neat!!
I was looking to eat Bondtech's lunch with my design.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
Im having trouble finding this on Firmware 4.3.3
Can someone help me please?
/** * @file filament_sensor.cpp * @author Radek Vana * @date 2019-12-16 */ #include "filament_sensor.hpp" #include "print_processor.hpp" #include "fsensor_eeprom.hpp" #include "rtos_api.hpp" //singleton FSensor &FS_instance() { static FSensor ret; return ret; } FSensor::FSensor() : state(fsensor_t::NotInitialized) , last_state(fsensor_t::NotInitialized) , meas_cycle(0) , event_lock(0) { PrintProcessor::Init(); } /*---------------------------------------------------------------------------*/ //debug functions bool FSensor::WasM600_send() { CriticalSection C; return status.M600_sent; } char FSensor::GetM600_send_on() { switch (status.send_event_on) { case inject_t::on_edge: return 'e'; case inject_t::on_level: return 'l'; case inject_t::never: return 'n'; } return 'x'; } //simple filter //without filter fs_meas_cycle1 could set FS_NO_SENSOR (in case filament just runout) void FSensor::set_state(fsensor_t st) { CriticalSection C; if (last_state == st) state = st; last_state = st; } /*---------------------------------------------------------------------------*/ //global thread safe functions fsensor_t FSensor::Get() { return state; } //value can change during read, but it is not a problem bool FSensor::DidRunOut() { return state == fsensor_t::NoFilament; } void FSensor::M600_on_edge() { CriticalSection C; status.send_event_on = inject_t::on_edge; } void FSensor::M600_on_level() { CriticalSection C; status.send_event_on = inject_t::on_level; } void FSensor::M600_never() { CriticalSection C; status.send_event_on = inject_t::never; } /*---------------------------------------------------------------------------*/ //global thread safe functions //but cannot be called from interrupt void FSensor::Enable() { CriticalSection C; enable(); FSensorEEPROM::Set(); } void FSensor::Disable() { CriticalSection C; disable(); FSensorEEPROM::Clr(); } FSensor::inject_t FSensor::getM600_send_on_and_disable() { CriticalSection C; inject_t ret = status.send_event_on; status.send_event_on = inject_t::never; return ret; } void FSensor::restore_send_M600_on(FSensor::inject_t send_event_on) { CriticalSection C; //cannot call init(); - it could cause stacking in uninitialized state status.send_event_on = send_event_on; } fsensor_t FSensor::WaitInitialized() { fsensor_t ret = FSensor::Get(); while (ret == fsensor_t::NotInitialized) { Rtos::Delay(0); // switch to other threads ret = FSensor::Get(); } return ret; } void FSensor::ClrM600Sent() { CriticalSection C; status.M600_sent = false; } void FSensor::ClrAutoloadSent() { CriticalSection C; status.Autoload_sent = false; } uint32_t FSensor::DecEvLock() { CriticalSection C; if (event_lock > 0) --event_lock; return event_lock; } uint32_t FSensor::IncEvLock() { CriticalSection C; return ++event_lock; } /*---------------------------------------------------------------------------*/ //global not thread safe functions void FSensor::init() { bool enabled = FSensorEEPROM::Get(); if (enabled) enable(); else disable(); } void FSensor::InitOnEdge() { init(); FSensor::M600_on_edge(); } void FSensor::InitOnLevel() { init(); FSensor::M600_on_level(); } void FSensor::InitNever() { init(); FSensor::M600_never(); } /*---------------------------------------------------------------------------*/ //methods called only in fs_cycle //M600_on_edge == inject after state was changed from HasFilament to NoFilament //M600_on_level == inject on NoFilament //M600_never == do not inject void FSensor::evaluateEventConditions(event ev) { if (isEvLocked()) return; //M600 if (((status.send_event_on == inject_t::on_edge && ev == event::EdgeFilamentRemoved) || (status.send_event_on == inject_t::on_level && ev == event::NoFilament)) && !status.M600_sent && PrintProcessor::IsPrinting()) { status.M600_sent = true; PrintProcessor::InjectGcode("M600"); //change filament } //autoload if (((status.send_event_on == inject_t::on_edge && ev == event::EdgeFilamentInserted) || (status.send_event_on == inject_t::on_level && ev == event::HasFilament)) && (!status.Autoload_sent) && PrintProcessor::IsAutoloadEnabled() && !PrintProcessor::IsPrinting()) { status.Autoload_sent = true; PrintProcessor::InjectGcode("M1400 S65"); //load with return option } } FSensor::event FSensor::generateEvent(fsensor_t previous_state) const { const bool has_filament = fsensor_t::HasFilament == state; const bool had_filament = fsensor_t::HasFilament == previous_state; if (has_filament == had_filament) return has_filament ? event::HasFilament : event::NoFilament; /// state has changed if (has_filament) return event::EdgeFilamentInserted; //has && !had return event::EdgeFilamentRemoved; //!has && had } //delay between calls must be 1us or longer void FSensor::Cycle() { volatile const fsensor_t last_state_before_cycle = state; //sensor is disabled (only init can enable it) if (last_state_before_cycle == fsensor_t::Disabled) { return; } cycle(); event ev = generateEvent(last_state_before_cycle); evaluateEventConditions(ev); }
RE:
3DMYG
Not sure what do you want to do with it, but for master try here https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/master/src/common/filament_sensor.cpp
and for 4.3.3 release here https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/RELEASE-4.3.3/src/common/filament_sensor.cpp
even an old man can learn new things 🙂
Standard I3 mk3s, MMU2S, Prusa Enclosure, Fusion 360, PrusaSlicer, Windows 10
PRUSA MINI+ Prusalink + Prusa Connect
RE: Prusa Mini with MK3S Extruder/Filament Sensor
Neat idea
RE:
Hi
@djkirkendall, @karl-herbert or anyone else who has successfully modified firmware to invert filament sensor, I just completed my Mini Bear conversion and everything works as intended except the Mini's filament sensor. I have compiled my own firmware for the Bear Mini with some features to suit the Bear. I tried to invert the filament sensor logic in the Configuration_Mini.h file in /include/marlin but didn't work. The sensor value returns 1 while no filament, and 0 with filament inserted.
Then I found this post and trying to alter the firmware code in what I assume to be the corresponding file that was referenced in posts above. The new file name in 4.4.1 is called filament_sensor_photoelectric.cpp in the /src/common folder. The code in the latest firmware version seem different than prior versions above. I don't understand C++ so I'm asking for help to change the code in order to invert the Filament Sensor logic properly.
Thanks!
---------------------
/**
* @file filament_sensor_photoeletric.cpp
* @author Radek Vana
* @date 2021-02-12
*/
//there is 10kOhm PU to 5V in filament sensor
//MCU PU/PD is in range 30 - 50 kOhm
//when PD is selected and sensor is connected Vmcu = min 3.75V .. (5V * 30kOhm) / (30 + 10 kOhm)
//pin is 5V tolerant
//MCU has 5pF, transistor D-S max 15pF
//max R is 50kOhm
//Max Tau ~= 20*10^-12 * 50*10^3 = 1*10^-6 s ... about 1us
#include "filament_sensor_photoeletric.hpp"
#include "fsensor_pins.hpp"
#include "rtos_api.hpp"
static volatile fsensor_t last_state = fsensor_t::NotInitialized;
void FSensor::cycle0() {
if (FSensorPins::Get()) {
FSensorPins::pullDown();
meas_cycle = 1; //next cycle shall be 1
} else {
set_state(fsensor_t::NoFilament); //it is filtered, 2 requests are needed to change state
meas_cycle = 0; //remain in cycle 0
}
}
void FSensor::cycle1() {
//pulldown was set in cycle 0
set_state(FSensorPins::Get() ? fsensor_t::HasFilament : fsensor_t::NotConnected);
FSensorPins::pullUp();
meas_cycle = 0; //next cycle shall be 0
}
void FSensor::cycle() {
if (meas_cycle == 0) {
cycle0();
} else {
cycle1();
}
}
void FSensor::enable() {
FSensorPins::pullUp();
state = fsensor_t::NotInitialized;
last_state = fsensor_t::NotInitialized;
meas_cycle = 0;
}
void FSensor::disable() {
state = fsensor_t::Disabled;
last_state = fsensor_t::Disabled;
meas_cycle = 0;
}
//not recorded
void FSensor::record_state() {
}
//simple filter
//without filter fs_meas_cycle1 could set FS_NO_SENSOR (in case filament just runout)
void FSensor::set_state(fsensor_t st) {
CriticalSection C;
if (last_state == st)
state = st;
last_state = st;
}
RE: Prusa Mini with MK3S Extruder/Filament Sensor
For 4.2.0 I made following changes (marked blue and red):
\Prusa-Firmware-Buddy-RELEASE-4.2.0\src\common\filament_sensor.cpp
original (Zeile 212):
static void _cycle0() {
if (gpio_get(PIN_FSENSOR) == 1) {
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLDOWN, GPIO_SPEED_FREQ_VERY_HIGH); // pulldown
status.meas_cycle = 1; //next cycle shall be 1
geaendert:
static void _cycle0() {
if (gpio_get(PIN_FSENSOR) == 0) {
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLDOWN, GPIO_SPEED_FREQ_VERY_HIGH); // pulldown
status.meas_cycle = 1; //next cycle shall be 1
original (Zeile 244):
//called only in fs_cycle
static void _cycle1() {
//pulldown was set in cycle 0
_set_state(gpio_get(PIN_FSENSOR) == 1 ? FS_HAS_FILAMENT : FS_NOT_CONNECTED);
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_FREQ_VERY_HIGH); // pullup
status.meas_cycle = 0; //next cycle shall be 0
}
geaendert:
//called only in fs_cycle
static void _cycle1() {
//pulldown was set in cycle 0
_set_state(gpio_get(PIN_FSENSOR) == 0 ? FS_HAS_FILAMENT : FS_NOT_CONNECTED);
gpio_init(PIN_FSENSOR, GPIO_MODE_INPUT, GPIO_PULLUP, GPIO_SPEED_FREQ_VERY_HIGH); // pullup
status.meas_cycle = 0; //next cycle shall be 0
}
Thus, at least the status is correctly displayed, but unfortunately no outgoing filament is detected (pullup=0, pulldown=1). I can live with that 😊
wbr,
Karl
Statt zu klagen, dass wir nicht alles haben, was wir wollen, sollten wir lieber dankbar sein, dass wir nicht alles bekommen, was wir verdienen.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
@karl-herbert Thank you for replying and helping. I was able to find another post that showed where to change code for a later version of the firmware, similar to 4.4.1. I just compiled firmware with the changes and filament sensor works properly now.
Thanks!
RE: Prusa Mini with MK3S Extruder/Filament Sensor
By the way, in case anyone else was looking to do the same, I referenced a post written by user EpicMount (last posting in the thread as of now) here: https://forum.prusa3d.com/forum/hardware-firmware-and-software-help/prusa-mini-with-mk3s-extruder-and-filament-runout-sensor/
I got this to work with Firmware 4.4.1 on my Mini Bear.
RE: Prusa Mini with MK3S Extruder/Filament Sensor
Thanks for reply and happy printing 👍
wbr,
Karl
Statt zu klagen, dass wir nicht alles haben, was wir wollen, sollten wir lieber dankbar sein, dass wir nicht alles bekommen, was wir verdienen.