3D Printed Ball Mill

https://www.thingiverse.com/thing:2713357
Product: https://www.tindie.com/products/williambailes/plex-controller/
Product:

This ball mill was made for grinding sand and cleaning objects like rusty bolts. It works but takes a very long time to grind sand down, this is because of the size of the balls are too small. Getting larger balls will help.
Some professionals that design and manufacture mill for industry helped in the design of the lifter and the correct speed for milling. The professionals were interested in how long it would take for the lining of the mill to be worn out. This is yet to be tested.
The parts can be found here: https://www.thingiverse.com/thing:2713357

Circuit and program:

https://github.com/tinkersprojects/Ball-Mill

Operation:

After powering the mill with 12V DC power, settings can be seen/changed using the LCD and can be altered using the 3 buttons (up, down and enter). Speed and duration are the 2 settings that can be set to control the mill. While the mill is in operation, the LCD will display the current speed and the time left of milling. By pressing the enter button, the mill will stop.

parts list:

1 x controller, PLEX or Arduino UNO (see below for more details)
1 x photo interupt
2 x 20mm M3 srew
2 x 20mm M3 srew
1 x 100mm M8 bolt
2 x 60mm M8 bolt
4 x M8 nut
4 x 608 bearing
1 x 12V 688RPM 9Kg.cm geared DC motor, part no.:JGB37-550 (https://www.aliexpress.com/item/Free-Shipping-12V-688RPM-9Kg-cm-high-power-High-torque-miniature-dc-gear-motor-motors-JGB37/32776724375.html?spm=a2g0s.9042311.0.0.JbnZ7R)
4 x rubber feet
100 x 6mm-10mm ball bearings

Controller:

The controller used is the PLEX board from https://tinkersprojects.com/project/plex-controller/ (an Arduino UNO can be used instead). The controller Uses a 16×2 LCD and buttons inputs to set settings display speed/timer while in operation. A photo interrupt and encoder are used to calculate the speed of the mill to be compared to the set speed. This comparison is analyzed and an output is used to control a MOSFET for the motor.

NOTE:

A diode and capacitor were used to block current drawn from the controller to the DC motor. If not used the controller will rest.

Code for Project

GNU General Public License v3.0

#include <LiquidCrystal.h>
#include <Plex.h>

double currentspeed,nextspeed,finalspeed;

LiquidCrystal lcd(2, 4, 5, 6, 7, 8);

#define en 10
#define PulsePin 3

#define upbutton 5
#define selectbutton 6
#define downbutton 7

#define OutPin 19

int unsigned millspeed = 90;
int unsigned milltime = 1;
bool millrun = 1;

void setup() 
{
  lcd.begin(16, 2);
  
  pinMode(PulsePin, INPUT);
  pinMode(en, OUTPUT);
  pinMode(OutPin, OUTPUT);
  digitalWrite(en, HIGH);
  setupPlex();
  digitalWrite(OutPin,LOW);
  selectB(3);
}

void loop() 
{
  millrun = 1;
  digitalWrite(en, HIGH);
  
  lcd.clear();
  lcd.print("Speed");  
  while(digitalReadC(selectbutton) == LOW)
  {  
    lcd.setCursor(0,1);
    lcd.print(millspeed);
    lcd.print(" rpm      ");
    delay(100);
    if(digitalReadC(upbutton) == HIGH)millspeed++;
    if(digitalReadC(downbutton) == HIGH)millspeed--;
    if(millspeed > 180) millspeed = 180;
    if(millspeed < 10) millspeed = 10;
  }

  delay(100);
  while(digitalReadC(selectbutton) == HIGH);
  delay(100);

  lcd.clear();
  lcd.print("Time");  
  while(digitalReadC(selectbutton) == LOW)
  {  
    lcd.setCursor(0,1);
    lcd.print(milltime);
    lcd.print(" mins      ");
    delay(100);
    if(digitalReadC(upbutton) == HIGH)milltime++;
    if(digitalReadC(downbutton) == HIGH)milltime--;
    if(milltime > 60) milltime = 60;
    if(milltime < 1) milltime = 1;
  }

  delay(100);
  while(digitalReadC(selectbutton) == HIGH);
  delay(100);

  lcd.clear();
  lcd.print("Start milling");  
  while(digitalReadC(selectbutton) == LOW)
  {  
    lcd.setCursor(0,1);
    if(millrun)
    {lcd.print("Yes");}
    else
    {lcd.print("No ");}
    
    delay(100);
    if(digitalReadC(upbutton) == HIGH)millrun = 1;
    if(digitalReadC(downbutton) == HIGH)millrun = 0;
  }

  delay(100);
  while(digitalReadC(selectbutton) == HIGH);
  delay(100);

  if(!millrun){return;}

  lcd.clear();
  lcd.print("Runnning");
  
  long unsigned timefromstart = millis() + (milltime*60000);
  
  digitalWrite(OutPin, HIGH);

  delay(50);
  finalspeed = millspeed;

  while(millis() < timefromstart)
  {
    unsigned long Pulselow = pulseIn(PulsePin, LOW);
    unsigned long Pulsehigh = pulseIn(PulsePin, HIGH);
    unsigned long Pulsetotal = (Pulselow+Pulsehigh);

    float PulsetotalSeconds = (long)Pulsetotal*0.000001f;
    //unsigned long f = 1/PulsetotalSeconds;
    currentspeed = 1/(PulsetotalSeconds*15)*12;

    if(currentspeed<finalspeed)
    {
      digitalWrite(OutPin, HIGH);
    }
    else
    {
      digitalWrite(OutPin, LOW);
    }
    if(digitalReadC(selectbutton) == HIGH)break;

    
    long unsigned timeleft =  timefromstart - millis();
    lcd.setCursor(0,0);
    lcd.print(timeleft/60000);
    lcd.print(":");
    lcd.print(timeleft/1000%60);
    lcd.print("      ");

    lcd.setCursor(0,1);
    lcd.print("RPM: ");
    if(currentspeed<100) lcd.print(" ");
    lcd.print((int)currentspeed);
    lcd.print("       ");
  }
  digitalWrite(OutPin, LOW);

  lcd.clear();
  lcd.print("Finished"); 
  
  delay(100);
  while(digitalReadC(selectbutton) == HIGH);
  delay(100);
  while(digitalReadC(selectbutton) == LOW) {}
  delay(100);
  while(digitalReadC(selectbutton) == HIGH);
  delay(100);
}

Latest Projects

Popular Projects