Skip to content

Instantly share code, notes, and snippets.

@petermllrr
Created April 10, 2022 15:01
Show Gist options
  • Save petermllrr/4d1f32c103d030856d1df86088ab2983 to your computer and use it in GitHub Desktop.
Save petermllrr/4d1f32c103d030856d1df86088ab2983 to your computer and use it in GitHub Desktop.
/*
* MIT License
*
* Copyright (c) 2022 Hans Peter Müller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Smol Orion
* ==========
*
* This code runs the ATtiny45 microcontroller embedded in my ORION model.
* Read more about this project: https://smolspaceprogram.com/project/orion
*
* The model consists of solar cells, capacitors and LEDs. During the day, the
* solar cells charge the capacitors. While charging, the microcontroller powers
* itself down to preserve energy so the model can charge faster. In the night,
* when the solar cells don't produce any more energy, the microcontroller
* switches on and blinks the LED.
*
* Pin 2 (PIN_SOLAR_CELL) is connected to the solar cell's (+). If this pin
* measures a high voltage it means that the solar cells are charging and the
* microcontroller will go to sleep. If pin 2 measures a low voltage it means
* that the solar cells don't receive enough sunlight anymore. An interrupt
* listening to pin 2 will fire and wake the microcontroller up.
*
* Pinout for ATtiny45/85:
*
* -|--‿--|- VCC
* -| |- 2 PIN_SOLAR_CELL --> connected to solar cells
* -| •‿• |-
* GND -|-----|- 0 PIN_LED --> connected to LED
*/
#include <avr/sleep.h>
#include <avr/wdt.h>
const int PIN_SOLAR_CELL = 2;
const int PIN_LED = 0;
const int INTERRUPT_NR_SOLAR_CELLS = 0;
void setup() {
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_SOLAR_CELL, INPUT);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
disableADC();
}
// ADC is not needed and preserves energy if disabled
void disableADC() {
ADCSRA = 0;
}
void loop() {
if (solarCellHasSunlight()) {
goToSleep();
} else {
flashLED();
}
}
boolean solarCellHasSunlight() {
if (digitalRead(PIN_SOLAR_CELL) == HIGH) {
return true;
} else {
return false;
}
}
void goToSleep() {
attachInterrupt(INTERRUPT_NR_SOLAR_CELLS, handleInterrupt, LOW);
sleep_mode();
}
// Immediately detaches the interrupt to avoid endless interrupt cycles
void handleInterrupt() {
detachInterrupt(INTERRUPT_NR_SOLAR_CELLS);
}
void flashLED() {
digitalWrite(PIN_LED, HIGH);
sleep(WDTO_60MS);
digitalWrite(PIN_LED, LOW);
sleep(WDTO_60MS);
digitalWrite(PIN_LED, HIGH);
sleep(WDTO_60MS);
digitalWrite(PIN_LED, LOW);
sleep(WDTO_8S);
}
// Uses sleep mode instead of a delay to preserve energy
void sleep(int time)
{
wdt_enable(time);
enableInterruptMode();
sleep_mode();
}
// Makes watchdog fire an interrupt instead of resetting the device
void enableInterruptMode() {
WDTCR |= _BV(WDIE);
}
// Watchdog interrupt handler. Needs to deactivate watchdog in the first 15 ms
ISR(WDT_vect)
{
clearInterruptFlags();
wdt_disable();
}
void clearInterruptFlags() {
MCUSR = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment