• This Forum is for adults 18 years of age or over. By continuing to use this Forum you are confirming that you are 18 or older. No content shall be viewed by any person under 18 in California.

Induction brass annealer redux

Having finally waded through this wealth of information, I'm getting ready to start my build. I already have a home-built annealer using a propane torch, but this will be so much more accurate.

@KeeWay , do you have a wiring diagram for your design? I've built a 3D printer and a laser engraver using Arduino and Nema17 motors and would love to base my annealer off your design.

@mktacop i don't have a real wiring design just threw together a fritzing design, there is a diagram included in the arduino code download in my earlier post.
 
@KeeWay Thnk you. If there is a frtzing design included that will be great. I can't download the files on my work computer, so I'll check them out when I get home.

One other question, would the 4.3" Nextion screen require any changes to the code? I'd rather go with a slightly larger screen if it doesn't require any refactoring.
 
@KeeWay Thnk you. If there is a frtzing design included that will be great. I can't download the files on my work computer, so I'll check them out when I get home.

One other question, would the 4.3" Nextion screen require any changes to the code? I'd rather go with a slightly larger screen if it doesn't require any refactoring.

unfortunately it would require changes to the layout in the nextion software as the screen resolutions with the 5" and up are a larger resolution. the images would need to be resized and hot spots would need to be shifted to the resized images, the actual code should be ok i believe.
 
unfortunately it would require changes to the layout in the nextion software as the screen resolutions with the 5" and up are a larger resolution. the images would need to be resized and hot spots would need to be shifted to the resized images, the actual code should be ok i believe.

Thanks. I'll stick with the same size screen in that case. I appreciate the responses! I may have more questions as this progresses, if you don't mind answering.
 
thanks for the suggestions, i think that by increasing the copper tubing to 3/16" the height of the coil also increased and having the shelf at 1/2" thick makes the 308 case mouth a couple coils below the top with the shelf at the bottom of the coil. i guess i might change back to the 1/8" tubing but it almost seems like you need a super pump to push water through it because my current brushless pump is rated at 380GPH with about 11ft of lift and it barely pushes any water through the 3/16" tubing. what pumps are good to push water through the 1/8" tubing?

thanks
James

I use a small peristaltic pump, they can generate high pressure. And you can change the pump volume by changing tubing OD and keeping wall thickness the same. The only issue with these is the planetary gears are toothless so the gearset needs to stay clean and dry, with some rosin for traction.

https://www.mouser.com/ProductDetail/Adafruit/1150?qs=/ha2pyFaduhz4H9xHAHKV56SmHv1BaNrakkNEg8icNA=
 
@KeeWay. Hi KeeWay, struggling to get the Arduino Due Sketch to compile. Have checked that all libraries are correct as i can see it but still not working. Would you be willing to PM to to see what i am doing wrong. Rest of parts almost all here so looking forward to overcoming this hurdle.
 
Well it dont look pretty (proof fitting) but i think it will work, but im stuffed when it comes to the arduino code fault finding :)
 

Attachments

  • 20190928_165518.jpg
    20190928_165518.jpg
    296 KB · Views: 302
Well it dont look pretty (proof fitting) but i think it will work, but im stuffed when it comes to the arduino code fault finding :)
WOW do you make under statements often. No really, we all started there at some point. I see a lot of work there, it all is a learning experience. I'm sure once we see a final, finished photo, it will look and work great.
Gina
 
Been awhile since I've looked at this code but for those wanting ideas to share see the code below. It was setup for a 4 row LCD with a lighted rotary knob encoder for the user input. I needed to make a menu selection for some of the settings but never got around to it. It has a water flow sensor that stops the sequence if the water isn't flowing. The thermistor temperature readings are useful but the fan speed control isn't worth it given the temperature quickly rises and full speed is soon needed anyway. The induction timing sequence can be stopped by pressing the encoder button which is useful in aborting if things start to glow red too soon. Time can also be changed on the fly.

Code:
/**********************************
 * Annealing Circuit              *
 * By SMO 07/25/2018              *
 **********************************/

