Paso 5: Cargar el código
Ir al sitio del proyecto pequeño Arduino y descargar la versión arduino-minúsculo-0100-0010.zip. Siga el archivo incluido readme.txt para obtener instrucciones paso a paso sobre cómo hacer que funcione con su entorno de arduino. (No muy difícil). También, usted tendrá que descargar PinChangeInterrupt 0001.zip desde el mismo sitio Web. Descargar la biblioteca en tiempo de Arduino. Instalación de bibliotecas es bastante sencillo, en caso de confusión se refieren a este sitio.Girar a tu arduino en isp supuesto abrir el ide de arduino, seleccionar archivo-ejemplos-Arduino como ISP en el menú desplegable y pulsando subir botón.
Una vez que ha hecho que, pasta siguiente código allí, seleccione Herramientas-tablero-attiny85 (oscilador interno, BOD deshabilitado), coloque el attiny chip en el zócalo del programador o protoboard o lo que sea como mencionado aquí y proceder a cargar.
!!!! IMPORTANTE!!!!!!
Si carga falla, intente cargar el arduino como isp bosquejo de una más vieja versión del ide de arduino, como 0022. Si eso falla, usted tiene probablemente sus conexiones mal
#define encoderPinA 2
#define encoderPinB 0
#define buttonpin 2
#define loudspeakerpin 1
#include "Time.h"//I no hizo esta biblioteca
#include "PinChangeInterruptSimple.h"//And también esta biblioteca no fue hecha por mi
volátiles int encoderPos = 0; //position del codificador, volátil porque cambia en interrupción
unsigned int lastReportedPos = 1; gestión del cambio
estática rotación boolean = false; Debounce gestión
int stepstochangeitem = 10; Cuántos pasos de encoder son necesarios para que el elemento de menú para cambiar
Boolean A_set = false; algunos vars relacionados debouncing, quién sabe, yo no he hecho esta parte del código
Boolean B_set = false;
int elementos = 4; //number de los elementos de menú
selecteditem int = 0;
int R = 512; //307; //telling el botón es presionado-512 = pullup resistencia tiene el mismo valor que el botón está
int numbertype [] = {//roman números; si cambia esto, por favor, también cambio la variable de typecount abd numtypesound array
50, 10,5,1};
int numbertypesound [] = {//pitches de diferente numeración
100, 300, 500, 700};
int typecount = 4; //number del conjunto de números
int delaytime = 150;
¿inmenu booleano = true; / / estamos en el menú ahora?
presslength largo sin signo = 0; //buttons-for cuánto tiempo se pulsa un botón
var de gestión de tiempo abajo
largo diff = 0; //difference entre sincronizaciones de tiempo en millis
realdiff largo = 0; //same que el anterior, redondeado pero a la mitad de las horas
const unsigned hh larga = 1800000; //half hora en milisegundos
largo de la deriva = 0; //by cuánto la realdiff diferencia de diff
unsigned lastmillis largo = 0;
lastcheckedtime largo sin signo = 0;
int onemetervalue = 300; //how (en pasos de encoder) es un metro
¿Boolean driftenabled = false; //are tenemos tiempo de corregir la deriva?
void setup() {}
pinMode (encoderPinA, entrada);
pinMode (encoderPinB, entrada);
pinMode (buttonpin, entrada);
pinMode (loudspeakerpin, salida);
codificador de pin de interrupción 0 (pin 2)
attachPcInterrupt (2, doEncoderA, cambio);
codificador de pin de interrupción 1 (pin 3)
attachPcInterrupt (0, doEncoderB, cambio);
Serial.Begin (9600);
beepnumber (35); //I encanta el sonido que
/ * int tempR=analogRead(buttonpin);
Si (tempR > 5)
{
R = tempR;
playSound(1);
beepnumber(tempR);
encoderPos = 0;
SelectedItem = 0;
Delay(500);
}*/
}
int setvalue (boolean minutos) //set valor; utilizados para las rutinas de reloj y temporizador de huevo
{
[] wrapvalues = {0,2,1,4};
encoderPos = 0; posición de codificador de //reset
SelectedItem = 0; //reset posición del menú
int returnvalue = 0; el valor a ser devuelto al final de la función
int stepnumber = 0; //number de paso actual. cada numeral ajuste = 1 paso
int laststepnumber = 0;
mientras (1) //infinite lazo roto fuera el comando break
{
inmenu = true; //so que suena hacia fuera del menú, que aquí se utiliza para determinar cuantas veces te desee cada numeral en su número deseado
wrapEncValues();
inmenu = false; //resets a valor apropiado
¿Si (stepnumber == 0 & & minutos == false) //setting horas? Luego saltar 50-valor de ajuste (paso 0)
{
stepnumber = 1;
laststepnumber = 1;
}
Si (laststepnumber == stepnumber)
{
Si (minutos == false & & stepnumber == 2 & & returnvalue > = 20) //skipping valor ajuste 5 si el usuario es la creación de horas y ha que ser > 20 (ajuste 25:00 como tiempo no tendría sentido)
stepnumber = 3;
Si (minutos == true & & stepnumber == 1 & & returnvalue > = 50) //skipping valor 10 ajuste si usuario es ajuste de minutos y ha que ser > 50 (el valor máximo es 59 minutos)
stepnumber = 2;
beepnumber(numbertype[stepnumber]);
laststepnumber =-1;
}
Si (minutos == false)
{
interruptor (stepnumber)
{
caso 1: / / 10s
elementos = 2;
rotura;
caso 2: / / 5s
Si (returnvalue > = 20) valor de //20-something
stepnumber = 3; //skip 5s
elementos = 1;
rotura;
caso 3: / / 1s
Si (returnvalue > = 20) valor de //20-something
{
elementos = 3;
}
otra cosa
elementos = 4;
rotura;
}
}
otra cosa
{
interruptor (stepnumber)
{
caso 0: / / 50s
elementos = 1;
rotura;
caso 1: / / 10s
Si (returnvalue > = 50) //50-something valor
{
stepnumber = 2; //skip 10s
rotura;
}
elementos = 4;
rotura;
caso 2: / / 5s
elementos = 1;
rotura;
caso 3: / / 1s
elementos = 4;
rotura;
}
}
Si (buttonpressed()==1)
{
ReturnValue += numbertype [stepnumber] * selecteditem;
stepnumber += 1;
SelectedItem = 0;
laststepnumber = stepnumber;
Si (stepnumber > 3)
{
inmenu = true;
stepstochangeitem = 10;
SelectedItem = 1; //back a menú
elementos = 4; //not realmente necesario ya que "elementos" ya tendrá este valor por coincidencia
volver returnvalue;
rotura;
}
}
}
}
void wrapEncValues()
{
int beepnum =-1;
mientras que (encoderPos > stepstochangeitem)
{
encoderPos = encoderPos-stepstochangeitem;
SelectedItem += 1;
beepnum = selecteditem;
}
mientras que (encoderPos < 0)
{
encoderPos = stepstochangeitem + encoderPos;
SelectedItem-= 1;
beepnum = selecteditem;
}
Si (selecteditem > artículos)
{
SelectedItem = 0;
beepnum = selecteditem;
}
Si (selecteditem < 0)
{
SelectedItem = elementos;
beepnum = selecteditem;
}
Si (beepnum! =-1 & & inmenu == true)
beepnumber(beepnum);
}
anular //routine playSound (int soundtype) para pitar los códigos específicos (cero, entrar en el programa y alarma "Beep OK" que se utiliza también para separar horas y minutos al visualizar hora
{
interruptor (soundtype)
{
caso 0: / / enter
/ * para (int i = 0; i < = 100; i ++)
{
tono (loudspeakerpin, i * 5);
Delay(5);
}
noTone(loudspeakerpin);
*/
tono (loudspeakerpin, 500.250);
Delay(100);
tono (loudspeakerpin, 800.250);
Delay(500);
rotura;
caso 1: / / melodía
tono (loudspeakerpin, 200.250);
Delay(100);
tono (loudspeakerpin, 500.500);
Delay(50);
rotura;
caso 2: / / cero
tono (loudspeakerpin, 950.250);
Delay(50);
tono (loudspeakerpin, 250.250);
rotura;
caso 3: / / punto
Delay(100);
tono (loudspeakerpin, 950.250);
Delay(100);
noTone(loudspeakerpin);
tono (loudspeakerpin, 950.250);
Delay(400);
rotura;
}
}
void loop()
{//Do cosas aquí
/ * pinMode(13,OUTPUT);
digitalWrite(13,HIGH);
delayMicroseconds(100000);
digitalWrite(13,LOW); * /
Si (driftenabled == true) //auto corrección de tiempo permitido
{
Boolean setlastcheckedtime = false;
mientras que (ahora ()-lastcheckedtime > 3600) //more que diferencia de horas desde la última vez que sync
{
setlastcheckedtime = true; //sync pasó
lastcheckedtime += 3600;
adjustTime(drift/1000);
}
Si (setlastcheckedtime == true) //set el momento de la última sincronización solo si la sincronización ocurrido
lastcheckedtime=Now()-(Drift/1000);
}
código movido
wrapEncValues();
Si (Serial.read()=='B')
Serial.println (encoderPos, DEC);
Si (inmenu == true & & buttonpressed()==1)
{
inmenu = false;
playSound(0);
interruptor (selecteditem)
{
caso 0: / / reloj
Si (presslength < 2000) //press no más de 2 segundos
{
beepnumber(hour());
Delay(200);
playSound(3);
Delay(200);
beepnumber(minute());
inmenu = true;
rotura;
}
//longer mas de 2 segs
{
Si (presslength > 5000) //longer de 5 segundos
{
Si (lastmillis! = 0)
driftenabled = true;
playSound(3);
código siguiente calcula la deriva del oscilador interno comparando demora prevista
(que se puede fácilmente calcular, ya que el usuario tiene que hacer el sync en: 30 o: 00) a ganado valor.
Luego calcula la deriva, nomina a una hora y ahorra para la "deriva" variable
diff = millis ()-lastmillis;
compval largo sin signo = hh/2;
int i;
para (i = 1; i < = 10000; i ++)
{
compval += hh;
Si (diff < = compval)
rotura;
}
realdiff = i * hh;
deriva = realdiff-diff;
Drift=(2*Drift)/(realdiff/HH);
lastmillis=Millis();
int hrz=hour();
minz int;
Si (minute() > 15 & & minute() < 45) //assume el reloj no es apagado por más de 15 minutos
Minz = 30;
otra cosa
{
Si (minute() > 45)
Hrz += 1;
Minz = 0;
}
setTime(hrz,minz,0,1,1,1);
}
otra cosa
{
int hrz=setvalue(false);
int minz=setvalue(true);
setTime(hrz,minz,0,1,1,1);
driftenabled = false;
lastmillis = 0;
lastcheckedtime=Now();
}
inmenu = true;
rotura;
}
rotura;
caso 1: / / cinta de medida
encoderPos = 0;
while(1)
{
wrapEncValues();
Si (buttonpressed()==1)
{
Si (presslength < 2000)
{
int cms=round(map(abs(encoderPos),0,onemetervalue,0,100));
beepnumber(CMS);
inmenu = true;
stepstochangeitem = 10;
SelectedItem = 1; //back a menú
elementos = 4;
encoderPos = 0;
rotura;
}
Else / / asumen usuario ha mide exactamente un metro y quiere calibrar la cinta métrica
{
playSound(3);
onemetervalue=ABS(encoderPos);
encoderPos = 0;
inmenu = true;
rotura;
}
}
}
rotura;
caso 2: / / detector de agua
{
stepstochangeitem = 4;
elementos = 10;
SelectedItem = 5;
{while(1)}
wrapEncValues();
Si (abs(selecteditem-5) > 2) //the sonda utiliza el mismo perno de la entrada como botones; por lo tanto, para salir del detector de agua, el usuario se obliga a girar la rueda del codificador
{
inmenu = true;
stepstochangeitem = 10;
encoderPos = 0;
SelectedItem = 2; //back a menú
elementos = 4;
noTone(loudspeakerpin);
rotura;
}
Tone(loudspeakerpin,Map(analogRead(buttonpin),0,512,100,1000)); //0-256; 100-500
}
rotura;
}
caso 3: / / cronómetro
{
int startingsecs;
Boolean watchrunning = false;
mientras (1)
{
if(buttonPressed()==1)
{
playSound(3);
Si (watchrunning == false)
{
watchrunning = true;
startingsecs = millis () / 1000;
}
otra cosa
{
watchrunning = false;
beepnumber(Millis()/1000-startingsecs);
inmenu = true;
SelectedItem = 3; //back al menú
rotura;
}
}
}
rotura;
}
caso 4: / / contador de tiempo del huevo
int minutemins = 99;
mientras (1)
{
buttoncode int = buttonpressed (); //so que no tiene que ser muestreado dos veces
Si (buttoncode == 0)
rotura;
Si (buttoncode == 1)
{
minutemins=SetValue(true);
minutemins = ((minutos) + minutemins) %60;//to garantizar que funciona correctamente incluso si cambia de hora mientras corre el reloj para cocer huevos (que no es posible ahora cuando lo pienso...)
playSound(3);
}
Si (minute()==minutemins)
{
playSound(1);
Si (buttoncode == 0)
rotura;
}
}
rotura;
}
}
}
Hasta nuevo aviso, el código siguiente no es mía
void doEncoderA() {}
Debounce
Si demora (giratorio) (1); Espere un poco hasta que el rebote se realiza
¿Prueba de transición, las cosas realmente cambiaron?
Si (digitalRead(encoderPinA)! = A_set) {/ / debounce una vez más
A_set =! A_set;
ajustar el contador + si A conduce a B
Si (A_set & &! B_set)
encoderPos += 1;
rotación = false; no más contra rebotes hasta loop() golpea otra vez
}
}
Interrumpir en B que cambia de estado, igual que A anterior
void doEncoderB() {}
Si demora (giratorio) (1);
Si (digitalRead(encoderPinB)! = B_set) {}
B_set =! B_set;
ajuste de contador - 1 si B conllevan una
Si (B_set & &! A_set)
encoderPos-= 1;
rotación = false;
}
}
de ahora en adelante, el código es mío otra vez
int buttonpressed()
{
¿Si (analogRead(buttonpin) > 5) //is pasa nada en absoluto?
{
int returnvalue =-1;
unsigned beginms largo = millis (); //variable para posterior comparación a cómo durante mucho tiempo ha sido presionado el botón
while(1)
{
lastmillis largo sin firmar;
int value=analogRead(buttonpin);
Si (valor > 5) //should ser 0, pero nunca perjudica a algunos hysteresion
{
lastmillis=Millis();
Si (abs(value-((2*R)/3)) < 10) //button 2
ReturnValue = 0;
otra cosa
Si (abs(value-R) < 10) //button 1
{
ReturnValue = 1;
R = valor;
}
otra cosa
Si (abs(value-((2*R)/5)*3) < 10) botones de //both, no funciona
ReturnValue = 2;
}
otra cosa
Si (millis ()-lastmillis > 20) //to hacer contra rebotes; botón cuenta como liberados una vez que ha sido lanzado para más de 20 MS
{
presslength = millis ()-beginms;
volver returnvalue;
rotura;
}
}
}
otra cosa
volver -1;
}
int beepnumber (int num) //beeping el número. Básicamente funciona pseudorecursively dividiendo el argumento de números de mayor a menor
y entonces alimenta el modulo de la división de sí mismo y se repite todo el proceso
{
Si (num == 0)
{
playSound (2); //special Código cero
return 0;
}
initpos int = encoderPos;
int numbertypevalue [] = {}
-1, -1, -1 ,-1 };
para (int i = 0; i < typecount; i ++)
{
Si (num/numbertype [i] > = 1)
{
numbertypevalue[i]=Floor(NUM/numbertype[i]);
Num = num % numbertype [i];
}
encoderPos = initpos; //basically ignorar usuario girando el codificador si pitar el valor
Si (numbertypevalue [i] > -1)
{
para (int i2 = 0; i2 < numbertypevalue[i];i2++)
{
para (int i3 = 0; i3 < 4-i; i3 ++)
{
Delay(Delaytime/2);
tono (loudspeakerpin, numbertypesound[i],delaytime);
Delay(Delaytime);
}
Delay(Delaytime*2);
}
}
}
}