UMFilMON

2019-10-18 18:51:00 / Produktvorstellungen / Kommentare 0
UMFilMON - Ultimaker Filament Sensor | MYBOTSHOP.DE

UMFilMON

Der UMFilMON (Ultimaker FIlament Monitor) ist wie der Name bereits impliziert, ein kleiner Sensor, welcher den Filamentfluss überwacht und bei einer leeren Filamentspule oder bei so genanntem "Grinding", den Druck pausiert. In dem Fall kann der Nutzer den Fehler beheben und den Druck im Anschluss fortsetzen.

Vorteile im Überblick

  • Zeit sparend
  • Höhere Zuverlässigkeit
  • Ressourcen Schonend
  • Leichte Montage & Inbetriebnahme

Montageanleitung

Bei der Entwicklung war uns besonders der Aspekt der leichten Montage überaus wichtig. In diversen Foren und Blogbeiträgen findet man reichlich Nutzer, welche bereits über die Umsetzung eines solchen Sensors diskutiert haben. Jeder dieser Ansätze war jedoch mit der Anpassung der Firmware und der zusätzlichen Modifikation des Kabelbaums verbunden. Unsere Lösung lässt sich in weniger als 10 Minuten verbauen und Bedarf nur folgende Werkzeuge

  • 2mm Inbus
  • Flachzange

Nachfolgend wird die Montage in wenigen kurzen Schritten erläutert

  1. Den UM2 von der Spannung trennen
  2. Displayabdeckung an der Unterseite des Geräts lösen und abnehmen
  3. Das Kabel EXP1 abstecken, und dafür das ca. 10cm lange beiliegende Kabel in den entsprechenden Port einstecken
  4. Nun beide Kabel Kabel in die beiden gegenüber liegenden Ports des Expansion Boards, mit der Aufschrift "Ulti" einstecken.
  5. Das längere, ca. 45cm lange Kabel in einen der beiden Ports mit der Bezeichnung "FilMON" einstecken und nach hinten, in Richtung Spulenhalter führen
  6. Displayabdeckung wieder anschrauben.
  7. Zuletzt den UMFilMON Sensor mit dem langen Kabel verbinden

Inbetriebnahme

Da wir auf Software und Hardwareanpassungen seitens des Ultimakers verzichten wollten, täuscht der Sensor einen Benutzer am Bedienfeld vor.
Damit der Sensor nun den Filamentfluss überwachen kann, führen wir das Filament an der Unterseite des Sensors ein, und durchlaufen nun wie gewohnt den Menüpunkt "Change Filament" des Ultimakers.

Der an der Seite befindliche Taster kann den Sensor sowohl aktivieren als auch deaktiveren.

Aktivieren: Ein kurzer Tastendruck lässt eine kleine rote LED für 3 Sekunde blinken, welche das aktivieren symbolisiert.
Deaktivieren: EIn längerer Tastendruck für ca. 1,5-2 Sekunden lässt die LED kurz aufblicken und dann erlischen - Der Sensor wurde deaktiviert.

Hardware

Der Sensor wurde mit Circuit Studio von Altium Designer designed. Diese Software ist kostenlos und cloud basiert, sodass wir bei vorheriger Kontaktaufnahme Nutzern gerne Zugriff auf das Projekt gewähren.

Der UMFilMON basiert auf einem Atmel Atmega328P, einer sehr rudimentären 8-bit MCU, welche jedoch sehr kostengünstig (ca. 1€) zu haben ist und für unsere Aufgabenstellung vollkommen ausreichend ist. Die Messungen werden von zwei analogen Hallsensoren (DRV5056) durchgeführt, welche in dem nachfolgenden Bild als SEN0 & SEN1 beschriftet sind. Wir haben uns für zwei gegenüberliegenden Sensoren entschieden, da dadurch jede Stellung/Magnetfeldänderung zuverlässig gemessen werden kann.

Um die MCU mit dem UMFilMON Code flashen zu können, haben wir sowohl einen FTDI Bus als auch eine ISP Schnittstelle an der Unterseite integriert. Selbstverständlich ist es auch möglich den AT328P vor dem löten mit einem TQFP32 Programmer zu flashen. Jedoch ist in dem Fall darauf zu achten, den Programmer mit einem 16MHz Quarz, sowie zwei Abblockkondensatoren auszustatten

Bill of Materials

Gerber Files

Wir haben noch einige PCB's, welche wir bei Bedarf gerne verschenken würden! Bei Interesse kontaktieren Sie uns bitte über das Kontaktformular.
We have several PCB's which we would like to make a gift to everyone, who is interested in building the UMFilMON on his own. If you are interested in it, please feel free to use our contact form to get in touch.

Software

Wie bereits erwähnt ist das Board vollständig Arduino IDE kompatibel und lässt sich bei Auswahl des Arduino Nano's, bequem darüber programmieren. Wir empfehlen die Programmierung über einen USBasp Programmer, über die an der Unterseite befindliche ISP Schnittstelle vorzunehmen.


