diff --git a/stir.ino b/stir.ino index 5b0649f..a2013c0 100644 --- a/stir.ino +++ b/stir.ino @@ -1,18 +1,15 @@ -/////////////////////////////////////////////////////////////////////////////// Stir Control (mwx'2019, v1.3.3) +/////////////////////////////////////////////////////////////////////////////// Stir Control (mwx'2019, v1.4.0) #include #include - -#define SX Serial.print -#define SXN Serial.println #define MS (long)millis() + int SPEEDINC = 50; // speed increment (rpm) int FANMIN = 200; // fan minimum speed (rpm) int FANMAX = 1600; // fan maximum speed (rpm) int CATCHSTOP = 20000; // catch stop period (ms) -double BOOSTRAMP = 60000; // rise time for boost speed (ms) int PWM0 = 9; // PWM pin for 1. fan int PWM1 = 10; // PWM pin for 2. fan @@ -31,27 +28,30 @@ int RTOL = 8; int SINTERVAL = 2000; // speed measurement interval int SAVERAGE = 4; // speed measurement average -int SAVETAG = 1006; // save tag +int SAVETAG = 1007; // save tag int SAVEDELAY = 60000; // EEPROM save delay (ms) +byte aright[] = {0x00,0x08,0x0C,0x0E,0x0C,0x08,0x00,0x00}; // LCD character +byte aup[] = {0x04,0x0E,0x1F,0x00,0x00,0x00,0x00,0x00}; + LiquidCrystal_I2C lcd(0x27,16,2); // LCD display (connect to SDA/SCL) int i,v0,b0,r0,v1,b1,r1,fanstate0,fanstate1; // speed and regulation -long rpmcount0,rpmcount1,speedcount0,speedcount1; // rpm counter -double r,rx,rpm0,rpm1,xpm0,xpm1,xb0,xb1; // rpm - -long xts,sts,rts,swts,bts,ox,savets,catchts0,catchts1,stop0,stop1,b0ts,b1ts; // timing +double r,rx,rpm0,rpm1,xpm0,xpm1,xb0,xb1,xv0,xv1,rtime0,rtime1; +long rpmcount0,rpmcount1,speedcount0,speedcount1; // interrupt rpm counter +long xts,sts,rts,swts,bts,ox,savets,catchts0,catchts1,stop0,stop1,b0ts,b1ts,v0ts,v1ts; // timing int bdelay,bprocess,enclast,encval,swmode,mode; // button/encoder processing -int OK,SAVE,LOCK,bstate0,bstate1,btime0,btime1,catch0,catch1,ctime0,ctime1; // operation state -char form[8],out[128];String str; // string buffer - - +int bstate0,bstate1,btime0,btime1,catch0,catch1,ctime0,ctime1,cstate0,cstate1,SAVE,LOCK; // operating states +char form[8],out[20]; // string buffer + + void setup() { ////////////////////////////////////////////////////////////////////////////////////////// SETUP - rpmcount0=0;rpmcount1=0;speedcount0=0;speedcount1=0;rpm0=0;rpm1=0;xpm0=0;xpm1=0;bprocess=0;r0=0;r1=0;swmode=2; + rpmcount0=0;rpmcount1=0;speedcount0=0;speedcount1=0;rpm0=0;rpm1=0;xpm0=0;xpm1=0; + bprocess=0;r0=0;r1=0;swmode=2;cstate0=0;cstate1=0; Serial.begin(9600); // start serial - lcd.init();lcd.clear();lcd.backlight(); // initialize lcd + lcd.init();lcd.clear();lcd.backlight();lcd.createChar(0,aright);lcd.createChar(1,aup); // initialize lcd pinMode(PWM0,OUTPUT);pinMode(PWM1,OUTPUT); // set PWM pins pinMode(CLK,INPUT);pinMode(DT,INPUT);pinMode(SW,INPUT); // set KY-040 pins @@ -64,19 +64,18 @@ void setup() { ///////////////////////////////////////////////////////////////// SAVE=0; // load/initialize settings if (eer(0)!=SAVETAG) { - v0=300;v1=300;b0=700;b1=700;btime0=30;btime1=30;catch0=0;catch1=0;ctime0=120;ctime1=120; - fanstate0=0;fanstate1=0; + v0=300;v1=300;b0=700;b1=700;btime0=30;btime1=30;catch0=0;catch1=0; + ctime0=120;ctime1=120;rtime0=60;rtime1=60;fanstate0=0;fanstate1=0; eew(0,SAVETAG);save(); } else { - v0=eer(1);v1=eer(2);b0=eer(3);b1=eer(4);btime0=eer(5);btime1=eer(6); - catch0=eer(7);catch1=eer(8);ctime0=eer(9);ctime1=eer(10);fanstate0=eer(11);fanstate1=eer(12); + v0=eer(1);v1=eer(2);b0=eer(3);b1=eer(4);btime0=eer(5);btime1=eer(6);catch0=eer(7);catch1=eer(8); + ctime0=eer(9);ctime1=eer(10);fanstate0=eer(11);fanstate1=eer(12);rtime0=eer(13);rtime1=eer(14); } enclast=digitalRead(CLK); // get encoder state - xts=MS;sts=MS;rts=MS;swts=MS;bts=MS;savets=MS;catchts0=MS;catchts1=MS;stop0=MS;stop1=MS; // set timer + xts=sts=rts=swts=bts=savets=catchts0=catchts1=stop0=stop1=v0ts=v1ts=MS; // set timer bstate0=0;bstate1=0;mode=0;updatePWM();updatelcd();updatespeed();updatemarker();LOCK=0; // set initial states - } @@ -84,67 +83,24 @@ void loop() { ////////////////////////////////////////////////////////////////// if (SAVE>0 && MS-savets>SAVEDELAY) {;save();SAVE=0;savets=MS;} ////////////////////// save settings if needed - if (catch0 && MS-catchts0>(long)ctime0*60000) { ////////////////////////////////////// check catch fish state - catchts0=MS;stop0=MS+CATCHSTOP; - updatePWM(); + if (catch0 && MS-catchts0>(long)ctime0*60000 && fanstate0==1) { ///////////////////////// initiate catch fish + catchts0=MS;cstate0=1;fanstate0=0;stop0=MS;updatePWM();updatespeed(); } - if (catch1 && MS-catchts1>(long)ctime1*60000) { - catchts1=MS;stop1=MS+CATCHSTOP; - updatePWM(); + if (catch1 && MS-catchts1>(long)ctime1*60000 && fanstate1==1) { + catchts1=MS;cstate1=1;fanstate1=0;stop1=MS;updatePWM();updatespeed(); + } + + if (cstate0 && MS-stop0>CATCHSTOP && fanstate0==0) { ///////////////////////// stop catch fish and start over + cstate0=0;fanstate0=1;v0ts=MS;rts=MS+2000;updatePWM();updatespeed(); + } + + if (cstate1 && MS-stop1>CATCHSTOP && fanstate1==0) { + cstate1=0;fanstate1=1;v1ts=MS;rts=MS+2000;updatePWM();updatespeed(); } if (bstate0 && MS-b0ts>(long)btime0*60000) {;bstate0=0;mode=0;updatelcd();} /////////////// check boost state if (bstate1 && MS-b1ts>(long)btime1*60000) {;bstate1=0;mode=0;updatelcd();} - if (Serial.available() > 0) { ////////////////////////////////////////////////////////// serial communication - str=Serial.readString();OK=0; - - if (str=="info") {;serinfo();OK=1;} // info - - if (str.substring(0,5)=="speed") { // speed - v0=sstr(str,':',1).toInt();v1=sstr(str,':',2).toInt(); - updatePWM();r0=0;r1=0;rts=MS+RDELAY; - SAVE++;OK=1;updatelcd();serinfo(); - } - - if (str.substring(0,6)=="bspeed") { // bspeed - b0=sstr(str,':',1).toInt();b1=sstr(str,':',2).toInt(); - updatePWM();r0=0;r1=0;rts=MS+RDELAY; - SAVE++;OK=1;updatelcd();updatespeed();serinfo(); - } - - if (str.substring(0,2)=="on") { // on (value: 0 or 1) - if (sstr(str,':',1).toInt()==1) {;fanstate0=1;r0=0;} else fanstate0=0; - if (sstr(str,':',2).toInt()==1) {;fanstate1=1;r1=0;} else fanstate1=0; - updatePWM();rts=MS+RDELAY; - SAVE++;OK=1;updatelcd();updatespeed();serinfo(); - } - - if (str.substring(0,5)=="boost") { // boost (value: 0 or 1) - if (sstr(str,':',1).toInt()==1) {;rts=MS+RDELAY;bstate0=1;b0ts=MS;} else {;bstate0=0;} - if (sstr(str,':',2).toInt()==1) {;rts=MS+RDELAY;bstate1=1;b1ts=MS;} else {;bstate1=0;} - SAVE++;OK=1;updatelcd();updatespeed();serinfo(); - } - - if (str.substring(0,5)=="catch") { // catch (value: 0 or 1) - if (sstr(str,':',1).toInt()==1) {;catch0=1;catchts0=MS;} else {;catch0=0;} - if (sstr(str,':',2).toInt()==1) {;catch1=1;catchts1=MS;} else {;catch1=0;} - SAVE++;OK=1;updatelcd();updatespeed();serinfo(); - } - - if (str.substring(0,5)=="btime") { // btime (value: 0-60) - btime0=cut(sstr(str,':',1).toInt(),0,60);btime1=cut(sstr(str,':',2).toInt(),0,60); - SAVE++;OK=1;updatelcd();updatespeed();serinfo(); - } - - if (str.substring(0,5)=="ctime") { // ctime (value: 60-240) - ctime0=cut(sstr(str,':',1).toInt(),60,240);ctime1=cut(sstr(str,':',2).toInt(),60,240); - SAVE++;OK=1;updatelcd();updatespeed();serinfo(); - } - - if (!OK) SXN("error"); - } - if (MS-xts>SINTERVAL) { /////////////////////////////////////////////////////////////////// speed measurement xpm0=xpm0*(SAVERAGE-1)/SAVERAGE+(speedcount0/((MS-xts)/1000.0)*30.0)/SAVERAGE; xpm1=xpm1*(SAVERAGE-1)/SAVERAGE+(speedcount1/((MS-xts)/1000.0)*30.0)/SAVERAGE; @@ -156,25 +112,23 @@ void loop() { ////////////////////////////////////////////////////////////////// rpm1=rpmcount1/((MS-sts)/1000.0)*30.0; sts=MS;rpmcount0=0;rpmcount1=0; - xb0=b0;if (bstate0) xb0=cut((((double)b0-(double)v0)/BOOSTRAMP*(MS-b0ts))+v0,v0,b0); - xb1=b1;if (bstate1) xb1=cut((((double)b1-(double)v1)/BOOSTRAMP*(MS-b1ts))+v1,v1,b1); + calcramp(); - if (MS>=stop0+20000) { - if (!fanstate0) r0=0; - else { - r=(bstate0?xb0:v0)-rpm0; - if (abs(r)>RTOL) r0=r<0?r0-1-abs(r)/10:r0+1+abs(r)/10; - } + if (!fanstate0) {;r0=0;OCR1A=0;} + else { + r=(bstate0?xb0:xv0)-rpm0; + if (abs(r)>RTOL) r0=r<0?r0-1-abs(r)/10:r0+1+abs(r)/10; + OCR1A=cut((bstate0?xb0:xv0)/(FANMAX/320.0)+r0,0,320); } - if (MS>=stop1+20000) { - if (!fanstate1) r1=0; - else { - r=(bstate1?xb1:v1)-rpm1; - if (abs(r)>RTOL) r1=r<0?r1-1-abs(r)/10:r1+1+abs(r)/10; - } - } - updatePWM();updatespeed();rts=MS; + if (!fanstate1) {;r1=0;OCR1B=0;} + else { + r=(bstate1?xb1:xv1)-rpm1; + if (abs(r)>RTOL) r1=r<0?r1-1-abs(r)/10:r1+1+abs(r)/10; + OCR1B=cut((bstate1?xb1:xv1)/(FANMAX/320.0)+r1,0,320); + } + + updatespeed();rts=MS; } bdelay=0; //////////////////////////////////////////////////////////////////////////////////// process switch @@ -191,27 +145,23 @@ void loop() { ////////////////////////////////////////////////////////////////// if (bdelay>20) { if (swmode==0 && mode==0 && !LOCK) { // fan 0 on/off - if (fanstate0==0) {;rts=MS+RDELAY;fanstate0=1;r0=0;updatePWM();} + if (fanstate0==0) {;rts=MS+RDELAY;fanstate0=1;catchts0=v0ts=MS;r0=0;updatePWM();} else {;fanstate0=0;bstate0=0;} - updatespeed(); } + if (swmode==1 && mode==0 && !LOCK) { // fan 1 on/off - if (fanstate1==0) {;rts=MS+RDELAY;fanstate1=1;r1=0;updatePWM();} + if (fanstate1==0) {;rts=MS+RDELAY;fanstate1=1;catchts1=v1ts=MS;r1=0;updatePWM();} else {;fanstate1=0;bstate1=0;} - updatespeed(); } if (swmode==0 && mode==1 && !LOCK) { // boost fan 0 on/off - if (bstate0==0) { - rts=MS+RDELAY;bstate0=1;b0ts=MS;fanstate0=1; - } else {;bstate0=0;rts=MS+RDELAY+2000;updatePWM();} - updatespeed(); + if (bstate0==0) {;rts=MS+RDELAY;bstate0=1;b0ts=MS;fanstate0=1;v0ts=MS;} + else {;bstate0=0;rts=MS+RDELAY+2000;updatePWM();} } + if (swmode==1 && mode==1 && !LOCK) { // boost fan 1 on/off - if (bstate1==0) { - rts=MS+RDELAY;bstate1=1;b1ts=MS;fanstate1=1; - } else {;bstate1=0;rts=MS+RDELAY+2000;updatePWM();} - updatespeed(); + if (bstate1==0) {;rts=MS+RDELAY;bstate1=1;b1ts=MS;fanstate1=1;v1ts=MS;} + else {;bstate1=0;rts=MS+RDELAY+2000;updatePWM();} } if (swmode==2) { // lock/unlock @@ -221,6 +171,7 @@ void loop() { ////////////////////////////////////////////////////////////////// save(); } + updatespeed(); bdelay=0; } else if (bdelay>0 && bdelay<20 && !LOCK) { // short button press, switch: menu -> fan 0 -> fan 1 @@ -248,6 +199,8 @@ void loop() { ////////////////////////////////////////////////////////////////// if (swmode==1 && mode==3) catch1++; // catch 1 on/off if (swmode==0 && mode==4) ctime0+=10; // catch time 0 up if (swmode==1 && mode==4) ctime1+=10; // catch time 1 up + if (swmode==0 && mode==5) rtime0+=10; // rise time 0 up + if (swmode==1 && mode==5) rtime1+=10; // rise time 1 up if (swmode==2) mode++; // scroll menu } else { // turn encoder counterclockwise if (swmode==0 && mode==0) v0-=SPEEDINC; // fan 0 speed down @@ -260,6 +213,8 @@ void loop() { ////////////////////////////////////////////////////////////////// if (swmode==1 && mode==3) catch1--; // catch 1 on/off if (swmode==0 && mode==4) ctime0-=10; // catch time 0 down if (swmode==1 && mode==4) ctime1-=10; // catch time 1 down + if (swmode==0 && mode==5) rtime0-=10; // rise time 0 down + if (swmode==1 && mode==5) rtime1-=10; // rise time 1 down if (swmode==2) mode--; // scroll menu } @@ -277,7 +232,10 @@ void loop() { ////////////////////////////////////////////////////////////////// if (swmode==0 && mode==4) ctime0=cut(ctime0,60,240); // check catch time fan 0 if (swmode==1 && mode==4) ctime1=cut(ctime1,60,240); // check catch time fan 1 - if (swmode==2) mode=cut(mode,0,4); // check menu mode + if (swmode==0 && mode==5) rtime0=cut(rtime0,0,240); // check rise time fan 0 + if (swmode==1 && mode==5) rtime1=cut(rtime1,0,240); // check rise time fan 1 + + if (swmode==2) mode=cut(mode,0,5); // check menu mode SAVE++;updatelcd();delay(50); } @@ -289,84 +247,80 @@ void loop() { ////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// SUPPORT void updatelcd() { ///////////////////////////////////////////////////////////////////////////////// update LCD - if (mode==0) { - slcd(1,1,5,"SPEED");ilcd(7,1,-4,int(v0));ilcd(12,1,-4,int(v1)); - } - if (mode==1) { - slcd(1,1,5,"BOOST");ilcd(7,1,-4,int(b0));ilcd(12,1,-4,int(b1)); - } - if (mode==2) { - slcd(1,1,5,"BTIME");ilcd(7,1,-4,int(btime0));ilcd(12,1,-4,int(btime1)); - } + if (mode==0) {;slcd(1,1,5,"SPEED");ilcd(7,1,-4,int(v0));ilcd(12,1,-4,int(v1));} + if (mode==1) {;slcd(1,1,5,"BOOST");ilcd(7,1,-4,int(b0));ilcd(12,1,-4,int(b1));} + if (mode==2) {;slcd(1,1,5,"BTIME");ilcd(7,1,-4,int(btime0));ilcd(12,1,-4,int(btime1));} if (mode==3) { slcd(1,1,5,"CATCH"); if (catch0==0) slcd( 7,1,-4,"OFF"); else slcd( 7,1,-3,"ON"); if (catch1==0) slcd(12,1,-4,"OFF"); else slcd(12,1,-3,"ON"); } - if (mode==4) { - slcd(1,1,5,"CTIME");ilcd(7,1,-4,int(ctime0));ilcd(12,1,-4,int(ctime1)); - } + if (mode==4) {;slcd(1,1,5,"CTIME");ilcd(7,1,-4,int(ctime0));ilcd(12,1,-4,int(ctime1));} + if (mode==5) {;slcd(1,1,5,"RTIME");ilcd(7,1,-4,int(rtime0));ilcd(12,1,-4,int(rtime1));} } -void updatemarker() { /////////////////////////////////////////////////////////////////// update current marker +void updatemarker() { ////////////////////////////////////////////////////////////////////// update menu marker slcd(0,1,1," ");slcd(6,1,1," ");slcd(11,1,1," "); if (!LOCK) { - if (swmode==0) slcd( 6,1,1,">"); - if (swmode==1) slcd(11,1,1,">"); - if (swmode==2) slcd( 0,1,1,">"); + if (swmode==0) clcd(6,1,0); + if (swmode==1) clcd(11,1,0); + if (swmode==2) clcd(0,1,0); } } void updatespeed() { ///////////////////////////////////////////////////////////////////////// update fan speed - slcd(1,0,5," "); - if (fanstate0) { - if (MSidx?data.substring(si[0],si[1]):""; + eew(1,v0);eew(2,v1);eew(3,b0);eew(4,b1);eew(5,btime0);eew(6,btime1);eew(7,catch0);eew(8,catch1); + eew(9,ctime0);eew(10,ctime1);eew(11,fanstate0);eew(12,fanstate1);eew(13,rtime0);eew(14,rtime1); } /////////////////////////////////////////////////////////////////////////////////////////////////////////// END \ No newline at end of file