Yrobot

Pochlubte se svým robotem ostatním!
Odpovědět
Baworek

Re: Yrobot

Příspěvek od Baworek »

Tak asi som na to prišiel možno... :D

Tak si to pozri či som sa potrápil :) dostatočne bo už fakt neviem...
Jeden Ujko na školení mi povedal že takto by to malo fungovať... :)
Síce som na pochybách ale čo ty na to ??

Kód: Vybrat vše

void initOPT(void) { // void znamena neco jako "nic" (tato funkce tedy nevraci zadnou navratovou hodnotu)
      // zatim ta funkce nedela vubec nic, ale pozdeji bude inicializovat porty a piny pro modul OPT
     
     OPT_PORT&=~((1<<PA0)|(1<<PA1)|(1<<PA2));
     OPT_DDR |= (1<<PA0)|(1<<PA1)|(1<<PA2);
   }
AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Yrobot

Příspěvek od AlesH »

Hmm, napsal jsem, že bity v DDR registru je třeba nastavit na nuly a ty tam zase napereš jedničky. To už docela nechápu. Kašlu na to, níže uvádím zápis, který považuji za funkční (a v komentářích uvádím, proč si to myslím [reálně ověřit to nemohu, protože nemám Yrobota]):

Kód: Vybrat vše

void initOPT() {  // funkce pro inicializaci portu pro OPT modul
  OPT_DDR &= ~((1<<PA0)|(1<<PA1)|(1<<PA2));  // OPT_DDR nuly pro vstupy (shift << nastavi jednicky na nase bity, negace ~ to otoci a &= zajisti zachovani ostatnich bitu)
  // OPT_PORT &= ~((1<<PA0)|(1<<PA1)|(1<<PA2));  // nastaveni OPT_PORT bitu na nuly jen vypina pull-up odpory a snad ani neni nutne (proto je to zatim zakomentovane)
}
Pojďme dál. Potřebujeme číst ADC hodnoty z jednotlivých snímačů a rozhodovat, jestli odpovídá bílé (papíru), nebo černé (čáře). Doporučuju pro začátek napsat testovací program, který třeba z prostředního snímače přečte hodnotu a zobrazí ji na LED sedmisegmentovkách robota. Tak půjde experimentálně určit vhodnou úroveň, podle které se pak budeme rozhodovat, jestli pod snímačem je čára nebo ne. Pro napsání toho programu je nejsnazší se nechat inspirovat částí funkce "basic_test()" z příkladu "Demo".

Takže tady je (neúplná) holá kostra takového testovacího programu (v komentářích je moje inspirace, jak ho doplnit):

Kód: Vybrat vše

int main()
{
  init();                  // inicializace vseho potrebneho mimo OPT modul
  initOPT();               // inicializace OPT modulu
  while(1) {            // zakladni nekonecna smycka
    // vyber AD prevodniku (prislusneho strednimu snimaci)
    // cteni hodnoty z ADC (rozsah je 0 - 1023)
    // zobrazeni orezane ADC hodnoty na LED displeji (je nutno ji delit 4 pro HEX vypis [0-FF] nebo 11 pro DEC vypis [0-99])
    // cekani cca 100 ms abychom tu smycku netocili zbytecne moc rychle
  }
}
Jdeš do toho pokračování? Pokud ano, tak do té while smyčky doplň reálné příkazy před ty moje komentáře (tam, kde příkazy ještě nejsou).
Baworek

Re: Yrobot

Příspěvek od Baworek »

Ahoj...

Najprv ti popíšem prečo som písal:

Kód: Vybrat vše

     OPT_PORT&=~((1<<PA0)|(1<<PA1)|(1<<PA2));
     OPT_DDR |= (1<<PA0)|(1<<PA1)|(1<<PA2);
Prezeral som si v yellow_robot veci ako sú tam napísané "ako zapína a vypína niečo"
a našiel som toto:
Obrázek
(nájdeš to aj ty v yellow_robot.c)

Preto som si to myslel ale v pohode nič sa nedeje dúfam ?

Čo sa týka... Pokračovania...
Nerozumiem sa moc do tých LED "segmentiek" a rád by som bol ak by som zistil ako to funguje... Spolu aj z tými AD kanálmi...
Aby som mal niečo v hlave naviac... :D

Dúfam že sa s toho vysomárim...

Pozeral som si basic_test() a neviem ako sa mi podarilo to tam hodiť teda som do while(1) nič nepísal len upravil ten basic_test a dopracoval som sa len k tomu že...
Ak som dal prst na ľavý senzor tak LED menila hodnoty C1 až C5 ale na ostatné mi to nikdy nešlo (myslím UPROSTRED/VPRAVO) a tak som si povedal že to bude špatne.

Iba toto som si upravoval (z toho basic_testu):

Kód: Vybrat vše

	for (i=0; i<1; i++)
	{
		led_on(VLAVO);	
		delay_ms(100);		/*cakaj*/
		led_off(VLAVO);
		delay_ms(100);		/*cakaj*/
	}
Potom ma napadlo že led_on je pre ledky :D tak som si vyrobil "void snimac_on/off(u8 sni)" a nahradil "led_on"

Kód: Vybrat vše

void snimac_on(u8 sni)
{
	sni&=(VLAVO|VPRACO|UPROSTRED);	
	OPT_PORT&=~sni;
}

void snimac_off(u8 sni)
{
	sni&=(VLAVO|VPRACO|UPROSTRED);	
	OPT_PORT|=sni;
}
Na základe tohto mi iba lavý senzor meni hodnotu na segmentovke C1-C5 :D

Fakt musím prísť na to čo to je a ako funguje ten LED a tie kanály :)
AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Yrobot

Příspěvek od AlesH »

Ahoj. Pro dobré pochopení situace je třeba vidět všechny potřebné souvislosti. V Yrobotu totiž piny pro BEEP, LED_7 a LED_8 používají tzv. "negativní logiku", takže např. LED svítí při logické nule a nesvítí při logické jedničce (lze to poznat ze schématu zapojení). Proto se ve "standardní logice" musí používat přesně obrácené zápisy pro "nastavení a vypnutí něčeho". A to je i případ DDR registru pro snímače. Inicializaci portu pro snímače už ale opusťme a berme ji za použitelnou (tu mojí).

Experimentovat s celým kódem funkce basic_test() je zajímavý přístup, ale myslím, že v tomto případě je to matoucí (v té funkci většinu věcí vůbec nepotřebujeme ani nechceme). Musíme si vybrat jen to, co se nám hodí. Nejdůležitější je si uvědomit, že pro čtení stavu snímačů už nebudeme OPT_PORT nastavovat, ale budeme z něho jen číst (OPT_PORT by se v našem programu už nikdy neměl vyskytnout vlevo od rovnítka). Číst budeme analogově, takže z basic_test() vybereme jen část, která se týká testu odporového trimru v Yrobotu. Jde nám tedy jen o funkce adc_channel_set(), adc_read(), led_display_hex() a delay_ms(). Výsledkem budou jen čtyři řádky našeho testovacího programu (jak už jsem naznačil v jeho "kostře" a jak teď ještě trochu víc "napovím"):

Kód: Vybrat vše

  while(1) {            // zakladni nekonecna smycka
    // vyber AD prevodniku (prislusneho strednimu snimaci) => pouzijeme adc_channel_set()
    // cteni hodnoty z ADC (rozsah je 0 - 1023) => pouzijeme adc_read()
    // zobrazeni orezane ADC hodnoty na LED displeji => pouzijeme  led_display_hex()
    // cekani cca 100 ms abychom tu smycku netocili zbytecne moc rychle => pouzijeme delay_ms()
  }
Zkus teď ty funkce reálně použít v programu (jejich zapsáním před komentářová dvojitá lomítka a doplněním vhodných parametrů). Znovu se inspiruj malou částí demo funkce basic_test() [ale nedávej ji celou do našeho programu]. To je nejbližší krok ke sledovači čáry.

Musím ještě zdůraznit, že navrhuji v testu číst zatím jen střední snímač, protože v Yrobotu je zřejmě standardně zapojen odporový trimr přesně tam, kam je zapojen levý snímač OPT modulu (na ADC0). Aby dobře fungoval levý snímač, bude třeba trimr od ADC0 nějak "odpojit" a to zatím nevím jak (ve schématu Yrobota není nakreslena žádná vhodná propojka, kterou by šlo rozpojit). Mimochodem, v basic_test() se na sedmisegmentovkách zobrazuje právě jen stav ADC0 (najdi si to v programu), a proto to zatím trochu reagovalo právě jen na levý snímač (ještě víc by to asi reagovalo na otáčení trimrem).

Teď se ale soustřeď na ten testovací program. Výsledkem musí být jen čtyři řádky kódu (s využitím funkcí navržených v komentářích). Ten výsledek sem potom, prosím, pošli.

Poznámku mám ještě k tomu, že v Yrobotu můžeš číst najednou jen jeden ADC kanál (nepokoušej se tedy analogově číst všechny tři senzory naráz).

P.S.: Tvoje pokusy s led_on() a snimac_on() byly zcela mimo. Zapomeňme na ně.
Baworek

Re: Yrobot

Příspěvek od Baworek »

Toto bude asi zle...
No keby nahodou tak adc_res>>2 mi nefunguje bo ho nemam deklarovaný...
ale vo void basic_test() ho mam... tak ako je original...

Kód: Vybrat vše

			adc_channel_set(UPROSTRED);
			adc_read(0);
			led_display_hex(adc_res>>2);
			delay_ms(100);
AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Yrobot

Příspěvek od AlesH »

Solidní výsledek. Řekl bych, že to "skoro" mohlo fungovat. Problém je jen s tím "adc_res" a "adc_read()", takže doporučuji to zapsat úplně stejně, jako je to v "basic_test()", tedy "u16 adc_res = adc_read();". Tím se v jednom řádku definuje potřebná proměnná a rovnou se do ní načte hodnota z aktuálního ADC.

Celý funkční testovací program by měl teď vypadat zhruba takto (volání celého "basic_test()" se v něm nikde nesmí vyskytovat):

Kód: Vybrat vše

#include "yellow_robot.h"   // vlozeni HAL knihovny pro abstrakci od HW Yrobota

#define VLEVO	PA0         // OPT snimac vlevo (vstup, ADC0)
#define UPROSTRED	PA1     // OPT snimac uprostred (vstup, ADC1)
#define VPRAVO	PA2         // OPT snimac vpravo (vstup, ADC2)
#define OPT_PORT	PORTA   // OPT modul je na portu A
#define OPT_DDR		DDRA    // registr pro nastaveni smeru pinu pro OPT modul

void initOPT() {            // funkce pro inicializaci portu pro OPT modul
  OPT_DDR  &= ~((1<<VLEVO)|(1<<UPROSTRED)|(1<<VPRAVO));  // DDR nuly pro vstupy
}

int main() {
  init();  // inicializace vseho potrebneho mimo OPT modul
  initOPT();  // inicializace OPT modulu

  while(1) {  // zakladni nekonecna smycka
    adc_channel_set(UPROSTRED);  // vyber AD prevodniku (prislusneho strednimu snimaci)
    u16 adc_res = adc_read();  // cteni hodnoty z ADC do promenne adc_res (rozsah 0 - 1023)
    led_display_hex(adc_res>>2);  // zobrazeni orezane ADC hodnoty na LED displeji (rozsah 0 - 255 [FF])
    delay_ms(100);  // cekani cca 100 ms abychom tu smycku netocili zbytecne moc rychle
  }
}
Přeložit to jde, reálně ověřit v Yrobotu to nemohu.

Pokud to bude fungovat, napiš co to zobrazuje za hodnoty, a pak budeme moci pokračovat.
Baworek

Re: Yrobot

Příspěvek od Baworek »

Funguje to :)

Vždy keď priložím pst na stredný senzor tak mení hodnoty na segmentovke :)
AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Yrobot

Příspěvek od AlesH »

Výborně! Tak teď si vyrob alespoň "simulátor čáry" (na kus papíru [čtvrtku] nalep čáru udělanou z elektrikářské izolačky [šíře 15 mm], nebo tu čáru nakresli sytou černou fixou), pak postav Yrobota do "pracovní polohy" a zaznamenej hodnoty pro "bílou" (papír) a "černou" (čáru). Ty čísla sem pak napiš (informace "mění se to" mi nestačí).
Baworek

Re: Yrobot

Příspěvek od Baworek »

Urobil som to tak ako píšeš...

Nebudeš veriť ale ono to je čudné...

Ak položím na čiernu pásku stredný snímač ukáže: Eb
Keď to položím na biely papier ukáže: EA

Ale... ak zmením polohu t.j. výšku snímača dajme tomu 1mm.
tak na bielom podklade mení hodnoty na : E4,E5,E6,E7,E8,E9 a na čiernej zobrazí Eb alebo ale to iba niekedy EA :D
Kukni video...
http://youtu.be/D-S9JXO7AQU
AlesH
Příspěvky: 323
Registrován: 25 úno 2013, 09:18

Re: Yrobot

Příspěvek od AlesH »

S vysokou pravděpodobností ty IR LED ve snímačích vůbec nesvítí (nejsou připojeny na napájení). Ty pozorované změny jsou totiž příliš malé. Potřebujeme dosáhnout výrazné změny i u toho prvního zobrazovaného čísla (které je teď pořád "E").

Obával jsem se nejasností v zapojení propojek a bohužel nastal ten horší případ (nefunguje to).

Nevím jistě, jaké propojky máš teď spojené, ale doporučuji u propojky S1 (té "dolní", blíže snímačů) spojit všechny tři vývody. Není to sice úplně "čisté", ale mělo by to spolehlivě zaručit funkčnost napájení IR LED ve snímačích. Druhou možností je vzít znovu multimetr a "propísknout", jestli je spojen vývod 8 dlouhého konektoru na OPT modulu (Ucc) s prostředním vývodem propojky S1.

Osobně bych to u S1 spojil všechno dohromady. Pak dej vědět, jestli se výsledek změnil (program v Yrobotu zůstane stejný).

P.S.: Pro jistotu bych zatím z OPT modulu vyndal ten ultrazvukový modul, protože ho teď nepotřebujeme a mohl by nám při testech překážet (jen zbytečně "žere baterku").
Odpovědět