Pavouk Hiwonder

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Odpovědět
Uživatelský avatar
gilhad
Příspěvky: 832
Registrován: 07 bře 2018, 11:22

Re: Pavouk Hiwonder

Příspěvek od gilhad » 27 lis 2024, 01:54

Nojo, sci-fi, já ty SD používám pro zaznamenávání měření teploty na chatičce, protože je to tak nejjednodušší.
A když potřebuju rychle něco spočítat a neudělat chybu, tak si otevřu další terminál a spočtu to v bc a taky neřeším, že to běží na 24 threadů/32GB RAM, zatímco bych mohl od toho počítače vstát, udělat pár kroků a spočíst to na darované reklamní kalkulačce, nebo třeba na logáru :) Ale já raději zvolím nejpohodlnější cestu, i když je to overkill. (A to ani nemluvím o tom, že ten počítač používám i jako sériový terminál k 8biťáku s 32kB RAM.)

A ta Math je tam možná jen pozůstatek po ladění, jak jsem psal už minule. Nejsnáz to zjistíš, když ji zakomentuješ a sestavíš plně od začátku to bez ní a kompilátor to vezme bez připomínek a linker to slinkuje bez ní a bude to následně chodit stejně. Pokud kompilátor začne mít řeči, tak nejspíš i označí aspoň jedno místo, kde se nějak používá...

luger
Příspěvky: 217
Registrován: 30 dub 2023, 11:06

Re: Pavouk Hiwonder

Příspěvek od luger » 27 lis 2024, 09:45

Nakonec jsem to vyřešil bez knihovny "Math". Prostudoval jsem ten program na hwkitchen a přemýšlel jsem proč sčítá 100 hodnot a pak udělá průměrnou hodnotu. Tak jsem to vrazil do pavoučka a ejhle, funguje to, jen jsem snížil počet měření na 50 a stačí to.
Ono totiž když ho jen držím v ruce tak nemá žádné zrychlení, ale když s ním rychle máchnu na stranu okamžitě se všechny osy X,Y,Z zblázní a udávají šílené hodnoty. Pavouček má silné serva takže se rozběhne fakt rychle.
Takže zatím výsledný kod:

Kód: Vybrat vše

void gyroskop() {
    
  // zjistí všechny hodnoty z akcelerometru    accelgyro.getMotion (&ax, &ay, &az);   accelgyro.getAcceleration(&ax, &ay, &az);
  //accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  
  counter = 0;
  while (counter < 50)             // provede  měření
  {
    accelgyro.getAcceleration(&ax, &ay, &az);
  
  ax_p = ax_p + ax;
  ay_p = ay_p + ay;
  az_p = az_p + az;

  counter++;
  }
    
    x = ax_p/counter;               //zjistíme průmerné hodnoty
    y = ay_p/counter;
    z = az_p/counter;
    
    angle_x = abs(atan2(x, sqrt(pow(y,2) + pow(z,2)))/(pi/180));
    angle_y = abs(atan2(y, sqrt(pow(x,2) + pow(z,2)))/(pi/180));    //angle_z = atan2(az, sqrt(square(ax) + square(ay)))/(pi/180);
    
    //counter = 0;
    ax_p = 0;
    ay_p = 0;
    az_p = 0;
  }
A kontrola náklonu:

Kód: Vybrat vše

void Stop_naklon () {
    
    Controller.stopActionGroup();               // zastavit kroky
    beep3 ();                                   // 3x krátké pípnutí  
    Controller.runActionGroup(LEHNOUT, 1);      // lehnout
    delay (1000);
    stavy = 4;                                  // proměnná pro oled  - výpis "naklon"  
    
  cekat:
   test_naklonu ();                             // kontrola náklonu pomocí gyroskopu 
   if(naklon == 1){                             // při stálém náklonu stát a čekat na vyrovnání 
         
       OLED ();
       goto cekat;
       }
}

Uživatelský avatar
kiRRow
Příspěvky: 1266
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Pavouk Hiwonder

Příspěvek od kiRRow » 27 lis 2024, 15:38

vykašli se na goto, raději používej

while(testujNaklon == TRUE){}

s příkazem goto se musí velmi opatrně, protože můžeš dostat program do stavu "nedefinovaného toku programu" což je docela nedebugovatelné potom.

Celkově
... pokud vím, nebo umím spočítat kolik bude třeba cyklů v progamu (přečtení celého bufferu, načtení 50ti) ... použiji cyklus for.
... pokud nevím kolik přesně bude potřeba provést cyklů (např příjem dat z seriové linky) ... použiju cyklus while
... goto bych použil asi snad jen v případě, kdybych chtěl aby procesor vykonával několik od sebe velice různých "programů" a jejich výběr by byl nastaven v úvodním menu ... např nějaká multi krabička, která při funkci 1 bude potřebovat naprosto jinačí proměnné v ram, spouštět naprosto jinačí loop příkazů ...

luger
Příspěvky: 217
Registrován: 30 dub 2023, 11:06

Re: Pavouk Hiwonder

Příspěvek od luger » 27 lis 2024, 17:52

čekal jsem kdo se první na to goto ozve. Vyhráváš kiRRow. :lol: je to pozůstatek z Basicu. Pro mě je to tak přehlednější, stejně tak používám "or" a "and" apod.

Uživatelský avatar
kiRRow
Příspěvky: 1266
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Pavouk Hiwonder

Příspěvek od kiRRow » 27 lis 2024, 18:36

Chápu ... ale v C(++) podobném jazyce ... sice akceptovatelné, ale né moc doporučované. U Basicu to byla nutnost.
Problém je v kompilaci ... u C(++) si při volání funkce přebírá veškerou starost o provedení kompilátor, linker ... jak tam napíšeš goto, tak za vše jsi trestně zodpovědný sám ... a pokud naprosto přesně nevíš co dělá kompilátor a linker, tak se můžeš tímhle dostat velmi snadno do konfliktu ... nenadálý tok programu někam do 9té dimenze ... a to fakt chceš hledat a trasovat takovou chybu.

PS:
To neděláš dobře s těma sirkama Jaromíre ...

luger
Příspěvky: 217
Registrován: 30 dub 2023, 11:06

Re: Pavouk Hiwonder

Příspěvek od luger » 03 pro 2024, 18:14

Prozatím jsem využíval fotosenzor jen ke zapnutí a vypnutí blesku pro wifi kameru. Teď se snažím využít jeho analogového výstupu. První jsem zjišťoval hodnoty při různém okolním světle a při osvětlení baterkou. Je to docela citlivé a opakovaná přesnost docela ujde. Hodnoty jsou v rozsahu teoreticky 0-1024. Pavouček bude běhat jen po bytě takže se hodnoty pohybují v rozmezí 400 (světlo) - 1000 (téměř tma). Funkce je logaritmická takže se nebudu pouštět do větších akcí. Pokusně si zjistím číselné hodnoty a ty budu vyhodnocovat.
Pro lepší přehlednost si tyto hodnoty převedu do škály 0-9:

Kód: Vybrat vše

urovenSvetla = abs (9 -( svetlo/100));

V závislosti na úrovni světla by to mělo dělat asi toto:

- úplná tma - lehnout a čekat na světlo nebo aktivaci PIR (pohyb), možná čekat na zvukový signál
- šero - normálně si bude běhat podle potřeby, při osvětlení baterkou vykonat nějakou reakci (např. otočit o 180°). Tato reakce bude ještě závislá na náhodě aby se netočil pořad jedním směrem:

Kód: Vybrat vše

if (urovenSvetla > 6)                     // při osvětlení baterkou
   {
   Controller.stopActionGroup();            // zastavit kroky
   beep3 ();                                // 3x pípnout   -   kontrola 
   uroven = random (10);                    // pomocná proměnná náhody pro osvětlení
  
     if (uroven <= 4) 
     { 
      Controller.runActionGroup(DOPRAVA, 8);       // otočit o 180° doprava
    }
      else 
    {  
    Controller.runActionGroup(DOLEVA, 8);       // otočit o 180° doleva
    }
  }
- velké světlo - normálně si běhat a nereagovat na baterku.

luger
Příspěvky: 217
Registrován: 30 dub 2023, 11:06

Re: Pavouk Hiwonder

Příspěvek od luger » 05 pro 2024, 11:15

Na radu zkušenějších se snažím odstranit skoky typu goto.
Může ,prosím, někdo poradit jak elegantně vyřešit a nebo upravit tento "problém" toku programu ?

Mělo by to dělat toto:
- pavouček se přepne do módu "lehnout a čekat" -> void PIR
- rozjede se počítání "čekání"
- kontroluje se PIR nebo náhoda (1 ze 100) nebo napočítání 800 kroků počítadla (později tam vrazím i kontrolu na světlo a zvuk) a zároveň NÁKLON pavoučka, ten musí být vodorovný (naklon == 0), jakmile je příliš skloněný nesmí být podmínka splněná
- pokud jsou splněné podmínky pavouček se zvedne (funkce NAHORU) a pokračuje na hlavní program
- pokud nejsou pokračovat v kontrole

Tato má verze funguje, ale je asi trochu krkolomná:

Program:

Kód: Vybrat vše

void PIR () {
  
  Controller.stopActionGroup();               // zastavit kroky
  beep1 ();                                   // písknutí
  Controller.runActionGroup(LEHNOUT, 1);      // lehnout
  delay (2000);                               // uklidnit pavoučka

  digitalWrite (10,LOW);                      // zhasnutí LED blesku
    
  kroky  = 0;                                 // vynulování počtu kroků pavouka
  cekani = 0;                                 // vynulování orientačního počítadla  
  stavy = 2;                                  // pro podmínku na výpis oled  -> "PIR"
    
      // if (digitalRead (2) == HIGH) {delay (3000);}                       // počkej pokud píská klíčenka - nefunkční
      
start1:
  test_naklonu();                             //kontrola náklonu pomocí gyroskopu
       
  if ((( digitalRead(11) == HIGH) or (cekani > 800 ) or (random(100) == 1)) and (naklon == 0 ))
  {                                                                                  // čeká na PIR (11)  a zvuk ()  nebo uplynutí určité doby a nebo na náhodě
                                                                                     // v minutách - cekani ( / 60 ),      poloha musí být vodorovná -> naklon      
     beep0 ();                              // zvukové potvrzení 
     OLED ();                               // výpis na oled displej                                  
     Controller.runActionGroup(NAHORU, 1);  // zvednout  
     delay (1000);                          // uklidnění
   }
  
  else
  {
    OLED ();                                // výpis na oled displej
    cekani = cekani + 1;                    // počítadlo čekání v PIR
   goto start1;                             // zpět na kontrolu 
  }
}   
Potřebuji do toho vsunout ještě toto:
při prvním zaznamenání a reakci na PIR nebo (osvícení baterkou nebo zvukový signál) aby pavouček se jen zvednul, počkal jestli se "to" bude opakovat a když ne tak aby si zase lehnul a čekal (falešný poplach). Po např. druhém opakování stejného podnětu aby už přešel na hlavní program.
Toto už je asi dost složité, teda pro mě určitě

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti