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

Jakie czujniki do linefollowera? Pomoc w wyborze

Autor Wiadomość
kamdz 



Posty: 64
Wysłany: 05-10-2017, 10:33   

No to tak: kod do adc jest tu

Wieczorkiem pokombinuję z tym czujniczkiem, sprawdze połączenia, czy coś gdzieś nie zwiera i te kilka testów od Marka. Jak coś to mam 1 czujnik w zapasie :)
Multimetrem też sprawdzałem, nie pamiętam wartości, ale nie działał tak jak powinien.
Schemat chyba nie ma tu znaczenia, skoro jest taki sam dla wszystkich czujek, a reszta działa dobrze.

Popularny artykuł » Kurs Arduino - #11 - podsumowanie, QUIZ


Ostatnio zmieniony przez kamdz 05-10-2017, 10:39, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 05-10-2017, 11:35   

Przy pytaniach o (dziwne lub nie-) działanie sprzętu schemat ma zawsze znaczenie, bo przecież nie wiemy co tam ostatecznie zmajstrowałeś. Jeśli możesz zastawić własną rękę za to, że wszystko jest OK a problem leży w sofcie, to napisz: wszystko sprawdziłem pięć razy, wykonałem fafnaście taki a takich testów, pomierzyłem co trzeba i sprzęt jest cacy. Jeśli nie wiesz co się dzieje, nie wiesz co i gdzie zmierzyć a prosisz o pomoc, schemat jest nieodłączną częścią pytania. Tylko na jego podstawie możemy snuć domysły i wymyślać kolejne testy.
To nie zawsze musi być pełny rysunek, bo jeśli wcześniej już coś zapodawałeś, to wystarczy wspomnieć co zrealizowałeś i na czym pracujesz: jest to (np.) wersja z dwoma multiplekserami i wspólnym opornikiem w kolektorze.
Inaczej dobrzy ludzie - wyobrażając sobie błędnie co tam masz na biurku - będą poświęcać swój czas na wymyślanie zupełnie nietrafionych podpowiedzi. Oszczędź im tego.

BTW: Żeby obejrzeć Twój kod trzeba się gdzieś zalogować i skorzystać z innego Forum. Nie mogłeś tego wrzucić tutaj? Rozumiem, że obsługa ADC wciąż nie działa. Jeśli tak, pochyl się nad bitami ADCSRA. Napisz w punktach jak powinien wg Ciebie wyglądać algorytm współpracy z tym ADC, od startu konwersji do odczytu wyniku i przygotowania na następny start. Bez kodu, tylko opis które bity/kasujesz ustawiasz i dlaczego.

Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 05-10-2017, 11:48   

Schemat taki jak wcześniej, tak jak piszesz. Ale skoro tylko 1 czujnik nie działa, to chyba układ jest dobry, albo coś zwarłem lutując, albo czujka uszkodzona, jak będę w domu to posprawdzam :) teraz jem kanapkę w szkole :mrgreen:

Nie wiedziałem, że się da nie mieć konta na elektrodzie ;)
Proszę kod

Kod programu: Zaznacz cały

 #include <stdlib.h>
 

 

#include <avr/io.h>
#include <util/delay.h>

//void setAngle(int angle);
//void InitServ(void);

#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdint.h>
    #define USART_BAUD 9600UL
    #define USART_UBBR_VALUE ((8000000UL/(USART_BAUD<<4))-1)

/*UART*/
void USART_Init(unsigned int ubrr) ;
void USART_Transmit(char data ) ;
unsigned char USART_Receive( void ) ;
int getADC(int number);
void USART_TransmitString (char *str) ;
int adc;
char adc1 [4];
int main(void)
{
 ADMUX |= (0<<REFS0)|(0<<REFS1); //porównuje z AREF
        //0 tylko dla zasyganlizowania ze jest tam zero bo to nic nie zmienia
        ADCSRA |= (1<<ADEN)
        |(1<<ADPS0) 
   |(1<<ADPS1) 
   |(1<<ADPS2); 
  //    unsigned char d[] = {"xyz"};
  unsigned char odb;
    USART_Init(USART_UBBR_VALUE);
    //InitServ();
    //int i;
    while(1) {

        //USART_TransmitString(d);
        odb = USART_Receive();
        if(odb =='0'){
adc = getADC(0);
 itoa(adc,adc1,10);
USART_TransmitString(adc1);
        }
//_delay_ms(1000);
       

    }

}




void USART_Init (unsigned int ubrr)
{
UBRRH = (unsigned char)((USART_UBBR_VALUE>>8) | _BV(URSEL));
    // Set baud rate
        UBRRH = (unsigned char)(USART_UBBR_VALUE>>8);
        UBRRL = (unsigned char)USART_UBBR_VALUE;

    // Enable receiver and transmitter
        UCSRB = (1<<RXEN)|(1<<TXEN);

    // Set frame format to 8 data bits, no parity, 1 stop bit
        UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);


}

void USART_Transmit(char data )
{

    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ) ;
    /* Put data into buffer, sends the data */
    UDR = data;
}

void USART_TransmitString (char *str)
{
    int i = 0;
    for (i=0; str[i]!='\0'; i++) {
        USART_Transmit(str[i]);
        //_delay_ms(50);
    }
}


unsigned char USART_Receive(void)
{
// Wait until a byte has been received

    while((UCSRA&(1<<RXC)) == 0);

// Return received data

    return UDR;

}

int getADC(int number)
//number należy do <0, 7>, kod nie sprawdza szkoda pamięci FLASH
{
        ADMUX &= 0xf0; //zerowanie 4 młodszych bitów
        ADMUX |= number; //ustawianie numeru kanału

        ADCSRA |= 1<<ADSC; //zaczyna konwersję
        while(ADCSRA & (1 << ADIF));    //dopuki bit ADIF nie jest ustawiony nie jest gotowa kowersja
        ADCSRA &= ~((1 << ADSC) | (1 << ADIF)); //zeruj flage konwersji i rozkaz rozpoczecia
        return ADCW;
}


Adc mi działa, kod za radą Trekera daję dla potomnych :)
A co do trybu adc free run, będę się dość mocno wzorował na tym więc wykorzystam tryb adc który tam jest użyty, czylichyba pojedyńczą konwersję:)

[ Dodano: 05-10-2017, 19:34 ]
Po pokazaniu czujnikom tej samej lampki wszystkie schodzą do ok 40, ten zostaje na 300 nie widzęna nim żadnych rysek, spróbuję poprawić luty, a jak nie pomoże to go podmienię na zapsowy.

[ Dodano: 05-10-2017, 21:24 ]
Po przelutowaniu działa. Co prawda nie wiem, czemu jedne czujki schodzą do 40, a inne do 200, no ale 200 to nie 700, od 1000 powinno się ładnie odzielać :)
No to cóż, hardware mam, to muszę się brać za softa. Także zapraszam do tematu wszystkich znających C, bo napewno będę miał dużo pytań :)

Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 09-10-2017, 00:07   

Witam ponownie. Zrobiłem już program testujący te multieksery: na uarta wysyła mi dane z wszystkich 8 czujników po kolei. Jednak coś tu nie działa dobrze. Nie wiem co ja mam z tymi czujkami, ale chyba ciąży na mnie fatum linefollowerów ;) nie mogę ich jakoś zmusić do poprawnej stabilnej pracy. Jak testowałem każde z osobna to jeszcze jakoś działały, po podłączeniu do muxa to z 5 dostaję wyniki 1023 a z 3 kolejnych coś koło 300(na białej kartce).
Schemat jak wcześniej, rezystor do diody 220 omów a do kolektora 10k. Testowane z kondensatorem do masy i bez. Nie mam już pojęcia co tu się dzieje, tak jakbym dostał jakąś felerną partię czujek. Jest jeszcze jakiś parametr, albo coś o czym mogłem zapomnieć? Proszę o pomoc zwłaszcza tych, którzy mieli doczynienia z tymi czujnikami, ale jak ktoś ma jakiś pomysł to walić śmiało, może coś wymyślimy...
Z góry dziękiza wszelkie propozycje.

Ostatnio popularny » Wytrzymałość materiałów - #2 - Symulacja w CAD


Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 09-10-2017, 00:40   

Pokaż ten program. Jeśli każdy czujnik z osobna działa OK, to w zestawie też tak powinno być. Podczas przełączania kanałów trzeba zachować pewną kolejność i reżim czasowy, bo wyniki będą od czapy. Spróbuj tak:
1. Przełączasz kanał.
2. Czekasz np. 10ms.
3. Mierzysz i wynik zapamiętujesz w tablicy.
4. Powtarzasz powyższe aż zassiesz wszystkie czujniki.
5. Dopiero teraz wypisujesz wyniki.

Pytania:

1. Czy sprawdzałeś (np. aparatem foto) że wszystkie diodki w czujnikach świecą? Zrób test i zapalaj każdą po kolei np. na min. sekundę i tak w kółko.

2. Czy jest szansa, że pomyliłeś numery wyjść multipleksera do diodek lub wejść multipleksera tranzystorów? Bo jeśli zapalasz diodkę w jednym a mierzysz drugi, to pomiar wyjdzie 1023, bo temu mierzonemu jest ciemno.

Jeżeli po przelutowaniu coś się poprawiło, to możesz mieć nadal kłopoty z poprawnym montażem - wcale nie znaczy, że pozbyłeś się wszystkich błędów. Bardzo grzałeś te czujniki? Jak to wygląda? Możesz dać dobre zdjęcie całej listwy?

Nie powinno być aż 4-krotnych różnic w prądzie tranzystorów. Zatrzymaj się przy tym i wniknij w to. To nie fatum tylko pośpiech i/lub złe lutowania, w tym być może już przegrzane elementy.

EDIT: Ech, piszę głupoty po ciemku. Przecież zmiana wyniku ADC z 200 na 50 to zmiana napięcia na oporniku kolektorowym z 4V na 4.9V co jest spowodowane zmianą prądu tranzystora o 20%. To jest zupełnie akceptowalne., Inna sprawa, że wynik 50 jest o wiele za mały. Wyrażając to w napięciu (względem zasilania i referencji ADC = 5V) masz na wejściu tylko 240mV czyli tranzystor właśnie zaczyna się nasycać i czujnik przestaje działać liniowo. Zmniejsz opornik kolektorowy lub zwiększ opornik diodek tak by dostawać na białej kartce wyniki w granicach 200-300, bo obecnie czułość jest za duża. No i prześledź te niedziałające. Aparat lub kamerka, multimetr i do roboty. To nie ma prawa niedziałać.

Acha, pomiary lampki to zły pomysł. Światło ze źródeł sztucznych zasilanych z sieci bardzo mocno kołysze się z częstotliwością 100Hz. Sam pomiar ADC jest krótki, więc w zależności od tego kiedy wypadnie w okresie sieci AC taki wynik możesz dostać. Wygląda to, jakby czujniki były niestabilne a to tylko drgania jasności zbyt szybkie dla naszego oka. Spróbuj z oknem za dnia. Wyniki kolejnych pomiarów tego samego czujnika nie powinny różnić się więcej jak o 10 jednostek ADC.

Ostatnio zmieniony przez marek1707 09-10-2017, 09:07, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 09-10-2017, 09:12   

Będę dodawał wszystko stopniowo.
Kod programu: Zaznacz cały
#include <stdlib.h>




#include <avr/io.h>
#include <util/delay.h>

//void setAngle(int angle);
//void InitServ(void);

#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdint.h>
    #define USART_BAUD 9600UL
    #define USART_UBBR_VALUE ((8000000UL/(USART_BAUD<<4))-1)

/*UART*/
void USART_Init(unsigned int ubrr) ;
void USART_Transmit(char data ) ;
unsigned char USART_Receive( void ) ;
int getADC(int number);
void USART_TransmitString (char *str) ;
void ustawmux (int liczba) ;
int adc;
char adc1 [4];
int main(void)
{
    DDRD = 11100000;

 ADMUX |= (0<<REFS0)|(0<<REFS1); //porównuje z AREF
        //0 tylko dla zasyganlizowania ze jest tam zero bo to nic nie zmienia
        ADCSRA |= (1<<ADEN)
        |(1<<ADPS0)
   |(1<<ADPS1)
   |(1<<ADPS2);
  //    unsigned char d[] = {"xyz"};
  unsigned char odb;
    USART_Init(USART_UBBR_VALUE);
    //InitServ();
    //int i;
    while(1) {

        //USART_TransmitString(d);
        odb = USART_Receive();
        if(odb =='0'){
            adc = getADC(0);
            itoa(adc,adc1,10);
for(int ster=0; ster<9; ster++){
ustawmux(ster);
adc = getADC(0);
 itoa(adc,adc1,10);
USART_TransmitString(adc1);
USART_TransmitString("\n");
_delay_ms(2000);
}}
//_delay_ms(1000);


    }

}




void USART_Init (unsigned int ubrr)
{
UBRRH = (unsigned char)((USART_UBBR_VALUE>>8) | _BV(URSEL));
    // Set baud rate
        UBRRH = (unsigned char)(USART_UBBR_VALUE>>8);
        UBRRL = (unsigned char)USART_UBBR_VALUE;

    // Enable receiver and transmitter
        UCSRB = (1<<RXEN)|(1<<TXEN);

    // Set frame format to 8 data bits, no parity, 1 stop bit
        UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);


}

void USART_Transmit(char data )
{

    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ) ;
    /* Put data into buffer, sends the data */
    UDR = data;
}

void USART_TransmitString (char *str)
{
    int i = 0;
    for (i=0; str[i]!='\0'; i++) {
        USART_Transmit(str[i]);
        //_delay_ms(50);
    }
}


unsigned char USART_Receive(void)
{
// Wait until a byte has been received

    while((UCSRA&(1<<RXC)) == 0);

// Return received data

    return UDR;

}

int getADC(int number)
//number należy do <0, 7>, kod nie sprawdza szkoda pamięci FLASH
{
        ADMUX &= 0xf0; //zerowanie 4 młodszych bitów
        ADMUX |= number; //ustawianie numeru kanału

        ADCSRA |= 1<<ADSC; //zaczyna konwersję
        while(ADCSRA & (1 << ADIF));    //dopuki bit ADIF nie jest ustawiony nie jest gotowa kowersja
        ADCSRA &= ~((1 << ADSC) | (1 << ADIF)); //zeruj flage konwersji i rozkaz rozpoczecia
        return ADCW;
}
void ustawmux (int liczba)
{
switch (liczba){
case 0:
PORTD=00000000;
break;
case 1:
PORTD=00100000;
break;
case 2:
PORTD=01000000;
break;
case 3:
PORTD=01100000;
break;
case 4:
PORTD=10000000;
break;
case 5:
PORTD=10100000;
break;
case 6:
PORTD=11000000;
break;
case 7:
PORTD=11100000;
break;

}

}

1.....
2. Raczej nie, sprawdzałem to kilka razy..
Grzałem je króciutko, mam oprową lutownice, rozgrzałem ją, i dosłownie w sekundę lutowałem jedną nóżkę.

A tak czytałem gdzieś, że ma być 220omów i 10k...


20171009_090613.zip
Pobierz Plik ściągnięto 7 raz(y) 25.8 MB

Ostatnio zmieniony przez kamdz 09-10-2017, 09:21, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 09-10-2017, 10:21   

Co się stanie, gdy funkcję ustawmux() wywołasz z argumentem 8? A tak robisz pod koniec pętli.

Skan czujników musi wyglądać tak:
1. Ustawienie kanału mux-a
2. Odczekanie krótkiego czasu, np. wywołanie funkcji delay_us(100). Multiplekser musi podać wybrane napięcie do ADC a ono musi się ustalić na linii ADC0 przed pomiarem
3. Wykonanie konwersji czyli Twoje getADC()
4. Zapamiętanie odczytu
5. Wypisanie wyników dopiero po odczytaniu wszystkich 8 (a nie 9 jak teraz) czujników

To ostatnie jest ważne, bo wypisywaniem zaburzasz wykonywanie skanu. Serial.print() nie jest bezkarne i kosztuje czas a w docelowym programie nie będziesz przecież wypisywał wyników w trakcie każdego skanu czujników. Pisz funkcje tak by były podobne do tych ostatecznych. Ew. printy kontrolne wstawiaj tam, gdzie najmniej zmieniają przebieg programu. Od razu stwórz funkcję np:
Kod programu: Zaznacz cały

void skan(uint16_t* wyniki, uint8_t dlugosc)
{
   for (uint8_t kanal=0; kanal<dlugosc; kanal++)
   {
      ustawmux(kanal);
      delay_us(100);
      wyniki[kanal] = getADC(0);
   }
}
i wołaj ją wskazując tablicę gdzie oczekujesz wyników:
Kod programu: Zaznacz cały
#define CZUJNIKI 8
uint16_t wynikiADC[CZUJNIKI];

skan(wynikiADC, CZUJNIKI);
a teraz możesz już sobie w pętli zawartość tablicy wynikiADC na spokojnie wypisać;

Nie musisz używać znakowego (signed) typu int do liczenia w zakresie 0-255, chodzi mi o zmienną ster. Zamiast męczenia procesora arytmetyką 16-bitową używaj krótszego i szybszego uint8_t. Tu przynajmniej widzisz jakiej długości jest zmienna (a wpisując uint16_t od razu byś zajarzył, że 16 bitów nie jest tu potrzebne).

Jeśli sterowanie muxem masz na 3 najstarszych bitach portu D i nie pozamieniałeś linii adresowych, to ustawmux() możesz napisać w jednej prostej linijce. Po co taki switch, który każdy czytający Twój kod musi przejrzeć żeby upewnić, się, ze nie robisz niczego ciekawego?
Kod programu: Zaznacz cały
PORTD = (PORTD & 0b00011111) | ((liczba & 0b111) << 5);

Szukaj wzorców. Tu wystarczy przesunąć trzy najmłodsze bity liczby o 5 pozycji w lewo i wstawić to do portu D, któremu obecne wartości tych bitów zerujesz. Jeśli masz problemy z takimi operacjami, narysuj to sobie na kartce.

Co to znaczy "....."? Oglądałeś świecenie diodek w podczerwieni, czy nie?

Dobrze, że czytasz, ale masz też swój rozum i to on (plus zasady fizyki) ma Ci dyktować co robisz. Jeśli Twój czujnik jest ewidentnie przesterowany, to jaki sens ma trzymanie się ogólnych zasad z internetu?

Ostatnio zmieniony przez marek1707 09-10-2017, 10:24, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 09-10-2017, 10:31   

Ok kody wypróbuję po szkole, bo zaraz idę (czyli koło 19)
.... znaczyło, że jestem w trakcie testu. Testowałem manualnie, bez muxów i wszystkie diody ładnie świecą.

Też myślałem, nad takim kodem jak ten Twój ostatni, ale jestem jeszcze za mało doświadczony w C żeby zrobić coś takiego. Chyba muszę zainwestować w jakąś książkę o C dla AVR (Mógłbyś jakąś polecić? oczywiście w privie, żeby reklamy nie robić ;) )

Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 09-10-2017, 11:20   

No ale masz testować układ który zbudowałeś, a nie same elementy składowe. W przypadku gdy skaszaniłeś montaż (na jakimkolwiek etapie), "manualny" test całej partii czujników wykazał 100% poprawności, a końcowy układ nie działa. Obejrzyj aparatem jak mux, komutowany np. co sekundę przemiata kolejne diodki. testy mają dowodzić poprawności poprzednich etapów projektu lub prowadzić do znajdowania błędów. Nie zakładaj, że coś zrobiłeś dobrze i tego nie trzeba sprawdzać, bo następnych testach zaczynasz mieć za dużo niewiadomych.

A na razie skup się na lekcjach :) To też ważne. Gdzie się uczysz i czego?

Ostatnio zmieniony przez marek1707 09-10-2017, 11:21, w całości zmieniany 1 raz  
Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 09-10-2017, 11:22   

Oczywiście, wiem, że muszę o zrobić, ale tak jak mówiłem, wieczorkiem :)

[ Dodano: 09-10-2017, 18:56 ]
Coś chyba zepsułem, przy podmianie funkcji na Twoje, bo dostaję 2 pytajniki, 3 apostrofy i 3 pytajniku na terminalu :D

Kod programu: Zaznacz cały
  #include <stdlib.h>




#include <avr/io.h>
#include <util/delay.h>

//void setAngle(int angle);
//void InitServ(void);

#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdint.h>
    #define USART_BAUD 9600UL
    #define USART_UBBR_VALUE ((8000000UL/(USART_BAUD<<4))-1)

/*UART*/
void skan(uint16_t* wyniki, uint8_t dlugosc);
void USART_Init(unsigned int ubrr) ;
void USART_Transmit(char data ) ;
unsigned char USART_Receive( void ) ;
int getADC(int number);
void USART_TransmitString (char *str) ;
void ustawmux (int liczba) ;
int adc;
char adc1 [4];
#define CZUJNIKI 8
uint16_t wynikiADC[CZUJNIKI];
int main(void)
{
    DDRD = 11100000;

 ADMUX |= (0<<REFS0)|(0<<REFS1); //porównuje z AREF
        //0 tylko dla zasyganlizowania ze jest tam zero bo to nic nie zmienia
        ADCSRA |= (1<<ADEN)
        |(1<<ADPS0)
   |(1<<ADPS1)
   |(1<<ADPS2);
  //    unsigned char d[] = {"xyz"};
  unsigned char odb;
    USART_Init(USART_UBBR_VALUE);
    //InitServ();
    //int i;
    while(1) {
        odb = USART_Receive();
                if(odb =='0'){
        skan(wynikiADC, CZUJNIKI);
        USART_TransmitString (wynikiADC);


    }
    }
//_delay_ms(1000);


    }






void USART_Init (unsigned int ubrr)
{
UBRRH = (unsigned char)((USART_UBBR_VALUE>>8) | _BV(URSEL));
    // Set baud rate
        UBRRH = (unsigned char)(USART_UBBR_VALUE>>8);
        UBRRL = (unsigned char)USART_UBBR_VALUE;

    // Enable receiver and transmitter
        UCSRB = (1<<RXEN)|(1<<TXEN);

    // Set frame format to 8 data bits, no parity, 1 stop bit
        UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);


}

