/* LED Probe (ATtiny202 Version) - see http://www.technoblogy.com/show?53Z6 David Johnson-Davies - www.technoblogy.com - 20th May 2025 ATtiny202 @ 1 MHz (internal oscillator; BOD disabled) CC BY 4.0 Licensed under a Creative Commons Attribution 4.0 International license: http://creativecommons.org/licenses/by/4.0/ */ #include #include const int RedLED = PIN_PA2; const int GreenLED = PIN_PA3; const int Output = PIN_PA1; const int Input = PIN_PA6; const int Lead = PIN_PA7; const unsigned long Timeout = (unsigned long)60*1000; // One minute volatile unsigned long Time; // Pin Change interrupt service routine - wakes up ISR(PORTA_PORT_vect) { PORTA.INTFLAGS = PORT_INT6_bm; // Need to clear interrupt flag } void setup () { pinMode(Lead, OUTPUT); pinMode(Output, OUTPUT); pinMode(RedLED, OUTPUT); pinMode(GreenLED, OUTPUT); set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Start running Time = millis(); } // Target ADC values const int Max = 1007; // 2.95V const int High = 768; // 2.25V const int Low = 256; // 0.75V const int Min = 17; // 0.05V int Flash = 0; void loop() { uint16_t v1, v2; // The two analogue readings do { // Probe positive digitalWrite(Lead, LOW); digitalWrite(Output, HIGH); delay(10); v1 = analogRead(Input); // Probe negative digitalWrite(Lead, HIGH); digitalWrite(Output, LOW); delay(10); v2 = analogRead(Input); // Display result if (v1 > Max && v2 < Min) { digitalWrite(RedLED, LOW); digitalWrite(GreenLED, LOW); // Open circuit } else if (v1 < Low && v2 > High) { digitalWrite(RedLED, HIGH); digitalWrite(GreenLED, HIGH); // Short circuit Time = millis(); } else if (v1 > Low && v1 < Max && v2 < Min) { digitalWrite(RedLED, HIGH); digitalWrite(GreenLED, LOW); // Probe to LED + Time = millis(); } else if (v1 > Max && v2 > Min && v2 < High) { digitalWrite(RedLED, LOW); digitalWrite(GreenLED, HIGH); // Probe to LED - Time = millis(); } else { int state = (Flash & 0b1000) ? HIGH : LOW; digitalWrite(RedLED, state); digitalWrite(GreenLED, state); // Error } Flash++; } while (millis() - Time < Timeout); // Go to sleep? // Power saving PORTA.PIN6CTRL = PORT_ISC_LEVEL_gc; // Enable Pin Change interrupt digitalWrite(RedLED, LOW); digitalWrite(GreenLED, LOW); // Make sure LEDs are off digitalWrite(Output, HIGH); digitalWrite(Lead, LOW); sleep_enable(); sleep_cpu(); // Go to sleep PORTA.PIN6CTRL = 0; // Disable Pin Change interrupt Time = millis(); // Reset timeout }