60 nap alatt Arduino #07 - SOS villogó

A "60 nap alatt Arduino" tanfolyam házi feladatai és közvetlen témái
Válasz küldése
Avatar
TryMan
Újonc
Újonc
Hozzászólások: 8
Csatlakozott: 2012. május 10. csütörtök, 6:00

Hozzászólás Szerző: TryMan »

kapu48 írta:OK! Arduino.
Miért használtok ciklusváltozónak INT-et?

Mikor az 2 Bytes: http://arduino.cc/en/Reference/Int
Szerintem elég lenne a Byte-is: http://arduino.cc/en/Reference/Byte

Igy nem kellene a For ciklusban állandóan ellenőrizni, hogy történt e átvitel L > H Byte között.

Eredmény: Rövidebb, gyorsabb program! (Most 8 bites gépet programozunk. Nem 64 bites pentiumot.)
:)
Azért, mert ha belefér egy byteba, akkor a gcc úgyis kioptimalizálja, tehát a binárisban az byte lesz. Próbáld ki!
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Hiszem is vagy nem is?

Példa:
Int b;
b = potrb;
for(int i=0;i<b;i++){}

Itt honnan tudja, hogy mindkét int lehetne Byte-is?

:lol:
Avatar
TryMan
Újonc
Újonc
Hozzászólások: 8
Csatlakozott: 2012. május 10. csütörtök, 6:00

Hozzászólás Szerző: TryMan »

Nyilván minden esetben nem fogja tudni, de amikor tudja, akkor megoldja. Én arra válaszoltam, amit kérdeztél, hogy én pl miért használok intet. Erre az a válasz, hogy az én ciklusváltozóm 18nál nagyobb értéket nem vesz fel, és ebben az esetben a gcc bizony bytera fogja optimalizálni, nem kell törődni vele. Ha a ciklusinvariáns implicit módon is befolyásolva van, akkor lehet értelme figyelni a típusára valóban.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Mi van, akkor, ha:

Kód: Egész kijelölése

Int b; 
Int z;
b = potrb; 
for(int i=0;i<b;i++){
    i = i + z;
} 
Nagyon csúnya lenne, ha kioptimalizálná.... :(

Tipp: arduinoban definiálni Int-ként, Byte-ként, Char-ként és a lefordított kódméretet meglesni?
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Re: eeprom

Hozzászólás Szerző: macsek »

fodor99 írta:Jól sejtem ha megtanuljuk az EEPROM-ot használni akkor az SOS szignál tud majd ott folytatódni ahol megszakadt mikor kikapcsoljuk az ARDUINO-t?
Hát elvileg lehetne, de hamar kinyuvasztanánk vele az EEPROMot. Az eddigi megoldások kb 5 mp alatt lenyomták az egész vészjelzést. Tehát mondjuk 1,5 mp jut egy betűre.
BraskoS írta: A Morse időzítése:
Rövid (ti): 1 egység
Hosszú (tá): 3 egység
Betün belüli szünet a jelek között: 1 egység
Betük közti szünet: 3 egység
Szavak közti szünet: 7 egység
10 WPM (Word Per Minute) sebesség esetén 1 egység = 120ms

Ez alapján az S betű 5*120ms+360ms=960 ms, mondjuk 1 sec
Némi elhanyagolással a 100.000-szer írható EEPROM 100.000 mp azaz 1,15 nap alatt eléri a gyártó által definiált élettartamát.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Javaslat!

Beépítesz az egységedbe valamilyen RTC ICt + elemet. Amelyikben van SRAM és oda írhatsz, amíg az ellem, ki nem merül megmarad a változód!

Timekeeping & Real-Time Clocks:
http://para.maxim-ic.com/en/search.mvp? ... ree=timers

8)
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Hozzászólás Szerző: Robert »

Van külső SRAM IC is. Egyszerűbb.
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

SOS

Hozzászólás Szerző: macsek »

Szerk: Admin
A cikk a haladó témakört érinti!



Kérlek segítsetek, mit néztem el ennyire?
Valami borzasztó berregés kijön a csipogóból, a SZUNET allitására szinte érzéketlen. Tettem bele DEBUGot is, ami mondjuk ront a hangon, de azzal sem lelem, hol a hiba.
// SOS
// Macsek 2012 08 09
// morze hang+led

// aktualis hardver parameterei
#define LED 13
#define HANXORO 10
#define DEBUG 1 // 1: van 0: nincs

#define SZUNET 120L  // morze alapido, ti hossza
// szabvanyos ertekek, ld. wikipedia morze kod
#define TI SZUNET
#define TA (3*SZUNET)
#define SZOSZUNET (3*SZUNET)
#define MONDATSZUNET (7*SZUNET)

#define HANGMAGASSAG_VARAKOZAS 2500  // usec

// minden delay() hivas helyett ezt hivjuk meg es akkor "nem blokkolo" kesleltetesunk lesz
// ezzel meglesz a lehetoseg pl masik led villogtatashoz vagy soros port figyeleshez varakozas kozben
//////
// bemeno parameter: millisec
void delay_hanggal(unsigned long dly, byte /*igazabol boolean*/ hangiskell)
{
  if(DEBUG)
  { 
    Serial.print(":T=");
    Serial.print(millis());
    Serial.print(" dly=");
    Serial.print(dly);
    Serial.print("---- Hang is kell: ");
    Serial.println(hangiskell);
  }

  dly*=1000;  // millisec -> mikroszekundum

  if(hangiskell)
  {
    if(DEBUG)
    { 
    Serial.print("::T=");
    Serial.print(millis());
    Serial.print(" dly=");
    Serial.print(dly);
   }

    while((dly) > (2*HANGMAGASSAG_VARAKOZAS) ) // meg csokkenthetjuk
    {
      dly -= 2*HANGMAGASSAG_VARAKOZAS;
      if(DEBUG)
      {
        Serial.print(":::T=");
        Serial.print(millis());
        Serial.print(" dly=");
        Serial.print(dly);
      }

      digitalWrite(HANXORO, HIGH);
      delayMicroseconds(HANGMAGASSAG_VARAKOZAS);
      
      digitalWrite(HANXORO, LOW);
      delayMicroseconds(HANGMAGASSAG_VARAKOZAS);
    }  
    if (dly>0) // nem maradek nelkul volt oszthato 2*HANGMAGASSAG_VARAKOZAS-sal, meg kell varni
      delayMicroseconds(dly);
  }
  else
    delayMicroseconds(dly);
}

void morze_szoszunet()
{
  delay_hanggal(SZOSZUNET-SZUNET, false); // egy szunetnyi mar megvolt
}

void morze_mondatszunet()
{
  //delay_hanggal(MONDATSZUNET-SZUNET, false);
  delay(MONDATSZUNET-SZUNET);
}

void ti()
{
  digitalWrite(LED, HIGH);
  delay_hanggal(TI, true);
  digitalWrite(LED, LOW);
  delay_hanggal(SZUNET, false);
}

void ta()
{
  digitalWrite(LED, HIGH);
  delay_hanggal(TA, true);
  digitalWrite(LED, LOW);
  delay_hanggal(SZUNET, false);
}

void morze_s()
{
  ti();  ti();  ti();
  morze_szoszunet();  
}

void morze_o()
{
  ta();  ta();  ta();
  morze_szoszunet();  
}

void setup() /////////////////////////////////////////////
{
  pinMode(LED, OUTPUT);
  pinMode(HANXORO, OUTPUT); // toggle meg jobb lenne
  
  if(DEBUG)
  {
    Serial.begin(9600);
  }
}

void loop() /////////////////////////////////////////////
{
  //
  morze_s();
  morze_o();
  morze_s();
  morze_mondatszunet();
}

Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Szerintem túlbonyolítódtad az egészet!
Kis teljesítményű (8 Bites magnál) hanggeneráló rutinba Nem lehetnek ilyen:
„dly*=1000, dly -= 2*HANGMAGASSAG_VARAKOZAS; + a sok IF” hosszan futó műveletek!

Szétcseszi az egész időzítést.
Amire a fül nagyon érzékeny. Ez nem átlagol, mint a szemed!
:lol:
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

kapu48 írta:Szerintem túlbonyolítódtad az egészet!
Lehet.
Viszont akkor kérlek mutass egy nem túlbonyolított progit, ami miközben elvillogja a vészjelzést ugyanakkor a LEDen is világít amikor a hangot adja.

Köszi
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

morze hang+feny

Hozzászólás Szerző: macsek »

Elkészült :D

a while-os részt átírtam for-ra, ami nem sokban különbözik, viszont előre kiszámoltam mindent és a hang-generálásban csak sima ciklus maradt.

Ezzel együtt nem értem még sajnos, mi volt az előző verzió bibije. :oops:

NEKEM fülre ez sem tetszik igazán: az O betű után mintha többet várna, mint az első S után. Valakinek 5let?
// SOS
// Macsek 2012 08 09
// morze hang+led

// aktualis hardver parameterei
#define LED 13
#define HANXORO 10

#define SZUNET 120L  // morze alapido, ti hossza
// szabvanyos ertekek, ld. wikipedia morze kod
#define TI SZUNET
#define TA (3*SZUNET)
#define SZOSZUNET (3*SZUNET)
#define MONDATSZUNET (7*SZUNET)

#define HANGMAGASSAG_VARAKOZAS 2500  // usec

//// minden delay() hivas helyett ezt hivjuk meg es akkor "nem blokkolo" kesleltetesunk lesz
//// ezzel meglesz a lehetoseg pl masik led villogtatashoz vagy soros port figyeleshez varakozas kozben
////////
void delay_hanggal(unsigned long dly, byte hangiskell)
{
  unsigned long dly_us;
  unsigned long h, maradek;
  
  if (!hangiskell)
    delay(dly);
  else
  {
    // dly ms idot kell itt tolteni, kozben HANGMAGASSAG_VARAKOZAS us idonkent valtani a hangkimenetet
    dly_us = 1000*dly;  // atszamoljuk us-ba
    h       = dly_us / (2*HANGMAGASSAG_VARAKOZAS); // hanyados
    maradek = dly_us % (2*HANGMAGASSAG_VARAKOZAS); // ez a maradekot adja

    for(h=dly_us / (2*HANGMAGASSAG_VARAKOZAS); h>0; h--)
    {
      digitalWrite(HANXORO, HIGH);
      delayMicroseconds(HANGMAGASSAG_VARAKOZAS);
      
      digitalWrite(HANXORO, LOW);
      delayMicroseconds(HANGMAGASSAG_VARAKOZAS);
    } // for
    // ha szepen akarjuk csinalni akkor itt meg varunk egy picit
    delay(maradek);
  } // if
// delay_hanggal

void morze_szoszunet()
{
  delay_hanggal(SZOSZUNET-SZUNET, false); // egy szunetnyi mar megvolt
}

void morze_mondatszunet()
{
  //delay_hanggal(MONDATSZUNET-SZUNET, false);
  delay(MONDATSZUNET-SZUNET);
}

void ti()
{
  digitalWrite(LED, HIGH);
  delay_hanggal(TI, true);
  digitalWrite(LED, LOW);
  delay_hanggal(SZUNET, false);
}

void ta()
{
  digitalWrite(LED, HIGH);
  delay_hanggal(TA, true);
  digitalWrite(LED, LOW);
  delay_hanggal(SZUNET, false);
}

void morze_s()
{
  ti();  ti();  ti();
  morze_szoszunet();  
}

void morze_o()
{
  ta();  ta();  ta();
  morze_szoszunet();  
}

void setup() /////////////////////////////////////////////
{
  pinMode(LED, OUTPUT);
  pinMode(HANXORO, OUTPUT); // toggle meg jobb lenne
}

void loop() /////////////////////////////////////////////
{
  //
  morze_s();
  morze_o();
  morze_s();
  morze_mondatszunet();
}


Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Hozzászólás Szerző: SzLacus »

Hopp! Megjelent az első multitaszk igény? Vagy meg lehet oldani a felvetést a mi soványka tudásunkkal is?
Nekem is van egy felvetésem meg egy kérdésem a #20 lecke for ciklusos megközelítésével. A setup rész elhagyásával erről beszélek.

Kód: Egész kijelölése

void loop() {
        //ennyi darab impulzust kell kiadni
    temp1long=tartam/(var*2);
       //0..temp1long-ig szamolj, egyesevel
    for (long i = 0; i == temp1long; i++) {
        //hangszoro alacsonyra
      digitalWrite(Speaker,LOW);
        //varakozas valtas kozt
      delayMicroseconds(var);
        //hangszoro magasra
      digitalWrite(Speaker,HIGH);
        //varakozas valtas kozt
      delayMicroseconds(var);
      temp1long = temp1long-1;
    } 
      //10 sec szunet
    delay(10000);
      //utana kezdjuk ujra
Arra rájöttem, hogy a azért néma, mert a for feltétele soha nem tud igaz lenni. Vagyis a feltételnél "nem egyenlő" (!=) kell használni, hogy a ciklusba bele tudjunk kerülni.
Ha játszunk kicsit a hangmagassággal, akkor a "var" változót kell macerálni. El lehet érni olyan értéket, ahol az ismétlődő rövid hang helyett folyamatos hang az eredmény. Miért? Ez a kulcs?
temp1long=tartam/(var*2);
Amikor az eredmény nem fér el a deklarált változó típusban, akkor típust vált, és így mindig igaz a for feltétele, így soha nem jövünk ki belőle?
Valaki segítsen megérteni.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Hozzászólás Szerző: kapu48 »

Ötlet!
Egy ilyen deszkához mit szólsz?

Ezen élvezheted a C programozás örömeit!

Olcsóbb mint az Arduino, és 32 Bites ARM. + van rajta MP3 Dekoder Chip!
STM32F4DISCOVERY: http://www.st.com/internet/evalboard/product/252419.jsp
:wink:
Avatar
macsek
Bitmanipulátor
Hozzászólások: 121
Csatlakozott: 2008. december 4. csütörtök, 7:00

Hozzászólás Szerző: macsek »

Hehe, tök jót találtál.
Az általában használt forma: for(i=0; i<10; i++) { ciklusmag; }, már csak azért is, mert nem olyan szigorú a bentmaradási feltétel.
SzLacus írta:Amikor az eredmény nem fér el a deklarált változó típusban, akkor típust vált, és így mindig igaz a for feltétele, így soha nem jövünk ki belőle?
Annyi tuti, h nem fog típust váltani.
Ha nem fér el az eredmény akkor túlcsordul v alulcsordul. Az egyedüli ciki, ha nullával osztasz futásidőben, mert akkor ez történik vele 8)
(adalék: az AVR mikrokontrollerekben nincs osztó utasítás, szoftverből oldják meg)
Avatar
SzLacus
Tranzisztorgyógyász
Hozzászólások: 175
Csatlakozott: 2012. május 20. vasárnap, 6:00

Hozzászólás Szerző: SzLacus »

:-) Hát nulláig nem merészkedtem le, mert állítólag a fekete lyukak is úgy keletkeztek, hogy a teremtő nullával osztott. :-) De 120-tól lefelé és 16000-től felfelé könnyen lehet olyan értéket találni ami folyamatos hangot eredményez.
Mondjuk azt sem emeltem be, hogy miért a hang magasságával kombinálunk a példában. Miért nem adunk meg egy hangmagasságot, meg egy időtartamot, hogy meddig szóljon és akkor ez az egész osztósdi nem játszik.
A példában az is egy érdekes húzás, hogy a hang hosszát megadjuk, de ravasz módon a ciklus végén az is csökkentjük, meg a cikluson belül a közelítését is. Vagyis fele olyan hosszan fog szólni, mint a definicíóban megadott érték. Ennek persze további vonzata lehet, hogy az alulról és felülről közelítés eredményeként középen szépen elkerülik egymást, és ezért nem jön ki a ciklusból. Hú ezt ki is próbálom, lehet, hogy ez a megfejtés.
Válasz küldése