ArtSuzhou
Published © CC BY-NC-SA

Digital 3D Printer Filament Counter Using PS/2 Mouse

Ever wonder how much filament you actually used for a project or have an old mechanical ball mouse laying around to be recycled?

IntermediateWork in progress4 hours9,463
Digital 3D Printer Filament Counter Using PS/2 Mouse

Things used in this project

Hardware components

Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×1
Standard LCD - 16x2 White on Blue
Adafruit Standard LCD - 16x2 White on Blue
×1
Momentary Tactile Push Button Switch 12x12x7.3mm
×1
Ball Bearing – 625 2RS 5x16x5
OpenBuilds Ball Bearing – 625 2RS 5x16x5
×1
Jumper wires (generic)
Jumper wires (generic)
several
×1
Dell Logitech 2-Button PS/2 Ball Mouse M-SAW34
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Custom parts and enclosures

Thingiverse

http://www.thingiverse.com/thing:1946445

Schematics

Schematic 1

Schematic 2

Schematic 3

Code

FPK8QVDIWE4HGET.ino

Arduino
#include <Wire.h>  // Comes with Arduino IDE
#include <ps2.h>
#include <LiquidCrystal_I2C.h>
/*
 * this is a modification to the original ps2 mouse sketch, it requires ps2 library,
 * can be found on arduino website.
 * Modified by Bin Sun.
 * Feel free to use or modify.
 * an arduino sketch to interface with a   mouse ( optical, ball, ps2 and some usb).
 * it measures the distance the mouse travels.
 * a button on pin 7 is used to zero the reading.
 * one side of the button is connected to pin 7 other to ground. 
 * it writes the results to a serial display.
 */

/*
 * Pin 5 is the mouse data pin, pin 6 is the clock pin
 * Feel free to use whatever pins are convenient.
 */
PS2 mouse(6, 5);
int val = 0 ;// variable for reading the pin
long newmx=0;
long newmy=0;
long total=0;
const int zeroPin=7; // set zeroPin pin number
boolean direct = true;

int buttonState;
unsigned long timePress = 0;
unsigned long timePressLimit = 0;
int clicks = 0;

float cal=2.5; //calibratino factor to conver mouse movement to milemeter

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
 
/*
 * initialize the mouse. Reset it, and place it into remote
 * mode, so we can get the encoder data on demand.
 */
void mouse_init()
{
  mouse.write(0xff);  // reset
  mouse.read();  // ack byte
  mouse.read();  // blank */
  mouse.read();  // blank */
  mouse.write(0xf0);  // remote mode
  mouse.read();  // ack
  delayMicroseconds(100);
}

void setup()
{
  pinMode(zeroPin, INPUT_PULLUP);
  Serial.begin(9600);
//  Serial.begin(115200);
 // lcd.init();
  lcd.backlight();
  lcd.begin(16,2);  // set up the LCD's number of columns and rows: 

 // Print a message to the LCD. 
  Serial.println("Filament Counter");
  lcd.setCursor(0,0);
  lcd.print("Filament Counter");
  lcd.setCursor(5,1);
  lcd.print("Bin Sun");
  delay(2000);
  
  lcd.clear();
  checkDir();
  mouse_init();
}

void checkDir(){
  lcd.setCursor(0,0);
  lcd.print("Change Direction?");
  lcd.setCursor(0,1);
  lcd.print("Hold RESET 4 YES");
  delay(2000);
  lcd.setCursor(0,1);
  lcd.print("                ");
  boolean resetPressed = false;
  int countdown = 3;
  while (!resetPressed && countdown >= 0){
    val = digitalRead(zeroPin);
    if(val == LOW){
      lcd.clear();
      lcd.setCursor(0,1);
      lcd.print("Direct. Changed");
      delay(1000);
      resetPressed = true;
      direct=false;
      lcd.clear();
    }
    lcd.setCursor(0,2);
    lcd.print("Countdown:   ");
    lcd.setCursor(0,2);
    lcd.print("Countdown: ");
    lcd.print(countdown);
    countdown--;
    if(countdown <0){
      lcd.clear();
      lcd.setCursor(0,0);
    }
    if(resetPressed){
      lcd.clear();
      lcd.setCursor(0,0);
    }
    delay(1000);
  }
}


/*
* get a reading from the mouse and report it back to the
* host via the serial line.
*/
void loop()
{
  char mstat;
  char mx;
  char my;
 
  /* get a reading from the mouse */
  mouse.write(0xeb);  // give me data!
  mouse.read();      // ignore ack
  mstat = mouse.read();
  mx = mouse.read();
  my = mouse.read();

//reverse direction
//  mx = mx*direct;
if(direct){
  mx = mx*-1;
}

  total =  total + mx; //calculate total
  newmx=newmx+ mx;

  buttonState = digitalRead(zeroPin);

  if (buttonState == LOW){
    delay(200);
//    Serial.println("Button Pressed");
    
    if (clicks == 0) {
    timePress = millis();
    timePressLimit = timePress + 500;    
    clicks = 1;
    }

    else if (clicks == 1 && millis() < timePressLimit){
//      Serial.println("Button Pressed twice");
      newmx = 0;
      total = 0;
      timePress = 0;
      timePressLimit = 0;
      clicks = 0;      
    }    
  

 if (clicks == 1 && timePressLimit != 0 && millis() > timePressLimit){
//     Serial.println("Button Pressed Once");
     timePress = 0;
     timePressLimit = 0;
     clicks = 0;
          
     newmx=0;


  }
  }
         
//  if ( digitalRead(zeroPin) == LOW)
//   {
//     newmy=0;
//     newmx=0;
//   }
//   else {
//     newmx=newmx+ mx;
//     newmy=newmy+my;
//   }

//while(digitalRead(zeroPin) == LOW){}
//  delay(1000);
//    if(digitalRead(zeroPin) == LOW){
//     total=0;
//      }
//    else{
//    newmx = 0;
//    }  
        
//  Serial.print(mstat, BIN);
//  Serial.println();
//  Serial.print("\tX=");
 // Serial.print(mx, DEC);// gives mm reading for my mouse
//  Serial.print("\t");
//  Serial.print(newmx/(cal));// gives mm reading for my mouse
//  Serial.print("\tY=");
//  Serial.print(my, DEC);//  gives mm reading for my mouse
//  Serial.print("\t");
//  Serial.print(newmy/(cal));//  gives mm reading for my mouse
//  Serial.println();
  
  lcd.setCursor(0,0);
  lcd.print("                ");
  lcd.setCursor(0,0);
  lcd.print("U~");
  lcd.print(newmx/(cal));
  lcd.print(" mm");
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(0,1);
  lcd.print("T~");
  lcd.print(total/(cal));
  lcd.print(" mm");
  
  
  delay(100);

  
   }

   

Credits

ArtSuzhou

ArtSuzhou

5 projects • 17 followers

Comments