Universal klocka passar för synskadade (5 / 6 steg)
Steg 5: Ladda upp koden
Gå till Arduino tiny projektets webbplats och hämta den version arduino-liten-0100-0010.zip. Följ inkluderade README.txt om steg för steg instruktioner om hur det fungerar med din arduino miljö. (Inte riktigt svårt.) Dessutom måste du ladda ner PinChangeInterrupt-0001.zip från samma webbplats. Också hämta Arduino tid biblioteket. Installation av bibliotek är ganska enkelt, vid förvirring hänvisa till denna webbplats.Sedan slå din arduino till så kallade isp genom att öppna arduino ide, att välja fil-exempel-Arduino som ISP från rullgardinsmenyn och trycka belasta upp knapp.
När du har gjort att klistra in följande kod det, Välj verktyg-styrelsen-attiny85 (intern oscillator, BOD inaktiverad), placera attiny marker i uttaget programmerare eller bakbord eller vad som nämns här och fortsätta ladda upp.
!!!! VIKTIGT!
Om uppladdning misslyckas, försök ladda upp arduino som isp skiss från en äldre version av arduino ide, såsom 0022. Om även det inte, har du förmodligen dina fel anslutningar
#define encoderPinA 2
#define encoderPinB 0
#define buttonpin 2
#define loudspeakerpin 1
#include "Time.h"//I inte gjorde detta bibliotek
#include "PinChangeInterruptSimple.h"//And även detta bibliotek inte var gjort av mig
flyktiga int encoderPos = 0; //position för kodaren, flyktiga eftersom det ändrar på avbrott
unsigned int lastReportedPos = 1; förändringsledning
statisk boolean roterande = false; Debounce management
int stepstochangeitem = 10; Hur många encoder steg behövs för menyalternativet ändras
booleska A_set = false; vissa debouncing relaterade vars, vem vet, jag inte har gjort denna del av koden
booleska B_set = false;
int objekt = 4; //number för objekt i menyn
int selecteditem = 0;
int R = 512; //307; //telling vilken knapp är intryckt-512 = pullup motstånd har samma värde som knappen en
int numbertype [] = {//roman siffror, om du ändrar detta, vänligen också ändra variabeln numtypesound array abd typecount
50, 10,5,1};
int numbertypesound [] = {//pitches av olika siffror
100, 300, 500, 700};
int typecount = 4; //number av siffror alltogether
int fördröjningstid = 150;
booleska inmenu = true; / / finns vi i menyn nu?
osignerade långa presslength = 0; //buttons-for hur länge har en knapp tryckts
tid förvaltning vars nedan
långa diff = 0; //difference mellan tid synkroniseras i millis
lång realdiff = 0; //same som ovan, men rundade till halv timme
CONST osignerade långa hh = 1800000; //half timme i millisekunder
lång drift = 0; //by hur mycket realdiff skiljer sig från diff
osignerade långa lastmillis = 0;
osignerade långa lastcheckedtime = 0;
int onemetervalue = 300; //how länge (i encoder steg) är en meter
booleska driftenabled = false; //are vi korrigera tiden glida?
void setup() {
pinMode (encoderPinA, ingång);
pinMode (encoderPinB, ingång);
pinMode (buttonpin, ingång);
pinMode (loudspeakerpin, produktionen);
Encoder stift på avbrott 0 (pin 2)
attachPcInterrupt (2, doEncoderA, förändring);
Encoder stift på avbrott 1 (pin 3)
attachPcInterrupt (0, doEncoderB, förändring);
Serial.BEGIN (9600);
beepnumber (35), //I bara älskar ljudet av som
/ * int tempR=analogRead(buttonpin);
om (tempR > 5)
{
R = tempR;
playSound(1);
beepnumber(tempR);
encoderPos = 0;
selectedItem = 0;
Delay(500);
}*/
}
int SättVärde (booleskt minuter) //set värde; används för klockan och äggklocka rutiner
{
wrapvalues [] = {0,2,1,4}.
encoderPos = 0; //reset encoder position
selectedItem = 0; //reset menyn position
int returnvalue = 0; värdet som ska returneras i slutet av funktionen
int stepnumber = 0; //number av nuvarande steg. varje siffran inställning = 1 steg
int laststepnumber = 0;
medan //infinite loop (1) skall delas ut med hjälp av kommandot break
{
inmenu = true; //so att det Piper ut menyn moment, som här används för att bestämma hur många gånger du vill att varje siffra vara i din önskat antal
wrapEncValues();
inmenu = false; //resets tillbaka till lämpligt värde
om (stepnumber == 0 & & minuter == false) //setting timmar? Sedan hoppa över 50-inställningsvärdet (steg 0)
{
stepnumber = 1;
laststepnumber = 1;
}
om (laststepnumber == stepnumber)
{
om (minuter == false & & stepnumber == 2 & & returnvalue > = 20) //skipping värde 5 inställningen om användaren är inställningen timmar och har satt dem vara > 20 (inställning 25:00 som tiden inte skulle vara meningsfullt)
stepnumber = 3;
om (minuter == true & & stepnumber == 1 & & returnvalue > = 50) //skipping värde 10 inställningen om användaren är inställningen minuter och har satt dem vara > 50 (59 är det max värdet i minuter)
stepnumber = 2;
beepnumber(numbertype[stepnumber]);
laststepnumber =-1;
}
om (minuter == false)
{
växel (stepnumber)
{
fall 1: / / 10s
artiklar = 2;
bryta;
fall 2: / / 5s
om (returnvalue > = 20) //20-something värde
stepnumber = 3; //skip 5s
artiklar = 1;
bryta;
fall 3: / / 1s
om (returnvalue > = 20) //20-something värde
{
artiklar = 3;
}
annat
artiklar = 4;
bryta;
}
}
annat
{
växel (stepnumber)
{
fall 0: / / 50s
artiklar = 1;
bryta;
fall 1: / / 10s
om (returnvalue > = 50) //50-something värde
{
stepnumber = 2; //skip 10s
bryta;
}
artiklar = 4;
bryta;
fall 2: / / 5s
artiklar = 1;
bryta;
fall 3: / / 1s
artiklar = 4;
bryta;
}
}
om (buttonpressed()==1)
{
returnvalue += numbertype [stepnumber] * selecteditem;
stepnumber + = 1;
selectedItem = 0;
laststepnumber = stepnumber;
om (stepnumber > 3)
{
inmenu = sant;
stepstochangeitem = 10;
selectedItem = 1; //back till menyn
artiklar = 4; //not verkligen nödvändigt eftersom "objekt" allready måste värdet av en tillfällighet
Return returnvalue;
bryta;
}
}
}
}
void wrapEncValues()
{
int beepnum =-1;
medan (encoderPos > stepstochangeitem)
{
encoderPos = encoderPos-stepstochangeitem;
selectedItem + = 1;
beepnum = selecteditem;
}
medan (encoderPos < 0)
{
encoderPos = stepstochangeitem + encoderPos;
selectedItem-= 1;
beepnum = selecteditem;
}
om (selecteditem > objekt)
{
selectedItem = 0;
beepnum = selecteditem;
}
om (selecteditem < 0)
{
selectedItem = objekt;
beepnum = selecteditem;
}
om (beepnum! =-1 & & inmenu == true)
beepnumber(beepnum);
}
Annullera playSound (int soundtype) //routine för pipa ut specifika koder (för noll, inmatning av program, alarm och "OK beep" som också används för att separera timmar och minuter när Visa tiden
{
växel (soundtype)
{
fall 0: / / ange
/ * för (int jag = 0; jag < = 100; i ++)
{
tonen (loudspeakerpin, jag * 5);
Delay(5);
}
noTone(loudspeakerpin);
*/
tonen (loudspeakerpin, 500,250);
Delay(100);
tonen (loudspeakerpin, 800,250);
Delay(500);
bryta;
fall 1: / / melodi
tonen (loudspeakerpin, 200,250);
Delay(100);
tonen (loudspeakerpin, 500,500);
Delay(50);
bryta;
fall 2: / / noll
tonen (loudspeakerpin, 950,250);
Delay(50);
tonen (loudspeakerpin, 250,250);
bryta;
fall 3: / / prick
Delay(100);
tonen (loudspeakerpin, 950,250);
Delay(100);
noTone(loudspeakerpin);
tonen (loudspeakerpin, 950,250);
Delay(400);
bryta;
}
}
void loop()
{//Do grejer här
/ * pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
delayMicroseconds(100000);
digitalWrite(13,LOW); * /
om (driftenabled == true) //auto tidskorrigering aktiverad
{
booleska setlastcheckedtime = false;
medan (nu ()-lastcheckedtime > 3600) //more än timmars skillnad sedan senaste synkroniseringstid
{
setlastcheckedtime = true; //sync hände
lastcheckedtime += 3600;
adjustTime(drift/1000);
}
om (setlastcheckedtime == true) //set tidpunkten för senaste synkronisering endast om sync egentligen hände
lastcheckedtime=Now()-(drift/1000);
}
flyttade kod
wrapEncValues();
om (Serial.read()=='B')
Serial.println (encoderPos, DEC);
om (inmenu == true & & buttonpressed()==1)
{
inmenu = false;
playSound(0);
Switch (selecteditem)
{
fall 0: / / klocka
om (presslength < 2000) //press var inte längre än 2 sek
{
beepnumber(Hour());
Delay(200);
playSound(3);
Delay(200);
beepnumber(Minute());
inmenu = sant;
bryta;
}
annat //longer än 2 sek
{
om (presslength > 5000) //longer än 5 sek
{
om (lastmillis! = 0)
driftenabled = sant;
playSound(3);
koden nedan beräknar drift av intern oscillator genom att jämföra förväntade förseningar
(som kan lätt beräknas, eftersom användaren har att göra sync på: 30 eller: 00) fått värde.
Beräknar sedan drift, nominerar det till en timme och sparar för att "drift" variabel
diff = millis ()-lastmillis;
osignerade långa compval = hh/2;
int i;
för (jag = 1; jag < = 10000; i ++)
{
compval += hh;
om (diff < = compval)
bryta;
}
realdiff = jag * hh;
drift = realdiff-diff;
drift=(2*drift)/(realdiff/HH);
lastmillis=Millis();
int hrz=hour();
int Escritt;
om (minute() > 15 & & minute() < 45) //assume klockan är inte av med mer än 15 minuter
Escritt = 30.
annat
{
om (minute() > 45)
hrz + = 1;
Escritt = 0;
}
setTime(hrz,minz,0,1,1,1);
}
annat
{
int hrz=setvalue(false);
int minz=setvalue(true);
setTime(hrz,minz,0,1,1,1);
driftenabled = false;
lastmillis = 0;
lastcheckedtime=Now();
}
inmenu = sant;
bryta;
}
bryta;
fall 1: / / tejpa åtgärd
encoderPos = 0;
While(1)
{
wrapEncValues();
om (buttonpressed()==1)
{
om (presslength < 2000)
{
int cms=round(map(abs(encoderPos),0,onemetervalue,0,100));
beepnumber(CMS);
inmenu = sant;
stepstochangeitem = 10;
selectedItem = 1; //back till menyn
artiklar = 4;
encoderPos = 0;
bryta;
}
annat / / antar användare har mätt exakt en meter och vill kalibrera måttbandet
{
playSound(3);
onemetervalue=ABS(encoderPos);
encoderPos = 0;
inmenu = sant;
bryta;
}
}
}
bryta;
fall 2: / / vatten detektor
{
stepstochangeitem = 4;
artiklar = 10;
selectedItem = 5;
While(1) {
wrapEncValues();
om (abs(selecteditem-5) > 2) //the sond använder samma ingångsstift som knappar. därför avsluta vatten detektorn genom är användaren skyldig att vrida hjulet encoder
{
inmenu = sant;
stepstochangeitem = 10;
encoderPos = 0;
selectedItem = 2. //back till menyn
artiklar = 4;
noTone(loudspeakerpin);
bryta;
}
Tone(loudspeakerpin,map(analogRead(buttonpin),0,512,100,1000)); //0-256; 100-500
}
bryta;
}
fall 3: / / stoppur
{
int startingsecs;
booleska watchrunning = false;
samtidigt (1)
{
IF(buttonpressed()==1)
{
playSound(3);
om (watchrunning == false)
{
watchrunning = sant;
startingsecs = millis () / 1000;
}
annat
{
watchrunning = false;
beepnumber(Millis()/1000-startingsecs);
inmenu = sant;
selectedItem = 3; //back till menyn
bryta;
}
}
}
bryta;
}
fall 4: / / egg timer
int minutemins = 99.
samtidigt (1)
{
int buttoncode = buttonpressed (); //so som det inte har som skall provtas två gånger
om (buttoncode == 0)
bryta;
om (buttoncode == 1)
{
minutemins=SetValue(true);
minutemins = ((minut) + minutemins) %60;//to att den garanterat fungerar korrekt även om timme ändras medan äggklocka körs (som egentligen inte möjligt nu när jag tänker på den...)
playSound(3);
}
om (minute()==minutemins)
{
playSound(1);
om (buttoncode == 0)
bryta;
}
}
bryta;
}
}
}
Tills vidare är koden nedan inte min
void doEncoderA() {
Debounce
om (roterande) fördröjning (1). vänta lite tills den studsande görs
Testa övergång, gjorde saker och ting verkligen förändras?
om (digitalRead(encoderPinA)! = A_set) {/ / Dämpningstid gång
A_set =! A_set;
justera counter + om A leder B
om (A_set & &! B_set)
encoderPos + = 1;
roterande = false; Inga fler debouncing tills loop() träffar igen
}
}
Avbryta på B ändra staten, samma som en ovan
void doEncoderB() {
om (roterande) fördröjning (1).
om (digitalRead(encoderPinB)! = B_set) {
B_set =! B_set;
justera counter - 1 om B leder A
om (B_set & &! A_set)
encoderPos-= 1;
roterande = false;
}
}
från nu på, är koden min igen
int buttonpressed()
{
om (analogRead(buttonpin) > 5) //is något händer alls?
{
int returnvalue =-1;
osignerade långa beginms = millis (), //variable för senare comparation att berätta hur länge knappen har tryckt
While(1)
{
osignerade långa lastmillis;
int value=analogRead(buttonpin);
om (värde > 5) //should vara 0, men lite hysteresion skadar aldrig
{
lastmillis=Millis();
om (abs(value-((2*R)/3)) < 10) //button 2
returnvalue = 0;
annat
om (abs(value-R) < 10) //button 1
{
returnvalue = 1;
R = värde;
}
annat
om (abs(value-((2*R)/5)*3) < 10) //both knappar, fungerar inte riktigt
returnvalue = 2;
}
annat
om (millis ()-lastmillis > 20) //to göra debouncing; räkningen knapp som släppas när det har släppts för mer än 20ms
{
presslength = millis ()-beginms;
Return returnvalue;
bryta;
}
}
}
annat
återvända -1;
}
int beepnumber (int num) //beeping ut numret. I princip fungerar pseudorecursively genom att dividera argumentet med siffror från högsta till lägsta
och sedan matar den modulo division tillbaka till sig själv och upprepar hela processen
{
om (num == 0)
{
playSound (2), //special koden för noll
Return 0;
}
int initpos = encoderPos;
int numbertypevalue [] = {
-1 -1, -1, -1};
för (int jag = 0; jag < typecount; i ++)
{
om (num/numbertype [i] > = 1)
{
numbertypevalue[i]=Floor(NUM/numbertype[i]);
NUM = num % numbertype [i];
}
encoderPos = initpos; //basically ignorera användaren roterande kodare om pipa ut värdet
om (numbertypevalue [i] > -1)
{
för (int i2 = 0; i2 < numbertypevalue[i];i2++)
{
för (int i3 = 0; i3 < 4-i; i3 ++)
{
Delay(delaytime/2);
tonen (loudspeakerpin, numbertypesound[i],delaytime);
Delay(delaytime);
}
Delay(delaytime*2);
}
}
}
}