logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Zestaw Qfix Minibot z atmegą

lesterasalas 21 Lut 2010 10:57 1173 2
REKLAMA
  • #1 7727270
    lesterasalas
    Poziom 10  
    Witajcie,

    Jestem początkujący w dziedzinie mikrokontrolerów (zawodowo zajmuje się systemami erp oraz programowaniem) więc z góry dziękuję za wyrozumiałość doświadczonych forumowiczów.
    Podobny post umieściłem w dziale robotyka modelarstwo, tak więc proszę nie banujcie mnie za ponowne wpisy tutaj - być może ktoś kto mógłby mi pomóc po prostu tam nie zagląda.
    Do rzeczy.
    Stałem się posiadaczem zestawu firmy Qfix - Minibot - jest to bardzo prosta kombinacja atmegi, płytki, kilku części montażowych, silników etc.
    Generalnie wszystko gra, udaje mi się zaprogramować działanie przycisków, diod, obsługę silników, czujników dotyku na portach cyfrowych etc.
    Wykorzystuje oprogramowanie dostarczone przez qfixa, czyli programmers notepad i ich biblioteki c.

    Problem pojawia się gdy usiłuje odczytać jakiekolwiek informacje z wejść analogowych. Zarówno dla czujnika podłoża jak i odległości (sharp 2D120X) zwracana wartości (z metody board.analog(n)) cały czas ma maksymalną wartość 255. Wg producenta wartości zwracana dzięki niej to przedział 0-255.

    Definicja w klasie minoboard wygląda tak:

    MiniBoard::MiniBoard()
    {
    // PORT A: Analog In (PA0-PA3) + buttons (PA4+PA5)//
    DDRA=0; // all bits input
    PORTA=16+32; // set pullups for buttons (PA4+PA5)
    ADCSRA=128; // set A/D enable bit (ADEN)

    // PORT B: Power Output //
    DDRB = 255; // all bits output
    PORTB = 0; // clear all bits -> power on

    // PORT C: LEDs (PC6+PC7), I2C (PC0+PC1) and motors //
    DDRC = 255-1-2; // direction port C, all bits output except I2C
    PORTC = 1+2; // clear bits 2-5 -> motors off; set bits 0,1 -> I2C pullUps
    PORTC |= 64+128; // set bits 6 and 7 -> LEDs off

    // PORT D: USB (PD0,PD1), digital Input (PD2,PD3,PD6,PD7), motor PWM (PD4,PD5) //
    DDRD = 16+32; // PWM pins output
    PORTD |= 4+8+64+128; // set pullups for digital inputs

    initTimer();
    }

    POtem tworzymy obiekt i wywołujemy metody. Aby odczytać pomiar składnia może wyglądać tak:

    int odczyt = board.analog(0);

    Definicja samej metody poniżej.

    // return 0-255 //
    int MiniBoard::analog(int i)
    {
    if ((i<0) || (i>3)) return -1;

    ADMUX=i; // select analog input and start A/D
    sbi(ADMUX, ADLAR); // left adjust -> we use only ADCH
    sbi(ADCSRA, ADSC); // start conversion
    while (ADCSRA & 64); // wait until ADSC is low again
    int value = ADCH; // read 8 bit value fom ADCH
    return value;
    }

    Niestety nie mam osprzętu elektronicznego aby cokolwiek zmierzyć.
    Jeśli ktoś jest posiadaczem takiego zestawu bardzo proszę o kontakt, może uda mi się ruszyć do przodu.
    Jeśli ktoś miał podobny problem i udało mu się go jakoś rozwiązać także bardzo proszę o kontakt.
    Jestem z Poznania więc jeśli ktokolwiek chciałby mi pomóc będę wdzięczny.
    Może powinienem reklamować zestaw. Wolałbym jednak wcześniej sprawdzić inne opcje.

    Pozdrawiam
    Alek
  • REKLAMA
  • Pomocny post
    #2 7736388
    baxter007
    Poziom 11  
    Witam,
    Nigdy nie miałem do czynienia z tym robotem, ale rozumiem że skoro w ADMUX wpisywane jest tylko wejście oraz zapis wartości od lewej to zakłada się ze Vref jest wyłączone. Spróbuj ustawić na sztywno wejście w ADMUX = 0 i tylko z niego tymczasem korzystaj czyli wpisz w ADMUX tylko 1 do ADLAR bez instrukcji if.


    
    // return 0-255 //
    int MiniBoard::analog(int i)
    {
    ADMUX = (1<<ADLAR);		// left adjust -> we use only ADCH
    ADCSRA |= _BV(ADSC);		// start conversion
    while ( !(ADCSRA & (1<<ADSC)) );// wait until ADSC is low again
    int value = ADCH;		// read 8 bit value fom ADCH
    return(value);
    }
    
  • #3 7746908
    lesterasalas
    Poziom 10  
    Cześć,

    Dziękuje za pomoc!
    Faktycznie podziękowałem bibliotekom firmowym, i skrobnąłem własne aby mieć pewność co jest ustawione w rejestrach. Tak to wyszło:

    void ustaw_rejestr(void)
    {
    ADMUX |= _BV(REFS0); //ustawiamy źródło dla odniesienia na wewnętrzne
    ADMUX |= _BV(REFS1);
    ADMUX |= _BV(ADLAR); //zapis wyniku do lewej
    ADCSRA |= _BV(ADEN); //pozwolenie na start konwersji
    ADCSRA |= _BV(ADPS0);//dostosowanie częstotliwości dla taktowania przetwornika
    ADCSRA |= _BV(ADPS1);
    };

    Funkcja do odczytu wygląda teraz tak:

    int analog(int i)
    {
    ADCSRA |= _BV(ADSC);//początek konwersji
    while(bit_is_set(ADCSRA,ADSC))
    {}; //czekamy do zakończenia
    int value = ADCH;//odczyt ADCH
    return(value);
    }

    No i wszystko gra.

    Dziękuję za pomoc. Gdyby ktoś miał podobny problem z tym zestawem, to może się przyda.

    Pozdrawiam
    Alek
REKLAMA