void USART_Transmit(char data )
{

    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ) ;
    /* Put data into buffer, sends the data */
    UDR = data;
}

void USART_TransmitString (char *str)
{
    int i = 0;
    for (i=0; str[i]!='\0'; i++) {
        USART_Transmit(str[i]);
        //_delay_ms(50);
    }
}


unsigned char USART_Receive(void)
{
// Wait until a byte has been received

    while((UCSRA&(1<<RXC)) == 0);

// Return received data

    return UDR;

}

int getADC(int number)
//number należy do <0, 7>, kod nie sprawdza szkoda pamięci FLASH
{
        ADMUX &= 0xf0; //zerowanie 4 młodszych bitów
        ADMUX |= number; //ustawianie numeru kanału

        ADCSRA |= 1<<ADSC; //zaczyna konwersję
        while(ADCSRA & (1 << ADIF));    //dopuki bit ADIF nie jest ustawiony nie jest gotowa kowersja
        ADCSRA &= ~((1 << ADSC) | (1 << ADIF)); //zeruj flage konwersji i rozkaz rozpoczecia
        return ADCW;
}

void ustawmux (int liczba)
{
    PORTD = (PORTD & 0b00011111) | ((liczba & 0b111) << 5);
}

void skan(uint16_t* wyniki, uint8_t dlugosc)
{
   for (uint8_t kanal=0; kanal<dlugosc; kanal++)
   {
      ustawmux(kanal);
      _delay_us(100);
      wyniki[kanal] = getADC(0);
   }
}


[ Dodano: 09-10-2017, 19:34 ]
A, teraz zauważyłem pytanie czego się uczę...
Te, no
Jestem w 3 gimbie więc wszystkiego :)
W Krakowie jak coś ;)

[ Dodano: 09-10-2017, 19:38 ]
A ok, zapomniałem dać konwersji na chara.
Kod programu: Zaznacz cały
  #include <stdlib.h>




#include <avr/io.h>
#include <util/delay.h>

//void setAngle(int angle);
//void InitServ(void);

#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdint.h>
    #define USART_BAUD 9600UL
    #define USART_UBBR_VALUE ((8000000UL/(USART_BAUD<<4))-1)

/*UART*/
void skan(uint16_t* wyniki, uint8_t dlugosc);
void USART_Init(unsigned int ubrr) ;
void USART_Transmit(char data ) ;
unsigned char USART_Receive( void ) ;
int getADC(int number);
void USART_TransmitString (char *str) ;
void ustawmux (int liczba) ;
int adc;
char adc1 [4];
#define CZUJNIKI 8
uint16_t wynikiADC[CZUJNIKI];
int main(void)
{
    DDRD = 11100000;

 ADMUX |= (0<<REFS0)|(0<<REFS1); //porównuje z AREF
        //0 tylko dla zasyganlizowania ze jest tam zero bo to nic nie zmienia
        ADCSRA |= (1<<ADEN)
        |(1<<ADPS0)
   |(1<<ADPS1)
   |(1<<ADPS2);
  //    unsigned char d[] = {"xyz"};
  unsigned char odb;
    USART_Init(USART_UBBR_VALUE);
    //InitServ();
    //int i;
    while(1) {
        odb = USART_Receive();
                if(odb =='0'){
        skan(wynikiADC, CZUJNIKI);
        itoa(wynikiADC,adc1,10);
        USART_TransmitString (adc1);


    }
    }
//_delay_ms(1000);


    }






void USART_Init (unsigned int ubrr)
{
UBRRH = (unsigned char)((USART_UBBR_VALUE>>8) | _BV(URSEL));
    // Set baud rate
        UBRRH = (unsigned char)(USART_UBBR_VALUE>>8);
        UBRRL = (unsigned char)USART_UBBR_VALUE;

    // Enable receiver and transmitter
        UCSRB = (1<<RXEN)|(1<<TXEN);

    // Set frame format to 8 data bits, no parity, 1 stop bit
        UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);


}

void USART_Transmit(char data )
{

    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ) ;
    /* Put data into buffer, sends the data */
    UDR = data;
}

void USART_TransmitString (char *str)
{
    int i = 0;
    for (i=0; str[i]!='\0'; i++) {
        USART_Transmit(str[i]);
        //_delay_ms(50);
    }
}


