Dvere - linearni motor

Odpovědět
Mike_cz
Příspěvky: 11
Registrován: 02 říj 2017, 13:15
Reputation: 0

Dvere - linearni motor

Příspěvek od Mike_cz » 07 zář 2019, 16:14

Ahoj,

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
DS3231 RTC je nastaveny uz pomoci jineho kodu a davaji spravny cas
Schema.jpg
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
Diky moc za pomoc

Mike_cz
Příspěvky: 11
Registrován: 02 říj 2017, 13:15
Reputation: 0

Re: Dvere - linearni motor

Příspěvek od Mike_cz » 07 zář 2019, 20:46

Nenasel jsem zpusob editace, tak vkladam schema bez chyby.
Přílohy
Schema.jpg

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Dvere - linearni motor

Příspěvek od petan » 08 zář 2019, 00:16

Doporučil bych ti nejdřív se oprostit od tohoto programu a zkusit si jenom arduino s nějakým jednoduchým programem a těmi relé. Jestli máš vše správně zapojené. Podle schématu, co jsi přiložil to dobře není. Pokud se nepletu, tak napájení desky (VCC, GND) je na krajních pinech a ty dva uprostřed jsou na ovládání samotných relátek (IN1, IN2).

Ty dvě relé přehazují polaritu na výstupu. Na výstup jde +-, když jsou obě vypnutá. Na výstup jde -+, když jsou obě zapnutá. Zkus tedy použít program, kde budeš jenom cvakat s relátky a motor by se měl točit jedním, nebo druhým směrem.

PS.: Záleží samozřejmě na konstrukci, ale osobně bych to zapojil tak, aby se to v případě obou vypnutých, nebo zapnutých relé nehýbalo. Mám na mysli toto schéma: https://www.mylms.cz/releove-obvody/#ssreverzace

Kód: Vybrat vše

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(13, OUTPUT);	//ledka
}

void loop() {
//směr na jednu stranu
  digitalWrite(2, LOW);	//relé 1
  digitalWrite(3, LOW);	//relé 2
  digitalWrite(13, LOW);	//ledka pro kontrolu
  delay(5000);
  
  //a na druhou stranu
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(13, HIGH);
  delay(5000);
}

Mike_cz
Příspěvky: 11
Registrován: 02 říj 2017, 13:15
Reputation: 0

Re: Dvere - linearni motor

Příspěvek od Mike_cz » 08 zář 2019, 10:25

Vyreseno, uz jsem na to prisel :)
Rele PINy jsou prave nestandardne:
Pri pohledu zhora tak jak je ve schematu je to zleva:
INT2, INT1, DC-, DC+ ...
Problem byl v nastaveni LOW/HIGH pri "OPEN" a "CLOSE"

Mike_cz
Příspěvky: 11
Registrován: 02 říj 2017, 13:15
Reputation: 0

Re: Dvere - linearni motor

Příspěvek od Mike_cz » 08 zář 2019, 16:09

Tak jeste nevyreseno. Motor funguje jak ma, ale spatne se me zpracovavaji hodnoty, i kdyz mam definovany datovy typ LONG pro array, a pak i pro promenne se kterymi se pocita, tak jakmile hodnota v array prekroci 65535(coz je 18hod a 12min) tak zacne pocitat od nuly. A s timto si uz fakt nevim rady. Diky za pomoc

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Dvere - linearni motor

Příspěvek od ondraN » 04 říj 2019, 07:17

Zkusil bych typ definovat jako unsigned long (unsigned je podmínkou, aby fungovalo ++ nebo --) ,pokud tedy nepočítáš se zápornými čísly. Pokud přičítáš nějake číslo, tak za něj dát L, např x=x+10L. pokud ani to nepomůže, dej sem inkriminovanou část kódu.

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 12 hostů