// Last used 08-05-20 // Last update 1: Fixed redisplay problem when exiting mode==3 // Intelligent_Plasma_Ball_V10.7 // //********************************************************************* //This is an example for our Monochrome OLEDs based on SSD1306 drivers // // Pick one up today in the adafruit shop! // ------> http://www.adafruit.com/category/63_98 // //This example is for a 128x64 size display using I2C to communicate //3 pins are required to interface (2 I2C and one reset) // //Adafruit invests time and resources providing this open source code, //please support Adafruit and open-source hardware by purchasing //products from Adafruit! // //Written by Limor Fried/Ladyada for Adafruit Industries. //BSD license, check license.txt for more information //All text above, and the splash screen must be included in any redistribution //*********************************************************************/ #include #include #define BAUD 9600 // defined serial port BAUD rate #define CPU_Clk 16000000 // Arduino base clock speed #define comptemp 0 // compensation Time for calling "checkTemp" routine #define comptime 1 // compensation time for calling "checkTime" routine #define cursorPin 8 // used to check if cursor move is requested // ***************************************************************** #define defaultFreqTime 5000 // 3 minutes in milliSeconds = 180000 #define defaultRunTime 1800000 // 30 minutes in milliSeconds = 1800000 // ***************************************************************** #define disablePin 12 // used to disable triggering the MOSFET #define intPin 2 // Interrupt 1 on pin 2 #define Freq2Pin 3 // Frequency 2 on pin 3 #define highEPromAd 900 // define High eeprom address #define line0X 2 // Proto (Frequency set Number) X position #define line1X 0 // F1 starting curX postion #define line2X 1 // F2 starting curX postion #define line0Y 0 // Proto (frequency set number) Y position #define line0YC 2 // Proto Y Cursor position #define line1YP 9 // 1st Y address for Protocol numbers #define line1Y 12 // F1 starting curY postion #define line1YC 14 // cursor for F1 starting curY postion #define line2Y 23 // F2 starting curY postion 18 #define line2YC 25 // cursor for F2 starting curY postion 20 #define lowEPromAd 0 // define low eeprom address #define OLED_RESET 4 // Needed for OLED Display #define outputA 6 // Rotary Encoder "A" connection #define outputB 7 // Rotary Encoder "B" connection #define shutDown 9 // Shutdown pin for disabling the MOSFET #define startFreq 2 // default Starting Frequency Range group ID #define startSweep 4 // default Starting Sweep Range group ID #define stopFreq 3 // default Starting Frequency Range group ID #define stopSweep 5 // default Starting Sweep Range group ID #define temp 720 // temperature limit for the MOSFET Adafruit_SSD1306 display(OLED_RESET); byte breakSw=0; // used to break out of scaling2B routine byte change = 0; // byte change2 = 0; // Set if the cursor has moved byte change3 = 0; // used to designate "protoID" has changed byte curX; // byte curX1; // byte curX2; // byte curY; // byte curY1; // byte curY2; // byte intFlag; // byte lowFreqSw; // byte mode; // Modes 1=SIMPLE, 2=PROTOCOL, 3=SWEEP byte runFlag; // byte runningOnce; // byte setupOpt = 0; // byte singleShot; // int eeAddress = 0; // EEPROM initgial starting address int eeAddress2 = 902; // Startup and Option area int eeAddress3 = 920; // Protocol sequence area int groups; // The number of groups being held in the EEPROM int i; // general purpose increment counter int protoID; // Protocal ID int startFreqGrpID; // starting Frequency Group ID int startSweepGrpID; // starting Sweep Group ID int stopFreqGrpID; // stopping Frequency Group ID int stopSweepGrpID; // stopping Sweep Group ID int temper = temp; // temper contains the present MOSFET temperature unsigned int sweepNumCnt; // Sweep Number Count word dutycycle; // word pulses; // unsigned long endTime1; // 180 seconds, freq set time, default = 180000 = 3 minutes unsigned long endTime2; // 1 minute, protocol time, default = 1800000 = 30 minutes unsigned long runTime; // work run Time field unsigned long runTime1; // working field for running time of a frequency set unsigned long runTime2; // working field for running time of a protocol unsigned long mills; // = OFF time when doing "scaling 2B" routine unsigned long mills2; // = ON time when doing "scaling 2B" routine unsigned long RunMills; // Work field for "scaling 2b" routine unsigned long longCnt = 0; // Long Cnt to waste time for checktemp calls float DutyCycleF = 0.20; // User Selected Floating Version float DutyCycle2F = 0.50; // User Selected Floating Version float F0 = 0.00; // used in Sweep function float F1 = 28512; // frequency (in Hz) float F1save; // a save field for F1 float F1work; // Working version for Increment or Decrement of F1 float F2 = 7.83; // frequency (in Hz) float FreqF; // User Selected Floating version of Frequency float Freq2F; // User Selected Floating version of Frequency float freqIncDec; // frequency Increment or Decrement number in hertz float MPUclockF; // CPU_Clk / FreqF for floating Prescaler float work; struct EPromObject { // This structure contains the two channel basics int field0; // number or ID of frequency & DutyCycle group stored float field1; // Frequency 1 float field2; // Duty Cycle 1 float field3; // Frequnecy 2 float field4; // Duty Cycle 2 }; struct EPromObject2 { // structure contains startup and range defaults int field0; // Last ProtoID used byte field1; // mode of operation SIMPLE, PROTOCOL, or SWEEP unsigned long field2; // Total Program runtime in seconds eg. 600000 = 10 minutes unsigned long field3; // Total frequency runtime in seconds eg 60000 = 1 minute int field4; // start group for Frequency Range int field5; // stop group for Frequency Range int field6; // start group for Sweep Range int field7; // stop group for Sweep Range }; void setup() { for(i=0; i<5; ++i){ Serial.begin(BAUD); // Set the baud rate to 9600 while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only }} pinMode(9, OUTPUT); // OCnA for timer 1 pinMode(10 , OUTPUT); // OCnB for timer 1 pinMode(11, OUTPUT); // OCnA for timer 2 pinMode(3 , OUTPUT); // OCnB for timer 2 // Adafruit_SSD1306 display(OLED_RESET); // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (hanged to 0x3C) (for the 128x64) // SSD1306 init done pinMode(disablePin, INPUT); // NOTE: Making it an INPUT effectively floats the PIN pinMode(cursorPin,INPUT); // This a polled pin to detect if cursor move switch pressed digitalWrite(cursorPin, INPUT_PULLUP);// Enable the pullup resistor on this pin pinMode(outputA,INPUT); // Used to detect rotary encoder movement digitalWrite(outputA, INPUT_PULLUP); // Enable the pullup resistor on this pin pinMode(outputB,INPUT); // Used to detect rotary encoder movement digitalWrite(outputB, INPUT_PULLUP); // Enable the pullup resistor on this pin pinMode(intPin, INPUT); // Interrupt Pin #2 pin digitalWrite(intPin, INPUT_PULLUP); // Insure interrupt is normally high attachInterrupt(digitalPinToInterrupt(intPin),breakout1,FALLING); display.setTextSize(1); display.setTextColor(WHITE); display.clearDisplay(); // Clear the buffer display.display(); // Clear the buffer curX=38; // Changes depending what line position is displayed curY=line0YC; // Changes depending what line is displayed intFlag = 0; // Initialize for startup runFlag = 0; // Initialize for startup runningOnce = 1; // initialize for startup singleShot = 0; // initialize for startup lowFreqSw=1; // turn on low Frequency Switch mode=1; // initialize mode to 1=SIMPLE if(!digitalRead(cursorPin)){ // clear EEPROM memory on condition for (int i = 0 ; i < EEPROM.length() ; i++) { EEPROM.write(i, 0); } } //************************Fetch the EProm Data*************************************** EPromObject2 customVar; // Variables to store custom objects in EEPROM eeAddress=highEPromAd; // define starting eeprom address EEPROM.get(eeAddress,customVar); // Fetch data from EPROM protoID=customVar.field0; // fetch the group number stored in the EPROM //********************************************************* //********************************************************* //protoID=0; //******************** // ***** temp to force a write to the EEPROM ***** if(protoID<=0){ // check if writing for the first time protoID=1; // initialize Protocol ID to 1 EPromObject customVar1; // assign customVar1 structure to this EProm Object customVar1.field0=protoID; // set for the startup default settings customVar1.field1=F1; // set for at least 1 group customVar1.field2=DutyCycleF; // set for at least 1 group customVar1.field3=F2; // set for at least 1 group customVar1.field4=DutyCycle2F; // set for at least 1 group eeAddress=lowEPromAd; // define beginning address to store variables EEPROM.put(eeAddress,customVar1); // Update EProm EPromObject2 customVar2; // Variables to store custom objects in EEPROM customVar2.field0=protoID; // set the default last_protoID to present protoID customVar2.field1=mode; // set to default SIMPLE Mode 1 customVar2.field2=defaultFreqTime; // set to run frequencies for default 3 minutes customVar2.field3=defaultRunTime; // set to 30 minutes default program Run time customVar2.field4=startFreq; // set a default Start Frequency Group ID customVar2.field5=stopFreq; // set a default Stop Frequency Group ID customVar2.field6=startSweep; // set a defaull Start Sweep Group ID customVar2.field7=stopSweep; // set a default Stop Sweep Group ID eeAddress=highEPromAd; // define starting eeprom address EEPROM.put(eeAddress,customVar2); // Update EProm } EPromObject customVar3; // Variables to store custom objects in EEPROM eeAddress=(protoID-1)*18; // point to proper "Frequency Set" eeprom area EEPROM.get(eeAddress,customVar3); // Fetch data from EPROM protoID=customVar3.field0; // fetch the the 'set' related to this protoID F1=customVar3.field1; // Fetch and load Frequency 1 F1save=F1; // save it in F1 save for mode==3 DutyCycleF=customVar3.field2; // Fetch and load Duty Cycle 1 F2=customVar3.field3; // Fetch and load Frequency 2 DutyCycle2F=customVar3.field4; // Fetch and load Duty Cycle 2 EPromObject2 customVar4; // Variables to store custom objects in EEPROM eeAddress=highEPromAd; // define starting eeprom address EEPROM.get(eeAddress,customVar4); // Fetch data from the EProm mode=customVar4.field1; // fetch the mode from EEPROM endTime1=customVar4.field2; // fetch the frequency run time from the EEPROM endTime2=customVar4.field3; // fetch the Program run time from the EEPROM startFreqGrpID=customVar4.field4; // fetch the starting Frequency Group ID stopFreqGrpID=customVar4.field5; // fetch the stopping Frequency Group ID startSweepGrpID=customVar4.field6; // fetch the starting Sweep Group ID stopSweepGrpID=customVar4.field7; // fetch the stopping Sweep Group ID Serial.println("Program Started"); // Used while in development mode } void loop(){ if(intFlag==1){ // Used to intercept Running the Arduino PWM runFlag=runFlag^1; // Whenever an interrupt flip the run flag if(mode==3 && runFlag==0){ // if Mode 3 then the screen needs to be displayed Display(); // Display Frequency & Duty Cycle of where you stopped singleShot=0; } delay(200); // debounce the intFlag=0; // turn off the interrupt flag interrupts(); // Enable INTERRUPTS if(runFlag==true){ // check if Runtime Clocks need to be set if(mode==2 && setupOpt==0){ // on condition run a Protocol & fetch related parameters protoID=startFreqGrpID; // fetch the Starting Protocol ID getGroup(); // fetch the Frequencies and Duty Cycles } if(mode==3 && setupOpt==0){ // on condition run a Sweep & fetch related parameters protoID=stopSweepGrpID; // fetch the stop frequency getGroup(); // fetch the frequencies and duty cycles F1work=F1; // used as the F1 working increment Frequency protoID=startSweepGrpID; // fetch the start frequency getGroup(); // fetch the frequencies and duty cycles F1save=F1; // save this because you will need it for "sweep()" function calcHertz(); // calculate the frequency shift in hertz } clocks(1); // set the runtime clocks to active mode } } if(runFlag==1){ // If run Flag on then start the PWM oscillators checkTemp(); // insure the MOSFET doesn't get too hot if(runningOnce==1 || (mode==3 && setupOpt==1)){ // Do once mode 1 & 2, always do (mode 3 && setupOpt = 1) if(F1!=0.0){ // check if F1=0 FreqF = F1; // Fetch the start or last frequency used for Timer 1 Freq2F = F2; // Fetch the start or last frequency used for Timer 2 displayRunning(); scaling1(); // Set up to run Frequency 1 using Arduino Timer 1 // if(mode!=3 || setupOpt==1){ // Do nothing with memory if in mode==3 if(Freq2F<=31.5) // Check if Timer 2 request is slower than 31.5 hertz scaling2B(); // perform Scaling for frequency below 31.5 hertz else // if here than frequency is above 31.5 hertz scaling2(); // peform the scaling for the frequency above 3.15 hertz EPromObject customVar1; // Variables to store custom objects in EEPROM if(mode!=3 || setupOpt==1){ // Do nothing with memory if in mode==3 customVar1.field1=F1; // set for at least 1 group customVar1.field2=DutyCycleF; // set for at least 1 group customVar1.field3=F2; // set for at least 1 group customVar1.field4=DutyCycle2F; // set for at least 1 group } customVar1.field0=protoID; // set for at least 1 group eeAddress=(protoID-1)*18; // move frequency set to appropriate area EEPROM.put(eeAddress,customVar1); // Update EProm EPromObject2 customVar; // setup customVar pointer customVar.field0=protoID; // save this to the last_protoID field in the eeprom customVar.field1=mode; // Save the mode customVar.field2=endTime1; // save the Frequency runtime customVar.field3=endTime2; // save the Program runtine customVar.field4=startFreqGrpID; // save the start Frequency Group ID customVar.field5=stopFreqGrpID; // save the stop Frequency Group ID customVar.field6=startSweepGrpID; // save the start Sweep Group ID customVar.field7=stopSweepGrpID; // save the stop Sweep Group ID eeAddress=highEPromAd; // the the high eeprom address EEPROM.put(eeAddress,customVar); // Update EProm singleShot=0; // allow the display "rotary" values if and when requested // } // feature not implemented if(Freq2F>31.5) // check if comint out of 'scaling2B' the low frequency routine runningOnce=0; // NOT coming from scaling2B so do do above until an interrupt happesn } else{ runFlag=0; // if here F1 == 0.0 so turn off runFlag //Serial.println("HERE Finished Stopping"); } } checkTime(); } else{ // If here running is stopped and addjust frequencies if(singleShot==0){ // If here than you are going to run the rotary encoder routine //Serial.println("SingleShot=0"); Display(); // Display the Frequencies values and associated Duty cycles scaling1(); // Fetch Frequency 1 scaling values scaling2(); // Fetch Frequency 2 scaling values TCCR1A=0; // shut PWM off which is Arduino Timer 1 TCCR2A=0; // shut PWM off which is Arduino Timer 2 singleShot=true; // allow looping on rotary without doing the Display with scaling runningOnce=true; // When RUN is requested this will display "RUNNING" and more if(mode==3){ EPromObject2 customVar; // setup customVar pointer customVar.field1=3; // Save the mode eeAddress=highEPromAd; // the the high eeprom address EEPROM.put(eeAddress,customVar); // Update EProm } pinMode(disablePin, INPUT); // This floats the Pin allowing the MOSFET to be triggered clocks(0); // set the runtime to STOP mode } rotary(); // allow the rotary to update frequency and duty cycle value cursorMove(); // move the cursot to value that potentially could change if(change==1 || change2==1){ // if a value or cursor postion changed than display the change Display(); // Something changed so do a Display if(setupOpt==0) // check if reading EEPROM memory settingsRtn(); // if here you are in setting mode } } } void calcHertz(){ F0=F1work-F1; sweepNumCnt = endTime2 / endTime1; freqIncDec=F0/sweepNumCnt; F1work=F1save; } void clocks(byte function){ // check what you want to do if(function == false){ // on condition zero out the RunTimes(s) runTime1=runTime2=0; // zero the Runtimes } if(function == true){ // if true then set the RunTime(s) runTime1=endTime1+millis(); // set the RUN Frequency Set time runTime2=endTime2+millis(); // set the RUN Protocol time } } void displayRunning(){ display.clearDisplay(); // Clear the OLED buffer display.setCursor(0,0); // Set the OLED cursor postion display.setTextSize(2); // Set the OLED text size display.print("Running"); // Display "Running" display.setTextSize(1); // switch back to the smaller text size display.print(" T="); // display a label for temperature temper=analogRead(A7); // actually read the temperature display.print(temper); // display the fetched temperature display.setCursor(0,21); // Position to display 'protoID' or 'sweepNumCnt' display.print("Num="); // display Number label if(mode!=3) // if not a sweep then display 'protoID' display.print(protoID); // display 'protoID' else display.print(sweepNumCnt); // if here display the Sweep number display.setCursor(48,17); // display.print(" F1="); // now display the Main Frequency 'F1' display.print(F1); // F1 is the channel 1 frequency display.setCursor(48,25); display.print(" F2="); // now display the Main Frequency 'F1' display.print(F2); // F1 is the channel 1 frequency display.display(); // This command actually displays text to the OLED } void scaling1(){ TCCR1A = _BV(COM1A0) | _BV(COM1B1) | _BV(WGM10) | _BV(WGM11); if(FreqF < 10){ // Use 1024 as prescaller TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10) | _BV(CS12); //Serial.println("Here 1024"); MPUclockF = CPU_Clk / 1024; // Clock division } if(FreqF >= 10 && FreqF < 100){ // Use 256 as prescaller TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS12); //Serial.println("Here 256"); MPUclockF = CPU_Clk / 256; // Clock division } if(FreqF >= 100 && FreqF < 250){ // Use 64 as prescaller TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10) | _BV(CS11); //Serial.println("Here 64"); MPUclockF = CPU_Clk / 64; // Clock division } if(FreqF >= 250 && FreqF < 1500){ // Use 8 as prescaller TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS11); //Serial.println("Here 8"); MPUclockF = CPU_Clk / 8; // Clock division } if(FreqF >= 1500){ // Use 1 as prescaller TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS10); //Serial.println("Here 1"); MPUclockF = CPU_Clk / 1; // Clock division } //Serial.print("F1 = "); //Serial.print(F1); //Serial.print(" DutyCycleF = "); //Serial.println(DutyCycleF); if(F1<5000&&DutyCycleF>0.20) DutyCycleF=0.20; if(F1<4000&&DutyCycleF>0.15) DutyCycleF=0.15; if(F1<3000&&DutyCycleF>0.10) DutyCycleF=0.10; if(F1<1000&&DutyCycleF>0.05) DutyCycleF=0.05; if(F1<100&&DutyCycleF>0.03) DutyCycleF=0.03; if(F1<50) DutyCycleF=0.00; FreqF = FreqF * 100; // This removes the decimal point values if any FreqF = round(FreqF); // round to give you a little better accuracy FreqF = FreqF / 100; // restore adjusted Frequency value MPUclockF = (MPUclockF+1) / FreqF; // MPU Clock pulses need to generate FreqF pulses = round(MPUclockF); // put the round value in pulses work field OCR1AH = pulses>>8; // Set the frequency pulses to OCR1A high register OCR1AL = pulses; // Set the frequency pulses to OCRIA low register dutycycle = MPUclockF * DutyCycleF; // calculate duty cycle pulse width OCR1BH = dutycycle>>8; // Set the pulse width to OCR1B high register OCR1BL = dutycycle; // Set the pulse width to OCR1B low register //Serial.print(" DutyCycleF = "); //Serial.println(DutyCycleF); } void scaling2(){ TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM20); if(Freq2F > 30.5 && Freq2F <260){ // Use 1024 as prescaller TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20); //Serial.println("Here 1024"); MPUclockF = CPU_Clk / 1024; // Clock division } if(Freq2F >= 260 && Freq2F < 1041){ // Use 256 as prescaller TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21); //Serial.println("Here 256"); MPUclockF = CPU_Clk / 256; // Clock division } if(Freq2F >= 1041 && Freq2F < 2083){ // Use 1024 as prescaller TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS20); //Serial.println("Here 128"); MPUclockF = CPU_Clk / 128; // Clock division } if(Freq2F >= 2083 && Freq2F < 4166){ // Use 1024 as prescaller TCCR2B = _BV(WGM22) | _BV(CS22); //Serial.println("Here 64"); MPUclockF = CPU_Clk / 64; // Clock division } if(Freq2F >= 4166 && Freq2F < 8333){ // Use 1024 as prescaller TCCR2B = _BV(WGM22) | _BV(CS21) | _BV(CS20); //Serial.println("Here 32"); MPUclockF = CPU_Clk / 32; // Clock division } if(Freq2F >= 8333 && FreqF < 33333){ // Use 256 as prescaller TCCR2B = _BV(WGM22) | _BV(CS21); //Serial.println("Here 8"); MPUclockF = CPU_Clk / 8; // Clock division } if(Freq2F >= 33333 && Freq2F >=50000){// Use 128 as prescaller TCCR2B = _BV(WGM22) | _BV(CS20); //Serial.println("Here 1"); MPUclockF = CPU_Clk ; // Clock division } Freq2F = Freq2F * 100; // This removes the decimal point values if any Freq2F = round(Freq2F); // round to give you a little better accuracy Freq2F = Freq2F / 100; // restore adjusted Frequency value MPUclockF = (MPUclockF)/ 2 /Freq2F; // MPU Clock pulses need to generate FreqF pulses = round(MPUclockF); // put the round value in pulses work field OCR2A = pulses; // Set the frequency pulses to OCRIA low register dutycycle = MPUclockF * DutyCycle2F; // calculate duty cycle pulse width OCR2B = dutycycle; // Set the pulse width to OCR1B low register } void scaling2B(){ lowFreqSw=1; // turn on low Frequency Switch if it is TCCR2A=0; // Shut of Timer2 work=(1/Freq2F)*(1.0-DutyCycle2F); // Calculate the ON time (see #define for "comptemp") mills2=(work*1000)+comptemp; // Set the OFF time amount to "mills" variable in milliseconds work=(1/Freq2F)*DutyCycle2F; // Calculate the on time (see #define for "comptime") mills=(work*1000)+comptime; // Set the OFF time amount to mills2 vaariable in milliseconds while(lowFreqSw==1){ // stay in the loop for as long as "lowFreqSw" is a low RunMills=mills+millis(); // do High part of cycle first digitalWrite(Freq2Pin, HIGH); // send the high level out to the port while(RunMills>millis()){ // stay high until timer runs out } checkTemp(); // while waiting check if MOSFET tempature OK RunMills=mills2+millis(); // do low part of cycle second digitalWrite(Freq2Pin, LOW); // send the low level out to the port while(RunMills>millis());{ // stay low untile timer runs out } runTime=millis(); // check if you need to break out if(runTime1=10000) F1=F1-10000; // if here decrement the 10000th position of F1 break; case 24: if(F1>=1000) F1=F1-1000; // if here decrement the 1000th position of F1 break; case 30: if(F1>=100) F1=F1-100; // if here decrement the 100th position of F1 break; case 36: if(F1>=10) F1=F1-10; // if here decrement the 10th position of F1 break; case 42: if(F1>=1) F1=F1-1; // if here decrement the units position of F1 break; case 54: F1=F1-0.1; // if here decrement the tenth position of F1 break; case 60: F1=F1-0.01; // if here decrement the hundredth position of F1 break; case 72: endTime1=endTime1-1000000; // if here dec 1000th position of endTime1 Time in seconds break; case 78: endTime1=endTime1-100000; // if here dec 100th position of endTime1 Time in seconds break; case 84: endTime1=endTime1-10000; // if here dec 10th position of endTime1 Time in seconds break; case 90: endTime1=endTime1-1000; // if here dec units position of endTime Time in seconds break; case 102: if(mode==2) --startFreqGrpID; // if here than inc the starting Frequency or Sweep Group ID if(mode==3) --startSweepGrpID; // if here then inc the Starting Sweep Group ID break; case 108: // where Duty Cycl 1 sits on the display DutyCycleF=DutyCycleF-0.1; // if here decrement the tenth position of the duty cycle break; case 114: DutyCycleF=DutyCycleF-0.01; // if here decrement the hundredth position of duty cycle break; } switch (curX){ // do the same as above for Frequency 2 F2 case 19: // where Frequency 2 F2 sits on the display if(F2>=10000) F2=F2-10000; // if here dec Frequency 2 10000th position break; case 25: if(F2>=1000) F2=F2-1000; // if here dec Frequency 2 1000th position break; case 31: if(F2>=100) F2=F2-100; // if here dec Frequency 2 100th position break; case 37: if(F2>=10) F2=F2-10; // if here dec Frequency 2 10th position break; case 43: if(F2>=1) F2=F2-1; // if here dec Frequency 2 units position break; case 55: F2=F2-0.1; // if here dec Frequency 2 tenth position break; case 61: F2=F2-0.01; // if here dec Frequency 2 hundredth position break; case 79: endTime2=endTime2-60000000;// if here dec endTime2 1000th position in minutes break; case 85: endTime2=endTime2-6000000; // if here dec endTime2 100th position in minutes break; case 91: endTime2=endTime2-600000; // if here dec endTime2 10th position in minutes break; case 97: endTime2=endTime2-60000; // if here dec endTime2 units position in minutes break; case 103: if(mode==2) --stopFreqGrpID; // if here than inc the starting Frequency or Sweep Group ID if(mode==3) --stopSweepGrpID; // if here then inc the Starting Sweep Group ID break; case 109: // this is where Duty Cycle 2 sits on the display DutyCycle2F=DutyCycle2F-0.1; // if here decrement the tenth position of Duty Cycle 2 break; case 115: DutyCycle2F=DutyCycle2F-0.01; // if here decrement the hundredth position break; } } if(setupOpt>200) // This can be no lower than 0 setupOpt=0; // if here make it a zero if(setupOpt>5) // check if greater than 5 setupOpt=5; // on condition make it a 5 if(protoID<1) // This can be no lower than 1 protoID=1; // if here make it a 1 if(protoID>50) // This can be no higher than 50t protoID=50; // if here make it a 1 if(mode<1) // This can be no lower than 1 mode=1; // if here make it a 1 if(mode>3) // This can be no higher than 3 mode=3; // if here make it a 3 if(startFreqGrpID<1) // This can be no lower than 1 startFreqGrpID=1; // if here make it a 1 if(startFreqGrpID>50) // This can be no higher than 50 startFreqGrpID=50; // if here make it a 50 if(stopFreqGrpID<1) // This can be no lower than 1 stopFreqGrpID=1; // if here make it a 1 if(stopFreqGrpID>50) // This can be no higher than 50 stopFreqGrpID=50; // if here make it a 50 if(startSweepGrpID<1) // This can be no lower than 1 startSweepGrpID=1; // if here make it a 1 if(startSweepGrpID>50) // This can be no higher than 50 startSweepGrpID=50; // if here make it a 50 if(stopSweepGrpID<1) // This can be no lower than 1 stopSweepGrpID=1; // if here make it a 1 if(stopSweepGrpID>50) // This can be no higher than 50 stopSweepGrpID=50; // if here make it a 50 if(F1>50000.00) // Frequency 1 can be no higher than 50K F1=50000.00; // if higher make it 50K if(F1<1.00) // Frequency 1 can be no lower than 1.00 hertz F1=1.00; // if lower make it 1.00 hertz if(DutyCycleF>0.25) // Duty Cycle 1 can be no higher than 25% DutyCycleF=0.25; // if higher make it 25% if(DutyCycleF<0.00) // Duty Cycle 1 can be no lower than 1% DutyCycleF=0.00; // if lower make it 1% if(F2>8300.00) // Frequency 2 can be no higher than 50K F2=8300.00; // if higher make it 50% if(F2<0.01) // Frequency 2 can be no lower than .01 hertz F2=0.01; // if lower make it .01 hertz if(DutyCycle2F>1.00) // Duty Cycle 2 can be no higher than 100% DutyCycle2F=1.00; // if higher than make it 100% if(DutyCycle2F<0.01) // Duty Cycle 2 can be no lower than 0% DutyCycle2F=0.01; // if lower than make it 0% if(endTime1<1000) // endTime1 can be no lower than 1 seconds endTime1=9999000; // if here make it 9999 seconds if(endTime1>9999000) // endTime can be no higher than 9999 second endTime1=1000; // if here make it cycle around to 1 second //Serial.print("Progm Time = "); //Serial.println(endTime2); if(endTime2<60000) // endTime1 can be no lower than 1 minute endTime2=30000; // if here make it make 30 seconds = 1/2 minute if(endTime2>599940000) // endTime can be no larger than 9999 minutes endTime2=60000; // if here make it 1 minute change=1; // indicate there has be a frequency or duty change } } void cursorMove(){ if(!digitalRead(cursorPin)){ change2=1; // if here then move cursor switch (curX){ case 38: curY=line0YC; // if(setupOpt<3) // means 3, 4, or 5 curX=110; // if here goto "mode" or "protoid" else { curY=line1YC; // now positioned at Freq Time if(setupOpt==5) curX=72; // if here then it was a 5 else curX=102; // if here then setupOpt is 3 or 4 } break; case 110: // if here the go back to setupOpt if(setupOpt!=1) curX=38; // if here go back setupOpt else { curX=18; // if here goto 1st frequency1 position curY=line1YC; } break; case 18: // at 1st frequency1 position curX=24; // if here goto 2nd frequency1 postion break; case 24: // at 2nd frequency1 position curX=30; // if here goto 3rd frequency1 position break; case 30: // at 3rd frequency1 position curX=36; // if here goto 4th frequency1 position break; case 36: // at 4th frequency1 position curX=42; // if here goto 5th frequency1 position break; case 42: // at 5th frequency1 position curX=54; // if here goto 6th frequency1 position break; case 54: // at 6th frequency1 position curX=60; // if here goto 7th frequency1 position break; case 60: // at 7th frequency1 position curX=108; // if here goto 1st duty cycle1 position break; case 72: // at 1st frequency time position curX=78; // if here goto 2nd frequency time position break; case 78: // at 2nd frequency time position curX=84; // if here goto 3rd frequency time position break; case 84: // at 3rd frequency time position curX=90; // if here goto 4th frequency time position break; case 90: // at 4th frequency time postion curX=79; // if here got to 1st program time position curY=line2YC; // program time start on next line break; case 102: // at starting frequency or Sweep protocol group id curX=103; // if here goto stopping frequency protocol group id curY=line2YC; // stopping frequency protocol start on the next break; case 108: // at 1st duty cycle1 position curX=114; // if here goto 2nd duty1 position break; case 114: // at 2nd duty cycle 1 position curX=19; // if here goto 1st frequency2 position curY=line2YC; // frequency2 starts on the next line break; // ************** second line *************** case 19: // at 1st position of frequency2 curX=25; // if here goto 2nd frequency position break; case 25: // at 2nd position of frequency2 curX=31; // if here goto 3rd frequency position break; case 31: // at 3rd position of frequency 2 curX=37; // if here goto 4th frequency position break; case 37: // at 4th position of frequency 2 curX=43; // if here goto 5th frequency position break; case 43: // at 5th position of frequency 2 curX=55; // if here next goto 6th frequency position break; case 55: // at 6th position of frequency 2 curX=61; // if here next goto 7th frequency position break; case 61: // at 7th position of frequency 2 curX=109; // if here next goto 1st Duty Cycle 2 position break; case 79: // at 1st position of program time curX=85; // if here next goto 2nd position of program time break; case 85: // at 2nd position of program time curX=91; // if here next goto 3rd position of program time break; case 91: // at 3rd position of program time curX=97; // if here next goto 4th position of program time break; case 97: // on condition at 4th position of program time curX=38; // if here next goto setupOpt position curY=line0YC; // setupOpt is on the 1st line break; case 103: // on condition at stopping frequency or sweep group ID curX=38; // if here next goto setupOpt position curY=line0YC; break; case 109: // if here at sweep Stopping position group id curX=115; // on condition goto next stopping position group id break; case 115: // on condition at stoppping position group id curX=38; // if here next goto setupOpt position curY=line0YC; break; } } } void Display(){ display.clearDisplay(); // Clear the buffer display.setCursor(line0X,line0Y); // point to Proto line display display.print("Setup="); // Setup Options 0=No, 1=Yes display.print(setupOpt); // setup Opt byte if(setupOpt==0){ display.print(" Freq Rds="); // display last Frequency Set 'protoID' pointer display.print(protoID);} // identifiy what frequency set you are at if(setupOpt==1){ // on condition you are in normal running mode display.print(" Freq Set="); // display last Frequency Set 'protoID' pointer display.print(protoID);} // identifiy what frequency set you are at if(setupOpt==2){ display.print(" Modes="); // if here display which Mode program is running in display.print(mode); // display the mode number display.setCursor(line1X,line1Y); // set the display cursor position display.print("1=SIMPLE, 2=PROTOCOL"); display.setCursor(line2X,line2Y); // set to next display line display.print("3=SWEEP");} if(setupOpt==3 && mode==2){ display.print(" Protocol"); display.setCursor(line1X,line1Y); // set the display cursor position display.print("Range Starting = "); // display line label display.print(startFreqGrpID); // display starting group id display.setCursor(line2X,line2Y); // set to next display line display.print("Range Stopping = "); // display line label display.print(stopFreqGrpID); // display stopping group id } if(setupOpt==4 && mode==3){ display.print(" Sweep"); display.setCursor(line1X,line1Y); // set the display cursor position display.print("Range Starting = "); // display line label display.print(startSweepGrpID); // display starting group id display.setCursor(line2X,line2Y); // set to next display line display.print("Range Stopping = "); // display line label display.print(stopSweepGrpID); // display stopping group id } if(setupOpt==5){ display.setCursor(line1X,line1Y); // set the display cursor position display.print("Freq Time = "); // Dispaly line label runTime=endTime1/1000; // "runTime" is a free work field if(runTime<1000) // on condition display leading zeros for runTime1 display.print('0'); // if here display the zero if(runTime<100) display.print('0'); // if here display the leading zero if(runTime<10) display.print('0'); // if here display the leading zero display.print(runTime); // now display the "runTime" value display.setCursor(line2X,line2Y); // set to next display line display.print("Progm Time = "); // DISPLAY LINE LABEL runTime=endTime2/60000; // "runTime" is a free work field if(runTime<1000) // on condition display leading zeros for runTime2 display.print('0'); // if here display the zero if(runTime<100) display.print('0'); // if here display the leading zero if(runTime<10) display.print('0'); // if here display the leading zero display.print(runTime); // display endTime2 in minutes } if(setupOpt<2){ display.setCursor(line1X,line1Y); // set display to point to line 2 of the display display.print("F1="); // display Frequency 1 designator if(F1<10000) // display leading zeros for Frequency 1 display.print('0'); // on condition display the zero if(F1<1000) display.print('0'); // on condition display the zero if(F1<100) display.print('0'); // on condition display the zero if(F1<10) display.print('0'); // on condition display the zero display.print(F1); // now display the frequency F1 display.print(" D1="); // display the Duty Cycle 1 designator display.print(DutyCycleF); // display Duty Cycle 1 display.setCursor(line2X,line2Y); // set display to point to line 3 of the display display.print("F2="); // display Frequency 2 designator if(F2<10000) // on condition display leading zeros for F2 display.print('0'); // if here display the zero if(F2<1000) display.print('0'); // if here display the zero if(F2<100) display.print('0'); // if here display the zero if(F2<10) display.print('0'); // if here display the zero display.print(F2); // now display the frequency F2 display.print(" D2="); // display the Duty Cycle 2 designator display.print(DutyCycle2F); // display Duty Cycle 2 } display.setCursor(curX,curY); // fetch the user cursor position display.print("_"); // using the underscore to show display cursor position display.display(); // This actually displays everything to the display change = change2 = 0; // clear out frequency and cursor change fields for next round } void settingsRtn(){ EPromObject customVar; // Variables to store custom objects in EEPROM eeAddress=(protoID-1)*18; // move frequency set to appropriate area EEPROM.get(eeAddress,customVar); // Fetch data from EPROM groups=customVar.field0; // fetch the group number stored in the EPROM F1=customVar.field1; // Fetch and load Frequency 1 DutyCycleF=customVar.field2; // Fetch and load Duty Cycle 1 F2=customVar.field3; // Fetch and load Frequency 2 DutyCycle2F=customVar.field4; // Fetch and load Duty Cycle 2 Display(); // on condition display } void sweep(){ F1work=F1work+freqIncDec; --sweepNumCnt; F1=F1work; runningOnce=1; if(sweepNumCnt==0) runFlag=0; } void getGroup(){ EPromObject customVar; //Variable to store custom object read from EEPROM. eeAddress=(protoID-1)*18; EEPROM.get(eeAddress, customVar); // F1=customVar.field1; DutyCycleF=customVar.field2; F2=customVar.field3; DutyCycle2F=customVar.field4; // runningOnce=1; lowFreqSw=0; // if in Scaling2B this forces a break from routine } void protocol(){ ++protoID; if(protoID>stopFreqGrpID) protoID=startFreqGrpID; getGroup(); } void checkTime(){ runTime=millis(); // fetch the present millisecond time if(runTime25000){ // Do this on condition longCnt=0; // clear for restarting count displayRunning(); // NOTE: Will not display when in "scaling2B" } } } void breakout1(){ noInterrupts(); lowFreqSw=0; // turn off low Frequency Switch intFlag=true; }