Standby pájecí stanice
Do programu pájecí stanice z minulého článku jsem chtěl zakomponovat funkci standby – teplota pájecího pera klesne na nějakou nízkou teplotu, např. 100°C. První úvaha byla, přejít do tohoto režimu při stisku tlačítka rotačního kodéru. Ale taková funkce mě neuspokojila. Nechce se mi uvažovat o tom, jak dlouho nebudu pájet a jestli má smysl pájku přepnout do standby režimu. Chtělo by to vymyslet program, který sám pozná, že se nepájí a po nějakém čase ztlumí teplotu pájky.
S pájecí stanicí jsem pracoval několik večerů a všiml si, že když odložím pájku do stojánku, tak se regulátor za chvíli ustálí na výkonu 7%. A kmitá jenom několik desetin procenta, aby vyrovnal výkyvy teploměru. Zatímco při pájení výkon vzroste vždy alespoň na 8%, aby regulátor vyrovnal ztrátu. Nedalo by se tohoto jevu využít? Sledovat změny ve výkonu a pokud bude hodnota PWM regulátoru několik minut stejná, přepnout pájecí stanici do standby režimu? Psát nějakou analýzu nové části programu na papír se mi nechce, kreslit vývojový diagram už vůbec ne. Tak to zkusíme zpaměti. Napřed jsem deklaroval několik proměnných, které se budou hodit během psaní programu a do poznámek popsal jejich význam. Při tom jsem si uvědomil, co všechno od nové části programu očekávám a čemu se budu muset věnovat.
// * * * * * * * * * * * * * * * * * * * * * * * * Promenne standby volatile signed int StandbyTimer; // pocita preruseni pro sekundy volatile signed int StandbyTimerSec; // pocita sekundy volatile signed int StandbyTimerMax; // hodnota pri ktere se prejde do Standby nastavit v EEPROM volatile signed int StandbyOldPower; // vykon pro porovnani volatile signed int StandbyDifference; // rozdil pri kterem sepne Standby nastavit v EEPROM volatile signed int StandbyTemp; // teplota pro Standby nastavit v EEPROM volatile signed int StandbyTempBuff; // schova starou teplotu
Program, který zkoumá změny výkonu PWM regulátoru v čase, je spouštěn periodicky v přerušení časovače. Přerušení je voláno 1000x za sekundu, proměnná StandbyTimer počítá do 1000, takže změna výkonu bude zkoumána jednou za sekundu:
if ( RotStatus == 0 ) StandbyTimer++; // neni v menu if ( StandbyTimer > 999 ) // pocita do jedne sekundy { StandbyTimer = 0; StandbyTimerSec++; // pocitadlo sekund if (( SolderPWM < ( StandbyOldPower - StandbyDifference )) || ( SolderPWM > ( StandbyOldPower + StandbyDifference ))) { StandbyTimerSec = 0; // zmena je vetsi nez povoleny interval } StandbyOldPower = SolderPWM; // zapamatuje vykon pro pristi srovnani if ( StandbyTimerSec > StandbyTimerMax ) // prejde do Standby rezimu { StandbyTempBuff = TempSet; // schova starou teplotu TempSet = StandbyTemp; // nastavi teplotu Standby RotStatus = 100; // Standby rezim StandbyTimerSec = 0; } }
Hlavní smyčka programu, která vypisuje aktuální teplotu pájecího pera, požadovanou teplotu pájecího pera a aktuální výkon PWM kanálu je doplněna o další smyčku. V té je výpis teploty při Standby režimu a sledování stisku tlačítka rotačního kodéru. Pro signalizaci standby jsem využil proměnnou RotStatus, jejíž hodnota jinak určuje proměnnou, která bude obsluhována rotačním kodérem. Když je RotStatus = 100, nebude rotační kodér měnit vůbec nic a to je v režimu standby docela užitečné.
while(1) { LCD_Position( 0, 0 ); // prvni radek // LCD_PrIntDec( StandbyTimerSec ); // LCD_WriteCString( " " ); LCD_WriteCString( "Tsold = " ); LCD_PrTemp( TempSolder ); // teplota telesa LCD_WriteCString( " " ); LCD_Position( 1, 0 ); LCD_PrTemp( TempSet ); // nastavena teplota LCD_PrPwm( SolderPWM / 8 ); // aktualni vykon v desetinach procenta _delay_ms( 100 ); if ( ROT_Key() > 2 ) MENU_Global(); // ceka na stisk rotacniho koderu if ( RotStatus == 100 ) // jede Standby rezim { Beep( 200 ); // pipne na zacatku Standby while ( RotStatus == 100 ) { LCD_Position( 0, 0 ); // prvni radek LCD_WriteCString( "Tsold = " ); LCD_PrTemp( TempSolder ); // teplota telesa LCD_WriteCString( " " ); LCD_Position( 1, 0 ); LCD_WriteCString( "* Standby mode *" ); _delay_ms( 100 ); if ( ROT_Key() > 2 ) RotStatus = 0; // ceka na stisk rotacniho koderu } TempSet = StandbyTempBuff; Beep( 100 ); // pipne na konci standby } }
Interval, ve kterém se může pohybovat změna výkonu tak, aby za stanovený čas došlo k přechodu do standby je určen proměnnou StandbyDifference. Čas v minutách, po který se čeká, jestli bude výraznější změna výkonu, je určen proměnnou StandbyTimerMax. Teplota, na které se regulátor ustálí, je zapsaná v proměnné StandbyTemp. Tyto hodnoty jsou uloženy do EEPROM procesoru a je možné je měnit v menu, které je dostupné po stisku rotačního kodéru. Část programu pro výpis menu na displej je zde:
case 3: { LCD_Position( 0, 0 ); LCD_WriteCString( "4 Teplota Standb" ); // teplota pro Standby rezim LCD_Position( 1, 0 ); LCD_PrTemp( StandbyTemp ); LCD_WriteCString( " " ); break; } case 4: { LCD_Position( 0, 0 ); LCD_WriteCString( "5 Standby Diff " ); // rozdil vykonu, pri kterem se neprejde do Standby LCD_Position( 1, 0 ); LCD_PrPwm( StandbyDifference/8 ); // vypisuje vykon v procentech LCD_WriteCString( " " ); break; } case 5: { LCD_Position( 0, 0 ); LCD_WriteCString( "6 Standby Timer " ); // cas v sekundach, po kterem se jde do Standby LCD_Position( 1, 0 ); LCD_PrPwm( StandbyTimerMax/6 ); // vypisuje cas v minutach LCD_Position( 1, 5 ); LCD_WriteCString( " min. " ); break; }
A na ni navazuje část v přerušení rotačního kodéru INT1. Proměnná RotStatus určuje, která hodnota z EEPROM bude změněna a zároveň, která část menu se bude zobrazovat na displeji. Přerušení je spouštěno jedním pinem rotačního kodéru vždy, když je kodérem pootočeno. Druhý pin kodéru je připojen na port D, pin PD4, jeho stav je detekován výrazem PIND&0x10. Stav určuje směr otáčení a proto rozhoduje o tom, jestli se proměnná bude přičítat, nebo odečítat. Zároveň je nutno vyhodnotit maximální a minimální mez proměnné, jejíž hodnotu v daném okamžiku měníme.
case 5: // listuje v MENU_Global - StandbyTemp { if (( PIND&0x10) && (StandbyTemp<TempMax)) StandbyTemp += 10; if ((~PIND&0x10) && (StandbyTemp>TempMin)) StandbyTemp -= 10; break; } case 6: // listuje v MENU_Global - StandbyDifference { if (( PIND&0x10) && (StandbyDifference<800)) StandbyDifference +=8; if ((~PIND&0x10) && (StandbyDifference> 8)) StandbyDifference -=8; break; } case 7: // listuje v MENU_Global - StandbyTimerMax { if (( PIND&0x10) && (StandbyTimerMax<1200)) StandbyTimerMax +=30; if ((~PIND&0x10) && (StandbyTimerMax> 60)) StandbyTimerMax -=30; break; }
Celý projekt pro AVR studio 6.2 je ke ztažení zde: Pajeci_stanice 01