Gamla flipperspel använder ju som bekant poänghjul, ett hjul med siffrorna 0-9 på, som roteras fram med en solenoid, en siffra i taget.
Hur kul vore det inte att använda dessa till att bygga en klocka?
Så det kommer den här tråden att handla om.
Jag började med att leta rätt på fyra stycken rullar, skickade ett mail till Arne på Flipperskroten och han plockade fram fyra sånahär till mig: 500 spänn med frakt, så det slog jag till på.
Dessa blev sedan liggandes i en låda i ett halvår eller så, tappade sugen lite, och fick lite annat att göra.
Men rätt som det var så plockade jag fram dem igen och började mäta upp dem, för att kunna räkna ut hur stor lådan skulle behöva vara.
Jag ville inte ha lådan större än absolut nödvändigt, men samtidigt efterlikna en gammal backbox. En rulle grovt uppritad i sketchup.
När jag hade måtten på rullarna kunde jag börja rita upp lådan, också den i sketchup. Skulle köpt 12mm MDF, men den var slut just den dagen som jag hade bestämt mig för att börja bygga, så det fick bli 12mm plywood istället(kvaliten på den var dock inte den bästa, men det får duga). Bitarna utsågade med sänksåg, samt spår utfrästa med överhandsfräs(lite vingligt blev det allt). Limning - Snett blir det, måste mäta bättre nästa gång

Kanske är dags att köpa sig en ramtving?
Printade en monteringspryl för kretskortet och sekund-lamporna som ska sitta i mitten. Testade att koppla upp en rulle till ett av solenoidkorten jag byggt till flipperspelsbygget
Tråkig video
Som syns i videon så kör jag den på runt 18V, perfekt, för då kan jag använda en gammal laptopladdare i slutprodukten.
Funderade ett tag på att bara köpa en arduino och slänga in i lådan, men det är ju roligare att rita egna kort, så så fick det bli: En liten förklaring kanske är på sin plats...
Rullarna matas som sagt fram en siffra i taget, så om man pulsar soilenoiden en gång, så tickar rullen fram en siffra. För att hålla koll på vilken siffra som visas, så finns det ju två varianter, antingen en switch per siffra, eller bara en switch på siffran 0.
Jag valde det senare alternativet, av två anledningar:
1 - Bara tre av rullarna hade "extrakortet" där alla switcharna fanns.
2 - Sparar ingångar
För att veta vilka siffror som visas får man alltså göra såhär:
Om siffran inte är 0, så får man pulsa solenoiden till den blir 0.
Därefter gå vidare till nästa siffra tills alla fyra är nollade.
Sedan kan vi börja "mata på" vad klockan faktiskt är.
Korten beställda hos itead 16 dec 2014, och jag fick dem igår, så då var det bara att börja bygga

Hade tidigare labbat med en liten RTC-modul för breadboard med DS1307, så jag designade in en sån på kortet, och köpte komponenter.
Körde in adafruits testkod, men får inget fel när batteriet inte är anslutet.Lyckas heller inte sätta klockan, och datum är helt fel(typ 2100:141:12)(?)
Klockan räknar dock upp sekunder.
Har installerat om datorn sedan jag testade på labbplattan, så jag monterar tillbaka allting dit och testar med RTC-modulen och samma kod, och då funkar allt.(??)
Kollade alla mina kopplingar osv, men hittar inget fel, så jag lödde helt enkelt bort DS1307-kretsen ifrån modulen, och lödde dit den på mitt kort istället, och nu funkar allt!
Den enda förklaringen jag kan tänka mig är att det är skräpkretsar jag har lyckats köpa(förmodligen från ebay).
Koden då?
Till att börja med vill jag säga att jag inte är någon hejare på programmering, så min kod är säkert allt annat än optimal, så jag tar gärna emot synpunkter, tips och allmänna klagomål

Jag använder mig av https://github.com/adafruit/RTClib
Kod: Markera allt
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
const int digits = 4; // How many digits are in the clock
const boolean zeromark[] = {2,3,4,5}; // What pins are the zero switches connected to?
const int solenoid[] = {6,7,9,8}; // What pins are the solenoids connected to?
const int seconds_pin = 10; // What pin are the second lamps connected to?
const int solenoid_ontime = 20; // How long should the solenoid be active?
const int solenoid_offtime = 100; // How long should the solenoid be inactive?
int hours_now; // Variable to hold the current hours read out from the RTC
int minutes_now; // Variable to hold the current minutes read out from the RTC
int seconds_now; // Variable to hold the current seconds read out from the RTC
int oldminutes; // Variable for when the digits were last updated
int hours_tens; // Variable for the breakdown of the current hours H
int hours_ones; // Variable for the breakdown of the current hours H
int minutes_tens; // Variable for the breakdown of the current minutes M
int minutes_ones; // Variable for the breakdown of the current minutes M
int digit0; // Variable for holding what the digits are acctually showing, hours tens
int digit1; // Variable for holding what the digits are acctually showing, hours ones
int digit2; // Variable for holding what the digits are acctually showing, minutes tens
int digit3; // Variable for holding what the digits are acctually showing, minutes ones
void setup() {
Serial.begin(57600); // Serial is not needed, but a nice way to debug
Wire.begin();
RTC.begin();
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
//RTC.adjust(DateTime(__DATE__, __TIME__));
}
pinMode(10, OUTPUT); // Set up the seconds pin
for(int i=0; i<digits; i++){
pinMode(zeromark[i], INPUT_PULLUP); // Set up the rest of the input pins, with internal pull up
}
for(int i=0; i<digits; i++){
pinMode(solenoid[i], OUTPUT); // Set up all the output pins
}
for(int i=0; i<digits; i++){ // Repeat for every digit, one at a time
while (digitalRead(zeromark[i]) == HIGH){ // If digit is not 0, pulse the solenoid until it reaches 0
Serial.print("Digit is not 0. Pulsing solenoid ");
Serial.println(i);
digitalWrite(solenoid[i],HIGH);
delay(solenoid_ontime);
digitalWrite(solenoid[i],LOW);
delay(solenoid_offtime);
}
}
// Now we have a known state, where all digits show 0
// Now we have to update the digits with the correct time
DateTime now = RTC.now(); // Get the time
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
hours_now = now.hour(); // Put the current hours into hours_now
minutes_now = now.minute(); // Put the current minutes into minutes_now
hours_tens = hours_now / 10; // Divide by 10 to get the first digit
hours_ones = hours_now % 10; // Modulo to get the last digit
minutes_tens = minutes_now / 10; // And the same for the minutes
minutes_ones = minutes_now % 10;
pulsesolenoid(0,hours_tens); // Pulse the solenoids in order, wth the amount of pulses set from the clock
pulsesolenoid(1,hours_ones);
pulsesolenoid(2,minutes_tens);
pulsesolenoid(3,minutes_ones);
digit0 = hours_tens; // Update the digit variables with what they are acctually showing
digit1 = hours_ones;
digit2 = minutes_tens;
digit3 = minutes_ones;
oldminutes = minutes_now; // Set oldminutes to when we last updated the clock
delay(1000); // Small delay just to separate the setup from the main loop
}
void loop() {
DateTime now = RTC.now(); // Get the time
hours_now = now.hour(); // Get the hours
minutes_now = now.minute(); // Get the minutes
seconds_now = now.second(); // Get the seconds
hours_tens = hours_now / 10; // Divide by 10 to get the first digit
hours_ones = hours_now % 10; // Modulo to get the last digit
minutes_tens = minutes_now / 10; // And the same for the minutes
minutes_ones = minutes_now % 10;
if(minutes_now != oldminutes){ // Check if it's time to advance the minutes.
advance();
oldminutes = minutes_now;
}
if ( (seconds_now % 2) == 0) { // If seconds are an odd number, turn on the lamps...
digitalWrite(seconds_pin, HIGH);
}
else{ // ... otherwise, turn them off
digitalWrite(seconds_pin, LOW);
}
}
void pulsesolenoid(int solenoid_number, int times){
Serial.print("Pulsing solenoid ");
Serial.print(solenoid_number);
Serial.print(" ");
Serial.print(times);
Serial.println(" times.");
for (int i=0; i<times; i++){
digitalWrite(solenoid[solenoid_number],HIGH);
delay(solenoid_ontime);
digitalWrite(solenoid[solenoid_number],LOW);
delay(solenoid_offtime);
}
}
void advance(){
Serial.println("Advancing time one minute");
if(digit3 == 9){ // If last digit is 9, we need to advance both ones and tens reel by one...
if(digit2 == 5){ // ...except if the minutes tens reel shows 5 (XX:59), then we need to pulse hours ones once, minutes tens five times, and minutes ones once.
if(digit1 == 9){ // ...and except if hours ones reel shows 9, then pulse hours tens once, hours ones once, minutes tens five times, minutes ones once.
pulsesolenoid(0,1);
pulsesolenoid(1,1);
pulsesolenoid(2,5);
pulsesolenoid(3,1);
}
else if(digit0 == 2 && digit1 == 3){ // ...and if the time is 23:59 then we need to andvance all the reels by 8, 7, 5 and 1. (This will make a lot of noise, and take some time)
pulsesolenoid(0,8);
pulsesolenoid(1,7);
pulsesolenoid(2,5);
pulsesolenoid(3,1);
}
else{
pulsesolenoid(1,1);
pulsesolenoid(2,5);
pulsesolenoid(3,1);
}
}
else{
pulsesolenoid(2,1);
pulsesolenoid(3,1);
}
}
else{
pulsesolenoid(3,1);
}
digit0 = hours_tens; // Update the time shown on the reels for the next time it's time to advance.
digit1 = hours_ones;
digit2 = minutes_tens;
digit3 = minutes_ones;
Serial.print("Time shown is now: ");
Serial.print(digit0);
Serial.print(digit1);
Serial.print(":");
Serial.print(digit2);
Serial.println(digit3);
}
För enkla sekunder är det jättebra, men för första siffran i timmar är allt annat än 0-2 onödigt, så det är därför det är så mycket if-else i advance.
Nu är det dags att montera ihop allt Lamporna lyste lite för mycket åt sidorna, så det löste jag så här: Och så här blev slutresultatet Bilden är ihopslängd i inkscape, och blev lite tråkig, men jag kom inte på något motiv, förslag?
Och såklart en film

http://youtu.be/tTz0llkBHWw
Phew, det tog ett par timmar att skriva det här inlägget, fixa till bilder och filmer

Och ja, den låter väldigt mycket
