Introduction
This program is a steam generator controller that is intended for use in a residential steam shower. It controls water inlet and drain valves, power to the heating element, and various level and thermal sensors.
Features
Push button automated control of the steam shower. High and low steam rates, extendable cycles, error conditions are sensed and handled.
Specifications
- Power: 220VAC, 3000W
- Time to boil: 6 minutes
- Added time to preheat steam room: 10 minutes
- Steam cycle: 20 minutes, plus additional 20 minute cycles if requested
- Steam level: Full steam, low steam
- Time to cool and drain: 20 minutes, typical
- Error conditions: six
Construction
This project works quite well but has not passed the prototype stage yet. (It’s still built on a wooden platform!)
The tank is a 4″ copper pipe with end caps. It is silver soldered to withstand heat. The replacable 3000W heating element extends inward through one end of the tank. Stainless bolts are used. The relay card is a pre-existing unit that I had in my collection. The 220/24V transformer, solid state relay, cooling fan are below the relay card. The “U” shaped 1/4″ flexible copper tubing alongside the tank is for preheating the incoming water so that it doesn’t squelch the steam when the inlet water valve opens.
Code:
/**************************************************************** STEAMGEN07.C This is a steam generator. WORKING CODE ERRORS - count the number of quick flashes 1 - not drained at beginning 2 - not filled within time limit during initial fill cycle 3 - not filled within time limit during rinse cycle 4 - not filled to limit during heating within time limit 5 - over temperature during preheat or soak cycles 6 - under temperature after preheat cycle LED FLASH SLOW - filling, preheating, draining SOLID - soak mode FAST - stop and wait (warn) period --------- +5--20-|Vdd C0|-11--- Heat-A relay | C1|-12--- Heat-B relay Gnd--08-|Vss C2|-13--- Heat - SSR Gnd--19-|Vss C3|-14--- Fill 4MHz--10-|Xtal C4|-15--- Drain --09-|Xtal | | | PROGRAMMING CONNECTOR | B7|-28--DATA | B6|-27--CLK | MCLR|-01--MCLR | | GND | 16F876 | | | Level --21-|B0 C5|-16-- LED1 Sw1 --22-|B1 C6|-17-- LED2 Sw2 --23-|B2 B4|-25-- LED RETURNS DS1820 --03-|A1 B3|-24-- BEEPER | B5|-26-- COOLING FAN --------- **********************************************************/ #include < 16F876.H > #include < jonsinc.h > #fuses XT, NOPROTECT, PUT, NOWDT, BROWNOUT, NOLVP, NOCPD, NOWRT #define RELAY_HEAT_A PIN_C0 #define RELAY_HEAT_B PIN_C1 #define RELAY_SSR PIN_C2 #define RELAY_FILL PIN_C3 #define RELAY_DRAIN PIN_C4 #define LED_1 PIN_C5 #define LED_2 PIN_C6 #define SWITCH_LEVEL PIN_B0 #define SWITCH_1 PIN_B1 #define SWITCH_2 PIN_B2 #define BEEPER PIN_B3 #define LED_RETURN PIN_B4 #define DS1820_DATA_PIN PIN_A1 #define FAN PIN_B5 //============================ #define PERCENT_100 4 #define PERCENT_75 3 #define PERCENT_50 2 #define PERCENT_25 1 #define PERCENT_0 0 #define LED_FLASH_NONE 0 #define LED_FLASH_SLOW 1 #define LED_FLASH_FAST 2 #define LED_INIT_FLASH_COUNT 16 #define MINIMUM_INTERVAL 1 #define HIGH_STEAM 1 #define LOW_STEAM 2 //============================ #define STATE_START 0 #define STATE_INITIAL_CHECKS 1 #define STATE_READ_SWITCHES 2 #define STATE_FILL 3 #define STATE_PREHEAT 4 #define STATE_SOAK 5 #define STATE_WARN 6 #define STATE_DRAIN 7 #define STATE_ERROR 9 //============================ #define ERROR_NONE 0 #define ERROR_NOT_DRAINED 1 #define ERROR_NOT_FILLED_DURING_FILL 2 #define ERROR_NOT_FILLED_DURING_RINSE 3 #define ERROR_FILL_ABSENCE 4 #define ERROR_OVERTEMP 5 #define ERROR_UNDERTEMP 6 //============================ // times in seconds #define TIME_FILL_LIMIT 240 #define TIME_DRAIN 160 #define TIME_PREBOIL 360 #define TIME_PREHEAT_SHOWER 600 #define TIME_SOAK_MODE 1200 #define TIME_STOP_AND_WAIT 130 #define TIME_FILL_ABSENCE 300 #define TIME_TEMPERATURE_MEAS 10 // times in mS #define TIME_ADD_WATER_INCR 1000 #define TIME_ADD_WATER_DELAY 100 #define TIME_DRAIN_COOL_FILL 10000 #define TIME_INITIAL_OVERFILL 3000 // times in uS #define BEEPER_PERIOD_DELAY 518 // number of cycles for beeper #define BEEP_CYCLES 500 //============================ // DS1820 temperature sensor #define DS1820_SKIP_ROM 0xCC #define DS1820_READ_SCRATCHPAD 0xBE #define DS1820_CONVERT_T 0x44 // temperature in degrees C #define TEMPERATURE_DRAIN_LIMIT 65 #define TEMPERATURE_OVER 105 #define TEMPERATURE_UNDER 90 //============================ #use delay ( clock=6000000 ) #use standard_io ( A ) #use standard_io ( B ) #use standard_io ( C ) void CheckSwitches ( void ); void AddWaterIfNecessary ( void ); void FlashErrorCode ( cError ); void AllRelaysOff ( void ); void Beep ( char cCount ); void SetHeaterPower ( char cLevel ); char ReadTemperature ( void ); void ResetDS1820 ( void ); void WriteDS1820 ( void ); void ReadDS1820 ( void ); void WaitForConversion ( void ); static char cInterruptCount; static long iSecondCount, iFillOvertimeCount; static char cSwitch1Count, cSwitch1on; static char cSwitch2Count, cSwitch2on; static char cError, cState, cMode, cOff, cResetCount; static char cLedFlash, cLedOn, cSSRon, cSSRcount, cDebugMode; static char cPower, cDutyCycleCount, cDutyCycleState; static char cShiftBit,cDataOut, cTemperatureSecondCount; static long iDataIn; //************************************************************************* #int_rtcc void TimerInterrupt ( void ) // 21.760mS tick, 46 interrupts per second { // ONE-SECOND TICK if ( cInterruptCount++ == 47 ) // a little more than one second so flashes divide evenly { cInterruptCount = 0; // restart interrupt count iSecondCount++; // increment second count cTemperatureSecondCount++; // increment temperature second count iFillOvertimeCount++; // increment overtime count } // SOLID STATE RELAY POWER CYCLING if ( cDutyCycleCount++ >= 4 ) // is it 84mS yet? (sets the overall duty cycle granularity) { cDutyCycleCount = 0; // reset if ( cDutyCycleState == cPower ) // is heat cycle done yet? { output_low ( RELAY_SSR ); // turn solid state relay off } else { if ( cDutyCycleState == 0 ) // if first state { output_high ( RELAY_SSR ); // turn solid state relay on } } if ( cDutyCycleState++ >= 3 ) // increment state { cDutyCycleState = 0; // reset } } // LED FLASH/SOLID CONTROL switch ( cLedFlash ) { case LED_FLASH_NONE: { cLedOn = YES; break; } case LED_FLASH_SLOW: { if ( ( cInterruptCount % 24 ) == 0 ) { cLedOn ^= 1; } break; } case LED_FLASH_FAST: { if ( ( cInterruptCount % 8 ) == 0 ) { cLedOn ^= 1; } break; } } if ( cLedOn == YES ) { output_low ( LED_RETURN ); // LED on } else { output_high ( LED_RETURN ); // LED off } // SWITCH 1 SENSE if ( input ( SWITCH_1 ) == LOW ) // if pressed { if ( cSwitch1Count++ >= 92 ) // increment count { cSwitch1Count = 92; // prevent wrap, limit to highest needed } } else // when button is released { if ( cSwitch1Count >= 92 ) // if was pressed for two seconds { cOff = YES; // signal OFF } else { if ( cSwitch1Count >= 2 ) // else if was pressed momentarily { cSwitch1on = YES; // signal normal press } } cSwitch1Count = 0; // switch up, restart } // SWITCH 2 SENSE if ( input ( SWITCH_2 ) == LOW ) // if pressed { if ( cSwitch2Count++ >= 92 ) // increment count { cSwitch2Count = 92; // prevent wrap, limit to highest needed } } else // when button is released { if ( cSwitch2Count >= 92 ) // if was pressed for two seconds { cOff = YES; // signal OFF } else { if ( cSwitch2Count >= 2 ) // else if was pressed momentarily { cSwitch2on = YES; // signal normal press } } cSwitch2Count = 0; // switch up, restart } // RESET (PRESS BOTH SWITCHES SIMULTANEOUSLY) if ( ( input ( SWITCH_1 ) == LOW ) && ( input ( SWITCH_2 ) == LOW ) ) // if pressed for three seconds { if ( cResetCount++ >= 143 ) // increment count { cResetCount = 143; // cap it } } else // when button is released { if ( cResetCount >= 143 ) // if was pressed for five seconds { reset_cpu(); } cResetCount = 0; // switch up, restart } } //****************************************************************************
For more detail: STEAM GENERATOR using PIC16F873