• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Opóźnienie działania arduino oraz 3 serwo.
#1
Witam,

Jak w temacie chciałbym opóźnić działanie arduino oraz serwo kolejno na 24, 48 i 72h. Po każdym cyklu arduino przebudzałoby się i aktywowało funkcję serwo. Zależy mi aby cały układ działał przez 3 dni na 6 bateriach AA, dlatego chce zastosować opóźnienie i wybudzenie. Widziałem wiele bibliotek odpowiedzialnych za to, ale nie wiem, z której skorzystać. Jako osoba początkująca prosiłbym o ukierunkowanie w jaką stronę zmierzać. 
Pozdrawiam.
 
Odpowiedź
#2
W jaką stronę zmierzać?
Ano w taką, która najbardziej odpowiada Twoim oczekiwaniom.
Chcesz wybudzać procesor przerwaniem z timera, więc masz do wyboru cztery tryby pracy.
IDLE, ADC Noise Reduction, Power-save, Extended Standby.
Najlepszym wyborem, według mnie, jest tryb Power-save.

Ja bym napisał tak:
Kod:
#include <avr/sleep.h>
#include <avr/power.h>
volatile int licznik=0;

ISR(TIMER1_OVF_VECT)
{
  licznik++;
}

void dobranoc()
{
 set_sleep_mode(SLEEP_MODE_PWR_SAVE);
 
 sleep_enable();
 power_adc_disable();
 power_spi_disable();
 power_timer0_disable();
 power_timer2_disable();
 power_twi_disable();  

 sleep_mode();
 
 sleep_disable();

 power_all_enable();
}

void setup()
{
 TCCR1A=0x00;
 TCNT1=0x0000;
 TCCR1B=0x05;
 TIMSK1=0x01;
}

void loop()
{
 
 dobranoc();
 if(licznik==21600)
 {
   funkcja_obslugi_serwaomechanizmu();
   dobranoc();
 }
 if(licznik==43200)
 {
   funkcja_obslugi_serwaomechanizmu();
   dobranoc();
 }
 if(licznik==64800)
 {
     licznik = 0;// po 72 godzinach resetujemy licznik
   funkcja_obslugi_serwaomechanizmu();
   dobranoc();
 }
}
void funkcja_obslugi_serwaomechanizmu(){
   // tutaj napisz co ma robic serwo
}


Tryb zegara jest tak ustawiony, żeby resetował się co miej więcej 4 sekundy.
Po tym czasie daje nam przerwanie TIMER1_OVF_VECT i inkrementuje się zmienna licznik.
Gdy procesor wyjdzie z uśpienia 21600 razy, to oznacza, że minęło 24 godziny i wykonujemy funkcję obsługi serwa i idziemy spać.
ITD...
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#3
Samo usypianie niewiele da gdy na PCB znajdują się układy, których nie możesz usypiać jak konwerter USB-USART. Należałoby go wylutować. Kolejnym problem są stabilizatory. Czy potrzebujesz 3,3V? Nie to wywal go. Stabilizator 5V i baterie AA? Gdybyś wybrał akumulatory, które mają ok 1,2V to wywalasz stabilizator 5V.

Wracając do usypiania. Zastosuj głębokie uśpienie (uA poboru prądu) i wybudzanie od watchdoga. Ustaw przerwania od watchdoga, dzięki czemu uC nie będzie resetowany. Czasy przerwań od WDG nie są zbyt precyzyjne, jeśli mają być użyj timera 2 w trybie asynchronicznym (sprawdź czy T2 w uC może pracować z zewnętrznym kwarcem, w Mega2560 tak, w Mega328 - nie pamiętam).
 
Odpowiedź
#4
Dzięki za odpowiedź,
Widzę, że usypianie dotyczy konkretnie arduino, a co z serwo? Jedyną opcją żeby zaoszczędzić energię i zapodać ją do serwo tylko kiedy będzie miała wykonać się funkcja jest budowa jakiegoś prostego przekaźnika?
 
Odpowiedź
#5
(25-04-2018, 09:26)killa8boll napisał(a): co z serwo? Jedyną opcją żeby zaoszczędzić energię i zapodać ją do serwo tylko kiedy będzie miała wykonać się funkcja jest budowa jakiegoś prostego przekaźnika?
Zamiast przekaźnika lepiej dać MOSFET. Trzeba by zbadać jaki układ steruje silnikiem w serwie. Może ma wejście wprowadzające w obniżony pobór prądu. Identyfikacja układu może być trudna bo serwo pewnie od "żółtych".
 
