O.k. First the parts: the counter is a 24 volts one. Not so ideal. Makes a DC/DC-Step-Up converter necessary to create 24 volts. And a 7805 to supply the Attiny85.
Zero power. The NO switch turns on the DC/DC, the Attiny85 boots and its first thing is to switch on the relay to get power. Now the switch can be released.
Failed. The DC/DC wants some higher voltage than I planned to supply. So a DC/DC converter from 1.2V (lowermost end) to 5V, than 5V to 24V.
Failed. Turning on the second DC/DC draws so much energy, that the 5 volts break down and the relay releases. Due to attiny rebooting or whatever. So the second DC/DC will be turned on later by the Attiny.
This gives a relay for self holding and a 2N7000 for switching second DC/DC. Don’t ask.
For some reasons I can’t remember I found it useful that the Attiny can detect the state of the switch. Don’t ask, too.
Next obstacle: my Attiny85 development library chooses to erase the EEPROM while flashing the program code. So no way to synchronize the mechanical counter with the Attiny EEPROM. Until I found out all the things about fuses and such.
All the parts are glued into a Eduplay pirate treasure box. Sadly the counter is quite small.
A little bit of code lives inside the Attiny85:
#include <EEPROM.h>
#include <EEPROMAnything.h>
/*
Zaehler etc
2014-06-27/28
Zielplattform: attiny85
*/
const byte PinButtonsensor = A3; // A3
const byte PinRelais = 4; // D4
const byte PinDCDC = 1; // D1 der Spannungswandler 5V->24V
const byte PinZaehler = 0; // D0
unsigned long currentcounterdisplay;
unsigned long nextcounterdisplay;
//********************************************************************************************************************
//********************************************************************************************************************
void readEEPROMcurrentdisplay() {
currentcounterdisplay=0;
currentcounterdisplay = EEPROM.read(0);
currentcounterdisplay += EEPROM.read(1)<<8;
currentcounterdisplay += (unsigned long)EEPROM.read(2)<<16;
currentcounterdisplay += (unsigned long)EEPROM.read(3)<<24;
}
//********************************************************************************************************************
//********************************************************************************************************************
void writeEEPROMcurrentdisplay() {
EEPROM.write(0, currentcounterdisplay);
EEPROM.write(1, currentcounterdisplay >> 8);
EEPROM.write(2, currentcounterdisplay >> 16);
EEPROM.write(3, currentcounterdisplay >> 24);
}
//********************************************************************************************************************
//********************************************************************************************************************
void setup() {
pinMode(PinRelais, OUTPUT);
digitalWrite(PinRelais,HIGH);
// nix tun, damit sich alles laden kann
delay(1000);
// Z�hlerausgang setzen
pinMode(PinZaehler,OUTPUT);
digitalWrite(PinZaehler,LOW);
// DCDC setzen
pinMode(PinDCDC,OUTPUT);
digitalWrite(PinDCDC,LOW);
readEEPROMcurrentdisplay();
// initialisieren des Displays bei Neubau etc.
// currentcounterdisplay=327;
// 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179,
// 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
// 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347,
// 349, 353, 359, 367, 373, 379, 383, 389,
// n�chste Primzahl ausrechnen
nextcounterdisplay=calcnextprime(currentcounterdisplay);
// DCDC-Wandler an und etwas warten
digitalWrite(PinDCDC,HIGH);
delay(4000);
// hochz�hlen
runtonumber();
// merken
writeEEPROMcurrentdisplay();
// und ausschalten
turnoff();
}
//********************************************************************************************************************
//********************************************************************************************************************
void runtonumber (void) {
while (nextcounterdisplay!=currentcounterdisplay) {
digitalWrite(PinZaehler,HIGH);
delay(200);
digitalWrite(PinZaehler,LOW);
delay(500);
currentcounterdisplay++;
}
}
//********************************************************************************************************************
//********************************************************************************************************************
boolean isprime(unsigned long number)
{
unsigned long limit = sqrt(number)+1;
// damit calcnextprime in einserschritten hochz�hlen kann. notwendig, wenn z�hler initialisiert werden muss
if ((number % 2) ==0) {
return false;
}
for (unsigned long i=3;i<limit;i=i+2) {
if ((number % i)==0) {
return false;
}
}
return true;
}
//********************************************************************************************************************
//********************************************************************************************************************
unsigned long calcnextprime(unsigned long number) {
number++;
while (! isprime(number)) {
number++;
}
return number;
}
//********************************************************************************************************************
//********************************************************************************************************************
void turnoff() {
// relais off
digitalWrite(PinRelais,LOW);
// so lange der Knopf nicht gedr�ckt ist, k�nnen wir nicht ausgehen
while (analogRead(PinButtonsensor)>100) {
delay(1000);
};
// sind wir noch oder schon tot?
delay(1000);
}
//********************************************************************************************************************
//********************************************************************************************************************
void loop() {
// will this ever happen?
delay(10000);
turnoff();
}