snazim se rozchodit linearni motor(actuator) s Arduinem, a nejak se me to nedari - poprosil bych o konzultaci, jestli mam vse jak ma byt - nechal jsem se inspirovat na Netu, jak zapojenim, tak kodem.
Samotny motor funguje, ale jakmile ho pripojim k Arduinu, tak se ani nepohne.
Projekt:
otevirani dveri - pri vychodu slunce, zavreni dveri pri zapadu.
Pouzite komponenty:
- Arduino Uno
- DS3231 RTC
- 2CH Rele
kod:
Kód: Vybrat vše
/*
ChickenDoor - V0.6
Opens and closes a linear actuator based on sunrise and sunset tables included in the program.
Uses the Timezone library (url below) to automatically adjust the time twice yearly for Daylight
Saving Time.
*/
// Includes
//
#include <Arduino.h>
#include <DS1307RTC.h> //http://www.arduino.cc/playground/Code/Time
#include <Time.h> //http://www.arduino.cc/playground/Code/Time
#include <TimeLib.h>
#include <Timezone.h> //https://github.com/JChristensen/Timezone
#include <Wire.h> //http://arduino.cc/en/Reference/Wire (supplied with the Arduino IDE)
#pragma GCC diagnostic ignored "-Wwrite-strings"
// Defines
//
#define DEBUG
#define OPEN 0
#define CLOSED 1
#define OFF 0
#define ON 1
#define SUNRISE_DELAY (0*60) //x minutes delay to open
#define SUNSET_DELAY (60*60) // x minutes delay to close
// Sunset times in seconds after midnight for each ordinal day of the year,
// eg, Jan 1 = array index 0, etc. The times are EST and are adjusted one
// hour when DST is in effect.
//
// The arrays are stored in program memory because dynamic memory is not
// big enough to hold them
//
static const long sunsetAr[] PROGMEM = {57900,57960,58080,58140,58200,58260,
58320,58380,58500,58560,58620,58740,58800,58860,58980,59040,59160,59220,59340,
59400,59520,59580,59700,59760,59880,60000,60060,60180,60300,60360,60480,60540,
60660,60720,60840,60960,61020,61140,61260,61380,61440,61560,61680,61740,61860,
61980,62040,62160,62280,62340,62460,62580,62640,62760,62880,62940,63060,63120,
63240,63360,63420,63540,63600,63720,63840,63900,64020,64080,64200,64320,64380,
64500,64560,64680,64740,64860,64980,65040,65160,65220,65340,65400,65520,65580,
65700,65760,65880,65940,69660,69720,69840,69960,70020,70140,70200,70320,70380,
70500,70560,70680,70740,70860,70920,71040,71100,71220,71280,71400,71460,71580,
71640,71760,71820,71940,72000,72120,72180,72300,72360,72480,72540,72660,72720,
72840,72900,73020,73080,73200,73260,73380,73440,73500,73620,73680,73800,73860,
73920,74040,74100,74160,74280,74340,74400,74460,74520,74640,74700,74760,74820,
74880,74940,75000,75060,75120,75180,75240,75300,75360,75360,75420,75480,75480,
75540,75600,75600,75660,75660,75720,75720,75720,75780,75780,75780,75780,75780,
75780,75780,75780,75780,75780,75780,75780,75780,75720,75720,75660,75660,75600,
75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,
75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,75600,
75600,75600,75600,75600,75600,75600,73320,73200,73080,73020,72900,72780,72660,
72600,72480,72360,72240,72120,72000,71880,71760,71640,71520,71400,71280,70200,
70200,70200,70200,70200,70200,70200,70200,70200,69000,69000,69000,69000,69000,
69000,69000,69000,69000,68880,68760,68640,68520,68400,68280,68100,67980,67860,
67740,67620,67500,67320,67200,67080,66960,66840,66720,66600,66480,66300,66180,
66060,65940,65820,65700,65580,65460,65340,65220,65100,64980,64860,64740,64620,
64500,64380,64260,64140,64080,63960,60240,60120,60000,59940,59820,59700,59580,
59520,59400,59340,59220,59100,59040,58920,58860,58800,58680,58620,58500,58440,
58380,58320,58200,58140,58080,58020,57960,57900,57840,57780,57720,57720,57660,
57600,57540,57540,57480,57480,57420,57420,57360,57360,57360,57300,57300,57300,
57300,57300,57300,57300,57300,57300,57360,57360,57360,57420,57420,57480,57480,
57540,57540,57600,57660,57660,57720,57780,57840,57900};
static const long sunriseAr[] PROGMEM = {26100,26100,26100,26100,26100,26100,
26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,
26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,
26100,26100,26100,26100,26100,26100,26100,26040,25920,25860,25740,25620,25560,
25440,25320,25200,25140,25020,24900,24780,24660,24540,24420,24300,24180,24120,
24000,23880,23760,23640,23520,23400,23220,23100,22980,22860,22740,22620,22500,
22380,22260,22140,22020,21840,21720,21600,21480,21360,21240,21120,21000,20820,
20700,20580,20460,20340,21600,21600,21600,21600,21600,21600,21600,21600,21600,
21600,21600,21600,21600,21600,21600,21600,21600,21600,21600,21480,21360,21240,
21120,21000,20880,20760,20640,20520,20460,20340,20220,20100,19980,19920,19800,
19680,19620,19500,19380,19320,19200,19140,19020,18960,18840,18780,18720,18600,
18540,18480,18360,18300,18240,18180,18120,18060,18000,17940,17880,17820,17760,
17700,17640,17580,17580,17520,17520,17460,17400,17400,17340,17340,17340,17280,
17280,17280,17280,17280,17280,17280,17280,17280,17280,17280,17280,17280,17340,
17340,17340,17400,17400,17460,17460,17520,17580,17580,17640,17700,17700,17760,
17820,17880,17940,18000,18060,18120,18180,18240,18300,18360,18420,18480,18540,
18660,18720,18780,18840,18960,19020,19080,19140,19260,19320,19380,19500,19560,
19620,19740,19800,19920,19980,20040,20160,20220,20340,20400,20460,20580,20640,
20760,20820,20940,21000,21120,21180,21240,21360,21420,21540,21600,21600,21600,
21600,21600,21600,21600,21600,21600,21600,21600,21600,21600,21600,21600,21600,
21600,21600,21600,21600,21600,22500,22500,22500,22500,22500,22500,22500,22500,
22500,22500,22500,22500,22500,22500,22500,22500,23400,23400,23400,23400,23400,
23400,23400,23400,23400,23400,23400,23400,23400,23400,23400,23400,23400,23400,
23400,23400,23400,23400,23400,23400,23460,23520,23640,23760,23820,23940,24060,
24120,24240,24300,24420,24540,24600,24720,24780,24900,25020,25080,25200,25260,
25380,25500,25560,25680,25740,25860,25920,26040,26100,26100,26100,26100,26100,
26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,
26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,26100,
26100,26100,26100,26100,26100,26100,26100,26100,26100};
// Constants
//
const int delayTime = 1000;
const int relayOnePin = 1; // Unused
const int relayTwoPin = 2; // Door 1
const int relayThreePin = 3; // Door 2
const int relayFourPin = 4; // Lights
const int secondsPerHour = 3600;
// Days of months array for ordinal calculation
static const int monthLen[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
// Globals
//
//Central European Time (Frankfurt, Paris, Prague)
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; //Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; //Central European Standard Time
Timezone myTZ(CEST, CET);
TimeChangeRule *tcr; // pointer to the time change rule, use to get TZ abbrev
time_t utc, local;
int doorState = CLOSED;
int lightState = OFF;
// Init
void setup()
{
long sunset = 0;
long sunrise = 0;
long seconds = 0;
// Initialize the relay pins
pinMode(relayOnePin, OUTPUT);
pinMode(relayTwoPin, OUTPUT);
pinMode(relayThreePin, OUTPUT);
pinMode(relayFourPin, OUTPUT);
#ifdef DEBUG
// Start the serial port
Serial.begin(9600);
while (!Serial)
;
delay(200);
#endif
// Set the time using the RTC's time
setSyncProvider(RTC.get); // Get the time from the RTC
#ifdef DEBUG
if(timeStatus()!= timeSet) // Again, this is check the TZ lib status
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time ");
#endif
// Door initialization based on TZ library time
utc = now();
local = myTZ.toLocal(utc, &tcr);
#ifdef DEBUG
Serial.print("Start-up time: ");
printTime(local, tcr -> abbrev);
#endif
// We have the date and time, convert it to seconds since midnight
seconds = toSeconds(hour(local), minute(local), 0);
// Get the ordinal day of the year to use as an index into the sunset/rise arrays
int ordinalDay = ordinalDayOfYear(tmYearToCalendar(year(local)), month(local), day(local));
// Get the times adjusted for DST and open/close delay
sunrise = getAdjustedSunriseTime(ordinalDay, local);
sunset = getAdjustedSunsetTime(ordinalDay, local);
// Close or open the door, the door methods check for current state
if ((seconds > sunrise) && (seconds < sunset))
{
doorState = CLOSED;
openDoor();
} else {
doorState = OPEN;
closeDoor();
}
// Turn the lights on (6AM) or off (9PM)
initCoopLights(local);
}
void loop()
{
long sunset = 0;
long sunrise = 0;
long seconds = 0;
// Wait the current delay time
delay(delayTime);
// get current date and time
utc = now();
local = myTZ.toLocal(utc, &tcr);
#ifdef DEBUG
// printTime(local, tcr -> abbrev);
#endif
// We have the date and time
seconds = toSeconds(hour(local), minute(local), 0);
// Now get the ordinal day of the year
int ordinalDay = ordinalDayOfYear(tmYearToCalendar(year(local)), month(local), day(local));
// Get the times adjusted for DST and open/close delay
sunrise = getAdjustedSunriseTime(ordinalDay, local);
sunset = getAdjustedSunsetTime(ordinalDay, local);
// Close or open the door, the door methods check for current state
if ((seconds > sunrise) && (seconds < sunset))
{
openDoor();
} else {
closeDoor();
}
// Turn the lights on (6AM) or off (9PM)
setCoopLights(local);
}
void openDoor()
{
// Is the door closed?
if (doorState == CLOSED)
{
#ifdef DEBUG
Serial.print("Opening door: ");
utc = now();
local = myTZ.toLocal(utc, &tcr);
printTime(local, tcr -> abbrev);
#endif
doorState = OPEN;
// open the door
digitalWrite(relayTwoPin, HIGH);
digitalWrite(relayThreePin, HIGH);
}
return;
}
void closeDoor()
{
// Is the door open?
if (doorState == OPEN)
{
#ifdef DEBUG
Serial.print("Closing door: ");
utc = now();
local = myTZ.toLocal(utc, &tcr);
printTime(local, tcr -> abbrev);
#endif
doorState = CLOSED;
// close the door
digitalWrite(relayTwoPin, LOW);
digitalWrite(relayThreePin, LOW);
}
return;
}
void initCoopLights(time_t t)
{
int curHour = hour(t);
// On between 6AM and 9PM
if (curHour > 5 && curHour < 21)
{
// Turn on the lights
lightState = ON;
#ifdef DEBUG
Serial.print("Turning lights on: ");
utc = now();
local = myTZ.toLocal(utc, &tcr);
printTime(local, tcr -> abbrev);
#endif
digitalWrite(relayFourPin, HIGH);
} else {
// Turn off the lights
lightState = OFF;
#ifdef DEBUG
Serial.print("Turning lights off: ");
utc = now();
local = myTZ.toLocal(utc, &tcr);
printTime(local, tcr -> abbrev);
#endif
digitalWrite(relayFourPin, LOW);
}
return;
}
void setCoopLights(time_t t)
{
int curHour = hour(t);
// On between 6AM and 9PM
if (curHour > 5 && curHour < 21)
{
if (lightState == OFF)
{
#ifdef DEBUG
Serial.print("Turning lights on at ");
Serial.println(curHour);
#endif
lightState = ON;
// Turn off the lights
digitalWrite(relayFourPin, HIGH);
}
} else {
if (lightState == ON)
{
lightState = OFF;
#ifdef DEBUG
Serial.print("Turning lights off at ");
Serial.println(curHour);
#endif
// Turn on the lights
digitalWrite(relayFourPin, LOW);
}
}
return;
}
long toSeconds(long hours, long minutes, long seconds)
{
long secs = (hours*secondsPerHour)+(minutes*60)+seconds;
return secs;
}
int ordinalDayOfYear(int year, int month, int day)
{
int ordinal = 0;
// Is it a leap year?
int leap = (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
// Add up the days of the months preceding the current month
for (int i = 0; i < month - 1; i++)
{
ordinal += monthLen[i];
}
// Check for leap year
if (leap && month > 2)
{
ordinal++;
}
// Include days in current month
ordinal += day;
return ordinal;
}
long getAdjustedSunriseTime(int ordinalDay, time_t local)
{
// Get the sunrise time from the table - adjust index for zero-based array
long sunrise = pgm_read_word_near(sunriseAr + (ordinalDay - 1));
// Check for DST and adjust if necessary
if (myTZ.locIsDST(local))
{
// Add an hour to sunrise
sunrise += secondsPerHour;
}
// And finally add the sunrise opening delay
sunrise += SUNRISE_DELAY;
return sunrise;
}
long getAdjustedSunsetTime(int ordinalDay, time_t local)
{
// Get the sunset time from the table - adjust index for zero-based array
long sunset = pgm_read_word_near(sunsetAr + (ordinalDay - 1));
// Check for DST and adjust if necessary
if (myTZ.locIsDST(local))
{
// Add an hour to sunset
sunset += secondsPerHour;
}
// And finally add the sunrise opening delay
sunset += SUNSET_DELAY;
return sunset;
}
#ifdef DEBUG
//Function to print time with time zone
void printTime(time_t t, char *tz)
{
sPrintI00(hour(t));
sPrintDigits(minute(t));
sPrintDigits(second(t));
Serial.print(' ');
Serial.print(dayShortStr(weekday(t)));
Serial.print(' ');
sPrintI00(day(t));
Serial.print(' ');
Serial.print(monthShortStr(month(t)));
Serial.print(' ');
Serial.print(year(t));
Serial.print(' ');
Serial.print(tz);
Serial.println();
}
//Print an integer in "00" format (with leading zero).
//Input value assumed to be between 0 and 99.
void sPrintI00(int val)
{
if (val < 10) Serial.print('0');
Serial.print(val, DEC);
return;
}
//Print an integer in ":00" format (with leading zero).
//Input value assumed to be between 0 and 99.
void sPrintDigits(int val)
{
Serial.print(':');
if(val < 10) Serial.print('0');
Serial.print(val, DEC);
}
#endif