/*******************************************************************************
* Copyright 2019 MYBOTSHOP.DE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

#define BLINK_RATE    500     // Blinking rate of LED
#define DEBOUNCE_TIME 150      // Debounce Time of the Button
#define LONG_PRESS    1000    // Duration of Long Press
#define INTERVAL_SHORT 5999
#define INTERVAL_LONG  5999   // 30 Second duration for the idle

#define D2  2
#define LED 3
#define BUTTON 4
#define S1 A0                 // Sensor
#define S2 A1
#define abs(x) ((int16_t)(x))<0 ? (-x):(x)

enum {OFF, BLINK, ON} LedState = OFF , nextState = OFF;

volatile bool debounce = LOW, isActive = LOW, isDetected = LOW;
volatile uint16_t ButtonPress = 0, Error_Blink = 0, counter = 0, Blink = 0, Duration = 0, 
               INTERVAL = INTERVAL_SHORT, NO_ACTIVITY_TIMELIMIT;

void setup() {
  PCICR |= _BV(PCIE2);
  PCMSK2 |= _BV(PCINT20);
  pinMode(LED, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  digitalWrite(2, LOW);
  digitalWrite(LED, LOW);
  Serial.begin(115200);
}

void loop() {
  ButtonState();  // monitors Button state, pressed or LongPressed
  LEDStatus();    // Controls the LED , OFF or BLINKING
  detectPulse();  // Reads Pulse from sensor
  if (!isActive )
  {
    if (abs((uint16_t)millis() - Error_Blink) >= 300)
      digitalWrite(2, LOW);
  }
}

uint8_t detectPulse ()
{
  static int16_t lastValue_1, lastValue_2, lastTick = 0;
  uint16_t presentValue_1, presentValue_2;
  if (abs((uint16_t)millis() - lastTick) > INTERVAL)
  {
    if (isActive)
    {
      // read the sensor value for every 1mS
      presentValue_1 = analogRead(S1);
      presentValue_2 = analogRead(S2);
      uint16_t error_1 = presentValue_1 - lastValue_1;
      uint16_t error_2 = presentValue_2 - lastValue_2;
      Serial.print("L 1:");
      Serial.println(lastValue_1);
      Serial.print("L 2:");
      Serial.println(lastValue_2);
      error_1 = abs(error_1);
      error_2 = abs(error_2);
      if ((error_1 >= 3) || (error_2 >= 3))
      {
        counter = 0;
        isDetected = HIGH;
      }
      lastValue_1 = presentValue_1;
      lastValue_2 = presentValue_2;
      lastTick = (uint16_t)millis();
      // if counter value exceeds 30000 then sends error signal and turns off the sensor
      if (isDetected && (counter++ >= NO_ACTIVITY_TIMELIMIT))
      {
        isDetected = LOW;
        Serial.println("Error detected! Pause printing!");
        Error();
      }
      Serial.print("E 1:");
      Serial.println(error_1);
      Serial.print("E 2:");
      Serial.println(error_2);
    }
    else
      lastValue_1 = analogRead(S1);
      lastValue_2 = analogRead(S2);
  }
}

// Error State Characteristics
void Error()
{
  LedState = BLINK;
  Duration = 2000;
  Blink = Error_Blink = (uint16_t)millis();
  digitalWrite(2, HIGH);
  isActive = LOW;
  nextState = OFF;
  counter = 0;
}

// LED Status
void LEDStatus()
{
  static uint16_t lastTick = 0;
  switch (LedState) {
    case OFF : {
        digitalWrite(LED, LOW); break;
      }
    case BLINK: {
        if ((abs((uint16_t)millis() - Blink)) < Duration )
        {
          if ((abs((uint16_t)millis() - lastTick)) > BLINK_RATE )
          {
            lastTick = (uint16_t)millis();
            digitalWrite(LED, !digitalRead(LED)); // Toggles LED
          }
        }
        else
          LedState = nextState;
        break;
      }
    case ON: {
        digitalWrite(LED, HIGH); break;
      }
  }
}

// interrupt for Button press detection
ISR(PCINT2_vect)
{
  if (!digitalRead(BUTTON))
  {
    ButtonPress = (uint16_t)millis();
    debounce = HIGH;
  }
}


// Monitors Button state and press event
void ButtonState()
{
  static uint8_t press;
  uint16_t tick = abs((uint16_t)millis() - ButtonPress);
  if (debounce && (tick > DEBOUNCE_TIME))
  {
    if (digitalRead(BUTTON) || (tick > LONG_PRESS))
    {
      debounce = LOW;
      if (tick < LONG_PRESS)  // short press
      {
        if (++press >= 4 )
        {
        //  press = 0;
        //  Duration = 5000;
        //  INTERVAL = INTERVAL_LONG;
        //  NO_ACTIVITY_TIMELIMIT = (25000/(INTERVAL + 1));
     //  }
     //   else
    //  {
         Duration = 3000;
         INTERVAL = INTERVAL_SHORT;
         NO_ACTIVITY_TIMELIMIT = (25000/(INTERVAL + 1));
        }
        Blink = (uint16_t)millis();
        LedState = BLINK;
        Serial.print("Interval = ");
        Serial.println(NO_ACTIVITY_TIMELIMIT);
        digitalWrite(2, LOW);
        isActive = HIGH;
        nextState = ON;
      }
      else                    // long press
      {
        Error();
      }
    }
  }
}


News

Unsere Instagram FEEDS

Social Media

Folgen Sie uns doch auch auf eine der folgenden Social Media Kanälen: