ektoras2012

ARDUINO BGA

Dec 27th, 2019
448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.75 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. }
  306. }
  307.  
  308. //Update whole screen only once
  309. if (updateScreen) {
  310. //setup idle screen
  311. lcd.clear();
  312. lcd.setCursor(8, 0);
  313. lcd.print("IDLE");
  314. lcd.setCursor(1, 1);
  315. lcd.print("PTN:");
  316. lcd.print(" STEP:1 ");
  317. lcd.setCursor(0, 2);
  318. lcd.print(" TH SP:");
  319. lcd.setCursor(13, 2);
  320. lcd.print("PV:");
  321. lcd.setCursor(0, 3);
  322. lcd.print(" BH SP:");
  323. lcd.setCursor(13, 3);
  324. lcd.print("PV:");
  325. updateScreen = false;
  326. }
  327. lcd.setCursor(5, 1);
  328. lcd.print(currentProfile);
  329. lcd.print(" ");
  330. lcd.setCursor(8, 2);
  331. lcd.print(temperatureStep[0]);
  332. lcd.print(" ");
  333. lcd.setCursor(8, 3);
  334. lcd.print(SP2);
  335. lcd.print(" ");
  336. windowStartTime = millis();
  337. if (upSwitchState == HIGH)//if up switch is pressed go to next profile
  338. {
  339. currentProfile = currentProfile + 1;
  340. delay(25);
  341. if (currentProfile >= 5)//if currentProfile = 4 and up is pressed go back to profile 1
  342. {
  343. currentProfile = 1;
  344. }
  345. }
  346. if (downSwitchState == HIGH)//same as above just go down one profile
  347. {
  348. currentProfile = currentProfile - 1;
  349. delay(25);
  350. if (currentProfile <= 0)
  351. {
  352. currentProfile = 4;
  353. }
  354. }
  355. loadProfile();//call the loadProfile function to load from eeprom
  356.  
  357. if (editSwitchState == HIGH ) //if edit is pressed go to menu
  358. {
  359. delay(25);
  360. reflowState = REFLOW_STATE_MENU_STEPS;
  361. //update next screen
  362. updateScreen = true;
  363. }
  364.  
  365. if (okSwitchState == HIGH)
  366. {
  367. //update next screen
  368. updateScreen = true;
  369. curCount = 0;
  370. nextRead2 = millis();
  371. reflowStatus = REFLOW_STATUS_ON;
  372. reflowState = REFLOW_STATE_STEP_RAMP;
  373. }
  374.  
  375. break;
  376.  
  377. case REFLOW_STATE_MENU_STEPS:
  378. if (updateScreen) {
  379. lcd.clear();
  380. lcd.setCursor(3, 0);
  381. lcd.print("Profile ");
  382. lcd.print(currentProfile);
  383. lcd.print(" Edit");
  384. lcd.setCursor(0, 1);
  385. lcd.print(" ");
  386. lcd.setCursor(2, 2);
  387. lcd.print("Profile Steps: ");
  388. lcd.print(profileSteps);
  389. updateScreen = false;
  390. }
  391. lcd.setCursor(17, 2);
  392. lcd.print(profileSteps);
  393.  
  394. if (upSwitchState == HIGH)
  395. {
  396. profileSteps = profileSteps + 1;
  397. delay(25);
  398. if (profileSteps >= 10) {
  399. profileSteps = 1;
  400. }
  401. }
  402. if (downSwitchState == HIGH)
  403. {
  404. profileSteps = profileSteps - 1;
  405. delay(25);
  406. if (profileSteps <= 0) {
  407. profileSteps = 9;
  408. }
  409. }
  410. if (okSwitchState == HIGH)
  411. {
  412. delay(25);
  413. updateScreen = true;
  414. reflowState = REFLOW_STATE_MENU_BOTTOM_HEAT;
  415. }
  416. if (cancelSwitchState == HIGH)
  417. {
  418. delay(25);
  419. updateScreen = true;
  420. reflowState = REFLOW_STATE_IDLE;
  421. }
  422.  
  423. break;
  424.  
  425. case REFLOW_STATE_MENU_BOTTOM_HEAT:
  426.  
  427. if (updateScreen) {
  428. lcd.setCursor(2, 2);
  429. lcd.print("Bottom Heat: ");
  430. updateScreen = false;
  431. }
  432. lcd.setCursor(14, 2);
  433. lcd.print(SP2);
  434.  
  435. if (upSwitchState == HIGH)
  436. {
  437. Setpoint2 = Setpoint2 + 10;
  438. delay(25);
  439. if (Setpoint2 >= 350)
  440. {
  441. Setpoint2 = 350;
  442. }
  443. }
  444. if (downSwitchState == HIGH)
  445. {
  446. Setpoint2 = Setpoint2 - 10;
  447. delay(25);
  448. if (Setpoint2 <= 100)
  449. {
  450. Setpoint2 = 100;
  451. }
  452. }
  453. if (okSwitchState == HIGH)
  454. {
  455. delay(25);
  456. updateScreen = true;
  457. reflowState = REFLOW_STATE_MENU_STEP_RAMP;
  458. }
  459. if (cancelSwitchState == HIGH)
  460. {
  461. delay(25);
  462. updateScreen = true;
  463. reflowState = REFLOW_STATE_IDLE;
  464. }
  465. break;
  466.  
  467. case REFLOW_STATE_MENU_STEP_RAMP:
  468.  
  469. if (updateScreen) {
  470. lcd.setCursor(2, 2);
  471. lcd.print("Step ");
  472. lcd.print(editStep + 1);
  473. lcd.print(" Ramp: ");
  474. updateScreen = false;
  475. }
  476. lcd.setCursor(14, 2);
  477. lcd.print(rampRateStep[editStep]);
  478. if (upSwitchState == HIGH)
  479. {
  480. rampRateStep[editStep] = rampRateStep[editStep] + .25;
  481. delay(25);
  482. if (rampRateStep[editStep] >= 9)
  483. {
  484. rampRateStep[editStep] = 9;
  485. }
  486. }
  487. if (downSwitchState == HIGH)
  488. {
  489. rampRateStep[editStep] = rampRateStep[editStep] - .25;
  490. delay(25);
  491. if (rampRateStep[editStep] <= .25)
  492. {
  493. rampRateStep[editStep] = .25;
  494. }
  495. }
  496. if (okSwitchState == HIGH)
  497. {
  498. delay(25);
  499. updateScreen = true;
  500. if (editStep + 1 == profileSteps){
  501. editStep = 0;
  502. reflowState = REFLOW_STATE_MENU_STEP_TARGET;
  503. }
  504. else {
  505. editStep++;
  506. }
  507. }
  508. if (cancelSwitchState == HIGH)
  509. {
  510. updateScreen = true;
  511. editStep = 0;
  512. delay(25);
  513. lcd.clear();
  514. reflowState = REFLOW_STATE_IDLE;
  515. }
  516. break;
  517.  
  518. case REFLOW_STATE_MENU_STEP_TARGET:
  519. if (updateScreen) {
  520. lcd.setCursor(2, 2);
  521. lcd.print("Step ");
  522. lcd.print(editStep + 1);
  523. lcd.print(" Target: ");
  524. lcd.print(temperatureStep[editStep]);
  525. lcd.print(" ");
  526. updateScreen = false;
  527. }
  528. lcd.print(" ");
  529. lcd.setCursor(16, 2);
  530. lcd.print(temperatureStep[editStep]);
  531. lcd.print(" ");
  532. if (upSwitchState == HIGH)
  533. {
  534. temperatureStep[editStep] = temperatureStep[editStep] + 2;
  535. delay(25);
  536. if (temperatureStep[editStep] >= 250)
  537. {
  538. temperatureStep[editStep] = 250;
  539. }
  540. }
  541. if (downSwitchState == HIGH)
  542. {
  543. temperatureStep[editStep] = temperatureStep[editStep] - 2;
  544. delay(25);
  545. if (temperatureStep[editStep] <= 0)
  546. {
  547. temperatureStep[editStep] = 0;
  548. }
  549. if (temperatureStep[editStep] <= 99)
  550. {
  551. lcd.setCursor(18, 2);
  552. lcd.print(" ");
  553. }
  554. if (temperatureStep[editStep] <= 9)
  555. {
  556. lcd.setCursor(17, 2);
  557. lcd.print(" ");
  558. }
  559. }
  560.  
  561. if (okSwitchState == HIGH)
  562. {
  563. delay(25);
  564. updateScreen = true;
  565. if (editStep + 1 == profileSteps){
  566. editStep = 0;
  567. reflowState = REFLOW_STATE_MENU_STEP_DWELL;
  568. }
  569. else {
  570. editStep++;
  571. }
  572. }
  573. if (cancelSwitchState == HIGH)
  574. {
  575. updateScreen = true;
  576. delay(25);
  577. editStep = 0;
  578. reflowState = REFLOW_STATE_IDLE;
  579. }
  580. break;
  581.  
  582. case REFLOW_STATE_MENU_STEP_DWELL:
  583.  
  584. if (updateScreen) {
  585. lcd.setCursor(2, 2);
  586. lcd.print("Step ");
  587. lcd.print(editStep + 1);
  588. lcd.print(" Dwell: ");
  589. lcd.print(dwellTimerStep[editStep]);
  590. lcd.print(" ");
  591. }
  592. lcd.print(" ");
  593. lcd.setCursor(15, 2);
  594. lcd.print(dwellTimerStep[editStep]);
  595. lcd.print(" ");
  596. if (upSwitchState == HIGH)
  597. {
  598. dwellTimerStep[editStep] = dwellTimerStep[editStep] + 5;
  599. delay(25);
  600. if (dwellTimerStep[editStep] >= 1000)
  601. {
  602. dwellTimerStep[editStep] = 1000;
  603. }
  604. }
  605. if (downSwitchState == HIGH)
  606. {
  607.  
  608. dwellTimerStep[editStep] = dwellTimerStep[editStep] - 5;
  609. delay(25);
  610. if (dwellTimerStep[editStep] <= 0)
  611. {
  612. dwellTimerStep[editStep] = 0;
  613. }
  614. if (dwellTimerStep[editStep] <= 99)
  615. {
  616. lcd.setCursor(18, 2);
  617. lcd.print(" ");
  618. }
  619. if (dwellTimerStep[editStep] <= 9)
  620. {
  621. lcd.setCursor(17, 2);
  622. lcd.print(" ");
  623. }
  624. }
  625. if (okSwitchState == HIGH)
  626. {
  627. delay(25);
  628. updateScreen = true;
  629. if (editStep + 1 == profileSteps){
  630.  
  631. editStep = 0;
  632. reflowState = REFLOW_STATE_MENU_BOTTOM_P;
  633. }
  634. else {
  635. editStep++;
  636. }
  637. }
  638. if (cancelSwitchState == HIGH)
  639. {
  640. delay(25);
  641. updateScreen = true;
  642. editStep = 0;
  643. reflowState = REFLOW_STATE_IDLE;
  644. }
  645. break;
  646.  
  647. case REFLOW_STATE_MENU_BOTTOM_P:
  648. if (updateScreen){
  649. lcd.setCursor(0, 2);
  650. lcd.print(" ");
  651. lcd.setCursor(3, 2);
  652. lcd.print("Bottom Heater:");
  653. lcd.setCursor(8, 3);
  654. lcd.print("P=");
  655. lcd.print(kp2);
  656. lcd.print(" ");
  657. updateScreen = false;
  658. }
  659. lcd.setCursor(10, 3);
  660. lcd.print(kp2);
  661. lcd.print(" ");
  662. if (upSwitchState == HIGH)
  663. {
  664. kp2 = kp2 + 1;
  665. delay(25);
  666. if (kp2 >= 500)
  667. {
  668. kp2 = 500;
  669. }
  670. }
  671. if (downSwitchState == HIGH)
  672. {
  673. kp2 = kp2 - 1;
  674. delay(25);
  675. if (kp2 <= 0)
  676. {
  677. kp2 = 0;
  678. }
  679.  
  680. }
  681. if (okSwitchState == HIGH)
  682. {
  683. delay(25);
  684. updateScreen = true;
  685. reflowState = REFLOW_STATE_MENU_BOTTOM_I;
  686. }
  687. if (cancelSwitchState == HIGH)
  688. {
  689. delay(25);
  690. updateScreen = true;
  691. reflowState = REFLOW_STATE_IDLE;
  692. }
  693. break;
  694. case REFLOW_STATE_MENU_BOTTOM_I:
  695. lcd.setCursor(8, 3);
  696. lcd.print("I=");
  697. lcd.print(ki2);
  698. lcd.print(" ");
  699. if (upSwitchState == HIGH)
  700. {
  701. ki2 = ki2 + 1;
  702. delay(25);
  703. if (ki2 >= 500)
  704. {
  705. ki2 = 500;
  706. }
  707. }
  708. if (downSwitchState == HIGH)
  709. {
  710. ki2 = ki2 - 1;
  711. delay(25);
  712. if (ki2 <= 0)
  713. {
  714. ki2 = 0;
  715. }
  716. }
  717. if (okSwitchState == HIGH)
  718. {
  719. delay(25);
  720. reflowState = REFLOW_STATE_MENU_BOTTOM_D;
  721. }
  722. if (cancelSwitchState == HIGH)
  723. {
  724. delay(25);
  725. reflowState = REFLOW_STATE_IDLE;
  726. }
  727. break;
  728.  
  729. case REFLOW_STATE_MENU_BOTTOM_D:
  730. lcd.setCursor(8, 3);
  731. lcd.print("D=");
  732. lcd.print(kd2);
  733. lcd.print(" ");
  734. if (upSwitchState == HIGH)
  735. {
  736. kd2 = kd2 + 1;
  737. delay(25);
  738. if (kd2 >= 500)
  739. {
  740. kd2 = 500;
  741. }
  742. }
  743. if (downSwitchState == HIGH)
  744. {
  745. kd2 = kd2 - 1;
  746. delay(25);
  747. if (kd2 <= 0)
  748. {
  749. kd2 = 0;
  750. }
  751. }
  752. if (okSwitchState == HIGH)
  753. {
  754. delay(25);
  755. reflowState = REFLOW_STATE_MENU_TOP_P;
  756. }
  757. if (cancelSwitchState == HIGH)
  758. {
  759. delay(25);
  760. reflowState = REFLOW_STATE_IDLE;
  761. }
  762. break;
  763.  
  764. case REFLOW_STATE_MENU_TOP_P:
  765. if (updateScreen){
  766. lcd.setCursor(0, 2);
  767. lcd.print(" ");
  768. lcd.setCursor(5, 2);
  769. lcd.print("Top Heater:");
  770. lcd.setCursor(8, 3);
  771. lcd.print("P=");
  772. lcd.print(kp1);
  773. lcd.print(" ");
  774. updateScreen = false;
  775. }
  776. lcd.setCursor(10, 3);
  777. lcd.print(kp1);
  778. lcd.print(" ");
  779. if (upSwitchState == HIGH)
  780. {
  781. kp1 = kp1 + 1;
  782. delay(25);
  783. if (kp1 >= 500)
  784. {
  785. kp1 = 500;
  786. }
  787. }
  788. if (downSwitchState == HIGH)
  789. {
  790. kp1 = kp1 - 1;
  791. delay(25);
  792. if (kp1 <= 0)
  793. {
  794. kp1 = 0;
  795. }
  796. }
  797. if (okSwitchState == HIGH)
  798. {
  799. delay(25);
  800. updateScreen = true;
  801. reflowState = REFLOW_STATE_MENU_TOP_I;
  802. }
  803. if (cancelSwitchState == HIGH)
  804. {
  805. delay(25);
  806. updateScreen = true;
  807. reflowState = REFLOW_STATE_IDLE;
  808. }
  809. break;
  810. case REFLOW_STATE_MENU_TOP_I:
  811. lcd.setCursor(8, 3);
  812. lcd.print("I=");
  813. lcd.print(ki1);
  814. lcd.print(" ");
  815. if (upSwitchState == HIGH)
  816. {
  817. ki1 = ki1 + 1;
  818. delay(25);
  819. if (ki1 >= 500)
  820. {
  821. ki1 = 500;
  822. }
  823. }
  824. if (downSwitchState == HIGH)
  825. {
  826. ki1 = ki1 - 1;
  827. delay(25);
  828. if (ki1 <= 0)
  829. {
  830. ki1 = 0;
  831. }
  832. }
  833. if (okSwitchState == HIGH)
  834. {
  835. delay(25);
  836. reflowState = REFLOW_STATE_MENU_TOP_D;
  837. }
  838. if (cancelSwitchState == HIGH)
  839. {
  840. delay(25);
  841. reflowState = REFLOW_STATE_IDLE;
  842. }
  843. break;
  844.  
  845. case REFLOW_STATE_MENU_TOP_D:
  846. lcd.setCursor(8, 3);
  847. lcd.print("D=");
  848. lcd.print(kd1);
  849. lcd.print(" ");
  850. if (upSwitchState == HIGH)
  851. {
  852. kd1 = kd1 + 1;
  853. delay(25);
  854. if (kd1 >= 500)
  855. {
  856. kd1 = 500;
  857. }
  858. }
  859. if (downSwitchState == HIGH)
  860. {
  861. kd1 = kd1 - 1;
  862. delay(25);
  863. if (kd1 <= 0)
  864. {
  865. kd1 = 0;
  866. }
  867.  
  868. }
  869. if (okSwitchState == HIGH)
  870. {
  871. //saving the current profile parameters
  872. EEPROM.write((currentProfile-1)*29, profileSteps);
  873. EEPROM.write((currentProfile-1)*29 + 1, Setpoint2);
  874. for (int i=0; i<9; i+1) {
  875. EEPROM.write(((currentProfile-1)*29 + i + 2), rampRateStep[i]*20);
  876. i++;
  877. }
  878. for (int i=0; i<9; i+1) {
  879. EEPROM.write(((currentProfile-1)*29 + i + 11), dwellTimerStep[i]/5);
  880. i++;
  881. }
  882. for (int i=0; i<9; i+1) {
  883. EEPROM.write(((currentProfile-1)*29 + i + 20), temperatureStep[i]);
  884. i++;
  885. }
  886. EEPROM.write(((currentProfile-1)*6 + 122), kp1);
  887. EEPROM.write(((currentProfile-1)*6 + 123), ki1);
  888. EEPROM.write(((currentProfile-1)*6 + 124), kd1);
  889. EEPROM.write(((currentProfile-1)*6 + 125), kp2);
  890. EEPROM.write(((currentProfile-1)*6 + 126), ki2);
  891. EEPROM.write(((currentProfile-1)*6 + 127), kd2);
  892.  
  893. delay(25);
  894. lcd.clear();
  895. reflowState = REFLOW_STATE_IDLE;
  896. }
  897. if (cancelSwitchState == HIGH)
  898. {
  899. delay(25);
  900. lcd.clear();
  901. reflowState = REFLOW_STATE_IDLE;
  902. }
  903. break;
  904.  
  905. case REFLOW_STATE_STEP_RAMP:
  906. //currentStep = 1;
  907. if (updateScreen){
  908. lcd.setCursor(8, 0);
  909. lcd.print("RUN!");
  910. updateScreen = false;
  911. }
  912. startTemp = tc1;
  913. lcd.setCursor(16, 1);
  914. lcd.print(currentStep);
  915. lcd.setCursor(8, 3);
  916. lcd.print(SP2);
  917. //ramp rate counter
  918. if(currentMillis - previousMillis > 1000 / rampRateStep[currentStep-1]) {//seconds counter
  919. previousMillis = currentMillis;
  920. counter = counter + 1;
  921. setpointRamp = startTemp + counter;
  922. lcd.setCursor(8, 2);
  923. lcd.print(" ");
  924. lcd.setCursor(8, 2);
  925. lcd.print(setpointRamp);
  926. lcd.print(" ");
  927. Setpoint1 = setpointRamp;
  928. }
  929.  
  930. if (setpointRamp >= temperatureStep[currentStep-1]) {
  931. lcd.setCursor(8,2);
  932. lcd.print(temperatureStep[currentStep-1]);
  933. reflowState = REFLOW_STATE_STEP;
  934. }
  935. if (cancelSwitchState == HIGH)
  936. {
  937. currentStep = 1;
  938. counter = 0;
  939. setpointRamp = 0;
  940. reflowStatus = REFLOW_STATUS_OFF;
  941. reflowState = REFLOW_STATE_IDLE;
  942. updateScreen = true;
  943. }
  944. break;
  945.  
  946. case REFLOW_STATE_STEP:
  947. Setpoint1 = temperatureStep[currentStep-1];
  948. if (Input1 >= temperatureStep[currentStep-1])
  949. {
  950. counter = 0;
  951. reflowState = REFLOW_STATE_STEP_DWELL;
  952. }
  953. if (cancelSwitchState == HIGH)
  954. {
  955. updateScreen = true;
  956. currentStep = 1;
  957. counter = 0;
  958. setpointRamp = 0;
  959. reflowStatus = REFLOW_STATUS_OFF;
  960. reflowState = REFLOW_STATE_IDLE;
  961. }
  962. break;
  963.  
  964. case REFLOW_STATE_STEP_DWELL:
  965. if(currentMillis - previousMillis > 1000) {
  966. previousMillis = currentMillis;
  967. counter = counter + 1;
  968. }
  969. if (counter == dwellTimerStep[currentStep-1]) {
  970. counter = 0;
  971. setpointRamp = 0;
  972. if (profileSteps == 1) {
  973. reflowState = REFLOW_STATE_COMPLETE;
  974. }
  975. else {
  976. currentStep++;
  977. reflowState = REFLOW_STATE_STEP_RAMP;
  978. }
  979. }
  980. if (cancelSwitchState == HIGH)
  981. {
  982. updateScreen = true;
  983. currentStep = 1;
  984. counter = 0;
  985. setpointRamp = 0;
  986. reflowStatus = REFLOW_STATUS_OFF;
  987. reflowState = REFLOW_STATE_IDLE;
  988. }
  989. break;
  990. case REFLOW_STATE_COMPLETE:
  991.  
  992. reflowStatus = REFLOW_STATUS_OFF;
  993. reflowState = REFLOW_STATE_IDLE;
  994. updateScreen = true;
  995. break;
  996. }
  997.  
  998. Input1 = thermocouple1.readCelsius();
  999. Input2 = thermocouple2.readCelsius();
  1000.  
  1001. if (reflowStatus == REFLOW_STATUS_ON)
  1002. {
  1003. if (millis() > nextRead2){
  1004. nextRead2 += GRAPHICS_SAMPLING_TIME;
  1005. if (curCount<=6) {
  1006. lcd.setCursor(curCount, 0);
  1007. lcd.print(" *");
  1008. lcd.setCursor(18-curCount, 0);
  1009. lcd.print("* ");
  1010. }
  1011. if (curCount>6) {
  1012. lcd.setCursor(13-curCount, 0);
  1013. lcd.print("* ");
  1014. lcd.setCursor(curCount+5, 0);
  1015. lcd.print(" *");
  1016. }
  1017. curCount++;
  1018. if (curCount>13) curCount=0;
  1019. }
  1020. if (millis() > nextRead1)
  1021. {
  1022.  
  1023. // Read thermocouples next sampling period
  1024. nextRead1 += SENSOR_SAMPLING_TIME;
  1025.  
  1026. lcd.setCursor(16, 2);
  1027. lcd.print(" ");
  1028. lcd.setCursor(16, 2);
  1029. if (isnan(Input1)){
  1030. lcd.print("Er");
  1031. }else {
  1032. lcd.print(tc1);
  1033. }
  1034. lcd.setCursor(16, 3);
  1035. lcd.print(" ");
  1036. lcd.setCursor(16, 3);
  1037. if (isnan(Input2)){
  1038. lcd.print("Er");
  1039. }else {
  1040. lcd.print(tc2);
  1041. }
  1042. }
  1043. myPID1.SetTunings(kp1,ki1,kd1);
  1044. myPID2.SetTunings(kp2,ki2,kd2);
  1045. myPID1.Compute();
  1046. myPID2.Compute();
  1047.  
  1048. if(millis() - windowStartTime>WindowSize)
  1049. { //time to shift the Relay Window
  1050. windowStartTime += WindowSize;
  1051. }
  1052. if(Output1 > millis() - windowStartTime) digitalWrite(RelayPin1,HIGH);
  1053.  
  1054. else digitalWrite(RelayPin1,LOW);
  1055.  
  1056. if(Output2 > millis() - windowStartTime) digitalWrite(RelayPin2,HIGH);
  1057.  
  1058. else digitalWrite(RelayPin2,LOW);
  1059. }
  1060. else
  1061. {
  1062. digitalWrite(RelayPin1, LOW);
  1063. digitalWrite(RelayPin2, LOW);
  1064. }
  1065. }
Add Comment
Please, Sign In to add comment