#include <Button.h> //note that this is a different version than the standard button help, it can be found at https://github.com/slavianp/improc/tree/master/Arduino/src/Library
#include <TicksPerSecond.h> // this can be found at https://github.com/slavianp/improc/tree/master/Arduino/src/Library
#include <RotaryEncoderAcelleration.h> // this can be found at https://github.com/slavianp/improc/tree/master/Arduino/src/Library
#include <Metro.h>
#include <elapsedMillis.h>
#include <LiquidCrystal_I2C.h>
//#include <Servo.h>
#include <EEPROM.h>
#include <PinChangeInterrupt.h>
#include <PID_v1.h>
#include <PWM.h>

// Assign I/O pins (Traffic Cop)
#define Encoder_A_Pin 2
#define Encoder_B_Pin 3
#define Encoder_Button_Pin 4
#define Encoder_LED_BLU_Pin 11
#define Encoder_LED_GRN_Pin 12
#define Encoder_LED_RED_Pin 13  // Note that LED is also on pin 13, avoid using as input except UNO board with buffer to LED
#define Case_Sensor_Pin 5
#define Relay_Output_Pin 6
#define Solenoid_Pin 7
//#define Drop_Servo_Pin 7
#define Flow_Sensor_Pin 8
#define Fan_PWM_Pin 9 // analogwrite pins on ATmega328p can only be on 3,5,6,9,10&11
#define Fan_RPM_Pin 10


#define Analog_Amps_Pin A0
#define Analog_Volt_Pin A1
#define Analog_Temp1_Pin A2
#define Analog_Temp2_Pin A3

// Thermistor Values
#define Thermistor_Nom     10000 //Resistance at 25 DegC
#define Thermistor_Temp    25    //Nominal temperature in DegC
#define Thermistor_Beta    3435  //Beta coefficient for thermistor
#define Thermistor_Res     10000 //Value of resistor in series with thermistor

// Initialize I/O values
boolean Relay_State = LOW;
boolean Pushbutton_State = LOW;
boolean Case_Sensor_State = LOW;
boolean Solenoid_State = LOW;
float Analog_Pot_Val = 0;
float Analog_Volt_Val = 0;
float Analog_Amps_Val = 0;
float Max_Amps_Val = 0;
float Analog_Temp1_Val = 0;
float Temp1_Steinhart_Val = 0;
float Analog_Temp2_Val = 0;
float Temp2_Steinhart_Val = 0;

// Initialize other values
int Seq_Step_Num = 1;
int Timer_Setpt = 0;
int Timer_Display = 0;
int Load_Delay_Setpt = 0500; //Delay time in mSEC, gives time for a brass to get into position for annealing
int Drop_Delay_Setpt = 0010; //Delay time in mSEC, gives time for the servo to get into drop position
int Case_Delay_Setpt = 0500; //Delay time in mSEC, gives time for brass to drop and clear the servo
int Home_Delay_Setpt = 0010; //Delay time in mSEC, gives time for the servo to get into home position
int Drop_Pos_Setpt = 90; //in degrees
int Home_Pos_Setpt = 0; //in degrees
volatile long Flow_Total = 0;
volatile long Flow_Interlock_Total = 0;
int Flow_Interlock_Val = 0;
float Flow_Rate = 0;
volatile boolean Button_Toggle_State = 0;
float Joules_Total = 0;
volatile long Fan_RPM_Total = 0;
int Fan_RPM_Rate = 0;
boolean Encoder_Inc = LOW;

// Set Memory location for last time setpoint, setpoint will be saved when power is down
int eeAddress = 0;
float eeData = 0;

// Setup PID for Fan Control
double PID_SP=1000, PID_PV, PID_OP, PID_Kp=2, PID_Ki=0.1, PID_Kd=.5; //Setpoint is multiplied by 10, example 950=95.0 degF
PID FanPID(&PID_PV, &PID_OP, &PID_SP, PID_Kp, PID_Ki, PID_Kd, REVERSE);

// Sequence Descriptions
char *Seq_Step_Desc[] = {
// 12345678901234567892  20 characters max
  "Step 0; not used    ",
  "Step 1; press start ",
  "Step 2; load case   ",
  "Step 3; load delay  ",
  "Step 4; start anneal",
  "Step 5; time anneal ",
  "Step 6; stop anneal ",
  "Step 7; drop pos    ",
  "Step 8; drop delay  ",
  "Step 9; case clear? ",
  "Step10; clear delay ",
  "Step11; home pos    ",
  "Step12; home delay  ",
  "Step13; Return      ",
  "Step14; Check Flow  ",
  "Step15; HIGH AMPS   "
};

// Set the LCD address and 20x4 display also define extra characters
LiquidCrystal_I2C lcd(0x20, 20, 4);
char Print_Buffer[40] = "";
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif
uint8_t Up_Arrow[8] = {0x04, 0x0E, 0x15, 0x04, 0x04, 0x04, 0x04, 0x00}; //Define Up Arrow for LCD
uint8_t Dn_Arrow[8] = {0x00, 0x04, 0x04, 0x04, 0x04, 0x15, 0x0E, 0x04}; //Define Down Arrow for LCD

//Configure Metro Objects
Metro LCD_Print_Data = Metro(10);
Metro Analog_Inputs_Read = Metro(10);
Metro Flow_Calculation = Metro(10000);
Metro Flow_Interlock = Metro(1000);
Metro Joules_Calculation = Metro(100);
Metro Fan_RPM_Calculation = Metro(6000);

//Configure Timers
elapsedMillis Timer_Actual;
elapsedMillis Button_Debounce;

//Configure Servos
//Servo Drop_Servo;

//Configure Encoder
RotaryEncoderAcelleration Encoder_Knob;

void UpdateEncoder(){
  Encoder_Knob.update();
}

/***************************
 * Setup Program Begin     *
 ***************************/
void setup() {
  //Assign pin modes
  pinMode(Relay_Output_Pin, OUTPUT);
  pinMode(Solenoid_Pin, OUTPUT);
  pinMode(Fan_PWM_Pin, OUTPUT);
  pinMode(Fan_RPM_Pin, INPUT_PULLUP);
  pinMode(Case_Sensor_Pin, INPUT_PULLUP);
  pinMode(Flow_Sensor_Pin, INPUT_PULLUP);
  pinMode(Encoder_Button_Pin, INPUT);
  pinMode(Encoder_LED_BLU_Pin, OUTPUT);
  pinMode(Encoder_LED_GRN_Pin, OUTPUT);
  pinMode(Encoder_LED_RED_Pin, OUTPUT);

  //Get last setpoint before power down to set initial encoder setpoint
  EEPROM.get(eeAddress, eeData); 

  //Initialize Encoder
  Encoder_Knob.initialize(Encoder_A_Pin, Encoder_B_Pin);
  Encoder_Knob.setMinMax(50, 2000);
  Encoder_Knob.setPosition(eeData); //Initialize Encoder Position with saved data
  attachInterrupt(0, UpdateEncoder, CHANGE);
 
  //Initialize LCD
  lcd.begin();
  lcd.backlight();
  lcd.createChar(0, Up_Arrow);
  lcd.createChar(1, Dn_Arrow);

  //Set initial postion for Drop Servo
  /*
  Drop_Servo.attach(Drop_Servo_Pin);
  Drop_Servo.write(Drop_Pos_Setpt);
  delay(Drop_Delay_Setpt);
  Drop_Servo.write(Home_Pos_Setpt);
  delay(Drop_Delay_Setpt);
  */

  //Setup PID
  FanPID.SetOutputLimits(100, 255);
  FanPID.SetMode(AUTOMATIC);

  //Setup PWM frequency
  InitTimersSafe(); //Initialize all timers except for 0, to save time keeping functions
  SetPinFrequencySafe(Fan_PWM_Pin, 25000); //Set frequency to 25khz
 
  //Set the flow meter pin change interrupt
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(Flow_Sensor_Pin), Flow_Rising, RISING);

  //Sense positive transition of button interrupt
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(Encoder_Button_Pin), Push_Button_Toggle, RISING);

  //Set the fan RPM pin change interrupt
  attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(Fan_RPM_Pin), Fan_RPM_Rising, RISING);
}


/***************************
 * Main Program Loop Begin *
 ***************************/
void loop() {
  //Write Digital Outputs
  digitalWrite(Relay_Output_Pin, Relay_State);
  digitalWrite(Solenoid_Pin, Solenoid_State);

  // Read Digital Inputs
  // Pushbutton_State = !digitalRead(Pushbutton_Pin);  //this button is normally closed
  Pushbutton_State = digitalRead(Encoder_Button_Pin);  //this button is normally open
  Case_Sensor_State = digitalRead(Case_Sensor_Pin); //This sensor is normally open

  // Read Analog & Do PID's
  if(Analog_Inputs_Read.check() == 1){
    //To smooth analog signals use a single Pole Digital Filter [out=wt*out+(1-wt)*new]
    Analog_Amps_Val = 0.50 * Analog_Amps_Val + 0.50 * ((analogRead(Analog_Amps_Pin) / 1023.0 * 5000.0 - 5000.0/2.0)/100.0);
    Analog_Volt_Val = 0.75 * Analog_Volt_Val + 0.25 * (analogRead(Analog_Volt_Pin) * 0.079101); // span is 80 volts or 80/1023=0.078201 adjust as needed for accuracy
    Analog_Temp1_Val = 0.95 * Analog_Temp1_Val + 0.05 * (10000.0 / ((1023.0 / analogRead(Analog_Temp1_Pin)) - 1));
    Temp1_Steinhart_Val = Analog_Temp1_Val / Thermistor_Nom;
    Temp1_Steinhart_Val = log(Temp1_Steinhart_Val);
    Temp1_Steinhart_Val /= Thermistor_Beta;
    Temp1_Steinhart_Val += 1.0 / (Thermistor_Temp + 273.15);
    Temp1_Steinhart_Val = 1.0 / Temp1_Steinhart_Val;
    Temp1_Steinhart_Val -= 273.15;
    Temp1_Steinhart_Val = Temp1_Steinhart_Val * 1.8 + 32.0;
    PID_PV = Temp1_Steinhart_Val * 10.0;
    FanPID.Compute();
    pwmWrite(Fan_PWM_Pin, PID_OP);
    Analog_Temp2_Val = 0.95 * Analog_Temp2_Val + 0.05 * (10000.0 / ((1023.0 / analogRead(Analog_Temp2_Pin)) - 1));
    Temp2_Steinhart_Val = Analog_Temp2_Val / Thermistor_Nom;
    Temp2_Steinhart_Val = log(Temp2_Steinhart_Val);
    Temp2_Steinhart_Val /= Thermistor_Beta;
    Temp2_Steinhart_Val += 1.0 / (Thermistor_Temp + 273.15);
    Temp2_Steinhart_Val = 1.0 / Temp2_Steinhart_Val;
    Temp2_Steinhart_Val -= 273.15;
    Temp2_Steinhart_Val = Temp2_Steinhart_Val * 1.8 + 32.0;
  }

  // Calculate Flow Rate
  if(Flow_Calculation.check() == 1){
    Flow_Rate = (Flow_Total / 10.0) * 0.68913; //Flow meter; 1380 pulses/Liter or 5224 pulses/gal, gph = pps * 3600/5224 or .68913
    Flow_Total = 0;
  }
 
  // Calculate Flow Interlock
  if(Flow_Interlock.check() == 1){
    Flow_Interlock_Val = Flow_Interlock_Total;
    Flow_Interlock_Total = 0;
  }

  // Calculate Fan RPM's
  if(Fan_RPM_Calculation.check() == 1){
    Fan_RPM_Rate = Fan_RPM_Total * 10 / 2;
    Fan_RPM_Total = 0;
  }
 
  // Read Encoder
  long Encoder_Val = Encoder_Knob.getPosition();
  if(Seq_Step_Num == 1){
    Encoder_Inc = Encoder_Knob.isIncrementing();
  }

  // Calculate Timer Setpoint
  Timer_Setpt = float(Encoder_Val) * 10.0;

  // Calculate Joules (not accurate because of analog reading can only occur so fast)
  if(Joules_Calculation.check() == 1 & Seq_Step_Num == 5){
    Joules_Total = Joules_Total + Analog_Amps_Val * Analog_Volt_Val * 0.100;
  }

  // Set Debounce timer to max value to avoid rollover of value
  if(Button_Debounce >= 10000){
    Button_Debounce = 10000;
  }

  // Begin Sequence Logic
  switch(Seq_Step_Num){
    // Step 1 Wait for pushbutton toggle ON
    case(1):
      //Encoder LED's are reverse logic, Zero is ON
      digitalWrite(Encoder_LED_BLU_Pin, 1);
      digitalWrite(Encoder_LED_GRN_Pin, 1);
      digitalWrite(Encoder_LED_RED_Pin, 1);
      if(Button_Toggle_State == HIGH){
        //Encoder LED's are reverse logic, Zero is ON
        digitalWrite(Encoder_LED_BLU_Pin, 1);
        digitalWrite(Encoder_LED_GRN_Pin, 0);
        digitalWrite(Encoder_LED_RED_Pin, 1);
        Seq_Step_Num++;
        break;
      }
      break;
      
    // Step 2 Wait for Case, also store setpoint if changed
    case(2):
      //Only store new setpoint if it has changed
      if(eeData != Timer_Setpt){
        eeData = Timer_Setpt / 10.0;
        EEPROM.put(eeAddress, eeData);
      }
      if(Case_Sensor_State == LOW){
        Timer_Actual = 0;
        Seq_Step_Num++;
        break;
      }
      if(Button_Toggle_State == LOW){
        Seq_Step_Num = 1;
        break;
      }
      break;
 
    // Step 3 Wait for Load Case Delay
    case(3):
      if(Case_Sensor_State == LOW & Timer_Actual >= Load_Delay_Setpt){
        Seq_Step_Num++;
        break;
      }
      if(Case_Sensor_State == HIGH){
        Seq_Step_Num = 2;
        break;
      }
      break;

    // Step 4 Initialize annealing timer and Energize Relay
    case(4):
      Timer_Actual = 0;
      Max_Amps_Val = Analog_Amps_Val;
      Relay_State = HIGH;
      Joules_Total = 0;
      Joules_Calculation.reset();
      //Encoder LED's are reverse logic, Zero is ON
      digitalWrite(Encoder_LED_BLU_Pin, 1);
      digitalWrite(Encoder_LED_GRN_Pin, 1);
      digitalWrite(Encoder_LED_RED_Pin, 0);
      Seq_Step_Num++;
      break;

    // Step 5 Wait for Timer at Setpoint
    case(5):
      Timer_Display = Timer_Actual;
      Max_Amps_Val = Analog_Amps_Val;
      if(Timer_Actual >= Timer_Setpt || Button_Toggle_State == LOW){
        Timer_Display = Timer_Actual;
        Seq_Step_Num++;
        break;
      }
      // if the amps go high then goto step 15
      if(Analog_Amps_Val > 14.0){
        Seq_Step_Num = 15;
        break;
      }
      // if low flow then goto step 14
      if(Flow_Interlock_Val <= 4){
        Seq_Step_Num = 14;
        break;
      }     
      break;

    // Step 6 Denergize Relay
    case(6):
      Relay_State = LOW;
      //Encoder LED's are reverse logic, Zero is ON
      digitalWrite(Encoder_LED_BLU_Pin, 0);
      digitalWrite(Encoder_LED_GRN_Pin, 1);
      digitalWrite(Encoder_LED_RED_Pin, 1);
      Seq_Step_Num++;
      break;

    // Step 7 Set Drop Servo to drop position & Reset Timer
    case(7):
      Timer_Actual = 0;
      //Drop_Servo.write(Drop_Pos_Setpt);
      Solenoid_State = HIGH;
      Seq_Step_Num++;
      break; 

    // Step 8 Wait for drop position
    case(8):
      if(Timer_Actual >= Drop_Delay_Setpt){
        Seq_Step_Num++;
        break;
      }
      break;

    // Step 9 Check for case clear & Reset Timer
    case(9):
      Timer_Actual = 0;
      if(Case_Sensor_State == HIGH){
        Seq_Step_Num++;
        break;
      }
      break; 

    // Step 10 Wait for case to clear
    case(10):
      if(Timer_Actual >= Case_Delay_Setpt){
        Seq_Step_Num++;
        break;
      }
      break;
      
    // Step 11 Set Servo to Home Position & Reset Timer
    case(11):
      Timer_Actual = 0;
      //Drop_Servo.write(Home_Pos_Setpt);
      Solenoid_State = LOW;
      Seq_Step_Num++;
      break; 

    // Step 12 Wait for servo home
    case(12):
      if(Timer_Actual >= Home_Delay_Setpt){
        Seq_Step_Num++;
        break;
      }
      break;

    // Step 13 Return to Step 1
    case(13):
      if(Button_Toggle_State == HIGH){
        digitalWrite(Encoder_LED_BLU_Pin, 1);
        digitalWrite(Encoder_LED_GRN_Pin, 0);
        digitalWrite(Encoder_LED_RED_Pin, 1);
        Seq_Step_Num = 2;
        break;
      }
      else{
        Seq_Step_Num = 1;
        break;
      }
      break;

    // Step 14 Check for flow
    case(14):
      Relay_State = LOW;
      //Encoder LED's are reverse logic, Zero is ON
      digitalWrite(Encoder_LED_BLU_Pin, 0);
      digitalWrite(Encoder_LED_GRN_Pin, 1);
      digitalWrite(Encoder_LED_RED_Pin, 1);
      if(Button_Toggle_State == LOW){
        Seq_Step_Num = 7;
        break;
      }
      break;

    // Step 15 HIGH AMPS
    case(15):
      Relay_State = LOW;
      //Encoder LED's are reverse logic, Zero is ON
      digitalWrite(Encoder_LED_BLU_Pin, 0);
      digitalWrite(Encoder_LED_GRN_Pin, 1);
      digitalWrite(Encoder_LED_RED_Pin, 1);
      if(Button_Toggle_State == LOW){
        Seq_Step_Num = 7;
        break;
      }
      break; 
  }
 
  // Write to LCD Display except for last 150mSec of timer to prevent overshoot from writing to I2C, didn't want the complexity of a timer interrupt
  if(LCD_Print_Data.check() == 1 && (Timer_Actual <= Timer_Setpt - 150 || Seq_Step_Num != 5)){
    //1st LCD Row
    lcd.home();
    lcd.print("Set;");
    lcd.setCursor(4,0);
    dtostrf(float(Timer_Setpt)/1000, 5, 2, Print_Buffer);
    lcd.print(Print_Buffer);
    lcd.print(" Act ");
    dtostrf(float(Timer_Display)/1000, 6, 3, Print_Buffer);
    lcd.print(Print_Buffer);

    //2nd LCD Row
    lcd.setCursor(0,1);
    dtostrf(Analog_Volt_Val, 4, 1, Print_Buffer);
    lcd.print(Print_Buffer);
    lcd.print("V");
    lcd.setCursor(6,1);
    if(Encoder_Inc){
      dtostrf(Fan_RPM_Rate, 4, 0, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.print("RPM");
    }
    else{
      dtostrf(Joules_Total, 5, 0, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.print("J ");   
    }
    lcd.setCursor(13,1);
    if(Seq_Step_Num == 5){
      dtostrf(Analog_Amps_Val, 5, 1, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.print(" A");
    }
    else{
      dtostrf(Max_Amps_Val, 5, 1, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.printByte(0); //Print Up Arrow
      lcd.print("A");
    }

    //3rd LCD Row
    lcd.setCursor(0,2);
    if(Encoder_Inc){
      lcd.print("T1;");
      dtostrf(Temp1_Steinhart_Val, 5, 1, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.print("F  ");
      lcd.setCursor(11,2);
      lcd.print("T2;");
      dtostrf(Temp2_Steinhart_Val, 5, 1, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.print("F");
    }
    else{
      lcd.print("F; ");
      dtostrf(Flow_Rate, 4, 1, Print_Buffer);
      lcd.print(Print_Buffer);
      lcd.print(" gph  ");
      lcd.setCursor(13,2);
      if(Case_Sensor_State == LOW){
        lcd.print("Case; Y");
      }
      else{
        lcd.print("Case; N");
      }
    }

    //4th LCD Row
    lcd.setCursor(0,3);
    lcd.print(Seq_Step_Desc[Seq_Step_Num]); 
  }
}

/***************************
 * Flow Meter Interrupt    *
 ***************************/
 void Flow_Rising(void){
  Flow_Total++;
  Flow_Interlock_Total++;
 }

/***************************
 * Fan RPM Interrupt       *
 ***************************/
 void Fan_RPM_Rising(void){
  Fan_RPM_Total++;
 }

/*********************************
 * Positive Transition Sense     *
 *********************************/
void Push_Button_Toggle(void){
  if(Button_Debounce >= 1000){
    if(Button_Toggle_State == HIGH && Button_Debounce >= 100){
      Button_Toggle_State = LOW;
    }
    else{
      Button_Toggle_State = HIGH;
    }
    Button_Debounce = 0;
  }
}
 
well that
took a while, but finally got my code working and it all works how i wanted it to, still some tweeking to do, but it works.
Code:
//Chris new code for annealer
// v308

//
//-- Include library

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//
//-- Assign I/O pins

int irPin = 2; // ir sensor
int trapPin = 8; // trap door relay
int feedPin = 7;  // feed motor relay
int ssrPin = 6; // annealer relay

int count = 0;  // set case counter to 0
int sensorState = 0, lastState = 0;  // sets the ir to open
int Anneal_Step = 0; // program steps

LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address

//
//-- Set up

void setup() {

  lcd.begin (); // turns on screen

  delay(1000); //delay before the program starts

}

//
//-- Main Program

void loop() {

  //-- set the outputs

  pinMode(irPin, INPUT_PULLUP);
  pinMode(ssrPin, OUTPUT);
  pinMode(feedPin, OUTPUT);
  pinMode(trapPin, OUTPUT);

  feedOffRelay();
  trapOffRelay();
  ssrOffRelay();
 
  int timerValue = analogRead(A1); //-- rotary timer
  int buttonValue = analogRead(A0); //-- push start button

  sensorState = digitalRead(irPin); // assigns the ir

  float voltage = timerValue * (10.23 / 1023.0);
  int a = round(voltage * 10);
  float newVoltage = a / 10.0;

  lcd.setCursor(0, 0); lcd.print(" -Set anneal time- ");
  lcd.setCursor(0, 1); lcd.print("Timer: "); lcd.print(newVoltage, 1); lcd.print(" sec ");

  //-- Begin Anneal Sequence

  switch (Anneal_Step) {

    //-- Timer set up
    case (0):

      lcd.setCursor(0, 3); lcd.print(" ...PRESS START... ");
      if (buttonValue > 1010) {
        lcd.setCursor(0, 3); lcd.print("                   ");
        Anneal_Step = 1;

        break;
      }
      break;

    // -- Turn on feed motor until case is detected by IR
    case (1):

      feedOnRelay(); // turns on feed motor
      if (sensorState == LOW) {
        feedOffRelay();

        Anneal_Step = 2;

        break;
      }

      break;

    //-- Case detected
    case (2):

      if (sensorState == LOW) {
        int b = newVoltage * 1000;
        delay(500);
        lcd.setCursor(1, 3); lcd.print(" ..Case Detected.. ");
        delay(500);
        lcd.setCursor(0, 3); lcd.print(" ....ANNEALING....");

        ssrOnRelay();
        delay(b - 150); // 150 is correction number to get precise ON/OFF timing on pin
        ssrOffRelay();

        Anneal_Step = 3;
        break;
      }

      break;

    //-- Case counter
    case (3):

      lcd.setCursor(0, 3); lcd.print(" ......DONE......");
      lcd.setCursor(0, 2); lcd.print("Count: "); lcd.print(++count, 1); // case counter
      Anneal_Step++;

      break;

    //-- Trap door
    case (4):

      trapOnRelay(); // turns on trap door
      delay(2000);
      trapOffRelay(); //turns off relay
      lcd.setCursor(0, 3); lcd.print("                    ");
      delay(2000); // delay before loop starts
      lastState = sensorState;
      Anneal_Step = 1;

      break;

  }

}

void feedOnRelay() {
  digitalWrite(feedPin, LOW);
}

void feedOffRelay() {
  digitalWrite(feedPin, HIGH);
}

void trapOnRelay() {
  digitalWrite(trapPin, LOW);
}

void trapOffRelay() {
  digitalWrite(trapPin, HIGH);
}

void ssrOnRelay() {
  digitalWrite(ssrPin, HIGH);
}

void ssrOffRelay() {
  digitalWrite(ssrPin, LOW);
}


//
//-- End code
//
 

Attachments

Hi, Thanks guys for all good information. I need some advice. I have bought 2500W ZVS Induction with 48v 3000w power supply. I can reach 500 deg. In couple seconds if I use screwdriver but can not reach over 200 deg in couple minutes if I try with cases. What I am doing wrong. Thanks for any advice.

aliexpress.com/item/32948518417.html?spm=a2g0s.9042311.0.0.54ec4c4dTcYN2j
 
Last edited:
Hi, Thanks guys for all good information. I need some advice. I have bought 2500W ZVS Induction with 48v 3000w power supply. I can reach 500 deg. In couple seconds if I use screwdriver but can not reach over 200 deg in couple minutes if I try with cases. What I am doing wrong. Thanks for any advice.

aliexpress.com/item/32948518417.html?spm=a2g0s.9042311.0.0.54ec4c4dTcYN2j

Question... Do you have the volt/amp meter connected up ? When you try to anneal what are your readings? What gauge wire are you using to connect the PS to the induction board?
Are you using the 1 1/8 inch coil that that "you" wind or the coil that came with the unit ? What relay or contactor are you using to switch the inductor board on and off? Are you building the basic GinaErick design ?
Will try to help you out
Gina
 
Question... Do you have the volt/amp meter connected up ? When you try to anneal what are your readings? What gauge wire are you using to connect the PS to the induction board?
Are you using the 1 1/8 inch coil that that "you" wind or the coil that came with the unit ? What relay or contactor are you using to switch the inductor board on and off? Are you building the basic GinaErick design ?
Will try to help you out
Gina

Thanks Gina for response. No, I don't have volt/amp meter connected and correct I using coil that came with unit. approx 5mm(3/16inch). Yes, I try to build according to GinaErick design with Arduino functionality
 
Do you have a volt/muli-meter ? If so What voltage are you reading at the power input terminals on the inductor board ?
 
47.5v and i have now reduced diameter from 60mm(2.36 inch) to 33mm (1.3) and get reached 662 degrees Fahrenheit in 6 sec. THANKS GiNA FOR YOUR SUPPORT!
 

Upgrades & Donations

This Forum's expenses are primarily paid by member contributions. You can upgrade your Forum membership in seconds. Gold and Silver members get unlimited FREE classifieds for one year. Gold members can upload custom avatars.


Click Upgrade Membership Button ABOVE to get Gold or Silver Status.

You can also donate any amount, large or small, with the button below. Include your Forum Name in the PayPal Notes field.


To DONATE by CHECK, or make a recurring donation, CLICK HERE to learn how.

Forum statistics

Threads
165,130
Messages
2,190,138
Members
78,719
Latest member
Gertvr63
Back
Top