#define F_CPU 8000000UL #include #include #include #include #include #include #include #include #include #define BAUDRATE 9600 #define NTCBETA 3380 #define NTCRES 10000 #define NTCFIXEDRES 10000 #define ONTEMP 4.0 // °C #define OFFTEMP 2.0 // °C #define POWERONDELAY 10 // sec #define ONTIME 60 // sec #define OFFTIME 180 // sec ////////////////////////////////////////////////////////////////////////////////////////////////////////// // attiny48 // // pins // // 1 : PB5 reset, ADC0 // // 2 : PB3 ADC3 / RELAY // // 3 : PB4 ADC2 / CAP // // 4 : gnd // // 5 : PB0 Mosi, AREF // // 6 : PB1 Miso / TX // // 7 : PB2 SCK, ADC1 / NTC // // 8 : VCC // // // // VCC -> 10k -> NTC -> GND // // NTC: NTSD1XH103FPB40 https://media.digikey.com/pdf/Data%20Sheets/Murata%20PDFs/NTSD1%20Spec.pdf // // Beta: 3380 // ////////////////////////////////////////////////////////////////////////////////////////////////////////// #define RELAYPIN PINB #define RELAYDDR DDRB #define RELAYPORT PORTB #define RELAYBIT 3 #define CAPPIN PINB #define CAPDDR DDRB #define CAPPORT PORTB #define CAPBIT 4 #define NTCPIN PINB #define NTCPORT PORTB #define NTCDDR DDRB #define NTCMUX 1 #define NTCBIT 2 #define UARTTXPIN PINB #define UARTTXPORT PORTB #define UARTTXDDR DDRB #define UARTTXBIT 1 //////////////////////// // Do not edit bellow // //////////////////////// volatile uint32_t timeSecs = 0; volatile uint32_t timeCycles = 0; volatile uint8_t status = 0; volatile uint16_t timeStatus = 0; volatile float temperature = 0.0; void usart_bitdelay() { _delay_us(1000000/BAUDRATE); // 1e6 us / baudrate } void usart_putchar(char data) { // 0 start, LSB...MSB, 1 stop uint8_t i; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // start bit, 0 UARTTXPORT &= ~(1 << UARTTXBIT); usart_bitdelay(); // 8 data bits for (i = 0; i <= 7; i++) { if (data & 0x01) { // 1 UARTTXPORT |= (1 << UARTTXBIT); } else { // 0 UARTTXPORT &= ~(1 << UARTTXBIT); } data = (data >> 1); usart_bitdelay(); } // stop bit, 1 UARTTXPORT |= (1 << UARTTXBIT); usart_bitdelay(); usart_bitdelay(); } } static FILE mystdout = FDEV_SETUP_STREAM(usart_putchar, NULL, _FDEV_SETUP_WRITE); void getTemp() { } void printData() { uint32_t lsecs; uint16_t lhours; uint8_t lmins; uint8_t lstatus; uint16_t ltstatus; float ltemp; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { lsecs = timeSecs; lstatus = status; ltstatus = timeStatus; ltemp = temperature; }; lhours = lsecs / 3600; lsecs = lsecs - (lhours * 3600); lmins = lsecs / 60; lsecs = lsecs - (lmins * 60); printf_P(PSTR("% 5d:%02d:%02d "), lhours, lmins, lsecs); //printf_P(PSTR("Temperature: % 6.1f°C "), ltemp); printf_P(PSTR("Temperature: %f°C "), ltemp); printf_P(PSTR("Status: %d "), lstatus); printf_P(PSTR("Since: %5d secs "), ltstatus); printf_P(PSTR("Reset: ")); if (MCUSR & (1<C temperature = 1.0 / ( (1.0/298.15) + (1.0/(float)NTCBETA) * log(resistance / (float)NTCRES) ) - 273.15; } int main(void) { uint32_t ltime = 0; // set up watchdog timer wdt_enable(WDTO_8S); // set relay pin to output, set to off RELAYDDR |= (1<= POWERONDELAY)) { // cap is discharged, release lockout status = 1; ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timeStatus = 0; } } } else if (status == 1) { // Off relay(0); if (temperature >= ONTEMP) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timeStatus = 0; } status = 4; } } else if (status == 2) { // Off with delay relay(0); if (timeStatus >= OFFTIME) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timeStatus = 0; } status = 1; } } else if (status == 3) { // On relay(1); if (temperature <= OFFTEMP) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timeStatus = 0; } status = 2; } } else if (status == 4) { // On with delay relay(1); if (timeStatus >= ONTIME) { ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timeStatus = 0; } status = 3; } } printData(); wdt_reset(); }; return(0); } ISR(TIM0_OVF_vect) { // time keeping timeCycles += 262144; // 8 bits timer with /1024 prescaller if (timeCycles >= F_CPU) { timeCycles -= F_CPU; timeSecs++; timeStatus++; } }