unsigned char USART_Receive(void)
{
// Wait until a byte has been received

    while((UCSRA&(1<<RXC)) == 0);

// Return received data

    return UDR;

}

int getADC(int number)
//number należy do <0, 7>, kod nie sprawdza szkoda pamięci FLASH
{
        ADMUX &= 0xf0; //zerowanie 4 młodszych bitów
        ADMUX |= number; //ustawianie numeru kanału

        ADCSRA |= 1<<ADSC; //zaczyna konwersję
        while(ADCSRA & (1 << ADIF));    //dopuki bit ADIF nie jest ustawiony nie jest gotowa kowersja
        ADCSRA &= ~((1 << ADSC) | (1 << ADIF)); //zeruj flage konwersji i rozkaz rozpoczecia
        return ADCW;
}

void ustawmux (int liczba)
{
    PORTD = (PORTD & 0b00011111) | ((liczba & 0b111) << 5);
}

void skan(uint16_t* wyniki, uint8_t dlugosc)
{
   for (uint8_t kanal=0; kanal<dlugosc; kanal++)
   {
      ustawmux(kanal);
      _delay_us(100);
      wyniki[kanal] = getADC(0);
   }
}


Teraz dostaję ciągle 96

Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 10-10-2017, 00:53   

Funkcji skan() świadomie przekazuję wskaźnik na tablicę zmiennych 16-bitowych, czyli adres elementu zerowego. A czego potrzebuje funkcja itoa, doczytałeś? Chyba wartości liczbowej a nie adresu w pamięci, prawda? Oj, chyba podręcznik do C bardzo by się przydał. Bierzesz się za pisanie w sumie nietrywialnego dzieła w języku, którego nie znasz. Sekwencję konwersji elementu tablicy na łańcuch i wypisanie przez UART musisz wykonać tyle razy ile masz czujników, za każdym razem dla kolejnego elementu. Szkoda czasu, nie rozumiejąc co robisz co chwila będziesz popełniał takie gafy. Proponuję: odpuść to na razie i poczytaj o C.

Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 10-10-2017, 18:45   

Kod programu: Zaznacz cały
  #include <stdlib.h>




#include <avr/io.h>
#include <util/delay.h>

//void setAngle(int angle);
//void InitServ(void);

#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdint.h>
    #define USART_BAUD 9600UL
    #define USART_UBBR_VALUE ((8000000UL/(USART_BAUD<<4))-1)

/*UART*/
void skan(uint16_t* wyniki, uint8_t dlugosc);
void USART_Init(unsigned int ubrr) ;
void USART_Transmit(char data ) ;
unsigned char USART_Receive( void ) ;
int getADC(int number);
void USART_TransmitString (char *str) ;
void ustawmux (int liczba) ;
int adc;
char adc1 [4];
#define CZUJNIKI 8
uint16_t wynikiADC[CZUJNIKI];
int main(void)
{
    DDRD = 0b11100000;

 ADMUX |= (0<<REFS0)|(0<<REFS1); //porównuje z AREF
        //0 tylko dla zasyganlizowania ze jest tam zero bo to nic nie zmienia
        ADCSRA |= (1<<ADEN)
        |(1<<ADPS0)
   |(1<<ADPS1)
   |(1<<ADPS2);
  //    unsigned char d[] = {"xyz"};
  unsigned char odb;
    USART_Init(USART_UBBR_VALUE);
    //InitServ();
    //int i;
    while(1) {
        odb = USART_Receive();
                if(odb =='0'){
        skan(wynikiADC, CZUJNIKI);

        for(int a=0; a<8; a++){
        itoa(wynikiADC[a],adc1,10);
        USART_TransmitString (adc1);
        USART_TransmitString ("\n");
        }
    }
    }
//_delay_ms(1000);


    }






void USART_Init (unsigned int ubrr)
{
UBRRH = (unsigned char)((USART_UBBR_VALUE>>8) | _BV(URSEL));
    // Set baud rate
        UBRRH = (unsigned char)(USART_UBBR_VALUE>>8);
        UBRRL = (unsigned char)USART_UBBR_VALUE;

    // Enable receiver and transmitter
        UCSRB = (1<<RXEN)|(1<<TXEN);

    // Set frame format to 8 data bits, no parity, 1 stop bit
        UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<URSEL);


}

void USART_Transmit(char data )
{

    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) ) ;
    /* Put data into buffer, sends the data */
    UDR = data;
}