Odpowiedź
#6
Arduino w trybach Power-down oraz Power-save, przy wyłączonych peryferiach jak w moim kodzie, pobiera prąd około 37mA, przy czym sama atmega zjada wówczas 6,5μA, więc jest się o co bić.
No ale ufając, że płytka Arduino służy jedynie do prototypowania, to myślę, że ostateczna wersja urządzenia będzie gołą atmegą, zasilaną baterią ze StepUpa.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#7
Wszystko jasne, wielkie dzięki za pomoc.
 
Odpowiedź
#8
Napotkałem na problem z proponowanym wyżej programem z dołączonymi moimi funkcjami. Mianowicie nawet po zmniejszeniu wartości z 24/48/72h do kilku minut obrót serwo nie wykonuje się. Nie jestem w stanie znaleźć problemu. Prosiłbym o pomoc w działaniu programu:

#include <avr/sleep.h>
#include <avr/power.h>
volatile int licznik=0;
#include <HID.h>
#include <Narcoleptic.h>
#include <Servo.h>
#include <time.h>

Servo myservo1; // serwo nr 1
Servo myservo2; // serwo nr 2
Servo myservo3; // serwo nr 3

int pos = 0;

ISR(TIMER1_OVF_vect)
{
licznik++;
}

void dobranoc()
{
set_sleep_mode(SLEEP_MODE_PWR_SAVE);

sleep_enable();
power_adc_disable();
power_spi_disable();
power_timer0_disable();
power_timer2_disable();
power_twi_disable();

sleep_mode();

sleep_disable();

power_all_enable();
}

void setup()
{

myservo1.attach(9); // serwo nr 1, pin 9
myservo2.attach(8); // serwo nr 2, pin 8
myservo3.attach(7); // serwo nr 3, pin 7

TCCR1A=0x00;
TCNT1=0x0000;
TCCR1B=0x05;
TIMSK1=0x01;
}

void loop()
{

dobranoc();
if(licznik==21600)
{
funkcja_obslugi_serwaomechanizmu1();
dobranoc();
}
if(licznik==43200)
{
funkcja_obslugi_serwaomechanizmu2();
dobranoc();
}
if(licznik==64800)
{
licznik = 0; // po 72 godzinach resetujemy licznik
funkcja_obslugi_serwaomechanizmu3();
dobranoc();
}

}
void funkcja_obslugi_serwaomechanizmu1(){
for (pos = 90; pos <= 180; pos += 1) { //obrot z pozycji 90 stopni do 180
myservo1.write(pos);
delay(15); // szybkosc obrotu o 90 stopni
}
for (pos = 180; pos >= 90; pos -= 1) { //obrot z pozycji 180 stopni do 90
myservo1.write(pos);
delay(25); // szybkosc powrotu o 90 stopni

}
}
void funkcja_obslugi_serwaomechanizmu2(){
for (pos = 90; pos <= 180; pos += 1) { //obrot z pozycji 90 stopni do 180
myservo1.write(pos);
delay(15); // szybkosc obrotu o 90 stopni
}
for (pos = 180; pos >= 90; pos -= 1) { //obrot z pozycji 180 stopni do 90
myservo1.write(pos);
delay(25); // szybkosc powrotu o 90 stopni

}
}
void funkcja_obslugi_serwaomechanizmu3(){
for (pos = 90; pos <= 180; pos += 1) { //obrot z pozycji 90 stopni do 180
myservo1.write(pos);
delay(15); // szybkosc obrotu o 90 stopni
}
for (pos = 180; pos >= 90; pos -= 1) { //obrot z pozycji 180 stopni do 90
myservo1.write(pos);
delay(25); // szybkosc powrotu o 90 stopni
}

}
 
Odpowiedź
#9
Sprawdź czy program uruchamia funkcje.
Na przykład, zamiast:

Kod:
void funkcja_obslugi_serwaomechanizmu1(){
for (pos = 90; pos <= 180; pos += 1) { //obrot z pozycji 90 stopni do 180
myservo1.write(pos);
delay(15); // szybkosc obrotu o 90 stopni
}

Wpisz

Kod:
void funkcja_obslugi_serwaomechanizmu1(){
Serial.println("Wybudzenie 1");
}

Sprawdź, czy te pętle poruszają serwem.
Dopisz do funkcji setup
Kod:
for (pos = 90; pos <= 180; pos += 1) { //obrot z pozycji 90 stopni do 180
myservo1.write(pos);
delay(15); // szybkosc obrotu o 90 stopni
Powinno ruszyć serwem przed wejściem w śpiączkę.
A cha, jeszcze taka mała dygresja: nie używaj zmiennych globalnych dla licznika pętli.
Globalne, to zło. Deklaruj sobie zmienne tymczasowe.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości