Ta strona używa ciasteczek (plików cookies), dzięki którym może działać lepiej. Dowiedz się więcejRozumiem i akceptuję

[C] Wysterowanie silników według odczytów z ADC

Autor Wiadomość
sidek92 



Posty: 7
Skąd: KZ
Wysłany: 06-11-2017, 10:08   [C] Wysterowanie silników według odczytów z ADC

Witam, stworzyłem swojego pierwszego LF'a i jestem w trakcie pisania kodu. Początkowo będzie on sterowany w prostych pętlach "if", a w miarę rozwoju będę chciał dojść do napisania regulatora PD.
Aktualnie mam problem z odpowiednim wysterowaniem silników, w kodzie który napisałem nie dostaje oczekiwanych efektów.
Silniki zachowują się w następujący sposób:
1. Gdy czujniki nie wykrywają lini silniki dostają maksymalne obroty
2. Gdy wykryta jest linia na którymkolwiek czujniku obroty są identyczne, chociaż w kodzie wypełnienie się różni dla kolejnych par lub pojedynczych czujników.

Niestety nie mogę znaleźć gdzie leży błąd, dlatego też poprosił bym o pomoc z waszej strony.
Kod wygląda następująco:
Kod programu: Zaznacz cały
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define MOTOR_LEWY_PRZOD PORTD   // |= (1<<PD2)
#define MOTOR_PRAWY_PRZOD PORTD  // |= (1<<PD7)
#define MOTOR_LEWY_TYL PORTD     // |= (1<<PD3)
#define MOTOR_PRAWY_TYL PORTB    // |= (1<<PB0)
#define MOTOR_LEWY_PWM OCR1B    //PB2
#define MOTOR_PRAWY_PWM OCR1A    //PB1

void PWM(int LEWY, int PRAWY)
{
    if(LEWY>=0)
    {
        if (LEWY>255)
        LEWY=255;
        MOTOR_LEWY_PRZOD |= (1<<PD2);
        MOTOR_LEWY_TYL  |= (0<<PD3);
    }
    if (PRAWY>=0)                            //PRZÓD
    {
        if (PRAWY>255)
        PRAWY=255;
        MOTOR_PRAWY_PRZOD |= (1<<PD7);
        MOTOR_PRAWY_TYL |= (0<<PB0);
    }
   
    if(LEWY<0)
    {
        if (LEWY<-255)
        LEWY=-255;
        MOTOR_LEWY_PRZOD |= (0<<PD2);
        MOTOR_LEWY_TYL  |= (1<<PD3);
    }
    if (PRAWY<0)                                    //TYŁ
    {
        if (PRAWY<-255)
        PRAWY=-255;
        MOTOR_PRAWY_PRZOD |= (0<<PD7);
        MOTOR_PRAWY_TYL |= (1<<PB0);
    }
    MOTOR_LEWY_PWM = abs(LEWY);
    MOTOR_PRAWY_PWM = abs(PRAWY);
}

int czujniki[6]={0,0,0,0,0,0};
void odczyt_adc()
{
    for(int i=0; i<6; i++)
    {
       
        ADMUX &= 0b11100000;        //zerowanie bitów mux
        ADMUX |= i;                //tab_czujnikow[i];        //wybór kanału przetwornika
        ADCSRA |= (1<<ADSC);        //uruchomienie pomiaru
        while (ADCSRA & (ADSC==1)) {};    //oczekiwanie na zakonczenie pomiaru
       
        if(ADCH>200)                //porownanie wyniku
        {czujniki[i]=1;}            //wpisanie wyniku do tablicy
        else
        {czujniki[i]=0;}           
    }
}

int main(void)
{
    //------------------------------------- ADC oraz kierunki pinów dla ADC ---------------------------------------
    ADMUX  |= (0<<REFS0) | (0<<REFS1);    //AREF, Internal Vref turned off
    ADMUX  |= (1<<ADLAR);                //wyrównanie do lewej, 8 bitowy wynik konwersji
    ADCSRA |= (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2); //uruchomienie adc, prescaler 128 = 128khz
    PORTC  |= (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5);
    DDRC   |= (0<<PC0) | (0<<PC1) | (0<<PC2) | (0<<PC3) | (0<<PC4) | (0<<PC5);
    PINC   |= (1<<PC0) | (1<<PC1) | (1<<PC2) | (1<<PC3) | (1<<PC4) | (1<<PC5);

    //--------------------- TIMER1 DLA PWM LEWY/PRAWY oraz kierunki pinów sterowania silnikami --------------------
    TCCR1A |= (1<<COM1A1) | (1<<COM1B1) | (1<<WGM10);        //Set OC0A on Compare Match, clear OC0A at BOTTOM (inverting mode),  fast pwm 8-bit counter
    TCCR1B |= (1<<WGM12) | (1<<CS11);                                    //fast pwm 8 bit counter, prescaler = 8
    DDRB   |= (1<<PB0) | (1<<PB1) | (1<<PB2);        //USTAWIENIE PB0/1/2 JAKO WYJSCIA (kierynek prawy/pwm lewy/pwm prawy)
    DDRD   |= (1<<PD2) | (1<<PD3) | (1<<PD7);        //USTAWIENIE PD2/3/7 JAKO WYJSCIA (kierunek lewy/kierunek lewy/kierunek prawy)

    while (1)
    {
        odczyt_adc();
        if (czujniki[0]==1 && czujniki[1]==0)        //tylko 0
        {
            PWM(100,0);
        }
        if (czujniki[0]==1 && czujniki[1]==1)        //0 i 1
        {
            PWM(150,0);
        }
        if (czujniki[0]==0 && czujniki[1]==1 && czujniki[2]==0)    //tylko 1
        {
            PWM(175,0);
        }
        if (czujniki[1]==1 && czujniki[2]==1)        //1 i 2
        {
            PWM(200,0);
        }
        if (czujniki[1]==0 && czujniki[2]==1 && czujniki[3]==0)    //tylko 2
        {
            PWM(225,0);
        }
        if (czujniki[2]==1 && czujniki[3]==1)    //2 i 3
        {
            PWM(250,250);
        }
        if (czujniki[2]==0 && czujniki[3]==1 && czujniki[4]==0)    //tylko 3
        {
            PWM(0,225);
        }
        if (czujniki[3]==1 && czujniki[4]==1)    //3 i 4
        {
            PWM(0,200);
        }
        if (czujniki[3]==0 && czujniki[4]==1 && czujniki[5]==0)    //tylko 4
        {
            PWM(0,175);
        }
        if (czujniki[4]==1 && czujniki[5]==1)    //4 i 5
        {
            PWM(0,150);
        }
        if (czujniki[5]==1 && czujniki[4]==0)    //tylko 5
        {
            PWM(0,100);
        }
       
    }

}



Z góry dziękuję za udzieloną pomoc.

EDIT: Do odmierzania czasu używam zewnętrznego kwarcu 16mhz.
Ustawienie fuse bitów:
-U lfuse:w:0xf7:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m
Czyli:
Full swing crystal, 16K CK, 14CK +65 ms [CKSEL = 0111, SUT = 111]

EDIT2: w symulatorze zauważyłem, że nie zmieniają mi się kanały na ADC

Polecany artykuł » Usuwalny atrament do fotopolimerowego druku 3D


Ostatnio zmieniony przez sidek92 06-11-2017, 12:06, w całości zmieniany 2 razy  
Postaw piwo autorowi tego posta
 
 
Wojciech 



Posty: 115
Pomógł: 14 razy
Otrzymał 12 piw(a)
Programuję w:
C/C++
Wysłany: 14-11-2017, 16:22   

"oczekiwanie na zakonczenie pomiaru" masz źle napisane
Kod programu: Zaznacz cały
while (ADCSRA & (ADSC==1)) {};

jest wogóle pomijane bo ADSC = 6, więc (6==1) daje 0, dalej x & 0 zawsze da 0 - brak oczekiwania.

Postaw piwo autorowi tego posta
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Wersja do druku

Skocz do:  

Nie rozwiązałeś swojego problemu? Zobacz podobne tematy: Generowanie przebieg... Jaki język programow... Kombinowanie z przer... Czym programujecie u...
lub przeszukaj forum po wybranych tagach: adc, odczytow, silnikow, wedlug, wysterowanie


Powered by phpBB modified by Przemo © 2003 phpBB Group
Popularne kursy: Arduinopodstawy elektroniki