void USART_TransmitString (char *str)
{
    int i = 0;
    for (i=0; str[i]!='\0'; i++) {
        USART_Transmit(str[i]);
        //_delay_ms(50);
    }
}


unsigned char USART_Receive(void)
{
// Wait until a byte has been received

    while((UCSRA&(1<<RXC)) == 0);

// Return received data

    return UDR;

}

int getADC(int number)
//number należy do <0, 7>, kod nie sprawdza szkoda pamięci FLASH
{
        ADMUX &= 0xf0; //zerowanie 4 młodszych bitów
        ADMUX |= number; //ustawianie numeru kanału

        ADCSRA |= 1<<ADSC; //zaczyna konwersję
        while(ADCSRA & (1 << ADIF));    //dopuki bit ADIF nie jest ustawiony nie jest gotowa kowersja
        ADCSRA &= ~((1 << ADSC) | (1 << ADIF)); //zeruj flage konwersji i rozkaz rozpoczecia
        return ADCW;
}

void ustawmux (int liczba)
{
    PORTD = (PORTD & 0b00011111) | ((liczba & 0b111) << 5);
}

void skan(uint16_t* wyniki, uint8_t dlugosc)
{
   for (uint8_t kanal=0; kanal<dlugosc; kanal++)
   {
      ustawmux(kanal);
      _delay_us(100);
      wyniki[kanal] = getADC(0);
   }
}


Nowy kod z poprawionym błędami. Chyba ;) Jestem na etapie wyboru książki.
Odpuściłbym sobie, ale to ma być projekt na 6 z techniki informatyki i jeszcze na dzień otwarty ;) więc do marca by mi to pasowało ogarnać. A książkę będę czytał i przyswajał pewnie ze dwa lata ;)
Czy w klejony kod powinien działać dobrze?
Acha i jakie rezystory zastosować do tych czujek, bo mówisz, że te złe...

Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 10-10-2017, 19:27   

Nie ja mówię, tylko Twoje eksperymenty. Też przecież je rozumiesz. Jeśli nowy kod działa, podaj wyniki to je omówimy. Przecież to tylko jeden z testów, nie pisałeś go dla wyglądu i elegancji tylko by coś sprawdzić. I co wyszło? Co mierzy ADC patrząc robotem w okno? Co na białej kartce? A co na czarnej? Liczby, wyniki, Kolego.
Dobrą książkę wciągniesz w tydzień. Potem jeszcze kilka projektów takich jak ten i zaczniesz czaić bazę :)

Postaw piwo autorowi tego posta
 
 
kamdz 



Posty: 64
Wysłany: 10-10-2017, 19:56   

Wyniki w zipie. Oczywiście okno jest z teraz, czyli ciemno.
Wyniki wyglądają raczej jakby powstały z funkcji
void zapodajjakasglupialosowaliczbe(); niż z mojej. Właśnie to mnie PRZERAŻA w tych czujkach...


screeny.zip
Pobierz Plik ściągnięto 4 raz(y) 177.17 KB

Postaw piwo autorowi tego posta
 
 
marek1707 



Posty: 4197
Pomógł: 450 razy
Otrzymał 595 piw(a)
Skąd: WAW
Programuję w:
C, asm
Wysłany: 10-10-2017, 23:59   

Czy przetestowałeś samą funkcję wypisywania wyników? Nie? To dlaczego jej wierzysz? Dlaczego wiele wpisów jest podwójnych? Skąd wiesz, że wypisywany string jest zakończony bajtem 0x00? Przecież itoa() tego nie robi a bufor ma tylko miejsce na 4 znaki. Może oznaczaj (np. gwiazdką) print pierwszego wyniku, bo teraz to sieczka.
Zacznij od testów poszczególnych kawałków. Jeśli napiszesz takie spaghetti, to same niepewne funkcje nie mają prawa działać a cóż dopiero całość. Wywal wypisywanie wyników do funkcji i każdą przetestuj osobno z pustego maina. Wymyśl jak to zrobić. Możesz np. samodzielnie wypełnić tablicę wyników znanymi liczbami i kazać je wypisać, prawda? Zaczynaj pisanie od prostych rzeczy, sprawdzaj czy to działa i dopiero bazując na tym pisz następne rzeczy.

Wyobraź sobie, że próbujesz naprawić telewizor przy pomocy zepsutego oscyloskopu pokazującego głupoty...

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: Czujnik siły - jaki ... "czunik" d... Gdzie kupić te czujn... Styczniki w MiniSumo...
lub przeszukaj forum po wybranych tagach: czujniki, do, jakie, linefollowera, pomoc, wyborze


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