ps19 Maj 15, 2014 Udostępnij Maj 15, 2014 Nie znam się na Arduino, ale tam chyba nie ustawia się rejestrów sądząc po tym co widzę tutaj: http://sprae.jogger.pl/2011/10/14/wielozadaniowosc-w-arduino/ Rozdział: Programowanie zdarzeniowe i Biblioteka Timers. Musisz zdecydować się czy piszesz w czystym C (wymagana zmiana bootloadera) czy w języku C dla Arduino bo teraz może to nie działać pomimo dobrego programu z racji tego, że kompilator/procek nie wie o co nam chodzi np. z ISR czy sei(); W przypadku czystego C (bardziej przyszłościowe) polecam zakupienie jakiejś książki na ten temat np. "Mikrokontrolery AVR Język C - podstawy programowania" w przypadku Arduino nie umiem doradzić. Cytuj Link do komentarza Share on other sites More sharing options...
daniel89 Maj 15, 2014 Autor tematu Udostępnij Maj 15, 2014 http://arduino.cc/en/Reference/Interrupts http://www.instructables.com/id/Arduino-Timer-Interrupts/ Sądząc po tej drugiej stronie Interrupts(); - tym się powinno załączać te timery , tylko z tego co Ty mi pokazałeś wynika że gościu używa mills() które dają wielozadaniowość , albo wprowadza własną bibliotekę z timerami tylko to dziwne jakieś bo przecież timery trzeba dla każdego procka i jego częstotliwości ustwić samemu , czy by miał tam wszystkie możliwe poustawiane wątpię? Powinno dać się te sprzętowe ustwić na tej stronce od arduino.cc jest referencja ustawień mógł byś na to rzucić okiem ? Tutaj gościu w wersji polskiej ustawiał timery i używał sei(), ISR -->> http://majsterkowo.pl/zegar-cyfrowy-led-z-bajerami-czesc-iii-przerwania-zegarowe/ To jak da się to ustawić z tym sei, ISR czy nie? a co do książki to dziękuję za radę, a jakie środowisko pracy dla niego byś mi polecił AVR Studio czy Eclipse ? Cytuj Link do komentarza Share on other sites More sharing options...
ps19 Maj 15, 2014 Udostępnij Maj 15, 2014 1,2. To na pewno da się ustawić, ale dobrze by było poczekać aż wypowie się ktoś kto cokolwiek robił na arduino, posiada zestaw z arduino aby sprawdzić czy działa. 3. Eclipse Wrzuć ten program do procka bez zmienian, dioda powinna zmieniać stan co 500 ms. Zmień wartość zmiennej dioda_pin na numer pinu do którego masz podłączoną jakąś diodę led. #include <Servo.h> #include <interrupts.h> volatile boolean x=0; volatile int dioda_pin = 1; // zmien tutaj na numer pinu do którego masz podłączoną jakas diode led void setup () { TCCR1A |= (1<<WGM12); //tryb CTC TCCR1B |= (1<<CS12) | (1<<CS10); //prescaler 1024 TIMSK1 |= (1<<OCIE1B); OCR1B = 7811; //500 ms pinMode(dioda_pin, OUTPUT); sei(); }; ISR(TIMER1_COMPB_vect){ digitalWrite(dioda_pin, 0); } void loop () { digitalWrite(dioda_pin, 1); } lub #include <Servo.h> #include <interrupts.h> volatile boolean x=0; volatile int dioda_pin = 1; // zmien tutaj na numer pinu do którego masz podłączoną jakas diode led void setup () { TCCR1A |= (1<<WGM12); //tryb CTC TCCR1B |= (1<<CS12) | (1<<CS10); //prescaler 1024 TIMSK1 |= (1<<OCIE1B); OCR1B = 7811; //500 ms pinMode(dioda_pin, OUTPUT); }; ISR(TIMER1_COMPB_vect){ digitalWrite(dioda_pin, 0); } void loop () { sei(); digitalWrite(dioda_pin, 1); } Nie wiem czy w Arduino też tak jest, ale może masz w Fusach włączony CKDIV8 i dlatego z 1 sekundy robi się 5 sekund, albo masz źle ustawiony zegar, może jest coś takiego jak jakieś ustawienia projektu w arduino w którym trzeba ustawić jakieś taktowanie (F_CPU) Ewentualnie, jak dioda będzie świecić albo będzie cały czas zgaszona to spróbuj wpisać do OCR1B = 1952; //1 sekunda przy 2 Mhz lub OCR1B = 7811; //1 sekunda przy 8 Mhz Może masz coś z zegarem Cytuj Link do komentarza Share on other sites More sharing options...
daniel89 Maj 15, 2014 Autor tematu Udostępnij Maj 15, 2014 Tutaj masz ustawienia tego leonardo (plik boards) : leonardo.name=Arduino Leonardo leonardo.upload.protocol=avr109 leonardo.upload.maximum_size=28672 leonardo.upload.speed=57600 leonardo.upload.disable_flushing=true leonardo.bootloader.low_fuses=0xff leonardo.bootloader.high_fuses=0xd8 leonardo.bootloader.extended_fuses=0xcb leonardo.bootloader.path=caterina leonardo.bootloader.file=Caterina-Leonardo.hex leonardo.bootloader.unlock_bits=0x3F leonardo.bootloader.lock_bits=0x2F leonardo.build.mcu=atmega32u4 leonardo.build.f_cpu=16000000L leonardo.build.vid=0x2341 leonardo.build.pid=0x8036 leonardo.build.core=arduino leonardo.build.variant=leonardo Po wgraniu tych dwóch Twoich przykładów dioda się zapala i pali się stale. Nawet po wyzerowaniu liczników. Przerwania uzyskałem tylko dzięki funkcji mills(); z tego postu co mi przesłałeś - to jest tzw. wielozadaniowość, ale i tak pomimo tej funkcji powinno dać się ustawić fabryczne timery, chyba że to całe środowisko Arduino losowo wybiera timera, który wolny funkcją mills(); ale to po co by wrzucali w necie te przykłady z własnymi ustawieniami wewnętrznych timerów i podobno im działały. Tutaj masz po angielsku obsługę timerów w Arduino taki tutorial -->> http://www.instructables.com/id/Arduino-Timer-Interrupts/?ALLSTEPS Po modyfikacji tym programem załączam timera ale miga co 3 sekundy a powinien co 1 według Twojego wzoru. Próbowałem ustawiać na różne taktowanie na 1 MHz, na 2, na 8 i ciągle było to samo czyli miga co 3 sec na 3 sec. Oto ten kod: #include <Servo.h> #include <interrupts.h> volatile boolean x=0; volatile int dioda_pin = 1; void setup () { TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; OCR1B = 15624; // 1 Hz przy 16Mhz (zegar) TCCR1A |= (1<<WGM12); //tryb CTC TCCR1B |= (1<<CS12) | (1<<CS10); //prescaler 1024 TIMSK1 |= (1<<OCIE1B); sei(); pinMode(dioda_pin, OUTPUT); }; ISR(TIMER1_COMPB_vect){ x=!x; digitalWrite(1,x) ; } void loop () {} PS. Działa tylko po wyzerowaniu liczników. Procek ten ma timer0, timer1, timer3 oraz timer4 (z noty katalogowej). Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
ps19 Maj 16, 2014 Udostępnij Maj 16, 2014 Już chyba rozgryzłem dlaczego z 1 sekundy robiły się 3 - błędny wzór. Jak kod działa to go nie ruszaj, potem resztę stopniowo dodasz jak uzyskamy miganie takie jak chcemy. Ma być: OCR = (F_CPU/2*PRESKALER/CZESTOTLIWOSC) -1 7811 = (16000000/2048/2)-1 1 sekunda świeci i 1 sekunda zgaszona - 2Hz a nie IRQ = (F_CPU/PRESKALER/CZESTOTLIWOSC) -1 to jest wzór tj. na czestotliwość wejściową (pin ICP (Input Capture Register)) Cytuj Link do komentarza Share on other sites More sharing options...
daniel89 Maj 16, 2014 Autor tematu Udostępnij Maj 16, 2014 Próbowałem to na tych millsach zrobić , ale jak pilotem załączam to servo się po jednym impulsie obraca, a silniki ani odczyt z czujnika nie działają . Czego to jest wina ? Przecież kod powinien być dobry, oto on : #include <IRremote.h> #define irPin 11 IRrecv irrecv(irPin); decode_results results; #include <Servo.h> # define SERVO_PIN 12 Servo servo; byte stan = 0; byte angle = 0; unsigned long servo_time = millis() + 20; unsigned long silnik_time = millis() + 500; unsigned long pilot_time = millis() + 500; #define trig 2 #define echo 3 int pwmMotorA=6; int InMotorA1=5; int InMotorA2=4; int pwmMotorB=10; int InMotorB1=9; int InMotorB2=8; int pwm = 0; void setup() { irrecv.enableIRIn(); servo.attach(SERVO_PIN); pinMode(pwmMotorA, OUTPUT); pinMode(pwmMotorB, OUTPUT); pinMode(InMotorA1, OUTPUT); pinMode(InMotorA2, OUTPUT); pinMode(InMotorB1, OUTPUT); pinMode(InMotorB2, OUTPUT); pinMode (trig, OUTPUT); pinMode (echo, INPUT); } void loop() { unsigned long time = millis(); if (time >= pilot_time){ if (irrecv.decode(&results)) { switch (results.value) { case 0x1D00B946: stan=!stan; break; } irrecv.resume(); pilot_time = time + 500; } } int duration, distance; digitalWrite( trig, LOW); delayMicroseconds (2); digitalWrite (trig, HIGH); delayMicroseconds(10); digitalWrite (trig, LOW); duration = pulseIn(echo, HIGH); distance = (duration/2) / 29.1; if (time >=silnik_time && distance<=30 && stan==1) { unsigned long silnik_time = millis() + 500; digitalWrite(InMotorA1, LOW); digitalWrite(InMotorA2, HIGH); digitalWrite(InMotorB1, LOW); digitalWrite(InMotorB2, LOW); analogWrite(pwmMotorA,200); analogWrite(pwmMotorB,0); silnik_time = time + 500; } if (time >= servo_time && stan==1 && distance<15 && distance >2) { servo.write(angle); angle++; if (angle > 180) angle = 0; servo_time = time + 20; } if (time >= silnik_time && stan==1 && distance<15 && distance >2 ) { unsigned long silnik_time = millis() + 500; digitalWrite(InMotorA1, LOW); digitalWrite(InMotorA2, HIGH); digitalWrite(InMotorB1, LOW); digitalWrite(InMotorB2, HIGH); if (pwm<250) { pwm=pwm+50;} analogWrite(pwmMotorA, pwm); analogWrite(pwmMotorB, pwm); silnik_time = time + 500; } if(stan==0){ analogWrite(pwmMotorB,0); analogWrite(pwmMotorA,0); servo.write(angle=90); } else if (time >=silnik_time && stan==1) { unsigned long silnik_time = millis() + 500; analogWrite(pwmMotorA,200); analogWrite(pwmMotorB,200); digitalWrite(InMotorA1, LOW); digitalWrite(InMotorA2, HIGH); digitalWrite(InMotorB1, LOW); digitalWrite(InMotorB2, HIGH); silnik_time = time + 500;} } Timery w tym kodzie pomimo ich modyfikacji według Twojego drugiego wzoru działają ciągle tak samo czyli co 3 sekundy się załącza i wyłącza. Gdy usunąłem zerowanie TCCR1A = 0; wtedy zaczęło migać jak oszalałe co 0,1 s. Zmieniłem wartość OCR1B i dalej było to samo . Żadna liczba którą wpisałem do kodu w OCR1B nic nie zmieniała. Cytuj Link do komentarza Share on other sites More sharing options...
daniel89 Maj 19, 2014 Autor tematu Udostępnij Maj 19, 2014 Z tymi wewnętrznymi timerami sobie nie mogę poradzić, gdyż po ustawieniu danej wartości i tak mi przerwanie działa tylko co 3 sekundy , ale za to udało mi się napisać ten program na milsach , zdefiniowanych jako timery Arduino IDE. także już ten robocik jeździ mniej więcej tak jak chciałem. Do pełni szczęścia muszę jeszcze rozgryźć ustawienia tych timerów także jakby ktoś miał jakiś pomysł to proszę pisać śmiało . Cytuj Link do komentarza Share on other sites More sharing options...
daniel89 Maj 23, 2014 Autor tematu Udostępnij Maj 23, 2014 Czemu w tym kodzie jak ustawię wielozadaniowość na odległość mniejszą od 10, to program wykonuje i obrót serwem i jedzie do tyłu, a jak ustawię na odległość większą od 30, aby się serwo obracało wraz z jechaniem do przodu, to serwo nie idzie tzn. wykonuje takie impulsy w bok i się cofa na 90stopni.? #include <IRremote.h> #define irPin 10 IRrecv irrecv(irPin); decode_results results; #include <Servo.h> # define SERVO_PIN 12 Servo servo; byte stan = 0; byte angle = 0; unsigned long servo_time = millis() + 20; unsigned long silnik_time = millis() + 500; // unsigned long pilot_time = millis() + 200; #define trig 2 #define echo 3 int pwmMotorA=5; int InMotorA1=7; int InMotorA2=4; int pwmMotorB=11; int InMotorB1=9; int InMotorB2=8; int pwm; void setup() { irrecv.enableIRIn(); servo.attach(SERVO_PIN); pinMode(pwmMotorA, OUTPUT); pinMode(pwmMotorB, OUTPUT); pinMode(InMotorA1, OUTPUT); pinMode(InMotorA2, OUTPUT); pinMode(InMotorB1, OUTPUT); pinMode(InMotorB2, OUTPUT); pinMode (trig, OUTPUT); pinMode (echo, INPUT); } void loop() { unsigned long time = millis(); // if (time >= pilot_time){ if (irrecv.decode(&results)) { switch (results.value) { case 0x1D00B946: stan=!stan; break; } irrecv.resume(); // pilot_time = time + 200; } int duration, distance; digitalWrite( trig, LOW); delayMicroseconds (2); digitalWrite (trig, HIGH); delayMicroseconds(10); digitalWrite (trig, LOW); duration = pulseIn(echo, HIGH); distance = (duration/2) / 29.1; if (time >=silnik_time && distance<=30 && distance>10 && stan==1) { servo.write(angle=90); analogWrite(pwmMotorA, 225); digitalWrite(pwmMotorB, LOW); digitalWrite(InMotorA1, LOW); digitalWrite(InMotorA2, HIGH); digitalWrite(InMotorB1, LOW); digitalWrite(InMotorB2, LOW); silnik_time = time + 500; } if (time >= servo_time && stan==1 && distance<=10 ) { servo.write(angle); angle+=1; if (angle > 180) angle = 0; servo_time = time + 20; } if (time >= silnik_time && stan==1 && distance<=10 ) { for (pwm=0; pwm <=225 ; pwm=pwm+5){ analogWrite(pwmMotorA, pwm); analogWrite(pwmMotorB, pwm); digitalWrite(InMotorA1, HIGH); digitalWrite(InMotorA2, LOW); digitalWrite(InMotorB1, HIGH); digitalWrite(InMotorB2, LOW);} silnik_time = time + 500; } if( stan==0){ digitalWrite(pwmMotorB,LOW); digitalWrite(pwmMotorA,LOW); servo.write(angle=90); } if (distance > 30 && time >=silnik_time && stan==1) { servo.write(angle=90); digitalWrite(pwmMotorA,1); digitalWrite(pwmMotorB,1); digitalWrite(InMotorA1, LOW); digitalWrite(InMotorA2, HIGH); digitalWrite(InMotorB1, LOW); digitalWrite(InMotorB2, HIGH); silnik_time = time + 500;} } Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!