3D tryckt Automatisk Sällskapsdjur Mataren (6 / 7 steg)
Steg 6: Arduino kod
För vårt projekt att köra måste vi ladda upp koden till Arduino att kontrollera elektriska komponenter. Bibliotek ingår i zip-filen nedan och mappar inuti måste placeras i främsta Arduino library-mappen på din dator efter packa. Här ingår bibliotek för IR-sensor, stegmotor och sju segment display. Den bifogade zipfilen med titeln PetFeeder innehåller mappen med Arduino skiss behövs för att köra koden. Detta måste helt enkelt bli blinkat till Arduino för att koden ska köras.
< br >< p > < br > #include #include
#include
#include
#include "SevSeg.h"
SevSeg sevseg;
#define STEPS_PER_MOTOR_REVOLUTION 32
#define STEPS_PER_OUTPUT_REVOLUTION 32 * 64 / / uppsättningar motorn för en revolution
Stepper small_stepper (STEPS_PER_MOTOR_REVOLUTION, A1, A4, A2, A3);
CONST int touchPin = A5; Touch sensor tilldelas här
int touchState; Behandlingen av touch sensor
int rörde; Villkor om touch sensor trycktes
int disableTouch; Inaktiverar flera inslag
int foder; Kör den utfodring loopen
int AMorPM = låg; Beslutar om utfodring cykel är på morgonen eller kvällen används för att ställa tiden
int justFed; Villkoret som används för att ställa in tiden
int minuter; För timern
int jag = 0; Används i formeln för att bestämma om det är AM eller PM
int disableMinutes; Hur länge touch sensor är inaktiverad
CONST int limPin = 8; Limit sensor tilldelas här
int limState = hög; Limit state
int tryckte = låg; Hur många gånger gräns sensorn var tryckt
int upprätt;
int IRpin = A0; PIN-koden för IR-sensor
IRrecv irrecv(IRpin);
decode_results resultat.
int singlecup;
int resetPin = 9. < /p >
Denna initalizes variabler och sätter vissa stater. Om du börjar koden på kvällen, kommer du vill int AMorPM så högt.
{Ogiltig setup() < br > < br >< p >
digitalWrite (resetPin, hög);
Delay(200);
pinMode (limPin, indata);
pinMode (touchPin, ingång);
pinMode (resetPin, produktionen);
Serial.BEGIN(9600);
Serial.println ("reset"); //print Återställ till vet programmet har återställts och
byte numDigits = 4;
byte digitPins [] = {10, 11, 12, 13}; Ställa in för den 4-siffriga sju segment displayen
byte segmentPins [] = {2, 3, 4, 5, 6, 7, 1, 14}; < /p >< p > sevseg.begin (COMMON_CATHODE, numDigits, digitPins, segmentPins);
sevseg.setBrightness(90);
irrecv.enableIRIn(); Starta mottagaren < /p >< p >} < /p >
Denna installation körs en gång och anges stiften som indata eller utdata. Det sätter också upp ljusstyrkan på de sju segment display som kan justeras.
< br >< p > void loop() {< br > statisk osignerade långa startTime = millis();
statisk int minuter = 480; Initierar för 480 minuter eller timmar, eftersom det är till att börja med (9 på utfodring -> 8 timmar -> 5 pm utfodring)
int justFed = låg;
touchState = digitalRead(touchPin); Kontrollerar om touchpin trycktes
limState = digitalRead(limPin);
medan (upprätt == låg & & limState == låg) {/ / denna loop gör en engångsavgift kontroll för att se om cylindern är
linje, om inte kommer att rotera tills den är upprätt
limState = digitalRead(limPin);
small_stepper.setSpeed(380);
small_stepper.Step(10);
om (limState == hög) {
small_stepper.Step(-60); < /p >< p > upprätt = hög;
Serial.println ("växla hit"); < /p >< p >
}
} < /p >< p > om (touchState == låg & & disableTouch == låg) {
berört = hög;
flöde = hög;
Delay(10);
Serial.println ("Pad var inne"); < /p >< p >} < /p >
Detta är början av huvudkoden. Det börjar med att initiera hur många minuter förrän nästa utfodring. Om du börjar på kvällen och har satt AMorPM till hög, då du måste också ändra protokollet här till 960 (eller 16 timmar tills nästa utfodring). Detta gör också en inledande kontroll se till att cylindern är upprätt när du slår systemet på - cylindern roterar tills växeln är hit. Längst ned i koden anges att om kapacitans touch sensor går låg (dvs du tryckte den) då det sätter hög matning slingan, och touch kommer att inaktiveras för att undvika flera utfodringar.
< p > om (irrecv.decode (& resultat)) {//has en överföring varit emot? < br > Serial.println (results.value), //If ja: tolka de mottagna kommandona...
om (results.value == 3810010651) {
flöde = hög;
berört = hög;
}
Marks uppdateringsknappen 5316027
Joe's - digital zoom-knappen
om (results.value == 2885434849) {
disableTouch = låg;
}
om (results.value == 810318687) {
Serial.println("resetting");
Delay(10);
digitalWrite (resetPin, låg);
Serial.println ("det aldrig händer");
}
Marks en knapp 2534850111
Joe's timer på knappen
om (results.value == 1429432985) {
small_stepper.setSpeed(300);
small_stepper.Step(2000);
tryckte = låg;
Delay(3000); Från början har ett stort steg att få bort begränsande sensorn (mindre och sensorn registrerar flera pressar)
While(Pressed == low) {
small_stepper.setSpeed(450); Denna loop fortsätter tills begränsande sensorn trycks en gång (vilket betyder att cylindern gick runt en gång för en kopp)
small_stepper.Step(30);
Delay(200); Det kommer att flytta fram 50 steg och tillbaka 20, för att minimera störning
small_stepper.Step(-10);
limState = digitalRead(limPin);
om (limState == hög) {
tryckte = hög; Läser gräns pin och räknar en press
Serial.println ("switch hit");
Delay(4500);
}
}
small_stepper.setSpeed(500);
small_stepper.Step(-20);
Delay(10);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.Step(50);
Delay(500);
tryckte = låg;
} < /p >< p > irrecv.resume(); Ta emot nästa värde
} < /p >
Denna kod motsvarar fjärrkontrollerna. Dessa siffror kommer att ersättas av de värden som du fått från IRdecoder. Det finns en funktion för att köra en utfodring cykel, med en extra kopp (för dagar där du tror att ditt husdjur behöver de extra kalorierna), och en funktion för att återställa hela systemet.
< p > if(feed == HIGH) {//Feeds Lydia < br >
small_stepper.setSpeed(300);
small_stepper.Step(2000);
tryckte = låg;
Delay(3000); Från början har ett stort steg att få bort begränsande sensorn (mindre och sensorn registrerar flera pressar)
While(Pressed == low) {
small_stepper.setSpeed(450); Denna loop fortsätter tills begränsande sensorn trycks en gång (vilket betyder att cylindern gick runt en gång för en kopp)
small_stepper.Step(30);
Delay(200); Det kommer att flytta fram 50 steg och tillbaka 20, för att minimera störning
small_stepper.Step(-10);
limState = digitalRead(limPin);
om (limState == hög) {
tryckte = hög; Läser gräns pin och räknar en press
Serial.println ("switch hit");
Delay(4500);
}
} < /p >< p > small_stepper.setSpeed(500);
small_stepper.Step(-20);
Delay(10);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(300);
small_stepper.Step(2000);
Delay(3000);
tryckte = låg;
While(Pressed == low) {< /p >< p > small_stepper.setSpeed(450);
small_stepper.Step(30);
Delay(200);
small_stepper.Step(-10);
limState = digitalRead(limPin);
om (limState == hög) {
tryckte = hög;
Delay(500);
Serial.println ("Pad var inne");
Serial.println ("växla hit"); < /p >< p >}
}
small_stepper.setSpeed(500);
small_stepper.Step(-25);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
small_stepper.setSpeed(500);
small_stepper.Step(-50);
small_stepper.setSpeed(500);
small_stepper.Step(50);
Delay(500);
tryckte = låg;
flöde = låg;
jag = i + 1. Berättar mataren det går vidare till nästa cykel (AMorPM)
justFed = hög;
} < /p >
Detta är den viktigaste delen av koden - den utfodring cykeln. Det börjar med ett stort "steg" att flytta de flesta av vägen runt systemet. Det därefter uppsättningar att låg, vilket korrelerar till den begränsande växla. Om det inte gör det hela vägen runt då det var en sylt, så det går genom en un-störning tag-loop. Det kommer att börja ta 30 steg framåt och 10 steg tillbaka fram till växeln begränsande slog. Väl på toppen, kommer det gå fram och tillbaka för att skaka mat in i cylindern. Denna cykel börjar sedan igen, att mata mitt husdjur sammanlagt två koppar. Detta kan justeras för ditt husdjur genom att ta bort den andra cykeln.
< p > om (disableTouch == hög & & minuter == 960 & & AMorPM == hög) {/ / om touch sensorn trycks någonsin, det blir funktionshindrade. Detta gör det möjligt att tryckas igen när en ny utfodring cykel har börjat. < br > disableTouch = låg;
}
om (disableTouch == hög & & minuter == 480 & & AMorPM == låg) {
disableTouch = låg;
} < /p >
Om touch sensor trycktes till en början matning, aktiveras funktionen disableTouch. Jag kallar detta min "Greg-bevis funktion." Jag har en vän som heter Greg, som jag vet, skulle spendera tid att trycka på touch sensor om och om igen tills alla 20 £ av hundmat skulle vara utspridda över mitt golv. Touch sensorn aktiveras igen när den tidiga-utfodring tiden förflutit, och det går tillbaka till det är ordinarie schemaläggning.
< p > om (millis() > = startTime) {< br > minuter--; / / 60000 sekunder är lika med 1 min
startTime += 60000;
om (minuter == 0) {/ / kör utfodring cykeln om timern når noll
flöde = hög;
disableTouch = låg;
berört = låg;
}
sevseg.setNumber (minuter, 1);
} < /p >
Om-funktionen är timerfunktionen. Det kommer nedräkning varje minut och om protokollet är lika med noll, det kommer att köra funktionen foder och inaktivera funktionen Greg-bevis.
< p > om (i %2 == 1) {/ / villkorlig uppgift att avgöra om det är AM eller PM udda cykler en re PM < br > AMorPM = hög;
}
annars om (i %2 == 0) {
AMorPM = låg;} < /p >
Detta är del av koden som växlar mellan de två utfodring cyklerna. Varje gång den utfodring cykeln körs "i" kommer att öka med ett. Det sägs att när "i" delas av och och har en fettåterstoden (udda), det kommer att växla till den kvällen foder cykeln och vice versa. Detta korrelerar till nollställa timern.
< p > om (justFed == hög & & rörd == låg & & AMorPM == låg) {/ / för tidsinställning och inaktivera touch sensor. < br > minuter = 480;
justFed = låg;
}
annat if (justFed == hög & & rörd == låg & & AMorPM == hög) {
minuter = 960;
justFed = låg;
}
annat if (justFed == hög & & rörd == hög & & AMorPM == låg) {
minuter = 480 + minuter.
justFed = låg;
disableTouch = hög; < /p >< p > sevseg.refreshDisplay(); < /p >< p >
}
annars om (justFed == hög & & rörd == hög & & AMorPM == hög) {
minuter = 960 + minuter.
justFed = låg;
disableTouch = hög; < /p >< p > sevseg.refreshDisplay(); < /p >< p >}
sevseg.refreshDisplay(); Måste köra flera gånger
} < /p >
Detta är slutet av kod som återställs timern till lämplig tidpunkt. Om touch sensor var nere, kommer det ta den tid som fanns kvar och lägga till den i nästa utfodring gång. Detta är så mataren är aldrig bort schemat. Om timern går ner till noll, sätts helt enkelt tiden till dess att nästa utfodring. Sevseg.refreshDisplay(); är vad berättar timern att uppdatera.