Advertisement
ektoras2012

ARDUINO BGA pid

Jan 11th, 2020
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.79 KB | None | 0 0
  1. /*DUAL LOOP PID CONTROLLER
  2. Coded badly by Norcal Reballer
  3. Facebook.com/norcal.reballer
  4. */
  5.  
  6.  
  7. #include <EEPROM.h>
  8. #include <max6675.h>
  9. //#include <Adafruit_MAX31855.h>
  10. #include <PID_v1.h>
  11. #include <LiquidCrystal.h>
  12. const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
  13. LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
  14.  
  15. //ssr pins. Any variables ending in 1 have to do with top heater
  16. //Any variables ending in 2 have to do with bottom heater
  17. #define RelayPin1 6
  18. #define RelayPin2 7
  19. int curCount = 0;
  20.  
  21. //current editing step pointer
  22. int editStep = 0;
  23.  
  24. int buzzerPin = 8;
  25.  
  26. int backLight = 13;
  27.  
  28. //declaring which pins buttons are connected to
  29. int upSwitchPin = 22;
  30. int downSwitchPin = 24;
  31. int editSwitchPin = 30;
  32. int cancelSwitchPin = 32;
  33. int okSwitchPin = 34;
  34.  
  35. //declaring switch state
  36. int upSwitchState = 0;
  37. int downSwitchState = 0;
  38. int leftSwitchState = 0;
  39. int rightSwitchState = 0;
  40. int editSwitchState = 0;
  41. int cancelSwitchState = 0;
  42. int okSwitchState = 0;
  43.  
  44. //profile stuff
  45. byte currentProfile = 1;
  46. int currentStep = 1;
  47. byte profileSteps;
  48.  
  49. double rampRateStep[9];
  50.  
  51. int dwellTimerStep[9];
  52.  
  53. int kp1;
  54. int ki1;
  55. int kd1;
  56. int kp2;
  57. int ki2;
  58. int kd2;
  59.  
  60. int setpointRamp;
  61. int startTemp;
  62.  
  63. int temperatureStep[9];
  64.  
  65. int eepromAddress = 0;//starting eepromaddress
  66.  
  67. long previousMillis; //these are for counters
  68. double counter;
  69.  
  70. //these are the different states of the sketch. We call different ones depending on conditions
  71. // ***** TYPE DEFINITIONS *****
  72. typedef enum REFLOW_STATE
  73. {
  74. REFLOW_STATE_IDLE,
  75. REFLOW_STATE_MENU_STEPS,
  76. REFLOW_STATE_MENU_BOTTOM_HEAT,
  77. REFLOW_STATE_MENU_STEP_RAMP,
  78. REFLOW_STATE_MENU_STEP_TARGET,
  79. REFLOW_STATE_MENU_STEP_DWELL,
  80. REFLOW_STATE_MENU_BOTTOM_P,
  81. REFLOW_STATE_MENU_BOTTOM_I,
  82. REFLOW_STATE_MENU_BOTTOM_D,
  83. REFLOW_STATE_MENU_TOP_P,
  84. REFLOW_STATE_MENU_TOP_I,
  85. REFLOW_STATE_MENU_TOP_D,
  86. REFLOW_STATE_STEP_RAMP,
  87. REFLOW_STATE_STEP,
  88. REFLOW_STATE_STEP_DWELL,
  89. REFLOW_STATE_COMPLETE,
  90. REFLOW_STATE_ERROR
  91. }
  92. reflowState_t;
  93.  
  94. typedef enum REFLOW_STATUS //this is simply to check if reflow should be running or not
  95. {
  96. REFLOW_STATUS_OFF,
  97. REFLOW_STATUS_ON
  98. }
  99. reflowStatus_t;
  100.  
  101. #define SENSOR_SAMPLING_TIME 1000 //read tc every second
  102. #define GRAPHICS_SAMPLING_TIME 500 //read tc every second
  103.  
  104. reflowStatus_t reflowStatus;
  105. // Reflow oven controller state machine state variable
  106. reflowState_t reflowState;
  107.  
  108.  
  109. //TC read timer variables
  110. unsigned long nextCheck1;
  111. unsigned long nextRead1;
  112. unsigned long nextRead2;
  113. //PID stuff
  114.  
  115. double Setpoint1, Input1, Output1;
  116. //Specify the links and initial tuning parameters
  117. PID myPID1(&Input1, &Output1, &Setpoint1,kp1,ki1,kd1, DIRECT);
  118. int WindowSize = 2000;
  119. unsigned long windowStartTime;
  120. //PID stuff
  121. double Setpoint2, Input2, Output2;
  122. //Specify the links and initial tuning parameters
  123. PID myPID2(&Input2, &Output2, &Setpoint2,kp2,ki2,kd2,DIRECT);
  124.  
  125. //Alarm state boolean
  126. boolean alarmOn=false;
  127.  
  128. //Update whole screen boolean
  129. boolean updateScreen = true;
  130.  
  131.  
  132. //31855 stuff - can be easily swapped for 6675
  133. int thermoCLK = 53;
  134. int thermoCS = 51;
  135. int thermoDO = 49;
  136. //31855 stuff - can be easily swapped for 6675
  137. int thermoCLK2 = 47;
  138. int thermoCS2 = 45;
  139. int thermoDO2 = 43;
  140.  
  141. int tc1;
  142. int tc2;
  143.  
  144. MAX6675 thermocouple1(thermoCLK, thermoCS, thermoDO);
  145. MAX6675 thermocouple2(thermoCLK2, thermoCS2, thermoDO2);
  146.  
  147. //Adafruit_MAX31855 thermocouple1(thermoCLK, thermoCS, thermoDO);//top heater thermocouple
  148. //Adafruit_MAX31855 thermocouple2(thermoCLK2, thermoCS2, thermoDO2);//bottom heater thermocouple
  149.  
  150. void loadProfile()//this function loads whichever profile currentProfile variable is set to
  151. {
  152. profileSteps = EEPROM.read((currentProfile-1)*29);
  153. Setpoint2 = EEPROM.read((currentProfile-1)*29 + 1);
  154. for (int i=0; i<9; i+1) {
  155. rampRateStep[i] = EEPROM.read((currentProfile-1)*29 + i + 2)/20;
  156. i++;
  157. }
  158. for (int i=0; i<9; i+1) {
  159. dwellTimerStep[i] = EEPROM.read((currentProfile-1)*29 + i + 11)*5;
  160. i++;
  161. }
  162. for (int i=0; i<9; i+1) {
  163. temperatureStep[i] = EEPROM.read((currentProfile-1)*29 + i + 20);
  164. i++;
  165. }
  166. kp1 = EEPROM.read((currentProfile-1)*6 + 122);
  167. ki1 = EEPROM.read((currentProfile-1)*6 + 123);
  168. kd1 = EEPROM.read((currentProfile-1)*6 + 124);
  169. kp2 = EEPROM.read((currentProfile-1)*6 + 125);
  170. ki2 = EEPROM.read((currentProfile-1)*6 + 126);
  171. kd2 = EEPROM.read((currentProfile-1)*6 + 127);
  172.  
  173. return;
  174. }
  175.  
  176.  
  177. void setup()
  178. {
  179. Serial.begin(9600);
  180. //setup pins as input for buttons
  181. pinMode (upSwitchPin, INPUT);
  182. pinMode (downSwitchPin, INPUT);
  183. pinMode (editSwitchPin, INPUT);
  184. pinMode (cancelSwitchPin, INPUT);
  185. pinMode (okSwitchPin, INPUT);
  186. pinMode (backLight, OUTPUT);
  187. pinMode (buzzerPin, OUTPUT);
  188. digitalWrite(backLight, HIGH);
  189. lcd.begin(20, 4);//setup lcd
  190. lcd.clear();
  191. lcd.setCursor(1, 1);
  192. lcd.print("ARDUINO REWORK 1.1");
  193. //Welcome melody
  194. tone(buzzerPin, 523);
  195. delay(200);
  196. tone(buzzerPin, 659);
  197. delay(200);
  198. tone(buzzerPin, 784);
  199. delay(200);
  200. tone(buzzerPin, 1046);
  201. delay(200);
  202. noTone(buzzerPin);
  203. // wait for MAX chips to stabilize and splash screen
  204. delay(2000);
  205. lcd.clear();
  206.  
  207. pinMode(RelayPin1, OUTPUT);//setup ssr pins as outputs
  208. pinMode(RelayPin2, OUTPUT);
  209.  
  210. windowStartTime = millis();//Just total time sketch has been running
  211. // Initialize time keeping variable for TC1
  212. nextCheck1 = millis();
  213. // Initialize top thermocouple reading variable
  214. nextRead1 = millis();
  215.  
  216. //initialize soak timer variable
  217.  
  218.  
  219. myPID1.SetOutputLimits(0, WindowSize);//myPID1 = top heater PID loop
  220. myPID2.SetOutputLimits(0, WindowSize);
  221. myPID1.SetMode(AUTOMATIC);
  222. myPID2.SetMode(AUTOMATIC);
  223. }
  224.  
  225. int i=0;
  226.  
  227. void loop()
  228. {
  229. Input1 = thermocouple1.readCelsius();
  230. Input2 = thermocouple2.readCelsius();
  231. tc1 = Input1;
  232. tc2 = Input2;
  233.  
  234. //these variables read switch pins
  235. upSwitchState = digitalRead(upSwitchPin);
  236. downSwitchState = digitalRead(downSwitchPin);
  237. editSwitchState = digitalRead(editSwitchPin);
  238. cancelSwitchState = digitalRead(cancelSwitchPin);
  239. okSwitchState = digitalRead(okSwitchPin);
  240.  
  241. unsigned long currentMillis = millis();
  242.  
  243. int SP1 = Setpoint1;
  244. int SP2 = Setpoint2;
  245.  
  246.  
  247. if (upSwitchState==HIGH || downSwitchState==HIGH || editSwitchState==HIGH || cancelSwitchState==HIGH || okSwitchState==HIGH) {
  248. tone(buzzerPin, 523);
  249. delay(100);
  250. noTone(buzzerPin);
  251. }
  252.  
  253.  
  254. if (reflowState==REFLOW_STATE_COMPLETE || alarmOn){
  255. if (i<15 && cancelSwitchState==LOW) {
  256. alarmOn=true;
  257. tone(buzzerPin, 1046);
  258. delay(100);
  259. noTone(buzzerPin);
  260. delay(100);
  261. tone(buzzerPin, 1046);
  262. delay(100);
  263. noTone(buzzerPin);
  264. delay(100);
  265. tone(buzzerPin, 1046);
  266. delay(100);
  267. noTone(buzzerPin);
  268. delay(100);
  269. tone(buzzerPin, 1046);
  270. delay(100);
  271. noTone(buzzerPin);
  272. delay(400);
  273. i++;
  274. }
  275. else {
  276. i=0;
  277. alarmOn=false;
  278. }
  279. }
  280.  
  281. switch (reflowState)
  282. {
  283. case REFLOW_STATE_IDLE:
  284. if (millis() > nextRead1)
  285. {
  286. // Read thermocouples next sampling period
  287. nextRead1 += SENSOR_SAMPLING_TIME;
  288.  
  289. lcd.setCursor(16, 2);
  290. lcd.print(" ");
  291. lcd.setCursor(16, 2);
  292. if (isnan(Input1)){
  293. lcd.print("Er");
  294. }else {
  295. lcd.print(tc1);
  296. //Serial.print(tc1);
  297. }
  298. lcd.setCursor(16, 3);
  299. lcd.print(" ");
  300. lcd.setCursor(16, 3);
  301. if (isnan(Input2)){
  302. lcd.print("Er");
  303. }else {
  304. lcd.print(tc2);
  305. delay(200);
  306. }
  307. }
  308.  
  309. //Update whole screen only once
  310. if (updateScreen) {
  311. //setup idle screen
  312. lcd.clear();
  313. lcd.setCursor(8, 0);
  314. lcd.print("IDLE");
  315. lcd.setCursor(1, 1);
  316. lcd.print("PTN:");
  317. lcd.print(" STEP:1 ");
  318. lcd.setCursor(0, 2);
  319. lcd.print(" TH SP:");
  320. lcd.setCursor(13, 2);
  321. lcd.print("PV:");
  322. lcd.setCursor(0, 3);
  323. lcd.print(" BH SP:");
  324. lcd.setCursor(13, 3);
  325. lcd.print("PV:");
  326. updateScreen = false;
  327. }
  328. lcd.setCursor(5, 1);
  329. lcd.print(currentProfile);
  330. lcd.print(" ");
  331. lcd.setCursor(8, 2);
  332. lcd.print(temperatureStep[0]);
  333. lcd.print(" ");
  334. lcd.setCursor(8, 3);
  335. lcd.print(SP2);
  336. lcd.print(" ");
  337. windowStartTime = millis();
  338. if (upSwitchState == HIGH)//if up switch is pressed go to next profile
  339. {
  340. currentProfile = currentProfile + 1;
  341. delay(25);
  342. if (currentProfile >= 5)//if currentProfile = 4 and up is pressed go back to profile 1
  343. {
  344. currentProfile = 1;
  345. }
  346. }
  347. if (downSwitchState == HIGH)//same as above just go down one profile
  348. {
  349. currentProfile = currentProfile - 1;
  350. delay(25);
  351. if (currentProfile <= 0)
  352. {
  353. currentProfile = 4;
  354. }
  355. }
  356. loadProfile();//call the loadProfile function to load from eeprom
  357.  
  358. if (editSwitchState == HIGH ) //if edit is pressed go to menu
  359. {
  360. delay(25);
  361. reflowState = REFLOW_STATE_MENU_STEPS;
  362. //update next screen
  363. updateScreen = true;
  364. }
  365.  
  366. if (okSwitchState == HIGH)
  367. {
  368. //update next screen
  369. updateScreen = true;
  370. curCount = 0;
  371. nextRead2 = millis();
  372. reflowStatus = REFLOW_STATUS_ON;
  373. reflowState = REFLOW_STATE_STEP_RAMP;
  374. }
  375.  
  376. break;
  377.  
  378. case REFLOW_STATE_MENU_STEPS:
  379. if (updateScreen) {
  380. lcd.clear();
  381. lcd.setCursor(3, 0);
  382. lcd.print("Profile ");
  383. lcd.print(currentProfile);
  384. lcd.print(" Edit");
  385. lcd.setCursor(0, 1);
  386. lcd.print(" ");
  387. lcd.setCursor(2, 2);
  388. lcd.print("Profile Steps: ");
  389. lcd.print(profileSteps);
  390. updateScreen = false;
  391. }
  392. lcd.setCursor(17, 2);
  393. lcd.print(profileSteps);
  394.  
  395. if (upSwitchState == HIGH)
  396. {
  397. profileSteps = profileSteps + 1;
  398. delay(25);
  399. if (profileSteps >= 10) {
  400. profileSteps = 1;
  401. }
  402. }
  403. if (downSwitchState == HIGH)
  404. {
  405. profileSteps = profileSteps - 1;
  406. delay(25);
  407. if (profileSteps <= 0) {
  408. profileSteps = 9;
  409. }
  410. }
  411. if (okSwitchState == HIGH)
  412. {
  413. delay(25);
  414. updateScreen = true;
  415. reflowState = REFLOW_STATE_MENU_BOTTOM_HEAT;
  416. }
  417. if (cancelSwitchState == HIGH)
  418. {
  419. delay(25);
  420. updateScreen = true;
  421. reflowState = REFLOW_STATE_IDLE;
  422. }
  423.  
  424. break;
  425.  
  426. case REFLOW_STATE_MENU_BOTTOM_HEAT:
  427.  
  428. if (updateScreen) {
  429. lcd.setCursor(2, 2);
  430. lcd.print("Bottom Heat: ");
  431. updateScreen = false;
  432. }
  433. lcd.setCursor(14, 2);
  434. lcd.print(SP2);
  435.  
  436. if (upSwitchState == HIGH)
  437. {
  438. Setpoint2 = Setpoint2 + 10;
  439. delay(25);
  440. if (Setpoint2 >= 350)
  441. {
  442. Setpoint2 = 350;
  443. }
  444. }
  445. if (downSwitchState == HIGH)
  446. {
  447. Setpoint2 = Setpoint2 - 10;
  448. delay(25);
  449. if (Setpoint2 <= 100)
  450. {
  451. Setpoint2 = 100;
  452. }
  453. }
  454. if (okSwitchState == HIGH)
  455. {
  456. delay(25);
  457. updateScreen = true;
  458. reflowState = REFLOW_STATE_MENU_STEP_RAMP;
  459. }
  460. if (cancelSwitchState == HIGH)
  461. {
  462. delay(25);
  463. updateScreen = true;
  464. reflowState = REFLOW_STATE_IDLE;
  465. }
  466. break;
  467.  
  468. case REFLOW_STATE_MENU_STEP_RAMP:
  469.  
  470. if (updateScreen) {
  471. lcd.setCursor(2, 2);
  472. lcd.print("Step ");
  473. lcd.print(editStep + 1);
  474. lcd.print(" Ramp: ");
  475. updateScreen = false;
  476. }
  477. lcd.setCursor(14, 2);
  478. lcd.print(rampRateStep[editStep]);
  479. if (upSwitchState == HIGH)
  480. {
  481. rampRateStep[editStep] = rampRateStep[editStep] + .25;
  482. delay(25);
  483. if (rampRateStep[editStep] >= 9)
  484. {
  485. rampRateStep[editStep] = 9;
  486. }
  487. }
  488. if (downSwitchState == HIGH)
  489. {
  490. rampRateStep[editStep] = rampRateStep[editStep] - .25;
  491. delay(25);
  492. if (rampRateStep[editStep] <= .25)
  493. {
  494. rampRateStep[editStep] = .25;
  495. }
  496. }
  497. if (okSwitchState == HIGH)
  498. {
  499. delay(25);
  500. updateScreen = true;
  501. if (editStep + 1 == profileSteps){
  502. editStep = 0;
  503. reflowState = REFLOW_STATE_MENU_STEP_TARGET;
  504. }
  505. else {
  506. editStep++;
  507. }
  508. }
  509. if (cancelSwitchState == HIGH)
  510. {
  511. updateScreen = true;
  512. editStep = 0;
  513. delay(25);
  514. lcd.clear();
  515. reflowState = REFLOW_STATE_IDLE;
  516. }
  517. break;
  518.  
  519. case REFLOW_STATE_MENU_STEP_TARGET:
  520. if (updateScreen) {
  521. lcd.setCursor(2, 2);
  522. lcd.print("Step ");
  523. lcd.print(editStep + 1);
  524. lcd.print(" Target: ");
  525. lcd.print(temperatureStep[editStep]);
  526. lcd.print(" ");
  527. updateScreen = false;
  528. }
  529. lcd.print(" ");
  530. lcd.setCursor(16, 2);
  531. lcd.print(temperatureStep[editStep]);
  532. lcd.print(" ");
  533. if (upSwitchState == HIGH)
  534. {
  535. temperatureStep[editStep] = temperatureStep[editStep] + 2;
  536. delay(25);
  537. if (temperatureStep[editStep] >= 250)
  538. {
  539. temperatureStep[editStep] = 250;
  540. }
  541. }
  542. if (downSwitchState == HIGH)
  543. {
  544. temperatureStep[editStep] = temperatureStep[editStep] - 2;
  545. delay(25);
  546. if (temperatureStep[editStep] <= 0)
  547. {
  548. temperatureStep[editStep] = 0;
  549. }
  550. if (temperatureStep[editStep] <= 99)
  551. {
  552. lcd.setCursor(18, 2);
  553. lcd.print(" ");
  554. }
  555. if (temperatureStep[editStep] <= 9)
  556. {
  557. lcd.setCursor(17, 2);
  558. lcd.print(" ");
  559. }
  560. }
  561.  
  562. if (okSwitchState == HIGH)
  563. {
  564. delay(25);
  565. updateScreen = true;
  566. if (editStep + 1 == profileSteps){
  567. editStep = 0;
  568. reflowState = REFLOW_STATE_MENU_STEP_DWELL;
  569. }
  570. else {
  571. editStep++;
  572. }
  573. }
  574. if (cancelSwitchState == HIGH)
  575. {
  576. updateScreen = true;
  577. delay(25);
  578. editStep = 0;
  579. reflowState = REFLOW_STATE_IDLE;
  580. }
  581. break;
  582.  
  583. case REFLOW_STATE_MENU_STEP_DWELL:
  584.  
  585. if (updateScreen) {
  586. lcd.setCursor(2, 2);
  587. lcd.print("Step ");
  588. lcd.print(editStep + 1);
  589. lcd.print(" Dwell: ");
  590. lcd.print(dwellTimerStep[editStep]);
  591. lcd.print(" ");
  592. }
  593. lcd.print(" ");
  594. lcd.setCursor(15, 2);
  595. lcd.print(dwellTimerStep[editStep]);
  596. lcd.print(" ");
  597. if (upSwitchState == HIGH)
  598. {
  599. dwellTimerStep[editStep] = dwellTimerStep[editStep] + 5;
  600. delay(25);
  601. if (dwellTimerStep[editStep] >= 1000)
  602. {
  603. dwellTimerStep[editStep] = 1000;
  604. }
  605. }
  606. if (downSwitchState == HIGH)
  607. {
  608.  
  609. dwellTimerStep[editStep] = dwellTimerStep[editStep] - 5;
  610. delay(25);
  611. if (dwellTimerStep[editStep] <= 0)
  612. {
  613. dwellTimerStep[editStep] = 0;
  614. }
  615. if (dwellTimerStep[editStep] <= 99)
  616. {
  617. lcd.setCursor(18, 2);
  618. lcd.print(" ");
  619. }
  620. if (dwellTimerStep[editStep] <= 9)
  621. {
  622. lcd.setCursor(17, 2);
  623. lcd.print(" ");
  624. }
  625. }
  626. if (okSwitchState == HIGH)
  627. {
  628. delay(25);
  629. updateScreen = true;
  630. if (editStep + 1 == profileSteps){
  631.  
  632. editStep = 0;
  633. reflowState = REFLOW_STATE_MENU_BOTTOM_P;
  634. }
  635. else {
  636. editStep++;
  637. }
  638. }
  639. if (cancelSwitchState == HIGH)
  640. {
  641. delay(25);
  642. updateScreen = true;
  643. editStep = 0;
  644. reflowState = REFLOW_STATE_IDLE;
  645. }
  646. break;
  647.  
  648. case REFLOW_STATE_MENU_BOTTOM_P:
  649. if (updateScreen){
  650. lcd.setCursor(0, 2);
  651. lcd.print(" ");
  652. lcd.setCursor(3, 2);
  653. lcd.print("Bottom Heater:");
  654. lcd.setCursor(8, 3);
  655. lcd.print("P=");
  656. lcd.print(kp2);
  657. lcd.print(" ");
  658. updateScreen = false;
  659. }
  660. lcd.setCursor(10, 3);
  661. lcd.print(kp2);
  662. lcd.print(" ");
  663. if (upSwitchState == HIGH)
  664. {
  665. kp2 = kp2 + 1;
  666. delay(25);
  667. if (kp2 >= 500)
  668. {
  669. kp2 = 500;
  670. }
  671. }
  672. if (downSwitchState == HIGH)
  673. {
  674. kp2 = kp2 - 1;
  675. delay(25);
  676. if (kp2 <= 0)
  677. {
  678. kp2 = 0;
  679. }
  680.  
  681. }
  682. if (okSwitchState == HIGH)
  683. {
  684. delay(25);
  685. updateScreen = true;
  686. reflowState = REFLOW_STATE_MENU_BOTTOM_I;
  687. }
  688. if (cancelSwitchState == HIGH)
  689. {
  690. delay(25);
  691. updateScreen = true;
  692. reflowState = REFLOW_STATE_IDLE;
  693. }
  694. break;
  695. case REFLOW_STATE_MENU_BOTTOM_I:
  696. lcd.setCursor(8, 3);
  697. lcd.print("I=");
  698. lcd.print(ki2);
  699. lcd.print(" ");
  700. if (upSwitchState == HIGH)
  701. {
  702. ki2 = ki2 + 1;
  703. delay(25);
  704. if (ki2 >= 500)
  705. {
  706. ki2 = 500;
  707. }
  708. }
  709. if (downSwitchState == HIGH)
  710. {
  711. ki2 = ki2 - 1;
  712. delay(25);
  713. if (ki2 <= 0)
  714. {
  715. ki2 = 0;
  716. }
  717. }
  718. if (okSwitchState == HIGH)
  719. {
  720. delay(25);
  721. reflowState = REFLOW_STATE_MENU_BOTTOM_D;
  722. }
  723. if (cancelSwitchState == HIGH)
  724. {
  725. delay(25);
  726. reflowState = REFLOW_STATE_IDLE;
  727. }
  728. break;
  729.  
  730. case REFLOW_STATE_MENU_BOTTOM_D:
  731. lcd.setCursor(8, 3);
  732. lcd.print("D=");
  733. lcd.print(kd2);
  734. lcd.print(" ");
  735. if (upSwitchState == HIGH)
  736. {
  737. kd2 = kd2 + 1;
  738. delay(25);
  739. if (kd2 >= 500)
  740. {
  741. kd2 = 500;
  742. }
  743. }
  744. if (downSwitchState == HIGH)
  745. {
  746. kd2 = kd2 - 1;
  747. delay(25);
  748. if (kd2 <= 0)
  749. {
  750. kd2 = 0;
  751. }
  752. }
  753. if (okSwitchState == HIGH)
  754. {
  755. delay(25);
  756. reflowState = REFLOW_STATE_MENU_TOP_P;
  757. }
  758. if (cancelSwitchState == HIGH)
  759. {
  760. delay(25);
  761. reflowState = REFLOW_STATE_IDLE;
  762. }
  763. break;
  764.  
  765. case REFLOW_STATE_MENU_TOP_P:
  766. if (updateScreen){
  767. lcd.setCursor(0, 2);
  768. lcd.print(" ");
  769. lcd.setCursor(5, 2);
  770. lcd.print("Top Heater:");
  771. lcd.setCursor(8, 3);
  772. lcd.print("P=");
  773. lcd.print(kp1);
  774. lcd.print(" ");
  775. updateScreen = false;
  776. }
  777. lcd.setCursor(10, 3);
  778. lcd.print(kp1);
  779. lcd.print(" ");
  780. if (upSwitchState == HIGH)
  781. {
  782. kp1 = kp1 + 1;
  783. delay(25);
  784. if (kp1 >= 500)
  785. {
  786. kp1 = 500;
  787. }
  788. }
  789. if (downSwitchState == HIGH)
  790. {
  791. kp1 = kp1 - 1;
  792. delay(25);
  793. if (kp1 <= 0)
  794. {
  795. kp1 = 0;
  796. }
  797. }
  798. if (okSwitchState == HIGH)
  799. {
  800. delay(25);
  801. updateScreen = true;
  802. reflowState = REFLOW_STATE_MENU_TOP_I;
  803. }
  804. if (cancelSwitchState == HIGH)
  805. {
  806. delay(25);
  807. updateScreen = true;
  808. reflowState = REFLOW_STATE_IDLE;
  809. }
  810. break;
  811. case REFLOW_STATE_MENU_TOP_I:
  812. lcd.setCursor(8, 3);
  813. lcd.print("I=");
  814. lcd.print(ki1);
  815. lcd.print(" ");
  816. if (upSwitchState == HIGH)
  817. {
  818. ki1 = ki1 + 1;
  819. delay(25);
  820. if (ki1 >= 500)
  821. {
  822. ki1 = 500;
  823. }
  824. }
  825. if (downSwitchState == HIGH)
  826. {
  827. ki1 = ki1 - 1;
  828. delay(25);
  829. if (ki1 <= 0)
  830. {
  831. ki1 = 0;
  832. }
  833. }
  834. if (okSwitchState == HIGH)
  835. {
  836. delay(25);
  837. reflowState = REFLOW_STATE_MENU_TOP_D;
  838. }
  839. if (cancelSwitchState == HIGH)
  840. {
  841. delay(25);
  842. reflowState = REFLOW_STATE_IDLE;
  843. }
  844. break;
  845.  
  846. case REFLOW_STATE_MENU_TOP_D:
  847. lcd.setCursor(8, 3);
  848. lcd.print("D=");
  849. lcd.print(kd1);
  850. lcd.print(" ");
  851. if (upSwitchState == HIGH)
  852. {
  853. kd1 = kd1 + 1;
  854. delay(25);
  855. if (kd1 >= 500)
  856. {
  857. kd1 = 500;
  858. }
  859. }
  860. if (downSwitchState == HIGH)
  861. {
  862. kd1 = kd1 - 1;
  863. delay(25);
  864. if (kd1 <= 0)
  865. {
  866. kd1 = 0;
  867. }
  868.  
  869. }
  870. if (okSwitchState == HIGH)
  871. {
  872. //saving the current profile parameters
  873. EEPROM.write((currentProfile-1)*29, profileSteps);
  874. EEPROM.write((currentProfile-1)*29 + 1, Setpoint2);
  875. for (int i=0; i<9; i+1) {
  876. EEPROM.write(((currentProfile-1)*29 + i + 2), rampRateStep[i]*20);
  877. i++;
  878. }
  879. for (int i=0; i<9; i+1) {
  880. EEPROM.write(((currentProfile-1)*29 + i + 11), dwellTimerStep[i]/5);
  881. i++;
  882. }
  883. for (int i=0; i<9; i+1) {
  884. EEPROM.write(((currentProfile-1)*29 + i + 20), temperatureStep[i]);
  885. i++;
  886. }
  887. EEPROM.write(((currentProfile-1)*6 + 122), kp1);
  888. EEPROM.write(((currentProfile-1)*6 + 123), ki1);
  889. EEPROM.write(((currentProfile-1)*6 + 124), kd1);
  890. EEPROM.write(((currentProfile-1)*6 + 125), kp2);
  891. EEPROM.write(((currentProfile-1)*6 + 126), ki2);
  892. EEPROM.write(((currentProfile-1)*6 + 127), kd2);
  893.  
  894. delay(25);
  895. lcd.clear();
  896. reflowState = REFLOW_STATE_IDLE;
  897. }
  898. if (cancelSwitchState == HIGH)
  899. {
  900. delay(25);
  901. lcd.clear();
  902. reflowState = REFLOW_STATE_IDLE;
  903. }
  904. break;
  905.  
  906. case REFLOW_STATE_STEP_RAMP:
  907. //currentStep = 1;
  908. if (updateScreen){
  909. lcd.setCursor(8, 0);
  910. lcd.print("RUN!");
  911. updateScreen = false;
  912. }
  913. startTemp = tc1;
  914. lcd.setCursor(16, 1);
  915. lcd.print(currentStep);
  916. lcd.setCursor(8, 3);
  917. lcd.print(SP2);
  918. //ramp rate counter
  919. if(currentMillis - previousMillis > 1000 / rampRateStep[currentStep-1]) {//seconds counter
  920. previousMillis = currentMillis;
  921. counter = counter + 1;
  922. setpointRamp = startTemp + counter;
  923. lcd.setCursor(8, 2);
  924. lcd.print(" ");
  925. lcd.setCursor(8, 2);
  926. lcd.print(setpointRamp);
  927. lcd.print(" ");
  928. Setpoint1 = setpointRamp;
  929. }
  930.  
  931. if (setpointRamp >= temperatureStep[currentStep-1]) {
  932. lcd.setCursor(8,2);
  933. lcd.print(temperatureStep[currentStep-1]);
  934. reflowState = REFLOW_STATE_STEP;
  935. }
  936. if (cancelSwitchState == HIGH)
  937. {
  938. currentStep = 1;
  939. counter = 0;
  940. setpointRamp = 0;
  941. reflowStatus = REFLOW_STATUS_OFF;
  942. reflowState = REFLOW_STATE_IDLE;
  943. updateScreen = true;
  944. }
  945. break;
  946.  
  947. case REFLOW_STATE_STEP:
  948. Setpoint1 = temperatureStep[currentStep-1];
  949. if (Input1 >= temperatureStep[currentStep-1])
  950. {
  951. counter = 0;
  952. reflowState = REFLOW_STATE_STEP_DWELL;
  953. }
  954. if (cancelSwitchState == HIGH)
  955. {
  956. updateScreen = true;
  957. currentStep = 1;
  958. counter = 0;
  959. setpointRamp = 0;
  960. reflowStatus = REFLOW_STATUS_OFF;
  961. reflowState = REFLOW_STATE_IDLE;
  962. }
  963. break;
  964.  
  965. case REFLOW_STATE_STEP_DWELL:
  966. if(currentMillis - previousMillis > 1000) {
  967. previousMillis = currentMillis;
  968. counter = counter + 1;
  969. }
  970. if (counter == dwellTimerStep[currentStep-1]) {
  971. counter = 0;
  972. setpointRamp = 0;
  973. if (profileSteps == 1) {
  974. reflowState = REFLOW_STATE_COMPLETE;
  975. }
  976. else {
  977. currentStep++;
  978. reflowState = REFLOW_STATE_STEP_RAMP;
  979. }
  980. }
  981. if (cancelSwitchState == HIGH)
  982. {
  983. updateScreen = true;
  984. currentStep = 1;
  985. counter = 0;
  986. setpointRamp = 0;
  987. reflowStatus = REFLOW_STATUS_OFF;
  988. reflowState = REFLOW_STATE_IDLE;
  989. }
  990. break;
  991. case REFLOW_STATE_COMPLETE:
  992.  
  993. reflowStatus = REFLOW_STATUS_OFF;
  994. reflowState = REFLOW_STATE_IDLE;
  995. updateScreen = true;
  996. break;
  997. }
  998.  
  999. Input1 = thermocouple1.readCelsius();
  1000. Input2 = thermocouple2.readCelsius();
  1001.  
  1002. if (reflowStatus == REFLOW_STATUS_ON)
  1003. {
  1004. if (millis() > nextRead2){
  1005. nextRead2 += GRAPHICS_SAMPLING_TIME;
  1006. if (curCount<=6) {
  1007. lcd.setCursor(curCount, 0);
  1008. lcd.print(" *");
  1009. lcd.setCursor(18-curCount, 0);
  1010. lcd.print("* ");
  1011. }
  1012. if (curCount>6) {
  1013. lcd.setCursor(13-curCount, 0);
  1014. lcd.print("* ");
  1015. lcd.setCursor(curCount+5, 0);
  1016. lcd.print(" *");
  1017. }
  1018. curCount++;
  1019. if (curCount>13) curCount=0;
  1020. }
  1021. if (millis() > nextRead1)
  1022. {
  1023.  
  1024. // Read thermocouples next sampling period
  1025. nextRead1 += SENSOR_SAMPLING_TIME;
  1026.  
  1027. lcd.setCursor(16, 2);
  1028. lcd.print(" ");
  1029. lcd.setCursor(16, 2);
  1030. if (isnan(Input1)){
  1031. lcd.print("Er");
  1032. }else {
  1033. lcd.print(tc1);
  1034. }
  1035. lcd.setCursor(16, 3);
  1036. lcd.print(" ");
  1037. lcd.setCursor(16, 3);
  1038. if (isnan(Input2)){
  1039. lcd.print("Er");
  1040. }else {
  1041. lcd.print(tc2);
  1042. delay(200);
  1043. }
  1044. }
  1045. myPID1.SetTunings(kp1,ki1,kd1);
  1046. myPID2.SetTunings(kp2,ki2,kd2);
  1047. myPID1.Compute();
  1048. myPID2.Compute();
  1049.  
  1050. if(millis() - windowStartTime>WindowSize)
  1051. { //time to shift the Relay Window
  1052. windowStartTime += WindowSize;
  1053. }
  1054. if(Output1 > millis() - windowStartTime) digitalWrite(RelayPin1,HIGH);
  1055.  
  1056. else digitalWrite(RelayPin1,LOW);
  1057.  
  1058. if(Output2 > millis() - windowStartTime) digitalWrite(RelayPin2,HIGH);
  1059.  
  1060. else digitalWrite(RelayPin2,LOW);
  1061. }
  1062. else
  1063. {
  1064. digitalWrite(RelayPin1, LOW);
  1065. digitalWrite(RelayPin2, LOW);
  1066. }
  1067. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement