DutyCycle 1.0
//----------------------------- // Long Cycle PWM Power Controller // Will allow a user to use a pot to initialize a cycle time (1/2 to 5 seconds) // then allow them to use the same pot to change the duty cycle within that cycle // time. This turns a circuit on and off accordingly. // // This uses A4 as the sensor for the 10K pot input, which is used to compute a // percent. // // The output is on control pin 12. Ostensibly to drive an Op Amp, which will drive an // SSR. // // Duty cycles less than 50 milliseconds drops the value to zero, to keep the SSR from cycling // on too short a pulse width. // // Glenn Murray - 2/1/2019 // #include#include #include LCD4Bit_mod lcd = LCD4Bit_mod(2); // Constants // Pins const int dutyCycleInput_SensorPin = A4; // select the input pin for the potentiometer const int ledPin = 13; // select the pin for the LED const int ssrCtrlPin = 12; // select the pin for SSR control output signal // Sensor const long sensorMin = 33; // Min sensor input * 100 const long sensorMax = 1023 - sensorMin; // Max sensor input * 100 // Time const long realMaxTime = 5000.0; // true Max duty cycle const long cycleTimeMin = 500.0; // Min duty cycle const long cycleTimeMax = realMaxTime - cycleTimeMin ; // Max duty cycle const char pc_sign = '%'; const boolean turnOn = true; const boolean turnOff = false; char on[1]; char off[1]; char onval[1]; char blanks[16] = " "; // Variables char buff[16]; long cycleTime; // init to one second cycle time long dutyCycle; // what delay for duty cycle is - as integer long percent; // what % delay for duty cycle is - as integer int n; void setup() { // put your setup code here, to run once: on[0]='+'; off[0]='-'; lcd.init(); lcd.clear(); int ndx = 0; long last_percent = 150; dutyCycle = 0; // This loop is used to determine the cycle time // After 2.5 seconds with no change, it will drop out of the loop, proceeding to the main processing // loop. // while (ndx < 25) { strcpy(buff, blanks); // Clear buffer percent = inputVal(); // Read input, set the percent use n = sprintf(buff, " %4ld",percent); // Write percent to buffer buff[n] = pc_sign; // Add percent sign after percent value lcd.cursorTo(1,0); // Set cursor to LCD first row lcd.printIn(buff); // Write to LCD cycleTime = longPercent( percent, cycleTimeMax ) + cycleTimeMin; // Compute cycle time n = sprintf(buff, " %4ld|%4ld ms", dutyCycle, cycleTime); // Write cycleTime to buffer, dutyCycle is zero at this point lcd.cursorTo(2,0); // Set cursor to LCD second row lcd.printIn(buff); // Write to LCD delay(100); // Delay for 1/10th second // Change detection code, if change made, reset exit counter ndx++; if (last_percent != percent) ndx = 0; last_percent = percent; } lcd.clear(); } void loop() { strcpy(buff, blanks); // Clear buffer at start of loop percent = inputVal(); // Input percent of cycleTime to compute dutyCycle dutyCycle = longPercent( percent, cycleTime); // Compute dutyCycle if (dutyCycle < 50) { // If less than 50 milliseconds, set to zero dutyCycle = 0; percent = 0; } // Prepare buffers to write settings lcd.cursorTo(1,0); n = sprintf(buff, " %4ld",percent); buff[n] = pc_sign; lcd.printIn(buff); n = sprintf(buff, " %4ld|%4ld ms", dutyCycle, cycleTime); lcd.cursorTo(2,0); lcd.printIn(buff); // On portion of cycle if (dutyCycle > 0) { pause( percent,turnOn ); } // Off portion of cycle if (dutyCycle != cycleTime) { pause( percent, turnOff ); } } // Computes percent. Takes number between 0 and 100, then uses that as percentage to compute the percent of value, to return long longPercent(long per, long val) { return (val * per / 100); } // Reads sensor, returns number between 0 and 100 long inputVal() { long sensorValue = (analogRead(dutyCycleInput_SensorPin)- sensorMin) * 100; //* 100; long rv = (sensorValue / sensorMax); return (rv); } // This sets the output to on or off, depending on 'lit' parameter, and pauses for the 'per' parameter (assumes milliseconds). void pause( long per, boolean lit) { long val; // Computed delay value uint8_t sigVal = HIGH; // Output signal variable - defaults to on if (lit) { val = dutyCycle; onval[0] = on[0]; } else { val = cycleTime - dutyCycle; // off time dutyCycle; onval[0] = off[0]; sigVal = LOW; } // Writes a plus or minus value to LCD depending on if this period is on or off lcd.cursorTo(1,14); // Set to write on first row lcd.printIn(onval); // Debug // if (delA != dutyCycle && delA != (cycleTime-dutyCycle)) { // Debug code // lcd.curortTo(1,0); // n = sprintf(buff, "Error "); // lcd.printIn(buff); // lcd.cursorTo(2,0); // Set to write on second row // n = sprintf(buff2, "%5lu / %4lu ", val, delA); // lcd.printIn(buff2); // delay (2000); // } digitalWrite(ssrCtrlPin, sigVal); // Sends SSR output value digitalWrite(ledPin, sigVal); // Sends LED output value (may be eliminated if output for OpAmp can be co-opted delay(val); // Pause }