Ovládání programovým vstupem, přepis programu v reálném čase

Ahoj všem, potřeboval bych poprosit o radu:
Existuje možnost ovládat jakéhosi robota “v reálném čase?” Chci říct, aniž bych musel před každou změnou chování flashovat?

Situace je taková, že mám (resp. známý má) robota, jehož včechny pohyby jsou tvořeny prací motorků. Vše funguje perfektně, je tam 12 motorků, některé řídí pohyb, některé ruce atd., ale je pro mě hodně nepohodlné za běhu programu vždycky přepisovat konkrétní hexa hodnoty, kompilovat a znovu flashovat při každém novém požadavku. Moc by se mi líbilo, kdyby šla spustit jakási konzole, kde by se čekalo na vstup z klávesnice. Představoval bych si to asi jako příkazy getch(); nějakej switch, pár podmínek a funkce, který budou přepisovat PORTA atd.

Existuje v takovémhle případě nějaká možnost, jak na základě vstupu uživatele okamžitě upravovat hexa hodnoty? Rád bych to ovládalů přes program, ne přes tlačítka. Snad sem popsal všechny potřebné věci. Děkuju moc všem za případné podněty. NK

:arrow_right: administrator: přejmenováno z "Ovládání programovým vstupem"

To jsem nějak nepochopil… Pokud chceš mít možnost manipulovat s porty ručně, tak si napiš podporu do programu. Jesli potřebuješ přepsat program pomocí nějakého komunikačního rozhraní bez připojování programátoru tak na to slouží bootloader.

Pokud se jedna jenom o to, prepisovat napr. rychlost zvedani nohy robota, nebo velikost zdvihu apod. Navrhoval bych tyto konstanty prepisovat pres FT232 (USB) nebo MAX232 (COM) rozhrani .
To znamena, ze si dodelas do robota RS232 komunikaci, a podle prikazu ti to potom zmeni hodnoty (napr. n1:10 bude znamenat ze nohu 1 bude zvedat jen na 10 stupnu maximalne)
Tyto hodnoty by bylo dobre pote ulozit do EEProm, aby pri vypnuti a zapnuti napajeni zustaly aktualni.
Na avrfreaks je mnoho tutorialu na RS232 komunikaci, jde to podle nich jednoduse udelat, jenom jsem neprisel na to jak pouzit FT232, jsem dost nesikovny na to zapajet do do DPS, takze zatim pouzivam MAX232
Doufam, ze to pomuze

Na prvním portu mám nastaveo pravou nohu robota. “01” znamená pohyb nohy vpřed, “10” pohyb vzad, čili otáčení motoru vpravo či vlevo. Zatím to dělám tak, že flashnu program s “00,” přes jinej port se rozsvitěj oči atd., potom otevřu zase zdroják, přepíšu “00” na “01,” robot vykročí pravou nohou. Pak zase ve zdrojáku přepíšu na nulu, druhej port, kde je druhá noha, nastavim hex na “01,” flashnu a robot zastaví pravou, vykročí druhou nohou, srovná krok a nakročí. Pak zase přepsat hodnoty, flashnout… pekelně otravný bych řek. Malej podprogram v céčku, kterej mi na základě vloženýho znaku z klávesnice změní nastavení portu, neboli jakékoli číslo budu chtít, bych měl, akorát to jaksi nejde implementovat. To čekání na vstup uživatele nejde provést. Ikdyž to jde zkompilovat a spustit, nikdo nečeká na vstup uživatele. Nevim, jestli je vůboc tohle možný v ATmega16 jo, jen se ptám, jestli je možný nějak napsat do zdrojáku “motorky.c” pár cyklů a podmínek.
Vlastně je to nastavený tak, že po flashnutí jsou nahraný do procesoru konstantní hexadecimální hodnoty. Já bych chtěl vědět, jestli je možný použít proměnný, který budou “proměnný” podle vstupu z klávesnice, třeba závislé na scanf(); nebo čemkoli,

př.:

char x;
char i;
scanf(“%c”,&x);
if (x==‘w’) i=0b00000001;


PORTA=i;

(syntaxe vem teďka čert)

abych mohl měnit hex hodnoty PORTA za běhu zkompilovaého a spuštěného programu. Jestli je možné v AVR naprogramovat a spustit konzoli, jako příkazovou řádku. Jestli ne, holt se nedá nic dělat.

Díky DragonSoul za nápad, pokud to nepůjde vyřešit softwarově, určitě o bude nejvhodnější řešení.

Jo aještě bych se chtěl zeptat: PORTA=0b00010000; -

  • v céčku je hexadecimální zápis datového typu int ve formátu 0x00010000, co za datovej typ, jestli se to tak dá říct, je 0b? Dá se použít i 0x? Je 0b prostě věc AVR a vlak přes to nejede? Týhle části zrovna moc nerozumim. Ještě jednou děkuju. NK

0b je binární formát - např. 0b11110000
0x je hexadecimální formát - např. 0xF0

A teď jen čistě teoreticky - přes UART si pošleš data z PC do uC a v něm si programově ošetříš zápis poslaných dat do příslušných proměnných pro pohyb robota. Prostě místo konstant použiješ proměnné, do kterých budeš sypat data přijatá z PC. Ovšem konkrétní návod ti nedám, s uC teprve začínám, živím se programováním PLC.

Tak pokud jsem to pochopil dobre tak bych udelal neco takoveho (symbolicke programovani)

nahrani knihoven (delay, io apod)

a potom v main
DDRA=0b00000011; //nastaveni 1 a 2 bitu porty A jako vystup
DDRB=0b00000001; //nastaveni 1.bitu portu B jako vystup
Portb=0b00000001; //Rosviceni oci

for (;;)
{
 PORTA=0b00000001; //zapnout motorek noha jede nahoru)
 _delay_ms(2000);      //Cekani 2 sekundy)
 PORTA=0b00000010; //zapnout motorek druhym smerem, noha jede dolu

// atakdale atakdeale
}

V pripade ze chces neco ovlivnovat treba neco jako dalkove ovladani tak neni nic jednodussiho, nez si vyhradit jeden port jako vstupni a na nej pripojit treba mikrotlacitka
a potom bude kod neco jako

nahrani knihoven (delay, io apod)

a potom v main
DDRA=0b00000011; //nastaveni 1 a 2 bitu porty A jako vystup
DDRB=0b00000001; //nastaveni 1.bitu portu B jako vystup

for (;;)
{
  if (PINC==1)  PORTB=0b00000001; // rosviceni oci 
  if (PINC==2)  PORTA=0b00000001; // noha jede nahoru
  if (PINC==4)  PORTA=0b00000010; // noha jede dolu

// atakdale atakdeale
}

Snad neprogramujes S7-300?

Dělám hlavně GE Fanuc, ale Siemens už jsem měl taky na stole. Jeden se mi dokonce válí ve skříni, ale chybí mi převodník na MPI, ty se u nás na firmě moc nepůjčují. Potřebuješ něco :smiley:

kolemjdouci: O to, jesli to zvládne mega16 nemusíš mít obavy. Ještě nějaký pátek potrvá než “přerosteš” její možnosti :slight_smile:
Pokud potřebuješ prozatím jen dle přijatého příkazu po sériové lince provést nějakou akci, zkus následující kód:

[code]// mega16
#include <avr/io.h>
//#include <util/delay.h>

void serialInit(void)
{
// 9600bd, 8N1, Fcpu=16MHz
UCSRB |= (1<<RXEN) | (1<<TXEN); // Receiver Enable, Transmitter Enable
// 8N1 je default nastaveni po resetu
UBRRL = 103;
}

unsigned char serialRead(void)
{
while(!(UCSRA & (1<<RXC))); // cekej nez dojdou data
return UDR;
}

int main ()
{
// inicializace mcu
// dopsat nastaveni portu apod.

serialInit();

for(;;)
{
	//
	switch(serialRead())
	{
		case 'a':
			// blok instrukci prikazu "a"

			break;

		case 'b':
			// blok instrukci prikazu "b"

			break;

		default:
			// blok instrukci pro prikaz jiny nez nektery z predchozich

			break;
	}
}
return 0;

}[/code]
Nezkoušel jsem ho, takže kdyby byl nějaký problém, jsem tu. Když pošleš po uartu do mcu písmeno, měly by se vykonat příkazy v příslušném bloku.

Dragon: Použití FT232 je jednoduché. Má Rx a Tx, které připojíš do mcu, pak usb linky, kterými komunikuje s PC. Do PC stačí nainstalovat VCP ovladače ze stránek výrobce. Připojením zařízení do USB je vytvořen virtuální sériový port. Co do něho zapíšeš bude automaticky posláno do mcu a naopak. Z pohledu obslužného SW a MCU se oproti fyzické RS232 s maxem nic nemění.

Ja se zivim programovanim S7-300.
Jinak k tomu FT232. Asi bych nemel problem pripojit ho tak aby komunikoval. Mam problem s tim, napajet ty strasne malicky nozicky na DPS tak aby se mi ani jedna neslila :slight_smile:

Myslim ze hlavni problem je, ze nevime, co to ma vlastne doopravdy delat.
Je mnoho zpusobu jak udelat robota na dalkove ovladani (IR, 232 atp).
Pokud je jenom problem udelat, aby se sam pohyboval dopredu a dozadu, doporucoval bych zacit jednoddussim pripadem, napr vozitko s 2 motory jeden pohaneci druhy zataceci a nejake narazove senzory a na tom se clovek nauci dost na to, aby potom ovladl 12 moturku apod.
Jen se toho nebat…

Mě to šlo poměrně dobře. Měl jsem desku s HALem, chytil si jen 2 protější a zbytek pájel bez přídavku cínu ale s tavidlem po čtyřech najednou :smiley:

Případ, kdy chtěl žadatel “jen poradit” s rozchozením jeho návrhu bez popisu požadované činnosti tu nedávno byl. Teprve po 3 stranách jsme se dozvěděli, že onen návrh nemá nejmenší šanci na splnění požadavků. Tohle ale snad nebude ten případ, jak jsem to zatím pochopil, mělo by pro začátek jen stačit to vykonávání operací dle přijatého příkazu.

Prakticky jsem se chtěl vyhnout sériovému portu, teď už ale vidím, že to bude nejjednoduší. Ale určitě využiju všechny rady, moc díky. Ještě přiložim trošku kódu.

Tohle je program na ovládnutí motorků


#define F_CPU 16000000
#include  <avr/io.h>				// vložení knihovny
#include<stdio.h>
#include<util/delay.h> 



int mezera_delay (void)				// podprogram zpozdeni
     {
      int i;						// deklarace promenne
      for (i=60; i>0; i--)			// cyklus for - probiha 100x 10ms = 1s
          {
           _delay_us(1);			// zpozdeni 10ms
	      }

      }


int impuls_delay (void)				// podprogram zpozdeni
     {
      int i;						// deklarace promenne
      for (i=40; i>0; i--)			// cyklus for - probiha 100x 10ms = 1s
          {
           _delay_us(1);			// zpozdeni 10ms
	      }

     }

// -------------------- 

 int main (void)
   {
      DDRB=0xff;						// nastaveni portu B jako vystup
      DDRA=0xff;


    while (1)
    {	  
		
		
		
		PORTA=0b00000000;                 
	  	mezera_delay();			
	    PORTA=z;                 // zde by byla promenna z nasledujiciho programu
        impuls_delay();

	}

//    PORTA=0b76543210; 
//    PORTA=0b00XX0000; 



    
}

A do toho zakomponovat něco takovýho. Když už běží program, proč to neovládat přes něj, třeba takhle:

[code]
char i; // globalni promenne
int z;

int main()
{
i=getch();
switch(i){ // “rozcestnik”

 case 'w': fce1(); break;         
 case 's': fce2(); break;
 case 'a': fce3(); break;
 case 'd': fce4(); break;
 case 'y': fce5(); break;
 case 'x': fce6(); break;
 case 'f': fce7(); break;
 case 'g': fce8(); break;
 case 'r': fce9(); break;
 case 'c': fce10(); break;
 case '0': fce11(); break;
}

if (i!='w' || i!='s' || i!='a' || i!='d' || i!='y' || i!='x' || i!='f' || i!='g' || i!='r' || i!='c' || i!=0)                   

main();                                 // cykluj menu, dokud se nezada spravny znak

}
int fce1(){
z=0b00000001; // tady nevim, jaky dat. typ mi precte binari cislo v tomhle formatu, detail
main();
}
int fce2(){
z=0b00000010;
main();
}

int fce11(){
z=0b00000000;
main();
}[/code]

tim by se zaručila změna binárního čísla na PORTA okamžitě při stisku klávesy. Toto je můj záměr z původního dotazu. Zkoušel jsem to tam nějak protlačit, ale nejede to. Vy určitě budete vědět proč, já netušim. 232 bude asi jednodušší… Díky za rady. NK

Ovladani RS232 neni taky zadna vyhra, protoze musis mit dost dlouhy kabel, nebo bluetooth modul, ktery se prodava cca za 600kc + notebook s bluetooth.
Ja bych se primlouval za dalkove ovladani (snurka s 10 vodici) kde by si mel tlacitka kterymi by si ovladal jednotlive veci robutka.
Nemusis se trapit s tim, jestli ti zrovna rs232 funguje nebo ne.
Pro jednoduche funkce jako je rozsviceni oci, nebo zvednuti spusteni rukou je jednoducha funkce pokud je tlacitko stlacene udelej prikaz, ale napr. pro pohyb robutka dopredu, nebo otaceni je potreba naprogramovat cely system pohybu, jejichz cyklickym opakovanim dojde k pohybu robota.
Protoze tady neni zadna fotka, predstavuji si tveho robutka zatim jako pavouka, ale prosim upresni, jestli je to pavouk, nebo auticko.
Hodilo by se schema robutka, nebo alespon nejake foto s umistenim moturku.
Pokud ma nozicky, tak bych docela uvazoval o mikrospinacich na noze robota, ktery by mi rekl, ze noha je konecne na zemi, a ja muzu pokracovat v dalsim pohybu.
Jinak programovani zdar, momentalne mam uz tyden problem s nahravanim SW do uC, takze jenom susim pusu :frowning:

S těma nohama to bylo dost složitý, už je jen na kolečkách, byly tam původně tažný nohy, ale to bylo moc velký maso. Na kolečkách to teď sviští pěkně. Vypadá to trochu jak číslo 5 :slight_smile: Ne, celkovej vzhled ještě neni jasnej, pořád měnim kastle, ale je tam podstava na třech kolech, třetí kolo v zadu se otáčí a mění směr pohybu, nosné tyče těla, pár plechů, ruce zvedané vysouváním šroubovice, lokty, tři prsty, hlava se otáčí stejným způsobem, oči z ledek blikají. Plánuju další funkce, ale všechno na stejnym principu. Prakticky jsem na začátku. Fotky jsem zatim nepořizoval, myslim, že ani nebudu, dokud to nebude k něčemu vypdadat. Nejsem tajnůstkář, ani se nebojim třeba o nápad nebo něco. To vůbec, jen se bojim, že když to vyfotim, tak s tim už dál nepohnu :slight_smile:
Abych řek pravdu, nejvíc by se mi líbilo, kdyby to šlo udělt přes ten program, myslim, že to musí nějak jít. Ještě jsem nikde nenarazil na nějaký podobný řešení, ale neni to nic tak zvláštního, ne? Vlastně bych jen chtěl, aby ten program, kterej jsem napsal, byl vidět nejen na otáčení motorů, ale i v softwarový podobě, chtěl bych monitorovat aktuální hodnoty na portech v programu, v konzoli normálně. V céčku jako takovym jsem už sem tam něco naprogramoval, spíš teď maličko přesedlávám na mikročipy a seznamuju se s implementací céčka v těchhle věcech. Ale opravdu mi tady pár věcí chybí. Vlastně celej koncept by měl vypdat tak, že robot bude mít na sobě eeePC a budu ho ovládat přes vzdálenou plochu, taková třešnička :slight_smile: K tomu právě potřebuju spuštění toho programu i v okně. Holt budu muset asi slevit ze svejch vizí a nároků.

Co ti pbrani napisat yklad pre ovladanie do mcu… a pomocou ineho programu v Cku (delphi) vztvorit hlavnz program na ovladanie robota :smiley:

Brání mi to, že nemám jedinej nápad, jak to dát do kupy. Jak jsem psal výše, instrukce pro MCU mám, program v C, kterej by dosadil na základě požadavku konkrétní binární hodnoty na port mám taky, ale nějak vůbec netušim, jak to oboje funkčně skloubit. Jsem fakt na začátku, takřka o tom vim kulový… :neutral_face: Nevim, možná na to jdu úplně blbě.

Na PC si napiš program, kterej bude na sériovou linku posílat příkazy. MCU je přijme a podle příkazu vykoná akci. Nic na tom není (pokud umíš napsat program pro PC), pro začátek stačí i nějaký terminál.
Je nutné si uvědomit, že program v MCU nemá s programem v PC krom komunikace nic společnýho.

Uf, fakt potřebuju nakopnout, a to pořádně, sám si neporadim. Terminál mám: Terminal v1.9b. Ale něco mi chybí. Myslim, že základní znalosti oboru. Znamená to, že do MCU nahraju svůj standardní program, s binárníma hodnotama na ovládání portu na stardardních hodnotách, a jsem pak schopnej pomocí sériové linky nahrávat konkrétně jen y hodnoty, které potřebuju měnit? Koukejte na mě, hrnu se tady do robota, zdrojáky poskládám ze střepů, náhodou to funguje, ale skončim na tom, ž nerozumim základům. Myslim, že je čas lehnout do knih. Mohl byste mi, prosím, někdo poradit, jak by to mělo schematicky vypadat? Nebo jak bych měl upravit ten zdroják, aby to bylo schopný měnit ty binární hodnoty?

Když vidím, jak se v tom programu pokoušíš volat main(), tak je vidět, že máš problémy i s C a cykly. Provádíš tam nějakou nekonečnou rekurzi a to není dobrý nápad.
Pro začátek bych vzal ten můj kód a do bloků “case” vepsal požadovaný kód třeba pro rozsvícení LEDky (kterou tam očividně máš. Do druhého dej zhasnutí a až to budeš mít funkční, tak se pokoušej dále. Ještě sem vlož propojení mcu s PC.

Tak sa mi zda, ze nevies ako pouzivat normalne premenne v RAM a EEPROM.
Na zaklade hodnory v nejakej premennej pomocou SWITCH/CASE modifikuj chovanie programu. No a tu hodnotu na konkretne miesto v RAM posielaj cez RS232. Alebo si inak potom myslim, ze si tu z nas robis srandu.
Este som sa nestretol s vacsim nezmyslom (prepac za vyjadrenie) ako ze chces modifikovat chovanie zariadenia pre okamzite zmeny - napr. pohyb dopredu/dozadu - prepisanim celeho programu.

Ak chces silou mocou pouzivat programator, tak si preprogramuj iba pamat EEPROM a na nejakom konkretnom mieste men hodnotu tak, aby Ti to vyhovovalo. Urcite neprepaluj cely program.