/* Portable Lab Power Supply ATtiny861 @ 1MHz (internal oscillator; BOD disabled) David Johnson-Davies - www.technoblogy.com - 17th January 2016 CC BY 4.0 Licensed under a Creative Commons Attribution 4.0 International license: http://creativecommons.org/licenses/by/4.0/ */ // Seven-segment definitions const int charArrayLen = 12; char charArray[charArrayLen] = { // ABCDEFG Segments 0b1111110, // 0 0b0110000, // 1 0b1101101, // 2 0b1111001, // 3 0b0110011, // 4 0b1011011, // 5 0b1011111, // 6 0b1110000, // 7 0b1111111, // 8 0b1111011, // 9 0b0000000, // 10 Space 0b0000001 // 11 Dash }; const int Dash = 11; const int Space = 10; const int Ndigits = 3; // Number of digits const int MaxVoltage = 550; // Maximum voltage; ie 5.5V const int Step = 2; // Step for each rotary encoder increment volatile char Buffer[] = { Dash, Dash, Dash }; volatile char digit = 0; // Pin assignments; give the bit position in PORTB for each digit char Digits[] = {2, 0, 6}; volatile int Voltage = 0; // Current voltage setting // Rotary Encoder ********************************************** // Pin change interrupt service routine ISR (PCINT_vect) { static int Laststate; // Debounce - wait for 4 identical readings int Last = -1, Count = 0, Gray; do { Gray = (PINB & 0x18)>>3; // Read PB3 and PB4 Count++; if (Last != Gray) Count = 0; Last = Gray; } while (Count < 4); // Have now had 4 identical readings in a row int State = (Gray>>1) ^ Gray; // Convert from Gray code to binary if (State != Laststate) { int Value = ((Laststate-State) & 3) - 2; // Gives -1 or +1 ChangeValue(Value); Laststate = State; } } // Called when encoder is rotated; Change is -1 (anticlockwise) or 1 (clockwise) void ChangeValue (int Change) { Voltage = max(min(Voltage + Change*Step, MaxVoltage), 0); TC1H = Voltage >> 8; // Set OC1A to voltage OCR1A = Voltage & 0xFF; } // Display multiplexer ********************************************** void DisplayNextDigit() { static int LastVoltage; DDRB = DDRB & ~(1<=2) { Display(Voltage>>1); LastVoltage = Voltage; } } } // Display a three digit decimal number void Display (int i) { for (int d=2; d>=0 ; d--) { Buffer[d]=i % 10; i = i / 10; } } // Timer interrupt - multiplexes display and does ADC conversions ISR (TIMER1_OVF_vect) { DisplayNextDigit(); } // Do ADC conversions ********************************************** int ReadADC () { static unsigned int Mean, Reading = 9999; unsigned char low, high; ADCSRA = ADCSRA | 1<> 8; // High byte - count up to 550 OCR1C = (MaxVoltage-1) & 0xFF; // Low byte TIMSK = 1<