Automatisk Arduino Powered sällskapsdjur mataren (5 / 5 steg)
Steg 5: Arduino - koden
Koden är inte så skrämmande som den först ser ut, och jag har försökt att kommentera den så mycket som möjligt.
Sammanfattning det:
Läser tiden från RTC chip
Visar tiden, och mata standardtider och mängd
Kontroller för att se om rotary encoder har tryckts om den har: det går sedan in i programmering rutin, cykling i ordning genom klocka, portion storlek, feed time 1, feed time 2. När du är klar, fortsätter det nedan...
Kontrollerar om det matdags 1 eller 2 - om så den matar.
Kontrollerar om du har tryckt på manuellt feed-knappen, om så den matar. Och sedan börjar det om igen.
Detta är första gången jag har använt en avbrottstjänstens rutin - för rotary encoder. Detta innebär att om du stänger den, oavsett programmet är upptagen gör, den registrerar din åtgärd. Så är det alltid lyssnar för kodaren.
Jag trodde att rutinen för att ställa klockan och foder gånger & antal skulle vara skrämmande, men jag bröt den bara i enkla steg. 1. jag lärde mig hur man gör flash markören på skärmen, lätt nog. Då jag placerade markören på den timme siffran i klockan, och berättade det för att öka timmen som kodaren förvandlades (eller minska), sedan när kodaren var tryckt, skriva nya "timmen" till realtidsklockan, och sedan flytta markören till den minut, och börja ändrar på det, och så vidare. Var förvånansvärt lätt.
Matande rutinerna är enkel "om" rutiner - dvs "om" gånger matchade, sedan göra rutinen utfodring. Enkelt är det. Jag var tvungen att lägga till lite så kontrollerar sekunderna eller annars den lever i en hel minut, som programmet öglorna och kontrollerar tiden igen - och det fortfarande matdags! så den upprepas... stannar att lägga till en kontroll av sekunderna här eftersom det tar minst en sekund för utfodring cykeln.
Programmet är inte perfekt - ibland vrida kodaren inte alltid öka numret på skärmen. Jag tycker detta är ner till min oerfarenhet. Det hindra inte emellertid drift av maskinen!
Jag har bifogat en screen grab av min arduino IDE för ingen verklig anledning annat än jag inte ville detta avsnitt vara utan en bild :-)
Uppenbarligen videon på 1: a sidan visar mig att trycka på den manuella knappen, men naturligtvis det auto-feeds på två tidpunkter (du kan ställa in båda gångerna samma och det skulle bara mata en gång).
/*
Skruv Audiono Automatisk Sällskapsdjur Mataren Copyright Roger Donoghue 28/03/2015 alla rättigheter reserverade. Endast för personligt bruk.
Inte för kommersiellt bruk eller återförsäljning.
Kan du ställa in 2 utfodring gånger och kvantiteten som en multipel av standard feed kvantitet.
Använder en DS1307 Realtidsklocka för att hålla tiden, med ett laddningsbart batteri byggdes.
(Du kan använda arduino RTC exempelkod i IDE för att ställa in klockan eller använda rotary encoder som avsett)
*/
inkludera bibliotek-koden:
#include < LiquidCrystal.h >
#include < Wire.h > / / behövs för RTC libraty
#include < Time.h >
#include < DS1307RTC.h > / / verklig tid klocka bibliotek
#include < Servo.h >
starta med numrerar av gränssnittet pins dor LCD-biblioteket
LiquidCrystal lcd (12, 11, 5, 8, 7, 6);
#define PIN_SERVO 9
Servo feedServo;
Servo stirServo;
int pos = 0;
flyktiga boolean TurnDetected;
flyktiga booleska upp;
CONST int PinCLK = 2; Används för att generera avbrott med CLK signal
CONST int PinDT = 3; Används för att läsa DT signal
CONST int PinSW = 4; Används för växeln tryckknapp för Rotary Encoder
CONST int buttonPin = A3; numrera av tryckknapp PIN-koden för manuell matning 13
int buttonState = 0; variabel för att läsa manualen foder tryckknapp status
int feed1hour = 07; variabler för utfodring gånger och kvantitet
int feed1minute = 00.
int feed2hour = 17;
int feed2minute = 30.
int feedQty = 4;
int matningshastighet = 800; en pwm som utlöser framåt på servo 75
int feedReversal = 80. en pwm takt som utlöser omvänd på servo
spela med dessa nummer för din servo. Min är en Futaba digital servo
att jag tagit bort potten från och den plast lug, att göra det kontinuerligt.
Annullera isr () {/ / avbrottstjänstens rutin körs när en hög till låg övergång upptäcks på CLK
om (digitalRead(PinCLK)) / / Detta håller ett öga på rotary encoder förvandlas oavsett om programmet är
upp = digitalRead(PinDT); för närvarande exectuting - med andra ord, under huvudloop denna ISR kommer alltid att vara aktiv
annat
upp =! digitalRead(PinDT);
TurnDetected = sant;
}
Ogiltiga inställningar () {
Ange den LCD antal kolumner och rader:
LCD.BEGIN (16, 2);
setup Rotary encoder
pinMode(PinCLK,INPUT);
pinMode(PinDT,INPUT);
pinMode(PinSW,INPUT);
pinMode (buttonPin, ingång);
attachInterrupt (0, isr, faller); avbryta 0 alltid är ansluten till stift 2 på Arduino UNO
lcd.setCursor(17,0);
LCD.Print ("Roger Donoghue's"); Lite kul :-)
lcd.setCursor(17,1);
LCD.Print ("katt-O-Matic");
för (int positionCounter = 0; positionCounter < 17; positionCounter ++) {
Bläddra en position åt vänster:
lcd.scrollDisplayLeft();
vänta lite:
Delay(150);
}
Delay(3000);
för (int positionCounter = 0; positionCounter < 17; positionCounter ++) {
Bläddra en position åt vänster:
lcd.scrollDisplayRight();
vänta lite:
Delay(150);
} / / end roligt
lcd.setCursor(17,0);
LCD.Print("");
lcd.setCursor(17,1);
LCD.Print("");
}
Ogiltig loop () {//Main program loop - de flesta saker här!
statiska lång virtualPosition = 0; utan STATIC räknas det inte korrekt!
tmElements_t tm; Denna sectionm läser tiden från RTC, skiljer det i tmElements tm (trevligt att arbeta med), då visar den.
RTC.read(tm);
lcd.setCursor (0, 0);
printDigits (tm. Timme). Ring för att skriva ut siffran funktion som lägger till inledande nollor som saknas kan vara
LCD.Print(":");
printDigits (tm. Minut).
LCD.Print(":");
printDigits (tm. Andra).
LCD.Print("");
LCD.Print ("antal");
LCD.Print(feedQty);
LCD.Print("");
lcd.setCursor(0,1);
LCD.Print("1)");
printDigits(feed1hour);
LCD.Print(":");
printDigits(feed1minute);
LCD.Print ("2)");
printDigits(feed2hour);
LCD.Print(":");
printDigits(feed2minute);
MAIN BREAKOUT "OM" SECION NEDAN SOM ÖVERVAKAR KNAPPEN OCH SKRIVER IN PROGRAMMERING OM DET SKJUTS
om (! () digitalRead(PinSW))) {/ / kolla om tryckknapp trycks
Om ja ange programmering subrutinen
LCD.Blink(); Aktivera den blinkande markören:
lcd.setCursor(5,0);
LCD.Print ("SET");
virtualPosition = tm. Timme; behövs eller timmen blir noll varje gång du ändra klockan.
göra {
lcd.setCursor(0,0); Placera markören på tid timme
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag timmen av tid-
TM. Timme = virtualPosition;
RTC.write(tm);
lcd.setCursor (0, 0);
printDigits (tm. Timme). sedan åter skriva ut timmen på LCD
} medan ((digitalRead(PinSW))); gör detta "gör" loop medan PinSW knappen inte trycks
lcd.noBlink();
Delay(1000);
ANGE MINS
LCD.Blink(); Aktivera den blinkande markören:
virtualPosition = tm. Minut. behövs eller i minuten blir noll varje gång du ändra klockan.
göra {
lcd.setCursor(3,0); Placera markören på tid Mins
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag min tid-
TM. Minut = virtualPosition;
RTC.write(tm);
lcd.setCursor (3, 0);
printDigits (tm. Minut). sedan åter skriva ut min på LCD-skärmen
} medan ((digitalRead(PinSW)));
lcd.noBlink();
Delay(1000);
Ange antal - foder kvantitet
LCD.Blink(); Aktivera den blinkande markören:
virtualPosition = feedQty; behövs eller antal kommer att vara noll.
göra {
lcd.setCursor(14,0); Placera markören på Kvt
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag den foder Kvt
feedQty = virtualPosition;
lcd.setCursor (14, 0);
LCD.Print(feedQty);
} medan ((digitalRead(PinSW)));
lcd.noBlink();
Delay(1000);
Ställa in Feed1 timmen
LCD.Blink(); Aktivera den blinkande markören:
virtualPosition = feed1hour; behövs eller kommer att vara noll till att börja med.
göra {
lcd.setCursor(2,1); Placera markören på feed1hour
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag feed1 timme
feed1hour = virtualPosition;
lcd.setCursor(2,1);
printDigits(feed1hour);
} medan ((digitalRead(PinSW)));
lcd.noBlink();
Delay(1000);
Ange Feed1 Mins
LCD.Blink(); Aktivera den blinkande markören:
virtualPosition = feed1minute; behövs eller kommer att vara noll till att börja med.
göra {
lcd.setCursor(5,1); Placera markören på feed1minute
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag i feed1 minuten
feed1minute = virtualPosition;
lcd.setCursor(5,1);
printDigits(feed1minute);
} medan ((digitalRead(PinSW)));
lcd.noBlink();
Delay(1000);
Ställa in Feed2 timmen
LCD.Blink(); Aktivera den blinkande markören:
virtualPosition = feed2hour; behövs eller kommer att vara noll till att börja med.
göra {
lcd.setCursor(10,1); Placera markören på feed1hour
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag feed1 timme
feed2hour = virtualPosition;
lcd.setCursor(10,1);
printDigits(feed2hour);
} medan ((digitalRead(PinSW)));
lcd.noBlink();
Delay(1000);
Ange Feed2 Mins
LCD.Blink(); Aktivera den blinkande markören:
virtualPosition = feed2minute; behövs eller kommer att vara noll till att börja med.
göra {
lcd.setCursor(13,1); Placera markören på feed1minute
Delay(500); Dröjsmål behövs eller samma knapptryckning avslutas göra-samtidigt som tag kontroll för en annan knapp push!
om (TurnDetected) {/ / gör detta endast om rotation upptäcktes
IF (upp)
virtualPosition--;
annat
virtualPosition ++;
TurnDetected = false; INTE upprepa om loop tills nya rotation upptäckt
}
Här ändra jag i feed1 minuten
feed2minute = virtualPosition;
lcd.setCursor(13,1);
printDigits(feed2minute);
} medan ((digitalRead(PinSW)));
lcd.noBlink();
Delay(1000);
} / / end för huvudsakliga om rotationsencoder tryckknapp checker
CHECK FÖR MANUELL MATNING KNAPP
buttonState = digitalRead(buttonPin);
om (buttonState == hög) {
feed();
}
NÄR UTFODRINGEN TID OCH FODER OM MATCHAS
om (tm. Timme == feed1hour & & tm. Minut == feed1minute & & tm. För det andra == 0) {/ / om jag inte "kontrollera sekunder är noll
feed(); sedan kommer det mata kontinuerligt i 1 minut!
}
om (tm. Timme == feed2hour & & tm. Minut == feed2minute & & tm. För det andra == 0) {
feed();
}
} / / End av huvudloop
void printDigits (int siffror) {/ / utility funktion för digital klockdisplay: utskrifter leder 0
IF(digits < 10)
LCD.Print('0');
LCD.Print(digits);
}
void feed() {
lcd.setCursor(17,0);
LCD.Print ("Meowwwww!");
för (int positionCounter = 0; positionCounter < 16; positionCounter ++) {
Bläddra en position åt vänster:
lcd.scrollDisplayLeft();
vänta lite:
Delay(150);
}
Rör om servo avsnitt om du inte behöver en uppståndelse servo kommentera helt enkelt ut alla fo detta fram till avsnittet Auger rotera
stirServo.attach(10); Jag vet inte om jag behöver en heller men jag lägger till det nu som det är lättast innan jag bygger det!
för (pos = 0; pos < = 180, pos + = 1) {
stirServo.write(pos);
Delay(5); }
för (pos = 180, pos > = 0; pos-= 1) {
stirServo.write(pos);
Delay(10); }
Delay(200);
för (pos = 0; pos < = 180, pos + = 1) {
stirServo.write(pos);
Delay(10); }
för (pos = 180, pos > = 0; pos-= 1) {
stirServo.write(pos);
Delay(5); }
stirServo.detach();
Vrid skruven
feedServo.attach(PIN_SERVO);
för (int cnt = 0; cnt < feedQty; cnt ++)
{
feedServo.write(feedRate); matningshastighet är verkligen foder riktning och hastighet.
Delay(600); denna försening anger hur länge stannar servo löper från föregående kommando